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, class... Args>
12 // concept constructible_from;
13 //    destructible<T> && is_constructible_v<T, Args...>;
14 
15 #include <array>
16 #include <concepts>
17 #include <memory>
18 #include <string>
19 #include <type_traits>
20 
21 struct Empty {};
22 
23 struct Defaulted {
24   ~Defaulted() = default;
25 };
26 struct Deleted {
27   ~Deleted() = delete;
28 };
29 
30 struct Noexcept {
31   ~Noexcept() noexcept;
32 };
33 struct NoexceptTrue {
34   ~NoexceptTrue() noexcept(true);
35 };
36 struct NoexceptFalse {
37   ~NoexceptFalse() noexcept(false);
38 };
39 
40 struct Protected {
41 protected:
42   ~Protected() = default;
43 };
44 struct Private {
45 private:
46   ~Private() = default;
47 };
48 
49 template <class T>
50 struct NoexceptDependant {
51   ~NoexceptDependant() noexcept(std::is_same_v<T, int>);
52 };
53 
54 template <class T, class... Args>
test()55 void test() {
56   static_assert(std::constructible_from<T, Args...> ==
57                 (std::destructible<T> && std::is_constructible_v<T, Args...>));
58 }
59 
test()60 void test() {
61   test<bool>();
62   test<bool, bool>();
63 
64   test<char>();
65   test<char, char>();
66   test<char, int>();
67 
68   test<int>();
69   test<int, int>();
70   test<int, int, int>();
71 
72   test<double, int>();
73   test<double, float>();
74   test<double, long double>();
75 
76   test<void>();
77   test<void, bool>();
78   test<void, int>();
79 
80   test<void*>();
81   test<void*, std::nullptr_t>();
82 
83   test<int*>();
84   test<int*, std::nullptr_t>();
85   test<int[], int, int, int>();
86   test<int[1]>();
87   test<int[1], int>();
88   test<int[1], int, int>();
89 
90   test<int (*)(int)>();
91   test<int (*)(int), int>();
92   test<int (*)(int), double>();
93   test<int (*)(int), std::nullptr_t>();
94   test<int (*)(int), int (*)(int)>();
95 
96   test<void (Empty::*)(const int&)>();
97   test<void (Empty::*)(const int&), std::nullptr_t>();
98   test<void (Empty::*)(const int&) const>();
99   test<void (Empty::*)(const int&) const, void (Empty::*)(const int&)>();
100   test<void (Empty::*)(const int&) volatile>();
101   test<void (Empty::*)(const int&) volatile,
102        void (Empty::*)(const int&) const volatile>();
103   test<void (Empty::*)(const int&) const volatile>();
104   test<void (Empty::*)(const int&) const volatile, double>();
105   test<void (Empty::*)(const int&)&>();
106   test<void (Empty::*)(const int&)&, void (Empty::*)(const int&) &&>();
107   test<void (Empty::*)(const int&) &&>();
108   test<void (Empty::*)(const int&)&&, void (Empty::*)(const int&)>();
109   test<void (Empty::*)(const int&) throw()>();
110   test<void (Empty::*)(const int&) throw(),
111        void(Empty::*)(const int&) noexcept(true)>();
112   test<void (Empty::*)(const int&) noexcept>();
113   test<void (Empty::*)(const int&) noexcept(true)>();
114   test<void (Empty::*)(const int&) noexcept(true),
115        void (Empty::*)(const int&) noexcept(false)>();
116   test<void (Empty::*)(const int&) noexcept(false)>();
117 
118   test<int&>();
119   test<int&, int>();
120   test<int&&>();
121   test<int&&, int>();
122 
123   test<Empty>();
124 
125   test<Defaulted>();
126   test<Deleted>();
127 
128   test<NoexceptTrue>();
129   test<NoexceptFalse>();
130   test<Noexcept>();
131 
132   test<Protected>();
133   test<Private>();
134 
135   test<NoexceptDependant<int> >();
136   test<NoexceptDependant<double> >();
137 
138   test<std::string, char*>();
139   test<std::string, const char*>();
140   test<std::string, std::string&>();
141   test<std::string, std::initializer_list<char> >();
142 
143   test<std::unique_ptr<int>, std::unique_ptr<int> >();
144   test<std::unique_ptr<int>, std::unique_ptr<int>&>();
145   test<std::unique_ptr<int>, std::unique_ptr<int>&&>();
146 
147   test<std::array<int, 1> >();
148   test<std::array<int, 1>, int>();
149   test<std::array<int, 1>, int, int>();
150 }
151