Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

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