cpp-common/bt2: `User*Component`: pass query method data to user `_query` methods
[babeltrace.git] / src / cpp-common / bt2 / shared-object.hpp
CommitLineData
01bf7a3a
PP
1/*
2 * Copyright (c) 2019-2020 Philippe Proulx <pproulx@efficios.com>
3 *
4 * SPDX-License-Identifier: MIT
5 */
6
7f5cdaf0
PP
7#ifndef BABELTRACE_CPP_COMMON_BT2_SHARED_OBJECT_HPP
8#define BABELTRACE_CPP_COMMON_BT2_SHARED_OBJECT_HPP
01bf7a3a 9
ca61ecbc
PP
10#include <utility>
11
01bf7a3a 12#include "common/assert.h"
ca61ecbc
PP
13
14#include "optional-borrowed-object.hpp"
01bf7a3a
PP
15
16namespace bt2 {
01bf7a3a
PP
17
18/*
19 * An instance of this class wraps an optional instance of `ObjT` and
20 * manages the reference counting of the underlying libbabeltrace2
21 * object.
22 *
64fbd3f7
PP
23 * When you move a shared object, it becomes empty, in that operator*()
24 * and operator->() will either fail to assert in debug mode or trigger
25 * a segmentation fault.
26 *
27 * The default constructor builds an empty shared object. You may also
28 * call the reset() method to make a shared object empty. Check whether
29 * or not a shared object is empty with the `bool` operator.
01bf7a3a
PP
30 *
31 * `LibObjT` is the direct libbabeltrace2 object type, for example
32 * `bt_stream_class` or `const bt_value`.
33 *
34 * RefFuncsT::get() must accept a `const LibObjT *` value and increment
35 * its reference count.
36 *
37 * RefFuncsT::put() must accept a `const LibObjT *` value and decrement
38 * its reference count.
39 */
40template <typename ObjT, typename LibObjT, typename RefFuncsT>
7f5cdaf0 41class SharedObject final
01bf7a3a
PP
42{
43 /*
44 * This makes it possible for a
7f5cdaf0 45 * `SharedObject<Something, bt_something, ...>` instance to get
01bf7a3a 46 * assigned an instance of
7f5cdaf0 47 * `SharedObject<SpecificSomething, bt_something, ...>` (copy/move
e60a53f1 48 * constructors and assignment operators), given that
01bf7a3a
PP
49 * `SpecificSomething` inherits `Something`.
50 */
96643d28 51 template <typename, typename, typename>
7f5cdaf0 52 friend class SharedObject;
01bf7a3a 53
64fbd3f7
PP
54public:
55 /*
56 * Builds an empty shared object.
57 */
58 explicit SharedObject() noexcept
59 {
60 }
61
c9c0b6e2
PP
62private:
63 /*
64 * Builds a shared object from `obj` without getting a reference.
65 */
7f5cdaf0 66 explicit SharedObject(const ObjT& obj) noexcept : _mObj {obj}
c9c0b6e2
PP
67 {
68 }
69
e60a53f1
PP
70 /*
71 * Common generic "copy" constructor.
72 *
73 * This constructor is meant to be delegated to by the copy
74 * constructor and the generic "copy" constructor.
75 *
76 * The second parameter, of type `int`, makes it possible to
77 * delegate by deduction as you can't explicit the template
78 * parameters when delegating to a constructor template.
79 */
80 template <typename OtherObjT, typename OtherLibObjT>
7f5cdaf0 81 SharedObject(const SharedObject<OtherObjT, OtherLibObjT, RefFuncsT>& other, int) noexcept :
e60a53f1
PP
82 _mObj {other._mObj}
83 {
84 this->_getRef();
85 }
86
87 /*
88 * Common generic "move" constructor.
89 *
90 * See the comment of the common generic "copy" constructor above.
91 */
92 template <typename OtherObjT, typename OtherLibObjT>
7f5cdaf0 93 SharedObject(SharedObject<OtherObjT, OtherLibObjT, RefFuncsT>&& other, int) noexcept :
e60a53f1
PP
94 _mObj {other._mObj}
95 {
96 /* Reset moved-from object */
97 other._reset();
98 }
99
01bf7a3a 100public:
c9c0b6e2
PP
101 /*
102 * Builds a shared object from `obj` without getting a reference.
103 */
7f5cdaf0 104 static SharedObject createWithoutRef(const ObjT& obj) noexcept
c9c0b6e2 105 {
7f5cdaf0 106 return SharedObject {obj};
c9c0b6e2 107 }
01bf7a3a
PP
108
109 /*
c9c0b6e2
PP
110 * Builds a shared object from `libObjPtr` without getting a
111 * reference.
01bf7a3a 112 */
7f5cdaf0 113 static SharedObject createWithoutRef(LibObjT * const libObjPtr) noexcept
01bf7a3a 114 {
7f5cdaf0 115 return SharedObject::createWithoutRef(ObjT {libObjPtr});
01bf7a3a
PP
116 }
117
118 /*
c9c0b6e2
PP
119 * Builds a shared object from `obj`, immediately getting a new
120 * reference.
01bf7a3a 121 */
7f5cdaf0 122 static SharedObject createWithRef(const ObjT& obj) noexcept
01bf7a3a 123 {
7f5cdaf0 124 SharedObject sharedObj {obj};
01bf7a3a
PP
125
126 sharedObj._getRef();
127 return sharedObj;
128 }
129
c9c0b6e2 130 /*
7f5cdaf0
PP
131 * Builds a shared object from `libObjPtr`, immediately getting a
132 * new reference.
c9c0b6e2 133 */
7f5cdaf0 134 static SharedObject createWithRef(LibObjT * const libObjPtr) noexcept
c9c0b6e2 135 {
7f5cdaf0 136 return SharedObject::createWithRef(ObjT {libObjPtr});
c9c0b6e2
PP
137 }
138
01bf7a3a 139 /*
e60a53f1
PP
140 * Copy constructor.
141 */
7f5cdaf0 142 SharedObject(const SharedObject& other) noexcept : SharedObject {other, 0}
e60a53f1
PP
143 {
144 }
145
146 /*
147 * Move constructor.
148 */
7f5cdaf0 149 SharedObject(SharedObject&& other) noexcept : SharedObject {std::move(other), 0}
e60a53f1
PP
150 {
151 }
152
153 /*
154 * Copy assignment operator.
155 */
7f5cdaf0 156 SharedObject& operator=(const SharedObject& other) noexcept
e60a53f1
PP
157 {
158 /* Use generic "copy" assignment operator */
159 return this->operator=<ObjT, LibObjT>(other);
160 }
161
162 /*
163 * Move assignment operator.
164 */
7f5cdaf0 165 SharedObject& operator=(SharedObject&& other) noexcept
e60a53f1
PP
166 {
167 /* Use generic "move" assignment operator */
168 return this->operator=<ObjT, LibObjT>(std::move(other));
169 }
170
171 /*
172 * Generic "copy" constructor.
01bf7a3a 173 *
7f5cdaf0 174 * See the `friend class SharedObject` comment above.
01bf7a3a
PP
175 */
176 template <typename OtherObjT, typename OtherLibObjT>
7f5cdaf0
PP
177 SharedObject(const SharedObject<OtherObjT, OtherLibObjT, RefFuncsT>& other) noexcept :
178 SharedObject {other, 0}
01bf7a3a 179 {
01bf7a3a
PP
180 }
181
182 /*
e60a53f1 183 * Generic "move" constructor.
01bf7a3a 184 *
7f5cdaf0 185 * See the `friend class SharedObject` comment above.
01bf7a3a
PP
186 */
187 template <typename OtherObjT, typename OtherLibObjT>
7f5cdaf0
PP
188 SharedObject(SharedObject<OtherObjT, OtherLibObjT, RefFuncsT>&& other) noexcept :
189 SharedObject {std::move(other), 0}
01bf7a3a 190 {
01bf7a3a
PP
191 }
192
193 /*
e60a53f1 194 * Generic "copy" assignment operator.
01bf7a3a 195 *
7f5cdaf0 196 * See the `friend class SharedObject` comment above.
01bf7a3a
PP
197 */
198 template <typename OtherObjT, typename OtherLibObjT>
7f5cdaf0 199 SharedObject& operator=(const SharedObject<OtherObjT, OtherLibObjT, RefFuncsT>& other) noexcept
01bf7a3a 200 {
b5f55e9f 201 /* Put current object's reference */
01bf7a3a
PP
202 this->_putRef();
203
b5f55e9f 204 /* Set new current object and get a reference */
01bf7a3a
PP
205 _mObj = other._mObj;
206 this->_getRef();
207
208 return *this;
209 }
210
211 /*
e60a53f1 212 * Generic "move" assignment operator.
01bf7a3a 213 *
7f5cdaf0 214 * See the `friend class SharedObject` comment above.
01bf7a3a
PP
215 */
216 template <typename OtherObjT, typename OtherLibObjT>
7f5cdaf0 217 SharedObject& operator=(SharedObject<OtherObjT, OtherLibObjT, RefFuncsT>&& other) noexcept
01bf7a3a 218 {
b5f55e9f 219 /* Put current object's reference */
01bf7a3a
PP
220 this->_putRef();
221
b5f55e9f 222 /* Set new current object */
01bf7a3a
PP
223 _mObj = other._mObj;
224
b5f55e9f 225 /* Reset moved-from object */
01bf7a3a
PP
226 other._reset();
227
228 return *this;
229 }
230
7f5cdaf0 231 ~SharedObject()
01bf7a3a
PP
232 {
233 this->_putRef();
234 }
235
ca61ecbc 236 ObjT operator*() const noexcept
01bf7a3a
PP
237 {
238 BT_ASSERT_DBG(_mObj);
239 return *_mObj;
240 }
241
ca61ecbc 242 BorrowedObjectProxy<ObjT> operator->() const noexcept
01bf7a3a
PP
243 {
244 BT_ASSERT_DBG(_mObj);
ca61ecbc 245 return _mObj.operator->();
01bf7a3a
PP
246 }
247
64fbd3f7
PP
248 operator bool() const noexcept
249 {
ca61ecbc 250 return _mObj.hasObject();
64fbd3f7
PP
251 }
252
253 /*
254 * Makes this shared object empty.
255 */
256 void reset() noexcept
257 {
258 if (_mObj) {
259 this->_putRef();
260 this->_reset();
261 }
262 }
263
d0b6533a
SM
264 /*
265 * Transfers the reference of the object which this shared object
7f5cdaf0
PP
266 * wrapper manages and returns it, making the caller become an
267 * active owner.
d0b6533a 268 *
64fbd3f7 269 * This method makes this object empty.
d0b6533a
SM
270 */
271 ObjT release() noexcept
272 {
273 BT_ASSERT_DBG(_mObj);
762ca3c0 274
d0b6533a 275 const auto obj = *_mObj;
762ca3c0 276
d0b6533a
SM
277 this->_reset();
278 return obj;
279 }
280
01bf7a3a
PP
281private:
282 /*
283 * Resets this shared object.
284 *
285 * To be used when moving it.
286 */
287 void _reset() noexcept
288 {
289 _mObj.reset();
290 }
291
292 /*
293 * Gets a new reference using the configured libbabeltrace2
294 * reference incrementation function.
295 */
296 void _getRef() const noexcept
297 {
ca61ecbc 298 RefFuncsT::get(_mObj.libObjPtr());
01bf7a3a
PP
299 }
300
301 /*
302 * Puts a reference using the configured libbabeltrace2 reference
303 * decrementation function.
304 */
305 void _putRef() const noexcept
306 {
ca61ecbc 307 RefFuncsT::put(_mObj.libObjPtr());
01bf7a3a
PP
308 }
309
ca61ecbc 310 OptionalBorrowedObject<ObjT> _mObj;
01bf7a3a
PP
311};
312
b5f55e9f 313} /* namespace bt2 */
01bf7a3a 314
7f5cdaf0 315#endif /* BABELTRACE_CPP_COMMON_BT2_SHARED_OBJECT_HPP */
This page took 0.050305 seconds and 4 git commands to generate.