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