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
27template <class T>
28struct EnumType
29{
30  enum type : T {E_zero, E_one};
31};
32
33
34template <class From, class To>
35void 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
69template <class From, class To>
70void 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
78enum enum1 { zero = 0, one = 1 };
79enum enum2 : unsigned long {
80  value = std::numeric_limits<unsigned long>::max()
81};
82
83int 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