PMDK C++ bindings  1.13.0-git107.g7e59f08f
This is the C++ bindings documentation for PMDK's libpmemobj.
self_relative_ptr.hpp
Go to the documentation of this file.
1 // SPDX-License-Identifier: BSD-3-Clause
2 /* Copyright 2020-2021, Intel Corporation */
3 
9 #ifndef LIBPMEMOBJ_CPP_SELF_RELATIVE_PTR_HPP
10 #define LIBPMEMOBJ_CPP_SELF_RELATIVE_PTR_HPP
11 
15 #include <type_traits>
16 
17 namespace pmem
18 {
19 namespace obj
20 {
21 namespace experimental
22 {
23 
24 template <typename T>
25 class self_relative_ptr;
26 
27 template <>
28 class self_relative_ptr<void> : public self_relative_ptr_base {
29 public:
30  using base_type = self_relative_ptr_base;
31  using this_type = self_relative_ptr;
32  using element_type = void;
33 
34  constexpr self_relative_ptr() noexcept = default;
35 
36  constexpr self_relative_ptr(std::nullptr_t) noexcept
38  {
39  }
40 
41  self_relative_ptr(element_type *ptr) noexcept
42  : self_relative_ptr_base(self_offset(ptr))
43  {
44  }
45 
46  inline element_type *
47  get() const noexcept
48  {
49  return static_cast<element_type *>(
51  }
52 
53 private:
55  self_offset(element_type *ptr) const noexcept
56  {
57  return base_type::pointer_to_offset(static_cast<void *>(ptr));
58  }
59 };
60 
81 template <typename T>
83 public:
86  using element_type = typename pmem::detail::sp_element<T>::type;
87 
95  using iterator_category = std::random_access_iterator_tag;
96 
100  using difference_type = typename base_type::difference_type;
101 
105  using value_type = T;
106 
110  using reference = T &;
111 
112  /*
113  * Constructors
114  */
115 
119  constexpr self_relative_ptr() noexcept = default;
120 
124  constexpr self_relative_ptr(std::nullptr_t) noexcept
126  {
127  }
128 
134  self_relative_ptr(element_type *ptr) noexcept
135  : self_relative_ptr_base(self_offset(ptr))
136  {
137  }
138 
143  : self_relative_ptr_base(self_offset(ptr.get()))
144  {
145  }
146 
154  self_relative_ptr(PMEMoid oid) noexcept
155  : self_relative_ptr_base(self_offset(
156  static_cast<element_type *>(pmemobj_direct(oid))))
157  {
158  }
159 
165  {
166  }
167 
173  template <
174  typename U,
175  typename = typename std::enable_if<
176  !std::is_same<
177  typename std::remove_cv<T>::type,
178  typename std::remove_cv<U>::type>::value &&
179  !std::is_void<U>::value,
180  decltype(static_cast<T *>(std::declval<U *>()))>::type>
182  : self_relative_ptr_base(self_offset(static_cast<T *>(r.get())))
183  {
184  }
185 
187  {
188  verify_type();
189  }
190 
196  inline element_type *
197  get() const noexcept
198  {
199  return static_cast<element_type *>(
201  }
202 
208  {
209  return persistent_ptr<T>{this->get()};
210  }
211 
212  /*
213  * Operators
214  */
215 
219  explicit operator bool() const noexcept
220  {
221  return !is_null();
222  }
223 
227  operator persistent_ptr<T>() const
228  {
229  return to_persistent_ptr();
230  }
231 
235  typename pmem::detail::sp_dereference<T>::type operator*() const
236  noexcept
237  {
238  return *(this->get());
239  }
240 
244  typename pmem::detail::sp_member_access<T>::type operator->() const
245  noexcept
246  {
247  return this->get();
248  }
249 
255  template <typename = typename std::enable_if<!std::is_void<T>::value>>
256  typename pmem::detail::sp_array_access<T>::type
257  operator[](difference_type i) const noexcept
258  {
259  assert(i >= 0 &&
260  (i < pmem::detail::sp_extent<T>::value ||
261  pmem::detail::sp_extent<T>::value == 0) &&
262  "persistent array index out of bounds");
263 
264  return this->get()[i];
265  }
266 
279  {
280  this->base_type::operator=(r);
281  return *this;
282  }
283 
295  template <typename Y,
296  typename = typename std::enable_if<
297  std::is_convertible<Y *, T *>::value>::type>
300  {
301  this_type(r).swap(*this);
302  return *this;
303  }
304 
311  self_relative_ptr &operator=(std::nullptr_t)
312  {
314  this->offset = self_offset(nullptr);
315  return *this;
316  }
317 
321  inline self_relative_ptr<T> &
323  {
325  this->offset += static_cast<difference_type>(sizeof(T));
326 
327  return *this;
328  }
329 
333  inline self_relative_ptr<T>
335  {
336  auto copy = *this;
337  ++(*this);
338 
339  return copy;
340  }
341 
345  inline self_relative_ptr<T> &
347  {
349  this->offset -= static_cast<difference_type>(sizeof(T));
350 
351  return *this;
352  }
353 
357  inline self_relative_ptr<T>
359  {
360  auto copy = *this;
361  --(*this);
362 
363  return copy;
364  }
365 
369  inline self_relative_ptr<T> &
370  operator+=(std::ptrdiff_t s)
371  {
373  this->offset += s * static_cast<difference_type>(sizeof(T));
374  return *this;
375  }
376 
380  inline self_relative_ptr<T> &
381  operator-=(std::ptrdiff_t s)
382  {
384  this->offset -= s * static_cast<difference_type>(sizeof(T));
385  return *this;
386  }
387 
388 protected:
392  void
394  {
395  static_assert(!std::is_polymorphic<element_type>::value,
396  "Polymorphic types are not supported");
397  }
398 
399 private:
401  self_offset(element_type *ptr) const noexcept
402  {
403  return base_type::pointer_to_offset(static_cast<void *>(ptr));
404  }
405 };
406 
415 template <class T>
416 inline void
418 {
419  a.swap(b);
420 }
421 
426 template <typename T, typename Y>
427 inline bool
429  self_relative_ptr<Y> const &rhs) noexcept
430 {
431  return lhs.to_byte_pointer() == rhs.to_byte_pointer();
432 }
433 
438 template <typename T, typename Y>
439 inline bool
441  self_relative_ptr<Y> const &rhs) noexcept
442 {
443  return !(lhs == rhs);
444 }
445 
450 template <typename T>
451 inline bool
452 operator==(self_relative_ptr<T> const &lhs, std::nullptr_t) noexcept
453 {
454  return !bool(lhs);
455 }
456 
461 template <typename T>
462 inline bool
463 operator==(std::nullptr_t, self_relative_ptr<T> const &lhs) noexcept
464 {
465  return !bool(lhs);
466 }
467 
472 template <typename T>
473 inline bool
474 operator!=(self_relative_ptr<T> const &lhs, std::nullptr_t) noexcept
475 {
476  return bool(lhs);
477 }
478 
483 template <typename T>
484 inline bool
485 operator!=(std::nullptr_t, self_relative_ptr<T> const &lhs) noexcept
486 {
487  return bool(lhs);
488 }
489 
497 template <typename T, typename Y>
498 inline bool
499 operator<(self_relative_ptr<T> const &lhs,
500  self_relative_ptr<Y> const &rhs) noexcept
501 {
502  return lhs.to_byte_pointer() < rhs.to_byte_pointer();
503 }
504 
511 template <typename T, typename Y>
512 inline bool
513 operator<=(self_relative_ptr<T> const &lhs,
514  self_relative_ptr<Y> const &rhs) noexcept
515 {
516  return !(rhs < lhs);
517 }
518 
525 template <typename T, typename Y>
526 inline bool
528  self_relative_ptr<Y> const &rhs) noexcept
529 {
530  return (rhs < lhs);
531 }
532 
539 template <typename T, typename Y>
540 inline bool
542  self_relative_ptr<Y> const &rhs) noexcept
543 {
544  return !(lhs < rhs);
545 }
546 
547 /* nullptr comparisons */
548 
553 template <typename T>
554 inline bool
555 operator<(self_relative_ptr<T> const &lhs, std::nullptr_t) noexcept
556 {
557  return std::less<typename self_relative_ptr<T>::element_type *>()(
558  lhs.get(), nullptr);
559 }
560 
565 template <typename T>
566 inline bool
567 operator<(std::nullptr_t, self_relative_ptr<T> const &rhs) noexcept
568 {
569  return std::less<typename self_relative_ptr<T>::element_type *>()(
570  nullptr, rhs.get());
571 }
572 
577 template <typename T>
578 inline bool
579 operator<=(self_relative_ptr<T> const &lhs, std::nullptr_t) noexcept
580 {
581  return !(nullptr < lhs);
582 }
583 
588 template <typename T>
589 inline bool
590 operator<=(std::nullptr_t, self_relative_ptr<T> const &rhs) noexcept
591 {
592  return !(rhs < nullptr);
593 }
594 
599 template <typename T>
600 inline bool
601 operator>(self_relative_ptr<T> const &lhs, std::nullptr_t) noexcept
602 {
603  return nullptr < lhs;
604 }
605 
610 template <typename T>
611 inline bool
612 operator>(std::nullptr_t, self_relative_ptr<T> const &rhs) noexcept
613 {
614  return rhs < nullptr;
615 }
616 
621 template <typename T>
622 inline bool
623 operator>=(self_relative_ptr<T> const &lhs, std::nullptr_t) noexcept
624 {
625  return !(lhs < nullptr);
626 }
627 
632 template <typename T>
633 inline bool
634 operator>=(std::nullptr_t, self_relative_ptr<T> const &rhs) noexcept
635 {
636  return !(nullptr < rhs);
637 }
638 
643 template <typename T>
645 operator+(self_relative_ptr<T> const &lhs, std::ptrdiff_t s)
646 {
647  self_relative_ptr<T> ptr = lhs;
648  ptr += s;
649  return ptr;
650 }
651 
656 template <typename T>
658 operator-(self_relative_ptr<T> const &lhs, std::ptrdiff_t s)
659 {
660  self_relative_ptr<T> ptr = lhs;
661  ptr -= s;
662  return ptr;
663 }
664 
673 template <typename T, typename Y,
674  typename = typename std::enable_if<
675  std::is_same<typename std::remove_cv<T>::type,
676  typename std::remove_cv<Y>::type>::value>>
677 inline ptrdiff_t
679 {
681  static_cast<ptrdiff_t>(sizeof(T));
682 }
683 
688 template <typename T>
689 std::ostream &
690 operator<<(std::ostream &os, self_relative_ptr<T> const &ptr)
691 {
692  os << ptr.to_void_pointer();
693  return os;
694 }
695 
696 } /* namespace experimental */
697 
698 } /* namespace obj */
699 
700 } /* namespace pmem */
701 
702 #endif /* LIBPMEMOBJ_CPP_SELF_RELATIVE_PTR_HPP */
self_relative_ptr base template class
Definition: self_relative_ptr_base_impl.hpp:39
static difference_type distance_between(const self_relative_ptr_base_impl &first, const self_relative_ptr_base_impl &second)
Byte distance between two relative pointers.
Definition: self_relative_ptr_base_impl.hpp:179
void * to_void_pointer() const noexcept
Conversion to void*.
Definition: self_relative_ptr_base_impl.hpp:154
bool is_null() const noexcept
Fast null checking without conversion to void*.
Definition: self_relative_ptr_base_impl.hpp:189
void swap(self_relative_ptr_base_impl &other)
Swaps two self_relative_ptr_base objects of the same type.
Definition: self_relative_ptr_base_impl.hpp:129
self_relative_ptr_base_impl & operator=(self_relative_ptr_base_impl const &r)
Assignment operator.
Definition: self_relative_ptr_base_impl.hpp:100
difference_type pointer_to_offset(const self_relative_ptr_base_impl &ptr) const noexcept
Conversion self_relative_ptr_base to offset from itself.
Definition: self_relative_ptr_base_impl.hpp:235
Persistent self-relative pointer class.
Definition: self_relative_ptr.hpp:82
bool operator==(self_relative_ptr< T > const &lhs, self_relative_ptr< Y > const &rhs) noexcept
Equality operator.
Definition: self_relative_ptr.hpp:428
self_relative_ptr< T > operator++(int)
Postfix increment operator.
Definition: self_relative_ptr.hpp:334
bool operator>(self_relative_ptr< T > const &lhs, std::nullptr_t) noexcept
Compare a self_relative_ptr with a null pointer.
Definition: self_relative_ptr.hpp:601
self_relative_ptr< T > operator-(self_relative_ptr< T > const &lhs, std::ptrdiff_t s)
Subtraction operator for self-relative pointers.
Definition: self_relative_ptr.hpp:658
self_relative_ptr< T > & operator+=(std::ptrdiff_t s)
Addition assignment operator.
Definition: self_relative_ptr.hpp:370
pmem::detail::sp_dereference< T >::type operator*() const noexcept
Dereference operator.
Definition: self_relative_ptr.hpp:235
self_relative_ptr(element_type *ptr) noexcept
Volatile pointer constructor.
Definition: self_relative_ptr.hpp:134
T & reference
The reference type of the value pointed to by the self_relative_ptr.
Definition: self_relative_ptr.hpp:110
self_relative_ptr & operator=(const self_relative_ptr &r)
Assignment operator.
Definition: self_relative_ptr.hpp:278
bool operator>(self_relative_ptr< T > const &lhs, self_relative_ptr< Y > const &rhs) noexcept
Greater than operator.
Definition: self_relative_ptr.hpp:527
bool operator>=(std::nullptr_t, self_relative_ptr< T > const &rhs) noexcept
Compare a self_relative_ptr with a null pointer.
Definition: self_relative_ptr.hpp:634
T value_type
The type of the value pointed to by the self_relative_ptr.
Definition: self_relative_ptr.hpp:105
self_relative_ptr(persistent_ptr< T > ptr) noexcept
Constructor from persistent_ptr<T>
Definition: self_relative_ptr.hpp:142
self_relative_ptr(PMEMoid oid) noexcept
PMEMoid constructor.
Definition: self_relative_ptr.hpp:154
bool operator!=(self_relative_ptr< T > const &lhs, self_relative_ptr< Y > const &rhs) noexcept
Inequality operator.
Definition: self_relative_ptr.hpp:440
self_relative_ptr< T > & operator--()
Prefix decrement operator.
Definition: self_relative_ptr.hpp:346
self_relative_ptr< T > & operator++()
Prefix increment operator.
Definition: self_relative_ptr.hpp:322
void verify_type()
Verify if element_type is not polymorphic.
Definition: self_relative_ptr.hpp:393
self_relative_ptr< T > & operator=(self_relative_ptr< Y > const &r)
Converting assignment operator from a different self_relative_ptr<>.
Definition: self_relative_ptr.hpp:299
self_relative_ptr< T > & operator-=(std::ptrdiff_t s)
Subtraction assignment operator.
Definition: self_relative_ptr.hpp:381
bool operator>(std::nullptr_t, self_relative_ptr< T > const &rhs) noexcept
Compare a self_relative_ptr with a null pointer.
Definition: self_relative_ptr.hpp:612
self_relative_ptr< T > operator--(int)
Postfix decrement operator.
Definition: self_relative_ptr.hpp:358
persistent_ptr< T > to_persistent_ptr() const
Conversion to persitent ptr.
Definition: self_relative_ptr.hpp:207
bool operator==(self_relative_ptr< T > const &lhs, std::nullptr_t) noexcept
Equality operator with nullptr.
Definition: self_relative_ptr.hpp:452
pmem::detail::sp_array_access< T >::type operator[](difference_type i) const noexcept
Array access operator.
Definition: self_relative_ptr.hpp:257
element_type * get() const noexcept
Get the direct pointer.
Definition: self_relative_ptr.hpp:197
bool operator!=(std::nullptr_t, self_relative_ptr< T > const &lhs) noexcept
Inequality operator with nullptr.
Definition: self_relative_ptr.hpp:485
bool operator>=(self_relative_ptr< T > const &lhs, std::nullptr_t) noexcept
Compare a self_relative_ptr with a null pointer.
Definition: self_relative_ptr.hpp:623
bool operator!=(self_relative_ptr< T > const &lhs, std::nullptr_t) noexcept
Inequality operator with nullptr.
Definition: self_relative_ptr.hpp:474
ptrdiff_t operator-(self_relative_ptr< T > const &lhs, self_relative_ptr< Y > const &rhs)
Subtraction operator for self-relative pointers of identical type.
Definition: self_relative_ptr.hpp:678
bool operator>=(self_relative_ptr< T > const &lhs, self_relative_ptr< Y > const &rhs) noexcept
Greater or equal than operator.
Definition: self_relative_ptr.hpp:541
self_relative_ptr(const self_relative_ptr &ptr) noexcept
Copy constructor.
Definition: self_relative_ptr.hpp:163
void swap(self_relative_ptr< T > &a, self_relative_ptr< T > &b)
Swaps two self_relative_ptr objects of the same type.
Definition: self_relative_ptr.hpp:417
typename base_type::difference_type difference_type
The self_relative_ptr difference type.
Definition: self_relative_ptr.hpp:100
pmem::detail::sp_member_access< T >::type operator->() const noexcept
Member access operator.
Definition: self_relative_ptr.hpp:244
self_relative_ptr(self_relative_ptr< U > const &r) noexcept
Copy constructor from a different self_relative_ptr<>.
Definition: self_relative_ptr.hpp:181
constexpr self_relative_ptr() noexcept=default
Default constructor, equal the nullptr.
self_relative_ptr & operator=(std::nullptr_t)
Nullptr move assignment operator.
Definition: self_relative_ptr.hpp:311
self_relative_ptr< T > operator+(self_relative_ptr< T > const &lhs, std::ptrdiff_t s)
Addition operator for self-relative pointers.
Definition: self_relative_ptr.hpp:645
bool operator==(std::nullptr_t, self_relative_ptr< T > const &lhs) noexcept
Equality operator with nullptr.
Definition: self_relative_ptr.hpp:463
std::random_access_iterator_tag iterator_category
Random access iterator requirements (members)
Definition: self_relative_ptr.hpp:95
Persistent pointer class.
Definition: persistent_ptr.hpp:153
void conditional_add_to_tx(const T *that, std::size_t count=1, uint64_t flags=0)
Conditionally add 'count' objects to a transaction.
Definition: common.hpp:176
std::ostream & operator<<(std::ostream &os, const radix_tree< K, V, BV, MtMode > &tree)
Prints tree in DOT format.
Definition: radix_tree.hpp:2843
pmem::detail::self_relative_ptr_base_impl< std::ptrdiff_t > self_relative_ptr_base
self_relative_ptr base (non-template) class
Definition: self_relative_ptr_base.hpp:36
Persistent memory namespace.
Definition: allocation_flag.hpp:15
Persistent smart pointer.
Base class for self_relative_ptr.
Helper template for persistent ptr specialization.