mirror of
https://github.com/boostorg/iterator.git
synced 2025-11-11 21:59:54 +01:00
Extracted min_category as a variadic metafunction.
The new min_category is similar to minimum_category but accepts variable number of iterator categories on input instead of just two, and also does not depend on Boost.MPL for lambda placeholders. The existing minimum_category trait has been reimplemented in terms of min_category and deprecated. We don't yet emit deprecation warnings as there is still code that uses the old trait which we first need to update. Eventually, minimum_category will emit warnings and will be removed.
This commit is contained in:
83
include/boost/iterator/min_category.hpp
Normal file
83
include/boost/iterator/min_category.hpp
Normal file
@@ -0,0 +1,83 @@
|
||||
// Copyright Andrey Semashev 2025.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_ITERATOR_MIN_CATEGORY_HPP_INCLUDED_
|
||||
#define BOOST_ITERATOR_MIN_CATEGORY_HPP_INCLUDED_
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
namespace detail {
|
||||
|
||||
template<
|
||||
typename T1,
|
||||
typename T2,
|
||||
bool GreaterEqual = std::is_convertible< T1, T2 >::value,
|
||||
bool LessEqual = std::is_convertible< T2, T1 >::value
|
||||
>
|
||||
struct min_category_impl
|
||||
{
|
||||
static_assert(GreaterEqual || LessEqual, "Iterator category types must be related through convertibility.");
|
||||
};
|
||||
|
||||
template< typename T1, typename T2 >
|
||||
struct min_category_impl< T1, T2, true, false >
|
||||
{
|
||||
using type = T2;
|
||||
};
|
||||
|
||||
template< typename T1, typename T2 >
|
||||
struct min_category_impl< T1, T2, false, true >
|
||||
{
|
||||
using type = T1;
|
||||
};
|
||||
|
||||
template< typename T1, typename T2 >
|
||||
struct min_category_impl< T1, T2, true, true >
|
||||
{
|
||||
static_assert(std::is_same< T1, T2 >::value, "Iterator category types must be the same when they are equivalent.");
|
||||
using type = T1;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
//
|
||||
// Returns the minimum iterator category type in the list
|
||||
// or fails to compile if any of the categories are unrelated.
|
||||
//
|
||||
template< typename... Categories >
|
||||
struct min_category;
|
||||
|
||||
template< typename T >
|
||||
struct min_category< T >
|
||||
{
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template< typename T1, typename T2, typename... Tail >
|
||||
struct min_category< T1, T2, Tail... >
|
||||
{
|
||||
using type = typename min_category<
|
||||
typename iterators::detail::min_category_impl< T1, T2 >::type,
|
||||
Tail...
|
||||
>::type;
|
||||
};
|
||||
|
||||
// Shortcut to slightly optimize compilation speed
|
||||
template< typename T1, typename T2 >
|
||||
struct min_category< T1, T2 >
|
||||
{
|
||||
using type = typename iterators::detail::min_category_impl< T1, T2 >::type;
|
||||
};
|
||||
|
||||
template< typename... Categories >
|
||||
using min_category_t = typename min_category< Categories... >::type;
|
||||
|
||||
} // namespace iterators
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_ITERATOR_MIN_CATEGORY_HPP_INCLUDED_
|
||||
@@ -4,61 +4,26 @@
|
||||
#ifndef BOOST_ITERATOR_MINIMUM_CATEGORY_HPP_INCLUDED_
|
||||
#define BOOST_ITERATOR_MINIMUM_CATEGORY_HPP_INCLUDED_
|
||||
|
||||
#include <type_traits>
|
||||
#include <boost/mpl/arg_fwd.hpp>
|
||||
#include <boost/iterator/min_category.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
namespace detail {
|
||||
|
||||
template <class T1, class T2, bool GreaterEqual, bool LessEqual>
|
||||
struct minimum_category_impl;
|
||||
|
||||
template <class T1, class T2>
|
||||
struct minimum_category_impl<T1, T2, true, false>
|
||||
{
|
||||
using type = T2;
|
||||
};
|
||||
|
||||
template <class T1, class T2>
|
||||
struct minimum_category_impl<T1, T2, false, true>
|
||||
{
|
||||
using type = T1;
|
||||
};
|
||||
|
||||
template <class T1, class T2>
|
||||
struct minimum_category_impl<T1, T2, true, true>
|
||||
{
|
||||
static_assert(std::is_same<T1, T2>::value, "Iterator category types must be the same when they are equivalent.");
|
||||
using type = T1;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
//
|
||||
// Returns the minimum category type or fails to compile
|
||||
// if T1 and T2 are unrelated.
|
||||
//
|
||||
// Deprecated metafunction for selecting minimum iterator category,
|
||||
// use min_category instead.
|
||||
template< class T1 = mpl::arg<1>, class T2 = mpl::arg<2> >
|
||||
struct minimum_category
|
||||
struct minimum_category :
|
||||
public min_category<T1, T2>
|
||||
{
|
||||
static_assert(
|
||||
std::is_convertible<T1, T2>::value || std::is_convertible<T2, T1>::value,
|
||||
"Iterator category types must be related through convertibility.");
|
||||
|
||||
using type = typename boost::iterators::detail::minimum_category_impl<
|
||||
T1,
|
||||
T2,
|
||||
std::is_convertible<T1, T2>::value,
|
||||
std::is_convertible<T2, T1>::value
|
||||
>::type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct minimum_category< mpl::arg<1>, mpl::arg<2> >
|
||||
{
|
||||
template <class T1, class T2>
|
||||
struct apply : minimum_category<T1, T2>
|
||||
struct apply :
|
||||
public min_category<T1, T2>
|
||||
{};
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user