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
10 
11 // template<class T>
12 //     concept default_initializable = constructible_from<T> &&
13 //     requires { T{}; } &&
14 //     is-default-initializable<T>;
15 
16 #include <array>
17 #include <concepts>
18 #include <deque>
19 #include <forward_list>
20 #include <list>
21 #include <map>
22 #include <memory>
23 #include <queue>
24 #include <set>
25 #include <span>
26 #include <stack>
27 #include <string>
28 #include <string_view>
29 #include <unordered_map>
30 #include <unordered_set>
31 #include <vector>
32 
33 #include "test_macros.h"
34 
35 struct Empty {};
36 
37 struct CtorDefaulted {
38   CtorDefaulted() = default;
39 };
40 struct CtorDeleted {
41   CtorDeleted() = delete;
42 };
43 struct DtorDefaulted {
44   ~DtorDefaulted() = default;
45 };
46 struct DtorDeleted {
47   ~DtorDeleted() = delete;
48 };
49 
50 struct Noexcept {
51   ~Noexcept() noexcept;
52 };
53 struct NoexceptTrue {
54   ~NoexceptTrue() noexcept(true);
55 };
56 struct NoexceptFalse {
57   ~NoexceptFalse() noexcept(false);
58 };
59 
60 struct CtorProtected {
61 protected:
62   CtorProtected() = default;
63 };
64 struct CtorPrivate {
65 private:
66   CtorPrivate() = default;
67 };
68 struct DtorProtected {
69 protected:
70   ~DtorProtected() = default;
71 };
72 struct DtorPrivate {
73 private:
74   ~DtorPrivate() = default;
75 };
76 
77 template <class T>
78 struct NoexceptDependant {
79   ~NoexceptDependant() noexcept(std::is_same_v<T, int>);
80 };
81 
82 struct CtorExplicit {
83   explicit CtorExplicit() = default;
84 };
85 struct CtorArgument {
86   CtorArgument(int) {}
87 };
88 struct CtorDefaultArgument {
89   CtorDefaultArgument(int = 0) {}
90 };
91 struct CtorExplicitDefaultArgument {
92   explicit CtorExplicitDefaultArgument(int = 0) {}
93 };
94 
95 struct Derived : public Empty {};
96 
97 class Abstract {
98   virtual void foo() = 0;
99 };
100 
101 class AbstractDestructor {
102   virtual ~AbstractDestructor() = 0;
103 };
104 
105 class OperatorNewDeleted {
106   void* operator new(std::size_t) = delete;
107   void operator delete(void* ptr) = delete;
108 };
109 
110 [[maybe_unused]] auto Lambda = [](const int&, int&&, double){};
111 
112 template<class T>
113 void test_not_const()
114 {
115     static_assert( std::default_initializable<               T>);
116     static_assert(!std::default_initializable<const          T>);
117     static_assert( std::default_initializable<      volatile T>);
118     static_assert(!std::default_initializable<const volatile T>);
119 }
120 
121 template<class T>
122 void test_true()
123 {
124     static_assert( std::default_initializable<               T>);
125     static_assert( std::default_initializable<const          T>);
126     static_assert( std::default_initializable<      volatile T>);
127     static_assert( std::default_initializable<const volatile T>);
128 }
129 
130 template<class T>
131 void test_false()
132 {
133     static_assert(!std::default_initializable<               T>);
134     static_assert(!std::default_initializable<const          T>);
135     static_assert(!std::default_initializable<      volatile T>);
136     static_assert(!std::default_initializable<const volatile T>);
137 }
138 
139 void test()
140 {
141     test_not_const<bool>();
142     test_not_const<char>();
143     test_not_const<int>();
144     test_not_const<double>();
145 
146     test_false    <void>();
147     test_not_const<void*>();
148 
149     test_not_const<int*>();
150     test_false    <int[]>();
151     test_not_const<int[1]>();
152     test_false    <int&>();
153     test_false    <int&&>();
154 
155     test_true     <Empty>();
156 
157     test_true     <CtorDefaulted>();
158     test_false    <CtorDeleted>();
159     test_true     <DtorDefaulted>();
160     test_false    <DtorDeleted>();
161 
162     test_true     <Noexcept>();
163     test_true     <NoexceptTrue>();
164     test_false    <NoexceptFalse>();
165 
166     test_false    <CtorProtected>();
167     test_false    <CtorPrivate>();
168     test_false    <DtorProtected>();
169     test_false    <DtorPrivate>();
170 
171     test_true     <NoexceptDependant<int>>();
172     test_false    <NoexceptDependant<double>>();
173 
174     test_true     <CtorExplicit>();
175     test_false    <CtorArgument>();
176     test_true     <CtorDefaultArgument>();
177     test_true     <CtorExplicitDefaultArgument>();
178 
179     test_true     <Derived>();
180     test_false    <Abstract>();
181     test_false    <AbstractDestructor>();
182 
183     test_true     <OperatorNewDeleted>();
184 
185     test_true     <decltype(Lambda)>();
186     test_not_const<void(*)(const int&)>();
187     test_not_const<void(Empty::*)(const int&)               >();
188     test_not_const<void(Empty::*)(const int&) const         >();
189     test_not_const<void(Empty::*)(const int&)       volatile>();
190     test_not_const<void(Empty::*)(const int&) const volatile>();
191     test_not_const<void(Empty::*)(const int&) &>();
192     test_not_const<void(Empty::*)(const int&) &&>();
193     test_not_const<void(Empty::*)(const int&) noexcept>();
194     test_not_const<void(Empty::*)(const int&) noexcept(true)>();
195     test_not_const<void(Empty::*)(const int&) noexcept(false)>();
196 
197     // Sequence containers
198     test_not_const<std::array<               int, 0>>();
199     test_not_const<std::array<               int, 1>>();
200     test_false    <std::array<const          int, 1>>();
201     test_not_const<std::array<      volatile int, 1>>();
202     test_false    <std::array<const volatile int, 1>>();
203     test_true     <std::deque<               int>>();
204 #ifdef _LIBCPP_VERSION
205     test_true     <std::deque<const          int>>();
206 #endif // _LIBCPP_VERSION
207     test_true     <std::forward_list<int>>();
208     test_true     <std::list<int>>();
209     test_true     <std::vector<int>>();
210 
211     // Associative containers
212     test_true     <std::set<int>>();
213     test_true     <std::map<int, int>>();
214     test_true     <std::multiset<int>>();
215     test_true     <std::multimap<int, int>>();
216 
217     // Unordered associative containers
218     test_true     <std::unordered_set<int>>();
219     test_true     <std::unordered_map<int, int>>();
220     test_true     <std::unordered_multiset<int>>();
221     test_true     <std::unordered_multimap<int, int>>();
222 
223     // Container adaptors
224     test_true     <std::stack<               int>>();
225 #ifdef _LIBCPP_VERSION
226     test_true     <std::stack<const          int>>();
227 #endif // _LIBCPP_VERSION
228     test_true     <std::queue<int>>();
229     test_true     <std::priority_queue<int>>();
230 
231     test_true     <std::span<               int>>();
232     test_true     <std::span<const          int>>();
233     test_true     <std::span<      volatile int>>();
234     test_true     <std::span<const volatile int>>();
235 
236     // Strings
237     test_true     <std::string>();
238 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
239     test_true     <std::wstring>();
240 #endif
241     test_true     <std::u8string>();
242     test_true     <std::u16string>();
243     test_true     <std::u32string>();
244 
245     // String views
246     test_true     <std::string_view>();
247 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
248     test_true     <std::wstring_view>();
249 #endif
250     test_true     <std::u8string_view>();
251     test_true     <std::u16string_view>();
252     test_true     <std::u32string_view>();
253 
254     // Smart pointers
255     test_true     <std::unique_ptr<int>>();
256     test_true     <std::shared_ptr<int>>();
257     test_true     <std::weak_ptr<int>>();
258 
259 }
260 
261 // Required for MSVC internal test runner compatibility.
262 int main(int, char**) {
263     return 0;
264 }
265