-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refs #121 Инструменты для приведения разнотипных диапазонов к общему …
…типу
- Loading branch information
Showing
9 changed files
with
257 additions
and
0 deletions.
There are no files selected for viewing
68 changes: 68 additions & 0 deletions
68
include/burst/iterator/detail/uniform_range_tuple_please.hpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
#ifndef BURST_ITERATOR_DETAIL_UNIFORM_RANGE_TUPLE_PLEASE_HPP | ||
#define BURST_ITERATOR_DETAIL_UNIFORM_RANGE_TUPLE_PLEASE_HPP | ||
|
||
#include <burst/range/to_any_range.hpp> | ||
#include <burst/tuple/by_all.hpp> | ||
#include <burst/type_traits/are_same.hpp> | ||
#include <burst/type_traits/minimum_category.hpp> | ||
#include <burst/type_traits/range_category.hpp> | ||
|
||
#include <boost/iterator/iterator_categories.hpp> | ||
|
||
#include <tuple> | ||
#include <type_traits> | ||
|
||
namespace burst | ||
{ | ||
namespace detail | ||
{ | ||
/*! | ||
\brief | ||
Перегрузка для случая, когда все переданные диапазоны имеют один и тот же тип | ||
\see uniform_range_tuple_please | ||
*/ | ||
template <typename... Ranges> | ||
auto uniform_range_tuple_please_impl (std::tuple<Ranges &...> ranges, std::true_type) | ||
{ | ||
static_assert(are_same_v<Ranges...>, ""); | ||
return ranges; | ||
} | ||
|
||
/*! | ||
\brief | ||
Перегрузка для случая, когда переданные диапазоны разнотипны | ||
\see uniform_range_tuple_please | ||
*/ | ||
template <typename... Ranges> | ||
auto uniform_range_tuple_please_impl (std::tuple<Ranges &...> ranges, std::false_type) | ||
{ | ||
static_assert(not are_same_v<Ranges...>, ""); | ||
using iterator_category = minimum_category_t<range_category_t<Ranges>...>; | ||
using boost_traversal = | ||
typename boost::iterator_category_to_traversal<iterator_category>::type; | ||
return by_all(to_any_range<boost_traversal>, ranges); | ||
} | ||
|
||
/*! | ||
\brief | ||
Сделать из кортежа возможно разнотипных диапазонов кортеж заведомо однотипных | ||
диапазонов | ||
\returns | ||
Если диапазоны изначально однотипны, то возвращается изначальный кортеж, в | ||
противном случае создаётся кортеж, в котором каждый из диапазонов приведён к | ||
boost::any_range. | ||
\see are_same | ||
*/ | ||
template <typename... Ranges> | ||
auto uniform_range_tuple_please (std::tuple<Ranges &...> ranges) | ||
{ | ||
return uniform_range_tuple_please_impl(ranges, are_same<Ranges...>{}); | ||
} | ||
} | ||
} | ||
|
||
#endif // BURST_ITERATOR_DETAIL_UNIFORM_RANGE_TUPLE_PLEASE_HPP |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
#ifndef BURST_RANGE_TO_ANY_RANGE_HPP | ||
#define BURST_RANGE_TO_ANY_RANGE_HPP | ||
|
||
#include <burst/type_traits/range_reference.hpp> | ||
#include <burst/type_traits/range_value.hpp> | ||
|
||
#include <boost/range/any_range.hpp> | ||
|
||
namespace burst | ||
{ | ||
/*! | ||
\brief | ||
Стирает настоящий тип диапазона | ||
\details | ||
Создаёт диапазон, абстрагированный от типа контейнера. Полученный диапазон имеет те же | ||
самые характеристики, что и исходный диапазон, но имеет некий "универсальный" тип, в | ||
котором имеет значение только категория итератора, его значение и т.п. | ||
\tparam Traversal | ||
\parblock | ||
Способ обхода итератора. Нечто типа бустового эквивалента категории итератора. | ||
Его можно получить из обычной std-категории с помощью специальной метафункции: | ||
\code{.cpp} | ||
using boost_traversal = | ||
typename boost::iterator_category_to_traversal<iterator_category>::type; | ||
\endcode | ||
\endparblock | ||
*/ | ||
template <typename Traversal> | ||
struct to_any_range_t | ||
{ | ||
template <typename Range> | ||
constexpr auto operator () (Range && range) const | ||
{ | ||
using value_type = range_value_t<Range>; | ||
using reference_type = range_reference_t<Range>; | ||
return boost::any_range<value_type, Traversal, reference_type>(range); | ||
} | ||
}; | ||
|
||
template <typename Traversal> | ||
constexpr auto to_any_range = to_any_range_t<Traversal>{}; | ||
} // namespace burst | ||
|
||
#endif // BURST_RANGE_TO_ANY_RANGE_HPP |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
#ifndef BURST_TYPE_TRAITS_ARE_SAME_HPP | ||
#define BURST_TYPE_TRAITS_ARE_SAME_HPP | ||
|
||
#include <burst/type_traits/type_list.hpp> | ||
|
||
#include <type_traits> | ||
|
||
namespace burst | ||
{ | ||
/*! | ||
\brief | ||
Проверяет "одинаковость" типов | ||
\returns | ||
Истину, когда все переданные типы одинаковы, и ложь в противном случае. | ||
*/ | ||
template <typename T, typename... Ts> | ||
struct are_same: std::is_same<type_list<T, Ts...>, type_list<Ts..., T>> {}; | ||
|
||
template <typename... Ts> | ||
constexpr const auto are_same_v = are_same<Ts...>::value; | ||
} // namespace burst | ||
|
||
#endif // BURST_TYPE_TRAITS_ARE_SAME_HPP |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
#ifndef BURST_TYPE_TRAITS_MINIMUM_CATEGORY_HPP | ||
#define BURST_TYPE_TRAITS_MINIMUM_CATEGORY_HPP | ||
|
||
#include <iterator> | ||
#include <type_traits> | ||
|
||
namespace burst | ||
{ | ||
/*! | ||
\brief | ||
Вычисляет меньшую категорию итератора из заданных | ||
\details | ||
Категории стандартной библиотеки по возрастанию: | ||
1. input_iterator_tag | ||
2. forward_iterator_tag | ||
3. bidirectional_iterator_tag | ||
4. random_access_iterator_tag | ||
5. contiguous_iterator_tag [C++20] | ||
*/ | ||
template <typename... Categories> | ||
struct minimum_category; | ||
|
||
template <typename... Categories> | ||
using minimum_category_t = typename minimum_category<Categories...>::type; | ||
|
||
template <typename Category, typename... Categories> | ||
struct minimum_category<Category, Categories...> | ||
{ | ||
static_assert(std::is_convertible<Category, std::input_iterator_tag>::value, ""); | ||
using type = std::common_type_t<Category, minimum_category_t<Categories...>>; | ||
}; | ||
|
||
template <typename Category> | ||
struct minimum_category<Category> | ||
{ | ||
static_assert(std::is_convertible<Category, std::input_iterator_tag>::value, ""); | ||
using type = Category; | ||
}; | ||
} // namespace burst | ||
|
||
#endif // BURST_TYPE_TRAITS_MINIMUM_CATEGORY_HPP |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
#ifndef BURST_TYPE_TRAITS_RANGE_CATEGORY_HPP | ||
#define BURST_TYPE_TRAITS_RANGE_CATEGORY_HPP | ||
|
||
#include <boost/range/category.hpp> | ||
|
||
namespace burst | ||
{ | ||
template <typename Range> | ||
using range_category_t = typename boost::range_category<Range>::type; | ||
} // namespace burst | ||
|
||
#endif // BURST_TYPE_TRAITS_RANGE_CATEGORY_HPP |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#ifndef BURST_TYPE_TRAITS_TYPE_LIST_HPP | ||
#define BURST_TYPE_TRAITS_TYPE_LIST_HPP | ||
|
||
namespace burst | ||
{ | ||
template <typename... Ts> | ||
struct type_list {}; | ||
} // namespace burst | ||
|
||
#endif // BURST_TYPE_TRAITS_TYPE_LIST_HPP |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
target_sources(burst-unit-tests PRIVATE | ||
${CMAKE_CURRENT_SOURCE_DIR}/minimum_category.cpp | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
#include <burst/type_traits/minimum_category.hpp> | ||
|
||
#include <doctest/doctest.h> | ||
|
||
#include <type_traits> | ||
#include <iterator> | ||
|
||
TEST_SUITE("minimum_category") | ||
{ | ||
TEST_CASE("Выбирает минимальную категорию итератора из набора категорий") | ||
{ | ||
using input = std::input_iterator_tag; | ||
using forward = std::forward_iterator_tag; | ||
using bidir = std::bidirectional_iterator_tag; | ||
using random = std::random_access_iterator_tag; | ||
|
||
CHECK(std::is_same<burst::minimum_category_t<input, input>, input>::value); | ||
CHECK(std::is_same<burst::minimum_category_t<input, forward>, input>::value); | ||
CHECK(std::is_same<burst::minimum_category_t<input, bidir>, input>::value); | ||
CHECK(std::is_same<burst::minimum_category_t<input, random>, input>::value); | ||
|
||
CHECK(std::is_same<burst::minimum_category_t<forward, input>, input>::value); | ||
CHECK(std::is_same<burst::minimum_category_t<forward, forward>, forward>::value); | ||
CHECK(std::is_same<burst::minimum_category_t<forward, bidir>, forward>::value); | ||
CHECK(std::is_same<burst::minimum_category_t<forward, random>, forward>::value); | ||
|
||
CHECK(std::is_same<burst::minimum_category_t<bidir, input>, input>::value); | ||
CHECK(std::is_same<burst::minimum_category_t<bidir, forward>, forward>::value); | ||
CHECK(std::is_same<burst::minimum_category_t<bidir, bidir>, bidir>::value); | ||
CHECK(std::is_same<burst::minimum_category_t<bidir, random>, bidir>::value); | ||
|
||
CHECK(std::is_same<burst::minimum_category_t<random, input>, input>::value); | ||
CHECK(std::is_same<burst::minimum_category_t<random, forward>, forward>::value); | ||
CHECK(std::is_same<burst::minimum_category_t<random, bidir>, bidir>::value); | ||
CHECK(std::is_same<burst::minimum_category_t<random, random>, random>::value); | ||
} | ||
|
||
TEST_CASE("Принимает произвольные наборы категорий") | ||
{ | ||
using input = std::input_iterator_tag; | ||
using forward = std::forward_iterator_tag; | ||
using bidir = std::bidirectional_iterator_tag; | ||
using random = std::random_access_iterator_tag; | ||
|
||
CHECK(std::is_same<burst::minimum_category_t<input, forward, bidir, random>, input>::value); | ||
CHECK(std::is_same<burst::minimum_category_t<forward, random, bidir>, forward>::value); | ||
CHECK(std::is_same<burst::minimum_category_t<bidir, random, bidir, random>, bidir>::value); | ||
CHECK(std::is_same<burst::minimum_category_t<random, random, random>, random>::value); | ||
} | ||
} |