SeqAn3  3.0.0
The Modern C++ library for sequence analysis.
alphabet_base.hpp
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------------------------------
2 // Copyright (c) 2006-2019, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2019, 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 
18 #include <seqan3/std/concepts>
19 #include <seqan3/std/type_traits>
20 
21 namespace seqan3
22 {
23 
51 template <typename derived_type, size_t size, typename char_t = char>
53 {
54 protected:
55  static_assert(size != 0, "Alphabet size must be >= 1"); // == 1 is handled below in separate specialisation
56 
65 
66 public:
70  constexpr alphabet_base() noexcept = default;
71  constexpr alphabet_base(alphabet_base const &) noexcept = default;
72  constexpr alphabet_base(alphabet_base &&) noexcept = default;
73  constexpr alphabet_base & operator=(alphabet_base const &) noexcept = default;
74  constexpr alphabet_base & operator=(alphabet_base &&) noexcept = default;
75  ~alphabet_base() noexcept = default;
76 
95  constexpr char_type to_char() const noexcept
97  requires !std::Same<char_t, void>
99  {
100  return derived_type::rank_to_char[rank];
101  }
102 
117  constexpr rank_type to_rank() const noexcept
118  {
119  return rank;
120  }
122 
141  constexpr derived_type & assign_char(char_type const c) noexcept
143  requires !std::Same<char_t, void>
145  {
146  using index_t = std::make_unsigned_t<char_type>;
147  rank = derived_type::char_to_rank[static_cast<index_t>(c)];
148  return static_cast<derived_type &>(*this);
149  }
150 
166  constexpr derived_type & assign_rank(rank_type const c) noexcept
167  {
168  assert(static_cast<size_t>(c) < static_cast<size_t>(alphabet_size));
169  rank = c;
170  return static_cast<derived_type &>(*this);
171  }
173 
176 
179  friend constexpr bool operator==(derived_type const lhs, derived_type const rhs) noexcept
180  {
181  using seqan3::to_rank;
182  return to_rank(lhs) == to_rank(rhs);
183  }
184 
185  friend constexpr bool operator!=(derived_type const lhs, derived_type const rhs) noexcept
186  {
187  using seqan3::to_rank;
188  return to_rank(lhs) != to_rank(rhs);
189  }
190 
191  friend constexpr bool operator<(derived_type const lhs, derived_type const rhs) noexcept
192  {
193  using seqan3::to_rank;
194  return to_rank(lhs) < to_rank(rhs);
195  }
196 
197  friend constexpr bool operator>(derived_type const lhs, derived_type const rhs) noexcept
198  {
199  using seqan3::to_rank;
200  return to_rank(lhs) > to_rank(rhs);
201  }
202 
203  friend constexpr bool operator<=(derived_type const lhs, derived_type const rhs) noexcept
204  {
205  using seqan3::to_rank;
206  return to_rank(lhs) <= to_rank(rhs);
207  }
208 
209  friend constexpr bool operator>=(derived_type const lhs, derived_type const rhs) noexcept
210  {
211  using seqan3::to_rank;
212  return to_rank(lhs) >= to_rank(rhs);
213  }
215 
216 private:
218  rank_type rank{};
219 };
220 
232 template <typename derived_type, typename char_t>
233 class alphabet_base<derived_type, 1ul, char_t>
234 {
235 protected:
242  using rank_type = bool;
244 
245 public:
249  constexpr alphabet_base() noexcept = default;
250  constexpr alphabet_base(alphabet_base const &) noexcept = default;
251  constexpr alphabet_base(alphabet_base &&) noexcept = default;
252  constexpr alphabet_base & operator=(alphabet_base const &) noexcept = default;
253  constexpr alphabet_base & operator=(alphabet_base &&) noexcept = default;
254  ~alphabet_base() noexcept = default;
255 
260  constexpr char_type to_char() const noexcept
263  requires !std::Same<char_t, void>
265  {
266  return derived_type::char_value;
267  }
268 
270  constexpr rank_type to_rank() const noexcept
271  {
272  return 0;
273  }
275 
279  constexpr derived_type & assign_char(char_type const) noexcept
282  requires !std::Same<char_t, void>
284  {
285  return static_cast<derived_type &>(*this);
286  }
287 
289  constexpr derived_type & assign_rank(rank_type const) noexcept
290  {
291  return static_cast<derived_type &>(*this);
292  }
294 
296  static constexpr bool alphabet_size = 1;
297 
300  friend constexpr bool operator==(derived_type const, derived_type const) noexcept
301  {
302  return true;
303  }
304 
305  friend constexpr bool operator!=(derived_type const, derived_type const) noexcept
306  {
307  return false;
308  }
309 
310  friend constexpr bool operator<(derived_type const, derived_type const) noexcept
311  {
312  return false;
313  }
314 
315  friend constexpr bool operator>(derived_type const, derived_type const) noexcept
316  {
317  return false;
318  }
319 
320  friend constexpr bool operator<=(derived_type const, derived_type const) noexcept
321  {
322  return true;
323  }
324 
325  friend constexpr bool operator>=(derived_type const, derived_type const) noexcept
326  {
327  return true;
328  }
330 
331 private:
332 #if SEQAN3_WORKAROUND_GCC_87113
333  bool _bug_workaround{};
334 #endif
335 };
336 
337 } // 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:63
constexpr derived_type & assign_rank(rank_type const) noexcept
Assign from a numeric value.
Definition: alphabet_base.hpp:289
Provides metaprogramming utilities for integer types.
constexpr auto to_rank
Return the rank representation of a (semi-)alphabet object.
Definition: concept.hpp:103
SeqAn specific customisations in the standard namespace.
::ranges::size size
Alias for ranges::size. Obtains the size of a range whose size can be calculated in constant time...
Definition: ranges:189
The main SeqAn3 namespace.
constexpr derived_type & assign_rank(rank_type const c) noexcept
Assign from a numeric value.
Definition: alphabet_base.hpp:166
The Concepts library.
constexpr alphabet_base() noexcept=default
Defaulted.
constexpr char_type to_char() const noexcept
Return the letter as a character of char_type.
Definition: alphabet_base.hpp:95
constexpr rank_type to_rank() const noexcept
Return the letter&#39;s numeric value (rank in the alphabet).
Definition: alphabet_base.hpp:270
static detail::min_viable_uint_t< size > constexpr alphabet_size
The size of the alphabet, i.e. the number of different values it can take.
Definition: alphabet_base.hpp:175
Provides C++20 additions to the type_traits header.
constexpr rank_type to_rank() const noexcept
Return the letter&#39;s numeric value (rank in the alphabet).
Definition: alphabet_base.hpp:117
Core alphabet concept and free function/type trait wrappers.
A CRTP-base that makes defining a custom alphabet easier.
Definition: alphabet_base.hpp:52
Static reflection for arbitrary types.
The concept std::Same<T, U> is satisfied if and only if T and U denote the same type.
constexpr derived_type & assign_char(char_type const c) noexcept
Assign from a character, implicitly converts invalid characters.
Definition: alphabet_base.hpp:141
std::conditional_t< std::Same< char_t, void >, char, char_t > char_type
The char representation; conditional needed to make semi alphabet definitions legal.
Definition: alphabet_base.hpp:61
bool rank_type
The type of the alphabet when represented as a number (e.g. via to_rank()).
Definition: alphabet_base.hpp:242