PMDK C++ bindings  1.2.0
This is the C++ bindings documentation for PMDK's libpmemobj.
vector.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2018-2019, 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_CPP_VECTOR_HPP
39 #define LIBPMEMOBJ_CPP_VECTOR_HPP
40 
48 #include <libpmemobj++/pext.hpp>
50 #include <libpmemobj.h>
51 
52 #include <algorithm>
53 #include <cassert>
54 #include <utility>
55 
56 namespace pmem
57 {
58 
59 namespace obj
60 {
61 
62 namespace experimental
63 {
64 
69 template <typename T>
70 class vector {
71 public:
72  /* Member types */
73  using value_type = T;
74  using size_type = std::size_t;
75  using difference_type = std::ptrdiff_t;
76  using reference = value_type &;
77  using const_reference = const value_type &;
78  using pointer = value_type *;
79  using const_pointer = const value_type *;
82  using reverse_iterator = std::reverse_iterator<iterator>;
83  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
84 
85  /* Constructors */
86  vector();
87  vector(size_type count, const value_type &value);
88  explicit vector(size_type count);
89  template <typename InputIt,
90  typename std::enable_if<
92  std::is_constructible<
93  value_type,
94  typename std::iterator_traits<
95  InputIt>::reference>::value,
96  InputIt>::type * = nullptr>
97  vector(InputIt first, InputIt last);
98  vector(const vector &other);
99  vector(vector &&other);
100  vector(std::initializer_list<T> init);
101 
102  /* Assign operators */
103  // vector &operator=(const vector &other);
104  // vector &operator=(vector &&other);
105  // vector &operator=(std::initializer_list<T> ilist);
106 
107  /* Assign methods */
108  // void assign(size_type count, const T &value);
109  // template <typename InputIt>
110  // void assign(InputIt first, typename
111  // std::enable_if<detail::is_input_iterator<InputIt>::value &&
112  // std::is_constructible<value_type, typename
113  // std::iterator_traits<InputIt>::reference>::value, InputIt>::type
114  // last); void assign(std::initializer_list<T> ilist);
115 
116  /* Destructor */
117  ~vector();
118 
119  /* Element access */
120  reference at(size_type n);
121  const_reference at(size_type n) const;
122  const_reference const_at(size_type n) const;
123  reference operator[](size_type n);
124  const_reference operator[](size_type n) const;
125  reference front();
126  const_reference front() const;
127  const_reference cfront() const;
128  reference back();
129  const_reference back() const;
130  const_reference cback() const;
131  value_type *data();
132  const value_type *data() const noexcept;
133  const value_type *cdata() const noexcept;
134 
135  /* Iterators */
136  iterator begin();
137  const_iterator begin() const noexcept;
138  const_iterator cbegin() const noexcept;
139  iterator end();
140  const_iterator end() const noexcept;
141  const_iterator cend() const noexcept;
142  reverse_iterator rbegin();
143  const_reverse_iterator rbegin() const noexcept;
144  const_reverse_iterator crbegin() const noexcept;
145  reverse_iterator rend();
146  const_reverse_iterator rend() const noexcept;
147  const_reverse_iterator crend() const noexcept;
148 
149  /* Capacity */
150  constexpr bool empty() const noexcept;
151  size_type size() const noexcept;
152  constexpr size_type max_size() const noexcept;
153  // void reserve(size_type capacity_new);
154  size_type capacity() const noexcept;
155  // void shrink_to_fit();
156 
157  /* Modifiers */
158  // void clear() noexcept;
159  void free_data();
160  // iterator insert(const_iterator pos, const T &value);
161  // iterator insert(const_iterator pos, T &&value);
162  // iterator insert(const_iterator pos, size_type count, const T &value);
163  // template <typename InputIt>
164  // iterator insert(const_iterator pos, InputIt first, typename
165  // std::enable_if<detail::is_input_iterator<InputIt>::value,
166  // InputIt>::type last); iterator insert(const_iterator pos,
167  // std::initializer_list<T> ilist); template <class... Args> iterator
168  // emplace(const_iterator pos, Args&&... args); template< class... Args
169  // > void emplace_back(Args&&... args); iterator erase(iterator pos);
170  // iterator erase(const_iterator pos);
171  // iterator erase(iterator first, iterator last);
172  // iterator erase(const_iterator first, const_iterator last);
173  // void push_back(const T& value);
174  // void push_back(T&& value);
175  // void pop_back();
176  // void resize(size_type count, T value = T());
177  // void resize(size_type count);
178  // void resize(size_type count, const value_type& value);
179  // void swap(vector &other);
180 
181 private:
182  /* helper functions */
183  void _alloc(size_type size);
184  void _dealloc();
185  void _grow(size_type count, const_reference value);
186  template <typename InputIt,
187  typename std::enable_if<
189  std::is_constructible<
190  value_type,
191  typename std::iterator_traits<
192  InputIt>::reference>::value,
193  InputIt>::type * = nullptr>
194  void _grow(InputIt first, InputIt last);
195  void _shrink(size_type size_new) noexcept;
196 
197  /* Underlying array */
198  persistent_ptr<T[]> _data;
199 
200  p<size_type> _size;
201  p<size_type> _capacity;
202 };
203 
204 /* Comparison operators */
205 template <typename T>
206 bool operator==(const vector<T> &lhs, const vector<T> &rhs);
207 template <typename T>
208 bool operator!=(const vector<T> &lhs, const vector<T> &rhs);
209 template <typename T>
210 bool operator<(const vector<T> &lhs, const vector<T> &rhs);
211 template <typename T>
212 bool operator<=(const vector<T> &lhs, const vector<T> &rhs);
213 template <typename T>
214 bool operator>(const vector<T> &lhs, const vector<T> &rhs);
215 template <typename T>
216 bool operator>=(const vector<T> &lhs, const vector<T> &rhs);
217 
226 template <typename T>
228 {
229  auto pop = pmemobj_pool_by_ptr(this);
230  if (pop == nullptr)
231  throw pool_error("Invalid pool handle.");
232 
233  if (pmemobj_tx_stage() != TX_STAGE_WORK)
234  throw transaction_error(
235  "Default constructor called out of transaction scope.");
236 
237  _data = nullptr;
238  _size = 0;
239  _capacity = 0;
240 }
241 
259 template <typename T>
260 vector<T>::vector(size_type count, const value_type &value)
261 {
262  auto pop = pmemobj_pool_by_ptr(this);
263  if (pop == nullptr)
264  throw pool_error("Invalid pool handle.");
265 
266  if (pmemobj_tx_stage() != TX_STAGE_WORK)
267  throw transaction_error(
268  "Fill constructor called out of transaction scope.");
269 
270  _data = nullptr;
271  _size = 0;
272  _alloc(count);
273  _grow(count, value);
274 }
275 
292 template <typename T>
293 vector<T>::vector(size_type count)
294 {
295  auto pop = pmemobj_pool_by_ptr(this);
296  if (pop == nullptr)
297  throw pool_error("Invalid pool handle.");
298 
299  if (pmemobj_tx_stage() != TX_STAGE_WORK)
300  throw transaction_error(
301  "Fill constructor called out of transaction scope.");
302 
303  _data = nullptr;
304  _size = 0;
305  _alloc(count);
306  // XXX: after "capacity" methods will be merged, _grow() overload
307  // without parameters will be available. After that, following lines
308  // should be replaced with _grow()
309  pointer dest = _data.get();
310  const_pointer end = dest + count;
311  for (; dest != end; ++dest)
312  detail::create<value_type>(dest);
313  _size = count;
314 }
315 
337 template <typename T>
338 template <typename InputIt,
339  typename std::enable_if<
341  std::is_constructible<
342  T,
343  typename std::iterator_traits<
344  InputIt>::reference>::value,
345  InputIt>::type *>
346 vector<T>::vector(InputIt first, InputIt last)
347 {
348  auto pop = pmemobj_pool_by_ptr(this);
349  if (pop == nullptr)
350  throw pool_error("Invalid pool handle.");
351 
352  if (pmemobj_tx_stage() != TX_STAGE_WORK)
353  throw transaction_error(
354  "Range constructor called out of transaction scope.");
355 
356  _data = nullptr;
357  _size = 0;
358  _alloc(static_cast<size_type>(std::distance(first, last)));
359  _grow(first, last);
360 }
361 
379 template <typename T>
381 {
382  auto pop = pmemobj_pool_by_ptr(this);
383  if (pop == nullptr)
384  throw pool_error("Invalid pool handle.");
385 
386  if (pmemobj_tx_stage() != TX_STAGE_WORK)
387  throw transaction_error(
388  "Copy constructor called out of transaction scope.");
389 
390  _data = nullptr;
391  _size = 0;
392  _alloc(other.capacity());
393  _grow(other.begin(), other.end());
394 }
395 
414 template <typename T>
416 {
417  auto pop = pmemobj_pool_by_ptr(this);
418  if (pop == nullptr)
419  throw pool_error("Invalid pool handle.");
420 
421  if (pmemobj_tx_stage() != TX_STAGE_WORK)
422  throw transaction_error(
423  "Move constructor called out of transaction scope.");
424 
425  _data = other._data;
426  _capacity = other.capacity();
427  _size = other.size();
428  other._data = nullptr;
429  other._capacity = other._size = 0;
430 }
431 
448 template <typename T>
449 vector<T>::vector(std::initializer_list<T> init)
450  : vector(init.begin(), init.end())
451 {
452 }
453 
460 template <typename T>
462 {
463  free_data();
464 }
465 
480 template <typename T>
481 typename vector<T>::reference
482 vector<T>::at(size_type n)
483 {
484  assert(pmemobj_tx_stage() == TX_STAGE_WORK);
485  if (n >= _size)
486  throw std::out_of_range("vector::at");
487  detail::conditional_add_to_tx(&_data[n]);
488  return _data[n];
489 }
490 
500 template <typename T>
501 typename vector<T>::const_reference
502 vector<T>::at(size_type n) const
503 {
504  if (n >= _size)
505  throw std::out_of_range("vector::at");
506  return _data[n];
507 }
508 
521 template <typename T>
522 typename vector<T>::const_reference
523 vector<T>::const_at(size_type n) const
524 {
525  if (n >= _size)
526  throw std::out_of_range("vector::const_at");
527  return _data[n];
528 }
529 
543 template <typename T>
544 typename vector<T>::reference vector<T>::operator[](size_type n)
545 {
546  assert(pmemobj_tx_stage() == TX_STAGE_WORK);
547  detail::conditional_add_to_tx(&_data[n]);
548  return _data[n];
549 }
550 
558 template <typename T>
559 typename vector<T>::const_reference vector<T>::operator[](size_type n) const
560 {
561  return _data[n];
562 }
563 
574 template <typename T>
575 typename vector<T>::reference
577 {
578  assert(pmemobj_tx_stage() == TX_STAGE_WORK);
579  detail::conditional_add_to_tx(&_data[0]);
580  return _data[0];
581 }
582 
588 template <typename T>
589 typename vector<T>::const_reference
591 {
592  return _data[0];
593 }
594 
602 template <typename T>
603 typename vector<T>::const_reference
605 {
606  return _data[0];
607 }
608 
619 template <typename T>
620 typename vector<T>::reference
622 {
623  assert(pmemobj_tx_stage() == TX_STAGE_WORK);
624  detail::conditional_add_to_tx(&_data[size() - 1]);
625  return _data[size() - 1];
626 }
627 
633 template <typename T>
634 typename vector<T>::const_reference
636 {
637  return _data[size() - 1];
638 }
639 
647 template <typename T>
648 typename vector<T>::const_reference
650 {
651  return _data[size() - 1];
652 }
653 
665 template <typename T>
666 typename vector<T>::value_type *
668 {
669  assert(pmemobj_tx_stage() == TX_STAGE_WORK);
670  detail::conditional_add_to_tx(_data.get(), size());
671  return _data.get();
672 }
673 
679 template <typename T>
680 const typename vector<T>::value_type *
681 vector<T>::data() const noexcept
682 {
683  return _data.get();
684 }
685 
693 template <typename T>
694 const typename vector<T>::value_type *
695 vector<T>::cdata() const noexcept
696 {
697  return _data.get();
698 }
699 
707 template <typename T>
708 typename vector<T>::iterator
710 {
711  assert(pmemobj_tx_stage() == TX_STAGE_WORK);
712  return iterator(_data.get());
713 }
714 
720 template <typename T>
722 vector<T>::begin() const noexcept
723 {
724  return const_iterator(_data.get());
725 }
726 
734 template <typename T>
736 vector<T>::cbegin() const noexcept
737 {
738  return const_iterator(_data.get());
739 }
740 
748 template <typename T>
749 typename vector<T>::iterator
751 {
752  assert(pmemobj_tx_stage() == TX_STAGE_WORK);
753  return iterator(_data.get() + static_cast<std::ptrdiff_t>(_size));
754 }
755 
761 template <typename T>
763 vector<T>::end() const noexcept
764 {
765  return const_iterator(_data.get() + static_cast<std::ptrdiff_t>(_size));
766 }
767 
775 template <typename T>
777 vector<T>::cend() const noexcept
778 {
779  return const_iterator(_data.get() + static_cast<std::ptrdiff_t>(_size));
780 }
781 
789 template <typename T>
790 typename vector<T>::reverse_iterator
792 {
793  assert(pmemobj_tx_stage() == TX_STAGE_WORK);
794  return reverse_iterator(end());
795 }
796 
802 template <typename T>
803 typename vector<T>::const_reverse_iterator
804 vector<T>::rbegin() const noexcept
805 {
806  return const_reverse_iterator(cend());
807 }
808 
816 template <typename T>
817 typename vector<T>::const_reverse_iterator
818 vector<T>::crbegin() const noexcept
819 {
820  return const_reverse_iterator(cend());
821 }
822 
831 template <typename T>
832 typename vector<T>::reverse_iterator
834 {
835  assert(pmemobj_tx_stage() == TX_STAGE_WORK);
836  return reverse_iterator(begin());
837 }
838 
845 template <typename T>
846 typename vector<T>::const_reverse_iterator
847 vector<T>::rend() const noexcept
848 {
849  return const_reverse_iterator(cbegin());
850 }
851 
860 template <typename T>
861 typename vector<T>::const_reverse_iterator
862 vector<T>::crend() const noexcept
863 {
864  return const_reverse_iterator(cbegin());
865 }
866 
872 template <typename T>
873 constexpr bool
874 vector<T>::empty() const noexcept
875 {
876  return _size == 0;
877 }
878 
882 template <typename T>
883 typename vector<T>::size_type
884 vector<T>::size() const noexcept
885 {
886  return _size;
887 }
888 
893 template <typename T>
894 constexpr typename vector<T>::size_type
895 vector<T>::max_size() const noexcept
896 {
897  return PMEMOBJ_MAX_ALLOC_SIZE / sizeof(value_type);
898 }
899 
903 template <typename T>
904 typename vector<T>::size_type
905 vector<T>::capacity() const noexcept
906 {
907  return _capacity;
908 }
909 
920 template <typename T>
921 void
923 {
924  if (_data == nullptr)
925  return;
926 
927  auto pop = pmemobj_pool_by_ptr(this);
928  assert(pop != nullptr);
929 
930  pool_base pb = pool_base(pop);
931  transaction::run(pb, [&] {
932  detail::conditional_add_to_tx(_data.get(), _size);
933  _dealloc();
934  });
935 }
936 
954 template <typename T>
955 void
956 vector<T>::_alloc(size_type capacity_new)
957 {
958  assert(pmemobj_tx_stage() == TX_STAGE_WORK);
959  assert(_data == nullptr);
960  assert(_size == 0);
961 
962  if (capacity_new > max_size())
963  throw std::length_error("New capacity exceeds max size.");
964 
965  _capacity = capacity_new;
966 
967  if (capacity_new == 0)
968  return;
969 
970  /*
971  * We need to cache pmemobj_tx_alloc return value and only after that
972  * assign it to _data, because when pmemobj_tx_alloc fails, it aborts
973  * transaction.
974  */
975  persistent_ptr<T[]> res =
976  pmemobj_tx_alloc(sizeof(value_type) * capacity_new,
977  detail::type_num<value_type>());
978 
979  if (res == nullptr)
981  "Failed to allocate persistent memory object");
982 
983  _data = res;
984 }
985 
999 template <typename T>
1000 void
1002 {
1003  assert(pmemobj_tx_stage() == TX_STAGE_WORK);
1004 
1005  if (_data != nullptr) {
1006  _shrink(0);
1007  if (pmemobj_tx_free(*_data.raw_ptr()) != 0)
1008  throw transaction_free_error(
1009  "failed to delete persistent memory object");
1010  _data = nullptr;
1011  _capacity = 0;
1012  }
1013 }
1014 
1033 template <typename T>
1034 void
1035 vector<T>::_grow(size_type count, const_reference value)
1036 {
1037  assert(pmemobj_tx_stage() == TX_STAGE_WORK);
1038  assert(_capacity >= count + _size);
1039 
1040  pointer dest = _data.get() + static_cast<size_type>(_size);
1041  const_pointer end = dest + count;
1042  for (; dest != end; ++dest)
1043  detail::create<value_type, const_reference>(dest, value);
1044  _size += count;
1045 }
1046 
1069 template <typename T>
1070 template <typename InputIt,
1071  typename std::enable_if<
1073  std::is_constructible<
1074  T,
1075  typename std::iterator_traits<
1076  InputIt>::reference>::value,
1077  InputIt>::type *>
1078 void
1079 vector<T>::_grow(InputIt first, InputIt last)
1080 {
1081  assert(pmemobj_tx_stage() == TX_STAGE_WORK);
1082  difference_type diff = std::distance(first, last);
1083  assert(diff >= 0);
1084  assert(_capacity >= static_cast<size_type>(diff) + _size);
1085 
1086  pointer dest = _data.get() + static_cast<size_type>(_size);
1087  _size += static_cast<size_type>(diff);
1088  while (first != last)
1089  detail::create<value_type>(dest++, *first++);
1090 }
1091 
1105 template <typename T>
1106 void
1107 vector<T>::_shrink(size_type size_new) noexcept
1108 {
1109  assert(pmemobj_tx_stage() == TX_STAGE_WORK);
1110  assert(size_new <= _size);
1111 
1112  for (size_type i = size_new; i < _size; ++i)
1113  detail::destroy<value_type>(_data[i]);
1114  _size = size_new;
1115 }
1116 
1128 template <typename T>
1129 bool
1130 operator==(const vector<T> &lhs, const vector<T> &rhs)
1131 {
1132  return lhs.size() == rhs.size() &&
1133  std::equal(lhs.begin(), lhs.end(), rhs.begin());
1134 }
1135 
1147 template <typename T>
1148 bool
1149 operator!=(const vector<T> &lhs, const vector<T> &rhs)
1150 {
1151  return !(lhs == rhs);
1152 }
1153 
1164 template <typename T>
1165 bool
1166 operator<(const vector<T> &lhs, const vector<T> &rhs)
1167 {
1168  return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(),
1169  rhs.end());
1170 }
1171 
1182 template <typename T>
1183 bool
1184 operator<=(const vector<T> &lhs, const vector<T> &rhs)
1185 {
1186  return !(rhs < lhs);
1187 }
1188 
1200 template <typename T>
1201 bool
1202 operator>(const vector<T> &lhs, const vector<T> &rhs)
1203 {
1204  return rhs < lhs;
1205 }
1206 
1217 template <typename T>
1218 bool
1219 operator>=(const vector<T> &lhs, const vector<T> &rhs)
1220 {
1221  return !(lhs < rhs);
1222 }
1223 
1224 } /* namespace experimental */
1225 
1226 } /* namespace obj */
1227 
1228 } /* namespace pmem */
1229 
1230 #endif /* LIBPMEMOBJ_CPP_VECTOR_HPP */
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:400
Custom transaction error class.
Definition: pexceptions.hpp:84
iterator begin()
Returns an iterator to the beginning.
Definition: vector.hpp:709
bool operator>=(const array< T, N > &lhs, const array< T, N > &rhs)
Non-member greater or equal operator.
Definition: array.hpp:631
constexpr bool empty() const noexcept
Checks whether the container is empty.
Definition: vector.hpp:874
~vector()
Destructor.
Definition: vector.hpp:461
constexpr size_type max_size() const noexcept
Definition: vector.hpp:895
void free_data()
Clears the content of a vector and frees all allocated persitent memory for data in transaction...
Definition: vector.hpp:922
reference at(size_type n)
Access element at specific index with bounds checking and add it to a transaction.
Definition: vector.hpp:482
pmem::obj::experimental::array< T, N >::const_iterator cend(const pmem::obj::experimental::array< T, N > &a)
Non-member cend.
Definition: array.hpp:661
Default non-const iterator which adds element to a transaction on every access.
Definition: contiguous_iterator.hpp:420
const_reverse_iterator crbegin() const noexcept
Returns a const reverse iterator to the beginning.
Definition: vector.hpp:818
void _grow(size_type count, const_reference value)
Private helper function.
Definition: vector.hpp:1035
Common iterator traits.
The non-template pool base class.
Definition: pool.hpp:67
const_reference cback() const
Access the last element.
Definition: vector.hpp:649
void _dealloc()
Private helper function.
Definition: vector.hpp:1001
pmem::obj::experimental::array< T, N >::iterator begin(pmem::obj::experimental::array< T, N > &a)
Non-member begin.
Definition: array.hpp:691
Custom pool error class.
Definition: pexceptions.hpp:53
const_reference cfront() const
Access the first element.
Definition: vector.hpp:604
reverse_iterator rbegin()
Returns a reverse iterator to the beginning.
Definition: vector.hpp:791
vector()
Default constructor.
Definition: vector.hpp:227
reference back()
Access the last element and add this element to a transaction.
Definition: vector.hpp:621
iterator end()
Returns an iterator to past the end.
Definition: vector.hpp:750
C++ pmemobj transactions.
Convenience extensions for the resides on pmem property template.
Functions for destroying arrays.
reference operator[](size_type n)
Access element at specific index and add it to a transaction.
Definition: vector.hpp:544
Commonly used functionality.
Iterators for pmem::obj::array.
value_type * data()
Returns raw pointer to the underlying data and adds entire array to a transaction.
Definition: vector.hpp:667
const value_type * cdata() const noexcept
Returns const raw pointer to the underlying data.
Definition: vector.hpp:695
const_iterator cend() const noexcept
Returns a const iterator to the end.
Definition: vector.hpp:777
pmem::obj::experimental::vector - EXPERIMENTAL persistent container with std::vector compatible inter...
Definition: vector.hpp:70
Custom transaction error class.
Definition: pexceptions.hpp:63
Type trait to determine if a given parameter type satisfies requirements of InputIterator.
Definition: iterator_traits.hpp:75
const_reference const_at(size_type n) const
Access element at specific index with bounds checking.
Definition: vector.hpp:523
reverse_iterator rend()
Returns a reverse iterator to the end.
Definition: vector.hpp:833
pmem::obj::experimental::array< T, N >::iterator end(pmem::obj::experimental::array< T, N > &a)
Non-member end.
Definition: array.hpp:701
Const iterator.
Definition: contiguous_iterator.hpp:208
void _alloc(size_type size)
Private helper function.
Definition: vector.hpp:956
Persistent smart pointer.
bool operator>(const array< T, N > &lhs, const array< T, N > &rhs)
Non-member greater than operator.
Definition: array.hpp:621
Iterface to access sequence of objects.
size_type capacity() const noexcept
Definition: vector.hpp:905
const_reverse_iterator crend() const noexcept
Returns a const reverse iterator to the beginning.
Definition: vector.hpp:862
reference front()
Access the first element and add this element to a transaction.
Definition: vector.hpp:576
Custom transaction error class.
Definition: pexceptions.hpp:94
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:516
pmem::obj::experimental::array< T, N >::const_iterator cbegin(const pmem::obj::experimental::array< T, N > &a)
Non-member cbegin.
Definition: array.hpp:651
Definition: allocator.hpp:48
size_type size() const noexcept
Definition: vector.hpp:884
void _shrink(size_type size_new) noexcept
Private helper function.
Definition: vector.hpp:1107
const_iterator cbegin() const noexcept
Returns const iterator to the beginning.
Definition: vector.hpp:736
Persistent_ptr allocation functions for arrays.
static void run(pool_base &pool, std::function< void()> tx, Locks &... locks)
Execute a closure-like transaction and lock locks.
Definition: transaction.hpp:397