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