OSDN Git Service

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