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