Commit | Line | Data |
---|---|---|
01bf7a3a PP |
1 | /* |
2 | * Copyright 2019-2020 (c) Philippe Proulx <pproulx@efficios.com> | |
3 | * | |
4 | * SPDX-License-Identifier: MIT | |
5 | */ | |
6 | ||
02f1b803 SM |
7 | #ifndef BABELTRACE_CPP_COMMON_BT2_BORROWED_OBJ_HPP |
8 | #define BABELTRACE_CPP_COMMON_BT2_BORROWED_OBJ_HPP | |
01bf7a3a | 9 | |
feeaa247 | 10 | #include <functional> |
01bf7a3a PP |
11 | #include <type_traits> |
12 | ||
13 | #include "common/assert.h" | |
14 | ||
15 | namespace bt2 { | |
01bf7a3a | 16 | |
01bf7a3a PP |
17 | /* |
18 | * An instance of this class wraps a pointer to a libbabeltrace2 object | |
19 | * of type `LibObjT` without managing any reference counting. | |
20 | * | |
21 | * This is an abstract base class for any libbabeltrace2 object wrapper. | |
22 | * | |
23 | * `LibObjT` is the direct libbabeltrace2 object type, for example | |
24 | * `bt_stream_class` or `const bt_value`. | |
25 | * | |
341a67c4 | 26 | * Methods of a derived class can call libObjPtr() to access the |
01bf7a3a PP |
27 | * libbabeltrace2 object pointer. |
28 | */ | |
29 | template <typename LibObjT> | |
30 | class BorrowedObj | |
31 | { | |
32 | static_assert(!std::is_pointer<LibObjT>::value, "`LibObjT` must not be a pointer"); | |
33 | ||
34 | /* | |
35 | * This makes it possible for a `BorrowedObj<const bt_something>` | |
36 | * instance to get assigned an instance of | |
5b2d3ebb | 37 | * `BorrowedObj<bt_something>` ("copy" constructor and "assignment" |
01bf7a3a PP |
38 | * operator). |
39 | * | |
40 | * C++ forbids the other way around. | |
41 | */ | |
96643d28 | 42 | template <typename> |
01bf7a3a PP |
43 | friend class BorrowedObj; |
44 | ||
462e8628 PP |
45 | private: |
46 | /* | |
47 | * Provides `val` which indicates whether or not you can assign this | |
48 | * object from a borrowed object of type `OtherLibObjT`. | |
49 | */ | |
50 | template <typename OtherLibObjT> | |
51 | struct _AssignableFromConst final | |
52 | { | |
53 | /* | |
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): | |
57 | * | |
58 | * bt_value * const meow = bt_value_bool_create_init(BT_TRUE); | |
59 | * const bt_value * const mix = meow; | |
60 | * | |
61 | * If `LibObjT` is non-const, then you may not assign from its | |
62 | * const equivalent. In C (not correct): | |
63 | * | |
64 | * const bt_value * const meow = | |
65 | * bt_value_array_borrow_element_by_index_const(some_val, 17); | |
66 | * bt_value * const mix = meow; | |
67 | */ | |
68 | static constexpr bool val = | |
69 | std::is_const<LibObjT>::value || !std::is_const<OtherLibObjT>::value; | |
70 | }; | |
71 | ||
01bf7a3a | 72 | protected: |
b5f55e9f | 73 | /* libbabeltrace2 object pointer */ |
01bf7a3a PP |
74 | using _LibObjPtr = LibObjT *; |
75 | ||
b5f55e9f | 76 | /* This complete borrowed object */ |
01bf7a3a PP |
77 | using _ThisBorrowedObj = BorrowedObj<LibObjT>; |
78 | ||
79 | /* | |
80 | * Builds a borrowed object to wrap the libbabeltrace2 object | |
81 | * pointer `libObjPtr`. | |
82 | * | |
83 | * `libObjPtr` must not be `nullptr`. | |
84 | */ | |
85 | explicit BorrowedObj(const _LibObjPtr libObjPtr) noexcept : _mLibObjPtr {libObjPtr} | |
86 | { | |
87 | BT_ASSERT(libObjPtr); | |
88 | } | |
89 | ||
5b2d3ebb PP |
90 | /* Default copy operations */ |
91 | BorrowedObj(const BorrowedObj&) noexcept = default; | |
92 | BorrowedObj& operator=(const BorrowedObj&) noexcept = default; | |
93 | ||
01bf7a3a | 94 | /* |
5b2d3ebb | 95 | * Generic "copy" constructor. |
01bf7a3a PP |
96 | * |
97 | * This converting constructor accepts both an instance of | |
98 | * `_ThisBorrowedObj` and an instance (`other`) of | |
99 | * `BorrowedObj<ConstLibObjT>`, where `ConstLibObjT` is the `const` | |
100 | * version of `LibObjT`, if applicable. | |
101 | * | |
102 | * This makes it possible for a `BorrowedObj<const bt_something>` | |
103 | * instance to be built from an instance of | |
104 | * `BorrowedObj<bt_something>`. C++ forbids the other way around. | |
105 | */ | |
106 | template <typename OtherLibObjT> | |
107 | BorrowedObj(const BorrowedObj<OtherLibObjT>& other) noexcept : BorrowedObj {other._mLibObjPtr} | |
108 | { | |
462e8628 PP |
109 | static_assert(_AssignableFromConst<OtherLibObjT>::val, |
110 | "Don't assign a non-const wrapper from a const wrapper."); | |
01bf7a3a PP |
111 | } |
112 | ||
113 | /* | |
5b2d3ebb | 114 | * Generic "assignment" operator. |
01bf7a3a PP |
115 | * |
116 | * This operator accepts both an instance of | |
117 | * `_ThisBorrowedObj` and an instance (`other`) of | |
118 | * `BorrowedObj<ConstLibObjT>`, where `ConstLibObjT` is the `const` | |
119 | * version of `LibObjT`, if applicable. | |
120 | * | |
121 | * This makes it possible for a `BorrowedObj<const bt_something>` | |
122 | * instance to get assigned an instance of | |
462e8628 PP |
123 | * `BorrowedObj<bt_something>`. C++ forbids the other way around, |
124 | * therefore we use `_EnableIfAssignableT` to show a more relevant | |
125 | * context in the compiler error message. | |
01bf7a3a PP |
126 | */ |
127 | template <typename OtherLibObjT> | |
128 | _ThisBorrowedObj& operator=(const BorrowedObj<OtherLibObjT>& other) noexcept | |
129 | { | |
462e8628 PP |
130 | static_assert(_AssignableFromConst<OtherLibObjT>::val, |
131 | "Don't assign a non-const wrapper from a const wrapper."); | |
132 | ||
01bf7a3a PP |
133 | _mLibObjPtr = other._mLibObjPtr; |
134 | return *this; | |
135 | } | |
136 | ||
feeaa247 FD |
137 | public: |
138 | /* | |
139 | * Returns a hash of this object, solely based on its raw libbabeltrace2 | |
140 | * pointer. | |
141 | */ | |
142 | std::size_t hash() const noexcept | |
143 | { | |
144 | return std::hash<_LibObjPtr> {}(_mLibObjPtr); | |
145 | } | |
146 | ||
147 | /* | |
148 | * Returns whether or not this object is the exact same as `other`, | |
149 | * solely based on the raw libbabeltrace2 pointers. | |
150 | */ | |
151 | bool isSame(const _ThisBorrowedObj& other) const noexcept | |
152 | { | |
153 | return _mLibObjPtr == other._mLibObjPtr; | |
154 | } | |
155 | ||
b5f55e9f | 156 | /* Wrapped libbabeltrace2 object pointer */ |
341a67c4 | 157 | _LibObjPtr libObjPtr() const noexcept |
01bf7a3a PP |
158 | { |
159 | return _mLibObjPtr; | |
160 | } | |
161 | ||
162 | private: | |
163 | _LibObjPtr _mLibObjPtr; | |
164 | }; | |
165 | ||
b5f55e9f | 166 | } /* namespace bt2 */ |
01bf7a3a | 167 | |
02f1b803 | 168 | #endif /* BABELTRACE_CPP_COMMON_BT2_BORROWED_OBJ_HPP */ |