fix doc example typo
[boost.git] / boost / concept_check.hpp
blob12ec2ad77525e1fbe0884d7ce12a275f0fafd16e
1 //
2 // (C) Copyright Jeremy Siek 2000.
3 // Distributed under the Boost Software License, Version 1.0. (See
4 // accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // Revision History:
8 // 05 May 2001: Workarounds for HP aCC from Thomas Matelich. (Jeremy Siek)
9 // 02 April 2001: Removed limits header altogether. (Jeremy Siek)
10 // 01 April 2001: Modified to use new <boost/limits.hpp> header. (JMaddock)
13 // See http://www.boost.org/libs/concept_check for documentation.
15 #ifndef BOOST_CONCEPT_CHECKS_HPP
16 # define BOOST_CONCEPT_CHECKS_HPP
18 # include <boost/concept/assert.hpp>
20 # include <boost/iterator.hpp>
21 # include <boost/type_traits/conversion_traits.hpp>
22 # include <utility>
23 # include <boost/type_traits/is_same.hpp>
24 # include <boost/type_traits/is_void.hpp>
25 # include <boost/mpl/assert.hpp>
26 # include <boost/mpl/bool.hpp>
27 # include <boost/detail/workaround.hpp>
28 # include <boost/detail/iterator.hpp>
30 # include <boost/concept/usage.hpp>
31 # include <boost/concept/detail/concept_def.hpp>
33 namespace boost
37 // Backward compatibility
40 template <class Model>
41 inline void function_requires(Model* = 0)
43 BOOST_CONCEPT_ASSERT((Model));
45 template <class T> inline void ignore_unused_variable_warning(T const&) {}
47 # define BOOST_CLASS_REQUIRE(type_var, ns, concept) \
48 BOOST_CONCEPT_ASSERT((ns::concept<type_var>))
50 # define BOOST_CLASS_REQUIRE2(type_var1, type_var2, ns, concept) \
51 BOOST_CONCEPT_ASSERT((ns::concept<type_var1,type_var2>))
53 # define BOOST_CLASS_REQUIRE3(tv1, tv2, tv3, ns, concept) \
54 BOOST_CONCEPT_ASSERT((ns::concept<tv1,tv2,tv3>))
56 # define BOOST_CLASS_REQUIRE4(tv1, tv2, tv3, tv4, ns, concept) \
57 BOOST_CONCEPT_ASSERT((ns::concept<tv1,tv2,tv3,tv4>))
61 // Begin concept definitions
63 BOOST_concept(Integer, (T))
65 BOOST_CONCEPT_USAGE(Integer)
67 x.error_type_must_be_an_integer_type();
69 private:
70 T x;
73 template <> struct Integer<signed char> {};
74 template <> struct Integer<unsigned char> {};
75 template <> struct Integer<short> {};
76 template <> struct Integer<unsigned short> {};
77 template <> struct Integer<int> {};
78 template <> struct Integer<unsigned int> {};
79 template <> struct Integer<long> {};
80 template <> struct Integer<unsigned long> {};
81 # if defined(BOOST_HAS_LONG_LONG)
82 template <> struct Integer< ::boost::long_long_type> {};
83 template <> struct Integer< ::boost::ulong_long_type> {};
84 # elif defined(BOOST_HAS_MS_INT64)
85 template <> struct Integer<__int64> {};
86 template <> struct Integer<unsigned __int64> {};
87 # endif
89 BOOST_concept(SignedInteger,(T)) {
90 BOOST_CONCEPT_USAGE(SignedInteger) {
91 x.error_type_must_be_a_signed_integer_type();
93 private:
94 T x;
96 template <> struct SignedInteger<signed char> { };
97 template <> struct SignedInteger<short> {};
98 template <> struct SignedInteger<int> {};
99 template <> struct SignedInteger<long> {};
100 # if defined(BOOST_HAS_LONG_LONG)
101 template <> struct SignedInteger< ::boost::long_long_type> {};
102 # elif defined(BOOST_HAS_MS_INT64)
103 template <> struct SignedInteger<__int64> {};
104 # endif
106 BOOST_concept(UnsignedInteger,(T)) {
107 BOOST_CONCEPT_USAGE(UnsignedInteger) {
108 x.error_type_must_be_an_unsigned_integer_type();
110 private:
111 T x;
114 template <> struct UnsignedInteger<unsigned char> {};
115 template <> struct UnsignedInteger<unsigned short> {};
116 template <> struct UnsignedInteger<unsigned int> {};
117 template <> struct UnsignedInteger<unsigned long> {};
118 # if defined(BOOST_HAS_LONG_LONG)
119 template <> struct UnsignedInteger< ::boost::ulong_long_type> {};
120 # elif defined(BOOST_HAS_MS_INT64)
121 template <> struct UnsignedInteger<unsigned __int64> {};
122 # endif
124 //===========================================================================
125 // Basic Concepts
127 BOOST_concept(DefaultConstructible,(TT))
129 BOOST_CONCEPT_USAGE(DefaultConstructible) {
130 TT a; // require default constructor
131 ignore_unused_variable_warning(a);
135 BOOST_concept(Assignable,(TT))
137 BOOST_CONCEPT_USAGE(Assignable) {
138 #if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
139 a = a; // require assignment operator
140 #endif
141 const_constraints(a);
143 private:
144 void const_constraints(const TT& b) {
145 #if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
146 a = b; // const required for argument to assignment
147 #else
148 ignore_unused_variable_warning(b);
149 #endif
151 private:
152 TT a;
156 BOOST_concept(CopyConstructible,(TT))
158 BOOST_CONCEPT_USAGE(CopyConstructible) {
159 TT a(b); // require copy constructor
160 TT* ptr = &a; // require address of operator
161 const_constraints(a);
162 ignore_unused_variable_warning(ptr);
164 private:
165 void const_constraints(const TT& a) {
166 TT c(a); // require const copy constructor
167 const TT* ptr = &a; // require const address of operator
168 ignore_unused_variable_warning(c);
169 ignore_unused_variable_warning(ptr);
171 TT b;
174 #if (defined _MSC_VER)
175 # pragma warning( push )
176 # pragma warning( disable : 4510 ) // default constructor could not be generated
177 # pragma warning( disable : 4610 ) // object 'class' can never be instantiated - user-defined constructor required
178 #endif
179 // The SGI STL version of Assignable requires copy constructor and operator=
180 BOOST_concept(SGIAssignable,(TT))
182 BOOST_CONCEPT_USAGE(SGIAssignable) {
183 TT b(a);
184 #if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
185 a = a; // require assignment operator
186 #endif
187 const_constraints(a);
188 ignore_unused_variable_warning(b);
190 private:
191 void const_constraints(const TT& b) {
192 TT c(b);
193 #if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
194 a = b; // const required for argument to assignment
195 #endif
196 ignore_unused_variable_warning(c);
198 TT a;
200 #if (defined _MSC_VER)
201 # pragma warning( pop )
202 #endif
204 BOOST_concept(Convertible,(X)(Y))
206 BOOST_CONCEPT_USAGE(Convertible) {
207 Y y = x;
208 ignore_unused_variable_warning(y);
210 private:
211 X x;
214 // The C++ standard requirements for many concepts talk about return
215 // types that must be "convertible to bool". The problem with this
216 // requirement is that it leaves the door open for evil proxies that
217 // define things like operator|| with strange return types. Two
218 // possible solutions are:
219 // 1) require the return type to be exactly bool
220 // 2) stay with convertible to bool, and also
221 // specify stuff about all the logical operators.
222 // For now we just test for convertible to bool.
223 template <class TT>
224 void require_boolean_expr(const TT& t) {
225 bool x = t;
226 ignore_unused_variable_warning(x);
229 BOOST_concept(EqualityComparable,(TT))
231 BOOST_CONCEPT_USAGE(EqualityComparable) {
232 require_boolean_expr(a == b);
233 require_boolean_expr(a != b);
235 private:
236 TT a, b;
239 BOOST_concept(LessThanComparable,(TT))
241 BOOST_CONCEPT_USAGE(LessThanComparable) {
242 require_boolean_expr(a < b);
244 private:
245 TT a, b;
248 // This is equivalent to SGI STL's LessThanComparable.
249 BOOST_concept(Comparable,(TT))
251 BOOST_CONCEPT_USAGE(Comparable) {
252 require_boolean_expr(a < b);
253 require_boolean_expr(a > b);
254 require_boolean_expr(a <= b);
255 require_boolean_expr(a >= b);
257 private:
258 TT a, b;
261 #define BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(OP,NAME) \
262 BOOST_concept(NAME, (First)(Second)) \
264 BOOST_CONCEPT_USAGE(NAME) { (void)constraints_(); } \
265 private: \
266 bool constraints_() { return a OP b; } \
267 First a; \
268 Second b; \
271 #define BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(OP,NAME) \
272 BOOST_concept(NAME, (Ret)(First)(Second)) \
274 BOOST_CONCEPT_USAGE(NAME) { (void)constraints_(); } \
275 private: \
276 Ret constraints_() { return a OP b; } \
277 First a; \
278 Second b; \
281 BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(==, EqualOp);
282 BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(!=, NotEqualOp);
283 BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<, LessThanOp);
284 BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<=, LessEqualOp);
285 BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>, GreaterThanOp);
286 BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>=, GreaterEqualOp);
288 BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(+, PlusOp);
289 BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(*, TimesOp);
290 BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(/, DivideOp);
291 BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(-, SubtractOp);
292 BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(%, ModOp);
294 //===========================================================================
295 // Function Object Concepts
297 BOOST_concept(Generator,(Func)(Return))
299 BOOST_CONCEPT_USAGE(Generator) { test(is_void<Return>()); }
301 private:
302 void test(boost::mpl::false_)
304 // Do we really want a reference here?
305 const Return& r = f();
306 ignore_unused_variable_warning(r);
309 void test(boost::mpl::true_)
311 f();
314 Func f;
317 BOOST_concept(UnaryFunction,(Func)(Return)(Arg))
319 BOOST_CONCEPT_USAGE(UnaryFunction) { test(is_void<Return>()); }
321 private:
322 void test(boost::mpl::false_)
324 f(arg); // "priming the pump" this way keeps msvc6 happy (ICE)
325 Return r = f(arg);
326 ignore_unused_variable_warning(r);
329 void test(boost::mpl::true_)
331 f(arg);
334 Func f;
335 Arg arg;
338 BOOST_concept(BinaryFunction,(Func)(Return)(First)(Second))
340 BOOST_CONCEPT_USAGE(BinaryFunction) { test(is_void<Return>()); }
341 private:
342 void test(boost::mpl::false_)
344 f(first,second);
345 Return r = f(first, second); // require operator()
346 (void)r;
349 void test(boost::mpl::true_)
351 f(first,second);
354 Func f;
355 First first;
356 Second second;
359 BOOST_concept(UnaryPredicate,(Func)(Arg))
361 BOOST_CONCEPT_USAGE(UnaryPredicate) {
362 require_boolean_expr(f(arg)); // require operator() returning bool
364 private:
365 Func f;
366 Arg arg;
369 BOOST_concept(BinaryPredicate,(Func)(First)(Second))
371 BOOST_CONCEPT_USAGE(BinaryPredicate) {
372 require_boolean_expr(f(a, b)); // require operator() returning bool
374 private:
375 Func f;
376 First a;
377 Second b;
380 // use this when functor is used inside a container class like std::set
381 BOOST_concept(Const_BinaryPredicate,(Func)(First)(Second))
382 : BinaryPredicate<Func, First, Second>
384 BOOST_CONCEPT_USAGE(Const_BinaryPredicate) {
385 const_constraints(f);
387 private:
388 void const_constraints(const Func& fun) {
389 // operator() must be a const member function
390 require_boolean_expr(fun(a, b));
392 Func f;
393 First a;
394 Second b;
397 BOOST_concept(AdaptableGenerator,(Func)(Return))
398 : Generator<Func, typename Func::result_type>
400 typedef typename Func::result_type result_type;
402 BOOST_CONCEPT_USAGE(AdaptableGenerator)
404 BOOST_CONCEPT_ASSERT((Convertible<result_type, Return>));
408 BOOST_concept(AdaptableUnaryFunction,(Func)(Return)(Arg))
409 : UnaryFunction<Func, typename Func::result_type, typename Func::argument_type>
411 typedef typename Func::argument_type argument_type;
412 typedef typename Func::result_type result_type;
414 ~AdaptableUnaryFunction()
416 BOOST_CONCEPT_ASSERT((Convertible<result_type, Return>));
417 BOOST_CONCEPT_ASSERT((Convertible<Arg, argument_type>));
421 BOOST_concept(AdaptableBinaryFunction,(Func)(Return)(First)(Second))
422 : BinaryFunction<
423 Func
424 , typename Func::result_type
425 , typename Func::first_argument_type
426 , typename Func::second_argument_type
429 typedef typename Func::first_argument_type first_argument_type;
430 typedef typename Func::second_argument_type second_argument_type;
431 typedef typename Func::result_type result_type;
433 ~AdaptableBinaryFunction()
435 BOOST_CONCEPT_ASSERT((Convertible<result_type, Return>));
436 BOOST_CONCEPT_ASSERT((Convertible<First, first_argument_type>));
437 BOOST_CONCEPT_ASSERT((Convertible<Second, second_argument_type>));
441 BOOST_concept(AdaptablePredicate,(Func)(Arg))
442 : UnaryPredicate<Func, Arg>
443 , AdaptableUnaryFunction<Func, bool, Arg>
447 BOOST_concept(AdaptableBinaryPredicate,(Func)(First)(Second))
448 : BinaryPredicate<Func, First, Second>
449 , AdaptableBinaryFunction<Func, bool, First, Second>
453 //===========================================================================
454 // Iterator Concepts
456 BOOST_concept(InputIterator,(TT))
457 : Assignable<TT>
458 , EqualityComparable<TT>
460 typedef typename boost::detail::iterator_traits<TT>::value_type value_type;
461 typedef typename boost::detail::iterator_traits<TT>::difference_type difference_type;
462 typedef typename boost::detail::iterator_traits<TT>::reference reference;
463 typedef typename boost::detail::iterator_traits<TT>::pointer pointer;
464 typedef typename boost::detail::iterator_traits<TT>::iterator_category iterator_category;
466 BOOST_CONCEPT_USAGE(InputIterator)
468 BOOST_CONCEPT_ASSERT((SignedInteger<difference_type>));
469 BOOST_CONCEPT_ASSERT((Convertible<iterator_category, std::input_iterator_tag>));
471 TT j(i);
472 (void)*i; // require dereference operator
473 ++j; // require preincrement operator
474 i++; // require postincrement operator
476 private:
477 TT i;
480 BOOST_concept(OutputIterator,(TT)(ValueT))
481 : Assignable<TT>
483 BOOST_CONCEPT_USAGE(OutputIterator) {
485 ++i; // require preincrement operator
486 i++; // require postincrement operator
487 *i++ = t; // require postincrement and assignment
489 private:
490 TT i, j;
491 ValueT t;
494 BOOST_concept(ForwardIterator,(TT))
495 : InputIterator<TT>
497 BOOST_CONCEPT_USAGE(ForwardIterator)
499 BOOST_CONCEPT_ASSERT((Convertible<
500 BOOST_DEDUCED_TYPENAME ForwardIterator::iterator_category
501 , std::forward_iterator_tag
502 >));
504 typename InputIterator<TT>::reference r = *i;
505 ignore_unused_variable_warning(r);
508 private:
509 TT i;
512 BOOST_concept(Mutable_ForwardIterator,(TT))
513 : ForwardIterator<TT>
515 BOOST_CONCEPT_USAGE(Mutable_ForwardIterator) {
516 *i++ = *i; // require postincrement and assignment
518 private:
519 TT i;
522 BOOST_concept(BidirectionalIterator,(TT))
523 : ForwardIterator<TT>
525 BOOST_CONCEPT_USAGE(BidirectionalIterator)
527 BOOST_CONCEPT_ASSERT((Convertible<
528 BOOST_DEDUCED_TYPENAME BidirectionalIterator::iterator_category
529 , std::bidirectional_iterator_tag
530 >));
532 --i; // require predecrement operator
533 i--; // require postdecrement operator
535 private:
536 TT i;
539 BOOST_concept(Mutable_BidirectionalIterator,(TT))
540 : BidirectionalIterator<TT>
541 , Mutable_ForwardIterator<TT>
543 BOOST_CONCEPT_USAGE(Mutable_BidirectionalIterator)
545 *i-- = *i; // require postdecrement and assignment
547 private:
548 TT i;
551 BOOST_concept(RandomAccessIterator,(TT))
552 : BidirectionalIterator<TT>
553 , Comparable<TT>
555 BOOST_CONCEPT_USAGE(RandomAccessIterator)
557 BOOST_CONCEPT_ASSERT((Convertible<
558 BOOST_DEDUCED_TYPENAME BidirectionalIterator<TT>::iterator_category
559 , std::random_access_iterator_tag
560 >));
562 i += n; // require assignment addition operator
563 i = i + n; i = n + i; // require addition with difference type
564 i -= n; // require assignment subtraction operator
565 i = i - n; // require subtraction with difference type
566 n = i - j; // require difference operator
567 (void)i[n]; // require element access operator
570 private:
571 TT a, b;
572 TT i, j;
573 typename boost::detail::iterator_traits<TT>::difference_type n;
576 BOOST_concept(Mutable_RandomAccessIterator,(TT))
577 : RandomAccessIterator<TT>
578 , Mutable_BidirectionalIterator<TT>
580 BOOST_CONCEPT_USAGE(Mutable_RandomAccessIterator)
582 i[n] = *i; // require element access and assignment
584 private:
585 TT i;
586 typename boost::detail::iterator_traits<TT>::difference_type n;
589 //===========================================================================
590 // Container s
592 BOOST_concept(Container,(C))
593 : Assignable<C>
595 typedef typename C::value_type value_type;
596 typedef typename C::difference_type difference_type;
597 typedef typename C::size_type size_type;
598 typedef typename C::const_reference const_reference;
599 typedef typename C::const_pointer const_pointer;
600 typedef typename C::const_iterator const_iterator;
602 BOOST_CONCEPT_USAGE(Container)
604 BOOST_CONCEPT_ASSERT((InputIterator<const_iterator>));
605 const_constraints(c);
608 private:
609 void const_constraints(const C& cc) {
610 i = cc.begin();
611 i = cc.end();
612 n = cc.size();
613 n = cc.max_size();
614 b = cc.empty();
616 C c;
617 bool b;
618 const_iterator i;
619 size_type n;
622 BOOST_concept(Mutable_Container,(C))
623 : Container<C>
625 typedef typename C::reference reference;
626 typedef typename C::iterator iterator;
627 typedef typename C::pointer pointer;
629 BOOST_CONCEPT_USAGE(Mutable_Container)
631 BOOST_CONCEPT_ASSERT((
632 Assignable<typename Mutable_Container::value_type>));
634 BOOST_CONCEPT_ASSERT((InputIterator<iterator>));
636 i = c.begin();
637 i = c.end();
638 c.swap(c2);
641 private:
642 iterator i;
643 C c, c2;
646 BOOST_concept(ForwardContainer,(C))
647 : Container<C>
649 BOOST_CONCEPT_USAGE(ForwardContainer)
651 BOOST_CONCEPT_ASSERT((
652 ForwardIterator<
653 typename ForwardContainer::const_iterator
654 >));
658 BOOST_concept(Mutable_ForwardContainer,(C))
659 : ForwardContainer<C>
660 , Mutable_Container<C>
662 BOOST_CONCEPT_USAGE(Mutable_ForwardContainer)
664 BOOST_CONCEPT_ASSERT((
665 Mutable_ForwardIterator<
666 typename Mutable_ForwardContainer::iterator
667 >));
671 BOOST_concept(ReversibleContainer,(C))
672 : ForwardContainer<C>
674 typedef typename
675 C::const_reverse_iterator
676 const_reverse_iterator;
678 BOOST_CONCEPT_USAGE(ReversibleContainer)
680 BOOST_CONCEPT_ASSERT((
681 BidirectionalIterator<
682 typename ReversibleContainer::const_iterator>));
684 BOOST_CONCEPT_ASSERT((BidirectionalIterator<const_reverse_iterator>));
686 const_constraints(c);
688 private:
689 void const_constraints(const C& cc)
691 const_reverse_iterator i = cc.rbegin();
692 i = cc.rend();
694 C c;
697 BOOST_concept(Mutable_ReversibleContainer,(C))
698 : Mutable_ForwardContainer<C>
699 , ReversibleContainer<C>
701 typedef typename C::reverse_iterator reverse_iterator;
703 BOOST_CONCEPT_USAGE(Mutable_ReversibleContainer)
705 typedef typename Mutable_ForwardContainer<C>::iterator iterator;
706 BOOST_CONCEPT_ASSERT((Mutable_BidirectionalIterator<iterator>));
707 BOOST_CONCEPT_ASSERT((Mutable_BidirectionalIterator<reverse_iterator>));
709 reverse_iterator i = c.rbegin();
710 i = c.rend();
712 private:
713 C c;
716 BOOST_concept(RandomAccessContainer,(C))
717 : ReversibleContainer<C>
719 typedef typename C::size_type size_type;
720 typedef typename C::const_reference const_reference;
722 BOOST_CONCEPT_USAGE(RandomAccessContainer)
724 BOOST_CONCEPT_ASSERT((
725 RandomAccessIterator<
726 typename RandomAccessContainer::const_iterator
727 >));
729 const_constraints(c);
731 private:
732 void const_constraints(const C& cc)
734 const_reference r = cc[n];
735 ignore_unused_variable_warning(r);
738 C c;
739 size_type n;
742 BOOST_concept(Mutable_RandomAccessContainer,(C))
743 : Mutable_ReversibleContainer<C>
744 , RandomAccessContainer<C>
746 private:
747 typedef Mutable_RandomAccessContainer self;
748 public:
749 BOOST_CONCEPT_USAGE(Mutable_RandomAccessContainer)
751 BOOST_CONCEPT_ASSERT((Mutable_RandomAccessIterator<typename self::iterator>));
752 BOOST_CONCEPT_ASSERT((Mutable_RandomAccessIterator<typename self::reverse_iterator>));
754 typename self::reference r = c[i];
755 ignore_unused_variable_warning(r);
758 private:
759 typename Mutable_ReversibleContainer<C>::size_type i;
760 C c;
763 // A Sequence is inherently mutable
764 BOOST_concept(Sequence,(S))
765 : Mutable_ForwardContainer<S>
766 // Matt Austern's book puts DefaultConstructible here, the C++
767 // standard places it in Container --JGS
768 // ... so why aren't we following the standard? --DWA
769 , DefaultConstructible<S>
771 BOOST_CONCEPT_USAGE(Sequence)
774 c(n),
775 c2(n, t),
776 c3(first, last);
778 c.insert(p, t);
779 c.insert(p, n, t);
780 c.insert(p, first, last);
782 c.erase(p);
783 c.erase(p, q);
785 typename Sequence::reference r = c.front();
787 ignore_unused_variable_warning(c);
788 ignore_unused_variable_warning(c2);
789 ignore_unused_variable_warning(c3);
790 ignore_unused_variable_warning(r);
791 const_constraints(c);
793 private:
794 void const_constraints(const S& c) {
795 typename Sequence::const_reference r = c.front();
796 ignore_unused_variable_warning(r);
799 typename S::value_type t;
800 typename S::size_type n;
801 typename S::value_type* first, *last;
802 typename S::iterator p, q;
805 BOOST_concept(FrontInsertionSequence,(S))
806 : Sequence<S>
808 BOOST_CONCEPT_USAGE(FrontInsertionSequence)
810 c.push_front(t);
811 c.pop_front();
813 private:
814 S c;
815 typename S::value_type t;
818 BOOST_concept(BackInsertionSequence,(S))
819 : Sequence<S>
821 BOOST_CONCEPT_USAGE(BackInsertionSequence)
823 c.push_back(t);
824 c.pop_back();
825 typename BackInsertionSequence::reference r = c.back();
826 ignore_unused_variable_warning(r);
827 const_constraints(c);
829 private:
830 void const_constraints(const S& cc) {
831 typename BackInsertionSequence::const_reference
832 r = cc.back();
833 ignore_unused_variable_warning(r);
835 S c;
836 typename S::value_type t;
839 BOOST_concept(AssociativeContainer,(C))
840 : ForwardContainer<C>
841 , DefaultConstructible<C>
843 typedef typename C::key_type key_type;
844 typedef typename C::key_compare key_compare;
845 typedef typename C::value_compare value_compare;
846 typedef typename C::iterator iterator;
848 BOOST_CONCEPT_USAGE(AssociativeContainer)
850 i = c.find(k);
851 r = c.equal_range(k);
852 c.erase(k);
853 c.erase(i);
854 c.erase(r.first, r.second);
855 const_constraints(c);
856 BOOST_CONCEPT_ASSERT((BinaryPredicate<key_compare,key_type,key_type>));
858 typedef typename AssociativeContainer::value_type value_type_;
859 BOOST_CONCEPT_ASSERT((BinaryPredicate<value_compare,value_type_,value_type_>));
862 // Redundant with the base concept, but it helps below.
863 typedef typename C::const_iterator const_iterator;
864 private:
865 void const_constraints(const C& cc)
867 ci = cc.find(k);
868 n = cc.count(k);
869 cr = cc.equal_range(k);
872 C c;
873 iterator i;
874 std::pair<iterator,iterator> r;
875 const_iterator ci;
876 std::pair<const_iterator,const_iterator> cr;
877 typename C::key_type k;
878 typename C::size_type n;
881 BOOST_concept(UniqueAssociativeContainer,(C))
882 : AssociativeContainer<C>
884 BOOST_CONCEPT_USAGE(UniqueAssociativeContainer)
886 C c(first, last);
888 pos_flag = c.insert(t);
889 c.insert(first, last);
891 ignore_unused_variable_warning(c);
893 private:
894 std::pair<typename C::iterator, bool> pos_flag;
895 typename C::value_type t;
896 typename C::value_type* first, *last;
899 BOOST_concept(MultipleAssociativeContainer,(C))
900 : AssociativeContainer<C>
902 BOOST_CONCEPT_USAGE(MultipleAssociativeContainer)
904 C c(first, last);
906 pos = c.insert(t);
907 c.insert(first, last);
909 ignore_unused_variable_warning(c);
910 ignore_unused_variable_warning(pos);
912 private:
913 typename C::iterator pos;
914 typename C::value_type t;
915 typename C::value_type* first, *last;
918 BOOST_concept(SimpleAssociativeContainer,(C))
919 : AssociativeContainer<C>
921 BOOST_CONCEPT_USAGE(SimpleAssociativeContainer)
923 typedef typename C::key_type key_type;
924 typedef typename C::value_type value_type;
925 BOOST_MPL_ASSERT((boost::is_same<key_type,value_type>));
929 BOOST_concept(PairAssociativeContainer,(C))
930 : AssociativeContainer<C>
932 BOOST_CONCEPT_USAGE(PairAssociativeContainer)
934 typedef typename C::key_type key_type;
935 typedef typename C::value_type value_type;
936 typedef typename C::mapped_type mapped_type;
937 typedef std::pair<const key_type, mapped_type> required_value_type;
938 BOOST_MPL_ASSERT((boost::is_same<value_type,required_value_type>));
942 BOOST_concept(SortedAssociativeContainer,(C))
943 : AssociativeContainer<C>
944 , ReversibleContainer<C>
946 BOOST_CONCEPT_USAGE(SortedAssociativeContainer)
949 c(kc),
950 c2(first, last),
951 c3(first, last, kc);
953 p = c.upper_bound(k);
954 p = c.lower_bound(k);
955 r = c.equal_range(k);
957 c.insert(p, t);
959 ignore_unused_variable_warning(c);
960 ignore_unused_variable_warning(c2);
961 ignore_unused_variable_warning(c3);
962 const_constraints(c);
965 void const_constraints(const C& c)
967 kc = c.key_comp();
968 vc = c.value_comp();
970 cp = c.upper_bound(k);
971 cp = c.lower_bound(k);
972 cr = c.equal_range(k);
975 private:
976 typename C::key_compare kc;
977 typename C::value_compare vc;
978 typename C::value_type t;
979 typename C::key_type k;
980 typedef typename C::iterator iterator;
981 typedef typename C::const_iterator const_iterator;
983 typedef SortedAssociativeContainer self;
984 iterator p;
985 const_iterator cp;
986 std::pair<typename self::iterator,typename self::iterator> r;
987 std::pair<typename self::const_iterator,typename self::const_iterator> cr;
988 typename C::value_type* first, *last;
991 // HashedAssociativeContainer
993 } // namespace boost
995 # include <boost/concept/detail/concept_undef.hpp>
997 #endif // BOOST_CONCEPT_CHECKS_HPP