PMDK C++ bindings 1.2.0
This is the C++ bindings documentation for PMDK's libpmemobj.
persistent_ptr.hpp
Go to the documentation of this file.
1/*
2 * Copyright 2015-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
38#ifndef PMEMOBJ_PERSISTENT_PTR_HPP
39#define PMEMOBJ_PERSISTENT_PTR_HPP
40
41#include <cassert>
42#include <limits>
43#include <memory>
44#include <ostream>
45
47#include "libpmemobj++/detail/persistent_ptr_base.hpp"
49#include "libpmemobj++/pool.hpp"
50#include "libpmemobj.h"
51
52namespace pmem
53{
54
55namespace obj
56{
57
58template <typename T>
59class pool;
60
61template <typename T>
62class persistent_ptr;
63
64/*
65 * persistent_ptr void specialization.
66 */
67template <>
68class persistent_ptr<void> : public detail::persistent_ptr_base<void> {
69public:
70 persistent_ptr() = default;
71 using detail::persistent_ptr_base<void>::persistent_ptr_base;
72 using detail::persistent_ptr_base<void>::operator=;
73};
74
75/*
76 * persistent_ptr const void specialization.
77 */
78template <>
79class persistent_ptr<const void>
80 : public detail::persistent_ptr_base<const void> {
81public:
82 persistent_ptr() = default;
83 using detail::persistent_ptr_base<const void>::persistent_ptr_base;
84 using detail::persistent_ptr_base<const void>::operator=;
85};
86
101template <typename T>
103public:
104 persistent_ptr() = default;
106
110 explicit persistent_ptr(persistent_ptr<void> const &rhs) noexcept
112 {
113 }
114
118 explicit persistent_ptr(persistent_ptr<const void> const &rhs) noexcept
120 {
121 }
122
126 operator persistent_ptr<void>() const noexcept
127 {
128 return this->get();
129 }
130
134 typename pmem::detail::sp_dereference<T>::type operator*() const
135 noexcept
136 {
137 return *this->get();
138 }
139
143 typename pmem::detail::sp_member_access<T>::type operator->() const
144 noexcept
145 {
146 return this->get();
147 }
148
154 template <typename = typename std::enable_if<!std::is_void<T>::value>>
155 typename pmem::detail::sp_array_access<T>::type
156 operator[](std::ptrdiff_t i) const noexcept
157 {
158 assert(i >= 0 && (i < pmem::detail::sp_extent<T>::value ||
159 pmem::detail::sp_extent<T>::value == 0) &&
160 "persistent array index out of bounds");
161
162 return this->get()[i];
163 }
164
169 {
170 detail::conditional_add_to_tx(this);
171 this->oid.off += sizeof(T);
172
173 return *this;
174 }
175
180 {
181 PMEMoid noid = this->oid;
182 ++(*this);
183
184 return persistent_ptr<T>(noid);
185 }
186
191 {
192 detail::conditional_add_to_tx(this);
193 this->oid.off -= sizeof(T);
194
195 return *this;
196 }
197
202 {
203 PMEMoid noid = this->oid;
204 --(*this);
205
206 return persistent_ptr<T>(noid);
207 }
208
212 inline persistent_ptr<T> &
213 operator+=(std::ptrdiff_t s)
214 {
215 detail::conditional_add_to_tx(this);
216 this->oid.off += s * sizeof(T);
217
218 return *this;
219 }
220
224 inline persistent_ptr<T> &
225 operator-=(std::ptrdiff_t s)
226 {
227 detail::conditional_add_to_tx(this);
228 this->oid.off -= s * sizeof(T);
229
230 return *this;
231 }
232
238 void
240 {
241 pop.persist(this->get(), sizeof(T));
242 }
243
250 void
252 {
253 pmemobjpool *pop = pmemobj_pool_by_oid(this->raw());
254
255 if (pop == nullptr)
256 throw pool_error("Cannot get pool from "
257 "persistent pointer");
258
259 pmemobj_persist(pop, this->get(), sizeof(T));
260 }
261
267 void
269 {
270 pop.flush(this->get(), sizeof(T));
271 }
272
279 void
280 flush(void)
281 {
282 pmemobjpool *pop = pmemobj_pool_by_oid(this->raw());
283
284 if (pop == nullptr)
285 throw pool_error("Cannot get pool from "
286 "persistent pointer");
287
288 pmemobj_flush(pop, this->get(), sizeof(T));
289 }
290
291 /*
292 * Pointer traits related.
293 */
294
303 static persistent_ptr<T>
305 {
306 return persistent_ptr<T>(std::addressof(ref), 0);
307 }
308
312 template <class U>
314
319
323 using bool_type = bool;
324
325 /*
326 * Random access iterator requirements (members)
327 */
328
332 using iterator_category = std::random_access_iterator_tag;
333
337 using difference_type = std::ptrdiff_t;
338
342 using value_type = T;
343
347 using reference = T &;
348
353};
354
361template <class T>
362inline void
364{
365 a.swap(b);
366}
367
373template <typename T, typename Y>
374inline bool
375operator==(persistent_ptr<T> const &lhs, persistent_ptr<Y> const &rhs) noexcept
376{
377 return OID_EQUALS(lhs.raw(), rhs.raw());
378}
379
383template <typename T, typename Y>
384inline bool
385operator!=(persistent_ptr<T> const &lhs, persistent_ptr<Y> const &rhs) noexcept
386{
387 return !(lhs == rhs);
388}
389
393template <typename T>
394inline bool
395operator==(persistent_ptr<T> const &lhs, std::nullptr_t) noexcept
396{
397 return lhs.get() == nullptr;
398}
399
403template <typename T>
404inline bool
405operator==(std::nullptr_t, persistent_ptr<T> const &lhs) noexcept
406{
407 return lhs.get() == nullptr;
408}
409
413template <typename T>
414inline bool
415operator!=(persistent_ptr<T> const &lhs, std::nullptr_t) noexcept
416{
417 return lhs.get() != nullptr;
418}
419
423template <typename T>
424inline bool
425operator!=(std::nullptr_t, persistent_ptr<T> const &lhs) noexcept
426{
427 return lhs.get() != nullptr;
428}
429
437template <typename T, typename Y>
438inline bool
439operator<(persistent_ptr<T> const &lhs, persistent_ptr<Y> const &rhs) noexcept
440{
441 if (lhs.raw().pool_uuid_lo == rhs.raw().pool_uuid_lo)
442 return lhs.raw().off < rhs.raw().off;
443 else
444 return lhs.raw().pool_uuid_lo < rhs.raw().pool_uuid_lo;
445}
446
452template <typename T, typename Y>
453inline bool
454operator<=(persistent_ptr<T> const &lhs, persistent_ptr<Y> const &rhs) noexcept
455{
456 return !(rhs < lhs);
457}
458
464template <typename T, typename Y>
465inline bool
466operator>(persistent_ptr<T> const &lhs, persistent_ptr<Y> const &rhs) noexcept
467{
468 return (rhs < lhs);
469}
470
476template <typename T, typename Y>
477inline bool
478operator>=(persistent_ptr<T> const &lhs, persistent_ptr<Y> const &rhs) noexcept
479{
480 return !(lhs < rhs);
481}
482
483/* nullptr comparisons */
484
488template <typename T>
489inline bool
490operator<(persistent_ptr<T> const &lhs, std::nullptr_t) noexcept
491{
492 return std::less<typename persistent_ptr<T>::element_type *>()(
493 lhs.get(), nullptr);
494}
495
499template <typename T>
500inline bool
501operator<(std::nullptr_t, persistent_ptr<T> const &rhs) noexcept
502{
503 return std::less<typename persistent_ptr<T>::element_type *>()(
504 nullptr, rhs.get());
505}
506
510template <typename T>
511inline bool
512operator<=(persistent_ptr<T> const &lhs, std::nullptr_t) noexcept
513{
514 return !(nullptr < lhs);
515}
516
520template <typename T>
521inline bool
522operator<=(std::nullptr_t, persistent_ptr<T> const &rhs) noexcept
523{
524 return !(rhs < nullptr);
525}
526
530template <typename T>
531inline bool
532operator>(persistent_ptr<T> const &lhs, std::nullptr_t) noexcept
533{
534 return nullptr < lhs;
535}
536
540template <typename T>
541inline bool
542operator>(std::nullptr_t, persistent_ptr<T> const &rhs) noexcept
543{
544 return rhs < nullptr;
545}
546
550template <typename T>
551inline bool
552operator>=(persistent_ptr<T> const &lhs, std::nullptr_t) noexcept
553{
554 return !(lhs < nullptr);
555}
556
560template <typename T>
561inline bool
562operator>=(std::nullptr_t, persistent_ptr<T> const &rhs) noexcept
563{
564 return !(nullptr < rhs);
565}
566
570template <typename T>
571inline persistent_ptr<T>
572operator+(persistent_ptr<T> const &lhs, std::ptrdiff_t s)
573{
574 PMEMoid noid;
575 noid.pool_uuid_lo = lhs.raw().pool_uuid_lo;
576 noid.off = lhs.raw().off + (s * sizeof(T));
577 return persistent_ptr<T>(noid);
578}
579
583template <typename T>
584inline persistent_ptr<T>
585operator-(persistent_ptr<T> const &lhs, std::ptrdiff_t s)
586{
587 PMEMoid noid;
588 noid.pool_uuid_lo = lhs.raw().pool_uuid_lo;
589 noid.off = lhs.raw().off - (s * sizeof(T));
590 return persistent_ptr<T>(noid);
591}
592
600template <typename T, typename Y,
601 typename = typename std::enable_if<
602 std::is_same<typename std::remove_cv<T>::type,
603 typename std::remove_cv<Y>::type>::value>>
604inline ptrdiff_t
606{
607 assert(lhs.raw().pool_uuid_lo == rhs.raw().pool_uuid_lo);
608 ptrdiff_t d = lhs.raw().off - rhs.raw().off;
609
610 return d / sizeof(T);
611}
612
616template <typename T>
617std::ostream &
618operator<<(std::ostream &os, persistent_ptr<T> const &pptr)
619{
620 PMEMoid raw_oid = pptr.raw();
621 os << std::hex << "0x" << raw_oid.pool_uuid_lo << ", 0x" << raw_oid.off
622 << std::dec;
623 return os;
624}
625
626} /* namespace obj */
627
628} /* namespace pmem */
629
630#endif /* PMEMOBJ_PERSISTENT_PTR_HPP */
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:522
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:406
Persistent_ptr base class.
Definition: persistent_ptr_base.hpp:62
const PMEMoid & raw() const noexcept
Get PMEMoid encapsulated by this object.
Definition: persistent_ptr_base.hpp:296
element_type * get() const noexcept
Get a direct pointer.
Definition: persistent_ptr_base.hpp:278
Resides on pmem class.
Definition: p.hpp:64
Persistent pointer class.
Definition: persistent_ptr.hpp:102
pmem::detail::sp_dereference< T >::type operator*() const noexcept
Dereference operator.
Definition: persistent_ptr.hpp:134
pmem::detail::sp_array_access< T >::type operator[](std::ptrdiff_t i) const noexcept
Array access operator.
Definition: persistent_ptr.hpp:156
persistent_ptr(persistent_ptr< void > const &rhs) noexcept
Explicit void specialization of the converting constructor.
Definition: persistent_ptr.hpp:110
void persist(pool_base &pop)
Persists the content of the underlying object.
Definition: persistent_ptr.hpp:239
persistent_ptr< T > & operator++()
Prefix increment operator.
Definition: persistent_ptr.hpp:168
void persist(void)
Persists what the persistent pointer points to.
Definition: persistent_ptr.hpp:251
void flush(pool_base &pop)
Flushes what the persistent pointer points to.
Definition: persistent_ptr.hpp:268
bool bool_type
The used bool_type.
Definition: persistent_ptr.hpp:323
static persistent_ptr< T > pointer_to(T &ref)
Create a persistent pointer from a given reference.
Definition: persistent_ptr.hpp:304
void flush(void)
Flushes what the persistent pointer points to.
Definition: persistent_ptr.hpp:280
persistent_ptr< T > operator++(int)
Postfix increment operator.
Definition: persistent_ptr.hpp:179
persistent_ptr(persistent_ptr< const void > const &rhs) noexcept
Explicit const void specialization of the converting constructor.
Definition: persistent_ptr.hpp:118
persistent_ptr< T > & operator-=(std::ptrdiff_t s)
Subtraction assignment operator.
Definition: persistent_ptr.hpp:225
persistent_ptr< T > & operator--()
Prefix decrement operator.
Definition: persistent_ptr.hpp:190
T & reference
The reference type of the value pointed to by the persistent_ptr.
Definition: persistent_ptr.hpp:347
pmem::detail::sp_member_access< T >::type operator->() const noexcept
Member access operator.
Definition: persistent_ptr.hpp:143
std::random_access_iterator_tag iterator_category
The persistent_ptr iterator category.
Definition: persistent_ptr.hpp:332
T value_type
The type of the value pointed to by the persistent_ptr.
Definition: persistent_ptr.hpp:342
persistent_ptr< T > & operator+=(std::ptrdiff_t s)
Addition assignment operator.
Definition: persistent_ptr.hpp:213
std::ptrdiff_t difference_type
The persistent_ptr difference type.
Definition: persistent_ptr.hpp:337
persistent_ptr< T > operator--(int)
Postfix decrement operator.
Definition: persistent_ptr.hpp:201
The non-template pool base class.
Definition: pool.hpp:65
void flush(const void *addr, size_t len) noexcept
Performs flush operation on a given chunk of memory.
Definition: pool.hpp:318
void persist(const void *addr, size_t len) noexcept
Performs persist operation on a given chunk of memory.
Definition: pool.hpp:282
Custom pool error class.
Definition: pexceptions.hpp:53
Commonly used functionality.
void swap(p< T > &a, p< T > &b)
Swaps two p objects of the same type.
Definition: p.hpp:187
bool operator<=(persistent_ptr< T > const &lhs, persistent_ptr< Y > const &rhs) noexcept
Less or equal than operator.
Definition: persistent_ptr.hpp:454
bool operator<(persistent_ptr< T > const &lhs, persistent_ptr< Y > const &rhs) noexcept
Less than operator.
Definition: persistent_ptr.hpp:439
bool operator>(persistent_ptr< T > const &lhs, persistent_ptr< Y > const &rhs) noexcept
Greater than operator.
Definition: persistent_ptr.hpp:466
std::ostream & operator<<(std::ostream &os, persistent_ptr< T > const &pptr)
Ostream operator for the persistent pointer.
Definition: persistent_ptr.hpp:618
bool operator>=(persistent_ptr< T > const &lhs, persistent_ptr< Y > const &rhs) noexcept
Greater or equal than operator.
Definition: persistent_ptr.hpp:478
persistent_ptr< T > operator-(persistent_ptr< T > const &lhs, std::ptrdiff_t s)
Subtraction operator for persistent pointers.
Definition: persistent_ptr.hpp:585
persistent_ptr< T > operator+(persistent_ptr< T > const &lhs, std::ptrdiff_t s)
Addition operator for persistent pointers.
Definition: persistent_ptr.hpp:572
C++ pmemobj pool.
Helper template for persistent ptr specialization.