SeqAn3 3.2.0
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
25namespace seqan3::detail
26{
27
33template <typename t>
34concept arithmetic_or_simd = arithmetic<t> || simd_concept<t>;
36
43template <typename t>
44concept tracedirections_or_simd = std::same_as<std::remove_cvref_t<t>, trace_directions> || simd_concept<t>;
46
58template <typename t>
59concept 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
76template <typename t>
77concept 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
94template <typename t>
95concept 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
114template <typename tuple_t>
115 requires (affine_score_cell<tuple_t> || affine_score_and_trace_cell<tuple_t>)
116class affine_cell_proxy : public tuple_t
117{
118private:
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
125public:
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
335private:
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
381namespace std
382{
384template <typename tuple_t>
385 requires (seqan3::detail::affine_score_cell<tuple_t> || seqan3::detail::affine_score_and_trace_cell<tuple_t>)
386struct tuple_size<seqan3::detail::affine_cell_proxy<tuple_t>> : public tuple_size<tuple_t>
387{};
388
389template <size_t index, typename tuple_t>
390 requires (seqan3::detail::affine_score_cell<tuple_t> || seqan3::detail::affine_score_and_trace_cell<tuple_t>)
391struct tuple_element<index, seqan3::detail::affine_cell_proxy<tuple_t>> : public tuple_element<index, tuple_t>
392{};
394} // namespace std
Provides seqan3::detail::empty_type.
T forward(T... args)
A type that satisfies std::is_arithmetic_v<t>.
Whether a type behaves like a tuple.
T move(T... args)
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.