@@ -348,138 +348,191 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
348348 : public true_type { };
349349
350350 // / @cond undocumented
351+
352+ // Every integral type is either one of the character types, one of the
353+ // signed integer types, one of the unsigned integer types, or bool,
354+ // or a cv-qualified version of one of those types ([basic.fundamental]).
355+ // For now we only need to distinguish the signed/unsigned integer types.
356+ enum class _Integer_kind { _None, _Signed, _Unsigned };
357+
351358 template <typename >
352359 struct __is_integral_helper
353- : public false_type { };
360+ : public false_type
361+ { static constexpr auto _S_kind = _Integer_kind::_None; };
354362
355363 template <>
356364 struct __is_integral_helper <bool >
357- : public true_type { };
365+ : public true_type
366+ { static constexpr auto _S_kind = _Integer_kind::_None; };
358367
359368 template <>
360369 struct __is_integral_helper <char >
361- : public true_type { };
370+ : public true_type
371+ { static constexpr auto _S_kind = _Integer_kind::_None; };
362372
363373 template <>
364374 struct __is_integral_helper <signed char >
365- : public true_type { };
375+ : public true_type
376+ { static constexpr auto _S_kind = _Integer_kind::_Signed; };
366377
367378 template <>
368379 struct __is_integral_helper <unsigned char >
369- : public true_type { };
380+ : public true_type
381+ { static constexpr auto _S_kind = _Integer_kind::_Unsigned; };
370382
371383 // We want is_integral<wchar_t> to be true (and make_signed/unsigned to work)
372384 // even when libc doesn't provide working <wchar.h> and related functions,
373385 // so don't check _GLIBCXX_USE_WCHAR_T here.
374386 template <>
375387 struct __is_integral_helper <wchar_t >
376- : public true_type { };
388+ : public true_type
389+ { static constexpr auto _S_kind = _Integer_kind::_None; };
377390
378391#ifdef _GLIBCXX_USE_CHAR8_T
379392 template <>
380393 struct __is_integral_helper <char8_t >
381- : public true_type { };
394+ : public true_type
395+ { static constexpr auto _S_kind = _Integer_kind::_None; };
382396#endif
383397
384398 template <>
385399 struct __is_integral_helper <char16_t >
386- : public true_type { };
400+ : public true_type
401+ { static constexpr auto _S_kind = _Integer_kind::_None; };
387402
388403 template <>
389404 struct __is_integral_helper <char32_t >
390- : public true_type { };
405+ : public true_type
406+ { static constexpr auto _S_kind = _Integer_kind::_None; };
391407
392408 template <>
393409 struct __is_integral_helper <short >
394- : public true_type { };
410+ : public true_type
411+ { static constexpr auto _S_kind = _Integer_kind::_Signed; };
395412
396413 template <>
397414 struct __is_integral_helper <unsigned short >
398- : public true_type { };
415+ : public true_type
416+ { static constexpr auto _S_kind = _Integer_kind::_Unsigned; };
399417
400418 template <>
401419 struct __is_integral_helper <int >
402- : public true_type { };
420+ : public true_type
421+ { static constexpr auto _S_kind = _Integer_kind::_Signed; };
403422
404423 template <>
405424 struct __is_integral_helper <unsigned int >
406- : public true_type { };
425+ : public true_type
426+ { static constexpr auto _S_kind = _Integer_kind::_Unsigned; };
407427
408428 template <>
409429 struct __is_integral_helper <long >
410- : public true_type { };
430+ : public true_type
431+ { static constexpr auto _S_kind = _Integer_kind::_Signed; };
411432
412433 template <>
413434 struct __is_integral_helper <unsigned long >
414- : public true_type { };
435+ : public true_type
436+ { static constexpr auto _S_kind = _Integer_kind::_Unsigned; };
415437
416438 template <>
417439 struct __is_integral_helper <long long >
418- : public true_type { };
440+ : public true_type
441+ { static constexpr auto _S_kind = _Integer_kind::_Signed; };
419442
420443 template <>
421444 struct __is_integral_helper <unsigned long long >
422- : public true_type { };
445+ : public true_type
446+ { static constexpr auto _S_kind = _Integer_kind::_Unsigned; };
423447
424448 // Conditionalizing on __STRICT_ANSI__ here will break any port that
425449 // uses one of these types for size_t.
426450#if defined(__GLIBCXX_TYPE_INT_N_0)
427451 __extension__
428452 template <>
429453 struct __is_integral_helper <__GLIBCXX_TYPE_INT_N_0>
430- : public true_type { };
454+ : public true_type
455+ { static constexpr auto _S_kind = _Integer_kind::_Signed; };
431456
432457 __extension__
433458 template <>
434459 struct __is_integral_helper <unsigned __GLIBCXX_TYPE_INT_N_0>
435- : public true_type { };
460+ : public true_type
461+ { static constexpr auto _S_kind = _Integer_kind::_Unsigned; };
436462#endif
437463#if defined(__GLIBCXX_TYPE_INT_N_1)
438464 __extension__
439465 template <>
440466 struct __is_integral_helper <__GLIBCXX_TYPE_INT_N_1>
441- : public true_type { };
467+ : public true_type
468+ { static constexpr auto _S_kind = _Integer_kind::_Signed; };
442469
443470 __extension__
444471 template <>
445472 struct __is_integral_helper <unsigned __GLIBCXX_TYPE_INT_N_1>
446- : public true_type { };
473+ : public true_type
474+ { static constexpr auto _S_kind = _Integer_kind::_Unsigned; };
447475#endif
448476#if defined(__GLIBCXX_TYPE_INT_N_2)
449477 __extension__
450478 template <>
451479 struct __is_integral_helper <__GLIBCXX_TYPE_INT_N_2>
452- : public true_type { };
480+ : public true_type
481+ { static constexpr auto _S_kind = _Integer_kind::_Signed; };
453482
454483 __extension__
455484 template <>
456485 struct __is_integral_helper <unsigned __GLIBCXX_TYPE_INT_N_2>
457- : public true_type { };
486+ : public true_type
487+ { static constexpr auto _S_kind = _Integer_kind::_Unsigned; };
458488#endif
459489#if defined(__GLIBCXX_TYPE_INT_N_3)
460490 __extension__
461491 template <>
462492 struct __is_integral_helper <__GLIBCXX_TYPE_INT_N_3>
463- : public true_type { };
493+ : public true_type
494+ { static constexpr auto _S_kind = _Integer_kind::_Signed; };
464495
465496 __extension__
466497 template <>
467498 struct __is_integral_helper <unsigned __GLIBCXX_TYPE_INT_N_3>
468- : public true_type { };
499+ : public true_type
500+ { static constexpr auto _S_kind = _Integer_kind::_Unsigned; };
469501#endif
470502
471503#if defined __SIZEOF_INT128__ && defined __STRICT_ANSI__
472504 __extension__
473505 template <>
474506 struct __is_integral_helper <__int128>
475- : public true_type { };
507+ : public true_type
508+ { static constexpr auto _S_kind = _Integer_kind::_Signed; };
476509
477510 __extension__
478511 template <>
479512 struct __is_integral_helper <unsigned __int128>
480- : public true_type { };
513+ : public true_type
514+ { static constexpr auto _S_kind = _Integer_kind::_Unsigned; };
481515#endif
482516
517+ // Check if a type is one of the signed integer types.
518+ template <typename _Tp>
519+ using __is_signed_integer
520+ = __bool_constant<__is_integral_helper<_Tp>::_S_kind
521+ == _Integer_kind::_Signed>;
522+
523+ // Check if a type is one of the unsigned integer types.
524+ template <typename _Tp>
525+ using __is_unsigned_integer
526+ = __bool_constant<__is_integral_helper<_Tp>::_S_kind
527+ == _Integer_kind::_Unsigned>;
528+
529+ // Check if a type is one of the signed or unsigned integer types.
530+ // i.e. an integral type except bool, char, wchar_t, and charN_t.
531+ template <typename _Tp>
532+ using __is_signed_or_unsigned_integer
533+ = __bool_constant<__is_integral_helper<_Tp>::_S_kind
534+ != _Integer_kind::_None>;
535+
483536 // / @endcond
484537
485538 // / is_integral
@@ -823,58 +876,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
823876 template <typename _Tp, typename ... _Types>
824877 using __is_one_of = __or_<is_same<_Tp, _Types>...>;
825878
826- // Check if a type is one of the signed integer types.
827- __extension__
828- template <typename _Tp>
829- using __is_signed_integer = __is_one_of<_Tp,
830- signed char , signed short , signed int , signed long ,
831- signed long long
832- #if defined(__GLIBCXX_TYPE_INT_N_0)
833- , signed __GLIBCXX_TYPE_INT_N_0
834- #endif
835- #if defined(__GLIBCXX_TYPE_INT_N_1)
836- , signed __GLIBCXX_TYPE_INT_N_1
837- #endif
838- #if defined(__GLIBCXX_TYPE_INT_N_2)
839- , signed __GLIBCXX_TYPE_INT_N_2
840- #endif
841- #if defined(__GLIBCXX_TYPE_INT_N_3)
842- , signed __GLIBCXX_TYPE_INT_N_3
843- #endif
844- #if defined __STRICT_ANSI__ && defined __SIZEOF_INT128__
845- , signed __int128
846- #endif
847- >;
848-
849- // Check if a type is one of the unsigned integer types.
850- __extension__
851- template <typename _Tp>
852- using __is_unsigned_integer = __is_one_of<_Tp,
853- unsigned char , unsigned short , unsigned int , unsigned long ,
854- unsigned long long
855- #if defined(__GLIBCXX_TYPE_INT_N_0)
856- , unsigned __GLIBCXX_TYPE_INT_N_0
857- #endif
858- #if defined(__GLIBCXX_TYPE_INT_N_1)
859- , unsigned __GLIBCXX_TYPE_INT_N_1
860- #endif
861- #if defined(__GLIBCXX_TYPE_INT_N_2)
862- , unsigned __GLIBCXX_TYPE_INT_N_2
863- #endif
864- #if defined(__GLIBCXX_TYPE_INT_N_3)
865- , unsigned __GLIBCXX_TYPE_INT_N_3
866- #endif
867- #if defined __STRICT_ANSI__ && defined __SIZEOF_INT128__
868- , unsigned __int128
869- #endif
870- >;
871-
872- // Check if a type is one of the signed or unsigned integer types.
873- // i.e. an integral type except bool, char, wchar_t, and charN_t.
874- template <typename _Tp>
875- using __is_signed_or_unsigned_integer
876- = __or_<__is_signed_integer<_Tp>, __is_unsigned_integer<_Tp>>;
877-
878879 // __void_t (std::void_t for C++11)
879880 template <typename ...> using __void_t = void ;
880881 // / @endcond
0 commit comments