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