PMDK C++ bindings  1.10
This is the C++ bindings documentation for PMDK's libpmemobj.
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 
21 #include <libpmemobj++/pext.hpp>
23 
24 #include <vector>
25 
26 namespace pmem
27 {
28 namespace obj
29 {
30 
31 namespace segment_vector_internal
32 {
40 template <typename Container, bool is_const>
42 public:
43  /* Traits */
44  using iterator_category = std::random_access_iterator_tag;
45  using difference_type = std::ptrdiff_t;
46  using table_type = Container;
47  using size_type = typename table_type::size_type;
48  using value_type = typename table_type::value_type;
49  /* Constant dependent traits */
50  using table_ptr =
51  typename std::conditional<is_const, const table_type *,
52  table_type *>::type;
53  using reference =
54  typename std::conditional<is_const,
55  typename table_type::const_reference,
56  typename table_type::reference>::type;
57  using pointer =
58  typename std::conditional<is_const,
59  typename table_type::const_pointer,
60  typename table_type::pointer>::type;
61 
62  /* To implement methods where operands differ in constancy */
63  friend class segment_iterator<Container, true>;
64  friend class segment_iterator<Container, false>;
65 
66 private:
67  /* Pointer to container for iteration */
68  table_ptr table;
69  /* Index of element in the container */
70  size_type index;
71 
72 public:
73  /* Сonstructors */
74  segment_iterator() noexcept;
75  explicit segment_iterator(table_ptr tab, size_type idx) noexcept;
76  segment_iterator(const segment_iterator &other);
77 
78  /* Copy ctor to enable conversion from non-const to const
79  * iterator */
80  template <typename U = void,
81  typename = typename std::enable_if<is_const, U>::type>
83 
84  /* In(de)crement methods */
87  segment_iterator operator+(difference_type idx) const;
88  segment_iterator &operator+=(difference_type idx);
91  segment_iterator operator-(difference_type idx) const;
92  segment_iterator &operator-=(difference_type idx);
93  template <bool C>
94  difference_type
95  operator+(const segment_iterator<Container, C> &rhs) const;
96  template <bool C>
97  difference_type
98  operator-(const segment_iterator<Container, C> &rhs) const;
99 
105  template <bool C>
106  bool operator==(const segment_iterator<Container, C> &rhs) const;
107  template <bool C>
108  bool operator!=(const segment_iterator<Container, C> &rhs) const;
109  template <bool C>
110  bool operator<(const segment_iterator<Container, C> &rhs) const;
111  template <bool C>
112  bool operator>(const segment_iterator<Container, C> &rhs) const;
113  template <bool C>
114  bool operator<=(const segment_iterator<Container, C> &rhs) const;
115  template <bool C>
116  bool operator>=(const segment_iterator<Container, C> &rhs) const;
117 
118  /* Access methods */
119  reference operator*() const;
120  pointer operator->() const;
121 };
122 
126 template <typename Container, bool is_const>
128  : table(nullptr), index()
129 {
130 }
131 
136 template <typename Container, bool is_const>
138  size_type idx) noexcept
139  : table(tab), index(idx)
140 {
141 }
142 
147 template <typename Container, bool is_const>
149  const segment_iterator &other)
150  : table(other.table), index(other.index)
151 {
152 }
153 
155 template <typename Container, bool is_const>
156 template <typename U, typename>
159  : table(other.table), index(other.index)
160 {
161 }
162 
168 template <typename Container, bool is_const>
171 {
172  ++index;
173  return *this;
174 }
175 
181 template <typename Container, bool is_const>
184 {
185  auto iterator = *this;
186  ++*this;
187  return iterator;
188 }
189 
195 template <typename Container, bool is_const>
198 {
199  return segment_iterator(table, index + static_cast<size_type>(idx));
200 }
201 
207 template <typename Container, bool is_const>
210 {
211  index += static_cast<size_type>(idx);
212  return *this;
213 }
214 
220 template <typename Container, bool is_const>
223 {
224  --index;
225  return *this;
226 }
227 
233 template <typename Container, bool is_const>
236 {
237  auto iterator = *this;
238  --*this;
239  return iterator;
240 }
241 
247 template <typename Container, bool is_const>
250 {
251  return segment_iterator(table, index - static_cast<size_type>(idx));
252 }
253 
259 template <typename Container, bool is_const>
262 {
263  index -= static_cast<size_type>(idx);
264  return *this;
265 }
266 
272 template <typename Container, bool is_const>
273 template <bool C>
274 typename segment_iterator<Container, is_const>::difference_type
276  const segment_iterator<Container, C> &rhs) const
277 {
278  return static_cast<difference_type>(index + rhs.index);
279 }
280 
286 template <typename Container, bool is_const>
287 template <bool C>
288 typename segment_iterator<Container, is_const>::difference_type
290  const segment_iterator<Container, C> &rhs) const
291 {
292  return static_cast<difference_type>(index - rhs.index);
293 }
294 
302 template <typename Container, bool is_const>
303 template <bool C>
304 bool
306  const segment_iterator<Container, C> &rhs) const
307 {
308  return (table == rhs.table) && (index == rhs.index);
309 }
310 
319 template <typename Container, bool is_const>
320 template <bool C>
321 bool
323  const segment_iterator<Container, C> &rhs) const
324 {
325  return (table != rhs.table) || (index != rhs.index);
326 }
327 
338 template <typename Container, bool is_const>
339 template <bool C>
340 bool
342  const segment_iterator<Container, C> &rhs) const
343 {
344  if (table != rhs.table)
345  throw std::invalid_argument("segment_iterator::operator<");
346 
347  return index < rhs.index;
348 }
349 
361 template <typename Container, bool is_const>
362 template <bool C>
363 bool
365  const segment_iterator<Container, C> &rhs) const
366 {
367  if (table != rhs.table)
368  throw std::invalid_argument("segment_iterator::operator<");
369 
370  return index > rhs.index;
371 }
372 
384 template <typename Container, bool is_const>
385 template <bool C>
386 bool
388  const segment_iterator<Container, C> &rhs) const
389 {
390  if (table != rhs.table)
391  throw std::invalid_argument("segment_iterator::operator<");
392 
393  return index <= rhs.index;
394 }
395 
407 template <typename Container, bool is_const>
408 template <bool C>
409 bool
411  const segment_iterator<Container, C> &rhs) const
412 {
413  if (table != rhs.table)
414  throw std::invalid_argument("segment_iterator::operator<");
415 
416  return index >= rhs.index;
417 }
418 
422 template <typename Container, bool is_const>
423 typename segment_iterator<Container, is_const>::reference
425 {
426  return table->operator[](index);
427 }
428 
432 template <typename Container, bool is_const>
433 typename segment_iterator<Container, is_const>::pointer
435 {
436  return &operator*();
437 }
438 
439 } /* segment_vector_internal namespace */
440 
449 template <template <typename> class SegmentType = pmem::obj::vector>
451  segment_vector_internal::exponential_size_policy<
452  segment_vector_internal::array_64, SegmentType>;
453 
462 template <size_t SegmentSize = 1024,
463  template <typename> class SegmentType = pmem::obj::vector>
465  segment_vector_internal::fixed_size_policy<pmem::obj::vector,
466  SegmentType, SegmentSize>;
467 
476 template <template <typename> class SegmentType = pmem::obj::vector>
478  segment_vector_internal::exponential_size_policy<pmem::obj::vector,
479  SegmentType>;
480 
496 template <typename T, typename Policy = exponential_size_vector_policy<>>
498 public:
499  /* Specific traits*/
500  using policy_type = Policy;
501  using segment_type = typename policy_type::template segment_type<T>;
502  using segment_vector_type =
503  typename policy_type::template segment_vector_type<T>;
504  /* Simple access to methods */
505  using policy = policy_type;
506  using storage = policy_type;
507 
508  /* Traits */
509  using value_type = T;
510  using size_type = std::size_t;
511  using difference_type = std::ptrdiff_t;
512  using reference = value_type &;
513  using const_reference = const value_type &;
514  using pointer = value_type *;
515  using const_pointer = const value_type *;
516  using iterator =
518  false>;
519  using const_iterator =
521  using reverse_iterator = std::reverse_iterator<iterator>;
522  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
523 
524  /* Constructors */
525  segment_vector();
526  segment_vector(size_type count, const value_type &value);
527  explicit segment_vector(size_type count);
528  template <typename InputIt,
529  typename std::enable_if<
531  InputIt>::type * = nullptr>
532  segment_vector(InputIt first, InputIt last);
533  segment_vector(const segment_vector &other);
535  segment_vector(std::initializer_list<T> init);
536  segment_vector(const std::vector<T> &other);
537 
538  /* Assign operators */
539  segment_vector &operator=(const segment_vector &other);
541  segment_vector &operator=(std::initializer_list<T> ilist);
542  segment_vector &operator=(const std::vector<T> &other);
543 
544  /* Assign methods */
545  void assign(size_type count, const_reference value);
546  template <typename InputIt,
547  typename std::enable_if<
549  InputIt>::type * = nullptr>
550  void assign(InputIt first, InputIt last);
551  void assign(std::initializer_list<T> ilist);
552  void assign(const segment_vector &other);
553  void assign(segment_vector &&other);
554  void assign(const std::vector<T> &other);
555 
556  /* Destructor */
557  ~segment_vector();
558 
559  /* Element access */
560  reference at(size_type n);
561  const_reference at(size_type n) const;
562  const_reference const_at(size_type n) const;
563  reference operator[](size_type n);
564  const_reference operator[](size_type n) const;
565  reference front();
566  const_reference front() const;
567  const_reference cfront() const;
568  reference back();
569  const_reference back() const;
570  const_reference cback() const;
571 
572  /* Iterators */
573  iterator begin();
574  const_iterator begin() const noexcept;
575  const_iterator cbegin() const noexcept;
576  iterator end();
577  const_iterator end() const noexcept;
578  const_iterator cend() const noexcept;
579  reverse_iterator rbegin();
580  const_reverse_iterator rbegin() const noexcept;
581  const_reverse_iterator crbegin() const noexcept;
582  reverse_iterator rend();
583  const_reverse_iterator rend() const noexcept;
584  const_reverse_iterator crend() const noexcept;
585 
586  /* Range */
587  slice<iterator> range(size_type start, size_type n);
588  slice<const_iterator> range(size_type start, size_type n) const;
589  slice<const_iterator> crange(size_type start, size_type n) const;
590 
591  /* Capacity */
592  constexpr bool empty() const noexcept;
593  size_type size() const noexcept;
594  constexpr size_type max_size() const noexcept;
595  void reserve(size_type capacity_new);
596  size_type capacity() const noexcept;
597  void shrink_to_fit();
598 
599  /* Modifiers */
600  void clear();
601  void free_data();
602  iterator insert(const_iterator pos, const T &value);
603  iterator insert(const_iterator pos, T &&value);
604  iterator insert(const_iterator pos, size_type count, const T &value);
605  template <typename InputIt,
606  typename std::enable_if<
608  InputIt>::type * = nullptr>
609  iterator insert(const_iterator pos, InputIt first, InputIt last);
610  iterator insert(const_iterator pos, std::initializer_list<T> ilist);
611  template <class... Args>
612  iterator emplace(const_iterator pos, Args &&... args);
613  template <class... Args>
614  reference emplace_back(Args &&... args);
617  void push_back(const T &value);
618  void push_back(T &&value);
619  void pop_back();
620  void resize(size_type count);
621  void resize(size_type count, const value_type &value);
622  void swap(segment_vector &other);
623 
624 private:
625  /* Helper functions */
626  void internal_reserve(size_type new_capacity);
627  template <typename... Args>
628  void construct(size_type idx, size_type count, Args &&... args);
629  template <typename InputIt,
630  typename std::enable_if<
632  InputIt>::type * = nullptr>
633  void construct_range(size_type idx, InputIt first, InputIt last);
634  void insert_gap(size_type idx, size_type count);
635  void shrink(size_type size_new);
636  pool_base get_pool() const noexcept;
637  void snapshot_data(size_type idx_first, size_type idx_last);
638 
639  /* Data structure specific helper functions */
640  reference get(size_type n);
641  const_reference get(size_type n) const;
642  const_reference cget(size_type n) const;
643  bool segment_capacity_validation() const;
644 
645  /* Number of segments that are currently enabled */
646  p<size_type> _segments_used = 0;
647  /* Segments storage */
648  segment_vector_type _data;
649 };
650 
651 /* Non-member swap */
652 template <typename T, typename Policy>
654 
655 /*
656  * Comparison operators between
657  * pmem::obj::experimental::segment_vector<T, Policy> and
658  * pmem::obj::experimental::segment_vector<T, Policy>
659  */
660 template <typename T, typename Policy>
661 bool operator==(const segment_vector<T, Policy> &lhs,
662  const segment_vector<T, Policy> &rhs);
663 template <typename T, typename Policy>
664 bool operator!=(const segment_vector<T, Policy> &lhs,
665  const segment_vector<T, Policy> &rhs);
666 template <typename T, typename Policy>
667 bool operator<(const segment_vector<T, Policy> &lhs,
668  const segment_vector<T, Policy> &rhs);
669 template <typename T, typename Policy>
670 bool operator<=(const segment_vector<T, Policy> &lhs,
671  const segment_vector<T, Policy> &rhs);
672 template <typename T, typename Policy>
673 bool operator>(const segment_vector<T, Policy> &lhs,
674  const segment_vector<T, Policy> &rhs);
675 template <typename T, typename Policy>
676 bool operator>=(const segment_vector<T, Policy> &lhs,
677  const segment_vector<T, Policy> &rhs);
678 
679 /*
680  * Comparison operators between
681  * pmem::obj::experimental::segment_vector<T, Policy> and
682  * std::vector<T>
683  */
684 template <typename T, typename Policy>
685 bool operator==(const segment_vector<T, Policy> &lhs,
686  const std::vector<T> &rhs);
687 template <typename T, typename Policy>
688 bool operator!=(const segment_vector<T, Policy> &lhs,
689  const std::vector<T> &rhs);
690 template <typename T, typename Policy>
691 bool operator<(const segment_vector<T, Policy> &lhs, const std::vector<T> &rhs);
692 template <typename T, typename Policy>
693 bool operator<=(const segment_vector<T, Policy> &lhs,
694  const std::vector<T> &rhs);
695 template <typename T, typename Policy>
696 bool operator>(const segment_vector<T, Policy> &lhs, const std::vector<T> &rhs);
697 template <typename T, typename Policy>
698 bool operator>=(const segment_vector<T, Policy> &lhs,
699  const std::vector<T> &rhs);
700 
701 /*
702  * Comparison operators between std::vector<T> and
703  * pmem::obj::experimental::segment_vector<T, Policy>
704  */
705 template <typename T, typename Policy>
706 bool operator==(const std::vector<T> &lhs,
707  const segment_vector<T, Policy> &rhs);
708 template <typename T, typename Policy>
709 bool operator!=(const std::vector<T> &lhs,
710  const segment_vector<T, Policy> &rhs);
711 template <typename T, typename Policy>
712 bool operator<(const std::vector<T> &lhs, const segment_vector<T, Policy> &rhs);
713 template <typename T, typename Policy>
714 bool operator<=(const std::vector<T> &lhs,
715  const segment_vector<T, Policy> &rhs);
716 template <typename T, typename Policy>
717 bool operator>(const std::vector<T> &lhs, const segment_vector<T, Policy> &rhs);
718 template <typename T, typename Policy>
719 bool operator>=(const std::vector<T> &lhs,
720  const segment_vector<T, Policy> &rhs);
721 
730 template <typename T, typename Policy>
732 {
733 }
734 
757 template <typename T, typename Policy>
759  const value_type &value)
760 {
761  internal_reserve(count);
762  construct(0, count, value);
763 }
764 
786 template <typename T, typename Policy>
788 {
789  internal_reserve(count);
790  construct(0, count);
791 }
792 
819 template <typename T, typename Policy>
820 template <typename InputIt,
821  typename std::enable_if<detail::is_input_iterator<InputIt>::value,
822  InputIt>::type *>
823 segment_vector<T, Policy>::segment_vector(InputIt first, InputIt last)
824 {
825  internal_reserve(static_cast<size_type>(std::distance(first, last)));
826  construct_range(0, first, last);
827 }
828 
850 template <typename T, typename Policy>
852 {
853  internal_reserve(other.capacity());
854  construct_range(0, other.cbegin(), other.cend());
855 }
856 
877 template <typename T, typename Policy>
879 {
880  _data = std::move(other._data);
881  _segments_used = other._segments_used;
882  other._segments_used = 0;
883 }
884 
906 template <typename T, typename Policy>
907 segment_vector<T, Policy>::segment_vector(std::initializer_list<T> init)
908  : segment_vector(init.begin(), init.end())
909 {
910 }
911 
933 template <typename T, typename Policy>
934 segment_vector<T, Policy>::segment_vector(const std::vector<T> &other)
935  : segment_vector(other.cbegin(), other.cend())
936 {
937 }
938 
956 template <typename T, typename Policy>
959 {
960  assign(other);
961  return *this;
962 }
963 
979 template <typename T, typename Policy>
982 {
983  assign(std::move(other));
984  return *this;
985 }
986 
1004 template <typename T, typename Policy>
1006 segment_vector<T, Policy>::operator=(std::initializer_list<T> ilist)
1007 {
1008  assign(ilist.begin(), ilist.end());
1009  return *this;
1010 }
1011 
1029 template <typename T, typename Policy>
1031 segment_vector<T, Policy>::operator=(const std::vector<T> &other)
1032 {
1033  assign(other);
1034  return *this;
1035 }
1036 
1059 template <typename T, typename Policy>
1060 void
1061 segment_vector<T, Policy>::assign(size_type count, const_reference value)
1062 {
1063  if (count > max_size())
1064  throw std::length_error("Assignable range exceeds max size.");
1065 
1066  pool_base pb = get_pool();
1067  transaction::run(pb, [&] {
1068  if (count > capacity())
1069  internal_reserve(count);
1070  else if (count < size())
1071  shrink(count);
1072 
1077  if (count != 0) {
1078  size_type end = policy::get_segment(count - 1);
1079  for (size_type i = 0; i < end; ++i)
1080  _data[i].assign(policy::segment_size(i), value);
1081  _data[end].assign(count - policy::segment_top(end),
1082  value);
1083 
1084  _segments_used = end + 1;
1085  }
1086  });
1087  assert(segment_capacity_validation());
1088 }
1089 
1112 template <typename T, typename Policy>
1113 template <typename InputIt,
1114  typename std::enable_if<detail::is_input_iterator<InputIt>::value,
1115  InputIt>::type *>
1116 void
1117 segment_vector<T, Policy>::assign(InputIt first, InputIt last)
1118 {
1119  size_type count = static_cast<size_type>(std::distance(first, last));
1120  if (count > max_size())
1121  throw std::length_error("Assignable range exceeds max size.");
1122 
1123  pool_base pb = get_pool();
1124  transaction::run(pb, [&] {
1125  if (count > capacity())
1126  internal_reserve(count);
1127  else if (count < size())
1128  shrink(count);
1129 
1134  if (count != 0) {
1135  difference_type num;
1136  size_type end = policy::get_segment(count - 1);
1137  for (size_type i = 0; i < end; ++i) {
1138  size_type size = policy::segment_size(i);
1139  num = static_cast<difference_type>(size);
1140  _data[i].assign(first, std::next(first, num));
1141  std::advance(first, num);
1142  }
1143  num = static_cast<difference_type>(
1144  std::distance(first, last));
1145  _data[end].assign(first, std::next(first, num));
1146 
1147  _segments_used = end + 1;
1148  }
1149  });
1150  assert(segment_capacity_validation());
1151 }
1152 
1173 template <typename T, typename Policy>
1174 void
1175 segment_vector<T, Policy>::assign(std::initializer_list<T> ilist)
1176 {
1177  assign(ilist.begin(), ilist.end());
1178 }
1179 
1196 template <typename T, typename Policy>
1197 void
1199 {
1200  if (this != &other)
1201  assign(other.cbegin(), other.cend());
1202 }
1203 
1219 template <typename T, typename Policy>
1220 void
1222 {
1223  if (this == &other)
1224  return;
1225 
1226  pool_base pb = get_pool();
1227  transaction::run(pb, [&] {
1228  _data = std::move(other._data);
1229  _segments_used = other._segments_used;
1230  other._segments_used = 0;
1231  });
1232 }
1233 
1250 template <typename T, typename Policy>
1251 void
1252 segment_vector<T, Policy>::assign(const std::vector<T> &other)
1253 {
1254  assign(other.cbegin(), other.cend());
1255 }
1256 
1264 template <typename T, typename Policy>
1266 {
1267  try {
1268  free_data();
1269  } catch (...) {
1270  std::terminate();
1271  }
1272 }
1273 
1287 template <typename T, typename Policy>
1288 typename segment_vector<T, Policy>::reference
1290 {
1291  if (n >= size())
1292  throw std::out_of_range("segment_vector::at");
1293 
1294  detail::conditional_add_to_tx(&get(n), 1, POBJ_XADD_ASSUME_INITIALIZED);
1295 
1296  return get(n);
1297 }
1298 
1309 template <typename T, typename Policy>
1310 typename segment_vector<T, Policy>::const_reference
1312 {
1313  if (n >= size())
1314  throw std::out_of_range("segment_vector::at");
1315  return get(n);
1316 }
1317 
1330 template <typename T, typename Policy>
1331 typename segment_vector<T, Policy>::const_reference
1333 {
1334  if (n >= size())
1335  throw std::out_of_range("segment_vector::const_at");
1336  return get(n);
1337 }
1338 
1350 template <typename T, typename Policy>
1351 typename segment_vector<T, Policy>::reference
1353 {
1354  reference element = get(n);
1355 
1356  detail::conditional_add_to_tx(&element, 1,
1357  POBJ_XADD_ASSUME_INITIALIZED);
1358 
1359  return element;
1360 }
1361 
1369 template <typename T, typename Policy>
1370 typename segment_vector<T, Policy>::const_reference
1372 {
1373  return get(n);
1374 }
1375 
1384 template <typename T, typename Policy>
1385 typename segment_vector<T, Policy>::reference
1387 {
1388  detail::conditional_add_to_tx(&_data[0][0], 1,
1389  POBJ_XADD_ASSUME_INITIALIZED);
1390 
1391  return _data[0][0];
1392 }
1393 
1399 template <typename T, typename Policy>
1400 typename segment_vector<T, Policy>::const_reference
1402 {
1403  return _data[0][0];
1404 }
1405 
1413 template <typename T, typename Policy>
1414 typename segment_vector<T, Policy>::const_reference
1416 {
1417  return _data[0][0];
1418 }
1419 
1428 template <typename T, typename Policy>
1429 typename segment_vector<T, Policy>::reference
1431 {
1432  reference element = get(size() - 1);
1433 
1434  detail::conditional_add_to_tx(&element, 1,
1435  POBJ_XADD_ASSUME_INITIALIZED);
1436 
1437  return element;
1438 }
1439 
1445 template <typename T, typename Policy>
1446 typename segment_vector<T, Policy>::const_reference
1448 {
1449  return get(size() - 1);
1450 }
1451 
1459 template <typename T, typename Policy>
1460 typename segment_vector<T, Policy>::const_reference
1462 {
1463  return get(size() - 1);
1464 }
1465 
1471 template <typename T, typename Policy>
1474 {
1475  return iterator(this, 0);
1476 }
1477 
1484 template <typename T, typename Policy>
1487 {
1488  return const_iterator(this, 0);
1489 }
1490 
1499 template <typename T, typename Policy>
1502 {
1503  return const_iterator(this, 0);
1504 }
1505 
1512 template <typename T, typename Policy>
1515 {
1516  return iterator(this, size());
1517 }
1518 
1525 template <typename T, typename Policy>
1528 {
1529  return const_iterator(this, size());
1530 }
1531 
1540 template <typename T, typename Policy>
1543 {
1544  return const_iterator(this, size());
1545 }
1546 
1553 template <typename T, typename Policy>
1554 typename segment_vector<T, Policy>::reverse_iterator
1556 {
1557  return reverse_iterator(end());
1558 }
1559 
1566 template <typename T, typename Policy>
1567 typename segment_vector<T, Policy>::const_reverse_iterator
1569 {
1570  return const_reverse_iterator(end());
1571 }
1572 
1581 template <typename T, typename Policy>
1582 typename segment_vector<T, Policy>::const_reverse_iterator
1584 {
1585  return rbegin();
1586 }
1587 
1594 template <typename T, typename Policy>
1595 typename segment_vector<T, Policy>::reverse_iterator
1597 {
1598  return reverse_iterator(begin());
1599 }
1600 
1607 template <typename T, typename Policy>
1608 typename segment_vector<T, Policy>::const_reverse_iterator
1610 {
1611  return const_reverse_iterator(begin());
1612 }
1613 
1622 template <typename T, typename Policy>
1623 typename segment_vector<T, Policy>::const_reverse_iterator
1625 {
1626  return rend();
1627 }
1628 
1642 template <typename T, typename Policy>
1644 segment_vector<T, Policy>::range(size_type start, size_type n)
1645 {
1646  if (start + n > size())
1647  throw std::out_of_range("segment_vector::range");
1648 
1649  snapshot_data(start, start + n);
1650 
1651  return {iterator(this, start), iterator(this, start + n)};
1652 }
1653 
1665 template <typename T, typename Policy>
1667 segment_vector<T, Policy>::range(size_type start, size_type n) const
1668 {
1669  if (start + n > size())
1670  throw std::out_of_range("segment_vector::range");
1671 
1672  return {const_iterator(this, start), const_iterator(this, start + n)};
1673 }
1674 
1686 template <typename T, typename Policy>
1688 segment_vector<T, Policy>::crange(size_type start, size_type n) const
1689 {
1690  if (start + n > size())
1691  throw std::out_of_range("segment_vector::range");
1692 
1693  return {const_iterator(this, start), const_iterator(this, start + n)};
1694 }
1695 
1701 template <typename T, typename Policy>
1702 constexpr bool
1704 {
1705  return size() == 0;
1706 }
1707 
1711 template <typename T, typename Policy>
1712 typename segment_vector<T, Policy>::size_type
1714 {
1715  size_type result = 0;
1716 
1717  try {
1718  for (size_type i = 0; i < _segments_used; ++i)
1719  result += _data.const_at(i).size();
1720  } catch (std::out_of_range &) {
1721  /* Can only happen in case of a bug with segments_used calc */
1722  assert(false);
1723  }
1724 
1725  return result;
1726 }
1727 
1732 template <typename T, typename Policy>
1733 constexpr typename segment_vector<T, Policy>::size_type
1735 {
1736  return policy::max_size(_data);
1737 }
1738 
1755 template <typename T, typename Policy>
1756 void
1757 segment_vector<T, Policy>::reserve(size_type capacity_new)
1758 {
1759  if (capacity_new <= capacity())
1760  return;
1761 
1762  pool_base pb = get_pool();
1763  transaction::run(pb, [&] { internal_reserve(capacity_new); });
1764 }
1765 
1770 template <typename T, typename Policy>
1771 typename segment_vector<T, Policy>::size_type
1773 {
1774  if (_segments_used == 0)
1775  return 0;
1776  return policy::capacity(_segments_used - 1);
1777 }
1778 
1790 template <typename T, typename Policy>
1791 void
1793 {
1794  if (empty())
1795  return;
1796  size_type new_last = policy::get_segment(size() - 1);
1797  if (_segments_used - 1 == new_last)
1798  return;
1799 
1800  pool_base pb = get_pool();
1801  transaction::run(pb, [&] {
1802  for (size_type i = new_last + 1; i < _segments_used; ++i)
1803  _data[i].free_data();
1804  _segments_used = new_last + 1;
1805  storage::resize(_data, _segments_used);
1806  });
1807 }
1808 
1820 template <typename T, typename Policy>
1821 void
1823 {
1824  pool_base pb = get_pool();
1825  transaction::run(pb, [&] { shrink(0); });
1826  assert(segment_capacity_validation());
1827 }
1828 
1841 template <typename T, typename Policy>
1842 void
1844 {
1845  pool_base pb = get_pool();
1846  transaction::run(pb, [&] {
1847  for (size_type i = 0; i < _segments_used; ++i)
1848  _data[i].free_data();
1849  _segments_used = 0;
1850  });
1851 }
1852 
1876 template <typename T, typename Policy>
1879 {
1880  return insert(pos, 1, value);
1881 }
1882 
1906 template <typename T, typename Policy>
1909 {
1910  size_type idx = static_cast<size_type>(pos - cbegin());
1911 
1912  pool_base pb = get_pool();
1913  transaction::run(pb, [&] {
1914  insert_gap(idx, 1);
1915  get(idx) = std::move(value);
1916  });
1917 
1918  return iterator(this, idx);
1919 }
1920 
1947 template <typename T, typename Policy>
1950  const T &value)
1951 {
1952  size_type idx = static_cast<size_type>(pos - cbegin());
1953 
1954  pool_base pb = get_pool();
1955  transaction::run(pb, [&] {
1956  insert_gap(idx, count);
1957  for (size_type i = idx; i < idx + count; ++i)
1958  get(i) = std::move(value);
1959  });
1960 
1961  return iterator(this, idx);
1962 }
1963 
1997 template <typename T, typename Policy>
1998 template <typename InputIt,
1999  typename std::enable_if<detail::is_input_iterator<InputIt>::value,
2000  InputIt>::type *>
2003  InputIt last)
2004 {
2005  size_type idx = static_cast<size_type>(pos - cbegin());
2006  size_type gap_size = static_cast<size_type>(std::distance(first, last));
2007 
2008  pool_base pb = get_pool();
2009  transaction::run(pb, [&] {
2010  insert_gap(idx, gap_size);
2011  for (size_type i = idx; i < idx + gap_size; ++i, ++first)
2012  get(i) = *first;
2013  });
2014 
2015  return iterator(this, idx);
2016 }
2017 
2044 template <typename T, typename Policy>
2047  std::initializer_list<T> ilist)
2048 {
2049  return insert(pos, ilist.begin(), ilist.end());
2050 }
2051 
2080 template <typename T, typename Policy>
2081 template <class... Args>
2084 {
2085  size_type idx = static_cast<size_type>(pos - cbegin());
2086 
2087  pool_base pb = get_pool();
2088  transaction::run(pb, [&] {
2089  detail::temp_value<value_type,
2090  noexcept(T(std::forward<Args>(args)...))>
2091  tmp(std::forward<Args>(args)...);
2092  insert_gap(idx, 1);
2093  get(idx) = std::move(tmp.get());
2094  });
2095 
2096  return iterator(this, idx);
2097 }
2098 
2123 template <typename T, typename Policy>
2124 template <class... Args>
2125 typename segment_vector<T, Policy>::reference
2127 {
2128  assert(size() < max_size());
2129 
2130  pool_base pb = get_pool();
2131  transaction::run(pb, [&] {
2132  if (size() == capacity())
2133  internal_reserve(capacity() + 1);
2134 
2135  size_type segment = policy::get_segment(size());
2136  _data[segment].emplace_back(std::forward<Args>(args)...);
2137  });
2138 
2139  return back();
2140 }
2141 
2163 template <typename T, typename Policy>
2166 {
2167  return erase(pos, pos + 1);
2168 }
2169 
2194 template <typename T, typename Policy>
2197 {
2198  size_type count = static_cast<size_type>(std::distance(first, last));
2199  size_type idx = static_cast<size_type>(first - cbegin());
2200 
2201  if (count == 0)
2202  return iterator(this, idx);
2203 
2204  pool_base pb = get_pool();
2205  transaction::run(pb, [&] {
2206  size_type _size = size();
2207 
2208  if (!std::is_trivially_destructible<T>::value ||
2209  idx + count < _size)
2210  snapshot_data(idx, _size);
2211 
2212  /* Moving after-range elements to the place of deleted
2213  */
2214  iterator dest = iterator(this, idx);
2215  iterator begin = iterator(this, idx + count);
2216  iterator end = iterator(this, _size);
2217  std::move(begin, end, dest);
2218 
2219  /* Clearing the range where the elements were moved from
2220  */
2221  size_type middle = policy::get_segment(_size - count);
2222  size_type last = policy::get_segment(_size - 1);
2223  size_type middle_size = policy::index_in_segment(_size - count);
2224  for (size_type s = last; s > middle; --s)
2225  _data[s].clear();
2226  _data[middle].resize(middle_size);
2227 
2228  _segments_used = middle + 1;
2229  });
2230 
2231  assert(segment_capacity_validation());
2232 
2233  return iterator(this, idx);
2234 }
2235 
2254 template <typename T, typename Policy>
2255 void
2257 {
2258  emplace_back(value);
2259 }
2260 
2279 template <typename T, typename Policy>
2280 void
2282 {
2283  emplace_back(std::move(value));
2284 }
2285 
2299 template <typename T, typename Policy>
2300 void
2302 {
2303  if (empty())
2304  return;
2305 
2306  pool_base pb = get_pool();
2307  transaction::run(pb, [&] { shrink(size() - 1); });
2308  assert(segment_capacity_validation());
2309 }
2310 
2334 template <typename T, typename Policy>
2335 void
2337 {
2338  pool_base pb = get_pool();
2339  transaction::run(pb, [&] {
2340  size_type _size = size();
2341  if (count < _size)
2342  shrink(count);
2343  else {
2344  if (capacity() < count)
2345  internal_reserve(count);
2346  construct(_size, count - _size);
2347  }
2348  });
2349  assert(segment_capacity_validation());
2350 }
2351 
2376 template <typename T, typename Policy>
2377 void
2378 segment_vector<T, Policy>::resize(size_type count, const value_type &value)
2379 {
2380  pool_base pb = get_pool();
2381  transaction::run(pb, [&] {
2382  size_type _size = size();
2383  if (count < _size)
2384  shrink(count);
2385  else {
2386  if (capacity() < count)
2387  internal_reserve(count);
2388  construct(_size, count - _size, value);
2389  }
2390  });
2391  assert(segment_capacity_validation());
2392 }
2393 
2397 template <typename T, typename Policy>
2398 void
2400 {
2401  pool_base pb = get_pool();
2402  transaction::run(pb, [&] {
2403  _data.swap(other._data);
2404  std::swap(_segments_used, other._segments_used);
2405  });
2406 }
2407 
2423 template <typename T, typename Policy>
2424 void
2426 {
2427  assert(pmemobj_tx_stage() == TX_STAGE_WORK);
2428 
2429  if (new_capacity > max_size())
2430  throw std::length_error("New capacity exceeds max size.");
2431 
2432  if (new_capacity == 0)
2433  return;
2434 
2435  size_type old_idx = policy::get_segment(capacity());
2436  size_type new_idx = policy::get_segment(new_capacity - 1);
2437  storage::resize(_data, new_idx + 1);
2438  for (size_type i = old_idx; i <= new_idx; ++i) {
2439  size_type segment_capacity = policy::segment_size(i);
2440  _data[i].reserve(segment_capacity);
2441  }
2442  _segments_used = new_idx + 1;
2443 
2444  assert(segment_capacity_validation());
2445 }
2446 
2473 template <typename T, typename Policy>
2474 template <typename... Args>
2475 void
2476 segment_vector<T, Policy>::construct(size_type idx, size_type count,
2477  Args &&... args)
2478 {
2479  assert(pmemobj_tx_stage() == TX_STAGE_WORK);
2480  assert(capacity() >= size() + count);
2481 
2482  for (size_type i = idx; i < idx + count; ++i) {
2483  size_type segment = policy::get_segment(i);
2484  _data[segment].emplace_back(std::forward<Args>(args)...);
2485  }
2486 
2487  assert(segment_capacity_validation());
2488 }
2489 
2520 template <typename T, typename Policy>
2521 template <typename InputIt,
2522  typename std::enable_if<detail::is_input_iterator<InputIt>::value,
2523  InputIt>::type *>
2524 void
2525 segment_vector<T, Policy>::construct_range(size_type idx, InputIt first,
2526  InputIt last)
2527 {
2528  assert(pmemobj_tx_stage() == TX_STAGE_WORK);
2529  size_type count = static_cast<size_type>(std::distance(first, last));
2530  assert(capacity() >= size() + count);
2531 
2532  for (size_type i = idx; i < idx + count; ++i, ++first) {
2533  size_type segment = policy::get_segment(i);
2534  _data[segment].emplace_back(*first);
2535  }
2536 
2537  assert(segment_capacity_validation());
2538 }
2539 
2561 template <typename T, typename Policy>
2562 void
2563 segment_vector<T, Policy>::insert_gap(size_type idx, size_type count)
2564 {
2565  assert(pmemobj_tx_stage() == TX_STAGE_WORK);
2566  if (count == 0)
2567  return;
2568 
2569  size_type _size = size();
2570 
2571  if (capacity() < _size + count)
2572  internal_reserve(_size + count);
2573 
2574  iterator dest = iterator(this, _size + count);
2575  iterator begin = iterator(this, idx);
2576  iterator end = iterator(this, _size);
2577 
2578  snapshot_data(idx, _size);
2579 
2580  resize(_size + count);
2581  std::move_backward(begin, end, dest);
2582 
2583  assert(segment_capacity_validation());
2584 }
2585 
2605 template <typename T, typename Policy>
2606 void
2608 {
2609  assert(pmemobj_tx_stage() == TX_STAGE_WORK);
2610  assert(size_new <= size());
2611 
2612  if (empty())
2613  return;
2614 
2615  if (!std::is_trivially_destructible<T>::value)
2616  snapshot_data(size_new, size());
2617 
2618  size_type begin = policy::get_segment(size() - 1);
2619  size_type end = policy::get_segment(size_new);
2620  for (; begin > end; --begin) {
2621  _data[begin].clear();
2622  }
2623  size_type residue = policy::index_in_segment(size_new);
2624  _data[end].erase(_data[end].cbegin() + residue, _data[end].cend());
2625 
2626  assert(segment_capacity_validation());
2627 }
2628 
2636 template <typename T, typename Policy>
2637 pool_base
2639 {
2640  auto pop = pmemobj_pool_by_ptr(this);
2641  assert(pop != nullptr);
2642  return pool_base(pop);
2643 }
2644 
2654 template <typename T, typename Policy>
2655 void
2656 segment_vector<T, Policy>::snapshot_data(size_type first, size_type last)
2657 {
2658  if (first == last)
2659  return;
2660 
2661  size_type segment = policy::get_segment(first);
2662  size_type end = policy::get_segment(last - 1);
2663  size_type count = policy::segment_top(segment + 1) - first;
2664 
2665  while (segment != end) {
2666  detail::conditional_add_to_tx(&cget(first), count,
2667  POBJ_XADD_ASSUME_INITIALIZED);
2668  first = policy::segment_top(++segment);
2669  count = policy::segment_size(segment);
2670  }
2671  detail::conditional_add_to_tx(&cget(first), last - first,
2672  POBJ_XADD_ASSUME_INITIALIZED);
2673 }
2674 
2680 template <typename T, typename Policy>
2681 typename segment_vector<T, Policy>::reference
2683 {
2684  size_type s_idx = policy::get_segment(n);
2685  size_type local_idx = policy::index_in_segment(n);
2686 
2687  return _data[s_idx][local_idx];
2688 }
2689 
2695 template <typename T, typename Policy>
2696 typename segment_vector<T, Policy>::const_reference
2698 {
2699  size_type s_idx = policy::get_segment(n);
2700  size_type local_idx = policy::index_in_segment(n);
2701 
2702  return _data[s_idx][local_idx];
2703 }
2704 
2710 template <typename T, typename Policy>
2711 typename segment_vector<T, Policy>::const_reference
2713 {
2714  size_type s_idx = policy::get_segment(n);
2715  size_type local_idx = policy::index_in_segment(n);
2716 
2717  return _data[s_idx][local_idx];
2718 }
2719 
2727 template <typename T, typename Policy>
2728 bool
2730 {
2731  for (size_type i = 0; i < _segments_used; ++i)
2732  if (_data.const_at(i).capacity() != policy::segment_size(i))
2733  return false;
2734  return true;
2735 }
2736 
2743 template <typename T, typename Policy>
2744 void
2746 {
2747  lhs.swap(rhs);
2748 }
2749 
2764 template <typename T, typename Policy>
2765 bool
2767  const segment_vector<T, Policy> &rhs)
2768 {
2769  return lhs.size() == rhs.size() &&
2770  std::equal(lhs.begin(), lhs.end(), rhs.begin());
2771 }
2772 
2788 template <typename T, typename Policy>
2789 bool
2791  const segment_vector<T, Policy> &rhs)
2792 {
2793  return !(lhs == rhs);
2794 }
2795 
2808 template <typename T, typename Policy>
2809 bool
2811  const segment_vector<T, Policy> &rhs)
2812 {
2813  return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(),
2814  rhs.end());
2815 }
2816 
2829 template <typename T, typename Policy>
2830 bool
2832  const segment_vector<T, Policy> &rhs)
2833 {
2834  return !(rhs < lhs);
2835 }
2836 
2849 template <typename T, typename Policy>
2850 bool
2852  const segment_vector<T, Policy> &rhs)
2853 {
2854  return rhs < lhs;
2855 }
2856 
2869 template <typename T, typename Policy>
2870 bool
2872  const segment_vector<T, Policy> &rhs)
2873 {
2874  return !(lhs < rhs);
2875 }
2876 
2890 template <typename T, typename Policy>
2891 bool
2892 operator==(const segment_vector<T, Policy> &lhs, const std::vector<T> &rhs)
2893 {
2894  return lhs.size() == rhs.size() &&
2895  std::equal(lhs.begin(), lhs.end(), rhs.begin());
2896 }
2897 
2911 template <typename T, typename Policy>
2912 bool
2913 operator!=(const segment_vector<T, Policy> &lhs, const std::vector<T> &rhs)
2914 {
2915  return !(lhs == rhs);
2916 }
2917 
2929 template <typename T, typename Policy>
2930 bool
2931 operator<(const segment_vector<T, Policy> &lhs, const std::vector<T> &rhs)
2932 {
2933  return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(),
2934  rhs.end());
2935 }
2936 
2948 template <typename T, typename Policy>
2949 bool
2950 operator<=(const segment_vector<T, Policy> &lhs, const std::vector<T> &rhs)
2951 {
2952  return !(std::lexicographical_compare(rhs.begin(), rhs.end(),
2953  lhs.begin(), lhs.end()));
2954 }
2955 
2968 template <typename T, typename Policy>
2969 bool
2970 operator>(const segment_vector<T, Policy> &lhs, const std::vector<T> &rhs)
2971 {
2972  return !(lhs <= rhs);
2973 }
2974 
2986 template <typename T, typename Policy>
2987 bool
2988 operator>=(const segment_vector<T, Policy> &lhs, const std::vector<T> &rhs)
2989 {
2990  return !(lhs < rhs);
2991 }
2992 
3006 template <typename T, typename Policy>
3007 bool
3008 operator==(const std::vector<T> &lhs, const segment_vector<T, Policy> &rhs)
3009 {
3010  return rhs == lhs;
3011 }
3012 
3026 template <typename T, typename Policy>
3027 bool
3028 operator!=(const std::vector<T> &lhs, const segment_vector<T, Policy> &rhs)
3029 {
3030  return !(lhs == rhs);
3031 }
3032 
3044 template <typename T, typename Policy>
3045 bool
3046 operator<(const std::vector<T> &lhs, const segment_vector<T, Policy> &rhs)
3047 {
3048  return rhs > lhs;
3049 }
3050 
3062 template <typename T, typename Policy>
3063 bool
3064 operator<=(const std::vector<T> &lhs, const segment_vector<T, Policy> &rhs)
3065 {
3066  return !(rhs < lhs);
3067 }
3068 
3081 template <typename T, typename Policy>
3082 bool
3083 operator>(const std::vector<T> &lhs, const segment_vector<T, Policy> &rhs)
3084 {
3085  return rhs < lhs;
3086 }
3087 
3099 template <typename T, typename Policy>
3100 bool
3101 operator>=(const std::vector<T> &lhs, const segment_vector<T, Policy> &rhs)
3102 {
3103  return !(lhs < rhs);
3104 }
3105 
3106 } /* namespace obj */
3107 } /* namespace pmem */
3108 
3109 #endif /* LIBPMEMOBJ_SEGMENT_VECTOR_HPP */
pmem::obj::segment_vector::cfront
const_reference cfront() const
Access the first element.
Definition: segment_vector.hpp:1415
pmem::obj::segment_vector::at
reference at(size_type n)
Access element at specific index with bounds checking and add it to a transaction.
Definition: segment_vector.hpp:1289
pmem::obj::segment_vector::resize
void resize(size_type count)
Resizes the container to count elements transactionally.
Definition: segment_vector.hpp:2336
pmem::obj::segment_vector::swap
void swap(segment_vector &other)
Exchanges the contents of the container with other transactionally.
Definition: segment_vector.hpp:2399
pmem::obj::segment_vector_internal::segment_iterator::operator-
segment_iterator operator-(difference_type idx) const
Random access decrementing.
Definition: segment_vector.hpp:249
pmem::obj::segment_vector
Segment table is a data type with a vector-like interface The difference is that it does not do reall...
Definition: segment_vector.hpp:497
vector.hpp
Vector container with std::vector compatible interface.
pmem::obj::segment_vector_internal::segment_iterator::operator>
bool operator>(const segment_iterator< Container, C > &rhs) const
Greater operator.
Definition: segment_vector.hpp:364
pmem::obj::segment_vector::const_at
const_reference const_at(size_type n) const
Access element at specific index with bounds checking.
Definition: segment_vector.hpp:1332
pmem::obj::segment_vector::free_data
void free_data()
Clears the content of a segment_vector and frees all allocated persistent memory for data transaction...
Definition: segment_vector.hpp:1843
pmem::obj::segment_vector::clear
void clear()
Clears the content of a segment_vector transactionally.
Definition: segment_vector.hpp:1822
pmem::obj::rend
pmem::obj::array< T, N >::reverse_iterator rend(pmem::obj::array< T, N > &a)
Non-member rend.
Definition: array.hpp:864
pmem
Persistent memory namespace.
Definition: allocation_flag.hpp:15
pmem::obj::segment_vector::rbegin
reverse_iterator rbegin()
Returns a reverse iterator to the beginning.
Definition: segment_vector.hpp:1555
pmem::obj::begin
pmem::obj::array< T, N >::iterator begin(pmem::obj::array< T, N > &a)
Non-member begin.
Definition: array.hpp:804
pmem::obj::segment_vector_internal::segment_iterator::operator->
pointer operator->() const
Member access.
Definition: segment_vector.hpp:434
common.hpp
Commonly used functionality.
template_helpers.hpp
Commonly used SFINAE helpers.
pmem::obj::segment_vector::rend
reverse_iterator rend()
Returns a reverse iterator to the end.
Definition: segment_vector.hpp:1596
pmem::obj::segment_vector::operator=
segment_vector & operator=(const segment_vector &other)
Copy assignment operator.
Definition: segment_vector.hpp:958
pmem::obj::operator>
bool operator>(const array< T, N > &lhs, const array< T, N > &rhs)
Non-member greater than operator.
Definition: array.hpp:734
pmem::obj::segment_vector_internal::segment_iterator
Iterator for segment_vector Since a constant iterator differs only in the type of references and poin...
Definition: segment_vector.hpp:41
array.hpp
Array container with std::array compatible interface.
pmem::obj::segment_vector::begin
iterator begin()
Returns an iterator to the beginning.
Definition: segment_vector.hpp:1473
pmem::obj::segment_vector::end
iterator end()
Returns an iterator to past the end.
Definition: segment_vector.hpp:1514
pmem::obj::segment_vector::segment_vector
segment_vector()
Default constructor.
Definition: segment_vector.hpp:731
pmem::obj::operator>=
bool operator>=(const array< T, N > &lhs, const array< T, N > &rhs)
Non-member greater or equal operator.
Definition: array.hpp:744
pmem::obj::segment_vector::internal_reserve
void internal_reserve(size_type new_capacity)
Private helper method.
Definition: segment_vector.hpp:2425
pmem::obj::operator==
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:406
pmem::obj::segment_vector::operator[]
reference operator[](size_type n)
Access element at specific index and add it to a transaction.
Definition: segment_vector.hpp:1352
pmem::obj::p< size_type >
pmem::obj::segment_vector::segment_capacity_validation
bool segment_capacity_validation() const
Private helper function.
Definition: segment_vector.hpp:2729
pmem::obj::segment_vector::cbegin
const_iterator cbegin() const noexcept
Returns const iterator to the beginning.
Definition: segment_vector.hpp:1501
pmem::obj::segment_vector::cend
const_iterator cend() const noexcept
Returns a const iterator to the end.
Definition: segment_vector.hpp:1542
pmem::obj::segment_vector::crange
slice< const_iterator > crange(size_type start, size_type n) const
Returns const slice.
Definition: segment_vector.hpp:1688
make_persistent.hpp
Persistent_ptr transactional allocation functions for objects.
pmem::obj::segment_vector::get_pool
pool_base get_pool() const noexcept
Private helper function.
Definition: segment_vector.hpp:2638
pmem::obj::segment_vector_internal::segment_iterator::segment_iterator
segment_iterator() noexcept
Default constructor.
Definition: segment_vector.hpp:127
pmem::obj::transaction::run
static void run(pool_base &pool, std::function< void()> tx, Locks &... locks)
Execute a closure-like transaction and lock locks.
Definition: transaction.hpp:393
pmem::obj::segment_vector::crend
const_reverse_iterator crend() const noexcept
Returns a const reverse iterator to the beginning.
Definition: segment_vector.hpp:1624
pmem::obj::segment_vector::range
slice< iterator > range(size_type start, size_type n)
Returns slice and snapshots requested range.
Definition: segment_vector.hpp:1644
pmem::obj::swap
void swap(pmem::obj::array< T, N > &lhs, pmem::obj::array< T, N > &rhs)
Non-member swap function.
Definition: array.hpp:884
pmem::obj::segment_vector::size
size_type size() const noexcept
Definition: segment_vector.hpp:1713
pmem::obj::operator!=
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:522
pmem::obj::cend
pmem::obj::array< T, N >::const_iterator cend(const pmem::obj::array< T, N > &a)
Non-member cend.
Definition: array.hpp:774
pmem::obj::segment_vector::pop_back
void pop_back()
Removes the last element of the container transactionally.
Definition: segment_vector.hpp:2301
pmem::obj::vector
pmem::obj::vector - persistent container with std::vector compatible interface.
Definition: vector.hpp:40
pmem::obj::segment_vector_internal::segment_iterator::operator==
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:305
pmem::obj::segment_vector::emplace
iterator emplace(const_iterator pos, Args &&... args)
Inserts a new element into the container directly before pos.
Definition: segment_vector.hpp:2083
pmem::obj::segment_vector::push_back
void push_back(const T &value)
Appends the given element value to the end of the container transactionally.
Definition: segment_vector.hpp:2256
transaction.hpp
C++ pmemobj transactions.
pmem::obj::segment_vector_internal::segment_iterator::operator--
segment_iterator & operator--()
Prefix decrement.
Definition: segment_vector.hpp:222
pmem::obj::segment_vector::emplace_back
reference emplace_back(Args &&... args)
Appends a new element to the end of the container transactionally.
Definition: segment_vector.hpp:2126
pmem::obj::segment_vector::empty
constexpr bool empty() const noexcept
Checks whether the container is empty.
Definition: segment_vector.hpp:1703
pmem::detail::is_input_iterator
Type trait to determine if a given parameter type satisfies requirements of InputIterator.
Definition: iterator_traits.hpp:47
pmem::detail::temp_value
Template class for caching objects based on constructor's variadic template arguments and LIBPMEMOBJ_...
Definition: temp_value.hpp:35
pmem::obj::segment_vector::shrink
void shrink(size_type size_new)
Private helper function.
Definition: segment_vector.hpp:2607
pmem::obj::segment_vector::~segment_vector
~segment_vector()
Destructor.
Definition: segment_vector.hpp:1265
pmem::obj::segment_vector::shrink_to_fit
void shrink_to_fit()
Requests transactional removal of unused capacity.
Definition: segment_vector.hpp:1792
pmem::obj::segment_vector_internal::segment_iterator::operator<
bool operator<(const segment_iterator< Container, C > &rhs) const
Less operator.
Definition: segment_vector.hpp:341
temp_value.hpp
temp_value template class for caching objects.
pmem::obj::end
pmem::obj::array< T, N >::iterator end(pmem::obj::array< T, N > &a)
Non-member end.
Definition: array.hpp:824
pmem::obj::segment_vector::insert
iterator insert(const_iterator pos, const T &value)
Inserts value before pos in the container transactionally.
Definition: segment_vector.hpp:1878
pmem::obj::segment_vector::snapshot_data
void snapshot_data(size_type idx_first, size_type idx_last)
Private helper function.
Definition: segment_vector.hpp:2656
pmem::obj::operator<
bool operator<(const array< T, N > &lhs, const array< T, N > &rhs)
Non-member less than operator.
Definition: array.hpp:723
pmem::obj::segment_vector::back
reference back()
Access the last element and add this element to a transaction.
Definition: segment_vector.hpp:1430
pmem::obj::cbegin
pmem::obj::array< T, N >::const_iterator cbegin(const pmem::obj::array< T, N > &a)
Non-member cbegin.
Definition: array.hpp:764
pmem::obj::segment_vector::crbegin
const_reverse_iterator crbegin() const noexcept
Returns a const reverse iterator to the beginning.
Definition: segment_vector.hpp:1583
segment_vector_policies.hpp
A persistent version of segment vector implementation.
pmem::obj::segment_vector_internal::segment_iterator::operator>=
bool operator>=(const segment_iterator< Container, C > &rhs) const
Greater or equal operator.
Definition: segment_vector.hpp:410
pmem::obj::get
T & get(pmem::obj::array< T, N > &a)
Non-member get function.
Definition: array.hpp:894
pmem::obj::segment_vector_internal::segment_iterator::operator-=
segment_iterator & operator-=(difference_type idx)
Random access decrementing with assignment.
Definition: segment_vector.hpp:261
pmem::obj::slice
pmem::obj::slice - provides interface to access sequence of objects.
Definition: slice.hpp:27
pmem::obj::fixed_size_vector_policy
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:466
pmem::obj::operator<=
bool operator<=(const array< T, N > &lhs, const array< T, N > &rhs)
Non-member less or equal operator.
Definition: array.hpp:754
pmem::obj::array
pmem::obj::array - persistent container with std::array compatible interface.
Definition: array.hpp:45
pext.hpp
Convenience extensions for the resides on pmem property template.
pmem::obj::segment_vector_internal::segment_iterator::operator+
segment_iterator operator+(difference_type idx) const
Random access incrementing.
Definition: segment_vector.hpp:197
life.hpp
Functions for destroying arrays.
pmem::obj::segment_vector::get
reference get(size_type n)
Private helper function.
Definition: segment_vector.hpp:2682
pmem::obj::exponential_size_array_policy
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:452
pmem::obj::rbegin
pmem::obj::array< T, N >::reverse_iterator rbegin(pmem::obj::array< T, N > &a)
Non-member rbegin.
Definition: array.hpp:844
pmem::obj::segment_vector::cback
const_reference cback() const
Access the last element.
Definition: segment_vector.hpp:1461
pmem::obj::segment_vector_internal::segment_iterator::operator+=
segment_iterator & operator+=(difference_type idx)
Random access incrementing with assignment.
Definition: segment_vector.hpp:209
pmem::obj::segment_vector_internal::segment_iterator::operator<=
bool operator<=(const segment_iterator< Container, C > &rhs) const
Less or equal operator.
Definition: segment_vector.hpp:387
pmem::obj::exponential_size_vector_policy
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:479
pmem::obj::segment_vector::erase
iterator erase(const_iterator pos)
Removes the element at pos.
Definition: segment_vector.hpp:2165
pmem::obj::segment_vector::max_size
constexpr size_type max_size() const noexcept
Definition: segment_vector.hpp:1734
pmem::obj::segment_vector_internal::segment_iterator::operator*
reference operator*() const
Indirection (dereference).
Definition: segment_vector.hpp:424
pmem::obj::segment_vector::capacity
size_type capacity() const noexcept
Definition: segment_vector.hpp:1772
pmem::obj::segment_vector::front
reference front()
Access the first element and add this element to a transaction.
Definition: segment_vector.hpp:1386
pmem::obj::segment_vector::construct_range
void construct_range(size_type idx, InputIt first, InputIt last)
Private helper function.
Definition: segment_vector.hpp:2525
pmem::obj::segment_vector_internal::segment_iterator::operator++
segment_iterator & operator++()
Prefix increment.
Definition: segment_vector.hpp:170
pmem::obj::segment_vector::insert_gap
void insert_gap(size_type idx, size_type count)
Private helper function.
Definition: segment_vector.hpp:2563
pmem::obj::pool_base
The non-template pool base class.
Definition: pool.hpp:46
pmem::obj::segment_vector::reserve
void reserve(size_type capacity_new)
Increases the capacity of the segment_vector to capacity_new transactionally.
Definition: segment_vector.hpp:1757
pmem::obj::swap
void swap(segment_vector< T, Policy > &lhs, segment_vector< T, Policy > &rhs)
Swaps the contents of lhs and rhs.
Definition: segment_vector.hpp:2745
pmem::obj::segment_vector_internal::segment_iterator::operator!=
bool operator!=(const segment_iterator< Container, C > &rhs) const
Not equal operator.
Definition: segment_vector.hpp:322
pmem::obj::segment_vector::cget
const_reference cget(size_type n) const
Private helper function.
Definition: segment_vector.hpp:2712
pmem::obj::segment_vector::construct
void construct(size_type idx, size_type count, Args &&... args)
Private helper function.
Definition: segment_vector.hpp:2476
persistent_ptr.hpp
Persistent smart pointer.
pmem::obj::segment_vector::assign
void assign(size_type count, const_reference value)
Replaces the contents with count copies of value value transactionally.
Definition: segment_vector.hpp:1061