Commit 0383893a authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook GitHub Bot

revise int128 traits

Summary:
Rather than specializing standard library numeric traits for `signed __int128` and `unsigned __int128`, bring these traits into folly and choose them where needed.

Note that it is undefined behavior to specialize the standard traits types.

Reviewed By: ericniebler

Differential Revision: D26506904

fbshipit-source-id: 0f7b0fa445c2713961b345b453fef8ff58032ee5
parent 4720e456
...@@ -466,7 +466,7 @@ template Expected<double, ConversionCode> str_to_floating<double>( ...@@ -466,7 +466,7 @@ template Expected<double, ConversionCode> str_to_floating<double>(
* This class takes care of additional processing needed for signed values, * This class takes care of additional processing needed for signed values,
* like leading sign character and overflow checks. * like leading sign character and overflow checks.
*/ */
template <typename T, bool IsSigned = std::is_signed<T>::value> template <typename T, bool IsSigned = is_signed_v<T>>
class SignedValueHandler; class SignedValueHandler;
template <typename T> template <typename T>
...@@ -539,7 +539,7 @@ class SignedValueHandler<T, false> { ...@@ -539,7 +539,7 @@ class SignedValueHandler<T, false> {
template <class Tgt> template <class Tgt>
inline Expected<Tgt, ConversionCode> digits_to( inline Expected<Tgt, ConversionCode> digits_to(
const char* b, const char* const e) noexcept { const char* b, const char* const e) noexcept {
using UT = typename std::make_unsigned<Tgt>::type; using UT = make_unsigned_t<Tgt>;
assert(b <= e); assert(b <= e);
SignedValueHandler<Tgt> sgn; SignedValueHandler<Tgt> sgn;
...@@ -676,7 +676,7 @@ digits_to<unsigned __int128>(const char*, const char*) noexcept; ...@@ -676,7 +676,7 @@ digits_to<unsigned __int128>(const char*, const char*) noexcept;
*/ */
template <class Tgt> template <class Tgt>
Expected<Tgt, ConversionCode> str_to_integral(StringPiece* src) noexcept { Expected<Tgt, ConversionCode> str_to_integral(StringPiece* src) noexcept {
using UT = typename std::make_unsigned<Tgt>::type; using UT = make_unsigned_t<Tgt>;
auto b = src->data(), past = src->data() + src->size(); auto b = src->data(), past = src->data() + src->size();
...@@ -695,7 +695,7 @@ Expected<Tgt, ConversionCode> str_to_integral(StringPiece* src) noexcept { ...@@ -695,7 +695,7 @@ Expected<Tgt, ConversionCode> str_to_integral(StringPiece* src) noexcept {
if (UNLIKELY(err != ConversionCode::SUCCESS)) { if (UNLIKELY(err != ConversionCode::SUCCESS)) {
return makeUnexpected(err); return makeUnexpected(err);
} }
if (std::is_signed<Tgt>::value && UNLIKELY(b >= past)) { if (is_signed_v<Tgt> && UNLIKELY(b >= past)) {
return makeUnexpected(ConversionCode::NO_DIGITS); return makeUnexpected(ConversionCode::NO_DIGITS);
} }
if (UNLIKELY(!isdigit(*b))) { if (UNLIKELY(!isdigit(*b))) {
......
...@@ -243,7 +243,7 @@ to(Src&& value) { ...@@ -243,7 +243,7 @@ to(Src&& value) {
*/ */
template <class Tgt, class Src> template <class Tgt, class Src>
typename std::enable_if< typename std::enable_if<
std::is_arithmetic<Src>::value && !std::is_same<Tgt, Src>::value && is_arithmetic_v<Src> && !std::is_same<Tgt, Src>::value &&
std::is_same<Tgt, bool>::value, std::is_same<Tgt, bool>::value,
Expected<Tgt, ConversionCode>>::type Expected<Tgt, ConversionCode>>::type
tryTo(const Src& value) { tryTo(const Src& value) {
...@@ -252,7 +252,7 @@ tryTo(const Src& value) { ...@@ -252,7 +252,7 @@ tryTo(const Src& value) {
template <class Tgt, class Src> template <class Tgt, class Src>
typename std::enable_if< typename std::enable_if<
std::is_arithmetic<Src>::value && !std::is_same<Tgt, Src>::value && is_arithmetic_v<Src> && !std::is_same<Tgt, Src>::value &&
std::is_same<Tgt, bool>::value, std::is_same<Tgt, bool>::value,
Tgt>::type Tgt>::type
to(const Src& value) { to(const Src& value) {
...@@ -529,8 +529,8 @@ constexpr typename std:: ...@@ -529,8 +529,8 @@ constexpr typename std::
*/ */
template <class Tgt, class Src> template <class Tgt, class Src>
typename std::enable_if< typename std::enable_if<
std::is_integral<Src>::value && std::is_signed<Src>::value && is_integral_v<Src> && is_signed_v<Src> && IsSomeString<Tgt>::value &&
IsSomeString<Tgt>::value && sizeof(Src) >= 4>::type sizeof(Src) >= 4>::type
toAppend(Src value, Tgt* result) { toAppend(Src value, Tgt* result) {
char buffer[to_ascii_size_max_decimal<uint64_t>]; char buffer[to_ascii_size_max_decimal<uint64_t>];
auto uvalue = value < 0 ? ~static_cast<uint64_t>(value) + 1 auto uvalue = value < 0 ? ~static_cast<uint64_t>(value) + 1
...@@ -543,8 +543,8 @@ toAppend(Src value, Tgt* result) { ...@@ -543,8 +543,8 @@ toAppend(Src value, Tgt* result) {
template <class Src> template <class Src>
typename std::enable_if< typename std::enable_if<
std::is_integral<Src>::value && std::is_signed<Src>::value && is_integral_v<Src> && is_signed_v<Src> && sizeof(Src) >= 4 &&
sizeof(Src) >= 4 && sizeof(Src) < 16, sizeof(Src) < 16,
size_t>::type size_t>::type
estimateSpaceNeeded(Src value) { estimateSpaceNeeded(Src value) {
auto uvalue = value < 0 ? ~static_cast<uint64_t>(value) + 1 auto uvalue = value < 0 ? ~static_cast<uint64_t>(value) + 1
...@@ -557,8 +557,8 @@ estimateSpaceNeeded(Src value) { ...@@ -557,8 +557,8 @@ estimateSpaceNeeded(Src value) {
*/ */
template <class Tgt, class Src> template <class Tgt, class Src>
typename std::enable_if< typename std::enable_if<
std::is_integral<Src>::value && !std::is_signed<Src>::value && is_integral_v<Src> && !is_signed_v<Src> && IsSomeString<Tgt>::value &&
IsSomeString<Tgt>::value && sizeof(Src) >= 4>::type sizeof(Src) >= 4>::type
toAppend(Src value, Tgt* result) { toAppend(Src value, Tgt* result) {
char buffer[to_ascii_size_max_decimal<uint64_t>]; char buffer[to_ascii_size_max_decimal<uint64_t>];
result->append(buffer, to_ascii_decimal(buffer, value)); result->append(buffer, to_ascii_decimal(buffer, value));
...@@ -566,8 +566,8 @@ toAppend(Src value, Tgt* result) { ...@@ -566,8 +566,8 @@ toAppend(Src value, Tgt* result) {
template <class Src> template <class Src>
typename std::enable_if< typename std::enable_if<
std::is_integral<Src>::value && !std::is_signed<Src>::value && is_integral_v<Src> && !is_signed_v<Src> && sizeof(Src) >= 4 &&
sizeof(Src) >= 4 && sizeof(Src) < 16, sizeof(Src) < 16,
size_t>::type size_t>::type
estimateSpaceNeeded(Src value) { estimateSpaceNeeded(Src value) {
return to_ascii_size_decimal(value); return to_ascii_size_decimal(value);
...@@ -579,24 +579,20 @@ estimateSpaceNeeded(Src value) { ...@@ -579,24 +579,20 @@ estimateSpaceNeeded(Src value) {
*/ */
template <class Tgt, class Src> template <class Tgt, class Src>
typename std::enable_if< typename std::enable_if<
std::is_integral<Src>::value && IsSomeString<Tgt>::value && is_integral_v<Src> && IsSomeString<Tgt>::value && sizeof(Src) < 4>::type
sizeof(Src) < 4>::type
toAppend(Src value, Tgt* result) { toAppend(Src value, Tgt* result) {
typedef typedef typename std::conditional<is_signed_v<Src>, int64_t, uint64_t>::type
typename std::conditional<std::is_signed<Src>::value, int64_t, uint64_t>:: Intermediate;
type Intermediate;
toAppend<Tgt>(static_cast<Intermediate>(value), result); toAppend<Tgt>(static_cast<Intermediate>(value), result);
} }
template <class Src> template <class Src>
typename std::enable_if< typename std::enable_if<
std::is_integral<Src>::value && sizeof(Src) < 4 && is_integral_v<Src> && sizeof(Src) < 4 && !std::is_same<Src, char>::value,
!std::is_same<Src, char>::value,
size_t>::type size_t>::type
estimateSpaceNeeded(Src value) { estimateSpaceNeeded(Src value) {
typedef typedef typename std::conditional<is_signed_v<Src>, int64_t, uint64_t>::type
typename std::conditional<std::is_signed<Src>::value, int64_t, uint64_t>:: Intermediate;
type Intermediate;
return estimateSpaceNeeded(static_cast<Intermediate>(value)); return estimateSpaceNeeded(static_cast<Intermediate>(value));
} }
...@@ -1085,7 +1081,7 @@ convertTo(StringPiece* src) noexcept { ...@@ -1085,7 +1081,7 @@ convertTo(StringPiece* src) noexcept {
template <typename T> template <typename T>
typename std::enable_if< typename std::enable_if<
std::is_integral<T>::value && !std::is_same<T, bool>::value, is_integral_v<T> && !std::is_same<T, bool>::value,
Expected<T, ConversionCode>>::type Expected<T, ConversionCode>>::type
convertTo(StringPiece* src) noexcept { convertTo(StringPiece* src) noexcept {
return str_to_integral<T>(src); return str_to_integral<T>(src);
...@@ -1099,15 +1095,15 @@ convertTo(StringPiece* src) noexcept { ...@@ -1099,15 +1095,15 @@ convertTo(StringPiece* src) noexcept {
*/ */
template <typename Tgt> template <typename Tgt>
typename std::enable_if< typename std::enable_if<
std::is_integral<Tgt>::value && !std::is_same<Tgt, bool>::value, is_integral_v<Tgt> && !std::is_same<Tgt, bool>::value,
Expected<Tgt, ConversionCode>>::type Expected<Tgt, ConversionCode>>::type
tryTo(const char* b, const char* e) { tryTo(const char* b, const char* e) {
return detail::digits_to<Tgt>(b, e); return detail::digits_to<Tgt>(b, e);
} }
template <typename Tgt> template <typename Tgt>
typename std::enable_if< typename std::enable_if< //
std::is_integral<Tgt>::value && !std::is_same<Tgt, bool>::value, is_integral_v<Tgt> && !std::is_same<Tgt, bool>::value,
Tgt>::type Tgt>::type
to(const char* b, const char* e) { to(const char* b, const char* e) {
return tryTo<Tgt>(b, e).thenOrThrow( return tryTo<Tgt>(b, e).thenOrThrow(
...@@ -1125,8 +1121,8 @@ to(const char* b, const char* e) { ...@@ -1125,8 +1121,8 @@ to(const char* b, const char* e) {
* Parsing strings to numeric types. * Parsing strings to numeric types.
*/ */
template <typename Tgt> template <typename Tgt>
FOLLY_NODISCARD inline typename std::enable_if< FOLLY_NODISCARD inline typename std::enable_if< //
std::is_arithmetic<Tgt>::value, is_arithmetic_v<Tgt>,
Expected<StringPiece, ConversionCode>>::type Expected<StringPiece, ConversionCode>>::type
parseTo(StringPiece src, Tgt& out) { parseTo(StringPiece src, Tgt& out) {
return detail::convertTo<Tgt>(&src).then( return detail::convertTo<Tgt>(&src).then(
...@@ -1147,7 +1143,7 @@ namespace detail { ...@@ -1147,7 +1143,7 @@ namespace detail {
template <class Tgt> template <class Tgt>
typename std::enable_if< typename std::enable_if<
!std::is_same<Tgt, bool>::value && !std::is_same<Tgt, bool>::value &&
(std::is_integral<Tgt>::value || std::is_floating_point<Tgt>::value), (is_integral_v<Tgt> || std::is_floating_point<Tgt>::value),
Expected<Tgt, ConversionCode>>::type Expected<Tgt, ConversionCode>>::type
convertTo(const bool& value) noexcept { convertTo(const bool& value) noexcept {
return static_cast<Tgt>(value ? 1 : 0); return static_cast<Tgt>(value ? 1 : 0);
...@@ -1160,20 +1156,19 @@ convertTo(const bool& value) noexcept { ...@@ -1160,20 +1156,19 @@ convertTo(const bool& value) noexcept {
*/ */
template <class Tgt, class Src> template <class Tgt, class Src>
typename std::enable_if< typename std::enable_if<
std::is_integral<Src>::value && !std::is_same<Tgt, Src>::value && is_integral_v<Src> && !std::is_same<Tgt, Src>::value &&
!std::is_same<Tgt, bool>::value && std::is_integral<Tgt>::value, !std::is_same<Tgt, bool>::value && is_integral_v<Tgt>,
Expected<Tgt, ConversionCode>>::type Expected<Tgt, ConversionCode>>::type
convertTo(const Src& value) noexcept { convertTo(const Src& value) noexcept {
if /* constexpr */ ( if /* constexpr */ (
std::make_unsigned_t<Tgt>(std::numeric_limits<Tgt>::max()) < make_unsigned_t<Tgt>(std::numeric_limits<Tgt>::max()) <
std::make_unsigned_t<Src>(std::numeric_limits<Src>::max())) { make_unsigned_t<Src>(std::numeric_limits<Src>::max())) {
if (greater_than<Tgt, std::numeric_limits<Tgt>::max()>(value)) { if (greater_than<Tgt, std::numeric_limits<Tgt>::max()>(value)) {
return makeUnexpected(ConversionCode::ARITH_POSITIVE_OVERFLOW); return makeUnexpected(ConversionCode::ARITH_POSITIVE_OVERFLOW);
} }
} }
if /* constexpr */ ( if /* constexpr */ (
std::is_signed<Src>::value && is_signed_v<Src> && (!is_signed_v<Tgt> || sizeof(Src) > sizeof(Tgt))) {
(!std::is_signed<Tgt>::value || sizeof(Src) > sizeof(Tgt))) {
if (less_than<Tgt, std::numeric_limits<Tgt>::min()>(value)) { if (less_than<Tgt, std::numeric_limits<Tgt>::min()>(value)) {
return makeUnexpected(ConversionCode::ARITH_NEGATIVE_OVERFLOW); return makeUnexpected(ConversionCode::ARITH_NEGATIVE_OVERFLOW);
} }
...@@ -1210,7 +1205,7 @@ convertTo(const Src& value) noexcept { ...@@ -1210,7 +1205,7 @@ convertTo(const Src& value) noexcept {
*/ */
template <typename Tgt, typename Src> template <typename Tgt, typename Src>
inline typename std::enable_if< inline typename std::enable_if<
std::is_floating_point<Src>::value && std::is_integral<Tgt>::value && std::is_floating_point<Src>::value && is_integral_v<Tgt> &&
!std::is_same<Tgt, bool>::value, !std::is_same<Tgt, bool>::value,
bool>::type bool>::type
checkConversion(const Src& value) { checkConversion(const Src& value) {
...@@ -1225,7 +1220,7 @@ checkConversion(const Src& value) { ...@@ -1225,7 +1220,7 @@ checkConversion(const Src& value) {
std::numeric_limits<Tgt>::max() - static_cast<Tgt>(mmax)) { std::numeric_limits<Tgt>::max() - static_cast<Tgt>(mmax)) {
return false; return false;
} }
} else if (std::is_signed<Tgt>::value && value <= tgtMinAsSrc) { } else if (is_signed_v<Tgt> && value <= tgtMinAsSrc) {
if (value < tgtMinAsSrc) { if (value < tgtMinAsSrc) {
return false; return false;
} }
...@@ -1241,7 +1236,7 @@ checkConversion(const Src& value) { ...@@ -1241,7 +1236,7 @@ checkConversion(const Src& value) {
// Integers can always safely be converted to floating point values // Integers can always safely be converted to floating point values
template <typename Tgt, typename Src> template <typename Tgt, typename Src>
constexpr typename std::enable_if< constexpr typename std::enable_if<
std::is_integral<Src>::value && std::is_floating_point<Tgt>::value, is_integral_v<Src> && std::is_floating_point<Tgt>::value,
bool>::type bool>::type
checkConversion(const Src&) { checkConversion(const Src&) {
return true; return true;
...@@ -1266,8 +1261,8 @@ checkConversion(const Src&) { ...@@ -1266,8 +1261,8 @@ checkConversion(const Src&) {
*/ */
template <typename Tgt, typename Src> template <typename Tgt, typename Src>
typename std::enable_if< typename std::enable_if<
(std::is_integral<Src>::value && std::is_floating_point<Tgt>::value) || (is_integral_v<Src> && std::is_floating_point<Tgt>::value) ||
(std::is_floating_point<Src>::value && std::is_integral<Tgt>::value), (std::is_floating_point<Src>::value && is_integral_v<Tgt>),
Expected<Tgt, ConversionCode>>::type Expected<Tgt, ConversionCode>>::type
convertTo(const Src& value) noexcept { convertTo(const Src& value) noexcept {
if (LIKELY(checkConversion<Tgt>(value))) { if (LIKELY(checkConversion<Tgt>(value))) {
...@@ -1290,7 +1285,7 @@ inline std::string errorValue(const Src& value) { ...@@ -1290,7 +1285,7 @@ inline std::string errorValue(const Src& value) {
template <typename Tgt, typename Src> template <typename Tgt, typename Src>
using IsArithToArith = bool_constant< using IsArithToArith = bool_constant<
!std::is_same<Tgt, Src>::value && !std::is_same<Tgt, bool>::value && !std::is_same<Tgt, Src>::value && !std::is_same<Tgt, bool>::value &&
std::is_arithmetic<Src>::value && std::is_arithmetic<Tgt>::value>; is_arithmetic_v<Src> && is_arithmetic_v<Tgt>>;
} // namespace detail } // namespace detail
...@@ -1434,7 +1429,7 @@ tryTo(StringPiece src) { ...@@ -1434,7 +1429,7 @@ tryTo(StringPiece src) {
Tgt result{}; Tgt result{};
using Error = detail::ParseToError<Tgt>; using Error = detail::ParseToError<Tgt>;
using Check = typename std::conditional< using Check = typename std::conditional<
std::is_arithmetic<Tgt>::value, is_arithmetic_v<Tgt>,
detail::CheckTrailingSpace, detail::CheckTrailingSpace,
detail::ReturnUnit<Error>>::type; detail::ReturnUnit<Error>>::type;
return parseTo(src, result).then(Check(), [&](Unit) { return parseTo(src, result).then(Check(), [&](Unit) {
...@@ -1457,7 +1452,7 @@ inline ...@@ -1457,7 +1452,7 @@ inline
Tgt result{}; Tgt result{};
using Error = detail::ParseToError<Tgt>; using Error = detail::ParseToError<Tgt>;
using Check = typename std::conditional< using Check = typename std::conditional<
std::is_arithmetic<Tgt>::value, is_arithmetic_v<Tgt>,
detail::CheckTrailingSpace, detail::CheckTrailingSpace,
detail::ReturnUnit<Error>>::type; detail::ReturnUnit<Error>>::type;
auto tmp = detail::parseToWrap(src, result); auto tmp = detail::parseToWrap(src, result);
......
...@@ -769,44 +769,101 @@ FOLLY_ASSUME_FBVECTOR_COMPATIBLE_2(std::unique_ptr) ...@@ -769,44 +769,101 @@ FOLLY_ASSUME_FBVECTOR_COMPATIBLE_2(std::unique_ptr)
FOLLY_ASSUME_FBVECTOR_COMPATIBLE_1(std::shared_ptr) FOLLY_ASSUME_FBVECTOR_COMPATIBLE_1(std::shared_ptr)
#endif #endif
/* Some combinations of compilers and C++ libraries make __int128 and namespace folly {
* unsigned __int128 available but do not correctly define their standard type
* traits. // Some compilers have signed __int128 and unsigned __int128 types, and some
* // libraries with some compilers have traits for those types. It's a mess.
* If FOLLY_SUPPLY_MISSING_INT128_TRAITS is defined, we define these traits // Import things into folly and then fill in whatever is missing.
* here. //
* // The aliases:
* @author: Phil Willoughby <philwill@fb.com> // int128_t
*/ // uint128_t
#if FOLLY_SUPPLY_MISSING_INT128_TRAITS //
FOLLY_NAMESPACE_STD_BEGIN // The traits:
// is_arithmetic
// is_arithmetic_v
// is_integral
// is_integral_v
// is_signed
// is_signed_v
// is_unsigned
// is_unsigned_v
// make_signed
// make_signed_t
// make_unsigned
// make_unsigned_t
template <typename T>
struct is_arithmetic : std::is_arithmetic<T> {};
template <typename T>
FOLLY_INLINE_VARIABLE constexpr bool is_arithmetic_v = is_arithmetic<T>::value;
template <typename T>
struct is_integral : std::is_integral<T> {};
template <typename T>
FOLLY_INLINE_VARIABLE constexpr bool is_integral_v = is_integral<T>::value;
template <typename T>
struct is_signed : std::is_signed<T> {};
template <typename T>
FOLLY_INLINE_VARIABLE constexpr bool is_signed_v = is_signed<T>::value;
template <typename T>
struct is_unsigned : std::is_unsigned<T> {};
template <typename T>
FOLLY_INLINE_VARIABLE constexpr bool is_unsigned_v = is_unsigned<T>::value;
template <typename T>
struct make_signed : std::make_signed<T> {};
template <typename T>
using make_signed_t = typename make_signed<T>::type;
template <typename T>
struct make_unsigned : std::make_unsigned<T> {};
template <typename T>
using make_unsigned_t = typename make_unsigned<T>::type;
#if FOLLY_HAVE_INT128_T
using int128_t = signed __int128;
using uint128_t = unsigned __int128;
template <>
struct is_arithmetic<int128_t> : std::true_type {};
template <>
struct is_arithmetic<uint128_t> : std::true_type {};
template <> template <>
struct is_arithmetic<__int128> : ::std::true_type {}; struct is_integral<int128_t> : std::true_type {};
template <> template <>
struct is_arithmetic<unsigned __int128> : ::std::true_type {}; struct is_integral<uint128_t> : std::true_type {};
template <> template <>
struct is_integral<__int128> : ::std::true_type {}; struct is_signed<int128_t> : std::true_type {};
template <> template <>
struct is_integral<unsigned __int128> : ::std::true_type {}; struct is_signed<uint128_t> : std::false_type {};
template <> template <>
struct make_unsigned<__int128> { struct is_unsigned<int128_t> : std::false_type {};
typedef unsigned __int128 type;
};
template <> template <>
struct make_signed<__int128> { struct is_unsigned<uint128_t> : std::true_type {};
typedef __int128 type;
};
template <> template <>
struct make_unsigned<unsigned __int128> { struct make_signed<int128_t> {
typedef unsigned __int128 type; using type = int128_t;
}; };
template <> template <>
struct make_signed<unsigned __int128> { struct make_signed<uint128_t> {
typedef __int128 type; using type = int128_t;
}; };
template <> template <>
struct is_signed<__int128> : ::std::true_type {}; struct make_unsigned<int128_t> {
using type = uint128_t;
};
template <> template <>
struct is_unsigned<unsigned __int128> : ::std::true_type {}; struct make_unsigned<uint128_t> {
FOLLY_NAMESPACE_STD_END using type = uint128_t;
#endif // FOLLY_SUPPLY_MISSING_INT128_TRAITS };
#endif // FOLLY_HAVE_INT128_T
} // namespace folly
...@@ -109,8 +109,8 @@ void testIntegral2String() {} ...@@ -109,8 +109,8 @@ void testIntegral2String() {}
template <class String, class Int, class... Ints> template <class String, class Int, class... Ints>
void testIntegral2String() { void testIntegral2String() {
typedef typename make_unsigned<Int>::type Uint; typedef folly::make_unsigned_t<Int> Uint;
typedef typename make_signed<Int>::type Sint; typedef folly::make_signed_t<Int> Sint;
Uint value = 123; Uint value = 123;
EXPECT_EQ(to<String>(value), "123"); EXPECT_EQ(to<String>(value), "123");
...@@ -196,8 +196,8 @@ void testString2Integral() {} ...@@ -196,8 +196,8 @@ void testString2Integral() {}
template <class String, class Int, class... Ints> template <class String, class Int, class... Ints>
void testString2Integral() { void testString2Integral() {
typedef typename make_unsigned<Int>::type Uint; typedef folly::make_unsigned_t<Int> Uint;
typedef typename make_signed<Int>::type Sint; typedef folly::make_signed_t<Int> Sint;
// Unsigned numbers small enough to fit in a signed type // Unsigned numbers small enough to fit in a signed type
static const String strings[] = { static const String strings[] = {
......
...@@ -186,28 +186,21 @@ TEST(Traits, relational) { ...@@ -186,28 +186,21 @@ TEST(Traits, relational) {
TEST(Traits, int128) { TEST(Traits, int128) {
EXPECT_TRUE( EXPECT_TRUE(
(::std::is_same<::std::make_unsigned<__int128_t>::type, __uint128_t>:: (::std::is_same<folly::make_unsigned_t<int128_t>, uint128_t>::value));
value));
EXPECT_TRUE((
::std::is_same<::std::make_signed<__int128_t>::type, __int128_t>::value));
EXPECT_TRUE( EXPECT_TRUE(
(::std::is_same<::std::make_unsigned<__uint128_t>::type, __uint128_t>:: (::std::is_same<folly::make_signed_t<int128_t>, int128_t>::value));
value));
EXPECT_TRUE( EXPECT_TRUE(
(::std::is_same<::std::make_signed<__uint128_t>::type, __int128_t>:: (::std::is_same<folly::make_unsigned_t<uint128_t>, uint128_t>::value));
value)); EXPECT_TRUE( //
EXPECT_TRUE((::std::is_arithmetic<__int128_t>::value)); (::std::is_same<folly::make_signed_t<uint128_t>, int128_t>::value));
EXPECT_TRUE((::std::is_arithmetic<__uint128_t>::value)); EXPECT_TRUE((folly::is_arithmetic_v<int128_t>));
EXPECT_TRUE((::std::is_integral<__int128_t>::value)); EXPECT_TRUE((folly::is_arithmetic_v<uint128_t>));
EXPECT_TRUE((::std::is_integral<__uint128_t>::value)); EXPECT_TRUE((folly::is_integral_v<int128_t>));
EXPECT_FALSE((::std::is_unsigned<__int128_t>::value)); EXPECT_TRUE((folly::is_integral_v<uint128_t>));
EXPECT_TRUE((::std::is_signed<__int128_t>::value)); EXPECT_FALSE((folly::is_unsigned_v<int128_t>));
EXPECT_TRUE((::std::is_unsigned<__uint128_t>::value)); EXPECT_TRUE((folly::is_signed_v<int128_t>));
EXPECT_FALSE((::std::is_signed<__uint128_t>::value)); EXPECT_TRUE((folly::is_unsigned_v<uint128_t>));
EXPECT_TRUE((::std::is_fundamental<__int128_t>::value)); EXPECT_FALSE((folly::is_signed_v<__uint128_t>));
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 #endif // FOLLY_HAVE_INT128_T
......
...@@ -1462,7 +1462,7 @@ void verifyAllocator(int ele, int cap) { ...@@ -1462,7 +1462,7 @@ void verifyAllocator(int ele, int cap) {
// Master verifier // Master verifier
template <class Vector> template <class Vector>
void verify(int extras) { void verify(int extras) {
if (!is_arithmetic<typename Vector::value_type>::value) { if (!std::is_arithmetic<typename Vector::value_type>::value) {
ASSERT_EQ(0 + extras, getTotal()) << "there exist Data but no vectors"; ASSERT_EQ(0 + extras, getTotal()) << "there exist Data but no vectors";
} }
isSane(); isSane();
...@@ -1476,7 +1476,7 @@ void verify(int extras) { ...@@ -1476,7 +1476,7 @@ void verify(int extras) {
template <class Vector> template <class Vector>
void verify(int extras, const Vector& v) { void verify(int extras, const Vector& v) {
verifyVector(v); verifyVector(v);
if (!is_arithmetic<typename Vector::value_type>::value) { if (!std::is_arithmetic<typename Vector::value_type>::value) {
ASSERT_EQ(v.size() + extras, getTotal()) ASSERT_EQ(v.size() + extras, getTotal())
<< "not all Data are in the vector"; << "not all Data are in the vector";
} }
...@@ -1498,7 +1498,7 @@ void verify(int extras, const Vector& v1, const Vector& v2) { ...@@ -1498,7 +1498,7 @@ void verify(int extras, const Vector& v1, const Vector& v2) {
size += v2.size(); size += v2.size();
cap += v2.capacity(); cap += v2.capacity();
} }
if (!is_arithmetic<typename Vector::value_type>::value) { if (!std::is_arithmetic<typename Vector::value_type>::value) {
ASSERT_EQ(size + extras, getTotal()) << "not all Data are in the vector(s)"; ASSERT_EQ(size + extras, getTotal()) << "not all Data are in the vector(s)";
} }
isSane(); isSane();
...@@ -1674,7 +1674,7 @@ STL_TEST("23.2.1 Table 96.1-7", containerTypedefs, is_destructible) { ...@@ -1674,7 +1674,7 @@ STL_TEST("23.2.1 Table 96.1-7", containerTypedefs, is_destructible) {
typename Vector::const_iterator>::value, typename Vector::const_iterator>::value,
"Vector::iterator is not convertible to Vector::const_iterator"); "Vector::iterator is not convertible to Vector::const_iterator");
static_assert( static_assert(
is_signed<typename Vector::difference_type>::value, std::is_signed<typename Vector::difference_type>::value,
"Vector::difference_type is not signed"); "Vector::difference_type is not signed");
static_assert( static_assert(
is_same< is_same<
...@@ -1689,7 +1689,7 @@ STL_TEST("23.2.1 Table 96.1-7", containerTypedefs, is_destructible) { ...@@ -1689,7 +1689,7 @@ STL_TEST("23.2.1 Table 96.1-7", containerTypedefs, is_destructible) {
typename Vector::const_iterator>::difference_type>::value, typename Vector::const_iterator>::difference_type>::value,
"Vector::difference_type != Vector::const_iterator::difference_type"); "Vector::difference_type != Vector::const_iterator::difference_type");
static_assert( static_assert(
is_unsigned<typename Vector::size_type>::value, std::is_unsigned<typename Vector::size_type>::value,
"Vector::size_type is not unsigned"); "Vector::size_type is not unsigned");
static_assert( static_assert(
sizeof(typename Vector::size_type) >= sizeof(typename Vector::size_type) >=
...@@ -1837,7 +1837,7 @@ STL_TEST("23.2.1 Table 96.15-18", iterators, is_destructible, a) { ...@@ -1837,7 +1837,7 @@ STL_TEST("23.2.1 Table 96.15-18", iterators, is_destructible, a) {
ASSERT_TRUE(Cdist == ca.size()) << "distance(cbegin, cend) != size"; ASSERT_TRUE(Cdist == ca.size()) << "distance(cbegin, cend) != size";
} }
STL_TEST("23.2.1 Table 96.19-20", equitable, is_arithmetic, a, b) { STL_TEST("23.2.1 Table 96.19-20", equitable, std::is_arithmetic, a, b) {
const auto& ca = a; const auto& ca = a;
const auto& cb = b; const auto& cb = b;
DataState<Vector> dsa(a); DataState<Vector> dsa(a);
...@@ -2009,7 +2009,7 @@ STL_TEST("23.2.1 Table 97.3-5", reversibleIterators, is_destructible, a) { ...@@ -2009,7 +2009,7 @@ STL_TEST("23.2.1 Table 97.3-5", reversibleIterators, is_destructible, a) {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Lexicographical functions // Lexicographical functions
STL_TEST("23.2.1 Table 98", comparable, is_arithmetic) { STL_TEST("23.2.1 Table 98", comparable, std::is_arithmetic) {
const Vector v1 = {1, 2, 3, 4}; const Vector v1 = {1, 2, 3, 4};
const Vector v2 = {1, 2, 3, 4, 5}; const Vector v2 = {1, 2, 3, 4, 5};
const Vector v3 = {1, 2, 2}; const Vector v3 = {1, 2, 2};
...@@ -2157,7 +2157,7 @@ STL_TEST( ...@@ -2157,7 +2157,7 @@ STL_TEST(
ASSERT_TRUE(m == u.get_allocator()); ASSERT_TRUE(m == u.get_allocator());
} }
STL_TEST("23.2.1-7", ilAllocConstruction, is_arithmetic, m) { STL_TEST("23.2.1-7", ilAllocConstruction, std::is_arithmetic, m) {
// gcc fail // gcc fail
if (Ticker::TicksLeft >= 0) { if (Ticker::TicksLeft >= 0) {
return; return;
...@@ -2264,7 +2264,7 @@ STL_TEST( ...@@ -2264,7 +2264,7 @@ STL_TEST(
} }
} }
STL_TEST("23.2.3 Table 100.3", ilConstruction, is_arithmetic) { STL_TEST("23.2.3 Table 100.3", ilConstruction, std::is_arithmetic) {
// whitebox: ensure that Vector(il) is implemented in terms of // whitebox: ensure that Vector(il) is implemented in terms of
// Vector(il.begin(), il.end()) // Vector(il.begin(), il.end())
...@@ -2284,7 +2284,7 @@ STL_TEST("23.2.3 Table 100.3", ilConstruction, is_arithmetic) { ...@@ -2284,7 +2284,7 @@ STL_TEST("23.2.3 Table 100.3", ilConstruction, is_arithmetic) {
} }
} }
STL_TEST("23.2.3 Table 100.4", ilAssignment, is_arithmetic, a) { STL_TEST("23.2.3 Table 100.4", ilAssignment, std::is_arithmetic, a) {
// whitebox: ensure that assign(il) is implemented in terms of // whitebox: ensure that assign(il) is implemented in terms of
// assign(il.begin(), il.end()) // assign(il.begin(), il.end())
...@@ -2524,7 +2524,7 @@ STL_TEST( ...@@ -2524,7 +2524,7 @@ STL_TEST(
insertItCheck(a, dsa, idx, i, j); insertItCheck(a, dsa, idx, i, j);
} }
STL_TEST("23.2.3 Table 100.10", iteratorInsertIL, is_arithmetic, a, p) { STL_TEST("23.2.3 Table 100.10", iteratorInsertIL, std::is_arithmetic, a, p) {
// gcc fail // gcc fail
if (Ticker::TicksLeft >= 0) { if (Ticker::TicksLeft >= 0) {
return; return;
...@@ -2654,7 +2654,7 @@ STL_TEST( ...@@ -2654,7 +2654,7 @@ STL_TEST(
} }
} }
STL_TEST("23.2.3 Table 100.15", assignIL, is_arithmetic, a) { STL_TEST("23.2.3 Table 100.15", assignIL, std::is_arithmetic, a) {
// whitebox: ensure that assign(il) is implemented in terms of // whitebox: ensure that assign(il) is implemented in terms of
// assign(il.begin(), il.end()) // assign(il.begin(), il.end())
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment