Ocean
Loading...
Searching...
No Matches
ScopedObject.h
Go to the documentation of this file.
1/*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8#ifndef META_OCEAN_BASE_SCOPED_OBJECT_H
9#define META_OCEAN_BASE_SCOPED_OBJECT_H
10
11#include "ocean/base/Base.h"
12#include "ocean/base/DataType.h"
13
14namespace Ocean
15{
16
17/**
18 * This class wraps an unmanaged object (or reference) which needs to be released after usage.
19 * The release function can be defined at runtime.
20 * @tparam T The data type of the wrapped object
21 * @tparam TReleaseValue The optional explicit data type of the object to be released
22 * @tparam TReleaseFunction The data type of the release function
23 * @see ScopedObjectCompileTime.
24 * @ingroup base
25 */
26template <typename T, typename TReleaseValue = T, typename TReleaseFunction = void(*)(TReleaseValue)>
28{
29 public:
30
31 /**
32 * Default constructor creating an object with invalid object.
33 */
34 ScopedObjectT() = default;
35
36 /**
37 * Move constructor.
38 * @param scopedObject The scoped object to be moved
39 */
41
42 /**
43 * Creates a new scoped object.
44 * @param object The object to be wrapped
45 * @param releaseFunction The release function
46 */
47 ScopedObjectT(T&& object, TReleaseFunction&& releaseFunction) noexcept;
48
49 /**
50 * Creates a new scoped object.
51 * This constructor allows to decide at runtime whether the release function will be used or not.
52 * @param object The object to be wrapped
53 * @param releaseFunction The release function
54 * @param useReleaseFunction True, to use the provided release function; False, to ignore the provided release function (so that the wrapped object will never be released)
55 */
56 ScopedObjectT(T&& object, TReleaseFunction&& releaseFunction, const bool useReleaseFunction) noexcept;
57
58 /**
59 * Creates a new scoped object.
60 * @param object The object to be wrapped
61 * @param releaseFunction The release function
62 */
63 ScopedObjectT(const T& object, TReleaseFunction&& releaseFunction) noexcept;
64
65 /**
66 * Creates a new scoped object.
67 * This constructor allows to decide at runtime whether the release function will be used or not.
68 * @param object The object to be wrapped
69 * @param releaseFunction The release function
70 * @param useReleaseFunction True, to use the provided release function; False, to ignore the provided release function (so that the wrapped object will never be released)
71 */
72 ScopedObjectT(const T& object, TReleaseFunction&& releaseFunction, const bool useReleaseFunction) noexcept;
73
74 /**
75 * Destructs this scoped object and releases the internal wrapped object.
76 */
78
79 /**
80 * Returns whether this scoped object holds a valid release function (which will be invoked once the object is released).
81 * @return True, if so
82 */
83 bool isValid() const;
84
85 /**
86 * Returns the wrapped object.
87 * @return The wrapped object
88 */
89 const T& object() const;
90
91 /**
92 * Arrow operator returning the wrapped object.
93 * Ensure that the object is valid before calling this operator.
94 * @return The wrapped object
95 * @see isValid().
96 */
97 const T& operator->() const;
98
99 /**
100 * De-reference operator returning the wrapped object.
101 * Ensure that the object is valid before calling this operator.
102 * @return The wrapped object
103 * @see isValid().
104 */
105 const T& operator*() const;
106
107 /**
108 * Explicitly releases the wrapped object.
109 */
110 void release();
111
112 /**
113 * Move operator.
114 * @param scopedObject The scoped object to be moved
115 * @return Reference to this object
116 */
118
119 protected:
120
121 /**
122 * Disabled copy constructor.
123 */
125
126 /**
127 * Disabled assign operator.
128 * @return Reference to this object
129 */
131
132 protected:
133
134 /// The wrapped reference.
135 T object_ = T();
136
137 /// The function used to release the wrapped object.
138 TReleaseFunction releaseFunction_ = TReleaseFunction();
139};
140
141/**
142 * This class wraps an unmanaged object (or reference) which needs to be released after usage.
143 * The release function needs to be defined at compile time.
144 * @tparam T The data type of the wrapped object
145 * @tparam TReleaseValue The optional explicit data type of the object to be released
146 * @tparam TReleaseReturn The data type of the return value of the release function
147 * @tparam tReleaseFunction The data type of the release function
148 * @tparam tExpectedReturnValue The expected return value of the release function
149 * @tparam tCheckReturnValue True, to check the return value when calling the release function; False, to ignore the return value
150 * @tparam tInvalidValue The value of an invalid object
151 * @see ScopedObjectT.
152 * @ingroup base
153 */
154template <typename T, typename TReleaseValue, typename TReleaseReturn, TReleaseReturn (*tReleaseFunction)(TReleaseValue), typename NotVoidTyper<TReleaseReturn>::Type tExpectedReturnValue = NotVoidTyper<TReleaseReturn>::defaultValue(), bool tCheckReturnValue = true, T tInvalidValue = T()>
156{
157 public:
158
159 /**
160 * Default constructor creating an object with invalid object.
161 */
163
164 /**
165 * Move constructor.
166 * @param scopedObject The scoped object to be moved
167 */
169
170 /**
171 * Creates a new scoped object.
172 * If 'object == tInvalidValue' the object will not be released once this scoped object is disposed.
173 * @param object The object to be wrapped
174 */
175 explicit ScopedObjectCompileTimeT(T&& object) noexcept;
176
177 /**
178 * Creates a new scoped object.
179 * @param object The object to be wrapped
180 * @param needsRelease True, if the given object needs to be released once the scoped object is disposed; False, if the given object does not need to be released
181 */
182 ScopedObjectCompileTimeT(T&& object, const bool needsRelease) noexcept;
183
184 /**
185 * Creates a new scoped object.
186 * If 'object == tInvalidValue' the object will not be released once this scoped object is disposed.
187 * @param object The object to be wrapped
188 */
189 explicit ScopedObjectCompileTimeT(const T& object);
190
191 /**
192 * Creates a new scoped object.
193 * @param object The object to be wrapped
194 * @param needsRelease True, if the given object needs to be released once the scoped object is disposed; False, if the given object does not need to be released
195 */
196 ScopedObjectCompileTimeT(const T& object, const bool needsRelease);
197
198 /**
199 * Destructs this scoped object and releases the internal wrapped object.
200 */
202
203 /**
204 * Returns whether this scoped object holds a valid object.
205 * @return True, if so
206 */
207 bool isValid() const;
208
209 /**
210 * Returns the wrapped object.
211 * @return The wrapped object
212 */
213 const T& object() const;
214
215 /**
216 * Returns the wrapped object.
217 * Ensure that the object is valid before calling this operator.
218 * @return The wrapped object
219 * @see isValid().
220 */
221 const T& operator->() const;
222
223 /**
224 * De-reference operator returning the wrapped object.
225 * Ensure that the object is valid before calling this operator.
226 * @return The wrapped object
227 * @see isValid().
228 */
229 const T& operator*() const;
230
231 /**
232 * Releases the current wrapped object and returns a new wrapped object.
233 * @param needsRelease True, if the new object needs to be released once the scoped object is disposed; False, if the new object does not need to be released
234 * @return The new wrapped object
235 */
236 T& resetObject(const bool needsRelease = true);
237
238 /**
239 * Explicitly releases the wrapped object.
240 */
241 void release();
242
243 /**
244 * Move operator.
245 * @param scopedObject The scoped object to be moved
246 * @return Reference to this object
247 */
249
250 protected:
251
252 /**
253 * Disabled copy constructor.
254 */
256
257 /**
258 * Disabled assign operator.
259 * @return Reference to this object
260 */
262
263 protected:
264
265 /// The wrapped reference.
266 T object_ = tInvalidValue;
267
268 /// True, if the wrapped object needs to be released.
269 bool needsRelease_ = false;
270};
271
272/**
273 * Template specialization for ScopedObjectCompileTimeT with void return value.
274 * @tparam T The data type of the wrapped object
275 * @tparam tReleaseFunction The data type of the release function
276 * @see ScopedObjectCompileTimeT.
277 * @ingroup base
278 */
279template <typename T, void (*tReleaseFunction)(T)>
281
282template <typename T, typename TReleaseValue, typename TReleaseFunction>
287
288template <typename T, typename TReleaseValue, typename TReleaseFunction>
289ScopedObjectT<T, TReleaseValue, TReleaseFunction>::ScopedObjectT(T&& object, TReleaseFunction&& releaseFunction) noexcept :
290 object_(std::move(object)),
291 releaseFunction_(std::move(releaseFunction))
292{
293 // nothing to do here
294}
295
296template <typename T, typename TReleaseValue, typename TReleaseFunction>
297ScopedObjectT<T, TReleaseValue, TReleaseFunction>::ScopedObjectT(T&& object, TReleaseFunction&& releaseFunction, const bool useReleaseFunction) noexcept :
298 object_(std::move(object))
299{
300 if (useReleaseFunction)
301 {
302 releaseFunction_ = std::move(releaseFunction);
303 }
304}
305
306template <typename T, typename TReleaseValue, typename TReleaseFunction>
307ScopedObjectT<T, TReleaseValue, TReleaseFunction>::ScopedObjectT(const T& object, TReleaseFunction&& releaseFunction) noexcept :
308 object_(object),
309 releaseFunction_(std::move(releaseFunction))
310{
311 // nothing to do here
312}
313
314template <typename T, typename TReleaseValue, typename TReleaseFunction>
315ScopedObjectT<T, TReleaseValue, TReleaseFunction>::ScopedObjectT(const T& object, TReleaseFunction&& releaseFunction, const bool useReleaseFunction) noexcept :
316 object_(object)
317{
318 if (useReleaseFunction)
319 {
320 releaseFunction_ = std::move(releaseFunction);
321 }
322}
323
324template <typename T, typename TReleaseValue, typename TReleaseFunction>
329
330template <typename T, typename TReleaseValue, typename TReleaseFunction>
332{
333 return bool(releaseFunction_);
334}
335
336template <typename T, typename TReleaseValue, typename TReleaseFunction>
338{
339 return object_;
340}
341
342template <typename T, typename TReleaseValue, typename TReleaseFunction>
344{
345 ocean_assert(isValid());
346
347 return object();
348}
349
350template <typename T, typename TReleaseValue, typename TReleaseFunction>
352{
353 ocean_assert(isValid());
354
355 return object();
356}
357
358template <typename T, typename TReleaseValue, typename TReleaseFunction>
360{
361 if (releaseFunction_)
362 {
363 releaseFunction_(TReleaseValue(object_));
364
365 object_ = T();
366 releaseFunction_ = TReleaseFunction();
367 }
368}
369
370template <typename T, typename TReleaseValue, typename TReleaseFunction>
372{
373 if (this != &scopedObject)
374 {
375 release();
376
377 object_ = std::move(scopedObject.object_);
378 scopedObject.object_ = T();
379
380 releaseFunction_ = std::move(scopedObject.releaseFunction_);
381 scopedObject.releaseFunction_ = TReleaseFunction();
382 }
383
384 return *this;
385}
386
387template <typename T, typename TReleaseValue, typename TReleaseReturn, TReleaseReturn (*tReleaseFunction)(TReleaseValue), typename NotVoidTyper<TReleaseReturn>::Type tExpectedReturnValue, bool tCheckReturnValue, T tInvalidValue>
392
393template <typename T, typename TReleaseValue, typename TReleaseReturn, TReleaseReturn (*tReleaseFunction)(TReleaseValue), typename NotVoidTyper<TReleaseReturn>::Type tExpectedReturnValue, bool tCheckReturnValue, T tInvalidValue>
395 object_(std::move(object))
396{
397 needsRelease_ = object_ != tInvalidValue;
398}
399
400template <typename T, typename TReleaseValue, typename TReleaseReturn, TReleaseReturn (*tReleaseFunction)(TReleaseValue), typename NotVoidTyper<TReleaseReturn>::Type tExpectedReturnValue, bool tCheckReturnValue, T tInvalidValue>
402 object_(std::move(object)),
403 needsRelease_(needsRelease)
404{
405 // nothing to do here
406}
407
408template <typename T, typename TReleaseValue, typename TReleaseReturn, TReleaseReturn (*tReleaseFunction)(TReleaseValue), typename NotVoidTyper<TReleaseReturn>::Type tExpectedReturnValue, bool tCheckReturnValue, T tInvalidValue>
414
415template <typename T, typename TReleaseValue, typename TReleaseReturn, TReleaseReturn (*tReleaseFunction)(TReleaseValue), typename NotVoidTyper<TReleaseReturn>::Type tExpectedReturnValue, bool tCheckReturnValue, T tInvalidValue>
417 object_(object),
418 needsRelease_(needsRelease)
419{
420 // nothing to do here
421}
422
423template <typename T, typename TReleaseValue, typename TReleaseReturn, TReleaseReturn (*tReleaseFunction)(TReleaseValue), typename NotVoidTyper<TReleaseReturn>::Type tExpectedReturnValue, bool tCheckReturnValue, T tInvalidValue>
428
429template <typename T, typename TReleaseValue, typename TReleaseReturn, TReleaseReturn (*tReleaseFunction)(TReleaseValue), typename NotVoidTyper<TReleaseReturn>::Type tExpectedReturnValue, bool tCheckReturnValue, T tInvalidValue>
434
435template <typename T, typename TReleaseValue, typename TReleaseReturn, TReleaseReturn (*tReleaseFunction)(TReleaseValue), typename NotVoidTyper<TReleaseReturn>::Type tExpectedReturnValue, bool tCheckReturnValue, T tInvalidValue>
440
441template <typename T, typename TReleaseValue, typename TReleaseReturn, TReleaseReturn (*tReleaseFunction)(TReleaseValue), typename NotVoidTyper<TReleaseReturn>::Type tExpectedReturnValue, bool tCheckReturnValue, T tInvalidValue>
448
449template <typename T, typename TReleaseValue, typename TReleaseReturn, TReleaseReturn (*tReleaseFunction)(TReleaseValue), typename NotVoidTyper<TReleaseReturn>::Type tExpectedReturnValue, bool tCheckReturnValue, T tInvalidValue>
456
457template <typename T, typename TReleaseValue, typename TReleaseReturn, TReleaseReturn (*tReleaseFunction)(TReleaseValue), typename NotVoidTyper<TReleaseReturn>::Type tExpectedReturnValue, bool tCheckReturnValue, T tInvalidValue>
459{
460 release();
461 object_ = tInvalidValue;
462
463 needsRelease_ = needsRelease;
464
465 return object_;
466}
467
468template <typename T, typename TReleaseValue, typename TReleaseReturn, TReleaseReturn (*tReleaseFunction)(TReleaseValue), typename NotVoidTyper<TReleaseReturn>::Type tExpectedReturnValue, bool tCheckReturnValue, T tInvalidValue>
470{
471 if (needsRelease_ && object_ != tInvalidValue)
472 {
473 if constexpr (std::is_same<TReleaseReturn, void>::value)
474 {
475 tReleaseFunction(TReleaseValue(object_));
476 }
477 else
478 {
479 if constexpr (tCheckReturnValue)
480 {
481 const TReleaseReturn returnValue = tReleaseFunction(TReleaseValue(object_));
482 ocean_assert_and_suppress_unused(returnValue == tExpectedReturnValue, returnValue);
483 }
484 else
485 {
486 const TReleaseReturn returnValue = tReleaseFunction(TReleaseValue(object_));
487 OCEAN_SUPPRESS_UNUSED_WARNING(returnValue);
488 }
489 }
490
491 object_ = tInvalidValue;
492 needsRelease_ = false;
493 }
494}
495
496template <typename T, typename TReleaseValue, typename TReleaseReturn, TReleaseReturn (*tReleaseFunction)(TReleaseValue), typename NotVoidTyper<TReleaseReturn>::Type tExpectedReturnValue, bool tCheckReturnValue, T tInvalidValue>
498{
499 if (this != &scopedObject)
500 {
501 release();
502
503 object_ = std::move(scopedObject.object_);
504 scopedObject.object_ = tInvalidValue;
505
506 needsRelease_ = scopedObject.needsRelease_;
507 scopedObject.needsRelease_ = false;
508 }
509
510 return *this;
511}
512
513}
514
515#endif // META_OCEAN_BASE_SCOPED_OBJECT_H
This class wraps an unmanaged object (or reference) which needs to be released after usage.
Definition ScopedObject.h:156
ScopedObjectCompileTimeT & operator=(const ScopedObjectCompileTimeT< T, TReleaseValue, TReleaseReturn, tReleaseFunction, tExpectedReturnValue, tCheckReturnValue, tInvalidValue > &)=delete
Disabled assign operator.
bool needsRelease_
True, if the wrapped object needs to be released.
Definition ScopedObject.h:269
ScopedObjectCompileTimeT(T &&object, const bool needsRelease) noexcept
Creates a new scoped object.
Definition ScopedObject.h:401
bool isValid() const
Returns whether this scoped object holds a valid object.
Definition ScopedObject.h:430
ScopedObjectCompileTimeT(T &&object) noexcept
Creates a new scoped object.
Definition ScopedObject.h:394
ScopedObjectCompileTimeT(const T &object, const bool needsRelease)
Creates a new scoped object.
Definition ScopedObject.h:416
ScopedObjectCompileTimeT()=default
Default constructor creating an object with invalid object.
const T & object() const
Returns the wrapped object.
Definition ScopedObject.h:436
ScopedObjectCompileTimeT(const ScopedObjectCompileTimeT< T, TReleaseValue, TReleaseReturn, tReleaseFunction, tExpectedReturnValue, tCheckReturnValue, tInvalidValue > &)=delete
Disabled copy constructor.
void release()
Explicitly releases the wrapped object.
Definition ScopedObject.h:469
ScopedObjectCompileTimeT< T, TReleaseValue, TReleaseReturn, tReleaseFunction, tExpectedReturnValue, tCheckReturnValue, tInvalidValue > & operator=(ScopedObjectCompileTimeT< T, TReleaseValue, TReleaseReturn, tReleaseFunction, tExpectedReturnValue, tCheckReturnValue, tInvalidValue > &&scopedObject) noexcept
Move operator.
Definition ScopedObject.h:497
T object_
The wrapped reference.
Definition ScopedObject.h:266
const T & operator*() const
De-reference operator returning the wrapped object.
Definition ScopedObject.h:450
ScopedObjectCompileTimeT(ScopedObjectCompileTimeT< T, TReleaseValue, TReleaseReturn, tReleaseFunction, tExpectedReturnValue, tCheckReturnValue, tInvalidValue > &&scopedObject) noexcept
Move constructor.
Definition ScopedObject.h:388
~ScopedObjectCompileTimeT()
Destructs this scoped object and releases the internal wrapped object.
Definition ScopedObject.h:424
ScopedObjectCompileTimeT(const T &object)
Creates a new scoped object.
Definition ScopedObject.h:409
T & resetObject(const bool needsRelease=true)
Releases the current wrapped object and returns a new wrapped object.
Definition ScopedObject.h:458
const T & operator->() const
Returns the wrapped object.
Definition ScopedObject.h:442
This class wraps an unmanaged object (or reference) which needs to be released after usage.
Definition ScopedObject.h:28
ScopedObjectT(T &&object, TReleaseFunction &&releaseFunction) noexcept
Creates a new scoped object.
Definition ScopedObject.h:289
ScopedObjectT< T, TReleaseValue, TReleaseFunction > & operator=(const ScopedObjectT< T, TReleaseValue, TReleaseFunction > &)=delete
Disabled assign operator.
ScopedObjectT(T &&object, TReleaseFunction &&releaseFunction, const bool useReleaseFunction) noexcept
Creates a new scoped object.
Definition ScopedObject.h:297
T object_
The wrapped reference.
Definition ScopedObject.h:135
const T & operator*() const
De-reference operator returning the wrapped object.
Definition ScopedObject.h:351
void release()
Explicitly releases the wrapped object.
Definition ScopedObject.h:359
~ScopedObjectT()
Destructs this scoped object and releases the internal wrapped object.
Definition ScopedObject.h:325
ScopedObjectT(const T &object, TReleaseFunction &&releaseFunction, const bool useReleaseFunction) noexcept
Creates a new scoped object.
Definition ScopedObject.h:315
TReleaseFunction releaseFunction_
The function used to release the wrapped object.
Definition ScopedObject.h:138
ScopedObjectT()=default
Default constructor creating an object with invalid object.
const T & operator->() const
Arrow operator returning the wrapped object.
Definition ScopedObject.h:343
ScopedObjectT< T, TReleaseValue, TReleaseFunction > & operator=(ScopedObjectT< T, TReleaseValue, TReleaseFunction > &&scopedObject) noexcept
Move operator.
Definition ScopedObject.h:371
ScopedObjectT(const ScopedObjectT< T, TReleaseValue, TReleaseFunction > &)=delete
Disabled copy constructor.
bool isValid() const
Returns whether this scoped object holds a valid release function (which will be invoked once the obj...
Definition ScopedObject.h:331
const T & object() const
Returns the wrapped object.
Definition ScopedObject.h:337
ScopedObjectT(ScopedObjectT< T, TReleaseValue, TReleaseFunction > &&scopedObject) noexcept
Move constructor.
Definition ScopedObject.h:283
ScopedObjectT(const T &object, TReleaseFunction &&releaseFunction) noexcept
Creates a new scoped object.
Definition ScopedObject.h:307
The namespace covering the entire Ocean framework.
Definition Accessor.h:15