PMDK C++ bindings  1.13.0-git107.g7e59f08f
This is the C++ bindings documentation for PMDK's libpmemobj.
persistent_pool_ptr.hpp
Go to the documentation of this file.
1 // SPDX-License-Identifier: BSD-3-Clause
2 /* Copyright 2018-2021, Intel Corporation */
3 
9 #ifndef PMEMOBJ_PERSISTENT_POOL_PTR_HPP
10 #define PMEMOBJ_PERSISTENT_POOL_PTR_HPP
11 
12 #include <cassert>
13 #include <cstddef>
14 #include <type_traits>
15 
18 
19 namespace pmem
20 {
21 namespace detail
22 {
23 
24 template <typename T>
25 class persistent_pool_ptr {
26  template <typename Y>
27  friend class persistent_pool_ptr;
28 
29  typedef persistent_pool_ptr<T> this_type;
30 
31 public:
36  typedef typename pmem::detail::sp_element<T>::type element_type;
37 
38  persistent_pool_ptr() : off(0)
39  {
40  verify_type();
41  }
42 
46  persistent_pool_ptr(std::nullptr_t) noexcept : off(0)
47  {
48  verify_type();
49  }
50 
58  persistent_pool_ptr(PMEMoid oid) noexcept : off(oid.off)
59  {
60  verify_type();
61  }
62 
70  persistent_pool_ptr(uint64_t _off) noexcept : off(_off)
71  {
72  verify_type();
73  }
74 
81  template <typename Y,
82  typename = typename std::enable_if<
83  std::is_convertible<Y *, T *>::value>::type>
84  persistent_pool_ptr(const persistent_pool_ptr<Y> &r) noexcept
85  : off(r.off)
86  {
87  verify_type();
88  }
89 
96  template <typename Y,
97  typename = typename std::enable_if<
98  std::is_convertible<Y *, T *>::value>::type>
99  persistent_pool_ptr(const pmem::obj::persistent_ptr<Y> &r) noexcept
100  : off(r.raw().off)
101  {
102  verify_type();
103  }
104 
105  /*
106  * Copy constructor.
107  *
108  * @param r Persistent pool pointer to the same type.
109  */
110  persistent_pool_ptr(const persistent_pool_ptr &r) noexcept : off(r.off)
111  {
112  verify_type();
113  }
114 
115  /*
116  * Copy constructor from a persistent_ptr.
117  *
118  * @param r Persistent pointer to the same type.
119  */
120  persistent_pool_ptr(const pmem::obj::persistent_ptr<T> &r) noexcept
121  : off(r.raw().off)
122  {
123  verify_type();
124  }
125 
129  persistent_pool_ptr(persistent_pool_ptr &&r) noexcept
130  : off(std::move(r.off))
131  {
132  verify_type();
133  }
134 
138  persistent_pool_ptr &
139  operator=(persistent_pool_ptr &&r)
140  {
141  conditional_add_to_tx(this);
142  this->off = std::move(r.off);
143 
144  return *this;
145  }
146 
147  persistent_pool_ptr &operator=(std::nullptr_t)
148  {
149  conditional_add_to_tx(this);
150  this->off = 0;
151 
152  return *this;
153  }
154 
165  persistent_pool_ptr &
166  operator=(const persistent_pool_ptr &r)
167  {
168  conditional_add_to_tx(this);
169  this->off = r.off;
170 
171  return *this;
172  }
173 
184  persistent_pool_ptr &
185  operator=(const pmem::obj::persistent_ptr<T> &r)
186  {
187  conditional_add_to_tx(this);
188  this->off = r.raw().off;
189 
190  return *this;
191  }
192 
203  persistent_pool_ptr &
204  operator=(const PMEMoid &oid)
205  {
206  conditional_add_to_tx(this);
207  this->off = oid.off;
208  return *this;
209  }
210 
222  template <typename Y,
223  typename = typename std::enable_if<
224  std::is_convertible<Y *, T *>::value>::type>
225  persistent_pool_ptr &
226  operator=(const persistent_pool_ptr<Y> &r)
227  {
228  conditional_add_to_tx(this);
229  this->off = r.off;
230 
231  return *this;
232  }
233 
245  template <typename Y,
246  typename = typename std::enable_if<
247  std::is_convertible<Y *, T *>::value>::type>
248  persistent_pool_ptr &
249  operator=(const pmem::obj::persistent_ptr<Y> &r)
250  {
251  conditional_add_to_tx(this);
252  this->off = r.raw().off;
253 
254  return *this;
255  }
256 
264  element_type *
265  get(uint64_t pool_uuid) const noexcept
266  {
267  PMEMoid oid = {pool_uuid, this->off};
268  return static_cast<element_type *>(pmemobj_direct(oid));
269  }
270 
271  element_type *
272  operator()(uint64_t pool_uuid) const noexcept
273  {
274  return get(pool_uuid);
275  }
276 
285  get_persistent_ptr(uint64_t pool_uuid) const noexcept
286  {
287  PMEMoid oid = {pool_uuid, this->off};
288  return pmem::obj::persistent_ptr<T>(oid);
289  }
290 
294  void
295  swap(persistent_pool_ptr &other)
296  {
297  conditional_add_to_tx(this);
298  conditional_add_to_tx(&other);
299  std::swap(this->off, other.off);
300  }
301 
302  /*
303  * Bool conversion operator.
304  */
305  explicit operator bool() const noexcept
306  {
307  return this->off != 0;
308  }
309 
317  PMEMoid
318  raw_oid(uint64_t pool_uuid) const noexcept
319  {
320  PMEMoid oid = {pool_uuid, this->off};
321  return oid;
322  }
323 
324  const uint64_t &
325  raw() const noexcept
326  {
327  return this->off;
328  }
329 
330  uint64_t &
331  raw()
332  {
333  conditional_add_to_tx(this);
334  return this->off;
335  }
336 
340  inline persistent_pool_ptr<T> &
341  operator++()
342  {
343  conditional_add_to_tx(this);
344  this->off += sizeof(T);
345 
346  return *this;
347  }
348 
352  inline persistent_pool_ptr<T>
353  operator++(int)
354  {
355  persistent_pool_ptr<T> ret(*this);
356  ++(*this);
357 
358  return ret;
359  }
360 
364  inline persistent_pool_ptr<T> &
365  operator--()
366  {
367  conditional_add_to_tx(this);
368  this->off -= sizeof(T);
369 
370  return *this;
371  }
372 
376  inline persistent_pool_ptr<T>
377  operator--(int)
378  {
379  persistent_pool_ptr<T> ret(*this);
380  --(*this);
381 
382  return ret;
383  }
384 
388  inline persistent_pool_ptr<T> &
389  operator+=(std::ptrdiff_t s)
390  {
391  conditional_add_to_tx(this);
392  this->off += s * sizeof(T);
393 
394  return *this;
395  }
396 
400  inline persistent_pool_ptr<T> &
401  operator-=(std::ptrdiff_t s)
402  {
403  conditional_add_to_tx(this);
404  this->off -= s * sizeof(T);
405 
406  return *this;
407  }
408 
409  inline persistent_pool_ptr<T>
410  operator+(std::ptrdiff_t s)
411  {
412  persistent_pool_ptr<T> ret(*this);
413  ret.off += s * sizeof(T);
414 
415  return ret;
416  }
417 
418  inline persistent_pool_ptr<T>
419  operator-(std::ptrdiff_t s)
420  {
421  persistent_pool_ptr<T> ret(*this);
422  ret.off -= s * sizeof(T);
423 
424  return ret;
425  }
426 
427 private:
428  /* offset of persistent object in a persistent memory pool */
429  uint64_t off;
430 
431  void
432  verify_type()
433  {
434  static_assert(!std::is_polymorphic<element_type>::value,
435  "Polymorphic types are not supported");
436  }
437 };
438 
445 template <typename T, typename Y>
446 inline bool
447 operator==(const persistent_pool_ptr<T> &lhs,
448  const persistent_pool_ptr<Y> &rhs) noexcept
449 {
450  return lhs.raw() == rhs.raw();
451 }
452 
457 template <typename T, typename Y>
458 inline bool
459 operator!=(const persistent_pool_ptr<T> &lhs,
460  const persistent_pool_ptr<Y> &rhs) noexcept
461 {
462  return !(lhs == rhs);
463 }
464 
469 template <typename T>
470 inline bool
471 operator!=(const persistent_pool_ptr<T> &lhs, std::nullptr_t) noexcept
472 {
473  return lhs.raw() != 0;
474 }
475 
480 template <typename T>
481 inline bool
482 operator!=(std::nullptr_t, const persistent_pool_ptr<T> &lhs) noexcept
483 {
484  return lhs.raw() != 0;
485 }
486 
491 template <typename T>
492 inline bool
493 operator==(const persistent_pool_ptr<T> &lhs, std::nullptr_t) noexcept
494 {
495  return lhs.raw() == 0;
496 }
497 
502 template <typename T>
503 inline bool
504 operator==(std::nullptr_t, const persistent_pool_ptr<T> &lhs) noexcept
505 {
506  return lhs.raw() == 0;
507 }
508 
509 template <class T, class U>
510 persistent_pool_ptr<T>
511 static_persistent_pool_pointer_cast(const persistent_pool_ptr<U> &r)
512 {
513  static_assert(std::is_convertible<T *, U *>::value,
514  "Cannot cast persistent_pool_ptr");
515  return persistent_pool_ptr<T>(r.raw());
516 }
517 
518 } // namespace detail
519 } // namespace pmem
520 
521 #endif // PMEMOBJ_PERSISTENT_POOL_PTR_HPP
const PMEMoid & raw() const noexcept
Get PMEMoid encapsulated by this object.
Definition: persistent_ptr_base.hpp:151
Persistent pointer class.
Definition: persistent_ptr.hpp:153
void conditional_add_to_tx(const T *that, std::size_t count=1, uint64_t flags=0)
Conditionally add 'count' objects to a transaction.
Definition: common.hpp:176
Persistent memory namespace.
Definition: allocation_flag.hpp:15
Persistent smart pointer.
Helper template for persistent ptr specialization.