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