Saar Raz | ffa214e | 2019-10-25 00:09:37 +0300 | [diff] [blame] | 1 | // RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s |
| 2 | |
| 3 | namespace class_templates |
| 4 | { |
| 5 | template<typename T, typename U> requires sizeof(T) >= 4 // expected-note {{because 'sizeof(char) >= 4' (1 >= 4) evaluated to false}} |
| 6 | struct is_same { static constexpr bool value = false; }; |
| 7 | |
| 8 | template<typename T> requires sizeof(T*) >= 4 && sizeof(T) >= 4 |
| 9 | struct is_same<T*, T*> { static constexpr bool value = true; }; |
| 10 | |
| 11 | static_assert(!is_same<char*, char*>::value); |
| 12 | static_assert(!is_same<short*, short*>::value); |
| 13 | static_assert(is_same<int*, int*>::value); |
| 14 | static_assert(is_same<char, char>::value); // expected-error {{constraints not satisfied for class template 'is_same' [with T = char, U = char]}} |
| 15 | |
| 16 | template<typename T> |
| 17 | struct A { using type = typename T::type; }; // expected-error{{type 'int *' cannot be used prior to '::' because it has no members}} |
| 18 | |
| 19 | template<typename T> |
| 20 | struct B {}; |
| 21 | |
| 22 | template<typename T> requires A<T>::type // expected-note{{in instantiation of template class 'class_templates::A<int *>' requested here}} |
| 23 | // expected-note@-1{{while substituting template arguments into constraint expression here}} |
| 24 | struct B<T*> {}; |
| 25 | |
| 26 | template<typename T> requires T{} // expected-error{{atomic constraint must be of type 'bool' (found 'int')}} |
| 27 | struct B<T**> {}; |
| 28 | |
| 29 | static_assert((B<int**>{}, true)); // expected-note{{while checking constraint satisfaction for class template partial specialization 'B<int *>' required here}} |
| 30 | // expected-note@-1{{while checking constraint satisfaction for class template partial specialization 'B<int>' required here}} |
| 31 | // expected-note@-2{{during template argument deduction for class template partial specialization 'B<T *>' [with T = int *]}} |
| 32 | // expected-note@-3{{during template argument deduction for class template partial specialization 'B<T **>' [with T = int]}} |
| 33 | // expected-note@-4 2{{in instantiation of template class 'class_templates::B<int **>' requested here}} |
| 34 | } |
| 35 | |
| 36 | namespace variable_templates |
| 37 | { |
| 38 | template<typename T, typename U> requires sizeof(T) >= 4 |
| 39 | constexpr bool is_same_v = false; |
| 40 | |
| 41 | template<typename T> requires sizeof(T*) >= 4 && sizeof(T) >= 4 |
| 42 | constexpr bool is_same_v<T*, T*> = true; |
| 43 | |
| 44 | static_assert(!is_same_v<char*, char*>); |
| 45 | static_assert(!is_same_v<short*, short*>); |
| 46 | static_assert(is_same_v<int*, int*>); |
| 47 | |
| 48 | template<typename T> |
| 49 | struct A { using type = typename T::type; }; // expected-error{{type 'int *' cannot be used prior to '::' because it has no members}} |
| 50 | |
| 51 | template<typename T> |
| 52 | constexpr bool v1 = false; |
| 53 | |
| 54 | template<typename T> requires A<T>::type // expected-note{{in instantiation of template class 'variable_templates::A<int *>' requested here}} |
| 55 | // expected-note@-1{{while substituting template arguments into constraint expression here}} |
| 56 | constexpr bool v1<T*> = true; |
| 57 | |
| 58 | template<typename T> requires T{} // expected-error{{atomic constraint must be of type 'bool' (found 'int')}} |
| 59 | constexpr bool v1<T**> = true; |
| 60 | |
| 61 | static_assert(v1<int**>); // expected-note{{while checking constraint satisfaction for variable template partial specialization 'v1<int *>' required here}} |
| 62 | // expected-note@-1{{while checking constraint satisfaction for variable template partial specialization 'v1<int>' required here}} |
| 63 | // expected-note@-2{{during template argument deduction for variable template partial specialization 'v1<T *>' [with T = int *]}} |
| 64 | // expected-note@-3{{during template argument deduction for variable template partial specialization 'v1<T **>' [with T = int]}} |
| 65 | // expected-error@-4{{static_assert failed due to requirement 'v1<int **>'}} |
| 66 | |
| 67 | } |