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 
52 namespace pmem
53 {
54 
55 namespace obj
56 {
57 
58 template <typename T>
59 class pool;
60 
61 template <typename T>
62 class persistent_ptr;
63 
64 /*
65  * persistent_ptr void specialization.
66  */
67 template <>
68 class persistent_ptr<void> : public detail::persistent_ptr_base<void> {
69 public:
70  persistent_ptr() = default;
73 };
74 
75 /*
76  * persistent_ptr const void specialization.
77  */
78 template <>
79 class persistent_ptr<const void>
80  : public detail::persistent_ptr_base<const void> {
81 public:
82  persistent_ptr() = default;
85 };
86 
101 template <typename T>
102 class persistent_ptr : public detail::persistent_ptr_base<T> {
103 public:
104  persistent_ptr() = default;
106 
110  explicit persistent_ptr(persistent_ptr<void> const &rhs) noexcept
111  : detail::persistent_ptr_base<T>(rhs.raw())
112  {
113  }
114 
118  explicit persistent_ptr(persistent_ptr<const void> const &rhs) noexcept
119  : detail::persistent_ptr_base<T>(rhs.raw())
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
251  persist(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>
304  pointer_to(T &ref)
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 
361 template <class T>
362 inline void
364 {
365  a.swap(b);
366 }
367 
373 template <typename T, typename Y>
374 inline bool
375 operator==(persistent_ptr<T> const &lhs, persistent_ptr<Y> const &rhs) noexcept
376 {
377  return OID_EQUALS(lhs.raw(), rhs.raw());
378 }
379 
383 template <typename T, typename Y>
384 inline bool
385 operator!=(persistent_ptr<T> const &lhs, persistent_ptr<Y> const &rhs) noexcept
386 {
387  return !(lhs == rhs);
388 }
389 
393 template <typename T>
394 inline bool
395 operator==(persistent_ptr<T> const &lhs, std::nullptr_t) noexcept
396 {
397  return lhs.get() == nullptr;
398 }
399 
403 template <typename T>
404 inline bool
405 operator==(std::nullptr_t, persistent_ptr<T> const &lhs) noexcept
406 {
407  return lhs.get() == nullptr;
408 }
409 
413 template <typename T>
414 inline bool
415 operator!=(persistent_ptr<T> const &lhs, std::nullptr_t) noexcept
416 {
417  return lhs.get() != nullptr;
418 }
419 
423 template <typename T>
424 inline bool
425 operator!=(std::nullptr_t, persistent_ptr<T> const &lhs) noexcept
426 {
427  return lhs.get() != nullptr;
428 }
429 
437 template <typename T, typename Y>
438 inline bool
439 operator<(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 
452 template <typename T, typename Y>
453 inline bool
454 operator<=(persistent_ptr<T> const &lhs, persistent_ptr<Y> const &rhs) noexcept
455 {
456  return !(rhs < lhs);
457 }
458 
464 template <typename T, typename Y>
465 inline bool
466 operator>(persistent_ptr<T> const &lhs, persistent_ptr<Y> const &rhs) noexcept
467 {
468  return (rhs < lhs);
469 }
470 
476 template <typename T, typename Y>
477 inline bool
478 operator>=(persistent_ptr<T> const &lhs, persistent_ptr<Y> const &rhs) noexcept
479 {
480  return !(lhs < rhs);
481 }
482 
483 /* nullptr comparisons */
484 
488 template <typename T>
489 inline bool
490 operator<(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 
499 template <typename T>
500 inline bool
501 operator<(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 
510 template <typename T>
511 inline bool
512 operator<=(persistent_ptr<T> const &lhs, std::nullptr_t) noexcept
513 {
514  return !(nullptr < lhs);
515 }
516 
520 template <typename T>
521 inline bool
522 operator<=(std::nullptr_t, persistent_ptr<T> const &rhs) noexcept
523 {
524  return !(rhs < nullptr);
525 }
526 
530 template <typename T>
531 inline bool
532 operator>(persistent_ptr<T> const &lhs, std::nullptr_t) noexcept
533 {
534  return nullptr < lhs;
535 }
536 
540 template <typename T>
541 inline bool
542 operator>(std::nullptr_t, persistent_ptr<T> const &rhs) noexcept
543 {
544  return rhs < nullptr;
545 }
546 
550 template <typename T>
551 inline bool
552 operator>=(persistent_ptr<T> const &lhs, std::nullptr_t) noexcept
553 {
554  return !(lhs < nullptr);
555 }
556 
560 template <typename T>
561 inline bool
562 operator>=(std::nullptr_t, persistent_ptr<T> const &rhs) noexcept
563 {
564  return !(nullptr < rhs);
565 }
566 
570 template <typename T>
571 inline persistent_ptr<T>
572 operator+(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 
583 template <typename T>
584 inline persistent_ptr<T>
585 operator-(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 
600 template <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>>
604 inline 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 
616 template <typename T>
617 std::ostream &
618 operator<<(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==(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< T > & operator++()
Prefix increment operator.
Definition: persistent_ptr.hpp:168
Persistent_ptr base class.
Definition: persistent_ptr_base.hpp:62
void persist(void)
Persists what the persistent pointer points to.
Definition: persistent_ptr.hpp:251
Helper template for persistent ptr specialization.
Persistent pointer class.
Definition: common.hpp:51
pmem::detail::sp_member_access< T >::type operator->() const noexcept
Member access operator.
Definition: persistent_ptr.hpp:143
The non-template pool base class.
Definition: pool.hpp:65
Custom pool error class.
Definition: pexceptions.hpp:53
persistent_ptr< T > & operator-=(std::ptrdiff_t s)
Subtraction assignment operator.
Definition: persistent_ptr.hpp:225
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++(int)
Postfix increment operator.
Definition: persistent_ptr.hpp:179
bool operator>=(persistent_ptr< T > const &lhs, persistent_ptr< Y > const &rhs) noexcept
Greater or equal than operator.
Definition: persistent_ptr.hpp:478
void persist(pool_base &pop)
Persists the content of the underlying object.
Definition: persistent_ptr.hpp:239
bool bool_type
The used bool_type.
Definition: persistent_ptr.hpp:323
void flush(pool_base &pop)
Flushes what the persistent pointer points to.
Definition: persistent_ptr.hpp:268
PMEMobj pool class.
Definition: persistent_ptr.hpp:59
persistent_ptr< T > operator--(int)
Postfix decrement operator.
Definition: persistent_ptr.hpp:201
persistent_ptr< T > operator+(persistent_ptr< T > const &lhs, std::ptrdiff_t s)
Addition operator for persistent pointers.
Definition: persistent_ptr.hpp:572
Commonly used functionality.
std::random_access_iterator_tag iterator_category
The persistent_ptr iterator category.
Definition: persistent_ptr.hpp:332
persistent_ptr< T > & operator--()
Prefix decrement operator.
Definition: persistent_ptr.hpp:190
persistent_ptr< T > & operator+=(std::ptrdiff_t s)
Addition assignment operator.
Definition: persistent_ptr.hpp:213
void flush(void)
Flushes what the persistent pointer points to.
Definition: persistent_ptr.hpp:280
void persist(const void *addr, size_t len) noexcept
Performs persist operation on a given chunk of memory.
Definition: pool.hpp:282
pmem::detail::sp_array_access< T >::type operator[](std::ptrdiff_t i) const noexcept
Array access operator.
Definition: persistent_ptr.hpp:156
static persistent_ptr< T > pointer_to(T &ref)
Create a persistent pointer from a given reference.
Definition: persistent_ptr.hpp:304
persistent_ptr< T > operator-(persistent_ptr< T > const &lhs, std::ptrdiff_t s)
Subtraction operator for persistent pointers.
Definition: persistent_ptr.hpp:585
const PMEMoid & raw() const noexcept
Get PMEMoid encapsulated by this object.
Definition: persistent_ptr_base.hpp:296
pmem::detail::sp_dereference< T >::type operator*() const noexcept
Dereference operator.
Definition: persistent_ptr.hpp:134
Resides on pmem class.
Definition: p.hpp:64
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
T value_type
The type of the value pointed to by the persistent_ptr.
Definition: persistent_ptr.hpp:342
Definition: allocator.hpp:48
void flush(const void *addr, size_t len) noexcept
Performs flush operation on a given chunk of memory.
Definition: pool.hpp:318
std::ptrdiff_t difference_type
The persistent_ptr difference type.
Definition: persistent_ptr.hpp:337
bool operator>(persistent_ptr< T > const &lhs, persistent_ptr< Y > const &rhs) noexcept
Greater than operator.
Definition: persistent_ptr.hpp:466
persistent_ptr(persistent_ptr< void > const &rhs) noexcept
Explicit void specialization of the converting constructor.
Definition: persistent_ptr.hpp:110
C++ pmemobj pool.
void swap(p< T > &a, p< T > &b)
Swaps two p objects of the same type.
Definition: p.hpp:187
T & reference
The reference type of the value pointed to by the persistent_ptr.
Definition: persistent_ptr.hpp:347