SeqAn3  3.0.0
The Modern C++ library for sequence analysis.
alignment_coordinate.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 
15 #include <type_traits>
16 
19 #include <seqan3/std/concepts>
20 #include <seqan3/std/iterator>
21 
22 namespace seqan3::detail
23 {
26 struct column_index_type : detail::strong_type<size_t, column_index_type>
27 {
29  using detail::strong_type<size_t, column_index_type>::strong_type;
30 };
31 
34 struct row_index_type : detail::strong_type<size_t, row_index_type>
35 {
37  using detail::strong_type<size_t, row_index_type>::strong_type;
38 };
39 
50 enum struct advanceable_alignment_coordinate_state : uint8_t
51 {
53  none,
55  column,
57  row
58 };
59 
75 template <advanceable_alignment_coordinate_state state = advanceable_alignment_coordinate_state::none>
76 class advanceable_alignment_coordinate
77 {
78 public:
79 
84  using difference_type = std::make_signed_t<size_t>;
87 
91  constexpr advanceable_alignment_coordinate() noexcept = default;
92  constexpr advanceable_alignment_coordinate(advanceable_alignment_coordinate const &) noexcept = default;
94  constexpr advanceable_alignment_coordinate(advanceable_alignment_coordinate &&) noexcept = default;
95  constexpr advanceable_alignment_coordinate & operator=(advanceable_alignment_coordinate const &) noexcept = default;
98  constexpr advanceable_alignment_coordinate & operator=(advanceable_alignment_coordinate &&) noexcept = default;
99  ~advanceable_alignment_coordinate() noexcept = default;
100 
102  template <advanceable_alignment_coordinate_state other_state>
104  requires !std::Same<other_state, state>
106  constexpr advanceable_alignment_coordinate(advanceable_alignment_coordinate<other_state> const & other) :
107  first{other.first},
108  second{other.second}
109  {}
110 
112  template <advanceable_alignment_coordinate_state other_state>
116  constexpr advanceable_alignment_coordinate(advanceable_alignment_coordinate<other_state> && other) :
117  first{std::move(other.first)},
118  second{std::move(other.second)}
119  {}
120 
125  constexpr advanceable_alignment_coordinate(column_index_type const c_idx,
126  row_index_type const r_idx) noexcept :
127  first{c_idx.get()},
128  second{r_idx.get()}
129  {}
131 
133  constexpr friend bool operator==(advanceable_alignment_coordinate const & lhs,
134  advanceable_alignment_coordinate const & rhs) noexcept
135  {
136  return std::tie(lhs.first, lhs.second) == std::tie(rhs.first, rhs.second);
137  }
138 
139  constexpr friend bool operator!=(advanceable_alignment_coordinate const & lhs,
140  advanceable_alignment_coordinate const & rhs) noexcept
141  {
142  return std::tie(lhs.first, lhs.second) != std::tie(rhs.first, rhs.second);
143  }
144 
145  constexpr friend bool operator<=(advanceable_alignment_coordinate const & lhs,
146  advanceable_alignment_coordinate const & rhs) noexcept
147  {
148  return std::tie(lhs.first, lhs.second) <= std::tie(rhs.first, rhs.second);
149  }
150 
151  constexpr friend bool operator< (advanceable_alignment_coordinate const & lhs,
152  advanceable_alignment_coordinate const & rhs) noexcept
153  {
154  return std::tie(lhs.first, lhs.second) < std::tie(rhs.first, rhs.second);
155  }
156 
157  constexpr friend bool operator>=(advanceable_alignment_coordinate const & lhs,
158  advanceable_alignment_coordinate const & rhs) noexcept
159  {
160  return std::tie(lhs.first, lhs.second) >= std::tie(rhs.first, rhs.second);
161  }
162 
163  constexpr friend bool operator> (advanceable_alignment_coordinate const & lhs,
164  advanceable_alignment_coordinate const & rhs) noexcept
165  {
166  return std::tie(lhs.first, lhs.second) > std::tie(rhs.first, rhs.second);
167  }
169 
180  constexpr advanceable_alignment_coordinate & operator++(/*pre-increment*/) noexcept
182  requires state != advanceable_alignment_coordinate_state::none
184  {
185  if constexpr (state == advanceable_alignment_coordinate_state::column)
186  ++this->first;
187  else
188  ++this->second;
189  return *this;
190  }
191 
195  constexpr advanceable_alignment_coordinate operator++(int /*post-increment*/) noexcept
197  requires state != advanceable_alignment_coordinate_state::none
199  {
200  advanceable_alignment_coordinate tmp{*this};
201  ++(*this);
202  return tmp;
203  }
204 
208  constexpr advanceable_alignment_coordinate & operator--(/*pre-decrement*/) noexcept
210  requires state != advanceable_alignment_coordinate_state::none
212  {
213  if constexpr (state == advanceable_alignment_coordinate_state::column)
214  --this->first;
215  else
216  --this->second;
217  return *this;
218  }
219 
223  constexpr advanceable_alignment_coordinate operator--(int /*post-decrement*/) noexcept
225  requires state != advanceable_alignment_coordinate_state::none
227  {
228  advanceable_alignment_coordinate tmp{*this};
229  --(*this);
230  return tmp;
231  }
232 
237  constexpr advanceable_alignment_coordinate & operator+=(difference_type const offset) noexcept
239  requires state != advanceable_alignment_coordinate_state::none
241  {
242  if constexpr (state == advanceable_alignment_coordinate_state::column)
243  this->first += offset;
244  else
245  this->second += offset;
246  return *this;
247  }
248 
253  constexpr advanceable_alignment_coordinate & operator-=(difference_type const offset) noexcept
255  requires state != advanceable_alignment_coordinate_state::none
257  {
258  if constexpr (state == advanceable_alignment_coordinate_state::column)
259  this->first -= offset;
260  else
261  this->second -= offset;
262  return *this;
263  }
264 
269  constexpr advanceable_alignment_coordinate operator+(difference_type const offset) const noexcept
271  requires state != advanceable_alignment_coordinate_state::none
273  {
274  advanceable_alignment_coordinate tmp{*this};
275  tmp += offset;
276  return tmp;
277  }
278 
283  constexpr advanceable_alignment_coordinate operator-(difference_type const offset) const noexcept
285  requires state != advanceable_alignment_coordinate_state::none
287  {
288  advanceable_alignment_coordinate tmp{*this};
289  tmp -= offset;
290  return tmp;
291  }
292 
297  constexpr difference_type operator-(advanceable_alignment_coordinate const & other) const noexcept
299  requires state != advanceable_alignment_coordinate_state::none
301  {
302  if constexpr (state == advanceable_alignment_coordinate_state::column)
303  return this->first - other.first;
304  else
305  return this->second - other.second;
306  }
308 
311 
315  constexpr friend advanceable_alignment_coordinate operator+(difference_type const offset,
316  advanceable_alignment_coordinate const & me) noexcept
318  requires state != advanceable_alignment_coordinate_state::none
320  {
321  return me + offset;
322  }
324 
326  size_t first{};
328  size_t second{};
329 };
330 
331 } // namespace seqan3::detail
332 
333 namespace seqan3
334 {
335 
351  : public detail::advanceable_alignment_coordinate<detail::advanceable_alignment_coordinate_state::none>
353 {
356  using base_t = detail::advanceable_alignment_coordinate<detail::advanceable_alignment_coordinate_state::none>;
358 
359 public:
360 
364  constexpr alignment_coordinate() = default;
365  constexpr alignment_coordinate(alignment_coordinate const &) = default;
366  constexpr alignment_coordinate(alignment_coordinate &&) = default;
367  constexpr alignment_coordinate & operator=(alignment_coordinate const &) = default;
368  constexpr alignment_coordinate & operator=(alignment_coordinate &&) = default;
369  ~alignment_coordinate() = default;
370 
373  using base_t::base_t;
374 
376  constexpr alignment_coordinate(base_t const & base) : base_t{base}
377  {}
378 
380  constexpr alignment_coordinate(base_t && base) : base_t{std::move(base)}
381  {}
384 
385  using base_t::first;
386  using base_t::second;
387 
389  SEQAN3_DOXYGEN_ONLY(size_t first;)
391  SEQAN3_DOXYGEN_ONLY(size_t second;)
392 };
393 
404 template <typename coordinate_type>
407  detail::is_value_specialisation_of_v<remove_cvref_t<coordinate_type>,
408  detail::advanceable_alignment_coordinate>
410 inline debug_stream_type & operator<<(debug_stream_type & s, coordinate_type && c)
411 {
412  s << std::tie(c.first, c.second);
413  return s;
414 }
415 
416 } // namespace seqan3
size_t second
The begin/end position of the alignment in the second sequence.
Definition: alignment_coordinate.hpp:391
Provides basic data structure for strong types.
debug_stream_type & operator<<(debug_stream_type &s, coordinate_type &&c)
A seqan3::alignment_coordinate can be printed to the seqan3::debug_stream.
Definition: alignment_coordinate.hpp:410
constexpr alignment_coordinate & operator=(alignment_coordinate const &)=default
Defaulted.
T tie(T... args)
T operator<=(T... args)
Represents the begin/end of the pairwise alignment in the respective sequences.
Definition: alignment_coordinate.hpp:349
Provides C++20 additions to the <iterator> header.
SeqAn specific customisations in the standard namespace.
No flag is set.
Definition: debug_stream.hpp:39
The main SeqAn3 namespace.
size_t first
The begin/end position of the alignment in the first sequence.
Definition: alignment_coordinate.hpp:389
bool operator!=(type const &lhs, type const &rhs)
(In-)Equality comparison.
The Concepts library.
bool operator==(type const &lhs, type const &rhs)
(In-)Equality comparison.
~alignment_coordinate()=default
Defaulted.
Definition: aligned_sequence_concept.hpp:35
constexpr alignment_coordinate()=default
Defaulted.
The concept std::Same<T, U> is satisfied if and only if T and U denote the same type.
A "pretty printer" for most SeqAn data structures and related types.
Definition: debug_stream.hpp:78
Provides seqan3::debug_stream and related types.