]>
Commit | Line | Data |
---|---|---|
3cbc7af0 BK |
1 | // -*- C++ -*- |
2 | ||
8d9254fc | 3 | // Copyright (C) 2004-2020 Free Software Foundation, Inc. |
30a20a1e | 4 | // |
ce120bb2 MK |
5 | // This file is part of the GNU ISO C++ Library. This library is free |
6 | // software; you can redistribute it and/or modify it under the | |
7 | // terms of the GNU General Public License as published by the | |
748086b7 | 8 | // Free Software Foundation; either version 3, or (at your option) |
ce120bb2 MK |
9 | // any later version. |
10 | ||
11 | // This library is distributed in the hope that it will be useful, | |
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | // GNU General Public License for more details. | |
15 | ||
748086b7 JJ |
16 | // Under Section 7 of GPL version 3, you are granted additional |
17 | // permissions described in the GCC Runtime Library Exception, version | |
18 | // 3.1, as published by the Free Software Foundation. | |
ce120bb2 | 19 | |
748086b7 JJ |
20 | // You should have received a copy of the GNU General Public License and |
21 | // a copy of the GCC Runtime Library Exception along with this program; | |
22 | // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see | |
23 | // <http://www.gnu.org/licenses/>. | |
ce120bb2 | 24 | |
30a20a1e PE |
25 | // (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify, |
26 | // sell and distribute this software is granted provided this | |
27 | // copyright notice appears in all copies. This software is provided | |
28 | // "as is" without express or implied warranty, and with no claim as | |
29 | // to its suitability for any purpose. | |
30 | // | |
31 | ||
f910786b | 32 | /** @file bits/boost_concept_check.h |
729e3d3f | 33 | * This is an internal header file, included by other library headers. |
f910786b | 34 | * Do not attempt to use it directly. @headername{iterator} |
729e3d3f PE |
35 | */ |
36 | ||
143c27b0 BK |
37 | // GCC Note: based on version 1.12.0 of the Boost library. |
38 | ||
3d7c150e BK |
39 | #ifndef _BOOST_CONCEPT_CHECK_H |
40 | #define _BOOST_CONCEPT_CHECK_H 1 | |
30a20a1e PE |
41 | |
42 | #pragma GCC system_header | |
3d7c150e | 43 | |
8fc81078 | 44 | #include <bits/c++config.h> |
30a20a1e | 45 | #include <bits/stl_iterator_base_types.h> // for traits and tags |
30a20a1e | 46 | |
12ffa228 BK |
47 | namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) |
48 | { | |
49 | _GLIBCXX_BEGIN_NAMESPACE_VERSION | |
30a20a1e | 50 | |
9ed83a33 JW |
51 | #pragma GCC diagnostic push |
52 | #pragma GCC diagnostic ignored "-Wunused-local-typedefs" | |
53 | ||
62bb0c97 | 54 | #define _IsUnused __attribute__ ((__unused__)) |
30a20a1e | 55 | |
4d16bdbb PE |
56 | // When the C-C code is in use, we would like this function to do as little |
57 | // as possible at runtime, use as few resources as possible, and hopefully | |
58 | // be elided out of existence... hmmm. | |
62bb0c97 | 59 | template <class _Concept> |
4d16bdbb | 60 | inline void __function_requires() |
30a20a1e | 61 | { |
62bb0c97 | 62 | void (_Concept::*__x)() _IsUnused = &_Concept::__constraints; |
30a20a1e PE |
63 | } |
64 | ||
563ae04f BK |
65 | // No definition: if this is referenced, there's a problem with |
66 | // the instantiating type not being one of the required integer types. | |
67 | // Unfortunately, this results in a link-time error, not a compile-time error. | |
68 | void __error_type_must_be_an_integer_type(); | |
69 | void __error_type_must_be_an_unsigned_integer_type(); | |
70 | void __error_type_must_be_a_signed_integer_type(); | |
30a20a1e | 71 | |
62bb0c97 | 72 | // ??? Should the "concept_checking*" structs begin with more than _ ? |
3d7c150e | 73 | #define _GLIBCXX_CLASS_REQUIRES(_type_var, _ns, _concept) \ |
62bb0c97 PE |
74 | typedef void (_ns::_concept <_type_var>::* _func##_type_var##_concept)(); \ |
75 | template <_func##_type_var##_concept _Tp1> \ | |
76 | struct _concept_checking##_type_var##_concept { }; \ | |
77 | typedef _concept_checking##_type_var##_concept< \ | |
78 | &_ns::_concept <_type_var>::__constraints> \ | |
79 | _concept_checking_typedef##_type_var##_concept | |
80 | ||
3d7c150e | 81 | #define _GLIBCXX_CLASS_REQUIRES2(_type_var1, _type_var2, _ns, _concept) \ |
62bb0c97 PE |
82 | typedef void (_ns::_concept <_type_var1,_type_var2>::* _func##_type_var1##_type_var2##_concept)(); \ |
83 | template <_func##_type_var1##_type_var2##_concept _Tp1> \ | |
84 | struct _concept_checking##_type_var1##_type_var2##_concept { }; \ | |
85 | typedef _concept_checking##_type_var1##_type_var2##_concept< \ | |
86 | &_ns::_concept <_type_var1,_type_var2>::__constraints> \ | |
87 | _concept_checking_typedef##_type_var1##_type_var2##_concept | |
88 | ||
3d7c150e | 89 | #define _GLIBCXX_CLASS_REQUIRES3(_type_var1, _type_var2, _type_var3, _ns, _concept) \ |
62bb0c97 PE |
90 | typedef void (_ns::_concept <_type_var1,_type_var2,_type_var3>::* _func##_type_var1##_type_var2##_type_var3##_concept)(); \ |
91 | template <_func##_type_var1##_type_var2##_type_var3##_concept _Tp1> \ | |
92 | struct _concept_checking##_type_var1##_type_var2##_type_var3##_concept { }; \ | |
93 | typedef _concept_checking##_type_var1##_type_var2##_type_var3##_concept< \ | |
94 | &_ns::_concept <_type_var1,_type_var2,_type_var3>::__constraints> \ | |
95 | _concept_checking_typedef##_type_var1##_type_var2##_type_var3##_concept | |
96 | ||
3d7c150e | 97 | #define _GLIBCXX_CLASS_REQUIRES4(_type_var1, _type_var2, _type_var3, _type_var4, _ns, _concept) \ |
62bb0c97 PE |
98 | typedef void (_ns::_concept <_type_var1,_type_var2,_type_var3,_type_var4>::* _func##_type_var1##_type_var2##_type_var3##_type_var4##_concept)(); \ |
99 | template <_func##_type_var1##_type_var2##_type_var3##_type_var4##_concept _Tp1> \ | |
100 | struct _concept_checking##_type_var1##_type_var2##_type_var3##_type_var4##_concept { }; \ | |
101 | typedef _concept_checking##_type_var1##_type_var2##_type_var3##_type_var4##_concept< \ | |
102 | &_ns::_concept <_type_var1,_type_var2,_type_var3,_type_var4>::__constraints> \ | |
103 | _concept_checking_typedef##_type_var1##_type_var2##_type_var3##_type_var4##_concept | |
104 | ||
105 | ||
106 | template <class _Tp1, class _Tp2> | |
107 | struct _Aux_require_same { }; | |
108 | ||
109 | template <class _Tp> | |
110 | struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; }; | |
111 | ||
112 | template <class _Tp1, class _Tp2> | |
113 | struct _SameTypeConcept | |
114 | { | |
115 | void __constraints() { | |
116 | typedef typename _Aux_require_same<_Tp1, _Tp2>::_Type _Required; | |
117 | } | |
118 | }; | |
119 | ||
120 | template <class _Tp> | |
121 | struct _IntegerConcept { | |
ed6814f7 | 122 | void __constraints() { |
563ae04f | 123 | __error_type_must_be_an_integer_type(); |
62bb0c97 PE |
124 | } |
125 | }; | |
126 | template <> struct _IntegerConcept<short> { void __constraints() {} }; | |
127 | template <> struct _IntegerConcept<unsigned short> { void __constraints(){} }; | |
128 | template <> struct _IntegerConcept<int> { void __constraints() {} }; | |
129 | template <> struct _IntegerConcept<unsigned int> { void __constraints() {} }; | |
130 | template <> struct _IntegerConcept<long> { void __constraints() {} }; | |
131 | template <> struct _IntegerConcept<unsigned long> { void __constraints() {} }; | |
62bb0c97 PE |
132 | template <> struct _IntegerConcept<long long> { void __constraints() {} }; |
133 | template <> struct _IntegerConcept<unsigned long long> | |
134 | { void __constraints() {} }; | |
62bb0c97 PE |
135 | |
136 | template <class _Tp> | |
137 | struct _SignedIntegerConcept { | |
ed6814f7 | 138 | void __constraints() { |
563ae04f | 139 | __error_type_must_be_a_signed_integer_type(); |
62bb0c97 PE |
140 | } |
141 | }; | |
142 | template <> struct _SignedIntegerConcept<short> { void __constraints() {} }; | |
143 | template <> struct _SignedIntegerConcept<int> { void __constraints() {} }; | |
144 | template <> struct _SignedIntegerConcept<long> { void __constraints() {} }; | |
62bb0c97 | 145 | template <> struct _SignedIntegerConcept<long long> { void __constraints(){}}; |
62bb0c97 PE |
146 | |
147 | template <class _Tp> | |
148 | struct _UnsignedIntegerConcept { | |
ed6814f7 | 149 | void __constraints() { |
563ae04f | 150 | __error_type_must_be_an_unsigned_integer_type(); |
62bb0c97 PE |
151 | } |
152 | }; | |
153 | template <> struct _UnsignedIntegerConcept<unsigned short> | |
154 | { void __constraints() {} }; | |
155 | template <> struct _UnsignedIntegerConcept<unsigned int> | |
156 | { void __constraints() {} }; | |
157 | template <> struct _UnsignedIntegerConcept<unsigned long> | |
158 | { void __constraints() {} }; | |
62bb0c97 PE |
159 | template <> struct _UnsignedIntegerConcept<unsigned long long> |
160 | { void __constraints() {} }; | |
30a20a1e PE |
161 | |
162 | //=========================================================================== | |
163 | // Basic Concepts | |
164 | ||
62bb0c97 PE |
165 | template <class _Tp> |
166 | struct _DefaultConstructibleConcept | |
30a20a1e | 167 | { |
62bb0c97 PE |
168 | void __constraints() { |
169 | _Tp __a _IsUnused; // require default constructor | |
30a20a1e PE |
170 | } |
171 | }; | |
172 | ||
62bb0c97 PE |
173 | template <class _Tp> |
174 | struct _AssignableConcept | |
30a20a1e | 175 | { |
62bb0c97 PE |
176 | void __constraints() { |
177 | __a = __a; // require assignment operator | |
178 | __const_constraints(__a); | |
30a20a1e | 179 | } |
62bb0c97 PE |
180 | void __const_constraints(const _Tp& __b) { |
181 | __a = __b; // const required for argument to assignment | |
30a20a1e | 182 | } |
62bb0c97 | 183 | _Tp __a; |
224a45d0 PE |
184 | // possibly should be "Tp* a;" and then dereference "a" in constraint |
185 | // functions? present way would require a default ctor, i think... | |
30a20a1e PE |
186 | }; |
187 | ||
62bb0c97 PE |
188 | template <class _Tp> |
189 | struct _CopyConstructibleConcept | |
30a20a1e | 190 | { |
62bb0c97 PE |
191 | void __constraints() { |
192 | _Tp __a(__b); // require copy constructor | |
193 | _Tp* __ptr _IsUnused = &__a; // require address of operator | |
194 | __const_constraints(__a); | |
30a20a1e | 195 | } |
62bb0c97 | 196 | void __const_constraints(const _Tp& __a) { |
b2342b54 | 197 | _Tp __c _IsUnused(__a); // require const copy constructor |
62bb0c97 | 198 | const _Tp* __ptr _IsUnused = &__a; // require const address of operator |
30a20a1e | 199 | } |
62bb0c97 | 200 | _Tp __b; |
30a20a1e PE |
201 | }; |
202 | ||
203 | // The SGI STL version of Assignable requires copy constructor and operator= | |
62bb0c97 PE |
204 | template <class _Tp> |
205 | struct _SGIAssignableConcept | |
30a20a1e | 206 | { |
62bb0c97 | 207 | void __constraints() { |
b2342b54 | 208 | _Tp __b _IsUnused(__a); |
62bb0c97 PE |
209 | __a = __a; // require assignment operator |
210 | __const_constraints(__a); | |
30a20a1e | 211 | } |
62bb0c97 | 212 | void __const_constraints(const _Tp& __b) { |
b2342b54 | 213 | _Tp __c _IsUnused(__b); |
62bb0c97 | 214 | __a = __b; // const required for argument to assignment |
30a20a1e | 215 | } |
62bb0c97 | 216 | _Tp __a; |
30a20a1e PE |
217 | }; |
218 | ||
62bb0c97 PE |
219 | template <class _From, class _To> |
220 | struct _ConvertibleConcept | |
30a20a1e | 221 | { |
62bb0c97 PE |
222 | void __constraints() { |
223 | _To __y _IsUnused = __x; | |
30a20a1e | 224 | } |
62bb0c97 | 225 | _From __x; |
30a20a1e PE |
226 | }; |
227 | ||
228 | // The C++ standard requirements for many concepts talk about return | |
229 | // types that must be "convertible to bool". The problem with this | |
230 | // requirement is that it leaves the door open for evil proxies that | |
231 | // define things like operator|| with strange return types. Two | |
232 | // possible solutions are: | |
233 | // 1) require the return type to be exactly bool | |
234 | // 2) stay with convertible to bool, and also | |
235 | // specify stuff about all the logical operators. | |
236 | // For now we just test for convertible to bool. | |
62bb0c97 PE |
237 | template <class _Tp> |
238 | void __aux_require_boolean_expr(const _Tp& __t) { | |
239 | bool __x _IsUnused = __t; | |
30a20a1e PE |
240 | } |
241 | ||
62bb0c97 PE |
242 | // FIXME |
243 | template <class _Tp> | |
244 | struct _EqualityComparableConcept | |
30a20a1e | 245 | { |
62bb0c97 PE |
246 | void __constraints() { |
247 | __aux_require_boolean_expr(__a == __b); | |
30a20a1e | 248 | } |
62bb0c97 | 249 | _Tp __a, __b; |
30a20a1e PE |
250 | }; |
251 | ||
62bb0c97 PE |
252 | template <class _Tp> |
253 | struct _LessThanComparableConcept | |
30a20a1e | 254 | { |
62bb0c97 PE |
255 | void __constraints() { |
256 | __aux_require_boolean_expr(__a < __b); | |
30a20a1e | 257 | } |
62bb0c97 | 258 | _Tp __a, __b; |
30a20a1e PE |
259 | }; |
260 | ||
261 | // This is equivalent to SGI STL's LessThanComparable. | |
62bb0c97 PE |
262 | template <class _Tp> |
263 | struct _ComparableConcept | |
30a20a1e | 264 | { |
62bb0c97 PE |
265 | void __constraints() { |
266 | __aux_require_boolean_expr(__a < __b); | |
267 | __aux_require_boolean_expr(__a > __b); | |
268 | __aux_require_boolean_expr(__a <= __b); | |
269 | __aux_require_boolean_expr(__a >= __b); | |
30a20a1e | 270 | } |
62bb0c97 | 271 | _Tp __a, __b; |
30a20a1e PE |
272 | }; |
273 | ||
3d7c150e | 274 | #define _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(_OP,_NAME) \ |
62bb0c97 PE |
275 | template <class _First, class _Second> \ |
276 | struct _NAME { \ | |
277 | void __constraints() { (void)__constraints_(); } \ | |
278 | bool __constraints_() { \ | |
279 | return __a _OP __b; \ | |
30a20a1e | 280 | } \ |
62bb0c97 PE |
281 | _First __a; \ |
282 | _Second __b; \ | |
30a20a1e PE |
283 | } |
284 | ||
3d7c150e | 285 | #define _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(_OP,_NAME) \ |
62bb0c97 PE |
286 | template <class _Ret, class _First, class _Second> \ |
287 | struct _NAME { \ | |
288 | void __constraints() { (void)__constraints_(); } \ | |
289 | _Ret __constraints_() { \ | |
290 | return __a _OP __b; \ | |
30a20a1e | 291 | } \ |
62bb0c97 PE |
292 | _First __a; \ |
293 | _Second __b; \ | |
30a20a1e PE |
294 | } |
295 | ||
3d7c150e BK |
296 | _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(==, _EqualOpConcept); |
297 | _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(!=, _NotEqualOpConcept); | |
298 | _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<, _LessThanOpConcept); | |
299 | _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<=, _LessEqualOpConcept); | |
300 | _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>, _GreaterThanOpConcept); | |
301 | _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>=, _GreaterEqualOpConcept); | |
30a20a1e | 302 | |
3d7c150e BK |
303 | _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(+, _PlusOpConcept); |
304 | _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(*, _TimesOpConcept); | |
305 | _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(/, _DivideOpConcept); | |
306 | _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(-, _SubtractOpConcept); | |
307 | _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(%, _ModOpConcept); | |
30a20a1e | 308 | |
3d7c150e BK |
309 | #undef _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT |
310 | #undef _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT | |
30a20a1e PE |
311 | |
312 | //=========================================================================== | |
313 | // Function Object Concepts | |
314 | ||
62bb0c97 PE |
315 | template <class _Func, class _Return> |
316 | struct _GeneratorConcept | |
30a20a1e | 317 | { |
62bb0c97 PE |
318 | void __constraints() { |
319 | const _Return& __r _IsUnused = __f();// require operator() member function | |
30a20a1e | 320 | } |
62bb0c97 | 321 | _Func __f; |
30a20a1e PE |
322 | }; |
323 | ||
324 | ||
62bb0c97 PE |
325 | template <class _Func> |
326 | struct _GeneratorConcept<_Func,void> | |
30a20a1e | 327 | { |
62bb0c97 PE |
328 | void __constraints() { |
329 | __f(); // require operator() member function | |
30a20a1e | 330 | } |
62bb0c97 | 331 | _Func __f; |
30a20a1e PE |
332 | }; |
333 | ||
62bb0c97 PE |
334 | template <class _Func, class _Return, class _Arg> |
335 | struct _UnaryFunctionConcept | |
30a20a1e | 336 | { |
62bb0c97 PE |
337 | void __constraints() { |
338 | __r = __f(__arg); // require operator() | |
30a20a1e | 339 | } |
62bb0c97 PE |
340 | _Func __f; |
341 | _Arg __arg; | |
342 | _Return __r; | |
30a20a1e PE |
343 | }; |
344 | ||
62bb0c97 PE |
345 | template <class _Func, class _Arg> |
346 | struct _UnaryFunctionConcept<_Func, void, _Arg> { | |
ed6814f7 | 347 | void __constraints() { |
62bb0c97 | 348 | __f(__arg); // require operator() |
30a20a1e | 349 | } |
62bb0c97 PE |
350 | _Func __f; |
351 | _Arg __arg; | |
30a20a1e PE |
352 | }; |
353 | ||
62bb0c97 PE |
354 | template <class _Func, class _Return, class _First, class _Second> |
355 | struct _BinaryFunctionConcept | |
30a20a1e | 356 | { |
ed6814f7 | 357 | void __constraints() { |
62bb0c97 | 358 | __r = __f(__first, __second); // require operator() |
30a20a1e | 359 | } |
62bb0c97 PE |
360 | _Func __f; |
361 | _First __first; | |
362 | _Second __second; | |
363 | _Return __r; | |
30a20a1e PE |
364 | }; |
365 | ||
62bb0c97 PE |
366 | template <class _Func, class _First, class _Second> |
367 | struct _BinaryFunctionConcept<_Func, void, _First, _Second> | |
30a20a1e | 368 | { |
62bb0c97 PE |
369 | void __constraints() { |
370 | __f(__first, __second); // require operator() | |
30a20a1e | 371 | } |
62bb0c97 PE |
372 | _Func __f; |
373 | _First __first; | |
374 | _Second __second; | |
30a20a1e PE |
375 | }; |
376 | ||
62bb0c97 PE |
377 | template <class _Func, class _Arg> |
378 | struct _UnaryPredicateConcept | |
30a20a1e | 379 | { |
62bb0c97 PE |
380 | void __constraints() { |
381 | __aux_require_boolean_expr(__f(__arg)); // require op() returning bool | |
30a20a1e | 382 | } |
62bb0c97 PE |
383 | _Func __f; |
384 | _Arg __arg; | |
30a20a1e PE |
385 | }; |
386 | ||
62bb0c97 PE |
387 | template <class _Func, class _First, class _Second> |
388 | struct _BinaryPredicateConcept | |
30a20a1e | 389 | { |
62bb0c97 PE |
390 | void __constraints() { |
391 | __aux_require_boolean_expr(__f(__a, __b)); // require op() returning bool | |
30a20a1e | 392 | } |
62bb0c97 PE |
393 | _Func __f; |
394 | _First __a; | |
395 | _Second __b; | |
30a20a1e PE |
396 | }; |
397 | ||
398 | // use this when functor is used inside a container class like std::set | |
62bb0c97 PE |
399 | template <class _Func, class _First, class _Second> |
400 | struct _Const_BinaryPredicateConcept { | |
ed6814f7 | 401 | void __constraints() { |
62bb0c97 | 402 | __const_constraints(__f); |
30a20a1e | 403 | } |
62bb0c97 PE |
404 | void __const_constraints(const _Func& __fun) { |
405 | __function_requires<_BinaryPredicateConcept<_Func, _First, _Second> >(); | |
30a20a1e | 406 | // operator() must be a const member function |
62bb0c97 | 407 | __aux_require_boolean_expr(__fun(__a, __b)); |
30a20a1e | 408 | } |
62bb0c97 PE |
409 | _Func __f; |
410 | _First __a; | |
411 | _Second __b; | |
30a20a1e PE |
412 | }; |
413 | ||
414 | //=========================================================================== | |
415 | // Iterator Concepts | |
416 | ||
62bb0c97 PE |
417 | template <class _Tp> |
418 | struct _TrivialIteratorConcept | |
30a20a1e | 419 | { |
62bb0c97 | 420 | void __constraints() { |
dcbbf6f3 | 421 | // __function_requires< _DefaultConstructibleConcept<_Tp> >(); |
62bb0c97 PE |
422 | __function_requires< _AssignableConcept<_Tp> >(); |
423 | __function_requires< _EqualityComparableConcept<_Tp> >(); | |
361bf10c | 424 | // typedef typename std::iterator_traits<_Tp>::value_type _V; |
62bb0c97 | 425 | (void)*__i; // require dereference operator |
30a20a1e | 426 | } |
62bb0c97 | 427 | _Tp __i; |
30a20a1e PE |
428 | }; |
429 | ||
62bb0c97 PE |
430 | template <class _Tp> |
431 | struct _Mutable_TrivialIteratorConcept | |
30a20a1e | 432 | { |
62bb0c97 PE |
433 | void __constraints() { |
434 | __function_requires< _TrivialIteratorConcept<_Tp> >(); | |
435 | *__i = *__j; // require dereference and assignment | |
30a20a1e | 436 | } |
62bb0c97 | 437 | _Tp __i, __j; |
30a20a1e PE |
438 | }; |
439 | ||
62bb0c97 PE |
440 | template <class _Tp> |
441 | struct _InputIteratorConcept | |
30a20a1e | 442 | { |
62bb0c97 PE |
443 | void __constraints() { |
444 | __function_requires< _TrivialIteratorConcept<_Tp> >(); | |
30a20a1e | 445 | // require iterator_traits typedef's |
2b491e3a DG |
446 | typedef typename std::iterator_traits<_Tp>::difference_type _Diff; |
447 | // __function_requires< _SignedIntegerConcept<_Diff> >(); | |
448 | typedef typename std::iterator_traits<_Tp>::reference _Ref; | |
62bb0c97 PE |
449 | typedef typename std::iterator_traits<_Tp>::pointer _Pt; |
450 | typedef typename std::iterator_traits<_Tp>::iterator_category _Cat; | |
451 | __function_requires< _ConvertibleConcept< | |
452 | typename std::iterator_traits<_Tp>::iterator_category, | |
30a20a1e | 453 | std::input_iterator_tag> >(); |
62bb0c97 PE |
454 | ++__i; // require preincrement operator |
455 | __i++; // require postincrement operator | |
30a20a1e | 456 | } |
62bb0c97 | 457 | _Tp __i; |
30a20a1e PE |
458 | }; |
459 | ||
62bb0c97 PE |
460 | template <class _Tp, class _ValueT> |
461 | struct _OutputIteratorConcept | |
30a20a1e | 462 | { |
62bb0c97 PE |
463 | void __constraints() { |
464 | __function_requires< _AssignableConcept<_Tp> >(); | |
465 | ++__i; // require preincrement operator | |
466 | __i++; // require postincrement operator | |
467 | *__i++ = __t; // require postincrement and assignment | |
30a20a1e | 468 | } |
62bb0c97 PE |
469 | _Tp __i; |
470 | _ValueT __t; | |
30a20a1e PE |
471 | }; |
472 | ||
62bb0c97 PE |
473 | template <class _Tp> |
474 | struct _ForwardIteratorConcept | |
30a20a1e | 475 | { |
62bb0c97 PE |
476 | void __constraints() { |
477 | __function_requires< _InputIteratorConcept<_Tp> >(); | |
dcbbf6f3 | 478 | __function_requires< _DefaultConstructibleConcept<_Tp> >(); |
62bb0c97 PE |
479 | __function_requires< _ConvertibleConcept< |
480 | typename std::iterator_traits<_Tp>::iterator_category, | |
30a20a1e | 481 | std::forward_iterator_tag> >(); |
2b491e3a DG |
482 | typedef typename std::iterator_traits<_Tp>::reference _Ref; |
483 | _Ref __r _IsUnused = *__i; | |
30a20a1e | 484 | } |
62bb0c97 | 485 | _Tp __i; |
30a20a1e PE |
486 | }; |
487 | ||
62bb0c97 PE |
488 | template <class _Tp> |
489 | struct _Mutable_ForwardIteratorConcept | |
30a20a1e | 490 | { |
62bb0c97 PE |
491 | void __constraints() { |
492 | __function_requires< _ForwardIteratorConcept<_Tp> >(); | |
493 | *__i++ = *__i; // require postincrement and assignment | |
30a20a1e | 494 | } |
62bb0c97 | 495 | _Tp __i; |
30a20a1e PE |
496 | }; |
497 | ||
62bb0c97 PE |
498 | template <class _Tp> |
499 | struct _BidirectionalIteratorConcept | |
30a20a1e | 500 | { |
62bb0c97 PE |
501 | void __constraints() { |
502 | __function_requires< _ForwardIteratorConcept<_Tp> >(); | |
503 | __function_requires< _ConvertibleConcept< | |
504 | typename std::iterator_traits<_Tp>::iterator_category, | |
30a20a1e | 505 | std::bidirectional_iterator_tag> >(); |
62bb0c97 PE |
506 | --__i; // require predecrement operator |
507 | __i--; // require postdecrement operator | |
30a20a1e | 508 | } |
62bb0c97 | 509 | _Tp __i; |
30a20a1e PE |
510 | }; |
511 | ||
62bb0c97 PE |
512 | template <class _Tp> |
513 | struct _Mutable_BidirectionalIteratorConcept | |
30a20a1e | 514 | { |
62bb0c97 PE |
515 | void __constraints() { |
516 | __function_requires< _BidirectionalIteratorConcept<_Tp> >(); | |
517 | __function_requires< _Mutable_ForwardIteratorConcept<_Tp> >(); | |
518 | *__i-- = *__i; // require postdecrement and assignment | |
30a20a1e | 519 | } |
62bb0c97 | 520 | _Tp __i; |
30a20a1e PE |
521 | }; |
522 | ||
523 | ||
62bb0c97 PE |
524 | template <class _Tp> |
525 | struct _RandomAccessIteratorConcept | |
30a20a1e | 526 | { |
62bb0c97 PE |
527 | void __constraints() { |
528 | __function_requires< _BidirectionalIteratorConcept<_Tp> >(); | |
529 | __function_requires< _ComparableConcept<_Tp> >(); | |
530 | __function_requires< _ConvertibleConcept< | |
531 | typename std::iterator_traits<_Tp>::iterator_category, | |
30a20a1e | 532 | std::random_access_iterator_tag> >(); |
2b491e3a DG |
533 | // ??? We don't use _Ref, are we just checking for "referenceability"? |
534 | typedef typename std::iterator_traits<_Tp>::reference _Ref; | |
30a20a1e | 535 | |
62bb0c97 PE |
536 | __i += __n; // require assignment addition operator |
537 | __i = __i + __n; __i = __n + __i; // require addition with difference type | |
538 | __i -= __n; // require assignment subtraction op | |
539 | __i = __i - __n; // require subtraction with | |
540 | // difference type | |
541 | __n = __i - __j; // require difference operator | |
542 | (void)__i[__n]; // require element access operator | |
30a20a1e | 543 | } |
62bb0c97 PE |
544 | _Tp __a, __b; |
545 | _Tp __i, __j; | |
546 | typename std::iterator_traits<_Tp>::difference_type __n; | |
30a20a1e PE |
547 | }; |
548 | ||
62bb0c97 PE |
549 | template <class _Tp> |
550 | struct _Mutable_RandomAccessIteratorConcept | |
30a20a1e | 551 | { |
62bb0c97 PE |
552 | void __constraints() { |
553 | __function_requires< _RandomAccessIteratorConcept<_Tp> >(); | |
554 | __function_requires< _Mutable_BidirectionalIteratorConcept<_Tp> >(); | |
555 | __i[__n] = *__i; // require element access and assignment | |
30a20a1e | 556 | } |
62bb0c97 PE |
557 | _Tp __i; |
558 | typename std::iterator_traits<_Tp>::difference_type __n; | |
30a20a1e PE |
559 | }; |
560 | ||
561 | //=========================================================================== | |
562 | // Container Concepts | |
563 | ||
62bb0c97 PE |
564 | template <class _Container> |
565 | struct _ContainerConcept | |
566 | { | |
567 | typedef typename _Container::value_type _Value_type; | |
568 | typedef typename _Container::difference_type _Difference_type; | |
569 | typedef typename _Container::size_type _Size_type; | |
570 | typedef typename _Container::const_reference _Const_reference; | |
571 | typedef typename _Container::const_pointer _Const_pointer; | |
572 | typedef typename _Container::const_iterator _Const_iterator; | |
573 | ||
574 | void __constraints() { | |
575 | __function_requires< _InputIteratorConcept<_Const_iterator> >(); | |
576 | __function_requires< _AssignableConcept<_Container> >(); | |
577 | const _Container __c; | |
578 | __i = __c.begin(); | |
579 | __i = __c.end(); | |
580 | __n = __c.size(); | |
581 | __n = __c.max_size(); | |
582 | __b = __c.empty(); | |
583 | } | |
584 | bool __b; | |
585 | _Const_iterator __i; | |
586 | _Size_type __n; | |
587 | }; | |
588 | ||
589 | template <class _Container> | |
590 | struct _Mutable_ContainerConcept | |
591 | { | |
592 | typedef typename _Container::value_type _Value_type; | |
593 | typedef typename _Container::reference _Reference; | |
594 | typedef typename _Container::iterator _Iterator; | |
595 | typedef typename _Container::pointer _Pointer; | |
ed6814f7 | 596 | |
62bb0c97 PE |
597 | void __constraints() { |
598 | __function_requires< _ContainerConcept<_Container> >(); | |
599 | __function_requires< _AssignableConcept<_Value_type> >(); | |
600 | __function_requires< _InputIteratorConcept<_Iterator> >(); | |
30a20a1e | 601 | |
62bb0c97 PE |
602 | __i = __c.begin(); |
603 | __i = __c.end(); | |
604 | __c.swap(__c2); | |
30a20a1e | 605 | } |
f2d43953 | 606 | _Iterator __i; |
62bb0c97 | 607 | _Container __c, __c2; |
30a20a1e PE |
608 | }; |
609 | ||
62bb0c97 PE |
610 | template <class _ForwardContainer> |
611 | struct _ForwardContainerConcept | |
30a20a1e | 612 | { |
62bb0c97 PE |
613 | void __constraints() { |
614 | __function_requires< _ContainerConcept<_ForwardContainer> >(); | |
615 | typedef typename _ForwardContainer::const_iterator _Const_iterator; | |
616 | __function_requires< _ForwardIteratorConcept<_Const_iterator> >(); | |
30a20a1e | 617 | } |
ed6814f7 | 618 | }; |
30a20a1e | 619 | |
62bb0c97 PE |
620 | template <class _ForwardContainer> |
621 | struct _Mutable_ForwardContainerConcept | |
30a20a1e | 622 | { |
62bb0c97 PE |
623 | void __constraints() { |
624 | __function_requires< _ForwardContainerConcept<_ForwardContainer> >(); | |
625 | __function_requires< _Mutable_ContainerConcept<_ForwardContainer> >(); | |
626 | typedef typename _ForwardContainer::iterator _Iterator; | |
627 | __function_requires< _Mutable_ForwardIteratorConcept<_Iterator> >(); | |
30a20a1e | 628 | } |
ed6814f7 | 629 | }; |
30a20a1e | 630 | |
62bb0c97 PE |
631 | template <class _ReversibleContainer> |
632 | struct _ReversibleContainerConcept | |
30a20a1e | 633 | { |
62bb0c97 PE |
634 | typedef typename _ReversibleContainer::const_iterator _Const_iterator; |
635 | typedef typename _ReversibleContainer::const_reverse_iterator | |
636 | _Const_reverse_iterator; | |
30a20a1e | 637 | |
62bb0c97 PE |
638 | void __constraints() { |
639 | __function_requires< _ForwardContainerConcept<_ReversibleContainer> >(); | |
640 | __function_requires< _BidirectionalIteratorConcept<_Const_iterator> >(); | |
641 | __function_requires< | |
642 | _BidirectionalIteratorConcept<_Const_reverse_iterator> >(); | |
30a20a1e | 643 | |
62bb0c97 PE |
644 | const _ReversibleContainer __c; |
645 | _Const_reverse_iterator __i = __c.rbegin(); | |
646 | __i = __c.rend(); | |
30a20a1e PE |
647 | } |
648 | }; | |
649 | ||
62bb0c97 PE |
650 | template <class _ReversibleContainer> |
651 | struct _Mutable_ReversibleContainerConcept | |
30a20a1e | 652 | { |
62bb0c97 PE |
653 | typedef typename _ReversibleContainer::iterator _Iterator; |
654 | typedef typename _ReversibleContainer::reverse_iterator _Reverse_iterator; | |
30a20a1e | 655 | |
62bb0c97 PE |
656 | void __constraints() { |
657 | __function_requires<_ReversibleContainerConcept<_ReversibleContainer> >(); | |
658 | __function_requires< | |
659 | _Mutable_ForwardContainerConcept<_ReversibleContainer> >(); | |
660 | __function_requires<_Mutable_BidirectionalIteratorConcept<_Iterator> >(); | |
661 | __function_requires< | |
662 | _Mutable_BidirectionalIteratorConcept<_Reverse_iterator> >(); | |
30a20a1e | 663 | |
62bb0c97 PE |
664 | _Reverse_iterator __i = __c.rbegin(); |
665 | __i = __c.rend(); | |
30a20a1e | 666 | } |
62bb0c97 | 667 | _ReversibleContainer __c; |
30a20a1e PE |
668 | }; |
669 | ||
62bb0c97 PE |
670 | template <class _RandomAccessContainer> |
671 | struct _RandomAccessContainerConcept | |
30a20a1e | 672 | { |
62bb0c97 PE |
673 | typedef typename _RandomAccessContainer::size_type _Size_type; |
674 | typedef typename _RandomAccessContainer::const_reference _Const_reference; | |
675 | typedef typename _RandomAccessContainer::const_iterator _Const_iterator; | |
676 | typedef typename _RandomAccessContainer::const_reverse_iterator | |
677 | _Const_reverse_iterator; | |
30a20a1e | 678 | |
62bb0c97 PE |
679 | void __constraints() { |
680 | __function_requires< | |
681 | _ReversibleContainerConcept<_RandomAccessContainer> >(); | |
682 | __function_requires< _RandomAccessIteratorConcept<_Const_iterator> >(); | |
683 | __function_requires< | |
684 | _RandomAccessIteratorConcept<_Const_reverse_iterator> >(); | |
30a20a1e | 685 | |
62bb0c97 PE |
686 | const _RandomAccessContainer __c; |
687 | _Const_reference __r _IsUnused = __c[__n]; | |
30a20a1e | 688 | } |
62bb0c97 | 689 | _Size_type __n; |
30a20a1e PE |
690 | }; |
691 | ||
62bb0c97 PE |
692 | template <class _RandomAccessContainer> |
693 | struct _Mutable_RandomAccessContainerConcept | |
30a20a1e | 694 | { |
62bb0c97 PE |
695 | typedef typename _RandomAccessContainer::size_type _Size_type; |
696 | typedef typename _RandomAccessContainer::reference _Reference; | |
697 | typedef typename _RandomAccessContainer::iterator _Iterator; | |
698 | typedef typename _RandomAccessContainer::reverse_iterator _Reverse_iterator; | |
30a20a1e | 699 | |
62bb0c97 PE |
700 | void __constraints() { |
701 | __function_requires< | |
702 | _RandomAccessContainerConcept<_RandomAccessContainer> >(); | |
703 | __function_requires< | |
704 | _Mutable_ReversibleContainerConcept<_RandomAccessContainer> >(); | |
705 | __function_requires< _Mutable_RandomAccessIteratorConcept<_Iterator> >(); | |
706 | __function_requires< | |
707 | _Mutable_RandomAccessIteratorConcept<_Reverse_iterator> >(); | |
30a20a1e | 708 | |
62bb0c97 | 709 | _Reference __r _IsUnused = __c[__i]; |
30a20a1e | 710 | } |
62bb0c97 PE |
711 | _Size_type __i; |
712 | _RandomAccessContainer __c; | |
30a20a1e PE |
713 | }; |
714 | ||
715 | // A Sequence is inherently mutable | |
62bb0c97 PE |
716 | template <class _Sequence> |
717 | struct _SequenceConcept | |
30a20a1e | 718 | { |
62bb0c97 PE |
719 | typedef typename _Sequence::reference _Reference; |
720 | typedef typename _Sequence::const_reference _Const_reference; | |
30a20a1e | 721 | |
62bb0c97 | 722 | void __constraints() { |
30a20a1e PE |
723 | // Matt Austern's book puts DefaultConstructible here, the C++ |
724 | // standard places it in Container | |
725 | // function_requires< DefaultConstructible<Sequence> >(); | |
62bb0c97 PE |
726 | __function_requires< _Mutable_ForwardContainerConcept<_Sequence> >(); |
727 | __function_requires< _DefaultConstructibleConcept<_Sequence> >(); | |
30a20a1e | 728 | |
ed6814f7 | 729 | _Sequence |
e5a067e8 PC |
730 | __c _IsUnused(__n, __t), |
731 | __c2 _IsUnused(__first, __last); | |
30a20a1e | 732 | |
62bb0c97 PE |
733 | __c.insert(__p, __t); |
734 | __c.insert(__p, __n, __t); | |
735 | __c.insert(__p, __first, __last); | |
30a20a1e | 736 | |
62bb0c97 PE |
737 | __c.erase(__p); |
738 | __c.erase(__p, __q); | |
30a20a1e | 739 | |
62bb0c97 | 740 | _Reference __r _IsUnused = __c.front(); |
30a20a1e | 741 | |
62bb0c97 | 742 | __const_constraints(__c); |
30a20a1e | 743 | } |
62bb0c97 PE |
744 | void __const_constraints(const _Sequence& __c) { |
745 | _Const_reference __r _IsUnused = __c.front(); | |
30a20a1e | 746 | } |
62bb0c97 PE |
747 | typename _Sequence::value_type __t; |
748 | typename _Sequence::size_type __n; | |
749 | typename _Sequence::value_type *__first, *__last; | |
750 | typename _Sequence::iterator __p, __q; | |
30a20a1e PE |
751 | }; |
752 | ||
62bb0c97 PE |
753 | template <class _FrontInsertionSequence> |
754 | struct _FrontInsertionSequenceConcept | |
30a20a1e | 755 | { |
62bb0c97 PE |
756 | void __constraints() { |
757 | __function_requires< _SequenceConcept<_FrontInsertionSequence> >(); | |
30a20a1e | 758 | |
62bb0c97 PE |
759 | __c.push_front(__t); |
760 | __c.pop_front(); | |
30a20a1e | 761 | } |
62bb0c97 PE |
762 | _FrontInsertionSequence __c; |
763 | typename _FrontInsertionSequence::value_type __t; | |
30a20a1e PE |
764 | }; |
765 | ||
62bb0c97 PE |
766 | template <class _BackInsertionSequence> |
767 | struct _BackInsertionSequenceConcept | |
30a20a1e | 768 | { |
62bb0c97 PE |
769 | typedef typename _BackInsertionSequence::reference _Reference; |
770 | typedef typename _BackInsertionSequence::const_reference _Const_reference; | |
30a20a1e | 771 | |
62bb0c97 PE |
772 | void __constraints() { |
773 | __function_requires< _SequenceConcept<_BackInsertionSequence> >(); | |
30a20a1e | 774 | |
62bb0c97 PE |
775 | __c.push_back(__t); |
776 | __c.pop_back(); | |
777 | _Reference __r _IsUnused = __c.back(); | |
30a20a1e | 778 | } |
62bb0c97 PE |
779 | void __const_constraints(const _BackInsertionSequence& __c) { |
780 | _Const_reference __r _IsUnused = __c.back(); | |
30a20a1e | 781 | }; |
62bb0c97 PE |
782 | _BackInsertionSequence __c; |
783 | typename _BackInsertionSequence::value_type __t; | |
30a20a1e PE |
784 | }; |
785 | ||
12ffa228 BK |
786 | _GLIBCXX_END_NAMESPACE_VERSION |
787 | } // namespace | |
62bb0c97 | 788 | |
9ed83a33 | 789 | #pragma GCC diagnostic pop |
62bb0c97 PE |
790 | #undef _IsUnused |
791 | ||
3d7c150e | 792 | #endif // _GLIBCXX_BOOST_CONCEPT_CHECK |
30a20a1e | 793 | |
30a20a1e | 794 |