# 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< _ConvertibleConcept<
    00479         typename std::iterator_traits<_Tp>::iterator_category,
    00480         std::forward_iterator_tag> >();
    00481       typedef typename std::iterator_traits<_Tp>::reference _Ref;
    00482       _Ref __r _IsUnused = *__i;
    00483     }
    00484     _Tp __i;
    00485   };
    00486
    00487   template <class _Tp>
    00488   struct _Mutable_ForwardIteratorConcept
    00489   {
    00490     void __constraints() {
    00491       __function_requires< _ForwardIteratorConcept<_Tp> >();
    00492       *__i++ = *__i;                    // require postincrement and assignment
    00493     }
    00494     _Tp __i;
    00495   };
    00496
    00497   template <class _Tp>
    00498   struct _BidirectionalIteratorConcept
    00499   {
    00500     void __constraints() {
    00501       __function_requires< _ForwardIteratorConcept<_Tp> >();
    00502       __function_requires< _ConvertibleConcept<
    00503         typename std::iterator_traits<_Tp>::iterator_category,
    00504         std::bidirectional_iterator_tag> >();
    00505       --__i;                            // require predecrement operator
    00506       __i--;                            // require postdecrement operator
    00507     }
    00508     _Tp __i;
    00509   };
    00510
    00511   template <class _Tp>
    00512   struct _Mutable_BidirectionalIteratorConcept
    00513   {
    00514     void __constraints() {
    00515       __function_requires< _BidirectionalIteratorConcept<_Tp> >();
    00516       __function_requires< _Mutable_ForwardIteratorConcept<_Tp> >();
    00517       *__i-- = *__i;                    // require postdecrement and assignment
    00518     }
    00519     _Tp __i;
    00520   };
    00521
    00522
    00523   template <class _Tp>
    00524   struct _RandomAccessIteratorConcept
    00525   {
    00526     void __constraints() {
    00527       __function_requires< _BidirectionalIteratorConcept<_Tp> >();
    00528       __function_requires< _ComparableConcept<_Tp> >();
    00529       __function_requires< _ConvertibleConcept<
    00530         typename std::iterator_traits<_Tp>::iterator_category,
    00531         std::random_access_iterator_tag> >();
    00532       // ??? We don't use _Ref, are we just checking for "referenceability"?
    00533       typedef typename std::iterator_traits<_Tp>::reference _Ref;
    00534
    00535       __i += __n;                       // require assignment addition operator
    00536       __i = __i + __n; __i = __n + __i; // require addition with difference type
    00537       __i -= __n;                       // require assignment subtraction op
    00538       __i = __i - __n;                  // require subtraction with
    00539                                         //            difference type
    00540       __n = __i - __j;                  // require difference operator
    00541       (void)__i[__n];                   // require element access operator
    00542     }
    00543     _Tp __a, __b;
    00544     _Tp __i, __j;
    00545     typename std::iterator_traits<_Tp>::difference_type __n;
    00546   };
    00547
    00548   template <class _Tp>
    00549   struct _Mutable_RandomAccessIteratorConcept
    00550   {
    00551     void __constraints() {
    00552       __function_requires< _RandomAccessIteratorConcept<_Tp> >();
    00553       __function_requires< _Mutable_BidirectionalIteratorConcept<_Tp> >();
    00554       __i[__n] = *__i;                  // require element access and assignment
    00555     }
    00556     _Tp __i;
    00557     typename std::iterator_traits<_Tp>::difference_type __n;
    00558   };
    00559
    00560   //===========================================================================
    00561   // Container Concepts
    00562
    00563   template <class _Container>
    00564   struct _ContainerConcept
    00565   {
    00566     typedef typename _Container::value_type _Value_type;
    00567     typedef typename _Container::difference_type _Difference_type;
    00568     typedef typename _Container::size_type _Size_type;
    00569     typedef typename _Container::const_reference _Const_reference;
    00570     typedef typename _Container::const_pointer _Const_pointer;
    00571     typedef typename _Container::const_iterator _Const_iterator;
    00572
    00573     void __constraints() {
    00574       __function_requires< _InputIteratorConcept<_Const_iterator> >();
    00575       __function_requires< _AssignableConcept<_Container> >();
    00576       const _Container __c;
    00577       __i = __c.begin();
    00578       __i = __c.end();
    00579       __n = __c.size();
    00580       __n = __c.max_size();
    00581       __b = __c.empty();
    00582     }
    00583     bool __b;
    00584     _Const_iterator __i;
    00585     _Size_type __n;
    00586   };
    00587
    00588   template <class _Container>
    00589   struct _Mutable_ContainerConcept
    00590   {
    00591     typedef typename _Container::value_type _Value_type;
    00592     typedef typename _Container::reference _Reference;
    00593     typedef typename _Container::iterator _Iterator;
    00594     typedef typename _Container::pointer _Pointer;
    00595
    00596     void __constraints() {
    00597       __function_requires< _ContainerConcept<_Container> >();
    00598       __function_requires< _AssignableConcept<_Value_type> >();
    00599       __function_requires< _InputIteratorConcept<_Iterator> >();
    00600
    00601       __i = __c.begin();
    00602       __i = __c.end();
    00603       __c.swap(__c2);
    00604     }
    00605     _Iterator __i;
    00606     _Container __c, __c2;
    00607   };
    00608
    00609   template <class _ForwardContainer>
    00610   struct _ForwardContainerConcept
    00611   {
    00612     void __constraints() {
    00613       __function_requires< _ContainerConcept<_ForwardContainer> >();
    00614       typedef typename _ForwardContainer::const_iterator _Const_iterator;
    00615       __function_requires< _ForwardIteratorConcept<_Const_iterator> >();
    00616     }
    00617   };
    00618
    00619   template <class _ForwardContainer>
    00620   struct _Mutable_ForwardContainerConcept
    00621   {
    00622     void __constraints() {
    00623       __function_requires< _ForwardContainerConcept<_ForwardContainer> >();
    00624       __function_requires< _Mutable_ContainerConcept<_ForwardContainer> >();
    00625       typedef typename _ForwardContainer::iterator _Iterator;
    00626       __function_requires< _Mutable_ForwardIteratorConcept<_Iterator> >();
    00627     }
    00628   };
    00629
    00630   template <class _ReversibleContainer>
    00631   struct _ReversibleContainerConcept
    00632   {
    00633     typedef typename _ReversibleContainer::const_iterator _Const_iterator;
    00634     typedef typename _ReversibleContainer::const_reverse_iterator
    00635       _Const_reverse_iterator;
    00636
    00637     void __constraints() {
    00638       __function_requires< _ForwardContainerConcept<_ReversibleContainer> >();
    00639       __function_requires< _BidirectionalIteratorConcept<_Const_iterator> >();
    00640       __function_requires<
    00641         _BidirectionalIteratorConcept<_Const_reverse_iterator> >();
    00642
    00643       const _ReversibleContainer __c;
    00644       _Const_reverse_iterator __i = __c.rbegin();
    00645       __i = __c.rend();
    00646     }
    00647   };
    00648
    00649   template <class _ReversibleContainer>
    00650   struct _Mutable_ReversibleContainerConcept
    00651   {
    00652     typedef typename _ReversibleContainer::iterator _Iterator;
    00653     typedef typename _ReversibleContainer::reverse_iterator _Reverse_iterator;
    00654
    00655     void __constraints() {
    00656       __function_requires<_ReversibleContainerConcept<_ReversibleContainer> >();
    00657       __function_requires<
    00658         _Mutable_ForwardContainerConcept<_ReversibleContainer> >();
    00659       __function_requires<_Mutable_BidirectionalIteratorConcept<_Iterator> >();
    00660       __function_requires<
    00661         _Mutable_BidirectionalIteratorConcept<_Reverse_iterator> >();
    00662
    00663       _Reverse_iterator __i = __c.rbegin();
    00664       __i = __c.rend();
    00665     }
    00666     _ReversibleContainer __c;
    00667   };
    00668
    00669   template <class _RandomAccessContainer>
    00670   struct _RandomAccessContainerConcept
    00671   {
    00672     typedef typename _RandomAccessContainer::size_type _Size_type;
    00673     typedef typename _RandomAccessContainer::const_reference _Const_reference;
    00674     typedef typename _RandomAccessContainer::const_iterator _Const_iterator;
    00675     typedef typename _RandomAccessContainer::const_reverse_iterator
    00676       _Const_reverse_iterator;
    00677
    00678     void __constraints() {
    00679       __function_requires<
    00680         _ReversibleContainerConcept<_RandomAccessContainer> >();
    00681       __function_requires< _RandomAccessIteratorConcept<_Const_iterator> >();
    00682       __function_requires<
    00683         _RandomAccessIteratorConcept<_Const_reverse_iterator> >();
    00684
    00685       const _RandomAccessContainer __c;
    00686       _Const_reference __r _IsUnused = __c[__n];
    00687     }
    00688     _Size_type __n;
    00689   };
    00690
    00691   template <class _RandomAccessContainer>
    00692   struct _Mutable_RandomAccessContainerConcept
    00693   {
    00694     typedef typename _RandomAccessContainer::size_type _Size_type;
    00695     typedef typename _RandomAccessContainer::reference _Reference;
    00696     typedef typename _RandomAccessContainer::iterator _Iterator;
    00697     typedef typename _RandomAccessContainer::reverse_iterator _Reverse_iterator;
    00698
    00699     void __constraints() {
    00700       __function_requires<
    00701         _RandomAccessContainerConcept<_RandomAccessContainer> >();
    00702       __function_requires<
    00703         _Mutable_ReversibleContainerConcept<_RandomAccessContainer> >();
    00704       __function_requires< _Mutable_RandomAccessIteratorConcept<_Iterator> >();
    00705       __function_requires<
    00706         _Mutable_RandomAccessIteratorConcept<_Reverse_iterator> >();
    00707
    00708       _Reference __r _IsUnused = __c[__i];
    00709     }
    00710     _Size_type __i;
    00711     _RandomAccessContainer __c;
    00712   };
    00713
    00714   // A Sequence is inherently mutable
    00715   template <class _Sequence>
    00716   struct _SequenceConcept
    00717   {
    00718     typedef typename _Sequence::reference _Reference;
    00719     typedef typename _Sequence::const_reference _Const_reference;
    00720
    00721     void __constraints() {
    00722       // Matt Austern's book puts DefaultConstructible here, the C++
    00723       // standard places it in Container
    00724       //    function_requires< DefaultConstructible<Sequence> >();
    00725       __function_requires< _Mutable_ForwardContainerConcept<_Sequence> >();
    00726       __function_requires< _DefaultConstructibleConcept<_Sequence> >();
    00727
    00728       _Sequence
    00729         __c _IsUnused(__n),
    00730         __c2 _IsUnused(__n, __t),
    00731         __c3 _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