// (C) Copyright Jeremy Siek 2002. // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_ITERATOR_CONCEPTS_HPP #define BOOST_ITERATOR_CONCEPTS_HPP // Revision History // 26 Apr 2003 thw // Adapted to new iterator concepts // 22 Nov 2002 Thomas Witt // Added interoperable concept. #include #include // Use boost::detail::iterator_traits to work around some MSVC/Dinkumware problems. #include #include #include #include #include #include #include #include #include // Use boost/limits to work around missing limits headers on some compilers #include #include #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; void constraints() { boost::function_requires< boost::AssignableConcept >(); boost::function_requires< boost::CopyConstructibleConcept >(); value_type v = *i; boost::ignore_unused_variable_warning(v); } Iterator i; }; template < typename Iterator , typename ValueType = BOOST_DEDUCED_TYPENAME boost::detail::iterator_traits::value_type > class WritableIteratorConcept { public: void constraints() { boost::function_requires< boost::CopyConstructibleConcept >(); *i = v; } ValueType v; Iterator i; }; template class SwappableIteratorConcept { public: void constraints() { std::iter_swap(i1, i2); } Iterator i1; Iterator i2; }; template class LvalueIteratorConcept { public: typedef typename boost::detail::iterator_traits::value_type value_type; void constraints() { value_type& r = const_cast(*i); boost::ignore_unused_variable_warning(r); } Iterator i; }; //=========================================================================== // Iterator Traversal Concepts template class IncrementableIteratorConcept { public: typedef typename boost::iterator_traversal::type traversal_category; void constraints() { boost::function_requires< boost::AssignableConcept >(); boost::function_requires< boost::CopyConstructibleConcept >(); BOOST_STATIC_ASSERT( (boost::is_convertible< traversal_category , boost::incrementable_traversal_tag >::value )); ++i; (void)i++; } Iterator i; }; template class SinglePassIteratorConcept { public: typedef typename boost::iterator_traversal::type traversal_category; typedef typename boost::detail::iterator_traits::difference_type difference_type; void constraints() { boost::function_requires< IncrementableIteratorConcept >(); boost::function_requires< boost::EqualityComparableConcept >(); BOOST_STATIC_ASSERT( (boost::is_convertible< traversal_category , boost::single_pass_traversal_tag >::value )); } }; template class ForwardTraversalConcept { public: typedef typename boost::iterator_traversal::type traversal_category; typedef typename boost::detail::iterator_traits::difference_type difference_type; void constraints() { boost::function_requires< SinglePassIteratorConcept >(); boost::function_requires< boost::DefaultConstructibleConcept >(); typedef boost::mpl::and_< boost::is_integral, boost::mpl::bool_< std::numeric_limits::is_signed > > difference_type_is_signed_integral; BOOST_STATIC_ASSERT(difference_type_is_signed_integral::value); BOOST_STATIC_ASSERT( (boost::is_convertible< traversal_category , boost::forward_traversal_tag >::value )); } }; template class BidirectionalTraversalConcept { public: typedef typename boost::iterator_traversal::type traversal_category; void constraints() { boost::function_requires< ForwardTraversalConcept >(); BOOST_STATIC_ASSERT( (boost::is_convertible< traversal_category , boost::bidirectional_traversal_tag >::value )); --i; (void)i--; } Iterator i; }; template class RandomAccessTraversalConcept { public: typedef typename boost::iterator_traversal::type traversal_category; typedef typename boost::detail::iterator_traits::difference_type difference_type; void constraints() { boost::function_requires< BidirectionalTraversalConcept >(); BOOST_STATIC_ASSERT( (boost::is_convertible< traversal_category , boost::random_access_traversal_tag >::value )); 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 void interop_single_pass_constraints(Iterator1 const& i1, Iterator2 const& i2) { bool b; b = i1 == i2; b = i1 != i2; b = i2 == i1; b = i2 != i1; } template void interop_rand_access_constraints(Iterator1 const& i1, Iterator2 const& i2, boost::random_access_traversal_tag, boost::random_access_traversal_tag) { bool b; typename boost::detail::iterator_traits::difference_type n; b = i1 < i2; b = i1 <= i2; b = i1 > i2; b = i1 >= i2; n = i1 - i2; b = i2 < i1; b = i2 <= i1; b = i2 > i1; b = i2 >= i1; n = i2 - i1; } template void interop_rand_access_constraints(Iterator1 const& i1, Iterator2 const& i2, boost::single_pass_traversal_tag, boost::single_pass_traversal_tag) { } } // namespace detail template class InteroperableIteratorConcept { public: typedef typename boost::detail::pure_traversal_tag< typename boost::iterator_traversal< Iterator >::type >::type traversal_category; typedef typename boost::detail::pure_traversal_tag< typename boost::iterator_traversal< ConstIterator >::type >::type const_traversal_category; void constraints() { boost::function_requires< SinglePassIteratorConcept >(); boost::function_requires< SinglePassIteratorConcept >(); detail::interop_single_pass_constraints(i, ci); detail::interop_rand_access_constraints(i, ci, traversal_category(), const_traversal_category()); ci = i; } Iterator i; ConstIterator ci; }; } // namespace boost_concepts #endif // BOOST_ITERATOR_CONCEPTS_HPP