cpp-common/bt2: add C++ bindings around `bt_error *`
[babeltrace.git] / src / cpp-common / bt2 / error.hpp
CommitLineData
a65c7bf4
SM
1/*
2 * Copyright (c) 2024 EfficiOS Inc.
3 *
4 * SPDX-License-Identifier: MIT
5 */
6
7#ifndef BABELTRACE_CPP_COMMON_BT2_ERROR_HPP
8#define BABELTRACE_CPP_COMMON_BT2_ERROR_HPP
9
10#include <cstdint>
11#include <memory>
12
13#include <babeltrace2/babeltrace.h>
14
15#include "common/assert.h"
16#include "cpp-common/bt2c/c-string-view.hpp"
17#include "cpp-common/vendor/fmt/format.h" /* IWYU pragma: keep */
18
19#include "borrowed-object.hpp"
20#include "component-class.hpp"
21
22namespace bt2 {
23
24class ConstComponentClassErrorCause;
25class ConstComponentErrorCause;
26class ConstMessageIteratorErrorCause;
27
28class ConstErrorCause : public BorrowedObject<const bt_error_cause>
29{
30public:
31 enum class ActorType
32 {
33 UNKNOWN = BT_ERROR_CAUSE_ACTOR_TYPE_UNKNOWN,
34 COMPONENT = BT_ERROR_CAUSE_ACTOR_TYPE_COMPONENT,
35 COMPONENT_CLASS = BT_ERROR_CAUSE_ACTOR_TYPE_COMPONENT_CLASS,
36 MESSAGE_ITERATOR = BT_ERROR_CAUSE_ACTOR_TYPE_MESSAGE_ITERATOR,
37 };
38
39 explicit ConstErrorCause(const LibObjPtr libObjPtr) noexcept : _ThisBorrowedObject {libObjPtr}
40 {
41 }
42
43 ActorType actorType() const noexcept
44 {
45 return static_cast<ActorType>(bt_error_cause_get_actor_type(this->libObjPtr()));
46 }
47
48 bool actorTypeIsComponentClass() const noexcept
49 {
50 return this->actorType() == ActorType::COMPONENT_CLASS;
51 }
52
53 bool actorTypeIsComponent() const noexcept
54 {
55 return this->actorType() == ActorType::COMPONENT;
56 }
57
58 bool actorTypeIsMessageIterator() const noexcept
59 {
60 return this->actorType() == ActorType::MESSAGE_ITERATOR;
61 }
62
63 ConstComponentClassErrorCause asComponentClass() const noexcept;
64 ConstComponentErrorCause asComponent() const noexcept;
65 ConstMessageIteratorErrorCause asMessageIterator() const noexcept;
66
67 bt2c::CStringView message() const noexcept
68 {
69 return bt_error_cause_get_message(this->libObjPtr());
70 }
71
72 bt2c::CStringView moduleName() const noexcept
73 {
74 return bt_error_cause_get_module_name(this->libObjPtr());
75 }
76
77 bt2c::CStringView fileName() const noexcept
78 {
79 return bt_error_cause_get_file_name(this->libObjPtr());
80 }
81
82 std::uint64_t lineNumber() const noexcept
83 {
84 return bt_error_cause_get_line_number(this->libObjPtr());
85 }
86};
87
88class ConstComponentClassErrorCause final : public ConstErrorCause
89{
90public:
91 explicit ConstComponentClassErrorCause(const LibObjPtr libObjPtr) : ConstErrorCause {libObjPtr}
92 {
93 BT_ASSERT(this->actorTypeIsComponentClass());
94 }
95
96 bt2::ComponentClass::Type componentClassType() const noexcept
97 {
98 return static_cast<bt2::ComponentClass::Type>(
99 bt_error_cause_component_class_actor_get_component_class_type(this->libObjPtr()));
100 }
101
102 bt2c::CStringView componentClassName() const noexcept
103 {
104 return bt_error_cause_component_class_actor_get_component_class_name(this->libObjPtr());
105 }
106
107 bt2c::CStringView pluginName() const noexcept
108 {
109 return bt_error_cause_component_class_actor_get_plugin_name(this->libObjPtr());
110 }
111};
112
113inline ConstComponentClassErrorCause ConstErrorCause::asComponentClass() const noexcept
114{
115 return ConstComponentClassErrorCause {this->libObjPtr()};
116}
117
118class ConstComponentErrorCause final : public ConstErrorCause
119{
120public:
121 explicit ConstComponentErrorCause(const LibObjPtr libObjPtr) : ConstErrorCause {libObjPtr}
122 {
123 BT_ASSERT(this->actorTypeIsComponent());
124 }
125
126 bt2c::CStringView componentName() const noexcept
127 {
128 return bt_error_cause_component_actor_get_component_name(this->libObjPtr());
129 }
130
131 bt2::ComponentClass::Type componentClassType() const noexcept
132 {
133 return static_cast<bt2::ComponentClass::Type>(
134 bt_error_cause_component_actor_get_component_class_type(this->libObjPtr()));
135 }
136
137 bt2c::CStringView componentClassName() const noexcept
138 {
139 return bt_error_cause_component_actor_get_component_class_name(this->libObjPtr());
140 }
141
142 bt2c::CStringView pluginName() const noexcept
143 {
144 return bt_error_cause_component_actor_get_plugin_name(this->libObjPtr());
145 }
146};
147
148inline ConstComponentErrorCause ConstErrorCause::asComponent() const noexcept
149{
150 return ConstComponentErrorCause {this->libObjPtr()};
151}
152
153class ConstMessageIteratorErrorCause final : public ConstErrorCause
154{
155public:
156 explicit ConstMessageIteratorErrorCause(const LibObjPtr libObjPtr) : ConstErrorCause {libObjPtr}
157 {
158 BT_ASSERT(this->actorTypeIsMessageIterator());
159 }
160
161 bt2c::CStringView componentOutputPortName() const noexcept
162 {
163 return bt_error_cause_message_iterator_actor_get_component_name(this->libObjPtr());
164 }
165
166 bt2c::CStringView componentName() const noexcept
167 {
168 return bt_error_cause_message_iterator_actor_get_component_name(this->libObjPtr());
169 }
170
171 bt2::ComponentClass::Type componentClassType() const noexcept
172 {
173 return static_cast<bt2::ComponentClass::Type>(
174 bt_error_cause_message_iterator_actor_get_component_class_type(this->libObjPtr()));
175 }
176
177 bt2c::CStringView componentClassName() const noexcept
178 {
179 return bt_error_cause_message_iterator_actor_get_component_class_name(this->libObjPtr());
180 }
181
182 bt2c::CStringView pluginName() const noexcept
183 {
184 return bt_error_cause_message_iterator_actor_get_plugin_name(this->libObjPtr());
185 }
186};
187
188inline ConstMessageIteratorErrorCause ConstErrorCause::asMessageIterator() const noexcept
189{
190 return ConstMessageIteratorErrorCause {this->libObjPtr()};
191}
192
193class ConstErrorIterator;
194
195class ConstErrorCauseProxy final
196{
197 friend ConstErrorIterator;
198
199private:
200 explicit ConstErrorCauseProxy(const ConstErrorCause cause) noexcept : _mCause {cause}
201 {
202 }
203
204public:
205 const ConstErrorCause *operator->() const noexcept
206 {
207 return &_mCause;
208 }
209
210private:
211 ConstErrorCause _mCause;
212};
213
214class UniqueConstError;
215
216class ConstErrorIterator final
217{
218 friend UniqueConstError;
219
220private:
221 explicit ConstErrorIterator(const UniqueConstError& error, const std::uint64_t index) noexcept :
222 _mError {error}, _mIndex {index}
223 {
224 }
225
226public:
227 bool operator==(const ConstErrorIterator& other) const noexcept
228 {
229 BT_ASSERT(&other._mError == &_mError);
230 return other._mIndex == _mIndex;
231 }
232
233 bool operator!=(const ConstErrorIterator& other) const noexcept
234 {
235 return !(*this == other);
236 }
237
238 ConstErrorIterator& operator++() noexcept
239 {
240 ++_mIndex;
241 return *this;
242 }
243
244 ConstErrorIterator operator++(int) noexcept
245 {
246 const auto ret = *this;
247
248 ++_mIndex;
249 return ret;
250 }
251
252 ConstErrorCause operator*() const noexcept;
253
254 ConstErrorCauseProxy operator->() const noexcept
255 {
256 return ConstErrorCauseProxy {**this};
257 }
258
259private:
260 const UniqueConstError& _mError;
261 std::uint64_t _mIndex;
262};
263
264class UniqueConstError final
265{
266public:
267 using LibObjPtr = const bt_error *;
268
269 explicit UniqueConstError(const LibObjPtr libError) noexcept : _mLibError {libError}
270 {
271 }
272
273 explicit operator bool() const noexcept
274 {
275 return this->libObjPtr();
276 }
277
278 LibObjPtr libObjPtr() const noexcept
279 {
280 return _mLibError.get();
281 }
282
283 LibObjPtr release() noexcept
284 {
285 return _mLibError.release();
286 }
287
288 std::uint64_t length() const noexcept
289 {
290 return bt_error_get_cause_count(this->libObjPtr());
291 }
292
293 ConstErrorCause operator[](const std::uint64_t index) const noexcept
294 {
295 return ConstErrorCause {bt_error_borrow_cause_by_index(this->libObjPtr(), index)};
296 }
297
298 ConstErrorIterator begin() const noexcept
299 {
300 BT_ASSERT(_mLibError);
301 return ConstErrorIterator {*this, 0};
302 }
303
304 ConstErrorIterator end() const noexcept
305 {
306 BT_ASSERT(_mLibError);
307 return ConstErrorIterator {*this, this->length()};
308 }
309
310private:
311 struct _LibErrorDeleter final
312 {
313 void operator()(const LibObjPtr libError) const noexcept
314 {
315 bt_error_release(libError);
316 }
317 };
318
319 std::unique_ptr<std::remove_pointer<LibObjPtr>::type, _LibErrorDeleter> _mLibError;
320};
321
322inline ConstErrorCause ConstErrorIterator::operator*() const noexcept
323{
324 return _mError[_mIndex];
325}
326
327inline UniqueConstError takeCurrentThreadError() noexcept
328{
329 return UniqueConstError {bt_current_thread_take_error()};
330}
331
332inline void moveErrorToCurrentThread(UniqueConstError error) noexcept
333{
334 bt_current_thread_move_error(error.release());
335}
336
337} /* namespace bt2 */
338
339#endif /* BABELTRACE_CPP_COMMON_BT2_ERROR_HPP */
This page took 0.034854 seconds and 4 git commands to generate.