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