# boost_concept_check.h

Go to the documentation of this file.

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