1 //===----------------------------------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // TODO: Make this test pass for all standards. 11 // XFAIL: c++98, c++03 12 13 // <type_traits> 14 15 // __convert_to_integral(Tp) 16 17 // Test that the __convert_to_integral functions properly converts Tp to the 18 // correct type and value for integral, enum and user defined types. 19 20 #include <limits> 21 #include <type_traits> 22 #include <cstdint> 23 #include <cassert> 24 25 #include "user_defined_integral.hpp" 26 27 template <class T> 28 struct EnumType 29 { 30 enum type : T {E_zero, E_one}; 31 }; 32 33 34 template <class From, class To> 35 void check_integral_types() 36 { 37 typedef std::numeric_limits<From> Limits; 38 const From max = Limits::max(); 39 const From min = Limits::min(); 40 { 41 auto ret = std::__convert_to_integral((From)max); 42 assert(ret == max); 43 ret = std::__convert_to_integral((From)min); 44 assert(ret == min); 45 static_assert(std::is_same<decltype(ret), To>::value, ""); 46 } 47 { 48 UserDefinedIntegral<From> f(max); 49 auto ret = std::__convert_to_integral(f); 50 assert(ret == max); 51 f.value = min; 52 ret = std::__convert_to_integral(f); 53 assert(ret == min); 54 static_assert(std::is_same<decltype(ret), To>::value, ""); 55 } 56 { 57 typedef typename EnumType<From>::type Enum; 58 Enum e(static_cast<Enum>(max)); 59 auto ret = std::__convert_to_integral(e); 60 assert(ret == max); 61 e = static_cast<Enum>(min); 62 ret = std::__convert_to_integral(min); 63 assert(ret == min); 64 static_assert(std::is_same<decltype(ret), To>::value, ""); 65 } 66 } 67 68 69 template <class From, class To> 70 void check_enum_types() 71 { 72 auto ret = std::__convert_to_integral((From)1); 73 assert(ret == 1); 74 static_assert(std::is_same<decltype(ret), To>::value, ""); 75 } 76 77 78 enum enum1 { zero = 0, one = 1 }; 79 enum enum2 : unsigned long { 80 value = std::numeric_limits<unsigned long>::max() 81 }; 82 83 int main() 84 { 85 check_integral_types<bool, int>(); 86 check_integral_types<char, int>(); 87 check_integral_types<signed char, int>(); 88 check_integral_types<unsigned char, int>(); 89 check_integral_types<wchar_t, decltype(((wchar_t)1) + 1)>(); 90 check_integral_types<char16_t, int>(); 91 check_integral_types<char32_t, uint32_t>(); 92 check_integral_types<short, int>(); 93 check_integral_types<unsigned short, int>(); 94 check_integral_types<int, int>(); 95 check_integral_types<unsigned, unsigned>(); 96 check_integral_types<long, long>(); 97 check_integral_types<unsigned long, unsigned long>(); 98 check_integral_types<long long, long long>(); 99 check_integral_types<unsigned long long, unsigned long long>(); 100 #ifndef _LIBCPP_HAS_NO_INT128 101 check_integral_types<__int128_t, __int128_t>(); 102 check_integral_types<__uint128_t, __uint128_t>(); 103 #endif 104 // TODO(ericwf): Not standard 105 typedef std::underlying_type<enum1>::type Enum1UT; 106 check_enum_types<enum1, decltype(((Enum1UT)1) + 1)>(); 107 typedef std::underlying_type<enum2>::type Enum2UT; 108 check_enum_types<enum2, decltype(((Enum2UT)1) + 1)>(); 109 } 110