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