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