17 #include <range/v3/view/chunk.hpp>
29 namespace seqan3::detail
47 template <std::ranges::random_access_range urng_t, std::ranges::random_access_range inserted_rng_t>
49 requires std::ranges::view<urng_t> && std::ranges::sized_range<urng_t> &&
50 std::ranges::view<inserted_rng_t> && std::ranges::sized_range<inserted_rng_t> &&
51 std::common_reference_with<std::ranges::range_reference_t<urng_t>,
52 std::ranges::range_reference_t<inserted_rng_t>>
54 class view_interleave :
public std::ranges::view_interface<view_interleave<urng_t, inserted_rng_t>>
62 inserted_rng_t inserted_range;
68 using size_type = std::ranges::range_size_t<urng_t>;
71 using reference = ranges::common_reference_t<std::ranges::range_reference_t<urng_t>,
72 std::ranges::range_reference_t<inserted_rng_t>>;
74 using const_reference = detail::transformation_trait_or_t<
75 ranges::common_reference<std::ranges::range_reference_t<urng_t const>,
76 std::ranges::range_reference_t<inserted_rng_t const>>,
void>;
78 using value_type = std::ranges::range_value_t<urng_t>;
80 using difference_type = std::ranges::range_difference_t<urng_t>;
82 using iterator = detail::random_access_iterator<view_interleave>;
84 using const_iterator = detail::random_access_iterator<view_interleave const>;
88 template <
typename parent_type,
typename crtp_base>
89 friend class detail::random_access_iterator_base;
95 constexpr view_interleave() noexcept = default;
96 constexpr view_interleave(view_interleave const & rhs) noexcept = default;
97 constexpr view_interleave(view_interleave && rhs) noexcept = default;
98 constexpr view_interleave & operator=(view_interleave const & rhs) noexcept = default;
99 constexpr view_interleave & operator=(view_interleave && rhs) noexcept = default;
100 ~view_interleave() noexcept = default;
107 view_interleave(urng_t && _urange,
size_t const _step_size, inserted_rng_t && _inserted_range) :
108 urange{_urange}, step_size{_step_size}, inserted_range{_inserted_range}
120 template <
typename orng_t,
typename oirng_t>
122 requires std::constructible_from<urng_t, decltype(views::type_reduce(std::declval<orng_t>()))> &&
123 std::constructible_from<inserted_rng_t, decltype(views::persist(std::declval<oirng_t>()))>
125 view_interleave(orng_t && _urange,
size_t const _step_size, oirng_t && _inserted_range) :
147 iterator
begin() noexcept
153 const_iterator
begin() const noexcept
171 iterator
end() noexcept
173 return {*
this,
size()};
177 const_iterator
end() const noexcept
179 return {*
this,
size()};
200 size_type
size()
const
223 reference operator[](size_type
const i)
227 if (i % (combined_size) < step_size)
230 return inserted_range[(i % (combined_size)) - step_size];
234 const_reference operator[](size_type
const i)
const
238 if (i % (combined_size) < step_size)
241 return inserted_range[(i % (combined_size)) - step_size];
247 template <std::ranges::random_access_range urng_t, std::ranges::random_access_range inserted_rng_t>
249 requires std::ranges::viewable_range<urng_t> && std::ranges::sized_range<urng_t> &&
250 std::ranges::sized_range<inserted_rng_t> &&
251 std::common_reference_with<std::ranges::range_reference_t<urng_t>,
252 std::ranges::range_reference_t<inserted_rng_t>>
254 view_interleave(urng_t &&,
size_t, inserted_rng_t &&)
255 -> view_interleave<decltype(views::type_reduce(std::declval<urng_t>())),
267 template <std::ranges::forward_range inserted_rng_t, std::
integral
size_type>
268 constexpr
auto operator()(size_type
const size, inserted_rng_t && i)
const noexcept
270 return detail::adaptor_from_functor{*
this,
size, std::forward<inserted_rng_t>(i)};
279 template <std::ranges::range urng_t, std::ranges::range inserted_rng_t, std::
integral
size_type>
280 constexpr
auto operator()(urng_t && urange, size_type
const size, inserted_rng_t && i)
const noexcept
282 static_assert(std::ranges::forward_range<urng_t>,
283 "The underlying range parameter in views::interleave must model std::ranges::forward_range.");
284 static_assert(std::ranges::viewable_range<urng_t>,
285 "The underlying range parameter in views::interleave must model std::ranges::viewable_range.");
286 static_assert(std::ranges::forward_range<inserted_rng_t>,
287 "The range to be inserted by views::interleave must model std::ranges::forward_range.");
288 if constexpr (std::ranges::random_access_range<urng_t> && std::ranges::sized_range<urng_t> &&
289 std::ranges::random_access_range<inserted_rng_t> && std::ranges::sized_range<inserted_rng_t>)
291 return detail::view_interleave{std::forward<urng_t>(urange),
292 static_cast<size_t>(
size),
293 std::forward<inserted_rng_t>(i)};
297 return std::forward<urng_t>(urange) | ranges::views::chunk(
static_cast<size_t>(
size))
298 | views::join(std::forward<inserted_rng_t>(i));