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