Aeon Engine c550894
AeonGames Open Source Game Engine
Loading...
Searching...
No Matches
UniqueAnyPtr.hpp
1/*
2Copyright (C) 2018,2019,2025,2026 Rodrigo Jose Hernandez Cordoba
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16#ifndef AEONGAMES_UNIQUEANYPTR_H
17#define AEONGAMES_UNIQUEANYPTR_H
18#include <sstream>
19#include <memory>
20#include <typeinfo>
21#include <algorithm>
22
23namespace AeonGames
24{
31 {
32 void* mPointer{};
33 const std::type_info& ( *mManager ) ( void* aPointer )
34 {
35 nullptr
36 };
37 public:
41 void Swap ( UniqueAnyPtr& aUniqueAnyPtr ) noexcept
42 {
43 std::swap ( mPointer, aUniqueAnyPtr.mPointer );
44 std::swap ( mManager, aUniqueAnyPtr.mManager );
45 }
46
49 UniqueAnyPtr() noexcept = default;
51 UniqueAnyPtr ( std::nullptr_t ) noexcept : mManager
52 {
53 nullptr
54 } {};
55 UniqueAnyPtr ( const UniqueAnyPtr& aUniqueResource ) = delete;
56 UniqueAnyPtr& operator= ( const UniqueAnyPtr& aUniqueResource ) = delete;
60 UniqueAnyPtr ( UniqueAnyPtr&& aUniqueAnyPtr ) noexcept : mManager
61 {
62 nullptr
63 }
64 {
65 aUniqueAnyPtr.Swap ( *this );
66 }
67
72 template<class T>
73 UniqueAnyPtr ( std::unique_ptr<T>&& aUniquePointer ) noexcept :
74 mPointer{ aUniquePointer.release() }, mManager{Manager<T>} {}
75
80 template<class T>
81 UniqueAnyPtr ( T* aPointer ) noexcept :
82 mPointer{reinterpret_cast<void*> ( aPointer ) }, mManager{Manager<T>} {}
83
88 template<class T>
89 UniqueAnyPtr ( T&& aValue ) noexcept :
90 mPointer{new T ( std::move ( aValue ) ) }, mManager{Manager<T>} {}
91
94 {
95 if ( mManager )
96 {
97 mManager ( mPointer );
98 };
99 }
100
101
108 UniqueAnyPtr& operator= ( UniqueAnyPtr&& aUniqueAnyPtr ) noexcept
109 {
110 aUniqueAnyPtr.Swap ( *this );
111 return *this;
112 }
113
119 template<class T>
120 UniqueAnyPtr& operator= ( std::unique_ptr<T>&& aUniquePointer ) noexcept
121 {
122 if ( mManager )
123 {
124 mManager ( mPointer );
125 };
126 mPointer = aUniquePointer.release();
127 mManager = Manager<T>;
128 return *this;
129 }
130
136 template<class T>
137 UniqueAnyPtr& operator= ( T* aPointer ) noexcept
138 {
139 if ( mManager )
140 {
141 mManager ( mPointer );
142 };
143 mPointer = aPointer;
144 mManager = Manager<T>;
145 return *this;
146 }
147
148
152 const void* GetRaw() const
153 {
154 return mPointer;
155 }
156
162 template<class T> T* Get() const
163 {
164 if ( !mPointer )
165 {
166 return nullptr;
167 }
168 else if ( !HasType<T>() )
169 {
170 std::ostringstream stream;
171 stream << "Unique Any Pointer of different type, Requested: " << typeid ( T ).name() << " Contained: " << GetTypeInfo().name();
172 throw std::runtime_error ( stream.str().c_str() );
173 }
174 return reinterpret_cast<T*> ( mPointer );
175 }
176
182 template<class T> T* Get()
183 {
184 // EC++ Item 3
185 return const_cast<T*> ( static_cast<const UniqueAnyPtr*> ( this )->Get<T>() );
186 }
187
192 {
193 void* pointer = mPointer;
194 mPointer = nullptr;
195 mManager = nullptr;
196 return pointer;
197 }
198
204 template<class T> T* Release()
205 {
206 if ( !HasType<T>() )
207 {
208 std::ostringstream stream;
209 stream << "Unique Any Pointer of different type, Requested: " << typeid ( T ).name() << " Contained: " << GetTypeInfo().name();
210 throw std::runtime_error ( stream.str().c_str() );
211 }
212 return reinterpret_cast<T*> ( ReleaseRaw() );
213 }
214
220 template<class T> std::unique_ptr<T> UniquePointer()
221 {
222 return std::unique_ptr<T> ( Release<T>() );
223 }
224
226 void Reset()
227 {
228 UniqueAnyPtr unique_any_ptr{nullptr};
229 unique_any_ptr.Swap ( *this );
230 }
231
235 const std::type_info& GetTypeInfo() const
236 {
237 if ( mManager )
238 {
239 return mManager ( nullptr );
240 }
241 return typeid ( nullptr );
242 }
243
248 template<class T>
249 bool HasType() const
250 {
251 return GetTypeInfo().hash_code() == typeid ( T ).hash_code();
252 }
253
254 private:
255 template<typename T> static const std::type_info& Manager ( void* aPointer )
256 {
257 if ( aPointer )
258 {
259 delete reinterpret_cast<T*> ( aPointer );
260 }
261 return typeid ( T );
262 }
263 };
264
271 template<typename T, typename... Ts>
272 UniqueAnyPtr MakeUniqueAny ( Ts&&... params )
273 {
274 return UniqueAnyPtr ( new T ( ::std::forward<Ts> ( params )... ) );
275 }
276}
277#endif
A type-erased owning smart pointer with unique ownership semantics.
T * Get()
Returns a typed pointer to the owned object (non-const overload).
UniqueAnyPtr(T &&aValue) noexcept
Constructs by moving a value into a new heap allocation.
UniqueAnyPtr() noexcept=default
Default constructor.
const void * GetRaw() const
Returns a const void pointer to the owned object.
std::unique_ptr< T > UniquePointer()
Releases ownership and returns a std::unique_ptr.
T * Release()
Releases ownership and returns a typed pointer.
UniqueAnyPtr(UniqueAnyPtr &&aUniqueAnyPtr) noexcept
Move constructor.
UniqueAnyPtr(std::unique_ptr< T > &&aUniquePointer) noexcept
Constructs from a std::unique_ptr, taking ownership.
void * ReleaseRaw()
Releases ownership and returns the raw void pointer.
void Swap(UniqueAnyPtr &aUniqueAnyPtr) noexcept
Swaps the contents of this pointer with another.
const std::type_info & GetTypeInfo() const
Returns the std::type_info of the stored type.
T * Get() const
Returns a typed pointer to the owned object (const overload).
UniqueAnyPtr(T *aPointer) noexcept
Constructs from a raw pointer, taking ownership.
void Reset()
Destroys the owned object and resets to empty state.
bool HasType() const
Checks whether the stored object is of type T.
<- This is here just for the literals
Definition AABB.hpp:31
UniqueAnyPtr MakeUniqueAny(Ts &&... params)
Creates a UniqueAnyPtr owning a new instance of T.
STL namespace.