SeqAn3  3.2.0-rc.1
The Modern C++ library for sequence analysis.
affine_cell_proxy.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 <tuple>
17 #include <type_traits>
18 
24 
25 namespace seqan3::detail
26 {
27 
33 template <typename t>
34 concept arithmetic_or_simd = arithmetic<t> || simd_concept<t>;
36 
43 template <typename t>
44 concept tracedirections_or_simd = std::same_as<std::remove_cvref_t<t>, trace_directions> || simd_concept<t>;
46 
58 template <typename t>
59 concept affine_score_cell = tuple_like<t> && std::tuple_size_v<t> == 3
60  && arithmetic_or_simd<std::remove_reference_t<std::tuple_element_t<0, t>>>
61  && arithmetic_or_simd<std::remove_reference_t<std::tuple_element_t<1, t>>>
62  && arithmetic_or_simd<std::remove_reference_t<std::tuple_element_t<2, t>>>;
64 
76 template <typename t>
77 concept affine_trace_cell = tuple_like<t> && std::tuple_size_v<t> == 3
78  && tracedirections_or_simd<std::remove_reference_t<std::tuple_element_t<0, t>>>
79  && tracedirections_or_simd<std::remove_reference_t<std::tuple_element_t<1, t>>>
80  && tracedirections_or_simd<std::remove_reference_t<std::tuple_element_t<2, t>>>;
82 
94 template <typename t>
95 concept affine_score_and_trace_cell =
96  tuple_like<t> && std::tuple_size_v<t> == 2
97  && affine_score_cell<std::tuple_element_t<0, t>> && affine_trace_cell<std::tuple_element_t<1, t>>;
99 
114 template <typename tuple_t>
115  requires (affine_score_cell<tuple_t> || affine_score_and_trace_cell<tuple_t>)
116 class affine_cell_proxy : public tuple_t
117 {
118 private:
120  using score_cell_type = std::conditional_t<affine_score_cell<tuple_t>, tuple_t, std::tuple_element_t<0, tuple_t>>;
122  using trace_cell_type =
123  std::conditional_t<affine_score_and_trace_cell<tuple_t>, std::tuple_element_t<1, tuple_t>, empty_type>;
124 
125 public:
129  affine_cell_proxy() = default;
130  affine_cell_proxy(affine_cell_proxy const &) = default;
131  affine_cell_proxy(affine_cell_proxy &&) = default;
132  affine_cell_proxy & operator=(affine_cell_proxy const &) = default;
133  affine_cell_proxy & operator=(affine_cell_proxy &&) = default;
134  ~affine_cell_proxy() = default;
135 
136  // Inherit the base class's constructor to enable element-wise initialisation (direct and converting constructor).
137  using tuple_t::tuple_t;
138 
140  template <typename other_tuple_t>
141  requires std::constructible_from<tuple_t, other_tuple_t &&>
142  explicit affine_cell_proxy(other_tuple_t && other) : tuple_t{std::forward<other_tuple_t>(other)}
143  {}
144 
146  template <typename other_tuple_t>
147  requires std::constructible_from<tuple_t, other_tuple_t const &>
148  explicit affine_cell_proxy(affine_cell_proxy<other_tuple_t> const & other) :
149  tuple_t{static_cast<other_tuple_t const &>(other)}
150  {}
151 
153  template <typename other_tuple_t>
154  requires std::constructible_from<tuple_t, other_tuple_t>
155  explicit affine_cell_proxy(affine_cell_proxy<other_tuple_t> && other) :
156  tuple_t{static_cast<other_tuple_t &&>(std::move(other))}
157  {}
158 
160  template <typename other_tuple_t>
161  requires std::assignable_from<tuple_t &, other_tuple_t &&>
162  affine_cell_proxy & operator=(other_tuple_t && other)
163  {
164  as_base() = std::forward<other_tuple_t>(other);
165  return *this;
166  }
167 
169  template <typename other_tuple_t>
170  requires std::assignable_from<tuple_t &, other_tuple_t const &>
171  affine_cell_proxy & operator=(affine_cell_proxy<other_tuple_t> const & other)
172  {
173  as_base() = static_cast<other_tuple_t const &>(other);
174  return *this;
175  }
176 
178  template <typename other_tuple_t>
179  requires std::assignable_from<tuple_t &, other_tuple_t>
180  affine_cell_proxy & operator=(affine_cell_proxy<other_tuple_t> && other)
181  {
182  as_base() = static_cast<other_tuple_t &&>(std::move(other));
183  return *this;
184  }
186 
192  decltype(auto) best_score() & noexcept
193  {
194  return get_score_impl<0>(*this);
195  }
197  decltype(auto) best_score() const & noexcept
198  {
199  return get_score_impl<0>(*this);
200  }
202  decltype(auto) best_score() && noexcept
203  {
204  return get_score_impl<0>(std::move(*this));
205  }
207  decltype(auto) best_score() const && noexcept
208  {
209  return get_score_impl<0>(std::move(*this));
210  }
211 
213  decltype(auto) horizontal_score() & noexcept
214  {
215  return get_score_impl<1>(*this);
216  }
218  decltype(auto) horizontal_score() const & noexcept
219  {
220  return get_score_impl<1>(*this);
221  }
223  decltype(auto) horizontal_score() && noexcept
224  {
225  return get_score_impl<1>(std::move(*this));
226  }
228  decltype(auto) horizontal_score() const && noexcept
229  {
230  return get_score_impl<1>(std::move(*this));
231  }
232 
234  decltype(auto) vertical_score() & noexcept
235  {
236  return get_score_impl<2>(*this);
237  }
239  decltype(auto) vertical_score() const & noexcept
240  {
241  return get_score_impl<2>(*this);
242  }
244  decltype(auto) vertical_score() && noexcept
245  {
246  return get_score_impl<2>(std::move(*this));
247  }
249  decltype(auto) vertical_score() const && noexcept
250  {
251  return get_score_impl<2>(std::move(*this));
252  }
254 
260  decltype(auto) best_trace() & noexcept
261  requires affine_score_and_trace_cell<tuple_t>
262  {
263  return get_trace_impl<0>(*this);
264  }
266  decltype(auto) best_trace() const & noexcept
267  requires affine_score_and_trace_cell<tuple_t>
268  {
269  return get_trace_impl<0>(*this);
270  }
272  decltype(auto) best_trace() && noexcept
273  requires affine_score_and_trace_cell<tuple_t>
274  {
275  return get_trace_impl<0>(std::move(*this));
276  }
278  decltype(auto) best_trace() const && noexcept
279  requires affine_score_and_trace_cell<tuple_t>
280  {
281  return get_trace_impl<0>(std::move(*this));
282  }
283 
285  decltype(auto) horizontal_trace() & noexcept
286  requires affine_score_and_trace_cell<tuple_t>
287  {
288  return get_trace_impl<1>(*this);
289  }
291  decltype(auto) horizontal_trace() const & noexcept
292  requires affine_score_and_trace_cell<tuple_t>
293  {
294  return get_trace_impl<1>(*this);
295  }
297  decltype(auto) horizontal_trace() && noexcept
298  requires affine_score_and_trace_cell<tuple_t>
299  {
300  return get_trace_impl<1>(std::move(*this));
301  }
303  decltype(auto) horizontal_trace() const && noexcept
304  requires affine_score_and_trace_cell<tuple_t>
305  {
306  return get_trace_impl<1>(std::move(*this));
307  }
308 
310  decltype(auto) vertical_trace() & noexcept
311  requires affine_score_and_trace_cell<tuple_t>
312  {
313  return get_trace_impl<2>(*this);
314  }
316  decltype(auto) vertical_trace() const & noexcept
317  requires affine_score_and_trace_cell<tuple_t>
318  {
319  return get_trace_impl<2>(*this);
320  }
322  decltype(auto) vertical_trace() && noexcept
323  requires affine_score_and_trace_cell<tuple_t>
324  {
325  return get_trace_impl<2>(std::move(*this));
326  }
328  decltype(auto) vertical_trace() const && noexcept
329  requires affine_score_and_trace_cell<tuple_t>
330  {
331  return get_trace_impl<2>(std::move(*this));
332  }
334 
335 private:
344  template <size_t index, typename this_t>
345  requires (index < 3)
346  static constexpr decltype(auto) get_score_impl(this_t && me) noexcept
347  {
348  using std::get;
349 
350  if constexpr (affine_score_cell<tuple_t>)
351  return get<index>(std::forward<this_t>(me));
352  else
353  return get<index>(get<0>(std::forward<this_t>(me)));
354  }
355 
364  template <size_t index, typename this_t>
365  requires (index < 3 && affine_score_and_trace_cell<tuple_t>)
366  static constexpr decltype(auto) get_trace_impl(this_t && me) noexcept
367  {
368  using std::get;
369 
370  return get<index>(get<1>(std::forward<this_t>(me)));
371  }
372 
374  tuple_t & as_base() & noexcept
375  {
376  return static_cast<tuple_t &>(*this);
377  }
378 };
379 } // namespace seqan3::detail
380 
381 namespace std
382 {
384 template <typename tuple_t>
385  requires (seqan3::detail::affine_score_cell<tuple_t> || seqan3::detail::affine_score_and_trace_cell<tuple_t>)
386 struct tuple_size<seqan3::detail::affine_cell_proxy<tuple_t>> : public tuple_size<tuple_t>
387 {};
388 
389 template <size_t index, typename tuple_t>
390  requires (seqan3::detail::affine_score_cell<tuple_t> || seqan3::detail::affine_score_and_trace_cell<tuple_t>)
391 struct tuple_element<index, seqan3::detail::affine_cell_proxy<tuple_t>> : public tuple_element<index, tuple_t>
392 {};
394 } // namespace std
The <concepts> header from C++20's standard library.
Provides seqan3::detail::empty_type.
T forward(T... args)
requires requires
The rank_type of the semi-alphabet; defined as the return type of seqan3::to_rank....
Definition: alphabet/concept.hpp:164
A type that satisfies std::is_arithmetic_v<t>.
Whether a type behaves like a tuple.
The main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:29
constexpr auto const & get(configuration< configs_t... > const &config) noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: configuration.hpp:415
SeqAn specific customisations in the standard namespace.
Provides the declaration of seqan3::detail::trace_directions.
Provides concepts that do not have equivalents in C++20.
Provides seqan3::simd::simd_concept.
Provides seqan3::tuple_like.