SeqAn3  3.0.0
The Modern C++ library for sequence analysis.
bi_fm_index_cursor.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 <array>
16 
17 #include <sdsl/suffix_trees.hpp>
18 
19 #include <seqan3/alphabet/all.hpp>
23 #include <seqan3/std/ranges>
24 
25 namespace seqan3
26 {
27 
53 template <typename index_t>
55 {
56 public:
58  using index_type = index_t;
59 
63  using size_type = typename index_type::size_type;
66 
75 
76 protected:
78  using sdsl_char_type = typename index_type::sdsl_char_type;
80  using sdsl_sigma_type = typename index_type::sdsl_sigma_type;
81 
83  index_type const * index;
84 
96  //\}
97 
100 
107  // parent_* and _last_char only have to be stored for the (unidirectional) cursor that has been used last for
108  // extend_right() or cycle_back() resp. extend_left() or cycle_front(), (i.e. either fwd or rev). Thus there is no
109  // need to store it twice. Once the cursor is switched, the information becomes invalid anyway.
110 
117  //\}
118 
120  size_type depth; // equal for both cursors. only stored once
121 
122  // supports assertions to check whether cycle_back() resp. cycle_front() is called on the same direction as the last
123  // extend_right([...]) resp. extend_left([...])
124 #ifndef NDEBUG
125  // cycle_back() and cycle_front()
127  bool fwd_cursor_last_used = false;
128 #endif
129 
131  size_type offset() const noexcept
132  {
133  assert(index->size() > query_length());
134  return index->size() - query_length() - 1; // since the string is reversed during construction
135  }
136 
138  template <detail::SdslIndex csa_t>
139  bool bidirectional_search(csa_t const & csa, sdsl_char_type const c,
140  size_type & l_fwd, size_type & r_fwd,
141  size_type & l_bwd, size_type & r_bwd) const noexcept
142  {
143  assert((l_fwd <= r_fwd) && (r_fwd < csa.size()));
144  assert(r_fwd + 1 >= l_fwd);
145  assert(r_bwd + 1 - l_bwd == r_fwd + 1 - l_fwd);
146 
147  size_type _l_fwd, _r_fwd, _l_bwd, _r_bwd;
148 
149  size_type cc = c;
151  {
152  cc = csa.char2comp[c];
153  if (cc == 0 && c > 0) // [[unlikely]]
154  return false;
155  }
156 
157  size_type const c_begin = csa.C[cc];
158  if (r_fwd + 1 - l_fwd == csa.size()) // [[unlikely]]
159  {
160  _l_fwd = c_begin;
161  _l_bwd = c_begin;
162  _r_fwd = csa.C[cc + 1] - 1;
163  _r_bwd = _r_fwd;
164  // if we use not the plain_byte_alphabet, we could return always return true here
165  }
166  else
167  {
168  auto const r_s_b = csa.wavelet_tree.lex_count(l_fwd, r_fwd + 1, c);
169  size_type const rank_l = std::get<0>(r_s_b);
170  size_type const s = std::get<1>(r_s_b), b = std::get<2>(r_s_b);
171  size_type const rank_r = r_fwd - l_fwd - s - b + rank_l;
172  _l_fwd = c_begin + rank_l;
173  _r_fwd = c_begin + rank_r;
174  _l_bwd = l_bwd + s;
175  _r_bwd = r_bwd - b;
176  }
177 
178  if (_r_fwd >= _l_fwd)
179  {
180  l_fwd = _l_fwd;
181  r_fwd = _r_fwd;
182  l_bwd = _l_bwd;
183  r_bwd = _r_bwd;
184  assert(r_fwd + 1 >= l_fwd);
185  assert(r_bwd + 1 - l_bwd == r_fwd + 1 - l_fwd);
186  return true;
187  }
188  return false;
189  }
190 
192  template <detail::SdslIndex csa_t>
193  bool bidirectional_search_cycle(csa_t const & csa, sdsl_char_type const c,
194  size_type const l_parent, size_type const r_parent,
195  size_type & l_fwd, size_type & r_fwd,
196  size_type & l_bwd, size_type & r_bwd) const noexcept
197  {
198  assert((l_parent <= r_parent) && (r_parent < csa.size()));
199 
200  size_type c_begin;
202  c_begin = csa.C[c]; // TODO: check whether this can be removed
203  else
204  c_begin = csa.C[csa.char2comp[c]];
205 
206  auto const r_s_b = csa.wavelet_tree.lex_count(l_parent, r_parent + 1, c);
207  size_type const s = std::get<1>(r_s_b),
208  b = std::get<2>(r_s_b),
209  rank_l = std::get<0>(r_s_b),
210  rank_r = r_parent - l_parent - s - b + rank_l;
211 
212  size_type const _l_fwd = c_begin + rank_l;
213  size_type const _r_fwd = c_begin + rank_r;
214  size_type const _l_bwd = r_bwd + 1;
215  size_type const _r_bwd = r_bwd + 1 + rank_r - rank_l;
216 
217  if (_r_fwd >= _l_fwd)
218  {
219  l_fwd = _l_fwd;
220  r_fwd = _r_fwd;
221  l_bwd = _l_bwd;
222  r_bwd = _r_bwd;
223  assert(r_fwd + 1 >= l_fwd);
224  assert(r_bwd + 1 - l_bwd == r_fwd + 1 - l_fwd);
225  return true;
226  }
227  return false;
228  }
229 
230 public:
231 
235  // Default construction is necessary to make this class semi-regular and e.g., to allow construction of
237  // std::array of cursors.
238  bi_fm_index_cursor() noexcept = default;
239  bi_fm_index_cursor(bi_fm_index_cursor const &) noexcept = default;
240  bi_fm_index_cursor & operator=(bi_fm_index_cursor const &) noexcept = default;
241  bi_fm_index_cursor(bi_fm_index_cursor &&) noexcept = default;
242  bi_fm_index_cursor & operator=(bi_fm_index_cursor &&) noexcept = default;
243  ~bi_fm_index_cursor() = default;
244 
246  bi_fm_index_cursor(index_t const & _index) noexcept : index(&_index),
247  fwd_lb(0), fwd_rb(_index.size() - 1),
248  rev_lb(0), rev_rb(_index.size() - 1),
249  sigma(_index.fwd_fm.index.sigma - index_t::is_collection_),
250  depth(0)
251  {}
252  //\}
253 
266  bool operator==(bi_fm_index_cursor const & rhs) const noexcept
267  {
268  assert(index != nullptr);
269  // equal SA interval implies equal parent node information (or both are root nodes)
270  assert(!(fwd_lb == rhs.fwd_lb && fwd_rb == rhs.fwd_rb && depth == rhs.depth) ||
271  (depth == 0) ||
272  (parent_lb == rhs.parent_lb && parent_rb == rhs.parent_rb && _last_char == rhs._last_char));
273 
274  return std::tie(fwd_lb, fwd_rb, depth) == std::tie(rhs.fwd_lb, rhs.fwd_rb, rhs.depth);
275  }
276 
289  bool operator!=(bi_fm_index_cursor const & rhs) const noexcept
290  {
291  assert(index != nullptr);
292 
293  return !(*this == rhs);
294  }
295 
313  bool extend_right() noexcept
314  {
315  #ifndef NDEBUG
316  fwd_cursor_last_used = true;
317  #endif
318 
319  assert(index != nullptr);
320 
321  size_type new_parent_lb = fwd_lb, new_parent_rb = fwd_rb;
322 
323  sdsl_char_type c = 1; // NOTE: start with 0 or 1 depending on implicit_sentintel
324  while (c < sigma &&
325  !bidirectional_search(index->fwd_fm.index, index->fwd_fm.index.comp2char[c],
327  {
328  ++c;
329  }
330 
331  if (c != sigma)
332  {
333  parent_lb = new_parent_lb;
334  parent_rb = new_parent_rb;
335 
336  _last_char = c;
337  ++depth;
338 
339  return true;
340  }
341  return false;
342  }
343 
361  bool extend_left() noexcept
362  {
363  #ifndef NDEBUG
364  fwd_cursor_last_used = false;
365  #endif
366 
367  assert(index != nullptr);
368 
369  size_type new_parent_lb = rev_lb, new_parent_rb = rev_rb;
370 
371  sdsl_char_type c = 1; // NOTE: start with 0 or 1 depending on implicit_sentintel
372  while (c < sigma &&
373  !bidirectional_search(index->rev_fm.index, index->rev_fm.index.comp2char[c],
375  {
376  ++c;
377  }
378 
379  if (c != sigma)
380  {
381  parent_lb = new_parent_lb;
382  parent_rb = new_parent_rb;
383 
384  _last_char = c;
385  ++depth;
386 
387  return true;
388  }
389  return false;
390  }
391 
406  template <Alphabet char_t>
407  bool extend_right(char_t const c) noexcept
408  {
409  #ifndef NDEBUG
410  fwd_cursor_last_used = true;
411  #endif
412 
413  assert(index != nullptr);
414  assert(index->fwd_fm.sigma == alphabet_size<char_t>);
415 
416  size_type new_parent_lb = fwd_lb, new_parent_rb = fwd_rb;
417 
418  auto c_char = to_rank(c) + 1;
419  if (bidirectional_search(index->fwd_fm.index, c_char, fwd_lb, fwd_rb, rev_lb, rev_rb))
420  {
421  parent_lb = new_parent_lb;
422  parent_rb = new_parent_rb;
423 
424  _last_char = c_char;
425  ++depth;
426 
427  return true;
428  }
429  return false;
430  }
431 
446  template <Alphabet char_t>
447  bool extend_left(char_t const c) noexcept
448  {
449  #ifndef NDEBUG
450  fwd_cursor_last_used = false;
451  #endif
452 
453  assert(index != nullptr);
454  assert(index->fwd_fm.sigma == alphabet_size<char_t>);
455 
456  size_type new_parent_lb = rev_lb, new_parent_rb = rev_rb;
457 
458  auto c_char = to_rank(c) + 1;
459  if (bidirectional_search(index->rev_fm.index, c_char, rev_lb, rev_rb, fwd_lb, fwd_rb))
460  {
461  parent_lb = new_parent_lb;
462  parent_rb = new_parent_rb;
463 
464  _last_char = c_char;
465  ++depth;
466 
467  return true;
468  }
469  return false;
470  }
471 
488  template <std::ranges::Range seq_t>
489  bool extend_right(seq_t && seq) noexcept
490  {
491  static_assert(std::ranges::ForwardRange<seq_t>, "The query must model ForwardRange.");
492  assert(index != nullptr);
493  assert(index->fwd_fm.sigma == alphabet_size<innermost_value_type_t<seq_t>>);
494 
495  auto first = std::ranges::begin(seq);
496  auto last = std::ranges::end(seq);
497 
498  #ifndef NDEBUG
499  fwd_cursor_last_used = (first != last); // only if seq was not empty
500  #endif
501 
502  size_type _fwd_lb = fwd_lb, _fwd_rb = fwd_rb, _rev_lb = rev_lb, _rev_rb = rev_rb;
503  size_type new_parent_lb = parent_lb, new_parent_rb = parent_rb;
505  size_t len{0};
506 
507  for (auto it = first; it != last; ++len, ++it)
508  {
509  c = to_rank(*it) + 1;
510 
511  new_parent_lb = _fwd_lb;
512  new_parent_rb = _fwd_rb;
513  if (!bidirectional_search(index->fwd_fm.index, c, _fwd_lb, _fwd_rb, _rev_lb, _rev_rb))
514  return false;
515  }
516 
517  fwd_lb = _fwd_lb;
518  fwd_rb = _fwd_rb;
519  rev_lb = _rev_lb;
520  rev_rb = _rev_rb;
521 
522  parent_lb = new_parent_lb;
523  parent_rb = new_parent_rb;
524 
525  _last_char = c;
526  depth += len;
527 
528  return true;
529  }
530 
551  template <std::ranges::Range seq_t>
552  bool extend_left(seq_t && seq) noexcept
553  {
554  static_assert(std::ranges::BidirectionalRange<seq_t>, "The query must model BidirectionalRange.");
555  assert(index != nullptr);
556  assert(index->fwd_fm.sigma == alphabet_size<innermost_value_type_t<seq_t>>);
557 
558  auto rev_seq = std::view::reverse(seq);
559  auto first = std::ranges::begin(rev_seq);
560  auto last = std::ranges::end(rev_seq);
561 
562  #ifndef NDEBUG
563  if (first != last) // only if seq was not empty
564  fwd_cursor_last_used = false;
565  #endif
566 
567  size_type _fwd_lb = fwd_lb, _fwd_rb = fwd_rb,
568  _rev_lb = rev_lb, _rev_rb = rev_rb;
569  size_type new_parent_lb = parent_lb, new_parent_rb = parent_rb;
571  size_t len{0};
572 
573  for (auto it = first; it != last; ++len, ++it)
574  {
575  c = to_rank(*it) + 1;
576 
577  new_parent_lb = _rev_lb;
578  new_parent_rb = _rev_rb;
579  if (!bidirectional_search(index->rev_fm.index, c, _rev_lb, _rev_rb, _fwd_lb, _fwd_rb))
580  return false;
581  }
582 
583  fwd_lb = _fwd_lb;
584  fwd_rb = _fwd_rb;
585  rev_lb = _rev_lb;
586  rev_rb = _rev_rb;
587 
588  parent_lb = new_parent_lb;
589  parent_rb = new_parent_rb;
590  _last_char = c;
591  depth += len;
592 
593  return true;
594  }
595 
622  bool cycle_back() noexcept
623  {
624  #ifndef NDEBUG
625  // cycle_back() can only be used if the last extension was to the right.
626  assert(fwd_cursor_last_used);
627  #endif
628 
629  assert(index != nullptr && query_length() > 0);
630 
631  sdsl_char_type c = _last_char + 1;
632 
633  while (c < sigma &&
634  !bidirectional_search_cycle(index->fwd_fm.index, index->fwd_fm.index.comp2char[c],
636  {
637  ++c;
638  }
639 
640  if (c != sigma)
641  {
642  _last_char = c;
643 
644  return true;
645  }
646  return false;
647  }
648 
675  bool cycle_front() noexcept
676  {
677  #ifndef NDEBUG
678  // cycle_front() can only be used if the last extension was to the left.
679  assert(!fwd_cursor_last_used);
680  #endif
681 
682  assert(index != nullptr && query_length() > 0);
683 
684  sdsl_char_type c = _last_char + 1;
685  while (c < sigma &&
686  !bidirectional_search_cycle(index->rev_fm.index, index->rev_fm.index.comp2char[c],
688  {
689  ++c;
690  }
691 
692  if (c != sigma)
693  {
694  _last_char = c;
695 
696  return true;
697  }
698  return false;
699  }
700 
701 
718  size_type last_rank() noexcept
719  {
720  assert(index != nullptr && query_length() > 0);
721 
722  return index->fwd_fm.index.comp2char[_last_char] - 1; // text is not allowed to contain ranks of 0
723  }
724 
737  size_type query_length() const noexcept
738  {
739  assert(index != nullptr);
740  // depth == 0 -> root node
741  assert(depth != 0 ||
742  (fwd_lb == rev_lb &&
743  fwd_rb == rev_rb &&
744  fwd_lb == 0 &&
745  fwd_rb == index->size() - 1));
746 
747  return depth;
748  }
749 
769  fwd_cursor to_fwd_cursor() const noexcept
770  {
771  assert(index != nullptr);
772 
773  fwd_cursor cur{index->fwd_fm};
774  cur.parent_lb = parent_lb;
775  cur.parent_rb = parent_rb;
776  cur.node = {fwd_lb, fwd_rb, depth, _last_char};
777 
778  #ifndef NDEBUG
780  {
781  // invalidate parent interval
782  cur.parent_lb = 1;
783  cur.parent_rb = 0;
784  }
785  #endif
786 
787  return cur;
788  }
789 
814  rev_cursor to_rev_cursor() const noexcept
815  {
816  assert(index != nullptr);
817 
818  rev_cursor cur{index->rev_fm};
819  cur.parent_lb = parent_lb;
820  cur.parent_rb = parent_rb;
821  cur.node = {rev_lb, rev_rb, depth, _last_char};
822 
823  #ifndef NDEBUG
825  {
826  // invalidate parent interval
827  cur.parent_lb = 1;
828  cur.parent_rb = 0;
829  }
830  #endif
831 
832  return cur;
833  }
834 
851  template <std::ranges::Range text_t>
852  auto path_label(text_t && text) const noexcept
854  requires !index_t::is_collection_
856  {
857  static_assert(std::ranges::InputRange<text_t>, "The text must model InputRange.");
858  static_assert(dimension_v<text_t> == 1, "The input cannot be a text collection.");
859  assert(index != nullptr);
860  assert(index->fwd_fm.sigma == alphabet_size<value_type_t<text_t>>);
861 
862  size_type const query_begin = offset() - index->fwd_fm.index[fwd_lb];
863  return text | view::slice(query_begin, query_begin + query_length());
864  }
865 
867  template <std::ranges::Range text_t>
868  auto path_label(text_t && text) const noexcept
870  requires index_t::is_collection_
872  {
873  static_assert(std::ranges::InputRange<text_t>, "The text collection must model InputRange.");
874  static_assert(dimension_v<text_t> == 2, "The input must be a text collection.");
875  assert(index != nullptr);
876  assert(index->fwd_fm.sigma == alphabet_size<innermost_value_type_t<text_t>>);
877 
878  size_type const loc = offset() - index->fwd_fm.index[fwd_lb];
879  size_type const query_begin = loc - index->fwd_fm.text_begin_rs.rank(loc + 1) + 1; // Substract delimiters
880  return text | std::view::join | view::slice(query_begin, query_begin + query_length());
881  }
882 
894  size_type count() const noexcept
895  {
896  assert(index != nullptr && (1 + fwd_rb - fwd_lb == 1 + rev_rb - rev_lb));
897 
898  return 1 + fwd_rb - fwd_lb;
899  }
900 
914  requires !index_t::is_collection_
916  {
917  assert(index != nullptr);
918 
920  for (size_type i = 0; i < occ.size(); ++i)
921  {
922  occ[i] = offset() - index->fwd_fm.index[fwd_lb + i];
923  }
924  return occ;
925  }
926 
930  requires index_t::is_collection_
932  {
933  assert(index != nullptr);
934 
936  occ.reserve(count());
937  for (size_type i = 0; i < count(); ++i)
938  {
939  size_type loc = offset() - index->fwd_fm.index[fwd_lb + i];
940  size_type sequence_rank = index->fwd_fm.text_begin_rs.rank(loc + 1);
941  size_type sequence_position = loc - index->fwd_fm.text_begin_ss.select(sequence_rank);
942  occ.emplace_back(sequence_rank - 1, sequence_position);
943  }
944  return occ;
945  }
946 
959  auto lazy_locate() const
961  requires !index_t::is_collection_
963  {
964  assert(index != nullptr);
965 
966  return std::view::iota(fwd_lb, fwd_lb + count())
967  | std::view::transform([*this, _offset = offset()] (auto sa_pos)
968  {
969  return _offset - index->fwd_fm.index[sa_pos];
970  });
971  }
972 
974  auto lazy_locate() const
976  requires index_t::is_collection_
978  {
979  assert(index != nullptr);
980 
981  return std::view::iota(fwd_lb, fwd_lb + count())
982  | std::view::transform([*this, _offset = offset()] (auto sa_pos)
983  {
984  return _offset - index->fwd_fm.index[sa_pos];
985  })
986  | std::view::transform([*this] (auto loc)
987  {
988  size_type sequence_rank = index->fwd_fm.text_begin_rs.rank(loc + 1);
989  size_type sequence_position = loc - index->fwd_fm.text_begin_ss.select(sequence_rank);
990  return std::make_pair(sequence_rank-1, sequence_position);
991  });
992  }
993 
994 };
995 
997 
998 } // namespace seqan3
bool extend_left(char_t const c) noexcept
Tries to extend the query by the character c to the left.
Definition: bi_fm_index_cursor.hpp:447
typename index_type::sdsl_char_type sdsl_char_type
Type of the representation of characters in the underlying SDSL index.
Definition: bi_fm_index_cursor.hpp:78
bool extend_left() noexcept
Tries to extend the query by the smallest possible character to the left such that the query is found...
Definition: bi_fm_index_cursor.hpp:361
bool operator!=(bi_fm_index_cursor const &rhs) const noexcept
Compares two cursors.
Definition: bi_fm_index_cursor.hpp:289
typename value_type< t >::type value_type_t
Shortcut for seqan3::value_type (TransformationTrait shortcut).
Definition: pre.hpp:48
constexpr sequenced_policy seq
Global execution policy object for sequenced execution policy.
Definition: execution.hpp:54
T tie(T... args)
index_t index_type
Type of the index.
Definition: bi_fm_index_cursor.hpp:58
bool cycle_front() noexcept
Tries to replace the leftmost character of the query by the next lexicographically larger character s...
Definition: bi_fm_index_cursor.hpp:675
bool extend_right(char_t const c) noexcept
Tries to extend the query by the character c to the right.
Definition: bi_fm_index_cursor.hpp:407
constexpr auto to_rank
Return the rank representation of a (semi-)alphabet object.
Definition: concept.hpp:103
constexpr auto reverse
A range adaptor that presents the underlying range in reverse order.
Definition: ranges:721
rev_cursor to_rev_cursor() const noexcept
Returns a unidirectional seqan3::fm_index_cursor on the reversed text. path_label() on the returned u...
Definition: bi_fm_index_cursor.hpp:814
std::vector< size_type > locate() const
Locates the occurrences of the searched query in the text.
Definition: bi_fm_index_cursor.hpp:912
sdsl_char_type _last_char
Label of the last edge moved down. Needed for cycle_back() or cycle_front().
Definition: bi_fm_index_cursor.hpp:116
::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.
size_type count() const noexcept
Counts the number of occurrences of the searched query in the text.
Definition: bi_fm_index_cursor.hpp:894
auto lazy_locate() const
Locates the occurrences of the searched query in the text on demand, i.e. a ranges::view is returned ...
Definition: bi_fm_index_cursor.hpp:959
constexpr auto join
Flattens a View of ranges into a View.
Definition: ranges:683
constexpr auto slice
A view adaptor that returns a half-open interval on the underlying range.
Definition: slice.hpp:144
bool operator==(bi_fm_index_cursor const &rhs) const noexcept
Compares two cursors.
Definition: bi_fm_index_cursor.hpp:266
Specifies requirements of a Range type for which begin returns a type that models std::BidirectionalI...
std::vector< std::pair< size_type, size_type > > locate() const
Definition: bi_fm_index_cursor.hpp:928
Meta-header for the alphabet module.
bool fwd_cursor_last_used
Stores the information which cursor has been used last for extend_*([...]) to allow for assert() in...
Definition: bi_fm_index_cursor.hpp:127
typename index_type::sdsl_sigma_type sdsl_sigma_type
Type of the alphabet size in the underlying SDSL index.
Definition: bi_fm_index_cursor.hpp:80
Adaptations of concepts from the Ranges TS.
size_type fwd_rb
Right suffix array interval of the forward cursor (for extend_right).
Definition: bi_fm_index_cursor.hpp:91
typename innermost_value_type< t >::type innermost_value_type_t
Shortcut for seqan3::innermost_value_type (TransformationTrait shortcut).
Definition: range.hpp:191
::ranges::begin begin
Alias for ranges::begin. Returns an iterator to the beginning of a range.
Definition: ranges:174
size_type offset() const noexcept
Helper function to recompute text positions since the indexed text is reversed.
Definition: bi_fm_index_cursor.hpp:131
T make_pair(T... args)
size_type depth
Depth of the node in the suffix tree, i.e. length of the searched query.
Definition: bi_fm_index_cursor.hpp:120
fwd_cursor to_fwd_cursor() const noexcept
Returns a unidirectional seqan3::fm_index_cursor on the original text. path_label() on the returned u...
Definition: bi_fm_index_cursor.hpp:769
constexpr auto iota
Generates a sequence of elements by repeatedly incrementing an initial value.
Definition: ranges:647
bool bidirectional_search(csa_t const &csa, sdsl_char_type const c, size_type &l_fwd, size_type &r_fwd, size_type &l_bwd, size_type &r_bwd) const noexcept
Optimized bidirectional search without alphabet mapping.
Definition: bi_fm_index_cursor.hpp:139
T size(T... args)
index_type const * index
Type of the underlying FM index.
Definition: bi_fm_index_cursor.hpp:83
Provides the bidirectional seqan3::bi_fm_index.
size_type fwd_lb
Left suffix array interval of the forward cursor (for extend_right).
Definition: bi_fm_index_cursor.hpp:89
typename index_type::size_type size_type
Type for representing positions in the indexed text.
Definition: bi_fm_index_cursor.hpp:64
Specifies requirements of a Range type for which begin returns a type that models std::InputIterator...
size_type parent_lb
Left suffix array interval of the parent node.
Definition: bi_fm_index_cursor.hpp:112
The SeqAn Bidirectional FM Index Cursor.
Definition: bi_fm_index_cursor.hpp:54
size_type last_rank() noexcept
Outputs the rightmost respectively leftmost rank depending on whether extend_right() or extend_left()...
Definition: bi_fm_index_cursor.hpp:718
bool bidirectional_search_cycle(csa_t const &csa, sdsl_char_type const c, size_type const l_parent, size_type const r_parent, size_type &l_fwd, size_type &r_fwd, size_type &l_bwd, size_type &r_bwd) const noexcept
Optimized bidirectional search for cycle_back() and cycle_front() without alphabet mapping...
Definition: bi_fm_index_cursor.hpp:193
bool cycle_back() noexcept
Tries to replace the rightmost character of the query by the next lexicographically larger character ...
Definition: bi_fm_index_cursor.hpp:622
Provides seqan3::view::slice.
bi_fm_index_cursor() noexcept=default
Default constructor. Accessing member functions on a default constructed object is undefined behavior...
Provides various transformation traits used by the range module.
auto path_label(text_t &&text) const noexcept
Returns the searched query.
Definition: bi_fm_index_cursor.hpp:852
Specifies requirements of a Range type for which begin returns a type that models std::ForwardIterato...
size_type rev_rb
Right suffix array interval of the reverse cursor (for extend_left).
Definition: bi_fm_index_cursor.hpp:95
bool extend_right() noexcept
Tries to extend the query by the smallest possible character to the right such that the query is foun...
Definition: bi_fm_index_cursor.hpp:313
The concept std::Same<T, U> is satisfied if and only if T and U denote the same type.
constexpr auto alphabet_size
A type trait that holds the size of a (semi-)alphabet.
Definition: concept.hpp:678
sdsl_sigma_type sigma
Alphabet size of the index without delimiters.
Definition: bi_fm_index_cursor.hpp:99
bool extend_right(seq_t &&seq) noexcept
Tries to extend the query by seq to the right.
Definition: bi_fm_index_cursor.hpp:489
bool extend_left(seq_t &&seq) noexcept
Tries to extend the query by seq to the left.
Definition: bi_fm_index_cursor.hpp:552
::ranges::end end
Alias for ranges::end. Returns an iterator to the end of a range.
Definition: ranges:179
constexpr auto transform
A range adaptor that takes a invocable and returns a view of the elements with the invocable applied...
Definition: ranges:911
size_type query_length() const noexcept
Returns the depth of the cursor node in the implicit suffix tree, i.e. the length of the sequence sea...
Definition: bi_fm_index_cursor.hpp:737
The SeqAn FM Index Cursor.
Definition: fm_index_cursor.hpp:64
size_type rev_lb
Left suffix array interval of the reverse cursor (for extend_left).
Definition: bi_fm_index_cursor.hpp:93
T reserve(T... args)
T emplace_back(T... args)
size_type parent_rb
Left suffix array interval of the parent node.
Definition: bi_fm_index_cursor.hpp:114