PMDK C++ bindings 1.13.0
This is the C++ bindings documentation for PMDK's libpmemobj.
Loading...
Searching...
No Matches
segment_vector.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: BSD-3-Clause
2/* Copyright 2019-2020, Intel Corporation */
3
9#ifndef LIBPMEMOBJ_SEGMENT_VECTOR_HPP
10#define LIBPMEMOBJ_SEGMENT_VECTOR_HPP
11
17#include <libpmemobj++/detail/temp_value.hpp>
21#include <libpmemobj++/pext.hpp>
24
25#include <vector>
26
27namespace pmem
28{
29namespace obj
30{
31
35namespace segment_vector_internal
36{
45template <typename Container, bool is_const>
47public:
48 /* Traits */
49 using iterator_category = std::random_access_iterator_tag;
50 using difference_type = std::ptrdiff_t;
51 using table_type = Container;
52 using size_type = typename table_type::size_type;
53 using value_type = typename table_type::value_type;
54 /* Constant dependent traits */
55 using table_ptr =
56 typename std::conditional<is_const, const table_type *,
57 table_type *>::type;
58 using reference =
59 typename std::conditional<is_const,
60 typename table_type::const_reference,
61 typename table_type::reference>::type;
62 using pointer =
63 typename std::conditional<is_const,
64 typename table_type::const_pointer,
65 typename table_type::pointer>::type;
66
67 /* To implement methods where operands differ in constancy */
68 friend class segment_iterator<Container, true>;
69 friend class segment_iterator<Container, false>;
70
71private:
72 /* Pointer to container for iteration */
73 table_ptr table;
74 /* Index of element in the container */
75 size_type index;
76
77public:
78 /* Сonstructors */
79 segment_iterator() noexcept;
80 explicit segment_iterator(table_ptr tab, size_type idx) noexcept;
82
83 /* Copy ctor to enable conversion from non-const to const
84 * iterator */
85 template <typename U = void,
86 typename = typename std::enable_if<is_const, U>::type>
88
89 /* In(de)crement methods */
92 segment_iterator operator+(difference_type idx) const;
93 segment_iterator &operator+=(difference_type idx);
96 segment_iterator operator-(difference_type idx) const;
97 segment_iterator &operator-=(difference_type idx);
98 template <bool C>
99 difference_type
101 template <bool C>
102 difference_type
104
110 template <bool C>
111 bool operator==(const segment_iterator<Container, C> &rhs) const;
112 template <bool C>
113 bool operator!=(const segment_iterator<Container, C> &rhs) const;
114 template <bool C>
115 bool operator<(const segment_iterator<Container, C> &rhs) const;
116 template <bool C>
117 bool operator>(const segment_iterator<Container, C> &rhs) const;
118 template <bool C>
119 bool operator<=(const segment_iterator<Container, C> &rhs) const;
120 template <bool C>
121 bool operator>=(const segment_iterator<Container, C> &rhs) const;
122
123 /* Access methods */
124 reference operator*() const;
125 pointer operator->() const;
126};
127
131template <typename Container, bool is_const>
133 : table(nullptr), index()
134{
135}
136
141template <typename Container, bool is_const>
143 size_type idx) noexcept
144 : table(tab), index(idx)
145{
146}
147
152template <typename Container, bool is_const>
154 const segment_iterator &other)
155 : table(other.table), index(other.index)
156{
157}
158
160template <typename Container, bool is_const>
161template <typename U, typename>
164 : table(other.table), index(other.index)
165{
166}
167
173template <typename Container, bool is_const>
176{
177 ++index;
178 return *this;
179}
180
186template <typename Container, bool is_const>
189{
190 auto iterator = *this;
191 ++*this;
192 return iterator;
193}
194
200template <typename Container, bool is_const>
203{
204 return segment_iterator(table, index + static_cast<size_type>(idx));
205}
206
212template <typename Container, bool is_const>
215{
216 index += static_cast<size_type>(idx);
217 return *this;
218}
219
225template <typename Container, bool is_const>
228{
229 --index;
230 return *this;
231}
232
238template <typename Container, bool is_const>
241{
242 auto iterator = *this;
243 --*this;
244 return iterator;
245}
246
252template <typename Container, bool is_const>
255{
256 return segment_iterator(table, index - static_cast<size_type>(idx));
257}
258
264template <typename Container, bool is_const>
267{
268 index -= static_cast<size_type>(idx);
269 return *this;
270}
271
277template <typename Container, bool is_const>
278template <bool C>
279typename segment_iterator<Container, is_const>::difference_type
281 const segment_iterator<Container, C> &rhs) const
282{
283 return static_cast<difference_type>(index + rhs.index);
284}
285
291template <typename Container, bool is_const>
292template <bool C>
293typename segment_iterator<Container, is_const>::difference_type
295 const segment_iterator<Container, C> &rhs) const
296{
297 return static_cast<difference_type>(index - rhs.index);
298}
299
307template <typename Container, bool is_const>
308template <bool C>
309bool
311 const segment_iterator<Container, C> &rhs) const
312{
313 return (table == rhs.table) && (index == rhs.index);
314}
315
324template <typename Container, bool is_const>
325template <bool C>
326bool
328 const segment_iterator<Container, C> &rhs) const
329{
330 return (table != rhs.table) || (index != rhs.index);
331}
332
343template <typename Container, bool is_const>
344template <bool C>
345bool
347 const segment_iterator<Container, C> &rhs) const
348{
349 if (table != rhs.table)
350 throw std::invalid_argument("segment_iterator::operator<");
351
352 return index < rhs.index;
353}
354
366template <typename Container, bool is_const>
367template <bool C>
368bool
370 const segment_iterator<Container, C> &rhs) const
371{
372 if (table != rhs.table)
373 throw std::invalid_argument("segment_iterator::operator>");
374
375 return index > rhs.index;
376}
377
389template <typename Container, bool is_const>
390template <bool C>
391bool
393 const segment_iterator<Container, C> &rhs) const
394{
395 if (table != rhs.table)
396 throw std::invalid_argument("segment_iterator::operator<=");
397
398 return index <= rhs.index;
399}
400
412template <typename Container, bool is_const>
413template <bool C>
414bool
416 const segment_iterator<Container, C> &rhs) const
417{
418 if (table != rhs.table)
419 throw std::invalid_argument("segment_iterator::operator>=");
420
421 return index >= rhs.index;
422}
423
427template <typename Container, bool is_const>
428typename segment_iterator<Container, is_const>::reference
430{
431 return table->operator[](index);
432}
433
437template <typename Container, bool is_const>
438typename segment_iterator<Container, is_const>::pointer
440{
441 return &operator*();
442}
443
444} /* segment_vector_internal namespace */
445
454template <template <typename> class SegmentType = pmem::obj::vector>
456 segment_vector_internal::exponential_size_policy<
458
467template <size_t SegmentSize = 1024,
468 template <typename> class SegmentType = pmem::obj::vector>
470 segment_vector_internal::fixed_size_policy<pmem::obj::vector,
471 SegmentType, SegmentSize>;
472
481template <template <typename> class SegmentType = pmem::obj::vector>
483 segment_vector_internal::exponential_size_policy<pmem::obj::vector,
484 SegmentType>;
485
503template <typename T, typename Policy = exponential_size_vector_policy<>>
505public:
506 /* Specific traits*/
507 using policy_type = Policy;
508 using segment_type = typename policy_type::template segment_type<T>;
509 using segment_vector_type =
510 typename policy_type::template segment_vector_type<T>;
511 /* Simple access to methods */
512 using policy = policy_type;
513 using storage = policy_type;
514
515 /* Traits */
516 using value_type = T;
517 using size_type = std::size_t;
518 using difference_type = std::ptrdiff_t;
519 using reference = value_type &;
520 using const_reference = const value_type &;
521 using pointer = value_type *;
522 using const_pointer = const value_type *;
523 using iterator =
525 false>;
526 using const_iterator =
528 using reverse_iterator = std::reverse_iterator<iterator>;
529 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
530
531 /* Constructors */
533 segment_vector(size_type count, const value_type &value);
534 explicit segment_vector(size_type count);
535 template <typename InputIt,
536 typename std::enable_if<
538 InputIt>::type * = nullptr>
539 segment_vector(InputIt first, InputIt last);
542 segment_vector(std::initializer_list<T> init);
543 segment_vector(const std::vector<T> &other);
544
545 /* Assign operators */
548 segment_vector &operator=(std::initializer_list<T> ilist);
549 segment_vector &operator=(const std::vector<T> &other);
550
551 /* Assign methods */
552 void assign(size_type count, const_reference value);
553 template <typename InputIt,
554 typename std::enable_if<
556 InputIt>::type * = nullptr>
557 void assign(InputIt first, InputIt last);
558 void assign(std::initializer_list<T> ilist);
559 void assign(const segment_vector &other);
560 void assign(segment_vector &&other);
561 void assign(const std::vector<T> &other);
562
563 /* Destructor */
565
566 /* Element access */
567 reference at(size_type n);
568 const_reference at(size_type n) const;
569 const_reference const_at(size_type n) const;
570 reference operator[](size_type n);
571 const_reference operator[](size_type n) const;
572 reference front();
573 const_reference front() const;
574 const_reference cfront() const;
575 reference back();
576 const_reference back() const;
577 const_reference cback() const;
578
579 /* Iterators */
581 const_iterator begin() const noexcept;
582 const_iterator cbegin() const noexcept;
584 const_iterator end() const noexcept;
585 const_iterator cend() const noexcept;
586 reverse_iterator rbegin();
587 const_reverse_iterator rbegin() const noexcept;
588 const_reverse_iterator crbegin() const noexcept;
589 reverse_iterator rend();
590 const_reverse_iterator rend() const noexcept;
591 const_reverse_iterator crend() const noexcept;
592
593 /* Range */
594 slice<iterator> range(size_type start, size_type n);
595 slice<const_iterator> range(size_type start, size_type n) const;
596 slice<const_iterator> crange(size_type start, size_type n) const;
597
598 /* Capacity */
599 constexpr bool empty() const noexcept;
600 size_type size() const noexcept;
601 constexpr size_type max_size() const noexcept;
602 void reserve(size_type capacity_new);
603 size_type capacity() const noexcept;
605
606 /* Modifiers */
607 void clear();
608 void free_data();
609 iterator insert(const_iterator pos, const T &value);
611 iterator insert(const_iterator pos, size_type count, const T &value);
612 template <typename InputIt,
613 typename std::enable_if<
614 detail::is_input_iterator<InputIt>::value,
615 InputIt>::type * = nullptr>
616 iterator insert(const_iterator pos, InputIt first, InputIt last);
617 iterator insert(const_iterator pos, std::initializer_list<T> ilist);
618 template <class... Args>
619 iterator emplace(const_iterator pos, Args &&... args);
620 template <class... Args>
621 reference emplace_back(Args &&... args);
624 void push_back(const T &value);
625 void push_back(T &&value);
626 void pop_back();
627 void resize(size_type count);
628 void resize(size_type count, const value_type &value);
629 void swap(segment_vector &other);
630
631private:
632 /* Helper functions */
633 void internal_reserve(size_type new_capacity);
634 template <typename... Args>
635 void construct(size_type idx, size_type count, Args &&... args);
636 template <typename InputIt,
637 typename std::enable_if<
638 detail::is_input_iterator<InputIt>::value,
639 InputIt>::type * = nullptr>
640 void construct_range(size_type idx, InputIt first, InputIt last);
641 void insert_gap(size_type idx, size_type count);
642 void shrink(size_type size_new);
644 void snapshot_data(size_type idx_first, size_type idx_last);
645
646 /* Data structure specific helper functions */
647 reference get(size_type n);
648 const_reference get(size_type n) const;
649 const_reference cget(size_type n) const;
651
652 /* Number of segments that are currently enabled */
653 p<size_type> _segments_used = 0;
654 /* Segments storage */
655 segment_vector_type _data;
656};
657
658/* Non-member swap */
659template <typename T, typename Policy>
660void swap(segment_vector<T, Policy> &lhs, segment_vector<T, Policy> &rhs);
661
662/*
663 * Comparison operators between
664 * pmem::obj::experimental::segment_vector<T, Policy> and
665 * pmem::obj::experimental::segment_vector<T, Policy>
666 */
667template <typename T, typename Policy>
668bool operator==(const segment_vector<T, Policy> &lhs,
669 const segment_vector<T, Policy> &rhs);
670template <typename T, typename Policy>
671bool operator!=(const segment_vector<T, Policy> &lhs,
672 const segment_vector<T, Policy> &rhs);
673template <typename T, typename Policy>
674bool operator<(const segment_vector<T, Policy> &lhs,
675 const segment_vector<T, Policy> &rhs);
676template <typename T, typename Policy>
677bool operator<=(const segment_vector<T, Policy> &lhs,
678 const segment_vector<T, Policy> &rhs);
679template <typename T, typename Policy>
680bool operator>(const segment_vector<T, Policy> &lhs,
681 const segment_vector<T, Policy> &rhs);
682template <typename T, typename Policy>
683bool operator>=(const segment_vector<T, Policy> &lhs,
684 const segment_vector<T, Policy> &rhs);
685
686/*
687 * Comparison operators between
688 * pmem::obj::experimental::segment_vector<T, Policy> and
689 * std::vector<T>
690 */
691template <typename T, typename Policy>
692bool operator==(const segment_vector<T, Policy> &lhs,
693 const std::vector<T> &rhs);
694template <typename T, typename Policy>
695bool operator!=(const segment_vector<T, Policy> &lhs,
696 const std::vector<T> &rhs);
697template <typename T, typename Policy>
698bool operator<(const segment_vector<T, Policy> &lhs, const std::vector<T> &rhs);
699template <typename T, typename Policy>
700bool operator<=(const segment_vector<T, Policy> &lhs,
701 const std::vector<T> &rhs);
702template <typename T, typename Policy>
703bool operator>(const segment_vector<T, Policy> &lhs, const std::vector<T> &rhs);
704template <typename T, typename Policy>
705bool operator>=(const segment_vector<T, Policy> &lhs,
706 const std::vector<T> &rhs);
707
708/*
709 * Comparison operators between std::vector<T> and
710 * pmem::obj::experimental::segment_vector<T, Policy>
711 */
712template <typename T, typename Policy>
713bool operator==(const std::vector<T> &lhs,
714 const segment_vector<T, Policy> &rhs);
715template <typename T, typename Policy>
716bool operator!=(const std::vector<T> &lhs,
717 const segment_vector<T, Policy> &rhs);
718template <typename T, typename Policy>
719bool operator<(const std::vector<T> &lhs, const segment_vector<T, Policy> &rhs);
720template <typename T, typename Policy>
721bool operator<=(const std::vector<T> &lhs,
722 const segment_vector<T, Policy> &rhs);
723template <typename T, typename Policy>
724bool operator>(const std::vector<T> &lhs, const segment_vector<T, Policy> &rhs);
725template <typename T, typename Policy>
726bool operator>=(const std::vector<T> &lhs,
727 const segment_vector<T, Policy> &rhs);
728
737template <typename T, typename Policy>
739{
740}
741
764template <typename T, typename Policy>
766 const value_type &value)
767{
768 internal_reserve(count);
769 construct(0, count, value);
770}
771
793template <typename T, typename Policy>
795{
796 internal_reserve(count);
797 construct(0, count);
798}
799
826template <typename T, typename Policy>
827template <typename InputIt,
828 typename std::enable_if<detail::is_input_iterator<InputIt>::value,
829 InputIt>::type *>
831{
832 internal_reserve(static_cast<size_type>(std::distance(first, last)));
833 construct_range(0, first, last);
834}
835
857template <typename T, typename Policy>
859{
860 internal_reserve(other.capacity());
861 construct_range(0, other.cbegin(), other.cend());
862}
863
884template <typename T, typename Policy>
886{
887 _data = std::move(other._data);
888 _segments_used = other._segments_used;
889 other._segments_used = 0;
890}
891
913template <typename T, typename Policy>
914segment_vector<T, Policy>::segment_vector(std::initializer_list<T> init)
915 : segment_vector(init.begin(), init.end())
916{
917}
918
940template <typename T, typename Policy>
942 : segment_vector(other.cbegin(), other.cend())
943{
944}
945
963template <typename T, typename Policy>
966{
967 assign(other);
968 return *this;
969}
970
986template <typename T, typename Policy>
989{
990 assign(std::move(other));
991 return *this;
992}
993
1011template <typename T, typename Policy>
1013segment_vector<T, Policy>::operator=(std::initializer_list<T> ilist)
1014{
1015 assign(ilist.begin(), ilist.end());
1016 return *this;
1017}
1018
1036template <typename T, typename Policy>
1038segment_vector<T, Policy>::operator=(const std::vector<T> &other)
1039{
1040 assign(other);
1041 return *this;
1042}
1043
1066template <typename T, typename Policy>
1067void
1068segment_vector<T, Policy>::assign(size_type count, const_reference value)
1069{
1070 if (count > max_size())
1071 throw std::length_error("Assignable range exceeds max size.");
1072
1073 pool_base pb = get_pool();
1074 flat_transaction::run(pb, [&] {
1075 if (count > capacity())
1076 internal_reserve(count);
1077 else if (count < size())
1078 shrink(count);
1079
1084 if (count != 0) {
1085 size_type end = policy::get_segment(count - 1);
1086 for (size_type i = 0; i < end; ++i)
1087 _data[i].assign(policy::segment_size(i), value);
1088 _data[end].assign(count - policy::segment_top(end),
1089 value);
1090
1091 _segments_used = end + 1;
1092 }
1093 });
1094 assert(segment_capacity_validation());
1095}
1096
1119template <typename T, typename Policy>
1120template <typename InputIt,
1121 typename std::enable_if<detail::is_input_iterator<InputIt>::value,
1122 InputIt>::type *>
1123void
1124segment_vector<T, Policy>::assign(InputIt first, InputIt last)
1125{
1126 size_type count = static_cast<size_type>(std::distance(first, last));
1127 if (count > max_size())
1128 throw std::length_error("Assignable range exceeds max size.");
1129
1130 pool_base pb = get_pool();
1131 flat_transaction::run(pb, [&] {
1132 if (count > capacity())
1133 internal_reserve(count);
1134 else if (count < size())
1135 shrink(count);
1136
1141 if (count != 0) {
1142 difference_type num;
1143 size_type end = policy::get_segment(count - 1);
1144 for (size_type i = 0; i < end; ++i) {
1145 size_type size = policy::segment_size(i);
1146 num = static_cast<difference_type>(size);
1147 _data[i].assign(first, std::next(first, num));
1148 std::advance(first, num);
1149 }
1150 num = static_cast<difference_type>(
1151 std::distance(first, last));
1152 _data[end].assign(first, std::next(first, num));
1153
1154 _segments_used = end + 1;
1155 }
1156 });
1157 assert(segment_capacity_validation());
1158}
1159
1180template <typename T, typename Policy>
1181void
1182segment_vector<T, Policy>::assign(std::initializer_list<T> ilist)
1183{
1184 assign(ilist.begin(), ilist.end());
1185}
1186
1203template <typename T, typename Policy>
1204void
1206{
1207 if (this != &other)
1208 assign(other.cbegin(), other.cend());
1209}
1210
1226template <typename T, typename Policy>
1227void
1229{
1230 if (this == &other)
1231 return;
1232
1233 pool_base pb = get_pool();
1234 flat_transaction::run(pb, [&] {
1235 _data = std::move(other._data);
1236 _segments_used = other._segments_used;
1237 other._segments_used = 0;
1238 });
1239}
1240
1257template <typename T, typename Policy>
1258void
1259segment_vector<T, Policy>::assign(const std::vector<T> &other)
1260{
1261 assign(other.cbegin(), other.cend());
1262}
1263
1271template <typename T, typename Policy>
1273{
1274 try {
1275 free_data();
1276 } catch (...) {
1277 std::terminate();
1278 }
1279}
1280
1294template <typename T, typename Policy>
1295typename segment_vector<T, Policy>::reference
1297{
1298 if (n >= size())
1299 throw std::out_of_range("segment_vector::at");
1300
1301 detail::conditional_add_to_tx(&get(n), 1, POBJ_XADD_ASSUME_INITIALIZED);
1302
1303 return get(n);
1304}
1305
1316template <typename T, typename Policy>
1317typename segment_vector<T, Policy>::const_reference
1319{
1320 if (n >= size())
1321 throw std::out_of_range("segment_vector::at");
1322 return get(n);
1323}
1324
1337template <typename T, typename Policy>
1338typename segment_vector<T, Policy>::const_reference
1340{
1341 if (n >= size())
1342 throw std::out_of_range("segment_vector::const_at");
1343 return get(n);
1344}
1345
1357template <typename T, typename Policy>
1358typename segment_vector<T, Policy>::reference
1360{
1361 reference element = get(n);
1362
1363 detail::conditional_add_to_tx(&element, 1,
1364 POBJ_XADD_ASSUME_INITIALIZED);
1365
1366 return element;
1367}
1368
1376template <typename T, typename Policy>
1377typename segment_vector<T, Policy>::const_reference
1379{
1380 return get(n);
1381}
1382
1391template <typename T, typename Policy>
1392typename segment_vector<T, Policy>::reference
1394{
1395 detail::conditional_add_to_tx(&_data[0][0], 1,
1396 POBJ_XADD_ASSUME_INITIALIZED);
1397
1398 return _data[0][0];
1399}
1400
1406template <typename T, typename Policy>
1407typename segment_vector<T, Policy>::const_reference
1409{
1410 return _data[0][0];
1411}
1412
1420template <typename T, typename Policy>
1421typename segment_vector<T, Policy>::const_reference
1423{
1424 return _data[0][0];
1425}
1426
1435template <typename T, typename Policy>
1436typename segment_vector<T, Policy>::reference
1438{
1439 reference element = get(size() - 1);
1440
1441 detail::conditional_add_to_tx(&element, 1,
1442 POBJ_XADD_ASSUME_INITIALIZED);
1443
1444 return element;
1445}
1446
1452template <typename T, typename Policy>
1453typename segment_vector<T, Policy>::const_reference
1455{
1456 return get(size() - 1);
1457}
1458
1466template <typename T, typename Policy>
1467typename segment_vector<T, Policy>::const_reference
1469{
1470 return get(size() - 1);
1471}
1472
1478template <typename T, typename Policy>
1481{
1482 return iterator(this, 0);
1483}
1484
1491template <typename T, typename Policy>
1494{
1495 return const_iterator(this, 0);
1496}
1497
1506template <typename T, typename Policy>
1509{
1510 return const_iterator(this, 0);
1511}
1512
1519template <typename T, typename Policy>
1522{
1523 return iterator(this, size());
1524}
1525
1532template <typename T, typename Policy>
1535{
1536 return const_iterator(this, size());
1537}
1538
1547template <typename T, typename Policy>
1550{
1551 return const_iterator(this, size());
1552}
1553
1560template <typename T, typename Policy>
1561typename segment_vector<T, Policy>::reverse_iterator
1563{
1564 return reverse_iterator(end());
1565}
1566
1573template <typename T, typename Policy>
1574typename segment_vector<T, Policy>::const_reverse_iterator
1576{
1577 return const_reverse_iterator(end());
1578}
1579
1588template <typename T, typename Policy>
1589typename segment_vector<T, Policy>::const_reverse_iterator
1591{
1592 return rbegin();
1593}
1594
1601template <typename T, typename Policy>
1602typename segment_vector<T, Policy>::reverse_iterator
1604{
1605 return reverse_iterator(begin());
1606}
1607
1614template <typename T, typename Policy>
1615typename segment_vector<T, Policy>::const_reverse_iterator
1617{
1618 return const_reverse_iterator(begin());
1619}
1620
1629template <typename T, typename Policy>
1630typename segment_vector<T, Policy>::const_reverse_iterator
1632{
1633 return rend();
1634}
1635
1649template <typename T, typename Policy>
1651segment_vector<T, Policy>::range(size_type start, size_type n)
1652{
1653 if (start + n > size())
1654 throw std::out_of_range("segment_vector::range");
1655
1656 snapshot_data(start, start + n);
1657
1658 return {iterator(this, start), iterator(this, start + n)};
1659}
1660
1672template <typename T, typename Policy>
1674segment_vector<T, Policy>::range(size_type start, size_type n) const
1675{
1676 if (start + n > size())
1677 throw std::out_of_range("segment_vector::range");
1678
1679 return {const_iterator(this, start), const_iterator(this, start + n)};
1680}
1681
1693template <typename T, typename Policy>
1695segment_vector<T, Policy>::crange(size_type start, size_type n) const
1696{
1697 if (start + n > size())
1698 throw std::out_of_range("segment_vector::range");
1699
1700 return {const_iterator(this, start), const_iterator(this, start + n)};
1701}
1702
1708template <typename T, typename Policy>
1709constexpr bool
1711{
1712 return size() == 0;
1713}
1714
1718template <typename T, typename Policy>
1719typename segment_vector<T, Policy>::size_type
1721{
1722 size_type result = 0;
1723
1724 try {
1725 for (size_type i = 0; i < _segments_used; ++i)
1726 result += _data.const_at(i).size();
1727 } catch (std::out_of_range &) {
1728 /* Can only happen in case of a bug with segments_used calc */
1729 assert(false);
1730 }
1731
1732 return result;
1733}
1734
1739template <typename T, typename Policy>
1740constexpr typename segment_vector<T, Policy>::size_type
1742{
1743 return policy::max_size(_data);
1744}
1745
1762template <typename T, typename Policy>
1763void
1765{
1766 if (capacity_new <= capacity())
1767 return;
1768
1769 pool_base pb = get_pool();
1770 flat_transaction::run(pb, [&] { internal_reserve(capacity_new); });
1771}
1772
1777template <typename T, typename Policy>
1778typename segment_vector<T, Policy>::size_type
1780{
1781 if (_segments_used == 0)
1782 return 0;
1783 return policy::capacity(_segments_used - 1);
1784}
1785
1797template <typename T, typename Policy>
1798void
1800{
1801 if (empty())
1802 return;
1803 size_type new_last = policy::get_segment(size() - 1);
1804 if (_segments_used - 1 == new_last)
1805 return;
1806
1807 pool_base pb = get_pool();
1808 flat_transaction::run(pb, [&] {
1809 for (size_type i = new_last + 1; i < _segments_used; ++i)
1810 _data[i].free_data();
1811 _segments_used = new_last + 1;
1812 storage::resize(_data, _segments_used);
1813 });
1814}
1815
1827template <typename T, typename Policy>
1828void
1830{
1831 pool_base pb = get_pool();
1832 flat_transaction::run(pb, [&] { shrink(0); });
1833 assert(segment_capacity_validation());
1834}
1835
1848template <typename T, typename Policy>
1849void
1851{
1852 pool_base pb = get_pool();
1853 flat_transaction::run(pb, [&] {
1854 for (size_type i = 0; i < _segments_used; ++i)
1855 _data[i].free_data();
1856 _segments_used = 0;
1857 });
1858}
1859
1883template <typename T, typename Policy>
1886{
1887 return insert(pos, 1, value);
1888}
1889
1913template <typename T, typename Policy>
1916{
1917 size_type idx = static_cast<size_type>(pos - cbegin());
1918
1919 pool_base pb = get_pool();
1920 flat_transaction::run(pb, [&] {
1921 insert_gap(idx, 1);
1922 get(idx) = std::move(value);
1923 });
1924
1925 return iterator(this, idx);
1926}
1927
1954template <typename T, typename Policy>
1957 const T &value)
1958{
1959 size_type idx = static_cast<size_type>(pos - cbegin());
1960
1961 pool_base pb = get_pool();
1962 flat_transaction::run(pb, [&] {
1963 insert_gap(idx, count);
1964 for (size_type i = idx; i < idx + count; ++i)
1965 get(i) = std::move(value);
1966 });
1967
1968 return iterator(this, idx);
1969}
1970
2004template <typename T, typename Policy>
2005template <typename InputIt,
2006 typename std::enable_if<detail::is_input_iterator<InputIt>::value,
2007 InputIt>::type *>
2010 InputIt last)
2011{
2012 size_type idx = static_cast<size_type>(pos - cbegin());
2013 size_type gap_size = static_cast<size_type>(std::distance(first, last));
2014
2015 pool_base pb = get_pool();
2016 flat_transaction::run(pb, [&] {
2017 insert_gap(idx, gap_size);
2018 for (size_type i = idx; i < idx + gap_size; ++i, ++first)
2019 get(i) = *first;
2020 });
2021
2022 return iterator(this, idx);
2023}
2024
2051template <typename T, typename Policy>
2054 std::initializer_list<T> ilist)
2055{
2056 return insert(pos, ilist.begin(), ilist.end());
2057}
2058
2087template <typename T, typename Policy>
2088template <class... Args>
2091{
2092 size_type idx = static_cast<size_type>(pos - cbegin());
2093
2094 pool_base pb = get_pool();
2095 flat_transaction::run(pb, [&] {
2096 detail::temp_value<value_type,
2097 noexcept(T(std::forward<Args>(args)...))>
2098 tmp(std::forward<Args>(args)...);
2099 insert_gap(idx, 1);
2100 get(idx) = std::move(tmp.get());
2101 });
2102
2103 return iterator(this, idx);
2104}
2105
2130template <typename T, typename Policy>
2131template <class... Args>
2132typename segment_vector<T, Policy>::reference
2134{
2135 assert(size() < max_size());
2136
2137 pool_base pb = get_pool();
2138 flat_transaction::run(pb, [&] {
2139 if (size() == capacity())
2140 internal_reserve(capacity() + 1);
2141
2142 size_type segment = policy::get_segment(size());
2143 _data[segment].emplace_back(std::forward<Args>(args)...);
2144 });
2145
2146 return back();
2147}
2148
2170template <typename T, typename Policy>
2173{
2174 return erase(pos, pos + 1);
2175}
2176
2201template <typename T, typename Policy>
2204{
2205 size_type count = static_cast<size_type>(std::distance(first, last));
2206 size_type idx = static_cast<size_type>(first - cbegin());
2207
2208 if (count == 0)
2209 return iterator(this, idx);
2210
2211 pool_base pb = get_pool();
2212 flat_transaction::run(pb, [&] {
2213 size_type _size = size();
2214
2215 if (!std::is_trivially_destructible<T>::value ||
2216 idx + count < _size)
2217 snapshot_data(idx, _size);
2218
2219 /* Moving after-range elements to the place of deleted
2220 */
2221 iterator dest = iterator(this, idx);
2222 iterator begin = iterator(this, idx + count);
2223 iterator end = iterator(this, _size);
2224 std::move(begin, end, dest);
2225
2226 /* Clearing the range where the elements were moved from
2227 */
2228 size_type middle = policy::get_segment(_size - count);
2229 size_type last = policy::get_segment(_size - 1);
2230 size_type middle_size = policy::index_in_segment(_size - count);
2231 for (size_type s = last; s > middle; --s)
2232 _data[s].clear();
2233 _data[middle].resize(middle_size);
2234
2235 _segments_used = middle + 1;
2236 });
2237
2238 assert(segment_capacity_validation());
2239
2240 return iterator(this, idx);
2241}
2242
2261template <typename T, typename Policy>
2262void
2264{
2265 emplace_back(value);
2266}
2267
2286template <typename T, typename Policy>
2287void
2289{
2290 emplace_back(std::move(value));
2291}
2292
2306template <typename T, typename Policy>
2307void
2309{
2310 if (empty())
2311 return;
2312
2313 pool_base pb = get_pool();
2314 flat_transaction::run(pb, [&] { shrink(size() - 1); });
2315 assert(segment_capacity_validation());
2316}
2317
2341template <typename T, typename Policy>
2342void
2344{
2345 pool_base pb = get_pool();
2346 flat_transaction::run(pb, [&] {
2347 size_type _size = size();
2348 if (count < _size)
2349 shrink(count);
2350 else {
2351 if (capacity() < count)
2352 internal_reserve(count);
2353 construct(_size, count - _size);
2354 }
2355 });
2356 assert(segment_capacity_validation());
2357}
2358
2383template <typename T, typename Policy>
2384void
2385segment_vector<T, Policy>::resize(size_type count, const value_type &value)
2386{
2387 pool_base pb = get_pool();
2388 flat_transaction::run(pb, [&] {
2389 size_type _size = size();
2390 if (count < _size)
2391 shrink(count);
2392 else {
2393 if (capacity() < count)
2394 internal_reserve(count);
2395 construct(_size, count - _size, value);
2396 }
2397 });
2398 assert(segment_capacity_validation());
2399}
2400
2404template <typename T, typename Policy>
2405void
2407{
2408 pool_base pb = get_pool();
2409 flat_transaction::run(pb, [&] {
2410 _data.swap(other._data);
2411 std::swap(_segments_used, other._segments_used);
2412 });
2413}
2414
2430template <typename T, typename Policy>
2431void
2433{
2434 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
2435
2436 if (new_capacity > max_size())
2437 throw std::length_error("New capacity exceeds max size.");
2438
2439 if (new_capacity == 0)
2440 return;
2441
2442 size_type old_idx = policy::get_segment(capacity());
2443 size_type new_idx = policy::get_segment(new_capacity - 1);
2444 storage::resize(_data, new_idx + 1);
2445 for (size_type i = old_idx; i <= new_idx; ++i) {
2446 size_type segment_capacity = policy::segment_size(i);
2447 _data[i].reserve(segment_capacity);
2448 }
2449 _segments_used = new_idx + 1;
2450
2451 assert(segment_capacity_validation());
2452}
2453
2480template <typename T, typename Policy>
2481template <typename... Args>
2482void
2483segment_vector<T, Policy>::construct(size_type idx, size_type count,
2484 Args &&... args)
2485{
2486 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
2487 assert(capacity() >= size() + count);
2488
2489 for (size_type i = idx; i < idx + count; ++i) {
2490 size_type segment = policy::get_segment(i);
2491 _data[segment].emplace_back(std::forward<Args>(args)...);
2492 }
2493
2494 assert(segment_capacity_validation());
2495}
2496
2527template <typename T, typename Policy>
2528template <typename InputIt,
2529 typename std::enable_if<detail::is_input_iterator<InputIt>::value,
2530 InputIt>::type *>
2531void
2533 InputIt last)
2534{
2535 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
2536 size_type count = static_cast<size_type>(std::distance(first, last));
2537 assert(capacity() >= size() + count);
2538
2539 for (size_type i = idx; i < idx + count; ++i, ++first) {
2540 size_type segment = policy::get_segment(i);
2541 _data[segment].emplace_back(*first);
2542 }
2543
2544 assert(segment_capacity_validation());
2545}
2546
2568template <typename T, typename Policy>
2569void
2570segment_vector<T, Policy>::insert_gap(size_type idx, size_type count)
2571{
2572 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
2573 if (count == 0)
2574 return;
2575
2576 size_type _size = size();
2577
2578 if (capacity() < _size + count)
2579 internal_reserve(_size + count);
2580
2581 iterator dest = iterator(this, _size + count);
2582 iterator begin = iterator(this, idx);
2583 iterator end = iterator(this, _size);
2584
2585 snapshot_data(idx, _size);
2586
2587 resize(_size + count);
2588 std::move_backward(begin, end, dest);
2589
2590 assert(segment_capacity_validation());
2591}
2592
2612template <typename T, typename Policy>
2613void
2615{
2616 assert(pmemobj_tx_stage() == TX_STAGE_WORK);
2617 assert(size_new <= size());
2618
2619 if (empty())
2620 return;
2621
2622 if (!std::is_trivially_destructible<T>::value)
2623 snapshot_data(size_new, size());
2624
2625 size_type begin = policy::get_segment(size() - 1);
2626 size_type end = policy::get_segment(size_new);
2627 for (; begin > end; --begin) {
2628 _data[begin].clear();
2629 }
2630 size_type residue = policy::index_in_segment(size_new);
2631 _data[end].erase(_data[end].cbegin() + residue, _data[end].cend());
2632
2633 assert(segment_capacity_validation());
2634}
2635
2643template <typename T, typename Policy>
2646{
2647 return pmem::obj::pool_by_vptr(this);
2648}
2649
2659template <typename T, typename Policy>
2660void
2661segment_vector<T, Policy>::snapshot_data(size_type first, size_type last)
2662{
2663 if (first == last)
2664 return;
2665
2666 size_type segment = policy::get_segment(first);
2667 size_type end = policy::get_segment(last - 1);
2668 size_type count = policy::segment_top(segment + 1) - first;
2669
2670 while (segment != end) {
2671 detail::conditional_add_to_tx(&cget(first), count,
2672 POBJ_XADD_ASSUME_INITIALIZED);
2673 first = policy::segment_top(++segment);
2674 count = policy::segment_size(segment);
2675 }
2676 detail::conditional_add_to_tx(&cget(first), last - first,
2677 POBJ_XADD_ASSUME_INITIALIZED);
2678}
2679
2685template <typename T, typename Policy>
2686typename segment_vector<T, Policy>::reference
2688{
2689 size_type s_idx = policy::get_segment(n);
2690 size_type local_idx = policy::index_in_segment(n);
2691
2692 return _data[s_idx][local_idx];
2693}
2694
2700template <typename T, typename Policy>
2701typename segment_vector<T, Policy>::const_reference
2703{
2704 size_type s_idx = policy::get_segment(n);
2705 size_type local_idx = policy::index_in_segment(n);
2706
2707 return _data[s_idx][local_idx];
2708}
2709
2715template <typename T, typename Policy>
2716typename segment_vector<T, Policy>::const_reference
2718{
2719 size_type s_idx = policy::get_segment(n);
2720 size_type local_idx = policy::index_in_segment(n);
2721
2722 return _data[s_idx][local_idx];
2723}
2724
2732template <typename T, typename Policy>
2733bool
2735{
2736 for (size_type i = 0; i < _segments_used; ++i)
2737 if (_data.const_at(i).capacity() != policy::segment_size(i))
2738 return false;
2739 return true;
2740}
2741
2748template <typename T, typename Policy>
2749void
2751{
2752 lhs.swap(rhs);
2753}
2754
2769template <typename T, typename Policy>
2770bool
2772 const segment_vector<T, Policy> &rhs)
2773{
2774 return lhs.size() == rhs.size() &&
2775 std::equal(lhs.begin(), lhs.end(), rhs.begin());
2776}
2777
2793template <typename T, typename Policy>
2794bool
2796 const segment_vector<T, Policy> &rhs)
2797{
2798 return !(lhs == rhs);
2799}
2800
2813template <typename T, typename Policy>
2814bool
2816 const segment_vector<T, Policy> &rhs)
2817{
2818 return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(),
2819 rhs.end());
2820}
2821
2834template <typename T, typename Policy>
2835bool
2837 const segment_vector<T, Policy> &rhs)
2838{
2839 return !(rhs < lhs);
2840}
2841
2854template <typename T, typename Policy>
2855bool
2857 const segment_vector<T, Policy> &rhs)
2858{
2859 return rhs < lhs;
2860}
2861
2874template <typename T, typename Policy>
2875bool
2877 const segment_vector<T, Policy> &rhs)
2878{
2879 return !(lhs < rhs);
2880}
2881
2895template <typename T, typename Policy>
2896bool
2897operator==(const segment_vector<T, Policy> &lhs, const std::vector<T> &rhs)
2898{
2899 return lhs.size() == rhs.size() &&
2900 std::equal(lhs.begin(), lhs.end(), rhs.begin());
2901}
2902
2916template <typename T, typename Policy>
2917bool
2918operator!=(const segment_vector<T, Policy> &lhs, const std::vector<T> &rhs)
2919{
2920 return !(lhs == rhs);
2921}
2922
2934template <typename T, typename Policy>
2935bool
2936operator<(const segment_vector<T, Policy> &lhs, const std::vector<T> &rhs)
2937{
2938 return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(),
2939 rhs.end());
2940}
2941
2953template <typename T, typename Policy>
2954bool
2955operator<=(const segment_vector<T, Policy> &lhs, const std::vector<T> &rhs)
2956{
2957 return !(std::lexicographical_compare(rhs.begin(), rhs.end(),
2958 lhs.begin(), lhs.end()));
2959}
2960
2973template <typename T, typename Policy>
2974bool
2975operator>(const segment_vector<T, Policy> &lhs, const std::vector<T> &rhs)
2976{
2977 return !(lhs <= rhs);
2978}
2979
2991template <typename T, typename Policy>
2992bool
2993operator>=(const segment_vector<T, Policy> &lhs, const std::vector<T> &rhs)
2994{
2995 return !(lhs < rhs);
2996}
2997
3011template <typename T, typename Policy>
3012bool
3013operator==(const std::vector<T> &lhs, const segment_vector<T, Policy> &rhs)
3014{
3015 return rhs == lhs;
3016}
3017
3031template <typename T, typename Policy>
3032bool
3033operator!=(const std::vector<T> &lhs, const segment_vector<T, Policy> &rhs)
3034{
3035 return !(lhs == rhs);
3036}
3037
3049template <typename T, typename Policy>
3050bool
3051operator<(const std::vector<T> &lhs, const segment_vector<T, Policy> &rhs)
3052{
3053 return rhs > lhs;
3054}
3055
3067template <typename T, typename Policy>
3068bool
3069operator<=(const std::vector<T> &lhs, const segment_vector<T, Policy> &rhs)
3070{
3071 return !(rhs < lhs);
3072}
3073
3086template <typename T, typename Policy>
3087bool
3088operator>(const std::vector<T> &lhs, const segment_vector<T, Policy> &rhs)
3089{
3090 return rhs < lhs;
3091}
3092
3104template <typename T, typename Policy>
3105bool
3106operator>=(const std::vector<T> &lhs, const segment_vector<T, Policy> &rhs)
3107{
3108 return !(lhs < rhs);
3109}
3110
3111} /* namespace obj */
3112} /* namespace pmem */
3113
3114#endif /* LIBPMEMOBJ_SEGMENT_VECTOR_HPP */
Array container with std::array compatible interface.
static void run(obj::pool_base &pool, std::function< void()> tx, Locks &... locks)
Execute a closure-like transaction and lock locks.
Definition: transaction.hpp:823
Resides on pmem class.
Definition: p.hpp:35
The non-template pool base class.
Definition: pool.hpp:50
Iterator for segment_vector.
Definition: segment_vector.hpp:46
segment_iterator & operator-=(difference_type idx)
Random access decrementing with assignment.
Definition: segment_vector.hpp:266
segment_iterator operator-(difference_type idx) const
Random access decrementing.
Definition: segment_vector.hpp:254
bool operator==(const segment_iterator< Container, C > &rhs) const
Compare methods Template parameter is needed to enable this methods work with non-constant and consta...
Definition: segment_vector.hpp:310
segment_iterator() noexcept
Default constructor.
Definition: segment_vector.hpp:132
bool operator<=(const segment_iterator< Container, C > &rhs) const
Less or equal operator.
Definition: segment_vector.hpp:392
bool operator>(const segment_iterator< Container, C > &rhs) const
Greater operator.
Definition: segment_vector.hpp:369
pointer operator->() const
Member access.
Definition: segment_vector.hpp:439
bool operator<(const segment_iterator< Container, C > &rhs) const
Less operator.
Definition: segment_vector.hpp:346
segment_iterator operator+(difference_type idx) const
Random access incrementing.
Definition: segment_vector.hpp:202
segment_iterator & operator--()
Prefix decrement.
Definition: segment_vector.hpp:227
reference operator*() const
Indirection (dereference).
Definition: segment_vector.hpp:429
segment_iterator & operator++()
Prefix increment.
Definition: segment_vector.hpp:175
bool operator!=(const segment_iterator< Container, C > &rhs) const
Not equal operator.
Definition: segment_vector.hpp:327
segment_iterator & operator+=(difference_type idx)
Random access incrementing with assignment.
Definition: segment_vector.hpp:214
bool operator>=(const segment_iterator< Container, C > &rhs) const
Greater or equal operator.
Definition: segment_vector.hpp:415
A persistent version of segment vector implementation.
Definition: segment_vector.hpp:504
reference front()
Access the first element and add this element to a transaction.
Definition: segment_vector.hpp:1393
void reserve(size_type capacity_new)
Increases the capacity of the segment_vector to capacity_new transactionally.
Definition: segment_vector.hpp:1764
void assign(InputIt first, InputIt last)
Replaces the contents with copies of those in the range [first, last) transactionally.
Definition: segment_vector.hpp:1124
constexpr bool empty() const noexcept
Checks whether the container is empty.
Definition: segment_vector.hpp:1710
const_reverse_iterator crbegin() const noexcept
Returns a const reverse iterator to the beginning.
Definition: segment_vector.hpp:1590
segment_vector(InputIt first, InputIt last)
Constructs the container with the contents of the range [first, last).
Definition: segment_vector.hpp:830
size_type capacity() const noexcept
Definition: segment_vector.hpp:1779
void assign(std::initializer_list< T > ilist)
Replaces the contents with the elements from the initializer list ilist transactionally.
Definition: segment_vector.hpp:1182
pool_base get_pool() const
Private helper function.
Definition: segment_vector.hpp:2645
void assign(segment_vector &&other)
Move assignment method.
Definition: segment_vector.hpp:1228
reference get(size_type n)
Private helper function.
Definition: segment_vector.hpp:2687
reverse_iterator rbegin()
Returns a reverse iterator to the beginning.
Definition: segment_vector.hpp:1562
constexpr size_type max_size() const noexcept
Definition: segment_vector.hpp:1741
reference emplace_back(Args &&... args)
Appends a new element to the end of the container transactionally.
Definition: segment_vector.hpp:2133
segment_vector(size_type count)
Constructs the container with count copies of T default constructed values.
Definition: segment_vector.hpp:794
const_reference at(size_type n) const
Access element at specific index with bounds checking.
Definition: segment_vector.hpp:1318
reference at(size_type n)
Access element at specific index with bounds checking and add it to a transaction.
Definition: segment_vector.hpp:1296
reference operator[](size_type n)
Access element at specific index and add it to a transaction.
Definition: segment_vector.hpp:1359
const_reference cfront() const
Access the first element.
Definition: segment_vector.hpp:1422
segment_vector(const std::vector< T > &other)
Copy constructor.
Definition: segment_vector.hpp:941
void swap(segment_vector &other)
Exchanges the contents of the container with other transactionally.
Definition: segment_vector.hpp:2406
void snapshot_data(size_type idx_first, size_type idx_last)
Private helper function.
Definition: segment_vector.hpp:2661
void clear()
Clears the content of a segment_vector transactionally.
Definition: segment_vector.hpp:1829
const_reference operator[](size_type n) const
Access element at specific index.
Definition: segment_vector.hpp:1378
~segment_vector()
Destructor.
Definition: segment_vector.hpp:1272
const_reference const_at(size_type n) const
Access element at specific index with bounds checking.
Definition: segment_vector.hpp:1339
const_reference cback() const
Access the last element.
Definition: segment_vector.hpp:1468
void assign(const std::vector< T > &other)
Copy assignment method.
Definition: segment_vector.hpp:1259
iterator begin()
Returns an iterator to the beginning.
Definition: segment_vector.hpp:1480
void resize(size_type count)
Resizes the container to count elements transactionally.
Definition: segment_vector.hpp:2343
const_iterator begin() const noexcept
Returns const iterator to the beginning.
Definition: segment_vector.hpp:1493
reference back()
Access the last element and add this element to a transaction.
Definition: segment_vector.hpp:1437
segment_vector(size_type count, const value_type &value)
Constructs the container with count copies of elements with value value.
Definition: segment_vector.hpp:765
const_reverse_iterator crend() const noexcept
Returns a const reverse iterator to the beginning.
Definition: segment_vector.hpp:1631
const_reference back() const
Access the last element.
Definition: segment_vector.hpp:1454
void push_back(const T &value)
Appends the given element value to the end of the container transactionally.
Definition: segment_vector.hpp:2263
const_reference front() const
Access the first element.
Definition: segment_vector.hpp:1408
slice< iterator > range(size_type start, size_type n)
Returns slice and snapshots requested range.
Definition: segment_vector.hpp:1651
size_type size() const noexcept
Definition: segment_vector.hpp:1720
void shrink(size_type size_new)
Private helper function.
Definition: segment_vector.hpp:2614
void assign(const segment_vector &other)
Copy assignment method.
Definition: segment_vector.hpp:1205
void free_data()
Clears the content of a segment_vector and frees all allocated persistent memory for data transaction...
Definition: segment_vector.hpp:1850
segment_vector & operator=(segment_vector &&other)
Move assignment operator.
Definition: segment_vector.hpp:988
iterator erase(const_iterator pos)
Removes the element at pos.
Definition: segment_vector.hpp:2172
const_reference cget(size_type n) const
Private helper function.
Definition: segment_vector.hpp:2717
segment_vector(const segment_vector &other)
Copy constructor.
Definition: segment_vector.hpp:858
iterator emplace(const_iterator pos, Args &&... args)
Inserts a new element into the container directly before pos.
Definition: segment_vector.hpp:2090
reverse_iterator rend()
Returns a reverse iterator to the end.
Definition: segment_vector.hpp:1603
segment_vector()
Default constructor.
Definition: segment_vector.hpp:738
segment_vector & operator=(const segment_vector &other)
Copy assignment operator.
Definition: segment_vector.hpp:965
void internal_reserve(size_type new_capacity)
Private helper method.
Definition: segment_vector.hpp:2432
iterator end()
Returns an iterator to past the end.
Definition: segment_vector.hpp:1521
void pop_back()
Removes the last element of the container transactionally.
Definition: segment_vector.hpp:2308
void shrink_to_fit()
Requests transactional removal of unused capacity.
Definition: segment_vector.hpp:1799
void construct(size_type idx, size_type count, Args &&... args)
Private helper function.
Definition: segment_vector.hpp:2483
iterator insert(const_iterator pos, const T &value)
Inserts value before pos in the container transactionally.
Definition: segment_vector.hpp:1885
const_iterator cend() const noexcept
Returns a const iterator to the end.
Definition: segment_vector.hpp:1549
segment_vector & operator=(std::initializer_list< T > ilist)
Replaces the contents with those identified by initializer list ilist transactionally.
Definition: segment_vector.hpp:1013
slice< const_iterator > crange(size_type start, size_type n) const
Returns const slice.
Definition: segment_vector.hpp:1695
void insert_gap(size_type idx, size_type count)
Private helper function.
Definition: segment_vector.hpp:2570
segment_vector & operator=(const std::vector< T > &other)
Copy assignment operator.
Definition: segment_vector.hpp:1038
void construct_range(size_type idx, InputIt first, InputIt last)
Private helper function.
Definition: segment_vector.hpp:2532
bool segment_capacity_validation() const
Private helper function.
Definition: segment_vector.hpp:2734
void assign(size_type count, const_reference value)
Replaces the contents with count copies of value value transactionally.
Definition: segment_vector.hpp:1068
segment_vector(std::initializer_list< T > init)
Constructs the container with the contents of the initializer list init.
Definition: segment_vector.hpp:914
segment_vector(segment_vector &&other)
Move constructor.
Definition: segment_vector.hpp:885
const_iterator cbegin() const noexcept
Returns const iterator to the beginning.
Definition: segment_vector.hpp:1508
pmem::obj::slice - provides interface to access sequence of objects.
Definition: slice.hpp:50
pmem::obj::vector - persistent container with std::vector compatible interface.
Definition: vector.hpp:41
Commonly used functionality.
Functions for destroying arrays.
Persistent_ptr transactional allocation functions for objects.
bool operator<=(const array< T, N > &lhs, const array< T, N > &rhs)
Non-member less or equal operator.
Definition: array.hpp:779
pmem::obj::array< T, N >::const_iterator cend(const pmem::obj::array< T, N > &a)
Non-member cend.
Definition: array.hpp:799
pmem::obj::array< T, N >::reverse_iterator rend(pmem::obj::array< T, N > &a)
Non-member rend.
Definition: array.hpp:889
pmem::obj::array< T, N >::iterator end(pmem::obj::array< T, N > &a)
Non-member end.
Definition: array.hpp:849
pmem::obj::array< T, N >::reverse_iterator rbegin(pmem::obj::array< T, N > &a)
Non-member rbegin.
Definition: array.hpp:869
bool operator<(const array< T, N > &lhs, const array< T, N > &rhs)
Non-member less than operator.
Definition: array.hpp:748
T & get(pmem::obj::array< T, N > &a)
Non-member get function.
Definition: array.hpp:919
bool operator>=(const array< T, N > &lhs, const array< T, N > &rhs)
Non-member greater or equal operator.
Definition: array.hpp:769
segment_vector_internal::exponential_size_policy< pmem::obj::vector, SegmentType > exponential_size_vector_policy
Exponential size policy with pmemobj vector as a type of segment vector, so this is a dynamic vector ...
Definition: segment_vector.hpp:484
bool operator!=(const allocator< T, P, Tr > &lhs, const OtherAllocator &rhs)
Determines if memory from another allocator can be deallocated from this one.
Definition: allocator.hpp:536
segment_vector_internal::fixed_size_policy< pmem::obj::vector, SegmentType, SegmentSize > fixed_size_vector_policy
Fixed size policy with pmemobj vector of a given size as a type of segment vector,...
Definition: segment_vector.hpp:471
segment_vector_internal::exponential_size_policy< segment_vector_internal::array_64, SegmentType > exponential_size_array_policy
Exponential size policy with pmemobj array of size 64 as a type of segment vector,...
Definition: segment_vector.hpp:457
pool_base pool_by_vptr(const T *that)
Retrieve pool handle for the given pointer.
Definition: utils.hpp:32
bool operator==(standard_alloc_policy< T > const &, standard_alloc_policy< T2 > const &)
Determines if memory from another allocator can be deallocated from this one.
Definition: allocator.hpp:420
bool operator>(const array< T, N > &lhs, const array< T, N > &rhs)
Non-member greater than operator.
Definition: array.hpp:759
pmem::obj::array< T, N >::const_iterator cbegin(const pmem::obj::array< T, N > &a)
Non-member cbegin.
Definition: array.hpp:789
pmem::obj::array< T, N >::iterator begin(pmem::obj::array< T, N > &a)
Non-member begin.
Definition: array.hpp:829
void swap(pmem::obj::array< T, N > &lhs, pmem::obj::array< T, N > &rhs)
Non-member swap function.
Definition: array.hpp:909
Persistent memory namespace.
Definition: allocation_flag.hpp:15
Persistent smart pointer.
Convenience extensions for the resides on pmem property template.
A persistent version of segment vector implementation.
Type trait to determine if a given parameter type satisfies requirements of InputIterator.
Definition: iterator_traits.hpp:47
pmem::obj::array - persistent container with std::array compatible interface.
Definition: array.hpp:56
Commonly used SFINAE helpers.
C++ pmemobj transactions.
Libpmemobj C++ utils.
Vector container with std::vector compatible interface.