SeqAn3  3.0.3
The Modern C++ library for sequence analysis.
interleave.hpp
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------------------------------
2 // Copyright (c) 2006-2020, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2020, Knut Reinert & MPI für molekulare Genetik
4 // This file may be used, modified and/or redistributed under the terms of the 3-clause BSD-License
5 // shipped with this file and also available at: https://github.com/seqan/seqan3/blob/master/LICENSE.md
6 // -----------------------------------------------------------------------------------------------------
7 
13 #pragma once
14 
15 #include <cmath>
16 #include <seqan3/std/concepts>
17 #include <seqan3/std/ranges>
18 
19 #include <range/v3/view/chunk.hpp>
20 
28 
29 namespace seqan3::detail
30 {
31 
32 // ============================================================================
33 // view_interleave
34 // ============================================================================
35 
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>>
55 {
56 private:
58  urng_t urange;
60  size_t step_size{};
62  inserted_rng_t inserted_range;
63 
69  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>>;
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>;
86 
88  template <typename parent_type, typename crtp_base>
90 
91 public:
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;
101 
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}
109  {}
110 
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(detail::persist(std::declval<oirng_t>()))>
125  view_interleave(orng_t && _urange, size_t const _step_size, oirng_t && _inserted_range) :
126  view_interleave{views::type_reduce(std::forward<orng_t>(_urange)), _step_size,
127  detail::persist(std::forward<oirng_t>(_inserted_range))}
128  {}
130 
147  iterator begin() noexcept
148  {
149  return {*this, 0};
150  }
151 
153  const_iterator begin() const noexcept
154  {
155  return {*this, 0};
156  }
157 
171  iterator end() noexcept
172  {
173  return {*this, size()};
174  }
175 
177  const_iterator end() const noexcept
178  {
179  return {*this, size()};
180  }
182 
192  {
193  return std::ranges::size(urange) +
195  (std::ranges::size(urange) % step_size == 0 ? 1 : 0)) *
197  }
198 
200  size_type size() const
201  {
202  return std::ranges::size(urange) +
204  (std::ranges::size(urange) % step_size == 0 ? 1 : 0)) *
206  }
207 
224  {
225  size_t combined_size = step_size + std::ranges::size(inserted_range);
226  assert(i < size());
227  if (i % (combined_size) < step_size)
228  return urange[i - (std::floor(i/(combined_size)) * std::ranges::size(inserted_range))];
229  else
230  return inserted_range[(i % (combined_size)) - step_size];
231  }
232 
235  {
236  size_t combined_size = step_size + std::ranges::size(inserted_range);
237  assert(i < size());
238  if (i % (combined_size) < step_size)
239  return urange[i - (std::floor(i/(combined_size)) * std::ranges::size(inserted_range))];
240  else
241  return inserted_range[(i % (combined_size)) - step_size];
242  }
243 };
244 
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 &&)
256  decltype(detail::persist(std::declval<inserted_rng_t>()))>;
257 
258 // ============================================================================
259 // interleave_fn (adaptor definition)
260 // ============================================================================
261 
265 {
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
269  {
270  return detail::adaptor_from_functor{*this, size, std::forward<inserted_rng_t>(i)};
271  }
272 
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
281  {
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>)
290  {
291  return detail::view_interleave{std::forward<urng_t>(urange),
292  static_cast<size_t>(size),
293  std::forward<inserted_rng_t>(i)};
294  }
295  else
296  {
297  return std::forward<urng_t>(urange) | ranges::views::chunk(static_cast<size_t>(size))
298  | views::join(std::forward<inserted_rng_t>(i));
299  }
300  }
301 };
302 
303 } // namespace seqan3::detail
304 
305 // ============================================================================
306 // views::interleave (adaptor instance definition)
307 // ============================================================================
308 
309 namespace seqan3::views
310 {
311 
384 inline constexpr auto interleave = detail::interleave_fn{};
385 
387 
388 } // namespace seqan3::views
Template for range adaptor closure objects that store arguments and wrap a proto-adaptor.
Definition: detail.hpp:371
A CRTP base template for creating random access iterators.
Definition: random_access_iterator.hpp:42
A generic random access iterator that delegates most operations to the range.
Definition: random_access_iterator.hpp:310
The type returned by seqan3::views::interleave.
Definition: interleave.hpp:55
std::ranges::range_difference_t< urng_t > difference_type
A signed integer type, usually std::ptrdiff_t.
Definition: interleave.hpp:80
iterator end() noexcept
Returns an iterator to the element following the last element of the container.
Definition: interleave.hpp:171
const_iterator begin() const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: interleave.hpp:153
inserted_rng_t inserted_range
The range to be inserted into urange.
Definition: interleave.hpp:62
const_iterator end() const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: interleave.hpp:177
view_interleave(urng_t &&, size_t, inserted_rng_t &&) -> view_interleave< decltype(views::type_reduce(std::declval< urng_t >())), decltype(detail::persist(std::declval< inserted_rng_t >()))>
Template argument type deduction guide for viewable_range inputs.
size_type size()
Returns the number of elements in the view.
Definition: interleave.hpp:191
std::ranges::range_value_t< urng_t > value_type
The value_type (which equals the reference_type with any references removed).
Definition: interleave.hpp:78
constexpr view_interleave() noexcept=default
Defaulted.
const_reference operator[](size_type const i) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: interleave.hpp:234
iterator begin() noexcept
Returns an iterator to the first element of the container.
Definition: interleave.hpp:147
urng_t urange
The underlying range.
Definition: interleave.hpp:58
ranges::common_reference_t< std::ranges::range_reference_t< urng_t >, std::ranges::range_reference_t< inserted_rng_t > > reference
The reference_type.
Definition: interleave.hpp:72
size_type size() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: interleave.hpp:200
detail::transformation_trait_or_t< ranges::common_reference< std::ranges::range_reference_t< urng_t const >, std::ranges::range_reference_t< inserted_rng_t const > >, void > const_reference
The const_reference type is equal to the reference type.
Definition: interleave.hpp:76
size_t step_size
The step size for the insertion.
Definition: interleave.hpp:60
reference operator[](size_type const i)
Return the i-th element.
Definition: interleave.hpp:223
view_interleave(orng_t &&_urange, size_t const _step_size, oirng_t &&_inserted_range)
Construct from a viewable_range urange and inserted_range by wrapping in a views::type_reduce.
Definition: interleave.hpp:125
std::ranges::range_size_t< urng_t > size_type
This resolves to range_type::size_type as the underlying range is guaranteed to be sized.
Definition: interleave.hpp:69
The Concepts library.
T floor(T... args)
constexpr size_t size
The size of a type pack.
Definition: traits.hpp:150
typename transformation_trait_or< type_t, default_t >::type transformation_trait_or_t
Helper type of seqan3::detail::transformation_trait_or (transformation_trait shortcut).
Definition: transformation_trait_or.hpp:51
constexpr auto chunk
A chunk view.
Definition: chunk.hpp:29
constexpr auto persist
A view adaptor that wraps rvalue references of non-views.
Definition: persist_view.hpp:228
constexpr auto type_reduce
A view adaptor that behaves like std::views::all, but type erases certain ranges.
Definition: type_reduce.hpp:158
constexpr auto interleave
A view that interleaves a given range into another range at regular intervals.
Definition: interleave.hpp:384
Provides seqan3::views::join.
The internal SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:29
The SeqAn namespace for views.
Definition: char_to.hpp:22
SeqAn specific customisations in the standard namespace.
Provides seqan3::detail::persist.
Provides the seqan3::detail::random_access_iterator class.
Auxiliary header for the views submodule .
Adaptations of concepts from the Ranges TS.
views::interleave's range adaptor object type (non-closure).
Definition: interleave.hpp:265
constexpr auto operator()(size_type const size, inserted_rng_t &&i) const noexcept
Store the argument and return a range adaptor closure object.
Definition: interleave.hpp:268
constexpr auto operator()(urng_t &&urange, size_type const size, inserted_rng_t &&i) const noexcept
Call the view's constructor with the underlying view as argument.
Definition: interleave.hpp:280
This is helper structure to deprecate seqan3::size_type and will be removed before SeqAn 3....
Definition: pre.hpp:279
Provides seqan3::views::type_reduce.
Provides seqan3::detail::transformation_trait_or.
Provides various transformation trait base templates and shortcuts.