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 

Generated on Thu Nov 21 03:12:47 2002 for libstdc++-v3 Source by doxygen1.2.18-20021030