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