PMDK C++ bindings  1.12-git53.g67ba2be4
This is the C++ bindings documentation for PMDK's libpmemobj.
persistent_pool_ptr.hpp
1 // SPDX-License-Identifier: BSD-3-Clause
2 /* Copyright 2018-2019, Intel Corporation */
3 
4 #ifndef PMEMOBJ_PERSISTENT_POOL_PTR_HPP
5 #define PMEMOBJ_PERSISTENT_POOL_PTR_HPP
6 
7 #include <cassert>
8 #include <cstddef>
9 #include <type_traits>
10 
13 
14 namespace pmem
15 {
16 namespace detail
17 {
18 
19 template <typename T>
20 class persistent_pool_ptr {
21  template <typename Y>
22  friend class persistent_pool_ptr;
23 
24  typedef persistent_pool_ptr<T> this_type;
25 
26 public:
31  typedef typename pmem::detail::sp_element<T>::type element_type;
32 
33  persistent_pool_ptr() : off(0)
34  {
35  verify_type();
36  }
37 
41  persistent_pool_ptr(std::nullptr_t) noexcept : off(0)
42  {
43  verify_type();
44  }
45 
53  persistent_pool_ptr(PMEMoid oid) noexcept : off(oid.off)
54  {
55  verify_type();
56  }
57 
65  persistent_pool_ptr(uint64_t _off) noexcept : off(_off)
66  {
67  verify_type();
68  }
69 
76  template <typename Y,
77  typename = typename std::enable_if<
78  std::is_convertible<Y *, T *>::value>::type>
79  persistent_pool_ptr(const persistent_pool_ptr<Y> &r) noexcept
80  : off(r.off)
81  {
82  verify_type();
83  }
84 
91  template <typename Y,
92  typename = typename std::enable_if<
93  std::is_convertible<Y *, T *>::value>::type>
94  persistent_pool_ptr(const pmem::obj::persistent_ptr<Y> &r) noexcept
95  : off(r.raw().off)
96  {
97  verify_type();
98  }
99 
100  /*
101  * Copy constructor.
102  *
103  * @param r Persistent pool pointer to the same type.
104  */
105  persistent_pool_ptr(const persistent_pool_ptr &r) noexcept : off(r.off)
106  {
107  verify_type();
108  }
109 
110  /*
111  * Copy constructor from a persistent_ptr.
112  *
113  * @param r Persistent pointer to the same type.
114  */
115  persistent_pool_ptr(const pmem::obj::persistent_ptr<T> &r) noexcept
116  : off(r.raw().off)
117  {
118  verify_type();
119  }
120 
124  persistent_pool_ptr(persistent_pool_ptr &&r) noexcept
125  : off(std::move(r.off))
126  {
127  verify_type();
128  }
129 
133  persistent_pool_ptr &
134  operator=(persistent_pool_ptr &&r)
135  {
136  conditional_add_to_tx(this);
137  this->off = std::move(r.off);
138 
139  return *this;
140  }
141 
142  persistent_pool_ptr &operator=(std::nullptr_t)
143  {
144  conditional_add_to_tx(this);
145  this->off = 0;
146 
147  return *this;
148  }
149 
160  persistent_pool_ptr &
161  operator=(const persistent_pool_ptr &r)
162  {
163  conditional_add_to_tx(this);
164  this->off = r.off;
165 
166  return *this;
167  }
168 
179  persistent_pool_ptr &
180  operator=(const pmem::obj::persistent_ptr<T> &r)
181  {
182  conditional_add_to_tx(this);
183  this->off = r.raw().off;
184 
185  return *this;
186  }
187 
198  persistent_pool_ptr &
199  operator=(const PMEMoid &oid)
200  {
201  conditional_add_to_tx(this);
202  this->off = oid.off;
203  return *this;
204  }
205 
217  template <typename Y,
218  typename = typename std::enable_if<
219  std::is_convertible<Y *, T *>::value>::type>
220  persistent_pool_ptr &
221  operator=(const persistent_pool_ptr<Y> &r)
222  {
223  conditional_add_to_tx(this);
224  this->off = r.off;
225 
226  return *this;
227  }
228 
240  template <typename Y,
241  typename = typename std::enable_if<
242  std::is_convertible<Y *, T *>::value>::type>
243  persistent_pool_ptr &
244  operator=(const pmem::obj::persistent_ptr<Y> &r)
245  {
246  conditional_add_to_tx(this);
247  this->off = r.raw().off;
248 
249  return *this;
250  }
251 
259  element_type *
260  get(uint64_t pool_uuid) const noexcept
261  {
262  PMEMoid oid = {pool_uuid, this->off};
263  return static_cast<element_type *>(pmemobj_direct(oid));
264  }
265 
266  element_type *
267  operator()(uint64_t pool_uuid) const noexcept
268  {
269  return get(pool_uuid);
270  }
271 
280  get_persistent_ptr(uint64_t pool_uuid) const noexcept
281  {
282  PMEMoid oid = {pool_uuid, this->off};
283  return pmem::obj::persistent_ptr<T>(oid);
284  }
285 
289  void
290  swap(persistent_pool_ptr &other)
291  {
292  conditional_add_to_tx(this);
293  conditional_add_to_tx(&other);
294  std::swap(this->off, other.off);
295  }
296 
297  /*
298  * Bool conversion operator.
299  */
300  explicit operator bool() const noexcept
301  {
302  return this->off != 0;
303  }
304 
312  PMEMoid
313  raw_oid(uint64_t pool_uuid) const noexcept
314  {
315  PMEMoid oid = {pool_uuid, this->off};
316  return oid;
317  }
318 
319  const uint64_t &
320  raw() const noexcept
321  {
322  return this->off;
323  }
324 
325  uint64_t &
326  raw()
327  {
328  conditional_add_to_tx(this);
329  return this->off;
330  }
331 
335  inline persistent_pool_ptr<T> &
336  operator++()
337  {
338  conditional_add_to_tx(this);
339  this->off += sizeof(T);
340 
341  return *this;
342  }
343 
347  inline persistent_pool_ptr<T>
348  operator++(int)
349  {
350  persistent_pool_ptr<T> ret(*this);
351  ++(*this);
352 
353  return ret;
354  }
355 
359  inline persistent_pool_ptr<T> &
360  operator--()
361  {
362  conditional_add_to_tx(this);
363  this->off -= sizeof(T);
364 
365  return *this;
366  }
367 
371  inline persistent_pool_ptr<T>
372  operator--(int)
373  {
374  persistent_pool_ptr<T> ret(*this);
375  --(*this);
376 
377  return ret;
378  }
379 
383  inline persistent_pool_ptr<T> &
384  operator+=(std::ptrdiff_t s)
385  {
386  conditional_add_to_tx(this);
387  this->off += s * sizeof(T);
388 
389  return *this;
390  }
391 
395  inline persistent_pool_ptr<T> &
396  operator-=(std::ptrdiff_t s)
397  {
398  conditional_add_to_tx(this);
399  this->off -= s * sizeof(T);
400 
401  return *this;
402  }
403 
404  inline persistent_pool_ptr<T>
405  operator+(std::ptrdiff_t s)
406  {
407  persistent_pool_ptr<T> ret(*this);
408  ret.off += s * sizeof(T);
409 
410  return ret;
411  }
412 
413  inline persistent_pool_ptr<T>
414  operator-(std::ptrdiff_t s)
415  {
416  persistent_pool_ptr<T> ret(*this);
417  ret.off -= s * sizeof(T);
418 
419  return ret;
420  }
421 
422 private:
423  /* offset of persistent object in a persistent memory pool*/
424  uint64_t off;
425 
426  void
427  verify_type()
428  {
429  static_assert(!std::is_polymorphic<element_type>::value,
430  "Polymorphic types are not supported");
431  }
432 };
433 
439 template <typename T, typename Y>
440 inline bool
441 operator==(const persistent_pool_ptr<T> &lhs,
442  const persistent_pool_ptr<Y> &rhs) noexcept
443 {
444  return lhs.raw() == rhs.raw();
445 }
446 
450 template <typename T, typename Y>
451 inline bool
452 operator!=(const persistent_pool_ptr<T> &lhs,
453  const persistent_pool_ptr<Y> &rhs) noexcept
454 {
455  return !(lhs == rhs);
456 }
457 
461 template <typename T>
462 inline bool
463 operator!=(const persistent_pool_ptr<T> &lhs, std::nullptr_t) noexcept
464 {
465  return lhs.raw() != 0;
466 }
467 
471 template <typename T>
472 inline bool
473 operator!=(std::nullptr_t, const persistent_pool_ptr<T> &lhs) noexcept
474 {
475  return lhs.raw() != 0;
476 }
477 
481 template <typename T>
482 inline bool
483 operator==(const persistent_pool_ptr<T> &lhs, std::nullptr_t) noexcept
484 {
485  return lhs.raw() == 0;
486 }
487 
491 template <typename T>
492 inline bool
493 operator==(std::nullptr_t, const persistent_pool_ptr<T> &lhs) noexcept
494 {
495  return lhs.raw() == 0;
496 }
497 
498 template <class T, class U>
499 persistent_pool_ptr<T>
500 static_persistent_pool_pointer_cast(const persistent_pool_ptr<U> &r)
501 {
502  static_assert(std::is_convertible<T *, U *>::value,
503  "Cannot cast persistent_pool_ptr");
504  return persistent_pool_ptr<T>(r.raw());
505 }
506 
507 } // namespace detail
508 } // namespace pmem
509 
510 #endif // PMEMOBJ_PERSISTENT_POOL_PTR_HPP
pmem::obj::experimental::operator-
self_relative_ptr< T > operator-(self_relative_ptr< T > const &lhs, std::ptrdiff_t s)
Subtraction operator for self-relative pointers.
Definition: self_relative_ptr.hpp:598
pmem
Persistent memory namespace.
Definition: allocation_flag.hpp:15
pmem::obj::operator++
p< T > & operator++(p< T > &pp)
Prefix increment operator overload.
Definition: pext.hpp:48
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::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::operator+=
p< T > & operator+=(p< T > &lhs, const p< Y > &rhs)
Addition assignment operator overload.
Definition: pext.hpp:94
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::operator-=
p< T > & operator-=(p< T > &lhs, const p< Y > &rhs)
Subtraction assignment operator overload.
Definition: pext.hpp:116
specialization.hpp
Helper template for persistent ptr specialization.
pmem::obj::persistent_ptr
Persistent pointer class.
Definition: persistent_ptr.hpp:152
pmem::obj::get
T & get(pmem::obj::array< T, N > &a)
Non-member get function.
Definition: array.hpp:890
pmem::obj::experimental::operator+
self_relative_ptr< T > operator+(self_relative_ptr< T > const &lhs, std::ptrdiff_t s)
Addition operator for self-relative pointers.
Definition: self_relative_ptr.hpp:586
persistent_ptr.hpp
Persistent smart pointer.
pmem::obj::operator--
p< T > & operator--(p< T > &pp)
Prefix decrement operator overload.
Definition: pext.hpp:59