OSDN Git Service

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