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