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#ifdef OCEAN_ENABLE_CAST_OPERATOR_FOR_SCOPED_OBJECT
120
121 /**
122 * Returns the wrapped object.
123 * @return The wrapped object
124 */
125 operator const T&() const;
126
127#endif // OCEAN_ENABLE_CAST_OPERATOR_FOR_SCOPED_OBJECT
128
129 protected:
130
131 /**
132 * Disabled copy constructor.
133 */
135
136 /**
137 * Disabled assign operator.
138 * @return Reference to this object
139 */
141
142 protected:
143
144 /// The wrapped reference.
145 T object_ = T();
146
147 /// The function used to release the wrapped object.
148 TReleaseFunction releaseFunction_ = TReleaseFunction();
149};
150
151/**
152 * This class wraps an unmanaged object (or reference) which needs to be released after usage.
153 * The release function needs to be defined at compile time.
154 * @tparam T The data type of the wrapped object
155 * @tparam TReleaseValue The optional explicit data type of the object to be released
156 * @tparam TReleaseReturn The data type of the return value of the release function
157 * @tparam tReleaseFunction The data type of the release function
158 * @tparam tExpectedReturnValue The expected return value of the release function
159 * @tparam tCheckReturnValue True, to check the return value when calling the release function; False, to ignore the return value
160 * @tparam tInvalidValue The value of an invalid object
161 * @see ScopedObjectT.
162 * @ingroup base
163 */
164template <typename T, typename TReleaseValue, typename TReleaseReturn, TReleaseReturn (*tReleaseFunction)(TReleaseValue), typename NotVoidTyper<TReleaseReturn>::Type tExpectedReturnValue = NotVoidTyper<TReleaseReturn>::defaultValue(), bool tCheckReturnValue = true, T tInvalidValue = T()>
166{
167 public:
168
169 /**
170 * Default constructor creating an object with invalid object.
171 */
173
174 /**
175 * Move constructor.
176 * @param scopedObject The scoped object to be moved
177 */
179
180 /**
181 * Creates a new scoped object.
182 * If 'object == tInvalidValue' the object will not be released once this scoped object is disposed.
183 * @param object The object to be wrapped
184 */
185 explicit ScopedObjectCompileTimeT(T&& object) noexcept;
186
187 /**
188 * Creates a new scoped object.
189 * @param object The object to be wrapped
190 * @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
191 */
192 ScopedObjectCompileTimeT(T&& object, const bool needsRelease) noexcept;
193
194 /**
195 * Creates a new scoped object.
196 * If 'object == tInvalidValue' the object will not be released once this scoped object is disposed.
197 * @param object The object to be wrapped
198 */
199 explicit ScopedObjectCompileTimeT(const T& object);
200
201 /**
202 * Creates a new scoped object.
203 * @param object The object to be wrapped
204 * @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
205 */
206 ScopedObjectCompileTimeT(const T& object, const bool needsRelease);
207
208 /**
209 * Destructs this scoped object and releases the internal wrapped object.
210 */
212
213 /**
214 * Returns whether this scoped object holds a valid object.
215 * @return True, if so
216 */
217 bool isValid() const;
218
219 /**
220 * Returns the wrapped object.
221 * @return The wrapped object
222 */
223 const T& object() const;
224
225 /**
226 * Returns the wrapped object.
227 * Ensure that the object is valid before calling this operator.
228 * @return The wrapped object
229 * @see isValid().
230 */
231 const T& operator->() const;
232
233 /**
234 * De-reference operator returning the wrapped object.
235 * Ensure that the object is valid before calling this operator.
236 * @return The wrapped object
237 * @see isValid().
238 */
239 const T& operator*() const;
240
241 /**
242 * Releases the current wrapped object and returns a new wrapped object.
243 * @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
244 * @return The new wrapped object
245 */
246 T& resetObject(const bool needsRelease = true);
247
248 /**
249 * Explicitly releases the wrapped object.
250 */
251 void release();
252
253 /**
254 * Move operator.
255 * @param scopedObject The scoped object to be moved
256 * @return Reference to this object
257 */
259
260#ifdef OCEAN_ENABLE_CAST_OPERATOR_FOR_SCOPED_OBJECT
261
262 /**
263 * Returns the wrapped object.
264 * @return The wrapped object
265 */
266 operator const T&() const;
267
268#endif // OCEAN_ENABLE_CAST_OPERATOR_FOR_SCOPED_OBJECT
269
270 protected:
271
272 /**
273 * Disabled copy constructor.
274 */
276
277 /**
278 * Disabled assign operator.
279 * @return Reference to this object
280 */
282
283 protected:
284
285 /// The wrapped reference.
286 T object_ = tInvalidValue;
287
288 /// True, if the wrapped object needs to be released.
289 bool needsRelease_ = false;
290};
291
292/**
293 * Template specialization for ScopedObjectCompileTimeT with void return value.
294 * @tparam T The data type of the wrapped object
295 * @tparam tReleaseFunction The data type of the release function
296 * @see ScopedObjectCompileTimeT.
297 * @ingroup base
298 */
299template <typename T, void (*tReleaseFunction)(T)>
301
302template <typename T, typename TReleaseValue, typename TReleaseFunction>
307
308template <typename T, typename TReleaseValue, typename TReleaseFunction>
309ScopedObjectT<T, TReleaseValue, TReleaseFunction>::ScopedObjectT(T&& object, TReleaseFunction&& releaseFunction) noexcept :
310 object_(std::move(object)),
311 releaseFunction_(std::move(releaseFunction))
312{
313 // nothing to do here
314}
315
316template <typename T, typename TReleaseValue, typename TReleaseFunction>
317ScopedObjectT<T, TReleaseValue, TReleaseFunction>::ScopedObjectT(T&& object, TReleaseFunction&& releaseFunction, const bool useReleaseFunction) noexcept :
318 object_(std::move(object))
319{
320 if (useReleaseFunction)
321 {
322 releaseFunction_ = std::move(releaseFunction);
323 }
324}
325
326template <typename T, typename TReleaseValue, typename TReleaseFunction>
327ScopedObjectT<T, TReleaseValue, TReleaseFunction>::ScopedObjectT(const T& object, TReleaseFunction&& releaseFunction) noexcept :
328 object_(object),
329 releaseFunction_(std::move(releaseFunction))
330{
331 // nothing to do here
332}
333
334template <typename T, typename TReleaseValue, typename TReleaseFunction>
335ScopedObjectT<T, TReleaseValue, TReleaseFunction>::ScopedObjectT(const T& object, TReleaseFunction&& releaseFunction, const bool useReleaseFunction) noexcept :
336 object_(object)
337{
338 if (useReleaseFunction)
339 {
340 releaseFunction_ = std::move(releaseFunction);
341 }
342}
343
344template <typename T, typename TReleaseValue, typename TReleaseFunction>
349
350template <typename T, typename TReleaseValue, typename TReleaseFunction>
352{
353 return bool(releaseFunction_);
354}
355
356template <typename T, typename TReleaseValue, typename TReleaseFunction>
358{
359 return object_;
360}
361
362template <typename T, typename TReleaseValue, typename TReleaseFunction>
364{
365 ocean_assert(isValid());
366
367 return object();
368}
369
370template <typename T, typename TReleaseValue, typename TReleaseFunction>
372{
373 ocean_assert(isValid());
374
375 return object();
376}
377
378template <typename T, typename TReleaseValue, typename TReleaseFunction>
380{
381 if (releaseFunction_)
382 {
383 releaseFunction_(TReleaseValue(object_));
384
385 object_ = T();
386 releaseFunction_ = TReleaseFunction();
387 }
388}
389
390template <typename T, typename TReleaseValue, typename TReleaseFunction>
392{
393 if (this != &scopedObject)
394 {
395 release();
396
397 object_ = std::move(scopedObject.object_);
398 scopedObject.object_ = T();
399
400 releaseFunction_ = std::move(scopedObject.releaseFunction_);
401 scopedObject.releaseFunction_ = TReleaseFunction();
402 }
403
404 return *this;
405}
406
407#ifdef OCEAN_ENABLE_CAST_OPERATOR_FOR_SCOPED_OBJECT
408
409template <typename T, typename TReleaseValue, typename TReleaseFunction>
411{
412 return object_;
413}
414
415#endif
416
417template <typename T, typename TReleaseValue, typename TReleaseReturn, TReleaseReturn (*tReleaseFunction)(TReleaseValue), typename NotVoidTyper<TReleaseReturn>::Type tExpectedReturnValue, bool tCheckReturnValue, T tInvalidValue>
422
423template <typename T, typename TReleaseValue, typename TReleaseReturn, TReleaseReturn (*tReleaseFunction)(TReleaseValue), typename NotVoidTyper<TReleaseReturn>::Type tExpectedReturnValue, bool tCheckReturnValue, T tInvalidValue>
425 object_(std::move(object))
426{
427 needsRelease_ = object_ != tInvalidValue;
428}
429
430template <typename T, typename TReleaseValue, typename TReleaseReturn, TReleaseReturn (*tReleaseFunction)(TReleaseValue), typename NotVoidTyper<TReleaseReturn>::Type tExpectedReturnValue, bool tCheckReturnValue, T tInvalidValue>
432 object_(std::move(object)),
433 needsRelease_(needsRelease)
434{
435 // nothing to do here
436}
437
438template <typename T, typename TReleaseValue, typename TReleaseReturn, TReleaseReturn (*tReleaseFunction)(TReleaseValue), typename NotVoidTyper<TReleaseReturn>::Type tExpectedReturnValue, bool tCheckReturnValue, T tInvalidValue>
444
445template <typename T, typename TReleaseValue, typename TReleaseReturn, TReleaseReturn (*tReleaseFunction)(TReleaseValue), typename NotVoidTyper<TReleaseReturn>::Type tExpectedReturnValue, bool tCheckReturnValue, T tInvalidValue>
447 object_(object),
448 needsRelease_(needsRelease)
449{
450 // nothing to do here
451}
452
453template <typename T, typename TReleaseValue, typename TReleaseReturn, TReleaseReturn (*tReleaseFunction)(TReleaseValue), typename NotVoidTyper<TReleaseReturn>::Type tExpectedReturnValue, bool tCheckReturnValue, T tInvalidValue>
458
459template <typename T, typename TReleaseValue, typename TReleaseReturn, TReleaseReturn (*tReleaseFunction)(TReleaseValue), typename NotVoidTyper<TReleaseReturn>::Type tExpectedReturnValue, bool tCheckReturnValue, T tInvalidValue>
464
465template <typename T, typename TReleaseValue, typename TReleaseReturn, TReleaseReturn (*tReleaseFunction)(TReleaseValue), typename NotVoidTyper<TReleaseReturn>::Type tExpectedReturnValue, bool tCheckReturnValue, T tInvalidValue>
470
471template <typename T, typename TReleaseValue, typename TReleaseReturn, TReleaseReturn (*tReleaseFunction)(TReleaseValue), typename NotVoidTyper<TReleaseReturn>::Type tExpectedReturnValue, bool tCheckReturnValue, T tInvalidValue>
478
479template <typename T, typename TReleaseValue, typename TReleaseReturn, TReleaseReturn (*tReleaseFunction)(TReleaseValue), typename NotVoidTyper<TReleaseReturn>::Type tExpectedReturnValue, bool tCheckReturnValue, T tInvalidValue>
486
487template <typename T, typename TReleaseValue, typename TReleaseReturn, TReleaseReturn (*tReleaseFunction)(TReleaseValue), typename NotVoidTyper<TReleaseReturn>::Type tExpectedReturnValue, bool tCheckReturnValue, T tInvalidValue>
489{
490 release();
491 object_ = tInvalidValue;
492
493 needsRelease_ = needsRelease;
494
495 return object_;
496}
497
498template <typename T, typename TReleaseValue, typename TReleaseReturn, TReleaseReturn (*tReleaseFunction)(TReleaseValue), typename NotVoidTyper<TReleaseReturn>::Type tExpectedReturnValue, bool tCheckReturnValue, T tInvalidValue>
500{
501 if (needsRelease_)
502 {
503 if constexpr (std::is_same<TReleaseReturn, void>::value)
504 {
505 tReleaseFunction(TReleaseValue(object_));
506 }
507 else
508 {
509 if constexpr (tCheckReturnValue)
510 {
511 const TReleaseReturn returnValue = tReleaseFunction(TReleaseValue(object_));
512 ocean_assert_and_suppress_unused(returnValue == tExpectedReturnValue, returnValue);
513 }
514 else
515 {
516 const TReleaseReturn returnValue = tReleaseFunction(TReleaseValue(object_));
517 OCEAN_SUPPRESS_UNUSED_WARNING(returnValue);
518 }
519 }
520
521 object_ = tInvalidValue;
522 needsRelease_ = false;
523 }
524}
525
526template <typename T, typename TReleaseValue, typename TReleaseReturn, TReleaseReturn (*tReleaseFunction)(TReleaseValue), typename NotVoidTyper<TReleaseReturn>::Type tExpectedReturnValue, bool tCheckReturnValue, T tInvalidValue>
528{
529 if (this != &scopedObject)
530 {
531 release();
532
533 object_ = std::move(scopedObject.object_);
534 scopedObject.object_ = tInvalidValue;
535
536 needsRelease_ = scopedObject.needsRelease_;
537 scopedObject.needsRelease_ = false;
538 }
539
540 return *this;
541}
542
543#ifdef OCEAN_ENABLE_CAST_OPERATOR_FOR_SCOPED_OBJECT
544
545template <typename T, typename TReleaseValue, typename TReleaseReturn, TReleaseReturn (*tReleaseFunction)(TReleaseValue), typename NotVoidTyper<TReleaseReturn>::Type tExpectedReturnValue, bool tCheckReturnValue, T tInvalidValue>
550
551#endif
552
553}
554
555#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:166
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:289
ScopedObjectCompileTimeT(T &&object, const bool needsRelease) noexcept
Creates a new scoped object.
Definition ScopedObject.h:431
bool isValid() const
Returns whether this scoped object holds a valid object.
Definition ScopedObject.h:460
ScopedObjectCompileTimeT(T &&object) noexcept
Creates a new scoped object.
Definition ScopedObject.h:424
ScopedObjectCompileTimeT(const T &object, const bool needsRelease)
Creates a new scoped object.
Definition ScopedObject.h:446
ScopedObjectCompileTimeT()=default
Default constructor creating an object with invalid object.
const T & object() const
Returns the wrapped object.
Definition ScopedObject.h:466
ScopedObjectCompileTimeT(const ScopedObjectCompileTimeT< T, TReleaseValue, TReleaseReturn, tReleaseFunction, tExpectedReturnValue, tCheckReturnValue, tInvalidValue > &)=delete
Disabled copy constructor.
void release()
Explicitly releases the wrapped object.
Definition ScopedObject.h:499
ScopedObjectCompileTimeT< T, TReleaseValue, TReleaseReturn, tReleaseFunction, tExpectedReturnValue, tCheckReturnValue, tInvalidValue > & operator=(ScopedObjectCompileTimeT< T, TReleaseValue, TReleaseReturn, tReleaseFunction, tExpectedReturnValue, tCheckReturnValue, tInvalidValue > &&scopedObject) noexcept
Move operator.
Definition ScopedObject.h:527
T object_
The wrapped reference.
Definition ScopedObject.h:286
const T & operator*() const
De-reference operator returning the wrapped object.
Definition ScopedObject.h:480
ScopedObjectCompileTimeT(ScopedObjectCompileTimeT< T, TReleaseValue, TReleaseReturn, tReleaseFunction, tExpectedReturnValue, tCheckReturnValue, tInvalidValue > &&scopedObject) noexcept
Move constructor.
Definition ScopedObject.h:418
~ScopedObjectCompileTimeT()
Destructs this scoped object and releases the internal wrapped object.
Definition ScopedObject.h:454
ScopedObjectCompileTimeT(const T &object)
Creates a new scoped object.
Definition ScopedObject.h:439
T & resetObject(const bool needsRelease=true)
Releases the current wrapped object and returns a new wrapped object.
Definition ScopedObject.h:488
const T & operator->() const
Returns the wrapped object.
Definition ScopedObject.h:472
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:309
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:317
T object_
The wrapped reference.
Definition ScopedObject.h:145
const T & operator*() const
De-reference operator returning the wrapped object.
Definition ScopedObject.h:371
void release()
Explicitly releases the wrapped object.
Definition ScopedObject.h:379
~ScopedObjectT()
Destructs this scoped object and releases the internal wrapped object.
Definition ScopedObject.h:345
ScopedObjectT(const T &object, TReleaseFunction &&releaseFunction, const bool useReleaseFunction) noexcept
Creates a new scoped object.
Definition ScopedObject.h:335
TReleaseFunction releaseFunction_
The function used to release the wrapped object.
Definition ScopedObject.h:148
ScopedObjectT()=default
Default constructor creating an object with invalid object.
const T & operator->() const
Arrow operator returning the wrapped object.
Definition ScopedObject.h:363
ScopedObjectT< T, TReleaseValue, TReleaseFunction > & operator=(ScopedObjectT< T, TReleaseValue, TReleaseFunction > &&scopedObject) noexcept
Move operator.
Definition ScopedObject.h:391
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:351
const T & object() const
Returns the wrapped object.
Definition ScopedObject.h:357
ScopedObjectT(ScopedObjectT< T, TReleaseValue, TReleaseFunction > &&scopedObject) noexcept
Move constructor.
Definition ScopedObject.h:303
ScopedObjectT(const T &object, TReleaseFunction &&releaseFunction) noexcept
Creates a new scoped object.
Definition ScopedObject.h:327
The namespace covering the entire Ocean framework.
Definition Accessor.h:15