mirror of
https://github.com/boostorg/iterator.git
synced 2025-05-10 07:33:53 +00: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:
parent
b30cbf634c
commit
dec7d0f24c
@ -48,14 +48,14 @@ information is needed, call on `indirect_reference`.
|
|||||||
Both of these templates are essential to the correct functioning of
|
Both of these templates are essential to the correct functioning of
|
||||||
[link iterator.specialized.indirect `indirect_iterator`].
|
[link iterator.specialized.indirect `indirect_iterator`].
|
||||||
|
|
||||||
[h2 `minimum_category`]
|
[h2 `min_category`]
|
||||||
|
|
||||||
`minimum_category` takes two iterator categories or two iterator traversal tags
|
`min_category` takes one or more iterator categories or iterator traversal tags
|
||||||
and returns the one that is the weakest (i.e. least advanced). For example:
|
and returns the one that is the weakest (i.e. least advanced). For example:
|
||||||
|
|
||||||
static_assert(
|
static_assert(
|
||||||
is_same<
|
is_same<
|
||||||
minimum_category<
|
min_category<
|
||||||
std::forward_iterator_tag,
|
std::forward_iterator_tag,
|
||||||
std::random_access_iterator_tag
|
std::random_access_iterator_tag
|
||||||
>::type,
|
>::type,
|
||||||
|
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_
|
#ifndef BOOST_ITERATOR_MINIMUM_CATEGORY_HPP_INCLUDED_
|
||||||
#define BOOST_ITERATOR_MINIMUM_CATEGORY_HPP_INCLUDED_
|
#define BOOST_ITERATOR_MINIMUM_CATEGORY_HPP_INCLUDED_
|
||||||
|
|
||||||
#include <type_traits>
|
|
||||||
#include <boost/mpl/arg_fwd.hpp>
|
#include <boost/mpl/arg_fwd.hpp>
|
||||||
|
#include <boost/iterator/min_category.hpp>
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
namespace iterators {
|
namespace iterators {
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template <class T1, class T2, bool GreaterEqual, bool LessEqual>
|
// Deprecated metafunction for selecting minimum iterator category,
|
||||||
struct minimum_category_impl;
|
// use min_category instead.
|
||||||
|
|
||||||
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.
|
|
||||||
//
|
|
||||||
template< class T1 = mpl::arg<1>, class T2 = mpl::arg<2> >
|
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 <>
|
template <>
|
||||||
struct minimum_category< mpl::arg<1>, mpl::arg<2> >
|
struct minimum_category< mpl::arg<1>, mpl::arg<2> >
|
||||||
{
|
{
|
||||||
template <class T1, class T2>
|
template <class T1, class T2>
|
||||||
struct apply : minimum_category<T1, T2>
|
struct apply :
|
||||||
|
public min_category<T1, T2>
|
||||||
{};
|
{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -61,6 +61,9 @@ test-suite iterator
|
|||||||
|
|
||||||
[ run generator_iterator_test.cpp ]
|
[ run generator_iterator_test.cpp ]
|
||||||
|
|
||||||
|
[ run min_category.cpp ]
|
||||||
|
[ compile-fail min_category_compile_fail1.cpp ]
|
||||||
|
[ compile-fail min_category_compile_fail2.cpp ]
|
||||||
[ run minimum_category.cpp ]
|
[ run minimum_category.cpp ]
|
||||||
[ compile-fail minimum_category_compile_fail.cpp ]
|
[ compile-fail minimum_category_compile_fail.cpp ]
|
||||||
|
|
||||||
|
33
test/min_category.cpp
Normal file
33
test/min_category.cpp
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// 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)
|
||||||
|
|
||||||
|
#include <boost/iterator/min_category.hpp>
|
||||||
|
#include <boost/core/lightweight_test_trait.hpp>
|
||||||
|
#include <iterator>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
using std::is_same;
|
||||||
|
using boost::iterators::min_category;
|
||||||
|
using boost::iterators::min_category_t;
|
||||||
|
|
||||||
|
int main(int, char*[])
|
||||||
|
{
|
||||||
|
BOOST_TEST_TRAIT_TRUE((is_same<min_category<std::forward_iterator_tag>::type, std::forward_iterator_tag>));
|
||||||
|
BOOST_TEST_TRAIT_TRUE((is_same<min_category<std::forward_iterator_tag, std::random_access_iterator_tag>::type, std::forward_iterator_tag>));
|
||||||
|
BOOST_TEST_TRAIT_TRUE((is_same<min_category<std::random_access_iterator_tag, std::forward_iterator_tag>::type, std::forward_iterator_tag>));
|
||||||
|
BOOST_TEST_TRAIT_TRUE((is_same<min_category<std::random_access_iterator_tag, std::random_access_iterator_tag>::type, std::random_access_iterator_tag>));
|
||||||
|
BOOST_TEST_TRAIT_TRUE((is_same<min_category<std::forward_iterator_tag, std::bidirectional_iterator_tag, std::random_access_iterator_tag>::type, std::forward_iterator_tag>));
|
||||||
|
BOOST_TEST_TRAIT_TRUE((is_same<min_category<std::random_access_iterator_tag, std::bidirectional_iterator_tag, std::forward_iterator_tag>::type, std::forward_iterator_tag>));
|
||||||
|
|
||||||
|
BOOST_TEST_TRAIT_TRUE((is_same<min_category_t<std::forward_iterator_tag>, std::forward_iterator_tag>));
|
||||||
|
BOOST_TEST_TRAIT_TRUE((is_same<min_category_t<std::forward_iterator_tag, std::random_access_iterator_tag>, std::forward_iterator_tag>));
|
||||||
|
BOOST_TEST_TRAIT_TRUE((is_same<min_category_t<std::random_access_iterator_tag, std::forward_iterator_tag>, std::forward_iterator_tag>));
|
||||||
|
BOOST_TEST_TRAIT_TRUE((is_same<min_category_t<std::random_access_iterator_tag, std::random_access_iterator_tag>, std::random_access_iterator_tag>));
|
||||||
|
BOOST_TEST_TRAIT_TRUE((is_same<min_category_t<std::forward_iterator_tag, std::bidirectional_iterator_tag, std::random_access_iterator_tag>, std::forward_iterator_tag>));
|
||||||
|
BOOST_TEST_TRAIT_TRUE((is_same<min_category_t<std::random_access_iterator_tag, std::bidirectional_iterator_tag, std::forward_iterator_tag>, std::forward_iterator_tag>));
|
||||||
|
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
19
test/min_category_compile_fail1.cpp
Normal file
19
test/min_category_compile_fail1.cpp
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// Copyright Andrey Semashev 2025.
|
||||||
|
//
|
||||||
|
// 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)
|
||||||
|
|
||||||
|
#include <boost/iterator/min_category.hpp>
|
||||||
|
|
||||||
|
using boost::iterators::min_category;
|
||||||
|
|
||||||
|
struct A {};
|
||||||
|
struct B {};
|
||||||
|
|
||||||
|
int main(int, char*[])
|
||||||
|
{
|
||||||
|
min_category<A, B>::type cat;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
16
test/min_category_compile_fail2.cpp
Normal file
16
test/min_category_compile_fail2.cpp
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// Copyright Andrey Semashev 2025.
|
||||||
|
//
|
||||||
|
// 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)
|
||||||
|
|
||||||
|
#include <boost/iterator/min_category.hpp>
|
||||||
|
|
||||||
|
using boost::iterators::min_category;
|
||||||
|
|
||||||
|
int main(int, char*[])
|
||||||
|
{
|
||||||
|
min_category<>::type cat;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -26,6 +26,7 @@
|
|||||||
#include <boost/iterator/iterator_concepts.hpp>
|
#include <boost/iterator/iterator_concepts.hpp>
|
||||||
#include <boost/iterator/iterator_facade.hpp>
|
#include <boost/iterator/iterator_facade.hpp>
|
||||||
#include <boost/iterator/iterator_traits.hpp>
|
#include <boost/iterator/iterator_traits.hpp>
|
||||||
|
#include <boost/iterator/min_category.hpp>
|
||||||
#include <boost/iterator/minimum_category.hpp>
|
#include <boost/iterator/minimum_category.hpp>
|
||||||
#include <boost/iterator/new_iterator_tests.hpp>
|
#include <boost/iterator/new_iterator_tests.hpp>
|
||||||
#include <boost/iterator/permutation_iterator.hpp>
|
#include <boost/iterator/permutation_iterator.hpp>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user