1 // { dg-do compile { target c++2a } }
2 
3 // Test the types of atomic constraints
4 
5 // req5.C
6 struct fool {
7   constexpr fool operator&&(fool) const { return {}; }
8   constexpr fool operator||(fool) const { return {}; }
9 };
10 
p1()11 template<typename T> constexpr fool p1() { return {}; }
p2()12 template<typename T> constexpr fool p2() { return {}; }
13 
14 template<typename T>
15 concept Bad = p1<T>() && p2<T>(); // { dg-error "bool" }
16 
bad(T x)17 template<typename T> requires Bad<T> void bad(T x) { }
18 
driver_2()19 void driver_2()
20 {
21   bad(0); // { dg-message "" }
22 }
23 
24 // req6.C
25 struct X { };
26 int operator==(X, X) { return 0; }
27 
28 template<typename T>
29 concept C1 = (X()); // { dg-error "bool" }
30 
31 template<typename T>
32 concept C2 = (X() == X()); // { dg-error "bool" }
33 
34 template<typename T>
35   requires C1<T>
h1(T)36 void h1(T) { }
37 
38 template<typename T>
39   requires C2<T>
40 void h2(T);
41 
driver_3()42 void driver_3()
43 {
44   h1(0); // { dg-message "" }
45   h2(0); // { dg-message "" }
46 }
47 
48 // req7.C
49 template<bool B>
50 struct boolean_constant
51 {
52   constexpr operator bool() const { return B; }
53 };
54 
55 using true_type = boolean_constant<true>;
56 using false_type = boolean_constant<false>;
57 
58 template<typename T>
59 struct dependent_true : true_type { };
60 
61 template<typename T>
62 struct dependent_false : false_type { };
63 
64 template<typename T>
65   requires (dependent_true<T>{}) // { dg-message "bool" }
66 struct S5 { };
67 
68 template<typename T>
69   requires (dependent_false<T>{}) // { dg-message "bool" }
70 struct S6 { };
71 
72 S5<int> x5; // { dg-error "template constraint failure" }
73 S6<int> x6; // { dg-error "template constraint failure" }
74 
75