Chris@16: // Chris@16: // (C) Copyright Jeremy Siek 2000. Chris@16: // Copyright 2002 The Trustees of Indiana University. Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. (See Chris@16: // accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: // Chris@16: // Revision History: Chris@16: // 05 May 2001: Workarounds for HP aCC from Thomas Matelich. (Jeremy Siek) Chris@16: // 02 April 2001: Removed limits header altogether. (Jeremy Siek) Chris@16: // 01 April 2001: Modified to use new header. (JMaddock) Chris@16: // Chris@16: Chris@16: // See http://www.boost.org/libs/concept_check for documentation. Chris@16: Chris@16: #ifndef BOOST_CONCEPT_CHECKS_HPP Chris@16: # define BOOST_CONCEPT_CHECKS_HPP Chris@16: Chris@16: # include Chris@16: Chris@16: # include Chris@16: # include Chris@16: # include Chris@16: # include Chris@16: # include Chris@16: # include Chris@16: # include Chris@16: # include Chris@16: # include Chris@16: Chris@16: # include Chris@16: # include Chris@16: Chris@101: #if (defined _MSC_VER) Chris@101: # pragma warning( push ) Chris@101: # pragma warning( disable : 4510 ) // default constructor could not be generated Chris@101: # pragma warning( disable : 4610 ) // object 'class' can never be instantiated - user-defined constructor required Chris@101: #endif Chris@101: Chris@16: namespace boost Chris@16: { Chris@16: Chris@16: // Chris@16: // Backward compatibility Chris@16: // Chris@16: Chris@16: template Chris@16: inline void function_requires(Model* = 0) Chris@16: { Chris@16: BOOST_CONCEPT_ASSERT((Model)); Chris@16: } Chris@16: template inline void ignore_unused_variable_warning(T const&) {} Chris@16: Chris@16: # define BOOST_CLASS_REQUIRE(type_var, ns, concept) \ Chris@16: BOOST_CONCEPT_ASSERT((ns::concept)) Chris@16: Chris@16: # define BOOST_CLASS_REQUIRE2(type_var1, type_var2, ns, concept) \ Chris@16: BOOST_CONCEPT_ASSERT((ns::concept)) Chris@16: Chris@16: # define BOOST_CLASS_REQUIRE3(tv1, tv2, tv3, ns, concept) \ Chris@16: BOOST_CONCEPT_ASSERT((ns::concept)) Chris@16: Chris@16: # define BOOST_CLASS_REQUIRE4(tv1, tv2, tv3, tv4, ns, concept) \ Chris@16: BOOST_CONCEPT_ASSERT((ns::concept)) Chris@16: Chris@16: Chris@16: // Chris@16: // Begin concept definitions Chris@16: // Chris@16: BOOST_concept(Integer, (T)) Chris@16: { Chris@16: BOOST_CONCEPT_USAGE(Integer) Chris@16: { Chris@16: x.error_type_must_be_an_integer_type(); Chris@16: } Chris@16: private: Chris@16: T x; Chris@16: }; Chris@16: Chris@16: template <> struct Integer {}; Chris@16: template <> struct Integer {}; Chris@16: template <> struct Integer {}; Chris@16: template <> struct Integer {}; Chris@16: template <> struct Integer {}; Chris@16: template <> struct Integer {}; Chris@16: template <> struct Integer {}; Chris@16: template <> struct Integer {}; Chris@16: template <> struct Integer {}; Chris@16: # if defined(BOOST_HAS_LONG_LONG) Chris@16: template <> struct Integer< ::boost::long_long_type> {}; Chris@16: template <> struct Integer< ::boost::ulong_long_type> {}; Chris@16: # elif defined(BOOST_HAS_MS_INT64) Chris@16: template <> struct Integer<__int64> {}; Chris@16: template <> struct Integer {}; Chris@16: # endif Chris@16: Chris@16: BOOST_concept(SignedInteger,(T)) { Chris@16: BOOST_CONCEPT_USAGE(SignedInteger) { Chris@16: x.error_type_must_be_a_signed_integer_type(); Chris@16: } Chris@16: private: Chris@16: T x; Chris@16: }; Chris@16: template <> struct SignedInteger { }; Chris@16: template <> struct SignedInteger {}; Chris@16: template <> struct SignedInteger {}; Chris@16: template <> struct SignedInteger {}; Chris@16: # if defined(BOOST_HAS_LONG_LONG) Chris@16: template <> struct SignedInteger< ::boost::long_long_type> {}; Chris@16: # elif defined(BOOST_HAS_MS_INT64) Chris@16: template <> struct SignedInteger<__int64> {}; Chris@16: # endif Chris@16: Chris@16: BOOST_concept(UnsignedInteger,(T)) { Chris@16: BOOST_CONCEPT_USAGE(UnsignedInteger) { Chris@16: x.error_type_must_be_an_unsigned_integer_type(); Chris@16: } Chris@16: private: Chris@16: T x; Chris@16: }; Chris@16: Chris@16: template <> struct UnsignedInteger {}; Chris@16: template <> struct UnsignedInteger {}; Chris@16: template <> struct UnsignedInteger {}; Chris@16: template <> struct UnsignedInteger {}; Chris@16: # if defined(BOOST_HAS_LONG_LONG) Chris@16: template <> struct UnsignedInteger< ::boost::ulong_long_type> {}; Chris@16: # elif defined(BOOST_HAS_MS_INT64) Chris@16: template <> struct UnsignedInteger {}; Chris@16: # endif Chris@16: Chris@16: //=========================================================================== Chris@16: // Basic Concepts Chris@16: Chris@16: BOOST_concept(DefaultConstructible,(TT)) Chris@16: { Chris@16: BOOST_CONCEPT_USAGE(DefaultConstructible) { Chris@16: TT a; // require default constructor Chris@16: ignore_unused_variable_warning(a); Chris@16: } Chris@16: }; Chris@16: Chris@16: BOOST_concept(Assignable,(TT)) Chris@16: { Chris@16: BOOST_CONCEPT_USAGE(Assignable) { Chris@16: #if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL Chris@16: a = b; // require assignment operator Chris@16: #endif Chris@16: const_constraints(b); Chris@16: } Chris@16: private: Chris@16: void const_constraints(const TT& x) { Chris@16: #if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL Chris@16: a = x; // const required for argument to assignment Chris@16: #else Chris@16: ignore_unused_variable_warning(x); Chris@16: #endif Chris@16: } Chris@16: private: Chris@16: TT a; Chris@16: TT b; Chris@16: }; Chris@16: Chris@16: Chris@16: BOOST_concept(CopyConstructible,(TT)) Chris@16: { Chris@16: BOOST_CONCEPT_USAGE(CopyConstructible) { Chris@16: TT a(b); // require copy constructor Chris@16: TT* ptr = &a; // require address of operator Chris@16: const_constraints(a); Chris@16: ignore_unused_variable_warning(ptr); Chris@16: } Chris@16: private: Chris@16: void const_constraints(const TT& a) { Chris@16: TT c(a); // require const copy constructor Chris@16: const TT* ptr = &a; // require const address of operator Chris@16: ignore_unused_variable_warning(c); Chris@16: ignore_unused_variable_warning(ptr); Chris@16: } Chris@16: TT b; Chris@16: }; Chris@16: Chris@16: // The SGI STL version of Assignable requires copy constructor and operator= Chris@16: BOOST_concept(SGIAssignable,(TT)) Chris@16: { Chris@16: BOOST_CONCEPT_USAGE(SGIAssignable) { Chris@16: TT c(a); Chris@16: #if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL Chris@16: a = b; // require assignment operator Chris@16: #endif Chris@16: const_constraints(b); Chris@16: ignore_unused_variable_warning(c); Chris@16: } Chris@16: private: Chris@16: void const_constraints(const TT& x) { Chris@16: TT c(x); Chris@16: #if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL Chris@16: a = x; // const required for argument to assignment Chris@16: #endif Chris@16: ignore_unused_variable_warning(c); Chris@16: } Chris@16: TT a; Chris@16: TT b; Chris@16: }; Chris@16: Chris@16: BOOST_concept(Convertible,(X)(Y)) Chris@16: { Chris@16: BOOST_CONCEPT_USAGE(Convertible) { Chris@16: Y y = x; Chris@16: ignore_unused_variable_warning(y); Chris@16: } Chris@16: private: Chris@16: X x; Chris@16: }; Chris@16: Chris@16: // The C++ standard requirements for many concepts talk about return Chris@16: // types that must be "convertible to bool". The problem with this Chris@16: // requirement is that it leaves the door open for evil proxies that Chris@16: // define things like operator|| with strange return types. Two Chris@16: // possible solutions are: Chris@16: // 1) require the return type to be exactly bool Chris@16: // 2) stay with convertible to bool, and also Chris@16: // specify stuff about all the logical operators. Chris@16: // For now we just test for convertible to bool. Chris@16: template Chris@16: void require_boolean_expr(const TT& t) { Chris@16: bool x = t; Chris@16: ignore_unused_variable_warning(x); Chris@16: } Chris@16: Chris@16: BOOST_concept(EqualityComparable,(TT)) Chris@16: { Chris@16: BOOST_CONCEPT_USAGE(EqualityComparable) { Chris@16: require_boolean_expr(a == b); Chris@16: require_boolean_expr(a != b); Chris@16: } Chris@16: private: Chris@16: TT a, b; Chris@16: }; Chris@16: Chris@16: BOOST_concept(LessThanComparable,(TT)) Chris@16: { Chris@16: BOOST_CONCEPT_USAGE(LessThanComparable) { Chris@16: require_boolean_expr(a < b); Chris@16: } Chris@16: private: Chris@16: TT a, b; Chris@16: }; Chris@16: Chris@16: // This is equivalent to SGI STL's LessThanComparable. Chris@16: BOOST_concept(Comparable,(TT)) Chris@16: { Chris@16: BOOST_CONCEPT_USAGE(Comparable) { Chris@16: require_boolean_expr(a < b); Chris@16: require_boolean_expr(a > b); Chris@16: require_boolean_expr(a <= b); Chris@16: require_boolean_expr(a >= b); Chris@16: } Chris@16: private: Chris@16: TT a, b; Chris@16: }; Chris@16: Chris@16: #define BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(OP,NAME) \ Chris@16: BOOST_concept(NAME, (First)(Second)) \ Chris@16: { \ Chris@16: BOOST_CONCEPT_USAGE(NAME) { (void)constraints_(); } \ Chris@16: private: \ Chris@16: bool constraints_() { return a OP b; } \ Chris@16: First a; \ Chris@16: Second b; \ Chris@16: } Chris@16: Chris@16: #define BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(OP,NAME) \ Chris@16: BOOST_concept(NAME, (Ret)(First)(Second)) \ Chris@16: { \ Chris@16: BOOST_CONCEPT_USAGE(NAME) { (void)constraints_(); } \ Chris@16: private: \ Chris@16: Ret constraints_() { return a OP b; } \ Chris@16: First a; \ Chris@16: Second b; \ Chris@16: } Chris@16: Chris@16: BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(==, EqualOp); Chris@16: BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(!=, NotEqualOp); Chris@16: BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<, LessThanOp); Chris@16: BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<=, LessEqualOp); Chris@16: BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>, GreaterThanOp); Chris@16: BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>=, GreaterEqualOp); Chris@16: Chris@16: BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(+, PlusOp); Chris@16: BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(*, TimesOp); Chris@16: BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(/, DivideOp); Chris@16: BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(-, SubtractOp); Chris@16: BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(%, ModOp); Chris@16: Chris@16: //=========================================================================== Chris@16: // Function Object Concepts Chris@16: Chris@16: BOOST_concept(Generator,(Func)(Return)) Chris@16: { Chris@16: BOOST_CONCEPT_USAGE(Generator) { test(is_void()); } Chris@16: Chris@16: private: Chris@16: void test(boost::mpl::false_) Chris@16: { Chris@16: // Do we really want a reference here? Chris@16: const Return& r = f(); Chris@16: ignore_unused_variable_warning(r); Chris@16: } Chris@16: Chris@16: void test(boost::mpl::true_) Chris@16: { Chris@16: f(); Chris@16: } Chris@16: Chris@16: Func f; Chris@16: }; Chris@16: Chris@16: BOOST_concept(UnaryFunction,(Func)(Return)(Arg)) Chris@16: { Chris@16: BOOST_CONCEPT_USAGE(UnaryFunction) { test(is_void()); } Chris@16: Chris@16: private: Chris@16: void test(boost::mpl::false_) Chris@16: { Chris@16: f(arg); // "priming the pump" this way keeps msvc6 happy (ICE) Chris@16: Return r = f(arg); Chris@16: ignore_unused_variable_warning(r); Chris@16: } Chris@16: Chris@16: void test(boost::mpl::true_) Chris@16: { Chris@16: f(arg); Chris@16: } Chris@16: Chris@16: #if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \ Chris@16: && BOOST_WORKAROUND(__GNUC__, > 3))) Chris@16: // Declare a dummy construktor to make gcc happy. Chris@16: // It seems the compiler can not generate a sensible constructor when this is instantiated with a refence type. Chris@16: // (warning: non-static reference "const double& boost::UnaryFunction::arg" Chris@16: // in class without a constructor [-Wuninitialized]) Chris@16: UnaryFunction(); Chris@16: #endif Chris@16: Chris@16: Func f; Chris@16: Arg arg; Chris@16: }; Chris@16: Chris@16: BOOST_concept(BinaryFunction,(Func)(Return)(First)(Second)) Chris@16: { Chris@16: BOOST_CONCEPT_USAGE(BinaryFunction) { test(is_void()); } Chris@16: private: Chris@16: void test(boost::mpl::false_) Chris@16: { Chris@16: f(first,second); Chris@16: Return r = f(first, second); // require operator() Chris@16: (void)r; Chris@16: } Chris@16: Chris@16: void test(boost::mpl::true_) Chris@16: { Chris@16: f(first,second); Chris@16: } Chris@16: Chris@16: #if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \ Chris@16: && BOOST_WORKAROUND(__GNUC__, > 3))) Chris@16: // Declare a dummy constructor to make gcc happy. Chris@16: // It seems the compiler can not generate a sensible constructor when this is instantiated with a refence type. Chris@16: // (warning: non-static reference "const double& boost::BinaryFunction::arg" Chris@16: // in class without a constructor [-Wuninitialized]) Chris@16: BinaryFunction(); Chris@16: #endif Chris@16: Chris@16: Func f; Chris@16: First first; Chris@16: Second second; Chris@16: }; Chris@16: Chris@16: BOOST_concept(UnaryPredicate,(Func)(Arg)) Chris@16: { Chris@16: BOOST_CONCEPT_USAGE(UnaryPredicate) { Chris@16: require_boolean_expr(f(arg)); // require operator() returning bool Chris@16: } Chris@16: private: Chris@16: #if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \ Chris@16: && BOOST_WORKAROUND(__GNUC__, > 3))) Chris@16: // Declare a dummy constructor to make gcc happy. Chris@16: // It seems the compiler can not generate a sensible constructor when this is instantiated with a refence type. Chris@16: // (warning: non-static reference "const double& boost::UnaryPredicate::arg" Chris@16: // in class without a constructor [-Wuninitialized]) Chris@16: UnaryPredicate(); Chris@16: #endif Chris@16: Chris@16: Func f; Chris@16: Arg arg; Chris@16: }; Chris@16: Chris@16: BOOST_concept(BinaryPredicate,(Func)(First)(Second)) Chris@16: { Chris@16: BOOST_CONCEPT_USAGE(BinaryPredicate) { Chris@16: require_boolean_expr(f(a, b)); // require operator() returning bool Chris@16: } Chris@16: private: Chris@16: #if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \ Chris@16: && BOOST_WORKAROUND(__GNUC__, > 3))) Chris@16: // Declare a dummy constructor to make gcc happy. Chris@16: // It seems the compiler can not generate a sensible constructor when this is instantiated with a refence type. Chris@16: // (warning: non-static reference "const double& boost::BinaryPredicate::arg" Chris@16: // in class without a constructor [-Wuninitialized]) Chris@16: BinaryPredicate(); Chris@16: #endif Chris@16: Func f; Chris@16: First a; Chris@16: Second b; Chris@16: }; Chris@16: Chris@16: // use this when functor is used inside a container class like std::set Chris@16: BOOST_concept(Const_BinaryPredicate,(Func)(First)(Second)) Chris@16: : BinaryPredicate Chris@16: { Chris@16: BOOST_CONCEPT_USAGE(Const_BinaryPredicate) { Chris@16: const_constraints(f); Chris@16: } Chris@16: private: Chris@16: void const_constraints(const Func& fun) { Chris@16: // operator() must be a const member function Chris@16: require_boolean_expr(fun(a, b)); Chris@16: } Chris@16: #if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \ Chris@16: && BOOST_WORKAROUND(__GNUC__, > 3))) Chris@16: // Declare a dummy constructor to make gcc happy. Chris@16: // It seems the compiler can not generate a sensible constructor when this is instantiated with a refence type. Chris@16: // (warning: non-static reference "const double& boost::Const_BinaryPredicate::arg" Chris@16: // in class without a constructor [-Wuninitialized]) Chris@16: Const_BinaryPredicate(); Chris@16: #endif Chris@16: Chris@16: Func f; Chris@16: First a; Chris@16: Second b; Chris@16: }; Chris@16: Chris@16: BOOST_concept(AdaptableGenerator,(Func)(Return)) Chris@16: : Generator Chris@16: { Chris@16: typedef typename Func::result_type result_type; Chris@16: Chris@16: BOOST_CONCEPT_USAGE(AdaptableGenerator) Chris@16: { Chris@16: BOOST_CONCEPT_ASSERT((Convertible)); Chris@16: } Chris@16: }; Chris@16: Chris@16: BOOST_concept(AdaptableUnaryFunction,(Func)(Return)(Arg)) Chris@16: : UnaryFunction Chris@16: { Chris@16: typedef typename Func::argument_type argument_type; Chris@16: typedef typename Func::result_type result_type; Chris@16: Chris@16: ~AdaptableUnaryFunction() Chris@16: { Chris@16: BOOST_CONCEPT_ASSERT((Convertible)); Chris@16: BOOST_CONCEPT_ASSERT((Convertible)); Chris@16: } Chris@16: }; Chris@16: Chris@16: BOOST_concept(AdaptableBinaryFunction,(Func)(Return)(First)(Second)) Chris@16: : BinaryFunction< Chris@16: Func Chris@16: , typename Func::result_type Chris@16: , typename Func::first_argument_type Chris@16: , typename Func::second_argument_type Chris@16: > Chris@16: { Chris@16: typedef typename Func::first_argument_type first_argument_type; Chris@16: typedef typename Func::second_argument_type second_argument_type; Chris@16: typedef typename Func::result_type result_type; Chris@16: Chris@16: ~AdaptableBinaryFunction() Chris@16: { Chris@16: BOOST_CONCEPT_ASSERT((Convertible)); Chris@16: BOOST_CONCEPT_ASSERT((Convertible)); Chris@16: BOOST_CONCEPT_ASSERT((Convertible)); Chris@16: } Chris@16: }; Chris@16: Chris@16: BOOST_concept(AdaptablePredicate,(Func)(Arg)) Chris@16: : UnaryPredicate Chris@16: , AdaptableUnaryFunction Chris@16: { Chris@16: }; Chris@16: Chris@16: BOOST_concept(AdaptableBinaryPredicate,(Func)(First)(Second)) Chris@16: : BinaryPredicate Chris@16: , AdaptableBinaryFunction Chris@16: { Chris@16: }; Chris@16: Chris@16: //=========================================================================== Chris@16: // Iterator Concepts Chris@16: Chris@16: BOOST_concept(InputIterator,(TT)) Chris@16: : Assignable Chris@16: , EqualityComparable Chris@16: { Chris@16: typedef typename boost::detail::iterator_traits::value_type value_type; Chris@16: typedef typename boost::detail::iterator_traits::difference_type difference_type; Chris@16: typedef typename boost::detail::iterator_traits::reference reference; Chris@16: typedef typename boost::detail::iterator_traits::pointer pointer; Chris@16: typedef typename boost::detail::iterator_traits::iterator_category iterator_category; Chris@16: Chris@16: BOOST_CONCEPT_USAGE(InputIterator) Chris@16: { Chris@16: BOOST_CONCEPT_ASSERT((SignedInteger)); Chris@16: BOOST_CONCEPT_ASSERT((Convertible)); Chris@16: Chris@16: TT j(i); Chris@16: (void)*i; // require dereference operator Chris@16: ++j; // require preincrement operator Chris@16: i++; // require postincrement operator Chris@16: } Chris@16: private: Chris@16: TT i; Chris@16: }; Chris@16: Chris@16: BOOST_concept(OutputIterator,(TT)(ValueT)) Chris@16: : Assignable Chris@16: { Chris@16: BOOST_CONCEPT_USAGE(OutputIterator) { Chris@16: Chris@16: ++i; // require preincrement operator Chris@16: i++; // require postincrement operator Chris@16: *i++ = t; // require postincrement and assignment Chris@16: } Chris@16: private: Chris@16: TT i, j; Chris@16: ValueT t; Chris@16: }; Chris@16: Chris@16: BOOST_concept(ForwardIterator,(TT)) Chris@16: : InputIterator Chris@16: { Chris@16: BOOST_CONCEPT_USAGE(ForwardIterator) Chris@16: { Chris@16: BOOST_CONCEPT_ASSERT((Convertible< Chris@16: BOOST_DEDUCED_TYPENAME ForwardIterator::iterator_category Chris@16: , std::forward_iterator_tag Chris@16: >)); Chris@16: Chris@16: typename InputIterator::reference r = *i; Chris@16: ignore_unused_variable_warning(r); Chris@16: } Chris@16: Chris@16: private: Chris@16: TT i; Chris@16: }; Chris@16: Chris@16: BOOST_concept(Mutable_ForwardIterator,(TT)) Chris@16: : ForwardIterator Chris@16: { Chris@16: BOOST_CONCEPT_USAGE(Mutable_ForwardIterator) { Chris@101: *i++ = *j; // require postincrement and assignment Chris@16: } Chris@16: private: Chris@101: TT i, j; Chris@16: }; Chris@16: Chris@16: BOOST_concept(BidirectionalIterator,(TT)) Chris@16: : ForwardIterator Chris@16: { Chris@16: BOOST_CONCEPT_USAGE(BidirectionalIterator) Chris@16: { Chris@16: BOOST_CONCEPT_ASSERT((Convertible< Chris@16: BOOST_DEDUCED_TYPENAME BidirectionalIterator::iterator_category Chris@16: , std::bidirectional_iterator_tag Chris@16: >)); Chris@16: Chris@16: --i; // require predecrement operator Chris@16: i--; // require postdecrement operator Chris@16: } Chris@16: private: Chris@16: TT i; Chris@16: }; Chris@16: Chris@16: BOOST_concept(Mutable_BidirectionalIterator,(TT)) Chris@16: : BidirectionalIterator Chris@16: , Mutable_ForwardIterator Chris@16: { Chris@16: BOOST_CONCEPT_USAGE(Mutable_BidirectionalIterator) Chris@16: { Chris@101: *i-- = *j; // require postdecrement and assignment Chris@16: } Chris@16: private: Chris@101: TT i, j; Chris@16: }; Chris@16: Chris@16: BOOST_concept(RandomAccessIterator,(TT)) Chris@16: : BidirectionalIterator Chris@16: , Comparable Chris@16: { Chris@16: BOOST_CONCEPT_USAGE(RandomAccessIterator) Chris@16: { Chris@16: BOOST_CONCEPT_ASSERT((Convertible< Chris@16: BOOST_DEDUCED_TYPENAME BidirectionalIterator::iterator_category Chris@16: , std::random_access_iterator_tag Chris@16: >)); Chris@16: Chris@16: i += n; // require assignment addition operator Chris@16: i = i + n; i = n + i; // require addition with difference type Chris@16: i -= n; // require assignment subtraction operator Chris@16: i = i - n; // require subtraction with difference type Chris@16: n = i - j; // require difference operator Chris@16: (void)i[n]; // require element access operator Chris@16: } Chris@16: Chris@16: private: Chris@16: TT a, b; Chris@16: TT i, j; Chris@16: typename boost::detail::iterator_traits::difference_type n; Chris@16: }; Chris@16: Chris@16: BOOST_concept(Mutable_RandomAccessIterator,(TT)) Chris@16: : RandomAccessIterator Chris@16: , Mutable_BidirectionalIterator Chris@16: { Chris@16: BOOST_CONCEPT_USAGE(Mutable_RandomAccessIterator) Chris@16: { Chris@16: i[n] = *i; // require element access and assignment Chris@16: } Chris@16: private: Chris@16: TT i; Chris@16: typename boost::detail::iterator_traits::difference_type n; Chris@16: }; Chris@16: Chris@16: //=========================================================================== Chris@16: // Container s Chris@16: Chris@16: BOOST_concept(Container,(C)) Chris@16: : Assignable Chris@16: { Chris@16: typedef typename C::value_type value_type; Chris@16: typedef typename C::difference_type difference_type; Chris@16: typedef typename C::size_type size_type; Chris@16: typedef typename C::const_reference const_reference; Chris@16: typedef typename C::const_pointer const_pointer; Chris@16: typedef typename C::const_iterator const_iterator; Chris@16: Chris@16: BOOST_CONCEPT_USAGE(Container) Chris@16: { Chris@16: BOOST_CONCEPT_ASSERT((InputIterator)); Chris@16: const_constraints(c); Chris@16: } Chris@16: Chris@16: private: Chris@16: void const_constraints(const C& cc) { Chris@16: i = cc.begin(); Chris@16: i = cc.end(); Chris@16: n = cc.size(); Chris@16: n = cc.max_size(); Chris@16: b = cc.empty(); Chris@16: } Chris@16: C c; Chris@16: bool b; Chris@16: const_iterator i; Chris@16: size_type n; Chris@16: }; Chris@16: Chris@16: BOOST_concept(Mutable_Container,(C)) Chris@16: : Container Chris@16: { Chris@16: typedef typename C::reference reference; Chris@16: typedef typename C::iterator iterator; Chris@16: typedef typename C::pointer pointer; Chris@16: Chris@16: BOOST_CONCEPT_USAGE(Mutable_Container) Chris@16: { Chris@16: BOOST_CONCEPT_ASSERT(( Chris@16: Assignable)); Chris@16: Chris@16: BOOST_CONCEPT_ASSERT((InputIterator)); Chris@16: Chris@16: i = c.begin(); Chris@16: i = c.end(); Chris@16: c.swap(c2); Chris@16: } Chris@16: Chris@16: private: Chris@16: iterator i; Chris@16: C c, c2; Chris@16: }; Chris@16: Chris@16: BOOST_concept(ForwardContainer,(C)) Chris@16: : Container Chris@16: { Chris@16: BOOST_CONCEPT_USAGE(ForwardContainer) Chris@16: { Chris@16: BOOST_CONCEPT_ASSERT(( Chris@16: ForwardIterator< Chris@16: typename ForwardContainer::const_iterator Chris@16: >)); Chris@16: } Chris@16: }; Chris@16: Chris@16: BOOST_concept(Mutable_ForwardContainer,(C)) Chris@16: : ForwardContainer Chris@16: , Mutable_Container Chris@16: { Chris@16: BOOST_CONCEPT_USAGE(Mutable_ForwardContainer) Chris@16: { Chris@16: BOOST_CONCEPT_ASSERT(( Chris@16: Mutable_ForwardIterator< Chris@16: typename Mutable_ForwardContainer::iterator Chris@16: >)); Chris@16: } Chris@16: }; Chris@16: Chris@16: BOOST_concept(ReversibleContainer,(C)) Chris@16: : ForwardContainer Chris@16: { Chris@16: typedef typename Chris@16: C::const_reverse_iterator Chris@16: const_reverse_iterator; Chris@16: Chris@16: BOOST_CONCEPT_USAGE(ReversibleContainer) Chris@16: { Chris@16: BOOST_CONCEPT_ASSERT(( Chris@16: BidirectionalIterator< Chris@16: typename ReversibleContainer::const_iterator>)); Chris@16: Chris@16: BOOST_CONCEPT_ASSERT((BidirectionalIterator)); Chris@16: Chris@16: const_constraints(c); Chris@16: } Chris@16: private: Chris@16: void const_constraints(const C& cc) Chris@16: { Chris@16: const_reverse_iterator i = cc.rbegin(); Chris@16: i = cc.rend(); Chris@16: } Chris@16: C c; Chris@16: }; Chris@16: Chris@16: BOOST_concept(Mutable_ReversibleContainer,(C)) Chris@16: : Mutable_ForwardContainer Chris@16: , ReversibleContainer Chris@16: { Chris@16: typedef typename C::reverse_iterator reverse_iterator; Chris@16: Chris@16: BOOST_CONCEPT_USAGE(Mutable_ReversibleContainer) Chris@16: { Chris@16: typedef typename Mutable_ForwardContainer::iterator iterator; Chris@16: BOOST_CONCEPT_ASSERT((Mutable_BidirectionalIterator)); Chris@16: BOOST_CONCEPT_ASSERT((Mutable_BidirectionalIterator)); Chris@16: Chris@16: reverse_iterator i = c.rbegin(); Chris@16: i = c.rend(); Chris@16: } Chris@16: private: Chris@16: C c; Chris@16: }; Chris@16: Chris@16: BOOST_concept(RandomAccessContainer,(C)) Chris@16: : ReversibleContainer Chris@16: { Chris@16: typedef typename C::size_type size_type; Chris@16: typedef typename C::const_reference const_reference; Chris@16: Chris@16: BOOST_CONCEPT_USAGE(RandomAccessContainer) Chris@16: { Chris@16: BOOST_CONCEPT_ASSERT(( Chris@16: RandomAccessIterator< Chris@16: typename RandomAccessContainer::const_iterator Chris@16: >)); Chris@16: Chris@16: const_constraints(c); Chris@16: } Chris@16: private: Chris@16: void const_constraints(const C& cc) Chris@16: { Chris@16: const_reference r = cc[n]; Chris@16: ignore_unused_variable_warning(r); Chris@16: } Chris@16: Chris@16: C c; Chris@16: size_type n; Chris@16: }; Chris@16: Chris@16: BOOST_concept(Mutable_RandomAccessContainer,(C)) Chris@16: : Mutable_ReversibleContainer Chris@16: , RandomAccessContainer Chris@16: { Chris@16: private: Chris@16: typedef Mutable_RandomAccessContainer self; Chris@16: public: Chris@16: BOOST_CONCEPT_USAGE(Mutable_RandomAccessContainer) Chris@16: { Chris@16: BOOST_CONCEPT_ASSERT((Mutable_RandomAccessIterator)); Chris@16: BOOST_CONCEPT_ASSERT((Mutable_RandomAccessIterator)); Chris@16: Chris@16: typename self::reference r = c[i]; Chris@16: ignore_unused_variable_warning(r); Chris@16: } Chris@16: Chris@16: private: Chris@16: typename Mutable_ReversibleContainer::size_type i; Chris@16: C c; Chris@16: }; Chris@16: Chris@16: // A Sequence is inherently mutable Chris@16: BOOST_concept(Sequence,(S)) Chris@16: : Mutable_ForwardContainer Chris@16: // Matt Austern's book puts DefaultConstructible here, the C++ Chris@16: // standard places it in Container --JGS Chris@16: // ... so why aren't we following the standard? --DWA Chris@16: , DefaultConstructible Chris@16: { Chris@16: BOOST_CONCEPT_USAGE(Sequence) Chris@16: { Chris@16: S Chris@101: c(n, t), Chris@101: c2(first, last); Chris@16: Chris@16: c.insert(p, t); Chris@16: c.insert(p, n, t); Chris@16: c.insert(p, first, last); Chris@16: Chris@16: c.erase(p); Chris@16: c.erase(p, q); Chris@16: Chris@16: typename Sequence::reference r = c.front(); Chris@16: Chris@16: ignore_unused_variable_warning(c); Chris@16: ignore_unused_variable_warning(c2); Chris@16: ignore_unused_variable_warning(r); Chris@16: const_constraints(c); Chris@16: } Chris@16: private: Chris@16: void const_constraints(const S& c) { Chris@16: typename Sequence::const_reference r = c.front(); Chris@16: ignore_unused_variable_warning(r); Chris@16: } Chris@16: Chris@16: typename S::value_type t; Chris@16: typename S::size_type n; Chris@16: typename S::value_type* first, *last; Chris@16: typename S::iterator p, q; Chris@16: }; Chris@16: Chris@16: BOOST_concept(FrontInsertionSequence,(S)) Chris@16: : Sequence Chris@16: { Chris@16: BOOST_CONCEPT_USAGE(FrontInsertionSequence) Chris@16: { Chris@16: c.push_front(t); Chris@16: c.pop_front(); Chris@16: } Chris@16: private: Chris@16: S c; Chris@16: typename S::value_type t; Chris@16: }; Chris@16: Chris@16: BOOST_concept(BackInsertionSequence,(S)) Chris@16: : Sequence Chris@16: { Chris@16: BOOST_CONCEPT_USAGE(BackInsertionSequence) Chris@16: { Chris@16: c.push_back(t); Chris@16: c.pop_back(); Chris@16: typename BackInsertionSequence::reference r = c.back(); Chris@16: ignore_unused_variable_warning(r); Chris@16: const_constraints(c); Chris@16: } Chris@16: private: Chris@16: void const_constraints(const S& cc) { Chris@16: typename BackInsertionSequence::const_reference Chris@16: r = cc.back(); Chris@16: ignore_unused_variable_warning(r); Chris@101: } Chris@16: S c; Chris@16: typename S::value_type t; Chris@16: }; Chris@16: Chris@16: BOOST_concept(AssociativeContainer,(C)) Chris@16: : ForwardContainer Chris@16: , DefaultConstructible Chris@16: { Chris@16: typedef typename C::key_type key_type; Chris@16: typedef typename C::key_compare key_compare; Chris@16: typedef typename C::value_compare value_compare; Chris@16: typedef typename C::iterator iterator; Chris@16: Chris@16: BOOST_CONCEPT_USAGE(AssociativeContainer) Chris@16: { Chris@16: i = c.find(k); Chris@16: r = c.equal_range(k); Chris@16: c.erase(k); Chris@16: c.erase(i); Chris@16: c.erase(r.first, r.second); Chris@16: const_constraints(c); Chris@16: BOOST_CONCEPT_ASSERT((BinaryPredicate)); Chris@16: Chris@16: typedef typename AssociativeContainer::value_type value_type_; Chris@16: BOOST_CONCEPT_ASSERT((BinaryPredicate)); Chris@16: } Chris@16: Chris@16: // Redundant with the base concept, but it helps below. Chris@16: typedef typename C::const_iterator const_iterator; Chris@16: private: Chris@16: void const_constraints(const C& cc) Chris@16: { Chris@16: ci = cc.find(k); Chris@16: n = cc.count(k); Chris@16: cr = cc.equal_range(k); Chris@16: } Chris@16: Chris@16: C c; Chris@16: iterator i; Chris@16: std::pair r; Chris@16: const_iterator ci; Chris@16: std::pair cr; Chris@16: typename C::key_type k; Chris@16: typename C::size_type n; Chris@16: }; Chris@16: Chris@16: BOOST_concept(UniqueAssociativeContainer,(C)) Chris@16: : AssociativeContainer Chris@16: { Chris@16: BOOST_CONCEPT_USAGE(UniqueAssociativeContainer) Chris@16: { Chris@16: C c(first, last); Chris@16: Chris@16: pos_flag = c.insert(t); Chris@16: c.insert(first, last); Chris@16: Chris@16: ignore_unused_variable_warning(c); Chris@16: } Chris@16: private: Chris@16: std::pair pos_flag; Chris@16: typename C::value_type t; Chris@16: typename C::value_type* first, *last; Chris@16: }; Chris@16: Chris@16: BOOST_concept(MultipleAssociativeContainer,(C)) Chris@16: : AssociativeContainer Chris@16: { Chris@16: BOOST_CONCEPT_USAGE(MultipleAssociativeContainer) Chris@16: { Chris@16: C c(first, last); Chris@16: Chris@16: pos = c.insert(t); Chris@16: c.insert(first, last); Chris@16: Chris@16: ignore_unused_variable_warning(c); Chris@16: ignore_unused_variable_warning(pos); Chris@16: } Chris@16: private: Chris@16: typename C::iterator pos; Chris@16: typename C::value_type t; Chris@16: typename C::value_type* first, *last; Chris@16: }; Chris@16: Chris@16: BOOST_concept(SimpleAssociativeContainer,(C)) Chris@16: : AssociativeContainer Chris@16: { Chris@16: BOOST_CONCEPT_USAGE(SimpleAssociativeContainer) Chris@16: { Chris@16: typedef typename C::key_type key_type; Chris@16: typedef typename C::value_type value_type; Chris@16: BOOST_MPL_ASSERT((boost::is_same)); Chris@16: } Chris@16: }; Chris@16: Chris@16: BOOST_concept(PairAssociativeContainer,(C)) Chris@16: : AssociativeContainer Chris@16: { Chris@16: BOOST_CONCEPT_USAGE(PairAssociativeContainer) Chris@16: { Chris@16: typedef typename C::key_type key_type; Chris@16: typedef typename C::value_type value_type; Chris@16: typedef typename C::mapped_type mapped_type; Chris@16: typedef std::pair required_value_type; Chris@16: BOOST_MPL_ASSERT((boost::is_same)); Chris@16: } Chris@16: }; Chris@16: Chris@16: BOOST_concept(SortedAssociativeContainer,(C)) Chris@16: : AssociativeContainer Chris@16: , ReversibleContainer Chris@16: { Chris@16: BOOST_CONCEPT_USAGE(SortedAssociativeContainer) Chris@16: { Chris@16: C Chris@16: c(kc), Chris@16: c2(first, last), Chris@16: c3(first, last, kc); Chris@16: Chris@16: p = c.upper_bound(k); Chris@16: p = c.lower_bound(k); Chris@16: r = c.equal_range(k); Chris@16: Chris@16: c.insert(p, t); Chris@16: Chris@16: ignore_unused_variable_warning(c); Chris@16: ignore_unused_variable_warning(c2); Chris@16: ignore_unused_variable_warning(c3); Chris@16: const_constraints(c); Chris@16: } Chris@16: Chris@16: void const_constraints(const C& c) Chris@16: { Chris@16: kc = c.key_comp(); Chris@16: vc = c.value_comp(); Chris@16: Chris@16: cp = c.upper_bound(k); Chris@16: cp = c.lower_bound(k); Chris@16: cr = c.equal_range(k); Chris@16: } Chris@16: Chris@16: private: Chris@16: typename C::key_compare kc; Chris@16: typename C::value_compare vc; Chris@16: typename C::value_type t; Chris@16: typename C::key_type k; Chris@16: typedef typename C::iterator iterator; Chris@16: typedef typename C::const_iterator const_iterator; Chris@16: Chris@16: typedef SortedAssociativeContainer self; Chris@16: iterator p; Chris@16: const_iterator cp; Chris@16: std::pair r; Chris@16: std::pair cr; Chris@16: typename C::value_type* first, *last; Chris@16: }; Chris@16: Chris@16: // HashedAssociativeContainer Chris@16: Chris@16: BOOST_concept(Collection,(C)) Chris@16: { Chris@16: BOOST_CONCEPT_USAGE(Collection) Chris@16: { Chris@16: boost::function_requires >(); Chris@16: boost::function_requires >(); Chris@16: boost::function_requires >(); Chris@16: const_constraints(c); Chris@16: i = c.begin(); Chris@16: i = c.end(); Chris@16: c.swap(c); Chris@16: } Chris@16: Chris@16: void const_constraints(const C& cc) { Chris@16: ci = cc.begin(); Chris@16: ci = cc.end(); Chris@16: n = cc.size(); Chris@16: b = cc.empty(); Chris@16: } Chris@16: Chris@16: private: Chris@16: typedef typename C::value_type value_type; Chris@16: typedef typename C::iterator iterator; Chris@16: typedef typename C::const_iterator const_iterator; Chris@16: typedef typename C::reference reference; Chris@16: typedef typename C::const_reference const_reference; Chris@16: // typedef typename C::pointer pointer; Chris@16: typedef typename C::difference_type difference_type; Chris@16: typedef typename C::size_type size_type; Chris@16: Chris@16: C c; Chris@16: bool b; Chris@16: iterator i; Chris@16: const_iterator ci; Chris@16: size_type n; Chris@16: }; Chris@16: } // namespace boost Chris@16: Chris@101: #if (defined _MSC_VER) Chris@101: # pragma warning( pop ) Chris@101: #endif Chris@101: Chris@16: # include Chris@16: Chris@16: #endif // BOOST_CONCEPT_CHECKS_HPP Chris@16: