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 /**--------------------------------------------------------------------------------------------------
43 \brief Used by Pointer to store the reference count of the pointer.
44 **/
46 {
51 };
52
53 template< class t_other_type, class t_type>
54 constexpr typename std::enable_if<std::is_polymorphic<t_type>::value, bool>::type CheckCanCast(t_type* other)
55 {
56 return dynamic_cast<t_other_type*>(other) != nullptr;
57 }
58 template<class t_other_type, class t_type>
59 constexpr typename std::enable_if<!std::is_polymorphic<t_type>::value, bool>::type CheckCanCast(t_type*)
60 {
61 return true;
62 }
63
64 /**--------------------------------------------------------------------------------------------------
65 \brief Provides shared ownership of a dynamically allocated object.
66
67 Weaker overall logic (Cannot detect circular references) but faster.
68 **/
69 template<class t_type>
70 class Pointer
71 {
72 protected:
73 Pointer() noexcept
74 : m_core(nullptr)
75 , m_object(nullptr)
76 {}
77 Pointer(t_type* value) noexcept
78 : m_core(value == nullptr ? nullptr : new PointerCore())
79 , m_object(value)
80 {}
81 Pointer(t_type&& value) noexcept
82 : m_core(new PointerCore())
83 , m_object(new t_type(std::move(value)))
84 {}
85 Pointer(const Pointer<t_type>& value) noexcept
86 : m_core(value.m_core)
87 , m_object(value.m_object)
88 {
89 if (m_core != nullptr)
91 }
92 t_type& get() const
93 {
94 lib_assert(m_object != nullptr, "Tried to access null pointer");
95 return *m_object;
96 }
97 constexpr t_type* rawptr() const
98 {
99 return m_object;
100 }
101 void set(t_type&& value)
102 {
103 setToNull();
104 m_core = new PointerCore();
105 m_object = new t_type(std::move(value));
106 }
107 Pointer& operator=(const Pointer& pointer)
108 {
109 if (pointer.m_core == m_core)
110 return *this;
111 setToNull();
112 m_core = pointer.m_core;
113 m_object = pointer.m_object;
114 if(m_core)
116 lib_assert((m_core == nullptr) == (m_object == nullptr), "Pointer core null mismatch");
117 return *this;
118 }
119 Pointer& operator=(t_type* pointer)
120 {
121 setToNull();
122 if (pointer)
123 {
124 m_core = new PointerCore();
125 m_object = pointer;
126 }
127 lib_assert((m_core == nullptr) == (m_object == nullptr), "Pointer core null mismatch");
128 return *this;
129 }
130
132 {
133 setToNull();
134 }
135 public:
136 bool isNull() const { return m_object == nullptr; }
137 void setToNull()
138 {
139 if (m_core == nullptr)
140 return;
142 if (m_core->reference_count == 0)
143 {
144 delete m_core;
145 delete m_object;
146 }
147 m_core = nullptr;
148 m_object = nullptr;
149 }
150 [[nodiscard]] uint04 referenceCount() const
151 {
152 if (m_core)
153 return m_core->reference_count;
154 else
155 return 0;
156 }
157 bool operator==(const Pointer<t_type>& pointer) const
158 {
159 return pointer.m_object == m_object;
160 }
161 bool operator!=(const Pointer<t_type>& pointer) const
162 {
163 return pointer.m_object != m_object;
164 }
165 void swap(Pointer<t_type>& pointer)
166 {
167 std::swap(m_core, pointer.m_core);
168 std::swap(m_object, pointer.m_object);
169 }
170 protected:
171 PointerCore* m_core = nullptr;
172 t_type* m_object = nullptr;
173 };
174#else
175 template<class t_type>
176 class Pointer
177 {
178 template<class T>
179 friend class ConstPointer;
180 template<class T>
181 friend class DynamicPointer;
182 protected:
183 Pointer() noexcept
184 : m_ptr(nullptr)
185 {}
186 Pointer(t_type* value) noexcept
187 : m_ptr(value)
188 {}
189 Pointer(t_type&& value) noexcept
190 : m_ptr(new t_type(std::move(value)))
191 {}
192 Pointer(const Pointer<t_type>& value) noexcept
193 : m_ptr(value.m_ptr)
194 {
195 }
196 t_type& get() const
197 {
198 lib_assert(m_ptr != nullptr, "Tried to access null pointer");
199 return *m_ptr.get();
200 }
201 void set(t_type&& value)
202 {
203 m_ptr = std::shared_ptr<t_type>(new t_type(std::move(value)));
204 }
205 Pointer& operator=(const Pointer& pointer)
206 {
207 m_ptr = pointer.m_ptr;
208 return *this;
209 }
210 Pointer& operator=(t_type*&& pointer)
211 {
212 m_ptr = pointer;
213 return *this;
214 }
215
216 ~Pointer()
217 {
218 }
219 public:
220 bool isNull() const { return m_ptr == nullptr; }
221 void setToNull()
222 {
223 m_ptr = std::shared_ptr<t_type>();
224 }
225 bool operator==(const Pointer<t_type>& pointer) const
226 {
227 return pointer.m_ptr == m_ptr;
228 }
229 bool operator!=(const Pointer<t_type>& pointer) const
230 {
231 return pointer.m_ptr != m_ptr;
232 }
233 void swap(Pointer<t_type>& pointer)
234 {
235 std::swap(m_ptr, pointer.m_ptr);
236 }
237 protected:
238 std::shared_ptr<t_type> m_ptr;
239 };
240#endif
241 /**--------------------------------------------------------------------------------------------------
242 \brief Provides a constant, unmodifiable pointer that has shared ownership of a dynamically allocated object.
243
244 Weaker overall logic (Cannot detect circular references) but faster.
245 **/
246 template<class t_type>
247 class ConstPointer : public Pointer<t_type>
248 {
249 public:
251 {}
252 ConstPointer(t_type&& value) noexcept
253 : Pointer<t_type>(std::move(value))
254 {}
255 /*ConstPointer(t_type* value) noexcept
256 : Pointer<t_type>(value)
257 {}*/
258 ConstPointer(const t_type* value) noexcept
259 : Pointer<t_type>(const_cast<t_type*>(value))
260 {}
261 ConstPointer(const Pointer<t_type>& value) noexcept
262 : Pointer<t_type>(value)
263 {}
264
265 const t_type& get() const
266 {
267 lib_assert(!Pointer<t_type>::isNull(), "Tried to access nullptr");
268 return Pointer<t_type>::get();
269 }
270 constexpr const t_type* rawptr() const
271 {
273 }
274 void set(t_type&& value) noexcept
275 {
276 Pointer<t_type>::set(std::move(value));
277 }
278 const t_type* operator->() const
279 {
280 lib_assert(!Pointer<t_type>::isNull(), "Tried to access nullptr");
281 return &Pointer<t_type>::get();
282 }
283
285 {
287 return (*this);
288 }
290 {
292 return (*this);
293 }
294 template<class t_other_type>
296 {
298#ifndef NDEVR_USE_STD_POINTER
300 {
301 memcpy(&pointer, this, sizeof(ConstPointer<t_type>));
303 }
304#else
305 pointer.m_ptr = std::dynamic_pointer_cast<t_other_type>(Pointer<t_type>::m_ptr);
306#endif
307 return pointer;
308 }
309 };
310 template<class t_type, class t_index_type, bool t_null_term>
312
313 /**--------------------------------------------------------------------------------------------------
314 \brief Provides a modifiable pointer that has shared ownership of a dynamically allocated object.
315
316 Weaker overall logic (Cannot detect circular references) but faster.
317 **/
318 template<class t_type>
319 class DynamicPointer : public ConstPointer<t_type>
320 {
321 public:
324 DynamicPointer(t_type* value) noexcept
325 : ConstPointer<t_type>(value)
326 {}
327 DynamicPointer(t_type&& value) noexcept
328 : ConstPointer<t_type>(std::move(value))
329 {}
331 : ConstPointer<t_type>(value)
332 {}
334 : ConstPointer<t_type>(std::move(value))
335 {}
336 public:
337 constexpr t_type& get() const
338 {
339 return Pointer<t_type>::get();
340 }
341 constexpr t_type* rawptr() const
342 {
344 }
345
346 void set(t_type&& value)
347 {
348 Pointer<t_type>::set(std::move(value));
349 }
350 t_type* operator->() const
351 {
352 lib_assert(!Pointer<t_type>::isNull(), "Tried to access nullptr");
353 return &Pointer<t_type>::get();
354 }
355
357 {
359 return (*this);
360 }
361 DynamicPointer& operator=(t_type* pointer)
362 {
364 return (*this);
365 }
366
367 template<class t_other_type>
369 {
371#ifndef NDEVR_USE_STD_POINTER
373 {
374 memcpy(&pointer, this, sizeof(DynamicPointer<t_type>));
376 }
377#else
378 pointer.m_ptr = std::dynamic_pointer_cast<t_other_type>(Pointer<t_type>::m_ptr);
379#endif
380 return pointer;
381 }
382 };
383
384}
385
#define lib_assert(expression, message)
Definition LibAssert.h:61
Specific logic for reserving memory for a Buffer. When managed, and more memory is needed memory is r...
Definition Pointer.hpp:311
static uint04 decrement(volatile uint04 &value)
static uint04 increment(volatile uint04 &value)
Provides a constant, unmodifiable pointer that has shared ownership of a dynamically allocated object...
Definition GraphicsPipeline.h:42
ConstPointer()
Definition Pointer.hpp:250
constexpr const t_type * rawptr() const
Definition Pointer.hpp:270
ConstPointer< t_other_type > as() const
Definition Pointer.hpp:295
ConstPointer(const t_type *value) noexcept
Definition Pointer.hpp:258
ConstPointer(const Pointer< t_type > &value) noexcept
Definition Pointer.hpp:261
ConstPointer< t_type > & operator=(t_type *pointer)
Definition Pointer.hpp:289
ConstPointer(t_type &&value) noexcept
Definition Pointer.hpp:252
const t_type & get() const
Definition Pointer.hpp:265
ConstPointer< t_type > & operator=(const Pointer< t_type > &pointer) noexcept
Definition Pointer.hpp:284
void set(t_type &&value) noexcept
Definition Pointer.hpp:274
const t_type * operator->() const
Definition Pointer.hpp:278
Provides a modifiable pointer that has shared ownership of a dynamically allocated object.
Definition Pointer.hpp:320
DynamicPointer< t_other_type > as() const
Definition Pointer.hpp:368
void set(t_type &&value)
Definition Pointer.hpp:346
DynamicPointer & operator=(const DynamicPointer &pointer)
Definition Pointer.hpp:356
DynamicPointer(t_type *value) noexcept
Definition Pointer.hpp:324
DynamicPointer & operator=(t_type *pointer)
Definition Pointer.hpp:361
DynamicPointer()
Definition Pointer.hpp:322
constexpr t_type * rawptr() const
Definition Pointer.hpp:341
DynamicPointer(DynamicPointer< t_type > &&value) noexcept
Definition Pointer.hpp:333
t_type * operator->() const
Definition Pointer.hpp:350
DynamicPointer(t_type &&value) noexcept
Definition Pointer.hpp:327
constexpr t_type & get() const
Definition Pointer.hpp:337
DynamicPointer(const DynamicPointer< t_type > &value) noexcept
Definition Pointer.hpp:330
Provides shared ownership of a dynamically allocated object.
Definition Pointer.hpp:71
void set(t_type &&value)
Definition Pointer.hpp:101
t_type * m_object
Definition Pointer.hpp:172
Pointer & operator=(t_type *pointer)
Definition Pointer.hpp:119
PointerCore * m_core
Definition Pointer.hpp:171
constexpr t_type * rawptr() const
Definition Pointer.hpp:97
Pointer(t_type &&value) noexcept
Definition Pointer.hpp:81
t_type & get() const
Definition Pointer.hpp:92
void setToNull()
Definition Pointer.hpp:137
uint04 referenceCount() const
Definition Pointer.hpp:150
void swap(Pointer< t_type > &pointer)
Definition Pointer.hpp:165
~Pointer()
Definition Pointer.hpp:131
bool isNull() const
Definition Pointer.hpp:136
bool operator!=(const Pointer< t_type > &pointer) const
Definition Pointer.hpp:161
bool operator==(const Pointer< t_type > &pointer) const
Definition Pointer.hpp:157
Pointer() noexcept
Definition Pointer.hpp:73
Pointer(t_type *value) noexcept
Definition Pointer.hpp:77
Pointer & operator=(const Pointer &pointer)
Definition Pointer.hpp:107
Pointer(const Pointer< t_type > &value) noexcept
Definition Pointer.hpp:85
Definition ACIColor.h:37
constexpr std::enable_if< std::is_polymorphic< t_type >::value, bool >::type CheckCanCast(t_type *other)
Definition Pointer.hpp:54
uint32_t uint04
-Defines an alias representing a 4 byte, unsigned integer -Can represent exact integer values 0 throu...
Definition BaseValues.hpp:96
Used by Pointer to store the reference count of the pointer.
Definition Pointer.hpp:46
PointerCore()
Definition Pointer.hpp:47
volatile uint04 reference_count
Definition Pointer.hpp:50