This commit is contained in:
2024-06-03 18:02:46 +03:00
parent 65cd65b2d8
commit c0316937e3
4 changed files with 239 additions and 18 deletions

View File

@@ -46,6 +46,10 @@ template <typename R>
concept adc_char_view = std::ranges::view<R> && std::same_as<std::ranges::range_value_t<R>, char>;
template <typename R>
concept adc_range_of_view_char_range = std::ranges::range<R> && std::ranges::view<std::ranges::range_value_t<R>> &&
std::same_as<std::ranges::range_value_t<std::ranges::range_value_t<R>>, char>;
// deduce returned type of callable
// template <typename T>
// using adc_retval_t = std::invoke_result_t<std::remove_cvref_t<T>>;

View File

@@ -441,4 +441,62 @@ public:
}
};
/* join range elements using delimiter between its elements */
// NOTE: C++23 has std::views::join_with adapter but here I use upto C++20!!!
template <std::ranges::input_range R,
std::ranges::input_range RD,
std::ranges::output_range<std::ranges::range_value_t<RD>> RO>
static size_t AdcJoinRange(R& r, const RD& delim, RO& ro)
requires std::ranges::range<std::ranges::range_value_t<R>> && // input R is range of ranges
std::same_as<std::ranges::range_value_t<std::ranges::range_value_t<R>>, std::ranges::range_value_t<RD>>
{
auto N = std::ranges::distance(r.begin(), r.end());
if (!N) {
return 0;
}
size_t i = 0;
std::ranges::for_each(r, [&](const auto& el) {
std::ranges::copy(el, std::back_inserter(ro));
if (++i < N) {
std::ranges::copy(delim, std::back_inserter(ro));
}
});
return N;
}
// create a range with views of elements of input range and insert a view of input delimiter between them
template <std::ranges::input_range R, std::ranges::input_range RD, std::ranges::range RO>
static size_t AdcReturnRangeElementsView(const R& r, const RD& delim, RO& ro)
requires std::ranges::range<std::ranges::range_value_t<R>> && // input R is range of ranges
std::same_as<std::ranges::range_value_t<std::ranges::range_value_t<R>>, std::ranges::range_value_t<RD>> &&
std::ranges::view<std::ranges::range_value_t<RO>> && // output RO is range of views
std::same_as<std::ranges::range_value_t<std::ranges::range_value_t<RO>>, std::ranges::range_value_t<RD>>
{
auto N = std::ranges::distance(r.begin(), r.end());
if (!N) {
return 0;
}
size_t i = 0;
std::ranges::for_each(r, [&](const auto& el) {
std::back_inserter(ro) = {el.begin(), el.end()};
if (++i < N) {
std::back_inserter(ro) = {delim.begin(), delim.end()};
}
});
return N;
}
} // namespace adc::utils