Ocean
Loading...
Searching...
No Matches
SmartObjectRef.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_SMART_OBJECT_REF_H
9#define META_OCEAN_BASE_SMART_OBJECT_REF_H
10
11#include "ocean/base/Base.h"
13
14namespace Ocean
15{
16
17/**
18 * This template class implements a smart object reference which is a specialization of an ObjectRef object.
19 * In the following the application of the SmartObjectRef class together with the ObjectRef class is shown:<br>
20 * @code
21 * // any kind of base class
22 * class Base
23 * {
24 * public:
25 *
26 * void baseFunction();
27 *
28 * virtual void virtualFunction();
29 * };
30 *
31 * // any kind of derived class
32 * class Derived : public Base
33 * {
34 * public:
35 *
36 * void derivedFunction();
37 *
38 * virtual void virtualFunction();
39 * };
40 *
41 * void main()
42 * {
43 * // create a new object reference of type 'Base' holding an instance of type 'Base'
44 * ObjectRef<Base> base(new Base());
45 *
46 * // check whether 'base' really holds a valid instance
47 * if (base)
48 * {
49 * // call both function of the instance
50 * base->baseFunction();
51 * base->virtualFunction();
52 * }
53 *
54 * // create another object reference of type 'Base' holding an instance of type 'Derived'
55 * ObjectRef<Base> derived(new Derived());
56 *
57 * // check whether 'derived' really holds a valid instance
58 * if (derived)
59 * {
60 * // call the base function
61 * derived->baseFunction();
62 *
63 * // call the virtual function of the class 'Derived'
64 * derived->virtualFunction();
65 *
66 * // try to call the specific 'derivedFunction' of class 'Derived'
67 * derived->derivedFunction(); // we will receive a compiler error as the object reference 'derived' has no knowledge about the class 'Derived'
68 * }
69 *
70 * // we create a specialization of 'derived' so that we can finally access the specific function of class 'Derived'
71 * SmartObjectRef<Derived, Base> smartDerived(derived);
72 *
73 * // check whether the provided object reference 'derived' could be specialized
74 * if (smartDerived)
75 * {
76 * // three valid function calls
77 * smartDerived->baseFunction();
78 * smartDerived->virtualFunction();
79 * smartDerived->derivedFunction();
80 * }
81 * }
82 * @endcode
83 * @tparam T Type of the encapsulated object of the smart object reference, must be derived from TBase
84 * @tparam TBase Base type of the object to be encapsulated
85 * @see ObjectRef.
86 * @ingroup base
87 */
88template <typename T, typename TBase>
89class SmartObjectRef : public ObjectRef<TBase>
90{
91 public:
92
93 /**
94 * Redefinition of the release callback function defined in ObjectRef.
95 */
97
98 public:
99
100 /**
101 * Creates a new SmartObjectRef with no internal object.
102 */
103 SmartObjectRef() = default;
104
105 /**
106 * Creates a new SmartObjectRef by a given object.
107 * This given object will be released by the smart object reference itself.
108 * @param object Internal object
109 */
110 explicit inline SmartObjectRef(T* object);
111
112 /**
113 * Creates a new SmartObjectRef by a given object.
114 * This given object will be released by the smart object reference itself.
115 * @param object Internal object
116 * @param releaseCallback Callback function for the release event
117 */
118 inline SmartObjectRef(T* object, const ReleaseCallback& releaseCallback);
119
120 /**
121 * Copy constructor.
122 * @param smartObjectRef SmartObjectRef object to copy
123 */
124 inline SmartObjectRef(const SmartObjectRef<T, TBase>& smartObjectRef);
125
126 /**
127 * Move constructor.
128 * @param smartObjectRef SmartObjectRef object to move
129 */
130 inline SmartObjectRef(SmartObjectRef<T, TBase>&& smartObjectRef);
131
132 /**
133 * Creates a new SmartObjectRef by a given ObjectRef.
134 * @param objectRef Given object reference
135 */
136 inline SmartObjectRef(const ObjectRef<TBase>& objectRef);
137
138 /**
139 * Copies a SmartObjectRef object.
140 * @param smartObjectRef SmartObjectRef object to copy
141 * @tparam T2 Type of the encapsulated object of the given object, must be derived from TBase
142 */
143 template <typename T2>
144 explicit inline SmartObjectRef(const SmartObjectRef<T2, TBase>& smartObjectRef);
145
146 /**
147 * Assign operator.
148 * @param smartObjectRef Smart object reference to assign
149 * @return Reference to this object
150 */
152
153 /**
154 * Moves a smart object reference object to this smart object reference.
155 * @param smartObjectRef Smart object reference to move
156 * @return Reference to this object
157 */
159
160 /**
161 * Assigns a ObjectRef to this smart object reference
162 * @param objectRef ObjectRef to assign
163 * @return Reference to this SmartObjectRef object
164 */
166
167 /**
168 * Releases the internal object, if any.
169 * Beware: After the release the object can not be accessed anymore!
170 */
171 inline void release();
172
173 /**
174 * Returns a pointer to the objects that is encapsulated by this wrapper.
175 * @return Pointer to the object or nullptr if no object is encapsulated
176 */
177 inline T* pointer() const;
178
179 /**
180 * Returns a point to the internal object if existing.
181 * Beware: Check whether this reference holds an internal object before calling this function!
182 * @return Pointer to the internal object
183 */
184 inline T* operator->() const;
185
186 /**
187 * Returns a reference to the internal object if existing.
188 * Beware: Check whether this reference holds an internal object before calling this function!
189 * @return Reference to the internal object
190 */
191 inline T& operator*() const;
192
193 protected:
194
195 /// Pointer to the internal object.
196 T* objectPointer_ = nullptr;
197};
198
199template <typename T, typename TBase>
201 ObjectRef<TBase>(dynamic_cast<TBase*>(object))
202{
204 {
205 objectPointer_ = object;
206 }
207}
208
209template <typename T, typename TBase>
210inline SmartObjectRef<T, TBase>::SmartObjectRef(T* object, const ReleaseCallback& releaseCallback) :
211 ObjectRef<TBase>(dynamic_cast<TBase*>(object, releaseCallback))
212{
213 if (ObjectRef<TBase>::objectHolder_ != nullptr)
214 {
215 objectPointer_ = object;
216 }
217}
218
219template <typename T, typename TBase>
221 ObjectRef<TBase>()
222{
223 if (smartObjectRef)
224 {
225 objectPointer_ = dynamic_cast<T*>(&*smartObjectRef);
226
227 if (objectPointer_ != nullptr)
228 {
229 ObjectRef<TBase>::objectHolder_ = smartObjectRef.objectHolder_->ref();
230 }
231 }
232}
233
234template <typename T, typename TBase>
236 ObjectRef<TBase>()
237{
238 if (smartObjectRef.objectPointer_ != nullptr)
239 {
240 objectPointer_ = smartObjectRef.objectPointer_;
242
243 smartObjectRef.objectPointer_ = nullptr;
244 smartObjectRef.objectHolder_ = nullptr;
245 }
246}
247
248template <typename T, typename TBase>
250 ObjectRef<TBase>()
251{
252 if (objectRef)
253 {
254 objectPointer_ = dynamic_cast<T*>(&*objectRef);
255
256 if (objectPointer_ != nullptr)
257 {
259 }
260 }
261}
262
263template <typename T, typename TBase>
264template <typename T2>
266 ObjectRef<TBase>()
267{
268 if (smartObjectRef)
269 {
270 objectPointer_ = dynamic_cast<T*>(&*smartObjectRef);
271
272 if (objectPointer_ != nullptr)
273 {
274 ObjectRef<TBase>::objectHolder_ = smartObjectRef.objectHolder_->ref();
275 }
276 }
277}
278
279template <typename T, typename TBase>
281{
282 if (this != &smartObjectRef)
283 {
284 if (ObjectRef<TBase>::objectHolder_ != nullptr)
285 {
286 ocean_assert(objectPointer_ != nullptr);
287
290 objectPointer_ = nullptr;
291 }
292
293 ocean_assert(objectPointer_ == nullptr);
294
295 if (smartObjectRef.objectPointer_ != nullptr)
296 {
297 objectPointer_ = smartObjectRef.objectPointer_;
298 ObjectRef<TBase>::objectHolder_ = smartObjectRef.objectHolder_->ref();
299 }
300 }
301
302 return *this;
303}
304
305template <typename T, typename TBase>
307{
308 if (this != &smartObjectRef)
309 {
310 if (ObjectRef<TBase>::objectHolder_ != nullptr)
311 {
312 ocean_assert(objectPointer_);
313
316 objectPointer_ = nullptr;
317 }
318
319 ocean_assert(objectPointer_ == nullptr);
320
321 objectPointer_ = smartObjectRef.objectPointer_;
323
324 smartObjectRef.objectPointer_ = nullptr;
325 smartObjectRef.objectHolder_ = nullptr;
326 }
327
328 return *this;
329}
330
331template <typename T, typename TBase>
333{
334 if (ObjectRef<TBase>::objectHolder_ != nullptr)
335 {
336 ocean_assert(objectPointer_ != nullptr);
337
340 objectPointer_ = nullptr;
341 }
342
343 if (objectRef)
344 {
345 objectPointer_ = dynamic_cast<T*>(&*objectRef);
346
347 if (objectPointer_ != nullptr)
348 {
350 }
351 }
352
353 return *this;
354}
355
356template <typename T, typename TBase>
358{
360 objectPointer_ = nullptr;
361}
362
363template <typename T, typename TBase>
365{
366 return objectPointer_;
367}
368
369template <typename T, typename TBase>
371{
372 ocean_assert(objectPointer_ != nullptr);
373
374 return objectPointer_;
375}
376
377template <typename T, typename TBase>
379{
380 ocean_assert(objectPointer_ != nullptr);
381
382 return *objectPointer_;
383}
384
385}
386
387#endif
ObjectHolder * ref()
Increases the reference counter.
Definition base/ObjectRef.h:275
This template class implements a object reference with an internal reference counter.
Definition base/ObjectRef.h:58
ObjectHolder * objectHolder_
Pointer to the object holder.
Definition base/ObjectRef.h:262
void release()
Releases the internal object, if any.
Definition base/ObjectRef.h:407
This template class implements a smart object reference which is a specialization of an ObjectRef obj...
Definition SmartObjectRef.h:90
SmartObjectRef(SmartObjectRef< T, TBase > &&smartObjectRef)
Move constructor.
Definition SmartObjectRef.h:235
SmartObjectRef< T, TBase > & operator=(const SmartObjectRef< T, TBase > &smartObjectRef)
Assign operator.
Definition SmartObjectRef.h:280
T * objectPointer_
Pointer to the internal object.
Definition SmartObjectRef.h:196
SmartObjectRef< T, TBase > & operator=(SmartObjectRef< T, TBase > &&smartObjectRef)
Moves a smart object reference object to this smart object reference.
Definition SmartObjectRef.h:306
T & operator*() const
Returns a reference to the internal object if existing.
Definition SmartObjectRef.h:378
ObjectRef< TBase >::ReleaseCallback ReleaseCallback
Redefinition of the release callback function defined in ObjectRef.
Definition SmartObjectRef.h:96
SmartObjectRef(T *object)
Creates a new SmartObjectRef by a given object.
Definition SmartObjectRef.h:200
T * operator->() const
Returns a point to the internal object if existing.
Definition SmartObjectRef.h:370
SmartObjectRef< T, TBase > & operator=(const ObjectRef< TBase > &objectRef)
Assigns a ObjectRef to this smart object reference.
Definition SmartObjectRef.h:332
SmartObjectRef(const SmartObjectRef< T, TBase > &smartObjectRef)
Copy constructor.
Definition SmartObjectRef.h:220
SmartObjectRef(T *object, const ReleaseCallback &releaseCallback)
Creates a new SmartObjectRef by a given object.
Definition SmartObjectRef.h:210
T * pointer() const
Returns a pointer to the objects that is encapsulated by this wrapper.
Definition SmartObjectRef.h:364
SmartObjectRef(const ObjectRef< TBase > &objectRef)
Creates a new SmartObjectRef by a given ObjectRef.
Definition SmartObjectRef.h:249
SmartObjectRef()=default
Creates a new SmartObjectRef with no internal object.
void release()
Releases the internal object, if any.
Definition SmartObjectRef.h:357
SmartObjectRef(const SmartObjectRef< T2, TBase > &smartObjectRef)
Copies a SmartObjectRef object.
Definition SmartObjectRef.h:265
The namespace covering the entire Ocean framework.
Definition Accessor.h:15