17 #include <type_traits>
25 #if SEQAN3_WITH_CEREAL
26 # include <cereal/types/vector.hpp>
82 template <
typename underlying_container_type,
86 && std::is_same_v<std::ranges::range_size_t<underlying_container_type>,
87 std::ranges::range_value_t<data_delimiters_type>>
95 data_delimiters_type data_delimiters{0};
130 using iterator = detail::random_access_iterator<concatenated_sequences>;
137 using const_iterator = detail::random_access_iterator<concatenated_sequences const>;
151 using size_type = std::ranges::range_size_t<data_delimiters_type>;
162 template <std::ranges::range t>
163 static constexpr
bool is_compatible_with_value_type_aux(std::type_identity<t>)
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>>;
169 static constexpr
bool is_compatible_with_value_type_aux(...)
181 template <std::ranges::range t>
190 template <
typename t>
191 requires is_compatible_with_value_type<std::iter_reference_t<t>>
200 template <std::ranges::range t>
201 requires is_compatible_with_value_type<std::ranges::range_reference_t<t>>
237 template <std::ranges::input_range rng_of_rng_type>
239 requires range_value_t_is_compatible_with_value_type<rng_of_rng_type>
241 if constexpr (std::ranges::sized_range<rng_of_rng_type>)
244 for (
auto && val : rng_of_rng)
246 data_values.insert(data_values.end(), val.begin(), val.end());
247 data_delimiters.push_back(data_delimiters.back() + val.size());
266 template <std::ranges::forward_range rng_type>
268 requires is_compatible_with_value_type<rng_type>
274 insert(cend(),
count, std::forward<rng_type>(value));
294 template <std::forward_iterator begin_iterator_type,
typename end_iterator_type>
296 requires std::sized_sentinel_for<end_iterator_type, begin_iterator_type>
297 && iter_value_t_is_compatible_with_value_type<begin_iterator_type>
299 insert(cend(), begin_it, end_it);
316 template <std::ranges::forward_range value_type_t = value_type>
317 requires is_compatible_with_value_type<value_type_t>
337 template <std::ranges::forward_range value_type_t>
339 requires is_compatible_with_value_type<value_type_t>
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>
383 template <std::ranges::forward_range rng_type>
385 requires (is_compatible_with_value_type<rng_type>)
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>
431 template <std::ranges::forward_range rng_type = value_type>
433 requires is_compatible_with_value_type<rng_type>
530 throw std::out_of_range{
"Trying to access element behind the last in concatenated_sequences."};
539 throw std::out_of_range{
"Trying to access element behind the last in concatenated_sequences."};
562 return data_values |
views::slice(data_delimiters[i], data_delimiters[i + 1]);
569 return data_values |
views::slice(data_delimiters[i], data_delimiters[i + 1]);
616 return (*
this)[
size() - 1];
623 return (*
this)[
size() - 1];
662 return {data_values, data_delimiters};
666 std::pair<decltype(data_values)
const &, decltype(data_delimiters)
const &>
raw_data()
const
668 return {data_values, data_delimiters};
689 bool empty() const noexcept
709 return data_delimiters.size() - 1;
730 return data_delimiters.max_size() - 1;
752 return data_delimiters.capacity();
779 data_delimiters.reserve(new_cap + 1);
803 data_values.shrink_to_fit();
804 data_delimiters.shrink_to_fit();
826 return data_values.size();
844 return data_values.capacity();
869 data_values.reserve(new_cap);
888 void clear() noexcept
891 data_delimiters.clear();
892 data_delimiters.push_back(0);
921 template <std::ranges::forward_range rng_type>
923 requires is_compatible_with_value_type<rng_type>
925 return insert(pos, 1, std::forward<rng_type>(value));
955 template <std::ranges::forward_range rng_type>
957 requires is_compatible_with_value_type<rng_type>
962 return begin() + pos_as_num;
974 if constexpr (std::ranges::sized_range<rng_type>)
977 value_len =
std::distance(std::ranges::begin(value), std::ranges::end(value));
979 data_values.reserve(data_values.size() +
count * value_len);
981 views::repeat_n(std::ranges::range_value_t<rng_type>{},
count * value_len) | std::views::common;
983 data_values.insert(data_values.begin() + data_delimiters[pos_as_num],
984 std::ranges::begin(placeholder),
985 std::ranges::end(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;
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));
998 data_delimiters[pos_as_num + i + 1] += value_len * (i + 1);
1003 data_delimiters.end(),
1004 [full_len = value_len *
count](
auto & d)
1009 return begin() + pos_as_num;
1038 template <std::forward_iterator begin_iterator_type,
typename end_iterator_type>
1040 requires iter_value_t_is_compatible_with_value_type<begin_iterator_type>
1041 && std::sized_sentinel_for<end_iterator_type, begin_iterator_type>
1045 if (last - first == 0)
1046 return begin() + pos_as_num;
1049 std::ranges::subrange<begin_iterator_type, end_iterator_type>(first,
1051 std::ranges::distance(first, last));
1053 data_delimiters.reserve(data_values.size() + ilist.
size());
1054 data_delimiters.insert(data_delimiters.begin() + pos_as_num,
1056 *(data_delimiters.begin() + pos_as_num));
1062 full_len += std::ranges::distance(*first);
1063 data_delimiters[pos_as_num + 1 + i] += full_len;
1067 auto placeholder =
views::repeat_n(std::ranges::range_value_t<value_type>{}, full_len) | std::views::common;
1069 data_values.insert(data_values.begin() + data_delimiters[pos_as_num],
1070 std::ranges::begin(placeholder),
1071 std::ranges::end(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;
1081 std::for_each(data_delimiters.begin() + pos_as_num + ilist.size() + 1,
1082 data_delimiters.end(),
1083 [full_len](
auto & d)
1088 return begin() + pos_as_num;
1112 template <std::ranges::forward_range rng_type>
1114 requires is_compatible_with_value_type<rng_type>
1143 if (last - first == 0)
1144 return begin() + dist;
1150 for (; first != last; ++first)
1153 data_values.erase(data_values.begin() + data_delimiters[distf], data_values.begin() + data_delimiters[dist]);
1155 data_delimiters.erase(data_delimiters.begin() + distf + 1, data_delimiters.begin() + dist + 1);
1160 data_delimiters.end(),
1161 [sum_size](
auto & d)
1165 return begin() + dist;
1190 return erase(pos, pos + 1);
1214 template <std::ranges::forward_range rng_type>
1216 requires is_compatible_with_value_type<rng_type>
1218 data_values.insert(data_values.end(), std::ranges::begin(value), std::ranges::end(value));
1242 data_delimiters.push_back(data_delimiters.back());
1265 void last_push_back(std::ranges::range_value_t<underlying_container_type>
const value)
1267 data_values.push_back(value);
1268 ++data_delimiters.back();
1292 template <std::ranges::forward_range rng_type>
1294 requires is_compatible_with_value_type<rng_type>
1296 data_values.insert(data_values.end(), std::ranges::begin(value), std::ranges::end(value));
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();
1357 data_delimiters.resize(
count + 1, data_delimiters.back());
1358 data_values.resize(data_delimiters.back());
1366 template <std::ranges::forward_range rng_type>
1368 requires is_compatible_with_value_type<rng_type>
1394 std::swap(data_values, rhs.data_values);
1395 std::swap(data_delimiters, rhs.data_delimiters);
1401 std::swap(data_values, rhs.data_values);
1402 std::swap(data_delimiters, rhs.data_delimiters);
1416 return raw_data() == rhs.raw_data();
1425 return raw_data() != rhs.raw_data();
1434 return raw_data() < rhs.raw_data();
1443 return raw_data() > rhs.raw_data();
1452 return raw_data() <= rhs.raw_data();
1461 return raw_data() >= rhs.raw_data();
1472 template <cereal_archive archive_t>
1473 void CEREAL_SERIALIZE_FUNCTION_NAME(archive_t & archive)
1475 archive(data_values, data_delimiters);
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
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.
Adaptations of concepts from the standard library.