BioC++ core-0.7.0
The Modern C++ libraries for Bioinformatics.
 
Loading...
Searching...
No Matches
add_reverse_complement.hpp
Go to the documentation of this file.
1// -----------------------------------------------------------------------------------------------------
2// Copyright (c) 2022 deCODE Genetics
3// Copyright (c) 2006-2020, Knut Reinert & Freie Universität Berlin
4// Copyright (c) 2016-2020, Knut Reinert & MPI für molekulare Genetik
5// This file may be used, modified and/or redistributed under the terms of the 3-clause BSD-License
6// shipped with this file and also available at: https://github.com/biocpp/biocpp-core/blob/main/LICENSE.md
7// -----------------------------------------------------------------------------------------------------
8
14#pragma once
15
16#include <ranges>
17
21
22// ============================================================================
23// reverse_complement_or_not_fn (adaptor definition)
24// ============================================================================
25
26namespace bio::ranges::detail
27{
28
31struct reverse_complement_or_not_fn
32{
33private:
35 static auto func_nop(auto && urange, size_t pos) { return urange[pos]; }
36
38 static auto func_revcomp(auto && urange, size_t pos)
39 {
40 return bio::alphabet::complement(urange[std::ranges::size(urange) - pos - 1]);
41 }
42
43public:
45 constexpr auto operator()(bool const transform) const { return detail::adaptor_from_functor{*this, transform}; }
46
52 template <std::ranges::range urng_t>
53 constexpr auto operator()(urng_t && urange, bool const transform) const
54 {
55 static_assert(std::ranges::viewable_range<urng_t>,
56 "The range parameter to views::reverse_complement_or_not cannot be a temporary of a non-view "
57 "range.");
58 static_assert(std::ranges::sized_range<urng_t>,
59 "The range parameter to views::reverse_complement_or_not must model std::ranges::sized_range.");
60 static_assert(std::ranges::random_access_range<urng_t>,
61 "The range parameter to views::reverse_complement_or_not must model "
62 "std::ranges::random_access_range.");
63 static_assert(alphabet::nucleotide<std::ranges::range_reference_t<urng_t>>,
64 "The range parameter to views::reverse_complement_or_not must be over elements of "
65 "bio::alphabet::nucleotide.");
66
67 auto l = &func_nop<std::views::all_t<urng_t> const &>;
68 if (transform)
69 l = &func_revcomp<std::views::all_t<urng_t> const &>;
70 return std::forward<urng_t>(urange) | views::transform_by_pos(l);
71 }
72};
73
74// ============================================================================
75// reverse_complement_or_not (adaptor object)
76// ============================================================================
77
122inline constexpr auto reverse_complement_or_not = views::deep{reverse_complement_or_not_fn{}};
123
124// ============================================================================
125// add_reverse_complement_fn (adaptor definition)
126// ============================================================================
127
130class add_reverse_complement_fn : public detail::adaptor_base<add_reverse_complement_fn>
131{
132private:
134 using base_type = detail::adaptor_base<add_reverse_complement_fn>;
135
137 friend base_type;
138
143 template <std::ranges::range urng_t>
144 static auto impl(urng_t && urange)
145 {
146 static_assert(range_dimension_v<urng_t> == 2,
147 "This adaptor only handles range-of-range (two dimensions) as input.");
148 static_assert(std::ranges::viewable_range<urng_t>,
149 "The range parameter to views::add_reverse_complement cannot be a temporary of a non-view "
150 "range.");
151 static_assert(std::ranges::viewable_range<std::ranges::range_reference_t<urng_t>>,
152 "The inner range of the range parameter to views::add_reverse_complement cannot be a temporary "
153 "of "
154 "a non-view range.");
155 static_assert(std::ranges::sized_range<urng_t>,
156 "The range parameter to views::add_reverse_complement must model std::ranges::sized_range.");
157 static_assert(std::ranges::sized_range<std::ranges::range_reference_t<urng_t>>,
158 "The inner range of the range parameter to views::add_reverse_complement must model "
159 "std::ranges::sized_range.");
160 static_assert(std::ranges::random_access_range<urng_t>,
161 "The range parameter to views::add_reverse_complement must model "
162 "std::ranges::random_access_range.");
163 static_assert(std::ranges::random_access_range<std::ranges::range_reference_t<urng_t>>,
164 "The inner range of the range parameter to views::add_reverse_complement must model "
165 "std::ranges::random_access_range.");
166 static_assert(alphabet::nucleotide<std::ranges::range_reference_t<std::ranges::range_reference_t<urng_t>>>,
167 "The range parameter to views::add_reverse_complement must be over elements of "
168 "bio::alphabet::nucleotide.");
169
170 return std::forward<urng_t>(urange) |
171 views::transform_by_pos([](auto && urange, size_t pos)
172 { return urange[pos / 2] | reverse_complement_or_not(pos % 2 == 1); },
173 [](auto && urange) { return std::ranges::size(urange) * 2; });
174 }
175
176public:
181 constexpr add_reverse_complement_fn() = default;
183 constexpr add_reverse_complement_fn(add_reverse_complement_fn const &) noexcept = default;
185 constexpr add_reverse_complement_fn(add_reverse_complement_fn &&) noexcept = default;
187 constexpr add_reverse_complement_fn & operator=(add_reverse_complement_fn const &) noexcept = default;
189 constexpr add_reverse_complement_fn & operator=(add_reverse_complement_fn &&) noexcept = default;
191 ~add_reverse_complement_fn() noexcept = default;
192
194 using base_type::base_type;
196};
197
198} // namespace bio::ranges::detail
199
200// ============================================================================
201// add_reverse_complement (adaptor object)
202// ============================================================================
203
204namespace bio::ranges::views
205{
206
253inline constexpr auto add_reverse_complement = detail::add_reverse_complement_fn{};
254
255} // namespace bio::ranges::views
Provides bio::alphabet::nucleotide.
Provides bio::views::deep.
decltype(detail::transform< trait_t >(list_t{})) transform
Apply a transformation trait to every type in the list and return a meta::type_list of the results.
Definition: traits.hpp:500
constexpr auto complement
Return the complement of a nucleotide object.
Definition: concept.hpp:68
constexpr auto transform_by_pos
A view adaptor similar to std::views::transform. Calls the invocable with two arguments: underlying r...
Definition: transform_by_pos.hpp:313
constexpr auto add_reverse_complement
A view that adds the reverse complement of every inner range in a range-of-ranges after the respectiv...
Definition: add_reverse_complement.hpp:253
The main BioC++ namespace.
Definition: aa10li.hpp:23
Provides bio::views::transform_by_pos.