mirror of
https://github.com/boostorg/iterator.git
synced 2025-05-09 23:23:54 +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
|
||||
[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:
|
||||
|
||||
static_assert(
|
||||
is_same<
|
||||
minimum_category<
|
||||
min_category<
|
||||
std::forward_iterator_tag,
|
||||
std::random_access_iterator_tag
|
||||
>::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_
|
||||
#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>
|
||||
{};
|
||||
};
|
||||
|
||||
|
@ -61,6 +61,9 @@ test-suite iterator
|
||||
|
||||
[ 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 ]
|
||||
[ 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_facade.hpp>
|
||||
#include <boost/iterator/iterator_traits.hpp>
|
||||
#include <boost/iterator/min_category.hpp>
|
||||
#include <boost/iterator/minimum_category.hpp>
|
||||
#include <boost/iterator/new_iterator_tests.hpp>
|
||||
#include <boost/iterator/permutation_iterator.hpp>
|
||||
|
Loading…
x
Reference in New Issue
Block a user