SDL3pp
A slim C++ wrapper for SDL3
Loading...
Searching...
No Matches
SDL3pp_resource.h
1#ifndef SDL3PP_RESOURCE_H_
2#define SDL3PP_RESOURCE_H_
3
4#include <memory>
5#include <optional>
6
7namespace SDL {
8
15template<class T, class RESOURCE>
16concept ResourceHandle = requires(const T& test) {
17 { *test } -> std::convertible_to<RESOURCE>;
18};
19
27template<class T>
29{
30 T m_resource;
31
32public:
34 using value_type = T;
35
37 constexpr Resource(T resource = {})
38 : m_resource(std::move(resource))
39 {
40 }
41
43 constexpr Resource(const ResourceHandle<Resource<T>> auto& resource)
44 : Resource(*resource)
45 {
46 }
47
49 constexpr Resource(std::nullptr_t)
50 : m_resource{0}
51 {
52 }
53
55 constexpr Resource(std::nullopt_t)
56 : m_resource{0}
57 {
58 }
59
61 constexpr explicit operator bool() const { return m_resource; }
62
64 constexpr operator value_type() const { return m_resource; }
65
67 constexpr bool operator==(const Resource& other) const = default;
68
70 constexpr bool operator==(std::nullopt_t) const { return !m_resource; }
71
73 constexpr bool operator==(std::nullptr_t) const { return !m_resource; }
74
76 constexpr T get() const { return m_resource; }
77
79 constexpr const T operator->() const { return get(); }
80
82 constexpr T operator->() { return get(); }
83};
84
86template<class RESOURCE>
88{
90 void operator()(RESOURCE& ref) const { RESOURCE::reset(ref.get()); }
91};
92
98template<class RESOURCE>
100{
101public:
103 using reference = RESOURCE;
104
106 using value_type = typename reference::value_type;
107
108private:
110 reference m_value;
111
112protected:
114 constexpr ResourcePtrBase(value_type value = {})
115 : m_value(value)
116 {
117 }
118
120 reference& get() { return m_value; }
121
122public:
124 constexpr operator bool() const { return bool(m_value); }
125
127 constexpr bool operator==(const ResourcePtrBase& other) const
128 {
129 return m_value == other.m_value;
130 };
131
133 constexpr bool operator==(std::nullptr_t) const { return !*this; }
134
136 constexpr bool operator==(std::nullopt_t) const { return !*this; }
137
139 constexpr reference operator*() const { return m_value; }
140
142 constexpr const reference* operator->() const { return &m_value; }
143
145 constexpr reference* operator->() { return &m_value; }
146
148 reference get() const { return m_value; }
149};
150
156template<class RESOURCE, class DELETER>
157class ResourceOwnerBase : public ResourcePtrBase<RESOURCE>
158{
160 DELETER m_deleter;
161
162protected:
164 constexpr ResourceOwnerBase(base::value_type value = {}, DELETER deleter = {})
165 : base(value)
166 , m_deleter(std::move(deleter))
167 {
168 }
169
171 void free() { m_deleter(base::get()); }
172
173public:
175 using deleter = DELETER;
176
178 RESOURCE release()
179 {
180 RESOURCE value = base::get();
181 base::get() = {};
182 return value;
183 }
184};
185
195template<class RESOURCE, class DELETER = DefaultDeleter<RESOURCE>>
196class ResourceUnsafe : public ResourceOwnerBase<RESOURCE, DELETER>
197{
199
200public:
202 constexpr ResourceUnsafe() = default;
203
205 constexpr explicit ResourceUnsafe(RESOURCE other, DELETER deleter = {})
206 : base(other, std::move(deleter))
207 {
208 other = nullptr;
209 }
210
212 void reset()
213 {
214 base::free();
216 }
217};
218
224template<class RESOURCE, class DELETER = DefaultDeleter<RESOURCE>>
225class ResourceUnique : public ResourceOwnerBase<RESOURCE, DELETER>
226{
228
229public:
231 constexpr ResourceUnique(std::nullptr_t = nullptr) {};
232
234 constexpr explicit ResourceUnique(base::value_type value,
235 DELETER deleter = {})
236 : base(value, std::move(deleter))
237 {
238 }
239
242 : base(other)
243 {
244 other.release();
245 }
246
247 ResourceUnique(const ResourceUnique& other) = delete;
248
255
258 {
259 base::operator=(other);
260 other.release();
261 return *this;
262 }
263
265 void reset()
266 {
267 base::free();
269 }
270};
271
272// Forward decl
273template<class UNIQUE>
274class ResourceWeak;
275
281template<class UNIQUE>
282class ResourceShared : public ResourcePtrBase<typename UNIQUE::reference>
283{
285 std::shared_ptr<UNIQUE> m_shared;
286
288 constexpr explicit ResourceShared(std::shared_ptr<UNIQUE> shared)
289 : base(shared ? **shared : nullptr)
290 , m_shared(std::move(shared))
291 {
292 }
293
294public:
296 constexpr ResourceShared(std::nullptr_t = nullptr) {};
297
299 constexpr ResourceShared(UNIQUE&& value)
300 : base(*value)
301 , m_shared(std::make_shared<UNIQUE>(std::move(value)))
302 {
303 }
304
306 constexpr explicit ResourceShared(base::value_type value,
307 typename UNIQUE::deleter deleter = {})
308 : ResourceShared(UNIQUE(value, std::move(deleter)))
309 {
310 }
311
313 constexpr bool unique() const { return m_shared.unique(); }
314
316 void reset() { *this = {}; }
317
318 friend class ResourceWeak<UNIQUE>;
319};
320
326template<class UNIQUE>
328{
329 std::weak_ptr<UNIQUE> m_shared;
330
331public:
333 constexpr ResourceWeak() = default;
334
336 constexpr ResourceWeak(const ResourceShared<UNIQUE>& shared)
337 : m_shared(shared.m_shared)
338 {
339 }
340
342 constexpr bool operator==(const ResourceWeak& other) const = default;
343
345 constexpr bool expired() const { return m_shared.expired(); }
346
348 constexpr operator bool() const { return !expired(); }
349
352 {
353 return ResourceShared<UNIQUE>(m_shared.lock());
354 }
355};
356
370template<class RESOURCE, class UNIQUE>
372 : public ResourceOwnerBase<RESOURCE, DefaultDeleter<RESOURCE>>
373{
375
376public:
378 constexpr explicit DetachedResource(RESOURCE other)
379 : base(other)
380 {
381 other = nullptr;
382 }
383
384 DetachedResource(const DetachedResource& other) = delete;
385
387 constexpr DetachedResource(DetachedResource&& other) = default;
388
389 DetachedResource& operator=(const DetachedResource& other) = delete;
390
392 constexpr DetachedResource& operator=(DetachedResource&& other) = default;
393
395 operator UNIQUE() && { return UNIQUE{base::release()}; }
396};
397
406template<class RESOURCE>
407class LockBase : public ResourceOwnerBase<RESOURCE, DefaultDeleter<RESOURCE>>
408{
410
411protected:
413 constexpr LockBase(RESOURCE&& resource)
414 : base(std::move(resource))
415 {
416 }
417
418public:
420 constexpr LockBase() = default;
421
422 LockBase(const LockBase& other) = delete;
423
426 : base(std::move(other))
427 {
428 other.get() = nullptr;
429 }
430
432 constexpr ~LockBase() { SDL_assert_paranoid(!*this); }
433
436 {
437 base::operator=(other);
438 other.get() = nullptr;
439 return *this;
440 }
441};
442
446template<class T>
447std::size_t hash(const SDL::Resource<T>& s) noexcept
448{
449 return std::hash<T>{}(s.get());
450}
451
455template<class T>
456std::size_t hash(const SDL::ResourcePtrBase<T>& s) noexcept
457{
458 return hash(s.get());
459}
460
465struct Hash
466{
468 template<class T>
469 std::size_t operator()(const T& s) const noexcept
470 {
471 return hash(s);
472 }
473};
474
475} // namespace SDL
476
477#endif /* SDL3PP_RESOURCE_H_ */
A detached reference to resource that might be transformed into an owned handle.
Definition SDL3pp_resource.h:373
constexpr DetachedResource(DetachedResource &&other)=default
Move ctor.
constexpr DetachedResource & operator=(DetachedResource &&other)=default
Move assignment.
constexpr DetachedResource(RESOURCE other)
Constructs pointer from anything compatible.
Definition SDL3pp_resource.h:378
Base class for locks.
Definition SDL3pp_resource.h:408
LockBase & operator=(LockBase other)
Move assignment.
Definition SDL3pp_resource.h:435
LockBase(LockBase &&other)
Move ctor.
Definition SDL3pp_resource.h:425
constexpr LockBase(RESOURCE &&resource)
Constructs initializing member.
Definition SDL3pp_resource.h:413
constexpr LockBase()=default
Default ctor.
constexpr ~LockBase()
Dtor.
Definition SDL3pp_resource.h:432
Base class for resource pointer-like owner objects.
Definition SDL3pp_resource.h:158
constexpr ResourceOwnerBase(base::value_type value={}, DELETER deleter={})
Constructs from raw type.
Definition SDL3pp_resource.h:164
void free()
Frees resource.
Definition SDL3pp_resource.h:171
RESOURCE release()
Returns reference and reset this.
Definition SDL3pp_resource.h:178
DELETER deleter
The deleter type.
Definition SDL3pp_resource.h:175
Base class for resource pointer-like objects.
Definition SDL3pp_resource.h:100
constexpr bool operator==(const ResourcePtrBase &other) const
Comparison.
Definition SDL3pp_resource.h:127
constexpr ResourcePtrBase(value_type value={})
Constructs from raw type.
Definition SDL3pp_resource.h:114
constexpr bool operator==(std::nullopt_t) const
Comparison.
Definition SDL3pp_resource.h:136
constexpr bool operator==(std::nullptr_t) const
Comparison.
Definition SDL3pp_resource.h:133
constexpr const reference * operator->() const
Gets addressable reference.
Definition SDL3pp_resource.h:142
constexpr reference operator*() const
Gets reference.
Definition SDL3pp_resource.h:139
reference & get()
Get reference.
Definition SDL3pp_resource.h:120
typename reference::value_type value_type
The raw resource type.
Definition SDL3pp_resource.h:106
reference get() const
Get reference.
Definition SDL3pp_resource.h:148
constexpr reference * operator->()
Gets addressable reference.
Definition SDL3pp_resource.h:145
RESOURCE reference
The reference resource type.
Definition SDL3pp_resource.h:103
Implement shared ownership for a resource.
Definition SDL3pp_resource.h:283
constexpr ResourceShared(base::value_type value, typename UNIQUE::deleter deleter={})
Constructs from raw type.
Definition SDL3pp_resource.h:306
constexpr ResourceShared(std::nullptr_t=nullptr)
Default constructor.
Definition SDL3pp_resource.h:296
constexpr ResourceShared(UNIQUE &&value)
Constructs from unique type.
Definition SDL3pp_resource.h:299
void reset()
Reset this instance.
Definition SDL3pp_resource.h:316
constexpr bool unique() const
True if this is the only shared instance.
Definition SDL3pp_resource.h:313
Implement unique ownership for a resource.
Definition SDL3pp_resource.h:226
constexpr ResourceUnique(std::nullptr_t=nullptr)
Default constructor.
Definition SDL3pp_resource.h:231
void reset()
Resets the value, destroying the resource if not nullptr.
Definition SDL3pp_resource.h:265
constexpr ResourceUnique & operator=(ResourceUnique other)
Assignment operator.
Definition SDL3pp_resource.h:257
constexpr ResourceUnique(base::value_type value, DELETER deleter={})
Constructs from raw type.
Definition SDL3pp_resource.h:234
constexpr ResourceUnique(ResourceUnique &&other)
Move constructor.
Definition SDL3pp_resource.h:241
~ResourceUnique()
Destructor.
Definition SDL3pp_resource.h:254
A dumb pointer to resource.
Definition SDL3pp_resource.h:197
void reset()
Resets the value, destroying the resource if not nullptr.
Definition SDL3pp_resource.h:212
constexpr ResourceUnsafe(RESOURCE other, DELETER deleter={})
Constructs pointer from anything compatible.
Definition SDL3pp_resource.h:205
constexpr ResourceUnsafe()=default
Default constructor.
Implement weak ownership for a resource.
Definition SDL3pp_resource.h:328
ResourceShared< UNIQUE > lock() const
Lock back to ResourceShared.
Definition SDL3pp_resource.h:351
constexpr ResourceWeak(const ResourceShared< UNIQUE > &shared)
Constructs from ResourceShared.
Definition SDL3pp_resource.h:336
constexpr bool expired() const
True if expired.
Definition SDL3pp_resource.h:345
constexpr ResourceWeak()=default
Default constructor.
constexpr bool operator==(const ResourceWeak &other) const =default
Compares.
A SDL managed resource.
Definition SDL3pp_resource.h:29
constexpr bool operator==(const Resource &other) const =default
Comparison.
T value_type
The raw resource type.
Definition SDL3pp_resource.h:34
constexpr T operator->()
Access to fields.
Definition SDL3pp_resource.h:82
constexpr Resource(const ResourceHandle< Resource< T > > auto &resource)
Constructs from pointer like.
Definition SDL3pp_resource.h:43
constexpr Resource(T resource={})
Constructs from the underlying resource.
Definition SDL3pp_resource.h:37
constexpr Resource(std::nullptr_t)
Equivalent to default ctor.
Definition SDL3pp_resource.h:49
constexpr const T operator->() const
Access to fields.
Definition SDL3pp_resource.h:79
constexpr bool operator==(std::nullptr_t) const
Comparison.
Definition SDL3pp_resource.h:73
constexpr T get() const
Return contained resource;.
Definition SDL3pp_resource.h:76
constexpr bool operator==(std::nullopt_t) const
Comparison.
Definition SDL3pp_resource.h:70
constexpr Resource(std::nullopt_t)
Equivalent to default ctor.
Definition SDL3pp_resource.h:55
Concept representing a valid resource handle.
Definition SDL3pp_resource.h:16
#define SDL_assert_paranoid(condition)
An assertion test that is performed only when built with paranoid settings.
Definition SDL3pp_assert.h:364
the main namespace where all SDL3pp public functions and types live
Definition SDL3pp_assert.h:7
std::size_t hash(const SDL::Resource< T > &s) noexcept
Get hash for resource type.
Definition SDL3pp_resource.h:447
Default deleter.
Definition SDL3pp_resource.h:88
void operator()(RESOURCE &ref) const
Deletes resource.
Definition SDL3pp_resource.h:90
Utility class to help creating std::hash.
Definition SDL3pp_resource.h:466
std::size_t operator()(const T &s) const noexcept
Calculate hash.
Definition SDL3pp_resource.h:469