Ocean
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"
12 #include "ocean/base/ObjectRef.h"
13 
14 namespace 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  */
88 template <typename T, typename TBase>
89 class 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 
199 template <typename T, typename TBase>
201  ObjectRef<TBase>(dynamic_cast<TBase*>(object))
202 {
204  {
205  objectPointer_ = object;
206  }
207 }
208 
209 template <typename T, typename TBase>
210 inline 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 
219 template <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 
234 template <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 
248 template <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 
263 template <typename T, typename TBase>
264 template <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 
279 template <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 
305 template <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 
331 template <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 
356 template <typename T, typename TBase>
358 {
360  objectPointer_ = nullptr;
361 }
362 
363 template <typename T, typename TBase>
365 {
366  return objectPointer_;
367 }
368 
369 template <typename T, typename TBase>
371 {
372  ocean_assert(objectPointer_ != nullptr);
373 
374  return objectPointer_;
375 }
376 
377 template <typename T, typename TBase>
379 {
380  ocean_assert(objectPointer_ != nullptr);
381 
382  return *objectPointer_;
383 }
384 
385 }
386 
387 #endif
This class implements a container for callback functions.
Definition: Callback.h:3456
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