SeqAn3 3.2.0
The Modern C++ library for sequence analysis.
alphabet_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
24
25namespace seqan3
26{
27
57template <typename derived_type, writable_semialphabet alphabet_type>
58 requires std::regular<alphabet_type>
60 public std::conditional_t<std::is_class_v<alphabet_type>,
61 alphabet_type,
62 alphabet_base<derived_type,
63 alphabet_size<alphabet_type>,
64 detail::valid_template_spec_or_t<void, alphabet_char_t, alphabet_type>>>
65{
66private:
68 using base_t =
70 alphabet_type, // inherit from emulated type if possible
71 alphabet_base<derived_type, // else: alphabet_base
72 alphabet_size<alphabet_type>,
73 detail::valid_template_spec_or_t<void, alphabet_char_t, alphabet_type>>>;
74
76 friend base_t;
77
79 using char_type = detail::valid_template_spec_or_t<char, alphabet_char_t, alphabet_type>;
80
82 using phred_type = detail::valid_template_spec_or_t<int8_t, alphabet_phred_t, alphabet_type>;
83
84private:
88 constexpr alphabet_proxy() noexcept = default;
89 constexpr alphabet_proxy(alphabet_proxy const &) = default;
90 constexpr alphabet_proxy(alphabet_proxy &&) = default;
91 constexpr alphabet_proxy & operator=(alphabet_proxy const &) = default;
92 constexpr alphabet_proxy & operator=(alphabet_proxy &&) = default;
93 ~alphabet_proxy() = default;
94
96 constexpr alphabet_proxy(alphabet_type const a) noexcept
97 requires std::is_class_v<alphabet_type>
98 : base_t{a}
99 {}
100
102 constexpr alphabet_proxy(alphabet_type const a) noexcept
103 requires (!std::is_class_v<alphabet_type>)
104 : base_t{}
105 {
106 base_t::assign_rank(seqan3::to_rank(a));
107 }
108
110 constexpr derived_type & operator=(alphabet_type const & c) noexcept
111 {
112 if constexpr (std::is_class_v<alphabet_type>)
113 seqan3::assign_rank_to(seqan3::to_rank(c), static_cast<alphabet_type &>(*this));
114 else
115 base_t::assign_rank(seqan3::to_rank(c));
116
117 static_cast<derived_type &>(*this).on_update(); // <- this invokes the actual proxy behaviour!
118 return static_cast<derived_type &>(*this);
119 }
120
122 template <typename indirect_assignable_type>
123 constexpr derived_type & operator=(indirect_assignable_type const & c) noexcept
125 {
126 alphabet_type a{};
127 a = c;
128 return operator=(a);
129 }
131
133 friend derived_type;
134
135public:
137 static constexpr auto alphabet_size = seqan3::alphabet_size<alphabet_type>;
138
145 constexpr derived_type & assign_rank(alphabet_rank_t<alphabet_type> const r) noexcept
146 {
147 alphabet_type tmp{};
148 assign_rank_to(r, tmp);
149 return operator=(tmp);
150 }
151
153 constexpr derived_type & assign_char(char_type const c) noexcept
155 {
156 alphabet_type tmp{};
157 assign_char_to(c, tmp);
158 return operator=(tmp);
159 }
160
162 constexpr derived_type & assign_phred(phred_type const c) noexcept
164 {
165 alphabet_type tmp{};
166 assign_phred_to(c, tmp);
167 return operator=(tmp);
168 }
170
176 constexpr operator alphabet_type() const noexcept
177 {
178 if constexpr (std::is_class_v<alphabet_type>)
179 return *this;
180 else
181 return assign_rank_to(base_t::to_rank(), alphabet_type{});
182
183 /* Instead of static_cast'ing to the alphabet_type which also considers the constructors of the alphabet_type,
184 * we explicitly invoke this operator in various places.
185 * This prevents errors associated with using alphabet_type's constructors.
186 *
187 * This is one of error cases:
188 * The tuple composite seqan3::qualified returns a component_proxy which inherits from alphabet_proxy_base.
189 * The qualified alphabet itself inherits from phred_base.
190 * Now when accessing get<1>(seq_qual_alph) we want to call to_phred at some point because we want the quality,
191 * therefore the to_phred function from alphabet_proxy is called, but this function did a static_cast to the
192 * derived type which is calling the constructor from phred_base. Unfortunately now, the generic phred_base
193 * constructor uses `assign_phred_to(to_phred(other), static_cast<derived_type &>(*this))`; (here) which again
194 * tries to call to_phred of the alphabet_proxy => infinite loop :boom:
195 */
196 }
197
199 template <typename other_t>
200 requires (!std::is_class_v<alphabet_type>) && std::convertible_to<alphabet_type, other_t>
201 constexpr operator other_t() const noexcept
202 {
203 return operator alphabet_type();
204 }
205
207 constexpr auto to_rank() const noexcept
208 {
209 return seqan3::to_rank(operator alphabet_type());
210 }
211
213 constexpr auto to_char() const noexcept
214 requires alphabet<alphabet_type>
215 {
216 return seqan3::to_char(operator alphabet_type());
217 }
218
220 constexpr auto to_phred() const noexcept
221 requires quality_alphabet<alphabet_type>
222 {
223 return seqan3::to_phred(operator alphabet_type());
224 }
225
227 constexpr alphabet_type complement() const noexcept
228 requires nucleotide_alphabet<alphabet_type>
229 {
230 return seqan3::complement(operator alphabet_type());
231 }
232
234 static constexpr bool char_is_valid(char_type const c) noexcept
236 {
237 return char_is_valid_for<alphabet_type>(c);
238 }
240
247private:
249 template <typename t>
250 static constexpr bool is_alphabet_comparable_with =
251 !std::is_same_v<derived_type, t> && detail::weakly_equality_comparable_with<alphabet_type, t>;
252
253public:
255 template <typename t>
256 friend constexpr auto operator==(derived_type const lhs, t const rhs) noexcept
258 {
259 return (lhs.operator alphabet_type() == rhs);
260 }
261
263 template <typename t>
264 friend constexpr auto operator==(t const lhs, derived_type const rhs) noexcept
266 {
267 return (rhs == lhs);
268 }
269
271 template <typename t>
272 friend constexpr auto operator!=(derived_type const lhs, t const rhs) noexcept
274 {
275 return !(lhs == rhs);
276 }
277
279 template <typename t>
280 friend constexpr auto operator!=(t const lhs, derived_type const rhs) noexcept
282 {
283 return (rhs != lhs);
284 }
286};
287
288} // 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:57
A CRTP-base that eases the definition of proxy types returned in place of regular alphabets.
Definition: alphabet_proxy.hpp:65
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:272
constexpr derived_type & assign_char(char_type const c) noexcept
Assigns a character.
Definition: alphabet_proxy.hpp:153
constexpr derived_type & assign_rank(alphabet_rank_t< alphabet_type > const r) noexcept
Assigns a rank.
Definition: alphabet_proxy.hpp:145
static constexpr auto alphabet_size
The alphabet size.
Definition: alphabet_proxy.hpp:137
constexpr derived_type & assign_phred(phred_type const c) noexcept
Assigns a Phred score.
Definition: alphabet_proxy.hpp:162
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:280
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:264
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:256
constexpr alphabet_type complement() const noexcept
Returns the complement.
Definition: alphabet_proxy.hpp:227
constexpr auto to_char() const noexcept
Returns the character.
Definition: alphabet_proxy.hpp:213
constexpr auto to_phred() const noexcept
Returns the Phred score.
Definition: alphabet_proxy.hpp:220
constexpr auto to_rank() const noexcept
Returns the rank.
Definition: alphabet_proxy.hpp:207
static constexpr bool char_is_valid(char_type const c) noexcept
Delegate to the emulated type's validator.
Definition: alphabet_proxy.hpp:234
constexpr auto complement
Return the complement of a nucleotide object.
Definition: concept.hpp:105
constexpr auto to_phred
The public getter function for the Phred representation of a quality score.
Definition: concept.hpp:100
constexpr auto assign_phred_to
Assign a Phred score to a quality alphabet object.
Definition: concept.hpp:230
constexpr auto assign_char_to
Assign a character to an alphabet object.
Definition: concept.hpp:524
constexpr auto to_char
Return the char representation of an alphabet object.
Definition: concept.hpp:386
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: concept.hpp:169
constexpr auto assign_rank_to
Assign a rank to an alphabet object.
Definition: concept.hpp:293
constexpr auto to_rank
Return the rank representation of a (semi-)alphabet object.
Definition: concept.hpp:155
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:29
Provides type traits for working with templates.
Provides concepts that do not have equivalents in C++20.