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