libstdc++

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