131
|
1 // { dg-do compile { target c++17 } }
|
|
2 // { dg-options "-fconcepts" }
|
111
|
3
|
|
4 // Test that constraint satisfaction checks work even when
|
|
5 // processing template declarations.
|
|
6
|
|
7 namespace std
|
|
8 {
|
|
9
|
|
10 struct ostream { };
|
|
11 ostream cout;
|
|
12
|
|
13 template<typename T>
|
|
14 auto begin(T& t) -> decltype(t.begin()) { return t.begin(); }
|
|
15
|
|
16 template<typename T>
|
|
17 auto begin(T const& t) -> decltype(t.begin()) { return t.begin(); }
|
|
18
|
|
19 template<typename T>
|
|
20 auto end(T& t) -> decltype(t.end()) { return t.end(); }
|
|
21
|
|
22 template<typename T>
|
|
23 auto end(T const& t) -> decltype(t.end()) { return t.end(); }
|
|
24
|
|
25 } // namespace std
|
|
26
|
|
27
|
|
28 template <typename T>
|
|
29 concept bool Float()
|
|
30 {
|
|
31 return __is_same_as( T, float );
|
|
32 }
|
|
33
|
|
34 template <typename T>
|
|
35 constexpr decltype(auto) project( T t )
|
|
36 {
|
|
37 return t;
|
|
38 }
|
|
39
|
|
40 template <typename T>
|
|
41 concept bool Concept()
|
|
42 {
|
|
43 return requires( T t ) {
|
|
44 requires Float<decltype( project(t) )>();
|
|
45 };
|
|
46 }
|
|
47
|
|
48 template <Concept E, Concept F>
|
|
49 constexpr decltype(auto) operator<<( E&& e, F&& f ) {}
|
|
50
|
|
51 template <Concept T>
|
|
52 void foo( T t )
|
|
53 {
|
|
54 // Try to resolve operator<< from within a template context but
|
|
55 // with non-dependent arguments. We need to ensure that template
|
|
56 // processing is turned off whenever checking for satisfaction.
|
|
57 std::cout << "OK"; // { dg-error "no match" }
|
|
58 }
|
|
59
|
|
60
|
|
61 template <typename R>
|
|
62 concept bool Range()
|
|
63 {
|
|
64 return requires( R r ) {
|
|
65 requires __is_same_as(
|
|
66 decltype(std::begin(r)), decltype(std::end(r)) );
|
|
67 };
|
|
68 }
|
|
69
|
|
70 struct A
|
|
71 {
|
|
72 A() = default;
|
|
73 A( const A& ) = default;
|
|
74
|
|
75 // Derivation from this class forces the instantiation of
|
|
76 // this constructor, which results in the __is_same_as type
|
|
77 // trait above to become error_mark_node in this declaration.
|
|
78 template <Range R>
|
|
79 explicit A( R&& r ) { }
|
|
80 };
|
|
81
|
|
82 struct C : A
|
|
83 {
|
|
84 C() = default;
|
|
85 C( const C& ) = default;
|
|
86 };
|
|
87
|
|
88 int main()
|
|
89 {
|
|
90 C c; // OK
|
|
91 return 0;
|
|
92 }
|