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