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