# boost_concept_check.h

Go to the documentation of this file.

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