opynsim
Unofficial C++ Documentation
Loading...
Searching...
No Matches
lifetimed_ptr.h
Go to the documentation of this file.
1#pragma once
2
5
6#include <cstddef>
7#include <concepts>
8#include <stdexcept>
9#include <utility>
10
11namespace osc
12{
13 // a non-owning smart pointer that ties a `LifetimeWatcher` to an unmanaged (raw)
14 // pointer in order to enable lifetime checking at runtime on the pointer
15 //
16 // note: the main utility of this class is that it enables some basic runtime checking
17 // without having to invasively add reference counters etc. to the things being
18 // managed
19 //
20 // note: `LifetimedPtr` isn't thread-safe in the same way that (e.g.) `std::weak_ptr`
21 // is. Because there's no way to `lock` a raw pointer, this class is susceptible
22 // to (e.g.) checking the lifetime, followed by accessing the object while the
23 // owning thread is destructing it
24 template<typename T>
26 public:
27 // constructs a `nullptr` with an already-dead lifetime
28 constexpr LifetimedPtr() = default;
29
30 // constructs a `nullptr` with an already-dead lifetime
31 constexpr LifetimedPtr(std::nullptr_t) : LifetimedPtr{} {}
32
33 // constructs a `LifetimedPtr` that ties `lifetime_watcher` to `ptr`
34 LifetimedPtr(LifetimeWatcher lifetime_watcher, T* ptr) :
35 lifetime_watcher_{std::move(lifetime_watcher)},
36 ptr_{ptr}
37 {}
38
39 // constructs a `LifetimedPtr` that ties `lifetime` to `ptr`
40 template<WatchableLifetime Lifetime>
42 LifetimedPtr{lifetime.watch(), ptr}
43 {}
44
45 // normal copy construction (the lifetime is shared)
46 LifetimedPtr(const LifetimedPtr&) = default;
47
48 // constructs a `LifetimedPtr` by coercing from a more-derived pointer
49 template<std::derived_from<T> U>
51 lifetime_watcher_{other.lifetime_watcher_},
52 ptr_{other.ptr_}
53 {}
54
55 // normal move construction (the lifetime is moved from)
57
58 // constructs a `LifetimedPtr` by coercing from a more-derived pointer
61 lifetime_watcher_{std::move(other.lifetime_watcher_)},
62 ptr_{other.ptr_}
63 {}
64
67
69
71 {
72 return lifetime_watcher_.expired();
73 }
74
75 void reset()
76 {
77 *this = LifetimedPtr{};
78 }
79
80 T* get() const
81 {
82 if (ptr_ == nullptr) {
83 return nullptr;
84 }
85 assert_within_lifetime();
86 return ptr_;
87 }
88
90 {
91 return not expired() ? ptr_ : nullptr;
92 }
93
94 T& operator*() const
95 {
96 assert_within_lifetime();
97 return *ptr_;
98 }
99
100 T* operator->() const
101 {
102 assert_within_lifetime();
103 return ptr_;
104 }
105
106 explicit operator bool() const noexcept
107 {
108 return ptr_ and not lifetime_watcher_.expired();
109 }
110
111 template<typename U>
113 {
114 return {lifetime_watcher_, dynamic_cast<U*>(ptr_)};
115 }
116 private:
117 void assert_within_lifetime() const
118 {
119 if (lifetime_watcher_.expired()) {
120 throw std::runtime_error{"attempted to dereference a null pointer"};
121 }
122 }
123
124 // self-friend-class for the coercing constructor
125 template<typename> friend class LifetimedPtr;
126
127 template<typename T1, typename T2>
128 friend bool operator==(const LifetimedPtr<T1>&, const LifetimedPtr<T2>&);
129
130 template<typename T1>
131 friend bool operator==(const LifetimedPtr<T1>&, std::nullptr_t);
132
133 LifetimeWatcher lifetime_watcher_;
134 T* ptr_ = nullptr;
135 };
136
137 template<typename T, typename U>
139 {
140 return lhs.ptr_ == rhs .ptr_;
141 }
142
143 template<typename T>
144 bool operator==(const LifetimedPtr<T>& lhs, std::nullptr_t)
145 {
146 return lhs.ptr_ == nullptr;
147 }
148}
Definition lifetime_watcher.h:11
bool expired() const noexcept
Definition lifetime_watcher.h:15
Definition lifetimed_ptr.h:25
constexpr LifetimedPtr()=default
T * get() const
Definition lifetimed_ptr.h:80
T * get_if_not_expired() const
Definition lifetimed_ptr.h:89
LifetimedPtr(const LifetimedPtr< U > &other)
Definition lifetimed_ptr.h:50
constexpr LifetimedPtr(std::nullptr_t)
Definition lifetimed_ptr.h:31
T * operator->() const
Definition lifetimed_ptr.h:100
LifetimedPtr & operator=(LifetimedPtr &&) noexcept=default
LifetimedPtr< U > dynamic_downcast()
Definition lifetimed_ptr.h:112
bool expired() const noexcept
Definition lifetimed_ptr.h:70
T & operator*() const
Definition lifetimed_ptr.h:94
void reset()
Definition lifetimed_ptr.h:75
LifetimedPtr(LifetimedPtr &&) noexcept=default
LifetimedPtr(const LifetimedPtr &)=default
LifetimedPtr(const Lifetime &lifetime, T *ptr)
Definition lifetimed_ptr.h:41
LifetimedPtr & operator=(const LifetimedPtr &)=default
friend bool operator==(const LifetimedPtr< T1 > &, std::nullptr_t)
friend bool operator==(const LifetimedPtr< T1 > &, const LifetimedPtr< T2 > &)
LifetimedPtr(LifetimeWatcher lifetime_watcher, T *ptr)
Definition lifetimed_ptr.h:34
Definition custom_decoration_generator.h:5
bool operator==(const Class &, const Class &)
constexpr U to(T &&value)
Definition conversion.h:56
and
Definition algorithms.h:158