Add missing C++ interface for the libbabeltrace2 trace IR API
[babeltrace.git] / src / cpp-common / bt2 / value.hpp
CommitLineData
33a17831
PP
1/*
2 * Copyright (c) 2020 Philippe Proulx <pproulx@efficios.com>
3 *
4 * SPDX-License-Identifier: MIT
5 */
6
7#ifndef BABELTRACE_CPP_COMMON_BT2_VALUE_HPP
8#define BABELTRACE_CPP_COMMON_BT2_VALUE_HPP
9
10#include <type_traits>
11#include <cstdint>
12#include <functional>
13#include <babeltrace2/babeltrace.h>
14
15#include "common/assert.h"
16#include "common/common.h"
17#include "internal/borrowed-obj.hpp"
18#include "internal/shared-obj.hpp"
19#include "internal/utils.hpp"
20#include "cpp-common/optional.hpp"
21#include "cpp-common/string_view.hpp"
22#include "lib-error.hpp"
23
24namespace bt2 {
25
26namespace internal {
27
28struct ValueRefFuncs final
29{
30 static void get(const bt_value * const libObjPtr)
31 {
32 bt_value_get_ref(libObjPtr);
33 }
34
35 static void put(const bt_value * const libObjPtr)
36 {
37 bt_value_put_ref(libObjPtr);
38 }
39};
40
41template <typename ObjT, typename LibObjT>
42using SharedValue = internal::SharedObj<ObjT, LibObjT, internal::ValueRefFuncs>;
43
44} // namespace internal
45
46template <typename LibObjT>
47class CommonNullValue;
48
49template <typename LibObjT>
50class CommonBoolValue;
51
52template <typename LibObjT>
53class CommonUnsignedIntegerValue;
54
55template <typename LibObjT>
56class CommonSignedIntegerValue;
57
58template <typename LibObjT>
59class CommonRealValue;
60
61template <typename LibObjT>
62class CommonStringValue;
63
64template <typename LibObjT>
65class CommonArrayValue;
66
67template <typename LibObjT>
68class CommonMapValue;
69
70enum class ValueType
71{
72 NUL = BT_VALUE_TYPE_NULL,
73 BOOL = BT_VALUE_TYPE_BOOL,
74 UNSIGNED_INTEGER = BT_VALUE_TYPE_UNSIGNED_INTEGER,
75 SIGNED_INTEGER = BT_VALUE_TYPE_SIGNED_INTEGER,
76 REAL = BT_VALUE_TYPE_REAL,
77 STRING = BT_VALUE_TYPE_STRING,
78 ARRAY = BT_VALUE_TYPE_ARRAY,
79 MAP = BT_VALUE_TYPE_MAP,
80};
81
cfc44919
PP
82template <typename LibObjT>
83class CommonClockClass;
84
12435a68
PP
85template <typename LibObjT>
86class CommonFieldClass;
87
74fc764d
PP
88template <typename LibObjT>
89class CommonTraceClass;
90
91template <typename LibObjT>
92class CommonStreamClass;
93
94template <typename LibObjT>
95class CommonEventClass;
96
97template <typename LibObjT>
98class CommonStream;
99
33a17831
PP
100template <typename LibObjT>
101class CommonValue : public internal::BorrowedObj<LibObjT>
102{
103 // Allow append() to call `val._libObjPtr()`
104 friend class CommonArrayValue<bt_value>;
105
106 // Allow insert() to call `val._libObjPtr()`
107 friend class CommonMapValue<bt_value>;
108
cfc44919
PP
109 // Allow userAttributes() to call `val._libObjPtr()`
110 friend class CommonClockClass<bt_clock_class>;
12435a68 111 friend class CommonFieldClass<bt_field_class>;
74fc764d
PP
112 friend class CommonTraceClass<bt_trace_class>;
113 friend class CommonStreamClass<bt_stream_class>;
114 friend class CommonEventClass<bt_event_class>;
115 friend class CommonStream<bt_stream>;
cfc44919 116
33a17831
PP
117 // Allow operator==() to call `other._libObjPtr()`
118 friend class CommonValue<bt_value>;
119 friend class CommonValue<const bt_value>;
120
121private:
122 using typename internal::BorrowedObj<LibObjT>::_ThisBorrowedObj;
123
124protected:
125 using typename internal::BorrowedObj<LibObjT>::_LibObjPtr;
126 using _ThisCommonValue = CommonValue<LibObjT>;
127
128public:
129 using Shared = internal::SharedValue<CommonValue<LibObjT>, LibObjT>;
130
131 explicit CommonValue(const _LibObjPtr libObjPtr) noexcept : _ThisBorrowedObj {libObjPtr}
132 {
133 }
134
135 template <typename OtherLibObjT>
136 CommonValue(const CommonValue<OtherLibObjT>& val) noexcept : _ThisBorrowedObj {val}
137 {
138 }
139
140 template <typename OtherLibObjT>
141 _ThisCommonValue& operator=(const CommonValue<OtherLibObjT>& val) noexcept
142 {
143 _ThisBorrowedObj::operator=(val);
144 return *this;
145 }
146
147 ValueType type() const noexcept
148 {
149 return static_cast<ValueType>(bt_value_get_type(this->_libObjPtr()));
150 }
151
152 bool isNull() const noexcept
153 {
154 return this->_libTypeIs(BT_VALUE_TYPE_NULL);
155 }
156
157 bool isBool() const noexcept
158 {
159 return this->_libTypeIs(BT_VALUE_TYPE_BOOL);
160 }
161
162 bool isInteger() const noexcept
163 {
164 return this->_libTypeIs(BT_VALUE_TYPE_INTEGER);
165 }
166
167 bool isUnsignedInteger() const noexcept
168 {
169 return this->_libTypeIs(BT_VALUE_TYPE_UNSIGNED_INTEGER);
170 }
171
172 bool isSignedInteger() const noexcept
173 {
174 return this->_libTypeIs(BT_VALUE_TYPE_SIGNED_INTEGER);
175 }
176
177 bool isReal() const noexcept
178 {
179 return this->_libTypeIs(BT_VALUE_TYPE_REAL);
180 }
181
182 bool isString() const noexcept
183 {
184 return this->_libTypeIs(BT_VALUE_TYPE_STRING);
185 }
186
187 bool isArray() const noexcept
188 {
189 return this->_libTypeIs(BT_VALUE_TYPE_ARRAY);
190 }
191
192 bool isMap() const noexcept
193 {
194 return this->_libTypeIs(BT_VALUE_TYPE_MAP);
195 }
196
197 template <typename OtherLibObjT>
198 bool operator==(const CommonValue<OtherLibObjT>& other) const noexcept
199 {
200 return static_cast<bool>(bt_value_is_equal(this->_libObjPtr(), other._libObjPtr()));
201 }
202
203 template <typename OtherLibObjT>
204 bool operator!=(const CommonValue<OtherLibObjT>& other) const noexcept
205 {
206 return !(*this == other);
207 }
208
209 Shared shared() const noexcept
210 {
211 return Shared {*this};
212 }
213
214 CommonNullValue<LibObjT> asNull() const noexcept;
215 CommonBoolValue<LibObjT> asBool() const noexcept;
216 CommonSignedIntegerValue<LibObjT> asSignedInteger() const noexcept;
217 CommonUnsignedIntegerValue<LibObjT> asUnsignedInteger() const noexcept;
218 CommonRealValue<LibObjT> asReal() const noexcept;
219 CommonStringValue<LibObjT> asString() const noexcept;
220 CommonArrayValue<LibObjT> asArray() const noexcept;
221 CommonMapValue<LibObjT> asMap() const noexcept;
222
223protected:
224 bool _libTypeIs(const bt_value_type type) const noexcept
225 {
226 return bt_value_type_is(bt_value_get_type(this->_libObjPtr()), type);
227 }
228};
229
230using Value = CommonValue<bt_value>;
231using ConstValue = CommonValue<const bt_value>;
232
233template <typename LibObjT>
234class CommonNullValue final : public CommonValue<LibObjT>
235{
236private:
237 using typename CommonValue<LibObjT>::_ThisCommonValue;
238
239public:
240 using Shared = internal::SharedValue<CommonNullValue<LibObjT>, LibObjT>;
241
242 CommonNullValue() noexcept : _ThisCommonValue {bt_value_null}
243 {
244 }
245
246 template <typename OtherLibObjT>
247 CommonNullValue(const CommonNullValue<OtherLibObjT>& val) noexcept : _ThisCommonValue {val}
248 {
249 }
250
251 template <typename OtherLibObjT>
252 CommonNullValue<LibObjT>& operator=(const CommonNullValue<OtherLibObjT>& val) noexcept
253 {
254 _ThisCommonValue::operator=(val);
255 return *this;
256 }
257
258 Shared shared() const noexcept
259 {
260 return Shared {*this};
261 }
262};
263
264using NullValue = CommonNullValue<bt_value>;
265using ConstNullValue = CommonNullValue<const bt_value>;
266
267template <typename LibObjT>
268class CommonBoolValue final : public CommonValue<LibObjT>
269{
270private:
271 using typename CommonValue<LibObjT>::_LibObjPtr;
272 using typename CommonValue<LibObjT>::_ThisCommonValue;
273
274public:
275 using Shared = internal::SharedValue<CommonBoolValue<LibObjT>, LibObjT>;
276 using Value = bool;
277
278 explicit CommonBoolValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
279 {
280 BT_ASSERT_DBG(this->isBool());
281 }
282
283 template <typename OtherLibObjT>
284 CommonBoolValue(const CommonBoolValue<OtherLibObjT>& val) noexcept : _ThisCommonValue {val}
285 {
286 }
287
288 static Shared create(const Value rawVal = false)
289 {
290 const auto libObjPtr = bt_value_bool_create_init(static_cast<bt_bool>(rawVal));
291
292 internal::validateCreatedObjPtr(libObjPtr);
293 return Shared {CommonBoolValue<LibObjT> {libObjPtr}};
294 }
295
296 template <typename OtherLibObjT>
297 CommonBoolValue<LibObjT>& operator=(const CommonBoolValue<OtherLibObjT>& val) noexcept
298 {
299 _ThisCommonValue::operator=(val);
300 return *this;
301 }
302
303 CommonBoolValue<LibObjT>& operator=(const Value rawVal) noexcept
304 {
305 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
306
307 bt_value_bool_set(this->_libObjPtr(), static_cast<bt_bool>(rawVal));
308 return *this;
309 }
310
311 Value value() const noexcept
312 {
313 return static_cast<Value>(bt_value_bool_get(this->_libObjPtr()));
314 }
315
316 operator Value() const noexcept
317 {
318 return this->value();
319 }
320
321 Shared shared() const noexcept
322 {
323 return Shared {*this};
324 }
325};
326
327using BoolValue = CommonBoolValue<bt_value>;
328using ConstBoolValue = CommonBoolValue<const bt_value>;
329
330template <typename LibObjT>
331class CommonUnsignedIntegerValue final : public CommonValue<LibObjT>
332{
333private:
334 using typename CommonValue<LibObjT>::_LibObjPtr;
335 using typename CommonValue<LibObjT>::_ThisCommonValue;
336
337public:
338 using Shared = internal::SharedValue<CommonUnsignedIntegerValue<LibObjT>, LibObjT>;
339 using Value = std::uint64_t;
340
341 explicit CommonUnsignedIntegerValue(const _LibObjPtr libObjPtr) noexcept :
342 _ThisCommonValue {libObjPtr}
343 {
344 BT_ASSERT_DBG(this->isUnsignedInteger());
345 }
346
347 static Shared create(const Value rawVal = 0)
348 {
349 const auto libObjPtr = bt_value_integer_unsigned_create_init(rawVal);
350
351 internal::validateCreatedObjPtr(libObjPtr);
352 return Shared {CommonUnsignedIntegerValue<LibObjT> {libObjPtr}};
353 }
354
355 template <typename OtherLibObjT>
356 CommonUnsignedIntegerValue(const CommonUnsignedIntegerValue<OtherLibObjT>& val) noexcept :
357 _ThisCommonValue {val}
358 {
359 }
360
361 template <typename OtherLibObjT>
362 CommonUnsignedIntegerValue<LibObjT>&
363 operator=(const CommonUnsignedIntegerValue<OtherLibObjT>& val) noexcept
364 {
365 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
366
367 _ThisCommonValue::operator=(val);
368 return *this;
369 }
370
371 CommonUnsignedIntegerValue<LibObjT>& operator=(const Value rawVal) noexcept
372 {
373 bt_value_integer_unsigned_set(this->_libObjPtr(), rawVal);
374 return *this;
375 }
376
377 Value value() const noexcept
378 {
379 return bt_value_integer_unsigned_get(this->_libObjPtr());
380 }
381
382 operator Value() const noexcept
383 {
384 return this->value();
385 }
386
387 Shared shared() const noexcept
388 {
389 return Shared {*this};
390 }
391};
392
393using UnsignedIntegerValue = CommonUnsignedIntegerValue<bt_value>;
394using ConstUnsignedIntegerValue = CommonUnsignedIntegerValue<const bt_value>;
395
396template <typename LibObjT>
397class CommonSignedIntegerValue final : public CommonValue<LibObjT>
398{
399private:
400 using typename CommonValue<LibObjT>::_LibObjPtr;
401 using typename CommonValue<LibObjT>::_ThisCommonValue;
402
403public:
404 using Shared = internal::SharedValue<CommonSignedIntegerValue<LibObjT>, LibObjT>;
405 using Value = std::int64_t;
406
407 explicit CommonSignedIntegerValue(const _LibObjPtr libObjPtr) noexcept :
408 _ThisCommonValue {libObjPtr}
409 {
410 BT_ASSERT_DBG(this->isSignedInteger());
411 }
412
413 static Shared create(const Value rawVal = 0)
414 {
415 const auto libObjPtr = bt_value_integer_signed_create_init(rawVal);
416
417 internal::validateCreatedObjPtr(libObjPtr);
418 return Shared {CommonSignedIntegerValue<LibObjT> {libObjPtr}};
419 }
420
421 template <typename OtherLibObjT>
422 CommonSignedIntegerValue(const CommonSignedIntegerValue<OtherLibObjT>& val) noexcept :
423 _ThisCommonValue {val}
424 {
425 }
426
427 template <typename OtherLibObjT>
428 CommonSignedIntegerValue<LibObjT>&
429 operator=(const CommonSignedIntegerValue<OtherLibObjT>& val) noexcept
430 {
431 _ThisCommonValue::operator=(val);
432 return *this;
433 }
434
435 CommonSignedIntegerValue<LibObjT>& operator=(const Value rawVal) noexcept
436 {
437 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
438
439 bt_value_integer_signed_set(this->_libObjPtr(), rawVal);
440 return *this;
441 }
442
443 Value value() const noexcept
444 {
445 return bt_value_integer_signed_get(this->_libObjPtr());
446 }
447
448 operator Value() const noexcept
449 {
450 return this->value();
451 }
452
453 Shared shared() const noexcept
454 {
455 return Shared {*this};
456 }
457};
458
459using SignedIntegerValue = CommonSignedIntegerValue<bt_value>;
460using ConstSignedIntegerValue = CommonSignedIntegerValue<const bt_value>;
461
462template <typename LibObjT>
463class CommonRealValue final : public CommonValue<LibObjT>
464{
465private:
466 using typename CommonValue<LibObjT>::_LibObjPtr;
467 using typename CommonValue<LibObjT>::_ThisCommonValue;
468
469public:
470 using Shared = internal::SharedValue<CommonRealValue<LibObjT>, LibObjT>;
471 using Value = double;
472
473 explicit CommonRealValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
474 {
475 BT_ASSERT_DBG(this->isReal());
476 }
477
478 static Shared create(const Value rawVal = 0)
479 {
480 const auto libObjPtr = bt_value_real_create_init(rawVal);
481
482 internal::validateCreatedObjPtr(libObjPtr);
483 return Shared {CommonRealValue<LibObjT> {libObjPtr}};
484 }
485
486 template <typename OtherLibObjT>
487 CommonRealValue(const CommonRealValue<OtherLibObjT>& val) noexcept : _ThisCommonValue {val}
488 {
489 }
490
491 template <typename OtherLibObjT>
492 CommonRealValue<LibObjT>& operator=(const CommonRealValue<OtherLibObjT>& val) noexcept
493 {
494 _ThisCommonValue::operator=(val);
495 return *this;
496 }
497
498 CommonRealValue<LibObjT>& operator=(const Value rawVal) noexcept
499 {
500 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
501
502 bt_value_real_set(this->_libObjPtr(), rawVal);
503 return *this;
504 }
505
506 Value value() const noexcept
507 {
508 return bt_value_real_get(this->_libObjPtr());
509 }
510
511 operator Value() const noexcept
512 {
513 return this->value();
514 }
515
516 Shared shared() const noexcept
517 {
518 return Shared {*this};
519 }
520};
521
522using RealValue = CommonRealValue<bt_value>;
523using ConstRealValue = CommonRealValue<const bt_value>;
524
525template <typename LibObjT>
526class CommonStringValue final : public CommonValue<LibObjT>
527{
528private:
529 using typename CommonValue<LibObjT>::_LibObjPtr;
530 using typename CommonValue<LibObjT>::_ThisCommonValue;
531
532public:
533 using Shared = internal::SharedValue<CommonStringValue<LibObjT>, LibObjT>;
534
535 explicit CommonStringValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
536 {
537 BT_ASSERT_DBG(this->isString());
538 }
539
540 static Shared create(const char * const rawVal = "")
541 {
542 const auto libObjPtr = bt_value_string_create_init(rawVal);
543
544 internal::validateCreatedObjPtr(libObjPtr);
545 return Shared {CommonStringValue<LibObjT> {libObjPtr}};
546 }
547
548 static Shared create(const std::string& rawVal)
549 {
550 return CommonStringValue<LibObjT>::create(rawVal.data());
551 }
552
553 template <typename OtherLibObjT>
554 CommonStringValue(const CommonStringValue<OtherLibObjT>& val) noexcept : _ThisCommonValue {val}
555 {
556 }
557
558 template <typename OtherLibObjT>
559 CommonStringValue<LibObjT>& operator=(const CommonStringValue<OtherLibObjT>& val) noexcept
560 {
561 _ThisCommonValue::operator=(val);
562 return *this;
563 }
564
565 CommonStringValue<LibObjT>& operator=(const char * const rawVal)
566 {
567 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
568
569 const auto status = bt_value_string_set(this->_libObjPtr(), rawVal);
570
571 if (status == BT_VALUE_STRING_SET_STATUS_MEMORY_ERROR) {
572 throw LibMemoryError {};
573 }
574
575 return *this;
576 }
577
578 CommonStringValue<LibObjT>& operator=(const std::string& rawVal) noexcept
579 {
580 return *this = rawVal.data();
581 }
582
583 bpstd::string_view value() const noexcept
584 {
585 return bt_value_string_get(this->_libObjPtr());
586 }
587
588 Shared shared() const noexcept
589 {
590 return Shared {*this};
591 }
592};
593
594using StringValue = CommonStringValue<bt_value>;
595using ConstStringValue = CommonStringValue<const bt_value>;
596
597namespace internal {
598
599template <typename LibObjT>
600struct CommonArrayValueSpec;
601
602// Functions specific to mutable array values
603template <>
604struct CommonArrayValueSpec<bt_value> final
605{
606 static bt_value *elementByIndex(bt_value * const libValPtr, const std::uint64_t index) noexcept
607 {
608 return bt_value_array_borrow_element_by_index(libValPtr, index);
609 }
610};
611
612// Functions specific to constant array values
613template <>
614struct CommonArrayValueSpec<const bt_value> final
615{
616 static const bt_value *elementByIndex(const bt_value * const libValPtr,
617 const std::uint64_t index) noexcept
618 {
619 return bt_value_array_borrow_element_by_index_const(libValPtr, index);
620 }
621};
622
623} // namespace internal
624
625template <typename LibObjT>
626class CommonArrayValue final : public CommonValue<LibObjT>
627{
628private:
629 using typename CommonValue<LibObjT>::_LibObjPtr;
630 using typename CommonValue<LibObjT>::_ThisCommonValue;
631
632public:
633 using Shared = internal::SharedValue<CommonArrayValue<LibObjT>, LibObjT>;
634
635 explicit CommonArrayValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
636 {
637 BT_ASSERT_DBG(this->isArray());
638 }
639
640 static Shared create()
641 {
642 const auto libObjPtr = bt_value_array_create();
643
644 internal::validateCreatedObjPtr(libObjPtr);
645 return Shared {CommonArrayValue<LibObjT> {libObjPtr}};
646 }
647
648 template <typename OtherLibObjT>
649 CommonArrayValue(const CommonArrayValue<OtherLibObjT>& val) noexcept : _ThisCommonValue {val}
650 {
651 }
652
653 template <typename OtherLibObjT>
654 CommonArrayValue<LibObjT>& operator=(const CommonArrayValue<OtherLibObjT>& val) noexcept
655 {
656 _ThisCommonValue::operator=(val);
657 return *this;
658 }
659
660 std::uint64_t length() const noexcept
661 {
662 return bt_value_array_get_length(this->_libObjPtr());
663 }
664
665 bool isEmpty() const noexcept
666 {
667 return this->length() == 0;
668 }
669
670 ConstValue operator[](const std::uint64_t index) const noexcept
671 {
672 return ConstValue {internal::CommonArrayValueSpec<const bt_value>::elementByIndex(
673 this->_libObjPtr(), index)};
674 }
675
676 CommonValue<LibObjT> operator[](const std::uint64_t index) noexcept
677 {
678 return CommonValue<LibObjT> {
679 internal::CommonArrayValueSpec<LibObjT>::elementByIndex(this->_libObjPtr(), index)};
680 }
681
682 void append(const Value& val)
683 {
684 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
685
686 const auto status = bt_value_array_append_element(this->_libObjPtr(), val._libObjPtr());
687
688 this->_handleAppendLibStatus(status);
689 }
690
691 void append(const bool rawVal)
692 {
693 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
694
695 const auto status =
696 bt_value_array_append_bool_element(this->_libObjPtr(), static_cast<bt_bool>(rawVal));
697
698 this->_handleAppendLibStatus(status);
699 }
700
701 void append(const std::uint64_t rawVal)
702 {
703 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
704
705 const auto status =
706 bt_value_array_append_unsigned_integer_element(this->_libObjPtr(), rawVal);
707
708 this->_handleAppendLibStatus(status);
709 }
710
711 void append(const std::int64_t rawVal)
712 {
713 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
714
715 const auto status =
716 bt_value_array_append_signed_integer_element(this->_libObjPtr(), rawVal);
717
718 this->_handleAppendLibStatus(status);
719 }
720
721 void append(const double rawVal)
722 {
723 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
724
725 const auto status = bt_value_array_append_real_element(this->_libObjPtr(), rawVal);
726
727 this->_handleAppendLibStatus(status);
728 }
729
730 void append(const char * const rawVal)
731 {
732 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
733
734 const auto status = bt_value_array_append_string_element(this->_libObjPtr(), rawVal);
735
736 this->_handleAppendLibStatus(status);
737 }
738
739 void append(const std::string& rawVal)
740 {
741 this->append(rawVal.data());
742 }
743
744 CommonArrayValue<bt_value> appendEmptyArray();
745 CommonMapValue<bt_value> appendEmptyMap();
746
747 void operator+=(const Value& val)
748 {
749 this->append(val);
750 }
751
752 void operator+=(const bool rawVal)
753 {
754 this->append(rawVal);
755 }
756
757 void operator+=(const std::uint64_t rawVal)
758 {
759 this->append(rawVal);
760 }
761
762 void operator+=(const std::int64_t rawVal)
763 {
764 this->append(rawVal);
765 }
766
767 void operator+=(const double rawVal)
768 {
769 this->append(rawVal);
770 }
771
772 void operator+=(const char * const rawVal)
773 {
774 this->append(rawVal);
775 }
776
777 void operator+=(const std::string& rawVal)
778 {
779 this->append(rawVal);
780 }
781
782 Shared shared() const noexcept
783 {
784 return Shared {*this};
785 }
786
787private:
788 void _handleAppendLibStatus(const bt_value_array_append_element_status status) const
789 {
790 if (status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_MEMORY_ERROR) {
791 throw LibMemoryError {};
792 }
793 }
794};
795
796using ArrayValue = CommonArrayValue<bt_value>;
797using ConstArrayValue = CommonArrayValue<const bt_value>;
798
799namespace internal {
800
801/*
802 * Type of a user function passed to `CommonMapValue<ObjT>::forEach()`.
803 *
804 * First argument is the entry's key, second is its value.
805 */
806template <typename ObjT>
807using CommonMapValueForEachUserFunc = std::function<void(const bpstd::string_view&, ObjT)>;
808
809/*
810 * Template of a function to be passed to bt_value_map_foreach_entry()
811 * for bt_value_map_foreach_entry_const() which calls a user function.
812 *
813 * `userData` is casted to a `const` pointer to
814 * `CommonMapValueForEachUserFunc<ObjT>` (the user function to call).
815 *
816 * This function catches any exception which the user function throws
817 * and returns the `ErrorStatus` value. If there's no execption, this
818 * function returns the `OkStatus` value.
819 */
820template <typename ObjT, typename LibObjT, typename LibStatusT, int OkStatus, int ErrorStatus>
821LibStatusT mapValueForEachLibFunc(const char * const key, LibObjT * const libObjPtr,
822 void * const userData)
823{
824 const auto& userFunc = *reinterpret_cast<const CommonMapValueForEachUserFunc<ObjT> *>(userData);
825
826 try {
827 userFunc(key, ObjT {libObjPtr});
828 } catch (...) {
829 return static_cast<LibStatusT>(ErrorStatus);
830 }
831
832 return static_cast<LibStatusT>(OkStatus);
833}
834
835template <typename LibObjT>
836struct CommonMapValueSpec;
837
838// Functions specific to mutable map values
839template <>
840struct CommonMapValueSpec<bt_value> final
841{
842 static bt_value *entryByKey(bt_value * const libValPtr, const char * const key) noexcept
843 {
844 return bt_value_map_borrow_entry_value(libValPtr, key);
845 }
846
847 static void forEach(bt_value * const libValPtr,
848 const CommonMapValueForEachUserFunc<Value>& func)
849 {
850 const auto status = bt_value_map_foreach_entry(
851 libValPtr,
852 mapValueForEachLibFunc<Value, bt_value, bt_value_map_foreach_entry_func_status,
853 BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_OK,
854 BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_ERROR>,
855 const_cast<void *>(reinterpret_cast<const void *>(&func)));
856
857 switch (status) {
858 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_OK:
859 return;
860 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_USER_ERROR:
861 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_ERROR:
862 throw LibError {};
863 default:
864 bt_common_abort();
865 }
866 }
867};
868
869// Functions specific to constant map values
870template <>
871struct CommonMapValueSpec<const bt_value> final
872{
873 static const bt_value *entryByKey(const bt_value * const libValPtr,
874 const char * const key) noexcept
875 {
876 return bt_value_map_borrow_entry_value_const(libValPtr, key);
877 }
878
879 static void forEach(const bt_value * const libValPtr,
880 const CommonMapValueForEachUserFunc<ConstValue>& func)
881 {
882 const auto status = bt_value_map_foreach_entry_const(
883 libValPtr,
884 mapValueForEachLibFunc<ConstValue, const bt_value,
885 bt_value_map_foreach_entry_const_func_status,
886 BT_VALUE_MAP_FOREACH_ENTRY_CONST_FUNC_STATUS_OK,
887 BT_VALUE_MAP_FOREACH_ENTRY_CONST_FUNC_STATUS_ERROR>,
888 const_cast<void *>(reinterpret_cast<const void *>(&func)));
889
890 switch (status) {
891 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_OK:
892 return;
893 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_USER_ERROR:
894 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_ERROR:
895 throw LibError {};
896 default:
897 bt_common_abort();
898 }
899 }
900};
901
902} // namespace internal
903
904template <typename LibObjT>
905class CommonMapValue final : public CommonValue<LibObjT>
906{
907private:
908 using typename CommonValue<LibObjT>::_LibObjPtr;
909 using typename CommonValue<LibObjT>::_ThisCommonValue;
910
911public:
912 using Shared = internal::SharedValue<CommonMapValue<LibObjT>, LibObjT>;
913
914 explicit CommonMapValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
915 {
916 BT_ASSERT_DBG(this->isMap());
917 }
918
919 static Shared create()
920 {
921 const auto libObjPtr = bt_value_map_create();
922
923 internal::validateCreatedObjPtr(libObjPtr);
924 return Shared {CommonMapValue<LibObjT> {libObjPtr}};
925 }
926
927 template <typename OtherLibObjT>
928 CommonMapValue(const CommonMapValue<OtherLibObjT>& val) noexcept : _ThisCommonValue {val}
929 {
930 }
931
932 template <typename OtherLibObjT>
933 CommonMapValue<LibObjT>& operator=(const CommonMapValue<OtherLibObjT>& val) noexcept
934 {
935 _ThisCommonValue::operator=(val);
936 return *this;
937 }
938
939 std::uint64_t size() const noexcept
940 {
941 return bt_value_map_get_size(this->_libObjPtr());
942 }
943
944 bool isEmpty() const noexcept
945 {
946 return this->size() == 0;
947 }
948
949 nonstd::optional<ConstValue> operator[](const char * const key) const noexcept
950 {
951 const auto libObjPtr =
952 internal::CommonMapValueSpec<const bt_value>::entryByKey(this->_libObjPtr(), key);
953
954 if (!libObjPtr) {
955 return nonstd::nullopt;
956 }
957
958 return ConstValue {libObjPtr};
959 }
960
961 nonstd::optional<ConstValue> operator[](const std::string& key) const noexcept
962 {
963 return (*this)[key.data()];
964 }
965
966 nonstd::optional<CommonValue<LibObjT>> operator[](const char * const key) noexcept
967 {
968 const auto libObjPtr =
969 internal::CommonMapValueSpec<LibObjT>::entryByKey(this->_libObjPtr(), key);
970
971 if (!libObjPtr) {
972 return nonstd::nullopt;
973 }
974
975 return CommonValue<LibObjT> {libObjPtr};
976 }
977
978 nonstd::optional<CommonValue<LibObjT>> operator[](const std::string& key) noexcept
979 {
980 return (*this)[key.data()];
981 }
982
983 bool hasEntry(const char * const key) const noexcept
984 {
985 return static_cast<bool>(bt_value_map_has_entry(this->_libObjPtr(), key));
986 }
987
988 bool hasEntry(const std::string& key) const noexcept
989 {
990 return this->hasEntry(key.data());
991 }
992
993 void insert(const char * const key, const Value& val)
994 {
995 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
996
997 const auto status = bt_value_map_insert_entry(this->_libObjPtr(), key, val._libObjPtr());
998
999 this->_handleInsertLibStatus(status);
1000 }
1001
1002 void insert(const std::string& key, const Value& val)
1003 {
1004 this->insert(key.data(), val);
1005 }
1006
1007 void insert(const char * const key, const bool rawVal)
1008 {
1009 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1010
1011 const auto status =
1012 bt_value_map_insert_bool_entry(this->_libObjPtr(), key, static_cast<bt_bool>(rawVal));
1013
1014 this->_handleInsertLibStatus(status);
1015 }
1016
1017 void insert(const std::string& key, const bool rawVal)
1018 {
1019 this->insert(key.data(), rawVal);
1020 }
1021
1022 void insert(const char * const key, const std::uint64_t rawVal)
1023 {
1024 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1025
1026 const auto status =
1027 bt_value_map_insert_unsigned_integer_entry(this->_libObjPtr(), key, rawVal);
1028
1029 this->_handleInsertLibStatus(status);
1030 }
1031
1032 void insert(const std::string& key, const std::uint64_t rawVal)
1033 {
1034 this->insert(key.data(), rawVal);
1035 }
1036
1037 void insert(const char * const key, const std::int64_t rawVal)
1038 {
1039 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1040
1041 const auto status =
1042 bt_value_map_insert_signed_integer_entry(this->_libObjPtr(), key, rawVal);
1043
1044 this->_handleInsertLibStatus(status);
1045 }
1046
1047 void insert(const std::string& key, const std::int64_t rawVal)
1048 {
1049 this->insert(key.data(), rawVal);
1050 }
1051
1052 void insert(const char * const key, const double rawVal)
1053 {
1054 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1055
1056 const auto status = bt_value_map_insert_real_entry(this->_libObjPtr(), key, rawVal);
1057
1058 this->_handleInsertLibStatus(status);
1059 }
1060
1061 void insert(const std::string& key, const double rawVal)
1062 {
1063 this->insert(key.data(), rawVal);
1064 }
1065
1066 void insert(const char * const key, const char * const rawVal)
1067 {
1068 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1069
1070 const auto status = bt_value_map_insert_string_entry(this->_libObjPtr(), key, rawVal);
1071
1072 this->_handleInsertLibStatus(status);
1073 }
1074
1075 void insert(const char * const key, const std::string& rawVal)
1076 {
1077 this->insert(key, rawVal.data());
1078 }
1079
1080 void insert(const std::string& key, const char * const rawVal)
1081 {
1082 this->insert(key.data(), rawVal);
1083 }
1084
1085 void insert(const std::string& key, const std::string& rawVal)
1086 {
1087 this->insert(key.data(), rawVal.data());
1088 }
1089
1090 CommonArrayValue<bt_value> insertEmptyArray(const char *key);
1091 CommonArrayValue<bt_value> insertEmptyArray(const std::string& key);
1092 CommonMapValue<bt_value> insertEmptyMap(const char *key);
1093 CommonMapValue<bt_value> insertEmptyMap(const std::string& key);
1094
1095 void forEach(const internal::CommonMapValueForEachUserFunc<ConstValue>& func) const
1096 {
1097 internal::CommonMapValueSpec<const bt_value>::forEach(this->_libObjPtr(), func);
1098 }
1099
1100 void forEach(const internal::CommonMapValueForEachUserFunc<CommonValue<LibObjT>>& func)
1101 {
1102 internal::CommonMapValueSpec<LibObjT>::forEach(this->_libObjPtr(), func);
1103 }
1104
1105 Shared shared() const noexcept
1106 {
1107 return Shared {*this};
1108 }
1109
1110private:
1111 void _handleInsertLibStatus(const bt_value_map_insert_entry_status status) const
1112 {
1113 if (status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_MEMORY_ERROR) {
1114 throw LibMemoryError {};
1115 }
1116 }
1117};
1118
1119using MapValue = CommonMapValue<bt_value>;
1120using ConstMapValue = CommonMapValue<const bt_value>;
1121
1122template <typename LibObjT>
1123CommonNullValue<LibObjT> CommonValue<LibObjT>::asNull() const noexcept
1124{
1125 BT_ASSERT_DBG(this->isNull());
1126 return CommonNullValue<LibObjT> {this->_libObjPtr()};
1127}
1128
1129template <typename LibObjT>
1130CommonBoolValue<LibObjT> CommonValue<LibObjT>::asBool() const noexcept
1131{
1132 BT_ASSERT_DBG(this->isBool());
1133 return CommonBoolValue<LibObjT> {this->_libObjPtr()};
1134}
1135
1136template <typename LibObjT>
1137CommonSignedIntegerValue<LibObjT> CommonValue<LibObjT>::asSignedInteger() const noexcept
1138{
1139 BT_ASSERT_DBG(this->isSignedInteger());
1140 return CommonSignedIntegerValue<LibObjT> {this->_libObjPtr()};
1141}
1142
1143template <typename LibObjT>
1144CommonUnsignedIntegerValue<LibObjT> CommonValue<LibObjT>::asUnsignedInteger() const noexcept
1145{
1146 BT_ASSERT_DBG(this->isUnsignedInteger());
1147 return CommonUnsignedIntegerValue<LibObjT> {this->_libObjPtr()};
1148}
1149
1150template <typename LibObjT>
1151CommonRealValue<LibObjT> CommonValue<LibObjT>::asReal() const noexcept
1152{
1153 BT_ASSERT_DBG(this->isReal());
1154 return CommonRealValue<LibObjT> {this->_libObjPtr()};
1155}
1156
1157template <typename LibObjT>
1158CommonStringValue<LibObjT> CommonValue<LibObjT>::asString() const noexcept
1159{
1160 BT_ASSERT_DBG(this->isString());
1161 return CommonStringValue<LibObjT> {this->_libObjPtr()};
1162}
1163
1164template <typename LibObjT>
1165CommonArrayValue<LibObjT> CommonValue<LibObjT>::asArray() const noexcept
1166{
1167 BT_ASSERT_DBG(this->isArray());
1168 return CommonArrayValue<LibObjT> {this->_libObjPtr()};
1169}
1170
1171template <typename LibObjT>
1172CommonMapValue<LibObjT> CommonValue<LibObjT>::asMap() const noexcept
1173{
1174 BT_ASSERT_DBG(this->isMap());
1175 return CommonMapValue<LibObjT> {this->_libObjPtr()};
1176}
1177
1178template <typename LibObjT>
1179ArrayValue CommonArrayValue<LibObjT>::appendEmptyArray()
1180{
1181 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1182
1183 bt_value *libElemPtr;
1184 const auto status = bt_value_array_append_empty_array_element(this->_libObjPtr(), &libElemPtr);
1185
1186 this->_handleAppendLibStatus(status);
1187 return ArrayValue {libElemPtr};
1188}
1189
1190template <typename LibObjT>
1191MapValue CommonArrayValue<LibObjT>::appendEmptyMap()
1192{
1193 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1194
1195 bt_value *libElemPtr;
1196 const auto status = bt_value_array_append_empty_map_element(this->_libObjPtr(), &libElemPtr);
1197
1198 this->_handleAppendLibStatus(status);
1199 return MapValue {libElemPtr};
1200}
1201
1202template <typename LibObjT>
1203ArrayValue CommonMapValue<LibObjT>::insertEmptyArray(const char * const key)
1204{
1205 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1206
1207 bt_value *libEntryPtr;
1208 const auto status =
1209 bt_value_map_insert_empty_array_entry(this->_libObjPtr(), key, &libEntryPtr);
1210
1211 this->_handleInsertLibStatus(status);
1212 return ArrayValue {libEntryPtr};
1213}
1214
1215template <typename LibObjT>
1216ArrayValue CommonMapValue<LibObjT>::insertEmptyArray(const std::string& key)
1217{
1218 return this->insertEmptyArray(key.data());
1219}
1220
1221template <typename LibObjT>
1222MapValue CommonMapValue<LibObjT>::insertEmptyMap(const char * const key)
1223{
1224 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1225
1226 bt_value *libEntryPtr;
1227 const auto status = bt_value_map_insert_empty_map_entry(this->_libObjPtr(), key, &libEntryPtr);
1228
1229 this->_handleInsertLibStatus(status);
1230 return MapValue {libEntryPtr};
1231}
1232
1233template <typename LibObjT>
1234MapValue CommonMapValue<LibObjT>::insertEmptyMap(const std::string& key)
1235{
1236 return this->insertEmptyMap(key.data());
1237}
1238
1239inline BoolValue::Shared createValue(const bool rawVal)
1240{
1241 return BoolValue::create(rawVal);
1242}
1243
1244inline UnsignedIntegerValue::Shared createValue(const std::uint64_t rawVal)
1245{
1246 return UnsignedIntegerValue::create(rawVal);
1247}
1248
1249inline SignedIntegerValue::Shared createValue(const std::int64_t rawVal)
1250{
1251 return SignedIntegerValue::create(rawVal);
1252}
1253
1254inline RealValue::Shared createValue(const double rawVal)
1255{
1256 return RealValue::create(rawVal);
1257}
1258
1259inline StringValue::Shared createValue(const char * const rawVal)
1260{
1261 return StringValue::create(rawVal);
1262}
1263
1264inline StringValue::Shared createValue(const std::string& rawVal)
1265{
1266 return StringValue::create(rawVal);
1267}
1268
1269} // namespace bt2
1270
1271#endif // BABELTRACE_CPP_COMMON_BT2_VALUE_HPP
This page took 0.068091 seconds and 4 git commands to generate.