+2018-05-31 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/85951
+ * include/std/type_traits [_GLIBCXX_USE_C99_STDINT_TR1]: Do not define
+ uint_least16_t and uint_least32_t.
+ (__make_unsigned<wchar_t>): Define unconditionally.
+ (__make_unsigned_selector<_Tp, true, false>): Remove intermediate
+ typedefs.
+ (__make_unsigned_selector_base): New type to provide helper templates.
+ (__make_unsigned_selector<_Tp, false, true>): Reimplement using
+ __make_unsigned_selector_base helpers.
+ (__make_unsigned<char16_t>, __make_unsigned<char32_t>): Define.
+ (__make_signed_selector<_Tp, true, false>): Remove intermediate
+ typedefs.
+ (__make_signed<wchar_t>, __make_signed<char16_t>)
+ (__make_signed<char32_t>)): Define unconditionally.
+ * testsuite/20_util/make_signed/requirements/typedefs-3.cc: Check
+ wchar_t, char16_t and char32_t are transformed correctly.
+ * testsuite/20_util/make_signed/requirements/typedefs_neg.cc: Adjust
+ dg-error lineno.
+ * testsuite/20_util/make_unsigned/requirements/typedefs-3.cc: Check
+ wchar_t, char16_t and char32_t are transformed correctly.
+ * testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc: Adjust
+ dg-error lineno.
+
2018-05-29 Jonathan Wakely <jwakely@redhat.com>
* include/std/variant (__erased_dtor): Qualify call to __get.
#include <bits/c++config.h>
-#ifdef _GLIBCXX_USE_C99_STDINT_TR1
-# if defined (__UINT_LEAST16_TYPE__) && defined(__UINT_LEAST32_TYPE__)
-namespace std
-{
- typedef __UINT_LEAST16_TYPE__ uint_least16_t;
- typedef __UINT_LEAST32_TYPE__ uint_least32_t;
-}
-# else
-# include <cstdint>
-# endif
-#endif
-
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
struct __make_unsigned<long long>
{ typedef unsigned long long __type; };
-#if defined(_GLIBCXX_USE_WCHAR_T) && !defined(__WCHAR_UNSIGNED__)
- template<>
- struct __make_unsigned<wchar_t> : __make_unsigned<__WCHAR_TYPE__>
- { };
-#endif
-
#if defined(__GLIBCXX_TYPE_INT_N_0)
template<>
struct __make_unsigned<__GLIBCXX_TYPE_INT_N_0>
template<typename _Tp>
class __make_unsigned_selector<_Tp, true, false>
{
- typedef __make_unsigned<typename remove_cv<_Tp>::type> __unsignedt;
- typedef typename __unsignedt::__type __unsigned_type;
- typedef __match_cv_qualifiers<_Tp, __unsigned_type> __cv_unsigned;
+ using __unsigned_type
+ = typename __make_unsigned<typename remove_cv<_Tp>::type>::__type;
public:
- typedef typename __cv_unsigned::__type __type;
+ using __type
+ = typename __match_cv_qualifiers<_Tp, __unsigned_type>::__type;
};
+ class __make_unsigned_selector_base
+ {
+ protected:
+ template<typename...> struct _List { };
+
+ template<typename _Tp, typename... _Up>
+ struct _List<_Tp, _Up...> : _List<_Up...>
+ { static constexpr size_t __size = sizeof(_Tp); };
+
+ template<size_t _Sz, typename _Tp, bool = (_Sz <= _Tp::__size)>
+ struct __select;
+
+ template<size_t _Sz, typename _Uint, typename... _UInts>
+ struct __select<_Sz, _List<_Uint, _UInts...>, true>
+ { using __type = _Uint; };
+
+ template<size_t _Sz, typename _Uint, typename... _UInts>
+ struct __select<_Sz, _List<_Uint, _UInts...>, false>
+ : __select<_Sz, _List<_UInts...>>
+ { };
+ };
+
+ // Choose unsigned integer type with the smallest rank and same size as _Tp
template<typename _Tp>
class __make_unsigned_selector<_Tp, false, true>
+ : __make_unsigned_selector_base
{
// With -fshort-enums, an enum may be as small as a char.
- typedef unsigned char __smallest;
- static const bool __b0 = sizeof(_Tp) <= sizeof(__smallest);
- static const bool __b1 = sizeof(_Tp) <= sizeof(unsigned short);
- static const bool __b2 = sizeof(_Tp) <= sizeof(unsigned int);
- static const bool __b3 = sizeof(_Tp) <= sizeof(unsigned long);
- typedef conditional<__b3, unsigned long, unsigned long long> __cond3;
- typedef typename __cond3::type __cond3_type;
- typedef conditional<__b2, unsigned int, __cond3_type> __cond2;
- typedef typename __cond2::type __cond2_type;
- typedef conditional<__b1, unsigned short, __cond2_type> __cond1;
- typedef typename __cond1::type __cond1_type;
-
- typedef typename conditional<__b0, __smallest, __cond1_type>::type
- __unsigned_type;
- typedef __match_cv_qualifiers<_Tp, __unsigned_type> __cv_unsigned;
+ using _UInts = _List<unsigned char, unsigned short, unsigned int,
+ unsigned long, unsigned long long>;
+
+ using __unsigned_type = typename __select<sizeof(_Tp), _UInts>::__type;
public:
- typedef typename __cv_unsigned::__type __type;
+ using __type
+ = typename __match_cv_qualifiers<_Tp, __unsigned_type>::__type;
+ };
+
+ // wchar_t, char16_t and char32_t are integral types but are neither
+ // signed integer types not unsigned integer types, so must be
+ // transformed to the unsigned integer type with the smallest rank.
+ // Use the partial specialization for enumeration types to do that.
+#if defined(_GLIBCXX_USE_WCHAR_T)
+ template<>
+ struct __make_unsigned<wchar_t>
+ {
+ using __type
+ = typename __make_unsigned_selector<wchar_t, false, true>::__type;
+ };
+#endif
+
+ template<>
+ struct __make_unsigned<char16_t>
+ {
+ using __type
+ = typename __make_unsigned_selector<char16_t, false, true>::__type;
+ };
+
+ template<>
+ struct __make_unsigned<char32_t>
+ {
+ using __type
+ = typename __make_unsigned_selector<char32_t, false, true>::__type;
};
// Given an integral/enum type, return the corresponding unsigned
struct __make_signed<unsigned long long>
{ typedef signed long long __type; };
-#if defined(_GLIBCXX_USE_WCHAR_T) && defined(__WCHAR_UNSIGNED__)
- template<>
- struct __make_signed<wchar_t> : __make_signed<__WCHAR_TYPE__>
- { };
-#endif
-
-#ifdef _GLIBCXX_USE_C99_STDINT_TR1
- template<>
- struct __make_signed<char16_t> : __make_signed<uint_least16_t>
- { };
- template<>
- struct __make_signed<char32_t> : __make_signed<uint_least32_t>
- { };
-#endif
-
#if defined(__GLIBCXX_TYPE_INT_N_0)
template<>
struct __make_signed<unsigned __GLIBCXX_TYPE_INT_N_0>
template<typename _Tp>
class __make_signed_selector<_Tp, true, false>
{
- typedef __make_signed<typename remove_cv<_Tp>::type> __signedt;
- typedef typename __signedt::__type __signed_type;
- typedef __match_cv_qualifiers<_Tp, __signed_type> __cv_signed;
+ using __signed_type
+ = typename __make_signed<typename remove_cv<_Tp>::type>::__type;
public:
- typedef typename __cv_signed::__type __type;
+ using __type
+ = typename __match_cv_qualifiers<_Tp, __signed_type>::__type;
};
+ // Choose signed integer type with the smallest rank and same size as _Tp
template<typename _Tp>
class __make_signed_selector<_Tp, false, true>
{
typedef typename __make_signed_selector<__unsigned_type>::__type __type;
};
+ // wchar_t, char16_t and char32_t are integral types but are neither
+ // signed integer types not unsigned integer types, so must be
+ // transformed to the signed integer type with the smallest rank.
+ // Use the partial specialization for enumeration types to do that.
+#if defined(_GLIBCXX_USE_WCHAR_T)
+ template<>
+ struct __make_signed<wchar_t>
+ {
+ using __type
+ = typename __make_signed_selector<wchar_t, false, true>::__type;
+ };
+#endif
+
+ template<>
+ struct __make_signed<char16_t>
+ {
+ using __type
+ = typename __make_signed_selector<char16_t, false, true>::__type;
+ };
+
+ template<>
+ struct __make_signed<char32_t>
+ {
+ using __type
+ = typename __make_signed_selector<char32_t, false, true>::__type;
+ };
+
// Given an integral/enum type, return the corresponding signed
// integer type.
// Primary template.