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