Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/concept_check.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children | c530137014c0 |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 // | |
2 // (C) Copyright Jeremy Siek 2000. | |
3 // Copyright 2002 The Trustees of Indiana University. | |
4 // | |
5 // Distributed under the Boost Software License, Version 1.0. (See | |
6 // accompanying file LICENSE_1_0.txt or copy at | |
7 // http://www.boost.org/LICENSE_1_0.txt) | |
8 // | |
9 // Revision History: | |
10 // 05 May 2001: Workarounds for HP aCC from Thomas Matelich. (Jeremy Siek) | |
11 // 02 April 2001: Removed limits header altogether. (Jeremy Siek) | |
12 // 01 April 2001: Modified to use new <boost/limits.hpp> header. (JMaddock) | |
13 // | |
14 | |
15 // See http://www.boost.org/libs/concept_check for documentation. | |
16 | |
17 #ifndef BOOST_CONCEPT_CHECKS_HPP | |
18 # define BOOST_CONCEPT_CHECKS_HPP | |
19 | |
20 # include <boost/concept/assert.hpp> | |
21 | |
22 # include <boost/iterator.hpp> | |
23 # include <boost/type_traits/conversion_traits.hpp> | |
24 # include <utility> | |
25 # include <boost/type_traits/is_same.hpp> | |
26 # include <boost/type_traits/is_void.hpp> | |
27 # include <boost/mpl/assert.hpp> | |
28 # include <boost/mpl/bool.hpp> | |
29 # include <boost/detail/workaround.hpp> | |
30 # include <boost/detail/iterator.hpp> | |
31 | |
32 # include <boost/concept/usage.hpp> | |
33 # include <boost/concept/detail/concept_def.hpp> | |
34 | |
35 namespace boost | |
36 { | |
37 | |
38 // | |
39 // Backward compatibility | |
40 // | |
41 | |
42 template <class Model> | |
43 inline void function_requires(Model* = 0) | |
44 { | |
45 BOOST_CONCEPT_ASSERT((Model)); | |
46 } | |
47 template <class T> inline void ignore_unused_variable_warning(T const&) {} | |
48 | |
49 # define BOOST_CLASS_REQUIRE(type_var, ns, concept) \ | |
50 BOOST_CONCEPT_ASSERT((ns::concept<type_var>)) | |
51 | |
52 # define BOOST_CLASS_REQUIRE2(type_var1, type_var2, ns, concept) \ | |
53 BOOST_CONCEPT_ASSERT((ns::concept<type_var1,type_var2>)) | |
54 | |
55 # define BOOST_CLASS_REQUIRE3(tv1, tv2, tv3, ns, concept) \ | |
56 BOOST_CONCEPT_ASSERT((ns::concept<tv1,tv2,tv3>)) | |
57 | |
58 # define BOOST_CLASS_REQUIRE4(tv1, tv2, tv3, tv4, ns, concept) \ | |
59 BOOST_CONCEPT_ASSERT((ns::concept<tv1,tv2,tv3,tv4>)) | |
60 | |
61 | |
62 // | |
63 // Begin concept definitions | |
64 // | |
65 BOOST_concept(Integer, (T)) | |
66 { | |
67 BOOST_CONCEPT_USAGE(Integer) | |
68 { | |
69 x.error_type_must_be_an_integer_type(); | |
70 } | |
71 private: | |
72 T x; | |
73 }; | |
74 | |
75 template <> struct Integer<char> {}; | |
76 template <> struct Integer<signed char> {}; | |
77 template <> struct Integer<unsigned char> {}; | |
78 template <> struct Integer<short> {}; | |
79 template <> struct Integer<unsigned short> {}; | |
80 template <> struct Integer<int> {}; | |
81 template <> struct Integer<unsigned int> {}; | |
82 template <> struct Integer<long> {}; | |
83 template <> struct Integer<unsigned long> {}; | |
84 # if defined(BOOST_HAS_LONG_LONG) | |
85 template <> struct Integer< ::boost::long_long_type> {}; | |
86 template <> struct Integer< ::boost::ulong_long_type> {}; | |
87 # elif defined(BOOST_HAS_MS_INT64) | |
88 template <> struct Integer<__int64> {}; | |
89 template <> struct Integer<unsigned __int64> {}; | |
90 # endif | |
91 | |
92 BOOST_concept(SignedInteger,(T)) { | |
93 BOOST_CONCEPT_USAGE(SignedInteger) { | |
94 x.error_type_must_be_a_signed_integer_type(); | |
95 } | |
96 private: | |
97 T x; | |
98 }; | |
99 template <> struct SignedInteger<signed char> { }; | |
100 template <> struct SignedInteger<short> {}; | |
101 template <> struct SignedInteger<int> {}; | |
102 template <> struct SignedInteger<long> {}; | |
103 # if defined(BOOST_HAS_LONG_LONG) | |
104 template <> struct SignedInteger< ::boost::long_long_type> {}; | |
105 # elif defined(BOOST_HAS_MS_INT64) | |
106 template <> struct SignedInteger<__int64> {}; | |
107 # endif | |
108 | |
109 BOOST_concept(UnsignedInteger,(T)) { | |
110 BOOST_CONCEPT_USAGE(UnsignedInteger) { | |
111 x.error_type_must_be_an_unsigned_integer_type(); | |
112 } | |
113 private: | |
114 T x; | |
115 }; | |
116 | |
117 template <> struct UnsignedInteger<unsigned char> {}; | |
118 template <> struct UnsignedInteger<unsigned short> {}; | |
119 template <> struct UnsignedInteger<unsigned int> {}; | |
120 template <> struct UnsignedInteger<unsigned long> {}; | |
121 # if defined(BOOST_HAS_LONG_LONG) | |
122 template <> struct UnsignedInteger< ::boost::ulong_long_type> {}; | |
123 # elif defined(BOOST_HAS_MS_INT64) | |
124 template <> struct UnsignedInteger<unsigned __int64> {}; | |
125 # endif | |
126 | |
127 //=========================================================================== | |
128 // Basic Concepts | |
129 | |
130 BOOST_concept(DefaultConstructible,(TT)) | |
131 { | |
132 BOOST_CONCEPT_USAGE(DefaultConstructible) { | |
133 TT a; // require default constructor | |
134 ignore_unused_variable_warning(a); | |
135 } | |
136 }; | |
137 | |
138 BOOST_concept(Assignable,(TT)) | |
139 { | |
140 BOOST_CONCEPT_USAGE(Assignable) { | |
141 #if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL | |
142 a = b; // require assignment operator | |
143 #endif | |
144 const_constraints(b); | |
145 } | |
146 private: | |
147 void const_constraints(const TT& x) { | |
148 #if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL | |
149 a = x; // const required for argument to assignment | |
150 #else | |
151 ignore_unused_variable_warning(x); | |
152 #endif | |
153 } | |
154 private: | |
155 TT a; | |
156 TT b; | |
157 }; | |
158 | |
159 | |
160 BOOST_concept(CopyConstructible,(TT)) | |
161 { | |
162 BOOST_CONCEPT_USAGE(CopyConstructible) { | |
163 TT a(b); // require copy constructor | |
164 TT* ptr = &a; // require address of operator | |
165 const_constraints(a); | |
166 ignore_unused_variable_warning(ptr); | |
167 } | |
168 private: | |
169 void const_constraints(const TT& a) { | |
170 TT c(a); // require const copy constructor | |
171 const TT* ptr = &a; // require const address of operator | |
172 ignore_unused_variable_warning(c); | |
173 ignore_unused_variable_warning(ptr); | |
174 } | |
175 TT b; | |
176 }; | |
177 | |
178 #if (defined _MSC_VER) | |
179 # pragma warning( push ) | |
180 # pragma warning( disable : 4510 ) // default constructor could not be generated | |
181 # pragma warning( disable : 4610 ) // object 'class' can never be instantiated - user-defined constructor required | |
182 #endif | |
183 // The SGI STL version of Assignable requires copy constructor and operator= | |
184 BOOST_concept(SGIAssignable,(TT)) | |
185 { | |
186 BOOST_CONCEPT_USAGE(SGIAssignable) { | |
187 TT c(a); | |
188 #if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL | |
189 a = b; // require assignment operator | |
190 #endif | |
191 const_constraints(b); | |
192 ignore_unused_variable_warning(c); | |
193 } | |
194 private: | |
195 void const_constraints(const TT& x) { | |
196 TT c(x); | |
197 #if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL | |
198 a = x; // const required for argument to assignment | |
199 #endif | |
200 ignore_unused_variable_warning(c); | |
201 } | |
202 TT a; | |
203 TT b; | |
204 }; | |
205 #if (defined _MSC_VER) | |
206 # pragma warning( pop ) | |
207 #endif | |
208 | |
209 BOOST_concept(Convertible,(X)(Y)) | |
210 { | |
211 BOOST_CONCEPT_USAGE(Convertible) { | |
212 Y y = x; | |
213 ignore_unused_variable_warning(y); | |
214 } | |
215 private: | |
216 X x; | |
217 }; | |
218 | |
219 // The C++ standard requirements for many concepts talk about return | |
220 // types that must be "convertible to bool". The problem with this | |
221 // requirement is that it leaves the door open for evil proxies that | |
222 // define things like operator|| with strange return types. Two | |
223 // possible solutions are: | |
224 // 1) require the return type to be exactly bool | |
225 // 2) stay with convertible to bool, and also | |
226 // specify stuff about all the logical operators. | |
227 // For now we just test for convertible to bool. | |
228 template <class TT> | |
229 void require_boolean_expr(const TT& t) { | |
230 bool x = t; | |
231 ignore_unused_variable_warning(x); | |
232 } | |
233 | |
234 BOOST_concept(EqualityComparable,(TT)) | |
235 { | |
236 BOOST_CONCEPT_USAGE(EqualityComparable) { | |
237 require_boolean_expr(a == b); | |
238 require_boolean_expr(a != b); | |
239 } | |
240 private: | |
241 TT a, b; | |
242 }; | |
243 | |
244 BOOST_concept(LessThanComparable,(TT)) | |
245 { | |
246 BOOST_CONCEPT_USAGE(LessThanComparable) { | |
247 require_boolean_expr(a < b); | |
248 } | |
249 private: | |
250 TT a, b; | |
251 }; | |
252 | |
253 // This is equivalent to SGI STL's LessThanComparable. | |
254 BOOST_concept(Comparable,(TT)) | |
255 { | |
256 BOOST_CONCEPT_USAGE(Comparable) { | |
257 require_boolean_expr(a < b); | |
258 require_boolean_expr(a > b); | |
259 require_boolean_expr(a <= b); | |
260 require_boolean_expr(a >= b); | |
261 } | |
262 private: | |
263 TT a, b; | |
264 }; | |
265 | |
266 #define BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(OP,NAME) \ | |
267 BOOST_concept(NAME, (First)(Second)) \ | |
268 { \ | |
269 BOOST_CONCEPT_USAGE(NAME) { (void)constraints_(); } \ | |
270 private: \ | |
271 bool constraints_() { return a OP b; } \ | |
272 First a; \ | |
273 Second b; \ | |
274 } | |
275 | |
276 #define BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(OP,NAME) \ | |
277 BOOST_concept(NAME, (Ret)(First)(Second)) \ | |
278 { \ | |
279 BOOST_CONCEPT_USAGE(NAME) { (void)constraints_(); } \ | |
280 private: \ | |
281 Ret constraints_() { return a OP b; } \ | |
282 First a; \ | |
283 Second b; \ | |
284 } | |
285 | |
286 BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(==, EqualOp); | |
287 BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(!=, NotEqualOp); | |
288 BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<, LessThanOp); | |
289 BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<=, LessEqualOp); | |
290 BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>, GreaterThanOp); | |
291 BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>=, GreaterEqualOp); | |
292 | |
293 BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(+, PlusOp); | |
294 BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(*, TimesOp); | |
295 BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(/, DivideOp); | |
296 BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(-, SubtractOp); | |
297 BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(%, ModOp); | |
298 | |
299 //=========================================================================== | |
300 // Function Object Concepts | |
301 | |
302 BOOST_concept(Generator,(Func)(Return)) | |
303 { | |
304 BOOST_CONCEPT_USAGE(Generator) { test(is_void<Return>()); } | |
305 | |
306 private: | |
307 void test(boost::mpl::false_) | |
308 { | |
309 // Do we really want a reference here? | |
310 const Return& r = f(); | |
311 ignore_unused_variable_warning(r); | |
312 } | |
313 | |
314 void test(boost::mpl::true_) | |
315 { | |
316 f(); | |
317 } | |
318 | |
319 Func f; | |
320 }; | |
321 | |
322 BOOST_concept(UnaryFunction,(Func)(Return)(Arg)) | |
323 { | |
324 BOOST_CONCEPT_USAGE(UnaryFunction) { test(is_void<Return>()); } | |
325 | |
326 private: | |
327 void test(boost::mpl::false_) | |
328 { | |
329 f(arg); // "priming the pump" this way keeps msvc6 happy (ICE) | |
330 Return r = f(arg); | |
331 ignore_unused_variable_warning(r); | |
332 } | |
333 | |
334 void test(boost::mpl::true_) | |
335 { | |
336 f(arg); | |
337 } | |
338 | |
339 #if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \ | |
340 && BOOST_WORKAROUND(__GNUC__, > 3))) | |
341 // Declare a dummy construktor to make gcc happy. | |
342 // It seems the compiler can not generate a sensible constructor when this is instantiated with a refence type. | |
343 // (warning: non-static reference "const double& boost::UnaryFunction<YourClassHere>::arg" | |
344 // in class without a constructor [-Wuninitialized]) | |
345 UnaryFunction(); | |
346 #endif | |
347 | |
348 Func f; | |
349 Arg arg; | |
350 }; | |
351 | |
352 BOOST_concept(BinaryFunction,(Func)(Return)(First)(Second)) | |
353 { | |
354 BOOST_CONCEPT_USAGE(BinaryFunction) { test(is_void<Return>()); } | |
355 private: | |
356 void test(boost::mpl::false_) | |
357 { | |
358 f(first,second); | |
359 Return r = f(first, second); // require operator() | |
360 (void)r; | |
361 } | |
362 | |
363 void test(boost::mpl::true_) | |
364 { | |
365 f(first,second); | |
366 } | |
367 | |
368 #if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \ | |
369 && BOOST_WORKAROUND(__GNUC__, > 3))) | |
370 // Declare a dummy constructor to make gcc happy. | |
371 // It seems the compiler can not generate a sensible constructor when this is instantiated with a refence type. | |
372 // (warning: non-static reference "const double& boost::BinaryFunction<YourClassHere>::arg" | |
373 // in class without a constructor [-Wuninitialized]) | |
374 BinaryFunction(); | |
375 #endif | |
376 | |
377 Func f; | |
378 First first; | |
379 Second second; | |
380 }; | |
381 | |
382 BOOST_concept(UnaryPredicate,(Func)(Arg)) | |
383 { | |
384 BOOST_CONCEPT_USAGE(UnaryPredicate) { | |
385 require_boolean_expr(f(arg)); // require operator() returning bool | |
386 } | |
387 private: | |
388 #if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \ | |
389 && BOOST_WORKAROUND(__GNUC__, > 3))) | |
390 // Declare a dummy constructor to make gcc happy. | |
391 // It seems the compiler can not generate a sensible constructor when this is instantiated with a refence type. | |
392 // (warning: non-static reference "const double& boost::UnaryPredicate<YourClassHere>::arg" | |
393 // in class without a constructor [-Wuninitialized]) | |
394 UnaryPredicate(); | |
395 #endif | |
396 | |
397 Func f; | |
398 Arg arg; | |
399 }; | |
400 | |
401 BOOST_concept(BinaryPredicate,(Func)(First)(Second)) | |
402 { | |
403 BOOST_CONCEPT_USAGE(BinaryPredicate) { | |
404 require_boolean_expr(f(a, b)); // require operator() returning bool | |
405 } | |
406 private: | |
407 #if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \ | |
408 && BOOST_WORKAROUND(__GNUC__, > 3))) | |
409 // Declare a dummy constructor to make gcc happy. | |
410 // It seems the compiler can not generate a sensible constructor when this is instantiated with a refence type. | |
411 // (warning: non-static reference "const double& boost::BinaryPredicate<YourClassHere>::arg" | |
412 // in class without a constructor [-Wuninitialized]) | |
413 BinaryPredicate(); | |
414 #endif | |
415 Func f; | |
416 First a; | |
417 Second b; | |
418 }; | |
419 | |
420 // use this when functor is used inside a container class like std::set | |
421 BOOST_concept(Const_BinaryPredicate,(Func)(First)(Second)) | |
422 : BinaryPredicate<Func, First, Second> | |
423 { | |
424 BOOST_CONCEPT_USAGE(Const_BinaryPredicate) { | |
425 const_constraints(f); | |
426 } | |
427 private: | |
428 void const_constraints(const Func& fun) { | |
429 // operator() must be a const member function | |
430 require_boolean_expr(fun(a, b)); | |
431 } | |
432 #if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \ | |
433 && BOOST_WORKAROUND(__GNUC__, > 3))) | |
434 // Declare a dummy constructor to make gcc happy. | |
435 // It seems the compiler can not generate a sensible constructor when this is instantiated with a refence type. | |
436 // (warning: non-static reference "const double& boost::Const_BinaryPredicate<YourClassHere>::arg" | |
437 // in class without a constructor [-Wuninitialized]) | |
438 Const_BinaryPredicate(); | |
439 #endif | |
440 | |
441 Func f; | |
442 First a; | |
443 Second b; | |
444 }; | |
445 | |
446 BOOST_concept(AdaptableGenerator,(Func)(Return)) | |
447 : Generator<Func, typename Func::result_type> | |
448 { | |
449 typedef typename Func::result_type result_type; | |
450 | |
451 BOOST_CONCEPT_USAGE(AdaptableGenerator) | |
452 { | |
453 BOOST_CONCEPT_ASSERT((Convertible<result_type, Return>)); | |
454 } | |
455 }; | |
456 | |
457 BOOST_concept(AdaptableUnaryFunction,(Func)(Return)(Arg)) | |
458 : UnaryFunction<Func, typename Func::result_type, typename Func::argument_type> | |
459 { | |
460 typedef typename Func::argument_type argument_type; | |
461 typedef typename Func::result_type result_type; | |
462 | |
463 ~AdaptableUnaryFunction() | |
464 { | |
465 BOOST_CONCEPT_ASSERT((Convertible<result_type, Return>)); | |
466 BOOST_CONCEPT_ASSERT((Convertible<Arg, argument_type>)); | |
467 } | |
468 }; | |
469 | |
470 BOOST_concept(AdaptableBinaryFunction,(Func)(Return)(First)(Second)) | |
471 : BinaryFunction< | |
472 Func | |
473 , typename Func::result_type | |
474 , typename Func::first_argument_type | |
475 , typename Func::second_argument_type | |
476 > | |
477 { | |
478 typedef typename Func::first_argument_type first_argument_type; | |
479 typedef typename Func::second_argument_type second_argument_type; | |
480 typedef typename Func::result_type result_type; | |
481 | |
482 ~AdaptableBinaryFunction() | |
483 { | |
484 BOOST_CONCEPT_ASSERT((Convertible<result_type, Return>)); | |
485 BOOST_CONCEPT_ASSERT((Convertible<First, first_argument_type>)); | |
486 BOOST_CONCEPT_ASSERT((Convertible<Second, second_argument_type>)); | |
487 } | |
488 }; | |
489 | |
490 BOOST_concept(AdaptablePredicate,(Func)(Arg)) | |
491 : UnaryPredicate<Func, Arg> | |
492 , AdaptableUnaryFunction<Func, bool, Arg> | |
493 { | |
494 }; | |
495 | |
496 BOOST_concept(AdaptableBinaryPredicate,(Func)(First)(Second)) | |
497 : BinaryPredicate<Func, First, Second> | |
498 , AdaptableBinaryFunction<Func, bool, First, Second> | |
499 { | |
500 }; | |
501 | |
502 //=========================================================================== | |
503 // Iterator Concepts | |
504 | |
505 BOOST_concept(InputIterator,(TT)) | |
506 : Assignable<TT> | |
507 , EqualityComparable<TT> | |
508 { | |
509 typedef typename boost::detail::iterator_traits<TT>::value_type value_type; | |
510 typedef typename boost::detail::iterator_traits<TT>::difference_type difference_type; | |
511 typedef typename boost::detail::iterator_traits<TT>::reference reference; | |
512 typedef typename boost::detail::iterator_traits<TT>::pointer pointer; | |
513 typedef typename boost::detail::iterator_traits<TT>::iterator_category iterator_category; | |
514 | |
515 BOOST_CONCEPT_USAGE(InputIterator) | |
516 { | |
517 BOOST_CONCEPT_ASSERT((SignedInteger<difference_type>)); | |
518 BOOST_CONCEPT_ASSERT((Convertible<iterator_category, std::input_iterator_tag>)); | |
519 | |
520 TT j(i); | |
521 (void)*i; // require dereference operator | |
522 ++j; // require preincrement operator | |
523 i++; // require postincrement operator | |
524 } | |
525 private: | |
526 TT i; | |
527 }; | |
528 | |
529 BOOST_concept(OutputIterator,(TT)(ValueT)) | |
530 : Assignable<TT> | |
531 { | |
532 BOOST_CONCEPT_USAGE(OutputIterator) { | |
533 | |
534 ++i; // require preincrement operator | |
535 i++; // require postincrement operator | |
536 *i++ = t; // require postincrement and assignment | |
537 } | |
538 private: | |
539 TT i, j; | |
540 ValueT t; | |
541 }; | |
542 | |
543 BOOST_concept(ForwardIterator,(TT)) | |
544 : InputIterator<TT> | |
545 { | |
546 BOOST_CONCEPT_USAGE(ForwardIterator) | |
547 { | |
548 BOOST_CONCEPT_ASSERT((Convertible< | |
549 BOOST_DEDUCED_TYPENAME ForwardIterator::iterator_category | |
550 , std::forward_iterator_tag | |
551 >)); | |
552 | |
553 typename InputIterator<TT>::reference r = *i; | |
554 ignore_unused_variable_warning(r); | |
555 } | |
556 | |
557 private: | |
558 TT i; | |
559 }; | |
560 | |
561 BOOST_concept(Mutable_ForwardIterator,(TT)) | |
562 : ForwardIterator<TT> | |
563 { | |
564 BOOST_CONCEPT_USAGE(Mutable_ForwardIterator) { | |
565 *i++ = *i; // require postincrement and assignment | |
566 } | |
567 private: | |
568 TT i; | |
569 }; | |
570 | |
571 BOOST_concept(BidirectionalIterator,(TT)) | |
572 : ForwardIterator<TT> | |
573 { | |
574 BOOST_CONCEPT_USAGE(BidirectionalIterator) | |
575 { | |
576 BOOST_CONCEPT_ASSERT((Convertible< | |
577 BOOST_DEDUCED_TYPENAME BidirectionalIterator::iterator_category | |
578 , std::bidirectional_iterator_tag | |
579 >)); | |
580 | |
581 --i; // require predecrement operator | |
582 i--; // require postdecrement operator | |
583 } | |
584 private: | |
585 TT i; | |
586 }; | |
587 | |
588 BOOST_concept(Mutable_BidirectionalIterator,(TT)) | |
589 : BidirectionalIterator<TT> | |
590 , Mutable_ForwardIterator<TT> | |
591 { | |
592 BOOST_CONCEPT_USAGE(Mutable_BidirectionalIterator) | |
593 { | |
594 *i-- = *i; // require postdecrement and assignment | |
595 } | |
596 private: | |
597 TT i; | |
598 }; | |
599 | |
600 BOOST_concept(RandomAccessIterator,(TT)) | |
601 : BidirectionalIterator<TT> | |
602 , Comparable<TT> | |
603 { | |
604 BOOST_CONCEPT_USAGE(RandomAccessIterator) | |
605 { | |
606 BOOST_CONCEPT_ASSERT((Convertible< | |
607 BOOST_DEDUCED_TYPENAME BidirectionalIterator<TT>::iterator_category | |
608 , std::random_access_iterator_tag | |
609 >)); | |
610 | |
611 i += n; // require assignment addition operator | |
612 i = i + n; i = n + i; // require addition with difference type | |
613 i -= n; // require assignment subtraction operator | |
614 i = i - n; // require subtraction with difference type | |
615 n = i - j; // require difference operator | |
616 (void)i[n]; // require element access operator | |
617 } | |
618 | |
619 private: | |
620 TT a, b; | |
621 TT i, j; | |
622 typename boost::detail::iterator_traits<TT>::difference_type n; | |
623 }; | |
624 | |
625 BOOST_concept(Mutable_RandomAccessIterator,(TT)) | |
626 : RandomAccessIterator<TT> | |
627 , Mutable_BidirectionalIterator<TT> | |
628 { | |
629 BOOST_CONCEPT_USAGE(Mutable_RandomAccessIterator) | |
630 { | |
631 i[n] = *i; // require element access and assignment | |
632 } | |
633 private: | |
634 TT i; | |
635 typename boost::detail::iterator_traits<TT>::difference_type n; | |
636 }; | |
637 | |
638 //=========================================================================== | |
639 // Container s | |
640 | |
641 BOOST_concept(Container,(C)) | |
642 : Assignable<C> | |
643 { | |
644 typedef typename C::value_type value_type; | |
645 typedef typename C::difference_type difference_type; | |
646 typedef typename C::size_type size_type; | |
647 typedef typename C::const_reference const_reference; | |
648 typedef typename C::const_pointer const_pointer; | |
649 typedef typename C::const_iterator const_iterator; | |
650 | |
651 BOOST_CONCEPT_USAGE(Container) | |
652 { | |
653 BOOST_CONCEPT_ASSERT((InputIterator<const_iterator>)); | |
654 const_constraints(c); | |
655 } | |
656 | |
657 private: | |
658 void const_constraints(const C& cc) { | |
659 i = cc.begin(); | |
660 i = cc.end(); | |
661 n = cc.size(); | |
662 n = cc.max_size(); | |
663 b = cc.empty(); | |
664 } | |
665 C c; | |
666 bool b; | |
667 const_iterator i; | |
668 size_type n; | |
669 }; | |
670 | |
671 BOOST_concept(Mutable_Container,(C)) | |
672 : Container<C> | |
673 { | |
674 typedef typename C::reference reference; | |
675 typedef typename C::iterator iterator; | |
676 typedef typename C::pointer pointer; | |
677 | |
678 BOOST_CONCEPT_USAGE(Mutable_Container) | |
679 { | |
680 BOOST_CONCEPT_ASSERT(( | |
681 Assignable<typename Mutable_Container::value_type>)); | |
682 | |
683 BOOST_CONCEPT_ASSERT((InputIterator<iterator>)); | |
684 | |
685 i = c.begin(); | |
686 i = c.end(); | |
687 c.swap(c2); | |
688 } | |
689 | |
690 private: | |
691 iterator i; | |
692 C c, c2; | |
693 }; | |
694 | |
695 BOOST_concept(ForwardContainer,(C)) | |
696 : Container<C> | |
697 { | |
698 BOOST_CONCEPT_USAGE(ForwardContainer) | |
699 { | |
700 BOOST_CONCEPT_ASSERT(( | |
701 ForwardIterator< | |
702 typename ForwardContainer::const_iterator | |
703 >)); | |
704 } | |
705 }; | |
706 | |
707 BOOST_concept(Mutable_ForwardContainer,(C)) | |
708 : ForwardContainer<C> | |
709 , Mutable_Container<C> | |
710 { | |
711 BOOST_CONCEPT_USAGE(Mutable_ForwardContainer) | |
712 { | |
713 BOOST_CONCEPT_ASSERT(( | |
714 Mutable_ForwardIterator< | |
715 typename Mutable_ForwardContainer::iterator | |
716 >)); | |
717 } | |
718 }; | |
719 | |
720 BOOST_concept(ReversibleContainer,(C)) | |
721 : ForwardContainer<C> | |
722 { | |
723 typedef typename | |
724 C::const_reverse_iterator | |
725 const_reverse_iterator; | |
726 | |
727 BOOST_CONCEPT_USAGE(ReversibleContainer) | |
728 { | |
729 BOOST_CONCEPT_ASSERT(( | |
730 BidirectionalIterator< | |
731 typename ReversibleContainer::const_iterator>)); | |
732 | |
733 BOOST_CONCEPT_ASSERT((BidirectionalIterator<const_reverse_iterator>)); | |
734 | |
735 const_constraints(c); | |
736 } | |
737 private: | |
738 void const_constraints(const C& cc) | |
739 { | |
740 const_reverse_iterator i = cc.rbegin(); | |
741 i = cc.rend(); | |
742 } | |
743 C c; | |
744 }; | |
745 | |
746 BOOST_concept(Mutable_ReversibleContainer,(C)) | |
747 : Mutable_ForwardContainer<C> | |
748 , ReversibleContainer<C> | |
749 { | |
750 typedef typename C::reverse_iterator reverse_iterator; | |
751 | |
752 BOOST_CONCEPT_USAGE(Mutable_ReversibleContainer) | |
753 { | |
754 typedef typename Mutable_ForwardContainer<C>::iterator iterator; | |
755 BOOST_CONCEPT_ASSERT((Mutable_BidirectionalIterator<iterator>)); | |
756 BOOST_CONCEPT_ASSERT((Mutable_BidirectionalIterator<reverse_iterator>)); | |
757 | |
758 reverse_iterator i = c.rbegin(); | |
759 i = c.rend(); | |
760 } | |
761 private: | |
762 C c; | |
763 }; | |
764 | |
765 BOOST_concept(RandomAccessContainer,(C)) | |
766 : ReversibleContainer<C> | |
767 { | |
768 typedef typename C::size_type size_type; | |
769 typedef typename C::const_reference const_reference; | |
770 | |
771 BOOST_CONCEPT_USAGE(RandomAccessContainer) | |
772 { | |
773 BOOST_CONCEPT_ASSERT(( | |
774 RandomAccessIterator< | |
775 typename RandomAccessContainer::const_iterator | |
776 >)); | |
777 | |
778 const_constraints(c); | |
779 } | |
780 private: | |
781 void const_constraints(const C& cc) | |
782 { | |
783 const_reference r = cc[n]; | |
784 ignore_unused_variable_warning(r); | |
785 } | |
786 | |
787 C c; | |
788 size_type n; | |
789 }; | |
790 | |
791 BOOST_concept(Mutable_RandomAccessContainer,(C)) | |
792 : Mutable_ReversibleContainer<C> | |
793 , RandomAccessContainer<C> | |
794 { | |
795 private: | |
796 typedef Mutable_RandomAccessContainer self; | |
797 public: | |
798 BOOST_CONCEPT_USAGE(Mutable_RandomAccessContainer) | |
799 { | |
800 BOOST_CONCEPT_ASSERT((Mutable_RandomAccessIterator<typename self::iterator>)); | |
801 BOOST_CONCEPT_ASSERT((Mutable_RandomAccessIterator<typename self::reverse_iterator>)); | |
802 | |
803 typename self::reference r = c[i]; | |
804 ignore_unused_variable_warning(r); | |
805 } | |
806 | |
807 private: | |
808 typename Mutable_ReversibleContainer<C>::size_type i; | |
809 C c; | |
810 }; | |
811 | |
812 // A Sequence is inherently mutable | |
813 BOOST_concept(Sequence,(S)) | |
814 : Mutable_ForwardContainer<S> | |
815 // Matt Austern's book puts DefaultConstructible here, the C++ | |
816 // standard places it in Container --JGS | |
817 // ... so why aren't we following the standard? --DWA | |
818 , DefaultConstructible<S> | |
819 { | |
820 BOOST_CONCEPT_USAGE(Sequence) | |
821 { | |
822 S | |
823 c(n), | |
824 c2(n, t), | |
825 c3(first, last); | |
826 | |
827 c.insert(p, t); | |
828 c.insert(p, n, t); | |
829 c.insert(p, first, last); | |
830 | |
831 c.erase(p); | |
832 c.erase(p, q); | |
833 | |
834 typename Sequence::reference r = c.front(); | |
835 | |
836 ignore_unused_variable_warning(c); | |
837 ignore_unused_variable_warning(c2); | |
838 ignore_unused_variable_warning(c3); | |
839 ignore_unused_variable_warning(r); | |
840 const_constraints(c); | |
841 } | |
842 private: | |
843 void const_constraints(const S& c) { | |
844 typename Sequence::const_reference r = c.front(); | |
845 ignore_unused_variable_warning(r); | |
846 } | |
847 | |
848 typename S::value_type t; | |
849 typename S::size_type n; | |
850 typename S::value_type* first, *last; | |
851 typename S::iterator p, q; | |
852 }; | |
853 | |
854 BOOST_concept(FrontInsertionSequence,(S)) | |
855 : Sequence<S> | |
856 { | |
857 BOOST_CONCEPT_USAGE(FrontInsertionSequence) | |
858 { | |
859 c.push_front(t); | |
860 c.pop_front(); | |
861 } | |
862 private: | |
863 S c; | |
864 typename S::value_type t; | |
865 }; | |
866 | |
867 BOOST_concept(BackInsertionSequence,(S)) | |
868 : Sequence<S> | |
869 { | |
870 BOOST_CONCEPT_USAGE(BackInsertionSequence) | |
871 { | |
872 c.push_back(t); | |
873 c.pop_back(); | |
874 typename BackInsertionSequence::reference r = c.back(); | |
875 ignore_unused_variable_warning(r); | |
876 const_constraints(c); | |
877 } | |
878 private: | |
879 void const_constraints(const S& cc) { | |
880 typename BackInsertionSequence::const_reference | |
881 r = cc.back(); | |
882 ignore_unused_variable_warning(r); | |
883 }; | |
884 S c; | |
885 typename S::value_type t; | |
886 }; | |
887 | |
888 BOOST_concept(AssociativeContainer,(C)) | |
889 : ForwardContainer<C> | |
890 , DefaultConstructible<C> | |
891 { | |
892 typedef typename C::key_type key_type; | |
893 typedef typename C::key_compare key_compare; | |
894 typedef typename C::value_compare value_compare; | |
895 typedef typename C::iterator iterator; | |
896 | |
897 BOOST_CONCEPT_USAGE(AssociativeContainer) | |
898 { | |
899 i = c.find(k); | |
900 r = c.equal_range(k); | |
901 c.erase(k); | |
902 c.erase(i); | |
903 c.erase(r.first, r.second); | |
904 const_constraints(c); | |
905 BOOST_CONCEPT_ASSERT((BinaryPredicate<key_compare,key_type,key_type>)); | |
906 | |
907 typedef typename AssociativeContainer::value_type value_type_; | |
908 BOOST_CONCEPT_ASSERT((BinaryPredicate<value_compare,value_type_,value_type_>)); | |
909 } | |
910 | |
911 // Redundant with the base concept, but it helps below. | |
912 typedef typename C::const_iterator const_iterator; | |
913 private: | |
914 void const_constraints(const C& cc) | |
915 { | |
916 ci = cc.find(k); | |
917 n = cc.count(k); | |
918 cr = cc.equal_range(k); | |
919 } | |
920 | |
921 C c; | |
922 iterator i; | |
923 std::pair<iterator,iterator> r; | |
924 const_iterator ci; | |
925 std::pair<const_iterator,const_iterator> cr; | |
926 typename C::key_type k; | |
927 typename C::size_type n; | |
928 }; | |
929 | |
930 BOOST_concept(UniqueAssociativeContainer,(C)) | |
931 : AssociativeContainer<C> | |
932 { | |
933 BOOST_CONCEPT_USAGE(UniqueAssociativeContainer) | |
934 { | |
935 C c(first, last); | |
936 | |
937 pos_flag = c.insert(t); | |
938 c.insert(first, last); | |
939 | |
940 ignore_unused_variable_warning(c); | |
941 } | |
942 private: | |
943 std::pair<typename C::iterator, bool> pos_flag; | |
944 typename C::value_type t; | |
945 typename C::value_type* first, *last; | |
946 }; | |
947 | |
948 BOOST_concept(MultipleAssociativeContainer,(C)) | |
949 : AssociativeContainer<C> | |
950 { | |
951 BOOST_CONCEPT_USAGE(MultipleAssociativeContainer) | |
952 { | |
953 C c(first, last); | |
954 | |
955 pos = c.insert(t); | |
956 c.insert(first, last); | |
957 | |
958 ignore_unused_variable_warning(c); | |
959 ignore_unused_variable_warning(pos); | |
960 } | |
961 private: | |
962 typename C::iterator pos; | |
963 typename C::value_type t; | |
964 typename C::value_type* first, *last; | |
965 }; | |
966 | |
967 BOOST_concept(SimpleAssociativeContainer,(C)) | |
968 : AssociativeContainer<C> | |
969 { | |
970 BOOST_CONCEPT_USAGE(SimpleAssociativeContainer) | |
971 { | |
972 typedef typename C::key_type key_type; | |
973 typedef typename C::value_type value_type; | |
974 BOOST_MPL_ASSERT((boost::is_same<key_type,value_type>)); | |
975 } | |
976 }; | |
977 | |
978 BOOST_concept(PairAssociativeContainer,(C)) | |
979 : AssociativeContainer<C> | |
980 { | |
981 BOOST_CONCEPT_USAGE(PairAssociativeContainer) | |
982 { | |
983 typedef typename C::key_type key_type; | |
984 typedef typename C::value_type value_type; | |
985 typedef typename C::mapped_type mapped_type; | |
986 typedef std::pair<const key_type, mapped_type> required_value_type; | |
987 BOOST_MPL_ASSERT((boost::is_same<value_type,required_value_type>)); | |
988 } | |
989 }; | |
990 | |
991 BOOST_concept(SortedAssociativeContainer,(C)) | |
992 : AssociativeContainer<C> | |
993 , ReversibleContainer<C> | |
994 { | |
995 BOOST_CONCEPT_USAGE(SortedAssociativeContainer) | |
996 { | |
997 C | |
998 c(kc), | |
999 c2(first, last), | |
1000 c3(first, last, kc); | |
1001 | |
1002 p = c.upper_bound(k); | |
1003 p = c.lower_bound(k); | |
1004 r = c.equal_range(k); | |
1005 | |
1006 c.insert(p, t); | |
1007 | |
1008 ignore_unused_variable_warning(c); | |
1009 ignore_unused_variable_warning(c2); | |
1010 ignore_unused_variable_warning(c3); | |
1011 const_constraints(c); | |
1012 } | |
1013 | |
1014 void const_constraints(const C& c) | |
1015 { | |
1016 kc = c.key_comp(); | |
1017 vc = c.value_comp(); | |
1018 | |
1019 cp = c.upper_bound(k); | |
1020 cp = c.lower_bound(k); | |
1021 cr = c.equal_range(k); | |
1022 } | |
1023 | |
1024 private: | |
1025 typename C::key_compare kc; | |
1026 typename C::value_compare vc; | |
1027 typename C::value_type t; | |
1028 typename C::key_type k; | |
1029 typedef typename C::iterator iterator; | |
1030 typedef typename C::const_iterator const_iterator; | |
1031 | |
1032 typedef SortedAssociativeContainer self; | |
1033 iterator p; | |
1034 const_iterator cp; | |
1035 std::pair<typename self::iterator,typename self::iterator> r; | |
1036 std::pair<typename self::const_iterator,typename self::const_iterator> cr; | |
1037 typename C::value_type* first, *last; | |
1038 }; | |
1039 | |
1040 // HashedAssociativeContainer | |
1041 | |
1042 BOOST_concept(Collection,(C)) | |
1043 { | |
1044 BOOST_CONCEPT_USAGE(Collection) | |
1045 { | |
1046 boost::function_requires<boost::InputIteratorConcept<iterator> >(); | |
1047 boost::function_requires<boost::InputIteratorConcept<const_iterator> >(); | |
1048 boost::function_requires<boost::CopyConstructibleConcept<value_type> >(); | |
1049 const_constraints(c); | |
1050 i = c.begin(); | |
1051 i = c.end(); | |
1052 c.swap(c); | |
1053 } | |
1054 | |
1055 void const_constraints(const C& cc) { | |
1056 ci = cc.begin(); | |
1057 ci = cc.end(); | |
1058 n = cc.size(); | |
1059 b = cc.empty(); | |
1060 } | |
1061 | |
1062 private: | |
1063 typedef typename C::value_type value_type; | |
1064 typedef typename C::iterator iterator; | |
1065 typedef typename C::const_iterator const_iterator; | |
1066 typedef typename C::reference reference; | |
1067 typedef typename C::const_reference const_reference; | |
1068 // typedef typename C::pointer pointer; | |
1069 typedef typename C::difference_type difference_type; | |
1070 typedef typename C::size_type size_type; | |
1071 | |
1072 C c; | |
1073 bool b; | |
1074 iterator i; | |
1075 const_iterator ci; | |
1076 size_type n; | |
1077 }; | |
1078 } // namespace boost | |
1079 | |
1080 # include <boost/concept/detail/concept_undef.hpp> | |
1081 | |
1082 #endif // BOOST_CONCEPT_CHECKS_HPP | |
1083 |