1*f8a1b7d9SAlexander Kabaev // -*- C++ -*-
2*f8a1b7d9SAlexander Kabaev 
3*f8a1b7d9SAlexander Kabaev // Copyright (C) 2004, 2005 Free Software Foundation, Inc.
400db7afdSDavid E. O'Brien //
5ffeaf689SAlexander Kabaev // This file is part of the GNU ISO C++ Library.  This library is free
6ffeaf689SAlexander Kabaev // software; you can redistribute it and/or modify it under the
7ffeaf689SAlexander Kabaev // terms of the GNU General Public License as published by the
8ffeaf689SAlexander Kabaev // Free Software Foundation; either version 2, or (at your option)
9ffeaf689SAlexander Kabaev // any later version.
10ffeaf689SAlexander Kabaev 
11ffeaf689SAlexander Kabaev // This library is distributed in the hope that it will be useful,
12ffeaf689SAlexander Kabaev // but WITHOUT ANY WARRANTY; without even the implied warranty of
13ffeaf689SAlexander Kabaev // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14ffeaf689SAlexander Kabaev // GNU General Public License for more details.
15ffeaf689SAlexander Kabaev 
16ffeaf689SAlexander Kabaev // You should have received a copy of the GNU General Public License along
17ffeaf689SAlexander Kabaev // with this library; see the file COPYING.  If not, write to the Free
18*f8a1b7d9SAlexander Kabaev // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19ffeaf689SAlexander Kabaev // USA.
20ffeaf689SAlexander Kabaev 
21ffeaf689SAlexander Kabaev // As a special exception, you may use this file as part of a free software
22ffeaf689SAlexander Kabaev // library without restriction.  Specifically, if other files instantiate
23ffeaf689SAlexander Kabaev // templates or use macros or inline functions from this file, or you compile
24ffeaf689SAlexander Kabaev // this file and link it with other files to produce an executable, this
25ffeaf689SAlexander Kabaev // file does not by itself cause the resulting executable to be covered by
26ffeaf689SAlexander Kabaev // the GNU General Public License.  This exception does not however
27ffeaf689SAlexander Kabaev // invalidate any other reasons why the executable file might be covered by
28ffeaf689SAlexander Kabaev // the GNU General Public License.
29ffeaf689SAlexander Kabaev 
3000db7afdSDavid E. O'Brien // (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify,
3100db7afdSDavid E. O'Brien // sell and distribute this software is granted provided this
3200db7afdSDavid E. O'Brien // copyright notice appears in all copies. This software is provided
3300db7afdSDavid E. O'Brien // "as is" without express or implied warranty, and with no claim as
3400db7afdSDavid E. O'Brien // to its suitability for any purpose.
3500db7afdSDavid E. O'Brien //
3600db7afdSDavid E. O'Brien 
3700db7afdSDavid E. O'Brien /** @file boost_concept_check.h
3800db7afdSDavid E. O'Brien  *  This is an internal header file, included by other library headers.
3900db7afdSDavid E. O'Brien  *  You should not attempt to use it directly.
4000db7afdSDavid E. O'Brien  */
4100db7afdSDavid E. O'Brien 
42*f8a1b7d9SAlexander Kabaev // GCC Note:  based on version 1.12.0 of the Boost library.
43*f8a1b7d9SAlexander Kabaev 
44ffeaf689SAlexander Kabaev #ifndef _BOOST_CONCEPT_CHECK_H
45ffeaf689SAlexander Kabaev #define _BOOST_CONCEPT_CHECK_H 1
4600db7afdSDavid E. O'Brien 
4700db7afdSDavid E. O'Brien #pragma GCC system_header
48ffeaf689SAlexander Kabaev 
4900db7afdSDavid E. O'Brien #include <cstddef>                // for ptrdiff_t, used next
5000db7afdSDavid E. O'Brien #include <bits/stl_iterator_base_types.h>    // for traits and tags
5100db7afdSDavid E. O'Brien #include <utility>                           // for pair<>
5200db7afdSDavid E. O'Brien 
_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)53*f8a1b7d9SAlexander Kabaev _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
5400db7afdSDavid E. O'Brien 
5500db7afdSDavid E. O'Brien #define _IsUnused __attribute__ ((__unused__))
5600db7afdSDavid E. O'Brien 
5700db7afdSDavid E. O'Brien // When the C-C code is in use, we would like this function to do as little
5800db7afdSDavid E. O'Brien // as possible at runtime, use as few resources as possible, and hopefully
5900db7afdSDavid E. O'Brien // be elided out of existence... hmmm.
6000db7afdSDavid E. O'Brien template <class _Concept>
6100db7afdSDavid E. O'Brien inline void __function_requires()
6200db7afdSDavid E. O'Brien {
6300db7afdSDavid E. O'Brien   void (_Concept::*__x)() _IsUnused = &_Concept::__constraints;
6400db7afdSDavid E. O'Brien }
6500db7afdSDavid E. O'Brien 
66ffeaf689SAlexander Kabaev // No definition: if this is referenced, there's a problem with
67ffeaf689SAlexander Kabaev // the instantiating type not being one of the required integer types.
68ffeaf689SAlexander Kabaev // Unfortunately, this results in a link-time error, not a compile-time error.
69ffeaf689SAlexander Kabaev void __error_type_must_be_an_integer_type();
70ffeaf689SAlexander Kabaev void __error_type_must_be_an_unsigned_integer_type();
71ffeaf689SAlexander Kabaev void __error_type_must_be_a_signed_integer_type();
7200db7afdSDavid E. O'Brien 
7300db7afdSDavid E. O'Brien // ??? Should the "concept_checking*" structs begin with more than _ ?
74ffeaf689SAlexander Kabaev #define _GLIBCXX_CLASS_REQUIRES(_type_var, _ns, _concept) \
7500db7afdSDavid E. O'Brien   typedef void (_ns::_concept <_type_var>::* _func##_type_var##_concept)(); \
7600db7afdSDavid E. O'Brien   template <_func##_type_var##_concept _Tp1> \
7700db7afdSDavid E. O'Brien   struct _concept_checking##_type_var##_concept { }; \
7800db7afdSDavid E. O'Brien   typedef _concept_checking##_type_var##_concept< \
7900db7afdSDavid E. O'Brien     &_ns::_concept <_type_var>::__constraints> \
8000db7afdSDavid E. O'Brien     _concept_checking_typedef##_type_var##_concept
8100db7afdSDavid E. O'Brien 
82ffeaf689SAlexander Kabaev #define _GLIBCXX_CLASS_REQUIRES2(_type_var1, _type_var2, _ns, _concept) \
8300db7afdSDavid E. O'Brien   typedef void (_ns::_concept <_type_var1,_type_var2>::* _func##_type_var1##_type_var2##_concept)(); \
8400db7afdSDavid E. O'Brien   template <_func##_type_var1##_type_var2##_concept _Tp1> \
8500db7afdSDavid E. O'Brien   struct _concept_checking##_type_var1##_type_var2##_concept { }; \
8600db7afdSDavid E. O'Brien   typedef _concept_checking##_type_var1##_type_var2##_concept< \
8700db7afdSDavid E. O'Brien     &_ns::_concept <_type_var1,_type_var2>::__constraints> \
8800db7afdSDavid E. O'Brien     _concept_checking_typedef##_type_var1##_type_var2##_concept
8900db7afdSDavid E. O'Brien 
90ffeaf689SAlexander Kabaev #define _GLIBCXX_CLASS_REQUIRES3(_type_var1, _type_var2, _type_var3, _ns, _concept) \
9100db7afdSDavid E. O'Brien   typedef void (_ns::_concept <_type_var1,_type_var2,_type_var3>::* _func##_type_var1##_type_var2##_type_var3##_concept)(); \
9200db7afdSDavid E. O'Brien   template <_func##_type_var1##_type_var2##_type_var3##_concept _Tp1> \
9300db7afdSDavid E. O'Brien   struct _concept_checking##_type_var1##_type_var2##_type_var3##_concept { }; \
9400db7afdSDavid E. O'Brien   typedef _concept_checking##_type_var1##_type_var2##_type_var3##_concept< \
9500db7afdSDavid E. O'Brien     &_ns::_concept <_type_var1,_type_var2,_type_var3>::__constraints>  \
9600db7afdSDavid E. O'Brien   _concept_checking_typedef##_type_var1##_type_var2##_type_var3##_concept
9700db7afdSDavid E. O'Brien 
98ffeaf689SAlexander Kabaev #define _GLIBCXX_CLASS_REQUIRES4(_type_var1, _type_var2, _type_var3, _type_var4, _ns, _concept) \
9900db7afdSDavid E. O'Brien   typedef void (_ns::_concept <_type_var1,_type_var2,_type_var3,_type_var4>::* _func##_type_var1##_type_var2##_type_var3##_type_var4##_concept)(); \
10000db7afdSDavid E. O'Brien   template <_func##_type_var1##_type_var2##_type_var3##_type_var4##_concept _Tp1> \
10100db7afdSDavid E. O'Brien   struct _concept_checking##_type_var1##_type_var2##_type_var3##_type_var4##_concept { }; \
10200db7afdSDavid E. O'Brien   typedef _concept_checking##_type_var1##_type_var2##_type_var3##_type_var4##_concept< \
10300db7afdSDavid E. O'Brien   &_ns::_concept <_type_var1,_type_var2,_type_var3,_type_var4>::__constraints> \
10400db7afdSDavid E. O'Brien     _concept_checking_typedef##_type_var1##_type_var2##_type_var3##_type_var4##_concept
10500db7afdSDavid E. O'Brien 
10600db7afdSDavid E. O'Brien 
10700db7afdSDavid E. O'Brien template <class _Tp1, class _Tp2>
10800db7afdSDavid E. O'Brien struct _Aux_require_same { };
10900db7afdSDavid E. O'Brien 
11000db7afdSDavid E. O'Brien template <class _Tp>
11100db7afdSDavid E. O'Brien struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; };
11200db7afdSDavid E. O'Brien 
11300db7afdSDavid E. O'Brien   template <class _Tp1, class _Tp2>
11400db7afdSDavid E. O'Brien   struct _SameTypeConcept
11500db7afdSDavid E. O'Brien   {
11600db7afdSDavid E. O'Brien     void __constraints() {
11700db7afdSDavid E. O'Brien       typedef typename _Aux_require_same<_Tp1, _Tp2>::_Type _Required;
11800db7afdSDavid E. O'Brien     }
11900db7afdSDavid E. O'Brien   };
12000db7afdSDavid E. O'Brien 
12100db7afdSDavid E. O'Brien   template <class _Tp>
12200db7afdSDavid E. O'Brien   struct _IntegerConcept {
12300db7afdSDavid E. O'Brien     void __constraints() {
12400db7afdSDavid E. O'Brien       __error_type_must_be_an_integer_type();
12500db7afdSDavid E. O'Brien     }
12600db7afdSDavid E. O'Brien   };
12700db7afdSDavid E. O'Brien   template <> struct _IntegerConcept<short> { void __constraints() {} };
12800db7afdSDavid E. O'Brien   template <> struct _IntegerConcept<unsigned short> { void __constraints(){} };
12900db7afdSDavid E. O'Brien   template <> struct _IntegerConcept<int> { void __constraints() {} };
13000db7afdSDavid E. O'Brien   template <> struct _IntegerConcept<unsigned int> { void __constraints() {} };
13100db7afdSDavid E. O'Brien   template <> struct _IntegerConcept<long> { void __constraints() {} };
13200db7afdSDavid E. O'Brien   template <> struct _IntegerConcept<unsigned long> { void __constraints() {} };
13300db7afdSDavid E. O'Brien   template <> struct _IntegerConcept<long long> { void __constraints() {} };
13400db7afdSDavid E. O'Brien   template <> struct _IntegerConcept<unsigned long long>
13500db7afdSDavid E. O'Brien                                                 { void __constraints() {} };
13600db7afdSDavid E. O'Brien 
13700db7afdSDavid E. O'Brien   template <class _Tp>
13800db7afdSDavid E. O'Brien   struct _SignedIntegerConcept {
13900db7afdSDavid E. O'Brien     void __constraints() {
14000db7afdSDavid E. O'Brien       __error_type_must_be_a_signed_integer_type();
14100db7afdSDavid E. O'Brien     }
14200db7afdSDavid E. O'Brien   };
14300db7afdSDavid E. O'Brien   template <> struct _SignedIntegerConcept<short> { void __constraints() {} };
14400db7afdSDavid E. O'Brien   template <> struct _SignedIntegerConcept<int> { void __constraints() {} };
14500db7afdSDavid E. O'Brien   template <> struct _SignedIntegerConcept<long> { void __constraints() {} };
14600db7afdSDavid E. O'Brien   template <> struct _SignedIntegerConcept<long long> { void __constraints(){}};
14700db7afdSDavid E. O'Brien 
14800db7afdSDavid E. O'Brien   template <class _Tp>
14900db7afdSDavid E. O'Brien   struct _UnsignedIntegerConcept {
15000db7afdSDavid E. O'Brien     void __constraints() {
15100db7afdSDavid E. O'Brien       __error_type_must_be_an_unsigned_integer_type();
15200db7afdSDavid E. O'Brien     }
15300db7afdSDavid E. O'Brien   };
15400db7afdSDavid E. O'Brien   template <> struct _UnsignedIntegerConcept<unsigned short>
15500db7afdSDavid E. O'Brien     { void __constraints() {} };
15600db7afdSDavid E. O'Brien   template <> struct _UnsignedIntegerConcept<unsigned int>
15700db7afdSDavid E. O'Brien     { void __constraints() {} };
15800db7afdSDavid E. O'Brien   template <> struct _UnsignedIntegerConcept<unsigned long>
15900db7afdSDavid E. O'Brien     { void __constraints() {} };
16000db7afdSDavid E. O'Brien   template <> struct _UnsignedIntegerConcept<unsigned long long>
16100db7afdSDavid E. O'Brien     { void __constraints() {} };
16200db7afdSDavid E. O'Brien 
16300db7afdSDavid E. O'Brien   //===========================================================================
16400db7afdSDavid E. O'Brien   // Basic Concepts
16500db7afdSDavid E. O'Brien 
16600db7afdSDavid E. O'Brien   template <class _Tp>
16700db7afdSDavid E. O'Brien   struct _DefaultConstructibleConcept
16800db7afdSDavid E. O'Brien   {
16900db7afdSDavid E. O'Brien     void __constraints() {
17000db7afdSDavid E. O'Brien       _Tp __a _IsUnused;                // require default constructor
17100db7afdSDavid E. O'Brien     }
17200db7afdSDavid E. O'Brien   };
17300db7afdSDavid E. O'Brien 
17400db7afdSDavid E. O'Brien   template <class _Tp>
17500db7afdSDavid E. O'Brien   struct _AssignableConcept
17600db7afdSDavid E. O'Brien   {
17700db7afdSDavid E. O'Brien     void __constraints() {
17800db7afdSDavid E. O'Brien       __a = __a;                        // require assignment operator
17900db7afdSDavid E. O'Brien       __const_constraints(__a);
18000db7afdSDavid E. O'Brien     }
18100db7afdSDavid E. O'Brien     void __const_constraints(const _Tp& __b) {
18200db7afdSDavid E. O'Brien       __a = __b;                   // const required for argument to assignment
18300db7afdSDavid E. O'Brien     }
18400db7afdSDavid E. O'Brien     _Tp __a;
1851b86b14eSAlexander Kabaev     // possibly should be "Tp* a;" and then dereference "a" in constraint
1861b86b14eSAlexander Kabaev     // functions?  present way would require a default ctor, i think...
18700db7afdSDavid E. O'Brien   };
18800db7afdSDavid E. O'Brien 
18900db7afdSDavid E. O'Brien   template <class _Tp>
19000db7afdSDavid E. O'Brien   struct _CopyConstructibleConcept
19100db7afdSDavid E. O'Brien   {
19200db7afdSDavid E. O'Brien     void __constraints() {
19300db7afdSDavid E. O'Brien       _Tp __a(__b);                     // require copy constructor
19400db7afdSDavid E. O'Brien       _Tp* __ptr _IsUnused = &__a;      // require address of operator
19500db7afdSDavid E. O'Brien       __const_constraints(__a);
19600db7afdSDavid E. O'Brien     }
19700db7afdSDavid E. O'Brien     void __const_constraints(const _Tp& __a) {
198ffeaf689SAlexander Kabaev       _Tp __c _IsUnused(__a);           // require const copy constructor
19900db7afdSDavid E. O'Brien       const _Tp* __ptr _IsUnused = &__a; // require const address of operator
20000db7afdSDavid E. O'Brien     }
20100db7afdSDavid E. O'Brien     _Tp __b;
20200db7afdSDavid E. O'Brien   };
20300db7afdSDavid E. O'Brien 
20400db7afdSDavid E. O'Brien   // The SGI STL version of Assignable requires copy constructor and operator=
20500db7afdSDavid E. O'Brien   template <class _Tp>
20600db7afdSDavid E. O'Brien   struct _SGIAssignableConcept
20700db7afdSDavid E. O'Brien   {
20800db7afdSDavid E. O'Brien     void __constraints() {
209ffeaf689SAlexander Kabaev       _Tp __b _IsUnused(__a);
21000db7afdSDavid E. O'Brien       __a = __a;                        // require assignment operator
21100db7afdSDavid E. O'Brien       __const_constraints(__a);
21200db7afdSDavid E. O'Brien     }
21300db7afdSDavid E. O'Brien     void __const_constraints(const _Tp& __b) {
214ffeaf689SAlexander Kabaev       _Tp __c _IsUnused(__b);
21500db7afdSDavid E. O'Brien       __a = __b;              // const required for argument to assignment
21600db7afdSDavid E. O'Brien     }
21700db7afdSDavid E. O'Brien     _Tp __a;
21800db7afdSDavid E. O'Brien   };
21900db7afdSDavid E. O'Brien 
22000db7afdSDavid E. O'Brien   template <class _From, class _To>
22100db7afdSDavid E. O'Brien   struct _ConvertibleConcept
22200db7afdSDavid E. O'Brien   {
22300db7afdSDavid E. O'Brien     void __constraints() {
22400db7afdSDavid E. O'Brien       _To __y _IsUnused = __x;
22500db7afdSDavid E. O'Brien     }
22600db7afdSDavid E. O'Brien     _From __x;
22700db7afdSDavid E. O'Brien   };
22800db7afdSDavid E. O'Brien 
22900db7afdSDavid E. O'Brien   // The C++ standard requirements for many concepts talk about return
23000db7afdSDavid E. O'Brien   // types that must be "convertible to bool".  The problem with this
23100db7afdSDavid E. O'Brien   // requirement is that it leaves the door open for evil proxies that
23200db7afdSDavid E. O'Brien   // define things like operator|| with strange return types.  Two
23300db7afdSDavid E. O'Brien   // possible solutions are:
23400db7afdSDavid E. O'Brien   // 1) require the return type to be exactly bool
23500db7afdSDavid E. O'Brien   // 2) stay with convertible to bool, and also
23600db7afdSDavid E. O'Brien   //    specify stuff about all the logical operators.
23700db7afdSDavid E. O'Brien   // For now we just test for convertible to bool.
23800db7afdSDavid E. O'Brien   template <class _Tp>
23900db7afdSDavid E. O'Brien   void __aux_require_boolean_expr(const _Tp& __t) {
24000db7afdSDavid E. O'Brien     bool __x _IsUnused = __t;
24100db7afdSDavid E. O'Brien   }
24200db7afdSDavid E. O'Brien 
24300db7afdSDavid E. O'Brien // FIXME
24400db7afdSDavid E. O'Brien   template <class _Tp>
24500db7afdSDavid E. O'Brien   struct _EqualityComparableConcept
24600db7afdSDavid E. O'Brien   {
24700db7afdSDavid E. O'Brien     void __constraints() {
24800db7afdSDavid E. O'Brien       __aux_require_boolean_expr(__a == __b);
24900db7afdSDavid E. O'Brien     }
25000db7afdSDavid E. O'Brien     _Tp __a, __b;
25100db7afdSDavid E. O'Brien   };
25200db7afdSDavid E. O'Brien 
25300db7afdSDavid E. O'Brien   template <class _Tp>
25400db7afdSDavid E. O'Brien   struct _LessThanComparableConcept
25500db7afdSDavid E. O'Brien   {
25600db7afdSDavid E. O'Brien     void __constraints() {
25700db7afdSDavid E. O'Brien       __aux_require_boolean_expr(__a < __b);
25800db7afdSDavid E. O'Brien     }
25900db7afdSDavid E. O'Brien     _Tp __a, __b;
26000db7afdSDavid E. O'Brien   };
26100db7afdSDavid E. O'Brien 
26200db7afdSDavid E. O'Brien   // This is equivalent to SGI STL's LessThanComparable.
26300db7afdSDavid E. O'Brien   template <class _Tp>
26400db7afdSDavid E. O'Brien   struct _ComparableConcept
26500db7afdSDavid E. O'Brien   {
26600db7afdSDavid E. O'Brien     void __constraints() {
26700db7afdSDavid E. O'Brien       __aux_require_boolean_expr(__a < __b);
26800db7afdSDavid E. O'Brien       __aux_require_boolean_expr(__a > __b);
26900db7afdSDavid E. O'Brien       __aux_require_boolean_expr(__a <= __b);
27000db7afdSDavid E. O'Brien       __aux_require_boolean_expr(__a >= __b);
27100db7afdSDavid E. O'Brien     }
27200db7afdSDavid E. O'Brien     _Tp __a, __b;
27300db7afdSDavid E. O'Brien   };
27400db7afdSDavid E. O'Brien 
275ffeaf689SAlexander Kabaev #define _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(_OP,_NAME) \
27600db7afdSDavid E. O'Brien   template <class _First, class _Second> \
27700db7afdSDavid E. O'Brien   struct _NAME { \
27800db7afdSDavid E. O'Brien     void __constraints() { (void)__constraints_(); } \
27900db7afdSDavid E. O'Brien     bool __constraints_() {  \
28000db7afdSDavid E. O'Brien       return  __a _OP __b; \
28100db7afdSDavid E. O'Brien     } \
28200db7afdSDavid E. O'Brien     _First __a; \
28300db7afdSDavid E. O'Brien     _Second __b; \
28400db7afdSDavid E. O'Brien   }
28500db7afdSDavid E. O'Brien 
286ffeaf689SAlexander Kabaev #define _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(_OP,_NAME) \
28700db7afdSDavid E. O'Brien   template <class _Ret, class _First, class _Second> \
28800db7afdSDavid E. O'Brien   struct _NAME { \
28900db7afdSDavid E. O'Brien     void __constraints() { (void)__constraints_(); } \
29000db7afdSDavid E. O'Brien     _Ret __constraints_() {  \
29100db7afdSDavid E. O'Brien       return __a _OP __b; \
29200db7afdSDavid E. O'Brien     } \
29300db7afdSDavid E. O'Brien     _First __a; \
29400db7afdSDavid E. O'Brien     _Second __b; \
29500db7afdSDavid E. O'Brien   }
29600db7afdSDavid E. O'Brien 
297ffeaf689SAlexander Kabaev   _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(==, _EqualOpConcept);
298ffeaf689SAlexander Kabaev   _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(!=, _NotEqualOpConcept);
299ffeaf689SAlexander Kabaev   _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<, _LessThanOpConcept);
300ffeaf689SAlexander Kabaev   _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<=, _LessEqualOpConcept);
301ffeaf689SAlexander Kabaev   _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>, _GreaterThanOpConcept);
302ffeaf689SAlexander Kabaev   _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>=, _GreaterEqualOpConcept);
30300db7afdSDavid E. O'Brien 
304ffeaf689SAlexander Kabaev   _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(+, _PlusOpConcept);
305ffeaf689SAlexander Kabaev   _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(*, _TimesOpConcept);
306ffeaf689SAlexander Kabaev   _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(/, _DivideOpConcept);
307ffeaf689SAlexander Kabaev   _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(-, _SubtractOpConcept);
308ffeaf689SAlexander Kabaev   _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(%, _ModOpConcept);
30900db7afdSDavid E. O'Brien 
310ffeaf689SAlexander Kabaev #undef _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT
311ffeaf689SAlexander Kabaev #undef _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT
31200db7afdSDavid E. O'Brien 
31300db7afdSDavid E. O'Brien   //===========================================================================
31400db7afdSDavid E. O'Brien   // Function Object Concepts
31500db7afdSDavid E. O'Brien 
31600db7afdSDavid E. O'Brien   template <class _Func, class _Return>
31700db7afdSDavid E. O'Brien   struct _GeneratorConcept
31800db7afdSDavid E. O'Brien   {
31900db7afdSDavid E. O'Brien     void __constraints() {
32000db7afdSDavid E. O'Brien       const _Return& __r _IsUnused = __f();// require operator() member function
32100db7afdSDavid E. O'Brien     }
32200db7afdSDavid E. O'Brien     _Func __f;
32300db7afdSDavid E. O'Brien   };
32400db7afdSDavid E. O'Brien 
32500db7afdSDavid E. O'Brien 
32600db7afdSDavid E. O'Brien   template <class _Func>
32700db7afdSDavid E. O'Brien   struct _GeneratorConcept<_Func,void>
32800db7afdSDavid E. O'Brien   {
32900db7afdSDavid E. O'Brien     void __constraints() {
33000db7afdSDavid E. O'Brien       __f();                            // require operator() member function
33100db7afdSDavid E. O'Brien     }
33200db7afdSDavid E. O'Brien     _Func __f;
33300db7afdSDavid E. O'Brien   };
33400db7afdSDavid E. O'Brien 
33500db7afdSDavid E. O'Brien   template <class _Func, class _Return, class _Arg>
33600db7afdSDavid E. O'Brien   struct _UnaryFunctionConcept
33700db7afdSDavid E. O'Brien   {
33800db7afdSDavid E. O'Brien     void __constraints() {
33900db7afdSDavid E. O'Brien       __r = __f(__arg);                  // require operator()
34000db7afdSDavid E. O'Brien     }
34100db7afdSDavid E. O'Brien     _Func __f;
34200db7afdSDavid E. O'Brien     _Arg __arg;
34300db7afdSDavid E. O'Brien     _Return __r;
34400db7afdSDavid E. O'Brien   };
34500db7afdSDavid E. O'Brien 
34600db7afdSDavid E. O'Brien   template <class _Func, class _Arg>
34700db7afdSDavid E. O'Brien   struct _UnaryFunctionConcept<_Func, void, _Arg> {
34800db7afdSDavid E. O'Brien     void __constraints() {
34900db7afdSDavid E. O'Brien       __f(__arg);                       // require operator()
35000db7afdSDavid E. O'Brien     }
35100db7afdSDavid E. O'Brien     _Func __f;
35200db7afdSDavid E. O'Brien     _Arg __arg;
35300db7afdSDavid E. O'Brien   };
35400db7afdSDavid E. O'Brien 
35500db7afdSDavid E. O'Brien   template <class _Func, class _Return, class _First, class _Second>
35600db7afdSDavid E. O'Brien   struct _BinaryFunctionConcept
35700db7afdSDavid E. O'Brien   {
35800db7afdSDavid E. O'Brien     void __constraints() {
35900db7afdSDavid E. O'Brien       __r = __f(__first, __second);     // require operator()
36000db7afdSDavid E. O'Brien     }
36100db7afdSDavid E. O'Brien     _Func __f;
36200db7afdSDavid E. O'Brien     _First __first;
36300db7afdSDavid E. O'Brien     _Second __second;
36400db7afdSDavid E. O'Brien     _Return __r;
36500db7afdSDavid E. O'Brien   };
36600db7afdSDavid E. O'Brien 
36700db7afdSDavid E. O'Brien   template <class _Func, class _First, class _Second>
36800db7afdSDavid E. O'Brien   struct _BinaryFunctionConcept<_Func, void, _First, _Second>
36900db7afdSDavid E. O'Brien   {
37000db7afdSDavid E. O'Brien     void __constraints() {
37100db7afdSDavid E. O'Brien       __f(__first, __second);           // require operator()
37200db7afdSDavid E. O'Brien     }
37300db7afdSDavid E. O'Brien     _Func __f;
37400db7afdSDavid E. O'Brien     _First __first;
37500db7afdSDavid E. O'Brien     _Second __second;
37600db7afdSDavid E. O'Brien   };
37700db7afdSDavid E. O'Brien 
37800db7afdSDavid E. O'Brien   template <class _Func, class _Arg>
37900db7afdSDavid E. O'Brien   struct _UnaryPredicateConcept
38000db7afdSDavid E. O'Brien   {
38100db7afdSDavid E. O'Brien     void __constraints() {
38200db7afdSDavid E. O'Brien       __aux_require_boolean_expr(__f(__arg)); // require op() returning bool
38300db7afdSDavid E. O'Brien     }
38400db7afdSDavid E. O'Brien     _Func __f;
38500db7afdSDavid E. O'Brien     _Arg __arg;
38600db7afdSDavid E. O'Brien   };
38700db7afdSDavid E. O'Brien 
38800db7afdSDavid E. O'Brien   template <class _Func, class _First, class _Second>
38900db7afdSDavid E. O'Brien   struct _BinaryPredicateConcept
39000db7afdSDavid E. O'Brien   {
39100db7afdSDavid E. O'Brien     void __constraints() {
39200db7afdSDavid E. O'Brien       __aux_require_boolean_expr(__f(__a, __b)); // require op() returning bool
39300db7afdSDavid E. O'Brien     }
39400db7afdSDavid E. O'Brien     _Func __f;
39500db7afdSDavid E. O'Brien     _First __a;
39600db7afdSDavid E. O'Brien     _Second __b;
39700db7afdSDavid E. O'Brien   };
39800db7afdSDavid E. O'Brien 
39900db7afdSDavid E. O'Brien   // use this when functor is used inside a container class like std::set
40000db7afdSDavid E. O'Brien   template <class _Func, class _First, class _Second>
40100db7afdSDavid E. O'Brien   struct _Const_BinaryPredicateConcept {
40200db7afdSDavid E. O'Brien     void __constraints() {
40300db7afdSDavid E. O'Brien       __const_constraints(__f);
40400db7afdSDavid E. O'Brien     }
40500db7afdSDavid E. O'Brien     void __const_constraints(const _Func& __fun) {
40600db7afdSDavid E. O'Brien       __function_requires<_BinaryPredicateConcept<_Func, _First, _Second> >();
40700db7afdSDavid E. O'Brien       // operator() must be a const member function
40800db7afdSDavid E. O'Brien       __aux_require_boolean_expr(__fun(__a, __b));
40900db7afdSDavid E. O'Brien     }
41000db7afdSDavid E. O'Brien     _Func __f;
41100db7afdSDavid E. O'Brien     _First __a;
41200db7afdSDavid E. O'Brien     _Second __b;
41300db7afdSDavid E. O'Brien   };
41400db7afdSDavid E. O'Brien 
41500db7afdSDavid E. O'Brien   //===========================================================================
41600db7afdSDavid E. O'Brien   // Iterator Concepts
41700db7afdSDavid E. O'Brien 
41800db7afdSDavid E. O'Brien   template <class _Tp>
41900db7afdSDavid E. O'Brien   struct _TrivialIteratorConcept
42000db7afdSDavid E. O'Brien   {
42100db7afdSDavid E. O'Brien     void __constraints() {
422ffeaf689SAlexander Kabaev //    __function_requires< _DefaultConstructibleConcept<_Tp> >();
42300db7afdSDavid E. O'Brien       __function_requires< _AssignableConcept<_Tp> >();
42400db7afdSDavid E. O'Brien       __function_requires< _EqualityComparableConcept<_Tp> >();
42500db7afdSDavid E. O'Brien //      typedef typename std::iterator_traits<_Tp>::value_type _V;
42600db7afdSDavid E. O'Brien       (void)*__i;                       // require dereference operator
42700db7afdSDavid E. O'Brien     }
42800db7afdSDavid E. O'Brien     _Tp __i;
42900db7afdSDavid E. O'Brien   };
43000db7afdSDavid E. O'Brien 
43100db7afdSDavid E. O'Brien   template <class _Tp>
43200db7afdSDavid E. O'Brien   struct _Mutable_TrivialIteratorConcept
43300db7afdSDavid E. O'Brien   {
43400db7afdSDavid E. O'Brien     void __constraints() {
43500db7afdSDavid E. O'Brien       __function_requires< _TrivialIteratorConcept<_Tp> >();
43600db7afdSDavid E. O'Brien       *__i = *__j;                      // require dereference and assignment
43700db7afdSDavid E. O'Brien     }
43800db7afdSDavid E. O'Brien     _Tp __i, __j;
43900db7afdSDavid E. O'Brien   };
44000db7afdSDavid E. O'Brien 
44100db7afdSDavid E. O'Brien   template <class _Tp>
44200db7afdSDavid E. O'Brien   struct _InputIteratorConcept
44300db7afdSDavid E. O'Brien   {
44400db7afdSDavid E. O'Brien     void __constraints() {
44500db7afdSDavid E. O'Brien       __function_requires< _TrivialIteratorConcept<_Tp> >();
44600db7afdSDavid E. O'Brien       // require iterator_traits typedef's
447ffeaf689SAlexander Kabaev       typedef typename std::iterator_traits<_Tp>::difference_type _Diff;
448ffeaf689SAlexander Kabaev //      __function_requires< _SignedIntegerConcept<_Diff> >();
449ffeaf689SAlexander Kabaev       typedef typename std::iterator_traits<_Tp>::reference _Ref;
45000db7afdSDavid E. O'Brien       typedef typename std::iterator_traits<_Tp>::pointer _Pt;
45100db7afdSDavid E. O'Brien       typedef typename std::iterator_traits<_Tp>::iterator_category _Cat;
45200db7afdSDavid E. O'Brien       __function_requires< _ConvertibleConcept<
45300db7afdSDavid E. O'Brien         typename std::iterator_traits<_Tp>::iterator_category,
45400db7afdSDavid E. O'Brien         std::input_iterator_tag> >();
45500db7afdSDavid E. O'Brien       ++__i;                            // require preincrement operator
45600db7afdSDavid E. O'Brien       __i++;                            // require postincrement operator
45700db7afdSDavid E. O'Brien     }
45800db7afdSDavid E. O'Brien     _Tp __i;
45900db7afdSDavid E. O'Brien   };
46000db7afdSDavid E. O'Brien 
46100db7afdSDavid E. O'Brien   template <class _Tp, class _ValueT>
46200db7afdSDavid E. O'Brien   struct _OutputIteratorConcept
46300db7afdSDavid E. O'Brien   {
46400db7afdSDavid E. O'Brien     void __constraints() {
46500db7afdSDavid E. O'Brien       __function_requires< _AssignableConcept<_Tp> >();
46600db7afdSDavid E. O'Brien       ++__i;                            // require preincrement operator
46700db7afdSDavid E. O'Brien       __i++;                            // require postincrement operator
46800db7afdSDavid E. O'Brien       *__i++ = __t;                     // require postincrement and assignment
46900db7afdSDavid E. O'Brien     }
47000db7afdSDavid E. O'Brien     _Tp __i;
47100db7afdSDavid E. O'Brien     _ValueT __t;
47200db7afdSDavid E. O'Brien   };
47300db7afdSDavid E. O'Brien 
47400db7afdSDavid E. O'Brien   template <class _Tp>
47500db7afdSDavid E. O'Brien   struct _ForwardIteratorConcept
47600db7afdSDavid E. O'Brien   {
47700db7afdSDavid E. O'Brien     void __constraints() {
47800db7afdSDavid E. O'Brien       __function_requires< _InputIteratorConcept<_Tp> >();
479ffeaf689SAlexander Kabaev       __function_requires< _DefaultConstructibleConcept<_Tp> >();
48000db7afdSDavid E. O'Brien       __function_requires< _ConvertibleConcept<
48100db7afdSDavid E. O'Brien         typename std::iterator_traits<_Tp>::iterator_category,
48200db7afdSDavid E. O'Brien         std::forward_iterator_tag> >();
483ffeaf689SAlexander Kabaev       typedef typename std::iterator_traits<_Tp>::reference _Ref;
484ffeaf689SAlexander Kabaev       _Ref __r _IsUnused = *__i;
48500db7afdSDavid E. O'Brien     }
48600db7afdSDavid E. O'Brien     _Tp __i;
48700db7afdSDavid E. O'Brien   };
48800db7afdSDavid E. O'Brien 
48900db7afdSDavid E. O'Brien   template <class _Tp>
49000db7afdSDavid E. O'Brien   struct _Mutable_ForwardIteratorConcept
49100db7afdSDavid E. O'Brien   {
49200db7afdSDavid E. O'Brien     void __constraints() {
49300db7afdSDavid E. O'Brien       __function_requires< _ForwardIteratorConcept<_Tp> >();
49400db7afdSDavid E. O'Brien       *__i++ = *__i;                    // require postincrement and assignment
49500db7afdSDavid E. O'Brien     }
49600db7afdSDavid E. O'Brien     _Tp __i;
49700db7afdSDavid E. O'Brien   };
49800db7afdSDavid E. O'Brien 
49900db7afdSDavid E. O'Brien   template <class _Tp>
50000db7afdSDavid E. O'Brien   struct _BidirectionalIteratorConcept
50100db7afdSDavid E. O'Brien   {
50200db7afdSDavid E. O'Brien     void __constraints() {
50300db7afdSDavid E. O'Brien       __function_requires< _ForwardIteratorConcept<_Tp> >();
50400db7afdSDavid E. O'Brien       __function_requires< _ConvertibleConcept<
50500db7afdSDavid E. O'Brien         typename std::iterator_traits<_Tp>::iterator_category,
50600db7afdSDavid E. O'Brien         std::bidirectional_iterator_tag> >();
50700db7afdSDavid E. O'Brien       --__i;                            // require predecrement operator
50800db7afdSDavid E. O'Brien       __i--;                            // require postdecrement operator
50900db7afdSDavid E. O'Brien     }
51000db7afdSDavid E. O'Brien     _Tp __i;
51100db7afdSDavid E. O'Brien   };
51200db7afdSDavid E. O'Brien 
51300db7afdSDavid E. O'Brien   template <class _Tp>
51400db7afdSDavid E. O'Brien   struct _Mutable_BidirectionalIteratorConcept
51500db7afdSDavid E. O'Brien   {
51600db7afdSDavid E. O'Brien     void __constraints() {
51700db7afdSDavid E. O'Brien       __function_requires< _BidirectionalIteratorConcept<_Tp> >();
51800db7afdSDavid E. O'Brien       __function_requires< _Mutable_ForwardIteratorConcept<_Tp> >();
51900db7afdSDavid E. O'Brien       *__i-- = *__i;                    // require postdecrement and assignment
52000db7afdSDavid E. O'Brien     }
52100db7afdSDavid E. O'Brien     _Tp __i;
52200db7afdSDavid E. O'Brien   };
52300db7afdSDavid E. O'Brien 
52400db7afdSDavid E. O'Brien 
52500db7afdSDavid E. O'Brien   template <class _Tp>
52600db7afdSDavid E. O'Brien   struct _RandomAccessIteratorConcept
52700db7afdSDavid E. O'Brien   {
52800db7afdSDavid E. O'Brien     void __constraints() {
52900db7afdSDavid E. O'Brien       __function_requires< _BidirectionalIteratorConcept<_Tp> >();
53000db7afdSDavid E. O'Brien       __function_requires< _ComparableConcept<_Tp> >();
53100db7afdSDavid E. O'Brien       __function_requires< _ConvertibleConcept<
53200db7afdSDavid E. O'Brien         typename std::iterator_traits<_Tp>::iterator_category,
53300db7afdSDavid E. O'Brien         std::random_access_iterator_tag> >();
534ffeaf689SAlexander Kabaev       // ??? We don't use _Ref, are we just checking for "referenceability"?
535ffeaf689SAlexander Kabaev       typedef typename std::iterator_traits<_Tp>::reference _Ref;
53600db7afdSDavid E. O'Brien 
53700db7afdSDavid E. O'Brien       __i += __n;                       // require assignment addition operator
53800db7afdSDavid E. O'Brien       __i = __i + __n; __i = __n + __i; // require addition with difference type
53900db7afdSDavid E. O'Brien       __i -= __n;                       // require assignment subtraction op
54000db7afdSDavid E. O'Brien       __i = __i - __n;                  // require subtraction with
54100db7afdSDavid E. O'Brien                                         //            difference type
54200db7afdSDavid E. O'Brien       __n = __i - __j;                  // require difference operator
54300db7afdSDavid E. O'Brien       (void)__i[__n];                   // require element access operator
54400db7afdSDavid E. O'Brien     }
54500db7afdSDavid E. O'Brien     _Tp __a, __b;
54600db7afdSDavid E. O'Brien     _Tp __i, __j;
54700db7afdSDavid E. O'Brien     typename std::iterator_traits<_Tp>::difference_type __n;
54800db7afdSDavid E. O'Brien   };
54900db7afdSDavid E. O'Brien 
55000db7afdSDavid E. O'Brien   template <class _Tp>
55100db7afdSDavid E. O'Brien   struct _Mutable_RandomAccessIteratorConcept
55200db7afdSDavid E. O'Brien   {
55300db7afdSDavid E. O'Brien     void __constraints() {
55400db7afdSDavid E. O'Brien       __function_requires< _RandomAccessIteratorConcept<_Tp> >();
55500db7afdSDavid E. O'Brien       __function_requires< _Mutable_BidirectionalIteratorConcept<_Tp> >();
55600db7afdSDavid E. O'Brien       __i[__n] = *__i;                  // require element access and assignment
55700db7afdSDavid E. O'Brien     }
55800db7afdSDavid E. O'Brien     _Tp __i;
55900db7afdSDavid E. O'Brien     typename std::iterator_traits<_Tp>::difference_type __n;
56000db7afdSDavid E. O'Brien   };
56100db7afdSDavid E. O'Brien 
56200db7afdSDavid E. O'Brien   //===========================================================================
56300db7afdSDavid E. O'Brien   // Container Concepts
56400db7afdSDavid E. O'Brien 
56500db7afdSDavid E. O'Brien   template <class _Container>
56600db7afdSDavid E. O'Brien   struct _ContainerConcept
56700db7afdSDavid E. O'Brien   {
56800db7afdSDavid E. O'Brien     typedef typename _Container::value_type _Value_type;
56900db7afdSDavid E. O'Brien     typedef typename _Container::difference_type _Difference_type;
57000db7afdSDavid E. O'Brien     typedef typename _Container::size_type _Size_type;
57100db7afdSDavid E. O'Brien     typedef typename _Container::const_reference _Const_reference;
57200db7afdSDavid E. O'Brien     typedef typename _Container::const_pointer _Const_pointer;
57300db7afdSDavid E. O'Brien     typedef typename _Container::const_iterator _Const_iterator;
57400db7afdSDavid E. O'Brien 
57500db7afdSDavid E. O'Brien     void __constraints() {
57600db7afdSDavid E. O'Brien       __function_requires< _InputIteratorConcept<_Const_iterator> >();
57700db7afdSDavid E. O'Brien       __function_requires< _AssignableConcept<_Container> >();
57800db7afdSDavid E. O'Brien       const _Container __c;
57900db7afdSDavid E. O'Brien       __i = __c.begin();
58000db7afdSDavid E. O'Brien       __i = __c.end();
58100db7afdSDavid E. O'Brien       __n = __c.size();
58200db7afdSDavid E. O'Brien       __n = __c.max_size();
58300db7afdSDavid E. O'Brien       __b = __c.empty();
58400db7afdSDavid E. O'Brien     }
58500db7afdSDavid E. O'Brien     bool __b;
58600db7afdSDavid E. O'Brien     _Const_iterator __i;
58700db7afdSDavid E. O'Brien     _Size_type __n;
58800db7afdSDavid E. O'Brien   };
58900db7afdSDavid E. O'Brien 
59000db7afdSDavid E. O'Brien   template <class _Container>
59100db7afdSDavid E. O'Brien   struct _Mutable_ContainerConcept
59200db7afdSDavid E. O'Brien   {
59300db7afdSDavid E. O'Brien     typedef typename _Container::value_type _Value_type;
59400db7afdSDavid E. O'Brien     typedef typename _Container::reference _Reference;
59500db7afdSDavid E. O'Brien     typedef typename _Container::iterator _Iterator;
59600db7afdSDavid E. O'Brien     typedef typename _Container::pointer _Pointer;
59700db7afdSDavid E. O'Brien 
59800db7afdSDavid E. O'Brien     void __constraints() {
59900db7afdSDavid E. O'Brien       __function_requires< _ContainerConcept<_Container> >();
60000db7afdSDavid E. O'Brien       __function_requires< _AssignableConcept<_Value_type> >();
60100db7afdSDavid E. O'Brien       __function_requires< _InputIteratorConcept<_Iterator> >();
60200db7afdSDavid E. O'Brien 
60300db7afdSDavid E. O'Brien       __i = __c.begin();
60400db7afdSDavid E. O'Brien       __i = __c.end();
60500db7afdSDavid E. O'Brien       __c.swap(__c2);
60600db7afdSDavid E. O'Brien     }
60700db7afdSDavid E. O'Brien     _Iterator __i;
60800db7afdSDavid E. O'Brien     _Container __c, __c2;
60900db7afdSDavid E. O'Brien   };
61000db7afdSDavid E. O'Brien 
61100db7afdSDavid E. O'Brien   template <class _ForwardContainer>
61200db7afdSDavid E. O'Brien   struct _ForwardContainerConcept
61300db7afdSDavid E. O'Brien   {
61400db7afdSDavid E. O'Brien     void __constraints() {
61500db7afdSDavid E. O'Brien       __function_requires< _ContainerConcept<_ForwardContainer> >();
61600db7afdSDavid E. O'Brien       typedef typename _ForwardContainer::const_iterator _Const_iterator;
61700db7afdSDavid E. O'Brien       __function_requires< _ForwardIteratorConcept<_Const_iterator> >();
61800db7afdSDavid E. O'Brien     }
61900db7afdSDavid E. O'Brien   };
62000db7afdSDavid E. O'Brien 
62100db7afdSDavid E. O'Brien   template <class _ForwardContainer>
62200db7afdSDavid E. O'Brien   struct _Mutable_ForwardContainerConcept
62300db7afdSDavid E. O'Brien   {
62400db7afdSDavid E. O'Brien     void __constraints() {
62500db7afdSDavid E. O'Brien       __function_requires< _ForwardContainerConcept<_ForwardContainer> >();
62600db7afdSDavid E. O'Brien       __function_requires< _Mutable_ContainerConcept<_ForwardContainer> >();
62700db7afdSDavid E. O'Brien       typedef typename _ForwardContainer::iterator _Iterator;
62800db7afdSDavid E. O'Brien       __function_requires< _Mutable_ForwardIteratorConcept<_Iterator> >();
62900db7afdSDavid E. O'Brien     }
63000db7afdSDavid E. O'Brien   };
63100db7afdSDavid E. O'Brien 
63200db7afdSDavid E. O'Brien   template <class _ReversibleContainer>
63300db7afdSDavid E. O'Brien   struct _ReversibleContainerConcept
63400db7afdSDavid E. O'Brien   {
63500db7afdSDavid E. O'Brien     typedef typename _ReversibleContainer::const_iterator _Const_iterator;
63600db7afdSDavid E. O'Brien     typedef typename _ReversibleContainer::const_reverse_iterator
63700db7afdSDavid E. O'Brien       _Const_reverse_iterator;
63800db7afdSDavid E. O'Brien 
63900db7afdSDavid E. O'Brien     void __constraints() {
64000db7afdSDavid E. O'Brien       __function_requires< _ForwardContainerConcept<_ReversibleContainer> >();
64100db7afdSDavid E. O'Brien       __function_requires< _BidirectionalIteratorConcept<_Const_iterator> >();
64200db7afdSDavid E. O'Brien       __function_requires<
64300db7afdSDavid E. O'Brien         _BidirectionalIteratorConcept<_Const_reverse_iterator> >();
64400db7afdSDavid E. O'Brien 
64500db7afdSDavid E. O'Brien       const _ReversibleContainer __c;
64600db7afdSDavid E. O'Brien       _Const_reverse_iterator __i = __c.rbegin();
64700db7afdSDavid E. O'Brien       __i = __c.rend();
64800db7afdSDavid E. O'Brien     }
64900db7afdSDavid E. O'Brien   };
65000db7afdSDavid E. O'Brien 
65100db7afdSDavid E. O'Brien   template <class _ReversibleContainer>
65200db7afdSDavid E. O'Brien   struct _Mutable_ReversibleContainerConcept
65300db7afdSDavid E. O'Brien   {
65400db7afdSDavid E. O'Brien     typedef typename _ReversibleContainer::iterator _Iterator;
65500db7afdSDavid E. O'Brien     typedef typename _ReversibleContainer::reverse_iterator _Reverse_iterator;
65600db7afdSDavid E. O'Brien 
65700db7afdSDavid E. O'Brien     void __constraints() {
65800db7afdSDavid E. O'Brien       __function_requires<_ReversibleContainerConcept<_ReversibleContainer> >();
65900db7afdSDavid E. O'Brien       __function_requires<
66000db7afdSDavid E. O'Brien         _Mutable_ForwardContainerConcept<_ReversibleContainer> >();
66100db7afdSDavid E. O'Brien       __function_requires<_Mutable_BidirectionalIteratorConcept<_Iterator> >();
66200db7afdSDavid E. O'Brien       __function_requires<
66300db7afdSDavid E. O'Brien         _Mutable_BidirectionalIteratorConcept<_Reverse_iterator> >();
66400db7afdSDavid E. O'Brien 
66500db7afdSDavid E. O'Brien       _Reverse_iterator __i = __c.rbegin();
66600db7afdSDavid E. O'Brien       __i = __c.rend();
66700db7afdSDavid E. O'Brien     }
66800db7afdSDavid E. O'Brien     _ReversibleContainer __c;
66900db7afdSDavid E. O'Brien   };
67000db7afdSDavid E. O'Brien 
67100db7afdSDavid E. O'Brien   template <class _RandomAccessContainer>
67200db7afdSDavid E. O'Brien   struct _RandomAccessContainerConcept
67300db7afdSDavid E. O'Brien   {
67400db7afdSDavid E. O'Brien     typedef typename _RandomAccessContainer::size_type _Size_type;
67500db7afdSDavid E. O'Brien     typedef typename _RandomAccessContainer::const_reference _Const_reference;
67600db7afdSDavid E. O'Brien     typedef typename _RandomAccessContainer::const_iterator _Const_iterator;
67700db7afdSDavid E. O'Brien     typedef typename _RandomAccessContainer::const_reverse_iterator
67800db7afdSDavid E. O'Brien       _Const_reverse_iterator;
67900db7afdSDavid E. O'Brien 
68000db7afdSDavid E. O'Brien     void __constraints() {
68100db7afdSDavid E. O'Brien       __function_requires<
68200db7afdSDavid E. O'Brien         _ReversibleContainerConcept<_RandomAccessContainer> >();
68300db7afdSDavid E. O'Brien       __function_requires< _RandomAccessIteratorConcept<_Const_iterator> >();
68400db7afdSDavid E. O'Brien       __function_requires<
68500db7afdSDavid E. O'Brien         _RandomAccessIteratorConcept<_Const_reverse_iterator> >();
68600db7afdSDavid E. O'Brien 
68700db7afdSDavid E. O'Brien       const _RandomAccessContainer __c;
68800db7afdSDavid E. O'Brien       _Const_reference __r _IsUnused = __c[__n];
68900db7afdSDavid E. O'Brien     }
69000db7afdSDavid E. O'Brien     _Size_type __n;
69100db7afdSDavid E. O'Brien   };
69200db7afdSDavid E. O'Brien 
69300db7afdSDavid E. O'Brien   template <class _RandomAccessContainer>
69400db7afdSDavid E. O'Brien   struct _Mutable_RandomAccessContainerConcept
69500db7afdSDavid E. O'Brien   {
69600db7afdSDavid E. O'Brien     typedef typename _RandomAccessContainer::size_type _Size_type;
69700db7afdSDavid E. O'Brien     typedef typename _RandomAccessContainer::reference _Reference;
69800db7afdSDavid E. O'Brien     typedef typename _RandomAccessContainer::iterator _Iterator;
69900db7afdSDavid E. O'Brien     typedef typename _RandomAccessContainer::reverse_iterator _Reverse_iterator;
70000db7afdSDavid E. O'Brien 
70100db7afdSDavid E. O'Brien     void __constraints() {
70200db7afdSDavid E. O'Brien       __function_requires<
70300db7afdSDavid E. O'Brien         _RandomAccessContainerConcept<_RandomAccessContainer> >();
70400db7afdSDavid E. O'Brien       __function_requires<
70500db7afdSDavid E. O'Brien         _Mutable_ReversibleContainerConcept<_RandomAccessContainer> >();
70600db7afdSDavid E. O'Brien       __function_requires< _Mutable_RandomAccessIteratorConcept<_Iterator> >();
70700db7afdSDavid E. O'Brien       __function_requires<
70800db7afdSDavid E. O'Brien         _Mutable_RandomAccessIteratorConcept<_Reverse_iterator> >();
70900db7afdSDavid E. O'Brien 
71000db7afdSDavid E. O'Brien       _Reference __r _IsUnused = __c[__i];
71100db7afdSDavid E. O'Brien     }
71200db7afdSDavid E. O'Brien     _Size_type __i;
71300db7afdSDavid E. O'Brien     _RandomAccessContainer __c;
71400db7afdSDavid E. O'Brien   };
71500db7afdSDavid E. O'Brien 
71600db7afdSDavid E. O'Brien   // A Sequence is inherently mutable
71700db7afdSDavid E. O'Brien   template <class _Sequence>
71800db7afdSDavid E. O'Brien   struct _SequenceConcept
71900db7afdSDavid E. O'Brien   {
72000db7afdSDavid E. O'Brien     typedef typename _Sequence::reference _Reference;
72100db7afdSDavid E. O'Brien     typedef typename _Sequence::const_reference _Const_reference;
72200db7afdSDavid E. O'Brien 
72300db7afdSDavid E. O'Brien     void __constraints() {
72400db7afdSDavid E. O'Brien       // Matt Austern's book puts DefaultConstructible here, the C++
72500db7afdSDavid E. O'Brien       // standard places it in Container
72600db7afdSDavid E. O'Brien       //    function_requires< DefaultConstructible<Sequence> >();
72700db7afdSDavid E. O'Brien       __function_requires< _Mutable_ForwardContainerConcept<_Sequence> >();
72800db7afdSDavid E. O'Brien       __function_requires< _DefaultConstructibleConcept<_Sequence> >();
72900db7afdSDavid E. O'Brien 
73000db7afdSDavid E. O'Brien       _Sequence
731f260e61bSAlexander Kabaev 	__c _IsUnused(__n, __t),
732f260e61bSAlexander Kabaev         __c2 _IsUnused(__first, __last);
73300db7afdSDavid E. O'Brien 
73400db7afdSDavid E. O'Brien       __c.insert(__p, __t);
73500db7afdSDavid E. O'Brien       __c.insert(__p, __n, __t);
73600db7afdSDavid E. O'Brien       __c.insert(__p, __first, __last);
73700db7afdSDavid E. O'Brien 
73800db7afdSDavid E. O'Brien       __c.erase(__p);
73900db7afdSDavid E. O'Brien       __c.erase(__p, __q);
74000db7afdSDavid E. O'Brien 
74100db7afdSDavid E. O'Brien       _Reference __r _IsUnused = __c.front();
74200db7afdSDavid E. O'Brien 
74300db7afdSDavid E. O'Brien       __const_constraints(__c);
74400db7afdSDavid E. O'Brien     }
74500db7afdSDavid E. O'Brien     void __const_constraints(const _Sequence& __c) {
74600db7afdSDavid E. O'Brien       _Const_reference __r _IsUnused = __c.front();
74700db7afdSDavid E. O'Brien     }
74800db7afdSDavid E. O'Brien     typename _Sequence::value_type __t;
74900db7afdSDavid E. O'Brien     typename _Sequence::size_type __n;
75000db7afdSDavid E. O'Brien     typename _Sequence::value_type *__first, *__last;
75100db7afdSDavid E. O'Brien     typename _Sequence::iterator __p, __q;
75200db7afdSDavid E. O'Brien   };
75300db7afdSDavid E. O'Brien 
75400db7afdSDavid E. O'Brien   template <class _FrontInsertionSequence>
75500db7afdSDavid E. O'Brien   struct _FrontInsertionSequenceConcept
75600db7afdSDavid E. O'Brien   {
75700db7afdSDavid E. O'Brien     void __constraints() {
75800db7afdSDavid E. O'Brien       __function_requires< _SequenceConcept<_FrontInsertionSequence> >();
75900db7afdSDavid E. O'Brien 
76000db7afdSDavid E. O'Brien       __c.push_front(__t);
76100db7afdSDavid E. O'Brien       __c.pop_front();
76200db7afdSDavid E. O'Brien     }
76300db7afdSDavid E. O'Brien     _FrontInsertionSequence __c;
76400db7afdSDavid E. O'Brien     typename _FrontInsertionSequence::value_type __t;
76500db7afdSDavid E. O'Brien   };
76600db7afdSDavid E. O'Brien 
76700db7afdSDavid E. O'Brien   template <class _BackInsertionSequence>
76800db7afdSDavid E. O'Brien   struct _BackInsertionSequenceConcept
76900db7afdSDavid E. O'Brien   {
77000db7afdSDavid E. O'Brien     typedef typename _BackInsertionSequence::reference _Reference;
77100db7afdSDavid E. O'Brien     typedef typename _BackInsertionSequence::const_reference _Const_reference;
77200db7afdSDavid E. O'Brien 
77300db7afdSDavid E. O'Brien     void __constraints() {
77400db7afdSDavid E. O'Brien       __function_requires< _SequenceConcept<_BackInsertionSequence> >();
77500db7afdSDavid E. O'Brien 
77600db7afdSDavid E. O'Brien       __c.push_back(__t);
77700db7afdSDavid E. O'Brien       __c.pop_back();
77800db7afdSDavid E. O'Brien       _Reference __r _IsUnused = __c.back();
77900db7afdSDavid E. O'Brien     }
78000db7afdSDavid E. O'Brien     void __const_constraints(const _BackInsertionSequence& __c) {
78100db7afdSDavid E. O'Brien       _Const_reference __r _IsUnused = __c.back();
78200db7afdSDavid E. O'Brien     };
78300db7afdSDavid E. O'Brien     _BackInsertionSequence __c;
78400db7afdSDavid E. O'Brien     typename _BackInsertionSequence::value_type __t;
78500db7afdSDavid E. O'Brien   };
78600db7afdSDavid E. O'Brien 
78700db7afdSDavid E. O'Brien   template <class _AssociativeContainer>
78800db7afdSDavid E. O'Brien   struct _AssociativeContainerConcept
78900db7afdSDavid E. O'Brien   {
79000db7afdSDavid E. O'Brien     void __constraints() {
79100db7afdSDavid E. O'Brien       __function_requires< _ForwardContainerConcept<_AssociativeContainer> >();
79200db7afdSDavid E. O'Brien       __function_requires<
79300db7afdSDavid E. O'Brien         _DefaultConstructibleConcept<_AssociativeContainer> >();
79400db7afdSDavid E. O'Brien 
79500db7afdSDavid E. O'Brien       __i = __c.find(__k);
79600db7afdSDavid E. O'Brien       __r = __c.equal_range(__k);
79700db7afdSDavid E. O'Brien       __c.erase(__k);
79800db7afdSDavid E. O'Brien       __c.erase(__i);
79900db7afdSDavid E. O'Brien       __c.erase(__r.first, __r.second);
80000db7afdSDavid E. O'Brien       __const_constraints(__c);
80100db7afdSDavid E. O'Brien     }
80200db7afdSDavid E. O'Brien     void __const_constraints(const _AssociativeContainer& __c) {
80300db7afdSDavid E. O'Brien       __ci = __c.find(__k);
80400db7afdSDavid E. O'Brien       __n = __c.count(__k);
80500db7afdSDavid E. O'Brien       __cr = __c.equal_range(__k);
80600db7afdSDavid E. O'Brien     }
80700db7afdSDavid E. O'Brien     typedef typename _AssociativeContainer::iterator _Iterator;
80800db7afdSDavid E. O'Brien     typedef typename _AssociativeContainer::const_iterator _Const_iterator;
80900db7afdSDavid E. O'Brien 
81000db7afdSDavid E. O'Brien     _AssociativeContainer __c;
81100db7afdSDavid E. O'Brien     _Iterator __i;
81200db7afdSDavid E. O'Brien     std::pair<_Iterator,_Iterator> __r;
81300db7afdSDavid E. O'Brien     _Const_iterator __ci;
81400db7afdSDavid E. O'Brien     std::pair<_Const_iterator,_Const_iterator> __cr;
81500db7afdSDavid E. O'Brien     typename _AssociativeContainer::key_type __k;
81600db7afdSDavid E. O'Brien     typename _AssociativeContainer::size_type __n;
81700db7afdSDavid E. O'Brien   };
81800db7afdSDavid E. O'Brien 
81900db7afdSDavid E. O'Brien   template <class _UniqueAssociativeContainer>
82000db7afdSDavid E. O'Brien   struct _UniqueAssociativeContainerConcept
82100db7afdSDavid E. O'Brien   {
82200db7afdSDavid E. O'Brien     void __constraints() {
82300db7afdSDavid E. O'Brien       __function_requires<
82400db7afdSDavid E. O'Brien         _AssociativeContainerConcept<_UniqueAssociativeContainer> >();
82500db7afdSDavid E. O'Brien 
82600db7afdSDavid E. O'Brien       _UniqueAssociativeContainer __c(__first, __last);
82700db7afdSDavid E. O'Brien 
82800db7afdSDavid E. O'Brien       __pos_flag = __c.insert(__t);
82900db7afdSDavid E. O'Brien       __c.insert(__first, __last);
83000db7afdSDavid E. O'Brien     }
83100db7afdSDavid E. O'Brien     std::pair<typename _UniqueAssociativeContainer::iterator, bool> __pos_flag;
83200db7afdSDavid E. O'Brien     typename _UniqueAssociativeContainer::value_type __t;
83300db7afdSDavid E. O'Brien     typename _UniqueAssociativeContainer::value_type *__first, *__last;
83400db7afdSDavid E. O'Brien   };
83500db7afdSDavid E. O'Brien 
83600db7afdSDavid E. O'Brien   template <class _MultipleAssociativeContainer>
83700db7afdSDavid E. O'Brien   struct _MultipleAssociativeContainerConcept
83800db7afdSDavid E. O'Brien   {
83900db7afdSDavid E. O'Brien     void __constraints() {
84000db7afdSDavid E. O'Brien       __function_requires<
84100db7afdSDavid E. O'Brien         _AssociativeContainerConcept<_MultipleAssociativeContainer> >();
84200db7afdSDavid E. O'Brien 
84300db7afdSDavid E. O'Brien       _MultipleAssociativeContainer __c(__first, __last);
84400db7afdSDavid E. O'Brien 
84500db7afdSDavid E. O'Brien       __pos = __c.insert(__t);
84600db7afdSDavid E. O'Brien       __c.insert(__first, __last);
84700db7afdSDavid E. O'Brien 
84800db7afdSDavid E. O'Brien     }
849ffeaf689SAlexander Kabaev     typename _MultipleAssociativeContainer::iterator __pos;
85000db7afdSDavid E. O'Brien     typename _MultipleAssociativeContainer::value_type __t;
85100db7afdSDavid E. O'Brien     typename _MultipleAssociativeContainer::value_type *__first, *__last;
85200db7afdSDavid E. O'Brien   };
85300db7afdSDavid E. O'Brien 
85400db7afdSDavid E. O'Brien   template <class _SimpleAssociativeContainer>
85500db7afdSDavid E. O'Brien   struct _SimpleAssociativeContainerConcept
85600db7afdSDavid E. O'Brien   {
85700db7afdSDavid E. O'Brien     void __constraints() {
85800db7afdSDavid E. O'Brien       __function_requires<
85900db7afdSDavid E. O'Brien         _AssociativeContainerConcept<_SimpleAssociativeContainer> >();
86000db7afdSDavid E. O'Brien       typedef typename _SimpleAssociativeContainer::key_type _Key_type;
86100db7afdSDavid E. O'Brien       typedef typename _SimpleAssociativeContainer::value_type _Value_type;
86200db7afdSDavid E. O'Brien       typedef typename _Aux_require_same<_Key_type, _Value_type>::_Type
863ffeaf689SAlexander Kabaev         _Required;
86400db7afdSDavid E. O'Brien     }
86500db7afdSDavid E. O'Brien   };
86600db7afdSDavid E. O'Brien 
86700db7afdSDavid E. O'Brien   template <class _SimpleAssociativeContainer>
86800db7afdSDavid E. O'Brien   struct _PairAssociativeContainerConcept
86900db7afdSDavid E. O'Brien   {
87000db7afdSDavid E. O'Brien     void __constraints() {
87100db7afdSDavid E. O'Brien       __function_requires<
87200db7afdSDavid E. O'Brien         _AssociativeContainerConcept<_SimpleAssociativeContainer> >();
87300db7afdSDavid E. O'Brien       typedef typename _SimpleAssociativeContainer::key_type _Key_type;
87400db7afdSDavid E. O'Brien       typedef typename _SimpleAssociativeContainer::value_type _Value_type;
87500db7afdSDavid E. O'Brien       typedef typename _SimpleAssociativeContainer::mapped_type _Mapped_type;
87600db7afdSDavid E. O'Brien       typedef std::pair<const _Key_type, _Mapped_type> _Required_value_type;
87700db7afdSDavid E. O'Brien       typedef typename _Aux_require_same<_Value_type,
87800db7afdSDavid E. O'Brien         _Required_value_type>::_Type _Required;
87900db7afdSDavid E. O'Brien     }
88000db7afdSDavid E. O'Brien   };
88100db7afdSDavid E. O'Brien 
88200db7afdSDavid E. O'Brien   template <class _SortedAssociativeContainer>
88300db7afdSDavid E. O'Brien   struct _SortedAssociativeContainerConcept
88400db7afdSDavid E. O'Brien   {
88500db7afdSDavid E. O'Brien     void __constraints() {
88600db7afdSDavid E. O'Brien       __function_requires<
88700db7afdSDavid E. O'Brien         _AssociativeContainerConcept<_SortedAssociativeContainer> >();
88800db7afdSDavid E. O'Brien       __function_requires<
88900db7afdSDavid E. O'Brien         _ReversibleContainerConcept<_SortedAssociativeContainer> >();
89000db7afdSDavid E. O'Brien 
89100db7afdSDavid E. O'Brien       _SortedAssociativeContainer
892ffeaf689SAlexander Kabaev         __c _IsUnused(__kc),
893ffeaf689SAlexander Kabaev         __c2 _IsUnused(__first, __last),
894ffeaf689SAlexander Kabaev         __c3 _IsUnused(__first, __last, __kc);
89500db7afdSDavid E. O'Brien 
89600db7afdSDavid E. O'Brien       __p = __c.upper_bound(__k);
89700db7afdSDavid E. O'Brien       __p = __c.lower_bound(__k);
89800db7afdSDavid E. O'Brien       __r = __c.equal_range(__k);
89900db7afdSDavid E. O'Brien 
90000db7afdSDavid E. O'Brien       __c.insert(__p, __t);
90100db7afdSDavid E. O'Brien     }
90200db7afdSDavid E. O'Brien     void __const_constraints(const _SortedAssociativeContainer& __c) {
90300db7afdSDavid E. O'Brien       __kc = __c.key_comp();
90400db7afdSDavid E. O'Brien       __vc = __c.value_comp();
90500db7afdSDavid E. O'Brien 
90600db7afdSDavid E. O'Brien       __cp = __c.upper_bound(__k);
90700db7afdSDavid E. O'Brien       __cp = __c.lower_bound(__k);
90800db7afdSDavid E. O'Brien       __cr = __c.equal_range(__k);
90900db7afdSDavid E. O'Brien     }
91000db7afdSDavid E. O'Brien     typename _SortedAssociativeContainer::key_compare __kc;
91100db7afdSDavid E. O'Brien     typename _SortedAssociativeContainer::value_compare __vc;
91200db7afdSDavid E. O'Brien     typename _SortedAssociativeContainer::value_type __t;
91300db7afdSDavid E. O'Brien     typename _SortedAssociativeContainer::key_type __k;
91400db7afdSDavid E. O'Brien     typedef typename _SortedAssociativeContainer::iterator _Iterator;
91500db7afdSDavid E. O'Brien     typedef typename _SortedAssociativeContainer::const_iterator
91600db7afdSDavid E. O'Brien       _Const_iterator;
91700db7afdSDavid E. O'Brien 
91800db7afdSDavid E. O'Brien     _Iterator __p;
91900db7afdSDavid E. O'Brien     _Const_iterator __cp;
92000db7afdSDavid E. O'Brien     std::pair<_Iterator,_Iterator> __r;
92100db7afdSDavid E. O'Brien     std::pair<_Const_iterator,_Const_iterator> __cr;
92200db7afdSDavid E. O'Brien     typename _SortedAssociativeContainer::value_type *__first, *__last;
92300db7afdSDavid E. O'Brien   };
92400db7afdSDavid E. O'Brien 
92500db7afdSDavid E. O'Brien   // HashedAssociativeContainer
92600db7afdSDavid E. O'Brien 
927*f8a1b7d9SAlexander Kabaev _GLIBCXX_END_NAMESPACE
92800db7afdSDavid E. O'Brien 
92900db7afdSDavid E. O'Brien #undef _IsUnused
93000db7afdSDavid E. O'Brien 
931ffeaf689SAlexander Kabaev #endif // _GLIBCXX_BOOST_CONCEPT_CHECK
93200db7afdSDavid E. O'Brien 
93300db7afdSDavid E. O'Brien 
934