comparison gcc/testsuite/g++.dg/concepts/generic-fn.C @ 111:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents
children 84e7813d76e9
comparison
equal deleted inserted replaced
68:561a7518be6b 111:04ced10e8804
1 // { dg-do run }
2 // { dg-options "-std=c++17 -fconcepts" }
3
4 #include <cassert>
5 #include <type_traits>
6
7 template<typename T>
8 concept bool C() { return __is_class(T); }
9
10 template<typename T>
11 concept bool Type() { return true; }
12
13 struct S { };
14
15 int called;
16
17 // Basic terse notation
18 void f(auto x) { called = 1; }
19 void g(C x) { called = 2; }
20
21 // Overloading generic functions
22 void h(auto x) { called = 1; }
23 void h(C x) { called = 2; }
24
25 void p(auto x);
26 void p(C x);
27
28 struct S1 {
29 void f1(auto x) { called = 1; }
30 void f2(C x) { called = 2; }
31
32 void f3(auto x) { called = 1; }
33 void f3(C x) { called = 2; }
34 };
35
36 template<C T>
37 struct S2 {
38 void f1(auto x) { called = 1; }
39 void f2(C x) { called = 2; }
40
41 void f3(auto x) { called = 1; }
42 void f3(C x) { called = 2; }
43
44 void h1(auto x);
45 void h2(C x);
46
47 void h3(auto x);
48 void h3(C x);
49
50 template<C U>
51 void g1(T t, U u) { called = 1; }
52
53 template<C U>
54 void g2(T t, U u);
55 };
56
57
58 void ptr(C*) { called = 1; }
59 void ptr(const C*) { called = 2; }
60
61 void ref(C&) { called = 1; }
62 void ref(const C&) { called = 2; }
63
64 void
65 fwd_lvalue_ref(Type&& x) {
66 using T = decltype(x);
67 static_assert(std::is_lvalue_reference<T>::value, "not an lvlaue reference");
68 }
69
70 void
71 fwd_const_lvalue_ref(Type&& x) {
72 using T = decltype(x);
73 static_assert(std::is_lvalue_reference<T>::value, "not an lvalue reference");
74 using U = typename std::remove_reference<T>::type;
75 static_assert(std::is_const<U>::value, "not const-qualified");
76 }
77
78 void fwd_rvalue_ref(Type&& x) {
79 using T = decltype(x);
80 static_assert(std::is_rvalue_reference<T>::value, "not an rvalue reference");
81 }
82
83 // Make sure we can use nested names speicifers for concept names.
84 namespace N {
85 template<typename T>
86 concept bool C() { return true; }
87 } // namesspace N
88
89 void foo(N::C x) { }
90
91 int main() {
92 S s;
93 const S cs;
94
95 f(0); assert(called == 1);
96 g(s); assert(called == 2);
97
98 h(0); assert(called == 1);
99 h(s); assert(called == 2);
100
101 S1 s1;
102 s1.f1(0); assert(called == 1);
103 s1.f2(s); assert(called == 2);
104
105 s1.f3(0); assert(called == 1);
106 s1.f3(s); assert(called == 2);
107
108 S2<S> s2;
109 s2.f1(0); assert(called == 1);
110 s2.f2(s); assert(called == 2);
111
112 s2.f3(0); assert(called == 1);
113 s2.f3(s); assert(called == 2);
114
115 s2.h1(0); assert(called == 1);
116 s2.h2(s); assert(called == 2);
117
118 s2.h3(0); assert(called == 1);
119 s2.h3(s); assert(called == 2);
120
121 s2.g1(s, s); assert(called == 1);
122 s2.g2(s, s); assert(called == 2);
123
124 ptr(&s); assert(called == 1);
125 ptr(&cs); assert(called == 2);
126
127 ref(s); assert(called == 1);
128 ref(cs); assert(called == 2);
129
130 // Check forwarding problems
131 fwd_lvalue_ref(s);
132 fwd_const_lvalue_ref(cs);
133 fwd_rvalue_ref(S());
134
135 foo(0);
136 }
137
138 // Test that decl/def matching works.
139
140 void p(auto x) { called = 1; }
141 void p(C x) { called = 2; }
142
143 template<C T>
144 void S2<T>::h1(auto x) { called = 1; }
145
146 template<C T>
147 void S2<T>::h2(C x) { called = 2; }
148
149 template<C T>
150 void S2<T>::h3(auto x) { called = 1; }
151
152 template<C T>
153 void S2<T>::h3(C x) { called = 2; }
154
155 template<C T>
156 template<C U>
157 void S2<T>::g2(T t, U u) { called = 2; }