// Copyright David Abrahams 2003. Use, modification and distribution is // subject to 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 FACADE_ITERATOR_CATEGORY_DWA20031118_HPP # define FACADE_ITERATOR_CATEGORY_DWA20031118_HPP # include # include // used in iterator_tag inheritance logic # include # include # include # include # include # include # include # include # include # include # include // try to keep this last # ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY # include # endif // // iterator_category deduction for iterator_facade // // forward declaration namespace boost { struct use_default; } namespace boost { namespace detail { struct input_output_iterator_tag : std::input_iterator_tag { // Using inheritance for only input_iterator_tag helps to avoid // ambiguities when a stdlib implementation dispatches on a // function which is overloaded on both input_iterator_tag and // output_iterator_tag, as STLPort does, in its __valid_range // function. I claim it's better to avoid the ambiguity in these // cases. operator std::output_iterator_tag() const { return std::output_iterator_tag(); } }; // // True iff the user has explicitly disabled writability of this // iterator. Pass the iterator_facade's Value parameter and its // nested ::reference type. // template struct iterator_writability_disabled # ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY // Adding Thomas' logic? : mpl::or_< is_const , boost::detail::indirect_traits::is_reference_to_const , is_const > # else : is_const # endif {}; // // Convert an iterator_facade's traversal category, Value parameter, // and ::reference type to an appropriate old-style category. // // If writability has been disabled per the above metafunction, the // result will not be convertible to output_iterator_tag. // // Otherwise, if Traversal == single_pass_traversal_tag, the following // conditions will result in a tag that is convertible both to // input_iterator_tag and output_iterator_tag: // // 1. Reference is a reference to non-const // 2. Reference is not a reference and is convertible to Value // template struct iterator_facade_default_category : mpl::eval_if< mpl::and_< is_reference , is_convertible > , mpl::eval_if< is_convertible , mpl::identity , mpl::if_< is_convertible , std::bidirectional_iterator_tag , std::forward_iterator_tag > > , typename mpl::eval_if< mpl::and_< is_convertible // check for readability , is_convertible > , mpl::identity , mpl::identity > > { }; // True iff T is convertible to an old-style iterator category. template struct is_iterator_category : mpl::or_< is_convertible , is_convertible > { }; template struct is_iterator_traversal : is_convertible {}; // // A composite iterator_category tag convertible to Category (a pure // old-style category) and Traversal (a pure traversal tag). // Traversal must be a strict increase of the traversal power given by // Category. // template struct iterator_category_with_traversal : Category, Traversal { # if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) // Make sure this isn't used to build any categories where // convertibility to Traversal is redundant. Should just use the // Category element in that case. BOOST_MPL_ASSERT_NOT(( is_convertible< typename iterator_category_to_traversal::type , Traversal >)); BOOST_MPL_ASSERT((is_iterator_category)); BOOST_MPL_ASSERT_NOT((is_iterator_category)); BOOST_MPL_ASSERT_NOT((is_iterator_traversal)); # if !BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310)) BOOST_MPL_ASSERT((is_iterator_traversal)); # endif # endif }; // Computes an iterator_category tag whose traversal is Traversal and // which is appropriate for an iterator template struct facade_iterator_category_impl { # if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) BOOST_MPL_ASSERT_NOT((is_iterator_category)); # endif typedef typename iterator_facade_default_category< Traversal,ValueParam,Reference >::type category; typedef typename mpl::if_< is_same< Traversal , typename iterator_category_to_traversal::type > , category , iterator_category_with_traversal >::type type; }; // // Compute an iterator_category for iterator_facade // template struct facade_iterator_category : mpl::eval_if< is_iterator_category , mpl::identity // old-style categories are fine as-is , facade_iterator_category_impl > { }; }} // namespace boost::detail # include #endif // FACADE_ITERATOR_CATEGORY_DWA20031118_HPP