SeqAn3
constexpr_string.hpp
Go to the documentation of this file.
1 // ============================================================================
2 // SeqAn - The Library for Sequence Analysis
3 // ============================================================================
4 //
5 // Copyright (c) 2006-2018, Knut Reinert & Freie Universitaet Berlin
6 // Copyright (c) 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 
40 #pragma once
41 
42 #include <array>
43 #include <type_traits>
44 
45 #include <seqan3/core/platform.hpp>
46 
47 namespace seqan3
48 {
49 
64 template <size_t N>
66 {
67 protected:
69  using data_type = std::array<char, N + 1>;
70 
72  template <size_t N2>
73  friend class constexpr_string;
74 
77 
86  template <size_t N1>
87  constexpr constexpr_string(constexpr_string<N1> const & lhs,
88  constexpr_string<N - N1> const & rhs) noexcept
90  {
91  for (unsigned i = 0; i < N1; ++i)
92  lit[i] = lhs[i];
93  for (unsigned i = N1; i < N + 1; ++i)
94  lit[i] = rhs[i - N1];
95  }
96 
97 public:
98 
102  using value_type = char;
103  using reference = char &;
104  using const_reference = const char &;
105  using iterator = std::add_pointer_t<value_type>;
106  using const_iterator = std::add_pointer_t<value_type const>;
107  using difference_type = typename data_type::difference_type;
108  using size_type = typename data_type::size_type;
110 
112  // this signals to range-v3 that something is a container :|
113  using allocator_type = void;
115 
119  constexpr constexpr_string() = default;
122  constexpr constexpr_string(constexpr_string const &) = default;
124  constexpr constexpr_string(constexpr_string &&) = default;
126  constexpr constexpr_string & operator=(constexpr_string const &) = default;
128  constexpr constexpr_string & operator=(constexpr_string &&) = default;
129 
137  constexpr constexpr_string(const char (&_lit)[N + 1]) noexcept
138  : constexpr_string{}
139  {
140  // static_assert(lit[N] == '\0'); TODO(rrahn): Fix me
141  for (unsigned i = 0; i < N + 1; ++i)
142  lit[i] = _lit[i];
143  }
144 
152  constexpr constexpr_string(std::array<char, N> const & src) noexcept
153  : constexpr_string{}
154  {
155  // static_assert(src[N-1] != '\0'); TODO(rrahn): Fix me
156  for (unsigned i = 0; i < N; ++i)
157  lit[i] = src[i];
158  lit[N] = '\0';
159  }
160 
168  constexpr constexpr_string(const char c) noexcept
169  : constexpr_string{}
170  {
171  lit[0] = c;
172  lit[1] = '\0';
173  }
174 
176  ~constexpr_string() = default;
178 
192  constexpr reference operator[](size_t pos) noexcept
193  {
194  return lit[pos];
195  }
196 
207  constexpr const_reference operator[](size_t pos) const noexcept
208  {
209  return lit[pos];
210  }
211 
224  std::string string() const
225  {
226  return std::string{ lit.cbegin(), lit.cend() - 1};
227  }
228 
241  constexpr const char * c_str() const noexcept
242  {
243  return lit.data();
244  }
246 
250  constexpr size_type size() const noexcept
252  {
253  return N;
254  }
255 
257  constexpr size_type max_size() const noexcept
258  {
259  return size();
260  }
261 
263  constexpr bool empty() const noexcept
264  {
265  return cbegin() == cend();
266  }
268 
272  constexpr iterator begin() noexcept
274  {
275  return &lit[0];
276  }
277 
279  constexpr const_iterator begin() const noexcept
280  {
281  return &lit[0];
282  }
283 
285  constexpr const_iterator cbegin() const noexcept
286  {
287  return &lit[0];
288  }
289 
291  constexpr iterator end() noexcept
292  {
293  return &lit[N];
294  }
295 
297  constexpr const_iterator end() const noexcept
298  {
299  return &lit[N];
300  }
301 
303  constexpr const_iterator cend() const noexcept
304  {
305  return &lit[N];
306  }
308 
325  template <size_t N2>
326  constexpr constexpr_string<N + N2> operator+(constexpr_string<N2> const & rhs) const noexcept
327  {
328  return constexpr_string<N + N2>{*this, rhs};
329  }
330 
339  constexpr void swap(constexpr_string & other) noexcept
340  {
341  std::swap(*this, other);
342  }
344 
359  template <size_t N2>
360  constexpr bool operator==(constexpr_string<N2> const & rhs) const noexcept
361  {
362  if constexpr (N != N2)
363  return false;
364 
365  const_iterator it_rhs = rhs.cbegin();
366  for (const_iterator it = cbegin(); it != cend(); ++it, ++it_rhs)
367  {
368  if (*it != *it_rhs)
369  return false;
370  }
371 
372  return true;
373  }
374 
376  template <size_t N2>
377  constexpr bool operator!=(constexpr_string<N2> const & rhs) const noexcept
378  {
379  return !(*this == rhs);
380  }
381 
383  template <size_t N2>
384  constexpr bool operator<(constexpr_string<N2> const & rhs) const noexcept
385  {
386  for (unsigned i = 0; i < ((N < N2) ? N : N2); ++i)
387  {
388  if (lit[i] < rhs.lit[i])
389  return true;
390  else if (lit[i] != rhs.lit[i])
391  return false;
392  }
393  return N < N2;
394  }
395 
397  template <size_t N2>
398  constexpr bool operator<=(constexpr_string<N2> const & rhs) const noexcept
399  {
400  for (unsigned i = 0; i < ((N < N2) ? N : N2); ++i)
401  {
402  if (lit[i] > rhs.lit[i])
403  return false;
404  }
405  return N <= N2;
406  }
407 
409  template <size_t N2>
410  constexpr bool operator>(constexpr_string<N2> const & rhs) const noexcept
411  {
412  return !(*this <= rhs);
413  }
414 
416  template <size_t N2>
417  constexpr bool operator>=(constexpr_string<N2> const & rhs) const noexcept
418  {
419  return !(*this < rhs);
420  }
422 };
423 
441 template <size_t N>
442 constexpr inline void
444 {
445  lhs.swap(rhs);
446 }
448 
452 template <size_t N>
455 constexpr_string(const char (&)[N]) -> constexpr_string<N - 1>;
456 
459 template <size_t N>
460 constexpr_string(std::array<char, N> const &) -> constexpr_string<N>;
461 
466 } // namespace seqan3
constexpr reference operator[](size_t pos) noexcept
Access an element in the string.
Definition: constexpr_string.hpp:192
Contains platform and dependency checks.
constexpr bool empty() const noexcept
Determines whether the string is empty.
Definition: constexpr_string.hpp:263
std::string string() const
Returns the content represented as std::string.
Definition: constexpr_string.hpp:224
constexpr bool operator>=(constexpr_string< N2 > const &rhs) const noexcept
Compares two strings lexicographically.
Definition: constexpr_string.hpp:417
constexpr const_iterator end() const noexcept
Returns iterator pass the end of the string.
Definition: constexpr_string.hpp:297
constexpr const_iterator cbegin() const noexcept
Returns the begin to the string.
Definition: constexpr_string.hpp:285
constexpr constexpr_string< N+N2 > operator+(constexpr_string< N2 > const &rhs) const noexcept
Concatenates two constexpr_strings.
Definition: constexpr_string.hpp:326
The main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:58
constexpr iterator begin() noexcept
Returns the begin to the string.
Definition: constexpr_string.hpp:273
constexpr bool operator>(constexpr_string< N2 > const &rhs) const noexcept
Compares two strings lexicographically.
Definition: constexpr_string.hpp:410
constexpr constexpr_string(const char c) noexcept
Construction from char.
Definition: constexpr_string.hpp:168
constexpr void swap(constexpr_string< N > &lhs, constexpr_string< N > &rhs)
Exchanges the given values.
Definition: constexpr_string.hpp:443
constexpr constexpr_string()=default
Default default constructor.
constexpr const_iterator begin() const noexcept
Returns the begin to the string.
Definition: constexpr_string.hpp:279
constexpr constexpr_string(const char(&_lit)[N+1]) noexcept
Construction from literal.
Definition: constexpr_string.hpp:137
constexpr constexpr_string(std::array< char, N > const &src) noexcept
Construction from char array.
Definition: constexpr_string.hpp:152
constexpr constexpr_string(constexpr_string< N1 > const &lhs, constexpr_string< N - N1 > const &rhs) noexcept
Constructs new constexpr_string by merging two other constexpr_strings.
Definition: constexpr_string.hpp:87
constexpr const_iterator cend() const noexcept
Returns iterator pass the end of the string.
Definition: constexpr_string.hpp:303
std::array< char, N+1 > data_type
Alias for the underlying data type.
Definition: constexpr_string.hpp:69
constexpr const_reference operator[](size_t pos) const noexcept
Access an element in the string.
Definition: constexpr_string.hpp:207
data_type lit
The internal string stored as array including \0-byte as last character.
Definition: constexpr_string.hpp:76
constexpr bool operator!=(constexpr_string< N2 > const &rhs) const noexcept
Compares two strings lexicographically.
Definition: constexpr_string.hpp:377
constexpr void swap(constexpr_string &other) noexcept
Swaps the contents.
Definition: constexpr_string.hpp:339
constexpr constexpr_string & operator=(constexpr_string const &)=default
Default copy-assignment operator.
Implements a constexpr string that can be used for compile time computations.
Definition: constexpr_string.hpp:65
~constexpr_string()=default
Default destructor.
Provides C++20 additions to the type_traits header.
constexpr iterator end() noexcept
Returns iterator pass the end of the string.
Definition: constexpr_string.hpp:291
constexpr bool operator==(constexpr_string< N2 > const &rhs) const noexcept
Compares two strings lexicographically.
Definition: constexpr_string.hpp:360
constexpr size_type max_size() const noexcept
Returns the maximal capacity (same as size()).
Definition: constexpr_string.hpp:257
constexpr const char * c_str() const noexcept
Returns the content represented as 0-terminated c-style string.
Definition: constexpr_string.hpp:241
constexpr size_type size() const noexcept
Returns the size.
Definition: constexpr_string.hpp:251