SeqAn3 3.2.0
The Modern C++ library for sequence analysis.
translate_join.hpp
Go to the documentation of this file.
1// -----------------------------------------------------------------------------------------------------
2// Copyright (c) 2006-2022, Knut Reinert & Freie Universität Berlin
3// Copyright (c) 2016-2022, 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 <concepts>
16#include <ranges>
17#include <stdexcept>
18#include <vector>
19
23
24namespace seqan3::detail
25{
26
27// ============================================================================
28// view_translate_join (range definition)
29// ============================================================================
30
39template <std::ranges::view urng_t>
40class view_translate_join : public std::ranges::view_base
41{
42private:
44 urng_t urange;
48 small_vector<translation_frames, 6> selected_frames{};
49
55 using reference = view_translate_single<std::views::all_t<std::ranges::range_reference_t<urng_t>>>;
57 using const_reference = reference;
59 using value_type = reference;
61 using size_type = std::ranges::range_size_t<std::ranges::range_reference_t<urng_t>>;
63 using difference_type = std::ranges::range_difference_t<std::ranges::range_reference_t<urng_t>>;
65 using iterator = detail::random_access_iterator<view_translate_join>;
67 using const_iterator = detail::random_access_iterator<view_translate_join const>;
69
71 template <typename, template <typename...> typename>
72 friend class detail::random_access_iterator_base;
73
74public:
75 static_assert(range_dimension_v<urng_t> == 2,
76 "This adaptor only handles range-of-range (two dimensions) as input.");
77 static_assert(std::ranges::viewable_range<urng_t>,
78 "The range parameter to views::translate_join cannot be a temporary of a non-view range.");
79 static_assert(std::ranges::viewable_range<std::ranges::range_reference_t<urng_t>>,
80 "The inner range of the range parameter to views::translate_join cannot be a temporary of "
81 "a non-view range.");
82 static_assert(std::ranges::sized_range<urng_t>,
83 "The range parameter to views::translate_join must model std::ranges::sized_range.");
84 static_assert(std::ranges::sized_range<std::ranges::range_reference_t<urng_t>>,
85 "The inner range of the range parameter to views::translate_join must model "
86 "std::ranges::sized_range.");
87 static_assert(std::ranges::random_access_range<urng_t>,
88 "The range parameter to views::translate_join must model std::ranges::random_access_range.");
89 static_assert(std::ranges::random_access_range<std::ranges::range_reference_t<urng_t>>,
90 "The inner range of the range parameter to views::translate_join must model "
91 "std::ranges::random_access_range.");
93 "The range parameter to views::translate_join must be over a range over elements of "
94 "seqan3::nucleotide_alphabet.");
95
99 view_translate_join() noexcept = default;
100 constexpr view_translate_join(view_translate_join const & rhs) noexcept = default;
101 constexpr view_translate_join(view_translate_join && rhs) noexcept = default;
102 constexpr view_translate_join & operator=(view_translate_join const & rhs) noexcept = default;
103 constexpr view_translate_join & operator=(view_translate_join && rhs) noexcept = default;
104 ~view_translate_join() noexcept = default;
105
110 view_translate_join(urng_t _urange, translation_frames const _tf = translation_frames::six_frames) :
111 urange{std::move(_urange)},
112 tf{_tf}
113 {
115 selected_frames.push_back(translation_frames::forward_frame0);
117 selected_frames.push_back(translation_frames::forward_frame1);
119 selected_frames.push_back(translation_frames::forward_frame2);
121 selected_frames.push_back(translation_frames::reverse_frame0);
123 selected_frames.push_back(translation_frames::reverse_frame1);
125 selected_frames.push_back(translation_frames::reverse_frame2);
126 }
127
132 template <typename rng_t>
133 requires (!std::same_as<std::remove_cvref_t<rng_t>, view_translate_join>) && std::ranges::viewable_range<rng_t>
134 && std::constructible_from<urng_t, std::ranges::ref_view<std::remove_reference_t<rng_t>>>
135 view_translate_join(rng_t && _urange, translation_frames const _tf = translation_frames::six_frames) :
136 view_translate_join{std::views::all(std::forward<rng_t>(_urange)), _tf}
137 {}
139
156 iterator begin() noexcept
157 {
158 return {*this, 0};
159 }
160
162 const_iterator begin() const noexcept
163 requires const_iterable_range<urng_t>
164 {
165 return {*this, 0};
166 }
167
181 iterator end() noexcept
182 {
183 return {*this, size()};
184 }
185
187 const_iterator end() const noexcept
188 requires const_iterable_range<urng_t>
189 {
190 return {*this, size()};
191 }
193
205 size_type size() noexcept
206 {
207 return (size_type)std::ranges::size(urange) * selected_frames.size();
208 }
209
211 size_type size() const noexcept
212 requires const_iterable_range<urng_t>
213 {
214 return (size_type)std::ranges::size(urange) * selected_frames.size();
215 }
216
235 reference operator[](size_type const n)
236 {
237 assert(n < size());
238 size_type index_frame = n % selected_frames.size();
239 size_type index_urange = (n - index_frame) / selected_frames.size();
240 return urange[index_urange] | views::translate_single(selected_frames[index_frame]);
241 }
242
244 const_reference operator[](size_type const n) const
246 {
247 assert(n < size());
248 size_type index_frame = n % selected_frames.size();
249 size_type index_urange = (n - index_frame) / selected_frames.size();
250 return urange[index_urange] | views::translate_single(selected_frames[index_frame]);
251 }
253};
254
256template <typename urng_t>
257view_translate_join(urng_t &&, translation_frames const = translation_frames{})
258 -> view_translate_join<std::views::all_t<urng_t>>;
259
260// ============================================================================
261// translate_fn (adaptor definition for both views)
262// ============================================================================
263
265struct translate_join_fn
266{
268 constexpr auto operator()(translation_frames const tf = translation_frames::six_frames) const
269 {
270 return detail::adaptor_from_functor{*this, tf};
271 }
272
278 template <std::ranges::range urng_t>
279 constexpr auto operator()(urng_t && urange, translation_frames const tf = translation_frames::six_frames) const
280 {
281 static_assert(range_dimension_v<urng_t> == 2,
282 "This adaptor only handles range-of-range (two dimensions) as input.");
283 static_assert(std::ranges::viewable_range<urng_t>,
284 "The range parameter to views::translate_join cannot be a temporary of a non-view range.");
285 static_assert(std::ranges::viewable_range<std::ranges::range_reference_t<urng_t>>,
286 "The inner range of the range parameter to views::translate_join cannot be a "
287 "temporary of a non-view range.");
288 static_assert(std::ranges::sized_range<urng_t>,
289 "The range parameter to views::translate_join must model std::ranges::sized_range.");
290 static_assert(std::ranges::sized_range<std::ranges::range_reference_t<urng_t>>,
291 "The inner range of the range parameter to views::translate_join must model "
292 "std::ranges::sized_range.");
293 static_assert(std::ranges::random_access_range<urng_t>,
294 "The range parameter to views::translate_join must model std::ranges::random_access_range.");
295 static_assert(std::ranges::random_access_range<std::ranges::range_reference_t<urng_t>>,
296 "The inner range of the range parameter to views::translate_join must model "
297 "std::ranges::random_access_range.");
299 "The range parameter to views::translate_join must be over a range over elements of "
300 "seqan3::nucleotide_alphabet.");
301
302 return detail::view_translate_join{std::forward<urng_t>(urange), tf};
303 }
304
306 template <std::ranges::range urng_t>
307 constexpr friend auto operator|(urng_t && urange, translate_join_fn const & me)
308 {
309 return me(std::forward<urng_t>(urange));
310 }
311};
312
313} // namespace seqan3::detail
314
315// ============================================================================
316// translate (adaptor object)
317// ============================================================================
318
319namespace seqan3::views
320{
381inline constexpr auto translate_join = detail::translate_join_fn{};
382
383} // namespace seqan3::views
T begin(T... args)
Provides various transformation traits used by the range module.
T end(T... args)
constexpr auto translate_join
A view that translates nucleotide into aminoacid alphabet with 1, 2, 3 or 6 frames....
Definition: translate_join.hpp:381
constexpr auto translate_single
A view that translates nucleotide into aminoacid alphabet for one of the six frames.
Definition: translate.hpp:523
auto operator|(validator1_type &&vali1, validator2_type &&vali2)
Enables the chaining of validators.
Definition: validators.hpp:1124
constexpr size_t size
The size of a type pack.
Definition: traits.hpp:146
Specifies requirements of an input range type for which the const version of that type satisfies the ...
A concept that indicates whether an alphabet represents nucleotides.
The SeqAn namespace for views.
Definition: char_strictly_to.hpp:22
translation_frames
Specialisation values for single and multiple translation frames.
Definition: translate.hpp:62
@ forward_frame2
The third forward frame starting at position 2.
@ forward_frame0
The first forward frame starting at position 0.
@ reverse_frame0
The first reverse frame starting at position 0.
@ reverse_frame2
The third reverse frame starting at position 2.
@ forward_frame1
The second forward frame starting at position 1.
@ reverse_frame1
The second reverse frame starting at position 1.
A constexpr string implementation to manipulate string literals at compile time.
Provides seqan3::views::translate and seqan3::views::translate_single.