124dd2d2fSChristopher Di Bella //===----------------------------------------------------------------------===//
224dd2d2fSChristopher Di Bella //
324dd2d2fSChristopher Di Bella // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
424dd2d2fSChristopher Di Bella // See https://llvm.org/LICENSE.txt for license information.
524dd2d2fSChristopher Di Bella // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
624dd2d2fSChristopher Di Bella //
724dd2d2fSChristopher Di Bella //===----------------------------------------------------------------------===//
824dd2d2fSChristopher Di Bella 
924dd2d2fSChristopher Di Bella // UNSUPPORTED: c++03, c++11, c++14, c++17
1024dd2d2fSChristopher Di Bella 
1124dd2d2fSChristopher Di Bella // template<class T, class... Args>
1224dd2d2fSChristopher Di Bella // concept constructible_from;
1324dd2d2fSChristopher Di Bella //    destructible<T> && is_constructible_v<T, Args...>;
1424dd2d2fSChristopher Di Bella 
1524dd2d2fSChristopher Di Bella #include <array>
1624dd2d2fSChristopher Di Bella #include <concepts>
17*e99c4906SNikolas Klauser #include <cstddef>
1824dd2d2fSChristopher Di Bella #include <memory>
1924dd2d2fSChristopher Di Bella #include <string>
2024dd2d2fSChristopher Di Bella #include <type_traits>
2124dd2d2fSChristopher Di Bella 
2224dd2d2fSChristopher Di Bella struct Empty {};
2324dd2d2fSChristopher Di Bella 
2424dd2d2fSChristopher Di Bella struct Defaulted {
2524dd2d2fSChristopher Di Bella   ~Defaulted() = default;
2624dd2d2fSChristopher Di Bella };
2724dd2d2fSChristopher Di Bella struct Deleted {
2824dd2d2fSChristopher Di Bella   ~Deleted() = delete;
2924dd2d2fSChristopher Di Bella };
3024dd2d2fSChristopher Di Bella 
3124dd2d2fSChristopher Di Bella struct Noexcept {
3224dd2d2fSChristopher Di Bella   ~Noexcept() noexcept;
3324dd2d2fSChristopher Di Bella };
3424dd2d2fSChristopher Di Bella struct NoexceptTrue {
3524dd2d2fSChristopher Di Bella   ~NoexceptTrue() noexcept(true);
3624dd2d2fSChristopher Di Bella };
3724dd2d2fSChristopher Di Bella struct NoexceptFalse {
3824dd2d2fSChristopher Di Bella   ~NoexceptFalse() noexcept(false);
3924dd2d2fSChristopher Di Bella };
4024dd2d2fSChristopher Di Bella 
4124dd2d2fSChristopher Di Bella struct Protected {
4224dd2d2fSChristopher Di Bella protected:
4324dd2d2fSChristopher Di Bella   ~Protected() = default;
4424dd2d2fSChristopher Di Bella };
4524dd2d2fSChristopher Di Bella struct Private {
4624dd2d2fSChristopher Di Bella private:
4724dd2d2fSChristopher Di Bella   ~Private() = default;
4824dd2d2fSChristopher Di Bella };
4924dd2d2fSChristopher Di Bella 
5024dd2d2fSChristopher Di Bella template <class T>
5124dd2d2fSChristopher Di Bella struct NoexceptDependant {
5224dd2d2fSChristopher Di Bella   ~NoexceptDependant() noexcept(std::is_same_v<T, int>);
5324dd2d2fSChristopher Di Bella };
5424dd2d2fSChristopher Di Bella 
5524dd2d2fSChristopher Di Bella template <class T, class... Args>
5624dd2d2fSChristopher Di Bella void test() {
5724dd2d2fSChristopher Di Bella   static_assert(std::constructible_from<T, Args...> ==
5824dd2d2fSChristopher Di Bella                 (std::destructible<T> && std::is_constructible_v<T, Args...>));
5924dd2d2fSChristopher Di Bella }
6024dd2d2fSChristopher Di Bella 
6124dd2d2fSChristopher Di Bella void test() {
6224dd2d2fSChristopher Di Bella   test<bool>();
6324dd2d2fSChristopher Di Bella   test<bool, bool>();
6424dd2d2fSChristopher Di Bella 
6524dd2d2fSChristopher Di Bella   test<char>();
6624dd2d2fSChristopher Di Bella   test<char, char>();
6724dd2d2fSChristopher Di Bella   test<char, int>();
6824dd2d2fSChristopher Di Bella 
6924dd2d2fSChristopher Di Bella   test<int>();
7024dd2d2fSChristopher Di Bella   test<int, int>();
7124dd2d2fSChristopher Di Bella   test<int, int, int>();
7224dd2d2fSChristopher Di Bella 
7324dd2d2fSChristopher Di Bella   test<double, int>();
7424dd2d2fSChristopher Di Bella   test<double, float>();
7524dd2d2fSChristopher Di Bella   test<double, long double>();
7624dd2d2fSChristopher Di Bella 
7724dd2d2fSChristopher Di Bella   test<void>();
7824dd2d2fSChristopher Di Bella   test<void, bool>();
7924dd2d2fSChristopher Di Bella   test<void, int>();
8024dd2d2fSChristopher Di Bella 
8124dd2d2fSChristopher Di Bella   test<void*>();
8224dd2d2fSChristopher Di Bella   test<void*, std::nullptr_t>();
8324dd2d2fSChristopher Di Bella 
8424dd2d2fSChristopher Di Bella   test<int*>();
8524dd2d2fSChristopher Di Bella   test<int*, std::nullptr_t>();
8624dd2d2fSChristopher Di Bella   test<int[], int, int, int>();
8724dd2d2fSChristopher Di Bella   test<int[1]>();
8824dd2d2fSChristopher Di Bella   test<int[1], int>();
8924dd2d2fSChristopher Di Bella   test<int[1], int, int>();
9024dd2d2fSChristopher Di Bella 
9124dd2d2fSChristopher Di Bella   test<int (*)(int)>();
9224dd2d2fSChristopher Di Bella   test<int (*)(int), int>();
9324dd2d2fSChristopher Di Bella   test<int (*)(int), double>();
9424dd2d2fSChristopher Di Bella   test<int (*)(int), std::nullptr_t>();
9524dd2d2fSChristopher Di Bella   test<int (*)(int), int (*)(int)>();
9624dd2d2fSChristopher Di Bella 
9724dd2d2fSChristopher Di Bella   test<void (Empty::*)(const int&)>();
9824dd2d2fSChristopher Di Bella   test<void (Empty::*)(const int&), std::nullptr_t>();
9924dd2d2fSChristopher Di Bella   test<void (Empty::*)(const int&) const>();
10024dd2d2fSChristopher Di Bella   test<void (Empty::*)(const int&) const, void (Empty::*)(const int&)>();
10124dd2d2fSChristopher Di Bella   test<void (Empty::*)(const int&) volatile>();
10224dd2d2fSChristopher Di Bella   test<void (Empty::*)(const int&) volatile,
10324dd2d2fSChristopher Di Bella        void (Empty::*)(const int&) const volatile>();
10424dd2d2fSChristopher Di Bella   test<void (Empty::*)(const int&) const volatile>();
10524dd2d2fSChristopher Di Bella   test<void (Empty::*)(const int&) const volatile, double>();
10624dd2d2fSChristopher Di Bella   test<void (Empty::*)(const int&)&>();
10724dd2d2fSChristopher Di Bella   test<void (Empty::*)(const int&)&, void (Empty::*)(const int&) &&>();
10824dd2d2fSChristopher Di Bella   test<void (Empty::*)(const int&) &&>();
10924dd2d2fSChristopher Di Bella   test<void (Empty::*)(const int&)&&, void (Empty::*)(const int&)>();
11024dd2d2fSChristopher Di Bella   test<void (Empty::*)(const int&) throw()>();
11124dd2d2fSChristopher Di Bella   test<void (Empty::*)(const int&) throw(),
11224dd2d2fSChristopher Di Bella        void(Empty::*)(const int&) noexcept(true)>();
11324dd2d2fSChristopher Di Bella   test<void (Empty::*)(const int&) noexcept>();
11424dd2d2fSChristopher Di Bella   test<void (Empty::*)(const int&) noexcept(true)>();
11524dd2d2fSChristopher Di Bella   test<void (Empty::*)(const int&) noexcept(true),
11624dd2d2fSChristopher Di Bella        void (Empty::*)(const int&) noexcept(false)>();
11724dd2d2fSChristopher Di Bella   test<void (Empty::*)(const int&) noexcept(false)>();
11824dd2d2fSChristopher Di Bella 
11924dd2d2fSChristopher Di Bella   test<int&>();
12024dd2d2fSChristopher Di Bella   test<int&, int>();
12124dd2d2fSChristopher Di Bella   test<int&&>();
12224dd2d2fSChristopher Di Bella   test<int&&, int>();
12324dd2d2fSChristopher Di Bella 
12424dd2d2fSChristopher Di Bella   test<Empty>();
12524dd2d2fSChristopher Di Bella 
12624dd2d2fSChristopher Di Bella   test<Defaulted>();
12724dd2d2fSChristopher Di Bella   test<Deleted>();
12824dd2d2fSChristopher Di Bella 
12924dd2d2fSChristopher Di Bella   test<NoexceptTrue>();
13024dd2d2fSChristopher Di Bella   test<NoexceptFalse>();
13124dd2d2fSChristopher Di Bella   test<Noexcept>();
13224dd2d2fSChristopher Di Bella 
13324dd2d2fSChristopher Di Bella   test<Protected>();
13424dd2d2fSChristopher Di Bella   test<Private>();
13524dd2d2fSChristopher Di Bella 
13624dd2d2fSChristopher Di Bella   test<NoexceptDependant<int> >();
13724dd2d2fSChristopher Di Bella   test<NoexceptDependant<double> >();
13824dd2d2fSChristopher Di Bella 
13924dd2d2fSChristopher Di Bella   test<std::string, char*>();
14024dd2d2fSChristopher Di Bella   test<std::string, const char*>();
14124dd2d2fSChristopher Di Bella   test<std::string, std::string&>();
14224dd2d2fSChristopher Di Bella   test<std::string, std::initializer_list<char> >();
14324dd2d2fSChristopher Di Bella 
14424dd2d2fSChristopher Di Bella   test<std::unique_ptr<int>, std::unique_ptr<int> >();
14524dd2d2fSChristopher Di Bella   test<std::unique_ptr<int>, std::unique_ptr<int>&>();
14624dd2d2fSChristopher Di Bella   test<std::unique_ptr<int>, std::unique_ptr<int>&&>();
14724dd2d2fSChristopher Di Bella 
14824dd2d2fSChristopher Di Bella   test<std::array<int, 1> >();
14924dd2d2fSChristopher Di Bella   test<std::array<int, 1>, int>();
15024dd2d2fSChristopher Di Bella   test<std::array<int, 1>, int, int>();
15124dd2d2fSChristopher Di Bella }
152