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>
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>
31 # include <boost/concept/usage.hpp>
32 # include <boost/concept/detail/concept_def.hpp>
34 #if (defined _MSC_VER)
35 # pragma warning( push )
36 # pragma warning( disable : 4510 ) // default constructor could not be generated
37 # pragma warning( disable : 4610 ) // object 'class' can never be instantiated - user-defined constructor required
44 // Backward compatibility
47 template <class Model>
48 inline void function_requires(Model* = 0)
50 BOOST_CONCEPT_ASSERT((Model));
52 template <class T> inline void ignore_unused_variable_warning(T const&) {}
54 # define BOOST_CLASS_REQUIRE(type_var, ns, concept) \
55 BOOST_CONCEPT_ASSERT((ns::concept<type_var>))
57 # define BOOST_CLASS_REQUIRE2(type_var1, type_var2, ns, concept) \
58 BOOST_CONCEPT_ASSERT((ns::concept<type_var1,type_var2>))
60 # define BOOST_CLASS_REQUIRE3(tv1, tv2, tv3, ns, concept) \
61 BOOST_CONCEPT_ASSERT((ns::concept<tv1,tv2,tv3>))
63 # define BOOST_CLASS_REQUIRE4(tv1, tv2, tv3, tv4, ns, concept) \
64 BOOST_CONCEPT_ASSERT((ns::concept<tv1,tv2,tv3,tv4>))
68 // Begin concept definitions
70 BOOST_concept(Integer, (T))
72 BOOST_CONCEPT_USAGE(Integer)
74 x.error_type_must_be_an_integer_type();
80 template <> struct Integer<char> {};
81 template <> struct Integer<signed char> {};
82 template <> struct Integer<unsigned char> {};
83 template <> struct Integer<short> {};
84 template <> struct Integer<unsigned short> {};
85 template <> struct Integer<int> {};
86 template <> struct Integer<unsigned int> {};
87 template <> struct Integer<long> {};
88 template <> struct Integer<unsigned long> {};
89 # if defined(BOOST_HAS_LONG_LONG)
90 template <> struct Integer< ::boost::long_long_type> {};
91 template <> struct Integer< ::boost::ulong_long_type> {};
92 # elif defined(BOOST_HAS_MS_INT64)
93 template <> struct Integer<__int64> {};
94 template <> struct Integer<unsigned __int64> {};
97 BOOST_concept(SignedInteger,(T)) {
98 BOOST_CONCEPT_USAGE(SignedInteger) {
99 x.error_type_must_be_a_signed_integer_type();
104 template <> struct SignedInteger<signed char> { };
105 template <> struct SignedInteger<short> {};
106 template <> struct SignedInteger<int> {};
107 template <> struct SignedInteger<long> {};
108 # if defined(BOOST_HAS_LONG_LONG)
109 template <> struct SignedInteger< ::boost::long_long_type> {};
110 # elif defined(BOOST_HAS_MS_INT64)
111 template <> struct SignedInteger<__int64> {};
114 BOOST_concept(UnsignedInteger,(T)) {
115 BOOST_CONCEPT_USAGE(UnsignedInteger) {
116 x.error_type_must_be_an_unsigned_integer_type();
122 template <> struct UnsignedInteger<unsigned char> {};
123 template <> struct UnsignedInteger<unsigned short> {};
124 template <> struct UnsignedInteger<unsigned int> {};
125 template <> struct UnsignedInteger<unsigned long> {};
126 # if defined(BOOST_HAS_LONG_LONG)
127 template <> struct UnsignedInteger< ::boost::ulong_long_type> {};
128 # elif defined(BOOST_HAS_MS_INT64)
129 template <> struct UnsignedInteger<unsigned __int64> {};
132 //===========================================================================
135 BOOST_concept(DefaultConstructible,(TT))
137 BOOST_CONCEPT_USAGE(DefaultConstructible) {
138 TT a; // require default constructor
139 ignore_unused_variable_warning(a);
143 BOOST_concept(Assignable,(TT))
145 BOOST_CONCEPT_USAGE(Assignable) {
146 #if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
147 a = b; // require assignment operator
149 const_constraints(b);
152 void const_constraints(const TT& x) {
153 #if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
154 a = x; // const required for argument to assignment
156 ignore_unused_variable_warning(x);
165 BOOST_concept(CopyConstructible,(TT))
167 BOOST_CONCEPT_USAGE(CopyConstructible) {
168 TT a(b); // require copy constructor
169 TT* ptr = &a; // require address of operator
170 const_constraints(a);
171 ignore_unused_variable_warning(ptr);
174 void const_constraints(const TT& a) {
175 TT c(a); // require const copy constructor
176 const TT* ptr = &a; // require const address of operator
177 ignore_unused_variable_warning(c);
178 ignore_unused_variable_warning(ptr);
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);
206 BOOST_concept(Convertible,(X)(Y))
208 BOOST_CONCEPT_USAGE(Convertible) {
210 ignore_unused_variable_warning(y);
216 // The C++ standard requirements for many concepts talk about return
217 // types that must be "convertible to bool". The problem with this
218 // requirement is that it leaves the door open for evil proxies that
219 // define things like operator|| with strange return types. Two
220 // possible solutions are:
221 // 1) require the return type to be exactly bool
222 // 2) stay with convertible to bool, and also
223 // specify stuff about all the logical operators.
224 // For now we just test for convertible to bool.
226 void require_boolean_expr(const TT& t) {
228 ignore_unused_variable_warning(x);
231 BOOST_concept(EqualityComparable,(TT))
233 BOOST_CONCEPT_USAGE(EqualityComparable) {
234 require_boolean_expr(a == b);
235 require_boolean_expr(a != b);
241 BOOST_concept(LessThanComparable,(TT))
243 BOOST_CONCEPT_USAGE(LessThanComparable) {
244 require_boolean_expr(a < b);
250 // This is equivalent to SGI STL's LessThanComparable.
251 BOOST_concept(Comparable,(TT))
253 BOOST_CONCEPT_USAGE(Comparable) {
254 require_boolean_expr(a < b);
255 require_boolean_expr(a > b);
256 require_boolean_expr(a <= b);
257 require_boolean_expr(a >= b);
263 #define BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(OP,NAME) \
264 BOOST_concept(NAME, (First)(Second)) \
266 BOOST_CONCEPT_USAGE(NAME) { (void)constraints_(); } \
268 bool constraints_() { return a OP b; } \
273 #define BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(OP,NAME) \
274 BOOST_concept(NAME, (Ret)(First)(Second)) \
276 BOOST_CONCEPT_USAGE(NAME) { (void)constraints_(); } \
278 Ret constraints_() { return a OP b; } \
283 BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(==, EqualOp);
284 BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(!=, NotEqualOp);
285 BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<, LessThanOp);
286 BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<=, LessEqualOp);
287 BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>, GreaterThanOp);
288 BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>=, GreaterEqualOp);
290 BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(+, PlusOp);
291 BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(*, TimesOp);
292 BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(/, DivideOp);
293 BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(-, SubtractOp);
294 BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(%, ModOp);
296 //===========================================================================
297 // Function Object Concepts
299 BOOST_concept(Generator,(Func)(Return))
301 BOOST_CONCEPT_USAGE(Generator) { test(is_void<Return>()); }
304 void test(boost::mpl::false_)
306 // Do we really want a reference here?
307 const Return& r = f();
308 ignore_unused_variable_warning(r);
311 void test(boost::mpl::true_)
319 BOOST_concept(UnaryFunction,(Func)(Return)(Arg))
321 BOOST_CONCEPT_USAGE(UnaryFunction) { test(is_void<Return>()); }
324 void test(boost::mpl::false_)
326 f(arg); // "priming the pump" this way keeps msvc6 happy (ICE)
328 ignore_unused_variable_warning(r);
331 void test(boost::mpl::true_)
336 #if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \
337 && BOOST_WORKAROUND(__GNUC__, > 3)))
338 // Declare a dummy construktor to make gcc happy.
339 // It seems the compiler can not generate a sensible constructor when this is instantiated with a refence type.
340 // (warning: non-static reference "const double& boost::UnaryFunction<YourClassHere>::arg"
341 // in class without a constructor [-Wuninitialized])
349 BOOST_concept(BinaryFunction,(Func)(Return)(First)(Second))
351 BOOST_CONCEPT_USAGE(BinaryFunction) { test(is_void<Return>()); }
353 void test(boost::mpl::false_)
356 Return r = f(first, second); // require operator()
360 void test(boost::mpl::true_)
365 #if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \
366 && BOOST_WORKAROUND(__GNUC__, > 3)))
367 // Declare a dummy constructor to make gcc happy.
368 // It seems the compiler can not generate a sensible constructor when this is instantiated with a refence type.
369 // (warning: non-static reference "const double& boost::BinaryFunction<YourClassHere>::arg"
370 // in class without a constructor [-Wuninitialized])
379 BOOST_concept(UnaryPredicate,(Func)(Arg))
381 BOOST_CONCEPT_USAGE(UnaryPredicate) {
382 require_boolean_expr(f(arg)); // require operator() returning bool
385 #if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \
386 && BOOST_WORKAROUND(__GNUC__, > 3)))
387 // Declare a dummy constructor to make gcc happy.
388 // It seems the compiler can not generate a sensible constructor when this is instantiated with a refence type.
389 // (warning: non-static reference "const double& boost::UnaryPredicate<YourClassHere>::arg"
390 // in class without a constructor [-Wuninitialized])
398 BOOST_concept(BinaryPredicate,(Func)(First)(Second))
400 BOOST_CONCEPT_USAGE(BinaryPredicate) {
401 require_boolean_expr(f(a, b)); // require operator() returning bool
404 #if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \
405 && BOOST_WORKAROUND(__GNUC__, > 3)))
406 // Declare a dummy constructor to make gcc happy.
407 // It seems the compiler can not generate a sensible constructor when this is instantiated with a refence type.
408 // (warning: non-static reference "const double& boost::BinaryPredicate<YourClassHere>::arg"
409 // in class without a constructor [-Wuninitialized])
417 // use this when functor is used inside a container class like std::set
418 BOOST_concept(Const_BinaryPredicate,(Func)(First)(Second))
419 : BinaryPredicate<Func, First, Second>
421 BOOST_CONCEPT_USAGE(Const_BinaryPredicate) {
422 const_constraints(f);
425 void const_constraints(const Func& fun) {
426 // operator() must be a const member function
427 require_boolean_expr(fun(a, b));
429 #if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \
430 && BOOST_WORKAROUND(__GNUC__, > 3)))
431 // Declare a dummy constructor to make gcc happy.
432 // It seems the compiler can not generate a sensible constructor when this is instantiated with a refence type.
433 // (warning: non-static reference "const double& boost::Const_BinaryPredicate<YourClassHere>::arg"
434 // in class without a constructor [-Wuninitialized])
435 Const_BinaryPredicate();
443 BOOST_concept(AdaptableGenerator,(Func)(Return))
444 : Generator<Func, typename Func::result_type>
446 typedef typename Func::result_type result_type;
448 BOOST_CONCEPT_USAGE(AdaptableGenerator)
450 BOOST_CONCEPT_ASSERT((Convertible<result_type, Return>));
454 BOOST_concept(AdaptableUnaryFunction,(Func)(Return)(Arg))
455 : UnaryFunction<Func, typename Func::result_type, typename Func::argument_type>
457 typedef typename Func::argument_type argument_type;
458 typedef typename Func::result_type result_type;
460 ~AdaptableUnaryFunction()
462 BOOST_CONCEPT_ASSERT((Convertible<result_type, Return>));
463 BOOST_CONCEPT_ASSERT((Convertible<Arg, argument_type>));
467 BOOST_concept(AdaptableBinaryFunction,(Func)(Return)(First)(Second))
470 , typename Func::result_type
471 , typename Func::first_argument_type
472 , typename Func::second_argument_type
475 typedef typename Func::first_argument_type first_argument_type;
476 typedef typename Func::second_argument_type second_argument_type;
477 typedef typename Func::result_type result_type;
479 ~AdaptableBinaryFunction()
481 BOOST_CONCEPT_ASSERT((Convertible<result_type, Return>));
482 BOOST_CONCEPT_ASSERT((Convertible<First, first_argument_type>));
483 BOOST_CONCEPT_ASSERT((Convertible<Second, second_argument_type>));
487 BOOST_concept(AdaptablePredicate,(Func)(Arg))
488 : UnaryPredicate<Func, Arg>
489 , AdaptableUnaryFunction<Func, bool, Arg>
493 BOOST_concept(AdaptableBinaryPredicate,(Func)(First)(Second))
494 : BinaryPredicate<Func, First, Second>
495 , AdaptableBinaryFunction<Func, bool, First, Second>
499 //===========================================================================
502 BOOST_concept(InputIterator,(TT))
504 , EqualityComparable<TT>
506 typedef typename std::iterator_traits<TT>::value_type value_type;
507 typedef typename std::iterator_traits<TT>::difference_type difference_type;
508 typedef typename std::iterator_traits<TT>::reference reference;
509 typedef typename std::iterator_traits<TT>::pointer pointer;
510 typedef typename std::iterator_traits<TT>::iterator_category iterator_category;
512 BOOST_CONCEPT_USAGE(InputIterator)
514 BOOST_CONCEPT_ASSERT((SignedInteger<difference_type>));
515 BOOST_CONCEPT_ASSERT((Convertible<iterator_category, std::input_iterator_tag>));
518 (void)*i; // require dereference operator
519 ++j; // require preincrement operator
520 i++; // require postincrement operator
526 BOOST_concept(OutputIterator,(TT)(ValueT))
529 BOOST_CONCEPT_USAGE(OutputIterator) {
531 ++i; // require preincrement operator
532 i++; // require postincrement operator
533 *i++ = t; // require postincrement and assignment
540 BOOST_concept(ForwardIterator,(TT))
543 BOOST_CONCEPT_USAGE(ForwardIterator)
545 BOOST_CONCEPT_ASSERT((Convertible<
546 BOOST_DEDUCED_TYPENAME ForwardIterator::iterator_category
547 , std::forward_iterator_tag
550 typename InputIterator<TT>::reference r = *i;
551 ignore_unused_variable_warning(r);
558 BOOST_concept(Mutable_ForwardIterator,(TT))
559 : ForwardIterator<TT>
561 BOOST_CONCEPT_USAGE(Mutable_ForwardIterator) {
562 *i++ = *j; // require postincrement and assignment
568 BOOST_concept(BidirectionalIterator,(TT))
569 : ForwardIterator<TT>
571 BOOST_CONCEPT_USAGE(BidirectionalIterator)
573 BOOST_CONCEPT_ASSERT((Convertible<
574 BOOST_DEDUCED_TYPENAME BidirectionalIterator::iterator_category
575 , std::bidirectional_iterator_tag
578 --i; // require predecrement operator
579 i--; // require postdecrement operator
585 BOOST_concept(Mutable_BidirectionalIterator,(TT))
586 : BidirectionalIterator<TT>
587 , Mutable_ForwardIterator<TT>
589 BOOST_CONCEPT_USAGE(Mutable_BidirectionalIterator)
591 *i-- = *j; // require postdecrement and assignment
597 BOOST_concept(RandomAccessIterator,(TT))
598 : BidirectionalIterator<TT>
601 BOOST_CONCEPT_USAGE(RandomAccessIterator)
603 BOOST_CONCEPT_ASSERT((Convertible<
604 BOOST_DEDUCED_TYPENAME BidirectionalIterator<TT>::iterator_category
605 , std::random_access_iterator_tag
608 i += n; // require assignment addition operator
609 i = i + n; i = n + i; // require addition with difference type
610 i -= n; // require assignment subtraction operator
611 i = i - n; // require subtraction with difference type
612 n = i - j; // require difference operator
613 (void)i[n]; // require element access operator
619 typename std::iterator_traits<TT>::difference_type n;
622 BOOST_concept(Mutable_RandomAccessIterator,(TT))
623 : RandomAccessIterator<TT>
624 , Mutable_BidirectionalIterator<TT>
626 BOOST_CONCEPT_USAGE(Mutable_RandomAccessIterator)
628 i[n] = *i; // require element access and assignment
632 typename std::iterator_traits<TT>::difference_type n;
635 //===========================================================================
638 BOOST_concept(Container,(C))
641 typedef typename C::value_type value_type;
642 typedef typename C::difference_type difference_type;
643 typedef typename C::size_type size_type;
644 typedef typename C::const_reference const_reference;
645 typedef typename C::const_pointer const_pointer;
646 typedef typename C::const_iterator const_iterator;
648 BOOST_CONCEPT_USAGE(Container)
650 BOOST_CONCEPT_ASSERT((InputIterator<const_iterator>));
651 const_constraints(c);
655 void const_constraints(const C& cc) {
668 BOOST_concept(Mutable_Container,(C))
671 typedef typename C::reference reference;
672 typedef typename C::iterator iterator;
673 typedef typename C::pointer pointer;
675 BOOST_CONCEPT_USAGE(Mutable_Container)
677 BOOST_CONCEPT_ASSERT((
678 Assignable<typename Mutable_Container::value_type>));
680 BOOST_CONCEPT_ASSERT((InputIterator<iterator>));
692 BOOST_concept(ForwardContainer,(C))
695 BOOST_CONCEPT_USAGE(ForwardContainer)
697 BOOST_CONCEPT_ASSERT((
699 typename ForwardContainer::const_iterator
704 BOOST_concept(Mutable_ForwardContainer,(C))
705 : ForwardContainer<C>
706 , Mutable_Container<C>
708 BOOST_CONCEPT_USAGE(Mutable_ForwardContainer)
710 BOOST_CONCEPT_ASSERT((
711 Mutable_ForwardIterator<
712 typename Mutable_ForwardContainer::iterator
717 BOOST_concept(ReversibleContainer,(C))
718 : ForwardContainer<C>
721 C::const_reverse_iterator
722 const_reverse_iterator;
724 BOOST_CONCEPT_USAGE(ReversibleContainer)
726 BOOST_CONCEPT_ASSERT((
727 BidirectionalIterator<
728 typename ReversibleContainer::const_iterator>));
730 BOOST_CONCEPT_ASSERT((BidirectionalIterator<const_reverse_iterator>));
732 const_constraints(c);
735 void const_constraints(const C& cc)
737 const_reverse_iterator i = cc.rbegin();
743 BOOST_concept(Mutable_ReversibleContainer,(C))
744 : Mutable_ForwardContainer<C>
745 , ReversibleContainer<C>
747 typedef typename C::reverse_iterator reverse_iterator;
749 BOOST_CONCEPT_USAGE(Mutable_ReversibleContainer)
751 typedef typename Mutable_ForwardContainer<C>::iterator iterator;
752 BOOST_CONCEPT_ASSERT((Mutable_BidirectionalIterator<iterator>));
753 BOOST_CONCEPT_ASSERT((Mutable_BidirectionalIterator<reverse_iterator>));
755 reverse_iterator i = c.rbegin();
762 BOOST_concept(RandomAccessContainer,(C))
763 : ReversibleContainer<C>
765 typedef typename C::size_type size_type;
766 typedef typename C::const_reference const_reference;
768 BOOST_CONCEPT_USAGE(RandomAccessContainer)
770 BOOST_CONCEPT_ASSERT((
771 RandomAccessIterator<
772 typename RandomAccessContainer::const_iterator
775 const_constraints(c);
778 void const_constraints(const C& cc)
780 const_reference r = cc[n];
781 ignore_unused_variable_warning(r);
788 BOOST_concept(Mutable_RandomAccessContainer,(C))
789 : Mutable_ReversibleContainer<C>
790 , RandomAccessContainer<C>
793 typedef Mutable_RandomAccessContainer self;
795 BOOST_CONCEPT_USAGE(Mutable_RandomAccessContainer)
797 BOOST_CONCEPT_ASSERT((Mutable_RandomAccessIterator<typename self::iterator>));
798 BOOST_CONCEPT_ASSERT((Mutable_RandomAccessIterator<typename self::reverse_iterator>));
800 typename self::reference r = c[i];
801 ignore_unused_variable_warning(r);
805 typename Mutable_ReversibleContainer<C>::size_type i;
809 // A Sequence is inherently mutable
810 BOOST_concept(Sequence,(S))
811 : Mutable_ForwardContainer<S>
812 // Matt Austern's book puts DefaultConstructible here, the C++
813 // standard places it in Container --JGS
814 // ... so why aren't we following the standard? --DWA
815 , DefaultConstructible<S>
817 BOOST_CONCEPT_USAGE(Sequence)
825 c.insert(p, first, last);
830 typename Sequence::reference r = c.front();
832 ignore_unused_variable_warning(c);
833 ignore_unused_variable_warning(c2);
834 ignore_unused_variable_warning(r);
835 const_constraints(c);
838 void const_constraints(const S& c) {
839 typename Sequence::const_reference r = c.front();
840 ignore_unused_variable_warning(r);
843 typename S::value_type t;
844 typename S::size_type n;
845 typename S::value_type* first, *last;
846 typename S::iterator p, q;
849 BOOST_concept(FrontInsertionSequence,(S))
852 BOOST_CONCEPT_USAGE(FrontInsertionSequence)
859 typename S::value_type t;
862 BOOST_concept(BackInsertionSequence,(S))
865 BOOST_CONCEPT_USAGE(BackInsertionSequence)
869 typename BackInsertionSequence::reference r = c.back();
870 ignore_unused_variable_warning(r);
871 const_constraints(c);
874 void const_constraints(const S& cc) {
875 typename BackInsertionSequence::const_reference
877 ignore_unused_variable_warning(r);
880 typename S::value_type t;
883 BOOST_concept(AssociativeContainer,(C))
884 : ForwardContainer<C>
885 , DefaultConstructible<C>
887 typedef typename C::key_type key_type;
888 typedef typename C::key_compare key_compare;
889 typedef typename C::value_compare value_compare;
890 typedef typename C::iterator iterator;
892 BOOST_CONCEPT_USAGE(AssociativeContainer)
895 r = c.equal_range(k);
898 c.erase(r.first, r.second);
899 const_constraints(c);
900 BOOST_CONCEPT_ASSERT((BinaryPredicate<key_compare,key_type,key_type>));
902 typedef typename AssociativeContainer::value_type value_type_;
903 BOOST_CONCEPT_ASSERT((BinaryPredicate<value_compare,value_type_,value_type_>));
906 // Redundant with the base concept, but it helps below.
907 typedef typename C::const_iterator const_iterator;
909 void const_constraints(const C& cc)
913 cr = cc.equal_range(k);
918 std::pair<iterator,iterator> r;
920 std::pair<const_iterator,const_iterator> cr;
921 typename C::key_type k;
922 typename C::size_type n;
925 BOOST_concept(UniqueAssociativeContainer,(C))
926 : AssociativeContainer<C>
928 BOOST_CONCEPT_USAGE(UniqueAssociativeContainer)
932 pos_flag = c.insert(t);
933 c.insert(first, last);
935 ignore_unused_variable_warning(c);
938 std::pair<typename C::iterator, bool> pos_flag;
939 typename C::value_type t;
940 typename C::value_type* first, *last;
943 BOOST_concept(MultipleAssociativeContainer,(C))
944 : AssociativeContainer<C>
946 BOOST_CONCEPT_USAGE(MultipleAssociativeContainer)
951 c.insert(first, last);
953 ignore_unused_variable_warning(c);
954 ignore_unused_variable_warning(pos);
957 typename C::iterator pos;
958 typename C::value_type t;
959 typename C::value_type* first, *last;
962 BOOST_concept(SimpleAssociativeContainer,(C))
963 : AssociativeContainer<C>
965 BOOST_CONCEPT_USAGE(SimpleAssociativeContainer)
967 typedef typename C::key_type key_type;
968 typedef typename C::value_type value_type;
969 BOOST_MPL_ASSERT((boost::is_same<key_type,value_type>));
973 BOOST_concept(PairAssociativeContainer,(C))
974 : AssociativeContainer<C>
976 BOOST_CONCEPT_USAGE(PairAssociativeContainer)
978 typedef typename C::key_type key_type;
979 typedef typename C::value_type value_type;
980 typedef typename C::mapped_type mapped_type;
981 typedef std::pair<const key_type, mapped_type> required_value_type;
982 BOOST_MPL_ASSERT((boost::is_same<value_type,required_value_type>));
986 BOOST_concept(SortedAssociativeContainer,(C))
987 : AssociativeContainer<C>
988 , ReversibleContainer<C>
990 BOOST_CONCEPT_USAGE(SortedAssociativeContainer)
997 p = c.upper_bound(k);
998 p = c.lower_bound(k);
999 r = c.equal_range(k);
1003 ignore_unused_variable_warning(c);
1004 ignore_unused_variable_warning(c2);
1005 ignore_unused_variable_warning(c3);
1006 const_constraints(c);
1009 void const_constraints(const C& c)
1012 vc = c.value_comp();
1014 cp = c.upper_bound(k);
1015 cp = c.lower_bound(k);
1016 cr = c.equal_range(k);
1020 typename C::key_compare kc;
1021 typename C::value_compare vc;
1022 typename C::value_type t;
1023 typename C::key_type k;
1024 typedef typename C::iterator iterator;
1025 typedef typename C::const_iterator const_iterator;
1027 typedef SortedAssociativeContainer self;
1030 std::pair<typename self::iterator,typename self::iterator> r;
1031 std::pair<typename self::const_iterator,typename self::const_iterator> cr;
1032 typename C::value_type* first, *last;
1035 // HashedAssociativeContainer
1037 BOOST_concept(Collection,(C))
1039 BOOST_CONCEPT_USAGE(Collection)
1041 boost::function_requires<boost::InputIteratorConcept<iterator> >();
1042 boost::function_requires<boost::InputIteratorConcept<const_iterator> >();
1043 boost::function_requires<boost::CopyConstructibleConcept<value_type> >();
1044 const_constraints(c);
1050 void const_constraints(const C& cc) {
1058 typedef typename C::value_type value_type;
1059 typedef typename C::iterator iterator;
1060 typedef typename C::const_iterator const_iterator;
1061 typedef typename C::reference reference;
1062 typedef typename C::const_reference const_reference;
1063 // typedef typename C::pointer pointer;
1064 typedef typename C::difference_type difference_type;
1065 typedef typename C::size_type size_type;
1073 } // namespace boost
1075 #if (defined _MSC_VER)
1076 # pragma warning( pop )
1079 # include <boost/concept/detail/concept_undef.hpp>
1081 #endif // BOOST_CONCEPT_CHECKS_HPP