SeqAn3
alphabet_proxy.hpp
Go to the documentation of this file.
1 // ============================================================================
2 // SeqAn - The Library for Sequence Analysis
3 // ============================================================================
4 //
5 // Copyright (chr) 2006-2018, Knut Reinert & Freie Universitaet Berlin
6 // Copyright (chr) 2016-2018, Knut Reinert & MPI Molekulare Genetik
7 // All rights reserved.
8 //
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions are met:
11 //
12 // * Redistributions of source code must retain the above copyright
13 // notice, this list of conditions and the following disclaimer.
14 // * Redistributions in binary form must reproduce the above copyright
15 // notice, this list of conditions and the following disclaimer in the
16 // documentation and/or other materials provided with the distribution.
17 // * Neither the name of Knut Reinert or the FU Berlin nor the names of
18 // its contributors may be used to endorse or promote products derived
19 // from this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 // ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
25 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
31 // DAMAGE.
32 //
33 // ============================================================================
34 
42 #pragma once
43 
49 #include <seqan3/std/concepts>
50 
51 namespace seqan3
52 {
53 #if 0 // this is the alphabet_proxy I want, but GCC won't give me:
54 template <typename derived_type, typename alphabet_type>
55 class alphabet_proxy : public alphabet_type
56 {
57 public:
58  using base_t = alphabet_type;
59 
60  using base_t::value_size;
61  using typename base_t::rank_type;
62  using char_type = detail::transformation_trait_or_t<underlying_char<alphabet_type>, void>;
63  using phred_type = detail::transformation_trait_or_t<underlying_phred<alphabet_type>, void>;
64 
65  using char_type_virtual = std::conditional_t<std::Same<char_type, void>, char, char_type>;
66  using phred_type_virtual = std::conditional_t<std::Same<phred_type, void>, int8_t, phred_type>;
67 
68  constexpr alphabet_proxy() : base_t{} {}
69  constexpr alphabet_proxy(alphabet_proxy const &) = default;
70  constexpr alphabet_proxy(alphabet_proxy &&) = default;
71  constexpr alphabet_proxy & operator=(alphabet_proxy const &) = default;
72  constexpr alphabet_proxy & operator=(alphabet_proxy &&) = default;
73  ~alphabet_proxy() = default;
74 
75  constexpr alphabet_proxy(alphabet_type const a) :
76  base_t{a}
77  {}
78 
79  constexpr alphabet_proxy & operator=(alphabet_type const & c) noexcept
80  {
82  static_cast<derived_type &>(*this).on_update(); // <- this invokes the actual proxy behaviour!
83  return *this;
84  }
85 
86  template <typename indirect_assignable_type>
88  constexpr alphabet_proxy & operator=(indirect_assignable_type const & c) noexcept
89  {
90  alphabet_type a{};
91  a = c;
92  return operator=(a);
93  }
94 
95  constexpr alphabet_proxy & assign_char(char_type_virtual const c) noexcept
97  {
98  alphabet_type tmp{};
99  using seqan3::assign_char;
100  assign_char(tmp, c);
101  return operator=(tmp);
102  }
103 
104  constexpr alphabet_proxy & assign_rank(underlying_rank_t<alphabet_type> const r) noexcept
105  {
106  alphabet_type tmp{};
107  using seqan3::assign_rank;
108  assign_rank(tmp, r);
109  return operator=(tmp);
110  }
111 
112  constexpr alphabet_proxy & assign_phred(phred_type_virtual const c) noexcept
114  {
115  alphabet_type tmp{};
116  using seqan3::assign_phred;
117  assign_phred(tmp, c);
118  return operator=(tmp);
119  }
120 };
121 #endif
122 
123 #if 1// this is the one that works for most things, but not all
124 
151 template <typename derived_type, typename alphabet_type>
152 class alphabet_proxy : public alphabet_base<derived_type,
153  alphabet_size_v<alphabet_type>,
154  detail::transformation_trait_or_t<underlying_char<alphabet_type>, void>>
155 {
156 private:
158  using base_t = alphabet_base<derived_type,
159  alphabet_size_v<alphabet_type>,
160  detail::transformation_trait_or_t<underlying_char<alphabet_type>, void>>;
161 
163  friend base_t;
164 
165 public:
166  // Import from base:
167  using base_t::value_size;
168  using base_t::to_rank;
169 
173  using rank_type = underlying_rank_t<alphabet_type>;
174  using char_type = detail::transformation_trait_or_t<underlying_char<alphabet_type>, void>;
175  using phred_type = detail::transformation_trait_or_t<underlying_phred<alphabet_type>, void>;
177 
178 private:
180  using char_type_virtual = std::conditional_t<std::Same<char_type, void>, char, char_type>;
182  using phred_type_virtual = std::conditional_t<std::Same<phred_type, void>, int8_t, phred_type>;
183 
187  constexpr alphabet_proxy() noexcept : base_t{} {}
188  constexpr alphabet_proxy(alphabet_proxy const &) = default;
189  constexpr alphabet_proxy(alphabet_proxy &&) = default;
190  constexpr alphabet_proxy & operator=(alphabet_proxy const &) = default;
191  constexpr alphabet_proxy & operator=(alphabet_proxy &&) = default;
192  ~alphabet_proxy() = default;
193 
195  constexpr alphabet_proxy(alphabet_type const a) noexcept
196  {
198  }
199 
201  constexpr derived_type & operator=(alphabet_type const & c) noexcept
202  {
204  static_cast<derived_type &>(*this).on_update(); // <- this invokes the actual proxy behaviour!
205  return static_cast<derived_type &>(*this);
206  }
207 
209  template <typename indirect_assignable_type>
210  constexpr derived_type & operator=(indirect_assignable_type const & c) noexcept
212  {
213  alphabet_type a{};
214  a = c;
215  return operator=(a);
216  }
218 
220  friend derived_type;
221 
222 public:
228  constexpr derived_type & assign_rank(underlying_rank_t<alphabet_type> const r) noexcept
229  {
230  alphabet_type tmp{};
231  using seqan3::assign_rank;
232  assign_rank(tmp, r);
233  return operator=(tmp);
234  }
235 
236  constexpr derived_type & assign_char(char_type_virtual const c) noexcept
238  {
239  alphabet_type tmp{};
240  using seqan3::assign_char;
241  assign_char(tmp, c);
242  return operator=(tmp);
243  }
244 
245  constexpr derived_type & assign_phred(phred_type_virtual const c) noexcept
247  {
248  alphabet_type tmp{};
249  using seqan3::assign_phred;
250  assign_phred(tmp, c);
251  return operator=(tmp);
252  }
254 
259  constexpr operator alphabet_type() const noexcept
261  {
262  using seqan3::assign_rank;
263  return assign_rank(alphabet_type{}, to_rank());
264  }
265 
266  constexpr char_type to_char() const noexcept
268  {
269  using seqan3::to_char;
270  return to_char(static_cast<alphabet_type>(*this));
271  }
272 
273  constexpr phred_type to_phred() const noexcept
275  {
276  using seqan3::to_phred;
277  return to_phred(static_cast<alphabet_type>(*this));
278  }
279 
280 #if 0 // this currently causes GCC ICE in cartesian_composition test
281  constexpr alphabet_type complement() const noexcept
283  {
284  using seqan3::complement;
285  return complement(static_cast<alphabet_type>(*this));
286  }
287 #endif
288 };
290 
291 #endif
292 } // namespace seqan3
detail::min_viable_uint_t< size - 1 > rank_type
The type of the alphabet when represented as a number (e.g. via to_rank()).
Definition: alphabet_base.hpp:89
Provides concepts for core language types and relations that don&#39;t have concepts in C++20 (yet)...
constexpr nucleotide_type complement(nucleotide_type const alph) requires requires(nucleotide_type alph)
Implementation of seqan3::nucleotide_concept::complement() that delegates to a member function...
Definition: member_exposure.hpp:220
A CRTP-base that eases the definition of proxy types returned in place of regular alphabets...
Definition: alphabet_proxy.hpp:152
The concept std::Assignable<LHS, RHS> specifies that an expression of the type and value category spe...
Provides seqan3::detail::transformation_trait_or.
Resolves to std::is_assignable_v<t>.
constexpr underlying_phred_t< alphabet_type > to_phred(alphabet_type const &chr)
The public getter function for the phred representation of a score.
Definition: concept.hpp:127
constexpr alphabet_type & assign_phred(alphabet_type &chr, char const in)
The public setter function of a phred score.
Definition: concept.hpp:102
The generic alphabet concept that covers most data types used in ranges.This is the core alphabet con...
The main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:58
A concept that indicates whether an alphabet represents quality scores.In addition to the requirement...
constexpr derived_type & assign_rank(rank_type const c) noexcept
Assign from a numeric value.
Definition: alphabet_base.hpp:189
static detail::min_viable_uint_t< size > constexpr value_size
The size of the alphabet, i.e. the number of different values it can take.
Definition: alphabet_base.hpp:198
constexpr alphabet_type & assign_rank(alphabet_type &alph, underlying_rank_t< alphabet_type > const rank) requires requires(alphabet_type alph)
Implementation of seqan3::semi_alphabet_concept::assign_rank() that delegates to a member function...
Definition: member_exposure.hpp:110
Provides seqan3::nucleotide_concept.
The Concepts library.
Provides seqan3::alphabet_base.
The concept std::Same<T, U> is satisfied if and only if T and U denote the same type.
constexpr rank_type to_rank() const noexcept
Return the letter&#39;s numeric value (rank in the alphabet).
Definition: alphabet_base.hpp:142
constexpr alphabet_type & assign_char(alphabet_type &alph, underlying_char_t< alphabet_type > const chr) requires requires(alphabet_type alph)
Implementation of seqan3::alphabet_concept::assign_char() that delegates to a member function...
Definition: member_exposure.hpp:178
A CRTP-base that makes defining a custom alphabet easier.
Definition: alphabet_base.hpp:77
Quality alphabet concept.
constexpr underlying_rank_t< alphabet_type > to_rank(alphabet_type const alph) requires requires(alphabet_type alph)
Implementation of seqan3::semi_alphabet_concept::to_rank() that delegates to a member function...
Definition: member_exposure.hpp:97
constexpr underlying_char_t< alphabet_type > to_char(alphabet_type const alph) requires requires(alphabet_type alph)
Implementation of seqan3::alphabet_concept::to_char() that delegates to a member function.
Definition: member_exposure.hpp:165
A concept that indicates whether an alphabet represents nucleotides.In addition to the requirements f...