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 
24 namespace seqan3::detail
25 {
26 
27 // ============================================================================
28 // view_translate_join (range definition)
29 // ============================================================================
30 
39 template <std::ranges::view urng_t>
40 class view_translate_join : public std::ranges::view_base
41 {
42 private:
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 
74 public:
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.");
92  static_assert(nucleotide_alphabet<std::ranges::range_reference_t<std::ranges::range_reference_t<urng_t>>>,
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
164  {
165  return {*this, 0};
166  }
167 
181  iterator end() noexcept
182  {
183  return {*this, size()};
184  }
185 
187  const_iterator end() const noexcept
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
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 
256 template <typename urng_t>
257 view_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 
265 struct 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.");
298  static_assert(nucleotide_alphabet<std::ranges::range_reference_t<std::ranges::range_reference_t<urng_t>>>,
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 
319 namespace seqan3::views
320 {
381 inline constexpr auto translate_join = detail::translate_join_fn{};
382 
383 } // namespace seqan3::views
T begin(T... args)
The <concepts> header from C++20's standard library.
Provides various transformation traits used by the range module.
T end(T... args)
T forward(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
requires requires
The rank_type of the semi-alphabet; defined as the return type of seqan3::to_rank....
Definition: alphabet/concept.hpp:164
requires std::common_with< typename std::remove_reference_t< validator1_type >::option_value_type, typename std::remove_reference_t< validator2_type >::option_value_type > 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: type_pack/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.
SeqAn specific customisations in the standard namespace.
The <ranges> header from C++20's standard library.
A constexpr string implementation to manipulate string literals at compile time.
Provides seqan3::views::translate and seqan3::views::translate_single.