PMDK C++ bindings  1.11.1
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 
17 #include <libpmemobj++/detail/temp_value.hpp>
21 #include <libpmemobj++/pext.hpp>
23 #include <libpmemobj++/utils.hpp>
24 
25 #include <vector>
26 
27 namespace pmem
28 {
29 namespace obj
30 {
31 
35 namespace segment_vector_internal
36 {
45 template <typename Container, bool is_const>
47 public:
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 
71 private:
72  /* Pointer to container for iteration */
73  table_ptr table;
74  /* Index of element in the container */
75  size_type index;
76 
77 public:
78  /* –°onstructors */
79  segment_iterator() noexcept;
80  explicit segment_iterator(table_ptr tab, size_type idx) noexcept;
81  segment_iterator(const segment_iterator &other);
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
100  operator+(const segment_iterator<Container, C> &rhs) const;
101  template <bool C>
102  difference_type
103  operator-(const segment_iterator<Container, C> &rhs) const;
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 
131 template <typename Container, bool is_const>
133  : table(nullptr), index()
134 {
135 }
136 
141 template <typename Container, bool is_const>
143  size_type idx) noexcept
144  : table(tab), index(idx)
145 {
146 }
147 
152 template <typename Container, bool is_const>
154  const segment_iterator &other)
155  : table(other.table), index(other.index)
156 {
157 }
158 
160 template <typename Container, bool is_const>
161 template <typename U, typename>
164  : table(other.table), index(other.index)
165 {
166 }
167 
173 template <typename Container, bool is_const>
176 {
177  ++index;
178  return *this;
179 }
180 
186 template <typename Container, bool is_const>
189 {
190  auto iterator = *this;
191  ++*this;
192  return iterator;
193 }
194 
200 template <typename Container, bool is_const>
203 {
204  return segment_iterator(table, index + static_cast<size_type>(idx));
205 }
206 
212 template <typename Container, bool is_const>
215 {
216  index += static_cast<size_type>(idx);
217  return *this;
218 }
219 
225 template <typename Container, bool is_const>
228 {
229  --index;
230  return *this;
231 }
232 
238 template <typename Container, bool is_const>
241 {
242  auto iterator = *this;
243  --*this;
244  return iterator;
245 }
246 
252 template <typename Container, bool is_const>
255 {
256  return segment_iterator(table, index - static_cast<size_type>(idx));
257 }
258 
264 template <typename Container, bool is_const>
267 {
268  index -= static_cast<size_type>(idx);
269  return *this;
270 }
271 
277 template <typename Container, bool is_const>
278 template <bool C>
279 typename 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 
291 template <typename Container, bool is_const>
292 template <bool C>
293 typename 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 
307 template <typename Container, bool is_const>
308 template <bool C>
309 bool
311  const segment_iterator<Container, C> &rhs) const
312 {
313  return (table == rhs.table) && (index == rhs.index);
314 }
315 
324 template <typename Container, bool is_const>
325 template <bool C>
326 bool
328  const segment_iterator<Container, C> &rhs) const
329 {
330  return (table != rhs.table) || (index != rhs.index);
331 }
332 
343 template <typename Container, bool is_const>
344 template <bool C>
345 bool
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 
366 template <typename Container, bool is_const>
367 template <bool C>
368 bool
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 
389 template <typename Container, bool is_const>
390 template <bool C>
391 bool
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 
412 template <typename Container, bool is_const>
413 template <bool C>
414 bool
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 
427 template <typename Container, bool is_const>
428 typename segment_iterator<Container, is_const>::reference
430 {
431  return table->operator[](index);
432 }
433 
437 template <typename Container, bool is_const>
438 typename segment_iterator<Container, is_const>::pointer
440 {
441  return &operator*();
442 }
443 
444 } /* segment_vector_internal namespace */
445 
454 template <template <typename> class SegmentType = pmem::obj::vector>
456  segment_vector_internal::exponential_size_policy<
457  segment_vector_internal::array_64, SegmentType>;
458 
467 template <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 
481 template <template <typename> class SegmentType = pmem::obj::vector>
483  segment_vector_internal::exponential_size_policy<pmem::obj::vector,
484  SegmentType>;
485 
503 template <typename T, typename Policy = exponential_size_vector_policy<>>
505 public:
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 */
532  segment_vector();
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);
540  segment_vector(const segment_vector &other);
542  segment_vector(std::initializer_list<T> init);
543  segment_vector(const std::vector<T> &other);
544 
545  /* Assign operators */
546  segment_vector &operator=(const segment_vector &other);
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 */
564  ~segment_vector();
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 */
580  iterator begin();
581  const_iterator begin() const noexcept;
582  const_iterator cbegin() const noexcept;
583  iterator end();
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;
604  void shrink_to_fit();
605 
606  /* Modifiers */
607  void clear();
608  void free_data();
609  iterator insert(const_iterator pos, const T &value);
610  iterator insert(const_iterator pos, T &&value);
611  iterator insert(const_iterator pos, size_type count, const T &value);
612  template <typename InputIt,
613  typename std::enable_if<
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 
631 private:
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<
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);
643  pool_base get_pool() const;
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;
650  bool segment_capacity_validation() 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 */
659 template <typename T, typename Policy>
661 
662 /*
663  * Comparison operators between
664  * pmem::obj::experimental::segment_vector<T, Policy> and
665  * pmem::obj::experimental::segment_vector<T, Policy>
666  */
667 template <typename T, typename Policy>
668 bool operator==(const segment_vector<T, Policy> &lhs,
669  const segment_vector<T, Policy> &rhs);
670 template <typename T, typename Policy>
671 bool operator!=(const segment_vector<T, Policy> &lhs,
672  const segment_vector<T, Policy> &rhs);
673 template <typename T, typename Policy>
674 bool operator<(const segment_vector<T, Policy> &lhs,
675  const segment_vector<T, Policy> &rhs);
676 template <typename T, typename Policy>
677 bool operator<=(const segment_vector<T, Policy> &lhs,
678  const segment_vector<T, Policy> &rhs);
679 template <typename T, typename Policy>
680 bool operator>(const segment_vector<T, Policy> &lhs,
681  const segment_vector<T, Policy> &rhs);
682 template <typename T, typename Policy>
683 bool 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  */
691 template <typename T, typename Policy>
692 bool operator==(const segment_vector<T, Policy> &lhs,
693  const std::vector<T> &rhs);
694 template <typename T, typename Policy>
695 bool operator!=(const segment_vector<T, Policy> &lhs,
696  const std::vector<T> &rhs);
697 template <typename T, typename Policy>
698 bool operator<(const segment_vector<T, Policy> &lhs, const std::vector<T> &rhs);
699 template <typename T, typename Policy>
700 bool operator<=(const segment_vector<T, Policy> &lhs,
701  const std::vector<T> &rhs);
702 template <typename T, typename Policy>
703 bool operator>(const segment_vector<T, Policy> &lhs, const std::vector<T> &rhs);
704 template <typename T, typename Policy>
705 bool 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  */
712 template <typename T, typename Policy>
713 bool operator==(const std::vector<T> &lhs,
714  const segment_vector<T, Policy> &rhs);
715 template <typename T, typename Policy>
716 bool operator!=(const std::vector<T> &lhs,
717  const segment_vector<T, Policy> &rhs);
718 template <typename T, typename Policy>
719 bool operator<(const std::vector<T> &lhs, const segment_vector<T, Policy> &rhs);
720 template <typename T, typename Policy>
721 bool operator<=(const std::vector<T> &lhs,
722  const segment_vector<T, Policy> &rhs);
723 template <typename T, typename Policy>
724 bool operator>(const std::vector<T> &lhs, const segment_vector<T, Policy> &rhs);
725 template <typename T, typename Policy>
726 bool operator>=(const std::vector<T> &lhs,
727  const segment_vector<T, Policy> &rhs);
728 
737 template <typename T, typename Policy>
739 {
740 }
741 
764 template <typename T, typename Policy>
766  const value_type &value)
767 {
768  internal_reserve(count);
769  construct(0, count, value);
770 }
771 
793 template <typename T, typename Policy>
795 {
796  internal_reserve(count);
797  construct(0, count);
798 }
799 
826 template <typename T, typename Policy>
827 template <typename InputIt,
828  typename std::enable_if<detail::is_input_iterator<InputIt>::value,
829  InputIt>::type *>
830 segment_vector<T, Policy>::segment_vector(InputIt first, InputIt last)
831 {
832  internal_reserve(static_cast<size_type>(std::distance(first, last)));
833  construct_range(0, first, last);
834 }
835 
857 template <typename T, typename Policy>
859 {
860  internal_reserve(other.capacity());
861  construct_range(0, other.cbegin(), other.cend());
862 }
863 
884 template <typename T, typename Policy>
886 {
887  _data = std::move(other._data);
888  _segments_used = other._segments_used;
889  other._segments_used = 0;
890 }
891 
913 template <typename T, typename Policy>
914 segment_vector<T, Policy>::segment_vector(std::initializer_list<T> init)
915  : segment_vector(init.begin(), init.end())
916 {
917 }
918 
940 template <typename T, typename Policy>
941 segment_vector<T, Policy>::segment_vector(const std::vector<T> &other)
942  : segment_vector(other.cbegin(), other.cend())
943 {
944 }
945 
963 template <typename T, typename Policy>
966 {
967  assign(other);
968  return *this;
969 }
970 
986 template <typename T, typename Policy>
989 {
990  assign(std::move(other));
991  return *this;
992 }
993 
1011 template <typename T, typename Policy>
1013 segment_vector<T, Policy>::operator=(std::initializer_list<T> ilist)
1014 {
1015  assign(ilist.begin(), ilist.end());
1016  return *this;
1017 }
1018 
1036 template <typename T, typename Policy>
1038 segment_vector<T, Policy>::operator=(const std::vector<T> &other)
1039 {
1040  assign(other);
1041  return *this;
1042 }
1043 
1066 template <typename T, typename Policy>
1067 void
1068 segment_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  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 
1119 template <typename T, typename Policy>
1120 template <typename InputIt,
1121  typename std::enable_if<detail::is_input_iterator<InputIt>::value,
1122  InputIt>::type *>
1123 void
1124 segment_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  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 
1180 template <typename T, typename Policy>
1181 void
1182 segment_vector<T, Policy>::assign(std::initializer_list<T> ilist)
1183 {
1184  assign(ilist.begin(), ilist.end());
1185 }
1186 
1203 template <typename T, typename Policy>
1204 void
1206 {
1207  if (this != &other)
1208  assign(other.cbegin(), other.cend());
1209 }
1210 
1226 template <typename T, typename Policy>
1227 void
1229 {
1230  if (this == &other)
1231  return;
1232 
1233  pool_base pb = get_pool();
1234  transaction::run(pb, [&] {
1235  _data = std::move(other._data);
1236  _segments_used = other._segments_used;
1237  other._segments_used = 0;
1238  });
1239 }
1240 
1257 template <typename T, typename Policy>
1258 void
1259 segment_vector<T, Policy>::assign(const std::vector<T> &other)
1260 {
1261  assign(other.cbegin(), other.cend());
1262 }
1263 
1271 template <typename T, typename Policy>
1273 {
1274  try {
1275  free_data();
1276  } catch (...) {
1277  std::terminate();
1278  }
1279 }
1280 
1294 template <typename T, typename Policy>
1295 typename 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 
1316 template <typename T, typename Policy>
1317 typename 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 
1337 template <typename T, typename Policy>
1338 typename 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 
1357 template <typename T, typename Policy>
1358 typename 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 
1376 template <typename T, typename Policy>
1377 typename segment_vector<T, Policy>::const_reference
1379 {
1380  return get(n);
1381 }
1382 
1391 template <typename T, typename Policy>
1392 typename 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 
1406 template <typename T, typename Policy>
1407 typename segment_vector<T, Policy>::const_reference
1409 {
1410  return _data[0][0];
1411 }
1412 
1420 template <typename T, typename Policy>
1421 typename segment_vector<T, Policy>::const_reference
1423 {
1424  return _data[0][0];
1425 }
1426 
1435 template <typename T, typename Policy>
1436 typename 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 
1452 template <typename T, typename Policy>
1453 typename segment_vector<T, Policy>::const_reference
1455 {
1456  return get(size() - 1);
1457 }
1458 
1466 template <typename T, typename Policy>
1467 typename segment_vector<T, Policy>::const_reference
1469 {
1470  return get(size() - 1);
1471 }
1472 
1478 template <typename T, typename Policy>
1481 {
1482  return iterator(this, 0);
1483 }
1484 
1491 template <typename T, typename Policy>
1494 {
1495  return const_iterator(this, 0);
1496 }
1497 
1506 template <typename T, typename Policy>
1509 {
1510  return const_iterator(this, 0);
1511 }
1512 
1519 template <typename T, typename Policy>
1522 {
1523  return iterator(this, size());
1524 }
1525 
1532 template <typename T, typename Policy>
1535 {
1536  return const_iterator(this, size());
1537 }
1538 
1547 template <typename T, typename Policy>
1550 {
1551  return const_iterator(this, size());
1552 }
1553 
1560 template <typename T, typename Policy>
1561 typename segment_vector<T, Policy>::reverse_iterator
1563 {
1564  return reverse_iterator(end());
1565 }
1566 
1573 template <typename T, typename Policy>
1574 typename segment_vector<T, Policy>::const_reverse_iterator
1576 {
1577  return const_reverse_iterator(end());
1578 }
1579 
1588 template <typename T, typename Policy>
1589 typename segment_vector<T, Policy>::const_reverse_iterator
1591 {
1592  return rbegin();
1593 }
1594 
1601 template <typename T, typename Policy>
1602 typename segment_vector<T, Policy>::reverse_iterator
1604 {
1605  return reverse_iterator(begin());
1606 }
1607 
1614 template <typename T, typename Policy>
1615 typename segment_vector<T, Policy>::const_reverse_iterator
1617 {
1618  return const_reverse_iterator(begin());
1619 }
1620 
1629 template <typename T, typename Policy>
1630 typename segment_vector<T, Policy>::const_reverse_iterator
1632 {
1633  return rend();
1634 }
1635 
1649 template <typename T, typename Policy>
1651 segment_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 
1672 template <typename T, typename Policy>
1674 segment_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 
1693 template <typename T, typename Policy>
1695 segment_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 
1708 template <typename T, typename Policy>
1709 constexpr bool
1711 {
1712  return size() == 0;
1713 }
1714 
1718 template <typename T, typename Policy>
1719 typename 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 
1739 template <typename T, typename Policy>
1740 constexpr typename segment_vector<T, Policy>::size_type
1742 {
1743  return policy::max_size(_data);
1744 }
1745 
1762 template <typename T, typename Policy>
1763 void
1764 segment_vector<T, Policy>::reserve(size_type capacity_new)
1765 {
1766  if (capacity_new <= capacity())
1767  return;
1768 
1769  pool_base pb = get_pool();
1770  transaction::run(pb, [&] { internal_reserve(capacity_new); });
1771 }
1772 
1777 template <typename T, typename Policy>
1778 typename segment_vector<T, Policy>::size_type
1780 {
1781  if (_segments_used == 0)
1782  return 0;
1783  return policy::capacity(_segments_used - 1);
1784 }
1785 
1797 template <typename T, typename Policy>
1798 void
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  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 
1827 template <typename T, typename Policy>
1828 void
1830 {
1831  pool_base pb = get_pool();
1832  transaction::run(pb, [&] { shrink(0); });
1833  assert(segment_capacity_validation());
1834 }
1835 
1848 template <typename T, typename Policy>
1849 void
1851 {
1852  pool_base pb = get_pool();
1853  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 
1883 template <typename T, typename Policy>
1886 {
1887  return insert(pos, 1, value);
1888 }
1889 
1913 template <typename T, typename Policy>
1916 {
1917  size_type idx = static_cast<size_type>(pos - cbegin());
1918 
1919  pool_base pb = get_pool();
1920  transaction::run(pb, [&] {
1921  insert_gap(idx, 1);
1922  get(idx) = std::move(value);
1923  });
1924 
1925  return iterator(this, idx);
1926 }
1927 
1954 template <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  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 
2004 template <typename T, typename Policy>
2005 template <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  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 
2051 template <typename T, typename Policy>
2054  std::initializer_list<T> ilist)
2055 {
2056  return insert(pos, ilist.begin(), ilist.end());
2057 }
2058 
2087 template <typename T, typename Policy>
2088 template <class... Args>
2091 {
2092  size_type idx = static_cast<size_type>(pos - cbegin());
2093 
2094  pool_base pb = get_pool();
2095  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 
2130 template <typename T, typename Policy>
2131 template <class... Args>
2132 typename segment_vector<T, Policy>::reference
2134 {
2135  assert(size() < max_size());
2136 
2137  pool_base pb = get_pool();
2138  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 
2170 template <typename T, typename Policy>
2173 {
2174  return erase(pos, pos + 1);
2175 }
2176 
2201 template <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  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 
2261 template <typename T, typename Policy>
2262 void
2264 {
2265  emplace_back(value);
2266 }
2267 
2286 template <typename T, typename Policy>
2287 void
2289 {
2290  emplace_back(std::move(value));
2291 }
2292 
2306 template <typename T, typename Policy>
2307 void
2309 {
2310  if (empty())
2311  return;
2312 
2313  pool_base pb = get_pool();
2314  transaction::run(pb, [&] { shrink(size() - 1); });
2315  assert(segment_capacity_validation());
2316 }
2317 
2341 template <typename T, typename Policy>
2342 void
2344 {
2345  pool_base pb = get_pool();
2346  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 
2383 template <typename T, typename Policy>
2384 void
2385 segment_vector<T, Policy>::resize(size_type count, const value_type &value)
2386 {
2387  pool_base pb = get_pool();
2388  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 
2404 template <typename T, typename Policy>
2405 void
2407 {
2408  pool_base pb = get_pool();
2409  transaction::run(pb, [&] {
2410  _data.swap(other._data);
2411  std::swap(_segments_used, other._segments_used);
2412  });
2413 }
2414 
2430 template <typename T, typename Policy>
2431 void
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 
2480 template <typename T, typename Policy>
2481 template <typename... Args>
2482 void
2483 segment_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 
2527 template <typename T, typename Policy>
2528 template <typename InputIt,
2529  typename std::enable_if<detail::is_input_iterator<InputIt>::value,
2530  InputIt>::type *>
2531 void
2532 segment_vector<T, Policy>::construct_range(size_type idx, InputIt first,
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 
2568 template <typename T, typename Policy>
2569 void
2570 segment_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 
2612 template <typename T, typename Policy>
2613 void
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 
2643 template <typename T, typename Policy>
2644 pool_base
2646 {
2647  return pmem::obj::pool_by_vptr(this);
2648 }
2649 
2659 template <typename T, typename Policy>
2660 void
2661 segment_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 
2685 template <typename T, typename Policy>
2686 typename 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 
2700 template <typename T, typename Policy>
2701 typename 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 
2715 template <typename T, typename Policy>
2716 typename 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 
2732 template <typename T, typename Policy>
2733 bool
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 
2748 template <typename T, typename Policy>
2749 void
2751 {
2752  lhs.swap(rhs);
2753 }
2754 
2769 template <typename T, typename Policy>
2770 bool
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 
2793 template <typename T, typename Policy>
2794 bool
2796  const segment_vector<T, Policy> &rhs)
2797 {
2798  return !(lhs == rhs);
2799 }
2800 
2813 template <typename T, typename Policy>
2814 bool
2816  const segment_vector<T, Policy> &rhs)
2817 {
2818  return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(),
2819  rhs.end());
2820 }
2821 
2834 template <typename T, typename Policy>
2835 bool
2837  const segment_vector<T, Policy> &rhs)
2838 {
2839  return !(rhs < lhs);
2840 }
2841 
2854 template <typename T, typename Policy>
2855 bool
2857  const segment_vector<T, Policy> &rhs)
2858 {
2859  return rhs < lhs;
2860 }
2861 
2874 template <typename T, typename Policy>
2875 bool
2877  const segment_vector<T, Policy> &rhs)
2878 {
2879  return !(lhs < rhs);
2880 }
2881 
2895 template <typename T, typename Policy>
2896 bool
2897 operator==(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 
2916 template <typename T, typename Policy>
2917 bool
2918 operator!=(const segment_vector<T, Policy> &lhs, const std::vector<T> &rhs)
2919 {
2920  return !(lhs == rhs);
2921 }
2922 
2934 template <typename T, typename Policy>
2935 bool
2936 operator<(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 
2953 template <typename T, typename Policy>
2954 bool
2955 operator<=(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 
2973 template <typename T, typename Policy>
2974 bool
2975 operator>(const segment_vector<T, Policy> &lhs, const std::vector<T> &rhs)
2976 {
2977  return !(lhs <= rhs);
2978 }
2979 
2991 template <typename T, typename Policy>
2992 bool
2993 operator>=(const segment_vector<T, Policy> &lhs, const std::vector<T> &rhs)
2994 {
2995  return !(lhs < rhs);
2996 }
2997 
3011 template <typename T, typename Policy>
3012 bool
3013 operator==(const std::vector<T> &lhs, const segment_vector<T, Policy> &rhs)
3014 {
3015  return rhs == lhs;
3016 }
3017 
3031 template <typename T, typename Policy>
3032 bool
3033 operator!=(const std::vector<T> &lhs, const segment_vector<T, Policy> &rhs)
3034 {
3035  return !(lhs == rhs);
3036 }
3037 
3049 template <typename T, typename Policy>
3050 bool
3051 operator<(const std::vector<T> &lhs, const segment_vector<T, Policy> &rhs)
3052 {
3053  return rhs > lhs;
3054 }
3055 
3067 template <typename T, typename Policy>
3068 bool
3069 operator<=(const std::vector<T> &lhs, const segment_vector<T, Policy> &rhs)
3070 {
3071  return !(rhs < lhs);
3072 }
3073 
3086 template <typename T, typename Policy>
3087 bool
3088 operator>(const std::vector<T> &lhs, const segment_vector<T, Policy> &rhs)
3089 {
3090  return rhs < lhs;
3091 }
3092 
3104 template <typename T, typename Policy>
3105 bool
3106 operator>=(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 */
pmem::obj::segment_vector::cfront
const_reference cfront() const
Access the first element.
Definition: segment_vector.hpp:1422
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:1296
pmem::obj::segment_vector::resize
void resize(size_type count)
Resizes the container to count elements transactionally.
Definition: segment_vector.hpp:2343
pmem::obj::segment_vector::swap
void swap(segment_vector &other)
Exchanges the contents of the container with other transactionally.
Definition: segment_vector.hpp:2406
pmem::obj::segment_vector_internal::segment_iterator::operator-
segment_iterator operator-(difference_type idx) const
Random access decrementing.
Definition: segment_vector.hpp:254
pmem::obj::segment_vector
A persistent version of segment vector implementation.
Definition: segment_vector.hpp:504
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:369
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:1339
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:1850
pmem::obj::segment_vector::clear
void clear()
Clears the content of a segment_vector transactionally.
Definition: segment_vector.hpp:1829
utils.hpp
Libpmemobj C++ utils.
pmem::obj::rend
pmem::obj::array< T, N >::reverse_iterator rend(pmem::obj::array< T, N > &a)
Non-member rend.
Definition: array.hpp:860
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:1562
pmem::obj::begin
pmem::obj::array< T, N >::iterator begin(pmem::obj::array< T, N > &a)
Non-member begin.
Definition: array.hpp:800
pmem::obj::segment_vector_internal::segment_iterator::operator->
pointer operator->() const
Member access.
Definition: segment_vector.hpp:439
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:1603
pmem::obj::segment_vector::operator=
segment_vector & operator=(const segment_vector &other)
Copy assignment operator.
Definition: segment_vector.hpp:965
pmem::obj::operator>
bool operator>(const array< T, N > &lhs, const array< T, N > &rhs)
Non-member greater than operator.
Definition: array.hpp:730
pmem::obj::segment_vector_internal::segment_iterator
Iterator for segment_vector.
Definition: segment_vector.hpp:46
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:1480
pmem::obj::segment_vector::end
iterator end()
Returns an iterator to past the end.
Definition: segment_vector.hpp:1521
pmem::obj::segment_vector::segment_vector
segment_vector()
Default constructor.
Definition: segment_vector.hpp:738
pmem::obj::operator>=
bool operator>=(const array< T, N > &lhs, const array< T, N > &rhs)
Non-member greater or equal operator.
Definition: array.hpp:740
pmem::obj::segment_vector::internal_reserve
void internal_reserve(size_type new_capacity)
Private helper method.
Definition: segment_vector.hpp:2432
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:420
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:1359
pmem::obj::p< size_type >
pmem::obj::segment_vector::segment_capacity_validation
bool segment_capacity_validation() const
Private helper function.
Definition: segment_vector.hpp:2734
pmem::obj::segment_vector::cbegin
const_iterator cbegin() const noexcept
Returns const iterator to the beginning.
Definition: segment_vector.hpp:1508
pmem::obj::segment_vector::cend
const_iterator cend() const noexcept
Returns a const iterator to the end.
Definition: segment_vector.hpp:1549
pmem::obj::segment_vector::crange
slice< const_iterator > crange(size_type start, size_type n) const
Returns const slice.
Definition: segment_vector.hpp:1695
make_persistent.hpp
Persistent_ptr transactional allocation functions for objects.
pmem::obj::segment_vector_internal::segment_iterator::segment_iterator
segment_iterator() noexcept
Default constructor.
Definition: segment_vector.hpp:132
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:406
pmem::obj::segment_vector::crend
const_reverse_iterator crend() const noexcept
Returns a const reverse iterator to the beginning.
Definition: segment_vector.hpp:1631
pmem::obj::segment_vector::range
slice< iterator > range(size_type start, size_type n)
Returns slice and snapshots requested range.
Definition: segment_vector.hpp:1651
pmem::obj::swap
void swap(pmem::obj::array< T, N > &lhs, pmem::obj::array< T, N > &rhs)
Non-member swap function.
Definition: array.hpp:880
pmem::obj::segment_vector::size
size_type size() const noexcept
Definition: segment_vector.hpp:1720
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:536
pmem::obj::cend
pmem::obj::array< T, N >::const_iterator cend(const pmem::obj::array< T, N > &a)
Non-member cend.
Definition: array.hpp:770
pmem::obj::segment_vector::pop_back
void pop_back()
Removes the last element of the container transactionally.
Definition: segment_vector.hpp:2308
pmem::obj::vector
pmem::obj::vector - persistent container with std::vector compatible interface.
Definition: vector.hpp:41
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:310
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:2090
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:2263
transaction.hpp
C++ pmemobj transactions.
pmem::obj::segment_vector_internal::segment_iterator::operator--
segment_iterator & operator--()
Prefix decrement.
Definition: segment_vector.hpp:227
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:2133
pmem::obj::segment_vector::empty
constexpr bool empty() const noexcept
Checks whether the container is empty.
Definition: segment_vector.hpp:1710
pmem::detail::is_input_iterator
Type trait to determine if a given parameter type satisfies requirements of InputIterator.
Definition: iterator_traits.hpp:47
pmem::obj::segment_vector::shrink
void shrink(size_type size_new)
Private helper function.
Definition: segment_vector.hpp:2614
pmem::obj::segment_vector::~segment_vector
~segment_vector()
Destructor.
Definition: segment_vector.hpp:1272
pmem::obj::segment_vector::shrink_to_fit
void shrink_to_fit()
Requests transactional removal of unused capacity.
Definition: segment_vector.hpp:1799
pmem::obj::segment_vector_internal::segment_iterator::operator<
bool operator<(const segment_iterator< Container, C > &rhs) const
Less operator.
Definition: segment_vector.hpp:346
pmem::obj::end
pmem::obj::array< T, N >::iterator end(pmem::obj::array< T, N > &a)
Non-member end.
Definition: array.hpp:820
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:1885
pmem::obj::segment_vector::snapshot_data
void snapshot_data(size_type idx_first, size_type idx_last)
Private helper function.
Definition: segment_vector.hpp:2661
pmem::obj::operator<
bool operator<(const array< T, N > &lhs, const array< T, N > &rhs)
Non-member less than operator.
Definition: array.hpp:719
pmem::obj::segment_vector::back
reference back()
Access the last element and add this element to a transaction.
Definition: segment_vector.hpp:1437
pmem::obj::cbegin
pmem::obj::array< T, N >::const_iterator cbegin(const pmem::obj::array< T, N > &a)
Non-member cbegin.
Definition: array.hpp:760
pmem::obj::segment_vector::get_pool
pool_base get_pool() const
Private helper function.
Definition: segment_vector.hpp:2645
pmem::obj::segment_vector::crbegin
const_reverse_iterator crbegin() const noexcept
Returns a const reverse iterator to the beginning.
Definition: segment_vector.hpp:1590
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:415
pmem::obj::get
T & get(pmem::obj::array< T, N > &a)
Non-member get function.
Definition: array.hpp:890
pmem::obj::segment_vector_internal::segment_iterator::operator-=
segment_iterator & operator-=(difference_type idx)
Random access decrementing with assignment.
Definition: segment_vector.hpp:266
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:471
pmem::obj::operator<=
bool operator<=(const array< T, N > &lhs, const array< T, N > &rhs)
Non-member less or equal operator.
Definition: array.hpp:750
pmem::obj::array
pmem::obj::array - persistent container with std::array compatible interface.
Definition: array.hpp:46
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:202
life.hpp
Functions for destroying arrays.
pmem::obj::segment_vector::get
reference get(size_type n)
Private helper function.
Definition: segment_vector.hpp:2687
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:457
pmem::obj::rbegin
pmem::obj::array< T, N >::reverse_iterator rbegin(pmem::obj::array< T, N > &a)
Non-member rbegin.
Definition: array.hpp:840
pmem::obj::segment_vector::cback
const_reference cback() const
Access the last element.
Definition: segment_vector.hpp:1468
pmem::obj::segment_vector_internal::segment_iterator::operator+=
segment_iterator & operator+=(difference_type idx)
Random access incrementing with assignment.
Definition: segment_vector.hpp:214
pmem::obj::pool_by_vptr
pool_base pool_by_vptr(const T *that)
Retrieve pool handle for the given pointer.
Definition: utils.hpp:32
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:392
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:484
pmem::obj::segment_vector::erase
iterator erase(const_iterator pos)
Removes the element at pos.
Definition: segment_vector.hpp:2172
pmem::obj::segment_vector::max_size
constexpr size_type max_size() const noexcept
Definition: segment_vector.hpp:1741
pmem::obj::segment_vector_internal::segment_iterator::operator*
reference operator*() const
Indirection (dereference).
Definition: segment_vector.hpp:429
pmem::obj::segment_vector::capacity
size_type capacity() const noexcept
Definition: segment_vector.hpp:1779
pmem::obj::segment_vector::front
reference front()
Access the first element and add this element to a transaction.
Definition: segment_vector.hpp:1393
pmem::obj::segment_vector::construct_range
void construct_range(size_type idx, InputIt first, InputIt last)
Private helper function.
Definition: segment_vector.hpp:2532
pmem::obj::segment_vector_internal::segment_iterator::operator++
segment_iterator & operator++()
Prefix increment.
Definition: segment_vector.hpp:175
pmem::obj::segment_vector::insert_gap
void insert_gap(size_type idx, size_type count)
Private helper function.
Definition: segment_vector.hpp:2570
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:1764
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:2750
pmem::obj::segment_vector_internal::segment_iterator::operator!=
bool operator!=(const segment_iterator< Container, C > &rhs) const
Not equal operator.
Definition: segment_vector.hpp:327
pmem::obj::segment_vector::cget
const_reference cget(size_type n) const
Private helper function.
Definition: segment_vector.hpp:2717
pmem::obj::segment_vector::construct
void construct(size_type idx, size_type count, Args &&... args)
Private helper function.
Definition: segment_vector.hpp:2483
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:1068