Home | History | Annotate | Download | only in bits
      1 // -*- C++ -*-
      2 
      3 // Copyright (C) 2004, 2005, 2006, 2007, 2009 Free Software Foundation, Inc.
      4 //
      5 // This file is part of the GNU ISO C++ Library.  This library is free
      6 // software; you can redistribute it and/or modify it under the
      7 // terms of the GNU General Public License as published by the
      8 // Free Software Foundation; either version 3, or (at your option)
      9 // any later version.
     10 
     11 // This library is distributed in the hope that it will be useful,
     12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 // GNU General Public License for more details.
     15 
     16 // Under Section 7 of GPL version 3, you are granted additional
     17 // permissions described in the GCC Runtime Library Exception, version
     18 // 3.1, as published by the Free Software Foundation.
     19 
     20 // You should have received a copy of the GNU General Public License and
     21 // a copy of the GCC Runtime Library Exception along with this program;
     22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     23 // <http://www.gnu.org/licenses/>.
     24 
     25 // (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify,
     26 // sell and distribute this software is granted provided this
     27 // copyright notice appears in all copies. This software is provided
     28 // "as is" without express or implied warranty, and with no claim as
     29 // to its suitability for any purpose.
     30 //
     31 
     32 /** @file boost_concept_check.h
     33  *  This is an internal header file, included by other library headers.
     34  *  You should not attempt to use it directly.
     35  */
     36 
     37 // GCC Note:  based on version 1.12.0 of the Boost library.
     38 
     39 #ifndef _BOOST_CONCEPT_CHECK_H
     40 #define _BOOST_CONCEPT_CHECK_H 1
     41 
     42 #pragma GCC system_header
     43 
     44 #include <cstddef>                // for ptrdiff_t, used next
     45 #include <bits/stl_iterator_base_types.h>    // for traits and tags
     46 
     47 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
     48 
     49 #define _IsUnused __attribute__ ((__unused__))
     50 
     51 // When the C-C code is in use, we would like this function to do as little
     52 // as possible at runtime, use as few resources as possible, and hopefully
     53 // be elided out of existence... hmmm.
     54 template <class _Concept>
     55 inline void __function_requires()
     56 {
     57   void (_Concept::*__x)() _IsUnused = &_Concept::__constraints;
     58 }
     59 
     60 // No definition: if this is referenced, there's a problem with
     61 // the instantiating type not being one of the required integer types.
     62 // Unfortunately, this results in a link-time error, not a compile-time error.
     63 void __error_type_must_be_an_integer_type();
     64 void __error_type_must_be_an_unsigned_integer_type();
     65 void __error_type_must_be_a_signed_integer_type();
     66 
     67 // ??? Should the "concept_checking*" structs begin with more than _ ?
     68 #define _GLIBCXX_CLASS_REQUIRES(_type_var, _ns, _concept) \
     69   typedef void (_ns::_concept <_type_var>::* _func##_type_var##_concept)(); \
     70   template <_func##_type_var##_concept _Tp1> \
     71   struct _concept_checking##_type_var##_concept { }; \
     72   typedef _concept_checking##_type_var##_concept< \
     73     &_ns::_concept <_type_var>::__constraints> \
     74     _concept_checking_typedef##_type_var##_concept
     75 
     76 #define _GLIBCXX_CLASS_REQUIRES2(_type_var1, _type_var2, _ns, _concept) \
     77   typedef void (_ns::_concept <_type_var1,_type_var2>::* _func##_type_var1##_type_var2##_concept)(); \
     78   template <_func##_type_var1##_type_var2##_concept _Tp1> \
     79   struct _concept_checking##_type_var1##_type_var2##_concept { }; \
     80   typedef _concept_checking##_type_var1##_type_var2##_concept< \
     81     &_ns::_concept <_type_var1,_type_var2>::__constraints> \
     82     _concept_checking_typedef##_type_var1##_type_var2##_concept
     83 
     84 #define _GLIBCXX_CLASS_REQUIRES3(_type_var1, _type_var2, _type_var3, _ns, _concept) \
     85   typedef void (_ns::_concept <_type_var1,_type_var2,_type_var3>::* _func##_type_var1##_type_var2##_type_var3##_concept)(); \
     86   template <_func##_type_var1##_type_var2##_type_var3##_concept _Tp1> \
     87   struct _concept_checking##_type_var1##_type_var2##_type_var3##_concept { }; \
     88   typedef _concept_checking##_type_var1##_type_var2##_type_var3##_concept< \
     89     &_ns::_concept <_type_var1,_type_var2,_type_var3>::__constraints>  \
     90   _concept_checking_typedef##_type_var1##_type_var2##_type_var3##_concept
     91 
     92 #define _GLIBCXX_CLASS_REQUIRES4(_type_var1, _type_var2, _type_var3, _type_var4, _ns, _concept) \
     93   typedef void (_ns::_concept <_type_var1,_type_var2,_type_var3,_type_var4>::* _func##_type_var1##_type_var2##_type_var3##_type_var4##_concept)(); \
     94   template <_func##_type_var1##_type_var2##_type_var3##_type_var4##_concept _Tp1> \
     95   struct _concept_checking##_type_var1##_type_var2##_type_var3##_type_var4##_concept { }; \
     96   typedef _concept_checking##_type_var1##_type_var2##_type_var3##_type_var4##_concept< \
     97   &_ns::_concept <_type_var1,_type_var2,_type_var3,_type_var4>::__constraints> \
     98     _concept_checking_typedef##_type_var1##_type_var2##_type_var3##_type_var4##_concept
     99 
    100 
    101 template <class _Tp1, class _Tp2>
    102 struct _Aux_require_same { };
    103 
    104 template <class _Tp>
    105 struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; };
    106 
    107   template <class _Tp1, class _Tp2>
    108   struct _SameTypeConcept
    109   {
    110     void __constraints() {
    111       typedef typename _Aux_require_same<_Tp1, _Tp2>::_Type _Required;
    112     }
    113   };
    114 
    115   template <class _Tp>
    116   struct _IntegerConcept {
    117     void __constraints() {
    118       __error_type_must_be_an_integer_type();
    119     }
    120   };
    121   template <> struct _IntegerConcept<short> { void __constraints() {} };
    122   template <> struct _IntegerConcept<unsigned short> { void __constraints(){} };
    123   template <> struct _IntegerConcept<int> { void __constraints() {} };
    124   template <> struct _IntegerConcept<unsigned int> { void __constraints() {} };
    125   template <> struct _IntegerConcept<long> { void __constraints() {} };
    126   template <> struct _IntegerConcept<unsigned long> { void __constraints() {} };
    127   template <> struct _IntegerConcept<long long> { void __constraints() {} };
    128   template <> struct _IntegerConcept<unsigned long long>
    129                                                 { void __constraints() {} };
    130 
    131   template <class _Tp>
    132   struct _SignedIntegerConcept {
    133     void __constraints() {
    134       __error_type_must_be_a_signed_integer_type();
    135     }
    136   };
    137   template <> struct _SignedIntegerConcept<short> { void __constraints() {} };
    138   template <> struct _SignedIntegerConcept<int> { void __constraints() {} };
    139   template <> struct _SignedIntegerConcept<long> { void __constraints() {} };
    140   template <> struct _SignedIntegerConcept<long long> { void __constraints(){}};
    141 
    142   template <class _Tp>
    143   struct _UnsignedIntegerConcept {
    144     void __constraints() {
    145       __error_type_must_be_an_unsigned_integer_type();
    146     }
    147   };
    148   template <> struct _UnsignedIntegerConcept<unsigned short>
    149     { void __constraints() {} };
    150   template <> struct _UnsignedIntegerConcept<unsigned int>
    151     { void __constraints() {} };
    152   template <> struct _UnsignedIntegerConcept<unsigned long>
    153     { void __constraints() {} };
    154   template <> struct _UnsignedIntegerConcept<unsigned long long>
    155     { void __constraints() {} };
    156 
    157   //===========================================================================
    158   // Basic Concepts
    159 
    160   template <class _Tp>
    161   struct _DefaultConstructibleConcept
    162   {
    163     void __constraints() {
    164       _Tp __a _IsUnused;                // require default constructor
    165     }
    166   };
    167 
    168   template <class _Tp>
    169   struct _AssignableConcept
    170   {
    171     void __constraints() {
    172       __a = __a;                        // require assignment operator
    173       __const_constraints(__a);
    174     }
    175     void __const_constraints(const _Tp& __b) {
    176       __a = __b;                   // const required for argument to assignment
    177     }
    178     _Tp __a;
    179     // possibly should be "Tp* a;" and then dereference "a" in constraint
    180     // functions?  present way would require a default ctor, i think...
    181   };
    182 
    183   template <class _Tp>
    184   struct _CopyConstructibleConcept
    185   {
    186     void __constraints() {
    187       _Tp __a(__b);                     // require copy constructor
    188       _Tp* __ptr _IsUnused = &__a;      // require address of operator
    189       __const_constraints(__a);
    190     }
    191     void __const_constraints(const _Tp& __a) {
    192       _Tp __c _IsUnused(__a);           // require const copy constructor
    193       const _Tp* __ptr _IsUnused = &__a; // require const address of operator
    194     }
    195     _Tp __b;
    196   };
    197 
    198   // The SGI STL version of Assignable requires copy constructor and operator=
    199   template <class _Tp>
    200   struct _SGIAssignableConcept
    201   {
    202     void __constraints() {
    203       _Tp __b _IsUnused(__a);
    204       __a = __a;                        // require assignment operator
    205       __const_constraints(__a);
    206     }
    207     void __const_constraints(const _Tp& __b) {
    208       _Tp __c _IsUnused(__b);
    209       __a = __b;              // const required for argument to assignment
    210     }
    211     _Tp __a;
    212   };
    213 
    214   template <class _From, class _To>
    215   struct _ConvertibleConcept
    216   {
    217     void __constraints() {
    218       _To __y _IsUnused = __x;
    219     }
    220     _From __x;
    221   };
    222 
    223   // The C++ standard requirements for many concepts talk about return
    224   // types that must be "convertible to bool".  The problem with this
    225   // requirement is that it leaves the door open for evil proxies that
    226   // define things like operator|| with strange return types.  Two
    227   // possible solutions are:
    228   // 1) require the return type to be exactly bool
    229   // 2) stay with convertible to bool, and also
    230   //    specify stuff about all the logical operators.
    231   // For now we just test for convertible to bool.
    232   template <class _Tp>
    233   void __aux_require_boolean_expr(const _Tp& __t) {
    234     bool __x _IsUnused = __t;
    235   }
    236 
    237 // FIXME
    238   template <class _Tp>
    239   struct _EqualityComparableConcept
    240   {
    241     void __constraints() {
    242       __aux_require_boolean_expr(__a == __b);
    243     }
    244     _Tp __a, __b;
    245   };
    246 
    247   template <class _Tp>
    248   struct _LessThanComparableConcept
    249   {
    250     void __constraints() {
    251       __aux_require_boolean_expr(__a < __b);
    252     }
    253     _Tp __a, __b;
    254   };
    255 
    256   // This is equivalent to SGI STL's LessThanComparable.
    257   template <class _Tp>
    258   struct _ComparableConcept
    259   {
    260     void __constraints() {
    261       __aux_require_boolean_expr(__a < __b);
    262       __aux_require_boolean_expr(__a > __b);
    263       __aux_require_boolean_expr(__a <= __b);
    264       __aux_require_boolean_expr(__a >= __b);
    265     }
    266     _Tp __a, __b;
    267   };
    268 
    269 #define _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(_OP,_NAME) \
    270   template <class _First, class _Second> \
    271   struct _NAME { \
    272     void __constraints() { (void)__constraints_(); } \
    273     bool __constraints_() {  \
    274       return  __a _OP __b; \
    275     } \
    276     _First __a; \
    277     _Second __b; \
    278   }
    279 
    280 #define _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(_OP,_NAME) \
    281   template <class _Ret, class _First, class _Second> \
    282   struct _NAME { \
    283     void __constraints() { (void)__constraints_(); } \
    284     _Ret __constraints_() {  \
    285       return __a _OP __b; \
    286     } \
    287     _First __a; \
    288     _Second __b; \
    289   }
    290 
    291   _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(==, _EqualOpConcept);
    292   _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(!=, _NotEqualOpConcept);
    293   _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<, _LessThanOpConcept);
    294   _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<=, _LessEqualOpConcept);
    295   _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>, _GreaterThanOpConcept);
    296   _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>=, _GreaterEqualOpConcept);
    297 
    298   _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(+, _PlusOpConcept);
    299   _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(*, _TimesOpConcept);
    300   _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(/, _DivideOpConcept);
    301   _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(-, _SubtractOpConcept);
    302   _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(%, _ModOpConcept);
    303 
    304 #undef _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT
    305 #undef _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT
    306 
    307   //===========================================================================
    308   // Function Object Concepts
    309 
    310   template <class _Func, class _Return>
    311   struct _GeneratorConcept
    312   {
    313     void __constraints() {
    314       const _Return& __r _IsUnused = __f();// require operator() member function
    315     }
    316     _Func __f;
    317   };
    318 
    319 
    320   template <class _Func>
    321   struct _GeneratorConcept<_Func,void>
    322   {
    323     void __constraints() {
    324       __f();                            // require operator() member function
    325     }
    326     _Func __f;
    327   };
    328 
    329   template <class _Func, class _Return, class _Arg>
    330   struct _UnaryFunctionConcept
    331   {
    332     void __constraints() {
    333       __r = __f(__arg);                  // require operator()
    334     }
    335     _Func __f;
    336     _Arg __arg;
    337     _Return __r;
    338   };
    339 
    340   template <class _Func, class _Arg>
    341   struct _UnaryFunctionConcept<_Func, void, _Arg> {
    342     void __constraints() {
    343       __f(__arg);                       // require operator()
    344     }
    345     _Func __f;
    346     _Arg __arg;
    347   };
    348 
    349   template <class _Func, class _Return, class _First, class _Second>
    350   struct _BinaryFunctionConcept
    351   {
    352     void __constraints() {
    353       __r = __f(__first, __second);     // require operator()
    354     }
    355     _Func __f;
    356     _First __first;
    357     _Second __second;
    358     _Return __r;
    359   };
    360 
    361   template <class _Func, class _First, class _Second>
    362   struct _BinaryFunctionConcept<_Func, void, _First, _Second>
    363   {
    364     void __constraints() {
    365       __f(__first, __second);           // require operator()
    366     }
    367     _Func __f;
    368     _First __first;
    369     _Second __second;
    370   };
    371 
    372   template <class _Func, class _Arg>
    373   struct _UnaryPredicateConcept
    374   {
    375     void __constraints() {
    376       __aux_require_boolean_expr(__f(__arg)); // require op() returning bool
    377     }
    378     _Func __f;
    379     _Arg __arg;
    380   };
    381 
    382   template <class _Func, class _First, class _Second>
    383   struct _BinaryPredicateConcept
    384   {
    385     void __constraints() {
    386       __aux_require_boolean_expr(__f(__a, __b)); // require op() returning bool
    387     }
    388     _Func __f;
    389     _First __a;
    390     _Second __b;
    391   };
    392 
    393   // use this when functor is used inside a container class like std::set
    394   template <class _Func, class _First, class _Second>
    395   struct _Const_BinaryPredicateConcept {
    396     void __constraints() {
    397       __const_constraints(__f);
    398     }
    399     void __const_constraints(const _Func& __fun) {
    400       __function_requires<_BinaryPredicateConcept<_Func, _First, _Second> >();
    401       // operator() must be a const member function
    402       __aux_require_boolean_expr(__fun(__a, __b));
    403     }
    404     _Func __f;
    405     _First __a;
    406     _Second __b;
    407   };
    408 
    409   //===========================================================================
    410   // Iterator Concepts
    411 
    412   template <class _Tp>
    413   struct _TrivialIteratorConcept
    414   {
    415     void __constraints() {
    416 //    __function_requires< _DefaultConstructibleConcept<_Tp> >();
    417       __function_requires< _AssignableConcept<_Tp> >();
    418       __function_requires< _EqualityComparableConcept<_Tp> >();
    419 //      typedef typename std::iterator_traits<_Tp>::value_type _V;
    420       (void)*__i;                       // require dereference operator
    421     }
    422     _Tp __i;
    423   };
    424 
    425   template <class _Tp>
    426   struct _Mutable_TrivialIteratorConcept
    427   {
    428     void __constraints() {
    429       __function_requires< _TrivialIteratorConcept<_Tp> >();
    430       *__i = *__j;                      // require dereference and assignment
    431     }
    432     _Tp __i, __j;
    433   };
    434 
    435   template <class _Tp>
    436   struct _InputIteratorConcept
    437   {
    438     void __constraints() {
    439       __function_requires< _TrivialIteratorConcept<_Tp> >();
    440       // require iterator_traits typedef's
    441       typedef typename std::iterator_traits<_Tp>::difference_type _Diff;
    442 //      __function_requires< _SignedIntegerConcept<_Diff> >();
    443       typedef typename std::iterator_traits<_Tp>::reference _Ref;
    444       typedef typename std::iterator_traits<_Tp>::pointer _Pt;
    445       typedef typename std::iterator_traits<_Tp>::iterator_category _Cat;
    446       __function_requires< _ConvertibleConcept<
    447         typename std::iterator_traits<_Tp>::iterator_category,
    448         std::input_iterator_tag> >();
    449       ++__i;                            // require preincrement operator
    450       __i++;                            // require postincrement operator
    451     }
    452     _Tp __i;
    453   };
    454 
    455   template <class _Tp, class _ValueT>
    456   struct _OutputIteratorConcept
    457   {
    458     void __constraints() {
    459       __function_requires< _AssignableConcept<_Tp> >();
    460       ++__i;                            // require preincrement operator
    461       __i++;                            // require postincrement operator
    462       *__i++ = __t;                     // require postincrement and assignment
    463     }
    464     _Tp __i;
    465     _ValueT __t;
    466   };
    467 
    468   template <class _Tp>
    469   struct _ForwardIteratorConcept
    470   {
    471     void __constraints() {
    472       __function_requires< _InputIteratorConcept<_Tp> >();
    473       __function_requires< _DefaultConstructibleConcept<_Tp> >();
    474       __function_requires< _ConvertibleConcept<
    475         typename std::iterator_traits<_Tp>::iterator_category,
    476         std::forward_iterator_tag> >();
    477       typedef typename std::iterator_traits<_Tp>::reference _Ref;
    478       _Ref __r _IsUnused = *__i;
    479     }
    480     _Tp __i;
    481   };
    482 
    483   template <class _Tp>
    484   struct _Mutable_ForwardIteratorConcept
    485   {
    486     void __constraints() {
    487       __function_requires< _ForwardIteratorConcept<_Tp> >();
    488       *__i++ = *__i;                    // require postincrement and assignment
    489     }
    490     _Tp __i;
    491   };
    492 
    493   template <class _Tp>
    494   struct _BidirectionalIteratorConcept
    495   {
    496     void __constraints() {
    497       __function_requires< _ForwardIteratorConcept<_Tp> >();
    498       __function_requires< _ConvertibleConcept<
    499         typename std::iterator_traits<_Tp>::iterator_category,
    500         std::bidirectional_iterator_tag> >();
    501       --__i;                            // require predecrement operator
    502       __i--;                            // require postdecrement operator
    503     }
    504     _Tp __i;
    505   };
    506 
    507   template <class _Tp>
    508   struct _Mutable_BidirectionalIteratorConcept
    509   {
    510     void __constraints() {
    511       __function_requires< _BidirectionalIteratorConcept<_Tp> >();
    512       __function_requires< _Mutable_ForwardIteratorConcept<_Tp> >();
    513       *__i-- = *__i;                    // require postdecrement and assignment
    514     }
    515     _Tp __i;
    516   };
    517 
    518 
    519   template <class _Tp>
    520   struct _RandomAccessIteratorConcept
    521   {
    522     void __constraints() {
    523       __function_requires< _BidirectionalIteratorConcept<_Tp> >();
    524       __function_requires< _ComparableConcept<_Tp> >();
    525       __function_requires< _ConvertibleConcept<
    526         typename std::iterator_traits<_Tp>::iterator_category,
    527         std::random_access_iterator_tag> >();
    528       // ??? We don't use _Ref, are we just checking for "referenceability"?
    529       typedef typename std::iterator_traits<_Tp>::reference _Ref;
    530 
    531       __i += __n;                       // require assignment addition operator
    532       __i = __i + __n; __i = __n + __i; // require addition with difference type
    533       __i -= __n;                       // require assignment subtraction op
    534       __i = __i - __n;                  // require subtraction with
    535                                         //            difference type
    536       __n = __i - __j;                  // require difference operator
    537       (void)__i[__n];                   // require element access operator
    538     }
    539     _Tp __a, __b;
    540     _Tp __i, __j;
    541     typename std::iterator_traits<_Tp>::difference_type __n;
    542   };
    543 
    544   template <class _Tp>
    545   struct _Mutable_RandomAccessIteratorConcept
    546   {
    547     void __constraints() {
    548       __function_requires< _RandomAccessIteratorConcept<_Tp> >();
    549       __function_requires< _Mutable_BidirectionalIteratorConcept<_Tp> >();
    550       __i[__n] = *__i;                  // require element access and assignment
    551     }
    552     _Tp __i;
    553     typename std::iterator_traits<_Tp>::difference_type __n;
    554   };
    555 
    556   //===========================================================================
    557   // Container Concepts
    558 
    559   template <class _Container>
    560   struct _ContainerConcept
    561   {
    562     typedef typename _Container::value_type _Value_type;
    563     typedef typename _Container::difference_type _Difference_type;
    564     typedef typename _Container::size_type _Size_type;
    565     typedef typename _Container::const_reference _Const_reference;
    566     typedef typename _Container::const_pointer _Const_pointer;
    567     typedef typename _Container::const_iterator _Const_iterator;
    568 
    569     void __constraints() {
    570       __function_requires< _InputIteratorConcept<_Const_iterator> >();
    571       __function_requires< _AssignableConcept<_Container> >();
    572       const _Container __c;
    573       __i = __c.begin();
    574       __i = __c.end();
    575       __n = __c.size();
    576       __n = __c.max_size();
    577       __b = __c.empty();
    578     }
    579     bool __b;
    580     _Const_iterator __i;
    581     _Size_type __n;
    582   };
    583 
    584   template <class _Container>
    585   struct _Mutable_ContainerConcept
    586   {
    587     typedef typename _Container::value_type _Value_type;
    588     typedef typename _Container::reference _Reference;
    589     typedef typename _Container::iterator _Iterator;
    590     typedef typename _Container::pointer _Pointer;
    591 
    592     void __constraints() {
    593       __function_requires< _ContainerConcept<_Container> >();
    594       __function_requires< _AssignableConcept<_Value_type> >();
    595       __function_requires< _InputIteratorConcept<_Iterator> >();
    596 
    597       __i = __c.begin();
    598       __i = __c.end();
    599       __c.swap(__c2);
    600     }
    601     _Iterator __i;
    602     _Container __c, __c2;
    603   };
    604 
    605   template <class _ForwardContainer>
    606   struct _ForwardContainerConcept
    607   {
    608     void __constraints() {
    609       __function_requires< _ContainerConcept<_ForwardContainer> >();
    610       typedef typename _ForwardContainer::const_iterator _Const_iterator;
    611       __function_requires< _ForwardIteratorConcept<_Const_iterator> >();
    612     }
    613   };
    614 
    615   template <class _ForwardContainer>
    616   struct _Mutable_ForwardContainerConcept
    617   {
    618     void __constraints() {
    619       __function_requires< _ForwardContainerConcept<_ForwardContainer> >();
    620       __function_requires< _Mutable_ContainerConcept<_ForwardContainer> >();
    621       typedef typename _ForwardContainer::iterator _Iterator;
    622       __function_requires< _Mutable_ForwardIteratorConcept<_Iterator> >();
    623     }
    624   };
    625 
    626   template <class _ReversibleContainer>
    627   struct _ReversibleContainerConcept
    628   {
    629     typedef typename _ReversibleContainer::const_iterator _Const_iterator;
    630     typedef typename _ReversibleContainer::const_reverse_iterator
    631       _Const_reverse_iterator;
    632 
    633     void __constraints() {
    634       __function_requires< _ForwardContainerConcept<_ReversibleContainer> >();
    635       __function_requires< _BidirectionalIteratorConcept<_Const_iterator> >();
    636       __function_requires<
    637         _BidirectionalIteratorConcept<_Const_reverse_iterator> >();
    638 
    639       const _ReversibleContainer __c;
    640       _Const_reverse_iterator __i = __c.rbegin();
    641       __i = __c.rend();
    642     }
    643   };
    644 
    645   template <class _ReversibleContainer>
    646   struct _Mutable_ReversibleContainerConcept
    647   {
    648     typedef typename _ReversibleContainer::iterator _Iterator;
    649     typedef typename _ReversibleContainer::reverse_iterator _Reverse_iterator;
    650 
    651     void __constraints() {
    652       __function_requires<_ReversibleContainerConcept<_ReversibleContainer> >();
    653       __function_requires<
    654         _Mutable_ForwardContainerConcept<_ReversibleContainer> >();
    655       __function_requires<_Mutable_BidirectionalIteratorConcept<_Iterator> >();
    656       __function_requires<
    657         _Mutable_BidirectionalIteratorConcept<_Reverse_iterator> >();
    658 
    659       _Reverse_iterator __i = __c.rbegin();
    660       __i = __c.rend();
    661     }
    662     _ReversibleContainer __c;
    663   };
    664 
    665   template <class _RandomAccessContainer>
    666   struct _RandomAccessContainerConcept
    667   {
    668     typedef typename _RandomAccessContainer::size_type _Size_type;
    669     typedef typename _RandomAccessContainer::const_reference _Const_reference;
    670     typedef typename _RandomAccessContainer::const_iterator _Const_iterator;
    671     typedef typename _RandomAccessContainer::const_reverse_iterator
    672       _Const_reverse_iterator;
    673 
    674     void __constraints() {
    675       __function_requires<
    676         _ReversibleContainerConcept<_RandomAccessContainer> >();
    677       __function_requires< _RandomAccessIteratorConcept<_Const_iterator> >();
    678       __function_requires<
    679         _RandomAccessIteratorConcept<_Const_reverse_iterator> >();
    680 
    681       const _RandomAccessContainer __c;
    682       _Const_reference __r _IsUnused = __c[__n];
    683     }
    684     _Size_type __n;
    685   };
    686 
    687   template <class _RandomAccessContainer>
    688   struct _Mutable_RandomAccessContainerConcept
    689   {
    690     typedef typename _RandomAccessContainer::size_type _Size_type;
    691     typedef typename _RandomAccessContainer::reference _Reference;
    692     typedef typename _RandomAccessContainer::iterator _Iterator;
    693     typedef typename _RandomAccessContainer::reverse_iterator _Reverse_iterator;
    694 
    695     void __constraints() {
    696       __function_requires<
    697         _RandomAccessContainerConcept<_RandomAccessContainer> >();
    698       __function_requires<
    699         _Mutable_ReversibleContainerConcept<_RandomAccessContainer> >();
    700       __function_requires< _Mutable_RandomAccessIteratorConcept<_Iterator> >();
    701       __function_requires<
    702         _Mutable_RandomAccessIteratorConcept<_Reverse_iterator> >();
    703 
    704       _Reference __r _IsUnused = __c[__i];
    705     }
    706     _Size_type __i;
    707     _RandomAccessContainer __c;
    708   };
    709 
    710   // A Sequence is inherently mutable
    711   template <class _Sequence>
    712   struct _SequenceConcept
    713   {
    714     typedef typename _Sequence::reference _Reference;
    715     typedef typename _Sequence::const_reference _Const_reference;
    716 
    717     void __constraints() {
    718       // Matt Austern's book puts DefaultConstructible here, the C++
    719       // standard places it in Container
    720       //    function_requires< DefaultConstructible<Sequence> >();
    721       __function_requires< _Mutable_ForwardContainerConcept<_Sequence> >();
    722       __function_requires< _DefaultConstructibleConcept<_Sequence> >();
    723 
    724       _Sequence
    725 	__c _IsUnused(__n, __t),
    726         __c2 _IsUnused(__first, __last);
    727 
    728       __c.insert(__p, __t);
    729       __c.insert(__p, __n, __t);
    730       __c.insert(__p, __first, __last);
    731 
    732       __c.erase(__p);
    733       __c.erase(__p, __q);
    734 
    735       _Reference __r _IsUnused = __c.front();
    736 
    737       __const_constraints(__c);
    738     }
    739     void __const_constraints(const _Sequence& __c) {
    740       _Const_reference __r _IsUnused = __c.front();
    741     }
    742     typename _Sequence::value_type __t;
    743     typename _Sequence::size_type __n;
    744     typename _Sequence::value_type *__first, *__last;
    745     typename _Sequence::iterator __p, __q;
    746   };
    747 
    748   template <class _FrontInsertionSequence>
    749   struct _FrontInsertionSequenceConcept
    750   {
    751     void __constraints() {
    752       __function_requires< _SequenceConcept<_FrontInsertionSequence> >();
    753 
    754       __c.push_front(__t);
    755       __c.pop_front();
    756     }
    757     _FrontInsertionSequence __c;
    758     typename _FrontInsertionSequence::value_type __t;
    759   };
    760 
    761   template <class _BackInsertionSequence>
    762   struct _BackInsertionSequenceConcept
    763   {
    764     typedef typename _BackInsertionSequence::reference _Reference;
    765     typedef typename _BackInsertionSequence::const_reference _Const_reference;
    766 
    767     void __constraints() {
    768       __function_requires< _SequenceConcept<_BackInsertionSequence> >();
    769 
    770       __c.push_back(__t);
    771       __c.pop_back();
    772       _Reference __r _IsUnused = __c.back();
    773     }
    774     void __const_constraints(const _BackInsertionSequence& __c) {
    775       _Const_reference __r _IsUnused = __c.back();
    776     };
    777     _BackInsertionSequence __c;
    778     typename _BackInsertionSequence::value_type __t;
    779   };
    780 
    781 _GLIBCXX_END_NAMESPACE
    782 
    783 #undef _IsUnused
    784 
    785 #endif // _GLIBCXX_BOOST_CONCEPT_CHECK
    786 
    787 
    788