BioC++ core-0.7.0
The Modern C++ libraries for Bioinformatics.
 
Loading...
Searching...
No Matches
concatenated_sequences.hpp
Go to the documentation of this file.
1// -----------------------------------------------------------------------------------------------------
2// Copyright (c) 2022 deCODE Genetics
3// Copyright (c) 2006-2020, Knut Reinert & Freie Universität Berlin
4// Copyright (c) 2016-2020, Knut Reinert & MPI für molekulare Genetik
5// This file may be used, modified and/or redistributed under the terms of the 3-clause BSD-License
6// shipped with this file and also available at: https://github.com/biocpp/biocpp-core/blob/main/LICENSE.md
7// -----------------------------------------------------------------------------------------------------
8
14#pragma once
15
16#include <iterator>
17#include <ranges>
18#include <type_traits>
19#include <utility>
20#include <vector>
21
26
27namespace bio::ranges
28{
29
78template <typename underlying_container_type,
80 requires(detail::reservible_container<std::remove_reference_t<underlying_container_type>> &&
81 detail::reservible_container<std::remove_reference_t<data_delimiters_type>> &&
82 std::is_same_v<std::ranges::range_size_t<underlying_container_type>,
83 std::ranges::range_value_t<data_delimiters_type>>)
85{
86protected:
91 data_delimiters_type data_delimiters{0};
92
93public:
95
100 using value_type = decltype(std::declval<std::decay_t<underlying_container_type> &>() | views::slice(0, 1));
101
105
108 using const_reference = decltype(std::as_const(data_values) | views::slice(0, 1));
109
112 using iterator = detail::random_access_iterator<concatenated_sequences>;
113
116 using const_iterator = detail::random_access_iterator<concatenated_sequences const>;
117
120 using difference_type = std::ranges::range_difference_t<data_delimiters_type>;
121
124 using size_type = std::ranges::range_size_t<data_delimiters_type>;
126
128 // this signals to range-v3 that something is a container :|
129 using allocator_type = void;
131
132protected:
138 // unfortunately we cannot specialise the variable template so we have to add an auxiliary here
139 template <std::ranges::range t>
140 static constexpr bool is_compatible_with_value_type_aux(std::type_identity<t>)
141 {
142 return range_dimension_v<t> == range_dimension_v<value_type> &&
143 std::convertible_to<std::ranges::range_reference_t<t>, std::ranges::range_value_t<value_type>>;
144 }
145
146 static constexpr bool is_compatible_with_value_type_aux(...) { return false; }
148
151 // we explicitly check same-ness, because these types may not be fully resolved, yet
152 template <std::ranges::range t>
153 static constexpr bool is_compatible_with_value_type = is_compatible_with_value_type_aux(std::type_identity<t>{});
154
157 // cannot use the concept, because this class is not yet fully defined
158 template <typename t>
159 requires is_compatible_with_value_type<std::iter_reference_t<t>>
160 static constexpr bool iter_value_t_is_compatible_with_value_type = true;
161
164 // cannot use the concept, because this class is not yet fully defined
165 template <std::ranges::range t>
166 requires is_compatible_with_value_type<std::ranges::range_reference_t<t>>
167 static constexpr bool range_value_t_is_compatible_with_value_type = true;
169
170public:
177 constexpr concatenated_sequences(concatenated_sequences const &) = default;
179 constexpr concatenated_sequences(concatenated_sequences &&) noexcept = default;
181 constexpr concatenated_sequences & operator=(concatenated_sequences const &) = default;
183 constexpr concatenated_sequences & operator=(concatenated_sequences &&) noexcept = default;
186
200 template <meta::different_from<concatenated_sequences> rng_of_rng_type>
201 requires(std::ranges::input_range<rng_of_rng_type> &&
202 range_value_t_is_compatible_with_value_type<rng_of_rng_type>)
203 concatenated_sequences(rng_of_rng_type && rng_of_rng)
204 {
205 if constexpr (std::ranges::sized_range<rng_of_rng_type>)
206 data_delimiters.reserve(std::ranges::size(rng_of_rng) + 1);
207
208 for (auto && val : rng_of_rng)
209 {
210 data_values.insert(data_values.end(), val.begin(), val.end());
211 data_delimiters.push_back(data_delimiters.back() + val.size());
212 }
213 }
214
228 template <std::ranges::forward_range rng_type>
229 concatenated_sequences(size_type const count, rng_type && value)
230 requires is_compatible_with_value_type<rng_type>
231 {
232 // TODO SEQAN_UNLIKELY
233 if (count == 0)
234 return;
235
236 insert(cend(), count, std::forward<rng_type>(value));
237 }
238
254 template <std::forward_iterator begin_iterator_type, typename end_iterator_type>
255 concatenated_sequences(begin_iterator_type begin_it, end_iterator_type end_it)
256 requires(std::sized_sentinel_for<end_iterator_type, begin_iterator_type> &&
257 iter_value_t_is_compatible_with_value_type<begin_iterator_type>)
258 {
259 insert(cend(), begin_it, end_it);
260 }
261
274 template <std::ranges::forward_range value_type_t = value_type>
275 requires is_compatible_with_value_type<value_type_t>
277 {
278 assign(std::begin(ilist), std::end(ilist));
279 }
280
293 template <std::ranges::forward_range value_type_t>
295 requires is_compatible_with_value_type<value_type_t>
296 {
297 assign(std::begin(ilist), std::end(ilist));
298 return *this;
299 }
300
314 template <std::ranges::input_range rng_of_rng_type>
315 void assign(rng_of_rng_type && rng_of_rng)
316 requires range_value_t_is_compatible_with_value_type<rng_of_rng_type>
317 {
318 concatenated_sequences rhs{std::forward<rng_of_rng_type>(rng_of_rng)};
319 swap(rhs);
320 }
321
335 template <std::ranges::forward_range rng_type>
336 void assign(size_type const count, rng_type && value)
337 requires(is_compatible_with_value_type<rng_type>)
338 {
339 concatenated_sequences rhs{count, value};
340 swap(rhs);
341 }
342
358 template <std::forward_iterator begin_iterator_type, typename end_iterator_type>
359 void assign(begin_iterator_type begin_it, end_iterator_type end_it)
360 requires(iter_value_t_is_compatible_with_value_type<begin_iterator_type> &&
361 std::sized_sentinel_for<end_iterator_type, begin_iterator_type>)
362 {
363 concatenated_sequences rhs{begin_it, end_it};
364 swap(rhs);
365 }
366
379 template <std::ranges::forward_range rng_type = value_type>
381 requires is_compatible_with_value_type<rng_type>
382 {
383 assign(std::begin(ilist), std::end(ilist));
384 }
385
387
404 iterator begin() noexcept { return iterator{*this}; }
405
407 const_iterator begin() const noexcept { return const_iterator{*this}; }
408
410 const_iterator cbegin() const noexcept { return const_iterator{*this}; }
411
425 iterator end() noexcept { return iterator{*this, size()}; }
426
428 const_iterator end() const noexcept { return const_iterator{*this, size()}; }
429
431 const_iterator cend() const noexcept { return const_iterator{*this, size()}; }
433
451 {
452 //TODO add SEQAN_UNLIKELY
453 if (i >= size())
454 throw std::out_of_range{"Trying to access element behind the last in concatenated_sequences."};
455 return (*this)[i];
456 }
457
460 {
461 //TODO add SEQAN_UNLIKELY
462 if (i >= size())
463 throw std::out_of_range{"Trying to access element behind the last in concatenated_sequences."};
464 return (*this)[i];
465 }
466
482 {
483 assert(i < size());
484 return data_values | views::slice(data_delimiters[i], data_delimiters[i + 1]);
485 }
486
489 {
490 assert(i < size());
491 return data_values | views::slice(data_delimiters[i], data_delimiters[i + 1]);
492 }
493
507 {
508 assert(size() > 0);
509 return (*this)[0];
510 }
511
514 {
515 assert(size() > 0);
516 return (*this)[0];
517 }
518
532 {
533 assert(size() > 0);
534 return (*this)[size() - 1];
535 }
536
539 {
540 assert(size() > 0);
541 return (*this)[size() - 1];
542 }
543
558 reference concat() { return data_values | views::slice(static_cast<size_type>(0), concat_size()); }
559
561 const_reference concat() const { return data_values | views::slice(static_cast<size_type>(0), concat_size()); }
562
570 std::pair<decltype(data_values) &, decltype(data_delimiters) &> raw_data()
571 {
572 return {data_values, data_delimiters};
573 }
574
576 std::pair<decltype(data_values) const &, decltype(data_delimiters) const &> raw_data() const
577 {
578 return {data_values, data_delimiters};
579 }
581
596 bool empty() const noexcept { return size() == 0; }
597
609 size_type size() const noexcept { return data_delimiters.size() - 1; }
610
625 size_type max_size() const noexcept { return data_delimiters.max_size() - 1; }
626
642 size_type capacity() const noexcept { return data_delimiters.capacity(); }
643
666 void reserve(size_type const new_cap) { data_delimiters.reserve(new_cap + 1); }
667
688 {
689 data_values.shrink_to_fit();
690 data_delimiters.shrink_to_fit();
691 }
693
708 size_type concat_size() const noexcept { return data_values.size(); }
709
721 size_type concat_capacity() const noexcept { return data_values.capacity(); }
722
741 void concat_reserve(size_type const new_cap) { data_values.reserve(new_cap); }
743
757 void clear() noexcept
758 {
759 data_values.clear();
760 data_delimiters.clear();
761 data_delimiters.push_back(0);
762 }
763
788 template <std::ranges::forward_range rng_type>
789 iterator insert(const_iterator pos, rng_type && value)
790 requires is_compatible_with_value_type<rng_type>
791 {
792 return insert(pos, 1, std::forward<rng_type>(value));
793 }
794 // no specialisation for temporaries, since we have to copy anyway
795
820 template <std::ranges::forward_range rng_type>
821 iterator insert(const_iterator pos, size_type const count, rng_type && value)
822 requires is_compatible_with_value_type<rng_type>
823 {
824 auto const pos_as_num = std::distance(cbegin(), pos); // we want to insert BEFORE this position
825 // TODO SEQAN_UNLIKELY
826 if (count == 0)
827 return begin() + pos_as_num;
828
829 /* TODO implement views::flat_repeat_n that is like
830 * views::repeat_n(value, count) | views::join | ranges::views::bounded;
831 * but preserves random access and size.
832 *
833 * then do
834 * auto concatenated = ranges::views::flat_repeat_n(value, count);
835 * insert(pos, concatenated.cbegin(), concatenated.cend())
836 */
837
838 size_type value_len = 0;
839 if constexpr (std::ranges::sized_range<rng_type>)
840 value_len = std::ranges::size(value);
841 else
842 value_len = std::distance(std::ranges::begin(value), std::ranges::end(value));
843
844 data_values.reserve(data_values.size() + count * value_len);
845 auto placeholder =
846 views::repeat_n(std::ranges::range_value_t<rng_type>{}, count * value_len) | std::views::common;
847 // insert placeholder so the tail is moved once:
848 data_values.insert(data_values.begin() + data_delimiters[pos_as_num],
849 std::ranges::begin(placeholder),
850 std::ranges::end(placeholder));
851
852 // assign the actual values to the placeholder:
853 size_t i = data_delimiters[pos_as_num];
854 for (size_t j = 0; j < count; ++j)
855 for (auto && v : value)
856 data_values[i++] = v;
857
858 data_delimiters.reserve(data_values.size() + count);
859 data_delimiters.insert(data_delimiters.begin() + pos_as_num, count, *(data_delimiters.begin() + pos_as_num));
860
861 // adapt delimiters of inserted
862 for (size_type i = 0; i < count; ++i)
863 data_delimiters[pos_as_num + i + 1] += value_len * (i + 1);
864
865 // adapt delimiters after that
866 // TODO parallel execution policy or vectorization?
867 std::for_each(data_delimiters.begin() + pos_as_num + count + 1,
868 data_delimiters.end(),
869 [full_len = value_len * count](auto & d) { d += full_len; });
870
871 return begin() + pos_as_num;
872 }
873
898 template <std::forward_iterator begin_iterator_type, typename end_iterator_type>
899 iterator insert(const_iterator pos, begin_iterator_type first, end_iterator_type last)
900 requires(iter_value_t_is_compatible_with_value_type<begin_iterator_type> &&
901 std::sized_sentinel_for<end_iterator_type, begin_iterator_type>)
902 {
903 auto const pos_as_num = std::distance(cbegin(), pos);
904 // TODO SEQAN_UNLIKELY
905 if (last - first == 0)
906 return begin() + pos_as_num;
907
908 auto const ilist =
909 std::ranges::subrange<begin_iterator_type, end_iterator_type>(first,
910 last,
911 std::ranges::distance(first, last));
912
913 data_delimiters.reserve(data_values.size() + ilist.size());
914 data_delimiters.insert(data_delimiters.begin() + pos_as_num,
915 ilist.size(),
916 *(data_delimiters.begin() + pos_as_num));
917
918 // adapt delimiters of inserted region
919 size_type full_len = 0;
920 for (size_type i = 0; i < ilist.size(); ++i, ++first)
921 {
922 full_len += std::ranges::distance(*first);
923 data_delimiters[pos_as_num + 1 + i] += full_len;
924 }
925
926 // insert placeholder so the tail is moved only once:
927 data_values.insert(data_values.begin() + data_delimiters[pos_as_num],
928 full_len,
929 std::ranges::range_value_t<value_type>{});
930
931 // assign the actual values to the placeholder:
932 size_t i = data_delimiters[pos_as_num];
933 for (auto && v0 : ilist)
934 for (auto && v1 : v0)
935 data_values[i++] = v1;
936
937 // adapt delimiters behind inserted region
938 // TODO parallel execution policy or vectorization?
939 std::for_each(data_delimiters.begin() + pos_as_num + ilist.size() + 1,
940 data_delimiters.end(),
941 [full_len](auto & d) { d += full_len; });
942
943 return begin() + pos_as_num;
944 }
945
965 template <std::ranges::forward_range rng_type>
967 requires is_compatible_with_value_type<rng_type>
968 {
969 return insert(pos, ilist.begin(), ilist.end());
970 }
971
991 {
992 auto const dist = std::distance(cbegin(), last);
993 // TODO SEQAN_UNLIKELY
994 if (last - first == 0)
995 return begin() + dist;
996
997 auto const distf = std::distance(cbegin(), first);
998
999 // we need to scan once over the input
1000 size_type sum_size{0};
1001 for (; first != last; ++first)
1002 sum_size += std::ranges::size(*first);
1003
1004 data_values.erase(data_values.begin() + data_delimiters[distf], data_values.begin() + data_delimiters[dist]);
1005
1006 data_delimiters.erase(data_delimiters.begin() + distf + 1, data_delimiters.begin() + dist + 1);
1007
1008 // adapt delimiters after that
1009 // TODO parallel execution policy or vectorization?
1010 std::for_each(data_delimiters.begin() + distf + 1,
1011 data_delimiters.end(),
1012 [sum_size](auto & d) { d -= sum_size; });
1013 return begin() + dist;
1014 }
1015
1034 iterator erase(const_iterator pos) { return erase(pos, pos + 1); }
1035
1055 template <std::ranges::forward_range rng_type>
1056 void push_back(rng_type && value)
1057 requires is_compatible_with_value_type<rng_type>
1058 {
1059 data_values.insert(data_values.end(), std::ranges::begin(value), std::ranges::end(value));
1060 data_delimiters.push_back(data_delimiters.back() + std::ranges::size(value));
1061 }
1062
1080 void push_back() { data_delimiters.push_back(data_delimiters.back()); }
1081
1101 void push_back_inner(std::ranges::range_value_t<underlying_container_type> const value)
1102 {
1103 data_values.push_back(value);
1104 ++data_delimiters.back();
1105 }
1106
1127 template <std::ranges::forward_range rng_type>
1128 void append_inner(rng_type && value)
1129 requires is_compatible_with_value_type<rng_type>
1130 {
1131 data_values.insert(data_values.end(), std::ranges::begin(value), std::ranges::end(value));
1132 data_delimiters.back() += std::ranges::size(value);
1133 }
1134
1152 {
1153 assert(size() > 0);
1154 auto back_length = data_delimiters[size()] - data_delimiters[size() - 1];
1155 data_values.resize(data_values.size() - back_length);
1156 data_delimiters.pop_back();
1157 }
1158
1185 void resize(size_type const count)
1186 {
1187 assert(count < max_size());
1188 data_delimiters.resize(count + 1, data_delimiters.back());
1189 data_values.resize(data_delimiters.back());
1190 }
1191
1197 template <std::ranges::forward_range rng_type>
1198 void resize(size_type const count, rng_type && value)
1199 requires is_compatible_with_value_type<rng_type>
1200 {
1201 assert(count < max_size());
1202 assert(concat_size() + count * std::ranges::size(value) < data_values.max_size());
1203
1204 if (count < size())
1205 resize(count);
1206 else if (count > size())
1207 insert(cend(), count - size(), std::forward<rng_type>(value));
1208 }
1209
1221 constexpr void swap(concatenated_sequences & rhs) noexcept
1222 {
1223 std::swap(data_values, rhs.data_values);
1224 std::swap(data_delimiters, rhs.data_delimiters);
1225 }
1226
1228 constexpr void swap(concatenated_sequences && rhs) noexcept
1229 {
1230 std::swap(data_values, rhs.data_values);
1231 std::swap(data_delimiters, rhs.data_delimiters);
1232 }
1234
1240 constexpr bool operator==(concatenated_sequences const & rhs) const noexcept
1241 {
1242 return raw_data() == rhs.raw_data();
1243 }
1244
1246 constexpr bool operator<(concatenated_sequences const & rhs) const noexcept { return raw_data() < rhs.raw_data(); }
1247
1249 constexpr bool operator>(concatenated_sequences const & rhs) const noexcept { return raw_data() > rhs.raw_data(); }
1250
1252 constexpr bool operator<=(concatenated_sequences const & rhs) const noexcept
1253 {
1254 return raw_data() <= rhs.raw_data();
1255 }
1256
1258 constexpr bool operator>=(concatenated_sequences const & rhs) const noexcept
1259 {
1260 return raw_data() >= rhs.raw_data();
1261 }
1263
1271 template <typename archive_t>
1272 void serialize(archive_t & archive)
1273 {
1274 archive(data_values, data_delimiters);
1275 }
1277};
1278
1279} // namespace bio::ranges
T as_const(T... args)
T begin(T... args)
Container that stores sequences concatenated internally.
Definition: concatenated_sequences.hpp:85
iterator insert(const_iterator pos, rng_type &&value)
Inserts value before position in the container.
Definition: concatenated_sequences.hpp:789
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:741
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:625
std::pair< decltype(data_values) &, decltype(data_delimiters) & > raw_data()
Provides direct, unsafe access to underlying data structures.
Definition: concatenated_sequences.hpp:570
size_type concat_size() const noexcept
Returns the cumulative size of all elements in the container.
Definition: concatenated_sequences.hpp:708
constexpr concatenated_sequences(concatenated_sequences &&) noexcept=default
Default constructors.
void push_back(rng_type &&value)
Appends the given element value to the end of the container.
Definition: concatenated_sequences.hpp:1056
constexpr bool operator<=(concatenated_sequences const &rhs) const noexcept
Checks whether *this is less than or equal to rhs.
Definition: concatenated_sequences.hpp:1252
iterator erase(const_iterator first, const_iterator last)
Removes specified elements from the container.
Definition: concatenated_sequences.hpp:990
void assign(begin_iterator_type begin_it, end_iterator_type end_it)
Construct/assign from pair of iterators.
Definition: concatenated_sequences.hpp:359
void push_back()
Appends an empty element to the end of the container.
Definition: concatenated_sequences.hpp:1080
bool empty() const noexcept
Checks whether the container is empty.
Definition: concatenated_sequences.hpp:596
const_iterator cbegin() const noexcept
Returns an iterator to the first element of the container.
Definition: concatenated_sequences.hpp:410
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:899
size_type concat_capacity() const noexcept
Returns the concatenated size the container has currently allocated space for.
Definition: concatenated_sequences.hpp:721
const_reference front() const
Return the first element as a view. Calling front on an empty container is undefined.
Definition: concatenated_sequences.hpp:513
reference concat()
Return the concatenation of all members.
Definition: concatenated_sequences.hpp:558
constexpr bool operator==(concatenated_sequences const &rhs) const noexcept
Checks whether *this is equal to rhs.
Definition: concatenated_sequences.hpp:1240
std::ranges::range_difference_t< data_delimiters_type > difference_type
A signed integer type (usually std::ptrdiff_t)
Definition: concatenated_sequences.hpp:120
void assign(std::initializer_list< rng_type > ilist)
Construct/assign from std::initializer_list.
Definition: concatenated_sequences.hpp:380
std::ranges::range_size_t< data_delimiters_type > size_type
An unsigned integer type (usually std::size_t)
Definition: concatenated_sequences.hpp:124
void append_inner(rng_type &&value)
Appends the given elements to the end of the underlying container (increases size of last element by ...
Definition: concatenated_sequences.hpp:1128
concatenated_sequences()=default
Default constructors.
constexpr concatenated_sequences(concatenated_sequences const &)=default
Default constructors.
size_type capacity() const noexcept
Returns the number of elements that the container has currently allocated space for.
Definition: concatenated_sequences.hpp:642
reference front()
Return the first element as a view. Calling front on an empty container is undefined.
Definition: concatenated_sequences.hpp:506
concatenated_sequences(std::initializer_list< value_type_t > ilist)
Construct/assign from std::initializer_list.
Definition: concatenated_sequences.hpp:276
void clear() noexcept
Removes all elements from the container.
Definition: concatenated_sequences.hpp:757
concatenated_sequences & operator=(std::initializer_list< value_type_t > ilist)
Construct/assign from std::initializer_list.
Definition: concatenated_sequences.hpp:294
const_iterator begin() const noexcept
Returns an iterator to the first element of the container.
Definition: concatenated_sequences.hpp:407
void resize(size_type const count)
Resizes the container to contain count elements.
Definition: concatenated_sequences.hpp:1185
void pop_back()
Removes the last element of the container.
Definition: concatenated_sequences.hpp:1151
reference operator[](size_type const i)
Return the i-th element as a view.
Definition: concatenated_sequences.hpp:481
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:666
void resize(size_type const count, rng_type &&value)
Resizes the container to contain count elements.
Definition: concatenated_sequences.hpp:1198
const_reference operator[](size_type const i) const
Return the i-th element as a view.
Definition: concatenated_sequences.hpp:488
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:100
size_type size() const noexcept
Returns the number of elements in the container, i.e. std::distance(begin(), end()).
Definition: concatenated_sequences.hpp:609
void push_back_inner(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:1101
constexpr void swap(concatenated_sequences &rhs) noexcept
Swap contents with another instance.
Definition: concatenated_sequences.hpp:1221
constexpr bool operator>=(concatenated_sequences const &rhs) const noexcept
Checks whether *this is greater than or equal to rhs.
Definition: concatenated_sequences.hpp:1258
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:821
iterator end() noexcept
Returns an iterator to the element following the last element of the container.
Definition: concatenated_sequences.hpp:425
detail::random_access_iterator< concatenated_sequences const > const_iterator
The const iterator type of this container (a random access iterator).
Definition: concatenated_sequences.hpp:116
decltype(std::as_const(data_values)|views::slice(0, 1)) const_reference
An immutable proxy of type views::slice that represents the range on the concatenated vector.
Definition: concatenated_sequences.hpp:108
const_reference back() const
Return the last element as a view.
Definition: concatenated_sequences.hpp:538
void assign(rng_of_rng_type &&rng_of_rng)
Construct/assign from a different range.
Definition: concatenated_sequences.hpp:315
const_iterator cend() const noexcept
Returns an iterator to the element following the last element of the container.
Definition: concatenated_sequences.hpp:431
constexpr void swap(concatenated_sequences &&rhs) noexcept
Swap contents with another instance.
Definition: concatenated_sequences.hpp:1228
void assign(size_type const count, rng_type &&value)
Construct/assign with count times value.
Definition: concatenated_sequences.hpp:336
const_reference concat() const
Return the concatenation of all members.
Definition: concatenated_sequences.hpp:561
reference at(size_type const i)
Return the i-th element as a view.
Definition: concatenated_sequences.hpp:450
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:576
constexpr bool operator>(concatenated_sequences const &rhs) const noexcept
Checks whether *this is greater than rhs.
Definition: concatenated_sequences.hpp:1249
concatenated_sequences(begin_iterator_type begin_it, end_iterator_type end_it)
Construct/assign from pair of iterators.
Definition: concatenated_sequences.hpp:255
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:966
iterator erase(const_iterator pos)
Removes specified elements from the container.
Definition: concatenated_sequences.hpp:1034
iterator begin() noexcept
Returns an iterator to the first element of the container.
Definition: concatenated_sequences.hpp:404
const_reference at(size_type const i) const
Return the i-th element as a view.
Definition: concatenated_sequences.hpp:459
const_iterator end() const noexcept
Returns an iterator to the element following the last element of the container.
Definition: concatenated_sequences.hpp:428
void shrink_to_fit()
Requests the removal of unused capacity.
Definition: concatenated_sequences.hpp:687
value_type reference
A proxy of type views::slice that represents the range on the concatenated vector.
Definition: concatenated_sequences.hpp:104
detail::random_access_iterator< concatenated_sequences > iterator
The iterator type of this container (a random access iterator).
Definition: concatenated_sequences.hpp:112
concatenated_sequences(size_type const count, rng_type &&value)
Construct/assign with count times value.
Definition: concatenated_sequences.hpp:229
reference back()
Return the last element as a view.
Definition: concatenated_sequences.hpp:531
constexpr bool operator<(concatenated_sequences const &rhs) const noexcept
Checks whether *this is less than rhs.
Definition: concatenated_sequences.hpp:1246
T distance(T... args)
T end(T... args)
T for_each(T... args)
constexpr auto repeat_n
A view factory that repeats a given value n times.
Definition: repeat_n.hpp:98
constexpr auto slice
A view adaptor that returns a half-open interval on the underlying range.
Definition: slice.hpp:141
The ranges module's namespace.
Provides the bio::ranges::detail::random_access_iterator class.
Adaptations of concepts from the standard library.
Provides bio::views::repeat_n.
Provides bio::views::slice.
T swap(T... args)