Mercurial > hg > CbC > CbC_gcc
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; } |