SeqAn3  3.0.2
The Modern C++ library for sequence analysis.
translate_join.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 <vector>
16 #include <stdexcept>
17 
22 #include <seqan3/std/concepts>
23 #include <seqan3/std/ranges>
24 
25 namespace seqan3::detail
26 {
27 
28 // ============================================================================
29 // view_translate_join (range definition)
30 // ============================================================================
31 
40 template <std::ranges::view urng_t>
41 class view_translate_join : public std::ranges::view_base
42 {
43 private:
45  urng_t urange;
49  small_vector<translation_frames, 6> selected_frames{};
50 
55  using reference = view_translate_single<std::views::all_t<std::ranges::range_reference_t<urng_t>>>;
58  using const_reference = reference;
60  using value_type = reference;
62  using size_type = std::ranges::range_size_t<std::ranges::range_reference_t<urng_t>>;
64  using difference_type = std::ranges::range_difference_t<std::ranges::range_reference_t<urng_t>>;
66  using iterator = detail::random_access_iterator<view_translate_join>;
68  using const_iterator = detail::random_access_iterator<view_translate_join const>;
70 
72  template <typename, typename>
73  friend class detail::random_access_iterator_base;
74 
75 public:
76 
77  static_assert(range_dimension_v<urng_t> == 2,
78  "This adaptor only handles range-of-range (two dimensions) as input.");
79  static_assert(std::ranges::viewable_range<urng_t>,
80  "The range parameter to views::translate_join cannot be a temporary of a non-view range.");
81  static_assert(std::ranges::viewable_range<std::ranges::range_reference_t<urng_t>>,
82  "The inner range of the range parameter to views::translate_join cannot be a temporary of "
83  "a non-view range.");
84  static_assert(std::ranges::sized_range<urng_t>,
85  "The range parameter to views::translate_join must model std::ranges::sized_range.");
86  static_assert(std::ranges::sized_range<std::ranges::range_reference_t<urng_t>>,
87  "The inner range of the range parameter to views::translate_join must model "
88  "std::ranges::sized_range.");
89  static_assert(std::ranges::random_access_range<urng_t>,
90  "The range parameter to views::translate_join must model std::ranges::random_access_range.");
91  static_assert(std::ranges::random_access_range<std::ranges::range_reference_t<urng_t>>,
92  "The inner range of the range parameter to views::translate_join must model "
93  "std::ranges::random_access_range.");
94  static_assert(nucleotide_alphabet<std::ranges::range_reference_t<std::ranges::range_reference_t<urng_t>>>,
95  "The range parameter to views::translate_join must be over a range over elements of "
96  "seqan3::nucleotide_alphabet.");
97 
101  view_translate_join() noexcept = default;
102  constexpr view_translate_join(view_translate_join const & rhs) noexcept = default;
103  constexpr view_translate_join(view_translate_join && rhs) noexcept = default;
104  constexpr view_translate_join & operator=(view_translate_join const & rhs) noexcept = default;
105  constexpr view_translate_join & operator=(view_translate_join && rhs) noexcept = default;
106  ~view_translate_join() noexcept = default;
107 
112  view_translate_join(urng_t _urange, translation_frames const _tf = translation_frames::SIX_FRAME)
113  : urange{std::move(_urange)}, tf{_tf}
114  {
115  if ((_tf & translation_frames::FWD_FRAME_0) == translation_frames::FWD_FRAME_0)
116  selected_frames.push_back(translation_frames::FWD_FRAME_0);
117  if ((_tf & translation_frames::FWD_FRAME_1) == translation_frames::FWD_FRAME_1)
118  selected_frames.push_back(translation_frames::FWD_FRAME_1);
119  if ((_tf & translation_frames::FWD_FRAME_2) == translation_frames::FWD_FRAME_2)
120  selected_frames.push_back(translation_frames::FWD_FRAME_2);
121  if ((_tf & translation_frames::REV_FRAME_0) == translation_frames::REV_FRAME_0)
122  selected_frames.push_back(translation_frames::REV_FRAME_0);
123  if ((_tf & translation_frames::REV_FRAME_1) == translation_frames::REV_FRAME_1)
124  selected_frames.push_back(translation_frames::REV_FRAME_1);
125  if ((_tf & translation_frames::REV_FRAME_2) == translation_frames::REV_FRAME_2)
126  selected_frames.push_back(translation_frames::REV_FRAME_2);
127  }
128 
133  template <typename rng_t>
135  requires (!std::same_as<std::remove_cvref_t<rng_t>, view_translate_join>) &&
136  std::ranges::viewable_range<rng_t> &&
137  std::constructible_from<urng_t, std::ranges::ref_view<std::remove_reference_t<rng_t>>>
139  view_translate_join(rng_t && _urange, translation_frames const _tf = translation_frames::SIX_FRAME)
140  : view_translate_join{std::views::all(std::forward<rng_t>(_urange)), _tf}
141  {}
143 
160  iterator begin() noexcept
161  {
162  return {*this, 0};
163  }
164 
166  const_iterator begin() const noexcept
167  requires const_iterable_range<urng_t>
168  {
169  return {*this, 0};
170  }
171 
185  iterator end() noexcept
186  {
187  return {*this, size()};
188  }
189 
191  const_iterator end() const noexcept
192  requires const_iterable_range<urng_t>
193  {
194  return {*this, size()};
195  }
197 
209  size_type size() noexcept
210  {
211  return (size_type) std::ranges::size(urange) * selected_frames.size();
212  }
213 
215  size_type size() const noexcept
216  requires const_iterable_range<urng_t>
217  {
218  return (size_type) std::ranges::size(urange) * selected_frames.size();
219  }
220 
239  reference operator[](size_type const n)
240  {
241  assert(n < size());
242  size_type index_frame = n % selected_frames.size();
243  size_type index_urange = (n - index_frame) / selected_frames.size();
244  return urange[index_urange] | views::translate_single(selected_frames[index_frame]);
245  }
246 
248  const_reference operator[](size_type const n) const
250  {
251  assert(n < size());
252  size_type index_frame = n % selected_frames.size();
253  size_type index_urange = (n - index_frame) / selected_frames.size();
254  return urange[index_urange] | views::translate_single(selected_frames[index_frame]);
255  }
257 };
258 
260 template <typename urng_t>
261 view_translate_join(urng_t &&, translation_frames const = translation_frames{}) -> view_translate_join<std::views::all_t<urng_t>>;
262 
263 // ============================================================================
264 // translate_fn (adaptor definition for both views)
265 // ============================================================================
266 
268 struct translate_join_fn
269 {
271  constexpr auto operator()(translation_frames const tf = translation_frames::SIX_FRAME) const
272  {
273  return detail::adaptor_from_functor{*this, tf};
274  }
275 
281  template <std::ranges::range urng_t>
282  constexpr auto operator()(urng_t && urange, translation_frames const tf = translation_frames::SIX_FRAME) const
283  {
284  static_assert(range_dimension_v<urng_t> == 2,
285  "This adaptor only handles range-of-range (two dimensions) as input.");
286  static_assert(std::ranges::viewable_range<urng_t>,
287  "The range parameter to views::translate_join cannot be a temporary of a non-view range.");
288  static_assert(std::ranges::viewable_range<std::ranges::range_reference_t<urng_t>>,
289  "The inner range of the range parameter to views::translate_join cannot be a "
290  "temporary of a non-view range.");
291  static_assert(std::ranges::sized_range<urng_t>,
292  "The range parameter to views::translate_join must model std::ranges::sized_range.");
293  static_assert(std::ranges::sized_range<std::ranges::range_reference_t<urng_t>>,
294  "The inner range of the range parameter to views::translate_join must model "
295  "std::ranges::sized_range.");
296  static_assert(std::ranges::random_access_range<urng_t>,
297  "The range parameter to views::translate_join must model std::ranges::random_access_range.");
298  static_assert(std::ranges::random_access_range<std::ranges::range_reference_t<urng_t>>,
299  "The inner range of the range parameter to views::translate_join must model "
300  "std::ranges::random_access_range.");
301  static_assert(nucleotide_alphabet<std::ranges::range_reference_t<std::ranges::range_reference_t<urng_t>>>,
302  "The range parameter to views::translate_join must be over a range over elements of "
303  "seqan3::nucleotide_alphabet.");
304 
305  return detail::view_translate_join{std::forward<urng_t>(urange), tf};
306  }
307 
309  template <std::ranges::range urng_t>
310  constexpr friend auto operator|(urng_t && urange, translate_join_fn const & me)
311  {
312  return me(std::forward<urng_t>(urange));
313  }
314 };
315 
316 } // namespace seqan3::detail
317 
318 // ============================================================================
319 // translate (adaptor object)
320 // ============================================================================
321 
322 namespace seqan3::views
323 {
324 
385 inline constexpr auto translate_join = detail::translate_join_fn{};
387 
388 } // namespace seqan3::views
seqan3::views
The SeqAn namespace for views.
Definition: view_iota_simd.hpp:218
seqan3::views::translate_join
constexpr auto translate_join
A view that translates nucleotide into aminoacid alphabet with 1, 2, 3 or 6 frames....
Definition: translate_join.hpp:385
vector
seqan3::operator|
auto operator|(validator1_type &&vali1, validator2_type &&vali2)
Enables the chaining of validators.
Definition: validators.hpp:1037
concepts
The Concepts library.
stdexcept
random_access_iterator.hpp
Provides the seqan3::detail::random_access_iterator class.
translate.hpp
Provides seqan3::views::translate and seqan3::views::translate_single.
nucleotide_alphabet
A concept that indicates whether an alphabet represents nucleotides.
seqan3::views::move
auto const move
A view that turns lvalue-references into rvalue-references.
Definition: move.hpp:68
small_string.hpp
A constexpr string implementation to manipulate string literals at compile time.
range.hpp
Provides various transformation traits used by the range module.
const_iterable_range
Specifies requirements of an input range type for which the const version of that type satisfies the ...
seqan3::pack_traits::size
constexpr size_t size
The size of a type pack.
Definition: traits.hpp:116
ranges
Adaptations of concepts from the Ranges TS.
std::begin
T begin(T... args)
std::remove_cvref_t
std::end
T end(T... args)
seqan3::translation_frames
translation_frames
Specialisation values for single and multiple translation frames.
Definition: translate.hpp:65
seqan3::translation_frames::FWD_FRAME_0
@ FWD_FRAME_0
The first forward frame starting at position 0.
seqan3::views::translate_single
constexpr auto translate_single
A view that translates nucleotide into aminoacid alphabet for one of the six frames.
Definition: translate.hpp:492