API Documentation
Loading...
Searching...
No Matches
Pointer.hpp
Go to the documentation of this file.
1/**--------------------------------------------------------------------------------------------
2Copyright (c) 2019, NDEVR LLC
3tyler.parke@ndevr.org
4 __ __ ____ _____ __ __ _______
5 | \ | | | __ \ | ___|\ \ / / | __ \
6 | \ | | | | \ \ | |___ \ \ / / | |__) |
7 | . \| | | |__/ / | |___ \ V / | _ /
8 | |\ |_|_____/__|_____|___\_/____| | \ \
9 |__| \__________________________________| \__\
10
11Subject to the terms of the Enterprise+ Agreement, NDEVR hereby grants
12Licensee a limited, non-exclusive, non-transferable, royalty-free license
13(without the right to sublicense) to use the API solely for the purpose of
14Licensee's internal development efforts to develop applications for which
15the API was provided.
16
17The above copyright notice and this permission notice shall be included in all
18copies or substantial portions of the Software.
19
20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
21INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
22PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
23FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
24OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25DEALINGS IN THE SOFTWARE.
26
27Library: Base
28File: Pointer
29Included in API: True
30Author(s): Tyler Parke
31 *-----------------------------------------------------------------------------------------**/
32#pragma once
33#include <NDEVR/ConcurrentOperation.h>
34#include <NDEVR/BaseValues.h>
35#include <NDEVR/LibAssert.h>
36#ifdef NDEVR_USE_STD_POINTER
37 #include <memory>
38#endif
39#ifndef NDEVR_USE_STD_POINTER
40namespace NDEVR
41{
42 struct Core
43 {
46 {}
48 };
49
50 template< class t_other_type, class t_type>
51 constexpr typename std::enable_if<std::is_polymorphic<t_type>::value, bool>::type CheckCanCast(t_type* other)
52 {
53 return dynamic_cast<t_other_type*>(other) != nullptr;
54 }
55 template<class t_other_type, class t_type>
56 constexpr typename std::enable_if<!std::is_polymorphic<t_type>::value, bool>::type CheckCanCast(t_type*)
57 {
58 return true;
59 }
60 template<class t_type>
61 class Pointer
62 {
63 protected:
64 Pointer() noexcept
65 : m_core(nullptr)
66 , m_object(nullptr)
67 {}
68 Pointer(t_type* value) noexcept
69 : m_core(value == nullptr ? nullptr : new Core())
70 , m_object(value)
71 {}
72 Pointer(t_type&& value) noexcept
73 : m_core(new Core())
74 , m_object(new t_type(std::move(value)))
75 {}
76 Pointer(const Pointer<t_type>& value) noexcept
77 : m_core(value.m_core)
78 , m_object(value.m_object)
79 {
80 if (m_core != nullptr)
82 }
83 t_type& get() const
84 {
85 lib_assert(m_object != nullptr, "Tried to access null pointer");
86 return *m_object;
87 }
88 constexpr t_type* rawptr() const
89 {
90 return m_object;
91 }
92 void set(t_type&& value)
93 {
94 setToNull();
95 m_core = new Core();
96 m_object = new t_type(std::move(value));
97 }
98 Pointer& operator=(const Pointer& pointer)
99 {
100 if (pointer.m_core == m_core)
101 return *this;
102 setToNull();
103 m_core = pointer.m_core;
104 m_object = pointer.m_object;
105 if(m_core)
107 lib_assert((m_core == nullptr) == (m_object == nullptr), "Pointer core null mismatch");
108 return *this;
109 }
110 Pointer& operator=(t_type* pointer)
111 {
112 setToNull();
113 if (pointer)
114 {
115 m_core = new Core();
116 m_object = pointer;
117 }
118 lib_assert((m_core == nullptr) == (m_object == nullptr), "Pointer core null mismatch");
119 return *this;
120 }
121
123 {
124 setToNull();
125 }
126 public:
127 bool isNull() const { return m_object == nullptr; }
128 void setToNull()
129 {
130 if (m_core == nullptr)
131 return;
133 if (m_core->reference_count == 0)
134 {
135 delete m_core;
136 delete m_object;
137 }
138 m_core = nullptr;
139 m_object = nullptr;
140 }
141 [[nodiscard]] uint04 referenceCount() const
142 {
143 if (m_core)
144 return m_core->reference_count;
145 else
146 return 0;
147 }
148 bool operator==(const Pointer<t_type>& pointer) const
149 {
150 return pointer.m_object == m_object;
151 }
152 bool operator!=(const Pointer<t_type>& pointer) const
153 {
154 return pointer.m_object != m_object;
155 }
156 void swap(Pointer<t_type>& pointer)
157 {
158 std::swap(m_core, pointer.m_core);
159 std::swap(m_object, pointer.m_object);
160 }
161 protected:
162 Core* m_core = nullptr;
163 t_type* m_object = nullptr;
164 };
165#else
166 template<class t_type>
167 class Pointer
168 {
169 template<class T>
170 friend class ConstPointer;
171 template<class T>
172 friend class DynamicPointer;
173 protected:
174 Pointer() noexcept
175 : m_ptr(nullptr)
176 {}
177 Pointer(t_type* value) noexcept
178 : m_ptr(value)
179 {}
180 Pointer(t_type&& value) noexcept
181 : m_ptr(new t_type(std::move(value)))
182 {}
183 Pointer(const Pointer<t_type>& value) noexcept
184 : m_ptr(value.m_ptr)
185 {
186 }
187 t_type& get() const
188 {
189 lib_assert(m_ptr != nullptr, "Tried to access null pointer");
190 return *m_ptr.get();
191 }
192 void set(t_type&& value)
193 {
194 m_ptr = std::shared_ptr<t_type>(new t_type(std::move(value)));
195 }
196 Pointer& operator=(const Pointer& pointer)
197 {
198 m_ptr = pointer.m_ptr;
199 return *this;
200 }
201 Pointer& operator=(t_type*&& pointer)
202 {
203 m_ptr = pointer;
204 return *this;
205 }
206
207 ~Pointer()
208 {
209 }
210 public:
211 bool isNull() const { return m_ptr == nullptr; }
212 void setToNull()
213 {
214 m_ptr = std::shared_ptr<t_type>();
215 }
216 bool operator==(const Pointer<t_type>& pointer) const
217 {
218 return pointer.m_ptr == m_ptr;
219 }
220 bool operator!=(const Pointer<t_type>& pointer) const
221 {
222 return pointer.m_ptr != m_ptr;
223 }
224 void swap(Pointer<t_type>& pointer)
225 {
226 std::swap(m_ptr, pointer.m_ptr);
227 }
228 protected:
229 std::shared_ptr<t_type> m_ptr;
230 };
231#endif
232 template<class t_type>
233 class ConstPointer : public Pointer<t_type>
234 {
235 public:
237 {}
238 ConstPointer(t_type&& value) noexcept
239 : Pointer<t_type>(std::move(value))
240 {}
241 /*ConstPointer(t_type* value) noexcept
242 : Pointer<t_type>(value)
243 {}*/
244 ConstPointer(const t_type* value) noexcept
245 : Pointer<t_type>(const_cast<t_type*>(value))
246 {}
247 ConstPointer(const Pointer<t_type>& value) noexcept
248 : Pointer<t_type>(value)
249 {}
250
251 const t_type& get() const
252 {
253 lib_assert(!Pointer<t_type>::isNull(), "Tried to access nullptr");
254 return Pointer<t_type>::get();
255 }
256 constexpr const t_type* rawptr() const
257 {
259 }
260 void set(t_type&& value) noexcept
261 {
262 Pointer<t_type>::set(std::move(value));
263 }
264 const t_type* operator->() const
265 {
266 lib_assert(!Pointer<t_type>::isNull(), "Tried to access nullptr");
267 return &Pointer<t_type>::get();
268 }
269
271 {
273 return (*this);
274 }
276 {
278 return (*this);
279 }
280 template<class t_other_type>
282 {
284#ifndef NDEVR_USE_STD_POINTER
286 {
287 memcpy(&pointer, this, sizeof(ConstPointer<t_type>));
289 }
290#else
291 pointer.m_ptr = std::dynamic_pointer_cast<t_other_type>(Pointer<t_type>::m_ptr);
292#endif
293 return pointer;
294 }
295 };
296 template<class t_type, class t_index_type, bool t_null_term>
298 template<class t_allocater, class t_type>
300
301 template<class t_type>
302 class DynamicPointer : public ConstPointer<t_type>
303 {
304 friend class MemoryManager<BufferAllocator<DynamicPointer<t_type>, uint04, false>, t_type>;
305 public:
308 DynamicPointer(t_type* value) noexcept
309 : ConstPointer<t_type>(value)
310 {}
311 DynamicPointer(t_type&& value) noexcept
312 : ConstPointer<t_type>(std::move(value))
313 {}
315 : ConstPointer<t_type>(value)
316 {}
318 : ConstPointer<t_type>(std::move(value))
319 {}
320 public:
321 constexpr t_type& get() const
322 {
323 return Pointer<t_type>::get();
324 }
325 constexpr t_type* rawptr() const
326 {
328 }
329
330 void set(t_type&& value)
331 {
332 Pointer<t_type>::set(std::move(value));
333 }
334 t_type* operator->() const
335 {
336 lib_assert(!Pointer<t_type>::isNull(), "Tried to access nullptr");
337 return &Pointer<t_type>::get();
338 }
339
341 {
343 return (*this);
344 }
345 DynamicPointer& operator=(t_type* pointer)
346 {
348 return (*this);
349 }
350
351 template<class t_other_type>
353 {
355#ifndef NDEVR_USE_STD_POINTER
357 {
358 memcpy(&pointer, this, sizeof(DynamicPointer<t_type>));
360 }
361#else
362 pointer.m_ptr = std::dynamic_pointer_cast<t_other_type>(Pointer<t_type>::m_ptr);
363#endif
364 return pointer;
365 }
366 };
367
368}
369
#define lib_assert(expression, message)
Asserts some logic in the code. Disabled in non debug mode by default. Can be re-enabled in release u...
Definition LibAssert.h:70
Definition Pointer.hpp:297
static uint04 increment(volatile uint04 &value)
Definition ConcurrentOperation.cpp:12
static uint04 decrement(volatile uint04 &value)
Definition ConcurrentOperation.cpp:20
Definition GraphicsPipeline.h:42
ConstPointer()
Definition Pointer.hpp:236
constexpr const t_type * rawptr() const
Definition Pointer.hpp:256
ConstPointer< t_other_type > as() const
Definition Pointer.hpp:281
ConstPointer(const t_type *value) noexcept
Definition Pointer.hpp:244
ConstPointer(const Pointer< t_type > &value) noexcept
Definition Pointer.hpp:247
ConstPointer< t_type > & operator=(t_type *pointer)
Definition Pointer.hpp:275
ConstPointer(t_type &&value) noexcept
Definition Pointer.hpp:238
const t_type & get() const
Definition Pointer.hpp:251
ConstPointer< t_type > & operator=(const Pointer< t_type > &pointer) noexcept
Definition Pointer.hpp:270
void set(t_type &&value) noexcept
Definition Pointer.hpp:260
const t_type * operator->() const
Definition Pointer.hpp:264
Definition Pointer.hpp:303
DynamicPointer< t_other_type > as() const
Definition Pointer.hpp:352
void set(t_type &&value)
Definition Pointer.hpp:330
DynamicPointer & operator=(const DynamicPointer &pointer)
Definition Pointer.hpp:340
DynamicPointer(t_type *value) noexcept
Definition Pointer.hpp:308
DynamicPointer & operator=(t_type *pointer)
Definition Pointer.hpp:345
DynamicPointer()
Definition Pointer.hpp:306
constexpr t_type * rawptr() const
Definition Pointer.hpp:325
DynamicPointer(DynamicPointer< t_type > &&value) noexcept
Definition Pointer.hpp:317
t_type * operator->() const
Definition Pointer.hpp:334
DynamicPointer(t_type &&value) noexcept
Definition Pointer.hpp:311
constexpr t_type & get() const
Definition Pointer.hpp:321
DynamicPointer(const DynamicPointer< t_type > &value) noexcept
Definition Pointer.hpp:314
Definition Pointer.hpp:299
Definition Pointer.hpp:62
void set(t_type &&value)
Definition Pointer.hpp:92
t_type * m_object
Definition Pointer.hpp:163
Pointer & operator=(t_type *pointer)
Definition Pointer.hpp:110
constexpr t_type * rawptr() const
Definition Pointer.hpp:88
Pointer(t_type &&value) noexcept
Definition Pointer.hpp:72
Core * m_core
Definition Pointer.hpp:162
t_type & get() const
Definition Pointer.hpp:83
void setToNull()
Definition Pointer.hpp:128
uint04 referenceCount() const
Definition Pointer.hpp:141
void swap(Pointer< t_type > &pointer)
Definition Pointer.hpp:156
~Pointer()
Definition Pointer.hpp:122
bool isNull() const
Definition Pointer.hpp:127
bool operator!=(const Pointer< t_type > &pointer) const
Definition Pointer.hpp:152
bool operator==(const Pointer< t_type > &pointer) const
Definition Pointer.hpp:148
Pointer() noexcept
Definition Pointer.hpp:64
Pointer(t_type *value) noexcept
Definition Pointer.hpp:68
Pointer & operator=(const Pointer &pointer)
Definition Pointer.hpp:98
Pointer(const Pointer< t_type > &value) noexcept
Definition Pointer.hpp:76
Definition ACIColor.h:37
constexpr std::enable_if< std::is_polymorphic< t_type >::value, bool >::type CheckCanCast(t_type *other)
Definition Pointer.hpp:51
uint32_t uint04
-Defines an alias representing a 4 byte, unsigned integer -Can represent exact integer values 0 throu...
Definition BaseValues.hpp:120
Definition Pointer.hpp:43
Core()
Definition Pointer.hpp:44
volatile uint04 reference_count
Definition Pointer.hpp:47