SeqAn3  3.0.3
The Modern C++ library for sequence analysis.
slice.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 <stdexcept>
16 
17 #include <seqan3/io/exception.hpp>
18 #include <seqan3/range/concept.hpp>
22 #include <seqan3/std/concepts>
23 #include <seqan3/std/iterator>
24 #include <seqan3/std/ranges>
25 #include <seqan3/std/span>
26 #include <seqan3/std/type_traits>
27 
28 namespace seqan3::detail
29 {
30 
31 // ============================================================================
32 // slice_fn (adaptor definition)
33 // ============================================================================
34 
36 struct slice_fn
37 {
39  constexpr auto operator()(ptrdiff_t begin_pos, ptrdiff_t end_pos) const noexcept
40  {
41  return detail::adaptor_from_functor{*this, begin_pos, end_pos};
42  }
43 
47  template <std::ranges::viewable_range urng_t>
48  constexpr auto operator()(urng_t && urange,
49  std::ranges::range_difference_t<urng_t> begin_pos,
50  std::ranges::range_difference_t<urng_t> end_pos) const
51  {
52  if constexpr (std::ranges::sized_range<urng_t>)
53  {
54  using position_t = std::ranges::range_difference_t<urng_t>;
55  begin_pos = std::min(begin_pos, static_cast<position_t>(std::ranges::size(urange)));
56  end_pos = std::min(end_pos, static_cast<position_t>(std::ranges::size(urange)));
57  }
58 
59  if (end_pos < begin_pos)
60  throw std::invalid_argument{"end_pos argument to seqan3::views::slice must be >= the begin_pos argument."};
61 
62  // urange | drop | take
63  return views::take(views::drop(std::forward<urng_t>(urange), begin_pos), end_pos - begin_pos);
64  }
65 
66  // does not require special overloads, because views::drop and views::take handle the flattening.
67 };
68 
69 } // namespace seqan3::detail
70 
71 // ============================================================================
72 // views::slice (adaptor instance definition)
73 // ============================================================================
74 
75 namespace seqan3::views
76 {
77 
145 inline constexpr auto slice = detail::slice_fn{};
146 
148 
149 } // namespace seqan3::views
The Concepts library.
Provides seqan3::views::drop.
constexpr size_t size
The size of a type pack.
Definition: traits.hpp:150
constexpr auto drop
A view adaptor that returns all elements after n from the underlying range (or an empty range if the ...
Definition: drop.hpp:172
constexpr auto take
A view adaptor that returns the first size elements from the underlying range (or less if the underly...
Definition: take.hpp:611
constexpr auto slice
A view adaptor that returns a half-open interval on the underlying range.
Definition: slice.hpp:145
Provides exceptions used in the I/O module.
Provides C++20 additions to the <iterator> header.
T min(T... args)
The SeqAn namespace for views.
Additional non-standard concepts for ranges.
Adaptations of concepts from the Ranges TS.
Provides std::span from the C++20 standard library.
Provides seqan3::views::take.
Provides C++20 additions to the type_traits header.