libstdc++
boost_concept_check.h
Go to the documentation of this file.
1// -*- C++ -*-
2
3// Copyright (C) 2004-2025 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
49namespace 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
59namespace __gnu_debug
60{
61 template<typename _Iterator, typename _Sequence, typename _Category>
62 class _Safe_iterator;
63}
64
65namespace __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.
78template <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.
87void __error_type_must_be_an_integer_type();
88void __error_type_must_be_an_unsigned_integer_type();
89void __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
125template <class _Tp1, class _Tp2>
126struct _Aux_require_same { };
127
128template <class _Tp>
129struct _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<
471 typename std::iterator_traits<_Tp>::iterator_category,
472 std::input_iterator_tag> >();
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<
565 typename std::iterator_traits<_Tp>::iterator_category,
566 std::forward_iterator_tag> >();
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<
595 typename std::iterator_traits<_Tp>::iterator_category,
596 std::bidirectional_iterator_tag> >();
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<
623 typename std::iterator_traits<_Tp>::iterator_category,
624 std::random_access_iterator_tag> >();
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;
637 typename std::iterator_traits<_Tp>::difference_type __n;
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;
648 typename std::iterator_traits<_Tp>::difference_type __n;
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.
Safe iterator wrapper.