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