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