diff --git a/include/boost/iterator/iterator_categories.hpp b/include/boost/iterator/iterator_categories.hpp index 34c02ef..846575e 100644 --- a/include/boost/iterator/iterator_categories.hpp +++ b/include/boost/iterator/iterator_categories.hpp @@ -4,15 +4,13 @@ // http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_ITERATOR_CATEGORIES_HPP -# define BOOST_ITERATOR_CATEGORIES_HPP +#define BOOST_ITERATOR_CATEGORIES_HPP -# include -# include -# include -# include - -#include #include +#include + +#include +#include namespace boost { namespace iterators { @@ -20,168 +18,78 @@ 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< - std::is_convertible - , mpl::identity - , mpl::eval_if< - std::is_convertible - , mpl::identity - , mpl::eval_if< - std::is_convertible - , mpl::identity - , mpl::eval_if< - std::is_convertible - , mpl::identity - , mpl::eval_if< - std::is_convertible - , mpl::identity - , void - > - > - > - > - > - {}; - -} // namespace detail +struct incrementable_traversal_tag : public no_traversal_tag {}; +struct single_pass_traversal_tag : public incrementable_traversal_tag {}; +struct forward_traversal_tag : public single_pass_traversal_tag {}; +struct bidirectional_traversal_tag : public forward_traversal_tag {}; +struct random_access_traversal_tag : public bidirectional_traversal_tag {}; // // Convert an iterator category into a traversal tag // -template +template< typename Cat > +using iterator_category_to_traversal_t = mp11::mp_cond< + // if already convertible to a traversal tag, we're done. + std::is_convertible< Cat, incrementable_traversal_tag >, Cat, + std::is_convertible< Cat, std::random_access_iterator_tag >, random_access_traversal_tag, + std::is_convertible< Cat, std::bidirectional_iterator_tag >, bidirectional_traversal_tag, + std::is_convertible< Cat, std::forward_iterator_tag >, forward_traversal_tag, + std::is_convertible< Cat, std::input_iterator_tag >, single_pass_traversal_tag, + std::is_convertible< Cat, std::output_iterator_tag >, incrementable_traversal_tag, + std::true_type, void +>; + +template< typename Cat > struct iterator_category_to_traversal - : mpl::eval_if< // if already convertible to a traversal tag, we're done. - std::is_convertible - , mpl::identity - , boost::iterators::detail::old_category_to_traversal - > -{}; +{ + using type = iterator_category_to_traversal_t< Cat >; +}; // Trait to get an iterator's traversal category -template -struct iterator_traversal - : iterator_category_to_traversal< - typename std::iterator_traits::iterator_category - > -{}; +template< typename Iterator > +using iterator_traversal_t = iterator_category_to_traversal_t< + typename std::iterator_traits< Iterator >::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< typename Iterator = mpl::arg< 1 > > +struct iterator_traversal { - template - struct apply : iterator_traversal - {}; + using type = iterator_traversal_t< Iterator >; }; -template <> -struct iterator_traversal - : iterator_traversal -{}; -# endif // // Convert an iterator traversal to one of the traversal tags. // -template +template< typename Traversal > +using pure_traversal_tag_t = mp11::mp_cond< + std::is_convertible< Traversal, random_access_traversal_tag >, random_access_traversal_tag, + std::is_convertible< Traversal, bidirectional_traversal_tag >, bidirectional_traversal_tag, + std::is_convertible< Traversal, forward_traversal_tag >, forward_traversal_tag, + std::is_convertible< Traversal, single_pass_traversal_tag >, single_pass_traversal_tag, + std::is_convertible< Traversal, incrementable_traversal_tag >, incrementable_traversal_tag, + std::true_type, void +>; + +template< typename Traversal > struct pure_traversal_tag - : mpl::eval_if< - std::is_convertible - , mpl::identity - , mpl::eval_if< - std::is_convertible - , mpl::identity - , mpl::eval_if< - std::is_convertible - , mpl::identity - , mpl::eval_if< - std::is_convertible - , mpl::identity - , mpl::eval_if< - std::is_convertible - , mpl::identity - , void - > - > - > - > - > { + using type = pure_traversal_tag_t< Traversal >; }; // // Trait to retrieve one of the iterator traversal tags from the iterator category or traversal. // -template -struct pure_iterator_traversal - : pure_traversal_tag::type> -{}; +template< typename Iterator > +using pure_iterator_traversal_t = pure_traversal_tag_t< + iterator_traversal_t< Iterator > +>; -# ifdef BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT -template <> -struct pure_iterator_traversal +template< typename Iterator = mpl::arg< 1 > > +struct pure_iterator_traversal { - template - struct apply : pure_iterator_traversal - {}; + using type = pure_iterator_traversal_t< Iterator >; }; -template <> -struct pure_iterator_traversal - : pure_iterator_traversal -{}; -# endif } // namespace iterators @@ -194,13 +102,6 @@ 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 #endif // BOOST_ITERATOR_CATEGORIES_HPP