2 * Copyright 2019-2020 (c) Philippe Proulx <pproulx@efficios.com>
4 * SPDX-License-Identifier: MIT
7 #ifndef BABELTRACE_CPP_COMMON_BT2_BORROWED_OBJECT_HPP
8 #define BABELTRACE_CPP_COMMON_BT2_BORROWED_OBJECT_HPP
11 #include <type_traits>
13 #include "common/assert.h"
18 * An instance of this class wraps a pointer to a libbabeltrace2 object
19 * of type `LibObjT` without managing any reference counting.
21 * This is an abstract base class for any libbabeltrace2 object wrapper.
23 * `LibObjT` is the direct libbabeltrace2 object type, for example
24 * `bt_stream_class` or `const bt_value`.
26 * The user of a borrowed object, including methods of a derived class,
27 * can call libObjPtr() to access the libbabeltrace2 object pointer.
29 template <typename LibObjT>
32 static_assert(!std::is_pointer<LibObjT>::value, "`LibObjT` must not be a pointer");
35 * This makes it possible for a `BorrowedObject<const bt_something>`
36 * instance to get assigned an instance of
37 * `BorrowedObject<bt_something>` ("copy" constructor and
38 * "assignment" operator).
40 * C++ forbids the other way around.
43 friend class BorrowedObject;
47 * Provides `val` which indicates whether or not you can assign this
48 * object from a borrowed object of type `OtherLibObjT`.
50 template <typename OtherLibObjT>
51 struct _AssignableFromConst final
54 * If `LibObjT` is const (for example, `const bt_value`), then
55 * you may always assign from its non-const equivalent (for
56 * example, `bt_value`). In C (correct):
58 * bt_value * const meow = bt_value_bool_create_init(BT_TRUE);
59 * const bt_value * const mix = meow;
61 * If `LibObjT` is non-const, then you may not assign from its
62 * const equivalent. In C (not correct):
64 * const bt_value * const meow =
65 * bt_value_array_borrow_element_by_index_const(some_val, 17);
66 * bt_value * const mix = meow;
68 static constexpr bool val =
69 std::is_const<LibObjT>::value || !std::is_const<OtherLibObjT>::value;
73 /* libbabeltrace2 object pointer */
74 using _LibObjPtr = LibObjT *;
76 /* This complete borrowed object */
77 using _ThisBorrowedObject = BorrowedObject<LibObjT>;
80 * Builds a borrowed object to wrap the libbabeltrace2 object
81 * pointer `libObjPtr`.
83 * `libObjPtr` must not be `nullptr`.
85 explicit BorrowedObject(const _LibObjPtr libObjPtr) noexcept : _mLibObjPtr {libObjPtr}
87 BT_ASSERT_DBG(libObjPtr);
91 * Generic "copy" constructor.
93 * This converting constructor accepts both an instance of
94 * `_ThisBorrowedObject` and an instance (`other`) of
95 * `BorrowedObject<ConstLibObjT>`, where `ConstLibObjT` is the
96 * `const` version of `LibObjT`, if applicable.
98 * This makes it possible for a `BorrowedObject<const bt_something>`
99 * instance to be built from an instance of
100 * `BorrowedObject<bt_something>`. C++ forbids the other way around.
102 template <typename OtherLibObjT>
103 BorrowedObject(const BorrowedObject<OtherLibObjT>& other) noexcept :
104 BorrowedObject {other._mLibObjPtr}
106 static_assert(_AssignableFromConst<OtherLibObjT>::val,
107 "Don't assign a non-const wrapper from a const wrapper.");
111 * Generic "assignment" operator.
113 * This operator accepts both an instance of
114 * `_ThisBorrowedObject` and an instance (`other`) of
115 * `BorrowedObject<ConstLibObjT>`, where `ConstLibObjT` is the
116 * `const` version of `LibObjT`, if applicable.
118 * This makes it possible for a `BorrowedObject<const bt_something>`
119 * instance to get assigned an instance of
120 * `BorrowedObject<bt_something>`. C++ forbids the other way around,
121 * therefore we use `_EnableIfAssignableT` to show a more relevant
122 * context in the compiler error message.
124 template <typename OtherLibObjT>
125 _ThisBorrowedObject operator=(const BorrowedObject<OtherLibObjT>& other) noexcept
127 static_assert(_AssignableFromConst<OtherLibObjT>::val,
128 "Don't assign a non-const wrapper from a const wrapper.");
130 _mLibObjPtr = other._mLibObjPtr;
136 * Returns a hash of this object, solely based on its raw
137 * libbabeltrace2 pointer.
139 std::size_t hash() const noexcept
141 return std::hash<_LibObjPtr> {}(_mLibObjPtr);
145 * Returns whether or not this object is the exact same as `other`,
146 * solely based on the raw libbabeltrace2 pointers.
148 bool isSame(const _ThisBorrowedObject& other) const noexcept
150 return _mLibObjPtr == other._mLibObjPtr;
153 /* Wrapped libbabeltrace2 object pointer */
154 _LibObjPtr libObjPtr() const noexcept
160 _LibObjPtr _mLibObjPtr;
163 } /* namespace bt2 */
165 #endif /* BABELTRACE_CPP_COMMON_BT2_BORROWED_OBJECT_HPP */