#include <folly/FBString.h>
#include <folly/Likely.h>
#include <folly/Range.h>
+#include <folly/Traits.h>
#include <folly/Unit.h>
#include <folly/portability/Math.h>
classname, func_name, /* nolint */ volatile); \
FOLLY_CREATE_HAS_MEMBER_FN_TRAITS_IMPL( \
classname, func_name, /* nolint */ volatile const)
+
+/* Some combinations of compilers and C++ libraries make __int128 and
+ * unsigned __int128 available but do not correctly define their standard type
+ * traits.
+ *
+ * If FOLLY_SUPPLY_MISSING_INT128_TRAITS is defined, we define these traits
+ * here.
+ *
+ * @author: Phil Willoughby <philwill@fb.com>
+ */
+#if FOLLY_SUPPLY_MISSING_INT128_TRAITS
+FOLLY_NAMESPACE_STD_BEGIN
+template <>
+struct is_arithmetic<__int128> : ::std::true_type {};
+template <>
+struct is_arithmetic<unsigned __int128> : ::std::true_type {};
+template <>
+struct is_integral<__int128> : ::std::true_type {};
+template <>
+struct is_integral<unsigned __int128> : ::std::true_type {};
+template <>
+struct make_unsigned<__int128> {
+ typedef unsigned __int128 type;
+};
+template <>
+struct make_signed<__int128> {
+ typedef __int128 type;
+};
+template <>
+struct make_unsigned<unsigned __int128> {
+ typedef unsigned __int128 type;
+};
+template <>
+struct make_signed<unsigned __int128> {
+ typedef __int128 type;
+};
+template <>
+struct is_signed<__int128> : ::std::true_type {};
+template <>
+struct is_unsigned<unsigned __int128> : ::std::true_type {};
+FOLLY_NAMESPACE_STD_END
+#endif // FOLLY_SUPPLY_MISSING_INT128_TRAITS
AC_TYPE_SIZE_T
AC_HEADER_TIME
AC_C_VOLATILE
-AC_CHECK_TYPE([__int128], AC_DEFINE([HAVE_INT128_T], [1], [Define if we have __int128]))
+AC_CHECK_TYPE([__int128], [folly_cv_prog_cc_int128=yes],
+ [folly_cv_prog_cc_int128=no])
+if test "$folly_cv_prog_cc_int128" = "yes"; then
+ AC_DEFINE([HAVE_INT128_T], [1], [Define if we have __int128])
+ AC_CACHE_CHECK(
+ [for __int128 type traits],
+ [folly_cv_prog_cc_int128traits],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE([[
+#include <type_traits>
+static_assert(
+ ::std::is_same<::std::make_signed<unsigned __int128>::type, __int128>::value,
+ "signed form of `unsigned __uint128` must be `__int128`.");
+ ]])],
+ [folly_cv_prog_cc_int128traits=yes],
+ [folly_cv_prog_cc_int128traits=no])
+ ])
+ if test "$folly_cv_prog_cc_int128traits" = "no"; then
+ AC_DEFINE([FOLLY_SUPPLY_MISSING_INT128_TRAITS], [1], [Define if we need the standard integer traits defined for the type `__int128'.])
+ fi
+fi
+
AC_CHECK_TYPES([ptrdiff_t, pthread_spinlock_t])
AC_CACHE_CHECK(
AC_CHECK_HEADER([lzma.h], AC_CHECK_LIB([lzma], [main]))
AC_CHECK_HEADER([zstd.h], AC_CHECK_LIB([zstd], [main]))
AC_CHECK_HEADER([linux/membarrier.h], AC_DEFINE([HAVE_LINUX_MEMBARRIER_H], [1], [Define to 1 if membarrier.h is available]))
-
+
AC_ARG_ENABLE([follytestmain],
AS_HELP_STRING([--enable-follytestmain], [enables using main function from folly for tests]),
[follytestmain=${enableval}], [follytestmain=no])
EXPECT_FALSE((folly::greater_than<uint8_t, 255u, uint8_t>(254u)));
}
+#if FOLLY_HAVE_INT128_T
+
+TEST(Traits, int128) {
+ EXPECT_TRUE(
+ (::std::is_same<::std::make_unsigned<__int128_t>::type, __uint128_t>::
+ value));
+ EXPECT_TRUE((
+ ::std::is_same<::std::make_signed<__int128_t>::type, __int128_t>::value));
+ EXPECT_TRUE(
+ (::std::is_same<::std::make_unsigned<__uint128_t>::type, __uint128_t>::
+ value));
+ EXPECT_TRUE(
+ (::std::is_same<::std::make_signed<__uint128_t>::type, __int128_t>::
+ value));
+ EXPECT_TRUE((::std::is_arithmetic<__int128_t>::value));
+ EXPECT_TRUE((::std::is_arithmetic<__uint128_t>::value));
+ EXPECT_TRUE((::std::is_integral<__int128_t>::value));
+ EXPECT_TRUE((::std::is_integral<__uint128_t>::value));
+ EXPECT_FALSE((::std::is_unsigned<__int128_t>::value));
+ EXPECT_TRUE((::std::is_signed<__int128_t>::value));
+ EXPECT_TRUE((::std::is_unsigned<__uint128_t>::value));
+ EXPECT_FALSE((::std::is_signed<__uint128_t>::value));
+ EXPECT_TRUE((::std::is_fundamental<__int128_t>::value));
+ EXPECT_TRUE((::std::is_fundamental<__uint128_t>::value));
+ EXPECT_TRUE((::std::is_scalar<__int128_t>::value));
+ EXPECT_TRUE((::std::is_scalar<__uint128_t>::value));
+}
+
+#endif // FOLLY_HAVE_INT128_T
+
template <typename T, typename... Args>
void testIsRelocatable(Args&&... args) {
if (!IsRelocatable<T>::value) return;