SeqAn3  3.1.0
The Modern C++ library for sequence analysis.
concatenated_sequences.hpp
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------------------------------
2 // Copyright (c) 2006-2021, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2021, 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 <seqan3/std/iterator>
16 #include <seqan3/std/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::detail
30 {
31 
34 struct as_const_fn
35 {
37  template <typename t>
38  t operator()(t const && arg) const
39  {
40  return std::move(arg);
41  }
42 
44  template <typename t>
45  t const & operator()(t const & arg) const
46  {
47  return arg;
48  }
49 };
50 
87 inline constexpr auto as_const = std::views::transform(seqan3::detail::as_const_fn{});
88 
102 template <typename value_type, bool const_>
103 struct concatenated_sequences_reference_proxy :
104  public std::conditional_t<const_,
105  decltype(std::declval<value_type const &>() | detail::as_const | views::slice(0,1)),
106  decltype(std::declval<value_type &>() | views::slice(0,1))>
107 {
109  using base_t =
110  std::conditional_t<const_,
111  decltype(std::declval<value_type const &>() | detail::as_const | views::slice(0,1)),
112  decltype(std::declval<value_type &>() | views::slice(0,1))>;
113 
115  using base_t::base_t;
116 
118  concatenated_sequences_reference_proxy(base_t && rhs) : base_t{std::move(rhs)} {}
119 
121  operator value_type() const
122  {
123  value_type ret;
124  ret.resize(std::ranges::size(*this));
125  std::ranges::copy(*this, std::ranges::begin(ret));
126  return ret;
127  }
128 };
129 
130 } // namespace seqan3::detail
131 
132 namespace seqan3
133 {
134 
181 template <typename inner_type,
182  typename data_delimiters_type = std::vector<typename inner_type::size_type>>
186  std::is_same_v<std::ranges::range_size_t<inner_type>, std::ranges::range_value_t<data_delimiters_type>>
189 {
190 protected:
193  std::decay_t<inner_type> data_values;
195  data_delimiters_type data_delimiters{0};
196 
197 public:
199 
209 
215  using reference = detail::concatenated_sequences_reference_proxy<value_type, false>;
216 
222  using const_reference = detail::concatenated_sequences_reference_proxy<value_type, true>;
223 
229  using iterator = detail::random_access_iterator<concatenated_sequences>;
230 
236  using const_iterator = detail::random_access_iterator<concatenated_sequences const>;
237 
243  using difference_type = std::ranges::range_difference_t<data_delimiters_type>;
244 
250  using size_type = std::ranges::range_size_t<data_delimiters_type>;
252 
254  // this signals to range-v3 that something is a container :|
255  using allocator_type = void;
257 
258 protected:
265  // unfortunately we cannot specialise the variable template so we have to add an auxiliary here
266  template <std::ranges::range t>
267  static constexpr bool is_compatible_with_value_type_aux(std::type_identity<t>)
268  {
269  return range_dimension_v<t> == range_dimension_v<value_type> &&
270  std::convertible_to<std::ranges::range_reference_t<t>, std::ranges::range_value_t<value_type>>;
271  }
272 
273  static constexpr bool is_compatible_with_value_type_aux(...)
274  {
275  return false;
276  }
278 
284  // we explicitly check same-ness, because these types may not be fully resolved, yet
285  template <std::ranges::range t>
286  static constexpr bool is_compatible_with_value_type = is_compatible_with_value_type_aux(std::type_identity<t>{});
287 
293  // cannot use the concept, because this class is not yet fully defined
294  template <typename t>
296  requires is_compatible_with_value_type<std::iter_reference_t<t>>
298  static constexpr bool iter_value_t_is_compatible_with_value_type = true;
299 
305  // cannot use the concept, because this class is not yet fully defined
306  template <std::ranges::range t>
308  requires is_compatible_with_value_type<std::ranges::range_reference_t<t>>
310  static constexpr bool range_value_t_is_compatible_with_value_type = true;
312 
313 public:
320  constexpr concatenated_sequences(concatenated_sequences const &) = default;
329 
345  template <std::ranges::input_range rng_of_rng_type>
346  concatenated_sequences(rng_of_rng_type && rng_of_rng)
348  requires range_value_t_is_compatible_with_value_type<rng_of_rng_type>
350  {
351  if constexpr (std::ranges::sized_range<rng_of_rng_type>)
352  data_delimiters.reserve(std::ranges::size(rng_of_rng) + 1);
353 
354  for (auto && val : rng_of_rng)
355  {
356  data_values.insert(data_values.end(), val.begin(), val.end());
357  data_delimiters.push_back(data_delimiters.back() + val.size());
358  }
359  }
360 
376  template <std::ranges::forward_range rng_type>
377  concatenated_sequences(size_type const count, rng_type && value)
379  requires is_compatible_with_value_type<rng_type>
381  {
382  // TODO SEQAN_UNLIKELY
383  if (count == 0)
384  return;
385 
386  insert(cend(), count, std::forward<rng_type>(value));
387  }
388 
406  template <std::forward_iterator begin_iterator_type, typename end_iterator_type>
407  concatenated_sequences(begin_iterator_type begin_it, end_iterator_type end_it)
409  requires std::sized_sentinel_for<end_iterator_type, begin_iterator_type> &&
410  iter_value_t_is_compatible_with_value_type<begin_iterator_type>
412  {
413  insert(cend(), begin_it, end_it);
414  }
415 
430  template <std::ranges::forward_range value_type_t = value_type>
432  requires is_compatible_with_value_type<value_type_t>
435  {
436  assign(std::begin(ilist), std::end(ilist));
437  }
438 
453  template <std::ranges::forward_range value_type_t>
456  requires is_compatible_with_value_type<value_type_t>
458  {
459  assign(std::begin(ilist), std::end(ilist));
460  return *this;
461  }
462 
478  template <std::ranges::input_range rng_of_rng_type>
479  void assign(rng_of_rng_type && rng_of_rng)
481  requires range_value_t_is_compatible_with_value_type<rng_of_rng_type>
483  {
484  concatenated_sequences rhs{std::forward<rng_of_rng_type>(rng_of_rng)};
485  swap(rhs);
486  }
487 
503  template <std::ranges::forward_range rng_type>
504  void assign(size_type const count, rng_type && value)
506  requires (is_compatible_with_value_type<rng_type>)
508  {
509  concatenated_sequences rhs{count, value};
510  swap(rhs);
511  }
512 
530  template <std::forward_iterator begin_iterator_type, typename end_iterator_type>
531  void assign(begin_iterator_type begin_it, end_iterator_type end_it)
533  requires iter_value_t_is_compatible_with_value_type<begin_iterator_type> &&
534  std::sized_sentinel_for<end_iterator_type, begin_iterator_type>
536  {
537  concatenated_sequences rhs{begin_it, end_it};
538  swap(rhs);
539  }
540 
555  template <std::ranges::forward_range rng_type = value_type>
558  requires is_compatible_with_value_type<rng_type>
560  {
561  assign(std::begin(ilist), std::end(ilist));
562  }
563 
565 
584  iterator begin() noexcept
585  {
586  return iterator{*this};
587  }
588 
590  const_iterator begin() const noexcept
591  {
592  return const_iterator{*this};
593  }
594 
596  const_iterator cbegin() const noexcept
597  {
598  return const_iterator{*this};
599  }
600 
616  iterator end() noexcept
617  {
618  return iterator{*this, size()};
619  }
620 
622  const_iterator end() const noexcept
623  {
624  return const_iterator{*this, size()};
625  }
626 
628  const_iterator cend() const noexcept
629  {
630  return const_iterator{*this, size()};
631  }
633 
653  {
654  //TODO add SEQAN_UNLIKELY
655  if (i >= size())
656  throw std::out_of_range{"Trying to access element behind the last in concatenated_sequences."};
657  return (*this)[i];
658  }
659 
661  const_reference at(size_type const i) const
662  {
663  //TODO add SEQAN_UNLIKELY
664  if (i >= size())
665  throw std::out_of_range{"Trying to access element behind the last in concatenated_sequences."};
666  return (*this)[i];
667  }
668 
686  {
687  assert(i < size());
688  return data_values | views::slice(data_delimiters[i], data_delimiters[i+1]);
689  }
690 
693  {
694  assert(i < size());
695  return data_values | detail::as_const | views::slice(data_delimiters[i], data_delimiters[i+1]);
696  }
697 
713  {
714  assert(size() > 0);
715  return (*this)[0];
716  }
717 
720  {
721  assert(size() > 0);
722  return (*this)[0];
723  }
724 
740  {
741  assert(size() > 0);
742  return (*this)[size()-1];
743  }
744 
747  {
748  assert(size() > 0);
749  return (*this)[size()-1];
750  }
751 
769  {
770  return data_values | views::slice(static_cast<size_type>(0), concat_size());
771  }
772 
775  {
776  return data_values | detail::as_const | views::slice(static_cast<size_type>(0), concat_size());
777  }
778 
786  std::pair<decltype(data_values) &, decltype(data_delimiters) &> raw_data()
787  {
788  return {data_values, data_delimiters};
789  }
790 
792  std::pair<decltype(data_values) const &, decltype(data_delimiters) const &> raw_data() const
793  {
794  return {std::as_const(data_values), std::as_const(data_delimiters)};
795  }
796 
798 
815  bool empty() const noexcept
816  {
817  return size() == 0;
818  }
819 
833  size_type size() const noexcept
834  {
835  return data_delimiters.size() - 1;
836  }
837 
854  size_type max_size() const noexcept
855  {
856  return data_delimiters.max_size() - 1;
857  }
858 
876  size_type capacity() const noexcept
877  {
878  return data_delimiters.capacity();
879  }
880 
903  void reserve(size_type const new_cap)
904  {
905  data_delimiters.reserve(new_cap + 1);
906  }
907 
928  {
929  data_values.shrink_to_fit();
930  data_delimiters.shrink_to_fit();
931  }
933 
950  size_type concat_size() const noexcept
951  {
952  return data_values.size();
953  }
954 
968  size_type concat_capacity() const noexcept
969  {
970  return data_values.capacity();
971  }
972 
993  void concat_reserve(size_type const new_cap)
994  {
995  data_values.reserve(new_cap);
996  }
998 
999 
1016  void clear() noexcept
1017  {
1018  data_values.clear();
1019  data_delimiters.clear();
1020  data_delimiters.push_back(0);
1021  }
1022 
1049  template <std::ranges::forward_range rng_type>
1050  iterator insert(const_iterator pos, rng_type && value)
1052  requires is_compatible_with_value_type<rng_type>
1054  {
1055  return insert(pos, 1, std::forward<rng_type>(value));
1056  }
1057  // no specialisation for temporaries, since we have to copy anyway
1058 
1085  template <std::ranges::forward_range rng_type>
1086  iterator insert(const_iterator pos, size_type const count, rng_type && value)
1088  requires is_compatible_with_value_type<rng_type>
1090  {
1091  auto const pos_as_num = std::distance(cbegin(), pos); // we want to insert BEFORE this position
1092  // TODO SEQAN_UNLIKELY
1093  if (count == 0)
1094  return begin() + pos_as_num;
1095 
1096  /* TODO implement views::flat_repeat_n that is like
1097  * views::repeat_n(value, count) | std::views::join | ranges::views::bounded;
1098  * but preserves random access and size.
1099  *
1100  * then do
1101  * auto concatenated = ranges::views::flat_repeat_n(value, count);
1102  * insert(pos, concatenated.cbegin(), concatenated.cend())
1103  */
1104 
1105  size_type value_len = 0;
1106  if constexpr (std::ranges::sized_range<rng_type>)
1107  value_len = std::ranges::size(value);
1108  else
1109  value_len = std::distance(std::ranges::begin(value), std::ranges::end(value));
1110 
1111  data_values.reserve(data_values.size() + count * value_len);
1112  auto placeholder = views::repeat_n(std::ranges::range_value_t<rng_type>{}, count * value_len)
1113  | std::views::common;
1114  // insert placeholder so the tail is moved once:
1115  data_values.insert(data_values.begin() + data_delimiters[pos_as_num],
1116  std::ranges::begin(placeholder),
1117  std::ranges::end(placeholder));
1118 
1119  // assign the actual values to the placeholder:
1120  size_t i = data_delimiters[pos_as_num];
1121  for (size_t j = 0; j < count; ++j)
1122  for (auto && v : value)
1123  data_values[i++] = v;
1124 
1125  data_delimiters.reserve(data_values.size() + count);
1126  data_delimiters.insert(data_delimiters.begin() + pos_as_num,
1127  count,
1128  *(data_delimiters.begin() + pos_as_num));
1129 
1130  // adapt delimiters of inserted
1131  for (size_type i = 0; i < count; ++i)
1132  data_delimiters[pos_as_num + i + 1] += value_len * (i + 1);
1133 
1134  // adapt delimiters after that
1135  // TODO parallel execution policy or vectorization?
1136  std::for_each(data_delimiters.begin() + pos_as_num + count + 1,
1137  data_delimiters.end(),
1138  [full_len = value_len * count] (auto & d) { d += full_len; });
1139 
1140  return begin() + pos_as_num;
1141  }
1142 
1169  template <std::forward_iterator begin_iterator_type, typename end_iterator_type>
1170  iterator insert(const_iterator pos, begin_iterator_type first, end_iterator_type last)
1172  requires iter_value_t_is_compatible_with_value_type<begin_iterator_type> &&
1173  std::sized_sentinel_for<end_iterator_type, begin_iterator_type>
1175  {
1176  auto const pos_as_num = std::distance(cbegin(), pos);
1177  // TODO SEQAN_UNLIKELY
1178  if (last - first == 0)
1179  return begin() + pos_as_num;
1180 
1181  auto const ilist =
1182  std::ranges::subrange<begin_iterator_type, end_iterator_type>(first,
1183  last,
1184  std::ranges::distance(first, last));
1185 
1186  data_delimiters.reserve(data_values.size() + ilist.size());
1187  data_delimiters.insert(data_delimiters.begin() + pos_as_num,
1188  ilist.size(),
1189  *(data_delimiters.begin() + pos_as_num));
1190 
1191 
1192  // adapt delimiters of inserted region
1193  size_type full_len = 0;
1194  for (size_type i = 0; i < ilist.size(); ++i, ++first)
1195  {
1196  full_len += std::ranges::distance(*first);
1197  data_delimiters[pos_as_num + 1 + i] += full_len;
1198  }
1199 
1200  // adapt values of inserted region
1201  auto placeholder = views::repeat_n(std::ranges::range_value_t<value_type>{}, full_len)
1202  | std::views::common;
1203  // insert placeholder so the tail is moved only once:
1204  data_values.insert(data_values.begin() + data_delimiters[pos_as_num],
1205  std::ranges::begin(placeholder),
1206  std::ranges::end(placeholder));
1207 
1208  // assign the actual values to the placeholder:
1209  size_t i = data_delimiters[pos_as_num];
1210  for (auto && v0 : ilist)
1211  for (auto && v1 : v0)
1212  data_values[i++] = v1;
1213 
1214 
1215  // adapt delimiters behind inserted region
1216  // TODO parallel execution policy or vectorization?
1217  std::for_each(data_delimiters.begin() + pos_as_num + ilist.size() + 1,
1218  data_delimiters.end(),
1219  [full_len] (auto & d) { d += full_len; });
1220 
1221  return begin() + pos_as_num;
1222  }
1223 
1245  template <std::ranges::forward_range rng_type>
1248  requires is_compatible_with_value_type<rng_type>
1250  {
1251  return insert(pos, ilist.begin(), ilist.end());
1252  }
1253 
1275  {
1276  auto const dist = std::distance(cbegin(), last);
1277  // TODO SEQAN_UNLIKELY
1278  if (last - first == 0)
1279  return begin() + dist;
1280 
1281  auto const distf = std::distance(cbegin(), first);
1282 
1283  // we need to scan once over the input
1284  size_type sum_size{0};
1285  for (; first != last; ++first)
1286  sum_size += std::ranges::size(*first);
1287 
1288  data_values.erase(data_values.begin() + data_delimiters[distf],
1289  data_values.begin() + data_delimiters[dist]);
1290 
1291  data_delimiters.erase(data_delimiters.begin() + distf + 1,
1292  data_delimiters.begin() + dist + 1);
1293 
1294  // adapt delimiters after that
1295  // TODO parallel execution policy or vectorization?
1296  std::for_each(data_delimiters.begin() + distf + 1,
1297  data_delimiters.end(),
1298  [sum_size] (auto & d) { d -= sum_size; });
1299  return begin() + dist;
1300  }
1301 
1323  {
1324  return erase(pos, pos + 1);
1325  }
1326 
1345  template <std::ranges::forward_range rng_type>
1346  void push_back(rng_type && value)
1348  requires is_compatible_with_value_type<rng_type>
1350  {
1351  data_values.insert(data_values.end(), std::ranges::begin(value), std::ranges::end(value));
1352  data_delimiters.push_back(data_delimiters.back() + std::ranges::size(value));
1353  }
1354 
1373  void pop_back()
1374  {
1375  assert(size() > 0);
1376  auto back_length = data_delimiters[size()] - data_delimiters[size() - 1];
1377  data_values.resize(data_values.size() - back_length);
1378  data_delimiters.pop_back();
1379  }
1380 
1409  void resize(size_type const count)
1410  {
1411  assert(count < max_size());
1412  data_delimiters.resize(count + 1, data_delimiters.back());
1413  data_values.resize(data_delimiters.back());
1414  }
1415 
1421  template <std::ranges::forward_range rng_type>
1422  void resize(size_type const count, rng_type && value)
1424  requires is_compatible_with_value_type<rng_type>
1426  {
1427  assert(count < max_size());
1428  assert(concat_size() + count * std::ranges::size(value) < data_values.max_size());
1429 
1430  if (count < size())
1431  resize(count);
1432  else if (count > size())
1433  insert(cend(), count - size(), std::forward<rng_type>(value));
1434  }
1435 
1449  constexpr void swap(concatenated_sequences & rhs) noexcept
1450  {
1451  std::swap(data_values, rhs.data_values);
1452  std::swap(data_delimiters, rhs.data_delimiters);
1453  }
1454 
1456  constexpr void swap(concatenated_sequences && rhs) noexcept
1457  {
1458  std::swap(data_values, rhs.data_values);
1459  std::swap(data_delimiters, rhs.data_delimiters);
1460  }
1462 
1471  constexpr bool operator==(concatenated_sequences const & rhs) const noexcept
1472  {
1473  return raw_data() == rhs.raw_data();
1474  }
1475 
1480  constexpr bool operator!=(concatenated_sequences const & rhs) const noexcept
1481  {
1482  return raw_data() != rhs.raw_data();
1483  }
1484 
1489  constexpr bool operator<(concatenated_sequences const & rhs) const noexcept
1490  {
1491  return raw_data() < rhs.raw_data();
1492  }
1493 
1498  constexpr bool operator>(concatenated_sequences const & rhs) const noexcept
1499  {
1500  return raw_data() > rhs.raw_data();
1501  }
1502 
1507  constexpr bool operator<=(concatenated_sequences const & rhs) const noexcept
1508  {
1509  return raw_data() <= rhs.raw_data();
1510  }
1511 
1516  constexpr bool operator>=(concatenated_sequences const & rhs) const noexcept
1517  {
1518  return raw_data() >= rhs.raw_data();
1519  }
1521 
1529  template <cereal_archive archive_t>
1530  void CEREAL_SERIALIZE_FUNCTION_NAME(archive_t & archive)
1531  {
1532  archive(data_values, data_delimiters);
1533  }
1535 };
1536 
1537 } // namespace seqan3
T as_const(T... args)
T begin(T... args)
Adaptions of concepts from the Cereal library.
Container that stores sequences concatenated internally.
Definition: concatenated_sequences.hpp:189
std::pair< decltype(data_values) &, decltype(data_delimiters) & > raw_data()
Provides direct, unsafe access to underlying data structures.
Definition: concatenated_sequences.hpp:786
iterator erase(const_iterator first, const_iterator last)
Removes specified elements from the container.
Definition: concatenated_sequences.hpp:1274
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:854
void shrink_to_fit()
Requests the removal of unused capacity.
Definition: concatenated_sequences.hpp:927
size_type concat_size() const noexcept
Returns the cumulative size of all elements in the container.
Definition: concatenated_sequences.hpp:950
concatenated_sequences(size_type const count, rng_type &&value)
Construct/assign with count times value.
Definition: concatenated_sequences.hpp:377
constexpr concatenated_sequences & operator=(concatenated_sequences const &)=default
Default constructors.
void assign(rng_of_rng_type &&rng_of_rng)
Construct/assign from a different range.
Definition: concatenated_sequences.hpp:479
constexpr bool operator<(concatenated_sequences const &rhs) const noexcept
Checks whether *this is less than rhs.
Definition: concatenated_sequences.hpp:1489
size_type size() const noexcept
Returns the number of elements in the container, i.e. std::distance(begin(), end()).
Definition: concatenated_sequences.hpp:833
size_type concat_capacity() const noexcept
Returns the concatenated size the container has currently allocated space for.
Definition: concatenated_sequences.hpp:968
void assign(begin_iterator_type begin_it, end_iterator_type end_it)
Construct/assign from pair of iterators.
Definition: concatenated_sequences.hpp:531
iterator end() noexcept
Returns an iterator to the element following the last element of the container.
Definition: concatenated_sequences.hpp:616
constexpr concatenated_sequences(concatenated_sequences &&)=default
Default constructors.
iterator insert(const_iterator pos, rng_type &&value)
Inserts value before position in the container.
Definition: concatenated_sequences.hpp:1050
concatenated_sequences(std::initializer_list< value_type_t > ilist)
Construct/assign from std::initializer_list.
Definition: concatenated_sequences.hpp:434
iterator erase(const_iterator pos)
Removes specified elements from the container.
Definition: concatenated_sequences.hpp:1322
const_reference concat() const
Return the concatenation of all members.
Definition: concatenated_sequences.hpp:774
reference front()
Return the first element as a view. Calling front on an empty container is undefined.
Definition: concatenated_sequences.hpp:712
constexpr bool operator>=(concatenated_sequences const &rhs) const noexcept
Checks whether *this is greater than or equal to rhs.
Definition: concatenated_sequences.hpp:1516
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:1471
static constexpr bool iter_value_t_is_compatible_with_value_type
Whether a type is compatible with this class.
Definition: concatenated_sequences.hpp:298
reference at(size_type const i)
Return the i-th element as a view.
Definition: concatenated_sequences.hpp:652
const_reference front() const
Return the first element as a view. Calling front on an empty container is undefined.
Definition: concatenated_sequences.hpp:719
constexpr void swap(concatenated_sequences &rhs) noexcept
Swap contents with another instance.
Definition: concatenated_sequences.hpp:1449
constexpr void swap(concatenated_sequences &&rhs) noexcept
Swap contents with another instance.
Definition: concatenated_sequences.hpp:1456
concatenated_sequences()=default
Default constructors.
const_reference operator[](size_type const i) const
Return the i-th element as a view.
Definition: concatenated_sequences.hpp:692
void resize(size_type const count)
Resizes the container to contain count elements.
Definition: concatenated_sequences.hpp:1409
std::pair< decltype(data_values) const &, decltype(data_delimiters) const & > raw_data() const
Provides direct, unsafe access to underlying data structures.
Definition: concatenated_sequences.hpp:792
static constexpr bool range_value_t_is_compatible_with_value_type
Whether a type is compatible with this class.
Definition: concatenated_sequences.hpp:310
const_iterator end() const noexcept
Returns an iterator to the element following the last element of the container.
Definition: concatenated_sequences.hpp:622
void push_back(rng_type &&value)
Appends the given element value to the end of the container.
Definition: concatenated_sequences.hpp:1346
bool empty() const noexcept
Checks whether the container is empty.
Definition: concatenated_sequences.hpp:815
constexpr bool operator!=(concatenated_sequences const &rhs) const noexcept
Checks whether *this is not equal to rhs.
Definition: concatenated_sequences.hpp:1480
const_iterator begin() const noexcept
Returns an iterator to the first element of the container.
Definition: concatenated_sequences.hpp:590
iterator begin() noexcept
Returns an iterator to the first element of the container.
Definition: concatenated_sequences.hpp:584
detail::concatenated_sequences_reference_proxy< value_type, false > reference
A proxy of type views::slice that represents the range on the concatenated vector.
Definition: concatenated_sequences.hpp:215
std::ranges::range_size_t< data_delimiters_type > size_type
An unsigned integer type (usually std::size_t)
Definition: concatenated_sequences.hpp:250
const_reference back() const
Return the last element as a view.
Definition: concatenated_sequences.hpp:746
concatenated_sequences(begin_iterator_type begin_it, end_iterator_type end_it)
Construct/assign from pair of iterators.
Definition: concatenated_sequences.hpp:407
~concatenated_sequences()=default
Default constructors.
reference back()
Return the last element as a view.
Definition: concatenated_sequences.hpp:739
void assign(size_type const count, rng_type &&value)
Construct/assign with count times value.
Definition: concatenated_sequences.hpp:504
detail::concatenated_sequences_reference_proxy< value_type, true > const_reference
An immutable proxy of type views::slice that represents the range on the concatenated vector.
Definition: concatenated_sequences.hpp:222
constexpr bool operator>(concatenated_sequences const &rhs) const noexcept
Checks whether *this is greater than rhs.
Definition: concatenated_sequences.hpp:1498
void clear() noexcept
Removes all elements from the container.
Definition: concatenated_sequences.hpp:1016
const_iterator cend() const noexcept
Returns an iterator to the element following the last element of the container.
Definition: concatenated_sequences.hpp:628
size_type capacity() const noexcept
Returns the number of elements that the container has currently allocated space for.
Definition: concatenated_sequences.hpp:876
detail::random_access_iterator< concatenated_sequences const > const_iterator
The const iterator type of this container (a random access iterator).
Definition: concatenated_sequences.hpp:236
iterator insert(const_iterator pos, std::initializer_list< rng_type > const &ilist)
Inserts elements from initializer list before position in the container.
Definition: concatenated_sequences.hpp:1246
const_iterator cbegin() const noexcept
Returns an iterator to the first element of the container.
Definition: concatenated_sequences.hpp:596
std::ranges::range_difference_t< data_delimiters_type > difference_type
A signed integer type (usually std::ptrdiff_t)
Definition: concatenated_sequences.hpp:243
iterator insert(const_iterator pos, begin_iterator_type first, end_iterator_type last)
Inserts elements from range [first, last) before position in the container.
Definition: concatenated_sequences.hpp:1170
detail::random_access_iterator< concatenated_sequences > iterator
The iterator type of this container (a random access iterator).
Definition: concatenated_sequences.hpp:229
const_reference at(size_type const i) const
Return the i-th element as a view.
Definition: concatenated_sequences.hpp:661
void resize(size_type const count, rng_type &&value)
Resizes the container to contain count elements.
Definition: concatenated_sequences.hpp:1422
concatenated_sequences & operator=(std::initializer_list< value_type_t > ilist)
Construct/assign from std::initializer_list.
Definition: concatenated_sequences.hpp:454
iterator insert(const_iterator pos, size_type const count, rng_type &&value)
Inserts count copies of value before position in the container.
Definition: concatenated_sequences.hpp:1086
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:993
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:286
void pop_back()
Removes the last element of the container.
Definition: concatenated_sequences.hpp:1373
reference concat()
Return the concatenation of all members.
Definition: concatenated_sequences.hpp:768
concatenated_sequences(rng_of_rng_type &&rng_of_rng)
Construct/assign from a different range.
Definition: concatenated_sequences.hpp:346
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:903
void assign(std::initializer_list< rng_type > ilist)
Construct/assign from std::initializer_list.
Definition: concatenated_sequences.hpp:556
constexpr concatenated_sequences & operator=(concatenated_sequences &&)=default
Default constructors.
reference operator[](size_type const i)
Return the i-th element as a view.
Definition: concatenated_sequences.hpp:685
constexpr bool operator<=(concatenated_sequences const &rhs) const noexcept
Checks whether *this is less than or equal to rhs.
Definition: concatenated_sequences.hpp:1507
T distance(T... args)
T end(T... args)
T for_each(T... args)
decltype(detail::transform< trait_t >(list_t{})) transform
Apply a transformation trait to every type in the list and return a seqan3::type_list of the results.
Definition: traits.hpp:471
constexpr ptrdiff_t count
Count the occurrences of a type in a pack.
Definition: traits.hpp:169
constexpr size_t size
The size of a type pack.
Definition: traits.hpp:151
constexpr auto slice
A view adaptor that returns a half-open interval on the underlying range.
Definition: slice.hpp:183
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 <iterator> header from C++20's standard library.
The main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:29
SeqAn specific customisations in the standard namespace.
The <ranges> header from C++20's standard library.
Provides seqan3::views::repeat_n.
Provides seqan3::views::slice.
The identity transformation (a transformation_trait that returns the input).
Definition: type_traits:87
T swap(T... args)
Adaptations of concepts from the standard library.