Import pre-release gcc-5.0 to new vendor branch
[dragonfly.git] / contrib / gcc-5.0 / libstdc++-v3 / include / bits / boost_concept_check.h
1 // -*- C++ -*-
2
3 // Copyright (C) 2004-2015 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