> > > Maybe you need to refactor __glibcxx_digits so there is a version taking > > > the bitsize as an argument rather than using sizeof(T) * __CHAR_BIT__, > > > but > > > that should be the only change needed to handle such types with the > > > existing macros. The bitsize macros should be the only ones needing > > > predefining to pass information to libstdc++. > > > > Like this? > > Yes (well, the libstdc++ changes will need to go to the libstdc++ mailing > list for review there, but this is the sort of thing I'd expect to keep > the way libstdc++ defines these limits as consistent as possible between > different types).
Ok, here's the updated c-cppbuiltins.c and all the libstdc++-v3 changes, cross-posted to the libstdc++ list. I tested the macros on x86-64 (before and after) and msp430 (after) with __int128 and __int20 and get the right values in all cases. Index: gcc/c-family/c-cppbuiltin.c =================================================================== --- gcc/c-family/c-cppbuiltin.c (revision 213886) +++ gcc/c-family/c-cppbuiltin.c (working copy) @@ -775,12 +775,14 @@ cpp_iec_559_complex_value (void) } /* Hook that registers front end and target-specific built-ins. */ void c_cpp_builtins (cpp_reader *pfile) { + int i; + /* -undef turns off target-specific built-ins. */ if (flag_undef) return; define_language_independent_builtin_macros (pfile); @@ -845,12 +847,29 @@ c_cpp_builtins (cpp_reader *pfile) builtin_define_type_minmax ("__WCHAR_MIN__", "__WCHAR_MAX__", underlying_wchar_type_node); builtin_define_type_minmax ("__WINT_MIN__", "__WINT_MAX__", wint_type_node); builtin_define_type_max ("__PTRDIFF_MAX__", ptrdiff_type_node); builtin_define_type_max ("__SIZE_MAX__", size_type_node); + for (i = 0; i < NUM_INT_N_ENTS; i ++) + if (int_n_enabled_p[i]) + { + char buf[35+20+20]; + + /* These are used to configure the C++ library. */ + + if (!flag_iso || int_n_data[i].bitsize == POINTER_SIZE) + { + sprintf (buf, "__GLIBCXX_TYPE_INT_N_%d=__int%d", i, int_n_data[i].bitsize); + cpp_define (parse_in, buf); + + sprintf (buf, "__GLIBCXX_BITSIZE_INT_N_%d=%d", i, int_n_data[i].bitsize); + cpp_define (parse_in, buf); + } + } + /* stdint.h and the testsuite need to know these. */ builtin_define_stdint_macros (); /* Provide information for library headers to determine whether to define macros such as __STDC_IEC_559__ and __STDC_IEC_559_COMPLEX__. */ @@ -993,15 +1012,20 @@ c_cpp_builtins (cpp_reader *pfile) else if (flag_stack_protect == 1) cpp_define (pfile, "__SSP__=1"); if (flag_openmp) cpp_define (pfile, "_OPENMP=201307"); - if (int128_integer_type_node != NULL_TREE) - builtin_define_type_sizeof ("__SIZEOF_INT128__", - int128_integer_type_node); + for (i = 0; i < NUM_INT_N_ENTS; i ++) + if (int_n_enabled_p[i]) + { + char buf[15+20]; + sprintf(buf, "__SIZEOF_INT%d__", int_n_data[i].bitsize); + builtin_define_type_sizeof (buf, + int_n_trees[i].signed_type); + } builtin_define_type_sizeof ("__SIZEOF_WCHAR_T__", wchar_type_node); builtin_define_type_sizeof ("__SIZEOF_WINT_T__", wint_type_node); builtin_define_type_sizeof ("__SIZEOF_PTRDIFF_T__", unsigned_ptrdiff_type_node); /* A straightforward target hook doesn't work, because of problems Index: libstdc++-v3/src/c++11/limits.cc =================================================================== --- libstdc++-v3/src/c++11/limits.cc (revision 213886) +++ libstdc++-v3/src/c++11/limits.cc (working copy) @@ -385,60 +385,72 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const bool numeric_limits<unsigned long long>::is_bounded; const bool numeric_limits<unsigned long long>::is_modulo; const bool numeric_limits<unsigned long long>::traps; const bool numeric_limits<unsigned long long>::tinyness_before; const float_round_style numeric_limits<unsigned long long>::round_style; -#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_INT128) - const bool numeric_limits<__int128>::is_specialized; - const int numeric_limits<__int128>::digits; - const int numeric_limits<__int128>::digits10; - const int numeric_limits<__int128>::max_digits10; - const bool numeric_limits<__int128>::is_signed; - const bool numeric_limits<__int128>::is_integer; - const bool numeric_limits<__int128>::is_exact; - const int numeric_limits<__int128>::radix; - const int numeric_limits<__int128>::min_exponent; - const int numeric_limits<__int128>::min_exponent10; - const int numeric_limits<__int128>::max_exponent; - const int numeric_limits<__int128>::max_exponent10; - const bool numeric_limits<__int128>::has_infinity; - const bool numeric_limits<__int128>::has_quiet_NaN; - const bool numeric_limits<__int128>::has_signaling_NaN; - const float_denorm_style numeric_limits<__int128>::has_denorm; - const bool numeric_limits<__int128>::has_denorm_loss; - const bool numeric_limits<__int128>::is_iec559; - const bool numeric_limits<__int128>::is_bounded; - const bool numeric_limits<__int128>::is_modulo; - const bool numeric_limits<__int128>::traps; - const bool numeric_limits<__int128>::tinyness_before; - const float_round_style numeric_limits<__int128>::round_style; - - const bool numeric_limits<unsigned __int128>::is_specialized; - const int numeric_limits<unsigned __int128>::digits; - const int numeric_limits<unsigned __int128>::digits10; - const int numeric_limits<unsigned __int128>::max_digits10; - const bool numeric_limits<unsigned __int128>::is_signed; - const bool numeric_limits<unsigned __int128>::is_integer; - const bool numeric_limits<unsigned __int128>::is_exact; - const int numeric_limits<unsigned __int128>::radix; - const int numeric_limits<unsigned __int128>::min_exponent; - const int numeric_limits<unsigned __int128>::min_exponent10; - const int numeric_limits<unsigned __int128>::max_exponent; - const int numeric_limits<unsigned __int128>::max_exponent10; - const bool numeric_limits<unsigned __int128>::has_infinity; - const bool numeric_limits<unsigned __int128>::has_quiet_NaN; - const bool numeric_limits<unsigned __int128>::has_signaling_NaN; - const float_denorm_style numeric_limits<unsigned __int128>::has_denorm; - const bool numeric_limits<unsigned __int128>::has_denorm_loss; - const bool numeric_limits<unsigned __int128>::is_iec559; - const bool numeric_limits<unsigned __int128>::is_bounded; - const bool numeric_limits<unsigned __int128>::is_modulo; - const bool numeric_limits<unsigned __int128>::traps; - const bool numeric_limits<unsigned __int128>::tinyness_before; - const float_round_style numeric_limits<unsigned __int128>::round_style; +#define INT_N(__INT_N_TYPE) \ + const bool numeric_limits<__INT_N_TYPE>::is_specialized; \ + const int numeric_limits<__INT_N_TYPE>::digits; \ + const int numeric_limits<__INT_N_TYPE>::digits10; \ + const int numeric_limits<__INT_N_TYPE>::max_digits10; \ + const bool numeric_limits<__INT_N_TYPE>::is_signed; \ + const bool numeric_limits<__INT_N_TYPE>::is_integer; \ + const bool numeric_limits<__INT_N_TYPE>::is_exact; \ + const int numeric_limits<__INT_N_TYPE>::radix; \ + const int numeric_limits<__INT_N_TYPE>::min_exponent; \ + const int numeric_limits<__INT_N_TYPE>::min_exponent10; \ + const int numeric_limits<__INT_N_TYPE>::max_exponent; \ + const int numeric_limits<__INT_N_TYPE>::max_exponent10; \ + const bool numeric_limits<__INT_N_TYPE>::has_infinity; \ + const bool numeric_limits<__INT_N_TYPE>::has_quiet_NaN; \ + const bool numeric_limits<__INT_N_TYPE>::has_signaling_NaN; \ + const float_denorm_style numeric_limits<__INT_N_TYPE>::has_denorm; \ + const bool numeric_limits<__INT_N_TYPE>::has_denorm_loss; \ + const bool numeric_limits<__INT_N_TYPE>::is_iec559; \ + const bool numeric_limits<__INT_N_TYPE>::is_bounded; \ + const bool numeric_limits<__INT_N_TYPE>::is_modulo; \ + const bool numeric_limits<__INT_N_TYPE>::traps; \ + const bool numeric_limits<__INT_N_TYPE>::tinyness_before; \ + const float_round_style numeric_limits<__INT_N_TYPE>::round_style; \ + \ + const bool numeric_limits<unsigned __INT_N_TYPE>::is_specialized; \ + const int numeric_limits<unsigned __INT_N_TYPE>::digits; \ + const int numeric_limits<unsigned __INT_N_TYPE>::digits10; \ + const int numeric_limits<unsigned __INT_N_TYPE>::max_digits10; \ + const bool numeric_limits<unsigned __INT_N_TYPE>::is_signed; \ + const bool numeric_limits<unsigned __INT_N_TYPE>::is_integer; \ + const bool numeric_limits<unsigned __INT_N_TYPE>::is_exact; \ + const int numeric_limits<unsigned __INT_N_TYPE>::radix; \ + const int numeric_limits<unsigned __INT_N_TYPE>::min_exponent; \ + const int numeric_limits<unsigned __INT_N_TYPE>::min_exponent10; \ + const int numeric_limits<unsigned __INT_N_TYPE>::max_exponent; \ + const int numeric_limits<unsigned __INT_N_TYPE>::max_exponent10; \ + const bool numeric_limits<unsigned __INT_N_TYPE>::has_infinity; \ + const bool numeric_limits<unsigned __INT_N_TYPE>::has_quiet_NaN; \ + const bool numeric_limits<unsigned __INT_N_TYPE>::has_signaling_NaN; \ + const float_denorm_style numeric_limits<unsigned __INT_N_TYPE>::has_denorm; \ + const bool numeric_limits<unsigned __INT_N_TYPE>::has_denorm_loss; \ + const bool numeric_limits<unsigned __INT_N_TYPE>::is_iec559; \ + const bool numeric_limits<unsigned __INT_N_TYPE>::is_bounded; \ + const bool numeric_limits<unsigned __INT_N_TYPE>::is_modulo; \ + const bool numeric_limits<unsigned __INT_N_TYPE>::traps; \ + const bool numeric_limits<unsigned __INT_N_TYPE>::tinyness_before; \ + const float_round_style numeric_limits<unsigned __INT_N_TYPE>::round_style; + +#ifdef __GLIBCXX_TYPE_INT_N_0 + INT_N (__GLIBCXX_TYPE_INT_N_0) +#endif +#ifdef __GLIBCXX_TYPE_INT_N_1 + INT_N (__GLIBCXX_TYPE_INT_N_1) +#endif +#ifdef __GLIBCXX_TYPE_INT_N_2 + INT_N (__GLIBCXX_TYPE_INT_N_2) +#endif +#ifdef __GLIBCXX_TYPE_INT_N_3 + INT_N (__GLIBCXX_TYPE_INT_N_3) #endif // float const bool numeric_limits<float>::is_specialized; const int numeric_limits<float>::digits; const int numeric_limits<float>::digits10; Index: libstdc++-v3/include/std/type_traits =================================================================== --- libstdc++-v3/include/std/type_traits (revision 213886) +++ libstdc++-v3/include/std/type_traits (working copy) @@ -236,19 +236,48 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : public true_type { }; template<> struct __is_integral_helper<unsigned long long> : public true_type { }; -#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_INT128) + // Conditionalizing on __STRICT_ANSI__ here will break any port that + // uses one of these types for size_t. +#if defined(__GLIBCXX_TYPE_INT_N_0) template<> - struct __is_integral_helper<__int128> + struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_0> : public true_type { }; template<> - struct __is_integral_helper<unsigned __int128> + struct __is_integral_helper<unsigned __GLIBCXX_TYPE_INT_N_0> + : public true_type { }; +#endif +#if defined(__GLIBCXX_TYPE_INT_N_1) + template<> + struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_1> + : public true_type { }; + + template<> + struct __is_integral_helper<unsigned __GLIBCXX_TYPE_INT_N_1> + : public true_type { }; +#endif +#if defined(__GLIBCXX_TYPE_INT_N_2) + template<> + struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_2> + : public true_type { }; + + template<> + struct __is_integral_helper<unsigned __GLIBCXX_TYPE_INT_N_2> + : public true_type { }; +#endif +#if defined(__GLIBCXX_TYPE_INT_N_3) + template<> + struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_3> + : public true_type { }; + + template<> + struct __is_integral_helper<unsigned __GLIBCXX_TYPE_INT_N_3> : public true_type { }; #endif /// is_integral template<typename _Tp> struct is_integral @@ -1598,16 +1627,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #if defined(_GLIBCXX_USE_WCHAR_T) && !defined(__WCHAR_UNSIGNED__) template<> struct __make_unsigned<wchar_t> : __make_unsigned<__WCHAR_TYPE__> { }; #endif -#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_INT128) +#if defined(__GLIBCXX_TYPE_INT_N_0) + template<> + struct __make_unsigned<__GLIBCXX_TYPE_INT_N_0> + { typedef unsigned __GLIBCXX_TYPE_INT_N_0 __type; }; +#endif +#if defined(__GLIBCXX_TYPE_INT_N_1) + template<> + struct __make_unsigned<__GLIBCXX_TYPE_INT_N_1> + { typedef unsigned __GLIBCXX_TYPE_INT_N_1 __type; }; +#endif +#if defined(__GLIBCXX_TYPE_INT_N_2) template<> - struct __make_unsigned<__int128> - { typedef unsigned __int128 __type; }; + struct __make_unsigned<__GLIBCXX_TYPE_INT_N_2> + { typedef unsigned __GLIBCXX_TYPE_INT_N_2 __type; }; +#endif +#if defined(__GLIBCXX_TYPE_INT_N_3) + template<> + struct __make_unsigned<__GLIBCXX_TYPE_INT_N_3> + { typedef unsigned __GLIBCXX_TYPE_INT_N_3 __type; }; #endif // Select between integral and enum: not possible to be both. template<typename _Tp, bool _IsInt = is_integral<_Tp>::value, bool _IsEnum = is_enum<_Tp>::value> @@ -1695,16 +1739,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { }; template<> struct __make_signed<char32_t> : __make_signed<uint_least32_t> { }; #endif -#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_INT128) +#if defined(__GLIBCXX_TYPE_INT_N_0) + template<> + struct __make_signed<unsigned __GLIBCXX_TYPE_INT_N_0> + { typedef __GLIBCXX_TYPE_INT_N_0 __type; }; +#endif +#if defined(__GLIBCXX_TYPE_INT_N_1) + template<> + struct __make_signed<unsigned __GLIBCXX_TYPE_INT_N_1> + { typedef __GLIBCXX_TYPE_INT_N_1 __type; }; +#endif +#if defined(__GLIBCXX_TYPE_INT_N_2) + template<> + struct __make_signed<unsigned __GLIBCXX_TYPE_INT_N_2> + { typedef __GLIBCXX_TYPE_INT_N_2 __type; }; +#endif +#if defined(__GLIBCXX_TYPE_INT_N_3) template<> - struct __make_signed<unsigned __int128> - { typedef __int128 __type; }; + struct __make_signed<unsigned __GLIBCXX_TYPE_INT_N_3> + { typedef __GLIBCXX_TYPE_INT_N_3 __type; }; #endif // Select between integral and enum: not possible to be both. template<typename _Tp, bool _IsInt = is_integral<_Tp>::value, bool _IsEnum = is_enum<_Tp>::value> Index: libstdc++-v3/include/std/limits =================================================================== --- libstdc++-v3/include/std/limits (revision 213886) +++ libstdc++-v3/include/std/limits (working copy) @@ -122,27 +122,38 @@ #ifndef __glibcxx_long_double_tinyness_before # define __glibcxx_long_double_tinyness_before false #endif // You should not need to define any macros below this point. -#define __glibcxx_signed(T) ((T)(-1) < 0) +#define __glibcxx_signed_b(T,B) ((T)(-1) < 0) -#define __glibcxx_min(T) \ - (__glibcxx_signed (T) ? -__glibcxx_max (T) - 1 : (T)0) +#define __glibcxx_min_b(T,B) \ + (__glibcxx_signed_b (T,B) ? -__glibcxx_max_b (T,B) - 1 : (T)0) -#define __glibcxx_max(T) \ - (__glibcxx_signed (T) ? \ - (((((T)1 << (__glibcxx_digits (T) - 1)) - 1) << 1) + 1) : ~(T)0) +#define __glibcxx_max_b(T,B) \ + (__glibcxx_signed_b (T,B) ? \ + (((((T)1 << (__glibcxx_digits_b (T,B) - 1)) - 1) << 1) + 1) : ~(T)0) -#define __glibcxx_digits(T) \ - (sizeof(T) * __CHAR_BIT__ - __glibcxx_signed (T)) +#define __glibcxx_digits_b(T,B) \ + (B - __glibcxx_signed_b (T,B)) // The fraction 643/2136 approximates log10(2) to 7 significant digits. +#define __glibcxx_digits10_b(T,B) \ + (__glibcxx_digits_b (T,B) * 643L / 2136) + +#define __glibcxx_signed(T) \ + __glibcxx_signed_b (T, sizeof(T) * __CHAR_BIT__) +#define __glibcxx_min(T) \ + __glibcxx_min_b (T, sizeof(T) * __CHAR_BIT__) +#define __glibcxx_max(T) \ + __glibcxx_max_b (T, sizeof(T) * __CHAR_BIT__) +#define __glibcxx_digits(T) \ + __glibcxx_digits_b (T, sizeof(T) * __CHAR_BIT__) #define __glibcxx_digits10(T) \ - (__glibcxx_digits (T) * 643L / 2136) + __glibcxx_digits10_b (T, sizeof(T) * __CHAR_BIT__) #define __glibcxx_max_digits10(T) \ (2 + (T) * 643L / 2136) namespace std _GLIBCXX_VISIBILITY(default) { @@ -1396,159 +1407,187 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION static _GLIBCXX_USE_CONSTEXPR bool traps = __glibcxx_integral_traps; static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false; static _GLIBCXX_USE_CONSTEXPR float_round_style round_style = round_toward_zero; }; -#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_INT128) - /// numeric_limits<__int128> specialization. - template<> - struct numeric_limits<__int128> - { - static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true; +#if !defined(__STRICT_ANSI__) - static _GLIBCXX_CONSTEXPR __int128 - min() _GLIBCXX_USE_NOEXCEPT { return __glibcxx_min (__int128); } +#define __INT_N(TYPE, BITSIZE, EXT, UEXT) \ + template<> \ + struct numeric_limits<TYPE> \ + { \ + static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true; \ + \ + static _GLIBCXX_CONSTEXPR TYPE \ + min() _GLIBCXX_USE_NOEXCEPT { return __glibcxx_min_b (TYPE, BITSIZE); } \ + \ + static _GLIBCXX_CONSTEXPR TYPE \ + max() _GLIBCXX_USE_NOEXCEPT { return __glibcxx_max_b (TYPE, BITSIZE);; } \ + \ + static _GLIBCXX_USE_CONSTEXPR int digits \ + = BITSIZE - 1; \ + static _GLIBCXX_USE_CONSTEXPR int digits10 \ + = (BITSIZE - 1) * 643L / 2136; \ + \ + static _GLIBCXX_USE_CONSTEXPR bool is_signed = true; \ + static _GLIBCXX_USE_CONSTEXPR bool is_integer = true; \ + static _GLIBCXX_USE_CONSTEXPR bool is_exact = true; \ + static _GLIBCXX_USE_CONSTEXPR int radix = 2; \ + \ + static _GLIBCXX_CONSTEXPR TYPE \ + epsilon() _GLIBCXX_USE_NOEXCEPT { return 0; } \ + \ + static _GLIBCXX_CONSTEXPR TYPE \ + round_error() _GLIBCXX_USE_NOEXCEPT { return 0; } \ + \ + EXT \ + \ + static _GLIBCXX_USE_CONSTEXPR int min_exponent = 0; \ + static _GLIBCXX_USE_CONSTEXPR int min_exponent10 = 0; \ + static _GLIBCXX_USE_CONSTEXPR int max_exponent = 0; \ + static _GLIBCXX_USE_CONSTEXPR int max_exponent10 = 0; \ + \ + static _GLIBCXX_USE_CONSTEXPR bool has_infinity = false; \ + static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = false; \ + static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = false; \ + static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm \ + = denorm_absent; \ + static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = false; \ + \ + static _GLIBCXX_CONSTEXPR TYPE \ + infinity() _GLIBCXX_USE_NOEXCEPT \ + { return static_cast<TYPE>(0); } \ + \ + static _GLIBCXX_CONSTEXPR TYPE \ + quiet_NaN() _GLIBCXX_USE_NOEXCEPT \ + { return static_cast<TYPE>(0); } \ + \ + static _GLIBCXX_CONSTEXPR TYPE \ + signaling_NaN() _GLIBCXX_USE_NOEXCEPT \ + { return static_cast<TYPE>(0); } \ + \ + static _GLIBCXX_CONSTEXPR TYPE \ + denorm_min() _GLIBCXX_USE_NOEXCEPT \ + { return static_cast<TYPE>(0); } \ + \ + static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false; \ + static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true; \ + static _GLIBCXX_USE_CONSTEXPR bool is_modulo = false; \ + \ + static _GLIBCXX_USE_CONSTEXPR bool traps \ + = __glibcxx_integral_traps; \ + static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false; \ + static _GLIBCXX_USE_CONSTEXPR float_round_style round_style \ + = round_toward_zero; \ + }; \ + \ + template<> \ + struct numeric_limits<unsigned TYPE> \ + { \ + static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true; \ + \ + static _GLIBCXX_CONSTEXPR unsigned TYPE \ + min() _GLIBCXX_USE_NOEXCEPT { return 0; } \ + \ + static _GLIBCXX_CONSTEXPR unsigned TYPE \ + max() _GLIBCXX_USE_NOEXCEPT { return __glibcxx_max_b (TYPE, BITSIZE); } \ + \ + UEXT \ + \ + static _GLIBCXX_USE_CONSTEXPR int digits \ + = BITSIZE; \ + static _GLIBCXX_USE_CONSTEXPR int digits10 \ + = BITSIZE * 643L / 2136; \ + static _GLIBCXX_USE_CONSTEXPR bool is_signed = false; \ + static _GLIBCXX_USE_CONSTEXPR bool is_integer = true; \ + static _GLIBCXX_USE_CONSTEXPR bool is_exact = true; \ + static _GLIBCXX_USE_CONSTEXPR int radix = 2; \ + \ + static _GLIBCXX_CONSTEXPR unsigned TYPE \ + epsilon() _GLIBCXX_USE_NOEXCEPT { return 0; } \ + \ + static _GLIBCXX_CONSTEXPR unsigned TYPE \ + round_error() _GLIBCXX_USE_NOEXCEPT { return 0; } \ + \ + static _GLIBCXX_USE_CONSTEXPR int min_exponent = 0; \ + static _GLIBCXX_USE_CONSTEXPR int min_exponent10 = 0; \ + static _GLIBCXX_USE_CONSTEXPR int max_exponent = 0; \ + static _GLIBCXX_USE_CONSTEXPR int max_exponent10 = 0; \ + \ + static _GLIBCXX_USE_CONSTEXPR bool has_infinity = false; \ + static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = false; \ + static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = false; \ + static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm \ + = denorm_absent; \ + static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = false; \ + \ + static _GLIBCXX_CONSTEXPR unsigned TYPE \ + infinity() _GLIBCXX_USE_NOEXCEPT \ + { return static_cast<unsigned TYPE>(0); } \ + \ + static _GLIBCXX_CONSTEXPR unsigned TYPE \ + quiet_NaN() _GLIBCXX_USE_NOEXCEPT \ + { return static_cast<unsigned TYPE>(0); } \ + \ + static _GLIBCXX_CONSTEXPR unsigned TYPE \ + signaling_NaN() _GLIBCXX_USE_NOEXCEPT \ + { return static_cast<unsigned TYPE>(0); } \ + \ + static _GLIBCXX_CONSTEXPR unsigned TYPE \ + denorm_min() _GLIBCXX_USE_NOEXCEPT \ + { return static_cast<unsigned TYPE>(0); } \ + \ + static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false; \ + static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true; \ + static _GLIBCXX_USE_CONSTEXPR bool is_modulo = true; \ + \ + static _GLIBCXX_USE_CONSTEXPR bool traps = __glibcxx_integral_traps; \ + static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false; \ + static _GLIBCXX_USE_CONSTEXPR float_round_style round_style \ + = round_toward_zero; \ + }; + +#if __cplusplus >= 201103L + +#define __INT_N_201103(TYPE) \ + static constexpr TYPE \ + lowest() noexcept { return min(); } \ + static constexpr int max_digits10 = 0; - static _GLIBCXX_CONSTEXPR __int128 - max() _GLIBCXX_USE_NOEXCEPT { return __glibcxx_max (__int128); } +#define __INT_N_U201103(TYPE) \ + static constexpr unsigned TYPE \ + lowest() noexcept { return min(); } \ + static constexpr int max_digits10 = 0; -#if __cplusplus >= 201103L - static constexpr __int128 - lowest() noexcept { return min(); } +#else +#define __INT_N_201103(TYPE) +#define __INT_N_U201103(TYPE) #endif - static _GLIBCXX_USE_CONSTEXPR int digits - = __glibcxx_digits (__int128); - static _GLIBCXX_USE_CONSTEXPR int digits10 - = __glibcxx_digits10 (__int128); -#if __cplusplus >= 201103L - static constexpr int max_digits10 = 0; +#ifdef __GLIBCXX_TYPE_INT_N_0 + __INT_N(__GLIBCXX_TYPE_INT_N_0, __GLIBCXX_BITSIZE_INT_N_0, + __INT_N_201103 (__GLIBCXX_TYPE_INT_N_0), __INT_N_U201103 (__GLIBCXX_TYPE_INT_N_0)) #endif - static _GLIBCXX_USE_CONSTEXPR bool is_signed = true; - static _GLIBCXX_USE_CONSTEXPR bool is_integer = true; - static _GLIBCXX_USE_CONSTEXPR bool is_exact = true; - static _GLIBCXX_USE_CONSTEXPR int radix = 2; - - static _GLIBCXX_CONSTEXPR __int128 - epsilon() _GLIBCXX_USE_NOEXCEPT { return 0; } - - static _GLIBCXX_CONSTEXPR __int128 - round_error() _GLIBCXX_USE_NOEXCEPT { return 0; } - - static _GLIBCXX_USE_CONSTEXPR int min_exponent = 0; - static _GLIBCXX_USE_CONSTEXPR int min_exponent10 = 0; - static _GLIBCXX_USE_CONSTEXPR int max_exponent = 0; - static _GLIBCXX_USE_CONSTEXPR int max_exponent10 = 0; - - static _GLIBCXX_USE_CONSTEXPR bool has_infinity = false; - static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = false; - static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = false; - static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm - = denorm_absent; - static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = false; - - static _GLIBCXX_CONSTEXPR __int128 - infinity() _GLIBCXX_USE_NOEXCEPT - { return static_cast<__int128>(0); } - - static _GLIBCXX_CONSTEXPR __int128 - quiet_NaN() _GLIBCXX_USE_NOEXCEPT - { return static_cast<__int128>(0); } - - static _GLIBCXX_CONSTEXPR __int128 - signaling_NaN() _GLIBCXX_USE_NOEXCEPT - { return static_cast<__int128>(0); } - - static _GLIBCXX_CONSTEXPR __int128 - denorm_min() _GLIBCXX_USE_NOEXCEPT - { return static_cast<__int128>(0); } - - static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false; - static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true; - static _GLIBCXX_USE_CONSTEXPR bool is_modulo = false; - - static _GLIBCXX_USE_CONSTEXPR bool traps - = __glibcxx_integral_traps; - static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false; - static _GLIBCXX_USE_CONSTEXPR float_round_style round_style - = round_toward_zero; - }; - - /// numeric_limits<unsigned __int128> specialization. - template<> - struct numeric_limits<unsigned __int128> - { - static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true; - - static _GLIBCXX_CONSTEXPR unsigned __int128 - min() _GLIBCXX_USE_NOEXCEPT { return 0; } - - static _GLIBCXX_CONSTEXPR unsigned __int128 - max() _GLIBCXX_USE_NOEXCEPT { return __glibcxx_max (unsigned __int128); } - -#if __cplusplus >= 201103L - static constexpr unsigned __int128 - lowest() noexcept { return min(); } +#ifdef __GLIBCXX_TYPE_INT_N_1 + __INT_N (__GLIBCXX_TYPE_INT_N_1, __GLIBCXX_BITSIZE_INT_N_1, + __INT_N_201103 (__GLIBCXX_TYPE_INT_N_1), __INT_N_U201103 (__GLIBCXX_TYPE_INT_N_1)) #endif - - static _GLIBCXX_USE_CONSTEXPR int digits - = __glibcxx_digits (unsigned __int128); - static _GLIBCXX_USE_CONSTEXPR int digits10 - = __glibcxx_digits10 (unsigned __int128); -#if __cplusplus >= 201103L - static constexpr int max_digits10 = 0; +#ifdef __GLIBCXX_TYPE_INT_N_2 + __INT_N (__GLIBCXX_TYPE_INT_N_2, __GLIBCXX_BITSIZE_INT_N_2, + __INT_N_201103 (__GLIBCXX_TYPE_INT_N_2), __INT_N_U201103 (__GLIBCXX_TYPE_INT_N_2)) +#endif +#ifdef __GLIBCXX_TYPE_INT_N_3 + __INT_N (__GLIBCXX_TYPE_INT_N_3, __GLIBCXX_BITSIZE_INT_N_3, + __INT_N_201103 (__GLIBCXX_TYPE_INT_N_3), __INT_N_U201103 (__GLIBCXX_TYPE_INT_N_3)) #endif - static _GLIBCXX_USE_CONSTEXPR bool is_signed = false; - static _GLIBCXX_USE_CONSTEXPR bool is_integer = true; - static _GLIBCXX_USE_CONSTEXPR bool is_exact = true; - static _GLIBCXX_USE_CONSTEXPR int radix = 2; - - static _GLIBCXX_CONSTEXPR unsigned __int128 - epsilon() _GLIBCXX_USE_NOEXCEPT { return 0; } - - static _GLIBCXX_CONSTEXPR unsigned __int128 - round_error() _GLIBCXX_USE_NOEXCEPT { return 0; } - - static _GLIBCXX_USE_CONSTEXPR int min_exponent = 0; - static _GLIBCXX_USE_CONSTEXPR int min_exponent10 = 0; - static _GLIBCXX_USE_CONSTEXPR int max_exponent = 0; - static _GLIBCXX_USE_CONSTEXPR int max_exponent10 = 0; - - static _GLIBCXX_USE_CONSTEXPR bool has_infinity = false; - static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = false; - static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = false; - static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm - = denorm_absent; - static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = false; - - static _GLIBCXX_CONSTEXPR unsigned __int128 - infinity() _GLIBCXX_USE_NOEXCEPT - { return static_cast<unsigned __int128>(0); } - - static _GLIBCXX_CONSTEXPR unsigned __int128 - quiet_NaN() _GLIBCXX_USE_NOEXCEPT - { return static_cast<unsigned __int128>(0); } - - static _GLIBCXX_CONSTEXPR unsigned __int128 - signaling_NaN() _GLIBCXX_USE_NOEXCEPT - { return static_cast<unsigned __int128>(0); } - - static _GLIBCXX_CONSTEXPR unsigned __int128 - denorm_min() _GLIBCXX_USE_NOEXCEPT - { return static_cast<unsigned __int128>(0); } - static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false; - static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true; - static _GLIBCXX_USE_CONSTEXPR bool is_modulo = true; +#undef __INT_N +#undef __INT_N_201103 +#undef __INT_N_U201103 - static _GLIBCXX_USE_CONSTEXPR bool traps = __glibcxx_integral_traps; - static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false; - static _GLIBCXX_USE_CONSTEXPR float_round_style round_style - = round_toward_zero; - }; #endif /// numeric_limits<float> specialization. template<> struct numeric_limits<float> { Index: libstdc++-v3/include/c_std/cstdlib =================================================================== --- libstdc++-v3/include/c_std/cstdlib (revision 213886) +++ libstdc++-v3/include/c_std/cstdlib (working copy) @@ -166,15 +166,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #ifdef _GLIBCXX_USE_LONG_LONG inline long long abs(long long __x) { return __builtin_llabs (__x); } #endif -#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_INT128) - inline __int128 - abs(__int128 __x) { return __x >= 0 ? __x : -__x; } +#if defined(__GLIBCXX_TYPE_INT_N_0) + inline __GLIBCXX_TYPE_INT_N_0 + abs(__GLIBCXX_TYPE_INT_N_0 __x) { return __x >= 0 ? __x : -__x; } +#endif +#if defined(__GLIBCXX_TYPE_INT_N_1) + inline __GLIBCXX_TYPE_INT_N_1 + abs(__GLIBCXX_TYPE_INT_N_1 __x) { return __x >= 0 ? __x : -__x; } +#endif +#if defined(__GLIBCXX_TYPE_INT_N_2) + inline __GLIBCXX_TYPE_INT_N_2 + abs(__GLIBCXX_TYPE_INT_N_2 __x) { return __x >= 0 ? __x : -__x; } +#endif +#if defined(__GLIBCXX_TYPE_INT_N_3) + inline __GLIBCXX_TYPE_INT_N_3 + abs(__GLIBCXX_TYPE_INT_N_3 __x) { return __x >= 0 ? __x : -__x; } #endif inline ldiv_t div(long __i, long __j) { return ldiv(__i, __j); } _GLIBCXX_END_NAMESPACE_VERSION Index: libstdc++-v3/include/bits/cpp_type_traits.h =================================================================== --- libstdc++-v3/include/bits/cpp_type_traits.h (revision 213886) +++ libstdc++-v3/include/bits/cpp_type_traits.h (working copy) @@ -138,13 +138,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION enum { __value = 0 }; typedef __false_type __type; }; // Thirteen specializations (yes there are eleven standard integer // types; <em>long long</em> and <em>unsigned long long</em> are - // supported as extensions) + // supported as extensions). Up to four target-specific __int<N> + // types are supported as well. template<> struct __is_integer<bool> { enum { __value = 1 }; typedef __true_type __type; }; @@ -248,12 +249,41 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __is_integer<unsigned long long> { enum { __value = 1 }; typedef __true_type __type; }; +#define __INT_N(TYPE) \ + template<> \ + struct __is_integer<TYPE> \ + { \ + enum { __value = 1 }; \ + typedef __true_type __type; \ + }; \ + template<> \ + struct __is_integer<unsigned TYPE> \ + { \ + enum { __value = 1 }; \ + typedef __true_type __type; \ + }; + +#ifdef __GLIBCXX_TYPE_INT_N_0 +__INT_N(__GLIBCXX_TYPE_INT_N_0) +#endif +#ifdef __GLIBCXX_TYPE_INT_N_1 +__INT_N(__GLIBCXX_TYPE_INT_N_1) +#endif +#ifdef __GLIBCXX_TYPE_INT_N_2 +__INT_N(__GLIBCXX_TYPE_INT_N_2) +#endif +#ifdef __GLIBCXX_TYPE_INT_N_3 +__INT_N(__GLIBCXX_TYPE_INT_N_3) +#endif + +#undef __INT_N + // // Floating point types // template<typename _Tp> struct __is_floating { Index: libstdc++-v3/include/c_global/cstdlib =================================================================== --- libstdc++-v3/include/c_global/cstdlib (revision 213886) +++ libstdc++-v3/include/c_global/cstdlib (working copy) @@ -171,17 +171,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #ifdef _GLIBCXX_USE_LONG_LONG inline long long abs(long long __x) { return __builtin_llabs (__x); } #endif -#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_INT128) - inline __int128 - abs(__int128 __x) { return __x >= 0 ? __x : -__x; } +#if defined(__GLIBCXX_TYPE_INT_N_0) + inline __GLIBCXX_TYPE_INT_N_0 + abs(__GLIBCXX_TYPE_INT_N_0 __x) { return __x >= 0 ? __x : -__x; } +#endif +#if defined(__GLIBCXX_TYPE_INT_N_1) + inline __GLIBCXX_TYPE_INT_N_1 + abs(__GLIBCXX_TYPE_INT_N_1 __x) { return __x >= 0 ? __x : -__x; } +#endif +#if defined(__GLIBCXX_TYPE_INT_N_2) + inline __GLIBCXX_TYPE_INT_N_2 + abs(__GLIBCXX_TYPE_INT_N_2 __x) { return __x >= 0 ? __x : -__x; } +#endif +#if defined(__GLIBCXX_TYPE_INT_N_3) + inline __GLIBCXX_TYPE_INT_N_3 + abs(__GLIBCXX_TYPE_INT_N_3 __x) { return __x >= 0 ? __x : -__x; } #endif + _GLIBCXX_END_NAMESPACE_VERSION } // namespace #if _GLIBCXX_USE_C99 #undef _Exit