Removed MPL usage from facade_iterator_category.hpp.

This commit is contained in:
Andrey Semashev 2025-01-29 02:28:32 +03:00
parent 5f713e9b14
commit d8ce9ddfc7

View File

@ -4,36 +4,26 @@
#ifndef FACADE_ITERATOR_CATEGORY_DWA20031118_HPP #ifndef FACADE_ITERATOR_CATEGORY_DWA20031118_HPP
#define FACADE_ITERATOR_CATEGORY_DWA20031118_HPP #define FACADE_ITERATOR_CATEGORY_DWA20031118_HPP
# include <boost/core/use_default.hpp> #include <iterator>
# include <boost/iterator/iterator_categories.hpp>
# include <boost/mpl/eval_if.hpp>
# include <boost/mpl/identity.hpp>
#include <type_traits> #include <type_traits>
#include <boost/mp11/utility.hpp>
#include <boost/iterator/iterator_categories.hpp>
#include <boost/iterator/detail/type_traits/conjunction.hpp> #include <boost/iterator/detail/type_traits/conjunction.hpp>
#include <boost/iterator/detail/type_traits/disjunction.hpp> #include <boost/iterator/detail/type_traits/disjunction.hpp>
#include <boost/iterator/detail/config_def.hpp> // try to keep this last #include <boost/iterator/detail/config_def.hpp> // try to keep this last
# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
# include <boost/detail/indirect_traits.hpp>
# endif
// //
// iterator_category deduction for iterator_facade // iterator_category deduction for iterator_facade
// //
namespace boost { namespace boost {
namespace iterators { namespace iterators {
using boost::use_default;
namespace detail { namespace detail {
struct input_output_iterator_tag struct input_output_iterator_tag :
: std::input_iterator_tag public std::input_iterator_tag
{ {
// Using inheritance for only input_iterator_tag helps to avoid // Using inheritance for only input_iterator_tag helps to avoid
// ambiguities when a stdlib implementation dispatches on a // 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 // True iff the user has explicitly disabled writability of this
// iterator. Pass the iterator_facade's Value parameter and its // iterator. Pass the iterator_facade's Value parameter and its
// nested ::reference type. // nested ::reference type.
// //
template <class ValueParam, class Reference> template< typename ValueParam, typename Reference >
struct iterator_writability_disabled struct iterator_writability_disabled :
# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY // Adding Thomas' logic? # ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY // Adding Thomas' logic?
: disjunction< public disjunction<
std::is_const<Reference> is_const_lvalue_reference<Reference>,
, std::integral_constant<bool, boost::detail::indirect_traits::is_reference_to_const<Reference>::value> std::is_const<Reference>,
, std::is_const<ValueParam> std::is_const<ValueParam>
> >
# else # else
: std::is_const<ValueParam> public std::is_const<ValueParam>
# endif # endif
{}; {};
@ -74,69 +78,68 @@ struct iterator_writability_disabled
// to output_iterator_tag. // to output_iterator_tag.
// //
// Change at: https://svn.boost.org/trac/boost/changeset/21683 // Change at: https://svn.boost.org/trac/boost/changeset/21683
template <class Traversal, class ValueParam, class Reference> template< typename Traversal, typename ValueParam, typename Reference >
struct iterator_facade_default_category struct iterator_facade_default_category
: mpl::eval_if< {
using type = typename mp11::mp_if<
detail::conjunction< detail::conjunction<
std::is_reference<Reference> std::is_reference<Reference>,
, std::is_convertible<Traversal,forward_traversal_tag> std::is_convertible<Traversal, forward_traversal_tag>
> >,
, mpl::eval_if< mp11::mp_defer<
std::is_convertible<Traversal,random_access_traversal_tag> mp11::mp_cond,
, mpl::identity<std::random_access_iterator_tag> std::is_convertible<Traversal, random_access_traversal_tag>, std::random_access_iterator_tag,
, std::conditional< std::is_convertible<Traversal, bidirectional_traversal_tag>, std::bidirectional_iterator_tag,
std::is_convertible<Traversal,bidirectional_traversal_tag>::value std::true_type, std::forward_iterator_tag
, std::bidirectional_iterator_tag >,
, std::forward_iterator_tag mp11::mp_defer<
> mp11::mp_if,
>
, mpl::eval_if<
detail::conjunction< detail::conjunction<
std::is_convertible<Traversal, single_pass_traversal_tag> std::is_convertible<Traversal, single_pass_traversal_tag>,
// check for readability // check for readability
, std::is_convertible<Reference, ValueParam> std::is_convertible<Reference, ValueParam>
>,
std::input_iterator_tag,
Traversal
> >
, mpl::identity<std::input_iterator_tag> >::type;
, mpl::identity<Traversal>
>
>
{
}; };
template< typename Traversal, typename ValueParam, typename Reference >
using iterator_facade_default_category_t = typename iterator_facade_default_category<Traversal, ValueParam, Reference>::type;
// True iff T is convertible to an old-style iterator category. // True iff T is convertible to an old-style iterator category.
template <class T> template< typename T >
struct is_iterator_category struct is_iterator_category :
: disjunction< public disjunction<
std::is_convertible<T,std::input_iterator_tag> std::is_convertible<T, std::input_iterator_tag>,
, std::is_convertible<T,std::output_iterator_tag> std::is_convertible<T, std::output_iterator_tag>
> >
{
};
template <class T>
struct is_iterator_traversal
: std::is_convertible<T,incrementable_traversal_tag>
{}; {};
template< typename T >
struct is_iterator_traversal :
public std::is_convertible<T, incrementable_traversal_tag>
{};
// //
// A composite iterator_category tag convertible to Category (a pure // A composite iterator_category tag convertible to Category (a pure
// old-style category) and Traversal (a pure traversal tag). // old-style category) and Traversal (a pure traversal tag).
// Traversal must be a strict increase of the traversal power given by // Traversal must be a strict increase of the traversal power given by
// Category. // Category.
// //
template <class Category, class Traversal> template< typename Category, typename Traversal >
struct iterator_category_with_traversal struct iterator_category_with_traversal :
: Category, Traversal public Category,
public Traversal
{ {
// Make sure this isn't used to build any categories where // Make sure this isn't used to build any categories where
// convertibility to Traversal is redundant. Should just use the // convertibility to Traversal is redundant. Should just use the
// Category element in that case. // Category element in that case.
static_assert( static_assert(
!std::is_convertible< !std::is_convertible<iterator_category_to_traversal_t<Category>, Traversal>::value,
typename iterator_category_to_traversal<Category>::type
, Traversal
>::value,
"Category transformed to corresponding traversal must be convertible to Traversal." "Category transformed to corresponding traversal must be convertible to Traversal."
); );
@ -148,36 +151,37 @@ struct iterator_category_with_traversal
// Computes an iterator_category tag whose traversal is Traversal and // Computes an iterator_category tag whose traversal is Traversal and
// which is appropriate for an iterator // which is appropriate for an iterator
template <class Traversal, class ValueParam, class Reference> template< typename Traversal, typename ValueParam, typename Reference >
struct facade_iterator_category_impl struct facade_iterator_category_impl
{ {
static_assert(!is_iterator_category<Traversal>::value, "Traversal must not be an STL iterator category."); static_assert(!is_iterator_category<Traversal>::value, "Traversal must not be an STL iterator category.");
typedef typename iterator_facade_default_category< using category = iterator_facade_default_category_t<Traversal, ValueParam, Reference>;
Traversal,ValueParam,Reference
>::type category;
typedef typename std::conditional< using type = typename std::conditional<
std::is_same< std::is_same<
Traversal Traversal,
, typename iterator_category_to_traversal<category>::type typename iterator_category_to_traversal<category>::type
>::value >::value,
, category category,
, iterator_category_with_traversal<category,Traversal> iterator_category_with_traversal<category, Traversal>
>::type type; >::type;
}; };
template< typename Traversal, typename ValueParam, typename Reference >
using facade_iterator_category_impl_t = typename facade_iterator_category_impl<Traversal, ValueParam, Reference>::type;
// //
// Compute an iterator_category for iterator_facade // Compute an iterator_category for iterator_facade
// //
template <class CategoryOrTraversal, class ValueParam, class Reference> template< typename CategoryOrTraversal, typename ValueParam, typename Reference >
struct facade_iterator_category struct facade_iterator_category
: mpl::eval_if<
is_iterator_category<CategoryOrTraversal>
, mpl::identity<CategoryOrTraversal> // old-style categories are fine as-is
, facade_iterator_category_impl<CategoryOrTraversal,ValueParam,Reference>
>
{ {
using type = mp11::mp_eval_if<
is_iterator_category<CategoryOrTraversal>,
CategoryOrTraversal, // old-style categories are fine as-is
facade_iterator_category_impl_t, CategoryOrTraversal, ValueParam, Reference
>;
}; };
}}} // namespace boost::iterators::detail }}} // namespace boost::iterators::detail