SeqAn3 3.4.0-rc.1
The Modern C++ library for sequence analysis.
Loading...
Searching...
No Matches
alphabet_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
21
22namespace seqan3
23{
24
54template <typename derived_type, writable_semialphabet alphabet_type>
55 requires std::regular<alphabet_type>
57 public std::conditional_t<std::is_class_v<alphabet_type>,
58 alphabet_type,
59 alphabet_base<derived_type,
60 alphabet_size<alphabet_type>,
61 detail::valid_template_spec_or_t<void, alphabet_char_t, alphabet_type>>>
62{
63private:
65 using base_t =
67 alphabet_type, // inherit from emulated type if possible
68 alphabet_base<derived_type, // else: alphabet_base
69 alphabet_size<alphabet_type>,
70 detail::valid_template_spec_or_t<void, alphabet_char_t, alphabet_type>>>;
71
73 friend base_t;
74
76 using char_type = detail::valid_template_spec_or_t<char, alphabet_char_t, alphabet_type>;
77
79 using phred_type = detail::valid_template_spec_or_t<int8_t, alphabet_phred_t, alphabet_type>;
80
81private:
85 constexpr alphabet_proxy() noexcept = default;
86 constexpr alphabet_proxy(alphabet_proxy const &) = default;
87 constexpr alphabet_proxy(alphabet_proxy &&) = default;
88 constexpr alphabet_proxy & operator=(alphabet_proxy const &) = default;
89 constexpr alphabet_proxy & operator=(alphabet_proxy &&) = default;
90 ~alphabet_proxy() = default;
91
93 constexpr alphabet_proxy(alphabet_type const a) noexcept
94 requires std::is_class_v<alphabet_type>
95 : base_t{a}
96 {}
97
99 constexpr alphabet_proxy(alphabet_type const a) noexcept
100 requires (!std::is_class_v<alphabet_type>)
101 : base_t{}
102 {
103 base_t::assign_rank(seqan3::to_rank(a));
104 }
105
107 constexpr derived_type & operator=(alphabet_type const & c) noexcept
108 {
109 if constexpr (std::is_class_v<alphabet_type>)
110 seqan3::assign_rank_to(seqan3::to_rank(c), static_cast<alphabet_type &>(*this));
111 else
112 base_t::assign_rank(seqan3::to_rank(c));
113
114 static_cast<derived_type &>(*this).on_update(); // <- this invokes the actual proxy behaviour!
115 return static_cast<derived_type &>(*this);
116 }
117
119 template <typename indirect_assignable_type>
120 constexpr derived_type & operator=(indirect_assignable_type const & c) noexcept
122 {
123 alphabet_type a{};
124 a = c;
125 return operator=(a);
126 }
128
130 friend derived_type;
131
132public:
134 static constexpr auto alphabet_size = seqan3::alphabet_size<alphabet_type>;
135
142 constexpr derived_type & assign_rank(alphabet_rank_t<alphabet_type> const r) noexcept
143 {
144 alphabet_type tmp{};
145 assign_rank_to(r, tmp);
146 return operator=(tmp);
147 }
148
150 constexpr derived_type & assign_char(char_type const c) noexcept
152 {
153 alphabet_type tmp{};
154 assign_char_to(c, tmp);
155 return operator=(tmp);
156 }
157
159 constexpr derived_type & assign_phred(phred_type const c) noexcept
161 {
162 alphabet_type tmp{};
163 assign_phred_to(c, tmp);
164 return operator=(tmp);
165 }
167
173 constexpr operator alphabet_type() const noexcept
174 {
175 if constexpr (std::is_class_v<alphabet_type>)
176 return *this;
177 else
178 return assign_rank_to(base_t::to_rank(), alphabet_type{});
179
180 /* Instead of static_cast'ing to the alphabet_type which also considers the constructors of the alphabet_type,
181 * we explicitly invoke this operator in various places.
182 * This prevents errors associated with using alphabet_type's constructors.
183 *
184 * This is one of error cases:
185 * The tuple composite seqan3::qualified returns a component_proxy which inherits from alphabet_proxy_base.
186 * The qualified alphabet itself inherits from phred_base.
187 * Now when accessing get<1>(seq_qual_alph) we want to call to_phred at some point because we want the quality,
188 * therefore the to_phred function from alphabet_proxy is called, but this function did a static_cast to the
189 * derived type which is calling the constructor from phred_base. Unfortunately now, the generic phred_base
190 * constructor uses `assign_phred_to(to_phred(other), static_cast<derived_type &>(*this))`; (here) which again
191 * tries to call to_phred of the alphabet_proxy => infinite loop :boom:
192 */
193 }
194
196 template <typename other_t>
197 requires (!std::is_class_v<alphabet_type>) && std::convertible_to<alphabet_type, other_t>
198 constexpr operator other_t() const noexcept
199 {
200 return operator alphabet_type();
201 }
202
204 constexpr auto to_rank() const noexcept
205 {
206 return seqan3::to_rank(operator alphabet_type());
207 }
208
210 constexpr auto to_char() const noexcept
211 requires alphabet<alphabet_type>
212 {
213 return seqan3::to_char(operator alphabet_type());
214 }
215
217 constexpr auto to_phred() const noexcept
218 requires quality_alphabet<alphabet_type>
219 {
220 return seqan3::to_phred(operator alphabet_type());
221 }
222
224 constexpr alphabet_type complement() const noexcept
225 requires nucleotide_alphabet<alphabet_type>
226 {
227 return seqan3::complement(operator alphabet_type());
228 }
229
231 static constexpr bool char_is_valid(char_type const c) noexcept
233 {
234 return char_is_valid_for<alphabet_type>(c);
235 }
237
244private:
246 template <typename t>
247 static constexpr bool is_alphabet_comparable_with =
248 !std::is_same_v<derived_type, t> && detail::weakly_equality_comparable_with<alphabet_type, t>;
249
250public:
252 template <typename t>
253 friend constexpr auto operator==(derived_type const lhs, t const rhs) noexcept
255 {
256 return (lhs.operator alphabet_type() == rhs);
257 }
258
260 template <typename t>
261 friend constexpr auto operator==(t const lhs, derived_type const rhs) noexcept
263 {
264 return (rhs == lhs);
265 }
266
268 template <typename t>
269 friend constexpr auto operator!=(derived_type const lhs, t const rhs) noexcept
271 {
272 return !(lhs == rhs);
273 }
274
276 template <typename t>
277 friend constexpr auto operator!=(t const lhs, derived_type const rhs) noexcept
279 {
280 return (rhs != lhs);
281 }
283};
284
285} // namespace seqan3
Provides alphabet helper concepts.
Provides seqan3::nucleotide_alphabet.
Quality alphabet concept.
Provides seqan3::alphabet_base.
Provides various type traits on generic types.
A CRTP-base that makes defining a custom alphabet easier.
Definition alphabet_base.hpp:54
A CRTP-base that eases the definition of proxy types returned in place of regular alphabets.
Definition alphabet_proxy.hpp:62
friend constexpr auto operator!=(derived_type const lhs, t const rhs) noexcept -> std::enable_if_t< is_alphabet_comparable_with< t >, bool >
Allow (in-)equality comparison with types that the emulated type is comparable with.
Definition alphabet_proxy.hpp:269
constexpr derived_type & assign_char(char_type const c) noexcept
Assigns a character.
Definition alphabet_proxy.hpp:150
constexpr derived_type & assign_rank(alphabet_rank_t< alphabet_type > const r) noexcept
Assigns a rank.
Definition alphabet_proxy.hpp:142
static constexpr auto alphabet_size
The alphabet size.
Definition alphabet_proxy.hpp:134
constexpr derived_type & assign_phred(phred_type const c) noexcept
Assigns a Phred score.
Definition alphabet_proxy.hpp:159
friend constexpr auto operator!=(t const lhs, derived_type const rhs) noexcept -> std::enable_if_t< is_alphabet_comparable_with< t >, bool >
Allow (in-)equality comparison with types that the emulated type is comparable with.
Definition alphabet_proxy.hpp:277
friend constexpr auto operator==(t const lhs, derived_type const rhs) noexcept -> std::enable_if_t< is_alphabet_comparable_with< t >, bool >
Allow (in-)equality comparison with types that the emulated type is comparable with.
Definition alphabet_proxy.hpp:261
friend constexpr auto operator==(derived_type const lhs, t const rhs) noexcept -> std::enable_if_t< is_alphabet_comparable_with< t >, bool >
Allow (in-)equality comparison with types that the emulated type is comparable with.
Definition alphabet_proxy.hpp:253
constexpr alphabet_type complement() const noexcept
Returns the complement.
Definition alphabet_proxy.hpp:224
constexpr auto to_char() const noexcept
Returns the character.
Definition alphabet_proxy.hpp:210
constexpr auto to_phred() const noexcept
Returns the Phred score.
Definition alphabet_proxy.hpp:217
constexpr auto to_rank() const noexcept
Returns the rank.
Definition alphabet_proxy.hpp:204
static constexpr bool char_is_valid(char_type const c) noexcept
Delegate to the emulated type's validator.
Definition alphabet_proxy.hpp:231
constexpr auto complement
Return the complement of a nucleotide object.
Definition alphabet/nucleotide/concept.hpp:102
constexpr auto to_phred
The public getter function for the Phred representation of a quality score.
Definition alphabet/quality/concept.hpp:97
constexpr auto assign_phred_to
Assign a Phred score to a quality alphabet object.
Definition alphabet/quality/concept.hpp:227
constexpr auto assign_char_to
Assign a character to an alphabet object.
Definition alphabet/concept.hpp:521
constexpr auto to_char
Return the char representation of an alphabet object.
Definition alphabet/concept.hpp:383
decltype(seqan3::to_rank(std::declval< semi_alphabet_type >())) alphabet_rank_t
The rank_type of the semi-alphabet; defined as the return type of seqan3::to_rank....
Definition alphabet/concept.hpp:166
constexpr auto assign_rank_to
Assign a rank to an alphabet object.
Definition alphabet/concept.hpp:290
constexpr auto to_rank
Return the rank representation of a (semi-)alphabet object.
Definition alphabet/concept.hpp:152
The generic alphabet concept that covers most data types used in ranges.
A concept that indicates whether an alphabet represents nucleotides.
A concept that indicates whether an alphabet represents quality scores.
Resolves to std::is_assignable_v<t>.
Refines seqan3::alphabet and adds assignability.
A concept that indicates whether a writable alphabet represents quality scores.
The main SeqAn3 namespace.
Definition aligned_sequence_concept.hpp:26
Provides type traits for working with templates.
Provides concepts that do not have equivalents in C++20.
Hide me