xref: /llvm-project/clang/test/CXX/temp/temp.constr/temp.constr.constr/non-function-templates.cpp (revision fdf80e86a52849813d05da4b6c25884c06ba9e98)
1*fdf80e86SSaar Raz // RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
2*fdf80e86SSaar Raz 
3*fdf80e86SSaar Raz template<typename T> requires sizeof(T) >= 2 // expected-note{{because 'sizeof(char) >= 2' (1 >= 2) evaluated to false}}
4*fdf80e86SSaar Raz struct A {
5*fdf80e86SSaar Raz   static constexpr int value = sizeof(T);
6*fdf80e86SSaar Raz };
7*fdf80e86SSaar Raz 
8*fdf80e86SSaar Raz static_assert(A<int>::value == 4);
9*fdf80e86SSaar Raz static_assert(A<char>::value == 1); // expected-error{{constraints not satisfied for class template 'A' [with T = char]}}
10*fdf80e86SSaar Raz 
11*fdf80e86SSaar Raz template<typename T, typename U>
12*fdf80e86SSaar Raz   requires sizeof(T) != sizeof(U) // expected-note{{because 'sizeof(int) != sizeof(char [4])' (4 != 4) evaluated to false}}
13*fdf80e86SSaar Raz            && sizeof(T) >= 4 // expected-note{{because 'sizeof(char) >= 4' (1 >= 4) evaluated to false}}
14*fdf80e86SSaar Raz constexpr int SizeDiff = sizeof(T) > sizeof(U) ? sizeof(T) - sizeof(U) : sizeof(U) - sizeof(T);
15*fdf80e86SSaar Raz 
16*fdf80e86SSaar Raz static_assert(SizeDiff<int, char> == 3);
17*fdf80e86SSaar Raz static_assert(SizeDiff<int, char[4]> == 0); // expected-error{{constraints not satisfied for variable template 'SizeDiff' [with T = int, U = char [4]]}}
18*fdf80e86SSaar Raz static_assert(SizeDiff<char, int> == 3); // expected-error{{constraints not satisfied for variable template 'SizeDiff' [with T = char, U = int]}}
19*fdf80e86SSaar Raz 
20*fdf80e86SSaar Raz template<typename... Ts>
21*fdf80e86SSaar Raz   requires ((sizeof(Ts) == 4) || ...) // expected-note{{because 'sizeof(char) == 4' (1 == 4) evaluated to false}} expected-note{{'sizeof(long long) == 4' (8 == 4) evaluated to false}} expected-note{{'sizeof(int [20]) == 4' (80 == 4) evaluated to false}}
22*fdf80e86SSaar Raz constexpr auto SumSizes = (sizeof(Ts) + ...);
23*fdf80e86SSaar Raz 
24*fdf80e86SSaar Raz static_assert(SumSizes<char, long long, int> == 13);
25*fdf80e86SSaar Raz static_assert(SumSizes<char, long long, int[20]> == 89); // expected-error{{constraints not satisfied for variable template 'SumSizes' [with Ts = <char, long long, int [20]>]}}
26*fdf80e86SSaar Raz 
27*fdf80e86SSaar Raz template<typename T>
28*fdf80e86SSaar Raz concept IsBig = sizeof(T) > 100; // expected-note{{because 'sizeof(int) > 100' (4 > 100) evaluated to false}}
29*fdf80e86SSaar Raz 
30*fdf80e86SSaar Raz template<typename T>
31*fdf80e86SSaar Raz   requires IsBig<T> // expected-note{{'int' does not satisfy 'IsBig'}}
32*fdf80e86SSaar Raz using BigPtr = T*;
33*fdf80e86SSaar Raz 
34*fdf80e86SSaar Raz static_assert(sizeof(BigPtr<int>)); // expected-error{{constraints not satisfied for alias template 'BigPtr' [with T = int]}}}}
35*fdf80e86SSaar Raz 
36*fdf80e86SSaar Raz template<typename T> requires T::value // expected-note{{because substituted constraint expression is ill-formed: type 'int' cannot be used prior to '::' because it has no members}}
37*fdf80e86SSaar Raz struct S { static constexpr bool value = true; };
38*fdf80e86SSaar Raz 
39*fdf80e86SSaar Raz struct S2 { static constexpr bool value = true; };
40*fdf80e86SSaar Raz 
41*fdf80e86SSaar Raz static_assert(S<int>::value); // expected-error{{constraints not satisfied for class template 'S' [with T = int]}}
42*fdf80e86SSaar Raz static_assert(S<S2>::value);
43*fdf80e86SSaar Raz 
44*fdf80e86SSaar Raz template<typename T>
45*fdf80e86SSaar Raz struct AA
46*fdf80e86SSaar Raz {
47*fdf80e86SSaar Raz     template<typename U> requires sizeof(U) == sizeof(T) // expected-note{{because 'sizeof(int [2]) == sizeof(int)' (8 == 4) evaluated to false}}
48*fdf80e86SSaar Raz     struct B
49*fdf80e86SSaar Raz     {
50*fdf80e86SSaar Raz         static constexpr int a = 0;
51*fdf80e86SSaar Raz     };
52*fdf80e86SSaar Raz 
53*fdf80e86SSaar Raz     template<typename U> requires sizeof(U) == sizeof(T) // expected-note{{because 'sizeof(int [2]) == sizeof(int)' (8 == 4) evaluated to false}}
54*fdf80e86SSaar Raz     static constexpr int b = 1;
55*fdf80e86SSaar Raz 
56*fdf80e86SSaar Raz     template<typename U> requires sizeof(U) == sizeof(T) // expected-note{{because 'sizeof(int [2]) == sizeof(int)' (8 == 4) evaluated to false}}
57*fdf80e86SSaar Raz     static constexpr int getB() { // expected-note{{candidate template ignored: constraints not satisfied [with U = int [2]]}}
58*fdf80e86SSaar Raz         return 2;
59*fdf80e86SSaar Raz     }
60*fdf80e86SSaar Raz 
61*fdf80e86SSaar Raz     static auto foo()
62*fdf80e86SSaar Raz     {
63*fdf80e86SSaar Raz         return B<T[2]>::a; // expected-error{{constraints not satisfied for class template 'B' [with U = int [2]]}}
64*fdf80e86SSaar Raz     }
65*fdf80e86SSaar Raz 
66*fdf80e86SSaar Raz     static auto foo1()
67*fdf80e86SSaar Raz     {
68*fdf80e86SSaar Raz         return b<T[2]>; // expected-error{{constraints not satisfied for variable template 'b' [with U = int [2]]}}
69*fdf80e86SSaar Raz     }
70*fdf80e86SSaar Raz 
71*fdf80e86SSaar Raz     static auto foo2()
72*fdf80e86SSaar Raz     {
73*fdf80e86SSaar Raz         return AA<T>::getB<T[2]>(); // expected-error{{no matching function for call to 'getB'}}
74*fdf80e86SSaar Raz     }
75*fdf80e86SSaar Raz };
76*fdf80e86SSaar Raz 
77*fdf80e86SSaar Raz constexpr auto x = AA<int>::foo(); // expected-note{{in instantiation of member function 'AA<int>::foo' requested here}}
78*fdf80e86SSaar Raz constexpr auto x1 = AA<int>::foo1(); // expected-note{{in instantiation of member function 'AA<int>::foo1' requested here}}
79*fdf80e86SSaar Raz constexpr auto x2 = AA<int>::foo2(); // expected-note{{in instantiation of member function 'AA<int>::foo2' requested here}}
80*fdf80e86SSaar Raz 
81*fdf80e86SSaar Raz template<typename T>
82*fdf80e86SSaar Raz struct B { using type = typename T::type; }; // expected-error{{type 'int' cannot be used prior to '::' because it has no members}}
83*fdf80e86SSaar Raz 
84*fdf80e86SSaar Raz template<typename T> requires B<T>::type // expected-note{{in instantiation of template class 'B<int>' requested here}}
85*fdf80e86SSaar Raz                                          // expected-note@-1{{while substituting template arguments into constraint expression here}}
86*fdf80e86SSaar Raz struct C { };
87*fdf80e86SSaar Raz 
88*fdf80e86SSaar Raz template<typename T> requires T{} // expected-error{{atomic constraint must be of type 'bool' (found 'int')}}
89*fdf80e86SSaar Raz struct D { };
90*fdf80e86SSaar Raz 
91*fdf80e86SSaar Raz static_assert(C<int>{}); // expected-note{{while checking constraint satisfaction for template 'C<int>' required here}}
92*fdf80e86SSaar Raz static_assert(D<int>{}); // expected-note{{while checking constraint satisfaction for template 'D<int>' required here}}