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