SeqAn3 3.4.0-rc.1
The Modern C++ library for sequence analysis.
Loading...
Searching...
No Matches
affine_cell_proxy.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2006-2024 Knut Reinert & Freie Universität Berlin
2// SPDX-FileCopyrightText: 2016-2024 Knut Reinert & MPI für molekulare Genetik
3// SPDX-License-Identifier: BSD-3-Clause
4
10#pragma once
11
12#include <concepts>
13#include <tuple>
14#include <type_traits>
15
19#include <seqan3/utility/simd/concept.hpp>
21
22namespace seqan3::detail
23{
24
30template <typename t>
31concept arithmetic_or_simd = arithmetic<t> || simd_concept<t>;
33
40template <typename t>
41concept tracedirections_or_simd = std::same_as<std::remove_cvref_t<t>, trace_directions> || simd_concept<t>;
43
55template <typename t>
56concept affine_score_cell = tuple_like<t> && std::tuple_size_v<t> == 3
57 && arithmetic_or_simd<std::remove_reference_t<std::tuple_element_t<0, t>>>
58 && arithmetic_or_simd<std::remove_reference_t<std::tuple_element_t<1, t>>>
59 && arithmetic_or_simd<std::remove_reference_t<std::tuple_element_t<2, t>>>;
61
73template <typename t>
74concept affine_trace_cell = tuple_like<t> && std::tuple_size_v<t> == 3
75 && tracedirections_or_simd<std::remove_reference_t<std::tuple_element_t<0, t>>>
76 && tracedirections_or_simd<std::remove_reference_t<std::tuple_element_t<1, t>>>
77 && tracedirections_or_simd<std::remove_reference_t<std::tuple_element_t<2, t>>>;
79
91template <typename t>
92concept affine_score_and_trace_cell =
93 tuple_like<t> && std::tuple_size_v<t> == 2
94 && affine_score_cell<std::tuple_element_t<0, t>> && affine_trace_cell<std::tuple_element_t<1, t>>;
96
111template <typename tuple_t>
112 requires (affine_score_cell<tuple_t> || affine_score_and_trace_cell<tuple_t>)
113class affine_cell_proxy : public tuple_t
114{
115private:
117 using score_cell_type = std::conditional_t<affine_score_cell<tuple_t>, tuple_t, std::tuple_element_t<0, tuple_t>>;
119 using trace_cell_type =
120 std::conditional_t<affine_score_and_trace_cell<tuple_t>, std::tuple_element_t<1, tuple_t>, empty_type>;
121
122public:
126 affine_cell_proxy() = default;
127 affine_cell_proxy(affine_cell_proxy const &) = default;
128 affine_cell_proxy(affine_cell_proxy &&) = default;
129 affine_cell_proxy & operator=(affine_cell_proxy const &) = default;
130 affine_cell_proxy & operator=(affine_cell_proxy &&) = default;
131 ~affine_cell_proxy() = default;
132
133 // Inherit the base class's constructor to enable element-wise initialisation (direct and converting constructor).
134 using tuple_t::tuple_t;
135
137 template <typename other_tuple_t>
138 requires std::constructible_from<tuple_t, other_tuple_t &&>
139 explicit affine_cell_proxy(other_tuple_t && other) : tuple_t{std::forward<other_tuple_t>(other)}
140 {}
141
143 template <typename other_tuple_t>
144 requires std::constructible_from<tuple_t, other_tuple_t const &>
145 explicit affine_cell_proxy(affine_cell_proxy<other_tuple_t> const & other) :
146 tuple_t{static_cast<other_tuple_t const &>(other)}
147 {}
148
150 template <typename other_tuple_t>
151 requires std::constructible_from<tuple_t, other_tuple_t>
152 explicit affine_cell_proxy(affine_cell_proxy<other_tuple_t> && other) :
153 tuple_t{static_cast<other_tuple_t &&>(std::move(other))}
154 {}
155
157 template <typename other_tuple_t>
158 requires std::assignable_from<tuple_t &, other_tuple_t &&>
159 affine_cell_proxy & operator=(other_tuple_t && other)
160 {
161 as_base() = std::forward<other_tuple_t>(other);
162 return *this;
163 }
164
166 template <typename other_tuple_t>
167 requires std::assignable_from<tuple_t &, other_tuple_t const &>
168 affine_cell_proxy & operator=(affine_cell_proxy<other_tuple_t> const & other)
169 {
170 as_base() = static_cast<other_tuple_t const &>(other);
171 return *this;
172 }
173
175 template <typename other_tuple_t>
176 requires std::assignable_from<tuple_t &, other_tuple_t>
177 affine_cell_proxy & operator=(affine_cell_proxy<other_tuple_t> && other)
178 {
179 as_base() = static_cast<other_tuple_t &&>(std::move(other));
180 return *this;
181 }
183
189 decltype(auto) best_score() & noexcept
190 {
191 return get_score_impl<0>(*this);
192 }
194 decltype(auto) best_score() const & noexcept
195 {
196 return get_score_impl<0>(*this);
197 }
199 decltype(auto) best_score() && noexcept
200 {
201 return get_score_impl<0>(std::move(*this));
202 }
204 decltype(auto) best_score() const && noexcept
205 {
206 return get_score_impl<0>(std::move(*this));
207 }
208
210 decltype(auto) horizontal_score() & noexcept
211 {
212 return get_score_impl<1>(*this);
213 }
215 decltype(auto) horizontal_score() const & noexcept
216 {
217 return get_score_impl<1>(*this);
218 }
220 decltype(auto) horizontal_score() && noexcept
221 {
222 return get_score_impl<1>(std::move(*this));
223 }
225 decltype(auto) horizontal_score() const && noexcept
226 {
227 return get_score_impl<1>(std::move(*this));
228 }
229
231 decltype(auto) vertical_score() & noexcept
232 {
233 return get_score_impl<2>(*this);
234 }
236 decltype(auto) vertical_score() const & noexcept
237 {
238 return get_score_impl<2>(*this);
239 }
241 decltype(auto) vertical_score() && noexcept
242 {
243 return get_score_impl<2>(std::move(*this));
244 }
246 decltype(auto) vertical_score() const && noexcept
247 {
248 return get_score_impl<2>(std::move(*this));
249 }
251
257 decltype(auto) best_trace() & noexcept
258 requires affine_score_and_trace_cell<tuple_t>
259 {
260 return get_trace_impl<0>(*this);
261 }
263 decltype(auto) best_trace() const & noexcept
264 requires affine_score_and_trace_cell<tuple_t>
265 {
266 return get_trace_impl<0>(*this);
267 }
269 decltype(auto) best_trace() && noexcept
270 requires affine_score_and_trace_cell<tuple_t>
271 {
272 return get_trace_impl<0>(std::move(*this));
273 }
275 decltype(auto) best_trace() const && noexcept
276 requires affine_score_and_trace_cell<tuple_t>
277 {
278 return get_trace_impl<0>(std::move(*this));
279 }
280
282 decltype(auto) horizontal_trace() & noexcept
283 requires affine_score_and_trace_cell<tuple_t>
284 {
285 return get_trace_impl<1>(*this);
286 }
288 decltype(auto) horizontal_trace() const & noexcept
289 requires affine_score_and_trace_cell<tuple_t>
290 {
291 return get_trace_impl<1>(*this);
292 }
294 decltype(auto) horizontal_trace() && noexcept
295 requires affine_score_and_trace_cell<tuple_t>
296 {
297 return get_trace_impl<1>(std::move(*this));
298 }
300 decltype(auto) horizontal_trace() const && noexcept
301 requires affine_score_and_trace_cell<tuple_t>
302 {
303 return get_trace_impl<1>(std::move(*this));
304 }
305
307 decltype(auto) vertical_trace() & noexcept
308 requires affine_score_and_trace_cell<tuple_t>
309 {
310 return get_trace_impl<2>(*this);
311 }
313 decltype(auto) vertical_trace() const & noexcept
314 requires affine_score_and_trace_cell<tuple_t>
315 {
316 return get_trace_impl<2>(*this);
317 }
319 decltype(auto) vertical_trace() && noexcept
320 requires affine_score_and_trace_cell<tuple_t>
321 {
322 return get_trace_impl<2>(std::move(*this));
323 }
325 decltype(auto) vertical_trace() const && noexcept
326 requires affine_score_and_trace_cell<tuple_t>
327 {
328 return get_trace_impl<2>(std::move(*this));
329 }
331
332private:
341 template <size_t index, typename this_t>
342 requires (index < 3)
343 static constexpr decltype(auto) get_score_impl(this_t && me) noexcept
344 {
345 using std::get;
346
347 if constexpr (affine_score_cell<tuple_t>)
348 return get<index>(std::forward<this_t>(me));
349 else
350 return get<index>(get<0>(std::forward<this_t>(me)));
351 }
352
361 template <size_t index, typename this_t>
362 requires (index < 3 && affine_score_and_trace_cell<tuple_t>)
363 static constexpr decltype(auto) get_trace_impl(this_t && me) noexcept
364 {
365 using std::get;
366
367 return get<index>(get<1>(std::forward<this_t>(me)));
368 }
369
371 tuple_t & as_base() & noexcept
372 {
373 return static_cast<tuple_t &>(*this);
374 }
375};
376} // namespace seqan3::detail
377
378namespace std
379{
381template <typename tuple_t>
382 requires (seqan3::detail::affine_score_cell<tuple_t> || seqan3::detail::affine_score_and_trace_cell<tuple_t>)
383struct tuple_size<seqan3::detail::affine_cell_proxy<tuple_t>> : public tuple_size<tuple_t>
384{};
385
386template <size_t index, typename tuple_t>
387 requires (seqan3::detail::affine_score_cell<tuple_t> || seqan3::detail::affine_score_and_trace_cell<tuple_t>)
388struct tuple_element<index, seqan3::detail::affine_cell_proxy<tuple_t>> : public tuple_element<index, tuple_t>
389{};
391} // 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)
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::tuple_like.
Hide me