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