OSDN Git Service

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