IceShard
1
A personal game engine project, with development focused on 2D/2.5D games.
Toggle main menu visibility
Loading...
Searching...
No Matches
memsys
public
ice
mem_unique_ptr.hxx
Go to the documentation of this file.
1
3
4
#pragma once
5
#include <
ice/mem_allocator.hxx
>
6
7
namespace
ice
8
{
9
10
template
<
typename
T>
11
struct
UniquePtr
;
12
13
template
<
typename
T,
typename
... Args>
14
inline
auto
make_unique
(
ice::Allocator
&
alloc
, Args&&... args)
noexcept
-> ice::UniquePtr<T>;
15
16
template
<
typename
T>
17
using
UniquePtrCustomDeleter
= void(T*)
noexcept
;
18
19
template
<
typename
T>
20
inline
auto
make_unique
(
ice::UniquePtrCustomDeleter<T>
* fn_deleter, T* instanced_object)
noexcept
->
ice::UniquePtr<T>
;
21
22
23
template
<
typename
T>
24
struct
UniquePtr
25
{
26
struct
UserDeleterInfo
;
27
28
inline
UniquePtr
() noexcept;
29
inline ~
UniquePtr
() noexcept;
30
31
inline explicit
UniquePtr
(
ice
::
Allocator
*
alloc
, T* ptr) noexcept;
32
inline explicit
UniquePtr
(
ice
::
UniquePtrCustomDeleter
<T>* deleter_fn, T* ptr) noexcept;
33
34
inline
UniquePtr
(
UniquePtr
&& other) noexcept;
35
template<typename U> requires std::is_base_of_v<T, U>
36
inline
UniquePtr
(
UniquePtr
<U>&& other) noexcept;
37
38
inline auto operator=(
UniquePtr
&& other) noexcept ->
UniquePtr
&;
39
template<typename U> requires std::is_base_of_v<T, U>
40
inline auto operator=(
UniquePtr
<U>&& other) noexcept ->
UniquePtr
&;
41
inline auto operator=(std::nullptr_t) noexcept ->
UniquePtr
&;
42
43
bool
operator==(std::nullptr_t) const noexcept {
return
_ptr
==
nullptr
; }
44
45
auto
operator->
() const noexcept -> T* {
return
_ptr
; }
46
auto
operator*
() const noexcept -> T& {
return
*
_ptr
; }
47
48
inline
auto
get
() const noexcept -> T* {
return
_ptr
; }
49
inline
void
reset
() noexcept;
50
51
Allocator
*
_alloc
;
52
T*
_ptr
;
53
void
*
_deleter
;
54
};
55
56
template<typename T>
57
struct
UniquePtr
<T>::
UserDeleterInfo
58
{
59
//ice::Allocator* alloc;
60
ice::UniquePtrCustomDeleter<T>
*
fn_deleter
;
61
};
62
63
template
<
typename
T>
64
inline
UniquePtr<T>::UniquePtr
() noexcept
65
:
_alloc
{
nullptr
}
66
,
_ptr
{
nullptr
}
67
{ }
68
69
template
<
typename
T>
70
inline
UniquePtr<T>::~UniquePtr
() noexcept
71
{
72
reset
();
73
}
74
75
template
<
typename
T>
76
inline
UniquePtr<T>::UniquePtr
(
ice::Allocator
*
alloc
, T* ptr) noexcept
77
:
_alloc
{
alloc
}
78
,
_ptr
{ ptr }
79
,
_deleter
{
nullptr
}
80
{ }
81
82
template
<
typename
T>
83
inline
UniquePtr<T>::UniquePtr
(
ice::UniquePtrCustomDeleter<T>
* deleter_fn, T* ptr) noexcept
84
:
_alloc
{
nullptr
}
85
,
_ptr
{ ptr }
86
,
_deleter
{
reinterpret_cast<
void
*
>
(deleter_fn) }
87
{ }
88
89
template
<
typename
T>
90
inline
UniquePtr<T>::UniquePtr
(
UniquePtr
&& other) noexcept
91
:
_alloc
{ std::exchange(other._alloc,
nullptr
) }
92
,
_ptr
{ std::exchange(other._ptr,
nullptr
) }
93
,
_deleter
{ std::exchange(other._deleter,
nullptr
) }
94
{
95
}
96
97
template
<
typename
T>
98
template
<
typename
U>
requires
std::is_base_of_v<T, U>
99
inline
UniquePtr<T>::UniquePtr
(
UniquePtr<U>
&& other) noexcept
100
:
_alloc
{ std::exchange(other._alloc,
nullptr
) }
101
,
_ptr
{ std::exchange(other._ptr,
nullptr
) }
102
,
_deleter
{ std::exchange(other._deleter,
nullptr
) }
103
{
104
}
105
106
template
<
typename
T>
107
inline
auto
UniquePtr<T>::operator=
(
UniquePtr
&& other)
noexcept
->
UniquePtr
&
108
{
109
if
(
this
!= &other)
110
{
111
reset
();
112
113
_alloc
= std::exchange(other._alloc,
nullptr
);
114
_ptr
= std::exchange(other._ptr,
nullptr
);
115
_deleter
= std::exchange(other._deleter,
nullptr
);
116
}
117
return
*
this
;
118
}
119
120
template
<
typename
T>
121
template
<
typename
U>
requires
std::is_base_of_v<T, U>
122
inline
auto
UniquePtr<T>::operator=
(
UniquePtr<U>
&& other)
noexcept
->
UniquePtr
&
123
{
124
reset
();
125
126
_alloc
= std::exchange(other._alloc,
nullptr
);
127
_ptr
= std::exchange(other._ptr,
nullptr
);
128
_deleter
= std::exchange(other._deleter,
nullptr
);
129
return
*
this
;
130
}
131
132
template
<
typename
T>
133
inline
auto
UniquePtr<T>::operator=
(std::nullptr_t)
noexcept
->
UniquePtr
&
134
{
135
reset
();
136
return
*
this
;
137
}
138
139
template
<
typename
T>
140
inline
void
UniquePtr<T>::reset
() noexcept
141
{
142
if
(
_ptr
==
nullptr
)
143
{
144
return
;
145
}
146
147
// If we don't have a 'special' case
148
if
(
_alloc
!=
nullptr
)
149
{
150
if
constexpr
(
ice::is_type_complete<T>
)
151
{
152
ICE_ASSERT_CORE
(
_deleter
==
nullptr
);
// TODO: Implement various deleters
153
_alloc
->destroy(
_ptr
);
154
}
155
else
156
{
157
//static_assert(ice::is_type_complete<T>);
158
ICE_ASSERT_CORE
(
_deleter
!=
nullptr
);
// MEMORY LEAK INBOUND! Cannot delete object of incomplete type!
159
}
160
}
161
else
162
{
163
ICE_ASSERT_CORE
(
_deleter
!=
nullptr
);
// TODO: Implement various deleters
164
ice::UniquePtrCustomDeleter<T>
* fn_deleter = std::bit_cast<ice::UniquePtrCustomDeleter<T>*>(
_deleter
);
165
fn_deleter(
_ptr
);
166
}
167
168
_alloc
=
nullptr
;
169
_ptr
=
nullptr
;
170
_deleter
=
nullptr
;
171
}
172
173
template
<
typename
T,
typename
... Args>
174
concept
MakeUniqueConstructorAvailable
=
requires
(Args&&... args) {
175
{
new
T{ std::forward<Args>(args)... } } -> std::convertible_to<T*>;
176
};
177
178
template
<
typename
T,
typename
... Args>
179
inline
auto
make_unique
(
ice::Allocator
&
alloc
, Args&&... args)
noexcept
->
ice::UniquePtr<T>
180
{
181
static_assert
(std::is_abstract_v<T> ==
false
,
"Can't instantiate an abstract type!"
);
182
static_assert
(
MakeUniqueConstructorAvailable<T, decltype(ice::forward<Args>
(args))...>,
"Can't call the constructor for the given type and arguments!"
);
183
return
ice::UniquePtr<T>
{ &
alloc
,
alloc
.create<T>(ice::forward<Args>(args)...) };
184
}
185
186
template
<
typename
T>
187
inline
auto
make_unique
(
ice::UniquePtrCustomDeleter<T>
* fn_deleter, T* instanced_object)
noexcept
->
ice::UniquePtr<T>
188
{
189
return
ice::UniquePtr<T>
{ fn_deleter, instanced_object };
190
}
191
192
}
// namespace ice
ICE_ASSERT_CORE
#define ICE_ASSERT_CORE(expression)
Definition
assert_core.hxx:43
ice::MakeUniqueConstructorAvailable
Definition
mem_unique_ptr.hxx:174
mem_allocator.hxx
ice
SPDX-License-Identifier: MIT.
Definition
array.hxx:12
ice::is_type_complete
constexpr bool is_type_complete
Definition
base.hxx:76
ice::alloc
auto alloc(ice::usize size) noexcept -> ice::AllocResult
ice::make_unique
auto make_unique(ice::Allocator &alloc, Args &&... args) noexcept -> ice::UniquePtr< T >
Definition
mem_unique_ptr.hxx:179
ice::UniquePtrCustomDeleter
void(T *) noexcept UniquePtrCustomDeleter
Definition
mem_unique_ptr.hxx:17
ice::Allocator
ice::AllocatorBase< ice::build::is_debug||ice::build::is_develop > Allocator
Definition
mem_types.hxx:25
ice::UniquePtr::UserDeleterInfo
Definition
mem_unique_ptr.hxx:58
ice::UniquePtr::UserDeleterInfo::fn_deleter
ice::UniquePtrCustomDeleter< T > * fn_deleter
Definition
mem_unique_ptr.hxx:60
ice::UniquePtr
Definition
mem_unique_ptr.hxx:25
ice::UniquePtr< ParamsInternal > const::_alloc
Allocator * _alloc
Definition
mem_unique_ptr.hxx:51
ice::UniquePtr< ParamsInternal > const::_ptr
ParamsInternal * _ptr
Definition
mem_unique_ptr.hxx:52
ice::UniquePtr::operator*
auto operator*() const noexcept -> T &
Definition
mem_unique_ptr.hxx:46
ice::UniquePtr::~UniquePtr
~UniquePtr() noexcept
Definition
mem_unique_ptr.hxx:70
ice::UniquePtr::get
auto get() const noexcept -> T *
Definition
mem_unique_ptr.hxx:48
ice::UniquePtr::operator->
auto operator->() const noexcept -> T *
Definition
mem_unique_ptr.hxx:45
ice::UniquePtr::reset
void reset() noexcept
Definition
mem_unique_ptr.hxx:140
ice::UniquePtr< ParamsInternal > const::_deleter
void * _deleter
Definition
mem_unique_ptr.hxx:53
ice::UniquePtr::operator=
auto operator=(UniquePtr &&other) noexcept -> UniquePtr &
Definition
mem_unique_ptr.hxx:107
ice::UniquePtr::UniquePtr
UniquePtr() noexcept
Definition
mem_unique_ptr.hxx:64
Generated by
1.18.0