xref: /netbsd-src/external/gpl3/gcc/dist/libstdc++-v3/include/bits/boost_concept_check.h (revision e9e6e0f6fbc36b8de7586170291cf5fc97cab8b6)
1 // -*- C++ -*-
2 
3 // Copyright (C) 2004-2022 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 
_GLIBCXX_VISIBILITY(default)47 namespace std  _GLIBCXX_VISIBILITY(default)
48 {
49 _GLIBCXX_BEGIN_NAMESPACE_VERSION
50 _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
51   struct _Bit_iterator;
52   struct _Bit_const_iterator;
53 _GLIBCXX_END_NAMESPACE_CONTAINER
54 _GLIBCXX_END_NAMESPACE_VERSION
55 }
56 
57 namespace __gnu_debug
58 {
59   template<typename _Iterator, typename _Sequence, typename _Category>
60     class _Safe_iterator;
61 }
62 
_GLIBCXX_VISIBILITY(default)63 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
64 {
65 _GLIBCXX_BEGIN_NAMESPACE_VERSION
66 
67 #pragma GCC diagnostic push
68 #pragma GCC diagnostic ignored "-Wunused-local-typedefs"
69 
70 #define _IsUnused __attribute__ ((__unused__))
71 
72 // When the C-C code is in use, we would like this function to do as little
73 // as possible at runtime, use as few resources as possible, and hopefully
74 // be elided out of existence... hmmm.
75 template <class _Concept>
76 _GLIBCXX14_CONSTEXPR inline void __function_requires()
77 {
78   void (_Concept::*__x)() _IsUnused = &_Concept::__constraints;
79 }
80 
81 // No definition: if this is referenced, there's a problem with
82 // the instantiating type not being one of the required integer types.
83 // Unfortunately, this results in a link-time error, not a compile-time error.
84 void __error_type_must_be_an_integer_type();
85 void __error_type_must_be_an_unsigned_integer_type();
86 void __error_type_must_be_a_signed_integer_type();
87 
88 // ??? Should the "concept_checking*" structs begin with more than _ ?
89 #define _GLIBCXX_CLASS_REQUIRES(_type_var, _ns, _concept) \
90   typedef void (_ns::_concept <_type_var>::* _func##_type_var##_concept)(); \
91   template <_func##_type_var##_concept _Tp1> \
92   struct _concept_checking##_type_var##_concept { }; \
93   typedef _concept_checking##_type_var##_concept< \
94     &_ns::_concept <_type_var>::__constraints> \
95     _concept_checking_typedef##_type_var##_concept
96 
97 #define _GLIBCXX_CLASS_REQUIRES2(_type_var1, _type_var2, _ns, _concept) \
98   typedef void (_ns::_concept <_type_var1,_type_var2>::* _func##_type_var1##_type_var2##_concept)(); \
99   template <_func##_type_var1##_type_var2##_concept _Tp1> \
100   struct _concept_checking##_type_var1##_type_var2##_concept { }; \
101   typedef _concept_checking##_type_var1##_type_var2##_concept< \
102     &_ns::_concept <_type_var1,_type_var2>::__constraints> \
103     _concept_checking_typedef##_type_var1##_type_var2##_concept
104 
105 #define _GLIBCXX_CLASS_REQUIRES3(_type_var1, _type_var2, _type_var3, _ns, _concept) \
106   typedef void (_ns::_concept <_type_var1,_type_var2,_type_var3>::* _func##_type_var1##_type_var2##_type_var3##_concept)(); \
107   template <_func##_type_var1##_type_var2##_type_var3##_concept _Tp1> \
108   struct _concept_checking##_type_var1##_type_var2##_type_var3##_concept { }; \
109   typedef _concept_checking##_type_var1##_type_var2##_type_var3##_concept< \
110     &_ns::_concept <_type_var1,_type_var2,_type_var3>::__constraints>  \
111   _concept_checking_typedef##_type_var1##_type_var2##_type_var3##_concept
112 
113 #define _GLIBCXX_CLASS_REQUIRES4(_type_var1, _type_var2, _type_var3, _type_var4, _ns, _concept) \
114   typedef void (_ns::_concept <_type_var1,_type_var2,_type_var3,_type_var4>::* _func##_type_var1##_type_var2##_type_var3##_type_var4##_concept)(); \
115   template <_func##_type_var1##_type_var2##_type_var3##_type_var4##_concept _Tp1> \
116   struct _concept_checking##_type_var1##_type_var2##_type_var3##_type_var4##_concept { }; \
117   typedef _concept_checking##_type_var1##_type_var2##_type_var3##_type_var4##_concept< \
118   &_ns::_concept <_type_var1,_type_var2,_type_var3,_type_var4>::__constraints> \
119     _concept_checking_typedef##_type_var1##_type_var2##_type_var3##_type_var4##_concept
120 
121 
122 template <class _Tp1, class _Tp2>
123 struct _Aux_require_same { };
124 
125 template <class _Tp>
126 struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; };
127 
128   template <class _Tp1, class _Tp2>
129   struct _SameTypeConcept
130   {
131     void __constraints() {
132       typedef typename _Aux_require_same<_Tp1, _Tp2>::_Type _Required _IsUnused;
133     }
134   };
135 
136   template <class _Tp>
137   struct _IntegerConcept {
138     void __constraints() {
139       __error_type_must_be_an_integer_type();
140     }
141   };
142   template <> struct _IntegerConcept<short> { void __constraints() {} };
143   template <> struct _IntegerConcept<unsigned short> { void __constraints(){} };
144   template <> struct _IntegerConcept<int> { void __constraints() {} };
145   template <> struct _IntegerConcept<unsigned int> { void __constraints() {} };
146   template <> struct _IntegerConcept<long> { void __constraints() {} };
147   template <> struct _IntegerConcept<unsigned long> { void __constraints() {} };
148   template <> struct _IntegerConcept<long long> { void __constraints() {} };
149   template <> struct _IntegerConcept<unsigned long long>
150                                                 { void __constraints() {} };
151 
152   template <class _Tp>
153   struct _SignedIntegerConcept {
154     void __constraints() {
155       __error_type_must_be_a_signed_integer_type();
156     }
157   };
158   template <> struct _SignedIntegerConcept<short> { void __constraints() {} };
159   template <> struct _SignedIntegerConcept<int> { void __constraints() {} };
160   template <> struct _SignedIntegerConcept<long> { void __constraints() {} };
161   template <> struct _SignedIntegerConcept<long long> { void __constraints(){}};
162 
163   template <class _Tp>
164   struct _UnsignedIntegerConcept {
165     void __constraints() {
166       __error_type_must_be_an_unsigned_integer_type();
167     }
168   };
169   template <> struct _UnsignedIntegerConcept<unsigned short>
170     { void __constraints() {} };
171   template <> struct _UnsignedIntegerConcept<unsigned int>
172     { void __constraints() {} };
173   template <> struct _UnsignedIntegerConcept<unsigned long>
174     { void __constraints() {} };
175   template <> struct _UnsignedIntegerConcept<unsigned long long>
176     { void __constraints() {} };
177 
178   //===========================================================================
179   // Basic Concepts
180 
181   template <class _Tp>
182   struct _DefaultConstructibleConcept
183   {
184     void __constraints() {
185       _Tp __a _IsUnused;                // require default constructor
186     }
187   };
188 
189   template <class _Tp>
190   struct _AssignableConcept
191   {
192     void __constraints() {
193       __a = __a;                        // require assignment operator
194       __const_constraints(__a);
195     }
196     void __const_constraints(const _Tp& __b) {
197       __a = __b;                   // const required for argument to assignment
198     }
199     _Tp __a;
200     // possibly should be "Tp* a;" and then dereference "a" in constraint
201     // functions?  present way would require a default ctor, i think...
202   };
203 
204   template <class _Tp>
205   struct _CopyConstructibleConcept
206   {
207     void __constraints() {
208       _Tp __a(__b);                     // require copy constructor
209       _Tp* __ptr _IsUnused = &__a;      // require address of operator
210       __const_constraints(__a);
211     }
212     void __const_constraints(const _Tp& __a) {
213       _Tp __c _IsUnused(__a);           // require const copy constructor
214       const _Tp* __ptr _IsUnused = &__a; // require const address of operator
215     }
216     _Tp __b;
217   };
218 
219   // The SGI STL version of Assignable requires copy constructor and operator=
220   template <class _Tp>
221   struct _SGIAssignableConcept
222   {
223     void __constraints() {
224       _Tp __b _IsUnused(__a);
225       __a = __a;                        // require assignment operator
226       __const_constraints(__a);
227     }
228     void __const_constraints(const _Tp& __b) {
229       _Tp __c _IsUnused(__b);
230       __a = __b;              // const required for argument to assignment
231     }
232     _Tp __a;
233   };
234 
235   template <class _From, class _To>
236   struct _ConvertibleConcept
237   {
238     void __constraints() {
239       _To __y _IsUnused = __x;
240     }
241     _From __x;
242   };
243 
244   // The C++ standard requirements for many concepts talk about return
245   // types that must be "convertible to bool".  The problem with this
246   // requirement is that it leaves the door open for evil proxies that
247   // define things like operator|| with strange return types.  Two
248   // possible solutions are:
249   // 1) require the return type to be exactly bool
250   // 2) stay with convertible to bool, and also
251   //    specify stuff about all the logical operators.
252   // For now we just test for convertible to bool.
253   template <class _Tp>
254   void __aux_require_boolean_expr(const _Tp& __t) {
255     bool __x _IsUnused = __t;
256   }
257 
258 // FIXME
259   template <class _Tp>
260   struct _EqualityComparableConcept
261   {
262     void __constraints() {
263       __aux_require_boolean_expr(__a == __b);
264     }
265     _Tp __a, __b;
266   };
267 
268   template <class _Tp>
269   struct _LessThanComparableConcept
270   {
271     void __constraints() {
272       __aux_require_boolean_expr(__a < __b);
273     }
274     _Tp __a, __b;
275   };
276 
277   // This is equivalent to SGI STL's LessThanComparable.
278   template <class _Tp>
279   struct _ComparableConcept
280   {
281     void __constraints() {
282       __aux_require_boolean_expr(__a < __b);
283       __aux_require_boolean_expr(__a > __b);
284       __aux_require_boolean_expr(__a <= __b);
285       __aux_require_boolean_expr(__a >= __b);
286     }
287     _Tp __a, __b;
288   };
289 
290 #define _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(_OP,_NAME) \
291   template <class _First, class _Second> \
292   struct _NAME { \
293     void __constraints() { (void)__constraints_(); } \
294     bool __constraints_() {  \
295       return  __a _OP __b; \
296     } \
297     _First __a; \
298     _Second __b; \
299   }
300 
301 #define _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(_OP,_NAME) \
302   template <class _Ret, class _First, class _Second> \
303   struct _NAME { \
304     void __constraints() { (void)__constraints_(); } \
305     _Ret __constraints_() {  \
306       return __a _OP __b; \
307     } \
308     _First __a; \
309     _Second __b; \
310   }
311 
312   _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(==, _EqualOpConcept);
313   _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(!=, _NotEqualOpConcept);
314   _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<, _LessThanOpConcept);
315   _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<=, _LessEqualOpConcept);
316   _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>, _GreaterThanOpConcept);
317   _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>=, _GreaterEqualOpConcept);
318 
319   _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(+, _PlusOpConcept);
320   _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(*, _TimesOpConcept);
321   _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(/, _DivideOpConcept);
322   _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(-, _SubtractOpConcept);
323   _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(%, _ModOpConcept);
324 
325 #undef _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT
326 #undef _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT
327 
328   //===========================================================================
329   // Function Object Concepts
330 
331   template <class _Func, class _Return>
332   struct _GeneratorConcept
333   {
334     void __constraints() {
335       const _Return& __r _IsUnused = __f();// require operator() member function
336     }
337     _Func __f;
338   };
339 
340 
341   template <class _Func>
342   struct _GeneratorConcept<_Func,void>
343   {
344     void __constraints() {
345       __f();                            // require operator() member function
346     }
347     _Func __f;
348   };
349 
350   template <class _Func, class _Return, class _Arg>
351   struct _UnaryFunctionConcept
352   {
353     void __constraints() {
354       __r = __f(__arg);                  // require operator()
355     }
356     _Func __f;
357     _Arg __arg;
358     _Return __r;
359   };
360 
361   template <class _Func, class _Arg>
362   struct _UnaryFunctionConcept<_Func, void, _Arg> {
363     void __constraints() {
364       __f(__arg);                       // require operator()
365     }
366     _Func __f;
367     _Arg __arg;
368   };
369 
370   template <class _Func, class _Return, class _First, class _Second>
371   struct _BinaryFunctionConcept
372   {
373     void __constraints() {
374       __r = __f(__first, __second);     // require operator()
375     }
376     _Func __f;
377     _First __first;
378     _Second __second;
379     _Return __r;
380   };
381 
382   template <class _Func, class _First, class _Second>
383   struct _BinaryFunctionConcept<_Func, void, _First, _Second>
384   {
385     void __constraints() {
386       __f(__first, __second);           // require operator()
387     }
388     _Func __f;
389     _First __first;
390     _Second __second;
391   };
392 
393   template <class _Func, class _Arg>
394   struct _UnaryPredicateConcept
395   {
396     void __constraints() {
397       __aux_require_boolean_expr(__f(__arg)); // require op() returning bool
398     }
399     _Func __f;
400     _Arg __arg;
401   };
402 
403   template <class _Func, class _First, class _Second>
404   struct _BinaryPredicateConcept
405   {
406     void __constraints() {
407       __aux_require_boolean_expr(__f(__a, __b)); // require op() returning bool
408     }
409     _Func __f;
410     _First __a;
411     _Second __b;
412   };
413 
414   // use this when functor is used inside a container class like std::set
415   template <class _Func, class _First, class _Second>
416   struct _Const_BinaryPredicateConcept {
417     void __constraints() {
418       __const_constraints(__f);
419     }
420     void __const_constraints(const _Func& __fun) {
421       __function_requires<_BinaryPredicateConcept<_Func, _First, _Second> >();
422       // operator() must be a const member function
423       __aux_require_boolean_expr(__fun(__a, __b));
424     }
425     _Func __f;
426     _First __a;
427     _Second __b;
428   };
429 
430   //===========================================================================
431   // Iterator Concepts
432 
433   template <class _Tp>
434   struct _TrivialIteratorConcept
435   {
436     void __constraints() {
437 //    __function_requires< _DefaultConstructibleConcept<_Tp> >();
438       __function_requires< _AssignableConcept<_Tp> >();
439       __function_requires< _EqualityComparableConcept<_Tp> >();
440 //      typedef typename std::iterator_traits<_Tp>::value_type _V;
441       (void)*__i;                       // require dereference operator
442     }
443     _Tp __i;
444   };
445 
446   template <class _Tp>
447   struct _Mutable_TrivialIteratorConcept
448   {
449     void __constraints() {
450       __function_requires< _TrivialIteratorConcept<_Tp> >();
451       *__i = *__j;                      // require dereference and assignment
452     }
453     _Tp __i, __j;
454   };
455 
456   template <class _Tp>
457   struct _InputIteratorConcept
458   {
459     void __constraints() {
460       __function_requires< _TrivialIteratorConcept<_Tp> >();
461       // require iterator_traits typedef's
462       typedef typename std::iterator_traits<_Tp>::difference_type _Diff _IsUnused;
463 //      __function_requires< _SignedIntegerConcept<_Diff> >();
464       typedef typename std::iterator_traits<_Tp>::reference _Ref _IsUnused;
465       typedef typename std::iterator_traits<_Tp>::pointer _Pt _IsUnused;
466       typedef typename std::iterator_traits<_Tp>::iterator_category _Cat _IsUnused;
467       __function_requires< _ConvertibleConcept<
468         typename std::iterator_traits<_Tp>::iterator_category,
469         std::input_iterator_tag> >();
470       ++__i;                            // require preincrement operator
471       __i++;                            // require postincrement operator
472     }
473     _Tp __i;
474   };
475 
476   template <class _Tp, class _ValueT>
477   struct _OutputIteratorConcept
478   {
479     void __constraints() {
480       __function_requires< _AssignableConcept<_Tp> >();
481       ++__i;                            // require preincrement operator
482       __i++;                            // require postincrement operator
483       *__i++ = __val();                 // require postincrement and assignment
484     }
485     _Tp __i;
486     // Use a function pointer here so no definition of the function needed.
487     // Just need something that returns a _ValueT (which might be a reference).
488     _ValueT (*__val)();
489   };
490 
491   template<typename _Tp>
492   struct _Is_vector_bool_iterator
493   { static const bool __value = false; };
494 
495 #ifdef _GLIBCXX_DEBUG
496   namespace __cont = ::std::_GLIBCXX_STD_C;
497 #else
498   namespace __cont = ::std;
499 #endif
500 
501   // Trait to identify vector<bool>::iterator
502   template <>
503   struct _Is_vector_bool_iterator<__cont::_Bit_iterator>
504   { static const bool __value = true; };
505 
506   // And for vector<bool>::const_iterator.
507   template <>
508   struct _Is_vector_bool_iterator<__cont::_Bit_const_iterator>
509   { static const bool __value = true; };
510 
511   // And for __gnu_debug::vector<bool> iterators too.
512   template <typename _It, typename _Seq, typename _Tag>
513   struct _Is_vector_bool_iterator<__gnu_debug::_Safe_iterator<_It, _Seq, _Tag> >
514   : _Is_vector_bool_iterator<_It> { };
515 
516   template <class _Tp, bool = _Is_vector_bool_iterator<_Tp>::__value>
517   struct _ForwardIteratorReferenceConcept
518   {
519     void __constraints() {
520 #if __cplusplus >= 201103L
521       typedef typename std::iterator_traits<_Tp>::reference _Ref;
522       static_assert(std::is_reference<_Ref>::value,
523 	  "reference type of a forward iterator must be a real reference");
524 #endif
525     }
526   };
527 
528   template <class _Tp, bool = _Is_vector_bool_iterator<_Tp>::__value>
529   struct _Mutable_ForwardIteratorReferenceConcept
530   {
531     void __constraints() {
532       typedef typename std::iterator_traits<_Tp>::reference _Ref;
533       typedef typename std::iterator_traits<_Tp>::value_type _Val;
534       __function_requires< _SameTypeConcept<_Ref, _Val&> >();
535     }
536   };
537 
538   // vector<bool> iterators are not real forward iterators, but we ignore that.
539   template <class _Tp>
540   struct _ForwardIteratorReferenceConcept<_Tp, true>
541   {
542     void __constraints() { }
543   };
544 
545   // vector<bool> iterators are not real forward iterators, but we ignore that.
546   template <class _Tp>
547   struct _Mutable_ForwardIteratorReferenceConcept<_Tp, true>
548   {
549     void __constraints() { }
550   };
551 
552 #pragma GCC diagnostic push
553 #pragma GCC diagnostic ignored "-Wunused-variable"
554 
555   template <class _Tp>
556   struct _ForwardIteratorConcept
557   {
558     void __constraints() {
559       __function_requires< _InputIteratorConcept<_Tp> >();
560       __function_requires< _DefaultConstructibleConcept<_Tp> >();
561       __function_requires< _ConvertibleConcept<
562         typename std::iterator_traits<_Tp>::iterator_category,
563         std::forward_iterator_tag> >();
564       __function_requires< _ForwardIteratorReferenceConcept<_Tp> >();
565       _Tp& __j = ++__i;
566       const _Tp& __k = __i++;
567       typedef typename std::iterator_traits<_Tp>::reference _Ref;
568       _Ref __r = *__k;
569       _Ref __r2 = *__i++;
570     }
571     _Tp __i;
572   };
573 
574   template <class _Tp>
575   struct _Mutable_ForwardIteratorConcept
576   {
577     void __constraints() {
578       __function_requires< _ForwardIteratorConcept<_Tp> >();
579       typedef typename std::iterator_traits<_Tp>::reference _Ref;
580       typedef typename std::iterator_traits<_Tp>::value_type _Val;
581       __function_requires< _Mutable_ForwardIteratorReferenceConcept<_Tp> >();
582     }
583     _Tp __i;
584   };
585 
586   template <class _Tp>
587   struct _BidirectionalIteratorConcept
588   {
589     void __constraints() {
590       __function_requires< _ForwardIteratorConcept<_Tp> >();
591       __function_requires< _ConvertibleConcept<
592         typename std::iterator_traits<_Tp>::iterator_category,
593         std::bidirectional_iterator_tag> >();
594       _Tp& __j = --__i;                 // require predecrement operator
595       const _Tp& __k = __i--;           // require postdecrement operator
596       typedef typename std::iterator_traits<_Tp>::reference _Ref;
597       _Ref __r = *__j--;
598     }
599     _Tp __i;
600   };
601 
602   template <class _Tp>
603   struct _Mutable_BidirectionalIteratorConcept
604   {
605     void __constraints() {
606       __function_requires< _BidirectionalIteratorConcept<_Tp> >();
607       __function_requires< _Mutable_ForwardIteratorConcept<_Tp> >();
608     }
609     _Tp __i;
610   };
611 
612 
613   template <class _Tp>
614   struct _RandomAccessIteratorConcept
615   {
616     void __constraints() {
617       __function_requires< _BidirectionalIteratorConcept<_Tp> >();
618       __function_requires< _ComparableConcept<_Tp> >();
619       __function_requires< _ConvertibleConcept<
620         typename std::iterator_traits<_Tp>::iterator_category,
621         std::random_access_iterator_tag> >();
622       typedef typename std::iterator_traits<_Tp>::reference _Ref _IsUnused;
623 
624       _Tp& __j = __i += __n;            // require assignment addition operator
625       __i = __i + __n; __i = __n + __i; // require addition with difference type
626       _Tp& __k = __i -= __n;            // require assignment subtraction op
627       __i = __i - __n;                  // require subtraction with
628                                         //            difference type
629       __n = __i - __j;                  // require difference operator
630       _Ref __r = __i[__n];              // require element access operator
631     }
632     _Tp __a, __b;
633     _Tp __i, __j;
634     typename std::iterator_traits<_Tp>::difference_type __n;
635   };
636 
637   template <class _Tp>
638   struct _Mutable_RandomAccessIteratorConcept
639   {
640     void __constraints() {
641       __function_requires< _RandomAccessIteratorConcept<_Tp> >();
642       __function_requires< _Mutable_BidirectionalIteratorConcept<_Tp> >();
643     }
644     _Tp __i;
645     typename std::iterator_traits<_Tp>::difference_type __n;
646   };
647 
648 #pragma GCC diagnostic pop
649 
650   //===========================================================================
651   // Container Concepts
652 
653   template <class _Container>
654   struct _ContainerConcept
655   {
656     typedef typename _Container::value_type _Value_type;
657     typedef typename _Container::difference_type _Difference_type;
658     typedef typename _Container::size_type _Size_type;
659     typedef typename _Container::const_reference _Const_reference;
660     typedef typename _Container::const_pointer _Const_pointer;
661     typedef typename _Container::const_iterator _Const_iterator;
662 
663     void __constraints() {
664       __function_requires< _InputIteratorConcept<_Const_iterator> >();
665       __function_requires< _AssignableConcept<_Container> >();
666       const _Container __c;
667       __i = __c.begin();
668       __i = __c.end();
669       __n = __c.size();
670       __n = __c.max_size();
671       __b = __c.empty();
672     }
673     bool __b;
674     _Const_iterator __i;
675     _Size_type __n;
676   };
677 
678   template <class _Container>
679   struct _Mutable_ContainerConcept
680   {
681     typedef typename _Container::value_type _Value_type;
682     typedef typename _Container::reference _Reference;
683     typedef typename _Container::iterator _Iterator;
684     typedef typename _Container::pointer _Pointer;
685 
686     void __constraints() {
687       __function_requires< _ContainerConcept<_Container> >();
688       __function_requires< _AssignableConcept<_Value_type> >();
689       __function_requires< _InputIteratorConcept<_Iterator> >();
690 
691       __i = __c.begin();
692       __i = __c.end();
693       __c.swap(__c2);
694     }
695     _Iterator __i;
696     _Container __c, __c2;
697   };
698 
699   template <class _ForwardContainer>
700   struct _ForwardContainerConcept
701   {
702     void __constraints() {
703       __function_requires< _ContainerConcept<_ForwardContainer> >();
704       typedef typename _ForwardContainer::const_iterator _Const_iterator;
705       __function_requires< _ForwardIteratorConcept<_Const_iterator> >();
706     }
707   };
708 
709   template <class _ForwardContainer>
710   struct _Mutable_ForwardContainerConcept
711   {
712     void __constraints() {
713       __function_requires< _ForwardContainerConcept<_ForwardContainer> >();
714       __function_requires< _Mutable_ContainerConcept<_ForwardContainer> >();
715       typedef typename _ForwardContainer::iterator _Iterator;
716       __function_requires< _Mutable_ForwardIteratorConcept<_Iterator> >();
717     }
718   };
719 
720   template <class _ReversibleContainer>
721   struct _ReversibleContainerConcept
722   {
723     typedef typename _ReversibleContainer::const_iterator _Const_iterator;
724     typedef typename _ReversibleContainer::const_reverse_iterator
725       _Const_reverse_iterator;
726 
727     void __constraints() {
728       __function_requires< _ForwardContainerConcept<_ReversibleContainer> >();
729       __function_requires< _BidirectionalIteratorConcept<_Const_iterator> >();
730       __function_requires<
731         _BidirectionalIteratorConcept<_Const_reverse_iterator> >();
732 
733       const _ReversibleContainer __c;
734       _Const_reverse_iterator __i = __c.rbegin();
735       __i = __c.rend();
736     }
737   };
738 
739   template <class _ReversibleContainer>
740   struct _Mutable_ReversibleContainerConcept
741   {
742     typedef typename _ReversibleContainer::iterator _Iterator;
743     typedef typename _ReversibleContainer::reverse_iterator _Reverse_iterator;
744 
745     void __constraints() {
746       __function_requires<_ReversibleContainerConcept<_ReversibleContainer> >();
747       __function_requires<
748         _Mutable_ForwardContainerConcept<_ReversibleContainer> >();
749       __function_requires<_Mutable_BidirectionalIteratorConcept<_Iterator> >();
750       __function_requires<
751         _Mutable_BidirectionalIteratorConcept<_Reverse_iterator> >();
752 
753       _Reverse_iterator __i = __c.rbegin();
754       __i = __c.rend();
755     }
756     _ReversibleContainer __c;
757   };
758 
759   template <class _RandomAccessContainer>
760   struct _RandomAccessContainerConcept
761   {
762     typedef typename _RandomAccessContainer::size_type _Size_type;
763     typedef typename _RandomAccessContainer::const_reference _Const_reference;
764     typedef typename _RandomAccessContainer::const_iterator _Const_iterator;
765     typedef typename _RandomAccessContainer::const_reverse_iterator
766       _Const_reverse_iterator;
767 
768     void __constraints() {
769       __function_requires<
770         _ReversibleContainerConcept<_RandomAccessContainer> >();
771       __function_requires< _RandomAccessIteratorConcept<_Const_iterator> >();
772       __function_requires<
773         _RandomAccessIteratorConcept<_Const_reverse_iterator> >();
774 
775       const _RandomAccessContainer __c;
776       _Const_reference __r _IsUnused = __c[__n];
777     }
778     _Size_type __n;
779   };
780 
781   template <class _RandomAccessContainer>
782   struct _Mutable_RandomAccessContainerConcept
783   {
784     typedef typename _RandomAccessContainer::size_type _Size_type;
785     typedef typename _RandomAccessContainer::reference _Reference;
786     typedef typename _RandomAccessContainer::iterator _Iterator;
787     typedef typename _RandomAccessContainer::reverse_iterator _Reverse_iterator;
788 
789     void __constraints() {
790       __function_requires<
791         _RandomAccessContainerConcept<_RandomAccessContainer> >();
792       __function_requires<
793         _Mutable_ReversibleContainerConcept<_RandomAccessContainer> >();
794       __function_requires< _Mutable_RandomAccessIteratorConcept<_Iterator> >();
795       __function_requires<
796         _Mutable_RandomAccessIteratorConcept<_Reverse_iterator> >();
797 
798       _Reference __r _IsUnused = __c[__i];
799     }
800     _Size_type __i;
801     _RandomAccessContainer __c;
802   };
803 
804   // A Sequence is inherently mutable
805   template <class _Sequence>
806   struct _SequenceConcept
807   {
808     typedef typename _Sequence::reference _Reference;
809     typedef typename _Sequence::const_reference _Const_reference;
810 
811     void __constraints() {
812       // Matt Austern's book puts DefaultConstructible here, the C++
813       // standard places it in Container
814       //    function_requires< DefaultConstructible<Sequence> >();
815       __function_requires< _Mutable_ForwardContainerConcept<_Sequence> >();
816       __function_requires< _DefaultConstructibleConcept<_Sequence> >();
817 
818       _Sequence
819 	__c _IsUnused(__n, __t),
820         __c2 _IsUnused(__first, __last);
821 
822       __c.insert(__p, __t);
823       __c.insert(__p, __n, __t);
824       __c.insert(__p, __first, __last);
825 
826       __c.erase(__p);
827       __c.erase(__p, __q);
828 
829       _Reference __r _IsUnused = __c.front();
830 
831       __const_constraints(__c);
832     }
833     void __const_constraints(const _Sequence& __c) {
834       _Const_reference __r _IsUnused = __c.front();
835     }
836     typename _Sequence::value_type __t;
837     typename _Sequence::size_type __n;
838     typename _Sequence::value_type *__first, *__last;
839     typename _Sequence::iterator __p, __q;
840   };
841 
842   template <class _FrontInsertionSequence>
843   struct _FrontInsertionSequenceConcept
844   {
845     void __constraints() {
846       __function_requires< _SequenceConcept<_FrontInsertionSequence> >();
847 
848       __c.push_front(__t);
849       __c.pop_front();
850     }
851     _FrontInsertionSequence __c;
852     typename _FrontInsertionSequence::value_type __t;
853   };
854 
855   template <class _BackInsertionSequence>
856   struct _BackInsertionSequenceConcept
857   {
858     typedef typename _BackInsertionSequence::reference _Reference;
859     typedef typename _BackInsertionSequence::const_reference _Const_reference;
860 
861     void __constraints() {
862       __function_requires< _SequenceConcept<_BackInsertionSequence> >();
863 
864       __c.push_back(__t);
865       __c.pop_back();
866       _Reference __r _IsUnused = __c.back();
867     }
868     void __const_constraints(const _BackInsertionSequence& __c) {
869       _Const_reference __r _IsUnused = __c.back();
870     };
871     _BackInsertionSequence __c;
872     typename _BackInsertionSequence::value_type __t;
873   };
874 
875 _GLIBCXX_END_NAMESPACE_VERSION
876 } // namespace
877 
878 #pragma GCC diagnostic pop
879 #undef _IsUnused
880 
881 #endif // _GLIBCXX_BOOST_CONCEPT_CHECK
882 
883 
884