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
47namespace pmem
48{
49
50namespace detail
51{
52
61template <typename T>
64
65 template <typename U>
66 friend class persistent_ptr_base;
67
68public:
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
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
322protected:
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
ptrdiff_t calculate_offset() const
Calculate in-object offset for structures with inheritance.
Definition: persistent_ptr_base.hpp:371
void swap(persistent_ptr_base &other)
Swaps two persistent_ptr objects of the same type.
Definition: persistent_ptr_base.hpp:263
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 const &r)
Assignment operator.
Definition: persistent_ptr_base.hpp:214
persistent_ptr_base & operator=(persistent_ptr_base< Y > const &r)
Converting assignment operator from a different persistent_ptr<>.
Definition: persistent_ptr_base.hpp:250
const PMEMoid & raw() const noexcept
Get PMEMoid encapsulated by this object.
Definition: persistent_ptr_base.hpp:296
persistent_ptr_base(PMEMoid oid) noexcept
PMEMoid constructor.
Definition: persistent_ptr_base.hpp:96
persistent_ptr_base(persistent_ptr_base &&r) noexcept
Defaulted move constructor.
Definition: persistent_ptr_base.hpp:185
persistent_ptr_base(element_type *ptr)
Volatile pointer constructor.
Definition: persistent_ptr_base.hpp:109
persistent_ptr_base & operator=(persistent_ptr_base &&r)
Defaulted move assignment operator.
Definition: persistent_ptr_base.hpp:195
element_type * get() const noexcept
Get a direct pointer.
Definition: persistent_ptr_base.hpp:278
persistent_ptr_base(persistent_ptr_base< U > const &r) noexcept
Copy constructor from a different persistent_ptr<>.
Definition: persistent_ptr_base.hpp:144
persistent_ptr_base(element_type *vptr, int)
Private constructor enabling persistent_ptrs to volatile objects.
Definition: persistent_ptr_base.hpp:346
persistent_ptr_base()
Default constructor, zeroes the PMEMoid.
Definition: persistent_ptr_base.hpp:78
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
persistent_ptr_base & operator=(std::nullptr_t &&)
Nullptr move assignment operator.
Definition: persistent_ptr_base.hpp:228
PMEMoid * raw_ptr() noexcept
Get pointer to PMEMoid encapsulated by this object.
Definition: persistent_ptr_base.hpp:309
Commonly used functionality.
Helper template for persistent ptr specialization.