-
Notifications
You must be signed in to change notification settings - Fork 0
/
test_enum_traits.cpp
110 lines (92 loc) · 4.1 KB
/
test_enum_traits.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#include "enum_traits.hpp"
#include <cstdint>
enum class ABC : int8_t { a, b, c=3 };
static_assert( ltl::is_scoped_enum_v<ABC> );
static_assert( ltl::is_fixed_enum_v<ABC> );
static_assert( ltl::is_scoped_enum<ABC>::value );
static_assert( ltl::is_fixed_enum<ABC>::value );
static_assert( ltl::to_underlying(ABC::b) == 1 );
static_assert( std::is_same_v<std::underlying_type_t<ABC>, int8_t> );
static_assert( std::is_same_v<decltype(ltl::to_underlying(ABC::b)), int8_t> );
enum { uint64_max = 0xFFFFFFFFFFFFFFFF };
using MAX64 = decltype(uint64_max);
static_assert( ! ltl::is_scoped_enum_v<MAX64> );
static_assert( ! ltl::is_fixed_enum_v<MAX64> );
static_assert( ! ltl::is_scoped_enum<MAX64>::value );
static_assert( ! ltl::is_fixed_enum<MAX64>::value );
# if not defined(_MSC_VER)
static_assert( std::is_same_v<std::underlying_type_t<MAX64>, uint64_t> );
static_assert( std::is_same_v<decltype(ltl::to_underlying( uint64_max)), uint64_t> );
# endif
enum O {};
static_assert( ! ltl::is_scoped_enum_v<O> );
static_assert( ! ltl::is_fixed_enum_v<O> );
static_assert( ! ltl::is_scoped_enum<O>::value );
static_assert( ! ltl::is_fixed_enum<O>::value );
# if not defined(_MSC_VER)
static_assert( std::is_same_v<std::underlying_type_t<O>, uint32_t> );
static_assert( std::is_same_v<decltype(ltl::to_underlying(O())), uint32_t> );
# endif
enum N { n };
static_assert( ! ltl::is_scoped_enum_v<N> );
static_assert( ! ltl::is_fixed_enum_v<N> );
# if not defined(_MSC_VER)
static_assert( std::is_same_v<std::underlying_type_t<N>, uint32_t> );
static_assert( std::is_same_v<decltype(ltl::to_underlying(N{})), uint32_t> );
# endif
enum B : uint8_t { b };
static_assert( ! ltl::is_scoped_enum_v<B> );
static_assert( ltl::is_fixed_enum_v<B> );
static_assert( ltl::is_fixed_enum<B>::value );
static_assert( std::is_same_v<std::underlying_type_t<B>, uint8_t> );
static_assert( std::is_same_v<decltype(ltl::to_underlying(b)), uint8_t> );
enum class C : uint16_t { a, bade=0xbade, feca=0xFECA};
static_assert( ltl::is_scoped_enum_v<C> );
static_assert( ltl::is_fixed_enum_v<C> );
static_assert( std::is_same_v<std::underlying_type_t<C>, uint16_t> );
static_assert( std::is_same_v<decltype(ltl::to_underlying(C::a)), uint16_t> );
// ltl::underlying_type tests
// In C++17 std::underlying_type<non_enum_type> is UB
// In C++20 it is defined as a struct with no 'type' typedef member
static_assert( std::is_same_v<ltl::underlying_type<ABC>::type,
std::underlying_type<ABC>::type> );
namespace impl
{
template <typename, typename = void>
inline constexpr bool has_type_typedef_member{};
template <typename T>
inline constexpr bool has_type_typedef_member<T, std::void_t<
typename T::type>>{true};
// test the tester
static_assert( has_type_typedef_member<std::add_cv<int>> );
static_assert( ! has_type_typedef_member<int> );
static_assert( ! has_type_typedef_member<struct X> );
struct X { using type = int; };
static_assert( ! has_type_typedef_member<X> );
} // namespace impl
enum Y : int;
static_assert( impl::has_type_typedef_member<ltl::underlying_type<Y>> );
static_assert( ! impl::has_type_typedef_member<ltl::underlying_type<int>> );
// ltl::to_underlying SFINAE test
template <auto e, typename = int>
inline constexpr bool is_int_enum { };
template <auto e>
inline constexpr bool is_int_enum<e, decltype(ltl::to_underlying(e))> = true;
static_assert( ! is_int_enum<1> );
enum : int { e };
static_assert( is_int_enum<e> );
int main()
{
enum { min32 = INT32_MIN, max32 = INT32_MAX };
using M = decltype(min32);
static_assert( ! ltl::is_scoped_enum_v<M> );
static_assert( ! ltl::is_fixed_enum_v<M> );
static_assert( std::is_same_v<std::underlying_type_t<M>, int32_t> );
static_assert( ltl::to_underlying(min32) == -0x7fffffff - 1 ); // INT32_MIN
enum class L : int8_t {};
static_assert( ltl::is_scoped_enum_v<L> );
static_assert( ltl::is_fixed_enum_v<L> );
static_assert( ltl::to_underlying(L{1}) == 1 );
static_assert( std::is_same_v<std::underlying_type_t<L>, int8_t> );
static_assert( std::is_same_v<decltype(ltl::to_underlying(L{0})), int8_t> );
}