# boost_concept_check.h

Go to the documentation of this file.

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