// (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_CATEGORIES_HPP # define BOOST_ITERATOR_CATEGORIES_HPP # include # include # include # include # include # include # include # include # include # include namespace boost { namespace iterators { // // Traversal Categories // struct no_traversal_tag {}; struct incrementable_traversal_tag : no_traversal_tag { // incrementable_traversal_tag() {} // incrementable_traversal_tag(std::output_iterator_tag const&) {}; }; struct single_pass_traversal_tag : incrementable_traversal_tag { // single_pass_traversal_tag() {} // single_pass_traversal_tag(std::input_iterator_tag const&) {}; }; struct forward_traversal_tag : single_pass_traversal_tag { // forward_traversal_tag() {} // forward_traversal_tag(std::forward_iterator_tag const&) {}; }; struct bidirectional_traversal_tag : forward_traversal_tag { // bidirectional_traversal_tag() {}; // bidirectional_traversal_tag(std::bidirectional_iterator_tag const&) {}; }; struct random_access_traversal_tag : bidirectional_traversal_tag { // random_access_traversal_tag() {}; // random_access_traversal_tag(std::random_access_iterator_tag const&) {}; }; namespace detail { // // Convert a "strictly old-style" iterator category to a traversal // tag. This is broken out into a separate metafunction to reduce // the cost of instantiating iterator_category_to_traversal, below, // for new-style types. // template struct old_category_to_traversal : mpl::eval_if< is_convertible , mpl::identity , mpl::eval_if< is_convertible , mpl::identity , mpl::eval_if< is_convertible , mpl::identity , mpl::eval_if< is_convertible , mpl::identity , mpl::eval_if< is_convertible , mpl::identity , void > > > > > {}; } // namespace detail // // Convert an iterator category into a traversal tag // template struct iterator_category_to_traversal : mpl::eval_if< // if already convertible to a traversal tag, we're done. is_convertible , mpl::identity , boost::iterators::detail::old_category_to_traversal > {}; // Trait to get an iterator's traversal category template struct iterator_traversal : iterator_category_to_traversal< typename boost::detail::iterator_traits::iterator_category > {}; # ifdef BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT // Hack because BOOST_MPL_AUX_LAMBDA_SUPPORT doesn't seem to work // out well. Instantiating the nested apply template also // requires instantiating iterator_traits on the // placeholder. Instead we just specialize it as a metafunction // class. template <> struct iterator_traversal { template struct apply : iterator_traversal {}; }; template <> struct iterator_traversal : iterator_traversal {}; # endif // // Convert an iterator traversal to one of the traversal tags. // template struct pure_traversal_tag : mpl::eval_if< is_convertible , mpl::identity , mpl::eval_if< is_convertible , mpl::identity , mpl::eval_if< is_convertible , mpl::identity , mpl::eval_if< is_convertible , mpl::identity , mpl::eval_if< is_convertible , mpl::identity , void > > > > > { }; // This import is needed for backward compatibility with Boost.Range: // boost/range/detail/demote_iterator_traversal_tag.hpp // It should be removed when that header is fixed. namespace detail { using iterators::pure_traversal_tag; } // namespace detail // // Trait to retrieve one of the iterator traversal tags from the iterator category or traversal. // template struct pure_iterator_traversal : pure_traversal_tag::type> {}; # ifdef BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT template <> struct pure_iterator_traversal { template struct apply : pure_iterator_traversal {}; }; template <> struct pure_iterator_traversal : pure_iterator_traversal {}; # endif } // namespace iterators using iterators::no_traversal_tag; using iterators::incrementable_traversal_tag; using iterators::single_pass_traversal_tag; using iterators::forward_traversal_tag; using iterators::bidirectional_traversal_tag; using iterators::random_access_traversal_tag; using iterators::iterator_category_to_traversal; using iterators::iterator_traversal; // This import is needed for backward compatibility with Boost.Range: // boost/range/detail/demote_iterator_traversal_tag.hpp // It should be removed when that header is fixed. namespace detail { using iterators::pure_traversal_tag; } // namespace detail } // namespace boost #include #endif // BOOST_ITERATOR_CATEGORIES_HPP