boost_concept_check.h

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