SeqAn3 3.4.0-rc.1
The Modern C++ library for sequence analysis.
Loading...
Searching...
No Matches
slice.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2006-2024 Knut Reinert & Freie Universität Berlin
2// SPDX-FileCopyrightText: 2016-2024 Knut Reinert & MPI für molekulare Genetik
3// SPDX-License-Identifier: BSD-3-Clause
4
10#pragma once
11
12#include <concepts>
13#include <iterator>
14#include <ranges>
15#include <span>
16#include <stdexcept>
17#include <type_traits>
18
22
23namespace seqan3::detail
24{
25
26// ============================================================================
27// slice_fn (adaptor definition)
28// ============================================================================
29
31struct slice_fn
32{
34 constexpr auto operator()(ptrdiff_t begin_pos, ptrdiff_t end_pos) const noexcept
35 {
36 return detail::adaptor_from_functor{*this, begin_pos, end_pos};
37 }
38
42 template <std::ranges::viewable_range urng_t>
43 constexpr auto operator()(urng_t && urange,
44 std::ranges::range_difference_t<urng_t> begin_pos,
45 std::ranges::range_difference_t<urng_t> end_pos) const
46 {
47 using position_t = std::ranges::range_difference_t<urng_t>;
48 if constexpr (std::ranges::sized_range<urng_t>)
49 {
50 position_t urange_size = static_cast<position_t>(std::ranges::size(urange));
51
52 begin_pos = std::min(begin_pos, urange_size);
53 end_pos = std::min(end_pos, urange_size);
54 }
55 position_t target_size = end_pos - begin_pos;
56
57 if (end_pos < begin_pos)
58 throw std::invalid_argument{"end_pos argument to seqan3::views::slice must be >= the begin_pos argument."};
59
60 // SEQAN3_WORKAROUND_GCC_100139 == 1 if std::views::{take, drop} does not type reduce (e.g. keep in type
61 // std::basic_string_view, std::span, std::ranges::subrange).
62 // See https://github.com/seqan/seqan3/pull/2540/files#r617575294
63#if SEQAN3_WORKAROUND_GCC_100139
64 // string_view
65 if constexpr (is_type_specialisation_of_v<std::remove_cvref_t<urng_t>, std::basic_string_view>)
66 {
67 return urange.substr(begin_pos, static_cast<size_t>(target_size));
68 }
69 // string const &
70 else if constexpr (is_type_specialisation_of_v<std::remove_cvref_t<urng_t>, std::basic_string>
71 && std::is_const_v<std::remove_reference_t<urng_t>>)
72 {
73 return std::basic_string_view{std::ranges::data(urange) + begin_pos, static_cast<size_t>(target_size)};
74 }
75 // contiguous
76 else if constexpr (std::ranges::borrowed_range<urng_t> && std::ranges::contiguous_range<urng_t>
77 && std::ranges::sized_range<urng_t>)
78 {
79 return std::span{std::ranges::data(urange) + begin_pos, static_cast<size_t>(target_size)};
80 }
81 // random_access
82 else if constexpr (std::ranges::borrowed_range<urng_t> && std::ranges::random_access_range<urng_t>
83 && std::ranges::sized_range<urng_t>)
84 {
85 return std::ranges::subrange<std::ranges::iterator_t<urng_t>, std::ranges::iterator_t<urng_t>>{
86 std::ranges::begin(urange) + begin_pos,
87 std::ranges::begin(urange) + end_pos,
88 static_cast<size_t>(target_size)};
89 }
90 // std::views::drop
91 else
92 {
93 // urange | drop | take
94 return std::views::take(std::views::drop(std::forward<urng_t>(urange), begin_pos), target_size);
95 }
96#else /*^^^ workaround / no workaround vvv*/
97 // urange | type_reduce | drop | take
98 return std::views::take(std::views::drop(seqan3::views::type_reduce(std::forward<urng_t>(urange)), begin_pos),
99 target_size);
100#endif // SEQAN3_WORKAROUND_GCC_100139
101 }
102};
103
104} // namespace seqan3::detail
105
106// ============================================================================
107// views::slice (adaptor instance definition)
108// ============================================================================
109
110namespace seqan3::views
111{
175inline constexpr auto slice = detail::slice_fn{};
176
177} // namespace seqan3::views
Provides seqan3::detail::adaptor_from_functor.
T begin(T... args)
constexpr auto slice
A view adaptor that returns a half-open interval on the underlying range.
Definition slice.hpp:175
Provides exceptions used in the I/O module.
T min(T... args)
The SeqAn namespace for views.
Definition char_strictly_to.hpp:19
Provides seqan3::views::type_reduce.
Hide me