boost_concept_check.h

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

Generated on Thu Jul 23 21:16:01 2009 for libstdc++ by  doxygen 1.5.8