Toast Engine
Loading...
Searching...
No Matches
box.inl
1#pragma once
2#include "box.hpp"
3#include "toast/log.hpp"
4
5namespace toast {
6
7template<typename T>
8Box<T>::~Box() noexcept {
9 if (control) {
10 control->decrement();
11 }
12}
13
14template<typename T>
15Box<T>::Box(_detail::ControlBox* control_box) noexcept {
16 if (control_box) {
17 this->control = control_box;
18 control->increment();
19 }
20}
21
22template<typename T>
23Box<T>::Box(const T* node) noexcept {
25 if (control_box) {
26 control = control_box;
27 control->increment();
28 }
29}
30
31template<typename T>
32Box<T>::Box(const T& node) noexcept {
34 if (control_box) {
35 control = control_box;
36 control->increment();
37 }
38}
39
40template<typename T>
41Box<T>::Box(const Box& other) noexcept {
42 _detail::ControlBox* control_box = other.control;
43 if (control_box) {
44 control = control_box;
45 control->increment();
46 }
47}
48
49template<typename T>
50auto Box<T>::operator=(const Box& other) noexcept -> Box& {
51 if (this->control == other.control) {
52 return *this;
53 }
54 if (control) {
55 control->decrement();
56 }
57 control = other.control;
58 if (control) {
59 control->increment();
60 }
61 return *this;
62}
63
64template<typename T>
65Box<T>::Box(Box&& other) noexcept {
66 control = other.control;
67 other.control = nullptr;
68}
69
70template<typename T>
71auto Box<T>::operator=(Box&& other) noexcept -> Box& {
72 if (this->control == other.control) {
73 return *this;
74 }
75 if (control) {
76 control->decrement();
77 }
78 control = other.control;
79 other.control = nullptr;
80 return *this;
81}
82
83template<typename T>
84template<typename U>
85 requires std::convertible_to<U*, T*>
86Box<T>::Box(const Box<U>& other) noexcept {
87 _detail::ControlBox* control_box = other.control;
88 if (control_box) {
89 control = control_box;
90 control->increment();
91 }
92}
93
94template<typename T>
95template<typename U>
96 requires std::convertible_to<U*, T*>
97auto Box<T>::operator=(const Box<U>& other) noexcept -> Box& {
98 if (this->control == other.control) {
99 return *this;
100 }
101 if (control) {
102 control->decrement();
103 }
104 control = other.control;
105 if (control) {
106 control->increment();
107 }
108 return *this;
109}
110
111template<typename T>
112template<typename U>
113 requires std::convertible_to<U*, T*>
114Box<T>::Box(Box<U>&& other) noexcept {
115 control = other.control;
116 other.control = nullptr;
117}
118
119template<typename T>
120template<typename U>
121 requires std::convertible_to<U*, T*>
122auto Box<T>::operator=(Box<U>&& other) noexcept -> Box& {
123 if (this->control == other.control) {
124 return *this;
125 }
126 if (control) {
127 control->decrement();
128 }
129 control = other.control;
130 other.control = nullptr;
131 return *this;
132}
133
134template<typename T>
135auto Box<T>::exists() const noexcept -> bool {
136 return (control != nullptr) && (control->node != nullptr);
137}
138
139template<typename T>
140auto Box<T>::operator<=>(const Box& other) const noexcept -> std::strong_ordering {
141 if (this->control && other.control) {
142 return *this->control <=> *other.control;
143 }
144 return this->control <=> other.control;
145}
146
147template<typename T>
148auto Box<T>::operator==(const Box& other) const noexcept -> bool {
149 return (*this <=> other) == std::strong_ordering::equal;
150}
151
152template<typename T>
153Box<T>::operator bool() const noexcept {
154 return this->exists();
155}
156
157template<typename T>
158Box<T>::operator T&() noexcept {
159 TOAST_ASSERT(control && control->node, "Box", "Box is in a Invalid State: ControlBox or Node is nullptr");
160 return static_cast<T&>(*control->node);
161}
162
163template<typename T>
164auto Box<T>::operator->() noexcept -> T* {
165 TOAST_ASSERT(control && control->node, "Box", "Box is in a Invalid State: ControlBox or Node is nullptr");
166 return static_cast<T*>(control->node);
167}
168
169template<typename T>
170auto Box<T>::operator*() noexcept -> T& {
171 TOAST_ASSERT(control && control->node, "Box", "Box is in a Invalid State: ControlBox or Node is nullptr");
172 return static_cast<T&>(*control->node);
173}
174
175template<typename T>
176Box<T>::operator const T&() const noexcept {
177 TOAST_ASSERT(control && control->node, "Box", "Box is in a Invalid State: ControlBox or Node is nullptr");
178 return static_cast<T&>(*control->node);
179}
180
181template<typename T>
182auto Box<T>::operator->() const noexcept -> const T* {
183 TOAST_ASSERT(control && control->node, "Box", "Box is in a Invalid State: ControlBox or Node is nullptr");
184 return static_cast<T*>(control->node);
185}
186
187template<typename T>
188auto Box<T>::operator*() const noexcept -> const T& {
189 TOAST_ASSERT(control && control->node, "Box", "Box is in a Invalid State: ControlBox or Node is nullptr");
190 return static_cast<T&>(*control->node);
191}
192
193template<typename T>
194template<typename U>
195 requires std::derived_from<U, T>
196auto Box<T>::as() const noexcept -> Box<U> {
197 if (control && control->node) {
198 if (dynamic_cast<const U*>(control->node)) {
199 return Box<U>(control);
200 }
201 }
202 return Box<U>();
203}
204
205template<typename T>
206auto Box<T>::rid() const noexcept -> size_t {
207 return control->rid();
208}
209}
pseudo shared pointer for Nodes
Intrusive reference-counted handle to a Node.
Definition box.hpp:35
Box() noexcept=default
Default-constructs an empty (null) box; does not allocate anything.
auto operator=(const Box &other) noexcept -> Box &
Shares ownership with other; increments ref count.
Definition box.inl:50
auto as() const noexcept -> Box< U >
Downcasts to a derived type; a null Box returns a null Box rather than throwing.
Definition box.inl:196
auto rid() const noexcept -> size_t
Raw identity of the underlying ControlBox as a pointer value; stable for the node's lifetime; used as...
Definition box.inl:206
auto exists() const noexcept -> bool
Whether this box holds a live node.
Definition box.inl:135
Public logging interface for the engine.
Reference-count control block embedded inside the Node allocation.
Definition control_box.hpp:33
static auto get(const Node *node) -> ControlBox *
Recovers the ControlBox from a raw node pointer; the ControlBox sits immediately before the Node in m...
Definition control_box.cpp:37
void increment()
relaxed acquire; acquiring a Box is always preceded by an acquire elsewhere
Definition control_box.cpp:29