# boost_concept_check.h

Go to the documentation of this file.

    00001 //
    00002 // (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify,
    00003 // sell and distribute this software is granted provided this
    00004 // copyright notice appears in all copies. This software is provided
    00005 // "as is" without express or implied warranty, and with no claim as
    00006 // to its suitability for any purpose.
    00007 //
    00008
    00009 // GCC Note:  based on version 1.12.0 of the Boost library.
    00010
    00016 #ifndef _GLIBCPP_BOOST_CONCEPT_CHECK
    00017 #define _GLIBCPP_BOOST_CONCEPT_CHECK 1
    00018
    00019 #pragma GCC system_header
    00020 #include <cstddef>                // for ptrdiff_t, used next
    00021 #include <bits/stl_iterator_base_types.h>    // for traits and tags
    00022 #include <utility>                           // for pair<>
    00023
    00024
    00025 namespace __gnu_cxx
    00026 {
    00027
    00028 #define _IsUnused __attribute__ ((__unused__))
    00029
    00030 // When the C-C code is in use, we would like this function to do as little
    00031 // as possible at runtime, use as few resources as possible, and hopefully
    00032 // be elided out of existence... hmmm.
    00033 template <class _Concept>
    00034 inline void __function_requires()
    00035 {
    00036   void (_Concept::*__x)() _IsUnused = &_Concept::__constraints;
    00037 }
    00038
    00039
    00040 // ??? Should the "concept_checking*" structs begin with more than _ ?
    00041 #define _GLIBCPP_CLASS_REQUIRES(_type_var, _ns, _concept) \
    00042   typedef void (_ns::_concept <_type_var>::* _func##_type_var##_concept)(); \
    00043   template <_func##_type_var##_concept _Tp1> \
    00044   struct _concept_checking##_type_var##_concept { }; \
    00045   typedef _concept_checking##_type_var##_concept< \
    00046     &_ns::_concept <_type_var>::__constraints> \
    00047     _concept_checking_typedef##_type_var##_concept
    00048
    00049 #define _GLIBCPP_CLASS_REQUIRES2(_type_var1, _type_var2, _ns, _concept) \
    00050   typedef void (_ns::_concept <_type_var1,_type_var2>::* _func##_type_var1##_type_var2##_concept)(); \
    00051   template <_func##_type_var1##_type_var2##_concept _Tp1> \
    00052   struct _concept_checking##_type_var1##_type_var2##_concept { }; \
    00053   typedef _concept_checking##_type_var1##_type_var2##_concept< \
    00054     &_ns::_concept <_type_var1,_type_var2>::__constraints> \
    00055     _concept_checking_typedef##_type_var1##_type_var2##_concept
    00056
    00057 #define _GLIBCPP_CLASS_REQUIRES3(_type_var1, _type_var2, _type_var3, _ns, _concept) \
    00058   typedef void (_ns::_concept <_type_var1,_type_var2,_type_var3>::* _func##_type_var1##_type_var2##_type_var3##_concept)(); \
    00059   template <_func##_type_var1##_type_var2##_type_var3##_concept _Tp1> \
    00060   struct _concept_checking##_type_var1##_type_var2##_type_var3##_concept { }; \
    00061   typedef _concept_checking##_type_var1##_type_var2##_type_var3##_concept< \
    00062     &_ns::_concept <_type_var1,_type_var2,_type_var3>::__constraints>  \
    00063   _concept_checking_typedef##_type_var1##_type_var2##_type_var3##_concept
    00064
    00065 #define _GLIBCPP_CLASS_REQUIRES4(_type_var1, _type_var2, _type_var3, _type_var4, _ns, _concept) \
    00066   typedef void (_ns::_concept <_type_var1,_type_var2,_type_var3,_type_var4>::* _func##_type_var1##_type_var2##_type_var3##_type_var4##_concept)(); \
    00067   template <_func##_type_var1##_type_var2##_type_var3##_type_var4##_concept _Tp1> \
    00068   struct _concept_checking##_type_var1##_type_var2##_type_var3##_type_var4##_concept { }; \
    00069   typedef _concept_checking##_type_var1##_type_var2##_type_var3##_type_var4##_concept< \
    00070   &_ns::_concept <_type_var1,_type_var2,_type_var3,_type_var4>::__constraints> \
    00071     _concept_checking_typedef##_type_var1##_type_var2##_type_var3##_type_var4##_concept
    00072
    00073
    00074 template <class _Tp1, class _Tp2>
    00075 struct _Aux_require_same { };
    00076
    00077 template <class _Tp>
    00078 struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; };
    00079
    00080   template <class _Tp1, class _Tp2>
    00081   struct _SameTypeConcept
    00082   {
    00083     void __constraints() {
    00084       typedef typename _Aux_require_same<_Tp1, _Tp2>::_Type _Required;
    00085     }
    00086   };
    00087
    00088   template <class _Tp>
    00089   struct _IntegerConcept {
    00090     void __constraints() {
    00091       __error_type_must_be_an_integer_type();
    00092     }
    00093   };
    00094   template <> struct _IntegerConcept<short> { void __constraints() {} };
    00095   template <> struct _IntegerConcept<unsigned short> { void __constraints(){} };
    00096   template <> struct _IntegerConcept<int> { void __constraints() {} };
    00097   template <> struct _IntegerConcept<unsigned int> { void __constraints() {} };
    00098   template <> struct _IntegerConcept<long> { void __constraints() {} };
    00099   template <> struct _IntegerConcept<unsigned long> { void __constraints() {} };
    00100   template <> struct _IntegerConcept<long long> { void __constraints() {} };
    00101   template <> struct _IntegerConcept<unsigned long long>
    00102                                                 { void __constraints() {} };
    00103
    00104   template <class _Tp>
    00105   struct _SignedIntegerConcept {
    00106     void __constraints() {
    00107       __error_type_must_be_a_signed_integer_type();
    00108     }
    00109   };
    00110   template <> struct _SignedIntegerConcept<short> { void __constraints() {} };
    00111   template <> struct _SignedIntegerConcept<int> { void __constraints() {} };
    00112   template <> struct _SignedIntegerConcept<long> { void __constraints() {} };
    00113   template <> struct _SignedIntegerConcept<long long> { void __constraints(){}};
    00114
    00115   template <class _Tp>
    00116   struct _UnsignedIntegerConcept {
    00117     void __constraints() {
    00118       __error_type_must_be_an_unsigned_integer_type();
    00119     }
    00120   };
    00121   template <> struct _UnsignedIntegerConcept<unsigned short>
    00122     { void __constraints() {} };
    00123   template <> struct _UnsignedIntegerConcept<unsigned int>
    00124     { void __constraints() {} };
    00125   template <> struct _UnsignedIntegerConcept<unsigned long>
    00126     { void __constraints() {} };
    00127   template <> struct _UnsignedIntegerConcept<unsigned long long>
    00128     { void __constraints() {} };
    00129
    00130   //===========================================================================
    00131   // Basic Concepts
    00132
    00133   template <class _Tp>
    00134   struct _DefaultConstructibleConcept
    00135   {
    00136     void __constraints() {
    00137       _Tp __a _IsUnused;                // require default constructor
    00138     }
    00139   };
    00140
    00141   template <class _Tp>
    00142   struct _AssignableConcept
    00143   {
    00144     void __constraints() {
    00145       __a = __a;                        // require assignment operator
    00146       __const_constraints(__a);
    00147     }
    00148     void __const_constraints(const _Tp& __b) {
    00149       __a = __b;                   // const required for argument to assignment
    00150     }
    00151     _Tp __a;
    00152   };
    00153
    00154   template <class _Tp>
    00155   struct _CopyConstructibleConcept
    00156   {
    00157     void __constraints() {
    00158       _Tp __a(__b);                     // require copy constructor
    00159       _Tp* __ptr _IsUnused = &__a;      // require address of operator
    00160       __const_constraints(__a);
    00161     }
    00162     void __const_constraints(const _Tp& __a) {
    00163       _Tp __c(__a) _IsUnused;           // require const copy constructor
    00164       const _Tp* __ptr _IsUnused = &__a; // require const address of operator
    00165     }
    00166     _Tp __b;
    00167   };
    00168
    00169   // The SGI STL version of Assignable requires copy constructor and operator=
    00170   template <class _Tp>
    00171   struct _SGIAssignableConcept
    00172   {
    00173     void __constraints() {
    00174       _Tp __b(__a) _IsUnused;
    00175       __a = __a;                        // require assignment operator
    00176       __const_constraints(__a);
    00177     }
    00178     void __const_constraints(const _Tp& __b) {
    00179       _Tp __c(__b) _IsUnused;
    00180       __a = __b;              // const required for argument to assignment
    00181     }
    00182     _Tp __a;
    00183   };
    00184
    00185   template <class _From, class _To>
    00186   struct _ConvertibleConcept
    00187   {
    00188     void __constraints() {
    00189       _To __y _IsUnused = __x;
    00190     }
    00191     _From __x;
    00192   };
    00193
    00194   // The C++ standard requirements for many concepts talk about return
    00195   // types that must be "convertible to bool".  The problem with this
    00196   // requirement is that it leaves the door open for evil proxies that
    00197   // define things like operator|| with strange return types.  Two
    00198   // possible solutions are:
    00199   // 1) require the return type to be exactly bool
    00200   // 2) stay with convertible to bool, and also
    00201   //    specify stuff about all the logical operators.
    00202   // For now we just test for convertible to bool.
    00203   template <class _Tp>
    00204   void __aux_require_boolean_expr(const _Tp& __t) {
    00205     bool __x _IsUnused = __t;
    00206   }
    00207
    00208 // FIXME
    00209   template <class _Tp>
    00210   struct _EqualityComparableConcept
    00211   {
    00212     void __constraints() {
    00213       __aux_require_boolean_expr(__a == __b);
    00214       __aux_require_boolean_expr(__a != __b);
    00215     }
    00216     _Tp __a, __b;
    00217   };
    00218
    00219   template <class _Tp>
    00220   struct _LessThanComparableConcept
    00221   {
    00222     void __constraints() {
    00223       __aux_require_boolean_expr(__a < __b);
    00224     }
    00225     _Tp __a, __b;
    00226   };
    00227
    00228   // This is equivalent to SGI STL's LessThanComparable.
    00229   template <class _Tp>
    00230   struct _ComparableConcept
    00231   {
    00232     void __constraints() {
    00233       __aux_require_boolean_expr(__a < __b);
    00234       __aux_require_boolean_expr(__a > __b);
    00235       __aux_require_boolean_expr(__a <= __b);
    00236       __aux_require_boolean_expr(__a >= __b);
    00237     }
    00238     _Tp __a, __b;
    00239   };
    00240
    00241 #define _GLIBCPP_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(_OP,_NAME) \
    00242   template <class _First, class _Second> \
    00243   struct _NAME { \
    00244     void __constraints() { (void)__constraints_(); } \
    00245     bool __constraints_() {  \
    00246       return  __a _OP __b; \
    00247     } \
    00248     _First __a; \
    00249     _Second __b; \
    00250   }
    00251
    00252 #define _GLIBCPP_DEFINE_BINARY_OPERATOR_CONSTRAINT(_OP,_NAME) \
    00253   template <class _Ret, class _First, class _Second> \
    00254   struct _NAME { \
    00255     void __constraints() { (void)__constraints_(); } \
    00256     _Ret __constraints_() {  \
    00257       return __a _OP __b; \
    00258     } \
    00259     _First __a; \
    00260     _Second __b; \
    00261   }
    00262
    00263   _GLIBCPP_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(==, _EqualOpConcept);
    00264   _GLIBCPP_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(!=, _NotEqualOpConcept);
    00265   _GLIBCPP_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<, _LessThanOpConcept);
    00266   _GLIBCPP_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<=, _LessEqualOpConcept);
    00267   _GLIBCPP_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>, _GreaterThanOpConcept);
    00268   _GLIBCPP_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>=, _GreaterEqualOpConcept);
    00269
    00270   _GLIBCPP_DEFINE_BINARY_OPERATOR_CONSTRAINT(+, _PlusOpConcept);
    00271   _GLIBCPP_DEFINE_BINARY_OPERATOR_CONSTRAINT(*, _TimesOpConcept);
    00272   _GLIBCPP_DEFINE_BINARY_OPERATOR_CONSTRAINT(/, _DivideOpConcept);
    00273   _GLIBCPP_DEFINE_BINARY_OPERATOR_CONSTRAINT(-, _SubtractOpConcept);
    00274   _GLIBCPP_DEFINE_BINARY_OPERATOR_CONSTRAINT(%, _ModOpConcept);
    00275
    00276 #undef _GLIBCPP_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT
    00277 #undef _GLIBCPP_DEFINE_BINARY_OPERATOR_CONSTRAINT
    00278
    00279   //===========================================================================
    00280   // Function Object Concepts
    00281
    00282   template <class _Func, class _Return>
    00283   struct _GeneratorConcept
    00284   {
    00285     void __constraints() {
    00286       const _Return& __r _IsUnused = __f();// require operator() member function
    00287     }
    00288     _Func __f;
    00289   };
    00290
    00291
    00292   template <class _Func>
    00293   struct _GeneratorConcept<_Func,void>
    00294   {
    00295     void __constraints() {
    00296       __f();                            // require operator() member function
    00297     }
    00298     _Func __f;
    00299   };
    00300
    00301   template <class _Func, class _Return, class _Arg>
    00302   struct _UnaryFunctionConcept
    00303   {
    00304     void __constraints() {
    00305       __r = __f(__arg);                  // require operator()
    00306     }
    00307     _Func __f;
    00308     _Arg __arg;
    00309     _Return __r;
    00310   };
    00311
    00312   template <class _Func, class _Arg>
    00313   struct _UnaryFunctionConcept<_Func, void, _Arg> {
    00314     void __constraints() {
    00315       __f(__arg);                       // require operator()
    00316     }
    00317     _Func __f;
    00318     _Arg __arg;
    00319   };
    00320
    00321   template <class _Func, class _Return, class _First, class _Second>
    00322   struct _BinaryFunctionConcept
    00323   {
    00324     void __constraints() {
    00325       __r = __f(__first, __second);     // require operator()
    00326     }
    00327     _Func __f;
    00328     _First __first;
    00329     _Second __second;
    00330     _Return __r;
    00331   };
    00332
    00333   template <class _Func, class _First, class _Second>
    00334   struct _BinaryFunctionConcept<_Func, void, _First, _Second>
    00335   {
    00336     void __constraints() {
    00337       __f(__first, __second);           // require operator()
    00338     }
    00339     _Func __f;
    00340     _First __first;
    00341     _Second __second;
    00342   };
    00343
    00344   template <class _Func, class _Arg>
    00345   struct _UnaryPredicateConcept
    00346   {
    00347     void __constraints() {
    00348       __aux_require_boolean_expr(__f(__arg)); // require op() returning bool
    00349     }
    00350     _Func __f;
    00351     _Arg __arg;
    00352   };
    00353
    00354   template <class _Func, class _First, class _Second>
    00355   struct _BinaryPredicateConcept
    00356   {
    00357     void __constraints() {
    00358       __aux_require_boolean_expr(__f(__a, __b)); // require op() returning bool
    00359     }
    00360     _Func __f;
    00361     _First __a;
    00362     _Second __b;
    00363   };
    00364
    00365   // use this when functor is used inside a container class like std::set
    00366   template <class _Func, class _First, class _Second>
    00367   struct _Const_BinaryPredicateConcept {
    00368     void __constraints() {
    00369       __const_constraints(__f);
    00370     }
    00371     void __const_constraints(const _Func& __fun) {
    00372       __function_requires<_BinaryPredicateConcept<_Func, _First, _Second> >();
    00373       // operator() must be a const member function
    00374       __aux_require_boolean_expr(__fun(__a, __b));
    00375     }
    00376     _Func __f;
    00377     _First __a;
    00378     _Second __b;
    00379   };
    00380
    00381   //===========================================================================
    00382   // Iterator Concepts
    00383
    00384   template <class _Tp>
    00385   struct _TrivialIteratorConcept
    00386   {
    00387     void __constraints() {
    00388       __function_requires< _DefaultConstructibleConcept<_Tp> >();
    00389       __function_requires< _AssignableConcept<_Tp> >();
    00390       __function_requires< _EqualityComparableConcept<_Tp> >();
    00391 //      typedef typename std::iterator_traits<_Tp>::value_type _V;
    00392       (void)*__i;                       // require dereference operator
    00393     }
    00394     _Tp __i;
    00395   };
    00396
    00397   template <class _Tp>
    00398   struct _Mutable_TrivialIteratorConcept
    00399   {
    00400     void __constraints() {
    00401       __function_requires< _TrivialIteratorConcept<_Tp> >();
    00402       *__i = *__j;                      // require dereference and assignment
    00403     }
    00404     _Tp __i, __j;
    00405   };
    00406
    00407   template <class _Tp>
    00408   struct _InputIteratorConcept
    00409   {
    00410     void __constraints() {
    00411       __function_requires< _TrivialIteratorConcept<_Tp> >();
    00412       // require iterator_traits typedef's
    00413       typedef typename std::iterator_traits<_Tp>::difference_type _D;
    00414 //      __function_requires< _SignedIntegerConcept<_D> >();
    00415       typedef typename std::iterator_traits<_Tp>::reference _R;
    00416       typedef typename std::iterator_traits<_Tp>::pointer _Pt;
    00417       typedef typename std::iterator_traits<_Tp>::iterator_category _Cat;
    00418       __function_requires< _ConvertibleConcept<
    00419         typename std::iterator_traits<_Tp>::iterator_category,
    00420         std::input_iterator_tag> >();
    00421       ++__i;                            // require preincrement operator
    00422       __i++;                            // require postincrement operator
    00423     }
    00424     _Tp __i;
    00425   };
    00426
    00427   template <class _Tp, class _ValueT>
    00428   struct _OutputIteratorConcept
    00429   {
    00430     void __constraints() {
    00431       __function_requires< _AssignableConcept<_Tp> >();
    00432       ++__i;                            // require preincrement operator
    00433       __i++;                            // require postincrement operator
    00434       *__i++ = __t;                     // require postincrement and assignment
    00435     }
    00436     _Tp __i;
    00437     _ValueT __t;
    00438   };
    00439
    00440   template <class _Tp>
    00441   struct _ForwardIteratorConcept
    00442   {
    00443     void __constraints() {
    00444       __function_requires< _InputIteratorConcept<_Tp> >();
    00445       __function_requires< _ConvertibleConcept<
    00446         typename std::iterator_traits<_Tp>::iterator_category,
    00447         std::forward_iterator_tag> >();
    00448       typedef typename std::iterator_traits<_Tp>::reference _R;
    00449       _R __r _IsUnused = *__i;
    00450     }
    00451     _Tp __i;
    00452   };
    00453
    00454   template <class _Tp>
    00455   struct _Mutable_ForwardIteratorConcept
    00456   {
    00457     void __constraints() {
    00458       __function_requires< _ForwardIteratorConcept<_Tp> >();
    00459       *__i++ = *__i;                    // require postincrement and assignment
    00460     }
    00461     _Tp __i;
    00462   };
    00463
    00464   template <class _Tp>
    00465   struct _BidirectionalIteratorConcept
    00466   {
    00467     void __constraints() {
    00468       __function_requires< _ForwardIteratorConcept<_Tp> >();
    00469       __function_requires< _ConvertibleConcept<
    00470         typename std::iterator_traits<_Tp>::iterator_category,
    00471         std::bidirectional_iterator_tag> >();
    00472       --__i;                            // require predecrement operator
    00473       __i--;                            // require postdecrement operator
    00474     }
    00475     _Tp __i;
    00476   };
    00477
    00478   template <class _Tp>
    00479   struct _Mutable_BidirectionalIteratorConcept
    00480   {
    00481     void __constraints() {
    00482       __function_requires< _BidirectionalIteratorConcept<_Tp> >();
    00483       __function_requires< _Mutable_ForwardIteratorConcept<_Tp> >();
    00484       *__i-- = *__i;                    // require postdecrement and assignment
    00485     }
    00486     _Tp __i;
    00487   };
    00488
    00489
    00490   template <class _Tp>
    00491   struct _RandomAccessIteratorConcept
    00492   {
    00493     void __constraints() {
    00494       __function_requires< _BidirectionalIteratorConcept<_Tp> >();
    00495       __function_requires< _ComparableConcept<_Tp> >();
    00496       __function_requires< _ConvertibleConcept<
    00497         typename std::iterator_traits<_Tp>::iterator_category,
    00498         std::random_access_iterator_tag> >();
    00499       // ??? We don't use _R, are we just checking for "referenceability"?
    00500       typedef typename std::iterator_traits<_Tp>::reference _R;
    00501
    00502       __i += __n;                       // require assignment addition operator
    00503       __i = __i + __n; __i = __n + __i; // require addition with difference type
    00504       __i -= __n;                       // require assignment subtraction op
    00505       __i = __i - __n;                  // require subtraction with
    00506                                         //            difference type
    00507       __n = __i - __j;                  // require difference operator
    00508       (void)__i[__n];                   // require element access operator
    00509     }
    00510     _Tp __a, __b;
    00511     _Tp __i, __j;
    00512     typename std::iterator_traits<_Tp>::difference_type __n;
    00513   };
    00514
    00515   template <class _Tp>
    00516   struct _Mutable_RandomAccessIteratorConcept
    00517   {
    00518     void __constraints() {
    00519       __function_requires< _RandomAccessIteratorConcept<_Tp> >();
    00520       __function_requires< _Mutable_BidirectionalIteratorConcept<_Tp> >();
    00521       __i[__n] = *__i;                  // require element access and assignment
    00522     }
    00523     _Tp __i;
    00524     typename std::iterator_traits<_Tp>::difference_type __n;
    00525   };
    00526
    00527   //===========================================================================
    00528   // Container Concepts
    00529
    00530   template <class _Container>
    00531   struct _ContainerConcept
    00532   {
    00533     typedef typename _Container::value_type _Value_type;
    00534     typedef typename _Container::difference_type _Difference_type;
    00535     typedef typename _Container::size_type _Size_type;
    00536     typedef typename _Container::const_reference _Const_reference;
    00537     typedef typename _Container::const_pointer _Const_pointer;
    00538     typedef typename _Container::const_iterator _Const_iterator;
    00539
    00540     void __constraints() {
    00541       __function_requires< _InputIteratorConcept<_Const_iterator> >();
    00542       __function_requires< _AssignableConcept<_Container> >();
    00543       const _Container __c;
    00544       __i = __c.begin();
    00545       __i = __c.end();
    00546       __n = __c.size();
    00547       __n = __c.max_size();
    00548       __b = __c.empty();
    00549     }
    00550     bool __b;
    00551     _Const_iterator __i;
    00552     _Size_type __n;
    00553   };
    00554
    00555   template <class _Container>
    00556   struct _Mutable_ContainerConcept
    00557   {
    00558     typedef typename _Container::value_type _Value_type;
    00559     typedef typename _Container::reference _Reference;
    00560     typedef typename _Container::iterator _Iterator;
    00561     typedef typename _Container::pointer _Pointer;
    00562
    00563     void __constraints() {
    00564       __function_requires< _ContainerConcept<_Container> >();
    00565       __function_requires< _AssignableConcept<_Value_type> >();
    00566       __function_requires< _InputIteratorConcept<_Iterator> >();
    00567
    00568       __i = __c.begin();
    00569       __i = __c.end();
    00570       __c.swap(__c2);
    00571     }
    00572     _Iterator __i;
    00573     _Container __c, __c2;
    00574   };
    00575
    00576   template <class _ForwardContainer>
    00577   struct _ForwardContainerConcept
    00578   {
    00579     void __constraints() {
    00580       __function_requires< _ContainerConcept<_ForwardContainer> >();
    00581       typedef typename _ForwardContainer::const_iterator _Const_iterator;
    00582       __function_requires< _ForwardIteratorConcept<_Const_iterator> >();
    00583     }
    00584   };
    00585
    00586   template <class _ForwardContainer>
    00587   struct _Mutable_ForwardContainerConcept
    00588   {
    00589     void __constraints() {
    00590       __function_requires< _ForwardContainerConcept<_ForwardContainer> >();
    00591       __function_requires< _Mutable_ContainerConcept<_ForwardContainer> >();
    00592       typedef typename _ForwardContainer::iterator _Iterator;
    00593       __function_requires< _Mutable_ForwardIteratorConcept<_Iterator> >();
    00594     }
    00595   };
    00596
    00597   template <class _ReversibleContainer>
    00598   struct _ReversibleContainerConcept
    00599   {
    00600     typedef typename _ReversibleContainer::const_iterator _Const_iterator;
    00601     typedef typename _ReversibleContainer::const_reverse_iterator
    00602       _Const_reverse_iterator;
    00603
    00604     void __constraints() {
    00605       __function_requires< _ForwardContainerConcept<_ReversibleContainer> >();
    00606       __function_requires< _BidirectionalIteratorConcept<_Const_iterator> >();
    00607       __function_requires<
    00608         _BidirectionalIteratorConcept<_Const_reverse_iterator> >();
    00609
    00610       const _ReversibleContainer __c;
    00611       _Const_reverse_iterator __i = __c.rbegin();
    00612       __i = __c.rend();
    00613     }
    00614   };
    00615
    00616   template <class _ReversibleContainer>
    00617   struct _Mutable_ReversibleContainerConcept
    00618   {
    00619     typedef typename _ReversibleContainer::iterator _Iterator;
    00620     typedef typename _ReversibleContainer::reverse_iterator _Reverse_iterator;
    00621
    00622     void __constraints() {
    00623       __function_requires<_ReversibleContainerConcept<_ReversibleContainer> >();
    00624       __function_requires<
    00625         _Mutable_ForwardContainerConcept<_ReversibleContainer> >();
    00626       __function_requires<_Mutable_BidirectionalIteratorConcept<_Iterator> >();
    00627       __function_requires<
    00628         _Mutable_BidirectionalIteratorConcept<_Reverse_iterator> >();
    00629
    00630       _Reverse_iterator __i = __c.rbegin();
    00631       __i = __c.rend();
    00632     }
    00633     _ReversibleContainer __c;
    00634   };
    00635
    00636   template <class _RandomAccessContainer>
    00637   struct _RandomAccessContainerConcept
    00638   {
    00639     typedef typename _RandomAccessContainer::size_type _Size_type;
    00640     typedef typename _RandomAccessContainer::const_reference _Const_reference;
    00641     typedef typename _RandomAccessContainer::const_iterator _Const_iterator;
    00642     typedef typename _RandomAccessContainer::const_reverse_iterator
    00643       _Const_reverse_iterator;
    00644
    00645     void __constraints() {
    00646       __function_requires<
    00647         _ReversibleContainerConcept<_RandomAccessContainer> >();
    00648       __function_requires< _RandomAccessIteratorConcept<_Const_iterator> >();
    00649       __function_requires<
    00650         _RandomAccessIteratorConcept<_Const_reverse_iterator> >();
    00651
    00652       const _RandomAccessContainer __c;
    00653       _Const_reference __r _IsUnused = __c[__n];
    00654     }
    00655     _Size_type __n;
    00656   };
    00657
    00658   template <class _RandomAccessContainer>
    00659   struct _Mutable_RandomAccessContainerConcept
    00660   {
    00661     typedef typename _RandomAccessContainer::size_type _Size_type;
    00662     typedef typename _RandomAccessContainer::reference _Reference;
    00663     typedef typename _RandomAccessContainer::iterator _Iterator;
    00664     typedef typename _RandomAccessContainer::reverse_iterator _Reverse_iterator;
    00665
    00666     void __constraints() {
    00667       __function_requires<
    00668         _RandomAccessContainerConcept<_RandomAccessContainer> >();
    00669       __function_requires<
    00670         _Mutable_ReversibleContainerConcept<_RandomAccessContainer> >();
    00671       __function_requires< _Mutable_RandomAccessIteratorConcept<_Iterator> >();
    00672       __function_requires<
    00673         _Mutable_RandomAccessIteratorConcept<_Reverse_iterator> >();
    00674
    00675       _Reference __r _IsUnused = __c[__i];
    00676     }
    00677     _Size_type __i;
    00678     _RandomAccessContainer __c;
    00679   };
    00680
    00681   // A Sequence is inherently mutable
    00682   template <class _Sequence>
    00683   struct _SequenceConcept
    00684   {
    00685     typedef typename _Sequence::reference _Reference;
    00686     typedef typename _Sequence::const_reference _Const_reference;
    00687
    00688     void __constraints() {
    00689       // Matt Austern's book puts DefaultConstructible here, the C++
    00690       // standard places it in Container
    00691       //    function_requires< DefaultConstructible<Sequence> >();
    00692       __function_requires< _Mutable_ForwardContainerConcept<_Sequence> >();
    00693       __function_requires< _DefaultConstructibleConcept<_Sequence> >();
    00694
    00695       _Sequence
    00696         __c(__n) _IsUnused,
    00697         __c2(__n, __t) _IsUnused,
    00698         __c3(__first, __last) _IsUnused;
    00699
    00700       __c.insert(__p, __t);
    00701       __c.insert(__p, __n, __t);
    00702       __c.insert(__p, __first, __last);
    00703
    00704       __c.erase(__p);
    00705       __c.erase(__p, __q);
    00706
    00707       _Reference __r _IsUnused = __c.front();
    00708
    00709       __const_constraints(__c);
    00710     }
    00711     void __const_constraints(const _Sequence& __c) {
    00712       _Const_reference __r _IsUnused = __c.front();
    00713     }
    00714     typename _Sequence::value_type __t;
    00715     typename _Sequence::size_type __n;
    00716     typename _Sequence::value_type *__first, *__last;
    00717     typename _Sequence::iterator __p, __q;
    00718   };
    00719
    00720   template <class _FrontInsertionSequence>
    00721   struct _FrontInsertionSequenceConcept
    00722   {
    00723     void __constraints() {
    00724       __function_requires< _SequenceConcept<_FrontInsertionSequence> >();
    00725
    00726       __c.push_front(__t);
    00727       __c.pop_front();
    00728     }
    00729     _FrontInsertionSequence __c;
    00730     typename _FrontInsertionSequence::value_type __t;
    00731   };
    00732
    00733   template <class _BackInsertionSequence>
    00734   struct _BackInsertionSequenceConcept
    00735   {
    00736     typedef typename _BackInsertionSequence::reference _Reference;
    00737     typedef typename _BackInsertionSequence::const_reference _Const_reference;
    00738
    00739     void __constraints() {
    00740       __function_requires< _SequenceConcept<_BackInsertionSequence> >();
    00741
    00742       __c.push_back(__t);
    00743       __c.pop_back();
    00744       _Reference __r _IsUnused = __c.back();
    00745     }
    00746     void __const_constraints(const _BackInsertionSequence& __c) {
    00747       _Const_reference __r _IsUnused = __c.back();
    00748     };
    00749     _BackInsertionSequence __c;
    00750     typename _BackInsertionSequence::value_type __t;
    00751   };
    00752
    00753   template <class _AssociativeContainer>
    00754   struct _AssociativeContainerConcept
    00755   {
    00756     void __constraints() {
    00757       __function_requires< _ForwardContainerConcept<_AssociativeContainer> >();
    00758       __function_requires<
    00759         _DefaultConstructibleConcept<_AssociativeContainer> >();
    00760
    00761       __i = __c.find(__k);
    00762       __r = __c.equal_range(__k);
    00763       __c.erase(__k);
    00764       __c.erase(__i);
    00765       __c.erase(__r.first, __r.second);
    00766       __const_constraints(__c);
    00767     }
    00768     void __const_constraints(const _AssociativeContainer& __c) {
    00769       __ci = __c.find(__k);
    00770       __n = __c.count(__k);
    00771       __cr = __c.equal_range(__k);
    00772     }
    00773     typedef typename _AssociativeContainer::iterator _Iterator;
    00774     typedef typename _AssociativeContainer::const_iterator _Const_iterator;
    00775
    00776     _AssociativeContainer __c;
    00777     _Iterator __i;
    00778     std::pair<_Iterator,_Iterator> __r;
    00779     _Const_iterator __ci;
    00780     std::pair<_Const_iterator,_Const_iterator> __cr;
    00781     typename _AssociativeContainer::key_type __k;
    00782     typename _AssociativeContainer::size_type __n;
    00783   };
    00784
    00785   template <class _UniqueAssociativeContainer>
    00786   struct _UniqueAssociativeContainerConcept
    00787   {
    00788     void __constraints() {
    00789       __function_requires<
    00790         _AssociativeContainerConcept<_UniqueAssociativeContainer> >();
    00791
    00792       _UniqueAssociativeContainer __c(__first, __last);
    00793
    00794       __pos_flag = __c.insert(__t);
    00795       __c.insert(__first, __last);
    00796     }
    00797     std::pair<typename _UniqueAssociativeContainer::iterator, bool> __pos_flag;
    00798     typename _UniqueAssociativeContainer::value_type __t;
    00799     typename _UniqueAssociativeContainer::value_type *__first, *__last;
    00800   };
    00801
    00802   template <class _MultipleAssociativeContainer>
    00803   struct _MultipleAssociativeContainerConcept
    00804   {
    00805     void __constraints() {
    00806       __function_requires<
    00807         _AssociativeContainerConcept<_MultipleAssociativeContainer> >();
    00808
    00809       _MultipleAssociativeContainer __c(__first, __last);
    00810
    00811       __pos = __c.insert(__t);
    00812       __c.insert(__first, __last);
    00813
    00814     }
    00815     typename _MultipleAssociativeContainer::iterator __pos _IsUnused;
    00816     typename _MultipleAssociativeContainer::value_type __t;
    00817     typename _MultipleAssociativeContainer::value_type *__first, *__last;
    00818   };
    00819
    00820   template <class _SimpleAssociativeContainer>
    00821   struct _SimpleAssociativeContainerConcept
    00822   {
    00823     void __constraints() {
    00824       __function_requires<
    00825         _AssociativeContainerConcept<_SimpleAssociativeContainer> >();
    00826       typedef typename _SimpleAssociativeContainer::key_type _Key_type;
    00827       typedef typename _SimpleAssociativeContainer::value_type _Value_type;
    00828       typedef typename _Aux_require_same<_Key_type, _Value_type>::_Type
    00829         _Requqired;
    00830     }
    00831   };
    00832
    00833   template <class _SimpleAssociativeContainer>
    00834   struct _PairAssociativeContainerConcept
    00835   {
    00836     void __constraints() {
    00837       __function_requires<
    00838         _AssociativeContainerConcept<_SimpleAssociativeContainer> >();
    00839       typedef typename _SimpleAssociativeContainer::key_type _Key_type;
    00840       typedef typename _SimpleAssociativeContainer::value_type _Value_type;
    00841       typedef typename _SimpleAssociativeContainer::mapped_type _Mapped_type;
    00842       typedef std::pair<const _Key_type, _Mapped_type> _Required_value_type;
    00843       typedef typename _Aux_require_same<_Value_type,
    00844         _Required_value_type>::_Type _Required;
    00845     }
    00846   };
    00847
    00848   template <class _SortedAssociativeContainer>
    00849   struct _SortedAssociativeContainerConcept
    00850   {
    00851     void __constraints() {
    00852       __function_requires<
    00853         _AssociativeContainerConcept<_SortedAssociativeContainer> >();
    00854       __function_requires<
    00855         _ReversibleContainerConcept<_SortedAssociativeContainer> >();
    00856
    00857       _SortedAssociativeContainer
    00858         __c(__kc) _IsUnused,
    00859         __c2(__first, __last) _IsUnused,
    00860         __c3(__first, __last, __kc) _IsUnused;
    00861
    00862       __p = __c.upper_bound(__k);
    00863       __p = __c.lower_bound(__k);
    00864       __r = __c.equal_range(__k);
    00865
    00866       __c.insert(__p, __t);
    00867     }
    00868     void __const_constraints(const _SortedAssociativeContainer& __c) {
    00869       __kc = __c.key_comp();
    00870       __vc = __c.value_comp();
    00871
    00872       __cp = __c.upper_bound(__k);
    00873       __cp = __c.lower_bound(__k);
    00874       __cr = __c.equal_range(__k);
    00875     }
    00876     typename _SortedAssociativeContainer::key_compare __kc;
    00877     typename _SortedAssociativeContainer::value_compare __vc;
    00878     typename _SortedAssociativeContainer::value_type __t;
    00879     typename _SortedAssociativeContainer::key_type __k;
    00880     typedef typename _SortedAssociativeContainer::iterator _Iterator;
    00881     typedef typename _SortedAssociativeContainer::const_iterator
    00882       _Const_iterator;
    00883
    00884     _Iterator __p;
    00885     _Const_iterator __cp;
    00886     std::pair<_Iterator,_Iterator> __r;
    00887     std::pair<_Const_iterator,_Const_iterator> __cr;
    00888     typename _SortedAssociativeContainer::value_type *__first, *__last;
    00889   };
    00890
    00891   // HashedAssociativeContainer
    00892
    00893 } // namespace __gnu_cxx
    00894
    00895 #undef _IsUnused
    00896
    00897 #endif // _GLIBCPP_BOOST_CONCEPT_CHECK
    00898
    00899