PMDK C++ bindings 1.13.0
This is the C++ bindings documentation for PMDK's libpmemobj.
Loading...
Searching...
No Matches
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
17namespace pmem
18{
19namespace obj
20{
21namespace experimental
22{
23
24template <typename T>
25class self_relative_ptr;
26
27template <>
28class self_relative_ptr<void> : public self_relative_ptr_base {
29public:
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
53private:
55 self_offset(element_type *ptr) const noexcept
56 {
57 return base_type::pointer_to_offset(static_cast<void *>(ptr));
58 }
59};
60
80template <typename T>
82public:
85 using element_type = typename pmem::detail::sp_element<T>::type;
86
94 using iterator_category = std::random_access_iterator_tag;
95
99 using difference_type = typename base_type::difference_type;
100
104 using value_type = T;
105
109 using reference = T &;
110
111 /*
112 * Constructors
113 */
114
118 constexpr self_relative_ptr() noexcept = default;
119
123 constexpr self_relative_ptr(std::nullptr_t) noexcept
125 {
126 }
127
133 self_relative_ptr(element_type *ptr) noexcept
134 : self_relative_ptr_base(self_offset(ptr))
135 {
136 }
137
142 : self_relative_ptr_base(self_offset(ptr.get()))
143 {
144 }
145
153 self_relative_ptr(PMEMoid oid) noexcept
154 : self_relative_ptr_base(self_offset(
155 static_cast<element_type *>(pmemobj_direct(oid))))
156 {
157 }
158
164 {
165 }
166
172 template <
173 typename U,
174 typename = typename std::enable_if<
175 !std::is_same<
176 typename std::remove_cv<T>::type,
177 typename std::remove_cv<U>::type>::value &&
178 !std::is_void<U>::value,
179 decltype(static_cast<T *>(std::declval<U *>()))>::type>
181 : self_relative_ptr_base(self_offset(static_cast<T *>(r.get())))
182 {
183 }
184
186 {
187 verify_type();
188 }
189
195 inline element_type *
196 get() const noexcept
197 {
198 return static_cast<element_type *>(
200 }
201
207 {
208 return persistent_ptr<T>{this->get()};
209 }
210
211 /*
212 * Operators
213 */
214
218 explicit operator bool() const noexcept
219 {
220 return !is_null();
221 }
222
226 operator persistent_ptr<T>() const
227 {
228 return to_persistent_ptr();
229 }
230
234 typename pmem::detail::sp_dereference<T>::type operator*() const
235 noexcept
236 {
237 return *(this->get());
238 }
239
243 typename pmem::detail::sp_member_access<T>::type operator->() const
244 noexcept
245 {
246 return this->get();
247 }
248
254 template <typename = typename std::enable_if<!std::is_void<T>::value>>
255 typename pmem::detail::sp_array_access<T>::type
256 operator[](difference_type i) const noexcept
257 {
258 assert(i >= 0 &&
259 (i < pmem::detail::sp_extent<T>::value ||
260 pmem::detail::sp_extent<T>::value == 0) &&
261 "persistent array index out of bounds");
262
263 return this->get()[i];
264 }
265
278 {
279 this->base_type::operator=(r);
280 return *this;
281 }
282
294 template <typename Y,
295 typename = typename std::enable_if<
296 std::is_convertible<Y *, T *>::value>::type>
299 {
300 this_type(r).swap(*this);
301 return *this;
302 }
303
311 {
312 detail::conditional_add_to_tx(this);
313 this->offset = self_offset(nullptr);
314 return *this;
315 }
316
320 inline self_relative_ptr<T> &
322 {
323 detail::conditional_add_to_tx(this);
324 this->offset += static_cast<difference_type>(sizeof(T));
325
326 return *this;
327 }
328
334 {
335 auto copy = *this;
336 ++(*this);
337
338 return copy;
339 }
340
344 inline self_relative_ptr<T> &
346 {
347 detail::conditional_add_to_tx(this);
348 this->offset -= static_cast<difference_type>(sizeof(T));
349
350 return *this;
351 }
352
358 {
359 auto copy = *this;
360 --(*this);
361
362 return copy;
363 }
364
368 inline self_relative_ptr<T> &
369 operator+=(std::ptrdiff_t s)
370 {
371 detail::conditional_add_to_tx(this);
372 this->offset += s * static_cast<difference_type>(sizeof(T));
373 return *this;
374 }
375
379 inline self_relative_ptr<T> &
380 operator-=(std::ptrdiff_t s)
381 {
382 detail::conditional_add_to_tx(this);
383 this->offset -= s * static_cast<difference_type>(sizeof(T));
384 return *this;
385 }
386
387protected:
391 void
393 {
394 static_assert(!std::is_polymorphic<element_type>::value,
395 "Polymorphic types are not supported");
396 }
397
398private:
400 self_offset(element_type *ptr) const noexcept
401 {
402 return base_type::pointer_to_offset(static_cast<void *>(ptr));
403 }
404};
405
412template <class T>
413inline void
415{
416 a.swap(b);
417}
418
422template <typename T, typename Y>
423inline bool
425 self_relative_ptr<Y> const &rhs) noexcept
426{
427 return lhs.to_byte_pointer() == rhs.to_byte_pointer();
428}
429
433template <typename T, typename Y>
434inline bool
436 self_relative_ptr<Y> const &rhs) noexcept
437{
438 return !(lhs == rhs);
439}
440
444template <typename T>
445inline bool
446operator==(self_relative_ptr<T> const &lhs, std::nullptr_t) noexcept
447{
448 return !bool(lhs);
449}
450
454template <typename T>
455inline bool
456operator==(std::nullptr_t, self_relative_ptr<T> const &lhs) noexcept
457{
458 return !bool(lhs);
459}
460
464template <typename T>
465inline bool
466operator!=(self_relative_ptr<T> const &lhs, std::nullptr_t) noexcept
467{
468 return bool(lhs);
469}
470
474template <typename T>
475inline bool
476operator!=(std::nullptr_t, self_relative_ptr<T> const &lhs) noexcept
477{
478 return bool(lhs);
479}
480
487template <typename T, typename Y>
488inline bool
490 self_relative_ptr<Y> const &rhs) noexcept
491{
492 return lhs.to_byte_pointer() < rhs.to_byte_pointer();
493}
494
500template <typename T, typename Y>
501inline bool
503 self_relative_ptr<Y> const &rhs) noexcept
504{
505 return !(rhs < lhs);
506}
507
513template <typename T, typename Y>
514inline bool
516 self_relative_ptr<Y> const &rhs) noexcept
517{
518 return (rhs < lhs);
519}
520
526template <typename T, typename Y>
527inline bool
529 self_relative_ptr<Y> const &rhs) noexcept
530{
531 return !(lhs < rhs);
532}
533
534/* nullptr comparisons */
535
539template <typename T>
540inline bool
541operator<(self_relative_ptr<T> const &lhs, std::nullptr_t) noexcept
542{
543 return std::less<typename self_relative_ptr<T>::element_type *>()(
544 lhs.get(), nullptr);
545}
546
550template <typename T>
551inline bool
552operator<(std::nullptr_t, self_relative_ptr<T> const &rhs) noexcept
553{
554 return std::less<typename self_relative_ptr<T>::element_type *>()(
555 nullptr, rhs.get());
556}
557
561template <typename T>
562inline bool
563operator<=(self_relative_ptr<T> const &lhs, std::nullptr_t) noexcept
564{
565 return !(nullptr < lhs);
566}
567
571template <typename T>
572inline bool
573operator<=(std::nullptr_t, self_relative_ptr<T> const &rhs) noexcept
574{
575 return !(rhs < nullptr);
576}
577
581template <typename T>
582inline bool
583operator>(self_relative_ptr<T> const &lhs, std::nullptr_t) noexcept
584{
585 return nullptr < lhs;
586}
587
591template <typename T>
592inline bool
593operator>(std::nullptr_t, self_relative_ptr<T> const &rhs) noexcept
594{
595 return rhs < nullptr;
596}
597
601template <typename T>
602inline bool
603operator>=(self_relative_ptr<T> const &lhs, std::nullptr_t) noexcept
604{
605 return !(lhs < nullptr);
606}
607
611template <typename T>
612inline bool
613operator>=(std::nullptr_t, self_relative_ptr<T> const &rhs) noexcept
614{
615 return !(nullptr < rhs);
616}
617
621template <typename T>
622inline self_relative_ptr<T>
623operator+(self_relative_ptr<T> const &lhs, std::ptrdiff_t s)
624{
625 self_relative_ptr<T> ptr = lhs;
626 ptr += s;
627 return ptr;
628}
629
633template <typename T>
634inline self_relative_ptr<T>
635operator-(self_relative_ptr<T> const &lhs, std::ptrdiff_t s)
636{
637 self_relative_ptr<T> ptr = lhs;
638 ptr -= s;
639 return ptr;
640}
641
649template <typename T, typename Y,
650 typename = typename std::enable_if<
651 std::is_same<typename std::remove_cv<T>::type,
652 typename std::remove_cv<Y>::type>::value>>
653inline ptrdiff_t
655{
657 static_cast<ptrdiff_t>(sizeof(T));
658}
659
663template <typename T>
664std::ostream &
665operator<<(std::ostream &os, self_relative_ptr<T> const &ptr)
666{
667 os << ptr.to_void_pointer();
668 return os;
669}
670
671} /* namespace experimental */
672
673} /* namespace obj */
674
675} /* namespace pmem */
676
677#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
bool is_null() const noexcept
Fast null checking without conversion to void*.
Definition: self_relative_ptr_base_impl.hpp:189
self_relative_ptr_base_impl & operator=(self_relative_ptr_base_impl const &r)
Assignment operator.
Definition: self_relative_ptr_base_impl.hpp:100
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
void * to_void_pointer() const noexcept
Conversion to void*.
Definition: self_relative_ptr_base_impl.hpp:154
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:81
self_relative_ptr(element_type *ptr) noexcept
Volatile pointer constructor.
Definition: self_relative_ptr.hpp:133
self_relative_ptr< T > operator--(int)
Postfix decrement operator.
Definition: self_relative_ptr.hpp:357
T & reference
The reference type of the value pointed to by the self_relative_ptr.
Definition: self_relative_ptr.hpp:109
pmem::detail::sp_array_access< T >::type operator[](difference_type i) const noexcept
Array access operator.
Definition: self_relative_ptr.hpp:256
self_relative_ptr< T > & operator-=(std::ptrdiff_t s)
Subtraction assignment operator.
Definition: self_relative_ptr.hpp:380
T value_type
The type of the value pointed to by the self_relative_ptr.
Definition: self_relative_ptr.hpp:104
self_relative_ptr(persistent_ptr< T > ptr) noexcept
Constructor from persistent_ptr<T>
Definition: self_relative_ptr.hpp:141
self_relative_ptr(PMEMoid oid) noexcept
PMEMoid constructor.
Definition: self_relative_ptr.hpp:153
element_type * get() const noexcept
Get the direct pointer.
Definition: self_relative_ptr.hpp:196
void verify_type()
Verify if element_type is not polymorphic.
Definition: self_relative_ptr.hpp:392
pmem::detail::sp_member_access< T >::type operator->() const noexcept
Member access operator.
Definition: self_relative_ptr.hpp:243
self_relative_ptr< T > & operator++()
Prefix increment operator.
Definition: self_relative_ptr.hpp:321
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:298
self_relative_ptr & operator=(const self_relative_ptr &r)
Assignment operator.
Definition: self_relative_ptr.hpp:277
self_relative_ptr & operator=(std::nullptr_t)
Nullptr move assignment operator.
Definition: self_relative_ptr.hpp:310
self_relative_ptr< T > & operator--()
Prefix decrement operator.
Definition: self_relative_ptr.hpp:345
self_relative_ptr< T > & operator+=(std::ptrdiff_t s)
Addition assignment operator.
Definition: self_relative_ptr.hpp:369
self_relative_ptr(const self_relative_ptr &ptr) noexcept
Copy constructor.
Definition: self_relative_ptr.hpp:162
typename base_type::difference_type difference_type
The self_relative_ptr difference type.
Definition: self_relative_ptr.hpp:99
self_relative_ptr(self_relative_ptr< U > const &r) noexcept
Copy constructor from a different self_relative_ptr<>.
Definition: self_relative_ptr.hpp:180
constexpr self_relative_ptr() noexcept=default
Default constructor, equal the nullptr.
std::random_access_iterator_tag iterator_category
Random access iterator requirements (members)
Definition: self_relative_ptr.hpp:94
persistent_ptr< T > to_persistent_ptr() const
Conversion to persitent ptr.
Definition: self_relative_ptr.hpp:206
pmem::detail::sp_dereference< T >::type operator*() const noexcept
Dereference operator.
Definition: self_relative_ptr.hpp:234
self_relative_ptr< T > operator++(int)
Postfix increment operator.
Definition: self_relative_ptr.hpp:333
Persistent pointer class.
Definition: persistent_ptr.hpp:152
bool operator==(self_relative_ptr< T > const &lhs, self_relative_ptr< Y > const &rhs) noexcept
Equality operator.
Definition: self_relative_ptr.hpp:424
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:623
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:635
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:502
void swap(concurrent_map< Key, Value, Comp, Allocator > &lhs, concurrent_map< Key, Value, Comp, Allocator > &rhs)
Non-member swap.
Definition: concurrent_map.hpp:151
std::ostream & operator<<(std::ostream &os, const radix_tree< K, V, BV, MtMode > &tree)
Prints tree in DOT format.
Definition: radix_tree.hpp:2840
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:528
bool operator!=(self_relative_ptr< T > const &lhs, self_relative_ptr< Y > const &rhs) noexcept
Inequality operator.
Definition: self_relative_ptr.hpp:435
bool operator>(self_relative_ptr< T > const &lhs, self_relative_ptr< Y > const &rhs) noexcept
Greater than operator.
Definition: self_relative_ptr.hpp:515
bool operator<(self_relative_ptr< T > const &lhs, self_relative_ptr< Y > const &rhs) noexcept
Less than operator.
Definition: self_relative_ptr.hpp:489
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.