1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// TODO: Make this test pass for all standards.
10// XFAIL: c++03
11
12// <type_traits>
13
14// __convert_to_integral(Tp)
15
16// Test that the __convert_to_integral functions properly converts Tp to the
17// correct type and value for integral, enum and user defined types.
18
19#include "test_macros.h"
20
21TEST_CLANG_DIAGNOSTIC_IGNORED("-Wprivate-header")
22#include <__utility/convert_to_integral.h>
23#include <limits>
24#include <type_traits>
25#include <cstdint>
26#include <cassert>
27
28#include "user_defined_integral.h"
29
30template <class T>
31struct EnumType
32{
33 enum type : T {E_zero, E_one};
34};
35
36
37template <class From, class To>
38void check_integral_types()
39{
40 typedef std::numeric_limits<From> Limits;
41 const From max = Limits::max();
42 const From min = Limits::min();
43 {
44 auto ret = std::__convert_to_integral((From)max);
45 assert(ret == max);
46 ret = std::__convert_to_integral((From)min);
47 assert(ret == min);
48 static_assert(std::is_same<decltype(ret), To>::value, "");
49 }
50 {
51 UserDefinedIntegral<From> f(max);
52 auto ret = std::__convert_to_integral(f);
53 assert(ret == max);
54 f.value = min;
55 ret = std::__convert_to_integral(f);
56 assert(ret == min);
57 static_assert(std::is_same<decltype(ret), To>::value, "");
58 }
59 {
60 typedef typename EnumType<From>::type Enum;
61 Enum e(static_cast<Enum>(max));
62 auto ret = std::__convert_to_integral(e);
63 assert(ret == max);
64 e = static_cast<Enum>(min);
65 ret = std::__convert_to_integral(min);
66 assert(ret == min);
67 static_assert(std::is_same<decltype(ret), To>::value, "");
68 }
69}
70
71
72template <class From, class To>
73void check_enum_types()
74{
75 auto ret = std::__convert_to_integral((From)1);
76 assert(ret == 1);
77 static_assert(std::is_same<decltype(ret), To>::value, "");
78}
79
80
81enum enum1 { zero = 0, one = 1 };
82enum enum2 : unsigned long {
83 value = std::numeric_limits<unsigned long>::max()
84};
85
86int main(int, char**)
87{
88 check_integral_types<bool, int>();
89 check_integral_types<char, int>();
90 check_integral_types<signed char, int>();
91 check_integral_types<unsigned char, int>();
92#ifndef TEST_HAS_NO_WIDE_CHARACTERS
93 check_integral_types<wchar_t, decltype(((wchar_t)1) + 1)>();
94#endif
95 check_integral_types<char16_t, int>();
96 // On some platforms, unsigned int and long are the same size. These
97 // platforms have a choice of making std::uint32_t an int or a long. However
98 // char32_t must promote to an unsigned int on these platforms [conv.prom].
99 // Use the following logic to make the test work on such platforms.
100 // (sizeof(std::uint32_t) == sizeof(unsigned int)) ? unsigned int : std::uint32_t;
101 typedef std::conditional<sizeof(std::uint32_t) == sizeof(unsigned int),
102 unsigned int, std::uint32_t>::type char_integral;
103 check_integral_types<char32_t, char_integral>();
104 check_integral_types<short, int>();
105 check_integral_types<unsigned short, int>();
106 check_integral_types<int, int>();
107 check_integral_types<unsigned, unsigned>();
108 check_integral_types<long, long>();
109 check_integral_types<unsigned long, unsigned long>();
110 check_integral_types<long long, long long>();
111 check_integral_types<unsigned long long, unsigned long long>();
112#ifndef TEST_HAS_NO_INT128
113 check_integral_types<__int128_t, __int128_t>();
114 check_integral_types<__uint128_t, __uint128_t>();
115#endif
116 // TODO(ericwf): Not standard
117 typedef std::underlying_type<enum1>::type Enum1UT;
118 check_enum_types<enum1, decltype(((Enum1UT)1) + 1)>();
119 typedef std::underlying_type<enum2>::type Enum2UT;
120 check_enum_types<enum2, decltype(((Enum2UT)1) + 1)>();
121
122 return 0;
123}
124

source code of libcxx/test/libcxx/type_traits/convert_to_integral.pass.cpp