1 // { dg-do compile { target c++17_only } }
2 // { dg-options "-fconcepts" }
3 
4 // Performance test... This should be fast.
5 
6 #include <type_traits>
7 
8 template<typename T>
Destructible()9 concept bool Destructible() {
10     return std::is_destructible<T>::value;
11 }
12 template<typename T, typename... Args>
Constructible()13 concept bool Constructible() {
14     return Destructible<T>() && std::is_constructible<T, Args...>::value;
15 }
16 template<typename T>
Move_constructible()17 concept bool Move_constructible() {
18     return Constructible<T, T&&>();
19 }
20 template<typename T>
Copy_constructible()21 concept bool Copy_constructible() {
22     return Move_constructible<T>() && Constructible<T, const T&>();
23 }
24 template<typename T, typename U>
Assignable()25 concept bool Assignable() {
26     return std::is_assignable<T, U>::value;
27 }
28 template<typename T>
Move_assignable()29 concept bool Move_assignable() {
30     return Assignable<T&, T&&>();
31 }
32 template<typename T>
Copy_assignable()33 concept bool Copy_assignable() {
34     return Move_assignable<T>() && Assignable<T&, const T&>();
35 }
36 template<typename T>
Copyable()37 concept bool Copyable() {
38     return Copy_constructible<T>() && Copy_assignable<T>();
39 }
40 
41 template<typename T>
C1()42 concept bool C1() { return Copyable<T>(); }
43 template<typename T>
C2()44 concept bool C2() { return C1<T>(); }
45 template<typename T>
C3()46 concept bool C3() { return C2<T>(); }
47 template<typename T>
C4()48 concept bool C4() { return C3<T>(); }
49 template<typename T>
C5()50 concept bool C5() { return C4<T>(); }
51 template<typename T>
C6()52 concept bool C6() { return C5<T>(); }
53 template<typename T>
C7()54 concept bool C7() { return C6<T>(); }
55 template<typename T>
C8()56 concept bool C8() { return C7<T>(); }
57 template<typename T>
C9()58 concept bool C9() { return C8<T>(); }
59 template<typename T>
C10()60 concept bool C10() { return C9<T>(); }
61 template<typename T>
C11()62 concept bool C11() { return C10<T>(); }
63 
64 struct S1 {};
65 struct S2 {};
66 struct S3 {};
67 struct S4 {};
68 struct S5 {};
69 struct S6 {};
70 
71 static_assert(C11<S1>(), "");
72 static_assert(C11<S2>(), "");
73 static_assert(C11<S3>(), "");
74 static_assert(C11<S4>(), "");
75 static_assert(C11<S5>(), "");
76 static_assert(C11<S6>(), "");
77