// (C) Copyright Jeremy Siek 2002. Permission to copy, use, modify, // sell and distribute this software is granted provided this // copyright notice appears in all copies. This software is provided // "as is" without express or implied warranty, and with no claim as // to its suitability for any purpose. #ifndef BOOST_ITERATOR_CONCEPTS_HPP #define BOOST_ITERATOR_CONCEPTS_HPP // Revision History // 22 Nov 2002 Thomas Witt // Added interoperable concept. #include #include #include #include // Use boost::detail::iterator_traits to work around some MSVC/Dinkumware problems. #include namespace boost_concepts { // Used a different namespace here (instead of "boost") so that the // concept descriptions do not take for granted the names in // namespace boost. // We use this in place of STATIC_ASSERT((is_convertible<...>)) // because some compilers (CWPro7.x) can't detect convertibility. // // Of course, that just gets us a different error at the moment with // some tests, since new iterator category deduction still depends // on convertibility detection. We might need some specializations // to support this compiler. template struct static_assert_base_and_derived { static_assert_base_and_derived(Target* = (Source*)0) {} }; //=========================================================================== // Iterator Access Concepts template class ReadableIteratorConcept { public: typedef BOOST_DEDUCED_TYPENAME ::boost::detail::iterator_traits::value_type value_type; typedef BOOST_DEDUCED_TYPENAME ::boost::detail::iterator_traits::reference reference; typedef BOOST_DEDUCED_TYPENAME ::boost::access_category::type access_category; void constraints() { boost::function_requires< boost::SGIAssignableConcept >(); boost::function_requires< boost::EqualityComparableConcept >(); boost::function_requires< boost::DefaultConstructibleConcept >(); static_assert_base_and_derived(); reference r = *i; // or perhaps read(x) value_type v(r); boost::ignore_unused_variable_warning(v); } Iterator i; }; template class WritableIteratorConcept { public: typedef typename boost::access_category::type access_category; void constraints() { boost::function_requires< boost::SGIAssignableConcept >(); boost::function_requires< boost::EqualityComparableConcept >(); boost::function_requires< boost::DefaultConstructibleConcept >(); static_assert_base_and_derived(); *i = v; // a good alternative could be something like write(x, v) } ValueType v; Iterator i; }; template class ConstantLvalueIteratorConcept { public: typedef typename boost::detail::iterator_traits::value_type value_type; typedef typename boost::detail::iterator_traits::reference reference; typedef typename boost::access_category::type access_category; void constraints() { boost::function_requires< ReadableIteratorConcept >(); static_assert_base_and_derived(); BOOST_STATIC_ASSERT((boost::is_same::value)); reference v = *i; boost::ignore_unused_variable_warning(v); } Iterator i; }; template class MutableLvalueIteratorConcept { public: typedef typename boost::detail::iterator_traits::value_type value_type; typedef typename boost::detail::iterator_traits::reference reference; typedef typename boost::access_category::type access_category; void constraints() { boost::function_requires< ReadableIteratorConcept >(); boost::function_requires< WritableIteratorConcept >(); static_assert_base_and_derived(); BOOST_STATIC_ASSERT((boost::is_same::value)); reference v = *i; boost::ignore_unused_variable_warning(v); } Iterator i; }; //=========================================================================== // Iterator Traversal Concepts template class ForwardTraversalConcept { public: typedef typename boost::traversal_category::type traversal_category; void constraints() { boost::function_requires< boost::SGIAssignableConcept >(); boost::function_requires< boost::EqualityComparableConcept >(); boost::function_requires< boost::DefaultConstructibleConcept >(); static_assert_base_and_derived(); ++i; (void)i++; } Iterator i; }; template class BidirectionalTraversalConcept { public: typedef typename boost::traversal_category::type traversal_category; void constraints() { boost::function_requires< ForwardTraversalConcept >(); static_assert_base_and_derived(); --i; (void)i--; } Iterator i; }; template class RandomAccessTraversalConcept { public: typedef typename boost::traversal_category::type traversal_category; typedef typename boost::detail::iterator_traits::difference_type difference_type; void constraints() { boost::function_requires< BidirectionalTraversalConcept >(); static_assert_base_and_derived(); i += n; i = i + n; i = n + i; i -= n; i = i - n; n = i - j; } difference_type n; Iterator i, j; }; //=========================================================================== // Iterator Interoperability Concept namespace detail { template struct Operations; template <> struct Operations { template static void constraints(Iterator1 const& i1, Iterator2 const& i2) { // no interoperability constraints } }; template <> struct Operations { template static void constraints(Iterator1 const& i1, Iterator2 const& i2) { Operations(i1, i2); i1 == i2; i1 != i2; i2 == i1; i2 != i1; } }; template <> struct Operations { template static void constraints(Iterator1 const& i1, Iterator2 const& i2) { Operations::constraints(i1, i2); } }; template <> struct Operations { template static void constraints(Iterator1 const& i1, Iterator2 const& i2) { Operations::constraints(i1, i2); } }; template <> struct Operations { template static void constraints(Iterator1 const& i1, Iterator2 const& i2) { Operations::constraints(i1, i2); i1 < i2; i1 <= i2; i1 > i2; i1 >= i2; i1 - i2; i2 < i1; i2 <= i1; i2 > i1; i2 >= i1; i2 - i1; } }; } // namespace detail template class InteroperableConcept { public: typedef typename boost::traversal_category::type traversal_category; typedef typename boost::detail::iterator_traits::difference_type difference_type; typedef typename boost::traversal_category::type const_traversal_category; typedef typename boost::detail::iterator_traits::difference_type const_difference_type; void constraints() { BOOST_STATIC_ASSERT((boost::is_same< difference_type, const_difference_type>::value)); BOOST_STATIC_ASSERT((boost::is_same< traversal_category, const_traversal_category>::value)); // ToDo check what the std really requires // detail::Operations::constraints(i, ci); ci = i; } Iterator i; ConstIterator ci; }; } // namespace boost_concepts #endif // BOOST_ITERATOR_CONCEPTS_HPP