diff --git a/include/boost/iterator/detail/facade_iterator_category.hpp b/include/boost/iterator/detail/facade_iterator_category.hpp index f3f5848..2d808da 100644 --- a/include/boost/iterator/detail/facade_iterator_category.hpp +++ b/include/boost/iterator/detail/facade_iterator_category.hpp @@ -2,24 +2,17 @@ // 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 +#define FACADE_ITERATOR_CATEGORY_DWA20031118_HPP -# 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 +#include +#include +#include +#include // try to keep this last // // iterator_category deduction for iterator_facade @@ -27,13 +20,10 @@ namespace boost { namespace iterators { - -using boost::use_default; - namespace detail { -struct input_output_iterator_tag - : std::input_iterator_tag +struct input_output_iterator_tag : + public std::input_iterator_tag { // Using inheritance for only input_iterator_tag helps to avoid // ambiguities when a stdlib implementation dispatches on a @@ -47,21 +37,35 @@ struct input_output_iterator_tag } }; +#ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY + +template< typename T > +struct is_const_lvalue_reference : + public std::false_type +{}; + +template< typename T > +struct is_const_lvalue_reference< T const& > : + public std::true_type +{}; + +#endif // BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY + // // 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 +template< typename ValueParam, typename Reference > +struct iterator_writability_disabled : # ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY // Adding Thomas' logic? - : disjunction< - std::is_const - , std::integral_constant::value> - , std::is_const + public disjunction< + is_const_lvalue_reference, + std::is_const, + std::is_const > # else - : std::is_const + public std::is_const # endif {}; @@ -74,69 +78,68 @@ struct iterator_writability_disabled // to output_iterator_tag. // // Change at: https://svn.boost.org/trac/boost/changeset/21683 -template +template< typename Traversal, typename ValueParam, typename Reference > struct iterator_facade_default_category - : mpl::eval_if< - detail::conjunction< - std::is_reference - , std::is_convertible - > - , mpl::eval_if< - std::is_convertible - , mpl::identity - , std::conditional< - std::is_convertible::value - , std::bidirectional_iterator_tag - , std::forward_iterator_tag - > - > - , mpl::eval_if< - detail::conjunction< - std::is_convertible - - // check for readability - , std::is_convertible - > - , mpl::identity - , mpl::identity - > - > { + using type = typename mp11::mp_if< + detail::conjunction< + std::is_reference, + std::is_convertible + >, + mp11::mp_defer< + mp11::mp_cond, + std::is_convertible, std::random_access_iterator_tag, + std::is_convertible, std::bidirectional_iterator_tag, + std::true_type, std::forward_iterator_tag + >, + mp11::mp_defer< + mp11::mp_if, + detail::conjunction< + std::is_convertible, + + // check for readability + std::is_convertible + >, + std::input_iterator_tag, + Traversal + > + >::type; }; +template< typename Traversal, typename ValueParam, typename Reference > +using iterator_facade_default_category_t = typename iterator_facade_default_category::type; + // True iff T is convertible to an old-style iterator category. -template -struct is_iterator_category - : disjunction< - std::is_convertible - , std::is_convertible +template< typename T > +struct is_iterator_category : + public disjunction< + std::is_convertible, + std::is_convertible > -{ -}; - -template -struct is_iterator_traversal - : std::is_convertible {}; +template< typename T > +struct is_iterator_traversal : + public std::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 +template< typename Category, typename Traversal > +struct iterator_category_with_traversal : + public Category, + public Traversal { // 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. static_assert( - !std::is_convertible< - typename iterator_category_to_traversal::type - , Traversal - >::value, + !std::is_convertible, Traversal>::value, "Category transformed to corresponding traversal must be convertible to Traversal." ); @@ -148,40 +151,41 @@ struct iterator_category_with_traversal // Computes an iterator_category tag whose traversal is Traversal and // which is appropriate for an iterator -template +template< typename Traversal, typename ValueParam, typename Reference > struct facade_iterator_category_impl { static_assert(!is_iterator_category::value, "Traversal must not be an STL iterator category."); - typedef typename iterator_facade_default_category< - Traversal,ValueParam,Reference - >::type category; + using category = iterator_facade_default_category_t; - typedef typename std::conditional< + using type = typename std::conditional< std::is_same< - Traversal - , typename iterator_category_to_traversal::type - >::value - , category - , iterator_category_with_traversal - >::type type; + Traversal, + typename iterator_category_to_traversal::type + >::value, + category, + iterator_category_with_traversal + >::type; }; +template< typename Traversal, typename ValueParam, typename Reference > +using facade_iterator_category_impl_t = typename facade_iterator_category_impl::type; + // // Compute an iterator_category for iterator_facade // -template +template< typename CategoryOrTraversal, typename ValueParam, typename Reference > struct facade_iterator_category - : mpl::eval_if< - is_iterator_category - , mpl::identity // old-style categories are fine as-is - , facade_iterator_category_impl - > { + using type = mp11::mp_eval_if< + is_iterator_category, + CategoryOrTraversal, // old-style categories are fine as-is + facade_iterator_category_impl_t, CategoryOrTraversal, ValueParam, Reference + >; }; }}} // namespace boost::iterators::detail -# include +#include #endif // FACADE_ITERATOR_CATEGORY_DWA20031118_HPP