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 // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
10 
11 // type_traits
12 
13 // is_scoped_enum // C++2b
14 
15 #include <type_traits>
16 #include <cstddef> // for std::nullptr_t
17 #include "test_macros.h"
18 
19 template <class T>
test_positive()20 void test_positive() {
21   static_assert(std::is_scoped_enum<T>::value);
22   static_assert(std::is_scoped_enum<const T>::value);
23   static_assert(std::is_scoped_enum<volatile T>::value);
24   static_assert(std::is_scoped_enum<const volatile T>::value);
25 
26   static_assert(std::is_scoped_enum_v<T>);
27   static_assert(std::is_scoped_enum_v<const T>);
28   static_assert(std::is_scoped_enum_v<volatile T>);
29   static_assert(std::is_scoped_enum_v<const volatile T>);
30 }
31 
32 template <class T>
test_negative()33 void test_negative() {
34   static_assert(!std::is_scoped_enum<T>::value);
35   static_assert(!std::is_scoped_enum<const T>::value);
36   static_assert(!std::is_scoped_enum<volatile T>::value);
37   static_assert(!std::is_scoped_enum<const volatile T>::value);
38 
39   static_assert(!std::is_scoped_enum_v<T>);
40   static_assert(!std::is_scoped_enum_v<const T>);
41   static_assert(!std::is_scoped_enum_v<volatile T>);
42   static_assert(!std::is_scoped_enum_v<const volatile T>);
43 }
44 
45 class Empty {};
46 
47 class NotEmpty {
48   virtual ~NotEmpty();
49 };
50 
51 union Union {};
52 
53 struct bit_zero {
54   int : 0;
55 };
56 
57 class Abstract {
58   virtual ~Abstract() = 0;
59 };
60 
61 enum Enum { zero, one };
62 enum class CEnum1 { zero, one };
63 enum class CEnum2;
64 enum class CEnum3 : short;
65 struct incomplete_type;
66 
67 using FunctionPtr = void (*)();
68 using FunctionType = void();
69 
70 struct TestMembers {
static_methodTestMembers71   static int static_method(int) { return 0; }
methodTestMembers72   int method() { return 0; }
73 
74   enum E1 { m_zero, m_one };
75   enum class CE1;
76 };
77 
78 void func1();
79 int func2(int);
80 
main(int,char **)81 int main(int, char**) {
82   test_positive<CEnum1>();
83   test_positive<CEnum2>();
84   test_positive<CEnum3>();
85   test_positive<TestMembers::CE1>();
86 
87   test_negative<Enum>();
88   test_negative<TestMembers::E1>();
89 
90   test_negative<std::nullptr_t>();
91   test_negative<void>();
92   test_negative<int>();
93   test_negative<int&>();
94   test_negative<int&&>();
95   test_negative<int*>();
96   test_negative<double>();
97   test_negative<const int*>();
98   test_negative<char[3]>();
99   test_negative<char[]>();
100   test_negative<Union>();
101   test_negative<Empty>();
102   test_negative<bit_zero>();
103   test_negative<NotEmpty>();
104   test_negative<Abstract>();
105   test_negative<FunctionPtr>();
106   test_negative<FunctionType>();
107   test_negative<incomplete_type>();
108   test_negative<int TestMembers::*>();
109   test_negative<void (TestMembers::*)()>();
110 
111   test_negative<decltype(func1)>();
112   test_negative<decltype(&func1)>();
113   test_negative<decltype(func2)>();
114   test_negative<decltype(&func2)>();
115   test_negative<decltype(TestMembers::static_method)>();
116   test_negative<decltype(&TestMembers::static_method)>();
117   test_negative<decltype(&TestMembers::method)>();
118 
119   return 0;
120 }
121