38 #ifndef LIBPMEMOBJ_SEGMENT_VECTOR_HPP
39 #define LIBPMEMOBJ_SEGMENT_VECTOR_HPP
58 namespace experimental
61 namespace segment_vector_internal
70 template <
typename Container,
bool is_const>
74 using iterator_category = std::random_access_iterator_tag;
75 using difference_type = std::ptrdiff_t;
76 using table_type = Container;
77 using size_type =
typename table_type::size_type;
78 using value_type =
typename table_type::value_type;
81 typename std::conditional<is_const,
const table_type *,
84 typename std::conditional<is_const,
85 typename table_type::const_reference,
86 typename table_type::reference>::type;
88 typename std::conditional<is_const,
89 typename table_type::const_pointer,
90 typename table_type::pointer>::type;
110 template <
typename U = void,
111 typename =
typename std::enable_if<is_const, U>::type>
156 template <
typename Container,
bool is_const>
158 : table(
nullptr), index()
166 template <
typename Container,
bool is_const>
168 size_type idx) noexcept
169 : table(tab), index(idx)
177 template <
typename Container,
bool is_const>
180 : table(other.table), index(other.index)
185 template <
typename Container,
bool is_const>
186 template <
typename U,
typename>
189 : table(other.table), index(other.index)
198 template <
typename Container,
bool is_const>
211 template <
typename Container,
bool is_const>
215 auto iterator = *
this;
225 template <
typename Container,
bool is_const>
237 template <
typename Container,
bool is_const>
241 index +=
static_cast<size_type
>(idx);
250 template <
typename Container,
bool is_const>
263 template <
typename Container,
bool is_const>
267 auto iterator = *
this;
277 template <
typename Container,
bool is_const>
289 template <
typename Container,
bool is_const>
293 index -=
static_cast<size_type
>(idx);
302 template <
typename Container,
bool is_const>
304 typename segment_iterator<Container, is_const>::difference_type
308 return static_cast<difference_type
>(index + rhs.index);
316 template <
typename Container,
bool is_const>
318 typename segment_iterator<Container, is_const>::difference_type
322 return static_cast<difference_type
>(index - rhs.index);
332 template <
typename Container,
bool is_const>
338 return (table == rhs.table) && (index == rhs.index);
349 template <
typename Container,
bool is_const>
355 return (table != rhs.table) || (index != rhs.index);
368 template <
typename Container,
bool is_const>
374 if (table != rhs.table)
375 throw std::invalid_argument(
"segment_iterator::operator<");
377 return index < rhs.index;
391 template <
typename Container,
bool is_const>
397 if (table != rhs.table)
398 throw std::invalid_argument(
"segment_iterator::operator<");
400 return index > rhs.index;
414 template <
typename Container,
bool is_const>
420 if (table != rhs.table)
421 throw std::invalid_argument(
"segment_iterator::operator<");
423 return index <= rhs.index;
437 template <
typename Container,
bool is_const>
443 if (table != rhs.table)
444 throw std::invalid_argument(
"segment_iterator::operator<");
446 return index >= rhs.index;
452 template <
typename Container,
bool is_const>
453 typename segment_iterator<Container, is_const>::reference
456 return table->operator[](index);
462 template <
typename Container,
bool is_const>
463 typename segment_iterator<Container, is_const>::pointer
469 template <
typename Container>
470 using resize_method =
471 decltype(std::declval<Container>().resize(std::declval<size_t>()));
473 template <
typename Container>
474 using container_has_resize = detail::supports<Container, resize_method>;
476 template <typename Container, bool = container_has_resize<Container>::value>
477 struct segment_vector_resize {
478 using segment_vector_type = Container;
481 resize(segment_vector_type &c,
size_t n)
487 template <
typename Container>
488 struct segment_vector_resize<Container, false> {
489 using segment_vector_type = Container;
492 resize(segment_vector_type &c,
size_t n)
497 template <
typename SegmentVectorType,
size_t SegmentSize>
498 class fixed_size_policy {
501 using segment_vector_type = SegmentVectorType;
502 using segment_type =
typename segment_vector_type::value_type;
503 using value_type =
typename segment_type::value_type;
504 using size_type = std::size_t;
506 using segment_vector_resize_type =
507 segment_vector_resize<segment_vector_type>;
509 static constexpr size_type Size = SegmentSize;
512 resize(segment_vector_type &c, size_type n)
514 segment_vector_resize_type::resize(c, n);
523 get_segment(size_type index)
533 segment_top(size_type segment_index)
535 return segment_index * Size;
543 segment_size(size_type segment_index)
553 index_in_segment(size_type index)
562 max_size(
const SegmentVectorType &seg_storage)
564 return seg_storage.max_size() * SegmentSize;
571 capacity(size_type segment_index)
573 return (segment_index + 1) * Size;
577 template <
typename SegmentVectorType>
578 class exponential_size_policy {
581 using segment_vector_type = SegmentVectorType;
582 using segment_type =
typename segment_vector_type::value_type;
583 using value_type =
typename segment_type::value_type;
584 using size_type = std::size_t;
586 using segment_vector_resize_type =
587 segment_vector_resize<segment_vector_type>;
590 resize(segment_vector_type &c, size_type n)
592 segment_vector_resize_type::resize(c, n);
601 get_segment(size_type index)
603 return static_cast<size_type
>(detail::Log2(index | 1));
611 segment_top(size_type segment_index)
613 return (size_type(1) << segment_index) & ~size_type(1);
621 segment_size(size_type segment_index)
623 return (segment_index == 0) ? 2 : segment_top(segment_index);
631 index_in_segment(size_type index)
633 return index - segment_top(get_segment(index));
640 max_size(
const SegmentVectorType &)
642 return segment_size(get_segment(PMEMOBJ_MAX_ALLOC_SIZE /
643 sizeof(value_type)) +
651 capacity(size_type segment_index)
653 if (segment_index == 0)
655 return segment_size(segment_index) * 2;
661 template <
typename SegmentType>
662 using exponential_size_array_policy =
663 segment_vector_internal::exponential_size_policy<
670 template <
typename SegmentType,
size_t SegmentSize>
674 template <
typename SegmentType,
size_t SegmentSize>
675 using fixed_size_vector_policy = segment_vector_internal::fixed_size_policy<
678 template <
typename SegmentType>
679 using exponential_size_vector_policy =
680 segment_vector_internal::exponential_size_policy<
709 template <
typename T,
typename Segment = pmem::obj::vector<T>,
710 typename Policy = exponential_size_array_policy<Segment>>
714 using policy_type = Policy;
715 using segment_type =
typename policy_type::segment_type;
716 using segment_vector_type =
typename policy_type::segment_vector_type;
718 using policy = policy_type;
719 using storage = policy_type;
722 using value_type = T;
723 using size_type = std::size_t;
724 using difference_type = std::ptrdiff_t;
725 using reference = value_type &;
726 using const_reference =
const value_type &;
727 using pointer = value_type *;
728 using const_pointer =
const value_type *;
734 using reverse_iterator = std::reverse_iterator<iterator>;
735 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
741 template <
typename InputIt,
742 typename std::enable_if<
744 InputIt>::type * =
nullptr>
758 void assign(size_type count, const_reference value);
759 template <
typename InputIt,
760 typename std::enable_if<
762 InputIt>::type * =
nullptr>
763 void assign(InputIt first, InputIt last);
764 void assign(std::initializer_list<T> ilist);
767 void assign(
const std::vector<T> &other);
773 reference
at(size_type n);
774 const_reference
at(size_type n)
const;
775 const_reference
const_at(size_type n)
const;
777 const_reference
operator[](size_type n)
const;
779 const_reference
front()
const;
780 const_reference
cfront()
const;
782 const_reference
back()
const;
783 const_reference
cback()
const;
792 reverse_iterator
rbegin();
793 const_reverse_iterator
rbegin()
const noexcept;
794 const_reverse_iterator
crbegin()
const noexcept;
795 reverse_iterator
rend();
796 const_reverse_iterator
rend()
const noexcept;
797 const_reverse_iterator
crend()
const noexcept;
805 constexpr
bool empty()
const noexcept;
806 size_type
size()
const noexcept;
807 constexpr size_type
max_size()
const noexcept;
808 void reserve(size_type capacity_new);
809 size_type
capacity()
const noexcept;
818 template <
typename InputIt,
819 typename std::enable_if<
821 InputIt>::type * =
nullptr>
824 template <
class... Args>
826 template <
class... Args>
833 void resize(size_type count);
834 void resize(size_type count,
const value_type &value);
840 template <
typename... Args>
841 void construct(size_type idx, size_type count, Args &&... args);
842 template <
typename InputIt,
843 typename std::enable_if<
845 InputIt>::type * =
nullptr>
847 void insert_gap(size_type idx, size_type count);
848 void shrink(size_type size_new);
853 reference
get(size_type n);
854 const_reference
get(size_type n)
const;
855 const_reference
cget(size_type n)
const;
861 segment_vector_type _data;
865 template <
typename T,
typename Segment,
typename Policy>
874 template <
typename T,
typename Segment,
typename Policy>
877 template <
typename T,
typename Segment,
typename Policy>
880 template <
typename T,
typename Segment,
typename Policy>
883 template <
typename T,
typename Segment,
typename Policy>
886 template <
typename T,
typename Segment,
typename Policy>
889 template <
typename T,
typename Segment,
typename Policy>
898 template <
typename T,
typename Segment,
typename Policy>
900 const std::vector<T> &rhs);
901 template <
typename T,
typename Segment,
typename Policy>
903 const std::vector<T> &rhs);
904 template <
typename T,
typename Segment,
typename Policy>
906 const std::vector<T> &rhs);
907 template <
typename T,
typename Segment,
typename Policy>
909 const std::vector<T> &rhs);
910 template <
typename T,
typename Segment,
typename Policy>
912 const std::vector<T> &rhs);
913 template <
typename T,
typename Segment,
typename Policy>
915 const std::vector<T> &rhs);
921 template <
typename T,
typename Segment,
typename Policy>
924 template <
typename T,
typename Segment,
typename Policy>
927 template <
typename T,
typename Segment,
typename Policy>
928 bool operator<(
const std::vector<T> &lhs,
930 template <
typename T,
typename Segment,
typename Policy>
933 template <
typename T,
typename Segment,
typename Policy>
934 bool operator>(
const std::vector<T> &lhs,
936 template <
typename T,
typename Segment,
typename Policy>
948 template <
typename T,
typename Segment,
typename Policy>
975 template <
typename T,
typename Segment,
typename Policy>
977 const value_type &value)
979 internal_reserve(count);
980 construct(0, count, value);
1004 template <
typename T,
typename Segment,
typename Policy>
1007 internal_reserve(count);
1008 construct(0, count);
1037 template <
typename T,
typename Segment,
typename Policy>
1038 template <
typename InputIt,
1039 typename std::enable_if<detail::is_input_iterator<InputIt>::value,
1043 internal_reserve(
static_cast<size_type
>(std::distance(first, last)));
1044 construct_range(0, first, last);
1068 template <
typename T,
typename Segment,
typename Policy>
1071 internal_reserve(other.
capacity());
1072 construct_range(0, other.
cbegin(), other.
cend());
1095 template <
typename T,
typename Segment,
typename Policy>
1098 _data = std::move(other._data);
1099 _segments_used = other._segments_used;
1100 other._segments_used = 0;
1124 template <
typename T,
typename Segment,
typename Policy>
1126 std::initializer_list<T> init)
1152 template <
typename T,
typename Segment,
typename Policy>
1175 template <
typename T,
typename Segment,
typename Policy>
1198 template <
typename T,
typename Segment,
typename Policy>
1202 assign(std::move(other));
1223 template <
typename T,
typename Segment,
typename Policy>
1227 assign(ilist.begin(), ilist.end());
1248 template <
typename T,
typename Segment,
typename Policy>
1278 template <
typename T,
typename Segment,
typename Policy>
1281 const_reference value)
1283 if (count > max_size())
1284 throw std::length_error(
"Assignable range exceeds max size.");
1288 if (count > capacity())
1289 internal_reserve(count);
1290 else if (count < size())
1293 size_type
end = policy::get_segment(count - 1);
1294 for (size_type i = 0; i <
end; ++i)
1295 _data[i].assign(policy::segment_size(i), value);
1296 _data[
end].assign(count - policy::segment_top(
end), value);
1298 _segments_used =
end + 1;
1300 assert(segment_capacity_validation());
1325 template <
typename T,
typename Segment,
typename Policy>
1326 template <
typename InputIt,
1327 typename std::enable_if<detail::is_input_iterator<InputIt>::value,
1332 size_type count =
static_cast<size_type
>(std::distance(first, last));
1333 if (count > max_size())
1334 throw std::length_error(
"Assignable range exceeds max size.");
1338 if (count > capacity())
1339 internal_reserve(count);
1340 else if (count < size())
1343 difference_type num;
1344 size_type
end = policy::get_segment(count - 1);
1345 for (size_type i = 0; i <
end; ++i) {
1346 size_type size = policy::segment_size(i);
1347 num =
static_cast<difference_type
>(size);
1348 _data[i].assign(first, std::next(first, num));
1349 std::advance(first, num);
1351 num =
static_cast<difference_type
>(std::distance(first, last));
1352 _data[
end].assign(first, std::next(first, num));
1354 _segments_used =
end + 1;
1356 assert(segment_capacity_validation());
1379 template <
typename T,
typename Segment,
typename Policy>
1383 assign(ilist.begin(), ilist.end());
1402 template <
typename T,
typename Segment,
typename Policy>
1425 template <
typename T,
typename Segment,
typename Policy>
1434 _data = std::move(other._data);
1435 _segments_used = other._segments_used;
1436 other._segments_used = 0;
1456 template <
typename T,
typename Segment,
typename Policy>
1460 assign(other.cbegin(), other.cend());
1474 template <
typename T,
typename Segment,
typename Policy>
1493 template <
typename T,
typename Segment,
typename Policy>
1494 typename segment_vector<T, Segment, Policy>::reference
1498 throw std::out_of_range(
"segment_vector::at");
1500 detail::conditional_add_to_tx(&
get(n), 1, POBJ_XADD_ASSUME_INITIALIZED);
1515 template <
typename T,
typename Segment,
typename Policy>
1516 typename segment_vector<T, Segment, Policy>::const_reference
1520 throw std::out_of_range(
"segment_vector::at");
1536 template <
typename T,
typename Segment,
typename Policy>
1537 typename segment_vector<T, Segment, Policy>::const_reference
1541 throw std::out_of_range(
"segment_vector::const_at");
1556 template <
typename T,
typename Segment,
typename Policy>
1557 typename segment_vector<T, Segment, Policy>::reference
1560 reference element =
get(n);
1562 detail::conditional_add_to_tx(&element, 1,
1563 POBJ_XADD_ASSUME_INITIALIZED);
1575 template <
typename T,
typename Segment,
typename Policy>
1576 typename segment_vector<T, Segment, Policy>::const_reference
1590 template <
typename T,
typename Segment,
typename Policy>
1591 typename segment_vector<T, Segment, Policy>::reference
1594 detail::conditional_add_to_tx(&_data[0][0], 1,
1595 POBJ_XADD_ASSUME_INITIALIZED);
1605 template <
typename T,
typename Segment,
typename Policy>
1606 typename segment_vector<T, Segment, Policy>::const_reference
1619 template <
typename T,
typename Segment,
typename Policy>
1620 typename segment_vector<T, Segment, Policy>::const_reference
1634 template <
typename T,
typename Segment,
typename Policy>
1635 typename segment_vector<T, Segment, Policy>::reference
1638 reference element =
get(size() - 1);
1640 detail::conditional_add_to_tx(&element, 1,
1641 POBJ_XADD_ASSUME_INITIALIZED);
1651 template <
typename T,
typename Segment,
typename Policy>
1652 typename segment_vector<T, Segment, Policy>::const_reference
1655 return get(size() - 1);
1665 template <
typename T,
typename Segment,
typename Policy>
1666 typename segment_vector<T, Segment, Policy>::const_reference
1669 return get(size() - 1);
1677 template <
typename T,
typename Segment,
typename Policy>
1690 template <
typename T,
typename Segment,
typename Policy>
1705 template <
typename T,
typename Segment,
typename Policy>
1718 template <
typename T,
typename Segment,
typename Policy>
1731 template <
typename T,
typename Segment,
typename Policy>
1746 template <
typename T,
typename Segment,
typename Policy>
1759 template <
typename T,
typename Segment,
typename Policy>
1760 typename segment_vector<T, Segment, Policy>::reverse_iterator
1763 return reverse_iterator(
end());
1772 template <
typename T,
typename Segment,
typename Policy>
1773 typename segment_vector<T, Segment, Policy>::const_reverse_iterator
1776 return const_reverse_iterator(
end());
1787 template <
typename T,
typename Segment,
typename Policy>
1788 typename segment_vector<T, Segment, Policy>::const_reverse_iterator
1800 template <
typename T,
typename Segment,
typename Policy>
1801 typename segment_vector<T, Segment, Policy>::reverse_iterator
1804 return reverse_iterator(
begin());
1813 template <
typename T,
typename Segment,
typename Policy>
1814 typename segment_vector<T, Segment, Policy>::const_reverse_iterator
1817 return const_reverse_iterator(
begin());
1828 template <
typename T,
typename Segment,
typename Policy>
1829 typename segment_vector<T, Segment, Policy>::const_reverse_iterator
1848 template <
typename T,
typename Segment,
typename Policy>
1852 if (start + n > size())
1853 throw std::out_of_range(
"segment_vector::range");
1855 snapshot_data(start, start + n);
1871 template <
typename T,
typename Segment,
typename Policy>
1875 if (start + n > size())
1876 throw std::out_of_range(
"segment_vector::range");
1892 template <
typename T,
typename Segment,
typename Policy>
1896 if (start + n > size())
1897 throw std::out_of_range(
"segment_vector::range");
1907 template <
typename T,
typename Segment,
typename Policy>
1917 template <
typename T,
typename Segment,
typename Policy>
1918 typename segment_vector<T, Segment, Policy>::size_type
1921 size_type result = 0;
1922 for (size_type i = 0; i < _segments_used; ++i)
1923 result += _data.const_at(i).size();
1931 template <
typename T,
typename Segment,
typename Policy>
1932 constexpr
typename segment_vector<T, Segment, Policy>::size_type
1935 return policy::max_size(_data);
1954 template <
typename T,
typename Segment,
typename Policy>
1958 if (capacity_new <= capacity())
1969 template <
typename T,
typename Segment,
typename Policy>
1970 typename segment_vector<T, Segment, Policy>::size_type
1973 if (_segments_used == 0)
1975 return policy::capacity(_segments_used - 1);
1989 template <
typename T,
typename Segment,
typename Policy>
1993 size_type new_last = policy::get_segment(size() - 1);
1994 if (_segments_used - 1 == new_last)
1999 for (size_type i = new_last + 1; i < _segments_used; ++i)
2000 _data[i].free_data();
2001 _segments_used = new_last + 1;
2002 storage::resize(_data, _segments_used);
2017 template <
typename T,
typename Segment,
typename Policy>
2023 assert(segment_capacity_validation());
2038 template <
typename T,
typename Segment,
typename Policy>
2044 for (size_type i = 0; i < _segments_used; ++i)
2045 _data[i].free_data();
2073 template <
typename T,
typename Segment,
typename Policy>
2077 return insert(pos, 1, value);
2103 template <
typename T,
typename Segment,
typename Policy>
2107 size_type idx =
static_cast<size_type
>(pos -
cbegin());
2112 get(idx) = std::move(value);
2144 template <
typename T,
typename Segment,
typename Policy>
2149 size_type idx =
static_cast<size_type
>(pos -
cbegin());
2153 insert_gap(idx, count);
2154 for (size_type i = idx; i < idx + count; ++i)
2155 get(i) = std::move(value);
2194 template <
typename T,
typename Segment,
typename Policy>
2195 template <
typename InputIt,
2196 typename std::enable_if<detail::is_input_iterator<InputIt>::value,
2202 size_type idx =
static_cast<size_type
>(pos -
cbegin());
2203 size_type gap_size =
static_cast<size_type
>(std::distance(first, last));
2207 insert_gap(idx, gap_size);
2208 for (size_type i = idx; i < idx + gap_size; ++i, ++first)
2241 template <
typename T,
typename Segment,
typename Policy>
2244 std::initializer_list<T> ilist)
2246 return insert(pos, ilist.begin(), ilist.end());
2277 template <
typename T,
typename Segment,
typename Policy>
2278 template <
class... Args>
2282 size_type idx =
static_cast<size_type
>(pos -
cbegin());
2287 noexcept(T(std::forward<Args>(args)...))>
2288 tmp(std::forward<Args>(args)...);
2290 get(idx) = std::move(tmp.get());
2320 template <
typename T,
typename Segment,
typename Policy>
2321 template <
class... Args>
2322 typename segment_vector<T, Segment, Policy>::reference
2325 assert(size() < max_size());
2329 if (size() == capacity())
2330 internal_reserve(capacity() + 1);
2332 size_type segment = policy::get_segment(size());
2333 _data[segment].emplace_back(std::forward<Args>(args)...);
2360 template <
typename T,
typename Segment,
typename Policy>
2364 return erase(pos, pos + 1);
2391 template <
typename T,
typename Segment,
typename Policy>
2396 size_type count =
static_cast<size_type
>(std::distance(first, last));
2397 size_type idx =
static_cast<size_type
>(first -
cbegin());
2404 size_type _size = size();
2406 snapshot_data(idx, _size);
2417 size_type middle = policy::get_segment(_size - count);
2418 size_type last = policy::get_segment(_size - 1);
2419 size_type middle_size = policy::index_in_segment(_size - count);
2420 for (size_type s = last; s > middle; --s)
2422 _data[middle].resize(middle_size);
2424 _segments_used = middle + 1;
2427 assert(segment_capacity_validation());
2450 template <
typename T,
typename Segment,
typename Policy>
2454 emplace_back(value);
2475 template <
typename T,
typename Segment,
typename Policy>
2479 emplace_back(std::move(value));
2495 template <
typename T,
typename Segment,
typename Policy>
2504 assert(segment_capacity_validation());
2530 template <
typename T,
typename Segment,
typename Policy>
2536 size_type _size = size();
2540 if (capacity() < count)
2541 internal_reserve(count);
2542 construct(_size, count - _size);
2545 assert(segment_capacity_validation());
2572 template <
typename T,
typename Segment,
typename Policy>
2575 const value_type &value)
2579 size_type _size = size();
2583 if (capacity() < count)
2584 internal_reserve(count);
2585 construct(_size, count - _size, value);
2588 assert(segment_capacity_validation());
2594 template <
typename T,
typename Segment,
typename Policy>
2600 _data.swap(other._data);
2601 std::swap(_segments_used, other._segments_used);
2621 template <
typename T,
typename Segment,
typename Policy>
2625 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
2627 if (new_capacity > max_size())
2628 throw std::length_error(
"New capacity exceeds max size.");
2630 if (new_capacity == 0)
2633 size_type old_idx = policy::get_segment(capacity());
2634 size_type new_idx = policy::get_segment(new_capacity - 1);
2635 storage::resize(_data, new_idx + 1);
2636 for (size_type i = old_idx; i <= new_idx; ++i) {
2637 size_type segment_capacity = policy::segment_size(i);
2638 _data[i].reserve(segment_capacity);
2640 _segments_used = new_idx + 1;
2642 assert(segment_capacity_validation());
2671 template <
typename T,
typename Segment,
typename Policy>
2672 template <
typename... Args>
2677 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
2678 assert(_segments_used - 1 >= policy::get_segment(size() + count - 1));
2680 for (size_type i = idx; i < idx + count; ++i) {
2681 size_type segment = policy::get_segment(i);
2682 _data[segment].emplace_back(std::forward<Args>(args)...);
2716 template <
typename T,
typename Segment,
typename Policy>
2717 template <
typename InputIt,
2718 typename std::enable_if<detail::is_input_iterator<InputIt>::value,
2722 InputIt first, InputIt last)
2724 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
2725 size_type count =
static_cast<size_type
>(std::distance(first, last));
2727 assert(_segments_used - 1 >= policy::get_segment(size() + count - 1));
2729 for (size_type i = idx; i < idx + count; ++i, ++first) {
2730 size_type segment = policy::get_segment(i);
2731 _data[segment].emplace_back(*first);
2756 template <
typename T,
typename Segment,
typename Policy>
2760 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
2762 size_type _size = size();
2764 if (capacity() < _size + count)
2765 internal_reserve(_size + count);
2771 snapshot_data(idx, _size);
2773 resize(_size + count);
2774 std::move_backward(
begin,
end, dest);
2776 assert(segment_capacity_validation());
2798 template <
typename T,
typename Segment,
typename Policy>
2802 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
2803 assert(size_new <= size());
2805 snapshot_data(size_new, size());
2807 size_type
begin = policy::get_segment(size() - 1);
2808 size_type
end = policy::get_segment(size_new);
2810 _data[
begin].clear();
2812 size_type residue = policy::index_in_segment(size_new);
2823 template <
typename T,
typename Segment,
typename Policy>
2827 auto pop = pmemobj_pool_by_ptr(
this);
2828 assert(pop !=
nullptr);
2841 template <
typename T,
typename Segment,
typename Policy>
2849 size_type segment = policy::get_segment(first);
2850 size_type
end = policy::get_segment(last - 1);
2851 size_type count = policy::segment_top(segment + 1) - first;
2853 while (segment !=
end) {
2854 detail::conditional_add_to_tx(&cget(first), count,
2855 POBJ_XADD_ASSUME_INITIALIZED);
2856 first = policy::segment_top(++segment);
2857 count = policy::segment_size(segment);
2859 detail::conditional_add_to_tx(&cget(first), last - first,
2860 POBJ_XADD_ASSUME_INITIALIZED);
2868 template <
typename T,
typename Segment,
typename Policy>
2869 typename segment_vector<T, Segment, Policy>::reference
2872 size_type s_idx = policy::get_segment(n);
2873 size_type local_idx = policy::index_in_segment(n);
2875 return _data[s_idx][local_idx];
2883 template <
typename T,
typename Segment,
typename Policy>
2884 typename segment_vector<T, Segment, Policy>::const_reference
2887 size_type s_idx = policy::get_segment(n);
2888 size_type local_idx = policy::index_in_segment(n);
2890 return _data[s_idx][local_idx];
2898 template <
typename T,
typename Segment,
typename Policy>
2899 typename segment_vector<T, Segment, Policy>::const_reference
2902 size_type s_idx = policy::get_segment(n);
2903 size_type local_idx = policy::index_in_segment(n);
2905 return _data[s_idx][local_idx];
2915 template <
typename T,
typename Segment,
typename Policy>
2919 for (size_type i = 0; i < _segments_used; ++i)
2920 if (_data.const_at(i).capacity() != policy::segment_size(i))
2931 template <
typename T,
typename Segment,
typename Policy>
2953 template <
typename T,
typename Segment,
typename Policy>
2977 template <
typename T,
typename Segment,
typename Policy>
2982 return !(lhs == rhs);
2997 template <
typename T,
typename Segment,
typename Policy>
3002 return std::lexicographical_compare(lhs.
begin(), lhs.
end(), rhs.
begin(),
3018 template <
typename T,
typename Segment,
typename Policy>
3023 return !(rhs < lhs);
3038 template <
typename T,
typename Segment,
typename Policy>
3058 template <
typename T,
typename Segment,
typename Policy>
3063 return !(lhs < rhs);
3079 template <
typename T,
typename Segment,
typename Policy>
3082 const std::vector<T> &rhs)
3084 return lhs.
size() == rhs.size() &&
3085 std::equal(lhs.
begin(), lhs.
end(), rhs.begin());
3101 template <
typename T,
typename Segment,
typename Policy>
3104 const std::vector<T> &rhs)
3106 return !(lhs == rhs);
3120 template <
typename T,
typename Segment,
typename Policy>
3123 const std::vector<T> &rhs)
3125 return std::lexicographical_compare(lhs.
begin(), lhs.
end(), rhs.begin(),
3140 template <
typename T,
typename Segment,
typename Policy>
3143 const std::vector<T> &rhs)
3145 return !(std::lexicographical_compare(rhs.begin(), rhs.end(),
3161 template <
typename T,
typename Segment,
typename Policy>
3164 const std::vector<T> &rhs)
3166 return !(lhs <= rhs);
3180 template <
typename T,
typename Segment,
typename Policy>
3183 const std::vector<T> &rhs)
3185 return !(lhs < rhs);
3201 template <
typename T,
typename Segment,
typename Policy>
3222 template <
typename T,
typename Segment,
typename Policy>
3227 return !(lhs == rhs);
3241 template <
typename T,
typename Segment,
typename Policy>
3260 template <
typename T,
typename Segment,
typename Policy>
3265 return !(rhs < lhs);
3280 template <
typename T,
typename Segment,
typename Policy>
3299 template <
typename T,
typename Segment,
typename Policy>
3304 return !(lhs < rhs);