2 // (C) Copyright Jeremy Siek 2000.
3 // Copyright 2002 The Trustees of Indiana University.
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)
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)
15 // See http://www.boost.org/libs/concept_check for documentation.
17 #ifndef BOOST_CONCEPT_CHECKS_HPP
18 # define BOOST_CONCEPT_CHECKS_HPP
20 # include <boost/concept/assert.hpp>
22 # include <boost/iterator.hpp>
23 # include <boost/type_traits/conversion_traits.hpp>
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>
32 # include <boost/concept/usage.hpp>
33 # include <boost/concept/detail/concept_def.hpp>
39 // Backward compatibility
42 template <class Model>
43 inline void function_requires(Model* = 0)
45 BOOST_CONCEPT_ASSERT((Model));
47 template <class T> inline void ignore_unused_variable_warning(T const&) {}
49 # define BOOST_CLASS_REQUIRE(type_var, ns, concept) \
50 BOOST_CONCEPT_ASSERT((ns::concept<type_var>))
52 # define BOOST_CLASS_REQUIRE2(type_var1, type_var2, ns, concept) \
53 BOOST_CONCEPT_ASSERT((ns::concept<type_var1,type_var2>))
55 # define BOOST_CLASS_REQUIRE3(tv1, tv2, tv3, ns, concept) \
56 BOOST_CONCEPT_ASSERT((ns::concept<tv1,tv2,tv3>))
58 # define BOOST_CLASS_REQUIRE4(tv1, tv2, tv3, tv4, ns, concept) \
59 BOOST_CONCEPT_ASSERT((ns::concept<tv1,tv2,tv3,tv4>))
63 // Begin concept definitions
65 BOOST_concept(Integer, (T))
67 BOOST_CONCEPT_USAGE(Integer)
69 x.error_type_must_be_an_integer_type();
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> {};
92 BOOST_concept(SignedInteger,(T)) {
93 BOOST_CONCEPT_USAGE(SignedInteger) {
94 x.error_type_must_be_a_signed_integer_type();
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> {};
109 BOOST_concept(UnsignedInteger,(T)) {
110 BOOST_CONCEPT_USAGE(UnsignedInteger) {
111 x.error_type_must_be_an_unsigned_integer_type();
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> {};
127 //===========================================================================
130 BOOST_concept(DefaultConstructible,(TT))
132 BOOST_CONCEPT_USAGE(DefaultConstructible) {
133 TT a; // require default constructor
134 ignore_unused_variable_warning(a);
138 BOOST_concept(Assignable,(TT))
140 BOOST_CONCEPT_USAGE(Assignable) {
141 #if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
142 a = b; // require assignment operator
144 const_constraints(b);
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
151 ignore_unused_variable_warning(x);
160 BOOST_concept(CopyConstructible,(TT))
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);
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);
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
183 // The SGI STL version of Assignable requires copy constructor and operator=
184 BOOST_concept(SGIAssignable,(TT))
186 BOOST_CONCEPT_USAGE(SGIAssignable) {
188 #if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
189 a = b; // require assignment operator
191 const_constraints(b);
192 ignore_unused_variable_warning(c);
195 void const_constraints(const TT& x) {
197 #if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
198 a = x; // const required for argument to assignment
200 ignore_unused_variable_warning(c);
205 #if (defined _MSC_VER)
206 # pragma warning( pop )
209 BOOST_concept(Convertible,(X)(Y))
211 BOOST_CONCEPT_USAGE(Convertible) {
213 ignore_unused_variable_warning(y);
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.
229 void require_boolean_expr(const TT& t) {
231 ignore_unused_variable_warning(x);
234 BOOST_concept(EqualityComparable,(TT))
236 BOOST_CONCEPT_USAGE(EqualityComparable) {
237 require_boolean_expr(a == b);
238 require_boolean_expr(a != b);
244 BOOST_concept(LessThanComparable,(TT))
246 BOOST_CONCEPT_USAGE(LessThanComparable) {
247 require_boolean_expr(a < b);
253 // This is equivalent to SGI STL's LessThanComparable.
254 BOOST_concept(Comparable,(TT))
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);
266 #define BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(OP,NAME) \
267 BOOST_concept(NAME, (First)(Second)) \
269 BOOST_CONCEPT_USAGE(NAME) { (void)constraints_(); } \
271 bool constraints_() { return a OP b; } \
276 #define BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(OP,NAME) \
277 BOOST_concept(NAME, (Ret)(First)(Second)) \
279 BOOST_CONCEPT_USAGE(NAME) { (void)constraints_(); } \
281 Ret constraints_() { return a OP b; } \
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);
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);
299 //===========================================================================
300 // Function Object Concepts
302 BOOST_concept(Generator,(Func)(Return))
304 BOOST_CONCEPT_USAGE(Generator) { test(is_void<Return>()); }
307 void test(boost::mpl::false_)
309 // Do we really want a reference here?
310 const Return& r = f();
311 ignore_unused_variable_warning(r);
314 void test(boost::mpl::true_)
322 BOOST_concept(UnaryFunction,(Func)(Return)(Arg))
324 BOOST_CONCEPT_USAGE(UnaryFunction) { test(is_void<Return>()); }
327 void test(boost::mpl::false_)
329 f(arg); // "priming the pump" this way keeps msvc6 happy (ICE)
331 ignore_unused_variable_warning(r);
334 void test(boost::mpl::true_)
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])
352 BOOST_concept(BinaryFunction,(Func)(Return)(First)(Second))
354 BOOST_CONCEPT_USAGE(BinaryFunction) { test(is_void<Return>()); }
356 void test(boost::mpl::false_)
359 Return r = f(first, second); // require operator()
363 void test(boost::mpl::true_)
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])
382 BOOST_concept(UnaryPredicate,(Func)(Arg))
384 BOOST_CONCEPT_USAGE(UnaryPredicate) {
385 require_boolean_expr(f(arg)); // require operator() returning bool
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])
401 BOOST_concept(BinaryPredicate,(Func)(First)(Second))
403 BOOST_CONCEPT_USAGE(BinaryPredicate) {
404 require_boolean_expr(f(a, b)); // require operator() returning bool
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])
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>
424 BOOST_CONCEPT_USAGE(Const_BinaryPredicate) {
425 const_constraints(f);
428 void const_constraints(const Func& fun) {
429 // operator() must be a const member function
430 require_boolean_expr(fun(a, b));
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();
446 BOOST_concept(AdaptableGenerator,(Func)(Return))
447 : Generator<Func, typename Func::result_type>
449 typedef typename Func::result_type result_type;
451 BOOST_CONCEPT_USAGE(AdaptableGenerator)
453 BOOST_CONCEPT_ASSERT((Convertible<result_type, Return>));
457 BOOST_concept(AdaptableUnaryFunction,(Func)(Return)(Arg))
458 : UnaryFunction<Func, typename Func::result_type, typename Func::argument_type>
460 typedef typename Func::argument_type argument_type;
461 typedef typename Func::result_type result_type;
463 ~AdaptableUnaryFunction()
465 BOOST_CONCEPT_ASSERT((Convertible<result_type, Return>));
466 BOOST_CONCEPT_ASSERT((Convertible<Arg, argument_type>));
470 BOOST_concept(AdaptableBinaryFunction,(Func)(Return)(First)(Second))
473 , typename Func::result_type
474 , typename Func::first_argument_type
475 , typename Func::second_argument_type
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;
482 ~AdaptableBinaryFunction()
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>));
490 BOOST_concept(AdaptablePredicate,(Func)(Arg))
491 : UnaryPredicate<Func, Arg>
492 , AdaptableUnaryFunction<Func, bool, Arg>
496 BOOST_concept(AdaptableBinaryPredicate,(Func)(First)(Second))
497 : BinaryPredicate<Func, First, Second>
498 , AdaptableBinaryFunction<Func, bool, First, Second>
502 //===========================================================================
505 BOOST_concept(InputIterator,(TT))
507 , EqualityComparable<TT>
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;
515 BOOST_CONCEPT_USAGE(InputIterator)
517 BOOST_CONCEPT_ASSERT((SignedInteger<difference_type>));
518 BOOST_CONCEPT_ASSERT((Convertible<iterator_category, std::input_iterator_tag>));
521 (void)*i; // require dereference operator
522 ++j; // require preincrement operator
523 i++; // require postincrement operator
529 BOOST_concept(OutputIterator,(TT)(ValueT))
532 BOOST_CONCEPT_USAGE(OutputIterator) {
534 ++i; // require preincrement operator
535 i++; // require postincrement operator
536 *i++ = t; // require postincrement and assignment
543 BOOST_concept(ForwardIterator,(TT))
546 BOOST_CONCEPT_USAGE(ForwardIterator)
548 BOOST_CONCEPT_ASSERT((Convertible<
549 BOOST_DEDUCED_TYPENAME ForwardIterator::iterator_category
550 , std::forward_iterator_tag
553 typename InputIterator<TT>::reference r = *i;
554 ignore_unused_variable_warning(r);
561 BOOST_concept(Mutable_ForwardIterator,(TT))
562 : ForwardIterator<TT>
564 BOOST_CONCEPT_USAGE(Mutable_ForwardIterator) {
565 *i++ = *i; // require postincrement and assignment
571 BOOST_concept(BidirectionalIterator,(TT))
572 : ForwardIterator<TT>
574 BOOST_CONCEPT_USAGE(BidirectionalIterator)
576 BOOST_CONCEPT_ASSERT((Convertible<
577 BOOST_DEDUCED_TYPENAME BidirectionalIterator::iterator_category
578 , std::bidirectional_iterator_tag
581 --i; // require predecrement operator
582 i--; // require postdecrement operator
588 BOOST_concept(Mutable_BidirectionalIterator,(TT))
589 : BidirectionalIterator<TT>
590 , Mutable_ForwardIterator<TT>
592 BOOST_CONCEPT_USAGE(Mutable_BidirectionalIterator)
594 *i-- = *i; // require postdecrement and assignment
600 BOOST_concept(RandomAccessIterator,(TT))
601 : BidirectionalIterator<TT>
604 BOOST_CONCEPT_USAGE(RandomAccessIterator)
606 BOOST_CONCEPT_ASSERT((Convertible<
607 BOOST_DEDUCED_TYPENAME BidirectionalIterator<TT>::iterator_category
608 , std::random_access_iterator_tag
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
622 typename boost::detail::iterator_traits<TT>::difference_type n;
625 BOOST_concept(Mutable_RandomAccessIterator,(TT))
626 : RandomAccessIterator<TT>
627 , Mutable_BidirectionalIterator<TT>
629 BOOST_CONCEPT_USAGE(Mutable_RandomAccessIterator)
631 i[n] = *i; // require element access and assignment
635 typename boost::detail::iterator_traits<TT>::difference_type n;
638 //===========================================================================
641 BOOST_concept(Container,(C))
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;
651 BOOST_CONCEPT_USAGE(Container)
653 BOOST_CONCEPT_ASSERT((InputIterator<const_iterator>));
654 const_constraints(c);
658 void const_constraints(const C& cc) {
671 BOOST_concept(Mutable_Container,(C))
674 typedef typename C::reference reference;
675 typedef typename C::iterator iterator;
676 typedef typename C::pointer pointer;
678 BOOST_CONCEPT_USAGE(Mutable_Container)
680 BOOST_CONCEPT_ASSERT((
681 Assignable<typename Mutable_Container::value_type>));
683 BOOST_CONCEPT_ASSERT((InputIterator<iterator>));
695 BOOST_concept(ForwardContainer,(C))
698 BOOST_CONCEPT_USAGE(ForwardContainer)
700 BOOST_CONCEPT_ASSERT((
702 typename ForwardContainer::const_iterator
707 BOOST_concept(Mutable_ForwardContainer,(C))
708 : ForwardContainer<C>
709 , Mutable_Container<C>
711 BOOST_CONCEPT_USAGE(Mutable_ForwardContainer)
713 BOOST_CONCEPT_ASSERT((
714 Mutable_ForwardIterator<
715 typename Mutable_ForwardContainer::iterator
720 BOOST_concept(ReversibleContainer,(C))
721 : ForwardContainer<C>
724 C::const_reverse_iterator
725 const_reverse_iterator;
727 BOOST_CONCEPT_USAGE(ReversibleContainer)
729 BOOST_CONCEPT_ASSERT((
730 BidirectionalIterator<
731 typename ReversibleContainer::const_iterator>));
733 BOOST_CONCEPT_ASSERT((BidirectionalIterator<const_reverse_iterator>));
735 const_constraints(c);
738 void const_constraints(const C& cc)
740 const_reverse_iterator i = cc.rbegin();
746 BOOST_concept(Mutable_ReversibleContainer,(C))
747 : Mutable_ForwardContainer<C>
748 , ReversibleContainer<C>
750 typedef typename C::reverse_iterator reverse_iterator;
752 BOOST_CONCEPT_USAGE(Mutable_ReversibleContainer)
754 typedef typename Mutable_ForwardContainer<C>::iterator iterator;
755 BOOST_CONCEPT_ASSERT((Mutable_BidirectionalIterator<iterator>));
756 BOOST_CONCEPT_ASSERT((Mutable_BidirectionalIterator<reverse_iterator>));
758 reverse_iterator i = c.rbegin();
765 BOOST_concept(RandomAccessContainer,(C))
766 : ReversibleContainer<C>
768 typedef typename C::size_type size_type;
769 typedef typename C::const_reference const_reference;
771 BOOST_CONCEPT_USAGE(RandomAccessContainer)
773 BOOST_CONCEPT_ASSERT((
774 RandomAccessIterator<
775 typename RandomAccessContainer::const_iterator
778 const_constraints(c);
781 void const_constraints(const C& cc)
783 const_reference r = cc[n];
784 ignore_unused_variable_warning(r);
791 BOOST_concept(Mutable_RandomAccessContainer,(C))
792 : Mutable_ReversibleContainer<C>
793 , RandomAccessContainer<C>
796 typedef Mutable_RandomAccessContainer self;
798 BOOST_CONCEPT_USAGE(Mutable_RandomAccessContainer)
800 BOOST_CONCEPT_ASSERT((Mutable_RandomAccessIterator<typename self::iterator>));
801 BOOST_CONCEPT_ASSERT((Mutable_RandomAccessIterator<typename self::reverse_iterator>));
803 typename self::reference r = c[i];
804 ignore_unused_variable_warning(r);
808 typename Mutable_ReversibleContainer<C>::size_type i;
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>
820 BOOST_CONCEPT_USAGE(Sequence)
829 c.insert(p, first, last);
834 typename Sequence::reference r = c.front();
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);
843 void const_constraints(const S& c) {
844 typename Sequence::const_reference r = c.front();
845 ignore_unused_variable_warning(r);
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;
854 BOOST_concept(FrontInsertionSequence,(S))
857 BOOST_CONCEPT_USAGE(FrontInsertionSequence)
864 typename S::value_type t;
867 BOOST_concept(BackInsertionSequence,(S))
870 BOOST_CONCEPT_USAGE(BackInsertionSequence)
874 typename BackInsertionSequence::reference r = c.back();
875 ignore_unused_variable_warning(r);
876 const_constraints(c);
879 void const_constraints(const S& cc) {
880 typename BackInsertionSequence::const_reference
882 ignore_unused_variable_warning(r);
885 typename S::value_type t;
888 BOOST_concept(AssociativeContainer,(C))
889 : ForwardContainer<C>
890 , DefaultConstructible<C>
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;
897 BOOST_CONCEPT_USAGE(AssociativeContainer)
900 r = c.equal_range(k);
903 c.erase(r.first, r.second);
904 const_constraints(c);
905 BOOST_CONCEPT_ASSERT((BinaryPredicate<key_compare,key_type,key_type>));
907 typedef typename AssociativeContainer::value_type value_type_;
908 BOOST_CONCEPT_ASSERT((BinaryPredicate<value_compare,value_type_,value_type_>));
911 // Redundant with the base concept, but it helps below.
912 typedef typename C::const_iterator const_iterator;
914 void const_constraints(const C& cc)
918 cr = cc.equal_range(k);
923 std::pair<iterator,iterator> r;
925 std::pair<const_iterator,const_iterator> cr;
926 typename C::key_type k;
927 typename C::size_type n;
930 BOOST_concept(UniqueAssociativeContainer,(C))
931 : AssociativeContainer<C>
933 BOOST_CONCEPT_USAGE(UniqueAssociativeContainer)
937 pos_flag = c.insert(t);
938 c.insert(first, last);
940 ignore_unused_variable_warning(c);
943 std::pair<typename C::iterator, bool> pos_flag;
944 typename C::value_type t;
945 typename C::value_type* first, *last;
948 BOOST_concept(MultipleAssociativeContainer,(C))
949 : AssociativeContainer<C>
951 BOOST_CONCEPT_USAGE(MultipleAssociativeContainer)
956 c.insert(first, last);
958 ignore_unused_variable_warning(c);
959 ignore_unused_variable_warning(pos);
962 typename C::iterator pos;
963 typename C::value_type t;
964 typename C::value_type* first, *last;
967 BOOST_concept(SimpleAssociativeContainer,(C))
968 : AssociativeContainer<C>
970 BOOST_CONCEPT_USAGE(SimpleAssociativeContainer)
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>));
978 BOOST_concept(PairAssociativeContainer,(C))
979 : AssociativeContainer<C>
981 BOOST_CONCEPT_USAGE(PairAssociativeContainer)
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>));
991 BOOST_concept(SortedAssociativeContainer,(C))
992 : AssociativeContainer<C>
993 , ReversibleContainer<C>
995 BOOST_CONCEPT_USAGE(SortedAssociativeContainer)
1000 c3(first, last, kc);
1002 p = c.upper_bound(k);
1003 p = c.lower_bound(k);
1004 r = c.equal_range(k);
1008 ignore_unused_variable_warning(c);
1009 ignore_unused_variable_warning(c2);
1010 ignore_unused_variable_warning(c3);
1011 const_constraints(c);
1014 void const_constraints(const C& c)
1017 vc = c.value_comp();
1019 cp = c.upper_bound(k);
1020 cp = c.lower_bound(k);
1021 cr = c.equal_range(k);
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;
1032 typedef SortedAssociativeContainer self;
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;
1040 // HashedAssociativeContainer
1042 BOOST_concept(Collection,(C))
1044 BOOST_CONCEPT_USAGE(Collection)
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);
1055 void const_constraints(const C& cc) {
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;
1078 } // namespace boost
1080 # include <boost/concept/detail/concept_undef.hpp>
1082 #endif // BOOST_CONCEPT_CHECKS_HPP