PMDK C++ bindings  1.2.0
This is the C++ bindings documentation for PMDK's libpmemobj.
persistent_ptr_base.hpp
1 /*
2  * Copyright 2016-2017, 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_PTR_BASE_HPP
34 #define PMEMOBJ_PERSISTENT_PTR_BASE_HPP
35 
36 #include <type_traits>
37 
40 #include "libpmemobj.h"
41 
42 /* Windows has a max macro which collides with std::numeric_limits::max */
43 #if defined(max) && defined(_WIN32)
44 #undef max
45 #endif
46 
47 namespace pmem
48 {
49 
50 namespace detail
51 {
52 
61 template <typename T>
64 
65  template <typename U>
66  friend class persistent_ptr_base;
67 
68 public:
73  typedef typename pmem::detail::sp_element<T>::type element_type;
74 
78  persistent_ptr_base() : oid(OID_NULL)
79  {
80  verify_type();
81  }
82 
83  /*
84  * Curly braces initialization is not used because the
85  * PMEMoid is a plain C (POD) type and we can't add a default
86  * constructor in there.
87  */
88 
96  persistent_ptr_base(PMEMoid oid) noexcept : oid(oid)
97  {
98  verify_type();
99  }
100 
109  persistent_ptr_base(element_type *ptr) : oid(pmemobj_oid(ptr))
110  {
111  verify_type();
112  }
113 
119  template <typename U,
120  typename = typename std::enable_if<
121  !std::is_same<T, U>::value &&
122  std::is_same<typename std::remove_cv<T>::type,
123  U>::value>::type>
125  : oid(r.oid)
126  {
127  this->oid.off += calculate_offset<U>();
128  verify_type();
129  }
130 
136  template <
137  typename U, typename Dummy = void,
138  typename = typename std::enable_if<
139  !std::is_same<
140  typename std::remove_cv<T>::type,
141  typename std::remove_cv<U>::type>::value &&
142  !std::is_void<U>::value,
143  decltype(static_cast<T *>(std::declval<U *>()))>::type>
145  : oid(r.oid)
146  {
147  this->oid.off += calculate_offset<U>();
148  verify_type();
149  }
150 
156  template <
157  typename Y,
158  typename = typename std::enable_if<
159  !std::is_same<
160  typename std::remove_cv<T>::type,
161  typename std::remove_cv<Y>::type>::value &&
162  !std::is_void<Y>::value,
163  decltype(static_cast<T *>(std::declval<Y *>()))>::type>
164  operator persistent_ptr_base<Y>() noexcept
165  {
166  /*
167  * The offset conversion should not be required here.
168  */
169  return persistent_ptr_base<Y>(this->oid);
170  }
171 
172  /*
173  * Copy constructor.
174  *
175  * @param r Persistent pointer to the same type.
176  */
177  persistent_ptr_base(persistent_ptr_base const &r) noexcept : oid(r.oid)
178  {
179  verify_type();
180  }
181 
186  : oid(std::move(r.oid))
187  {
188  verify_type();
189  }
190 
196  {
197  detail::conditional_add_to_tx(this);
198  this->oid = std::move(r.oid);
199 
200  return *this;
201  }
202 
215  {
216  this_type(r).swap(*this);
217 
218  return *this;
219  }
220 
228  operator=(std::nullptr_t &&)
229  {
230  detail::conditional_add_to_tx(this);
231  this->oid = {0, 0};
232  return *this;
233  }
234 
246  template <typename Y,
247  typename = typename std::enable_if<
248  std::is_convertible<Y *, T *>::value>::type>
251  {
252  this_type(r).swap(*this);
253 
254  return *this;
255  }
256 
262  void
264  {
265  detail::conditional_add_to_tx(this);
266  detail::conditional_add_to_tx(&other);
267  std::swap(this->oid, other.oid);
268  }
269 
277  element_type *
278  get() const noexcept
279  {
280  if (this->oid.pool_uuid_lo ==
281  std::numeric_limits<decltype(oid.pool_uuid_lo)>::max())
282  return reinterpret_cast<element_type *>(oid.off);
283  else
284  return static_cast<element_type *>(
285  pmemobj_direct(this->oid));
286  }
287 
295  const PMEMoid &
296  raw() const noexcept
297  {
298  return this->oid;
299  }
300 
308  PMEMoid *
309  raw_ptr() noexcept
310  {
311  return &(this->oid);
312  }
313 
314  /*
315  * Bool conversion operator.
316  */
317  explicit operator bool() const noexcept
318  {
319  return get() != nullptr;
320  }
321 
322 protected:
323  /* The underlying PMEMoid of the held object. */
324  PMEMoid oid;
325 
326  /*
327  * C++ persistent memory support has following type limitations:
328  * en.cppreference.com/w/cpp/types/is_polymorphic
329  * en.cppreference.com/w/cpp/types/is_default_constructible
330  * en.cppreference.com/w/cpp/types/is_destructible
331  */
332  void
333  verify_type()
334  {
335  static_assert(!std::is_polymorphic<element_type>::value,
336  "Polymorphic types are not supported");
337  }
338 
347  {
348  if (OID_IS_NULL(oid)) {
349  oid.pool_uuid_lo = std::numeric_limits<decltype(
350  oid.pool_uuid_lo)>::max();
351  oid.off = reinterpret_cast<decltype(oid.off)>(vptr);
352  }
353  }
354 
369  template <typename U>
370  inline ptrdiff_t
372  {
373  static const ptrdiff_t ptr_offset_magic = 0xDEADBEEF;
374 
375  U *tmp{reinterpret_cast<U *>(ptr_offset_magic)};
376  T *diff = static_cast<T *>(tmp);
377  return reinterpret_cast<ptrdiff_t>(diff) -
378  reinterpret_cast<ptrdiff_t>(tmp);
379  }
380 };
381 
382 } /* namespace detail */
383 
384 } /* namespace pmem */
385 
386 #endif /* PMEMOBJ_PERSISTENT_PTR_BASE_HPP */
Persistent_ptr base class.
Definition: persistent_ptr_base.hpp:62
persistent_ptr_base & operator=(persistent_ptr_base &&r)
Defaulted move assignment operator.
Definition: persistent_ptr_base.hpp:195
Helper template for persistent ptr specialization.
persistent_ptr_base(persistent_ptr_base< U > const &r) noexcept
Copy constructor from a different persistent_ptr<>.
Definition: persistent_ptr_base.hpp:124
persistent_ptr_base & operator=(persistent_ptr_base< Y > const &r)
Converting assignment operator from a different persistent_ptr<>.
Definition: persistent_ptr_base.hpp:250
pmem::detail::sp_element< T >::type element_type
Type of an actual object with all qualifier removed, used for easy underlying type access...
Definition: persistent_ptr_base.hpp:73
void swap(persistent_ptr_base &other)
Swaps two persistent_ptr objects of the same type.
Definition: persistent_ptr_base.hpp:263
persistent_ptr_base & operator=(std::nullptr_t &&)
Nullptr move assignment operator.
Definition: persistent_ptr_base.hpp:228
persistent_ptr_base(persistent_ptr_base &&r) noexcept
Defaulted move constructor.
Definition: persistent_ptr_base.hpp:185
persistent_ptr_base(persistent_ptr_base< U > const &r) noexcept
Copy constructor from a different persistent_ptr<>.
Definition: persistent_ptr_base.hpp:144
Commonly used functionality.
persistent_ptr_base(element_type *ptr)
Volatile pointer constructor.
Definition: persistent_ptr_base.hpp:109
persistent_ptr_base()
Default constructor, zeroes the PMEMoid.
Definition: persistent_ptr_base.hpp:78
ptrdiff_t calculate_offset() const
Calculate in-object offset for structures with inheritance.
Definition: persistent_ptr_base.hpp:371
persistent_ptr_base & operator=(persistent_ptr_base const &r)
Assignment operator.
Definition: persistent_ptr_base.hpp:214
persistent_ptr_base(element_type *vptr, int)
Private constructor enabling persistent_ptrs to volatile objects.
Definition: persistent_ptr_base.hpp:346
const PMEMoid & raw() const noexcept
Get PMEMoid encapsulated by this object.
Definition: persistent_ptr_base.hpp:296
PMEMoid * raw_ptr() noexcept
Get pointer to PMEMoid encapsulated by this object.
Definition: persistent_ptr_base.hpp:309
persistent_ptr_base(PMEMoid oid) noexcept
PMEMoid constructor.
Definition: persistent_ptr_base.hpp:96
Definition: allocator.hpp:48