2 * Copyright (c) 2019-2020 Philippe Proulx <pproulx@efficios.com>
4 * SPDX-License-Identifier: MIT
7 #ifndef BABELTRACE_CPP_COMMON_BT2_SHARED_OBJECT_HPP
8 #define BABELTRACE_CPP_COMMON_BT2_SHARED_OBJECT_HPP
12 #include "optional-borrowed-object.hpp"
17 * An instance of this class wraps an optional instance of `ObjT` and
18 * manages the reference counting of the underlying libbabeltrace2
21 * When you move a shared object, it becomes empty, in that operator*()
22 * and operator->() will either fail to assert in debug mode or trigger
23 * a segmentation fault.
25 * The default constructor builds an empty shared object. You may also
26 * call the reset() method to make a shared object empty. Check whether
27 * or not a shared object is empty with the `bool` operator.
29 * `LibObjT` is the direct libbabeltrace2 object type, for example
30 * `bt_stream_class` or `const bt_value`.
32 * RefFuncsT::get() must accept a `const LibObjT *` value and increment
33 * its reference count.
35 * RefFuncsT::put() must accept a `const LibObjT *` value and decrement
36 * its reference count.
38 template <typename ObjT, typename LibObjT, typename RefFuncsT>
39 class SharedObject final
42 * This makes it possible for a
43 * `SharedObject<Something, bt_something, ...>` instance to get
44 * assigned an instance of
45 * `SharedObject<SpecificSomething, bt_something, ...>` (copy/move
46 * constructors and assignment operators), given that
47 * `SpecificSomething` inherits `Something`.
49 template <typename, typename, typename>
50 friend class SharedObject;
54 * Builds an empty shared object.
56 explicit SharedObject() noexcept
62 * Builds a shared object from `obj` without getting a reference.
64 explicit SharedObject(const ObjT& obj) noexcept : _mObj {obj}
69 * Common generic "copy" constructor.
71 * This constructor is meant to be delegated to by the copy
72 * constructor and the generic "copy" constructor.
74 * The second parameter, of type `int`, makes it possible to
75 * delegate by deduction as you can't explicit the template
76 * parameters when delegating to a constructor template.
78 template <typename OtherObjT, typename OtherLibObjT>
79 SharedObject(const SharedObject<OtherObjT, OtherLibObjT, RefFuncsT>& other, int) noexcept :
86 * Common generic "move" constructor.
88 * See the comment of the common generic "copy" constructor above.
90 template <typename OtherObjT, typename OtherLibObjT>
91 SharedObject(SharedObject<OtherObjT, OtherLibObjT, RefFuncsT>&& other, int) noexcept :
94 /* Reset moved-from object */
100 * Builds a shared object from `obj` without getting a reference.
102 static SharedObject createWithoutRef(const ObjT& obj) noexcept
104 return SharedObject {obj};
108 * Builds a shared object from `libObjPtr` without getting a
111 static SharedObject createWithoutRef(LibObjT * const libObjPtr) noexcept
113 return SharedObject::createWithoutRef(ObjT {libObjPtr});
117 * Builds a shared object from `obj`, immediately getting a new
120 static SharedObject createWithRef(const ObjT& obj) noexcept
122 SharedObject sharedObj {obj};
129 * Builds a shared object from `libObjPtr`, immediately getting a
132 static SharedObject createWithRef(LibObjT * const libObjPtr) noexcept
134 return SharedObject::createWithRef(ObjT {libObjPtr});
140 SharedObject(const SharedObject& other) noexcept : SharedObject {other, 0}
147 SharedObject(SharedObject&& other) noexcept : SharedObject {std::move(other), 0}
152 * Copy assignment operator.
154 SharedObject& operator=(const SharedObject& other) noexcept
156 /* Use generic "copy" assignment operator */
157 return this->operator=<ObjT, LibObjT>(other);
161 * Move assignment operator.
163 SharedObject& operator=(SharedObject&& other) noexcept
165 /* Use generic "move" assignment operator */
166 return this->operator=<ObjT, LibObjT>(std::move(other));
170 * Generic "copy" constructor.
172 * See the `friend class SharedObject` comment above.
174 template <typename OtherObjT, typename OtherLibObjT>
175 SharedObject(const SharedObject<OtherObjT, OtherLibObjT, RefFuncsT>& other) noexcept :
176 SharedObject {other, 0}
181 * Generic "move" constructor.
183 * See the `friend class SharedObject` comment above.
185 template <typename OtherObjT, typename OtherLibObjT>
186 SharedObject(SharedObject<OtherObjT, OtherLibObjT, RefFuncsT>&& other) noexcept :
187 SharedObject {std::move(other), 0}
192 * Generic "copy" assignment operator.
194 * See the `friend class SharedObject` comment above.
196 template <typename OtherObjT, typename OtherLibObjT>
197 SharedObject& operator=(const SharedObject<OtherObjT, OtherLibObjT, RefFuncsT>& other) noexcept
199 /* Put current object's reference */
202 /* Set new current object and get a reference */
210 * Generic "move" assignment operator.
212 * See the `friend class SharedObject` comment above.
214 template <typename OtherObjT, typename OtherLibObjT>
215 SharedObject& operator=(SharedObject<OtherObjT, OtherLibObjT, RefFuncsT>&& other) noexcept
217 /* Put current object's reference */
220 /* Set new current object */
223 /* Reset moved-from object */
234 ObjT operator*() const noexcept
239 BorrowedObjectProxy<ObjT> operator->() const noexcept
241 return _mObj.operator->();
244 explicit operator bool() const noexcept
246 return _mObj.hasObject();
250 * Makes this shared object empty.
252 void reset() noexcept
261 * Transfers the reference of the object which this shared object
262 * wrapper manages and returns it, making the caller become an
265 * This method makes this object empty.
267 ObjT release() noexcept
269 const auto obj = *_mObj;
277 * Resets this shared object.
279 * To be used when moving it.
281 void _reset() noexcept
287 * Gets a new reference using the configured libbabeltrace2
288 * reference incrementation function.
290 void _getRef() const noexcept
292 RefFuncsT::get(_mObj.libObjPtr());
296 * Puts a reference using the configured libbabeltrace2 reference
297 * decrementation function.
299 void _putRef() const noexcept
301 RefFuncsT::put(_mObj.libObjPtr());
304 OptionalBorrowedObject<ObjT> _mObj;
307 } /* namespace bt2 */
309 #endif /* BABELTRACE_CPP_COMMON_BT2_SHARED_OBJECT_HPP */