2 // (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify,
3 // sell and distribute this software is granted provided this
4 // copyright notice appears in all copies. This software is provided
5 // "as is" without express or implied warranty, and with no claim as
6 // to its suitability for any purpose.
9 // 05 May 2001: Workarounds for HP aCC from Thomas Matelich. (Jeremy Siek)
10 // 02 April 2001: Removed limits header altogether. (Jeremy Siek)
11 // 01 April 2001: Modified to use new <boost/limits.hpp> header. (JMaddock)
13 #ifndef BOOST_CONCEPT_CHECKS_HPP
14 #define BOOST_CONCEPT_CHECKS_HPP
16 #include <boost/config.hpp>
17 #include <boost/iterator.hpp>
18 #include <boost/type_traits/conversion_traits.hpp>
20 #include <boost/type_traits/conversion_traits.hpp>
21 #include <boost/static_assert.hpp>
22 #include <boost/type.hpp>
25 #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(__BORLANDC__)
34 "inline" is used for ignore_unused_variable_warning()
35 and function_requires() to make sure there is no
39 template <class T> inline void ignore_unused_variable_warning(const T&) { }
41 // the unused, defaulted parameter is a workaround for MSVC and Compaq C++
42 template <class Concept>
43 inline void function_requires(type<Concept>* = 0)
46 void (Concept::*x)() = BOOST_FPTR Concept::constraints;
47 ignore_unused_variable_warning(x);
51 #define BOOST_CLASS_REQUIRE(type_var, ns, concept) \
52 typedef void (ns::concept <type_var>::* func##type_var##concept)(); \
53 template <func##type_var##concept _Tp1> \
54 struct concept_checking_##type_var##concept { }; \
55 typedef concept_checking_##type_var##concept< \
56 BOOST_FPTR ns::concept<type_var>::constraints> \
57 concept_checking_typedef_##type_var##concept
59 #define BOOST_CLASS_REQUIRE2(type_var1, type_var2, ns, concept) \
60 typedef void (ns::concept <type_var1,type_var2>::* \
61 func##type_var1##type_var2##concept)(); \
62 template <func##type_var1##type_var2##concept _Tp1> \
63 struct concept_checking_##type_var1##type_var2##concept { }; \
64 typedef concept_checking_##type_var1##type_var2##concept< \
65 BOOST_FPTR ns::concept<type_var1,type_var2>::constraints> \
66 concept_checking_typedef_##type_var1##type_var2##concept
68 #define BOOST_CLASS_REQUIRE3(tv1, tv2, tv3, ns, concept) \
69 typedef void (ns::concept <tv1,tv2,tv3>::* \
70 func##tv1##tv2##tv3##concept)(); \
71 template <func##tv1##tv2##tv3##concept _Tp1> \
72 struct concept_checking_##tv1##tv2##tv3##concept { }; \
73 typedef concept_checking_##tv1##tv2##tv3##concept< \
74 BOOST_FPTR ns::concept<tv1,tv2,tv3>::constraints> \
75 concept_checking_typedef_##tv1##tv2##tv3##concept
77 #define BOOST_CLASS_REQUIRE4(tv1, tv2, tv3, tv4, ns, concept) \
78 typedef void (ns::concept <tv1,tv2,tv3,tv4>::* \
79 func##tv1##tv2##tv3##tv4##concept)(); \
80 template <func##tv1##tv2##tv3##tv4##concept _Tp1> \
81 struct concept_checking_##tv1##tv2##tv3##tv4##concept { }; \
82 typedef concept_checking_##tv1##tv2##tv3##tv4##concept< \
83 BOOST_FPTR ns::concept<tv1,tv2,tv3,tv4>::constraints> \
84 concept_checking_typedef_##tv1##tv2##tv3##tv4##concept
86 // NOTE: The BOOST_CLASS_REQUIRES (with an 'S' at the end) is deprecated.
88 // The BOOST_CLASS_REQUIRES macros use function pointers as
89 // template parameters, which VC++ does not support.
91 #if defined(BOOST_NO_FUNCTION_PTR_TEMPLATE_PARAMETERS)
93 #define BOOST_CLASS_REQUIRES(type_var, concept)
94 #define BOOST_CLASS_REQUIRES2(type_var1, type_var2, concept)
95 #define BOOST_CLASS_REQUIRES3(type_var1, type_var2, type_var3, concept)
96 #define BOOST_CLASS_REQUIRES4(type_var1, type_var2, type_var3, type_var4, concept)
100 #define BOOST_CLASS_REQUIRES(type_var, concept) \
101 typedef void (concept <type_var>::* func##type_var##concept)(); \
102 template <func##type_var##concept _Tp1> \
103 struct concept_checking_##type_var##concept { }; \
104 typedef concept_checking_##type_var##concept< \
105 BOOST_FPTR concept <type_var>::constraints> \
106 concept_checking_typedef_##type_var##concept
108 #define BOOST_CLASS_REQUIRES2(type_var1, type_var2, concept) \
109 typedef void (concept <type_var1,type_var2>::* func##type_var1##type_var2##concept)(); \
110 template <func##type_var1##type_var2##concept _Tp1> \
111 struct concept_checking_##type_var1##type_var2##concept { }; \
112 typedef concept_checking_##type_var1##type_var2##concept< \
113 BOOST_FPTR concept <type_var1,type_var2>::constraints> \
114 concept_checking_typedef_##type_var1##type_var2##concept
116 #define BOOST_CLASS_REQUIRES3(type_var1, type_var2, type_var3, concept) \
117 typedef void (concept <type_var1,type_var2,type_var3>::* func##type_var1##type_var2##type_var3##concept)(); \
118 template <func##type_var1##type_var2##type_var3##concept _Tp1> \
119 struct concept_checking_##type_var1##type_var2##type_var3##concept { }; \
120 typedef concept_checking_##type_var1##type_var2##type_var3##concept< \
121 BOOST_FPTR concept <type_var1,type_var2,type_var3>::constraints> \
122 concept_checking_typedef_##type_var1##type_var2##type_var3##concept
124 #define BOOST_CLASS_REQUIRES4(type_var1, type_var2, type_var3, type_var4, concept) \
125 typedef void (concept <type_var1,type_var2,type_var3,type_var4>::* func##type_var1##type_var2##type_var3##type_var4##concept)(); \
126 template <func##type_var1##type_var2##type_var3##type_var4##concept _Tp1> \
127 struct concept_checking_##type_var1##type_var2##type_var3##type_var4##concept { }; \
128 typedef concept_checking_##type_var1##type_var2##type_var3##type_var4##concept< \
129 BOOST_FPTR concept <type_var1,type_var2,type_var3,type_var4>::constraints> \
130 concept_checking_typedef_##type_var1##type_var2##type_var3##type_var4##concept
135 #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
136 template <class T, class U>
137 struct require_same { };
140 struct require_same<T,T> { typedef T type; };
142 // This version does not perform checking, but will not do any harm.
143 template <class T, class U>
144 struct require_same { typedef T type; };
148 struct IntegerConcept {
150 #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
151 x.error_type_must_be_an_integer_type();
156 #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
157 template <> struct IntegerConcept<short> { void constraints() {} };
158 template <> struct IntegerConcept<unsigned short> { void constraints() {} };
159 template <> struct IntegerConcept<int> { void constraints() {} };
160 template <> struct IntegerConcept<unsigned int> { void constraints() {} };
161 template <> struct IntegerConcept<long> { void constraints() {} };
162 template <> struct IntegerConcept<unsigned long> { void constraints() {} };
167 struct SignedIntegerConcept {
169 #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
170 x.error_type_must_be_a_signed_integer_type();
175 #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
176 template <> struct SignedIntegerConcept<short> { void constraints() {} };
177 template <> struct SignedIntegerConcept<int> { void constraints() {} };
178 template <> struct SignedIntegerConcept<long> { void constraints() {} };
179 # if defined(BOOST_HAS_LONG_LONG)
180 template <> struct SignedIntegerConcept<long long> { void constraints() {} };
186 struct UnsignedIntegerConcept {
188 #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
189 x.error_type_must_be_an_unsigned_integer_type();
194 #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
195 template <> struct UnsignedIntegerConcept<unsigned short>
196 { void constraints() {} };
197 template <> struct UnsignedIntegerConcept<unsigned int>
198 { void constraints() {} };
199 template <> struct UnsignedIntegerConcept<unsigned long>
200 { void constraints() {} };
204 //===========================================================================
208 struct DefaultConstructibleConcept
211 TT a; // require default constructor
212 ignore_unused_variable_warning(a);
217 struct AssignableConcept
220 #if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
221 a = a; // require assignment operator
223 const_constraints(a);
225 void const_constraints(const TT& b) {
226 #if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
227 a = b; // const required for argument to assignment
234 struct CopyConstructibleConcept
237 TT a(b); // require copy constructor
238 TT* ptr = &a; // require address of operator
239 const_constraints(a);
240 ignore_unused_variable_warning(ptr);
242 void const_constraints(const TT& a) {
243 TT c(a); // require const copy constructor
244 const TT* ptr = &a; // require const address of operator
245 ignore_unused_variable_warning(c);
246 ignore_unused_variable_warning(ptr);
251 // The SGI STL version of Assignable requires copy constructor and operator=
253 struct SGIAssignableConcept
257 #if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
258 a = a; // require assignment operator
260 const_constraints(a);
261 ignore_unused_variable_warning(b);
263 void const_constraints(const TT& b) {
265 #if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
266 a = b; // const required for argument to assignment
268 ignore_unused_variable_warning(c);
273 template <class X, class Y>
274 struct ConvertibleConcept
278 ignore_unused_variable_warning(y);
283 // The C++ standard requirements for many concepts talk about return
284 // types that must be "convertible to bool". The problem with this
285 // requirement is that it leaves the door open for evil proxies that
286 // define things like operator|| with strange return types. Two
287 // possible solutions are:
288 // 1) require the return type to be exactly bool
289 // 2) stay with convertible to bool, and also
290 // specify stuff about all the logical operators.
291 // For now we just test for convertible to bool.
293 void require_boolean_expr(const TT& t) {
295 ignore_unused_variable_warning(x);
299 struct EqualityComparableConcept
302 require_boolean_expr(a == b);
303 require_boolean_expr(a != b);
309 struct LessThanComparableConcept
312 require_boolean_expr(a < b);
317 // This is equivalent to SGI STL's LessThanComparable.
319 struct ComparableConcept
322 require_boolean_expr(a < b);
323 require_boolean_expr(a > b);
324 require_boolean_expr(a <= b);
325 require_boolean_expr(a >= b);
330 #define BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(OP,NAME) \
331 template <class First, class Second> \
333 void constraints() { (void)constraints_(); } \
334 bool constraints_() { \
341 #define BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(OP,NAME) \
342 template <class Ret, class First, class Second> \
344 void constraints() { (void)constraints_(); } \
345 Ret constraints_() { \
352 BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(==, EqualOpConcept);
353 BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(!=, NotEqualOpConcept);
354 BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<, LessThanOpConcept);
355 BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<=, LessEqualOpConcept);
356 BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>, GreaterThanOpConcept);
357 BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>=, GreaterEqualOpConcept);
359 BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(+, PlusOpConcept);
360 BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(*, TimesOpConcept);
361 BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(/, DivideOpConcept);
362 BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(-, SubtractOpConcept);
363 BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(%, ModOpConcept);
365 //===========================================================================
366 // Function Object Concepts
368 template <class Func, class Return>
369 struct GeneratorConcept
372 const Return& r = f(); // require operator() member function
373 ignore_unused_variable_warning(r);
379 #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
380 template <class Func>
381 struct GeneratorConcept<Func,void>
384 f(); // require operator() member function
390 template <class Func, class Return, class Arg>
391 struct UnaryFunctionConcept
393 // required in case any of our template args are const-qualified:
394 UnaryFunctionConcept();
397 r = f(arg); // require operator()
404 #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
405 template <class Func, class Arg>
406 struct UnaryFunctionConcept<Func, void, Arg> {
408 f(arg); // require operator()
415 template <class Func, class Return, class First, class Second>
416 struct BinaryFunctionConcept
419 r = f(first, second); // require operator()
427 #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
428 template <class Func, class First, class Second>
429 struct BinaryFunctionConcept<Func, void, First, Second>
432 f(first, second); // require operator()
440 template <class Func, class Arg>
441 struct UnaryPredicateConcept
444 require_boolean_expr(f(arg)); // require operator() returning bool
450 template <class Func, class First, class Second>
451 struct BinaryPredicateConcept
454 require_boolean_expr(f(a, b)); // require operator() returning bool
461 // use this when functor is used inside a container class like std::set
462 template <class Func, class First, class Second>
463 struct Const_BinaryPredicateConcept {
465 const_constraints(f);
467 void const_constraints(const Func& fun) {
468 function_requires<BinaryPredicateConcept<Func, First, Second> >();
469 // operator() must be a const member function
470 require_boolean_expr(fun(a, b));
477 template <class Func, class Return>
478 struct AdaptableGeneratorConcept
481 typedef typename Func::result_type result_type;
482 BOOST_STATIC_ASSERT((is_convertible<result_type, Return>::value));
483 function_requires< GeneratorConcept<Func, result_type> >();
487 template <class Func, class Return, class Arg>
488 struct AdaptableUnaryFunctionConcept
491 typedef typename Func::argument_type argument_type;
492 typedef typename Func::result_type result_type;
493 BOOST_STATIC_ASSERT((is_convertible<result_type, Return>::value));
494 BOOST_STATIC_ASSERT((is_convertible<Arg, argument_type>::value));
495 function_requires< UnaryFunctionConcept<Func, result_type, argument_type> >();
499 template <class Func, class Return, class First, class Second>
500 struct AdaptableBinaryFunctionConcept
503 typedef typename Func::first_argument_type first_argument_type;
504 typedef typename Func::second_argument_type second_argument_type;
505 typedef typename Func::result_type result_type;
506 BOOST_STATIC_ASSERT((is_convertible<result_type, Return>::value));
507 BOOST_STATIC_ASSERT((is_convertible<First, first_argument_type>::value));
508 BOOST_STATIC_ASSERT((is_convertible<Second, second_argument_type>::value));
509 function_requires< BinaryFunctionConcept<Func, result_type,
510 first_argument_type, second_argument_type> >();
514 template <class Func, class Arg>
515 struct AdaptablePredicateConcept
518 function_requires< UnaryPredicateConcept<Func, Arg> >();
519 function_requires< AdaptableUnaryFunctionConcept<Func, bool, Arg> >();
523 template <class Func, class First, class Second>
524 struct AdaptableBinaryPredicateConcept
527 function_requires< BinaryPredicateConcept<Func, First, Second> >();
528 function_requires< AdaptableBinaryFunctionConcept<Func, bool, First, Second> >();
532 //===========================================================================
536 struct TrivialIteratorConcept
539 function_requires< AssignableConcept<TT> >();
540 function_requires< DefaultConstructibleConcept<TT> >();
541 function_requires< EqualityComparableConcept<TT> >();
542 (void)*i; // require dereference operator
548 struct Mutable_TrivialIteratorConcept
551 function_requires< TrivialIteratorConcept<TT> >();
552 *i = *j; // require dereference and assignment
558 struct InputIteratorConcept
561 function_requires< TrivialIteratorConcept<TT> >();
562 // require iterator_traits typedef's
563 #ifndef BOOST_NO_STD_ITERATOR_TRAITS
564 typedef typename std::iterator_traits<TT>::difference_type D;
565 // Hmm, the following is a bit fragile
566 //function_requires< SignedIntegerConcept<D> >();
567 typedef typename std::iterator_traits<TT>::reference R;
568 typedef typename std::iterator_traits<TT>::pointer P;
569 typedef typename std::iterator_traits<TT>::iterator_category C;
570 function_requires< ConvertibleConcept<C, std::input_iterator_tag> >();
572 ++i; // require preincrement operator
573 i++; // require postincrement operator
578 template <class TT, class ValueT>
579 struct OutputIteratorConcept
582 function_requires< AssignableConcept<TT> >();
583 ++i; // require preincrement operator
584 i++; // require postincrement operator
585 *i++ = t; // require postincrement and assignment
592 struct ForwardIteratorConcept
595 function_requires< InputIteratorConcept<TT> >();
596 #ifndef BOOST_NO_STD_ITERATOR_TRAITS
597 typedef typename std::iterator_traits<TT>::iterator_category C;
598 function_requires< ConvertibleConcept<C, std::forward_iterator_tag> >();
599 typedef typename std::iterator_traits<TT>::reference reference;
601 ignore_unused_variable_warning(r);
608 struct Mutable_ForwardIteratorConcept
611 function_requires< ForwardIteratorConcept<TT> >();
612 *i++ = *i; // require postincrement and assignment
618 struct BidirectionalIteratorConcept
621 function_requires< ForwardIteratorConcept<TT> >();
622 #ifndef BOOST_NO_STD_ITERATOR_TRAITS
623 typedef typename std::iterator_traits<TT>::iterator_category C;
624 function_requires< ConvertibleConcept<C,
625 std::bidirectional_iterator_tag> >();
627 --i; // require predecrement operator
628 i--; // require postdecrement operator
634 struct Mutable_BidirectionalIteratorConcept
637 function_requires< BidirectionalIteratorConcept<TT> >();
638 function_requires< Mutable_ForwardIteratorConcept<TT> >();
639 *i-- = *i; // require postdecrement and assignment
646 struct RandomAccessIteratorConcept
649 function_requires< BidirectionalIteratorConcept<TT> >();
650 function_requires< ComparableConcept<TT> >();
651 #ifndef BOOST_NO_STD_ITERATOR_TRAITS
652 typedef typename std::iterator_traits<TT>::iterator_category C;
653 function_requires< ConvertibleConcept< C,
654 std::random_access_iterator_tag> >();
655 typedef typename std::iterator_traits<TT>::reference R;
658 i += n; // require assignment addition operator
659 i = i + n; i = n + i; // require addition with difference type
660 i -= n; // require assignment subtraction operator
661 i = i - n; // require subtraction with difference type
662 n = i - j; // require difference operator
663 (void)i[n]; // require element access operator
667 #ifndef BOOST_NO_STD_ITERATOR_TRAITS
668 typename std::iterator_traits<TT>::difference_type n;
675 struct Mutable_RandomAccessIteratorConcept
678 function_requires< RandomAccessIteratorConcept<TT> >();
679 function_requires< Mutable_BidirectionalIteratorConcept<TT> >();
680 i[n] = *i; // require element access and assignment
683 #ifndef BOOST_NO_STD_ITERATOR_TRAITS
684 typename std::iterator_traits<TT>::difference_type n;
690 //===========================================================================
691 // Container Concepts
693 template <class Container>
694 struct ContainerConcept
696 typedef typename Container::value_type value_type;
697 typedef typename Container::difference_type difference_type;
698 typedef typename Container::size_type size_type;
699 typedef typename Container::const_reference const_reference;
700 typedef typename Container::const_pointer const_pointer;
701 typedef typename Container::const_iterator const_iterator;
704 function_requires< InputIteratorConcept<const_iterator> >();
705 function_requires< AssignableConcept<Container> >();
706 const_constraints(c);
708 void const_constraints(const Container& c) {
721 template <class Container>
722 struct Mutable_ContainerConcept
724 typedef typename Container::value_type value_type;
725 typedef typename Container::reference reference;
726 typedef typename Container::iterator iterator;
727 typedef typename Container::pointer pointer;
730 function_requires< ContainerConcept<Container> >();
731 function_requires< AssignableConcept<value_type> >();
732 function_requires< InputIteratorConcept<iterator> >();
742 template <class ForwardContainer>
743 struct ForwardContainerConcept
746 function_requires< ContainerConcept<ForwardContainer> >();
747 typedef typename ForwardContainer::const_iterator const_iterator;
748 function_requires< ForwardIteratorConcept<const_iterator> >();
752 template <class ForwardContainer>
753 struct Mutable_ForwardContainerConcept
756 function_requires< ForwardContainerConcept<ForwardContainer> >();
757 function_requires< Mutable_ContainerConcept<ForwardContainer> >();
758 typedef typename ForwardContainer::iterator iterator;
759 function_requires< Mutable_ForwardIteratorConcept<iterator> >();
763 template <class ReversibleContainer>
764 struct ReversibleContainerConcept
766 typedef typename ReversibleContainer::const_iterator const_iterator;
767 typedef typename ReversibleContainer::const_reverse_iterator
768 const_reverse_iterator;
771 function_requires< ForwardContainerConcept<ReversibleContainer> >();
772 function_requires< BidirectionalIteratorConcept<const_iterator> >();
774 BidirectionalIteratorConcept<const_reverse_iterator> >();
775 const_constraints(c);
777 void const_constraints(const ReversibleContainer& c) {
778 const_reverse_iterator i = c.rbegin();
781 ReversibleContainer c;
784 template <class ReversibleContainer>
785 struct Mutable_ReversibleContainerConcept
787 typedef typename ReversibleContainer::iterator iterator;
788 typedef typename ReversibleContainer::reverse_iterator reverse_iterator;
791 function_requires< ReversibleContainerConcept<ReversibleContainer> >();
793 Mutable_ForwardContainerConcept<ReversibleContainer> >();
794 function_requires< Mutable_BidirectionalIteratorConcept<iterator> >();
796 Mutable_BidirectionalIteratorConcept<reverse_iterator> >();
798 reverse_iterator i = c.rbegin();
801 ReversibleContainer c;
804 template <class RandomAccessContainer>
805 struct RandomAccessContainerConcept
807 typedef typename RandomAccessContainer::size_type size_type;
808 typedef typename RandomAccessContainer::const_reference const_reference;
809 typedef typename RandomAccessContainer::const_iterator const_iterator;
810 typedef typename RandomAccessContainer::const_reverse_iterator
811 const_reverse_iterator;
814 function_requires< ReversibleContainerConcept<RandomAccessContainer> >();
815 function_requires< RandomAccessIteratorConcept<const_iterator> >();
817 RandomAccessIteratorConcept<const_reverse_iterator> >();
819 const_constraints(c);
821 void const_constraints(const RandomAccessContainer& c) {
822 const_reference r = c[n];
823 ignore_unused_variable_warning(r);
825 RandomAccessContainer c;
829 template <class RandomAccessContainer>
830 struct Mutable_RandomAccessContainerConcept
832 typedef typename RandomAccessContainer::size_type size_type;
833 typedef typename RandomAccessContainer::reference reference;
834 typedef typename RandomAccessContainer::iterator iterator;
835 typedef typename RandomAccessContainer::reverse_iterator reverse_iterator;
839 RandomAccessContainerConcept<RandomAccessContainer> >();
841 Mutable_ReversibleContainerConcept<RandomAccessContainer> >();
842 function_requires< Mutable_RandomAccessIteratorConcept<iterator> >();
844 Mutable_RandomAccessIteratorConcept<reverse_iterator> >();
847 ignore_unused_variable_warning(r);
850 RandomAccessContainer c;
853 // A Sequence is inherently mutable
854 template <class Sequence>
855 struct SequenceConcept
858 typedef typename Sequence::reference reference;
859 typedef typename Sequence::const_reference const_reference;
862 // Matt Austern's book puts DefaultConstructible here, the C++
863 // standard places it in Container
864 // function_requires< DefaultConstructible<Sequence> >();
865 function_requires< Mutable_ForwardContainerConcept<Sequence> >();
866 function_requires< DefaultConstructibleConcept<Sequence> >();
875 c.insert(p, first, last);
880 reference r = c.front();
882 ignore_unused_variable_warning(c);
883 ignore_unused_variable_warning(c2);
884 ignore_unused_variable_warning(c3);
885 ignore_unused_variable_warning(r);
886 const_constraints(c);
888 void const_constraints(const Sequence& c) {
889 const_reference r = c.front();
890 ignore_unused_variable_warning(r);
892 typename Sequence::value_type t;
893 typename Sequence::size_type n;
894 typename Sequence::value_type* first, *last;
895 typename Sequence::iterator p, q;
898 template <class FrontInsertionSequence>
899 struct FrontInsertionSequenceConcept
902 function_requires< SequenceConcept<FrontInsertionSequence> >();
907 FrontInsertionSequence c;
908 typename FrontInsertionSequence::value_type t;
911 template <class BackInsertionSequence>
912 struct BackInsertionSequenceConcept
914 typedef typename BackInsertionSequence::reference reference;
915 typedef typename BackInsertionSequence::const_reference const_reference;
918 function_requires< SequenceConcept<BackInsertionSequence> >();
922 reference r = c.back();
923 ignore_unused_variable_warning(r);
925 void const_constraints(const BackInsertionSequence& c) {
926 const_reference r = c.back();
927 ignore_unused_variable_warning(r);
929 BackInsertionSequence c;
930 typename BackInsertionSequence::value_type t;
933 template <class AssociativeContainer>
934 struct AssociativeContainerConcept
937 function_requires< ForwardContainerConcept<AssociativeContainer> >();
938 function_requires< DefaultConstructibleConcept<AssociativeContainer> >();
941 r = c.equal_range(k);
944 c.erase(r.first, r.second);
945 const_constraints(c);
947 void const_constraints(const AssociativeContainer& c) {
950 cr = c.equal_range(k);
952 typedef typename AssociativeContainer::iterator iterator;
953 typedef typename AssociativeContainer::const_iterator const_iterator;
955 AssociativeContainer c;
957 std::pair<iterator,iterator> r;
959 std::pair<const_iterator,const_iterator> cr;
960 typename AssociativeContainer::key_type k;
961 typename AssociativeContainer::size_type n;
964 template <class UniqueAssociativeContainer>
965 struct UniqueAssociativeContainerConcept
968 function_requires< AssociativeContainerConcept<UniqueAssociativeContainer> >();
970 UniqueAssociativeContainer c(first, last);
972 pos_flag = c.insert(t);
973 c.insert(first, last);
975 ignore_unused_variable_warning(c);
977 std::pair<typename UniqueAssociativeContainer::iterator, bool> pos_flag;
978 typename UniqueAssociativeContainer::value_type t;
979 typename UniqueAssociativeContainer::value_type* first, *last;
982 template <class MultipleAssociativeContainer>
983 struct MultipleAssociativeContainerConcept
986 function_requires< AssociativeContainerConcept<MultipleAssociativeContainer> >();
988 MultipleAssociativeContainer c(first, last);
991 c.insert(first, last);
993 ignore_unused_variable_warning(c);
994 ignore_unused_variable_warning(pos);
996 typename MultipleAssociativeContainer::iterator pos;
997 typename MultipleAssociativeContainer::value_type t;
998 typename MultipleAssociativeContainer::value_type* first, *last;
1001 template <class SimpleAssociativeContainer>
1002 struct SimpleAssociativeContainerConcept
1004 void constraints() {
1005 function_requires< AssociativeContainerConcept<SimpleAssociativeContainer> >();
1006 typedef typename SimpleAssociativeContainer::key_type key_type;
1007 typedef typename SimpleAssociativeContainer::value_type value_type;
1008 typedef typename require_same<key_type, value_type>::type req;
1012 template <class SimpleAssociativeContainer>
1013 struct PairAssociativeContainerConcept
1015 void constraints() {
1016 function_requires< AssociativeContainerConcept<SimpleAssociativeContainer> >();
1017 typedef typename SimpleAssociativeContainer::key_type key_type;
1018 typedef typename SimpleAssociativeContainer::value_type value_type;
1019 typedef typename SimpleAssociativeContainer::mapped_type mapped_type;
1020 typedef std::pair<const key_type, mapped_type> required_value_type;
1021 typedef typename require_same<value_type, required_value_type>::type req;
1025 template <class SortedAssociativeContainer>
1026 struct SortedAssociativeContainerConcept
1028 void constraints() {
1029 function_requires< AssociativeContainerConcept<SortedAssociativeContainer> >();
1030 function_requires< ReversibleContainerConcept<SortedAssociativeContainer> >();
1032 SortedAssociativeContainer
1035 c3(first, last, kc);
1037 p = c.upper_bound(k);
1038 p = c.lower_bound(k);
1039 r = c.equal_range(k);
1043 ignore_unused_variable_warning(c);
1044 ignore_unused_variable_warning(c2);
1045 ignore_unused_variable_warning(c3);
1047 void const_constraints(const SortedAssociativeContainer& c) {
1049 vc = c.value_comp();
1051 cp = c.upper_bound(k);
1052 cp = c.lower_bound(k);
1053 cr = c.equal_range(k);
1055 typename SortedAssociativeContainer::key_compare kc;
1056 typename SortedAssociativeContainer::value_compare vc;
1057 typename SortedAssociativeContainer::value_type t;
1058 typename SortedAssociativeContainer::key_type k;
1059 typedef typename SortedAssociativeContainer::iterator iterator;
1060 typedef typename SortedAssociativeContainer::const_iterator const_iterator;
1063 std::pair<iterator,iterator> r;
1064 std::pair<const_iterator,const_iterator> cr;
1065 typename SortedAssociativeContainer::value_type* first, *last;
1068 // HashedAssociativeContainer
1070 } // namespace boost
1072 #endif // BOOST_CONCEPT_CHECKS_HPP