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)
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>
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>
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();
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> {};
89 BOOST_concept(SignedInteger,(T)) {
90 BOOST_CONCEPT_USAGE(SignedInteger) {
91 x.error_type_must_be_a_signed_integer_type();
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> {};
106 BOOST_concept(UnsignedInteger,(T)) {
107 BOOST_CONCEPT_USAGE(UnsignedInteger) {
108 x.error_type_must_be_an_unsigned_integer_type();
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> {};
124 //===========================================================================
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
141 const_constraints(a);
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
148 ignore_unused_variable_warning(b);
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);
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);
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
179 // The SGI STL version of Assignable requires copy constructor and operator=
180 BOOST_concept(SGIAssignable,(TT))
182 BOOST_CONCEPT_USAGE(SGIAssignable) {
184 #if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
185 a = a; // require assignment operator
187 const_constraints(a);
188 ignore_unused_variable_warning(b);
191 void const_constraints(const TT& b) {
193 #if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
194 a = b; // const required for argument to assignment
196 ignore_unused_variable_warning(c);
200 #if (defined _MSC_VER)
201 # pragma warning( pop )
204 BOOST_concept(Convertible,(X)(Y))
206 BOOST_CONCEPT_USAGE(Convertible) {
208 ignore_unused_variable_warning(y);
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.
224 void require_boolean_expr(const TT& 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);
239 BOOST_concept(LessThanComparable,(TT))
241 BOOST_CONCEPT_USAGE(LessThanComparable) {
242 require_boolean_expr(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);
261 #define BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(OP,NAME) \
262 BOOST_concept(NAME, (First)(Second)) \
264 BOOST_CONCEPT_USAGE(NAME) { (void)constraints_(); } \
266 bool constraints_() { return a OP b; } \
271 #define BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(OP,NAME) \
272 BOOST_concept(NAME, (Ret)(First)(Second)) \
274 BOOST_CONCEPT_USAGE(NAME) { (void)constraints_(); } \
276 Ret constraints_() { return a OP 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>()); }
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_)
317 BOOST_concept(UnaryFunction,(Func)(Return)(Arg))
319 BOOST_CONCEPT_USAGE(UnaryFunction) { test(is_void<Return>()); }
322 void test(boost::mpl::false_)
324 f(arg); // "priming the pump" this way keeps msvc6 happy (ICE)
326 ignore_unused_variable_warning(r);
329 void test(boost::mpl::true_)
338 BOOST_concept(BinaryFunction,(Func)(Return)(First)(Second))
340 BOOST_CONCEPT_USAGE(BinaryFunction) { test(is_void<Return>()); }
342 void test(boost::mpl::false_)
345 Return r = f(first, second); // require operator()
349 void test(boost::mpl::true_)
359 BOOST_concept(UnaryPredicate,(Func)(Arg))
361 BOOST_CONCEPT_USAGE(UnaryPredicate) {
362 require_boolean_expr(f(arg)); // require operator() returning bool
369 BOOST_concept(BinaryPredicate,(Func)(First)(Second))
371 BOOST_CONCEPT_USAGE(BinaryPredicate) {
372 require_boolean_expr(f(a, b)); // require operator() returning bool
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);
388 void const_constraints(const Func& fun) {
389 // operator() must be a const member function
390 require_boolean_expr(fun(a, 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))
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 //===========================================================================
456 BOOST_concept(InputIterator,(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>));
472 (void)*i; // require dereference operator
473 ++j; // require preincrement operator
474 i++; // require postincrement operator
480 BOOST_concept(OutputIterator,(TT)(ValueT))
483 BOOST_CONCEPT_USAGE(OutputIterator) {
485 ++i; // require preincrement operator
486 i++; // require postincrement operator
487 *i++ = t; // require postincrement and assignment
494 BOOST_concept(ForwardIterator,(TT))
497 BOOST_CONCEPT_USAGE(ForwardIterator)
499 BOOST_CONCEPT_ASSERT((Convertible<
500 BOOST_DEDUCED_TYPENAME ForwardIterator::iterator_category
501 , std::forward_iterator_tag
504 typename InputIterator<TT>::reference r = *i;
505 ignore_unused_variable_warning(r);
512 BOOST_concept(Mutable_ForwardIterator,(TT))
513 : ForwardIterator<TT>
515 BOOST_CONCEPT_USAGE(Mutable_ForwardIterator) {
516 *i++ = *i; // require postincrement and assignment
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
532 --i; // require predecrement operator
533 i--; // require postdecrement operator
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
551 BOOST_concept(RandomAccessIterator,(TT))
552 : BidirectionalIterator<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
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
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
586 typename boost::detail::iterator_traits<TT>::difference_type n;
589 //===========================================================================
592 BOOST_concept(Container,(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);
609 void const_constraints(const C& cc) {
622 BOOST_concept(Mutable_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>));
646 BOOST_concept(ForwardContainer,(C))
649 BOOST_CONCEPT_USAGE(ForwardContainer)
651 BOOST_CONCEPT_ASSERT((
653 typename ForwardContainer::const_iterator
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
671 BOOST_concept(ReversibleContainer,(C))
672 : ForwardContainer<C>
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);
689 void const_constraints(const C& cc)
691 const_reverse_iterator i = cc.rbegin();
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();
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
729 const_constraints(c);
732 void const_constraints(const C& cc)
734 const_reference r = cc[n];
735 ignore_unused_variable_warning(r);
742 BOOST_concept(Mutable_RandomAccessContainer,(C))
743 : Mutable_ReversibleContainer<C>
744 , RandomAccessContainer<C>
747 typedef Mutable_RandomAccessContainer self;
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);
759 typename Mutable_ReversibleContainer<C>::size_type i;
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)
780 c.insert(p, first, last);
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);
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))
808 BOOST_CONCEPT_USAGE(FrontInsertionSequence)
815 typename S::value_type t;
818 BOOST_concept(BackInsertionSequence,(S))
821 BOOST_CONCEPT_USAGE(BackInsertionSequence)
825 typename BackInsertionSequence::reference r = c.back();
826 ignore_unused_variable_warning(r);
827 const_constraints(c);
830 void const_constraints(const S& cc) {
831 typename BackInsertionSequence::const_reference
833 ignore_unused_variable_warning(r);
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)
851 r = c.equal_range(k);
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;
865 void const_constraints(const C& cc)
869 cr = cc.equal_range(k);
874 std::pair<iterator,iterator> r;
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)
888 pos_flag = c.insert(t);
889 c.insert(first, last);
891 ignore_unused_variable_warning(c);
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)
907 c.insert(first, last);
909 ignore_unused_variable_warning(c);
910 ignore_unused_variable_warning(pos);
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)
953 p = c.upper_bound(k);
954 p = c.lower_bound(k);
955 r = c.equal_range(k);
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)
970 cp = c.upper_bound(k);
971 cp = c.lower_bound(k);
972 cr = c.equal_range(k);
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;
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
995 # include <boost/concept/detail/concept_undef.hpp>
997 #endif // BOOST_CONCEPT_CHECKS_HPP