PMDK C++ bindings  1.7
This is the C++ bindings documentation for PMDK's libpmemobj.
persistent_pool_ptr.hpp
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 
33 #ifndef PMEMOBJ_PERSISTENT_POOL_PTR_HPP
34 #define PMEMOBJ_PERSISTENT_POOL_PTR_HPP
35 
36 #include <cassert>
37 #include <cstddef>
38 #include <type_traits>
39 
42 
43 namespace pmem
44 {
45 namespace detail
46 {
47 
48 using namespace pmem;
49 using namespace pmem::obj;
50 
51 template <typename T>
52 class persistent_pool_ptr {
53  template <typename Y>
54  friend class persistent_pool_ptr;
55 
56  typedef persistent_pool_ptr<T> this_type;
57 
58 public:
63  typedef typename pmem::detail::sp_element<T>::type element_type;
64 
65  persistent_pool_ptr() : off(0)
66  {
67  verify_type();
68  }
69 
73  persistent_pool_ptr(std::nullptr_t) noexcept : off(0)
74  {
75  verify_type();
76  }
77 
85  persistent_pool_ptr(PMEMoid oid) noexcept : off(oid.off)
86  {
87  verify_type();
88  }
89 
97  persistent_pool_ptr(uint64_t _off) noexcept : off(_off)
98  {
99  verify_type();
100  }
101 
108  template <typename Y,
109  typename = typename std::enable_if<
110  std::is_convertible<Y *, T *>::value>::type>
111  persistent_pool_ptr(const persistent_pool_ptr<Y> &r) noexcept
112  : off(r.off)
113  {
114  verify_type();
115  }
116 
123  template <typename Y,
124  typename = typename std::enable_if<
125  std::is_convertible<Y *, T *>::value>::type>
126  persistent_pool_ptr(const persistent_ptr<Y> &r) noexcept
127  : off(r.raw().off)
128  {
129  verify_type();
130  }
131 
132  /*
133  * Copy constructor.
134  *
135  * @param r Persistent pool pointer to the same type.
136  */
137  persistent_pool_ptr(const persistent_pool_ptr &r) noexcept : off(r.off)
138  {
139  verify_type();
140  }
141 
142  /*
143  * Copy constructor from a persistent_ptr.
144  *
145  * @param r Persistent pointer to the same type.
146  */
147  persistent_pool_ptr(const persistent_ptr<T> &r) noexcept
148  : off(r.raw().off)
149  {
150  verify_type();
151  }
152 
156  persistent_pool_ptr(persistent_pool_ptr &&r) noexcept
157  : off(std::move(r.off))
158  {
159  verify_type();
160  }
161 
165  persistent_pool_ptr &
166  operator=(persistent_pool_ptr &&r)
167  {
168  conditional_add_to_tx(this);
169  this->off = std::move(r.off);
170 
171  return *this;
172  }
173 
174  persistent_pool_ptr &operator=(std::nullptr_t)
175  {
176  conditional_add_to_tx(this);
177  this->off = 0;
178 
179  return *this;
180  }
181 
192  persistent_pool_ptr &
193  operator=(const persistent_pool_ptr &r)
194  {
195  conditional_add_to_tx(this);
196  this->off = r.off;
197 
198  return *this;
199  }
200 
211  persistent_pool_ptr &
212  operator=(const persistent_ptr<T> &r)
213  {
214  conditional_add_to_tx(this);
215  this->off = r.raw().off;
216 
217  return *this;
218  }
219 
230  persistent_pool_ptr &
231  operator=(const PMEMoid &oid)
232  {
233  conditional_add_to_tx(this);
234  this->off = oid.off;
235  return *this;
236  }
237 
249  template <typename Y,
250  typename = typename std::enable_if<
251  std::is_convertible<Y *, T *>::value>::type>
252  persistent_pool_ptr &
253  operator=(const persistent_pool_ptr<Y> &r)
254  {
255  conditional_add_to_tx(this);
256  this->off = r.off;
257 
258  return *this;
259  }
260 
272  template <typename Y,
273  typename = typename std::enable_if<
274  std::is_convertible<Y *, T *>::value>::type>
275  persistent_pool_ptr &
276  operator=(const persistent_ptr<Y> &r)
277  {
278  conditional_add_to_tx(this);
279  this->off = r.raw().off;
280 
281  return *this;
282  }
283 
291  element_type *
292  get(uint64_t pool_uuid) const noexcept
293  {
294  PMEMoid oid = {pool_uuid, this->off};
295  return static_cast<element_type *>(pmemobj_direct(oid));
296  }
297 
298  element_type *
299  operator()(uint64_t pool_uuid) const noexcept
300  {
301  return get(pool_uuid);
302  }
303 
312  get_persistent_ptr(uint64_t pool_uuid) const noexcept
313  {
314  PMEMoid oid = {pool_uuid, this->off};
315  return persistent_ptr<T>(oid);
316  }
317 
321  void
322  swap(persistent_pool_ptr &other) noexcept
323  {
324  conditional_add_to_tx(this);
325  conditional_add_to_tx(&other);
326  std::swap(this->off, other.off);
327  }
328 
329  /*
330  * Bool conversion operator.
331  */
332  explicit operator bool() const noexcept
333  {
334  return this->off != 0;
335  }
336 
344  PMEMoid
345  raw_oid(uint64_t pool_uuid) const noexcept
346  {
347  PMEMoid oid = {pool_uuid, this->off};
348  return oid;
349  }
350 
351  const uint64_t &
352  raw() const noexcept
353  {
354  return this->off;
355  }
356 
357  uint64_t &
358  raw()
359  {
360  conditional_add_to_tx(this);
361  return this->off;
362  }
363 
367  inline persistent_pool_ptr<T> &
368  operator++()
369  {
370  conditional_add_to_tx(this);
371  this->off += sizeof(T);
372 
373  return *this;
374  }
375 
379  inline persistent_pool_ptr<T>
380  operator++(int)
381  {
382  persistent_pool_ptr<T> ret(*this);
383  ++(*this);
384 
385  return ret;
386  }
387 
391  inline persistent_pool_ptr<T> &
392  operator--()
393  {
394  conditional_add_to_tx(this);
395  this->off -= sizeof(T);
396 
397  return *this;
398  }
399 
403  inline persistent_pool_ptr<T>
404  operator--(int)
405  {
406  persistent_pool_ptr<T> ret(*this);
407  --(*this);
408 
409  return ret;
410  }
411 
415  inline persistent_pool_ptr<T> &
416  operator+=(std::ptrdiff_t s)
417  {
418  conditional_add_to_tx(this);
419  this->off += s * sizeof(T);
420 
421  return *this;
422  }
423 
427  inline persistent_pool_ptr<T> &
428  operator-=(std::ptrdiff_t s)
429  {
430  conditional_add_to_tx(this);
431  this->off -= s * sizeof(T);
432 
433  return *this;
434  }
435 
436  inline persistent_pool_ptr<T>
437  operator+(std::ptrdiff_t s)
438  {
439  persistent_pool_ptr<T> ret(*this);
440  ret.off += s * sizeof(T);
441 
442  return ret;
443  }
444 
445  inline persistent_pool_ptr<T>
446  operator-(std::ptrdiff_t s)
447  {
448  persistent_pool_ptr<T> ret(*this);
449  ret.off -= s * sizeof(T);
450 
451  return ret;
452  }
453 
454 private:
455  /* offset of persistent object in a persistent memory pool*/
456  uint64_t off;
457 
458  void
459  verify_type()
460  {
461  static_assert(!std::is_polymorphic<element_type>::value,
462  "Polymorphic types are not supported");
463  }
464 };
465 
471 template <typename T, typename Y>
472 inline bool
473 operator==(const persistent_pool_ptr<T> &lhs,
474  const persistent_pool_ptr<Y> &rhs) noexcept
475 {
476  return lhs.raw() == rhs.raw();
477 }
478 
482 template <typename T, typename Y>
483 inline bool
484 operator!=(const persistent_pool_ptr<T> &lhs,
485  const persistent_pool_ptr<Y> &rhs) noexcept
486 {
487  return !(lhs == rhs);
488 }
489 
493 template <typename T>
494 inline bool
495 operator!=(const persistent_pool_ptr<T> &lhs, std::nullptr_t) noexcept
496 {
497  return lhs.raw() != 0;
498 }
499 
503 template <typename T>
504 inline bool
505 operator!=(std::nullptr_t, const persistent_pool_ptr<T> &lhs) noexcept
506 {
507  return lhs.raw() != 0;
508 }
509 
513 template <typename T>
514 inline bool
515 operator==(const persistent_pool_ptr<T> &lhs, std::nullptr_t) noexcept
516 {
517  return lhs.raw() == 0;
518 }
519 
523 template <typename T>
524 inline bool
525 operator==(std::nullptr_t, const persistent_pool_ptr<T> &lhs) noexcept
526 {
527  return lhs.raw() == 0;
528 }
529 
530 template <class T, class U>
531 persistent_pool_ptr<T>
532 static_persistent_pool_pointer_cast(const persistent_pool_ptr<U> &r)
533 {
534  static_assert(std::is_convertible<T *, U *>::value,
535  "Cannot cast persistent_pool_ptr");
536  return persistent_pool_ptr<T>(r.raw());
537 }
538 
539 } // namespace detail
540 } // namespace pmem
541 
542 #endif // PMEMOBJ_PERSISTENT_POOL_PTR_HPP
pmem::obj::experimental::get
T & get(pmem::obj::experimental::array< T, N > &a)
Non-member get function.
Definition: array.hpp:908
pmem::obj::operator+=
p< T > & operator+=(p< T > &lhs, const p< Y > &rhs)
Addition assignment operator overload.
Definition: pext.hpp:123
pmem::obj::experimental::swap
void swap(pmem::obj::experimental::array< T, N > &lhs, pmem::obj::experimental::array< T, N > &rhs)
Non-member swap function.
Definition: array.hpp:897
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:516
specialization.hpp
Helper template for persistent ptr specialization.
pmem::obj::persistent_ptr
Persistent pointer class.
Definition: persistent_ptr.hpp:132
pmem::obj::operator-=
p< T > & operator-=(p< T > &lhs, const p< Y > &rhs)
Subtraction assignment operator overload.
Definition: pext.hpp:145
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:400
pmem::obj::operator++
p< T > & operator++(p< T > &pp)
Prefix increment operator overload.
Definition: pext.hpp:77
pmem::obj::operator+
persistent_ptr< T > operator+(persistent_ptr< T > const &lhs, std::ptrdiff_t s)
Addition operator for persistent pointers.
Definition: persistent_ptr.hpp:607
persistent_ptr.hpp
Persistent smart pointer.
pmem::obj::operator-
persistent_ptr< T > operator-(persistent_ptr< T > const &lhs, std::ptrdiff_t s)
Subtraction operator for persistent pointers.
Definition: persistent_ptr.hpp:621
pmem::obj::operator--
p< T > & operator--(p< T > &pp)
Prefix decrement operator overload.
Definition: pext.hpp:88