PMDK C++ bindings  1.11
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, 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 
43 template <typename T>
45 public:
48  using element_type = typename pmem::detail::sp_element<T>::type;
49 
57  using iterator_category = std::random_access_iterator_tag;
58 
62  using difference_type = typename base_type::difference_type;
63 
67  using value_type = T;
68 
72  using reference = T &;
73 
74  /*
75  * Constructors
76  */
77 
81  constexpr self_relative_ptr() noexcept = default;
82 
86  constexpr self_relative_ptr(std::nullptr_t) noexcept
88  {
89  }
90 
96  self_relative_ptr(element_type *ptr) noexcept
97  : self_relative_ptr_base(self_offset(ptr))
98  {
99  }
100 
105  : self_relative_ptr_base(self_offset(ptr.get()))
106  {
107  }
108 
116  self_relative_ptr(PMEMoid oid) noexcept
117  : self_relative_ptr_base(self_offset(
118  static_cast<element_type *>(pmemobj_direct(oid))))
119  {
120  }
121 
127  {
128  }
129 
135  template <
136  typename U,
137  typename = typename std::enable_if<
138  !std::is_same<
139  typename std::remove_cv<T>::type,
140  typename std::remove_cv<U>::type>::value &&
141  !std::is_void<U>::value,
142  decltype(static_cast<T *>(std::declval<U *>()))>::type>
144  : self_relative_ptr_base(self_offset(static_cast<T *>(r.get())))
145  {
146  }
147 
149  {
150  verify_type();
151  }
152 
158  inline element_type *
159  get() const noexcept
160  {
161  return static_cast<element_type *>(
163  }
164 
170  {
171  return persistent_ptr<T>{this->get()};
172  }
173 
174  /*
175  * Operators
176  */
177 
181  explicit operator bool() const noexcept
182  {
183  return !is_null();
184  }
185 
189  operator persistent_ptr<T>() const
190  {
191  return to_persistent_ptr();
192  }
193 
197  typename pmem::detail::sp_dereference<T>::type operator*() const
198  noexcept
199  {
200  return *(this->get());
201  }
202 
206  typename pmem::detail::sp_member_access<T>::type operator->() const
207  noexcept
208  {
209  return this->get();
210  }
211 
217  template <typename = typename std::enable_if<!std::is_void<T>::value>>
218  typename pmem::detail::sp_array_access<T>::type
219  operator[](difference_type i) const noexcept
220  {
221  assert(i >= 0 &&
222  (i < pmem::detail::sp_extent<T>::value ||
223  pmem::detail::sp_extent<T>::value == 0) &&
224  "persistent array index out of bounds");
225 
226  return this->get()[i];
227  }
228 
241  {
242  this->base_type::operator=(r);
243  return *this;
244  }
245 
257  template <typename Y,
258  typename = typename std::enable_if<
259  std::is_convertible<Y *, T *>::value>::type>
262  {
263  this_type(r).swap(*this);
264  return *this;
265  }
266 
273  self_relative_ptr &operator=(std::nullptr_t)
274  {
275  detail::conditional_add_to_tx(this);
276  this->offset = self_offset(nullptr);
277  return *this;
278  }
279 
283  inline self_relative_ptr<T> &
285  {
286  detail::conditional_add_to_tx(this);
287  this->offset += static_cast<difference_type>(sizeof(T));
288 
289  return *this;
290  }
291 
295  inline self_relative_ptr<T>
297  {
298  auto copy = *this;
299  ++(*this);
300 
301  return copy;
302  }
303 
307  inline self_relative_ptr<T> &
309  {
310  detail::conditional_add_to_tx(this);
311  this->offset -= static_cast<difference_type>(sizeof(T));
312 
313  return *this;
314  }
315 
319  inline self_relative_ptr<T>
321  {
322  auto copy = *this;
323  --(*this);
324 
325  return copy;
326  }
327 
331  inline self_relative_ptr<T> &
332  operator+=(std::ptrdiff_t s)
333  {
334  detail::conditional_add_to_tx(this);
335  this->offset += s * static_cast<difference_type>(sizeof(T));
336  return *this;
337  }
338 
342  inline self_relative_ptr<T> &
343  operator-=(std::ptrdiff_t s)
344  {
345  detail::conditional_add_to_tx(this);
346  this->offset -= s * static_cast<difference_type>(sizeof(T));
347  return *this;
348  }
349 
350 protected:
354  void
356  {
357  static_assert(!std::is_polymorphic<element_type>::value,
358  "Polymorphic types are not supported");
359  }
360 
361 private:
363  self_offset(element_type *ptr) const noexcept
364  {
365  return base_type::pointer_to_offset(static_cast<void *>(ptr));
366  }
367 };
368 
375 template <class T>
376 inline void
378 {
379  a.swap(b);
380 }
381 
385 template <typename T, typename Y>
386 inline bool
388  self_relative_ptr<Y> const &rhs) noexcept
389 {
390  return lhs.to_byte_pointer() == rhs.to_byte_pointer();
391 }
392 
396 template <typename T, typename Y>
397 inline bool
399  self_relative_ptr<Y> const &rhs) noexcept
400 {
401  return !(lhs == rhs);
402 }
403 
407 template <typename T>
408 inline bool
409 operator==(self_relative_ptr<T> const &lhs, std::nullptr_t) noexcept
410 {
411  return !bool(lhs);
412 }
413 
417 template <typename T>
418 inline bool
419 operator==(std::nullptr_t, self_relative_ptr<T> const &lhs) noexcept
420 {
421  return !bool(lhs);
422 }
423 
427 template <typename T>
428 inline bool
429 operator!=(self_relative_ptr<T> const &lhs, std::nullptr_t) noexcept
430 {
431  return bool(lhs);
432 }
433 
437 template <typename T>
438 inline bool
439 operator!=(std::nullptr_t, self_relative_ptr<T> const &lhs) noexcept
440 {
441  return bool(lhs);
442 }
443 
450 template <typename T, typename Y>
451 inline bool
453  self_relative_ptr<Y> const &rhs) noexcept
454 {
455  return lhs.to_byte_pointer() < rhs.to_byte_pointer();
456 }
457 
463 template <typename T, typename Y>
464 inline bool
466  self_relative_ptr<Y> const &rhs) noexcept
467 {
468  return !(rhs < lhs);
469 }
470 
476 template <typename T, typename Y>
477 inline bool
479  self_relative_ptr<Y> const &rhs) noexcept
480 {
481  return (rhs < lhs);
482 }
483 
489 template <typename T, typename Y>
490 inline bool
492  self_relative_ptr<Y> const &rhs) noexcept
493 {
494  return !(lhs < rhs);
495 }
496 
497 /* nullptr comparisons */
498 
502 template <typename T>
503 inline bool
504 operator<(self_relative_ptr<T> const &lhs, std::nullptr_t) noexcept
505 {
506  return std::less<typename self_relative_ptr<T>::element_type *>()(
507  lhs.get(), nullptr);
508 }
509 
513 template <typename T>
514 inline bool
515 operator<(std::nullptr_t, self_relative_ptr<T> const &rhs) noexcept
516 {
517  return std::less<typename self_relative_ptr<T>::element_type *>()(
518  nullptr, rhs.get());
519 }
520 
524 template <typename T>
525 inline bool
526 operator<=(self_relative_ptr<T> const &lhs, std::nullptr_t) noexcept
527 {
528  return !(nullptr < lhs);
529 }
530 
534 template <typename T>
535 inline bool
536 operator<=(std::nullptr_t, self_relative_ptr<T> const &rhs) noexcept
537 {
538  return !(rhs < nullptr);
539 }
540 
544 template <typename T>
545 inline bool
546 operator>(self_relative_ptr<T> const &lhs, std::nullptr_t) noexcept
547 {
548  return nullptr < lhs;
549 }
550 
554 template <typename T>
555 inline bool
556 operator>(std::nullptr_t, self_relative_ptr<T> const &rhs) noexcept
557 {
558  return rhs < nullptr;
559 }
560 
564 template <typename T>
565 inline bool
566 operator>=(self_relative_ptr<T> const &lhs, std::nullptr_t) noexcept
567 {
568  return !(lhs < nullptr);
569 }
570 
574 template <typename T>
575 inline bool
576 operator>=(std::nullptr_t, self_relative_ptr<T> const &rhs) noexcept
577 {
578  return !(nullptr < rhs);
579 }
580 
584 template <typename T>
585 inline self_relative_ptr<T>
586 operator+(self_relative_ptr<T> const &lhs, std::ptrdiff_t s)
587 {
588  self_relative_ptr<T> ptr = lhs;
589  ptr += s;
590  return ptr;
591 }
592 
596 template <typename T>
597 inline self_relative_ptr<T>
598 operator-(self_relative_ptr<T> const &lhs, std::ptrdiff_t s)
599 {
600  self_relative_ptr<T> ptr = lhs;
601  ptr -= s;
602  return ptr;
603 }
604 
612 template <typename T, typename Y,
613  typename = typename std::enable_if<
614  std::is_same<typename std::remove_cv<T>::type,
615  typename std::remove_cv<Y>::type>::value>>
616 inline ptrdiff_t
618 {
620  static_cast<ptrdiff_t>(sizeof(T));
621 }
622 
626 template <typename T>
627 std::ostream &
628 operator<<(std::ostream &os, self_relative_ptr<T> const &ptr)
629 {
630  os << ptr.to_void_pointer();
631  return os;
632 }
633 
634 } /* namespace experimental */
635 
636 } /* namespace obj */
637 
638 } /* namespace pmem */
639 
640 #endif /* LIBPMEMOBJ_CPP_SELF_RELATIVE_PTR_HPP */
pmem::obj::experimental::operator-
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:598
pmem::obj::experimental::self_relative_ptr::operator=
self_relative_ptr & operator=(std::nullptr_t)
Nullptr move assignment operator.
Definition: self_relative_ptr.hpp:273
pmem::obj::experimental::self_relative_ptr< list_node_type >::value_type
list_node_type value_type
The type of the value pointed to by the self_relative_ptr.
Definition: self_relative_ptr.hpp:67
pmem::obj::experimental::operator>=
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:491
pmem::obj::experimental::self_relative_ptr::operator++
self_relative_ptr< T > & operator++()
Prefix increment operator.
Definition: self_relative_ptr.hpp:284
pmem::obj::experimental::self_relative_ptr::operator++
self_relative_ptr< T > operator++(int)
Postfix increment operator.
Definition: self_relative_ptr.hpp:296
pmem::obj::experimental::self_relative_ptr::operator--
self_relative_ptr< T > operator--(int)
Postfix decrement operator.
Definition: self_relative_ptr.hpp:320
pmem::obj::experimental::self_relative_ptr::get
element_type * get() const noexcept
Get the direct pointer.
Definition: self_relative_ptr.hpp:159
pmem::obj::experimental::self_relative_ptr::difference_type
typename base_type::difference_type difference_type
The self_relative_ptr difference type.
Definition: self_relative_ptr.hpp:62
pmem::obj::experimental::self_relative_ptr::operator-=
self_relative_ptr< T > & operator-=(std::ptrdiff_t s)
Subtraction assignment operator.
Definition: self_relative_ptr.hpp:343
pmem
Persistent memory namespace.
Definition: allocation_flag.hpp:15
pmem::detail::self_relative_ptr_base_impl::swap
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
pmem::detail::self_relative_ptr_base_impl< std::ptrdiff_t >::to_void_pointer
void * to_void_pointer() const noexcept
Conversion to void*.
Definition: self_relative_ptr_base_impl.hpp:154
pmem::obj::experimental::self_relative_ptr::self_relative_ptr
self_relative_ptr(persistent_ptr< T > ptr) noexcept
Constructor from persistent_ptr<T>
Definition: self_relative_ptr.hpp:104
pmem::obj::experimental::self_relative_ptr
Persistent self-relative pointer class.
Definition: self_relative_ptr.hpp:44
pmem::obj::experimental::self_relative_ptr::operator--
self_relative_ptr< T > & operator--()
Prefix decrement operator.
Definition: self_relative_ptr.hpp:308
pmem::detail::self_relative_ptr_base_impl< std::ptrdiff_t >::distance_between
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
pmem::obj::experimental::self_relative_ptr::operator*
pmem::detail::sp_dereference< T >::type operator*() const noexcept
Dereference operator.
Definition: self_relative_ptr.hpp:197
pmem::obj::experimental::self_relative_ptr::self_relative_ptr
self_relative_ptr(PMEMoid oid) noexcept
PMEMoid constructor.
Definition: self_relative_ptr.hpp:116
pmem::obj::experimental::self_relative_ptr::operator[]
pmem::detail::sp_array_access< T >::type operator[](difference_type i) const noexcept
Array access operator.
Definition: self_relative_ptr.hpp:219
pmem::obj::experimental::self_relative_ptr::self_relative_ptr
self_relative_ptr(self_relative_ptr< U > const &r) noexcept
Copy constructor from a different self_relative_ptr<>.
Definition: self_relative_ptr.hpp:143
pmem::obj::experimental::operator<=
bool operator<=(self_relative_ptr< T > const &lhs, self_relative_ptr< Y > const &rhs) noexcept
Less or equal than operator.
Definition: self_relative_ptr.hpp:465
pmem::obj::experimental::self_relative_ptr::to_persistent_ptr
persistent_ptr< T > to_persistent_ptr() const
Conversion to persitent ptr.
Definition: self_relative_ptr.hpp:169
pmem::obj::experimental::operator<
bool operator<(self_relative_ptr< T > const &lhs, self_relative_ptr< Y > const &rhs) noexcept
Less than operator.
Definition: self_relative_ptr.hpp:452
pmem::obj::experimental::self_relative_ptr::operator=
self_relative_ptr & operator=(const self_relative_ptr &r)
Assignment operator.
Definition: self_relative_ptr.hpp:240
pmem::detail::self_relative_ptr_base_impl::is_null
bool is_null() const noexcept
Fast null checking without conversion to void*.
Definition: self_relative_ptr_base_impl.hpp:189
pmem::obj::experimental::self_relative_ptr::self_relative_ptr
self_relative_ptr(const self_relative_ptr &ptr) noexcept
Copy constructor.
Definition: self_relative_ptr.hpp:125
pmem::obj::experimental::self_relative_ptr::self_relative_ptr
self_relative_ptr(element_type *ptr) noexcept
Volatile pointer constructor.
Definition: self_relative_ptr.hpp:96
specialization.hpp
Helper template for persistent ptr specialization.
pmem::obj::experimental::swap
void swap(concurrent_map< Key, Value, Comp, Allocator > &lhs, concurrent_map< Key, Value, Comp, Allocator > &rhs)
Non-member swap.
Definition: concurrent_map.hpp:151
pmem::obj::persistent_ptr
Persistent pointer class.
Definition: persistent_ptr.hpp:152
pmem::obj::experimental::self_relative_ptr::operator=
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:261
pmem::obj::experimental::self_relative_ptr::operator->
pmem::detail::sp_member_access< T >::type operator->() const noexcept
Member access operator.
Definition: self_relative_ptr.hpp:206
pmem::obj::experimental::operator!=
bool operator!=(self_relative_ptr< T > const &lhs, self_relative_ptr< Y > const &rhs) noexcept
Inequality operator.
Definition: self_relative_ptr.hpp:398
pmem::obj::experimental::self_relative_ptr::self_relative_ptr
constexpr self_relative_ptr() noexcept=default
Default constructor, equal the nullptr.
pmem::obj::experimental::operator==
bool operator==(self_relative_ptr< T > const &lhs, self_relative_ptr< Y > const &rhs) noexcept
Equality operator.
Definition: self_relative_ptr.hpp:387
pmem::obj::experimental::self_relative_ptr< list_node_type >::iterator_category
std::random_access_iterator_tag iterator_category
Random access iterator requirements (members)
Definition: self_relative_ptr.hpp:57
pmem::obj::experimental::operator+
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:586
pmem::detail::self_relative_ptr_base_impl< std::ptrdiff_t >
pmem::obj::experimental::self_relative_ptr::verify_type
void verify_type()
Verify if element_type is not polymorphic.
Definition: self_relative_ptr.hpp:355
pmem::obj::experimental::operator>
bool operator>(self_relative_ptr< T > const &lhs, self_relative_ptr< Y > const &rhs) noexcept
Greater than operator.
Definition: self_relative_ptr.hpp:478
pmem::obj::experimental::self_relative_ptr_base
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
pmem::obj::experimental::operator<<
std::ostream & operator<<(std::ostream &os, const radix_tree< K, V, BV > &tree)
Prints tree in DOT format.
Definition: radix_tree.hpp:2404
persistent_ptr.hpp
Persistent smart pointer.
pmem::detail::self_relative_ptr_base_impl< std::ptrdiff_t >::pointer_to_offset
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
pmem::detail::self_relative_ptr_base_impl< std::ptrdiff_t >::operator=
self_relative_ptr_base_impl & operator=(self_relative_ptr_base_impl const &r)
Assignment operator.
Definition: self_relative_ptr_base_impl.hpp:100
pmem::obj::experimental::self_relative_ptr::operator+=
self_relative_ptr< T > & operator+=(std::ptrdiff_t s)
Addition assignment operator.
Definition: self_relative_ptr.hpp:332
pmem::obj::experimental::self_relative_ptr< list_node_type >::reference
list_node_type & reference
The reference type of the value pointed to by the self_relative_ptr.
Definition: self_relative_ptr.hpp:72
self_relative_ptr_base.hpp
Base class for self_relative_ptr.