PMDK C++ bindings  1.9
This is the C++ bindings documentation for PMDK's libpmemobj.
segment_vector.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2019-2020, Intel Corporation
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *
11  * * Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in
13  * the documentation and/or other materials provided with the
14  * distribution.
15  *
16  * * Neither the name of the copyright holder nor the names of its
17  * contributors may be used to endorse or promote products derived
18  * from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
38 #ifndef LIBPMEMOBJ_SEGMENT_VECTOR_HPP
39 #define LIBPMEMOBJ_SEGMENT_VECTOR_HPP
40 
50 #include <libpmemobj++/pext.hpp>
52 
53 #include <vector>
54 
55 namespace pmem
56 {
57 namespace obj
58 {
59 
60 namespace segment_vector_internal
61 {
69 template <typename Container, bool is_const>
71 public:
72  /* Traits */
73  using iterator_category = std::random_access_iterator_tag;
74  using difference_type = std::ptrdiff_t;
75  using table_type = Container;
76  using size_type = typename table_type::size_type;
77  using value_type = typename table_type::value_type;
78  /* Constant dependent traits */
79  using table_ptr =
80  typename std::conditional<is_const, const table_type *,
81  table_type *>::type;
82  using reference =
83  typename std::conditional<is_const,
84  typename table_type::const_reference,
85  typename table_type::reference>::type;
86  using pointer =
87  typename std::conditional<is_const,
88  typename table_type::const_pointer,
89  typename table_type::pointer>::type;
90 
91  /* To implement methods where operands differ in constancy */
92  friend class segment_iterator<Container, true>;
93  friend class segment_iterator<Container, false>;
94 
95 private:
96  /* Pointer to container for iteration */
97  table_ptr table;
98  /* Index of element in the container */
99  size_type index;
100 
101 public:
102  /* Сonstructors */
103  segment_iterator() noexcept;
104  explicit segment_iterator(table_ptr tab, size_type idx) noexcept;
105  segment_iterator(const segment_iterator &other);
106 
107  /* Copy ctor to enable conversion from non-const to const
108  * iterator */
109  template <typename U = void,
110  typename = typename std::enable_if<is_const, U>::type>
112 
113  /* In(de)crement methods */
116  segment_iterator operator+(difference_type idx) const;
117  segment_iterator &operator+=(difference_type idx);
120  segment_iterator operator-(difference_type idx) const;
121  segment_iterator &operator-=(difference_type idx);
122  template <bool C>
123  difference_type
124  operator+(const segment_iterator<Container, C> &rhs) const;
125  template <bool C>
126  difference_type
127  operator-(const segment_iterator<Container, C> &rhs) const;
128 
134  template <bool C>
135  bool operator==(const segment_iterator<Container, C> &rhs) const;
136  template <bool C>
137  bool operator!=(const segment_iterator<Container, C> &rhs) const;
138  template <bool C>
139  bool operator<(const segment_iterator<Container, C> &rhs) const;
140  template <bool C>
141  bool operator>(const segment_iterator<Container, C> &rhs) const;
142  template <bool C>
143  bool operator<=(const segment_iterator<Container, C> &rhs) const;
144  template <bool C>
145  bool operator>=(const segment_iterator<Container, C> &rhs) const;
146 
147  /* Access methods */
148  reference operator*() const;
149  pointer operator->() const;
150 };
151 
155 template <typename Container, bool is_const>
157  : table(nullptr), index()
158 {
159 }
160 
165 template <typename Container, bool is_const>
167  size_type idx) noexcept
168  : table(tab), index(idx)
169 {
170 }
171 
176 template <typename Container, bool is_const>
178  const segment_iterator &other)
179  : table(other.table), index(other.index)
180 {
181 }
182 
184 template <typename Container, bool is_const>
185 template <typename U, typename>
188  : table(other.table), index(other.index)
189 {
190 }
191 
197 template <typename Container, bool is_const>
200 {
201  ++index;
202  return *this;
203 }
204 
210 template <typename Container, bool is_const>
213 {
214  auto iterator = *this;
215  ++*this;
216  return iterator;
217 }
218 
224 template <typename Container, bool is_const>
227 {
228  return segment_iterator(table, index + static_cast<size_type>(idx));
229 }
230 
236 template <typename Container, bool is_const>
239 {
240  index += static_cast<size_type>(idx);
241  return *this;
242 }
243 
249 template <typename Container, bool is_const>
252 {
253  --index;
254  return *this;
255 }
256 
262 template <typename Container, bool is_const>
265 {
266  auto iterator = *this;
267  --*this;
268  return iterator;
269 }
270 
276 template <typename Container, bool is_const>
279 {
280  return segment_iterator(table, index - static_cast<size_type>(idx));
281 }
282 
288 template <typename Container, bool is_const>
291 {
292  index -= static_cast<size_type>(idx);
293  return *this;
294 }
295 
301 template <typename Container, bool is_const>
302 template <bool C>
303 typename segment_iterator<Container, is_const>::difference_type
305  const segment_iterator<Container, C> &rhs) const
306 {
307  return static_cast<difference_type>(index + rhs.index);
308 }
309 
315 template <typename Container, bool is_const>
316 template <bool C>
317 typename segment_iterator<Container, is_const>::difference_type
319  const segment_iterator<Container, C> &rhs) const
320 {
321  return static_cast<difference_type>(index - rhs.index);
322 }
323 
331 template <typename Container, bool is_const>
332 template <bool C>
333 bool
335  const segment_iterator<Container, C> &rhs) const
336 {
337  return (table == rhs.table) && (index == rhs.index);
338 }
339 
348 template <typename Container, bool is_const>
349 template <bool C>
350 bool
352  const segment_iterator<Container, C> &rhs) const
353 {
354  return (table != rhs.table) || (index != rhs.index);
355 }
356 
367 template <typename Container, bool is_const>
368 template <bool C>
369 bool
371  const segment_iterator<Container, C> &rhs) const
372 {
373  if (table != rhs.table)
374  throw std::invalid_argument("segment_iterator::operator<");
375 
376  return index < rhs.index;
377 }
378 
390 template <typename Container, bool is_const>
391 template <bool C>
392 bool
394  const segment_iterator<Container, C> &rhs) const
395 {
396  if (table != rhs.table)
397  throw std::invalid_argument("segment_iterator::operator<");
398 
399  return index > rhs.index;
400 }
401 
413 template <typename Container, bool is_const>
414 template <bool C>
415 bool
417  const segment_iterator<Container, C> &rhs) const
418 {
419  if (table != rhs.table)
420  throw std::invalid_argument("segment_iterator::operator<");
421 
422  return index <= rhs.index;
423 }
424 
436 template <typename Container, bool is_const>
437 template <bool C>
438 bool
440  const segment_iterator<Container, C> &rhs) const
441 {
442  if (table != rhs.table)
443  throw std::invalid_argument("segment_iterator::operator<");
444 
445  return index >= rhs.index;
446 }
447 
451 template <typename Container, bool is_const>
452 typename segment_iterator<Container, is_const>::reference
454 {
455  return table->operator[](index);
456 }
457 
461 template <typename Container, bool is_const>
462 typename segment_iterator<Container, is_const>::pointer
464 {
465  return &operator*();
466 }
467 
468 } /* segment_vector_internal namespace */
469 
478 template <template <typename> class SegmentType = pmem::obj::vector>
480  segment_vector_internal::exponential_size_policy<
481  segment_vector_internal::array_64, SegmentType>;
482 
491 template <size_t SegmentSize = 1024,
492  template <typename> class SegmentType = pmem::obj::vector>
494  segment_vector_internal::fixed_size_policy<pmem::obj::vector,
495  SegmentType, SegmentSize>;
496 
505 template <template <typename> class SegmentType = pmem::obj::vector>
507  segment_vector_internal::exponential_size_policy<pmem::obj::vector,
508  SegmentType>;
509 
525 template <typename T, typename Policy = exponential_size_vector_policy<>>
527 public:
528  /* Specific traits*/
529  using policy_type = Policy;
530  using segment_type = typename policy_type::template segment_type<T>;
531  using segment_vector_type =
532  typename policy_type::template segment_vector_type<T>;
533  /* Simple access to methods */
534  using policy = policy_type;
535  using storage = policy_type;
536 
537  /* Traits */
538  using value_type = T;
539  using size_type = std::size_t;
540  using difference_type = std::ptrdiff_t;
541  using reference = value_type &;
542  using const_reference = const value_type &;
543  using pointer = value_type *;
544  using const_pointer = const value_type *;
545  using iterator =
547  false>;
548  using const_iterator =
550  using reverse_iterator = std::reverse_iterator<iterator>;
551  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
552 
553  /* Constructors */
554  segment_vector();
555  segment_vector(size_type count, const value_type &value);
556  explicit segment_vector(size_type count);
557  template <typename InputIt,
558  typename std::enable_if<
560  InputIt>::type * = nullptr>
561  segment_vector(InputIt first, InputIt last);
562  segment_vector(const segment_vector &other);
564  segment_vector(std::initializer_list<T> init);
565  segment_vector(const std::vector<T> &other);
566 
567  /* Assign operators */
568  segment_vector &operator=(const segment_vector &other);
570  segment_vector &operator=(std::initializer_list<T> ilist);
571  segment_vector &operator=(const std::vector<T> &other);
572 
573  /* Assign methods */
574  void assign(size_type count, const_reference value);
575  template <typename InputIt,
576  typename std::enable_if<
578  InputIt>::type * = nullptr>
579  void assign(InputIt first, InputIt last);
580  void assign(std::initializer_list<T> ilist);
581  void assign(const segment_vector &other);
582  void assign(segment_vector &&other);
583  void assign(const std::vector<T> &other);
584 
585  /* Destructor */
586  ~segment_vector();
587 
588  /* Element access */
589  reference at(size_type n);
590  const_reference at(size_type n) const;
591  const_reference const_at(size_type n) const;
592  reference operator[](size_type n);
593  const_reference operator[](size_type n) const;
594  reference front();
595  const_reference front() const;
596  const_reference cfront() const;
597  reference back();
598  const_reference back() const;
599  const_reference cback() const;
600 
601  /* Iterators */
602  iterator begin();
603  const_iterator begin() const noexcept;
604  const_iterator cbegin() const noexcept;
605  iterator end();
606  const_iterator end() const noexcept;
607  const_iterator cend() const noexcept;
608  reverse_iterator rbegin();
609  const_reverse_iterator rbegin() const noexcept;
610  const_reverse_iterator crbegin() const noexcept;
611  reverse_iterator rend();
612  const_reverse_iterator rend() const noexcept;
613  const_reverse_iterator crend() const noexcept;
614 
615  /* Range */
616  slice<iterator> range(size_type start, size_type n);
617  slice<const_iterator> range(size_type start, size_type n) const;
618  slice<const_iterator> crange(size_type start, size_type n) const;
619 
620  /* Capacity */
621  constexpr bool empty() const noexcept;
622  size_type size() const noexcept;
623  constexpr size_type max_size() const noexcept;
624  void reserve(size_type capacity_new);
625  size_type capacity() const noexcept;
626  void shrink_to_fit();
627 
628  /* Modifiers */
629  void clear();
630  void free_data();
631  iterator insert(const_iterator pos, const T &value);
632  iterator insert(const_iterator pos, T &&value);
633  iterator insert(const_iterator pos, size_type count, const T &value);
634  template <typename InputIt,
635  typename std::enable_if<
637  InputIt>::type * = nullptr>
638  iterator insert(const_iterator pos, InputIt first, InputIt last);
639  iterator insert(const_iterator pos, std::initializer_list<T> ilist);
640  template <class... Args>
641  iterator emplace(const_iterator pos, Args &&... args);
642  template <class... Args>
643  reference emplace_back(Args &&... args);
646  void push_back(const T &value);
647  void push_back(T &&value);
648  void pop_back();
649  void resize(size_type count);
650  void resize(size_type count, const value_type &value);
651  void swap(segment_vector &other);
652 
653 private:
654  /* Helper functions */
655  void internal_reserve(size_type new_capacity);
656  template <typename... Args>
657  void construct(size_type idx, size_type count, Args &&... args);
658  template <typename InputIt,
659  typename std::enable_if<
661  InputIt>::type * = nullptr>
662  void construct_range(size_type idx, InputIt first, InputIt last);
663  void insert_gap(size_type idx, size_type count);
664  void shrink(size_type size_new);
665  pool_base get_pool() const noexcept;
666  void snapshot_data(size_type idx_first, size_type idx_last);
667 
668  /* Data structure specific helper functions */
669  reference get(size_type n);
670  const_reference get(size_type n) const;
671  const_reference cget(size_type n) const;
672  bool segment_capacity_validation() const;
673 
674  /* Number of segments that are currently enabled */
675  p<size_type> _segments_used = 0;
676  /* Segments storage */
677  segment_vector_type _data;
678 };
679 
680 /* Non-member swap */
681 template <typename T, typename Policy>
683 
684 /*
685  * Comparison operators between
686  * pmem::obj::experimental::segment_vector<T, Policy> and
687  * pmem::obj::experimental::segment_vector<T, Policy>
688  */
689 template <typename T, typename Policy>
690 bool operator==(const segment_vector<T, Policy> &lhs,
691  const segment_vector<T, Policy> &rhs);
692 template <typename T, typename Policy>
693 bool operator!=(const segment_vector<T, Policy> &lhs,
694  const segment_vector<T, Policy> &rhs);
695 template <typename T, typename Policy>
696 bool operator<(const segment_vector<T, Policy> &lhs,
697  const segment_vector<T, Policy> &rhs);
698 template <typename T, typename Policy>
699 bool operator<=(const segment_vector<T, Policy> &lhs,
700  const segment_vector<T, Policy> &rhs);
701 template <typename T, typename Policy>
702 bool operator>(const segment_vector<T, Policy> &lhs,
703  const segment_vector<T, Policy> &rhs);
704 template <typename T, typename Policy>
705 bool operator>=(const segment_vector<T, Policy> &lhs,
706  const segment_vector<T, Policy> &rhs);
707 
708 /*
709  * Comparison operators between
710  * pmem::obj::experimental::segment_vector<T, Policy> and
711  * std::vector<T>
712  */
713 template <typename T, typename Policy>
714 bool operator==(const segment_vector<T, Policy> &lhs,
715  const std::vector<T> &rhs);
716 template <typename T, typename Policy>
717 bool operator!=(const segment_vector<T, Policy> &lhs,
718  const std::vector<T> &rhs);
719 template <typename T, typename Policy>
720 bool operator<(const segment_vector<T, Policy> &lhs, const std::vector<T> &rhs);
721 template <typename T, typename Policy>
722 bool operator<=(const segment_vector<T, Policy> &lhs,
723  const std::vector<T> &rhs);
724 template <typename T, typename Policy>
725 bool operator>(const segment_vector<T, Policy> &lhs, const std::vector<T> &rhs);
726 template <typename T, typename Policy>
727 bool operator>=(const segment_vector<T, Policy> &lhs,
728  const std::vector<T> &rhs);
729 
730 /*
731  * Comparison operators between std::vector<T> and
732  * pmem::obj::experimental::segment_vector<T, Policy>
733  */
734 template <typename T, typename Policy>
735 bool operator==(const std::vector<T> &lhs,
736  const segment_vector<T, Policy> &rhs);
737 template <typename T, typename Policy>
738 bool operator!=(const std::vector<T> &lhs,
739  const segment_vector<T, Policy> &rhs);
740 template <typename T, typename Policy>
741 bool operator<(const std::vector<T> &lhs, const segment_vector<T, Policy> &rhs);
742 template <typename T, typename Policy>
743 bool operator<=(const std::vector<T> &lhs,
744  const segment_vector<T, Policy> &rhs);
745 template <typename T, typename Policy>
746 bool operator>(const std::vector<T> &lhs, const segment_vector<T, Policy> &rhs);
747 template <typename T, typename Policy>
748 bool operator>=(const std::vector<T> &lhs,
749  const segment_vector<T, Policy> &rhs);
750 
759 template <typename T, typename Policy>
761 {
762 }
763 
786 template <typename T, typename Policy>
788  const value_type &value)
789 {
790  internal_reserve(count);
791  construct(0, count, value);
792 }
793 
815 template <typename T, typename Policy>
817 {
818  internal_reserve(count);
819  construct(0, count);
820 }
821 
848 template <typename T, typename Policy>
849 template <typename InputIt,
850  typename std::enable_if<detail::is_input_iterator<InputIt>::value,
851  InputIt>::type *>
852 segment_vector<T, Policy>::segment_vector(InputIt first, InputIt last)
853 {
854  internal_reserve(static_cast<size_type>(std::distance(first, last)));
855  construct_range(0, first, last);
856 }
857 
879 template <typename T, typename Policy>
881 {
882  internal_reserve(other.capacity());
883  construct_range(0, other.cbegin(), other.cend());
884 }
885 
906 template <typename T, typename Policy>
908 {
909  _data = std::move(other._data);
910  _segments_used = other._segments_used;
911  other._segments_used = 0;
912 }
913 
935 template <typename T, typename Policy>
936 segment_vector<T, Policy>::segment_vector(std::initializer_list<T> init)
937  : segment_vector(init.begin(), init.end())
938 {
939 }
940 
962 template <typename T, typename Policy>
963 segment_vector<T, Policy>::segment_vector(const std::vector<T> &other)
964  : segment_vector(other.cbegin(), other.cend())
965 {
966 }
967 
985 template <typename T, typename Policy>
988 {
989  assign(other);
990  return *this;
991 }
992 
1008 template <typename T, typename Policy>
1011 {
1012  assign(std::move(other));
1013  return *this;
1014 }
1015 
1033 template <typename T, typename Policy>
1035 segment_vector<T, Policy>::operator=(std::initializer_list<T> ilist)
1036 {
1037  assign(ilist.begin(), ilist.end());
1038  return *this;
1039 }
1040 
1058 template <typename T, typename Policy>
1060 segment_vector<T, Policy>::operator=(const std::vector<T> &other)
1061 {
1062  assign(other);
1063  return *this;
1064 }
1065 
1088 template <typename T, typename Policy>
1089 void
1090 segment_vector<T, Policy>::assign(size_type count, const_reference value)
1091 {
1092  if (count > max_size())
1093  throw std::length_error("Assignable range exceeds max size.");
1094 
1095  pool_base pb = get_pool();
1096  transaction::run(pb, [&] {
1097  if (count > capacity())
1098  internal_reserve(count);
1099  else if (count < size())
1100  shrink(count);
1101 
1106  if (count != 0) {
1107  size_type end = policy::get_segment(count - 1);
1108  for (size_type i = 0; i < end; ++i)
1109  _data[i].assign(policy::segment_size(i), value);
1110  _data[end].assign(count - policy::segment_top(end),
1111  value);
1112 
1113  _segments_used = end + 1;
1114  }
1115  });
1116  assert(segment_capacity_validation());
1117 }
1118 
1141 template <typename T, typename Policy>
1142 template <typename InputIt,
1143  typename std::enable_if<detail::is_input_iterator<InputIt>::value,
1144  InputIt>::type *>
1145 void
1146 segment_vector<T, Policy>::assign(InputIt first, InputIt last)
1147 {
1148  size_type count = static_cast<size_type>(std::distance(first, last));
1149  if (count > max_size())
1150  throw std::length_error("Assignable range exceeds max size.");
1151 
1152  pool_base pb = get_pool();
1153  transaction::run(pb, [&] {
1154  if (count > capacity())
1155  internal_reserve(count);
1156  else if (count < size())
1157  shrink(count);
1158 
1163  if (count != 0) {
1164  difference_type num;
1165  size_type end = policy::get_segment(count - 1);
1166  for (size_type i = 0; i < end; ++i) {
1167  size_type size = policy::segment_size(i);
1168  num = static_cast<difference_type>(size);
1169  _data[i].assign(first, std::next(first, num));
1170  std::advance(first, num);
1171  }
1172  num = static_cast<difference_type>(
1173  std::distance(first, last));
1174  _data[end].assign(first, std::next(first, num));
1175 
1176  _segments_used = end + 1;
1177  }
1178  });
1179  assert(segment_capacity_validation());
1180 }
1181 
1202 template <typename T, typename Policy>
1203 void
1204 segment_vector<T, Policy>::assign(std::initializer_list<T> ilist)
1205 {
1206  assign(ilist.begin(), ilist.end());
1207 }
1208 
1225 template <typename T, typename Policy>
1226 void
1228 {
1229  if (this != &other)
1230  assign(other.cbegin(), other.cend());
1231 }
1232 
1248 template <typename T, typename Policy>
1249 void
1251 {
1252  if (this == &other)
1253  return;
1254 
1255  pool_base pb = get_pool();
1256  transaction::run(pb, [&] {
1257  _data = std::move(other._data);
1258  _segments_used = other._segments_used;
1259  other._segments_used = 0;
1260  });
1261 }
1262 
1279 template <typename T, typename Policy>
1280 void
1281 segment_vector<T, Policy>::assign(const std::vector<T> &other)
1282 {
1283  assign(other.cbegin(), other.cend());
1284 }
1285 
1297 template <typename T, typename Policy>
1299 {
1300  free_data();
1301 }
1302 
1316 template <typename T, typename Policy>
1317 typename segment_vector<T, Policy>::reference
1319 {
1320  if (n >= size())
1321  throw std::out_of_range("segment_vector::at");
1322 
1323  detail::conditional_add_to_tx(&get(n), 1, POBJ_XADD_ASSUME_INITIALIZED);
1324 
1325  return get(n);
1326 }
1327 
1338 template <typename T, typename Policy>
1339 typename segment_vector<T, Policy>::const_reference
1341 {
1342  if (n >= size())
1343  throw std::out_of_range("segment_vector::at");
1344  return get(n);
1345 }
1346 
1359 template <typename T, typename Policy>
1360 typename segment_vector<T, Policy>::const_reference
1362 {
1363  if (n >= size())
1364  throw std::out_of_range("segment_vector::const_at");
1365  return get(n);
1366 }
1367 
1379 template <typename T, typename Policy>
1380 typename segment_vector<T, Policy>::reference
1382 {
1383  reference element = get(n);
1384 
1385  detail::conditional_add_to_tx(&element, 1,
1386  POBJ_XADD_ASSUME_INITIALIZED);
1387 
1388  return element;
1389 }
1390 
1398 template <typename T, typename Policy>
1399 typename segment_vector<T, Policy>::const_reference
1401 {
1402  return get(n);
1403 }
1404 
1413 template <typename T, typename Policy>
1414 typename segment_vector<T, Policy>::reference
1416 {
1417  detail::conditional_add_to_tx(&_data[0][0], 1,
1418  POBJ_XADD_ASSUME_INITIALIZED);
1419 
1420  return _data[0][0];
1421 }
1422 
1428 template <typename T, typename Policy>
1429 typename segment_vector<T, Policy>::const_reference
1431 {
1432  return _data[0][0];
1433 }
1434 
1442 template <typename T, typename Policy>
1443 typename segment_vector<T, Policy>::const_reference
1445 {
1446  return _data[0][0];
1447 }
1448 
1457 template <typename T, typename Policy>
1458 typename segment_vector<T, Policy>::reference
1460 {
1461  reference element = get(size() - 1);
1462 
1463  detail::conditional_add_to_tx(&element, 1,
1464  POBJ_XADD_ASSUME_INITIALIZED);
1465 
1466  return element;
1467 }
1468 
1474 template <typename T, typename Policy>
1475 typename segment_vector<T, Policy>::const_reference
1477 {
1478  return get(size() - 1);
1479 }
1480 
1488 template <typename T, typename Policy>
1489 typename segment_vector<T, Policy>::const_reference
1491 {
1492  return get(size() - 1);
1493 }
1494 
1500 template <typename T, typename Policy>
1503 {
1504  return iterator(this, 0);
1505 }
1506 
1513 template <typename T, typename Policy>
1516 {
1517  return const_iterator(this, 0);
1518 }
1519 
1528 template <typename T, typename Policy>
1531 {
1532  return const_iterator(this, 0);
1533 }
1534 
1541 template <typename T, typename Policy>
1544 {
1545  return iterator(this, size());
1546 }
1547 
1554 template <typename T, typename Policy>
1557 {
1558  return const_iterator(this, size());
1559 }
1560 
1569 template <typename T, typename Policy>
1572 {
1573  return const_iterator(this, size());
1574 }
1575 
1582 template <typename T, typename Policy>
1583 typename segment_vector<T, Policy>::reverse_iterator
1585 {
1586  return reverse_iterator(end());
1587 }
1588 
1595 template <typename T, typename Policy>
1596 typename segment_vector<T, Policy>::const_reverse_iterator
1598 {
1599  return const_reverse_iterator(end());
1600 }
1601 
1610 template <typename T, typename Policy>
1611 typename segment_vector<T, Policy>::const_reverse_iterator
1613 {
1614  return rbegin();
1615 }
1616 
1623 template <typename T, typename Policy>
1624 typename segment_vector<T, Policy>::reverse_iterator
1626 {
1627  return reverse_iterator(begin());
1628 }
1629 
1636 template <typename T, typename Policy>
1637 typename segment_vector<T, Policy>::const_reverse_iterator
1639 {
1640  return const_reverse_iterator(begin());
1641 }
1642 
1651 template <typename T, typename Policy>
1652 typename segment_vector<T, Policy>::const_reverse_iterator
1654 {
1655  return rend();
1656 }
1657 
1671 template <typename T, typename Policy>
1673 segment_vector<T, Policy>::range(size_type start, size_type n)
1674 {
1675  if (start + n > size())
1676  throw std::out_of_range("segment_vector::range");
1677 
1678  snapshot_data(start, start + n);
1679 
1680  return {iterator(this, start), iterator(this, start + n)};
1681 }
1682 
1694 template <typename T, typename Policy>
1696 segment_vector<T, Policy>::range(size_type start, size_type n) const
1697 {
1698  if (start + n > size())
1699  throw std::out_of_range("segment_vector::range");
1700 
1701  return {const_iterator(this, start), const_iterator(this, start + n)};
1702 }
1703 
1715 template <typename T, typename Policy>
1717 segment_vector<T, Policy>::crange(size_type start, size_type n) const
1718 {
1719  if (start + n > size())
1720  throw std::out_of_range("segment_vector::range");
1721 
1722  return {const_iterator(this, start), const_iterator(this, start + n)};
1723 }
1724 
1730 template <typename T, typename Policy>
1731 constexpr bool
1733 {
1734  return size() == 0;
1735 }
1736 
1740 template <typename T, typename Policy>
1741 typename segment_vector<T, Policy>::size_type
1743 {
1744  size_type result = 0;
1745 
1746  try {
1747  for (size_type i = 0; i < _segments_used; ++i)
1748  result += _data.const_at(i).size();
1749  } catch (std::out_of_range &) {
1750  /* Can only happen in case of a bug with segments_used calc */
1751  assert(false);
1752  }
1753 
1754  return result;
1755 }
1756 
1761 template <typename T, typename Policy>
1762 constexpr typename segment_vector<T, Policy>::size_type
1764 {
1765  return policy::max_size(_data);
1766 }
1767 
1784 template <typename T, typename Policy>
1785 void
1786 segment_vector<T, Policy>::reserve(size_type capacity_new)
1787 {
1788  if (capacity_new <= capacity())
1789  return;
1790 
1791  pool_base pb = get_pool();
1792  transaction::run(pb, [&] { internal_reserve(capacity_new); });
1793 }
1794 
1799 template <typename T, typename Policy>
1800 typename segment_vector<T, Policy>::size_type
1802 {
1803  if (_segments_used == 0)
1804  return 0;
1805  return policy::capacity(_segments_used - 1);
1806 }
1807 
1819 template <typename T, typename Policy>
1820 void
1822 {
1823  if (empty())
1824  return;
1825  size_type new_last = policy::get_segment(size() - 1);
1826  if (_segments_used - 1 == new_last)
1827  return;
1828 
1829  pool_base pb = get_pool();
1830  transaction::run(pb, [&] {
1831  for (size_type i = new_last + 1; i < _segments_used; ++i)
1832  _data[i].free_data();
1833  _segments_used = new_last + 1;
1834  storage::resize(_data, _segments_used);
1835  });
1836 }
1837 
1849 template <typename T, typename Policy>
1850 void
1852 {
1853  pool_base pb = get_pool();
1854  transaction::run(pb, [&] { shrink(0); });
1855  assert(segment_capacity_validation());
1856 }
1857 
1870 template <typename T, typename Policy>
1871 void
1873 {
1874  pool_base pb = get_pool();
1875  transaction::run(pb, [&] {
1876  for (size_type i = 0; i < _segments_used; ++i)
1877  _data[i].free_data();
1878  _segments_used = 0;
1879  });
1880 }
1881 
1905 template <typename T, typename Policy>
1908 {
1909  return insert(pos, 1, value);
1910 }
1911 
1935 template <typename T, typename Policy>
1938 {
1939  size_type idx = static_cast<size_type>(pos - cbegin());
1940 
1941  pool_base pb = get_pool();
1942  transaction::run(pb, [&] {
1943  insert_gap(idx, 1);
1944  get(idx) = std::move(value);
1945  });
1946 
1947  return iterator(this, idx);
1948 }
1949 
1976 template <typename T, typename Policy>
1979  const T &value)
1980 {
1981  size_type idx = static_cast<size_type>(pos - cbegin());
1982 
1983  pool_base pb = get_pool();
1984  transaction::run(pb, [&] {
1985  insert_gap(idx, count);
1986  for (size_type i = idx; i < idx + count; ++i)
1987  get(i) = std::move(value);
1988  });
1989 
1990  return iterator(this, idx);
1991 }
1992 
2026 template <typename T, typename Policy>
2027 template <typename InputIt,
2028  typename std::enable_if<detail::is_input_iterator<InputIt>::value,
2029  InputIt>::type *>
2032  InputIt last)
2033 {
2034  size_type idx = static_cast<size_type>(pos - cbegin());
2035  size_type gap_size = static_cast<size_type>(std::distance(first, last));
2036 
2037  pool_base pb = get_pool();
2038  transaction::run(pb, [&] {
2039  insert_gap(idx, gap_size);
2040  for (size_type i = idx; i < idx + gap_size; ++i, ++first)
2041  get(i) = *first;
2042  });
2043 
2044  return iterator(this, idx);
2045 }
2046 
2073 template <typename T, typename Policy>
2076  std::initializer_list<T> ilist)
2077 {
2078  return insert(pos, ilist.begin(), ilist.end());
2079 }
2080 
2109 template <typename T, typename Policy>
2110 template <class... Args>
2113 {
2114  size_type idx = static_cast<size_type>(pos - cbegin());
2115 
2116  pool_base pb = get_pool();
2117  transaction::run(pb, [&] {
2118  detail::temp_value<value_type,
2119  noexcept(T(std::forward<Args>(args)...))>
2120  tmp(std::forward<Args>(args)...);
2121  insert_gap(idx, 1);
2122  get(idx) = std::move(tmp.get());
2123  });
2124 
2125  return iterator(this, idx);
2126 }
2127 
2152 template <typename T, typename Policy>
2153 template <class... Args>
2154 typename segment_vector<T, Policy>::reference
2156 {
2157  assert(size() < max_size());
2158 
2159  pool_base pb = get_pool();
2160  transaction::run(pb, [&] {
2161  if (size() == capacity())
2162  internal_reserve(capacity() + 1);
2163 
2164  size_type segment = policy::get_segment(size());
2165  _data[segment].emplace_back(std::forward<Args>(args)...);
2166  });
2167 
2168  return back();
2169 }
2170 
2192 template <typename T, typename Policy>
2195 {
2196  return erase(pos, pos + 1);
2197 }
2198 
2223 template <typename T, typename Policy>
2226 {
2227  size_type count = static_cast<size_type>(std::distance(first, last));
2228  size_type idx = static_cast<size_type>(first - cbegin());
2229 
2230  if (count == 0)
2231  return iterator(this, idx);
2232 
2233  pool_base pb = get_pool();
2234  transaction::run(pb, [&] {
2235  size_type _size = size();
2236 
2237  snapshot_data(idx, _size);
2238 
2239  /* Moving after-range elements to the place of deleted
2240  */
2241  iterator dest = iterator(this, idx);
2242  iterator begin = iterator(this, idx + count);
2243  iterator end = iterator(this, _size);
2244  std::move(begin, end, dest);
2245 
2246  /* Clearing the range where the elements were moved from
2247  */
2248  size_type middle = policy::get_segment(_size - count);
2249  size_type last = policy::get_segment(_size - 1);
2250  size_type middle_size = policy::index_in_segment(_size - count);
2251  for (size_type s = last; s > middle; --s)
2252  _data[s].clear();
2253  _data[middle].resize(middle_size);
2254 
2255  _segments_used = middle + 1;
2256  });
2257 
2258  assert(segment_capacity_validation());
2259 
2260  return iterator(this, idx);
2261 }
2262 
2281 template <typename T, typename Policy>
2282 void
2284 {
2285  emplace_back(value);
2286 }
2287 
2306 template <typename T, typename Policy>
2307 void
2309 {
2310  emplace_back(std::move(value));
2311 }
2312 
2326 template <typename T, typename Policy>
2327 void
2329 {
2330  if (empty())
2331  return;
2332 
2333  pool_base pb = get_pool();
2334  transaction::run(pb, [&] { shrink(size() - 1); });
2335  assert(segment_capacity_validation());
2336 }
2337 
2361 template <typename T, typename Policy>
2362 void
2364 {
2365  pool_base pb = get_pool();
2366  transaction::run(pb, [&] {
2367  size_type _size = size();
2368  if (count < _size)
2369  shrink(count);
2370  else {
2371  if (capacity() < count)
2372  internal_reserve(count);
2373  construct(_size, count - _size);
2374  }
2375  });
2376  assert(segment_capacity_validation());
2377 }
2378 
2403 template <typename T, typename Policy>
2404 void
2405 segment_vector<T, Policy>::resize(size_type count, const value_type &value)
2406 {
2407  pool_base pb = get_pool();
2408  transaction::run(pb, [&] {
2409  size_type _size = size();
2410  if (count < _size)
2411  shrink(count);
2412  else {
2413  if (capacity() < count)
2414  internal_reserve(count);
2415  construct(_size, count - _size, value);
2416  }
2417  });
2418  assert(segment_capacity_validation());
2419 }
2420 
2424 template <typename T, typename Policy>
2425 void
2427 {
2428  pool_base pb = get_pool();
2429  transaction::run(pb, [&] {
2430  _data.swap(other._data);
2431  std::swap(_segments_used, other._segments_used);
2432  });
2433 }
2434 
2450 template <typename T, typename Policy>
2451 void
2453 {
2454  assert(pmemobj_tx_stage() == TX_STAGE_WORK);
2455 
2456  if (new_capacity > max_size())
2457  throw std::length_error("New capacity exceeds max size.");
2458 
2459  if (new_capacity == 0)
2460  return;
2461 
2462  size_type old_idx = policy::get_segment(capacity());
2463  size_type new_idx = policy::get_segment(new_capacity - 1);
2464  storage::resize(_data, new_idx + 1);
2465  for (size_type i = old_idx; i <= new_idx; ++i) {
2466  size_type segment_capacity = policy::segment_size(i);
2467  _data[i].reserve(segment_capacity);
2468  }
2469  _segments_used = new_idx + 1;
2470 
2471  assert(segment_capacity_validation());
2472 }
2473 
2500 template <typename T, typename Policy>
2501 template <typename... Args>
2502 void
2503 segment_vector<T, Policy>::construct(size_type idx, size_type count,
2504  Args &&... args)
2505 {
2506  assert(pmemobj_tx_stage() == TX_STAGE_WORK);
2507  assert(capacity() >= size() + count);
2508 
2509  for (size_type i = idx; i < idx + count; ++i) {
2510  size_type segment = policy::get_segment(i);
2511  _data[segment].emplace_back(std::forward<Args>(args)...);
2512  }
2513 
2514  assert(segment_capacity_validation());
2515 }
2516 
2547 template <typename T, typename Policy>
2548 template <typename InputIt,
2549  typename std::enable_if<detail::is_input_iterator<InputIt>::value,
2550  InputIt>::type *>
2551 void
2552 segment_vector<T, Policy>::construct_range(size_type idx, InputIt first,
2553  InputIt last)
2554 {
2555  assert(pmemobj_tx_stage() == TX_STAGE_WORK);
2556  size_type count = static_cast<size_type>(std::distance(first, last));
2557  assert(capacity() >= size() + count);
2558 
2559  for (size_type i = idx; i < idx + count; ++i, ++first) {
2560  size_type segment = policy::get_segment(i);
2561  _data[segment].emplace_back(*first);
2562  }
2563 
2564  assert(segment_capacity_validation());
2565 }
2566 
2588 template <typename T, typename Policy>
2589 void
2590 segment_vector<T, Policy>::insert_gap(size_type idx, size_type count)
2591 {
2592  assert(pmemobj_tx_stage() == TX_STAGE_WORK);
2593  if (count == 0)
2594  return;
2595 
2596  size_type _size = size();
2597 
2598  if (capacity() < _size + count)
2599  internal_reserve(_size + count);
2600 
2601  iterator dest = iterator(this, _size + count);
2602  iterator begin = iterator(this, idx);
2603  iterator end = iterator(this, _size);
2604 
2605  snapshot_data(idx, _size);
2606 
2607  resize(_size + count);
2608  std::move_backward(begin, end, dest);
2609 
2610  assert(segment_capacity_validation());
2611 }
2612 
2632 template <typename T, typename Policy>
2633 void
2635 {
2636  assert(pmemobj_tx_stage() == TX_STAGE_WORK);
2637  assert(size_new <= size());
2638 
2639  if (empty())
2640  return;
2641 
2642  snapshot_data(size_new, size());
2643 
2644  size_type begin = policy::get_segment(size() - 1);
2645  size_type end = policy::get_segment(size_new);
2646  for (; begin > end; --begin) {
2647  _data[begin].clear();
2648  }
2649  size_type residue = policy::index_in_segment(size_new);
2650  _data[end].erase(_data[end].cbegin() + residue, _data[end].cend());
2651 
2652  assert(segment_capacity_validation());
2653 }
2654 
2662 template <typename T, typename Policy>
2663 pool_base
2665 {
2666  auto pop = pmemobj_pool_by_ptr(this);
2667  assert(pop != nullptr);
2668  return pool_base(pop);
2669 }
2670 
2680 template <typename T, typename Policy>
2681 void
2682 segment_vector<T, Policy>::snapshot_data(size_type first, size_type last)
2683 {
2684  if (first == last)
2685  return;
2686 
2687  size_type segment = policy::get_segment(first);
2688  size_type end = policy::get_segment(last - 1);
2689  size_type count = policy::segment_top(segment + 1) - first;
2690 
2691  while (segment != end) {
2692  detail::conditional_add_to_tx(&cget(first), count,
2693  POBJ_XADD_ASSUME_INITIALIZED);
2694  first = policy::segment_top(++segment);
2695  count = policy::segment_size(segment);
2696  }
2697  detail::conditional_add_to_tx(&cget(first), last - first,
2698  POBJ_XADD_ASSUME_INITIALIZED);
2699 }
2700 
2706 template <typename T, typename Policy>
2707 typename segment_vector<T, Policy>::reference
2709 {
2710  size_type s_idx = policy::get_segment(n);
2711  size_type local_idx = policy::index_in_segment(n);
2712 
2713  return _data[s_idx][local_idx];
2714 }
2715 
2721 template <typename T, typename Policy>
2722 typename segment_vector<T, Policy>::const_reference
2724 {
2725  size_type s_idx = policy::get_segment(n);
2726  size_type local_idx = policy::index_in_segment(n);
2727 
2728  return _data[s_idx][local_idx];
2729 }
2730 
2736 template <typename T, typename Policy>
2737 typename segment_vector<T, Policy>::const_reference
2739 {
2740  size_type s_idx = policy::get_segment(n);
2741  size_type local_idx = policy::index_in_segment(n);
2742 
2743  return _data[s_idx][local_idx];
2744 }
2745 
2753 template <typename T, typename Policy>
2754 bool
2756 {
2757  for (size_type i = 0; i < _segments_used; ++i)
2758  if (_data.const_at(i).capacity() != policy::segment_size(i))
2759  return false;
2760  return true;
2761 }
2762 
2769 template <typename T, typename Policy>
2770 void
2772 {
2773  lhs.swap(rhs);
2774 }
2775 
2790 template <typename T, typename Policy>
2791 bool
2793  const segment_vector<T, Policy> &rhs)
2794 {
2795  return lhs.size() == rhs.size() &&
2796  std::equal(lhs.begin(), lhs.end(), rhs.begin());
2797 }
2798 
2814 template <typename T, typename Policy>
2815 bool
2817  const segment_vector<T, Policy> &rhs)
2818 {
2819  return !(lhs == rhs);
2820 }
2821 
2834 template <typename T, typename Policy>
2835 bool
2837  const segment_vector<T, Policy> &rhs)
2838 {
2839  return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(),
2840  rhs.end());
2841 }
2842 
2855 template <typename T, typename Policy>
2856 bool
2858  const segment_vector<T, Policy> &rhs)
2859 {
2860  return !(rhs < lhs);
2861 }
2862 
2875 template <typename T, typename Policy>
2876 bool
2878  const segment_vector<T, Policy> &rhs)
2879 {
2880  return rhs < lhs;
2881 }
2882 
2895 template <typename T, typename Policy>
2896 bool
2898  const segment_vector<T, Policy> &rhs)
2899 {
2900  return !(lhs < rhs);
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.size() == rhs.size() &&
2921  std::equal(lhs.begin(), lhs.end(), rhs.begin());
2922 }
2923 
2937 template <typename T, typename Policy>
2938 bool
2939 operator!=(const segment_vector<T, Policy> &lhs, const std::vector<T> &rhs)
2940 {
2941  return !(lhs == rhs);
2942 }
2943 
2955 template <typename T, typename Policy>
2956 bool
2957 operator<(const segment_vector<T, Policy> &lhs, const std::vector<T> &rhs)
2958 {
2959  return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(),
2960  rhs.end());
2961 }
2962 
2974 template <typename T, typename Policy>
2975 bool
2976 operator<=(const segment_vector<T, Policy> &lhs, const std::vector<T> &rhs)
2977 {
2978  return !(std::lexicographical_compare(rhs.begin(), rhs.end(),
2979  lhs.begin(), lhs.end()));
2980 }
2981 
2994 template <typename T, typename Policy>
2995 bool
2996 operator>(const segment_vector<T, Policy> &lhs, const std::vector<T> &rhs)
2997 {
2998  return !(lhs <= rhs);
2999 }
3000 
3012 template <typename T, typename Policy>
3013 bool
3014 operator>=(const segment_vector<T, Policy> &lhs, const std::vector<T> &rhs)
3015 {
3016  return !(lhs < rhs);
3017 }
3018 
3032 template <typename T, typename Policy>
3033 bool
3034 operator==(const std::vector<T> &lhs, const segment_vector<T, Policy> &rhs)
3035 {
3036  return rhs == lhs;
3037 }
3038 
3052 template <typename T, typename Policy>
3053 bool
3054 operator!=(const std::vector<T> &lhs, const segment_vector<T, Policy> &rhs)
3055 {
3056  return !(lhs == rhs);
3057 }
3058 
3070 template <typename T, typename Policy>
3071 bool
3072 operator<(const std::vector<T> &lhs, const segment_vector<T, Policy> &rhs)
3073 {
3074  return rhs > lhs;
3075 }
3076 
3088 template <typename T, typename Policy>
3089 bool
3090 operator<=(const std::vector<T> &lhs, const segment_vector<T, Policy> &rhs)
3091 {
3092  return !(rhs < lhs);
3093 }
3094 
3107 template <typename T, typename Policy>
3108 bool
3109 operator>(const std::vector<T> &lhs, const segment_vector<T, Policy> &rhs)
3110 {
3111  return rhs < lhs;
3112 }
3113 
3125 template <typename T, typename Policy>
3126 bool
3127 operator>=(const std::vector<T> &lhs, const segment_vector<T, Policy> &rhs)
3128 {
3129  return !(lhs < rhs);
3130 }
3131 
3132 } /* namespace obj */
3133 } /* namespace pmem */
3134 
3135 #endif /* LIBPMEMOBJ_SEGMENT_VECTOR_HPP */
pmem::obj::segment_vector::cfront
const_reference cfront() const
Access the first element.
Definition: segment_vector.hpp:1444
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:1318
pmem::obj::segment_vector::resize
void resize(size_type count)
Resizes the container to count elements transactionally.
Definition: segment_vector.hpp:2363
pmem::obj::segment_vector::swap
void swap(segment_vector &other)
Exchanges the contents of the container with other transactionally.
Definition: segment_vector.hpp:2426
pmem::obj::segment_vector_internal::segment_iterator::operator-
segment_iterator operator-(difference_type idx) const
Random access decrementing.
Definition: segment_vector.hpp:278
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:526
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:393
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:1361
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:1872
pmem::obj::segment_vector::clear
void clear()
Clears the content of a segment_vector transactionally.
Definition: segment_vector.hpp:1851
pmem::obj::rend
pmem::obj::array< T, N >::reverse_iterator rend(pmem::obj::array< T, N > &a)
Non-member rend.
Definition: array.hpp:893
pmem
Persistent memory namespace.
Definition: allocation_flag.hpp:44
pmem::obj::segment_vector::rbegin
reverse_iterator rbegin()
Returns a reverse iterator to the beginning.
Definition: segment_vector.hpp:1584
pmem::obj::begin
pmem::obj::array< T, N >::iterator begin(pmem::obj::array< T, N > &a)
Non-member begin.
Definition: array.hpp:833
pmem::obj::segment_vector_internal::segment_iterator::operator->
pointer operator->() const
Member access.
Definition: segment_vector.hpp:463
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:1625
pmem::obj::segment_vector::operator=
segment_vector & operator=(const segment_vector &other)
Copy assignment operator.
Definition: segment_vector.hpp:987
pmem::obj::operator>
bool operator>(const array< T, N > &lhs, const array< T, N > &rhs)
Non-member greater than operator.
Definition: array.hpp:763
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:70
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:1502
pmem::obj::segment_vector::end
iterator end()
Returns an iterator to past the end.
Definition: segment_vector.hpp:1543
pmem::obj::segment_vector::segment_vector
segment_vector()
Default constructor.
Definition: segment_vector.hpp:760
pmem::obj::operator>=
bool operator>=(const array< T, N > &lhs, const array< T, N > &rhs)
Non-member greater or equal operator.
Definition: array.hpp:773
pmem::obj::segment_vector::internal_reserve
void internal_reserve(size_type new_capacity)
Private helper method.
Definition: segment_vector.hpp:2452
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:402
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:1381
pmem::obj::p< size_type >
pmem::obj::segment_vector::segment_capacity_validation
bool segment_capacity_validation() const
Private helper function.
Definition: segment_vector.hpp:2755
pmem::obj::segment_vector::cbegin
const_iterator cbegin() const noexcept
Returns const iterator to the beginning.
Definition: segment_vector.hpp:1530
pmem::obj::segment_vector::cend
const_iterator cend() const noexcept
Returns a const iterator to the end.
Definition: segment_vector.hpp:1571
pmem::obj::segment_vector::crange
slice< const_iterator > crange(size_type start, size_type n) const
Returns const slice.
Definition: segment_vector.hpp:1717
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:2664
pmem::obj::segment_vector_internal::segment_iterator::segment_iterator
segment_iterator() noexcept
Default constructor.
Definition: segment_vector.hpp:156
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:422
pmem::obj::segment_vector::crend
const_reverse_iterator crend() const noexcept
Returns a const reverse iterator to the beginning.
Definition: segment_vector.hpp:1653
pmem::obj::segment_vector::range
slice< iterator > range(size_type start, size_type n)
Returns slice and snapshots requested range.
Definition: segment_vector.hpp:1673
pmem::obj::swap
void swap(pmem::obj::array< T, N > &lhs, pmem::obj::array< T, N > &rhs)
Non-member swap function.
Definition: array.hpp:913
pmem::obj::segment_vector::size
size_type size() const noexcept
Definition: segment_vector.hpp:1742
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:518
pmem::obj::cend
pmem::obj::array< T, N >::const_iterator cend(const pmem::obj::array< T, N > &a)
Non-member cend.
Definition: array.hpp:803
pmem::obj::segment_vector::pop_back
void pop_back()
Removes the last element of the container transactionally.
Definition: segment_vector.hpp:2328
pmem::obj::vector
pmem::obj::vector - persistent container with std::vector compatible interface.
Definition: vector.hpp:69
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:334
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:2112
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:2283
transaction.hpp
C++ pmemobj transactions.
pmem::obj::segment_vector_internal::segment_iterator::operator--
segment_iterator & operator--()
Prefix decrement.
Definition: segment_vector.hpp:251
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:2155
pmem::obj::segment_vector::empty
constexpr bool empty() const noexcept
Checks whether the container is empty.
Definition: segment_vector.hpp:1732
pmem::detail::is_input_iterator
Type trait to determine if a given parameter type satisfies requirements of InputIterator.
Definition: iterator_traits.hpp:76
pmem::detail::temp_value
Template class for caching objects based on constructor's variadic template arguments and LIBPMEMOBJ_...
Definition: temp_value.hpp:64
pmem::obj::segment_vector::shrink
void shrink(size_type size_new)
Private helper function.
Definition: segment_vector.hpp:2634
pmem::obj::segment_vector::~segment_vector
~segment_vector()
Destructor.
Definition: segment_vector.hpp:1298
pmem::obj::segment_vector::shrink_to_fit
void shrink_to_fit()
Requests transactional removal of unused capacity.
Definition: segment_vector.hpp:1821
pmem::obj::segment_vector_internal::segment_iterator::operator<
bool operator<(const segment_iterator< Container, C > &rhs) const
Less operator.
Definition: segment_vector.hpp:370
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:853
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:1907
pmem::obj::segment_vector::snapshot_data
void snapshot_data(size_type idx_first, size_type idx_last)
Private helper function.
Definition: segment_vector.hpp:2682
pmem::obj::operator<
bool operator<(const array< T, N > &lhs, const array< T, N > &rhs)
Non-member less than operator.
Definition: array.hpp:752
pmem::obj::segment_vector::back
reference back()
Access the last element and add this element to a transaction.
Definition: segment_vector.hpp:1459
pmem::obj::cbegin
pmem::obj::array< T, N >::const_iterator cbegin(const pmem::obj::array< T, N > &a)
Non-member cbegin.
Definition: array.hpp:793
pmem::obj::segment_vector::crbegin
const_reverse_iterator crbegin() const noexcept
Returns a const reverse iterator to the beginning.
Definition: segment_vector.hpp:1612
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:439
pmem::obj::get
T & get(pmem::obj::array< T, N > &a)
Non-member get function.
Definition: array.hpp:923
pmem::obj::segment_vector_internal::segment_iterator::operator-=
segment_iterator & operator-=(difference_type idx)
Random access decrementing with assignment.
Definition: segment_vector.hpp:290
pmem::obj::slice
pmem::obj::slice - provides interface to access sequence of objects.
Definition: slice.hpp:56
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:495
pmem::obj::operator<=
bool operator<=(const array< T, N > &lhs, const array< T, N > &rhs)
Non-member less or equal operator.
Definition: array.hpp:783
pmem::obj::array
pmem::obj::array - persistent container with std::array compatible interface.
Definition: array.hpp:74
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:226
life.hpp
Functions for destroying arrays.
pmem::obj::segment_vector::get
reference get(size_type n)
Private helper function.
Definition: segment_vector.hpp:2708
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:481
pmem::obj::rbegin
pmem::obj::array< T, N >::reverse_iterator rbegin(pmem::obj::array< T, N > &a)
Non-member rbegin.
Definition: array.hpp:873
pmem::obj::segment_vector::cback
const_reference cback() const
Access the last element.
Definition: segment_vector.hpp:1490
pmem::obj::segment_vector_internal::segment_iterator::operator+=
segment_iterator & operator+=(difference_type idx)
Random access incrementing with assignment.
Definition: segment_vector.hpp:238
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:416
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:508
pmem::obj::segment_vector::erase
iterator erase(const_iterator pos)
Removes the element at pos.
Definition: segment_vector.hpp:2194
pmem::obj::segment_vector::max_size
constexpr size_type max_size() const noexcept
Definition: segment_vector.hpp:1763
pmem::obj::segment_vector_internal::segment_iterator::operator*
reference operator*() const
Indirection (dereference).
Definition: segment_vector.hpp:453
pmem::obj::segment_vector::capacity
size_type capacity() const noexcept
Definition: segment_vector.hpp:1801
pmem::obj::segment_vector::front
reference front()
Access the first element and add this element to a transaction.
Definition: segment_vector.hpp:1415
pmem::obj::segment_vector::construct_range
void construct_range(size_type idx, InputIt first, InputIt last)
Private helper function.
Definition: segment_vector.hpp:2552
pmem::obj::segment_vector_internal::segment_iterator::operator++
segment_iterator & operator++()
Prefix increment.
Definition: segment_vector.hpp:199
pmem::obj::segment_vector::insert_gap
void insert_gap(size_type idx, size_type count)
Private helper function.
Definition: segment_vector.hpp:2590
pmem::obj::pool_base
The non-template pool base class.
Definition: pool.hpp:75
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:1786
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:2771
pmem::obj::segment_vector_internal::segment_iterator::operator!=
bool operator!=(const segment_iterator< Container, C > &rhs) const
Not equal operator.
Definition: segment_vector.hpp:351
pmem::obj::segment_vector::cget
const_reference cget(size_type n) const
Private helper function.
Definition: segment_vector.hpp:2738
pmem::obj::segment_vector::construct
void construct(size_type idx, size_type count, Args &&... args)
Private helper function.
Definition: segment_vector.hpp:2503
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:1090