SeqAn3  3.2.0-rc.1
The Modern C++ library for sequence analysis.
concatenated_sequences.hpp
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------------------------------
2 // Copyright (c) 2006-2022, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2022, 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 <iterator>
16 #include <ranges>
17 #include <type_traits>
18 #include <vector>
19 
24 
25 #if SEQAN3_WITH_CEREAL
26 # include <cereal/types/vector.hpp>
27 #endif
28 
29 namespace seqan3
30 {
31 
82 template <typename underlying_container_type,
83  typename data_delimiters_type = std::vector<typename underlying_container_type::size_type>>
86  && std::is_same_v<std::ranges::range_size_t<underlying_container_type>,
87  std::ranges::range_value_t<data_delimiters_type>>
89 {
90 protected:
95  data_delimiters_type data_delimiters{0};
96 
97 public:
99 
109 
116 
124 
130  using iterator = detail::random_access_iterator<concatenated_sequences>;
131 
137  using const_iterator = detail::random_access_iterator<concatenated_sequences const>;
138 
144  using difference_type = std::ranges::range_difference_t<data_delimiters_type>;
145 
151  using size_type = std::ranges::range_size_t<data_delimiters_type>;
153 
154 protected:
161  // unfortunately we cannot specialise the variable template so we have to add an auxiliary here
162  template <std::ranges::range t>
163  static constexpr bool is_compatible_with_value_type_aux(std::type_identity<t>)
164  {
165  return range_dimension_v<t> == range_dimension_v<value_type>
166  && std::convertible_to<std::ranges::range_reference_t<t>, std::ranges::range_value_t<value_type>>;
167  }
168 
169  static constexpr bool is_compatible_with_value_type_aux(...)
170  {
171  return false;
172  }
174 
180  // we explicitly check same-ness, because these types may not be fully resolved, yet
181  template <std::ranges::range t>
182  static constexpr bool is_compatible_with_value_type = is_compatible_with_value_type_aux(std::type_identity<t>{});
183 
189  // cannot use the concept, because this class is not yet fully defined
190  template <typename t>
191  requires is_compatible_with_value_type<std::iter_reference_t<t>>
192  static constexpr bool iter_value_t_is_compatible_with_value_type = true;
193 
199  // cannot use the concept, because this class is not yet fully defined
200  template <std::ranges::range t>
201  requires is_compatible_with_value_type<std::ranges::range_reference_t<t>>
202  static constexpr bool range_value_t_is_compatible_with_value_type = true;
204 
205 public:
212  constexpr concatenated_sequences(concatenated_sequences const &) = default;
221 
237  template <std::ranges::input_range rng_of_rng_type>
238  concatenated_sequences(rng_of_rng_type && rng_of_rng)
239  requires range_value_t_is_compatible_with_value_type<rng_of_rng_type>
240  {
241  if constexpr (std::ranges::sized_range<rng_of_rng_type>)
242  data_delimiters.reserve(std::ranges::size(rng_of_rng) + 1);
243 
244  for (auto && val : rng_of_rng)
245  {
246  data_values.insert(data_values.end(), val.begin(), val.end());
247  data_delimiters.push_back(data_delimiters.back() + val.size());
248  }
249  }
250 
266  template <std::ranges::forward_range rng_type>
267  concatenated_sequences(size_type const count, rng_type && value)
268  requires is_compatible_with_value_type<rng_type>
269  {
270  // TODO SEQAN_UNLIKELY
271  if (count == 0)
272  return;
273 
274  insert(cend(), count, std::forward<rng_type>(value));
275  }
276 
294  template <std::forward_iterator begin_iterator_type, typename end_iterator_type>
295  concatenated_sequences(begin_iterator_type begin_it, end_iterator_type end_it)
296  requires std::sized_sentinel_for<end_iterator_type, begin_iterator_type>
297  && iter_value_t_is_compatible_with_value_type<begin_iterator_type>
298  {
299  insert(cend(), begin_it, end_it);
300  }
301 
316  template <std::ranges::forward_range value_type_t = value_type>
317  requires is_compatible_with_value_type<value_type_t>
319  {
320  assign(std::begin(ilist), std::end(ilist));
321  }
322 
337  template <std::ranges::forward_range value_type_t>
339  requires is_compatible_with_value_type<value_type_t>
340  {
341  assign(std::begin(ilist), std::end(ilist));
342  return *this;
343  }
344 
360  template <std::ranges::input_range rng_of_rng_type>
361  void assign(rng_of_rng_type && rng_of_rng)
362  requires range_value_t_is_compatible_with_value_type<rng_of_rng_type>
363  {
364  concatenated_sequences rhs{std::forward<rng_of_rng_type>(rng_of_rng)};
365  swap(rhs);
366  }
367 
383  template <std::ranges::forward_range rng_type>
384  void assign(size_type const count, rng_type && value)
385  requires (is_compatible_with_value_type<rng_type>)
386  {
387  concatenated_sequences rhs{count, value};
388  swap(rhs);
389  }
390 
408  template <std::forward_iterator begin_iterator_type, typename end_iterator_type>
409  void assign(begin_iterator_type begin_it, end_iterator_type end_it)
410  requires iter_value_t_is_compatible_with_value_type<begin_iterator_type>
411  && std::sized_sentinel_for<end_iterator_type, begin_iterator_type>
412  {
413  concatenated_sequences rhs{begin_it, end_it};
414  swap(rhs);
415  }
416 
431  template <std::ranges::forward_range rng_type = value_type>
433  requires is_compatible_with_value_type<rng_type>
434  {
435  assign(std::begin(ilist), std::end(ilist));
436  }
437 
439 
458  iterator begin() noexcept
459  {
460  return iterator{*this};
461  }
462 
464  const_iterator begin() const noexcept
465  {
466  return const_iterator{*this};
467  }
468 
470  const_iterator cbegin() const noexcept
471  {
472  return const_iterator{*this};
473  }
474 
490  iterator end() noexcept
491  {
492  return iterator{*this, size()};
493  }
494 
496  const_iterator end() const noexcept
497  {
498  return const_iterator{*this, size()};
499  }
500 
502  const_iterator cend() const noexcept
503  {
504  return const_iterator{*this, size()};
505  }
507 
526  reference at(size_type const i)
527  {
528  //TODO add SEQAN_UNLIKELY
529  if (i >= size())
530  throw std::out_of_range{"Trying to access element behind the last in concatenated_sequences."};
531  return (*this)[i];
532  }
533 
535  const_reference at(size_type const i) const
536  {
537  //TODO add SEQAN_UNLIKELY
538  if (i >= size())
539  throw std::out_of_range{"Trying to access element behind the last in concatenated_sequences."};
540  return (*this)[i];
541  }
542 
560  {
561  assert(i < size());
562  return data_values | views::slice(data_delimiters[i], data_delimiters[i + 1]);
563  }
564 
566  const_reference operator[](size_type const i) const
567  {
568  assert(i < size());
569  return data_values | views::slice(data_delimiters[i], data_delimiters[i + 1]);
570  }
571 
586  reference front()
587  {
588  assert(size() > 0);
589  return (*this)[0];
590  }
591 
593  const_reference front() const
594  {
595  assert(size() > 0);
596  return (*this)[0];
597  }
598 
613  reference back()
614  {
615  assert(size() > 0);
616  return (*this)[size() - 1];
617  }
618 
620  const_reference back() const
621  {
622  assert(size() > 0);
623  return (*this)[size() - 1];
624  }
625 
642  reference concat()
643  {
644  return data_values | views::slice(static_cast<size_type>(0), concat_size());
645  }
646 
648  const_reference concat() const
649  {
650  return data_values | views::slice(static_cast<size_type>(0), concat_size());
651  }
652 
660  std::pair<decltype(data_values) &, decltype(data_delimiters) &> raw_data()
661  {
662  return {data_values, data_delimiters};
663  }
664 
666  std::pair<decltype(data_values) const &, decltype(data_delimiters) const &> raw_data() const
667  {
668  return {data_values, data_delimiters};
669  }
670 
672 
689  bool empty() const noexcept
690  {
691  return size() == 0;
692  }
693 
707  size_type size() const noexcept
708  {
709  return data_delimiters.size() - 1;
710  }
711 
728  size_type max_size() const noexcept
729  {
730  return data_delimiters.max_size() - 1;
731  }
732 
750  size_type capacity() const noexcept
751  {
752  return data_delimiters.capacity();
753  }
754 
777  void reserve(size_type const new_cap)
778  {
779  data_delimiters.reserve(new_cap + 1);
780  }
781 
801  void shrink_to_fit()
802  {
803  data_values.shrink_to_fit();
804  data_delimiters.shrink_to_fit();
805  }
807 
824  size_type concat_size() const noexcept
825  {
826  return data_values.size();
827  }
828 
842  size_type concat_capacity() const noexcept
843  {
844  return data_values.capacity();
845  }
846 
867  void concat_reserve(size_type const new_cap)
868  {
869  data_values.reserve(new_cap);
870  }
872 
888  void clear() noexcept
889  {
890  data_values.clear();
891  data_delimiters.clear();
892  data_delimiters.push_back(0);
893  }
894 
921  template <std::ranges::forward_range rng_type>
922  iterator insert(const_iterator pos, rng_type && value)
923  requires is_compatible_with_value_type<rng_type>
924  {
925  return insert(pos, 1, std::forward<rng_type>(value));
926  }
927  // no specialisation for temporaries, since we have to copy anyway
928 
955  template <std::ranges::forward_range rng_type>
956  iterator insert(const_iterator pos, size_type const count, rng_type && value)
957  requires is_compatible_with_value_type<rng_type>
958  {
959  auto const pos_as_num = std::distance(cbegin(), pos); // we want to insert BEFORE this position
960  // TODO SEQAN_UNLIKELY
961  if (count == 0)
962  return begin() + pos_as_num;
963 
964  /* TODO implement views::flat_repeat_n that is like
965  * views::repeat_n(value, count) | std::views::join | ranges::views::bounded;
966  * but preserves random access and size.
967  *
968  * then do
969  * auto concatenated = ranges::views::flat_repeat_n(value, count);
970  * insert(pos, concatenated.cbegin(), concatenated.cend())
971  */
972 
973  size_type value_len = 0;
974  if constexpr (std::ranges::sized_range<rng_type>)
975  value_len = std::ranges::size(value);
976  else
977  value_len = std::distance(std::ranges::begin(value), std::ranges::end(value));
978 
979  data_values.reserve(data_values.size() + count * value_len);
980  auto placeholder =
981  views::repeat_n(std::ranges::range_value_t<rng_type>{}, count * value_len) | std::views::common;
982  // insert placeholder so the tail is moved once:
983  data_values.insert(data_values.begin() + data_delimiters[pos_as_num],
984  std::ranges::begin(placeholder),
985  std::ranges::end(placeholder));
986 
987  // assign the actual values to the placeholder:
988  size_t i = data_delimiters[pos_as_num];
989  for (size_t j = 0; j < count; ++j)
990  for (auto && v : value)
991  data_values[i++] = v;
992 
993  data_delimiters.reserve(data_values.size() + count);
994  data_delimiters.insert(data_delimiters.begin() + pos_as_num, count, *(data_delimiters.begin() + pos_as_num));
995 
996  // adapt delimiters of inserted
997  for (size_type i = 0; i < count; ++i)
998  data_delimiters[pos_as_num + i + 1] += value_len * (i + 1);
999 
1000  // adapt delimiters after that
1001  // TODO parallel execution policy or vectorization?
1002  std::for_each(data_delimiters.begin() + pos_as_num + count + 1,
1003  data_delimiters.end(),
1004  [full_len = value_len * count](auto & d)
1005  {
1006  d += full_len;
1007  });
1008 
1009  return begin() + pos_as_num;
1010  }
1011 
1038  template <std::forward_iterator begin_iterator_type, typename end_iterator_type>
1039  iterator insert(const_iterator pos, begin_iterator_type first, end_iterator_type last)
1040  requires iter_value_t_is_compatible_with_value_type<begin_iterator_type>
1041  && std::sized_sentinel_for<end_iterator_type, begin_iterator_type>
1042  {
1043  auto const pos_as_num = std::distance(cbegin(), pos);
1044  // TODO SEQAN_UNLIKELY
1045  if (last - first == 0)
1046  return begin() + pos_as_num;
1047 
1048  auto const ilist =
1049  std::ranges::subrange<begin_iterator_type, end_iterator_type>(first,
1050  last,
1051  std::ranges::distance(first, last));
1052 
1053  data_delimiters.reserve(data_values.size() + ilist.size());
1054  data_delimiters.insert(data_delimiters.begin() + pos_as_num,
1055  ilist.size(),
1056  *(data_delimiters.begin() + pos_as_num));
1057 
1058  // adapt delimiters of inserted region
1059  size_type full_len = 0;
1060  for (size_type i = 0; i < ilist.size(); ++i, ++first)
1061  {
1062  full_len += std::ranges::distance(*first);
1063  data_delimiters[pos_as_num + 1 + i] += full_len;
1064  }
1065 
1066  // adapt values of inserted region
1067  auto placeholder = views::repeat_n(std::ranges::range_value_t<value_type>{}, full_len) | std::views::common;
1068  // insert placeholder so the tail is moved only once:
1069  data_values.insert(data_values.begin() + data_delimiters[pos_as_num],
1070  std::ranges::begin(placeholder),
1071  std::ranges::end(placeholder));
1072 
1073  // assign the actual values to the placeholder:
1074  size_t i = data_delimiters[pos_as_num];
1075  for (auto && v0 : ilist)
1076  for (auto && v1 : v0)
1077  data_values[i++] = v1;
1078 
1079  // adapt delimiters behind inserted region
1080  // TODO parallel execution policy or vectorization?
1081  std::for_each(data_delimiters.begin() + pos_as_num + ilist.size() + 1,
1082  data_delimiters.end(),
1083  [full_len](auto & d)
1084  {
1085  d += full_len;
1086  });
1087 
1088  return begin() + pos_as_num;
1089  }
1090 
1112  template <std::ranges::forward_range rng_type>
1114  requires is_compatible_with_value_type<rng_type>
1115  {
1116  return insert(pos, ilist.begin(), ilist.end());
1117  }
1118 
1140  {
1141  auto const dist = std::distance(cbegin(), last);
1142  // TODO SEQAN_UNLIKELY
1143  if (last - first == 0)
1144  return begin() + dist;
1145 
1146  auto const distf = std::distance(cbegin(), first);
1147 
1148  // we need to scan once over the input
1149  size_type sum_size{0};
1150  for (; first != last; ++first)
1151  sum_size += std::ranges::size(*first);
1152 
1153  data_values.erase(data_values.begin() + data_delimiters[distf], data_values.begin() + data_delimiters[dist]);
1154 
1155  data_delimiters.erase(data_delimiters.begin() + distf + 1, data_delimiters.begin() + dist + 1);
1156 
1157  // adapt delimiters after that
1158  // TODO parallel execution policy or vectorization?
1159  std::for_each(data_delimiters.begin() + distf + 1,
1160  data_delimiters.end(),
1161  [sum_size](auto & d)
1162  {
1163  d -= sum_size;
1164  });
1165  return begin() + dist;
1166  }
1167 
1189  {
1190  return erase(pos, pos + 1);
1191  }
1192 
1214  template <std::ranges::forward_range rng_type>
1215  void push_back(rng_type && value)
1216  requires is_compatible_with_value_type<rng_type>
1217  {
1218  data_values.insert(data_values.end(), std::ranges::begin(value), std::ranges::end(value));
1219  data_delimiters.push_back(data_delimiters.back() + std::ranges::size(value));
1220  }
1221 
1240  void push_back()
1241  {
1242  data_delimiters.push_back(data_delimiters.back());
1243  }
1244 
1265  void last_push_back(std::ranges::range_value_t<underlying_container_type> const value)
1266  {
1267  data_values.push_back(value);
1268  ++data_delimiters.back();
1269  }
1270 
1292  template <std::ranges::forward_range rng_type>
1293  void last_append(rng_type && value)
1294  requires is_compatible_with_value_type<rng_type>
1295  {
1296  data_values.insert(data_values.end(), std::ranges::begin(value), std::ranges::end(value));
1297  data_delimiters.back() += std::ranges::size(value);
1298  }
1299 
1318  void pop_back()
1319  {
1320  assert(size() > 0);
1321  auto back_length = data_delimiters[size()] - data_delimiters[size() - 1];
1322  data_values.resize(data_values.size() - back_length);
1323  data_delimiters.pop_back();
1324  }
1325 
1354  void resize(size_type const count)
1355  {
1356  assert(count < max_size());
1357  data_delimiters.resize(count + 1, data_delimiters.back());
1358  data_values.resize(data_delimiters.back());
1359  }
1360 
1366  template <std::ranges::forward_range rng_type>
1367  void resize(size_type const count, rng_type && value)
1368  requires is_compatible_with_value_type<rng_type>
1369  {
1370  assert(count < max_size());
1371  assert(concat_size() + count * std::ranges::size(value) < data_values.max_size());
1372 
1373  if (count < size())
1374  resize(count);
1375  else if (count > size())
1376  insert(cend(), count - size(), std::forward<rng_type>(value));
1377  }
1378 
1392  constexpr void swap(concatenated_sequences & rhs) noexcept
1393  {
1394  std::swap(data_values, rhs.data_values);
1395  std::swap(data_delimiters, rhs.data_delimiters);
1396  }
1399  constexpr void swap(concatenated_sequences && rhs) noexcept
1400  {
1401  std::swap(data_values, rhs.data_values);
1402  std::swap(data_delimiters, rhs.data_delimiters);
1403  }
1405 
1414  constexpr bool operator==(concatenated_sequences const & rhs) const noexcept
1415  {
1416  return raw_data() == rhs.raw_data();
1417  }
1418 
1423  constexpr bool operator!=(concatenated_sequences const & rhs) const noexcept
1424  {
1425  return raw_data() != rhs.raw_data();
1426  }
1427 
1432  constexpr bool operator<(concatenated_sequences const & rhs) const noexcept
1433  {
1434  return raw_data() < rhs.raw_data();
1435  }
1436 
1441  constexpr bool operator>(concatenated_sequences const & rhs) const noexcept
1442  {
1443  return raw_data() > rhs.raw_data();
1444  }
1445 
1450  constexpr bool operator<=(concatenated_sequences const & rhs) const noexcept
1451  {
1452  return raw_data() <= rhs.raw_data();
1453  }
1454 
1459  constexpr bool operator>=(concatenated_sequences const & rhs) const noexcept
1460  {
1461  return raw_data() >= rhs.raw_data();
1462  }
1464 
1472  template <cereal_archive archive_t>
1473  void CEREAL_SERIALIZE_FUNCTION_NAME(archive_t & archive)
1474  {
1475  archive(data_values, data_delimiters);
1476  }
1478 };
1479 
1480 } // namespace seqan3
T begin(T... args)
Adaptions of concepts from the Cereal library.
Container that stores sequences concatenated internally.
Definition: concatenated_sequences.hpp:89
detail::random_access_iterator< concatenated_sequences const > const_iterator
The const iterator type of this container (a random access iterator).
Definition: concatenated_sequences.hpp:137
size_type capacity() const noexcept
Returns the number of elements that the container has currently allocated space for.
Definition: concatenated_sequences.hpp:749
concatenated_sequences()=default
Default constructors.
concatenated_sequences(size_type const count, rng_type &&value) requires is_compatible_with_value_type< rng_type >
Construct/assign with count times value.
Definition: concatenated_sequences.hpp:267
void reserve(size_type const new_cap)
Increase the capacity to a value that's greater or equal to new_cap.
Definition: concatenated_sequences.hpp:776
void last_push_back(std::ranges::range_value_t< underlying_container_type > const value)
Appends the given element-of-element value to the end of the underlying container.
Definition: concatenated_sequences.hpp:1263
constexpr concatenated_sequences(concatenated_sequences &&)=default
Default constructors.
requires static constexpr is_compatible_with_value_type< std::ranges::range_reference_t< t > > bool range_value_t_is_compatible_with_value_type
Whether a type is compatible with this class.
Definition: concatenated_sequences.hpp:202
reference concat()
Return the concatenation of all members.
Definition: concatenated_sequences.hpp:641
concatenated_sequences(begin_iterator_type begin_it, end_iterator_type end_it) requires std
Construct/assign from pair of iterators.
Definition: concatenated_sequences.hpp:295
requires static constexpr is_compatible_with_value_type< std::iter_reference_t< t > > bool iter_value_t_is_compatible_with_value_type
Whether a type is compatible with this class.
Definition: concatenated_sequences.hpp:192
constexpr bool operator>(concatenated_sequences const &rhs) const noexcept
Checks whether *this is greater than rhs.
Definition: concatenated_sequences.hpp:1439
bool empty() const noexcept
Checks whether the container is empty.
Definition: concatenated_sequences.hpp:688
reference operator[](size_type const i)
Return the i-th element as a view.
Definition: concatenated_sequences.hpp:558
constexpr void swap(concatenated_sequences &rhs) noexcept
Swap contents with another instance.
Definition: concatenated_sequences.hpp:1390
void clear() noexcept
Removes all elements from the container.
Definition: concatenated_sequences.hpp:887
~concatenated_sequences()=default
Default constructors.
void pop_back()
Removes the last element of the container.
Definition: concatenated_sequences.hpp:1316
reference front()
Return the first element as a view. Calling front on an empty container is undefined.
Definition: concatenated_sequences.hpp:585
reference back()
Return the last element as a view.
Definition: concatenated_sequences.hpp:612
concatenated_sequences(rng_of_rng_type &&rng_of_rng) requires range_value_t_is_compatible_with_value_type< rng_of_rng_type >
Construct/assign from a different range.
Definition: concatenated_sequences.hpp:238
size_type concat_capacity() const noexcept
Returns the concatenated size the container has currently allocated space for.
Definition: concatenated_sequences.hpp:841
iterator insert(const_iterator pos, rng_type &&value) requires is_compatible_with_value_type< rng_type >
Inserts value before position in the container.
Definition: concatenated_sequences.hpp:921
decltype(std::declval< std::decay_t< underlying_container_type > const & >()|views::slice(0, 1)) const_reference
An immutable views::slice that represents "one element", typically a std::span or std::string_view.
Definition: concatenated_sequences.hpp:123
void shrink_to_fit()
Requests the removal of unused capacity.
Definition: concatenated_sequences.hpp:800
constexpr concatenated_sequences(concatenated_sequences const &)=default
Default constructors.
constexpr bool operator==(concatenated_sequences const &rhs) const noexcept
Checks whether *this is equal to rhs.
Definition: concatenated_sequences.hpp:1412
detail::random_access_iterator< concatenated_sequences > iterator
The iterator type of this container (a random access iterator).
Definition: concatenated_sequences.hpp:130
void assign(size_type const count, rng_type &&value) requires(is_compatible_with_value_type< rng_type >)
Construct/assign with count times value.
Definition: concatenated_sequences.hpp:384
size_type max_size() const noexcept
Returns the maximum number of elements the container is able to hold due to system or library impleme...
Definition: concatenated_sequences.hpp:727
static constexpr bool is_compatible_with_value_type
Whether a type is compatible with this class's value_type or reference type.
Definition: concatenated_sequences.hpp:182
constexpr concatenated_sequences & operator=(concatenated_sequences const &)=default
Default constructors.
size_type size() const noexcept
Returns the number of elements in the container, i.e. std::distance(begin(), end()).
Definition: concatenated_sequences.hpp:706
void assign(rng_of_rng_type &&rng_of_rng) requires range_value_t_is_compatible_with_value_type< rng_of_rng_type >
Construct/assign from a different range.
Definition: concatenated_sequences.hpp:361
constexpr bool operator!=(concatenated_sequences const &rhs) const noexcept
Checks whether *this is not equal to rhs.
Definition: concatenated_sequences.hpp:1421
std::pair< decltype(data_values) &, decltype(data_delimiters) & > raw_data()
Provides direct, unsafe access to underlying data structures.
Definition: concatenated_sequences.hpp:659
void concat_reserve(size_type const new_cap)
Increase the concat_capacity() to a value that's greater or equal to new_cap.
Definition: concatenated_sequences.hpp:866
void push_back()
Appends an empty element to the end of the container.
Definition: concatenated_sequences.hpp:1238
constexpr concatenated_sequences & operator=(concatenated_sequences &&)=default
Default constructors.
iterator erase(const_iterator pos)
Removes specified elements from the container.
Definition: concatenated_sequences.hpp:1186
void resize(size_type const count)
Resizes the container to contain count elements.
Definition: concatenated_sequences.hpp:1352
value_type reference
A views::slice that represents "one element", typically a std::span.
Definition: concatenated_sequences.hpp:115
concatenated_sequences & operator=(std::initializer_list< value_type_t > ilist) requires is_compatible_with_value_type< value_type_t >
Construct/assign from std::initializer_list.
Definition: concatenated_sequences.hpp:338
constexpr bool operator>=(concatenated_sequences const &rhs) const noexcept
Checks whether *this is greater than or equal to rhs.
Definition: concatenated_sequences.hpp:1457
size_type concat_size() const noexcept
Returns the cumulative size of all elements in the container.
Definition: concatenated_sequences.hpp:823
decltype(std::declval< std::decay_t< underlying_container_type > & >()|views::slice(0, 1)) value_type
A views::slice that represents "one element", typically a std::span.
Definition: concatenated_sequences.hpp:108
constexpr bool operator<(concatenated_sequences const &rhs) const noexcept
Checks whether *this is less than rhs.
Definition: concatenated_sequences.hpp:1430
std::ranges::range_size_t< data_delimiters_type > size_type
An unsigned integer type (usually std::size_t)
Definition: concatenated_sequences.hpp:151
const_reference at(size_type const i) const
Definition: concatenated_sequences.hpp:534
void last_append(rng_type &&value) requires is_compatible_with_value_type< rng_type >
Appends the given elements to the end of the underlying container (increases size of last element by ...
Definition: concatenated_sequences.hpp:1291
std::ranges::range_difference_t< data_delimiters_type > difference_type
A signed integer type (usually std::ptrdiff_t)
Definition: concatenated_sequences.hpp:144
constexpr bool operator<=(concatenated_sequences const &rhs) const noexcept
Checks whether *this is less than or equal to rhs.
Definition: concatenated_sequences.hpp:1448
T declval(T... args)
T distance(T... args)
T end(T... args)
T for_each(T... args)
requires requires
The rank_type of the semi-alphabet; defined as the return type of seqan3::to_rank....
Definition: alphabet/concept.hpp:164
constexpr ptrdiff_t count
Count the occurrences of a type in a pack.
Definition: type_pack/traits.hpp:164
constexpr size_t size
The size of a type pack.
Definition: type_pack/traits.hpp:146
constexpr auto slice
A view adaptor that returns a half-open interval on the underlying range.
Definition: slice.hpp:178
constexpr auto repeat_n
A view factory that repeats a given value n times.
Definition: repeat_n.hpp:91
A more refined container concept than seqan3::random_access_container.
The main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:29
The <ranges> header from C++20's standard library.
Provides seqan3::views::repeat_n.
Provides seqan3::views::slice.
T swap(T... args)
Adaptations of concepts from the standard library.