stdex Additional custom or not Standard C++ covered algorithms

Loading...
Searching...
No Matches
memory.hpp
1/*
2 SPDX-License-Identifier: MIT
3 Copyright © 2023-2024 Amebis
4*/
5
6#pragma once
7
8#include "compat.hpp"
9#include <memory>
10
11#if defined(__GNUC__)
12#pragma GCC diagnostic push
13#pragma GCC diagnostic ignored "-Wunknown-pragmas"
14#endif
15
16 namespace stdex
17{
21 template <class T>
22 struct no_delete {
23 constexpr no_delete() noexcept = default;
24
25 template <class T2, std::enable_if_t<std::is_convertible_v<T2*, T*>, int> = 0>
26 no_delete(const no_delete<T2>&) noexcept {}
27
28 void operator()(T* p) const noexcept { _Unreferenced_(p); }
29 };
30
34 template <class T>
35 struct no_delete<T[]> {
36 constexpr no_delete() noexcept = default;
37
38 template <class T2, std::enable_if_t<std::is_convertible_v<T2(*)[], T(*)[]>, int> = 0>
39 no_delete(const no_delete<T2[]>&) noexcept {}
40
41 template <class T2, std::enable_if_t<std::is_convertible_v<T2(*)[], T(*)[]>, int> = 0>
42 void operator()(T2* p) const noexcept { p; }
43 };
44
53 template <class T>
54 std::shared_ptr<T> make_shared_no_delete(_In_ T* p)
55 {
56 return std::shared_ptr<T>(p, no_delete<T>{});
57 }
58
59 // sanitizing_allocator::destroy() member generates p parameter not used warning for primitive datatypes T.
60 #pragma warning(push)
61 #pragma warning(disable: 4100)
62
70 template <class T>
71 class sanitizing_allocator : public std::allocator<T>
72 {
73 public:
77 template <class T2>
78 struct rebind
79 {
80 typedef sanitizing_allocator<T2> other;
81 };
82
86 sanitizing_allocator() noexcept : std::allocator<T>()
87 {}
88
92 sanitizing_allocator(_In_ const sanitizing_allocator<T> &other) : std::allocator<T>(other)
93 {}
94
98 template <class T2>
99 sanitizing_allocator(_In_ const sanitizing_allocator<T2> &other) noexcept : std::allocator<T>(other)
100 {}
101
105 void deallocate(_In_ T* const p, _In_ const std::size_t n)
106 {
107#ifdef _WIN32
108 SecureZeroMemory(p, sizeof(T) * n);
109#else
110 memset(p, 0, sizeof(T) * n);
111#endif
112 std::allocator<T>::deallocate(p, n);
113 }
114 };
115
116 #pragma warning(pop)
117
121 template <size_t N>
122 class sanitizing_blob
123 {
124 public:
125 sanitizing_blob()
126 {
127 memset(m_data, 0, N);
128 }
129
130 ~sanitizing_blob()
131 {
132#ifdef _WIN32
133 SecureZeroMemory(m_data, N);
134#else
135 memset(m_data, 0, N);
136#endif
137 }
138
139 public:
140 unsigned char m_data[N];
141 };
142
146 template <typename T, typename D>
147 class ref_unique_ptr
148 {
149 public:
155 ref_unique_ptr(_Inout_ std::unique_ptr<T, D> &owner) :
156 m_own(owner),
157 m_ptr(owner.release())
158 {}
159
165 ref_unique_ptr(_Inout_ ref_unique_ptr<T, D> &&other) :
166 m_own(other.m_own),
167 m_ptr(other.m_ptr)
168 {
169 other.m_ptr = nullptr;
170 }
171
175 ~ref_unique_ptr()
176 {
177 if (m_ptr != nullptr)
178 m_own.reset(m_ptr);
179 }
180
186 operator T**()
187 {
188 return &m_ptr;
189 }
190
196 operator T*&()
197 {
198 return m_ptr;
199 }
200
201 protected:
202 std::unique_ptr<T, D> &m_own;
203 T *m_ptr;
204 };
205
213 template<class T, class D>
214 ref_unique_ptr<T, D> get_ptr(_Inout_ std::unique_ptr<T, D> &owner) noexcept
215 {
216 return ref_unique_ptr<T, D>(owner);
217 }
218
223 template<typename T, typename D>
224 class ref_unique_ptr<T[], D>
225 {
226 public:
232 ref_unique_ptr(_Inout_ std::unique_ptr<T[], D> &owner) noexcept :
233 m_own(owner),
234 m_ptr(owner.release())
235 {}
236
242 ref_unique_ptr(_Inout_ ref_unique_ptr<T[], D> &&other) :
243 m_own(other.m_own),
244 m_ptr(other.m_ptr)
245 {
246 other.m_ptr = nullptr;
247 }
248
252 virtual ~ref_unique_ptr()
253 {
254 if (m_ptr != nullptr)
255 m_own.reset(m_ptr);
256 }
257
263 operator T**() noexcept
264 {
265 return &m_ptr;
266 }
267
273 operator T*&()
274 {
275 return m_ptr;
276 }
277
278 protected:
279 std::unique_ptr<T[], D> &m_own;
280 T *m_ptr;
281 };
282
291 template<class T, class D>
292 ref_unique_ptr<T[], D> get_ptr(_Inout_ std::unique_ptr<T[], D>& owner) noexcept
293 {
294 return ref_unique_ptr<T[], D>(owner);
295 }
296}
297
298#if defined(__GNUC__)
299#pragma GCC diagnostic pop
300#endif
stdex::ref_unique_ptr< T[], D >::m_ptr
T * m_ptr
Pointer.
Definition memory.hpp:280
stdex::ref_unique_ptr< T[], D >::~ref_unique_ptr
virtual ~ref_unique_ptr()
Returns ownership of the pointer.
Definition memory.hpp:252
stdex::ref_unique_ptr< T[], D >::ref_unique_ptr
ref_unique_ptr(std::unique_ptr< T[], D > &owner) noexcept
Takes ownership of the pointer.
Definition memory.hpp:232
stdex::ref_unique_ptr< T[], D >::m_own
std::unique_ptr< T[], D > & m_own
Original owner of the pointer.
Definition memory.hpp:279
stdex::ref_unique_ptr< T[], D >::ref_unique_ptr
ref_unique_ptr(ref_unique_ptr< T[], D > &&other)
Moves object.
Definition memory.hpp:242
stdex::ref_unique_ptr
Helper class for returning pointers to std::unique_ptr.
Definition memory.hpp:148
stdex::ref_unique_ptr::ref_unique_ptr
ref_unique_ptr(ref_unique_ptr< T, D > &&other)
Moves object.
Definition memory.hpp:165
stdex::ref_unique_ptr::m_ptr
T * m_ptr
Pointer.
Definition memory.hpp:203
stdex::ref_unique_ptr::~ref_unique_ptr
~ref_unique_ptr()
Returns ownership of the pointer.
Definition memory.hpp:175
stdex::ref_unique_ptr::ref_unique_ptr
ref_unique_ptr(std::unique_ptr< T, D > &owner)
Takes ownership of the pointer.
Definition memory.hpp:155
stdex::ref_unique_ptr::m_own
std::unique_ptr< T, D > & m_own
Original owner of the pointer.
Definition memory.hpp:202
stdex::sanitizing_allocator
An allocator template that sanitizes each memory block before it is destroyed or reallocated.
Definition memory.hpp:72
stdex::sanitizing_allocator::deallocate
void deallocate(T *const p, const std::size_t n)
Deallocate object at p sanitizing its content first.
Definition memory.hpp:105
stdex::sanitizing_allocator::sanitizing_allocator
sanitizing_allocator() noexcept
Construct default allocator.
Definition memory.hpp:86
stdex::sanitizing_allocator::sanitizing_allocator
sanitizing_allocator(const sanitizing_allocator< T2 > &other) noexcept
Construct from a related allocator.
Definition memory.hpp:99
stdex::sanitizing_allocator::sanitizing_allocator
sanitizing_allocator(const sanitizing_allocator< T > &other)
Construct by copying.
Definition memory.hpp:92
stdex::sanitizing_blob
Sanitizing BLOB.
Definition memory.hpp:123
stdex::sanitizing_blob::m_data
unsigned char m_data[N]
BLOB data.
Definition memory.hpp:140
stdex::no_delete
Noop deleter.
Definition memory.hpp:22
stdex::sanitizing_allocator::rebind
Convert this type to sanitizing_allocator<T2>
Definition memory.hpp:79
stdex::sanitizing_allocator::rebind::other
sanitizing_allocator< T2 > other
Other type.
Definition memory.hpp:80