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> &&
53 class view_interleave :
public std::ranges::view_interface<view_interleave<urng_t, inserted_rng_t>>
61 inserted_rng_t inserted_range;
67 using reference = ranges::common_reference_t<reference_t<urng_t>, reference_t<inserted_rng_t>>;
70 using const_reference = detail::transformation_trait_or_t<
71 ranges::common_reference<reference_t<urng_t const>, reference_t<inserted_rng_t const>>,
void>;
73 using value_type = value_type_t<urng_t>;
75 using size_type = size_type_t<urng_t>;
77 using difference_type = difference_type_t<urng_t>;
79 using iterator = detail::random_access_iterator<view_interleave>;
81 using const_iterator = detail::random_access_iterator<view_interleave const>;
87 constexpr view_interleave() noexcept = default;
88 constexpr view_interleave(view_interleave const & rhs) noexcept = default;
89 constexpr view_interleave(view_interleave && rhs) noexcept = default;
90 constexpr view_interleave & operator=(view_interleave const & rhs) noexcept = default;
91 constexpr view_interleave & operator=(view_interleave && rhs) noexcept = default;
92 ~view_interleave() noexcept = default;
99 view_interleave(urng_t && _urange,
size_t const _step_size, inserted_rng_t && _inserted_range) :
100 urange{_urange}, step_size{_step_size}, inserted_range{_inserted_range}
112 template <
typename orng_t,
typename oirng_t>
117 view_interleave(orng_t && _urange,
size_t const _step_size, oirng_t && _inserted_range) :
138 iterator
begin() noexcept
144 const_iterator
begin() const noexcept
150 const_iterator
cbegin() const noexcept
168 iterator
end() noexcept
170 return {*
this,
size()};
174 const_iterator
end() const noexcept
176 return {*
this,
size()};
180 const_iterator
cend() const noexcept
203 size_type
size()
const
226 reference operator[](size_type
const i)
230 if (i % (combined_size) < step_size)
233 return inserted_range[(i % (combined_size)) - step_size];
237 const_reference operator[](size_type
const i)
const
241 if (i % (combined_size) < step_size)
244 return inserted_range[(i % (combined_size)) - step_size];
250 template <std::ranges::random_access_range urng_t, std::ranges::random_access_range inserted_rng_t>
252 requires std::ranges::viewable_range<urng_t> && std::ranges::sized_range<urng_t> &&
253 std::ranges::sized_range<inserted_rng_t> &&
256 view_interleave(urng_t &&,
size_t, inserted_rng_t &&)
257 -> view_interleave<decltype(views::type_reduce(std::declval<urng_t>())), decltype(
views::persist(std::declval<inserted_rng_t>()))>;
268 template <std::ranges::forward_range inserted_rng_t, std::
integral
size_type>
269 constexpr
auto operator()(size_type
const size, inserted_rng_t && i)
const noexcept
271 return detail::adaptor_from_functor{*
this,
size, std::forward<inserted_rng_t>(i)};
280 template <std::ranges::range urng_t, std::ranges::range inserted_rng_t, std::
integral
size_type>
281 constexpr
auto operator()(urng_t && urange, size_type
const size, inserted_rng_t && i)
const noexcept
283 static_assert(std::ranges::forward_range<urng_t>,
284 "The underlying range parameter in views::interleave must model std::ranges::forward_range.");
285 static_assert(std::ranges::viewable_range<urng_t>,
286 "The underlying range parameter in views::interleave must model std::ranges::viewable_range.");
287 static_assert(std::ranges::forward_range<inserted_rng_t>,
288 "The range to be inserted by views::interleave must model std::ranges::forward_range.");
289 if constexpr (std::ranges::random_access_range<urng_t> && std::ranges::sized_range<urng_t> &&
290 std::ranges::random_access_range<inserted_rng_t> && std::ranges::sized_range<inserted_rng_t>)
292 return detail::view_interleave{std::forward<urng_t>(urange),
293 static_cast<size_t>(
size),
294 std::forward<inserted_rng_t>(i)};
298 return std::forward<urng_t>(urange) | ranges::views::chunk(static_cast<size_t>(
size))
299 | views::join(std::forward<inserted_rng_t>(i));