2 * Copyright (c) 2020 Philippe Proulx <pproulx@efficios.com>
4 * SPDX-License-Identifier: MIT
7 #ifndef BABELTRACE_CPP_COMMON_BT2_VALUE_HPP
8 #define BABELTRACE_CPP_COMMON_BT2_VALUE_HPP
10 #include <type_traits>
14 #include <babeltrace2/babeltrace.h>
16 #include "common/assert.h"
17 #include "common/common.h"
18 #include "common-iter.hpp"
19 #include "internal/borrowed-obj.hpp"
20 #include "internal/shared-obj.hpp"
21 #include "internal/utils.hpp"
22 #include "cpp-common/optional.hpp"
23 #include "cpp-common/string_view.hpp"
24 #include "lib-error.hpp"
29 struct ValueRefFuncs final
31 static void get(const bt_value * const libObjPtr)
33 bt_value_get_ref(libObjPtr);
36 static void put(const bt_value * const libObjPtr)
38 bt_value_put_ref(libObjPtr);
42 template <typename ObjT, typename LibObjT>
43 using SharedValue = internal::SharedObj<ObjT, LibObjT, internal::ValueRefFuncs>;
45 } /* namespace internal */
47 template <typename LibObjT>
48 class CommonNullValue;
50 template <typename LibObjT>
51 class CommonBoolValue;
53 template <typename LibObjT>
54 class CommonUnsignedIntegerValue;
56 template <typename LibObjT>
57 class CommonSignedIntegerValue;
59 template <typename LibObjT>
60 class CommonRealValue;
62 template <typename LibObjT>
63 class CommonStringValue;
65 template <typename LibObjT>
66 class CommonArrayValue;
68 template <typename LibObjT>
73 NUL = BT_VALUE_TYPE_NULL,
74 BOOL = BT_VALUE_TYPE_BOOL,
75 UNSIGNED_INTEGER = BT_VALUE_TYPE_UNSIGNED_INTEGER,
76 SIGNED_INTEGER = BT_VALUE_TYPE_SIGNED_INTEGER,
77 REAL = BT_VALUE_TYPE_REAL,
78 STRING = BT_VALUE_TYPE_STRING,
79 ARRAY = BT_VALUE_TYPE_ARRAY,
80 MAP = BT_VALUE_TYPE_MAP,
83 template <typename LibObjT>
84 class CommonClockClass;
86 template <typename LibObjT>
87 class CommonFieldClass;
89 template <typename LibObjT>
90 class CommonTraceClass;
92 template <typename LibObjT>
93 class CommonStreamClass;
95 template <typename LibObjT>
96 class CommonEventClass;
98 template <typename LibObjT>
101 template <typename LibObjT>
102 class CommonValue : public internal::BorrowedObj<LibObjT>
104 /* Allow append() to call `val.libObjPtr()` */
105 friend class CommonArrayValue<bt_value>;
107 /* Allow insert() to call `val.libObjPtr()` */
108 friend class CommonMapValue<bt_value>;
110 /* Allow userAttributes() to call `val.libObjPtr()` */
111 friend class CommonClockClass<bt_clock_class>;
112 friend class CommonFieldClass<bt_field_class>;
113 friend class CommonTraceClass<bt_trace_class>;
114 friend class CommonStreamClass<bt_stream_class>;
115 friend class CommonEventClass<bt_event_class>;
116 friend class CommonStream<bt_stream>;
118 /* Allow operator==() to call `other.libObjPtr()` */
119 friend class CommonValue<bt_value>;
120 friend class CommonValue<const bt_value>;
123 using typename internal::BorrowedObj<LibObjT>::_ThisBorrowedObj;
126 using typename internal::BorrowedObj<LibObjT>::_LibObjPtr;
127 using _ThisCommonValue = CommonValue<LibObjT>;
130 using Shared = internal::SharedValue<CommonValue<LibObjT>, LibObjT>;
132 explicit CommonValue(const _LibObjPtr libObjPtr) noexcept : _ThisBorrowedObj {libObjPtr}
136 template <typename OtherLibObjT>
137 CommonValue(const CommonValue<OtherLibObjT>& val) noexcept : _ThisBorrowedObj {val}
141 template <typename OtherLibObjT>
142 _ThisCommonValue& operator=(const CommonValue<OtherLibObjT>& val) noexcept
144 _ThisBorrowedObj::operator=(val);
148 ValueType type() const noexcept
150 return static_cast<ValueType>(bt_value_get_type(this->libObjPtr()));
153 bool isNull() const noexcept
155 return this->_libTypeIs(BT_VALUE_TYPE_NULL);
158 bool isBool() const noexcept
160 return this->_libTypeIs(BT_VALUE_TYPE_BOOL);
163 bool isInteger() const noexcept
165 return this->_libTypeIs(BT_VALUE_TYPE_INTEGER);
168 bool isUnsignedInteger() const noexcept
170 return this->_libTypeIs(BT_VALUE_TYPE_UNSIGNED_INTEGER);
173 bool isSignedInteger() const noexcept
175 return this->_libTypeIs(BT_VALUE_TYPE_SIGNED_INTEGER);
178 bool isReal() const noexcept
180 return this->_libTypeIs(BT_VALUE_TYPE_REAL);
183 bool isString() const noexcept
185 return this->_libTypeIs(BT_VALUE_TYPE_STRING);
188 bool isArray() const noexcept
190 return this->_libTypeIs(BT_VALUE_TYPE_ARRAY);
193 bool isMap() const noexcept
195 return this->_libTypeIs(BT_VALUE_TYPE_MAP);
198 template <typename OtherLibObjT>
199 bool operator==(const CommonValue<OtherLibObjT>& other) const noexcept
201 return static_cast<bool>(bt_value_is_equal(this->libObjPtr(), other.libObjPtr()));
204 template <typename OtherLibObjT>
205 bool operator!=(const CommonValue<OtherLibObjT>& other) const noexcept
207 return !(*this == other);
210 Shared shared() const noexcept
212 return Shared {*this};
215 CommonNullValue<LibObjT> asNull() const noexcept;
216 CommonBoolValue<LibObjT> asBool() const noexcept;
217 CommonSignedIntegerValue<LibObjT> asSignedInteger() const noexcept;
218 CommonUnsignedIntegerValue<LibObjT> asUnsignedInteger() const noexcept;
219 CommonRealValue<LibObjT> asReal() const noexcept;
220 CommonStringValue<LibObjT> asString() const noexcept;
221 CommonArrayValue<LibObjT> asArray() const noexcept;
222 CommonMapValue<LibObjT> asMap() const noexcept;
225 bool _libTypeIs(const bt_value_type type) const noexcept
227 return bt_value_type_is(bt_value_get_type(this->libObjPtr()), type);
231 using Value = CommonValue<bt_value>;
232 using ConstValue = CommonValue<const bt_value>;
236 struct ValueTypeDescr
238 using Const = ConstValue;
239 using NonConst = Value;
243 struct TypeDescr<Value> : public ValueTypeDescr
248 struct TypeDescr<ConstValue> : public ValueTypeDescr
252 } /* namespace internal */
254 template <typename LibObjT>
255 class CommonNullValue final : public CommonValue<LibObjT>
258 using typename CommonValue<LibObjT>::_ThisCommonValue;
261 using Shared = internal::SharedValue<CommonNullValue<LibObjT>, LibObjT>;
263 CommonNullValue() noexcept : _ThisCommonValue {bt_value_null}
267 template <typename OtherLibObjT>
268 CommonNullValue(const CommonNullValue<OtherLibObjT>& val) noexcept : _ThisCommonValue {val}
272 template <typename OtherLibObjT>
273 CommonNullValue<LibObjT>& operator=(const CommonNullValue<OtherLibObjT>& val) noexcept
275 _ThisCommonValue::operator=(val);
279 Shared shared() const noexcept
281 return Shared {*this};
285 using NullValue = CommonNullValue<bt_value>;
286 using ConstNullValue = CommonNullValue<const bt_value>;
290 struct NullValueTypeDescr
292 using Const = ConstNullValue;
293 using NonConst = NullValue;
297 struct TypeDescr<NullValue> : public NullValueTypeDescr
302 struct TypeDescr<ConstNullValue> : public NullValueTypeDescr
306 } /* namespace internal */
308 template <typename LibObjT>
309 class CommonBoolValue final : public CommonValue<LibObjT>
312 using typename CommonValue<LibObjT>::_LibObjPtr;
313 using typename CommonValue<LibObjT>::_ThisCommonValue;
316 using Shared = internal::SharedValue<CommonBoolValue<LibObjT>, LibObjT>;
319 explicit CommonBoolValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
321 BT_ASSERT_DBG(this->isBool());
324 template <typename OtherLibObjT>
325 CommonBoolValue(const CommonBoolValue<OtherLibObjT>& val) noexcept : _ThisCommonValue {val}
329 static Shared create(const Value rawVal = false)
331 const auto libObjPtr = bt_value_bool_create_init(static_cast<bt_bool>(rawVal));
333 internal::validateCreatedObjPtr(libObjPtr);
334 return Shared {CommonBoolValue<LibObjT> {libObjPtr}};
337 template <typename OtherLibObjT>
338 CommonBoolValue<LibObjT>& operator=(const CommonBoolValue<OtherLibObjT>& val) noexcept
340 _ThisCommonValue::operator=(val);
344 CommonBoolValue<LibObjT>& operator=(const Value rawVal) noexcept
346 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
348 bt_value_bool_set(this->libObjPtr(), static_cast<bt_bool>(rawVal));
352 Value value() const noexcept
354 return static_cast<Value>(bt_value_bool_get(this->libObjPtr()));
357 operator Value() const noexcept
359 return this->value();
362 Shared shared() const noexcept
364 return Shared {*this};
368 using BoolValue = CommonBoolValue<bt_value>;
369 using ConstBoolValue = CommonBoolValue<const bt_value>;
373 struct BoolValueTypeDescr
375 using Const = ConstBoolValue;
376 using NonConst = BoolValue;
380 struct TypeDescr<BoolValue> : public BoolValueTypeDescr
385 struct TypeDescr<ConstBoolValue> : public BoolValueTypeDescr
389 } /* namespace internal */
391 template <typename LibObjT>
392 class CommonUnsignedIntegerValue final : public CommonValue<LibObjT>
395 using typename CommonValue<LibObjT>::_LibObjPtr;
396 using typename CommonValue<LibObjT>::_ThisCommonValue;
399 using Shared = internal::SharedValue<CommonUnsignedIntegerValue<LibObjT>, LibObjT>;
400 using Value = std::uint64_t;
402 explicit CommonUnsignedIntegerValue(const _LibObjPtr libObjPtr) noexcept :
403 _ThisCommonValue {libObjPtr}
405 BT_ASSERT_DBG(this->isUnsignedInteger());
408 static Shared create(const Value rawVal = 0)
410 const auto libObjPtr = bt_value_integer_unsigned_create_init(rawVal);
412 internal::validateCreatedObjPtr(libObjPtr);
413 return Shared {CommonUnsignedIntegerValue<LibObjT> {libObjPtr}};
416 template <typename OtherLibObjT>
417 CommonUnsignedIntegerValue(const CommonUnsignedIntegerValue<OtherLibObjT>& val) noexcept :
418 _ThisCommonValue {val}
422 template <typename OtherLibObjT>
423 CommonUnsignedIntegerValue<LibObjT>&
424 operator=(const CommonUnsignedIntegerValue<OtherLibObjT>& val) noexcept
426 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
428 _ThisCommonValue::operator=(val);
432 CommonUnsignedIntegerValue<LibObjT>& operator=(const Value rawVal) noexcept
434 bt_value_integer_unsigned_set(this->libObjPtr(), rawVal);
438 Value value() const noexcept
440 return bt_value_integer_unsigned_get(this->libObjPtr());
443 operator Value() const noexcept
445 return this->value();
448 Shared shared() const noexcept
450 return Shared {*this};
454 using UnsignedIntegerValue = CommonUnsignedIntegerValue<bt_value>;
455 using ConstUnsignedIntegerValue = CommonUnsignedIntegerValue<const bt_value>;
459 struct UnsignedIntegerValueTypeDescr
461 using Const = ConstUnsignedIntegerValue;
462 using NonConst = UnsignedIntegerValue;
466 struct TypeDescr<UnsignedIntegerValue> : public UnsignedIntegerValueTypeDescr
471 struct TypeDescr<ConstUnsignedIntegerValue> : public UnsignedIntegerValueTypeDescr
475 } /* namespace internal */
477 template <typename LibObjT>
478 class CommonSignedIntegerValue final : public CommonValue<LibObjT>
481 using typename CommonValue<LibObjT>::_LibObjPtr;
482 using typename CommonValue<LibObjT>::_ThisCommonValue;
485 using Shared = internal::SharedValue<CommonSignedIntegerValue<LibObjT>, LibObjT>;
486 using Value = std::int64_t;
488 explicit CommonSignedIntegerValue(const _LibObjPtr libObjPtr) noexcept :
489 _ThisCommonValue {libObjPtr}
491 BT_ASSERT_DBG(this->isSignedInteger());
494 static Shared create(const Value rawVal = 0)
496 const auto libObjPtr = bt_value_integer_signed_create_init(rawVal);
498 internal::validateCreatedObjPtr(libObjPtr);
499 return Shared {CommonSignedIntegerValue<LibObjT> {libObjPtr}};
502 template <typename OtherLibObjT>
503 CommonSignedIntegerValue(const CommonSignedIntegerValue<OtherLibObjT>& val) noexcept :
504 _ThisCommonValue {val}
508 template <typename OtherLibObjT>
509 CommonSignedIntegerValue<LibObjT>&
510 operator=(const CommonSignedIntegerValue<OtherLibObjT>& val) noexcept
512 _ThisCommonValue::operator=(val);
516 CommonSignedIntegerValue<LibObjT>& operator=(const Value rawVal) noexcept
518 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
520 bt_value_integer_signed_set(this->libObjPtr(), rawVal);
524 Value value() const noexcept
526 return bt_value_integer_signed_get(this->libObjPtr());
529 operator Value() const noexcept
531 return this->value();
534 Shared shared() const noexcept
536 return Shared {*this};
540 using SignedIntegerValue = CommonSignedIntegerValue<bt_value>;
541 using ConstSignedIntegerValue = CommonSignedIntegerValue<const bt_value>;
545 struct SignedIntegerValueTypeDescr
547 using Const = ConstSignedIntegerValue;
548 using NonConst = SignedIntegerValue;
552 struct TypeDescr<SignedIntegerValue> : public SignedIntegerValueTypeDescr
557 struct TypeDescr<ConstSignedIntegerValue> : public SignedIntegerValueTypeDescr
561 } /* namespace internal */
563 template <typename LibObjT>
564 class CommonRealValue final : public CommonValue<LibObjT>
567 using typename CommonValue<LibObjT>::_LibObjPtr;
568 using typename CommonValue<LibObjT>::_ThisCommonValue;
571 using Shared = internal::SharedValue<CommonRealValue<LibObjT>, LibObjT>;
572 using Value = double;
574 explicit CommonRealValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
576 BT_ASSERT_DBG(this->isReal());
579 static Shared create(const Value rawVal = 0)
581 const auto libObjPtr = bt_value_real_create_init(rawVal);
583 internal::validateCreatedObjPtr(libObjPtr);
584 return Shared {CommonRealValue<LibObjT> {libObjPtr}};
587 template <typename OtherLibObjT>
588 CommonRealValue(const CommonRealValue<OtherLibObjT>& val) noexcept : _ThisCommonValue {val}
592 template <typename OtherLibObjT>
593 CommonRealValue<LibObjT>& operator=(const CommonRealValue<OtherLibObjT>& val) noexcept
595 _ThisCommonValue::operator=(val);
599 CommonRealValue<LibObjT>& operator=(const Value rawVal) noexcept
601 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
603 bt_value_real_set(this->libObjPtr(), rawVal);
607 Value value() const noexcept
609 return bt_value_real_get(this->libObjPtr());
612 operator Value() const noexcept
614 return this->value();
617 Shared shared() const noexcept
619 return Shared {*this};
623 using RealValue = CommonRealValue<bt_value>;
624 using ConstRealValue = CommonRealValue<const bt_value>;
628 struct RealValueTypeDescr
630 using Const = ConstRealValue;
631 using NonConst = RealValue;
635 struct TypeDescr<RealValue> : public RealValueTypeDescr
640 struct TypeDescr<ConstRealValue> : public RealValueTypeDescr
644 } /* namespace internal */
646 template <typename LibObjT>
647 class CommonStringValue final : public CommonValue<LibObjT>
650 using typename CommonValue<LibObjT>::_LibObjPtr;
651 using typename CommonValue<LibObjT>::_ThisCommonValue;
654 using Shared = internal::SharedValue<CommonStringValue<LibObjT>, LibObjT>;
656 explicit CommonStringValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
658 BT_ASSERT_DBG(this->isString());
661 static Shared create(const char * const rawVal = "")
663 const auto libObjPtr = bt_value_string_create_init(rawVal);
665 internal::validateCreatedObjPtr(libObjPtr);
666 return Shared {CommonStringValue<LibObjT> {libObjPtr}};
669 static Shared create(const std::string& rawVal)
671 return CommonStringValue<LibObjT>::create(rawVal.data());
674 template <typename OtherLibObjT>
675 CommonStringValue(const CommonStringValue<OtherLibObjT>& val) noexcept : _ThisCommonValue {val}
679 template <typename OtherLibObjT>
680 CommonStringValue<LibObjT>& operator=(const CommonStringValue<OtherLibObjT>& val) noexcept
682 _ThisCommonValue::operator=(val);
686 CommonStringValue<LibObjT>& operator=(const char * const rawVal)
688 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
690 const auto status = bt_value_string_set(this->libObjPtr(), rawVal);
692 if (status == BT_VALUE_STRING_SET_STATUS_MEMORY_ERROR) {
693 throw LibMemoryError {};
699 CommonStringValue<LibObjT>& operator=(const std::string& rawVal) noexcept
701 return *this = rawVal.data();
704 bpstd::string_view value() const noexcept
706 return bt_value_string_get(this->libObjPtr());
709 Shared shared() const noexcept
711 return Shared {*this};
715 using StringValue = CommonStringValue<bt_value>;
716 using ConstStringValue = CommonStringValue<const bt_value>;
720 struct StringValueTypeDescr
722 using Const = ConstStringValue;
723 using NonConst = StringValue;
727 struct TypeDescr<StringValue> : public StringValueTypeDescr
732 struct TypeDescr<ConstStringValue> : public StringValueTypeDescr
736 template <typename LibObjT>
737 struct CommonArrayValueSpec;
739 /* Functions specific to mutable array values */
741 struct CommonArrayValueSpec<bt_value> final
743 static bt_value *elementByIndex(bt_value * const libValPtr, const std::uint64_t index) noexcept
745 return bt_value_array_borrow_element_by_index(libValPtr, index);
749 /* Functions specific to constant array values */
751 struct CommonArrayValueSpec<const bt_value> final
753 static const bt_value *elementByIndex(const bt_value * const libValPtr,
754 const std::uint64_t index) noexcept
756 return bt_value_array_borrow_element_by_index_const(libValPtr, index);
760 } /* namespace internal */
762 template <typename LibObjT>
763 class CommonArrayValue final : public CommonValue<LibObjT>
766 using typename CommonValue<LibObjT>::_LibObjPtr;
767 using typename CommonValue<LibObjT>::_ThisCommonValue;
770 using Shared = internal::SharedValue<CommonArrayValue<LibObjT>, LibObjT>;
771 using Iterator = CommonIterator<CommonArrayValue<LibObjT>, CommonValue<LibObjT>>;
773 explicit CommonArrayValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
775 BT_ASSERT_DBG(this->isArray());
778 static Shared create()
780 const auto libObjPtr = bt_value_array_create();
782 internal::validateCreatedObjPtr(libObjPtr);
783 return Shared {CommonArrayValue<LibObjT> {libObjPtr}};
786 template <typename OtherLibObjT>
787 CommonArrayValue(const CommonArrayValue<OtherLibObjT>& val) noexcept : _ThisCommonValue {val}
791 template <typename OtherLibObjT>
792 CommonArrayValue<LibObjT>& operator=(const CommonArrayValue<OtherLibObjT>& val) noexcept
794 _ThisCommonValue::operator=(val);
798 std::uint64_t length() const noexcept
800 return bt_value_array_get_length(this->libObjPtr());
803 /* Required by the `CommonIterator` template class */
804 std::uint64_t size() const noexcept
806 return this->length();
809 Iterator begin() const noexcept
811 return Iterator {*this, 0};
814 Iterator end() const noexcept
816 return Iterator {*this, this->length()};
819 bool isEmpty() const noexcept
821 return this->length() == 0;
824 ConstValue operator[](const std::uint64_t index) const noexcept
826 return ConstValue {internal::CommonArrayValueSpec<const bt_value>::elementByIndex(
827 this->libObjPtr(), index)};
830 CommonValue<LibObjT> operator[](const std::uint64_t index) noexcept
832 return CommonValue<LibObjT> {
833 internal::CommonArrayValueSpec<LibObjT>::elementByIndex(this->libObjPtr(), index)};
836 void append(const Value& val)
838 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
840 const auto status = bt_value_array_append_element(this->libObjPtr(), val.libObjPtr());
842 this->_handleAppendLibStatus(status);
845 void append(const bool rawVal)
847 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
850 bt_value_array_append_bool_element(this->libObjPtr(), static_cast<bt_bool>(rawVal));
852 this->_handleAppendLibStatus(status);
855 void append(const std::uint64_t rawVal)
857 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
860 bt_value_array_append_unsigned_integer_element(this->libObjPtr(), rawVal);
862 this->_handleAppendLibStatus(status);
865 void append(const std::int64_t rawVal)
867 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
869 const auto status = bt_value_array_append_signed_integer_element(this->libObjPtr(), rawVal);
871 this->_handleAppendLibStatus(status);
874 void append(const double rawVal)
876 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
878 const auto status = bt_value_array_append_real_element(this->libObjPtr(), rawVal);
880 this->_handleAppendLibStatus(status);
883 void append(const char * const rawVal)
885 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
887 const auto status = bt_value_array_append_string_element(this->libObjPtr(), rawVal);
889 this->_handleAppendLibStatus(status);
892 void append(const std::string& rawVal)
894 this->append(rawVal.data());
897 CommonArrayValue<bt_value> appendEmptyArray();
898 CommonMapValue<bt_value> appendEmptyMap();
900 void operator+=(const Value& val)
905 void operator+=(const bool rawVal)
907 this->append(rawVal);
910 void operator+=(const std::uint64_t rawVal)
912 this->append(rawVal);
915 void operator+=(const std::int64_t rawVal)
917 this->append(rawVal);
920 void operator+=(const double rawVal)
922 this->append(rawVal);
925 void operator+=(const char * const rawVal)
927 this->append(rawVal);
930 void operator+=(const std::string& rawVal)
932 this->append(rawVal);
935 Shared shared() const noexcept
937 return Shared {*this};
941 void _handleAppendLibStatus(const bt_value_array_append_element_status status) const
943 if (status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_MEMORY_ERROR) {
944 throw LibMemoryError {};
949 using ArrayValue = CommonArrayValue<bt_value>;
950 using ConstArrayValue = CommonArrayValue<const bt_value>;
954 struct ArrayValueTypeDescr
956 using Const = ConstArrayValue;
957 using NonConst = ArrayValue;
961 struct TypeDescr<ArrayValue> : public ArrayValueTypeDescr
966 struct TypeDescr<ConstArrayValue> : public ArrayValueTypeDescr
971 * Type of a user function passed to `CommonMapValue<ObjT>::forEach()`.
973 * First argument is the entry's key, second is its value.
975 template <typename ObjT>
976 using CommonMapValueForEachUserFunc = std::function<void(const bpstd::string_view&, ObjT)>;
979 * Template of a function to be passed to bt_value_map_foreach_entry()
980 * for bt_value_map_foreach_entry_const() which calls a user function.
982 * `userData` is casted to a `const` pointer to
983 * `CommonMapValueForEachUserFunc<ObjT>` (the user function to call).
985 * This function catches any exception which the user function throws
986 * and returns the `ErrorStatus` value. If there's no execption, this
987 * function returns the `OkStatus` value.
989 template <typename ObjT, typename LibObjT, typename LibStatusT, int OkStatus, int ErrorStatus>
990 LibStatusT mapValueForEachLibFunc(const char * const key, LibObjT * const libObjPtr,
991 void * const userData)
993 const auto& userFunc = *reinterpret_cast<const CommonMapValueForEachUserFunc<ObjT> *>(userData);
996 userFunc(key, ObjT {libObjPtr});
998 return static_cast<LibStatusT>(ErrorStatus);
1001 return static_cast<LibStatusT>(OkStatus);
1004 template <typename LibObjT>
1005 struct CommonMapValueSpec;
1007 /* Functions specific to mutable map values */
1009 struct CommonMapValueSpec<bt_value> final
1011 static bt_value *entryByKey(bt_value * const libValPtr, const char * const key) noexcept
1013 return bt_value_map_borrow_entry_value(libValPtr, key);
1016 static void forEach(bt_value * const libValPtr,
1017 const CommonMapValueForEachUserFunc<Value>& func)
1019 const auto status = bt_value_map_foreach_entry(
1021 mapValueForEachLibFunc<Value, bt_value, bt_value_map_foreach_entry_func_status,
1022 BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_OK,
1023 BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_ERROR>,
1024 const_cast<void *>(reinterpret_cast<const void *>(&func)));
1027 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_OK:
1029 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_USER_ERROR:
1030 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_ERROR:
1038 /* Functions specific to constant map values */
1040 struct CommonMapValueSpec<const bt_value> final
1042 static const bt_value *entryByKey(const bt_value * const libValPtr,
1043 const char * const key) noexcept
1045 return bt_value_map_borrow_entry_value_const(libValPtr, key);
1048 static void forEach(const bt_value * const libValPtr,
1049 const CommonMapValueForEachUserFunc<ConstValue>& func)
1051 const auto status = bt_value_map_foreach_entry_const(
1053 mapValueForEachLibFunc<ConstValue, const bt_value,
1054 bt_value_map_foreach_entry_const_func_status,
1055 BT_VALUE_MAP_FOREACH_ENTRY_CONST_FUNC_STATUS_OK,
1056 BT_VALUE_MAP_FOREACH_ENTRY_CONST_FUNC_STATUS_ERROR>,
1057 const_cast<void *>(reinterpret_cast<const void *>(&func)));
1060 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_OK:
1062 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_USER_ERROR:
1063 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_ERROR:
1071 } /* namespace internal */
1073 template <typename LibObjT>
1074 class CommonMapValue final : public CommonValue<LibObjT>
1077 using typename CommonValue<LibObjT>::_LibObjPtr;
1078 using typename CommonValue<LibObjT>::_ThisCommonValue;
1081 using Shared = internal::SharedValue<CommonMapValue<LibObjT>, LibObjT>;
1083 explicit CommonMapValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
1085 BT_ASSERT_DBG(this->isMap());
1088 static Shared create()
1090 const auto libObjPtr = bt_value_map_create();
1092 internal::validateCreatedObjPtr(libObjPtr);
1093 return Shared {CommonMapValue<LibObjT> {libObjPtr}};
1096 template <typename OtherLibObjT>
1097 CommonMapValue(const CommonMapValue<OtherLibObjT>& val) noexcept : _ThisCommonValue {val}
1101 template <typename OtherLibObjT>
1102 CommonMapValue<LibObjT>& operator=(const CommonMapValue<OtherLibObjT>& val) noexcept
1104 _ThisCommonValue::operator=(val);
1108 std::uint64_t size() const noexcept
1110 return bt_value_map_get_size(this->libObjPtr());
1113 bool isEmpty() const noexcept
1115 return this->size() == 0;
1118 nonstd::optional<ConstValue> operator[](const char * const key) const noexcept
1120 const auto libObjPtr =
1121 internal::CommonMapValueSpec<const bt_value>::entryByKey(this->libObjPtr(), key);
1124 return nonstd::nullopt;
1127 return ConstValue {libObjPtr};
1130 nonstd::optional<ConstValue> operator[](const std::string& key) const noexcept
1132 return (*this)[key.data()];
1135 nonstd::optional<CommonValue<LibObjT>> operator[](const char * const key) noexcept
1137 const auto libObjPtr =
1138 internal::CommonMapValueSpec<LibObjT>::entryByKey(this->libObjPtr(), key);
1141 return nonstd::nullopt;
1144 return CommonValue<LibObjT> {libObjPtr};
1147 nonstd::optional<CommonValue<LibObjT>> operator[](const std::string& key) noexcept
1149 return (*this)[key.data()];
1152 bool hasEntry(const char * const key) const noexcept
1154 return static_cast<bool>(bt_value_map_has_entry(this->libObjPtr(), key));
1157 bool hasEntry(const std::string& key) const noexcept
1159 return this->hasEntry(key.data());
1162 void insert(const char * const key, const Value& val)
1164 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1166 const auto status = bt_value_map_insert_entry(this->libObjPtr(), key, val.libObjPtr());
1168 this->_handleInsertLibStatus(status);
1171 void insert(const std::string& key, const Value& val)
1173 this->insert(key.data(), val);
1176 void insert(const char * const key, const bool rawVal)
1178 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1181 bt_value_map_insert_bool_entry(this->libObjPtr(), key, static_cast<bt_bool>(rawVal));
1183 this->_handleInsertLibStatus(status);
1186 void insert(const std::string& key, const bool rawVal)
1188 this->insert(key.data(), rawVal);
1191 void insert(const char * const key, const std::uint64_t rawVal)
1193 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1196 bt_value_map_insert_unsigned_integer_entry(this->libObjPtr(), key, rawVal);
1198 this->_handleInsertLibStatus(status);
1201 void insert(const std::string& key, const std::uint64_t rawVal)
1203 this->insert(key.data(), rawVal);
1206 void insert(const char * const key, const std::int64_t rawVal)
1208 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1211 bt_value_map_insert_signed_integer_entry(this->libObjPtr(), key, rawVal);
1213 this->_handleInsertLibStatus(status);
1216 void insert(const std::string& key, const std::int64_t rawVal)
1218 this->insert(key.data(), rawVal);
1221 void insert(const char * const key, const double rawVal)
1223 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1225 const auto status = bt_value_map_insert_real_entry(this->libObjPtr(), key, rawVal);
1227 this->_handleInsertLibStatus(status);
1230 void insert(const std::string& key, const double rawVal)
1232 this->insert(key.data(), rawVal);
1235 void insert(const char * const key, const char * const rawVal)
1237 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1239 const auto status = bt_value_map_insert_string_entry(this->libObjPtr(), key, rawVal);
1241 this->_handleInsertLibStatus(status);
1244 void insert(const char * const key, const std::string& rawVal)
1246 this->insert(key, rawVal.data());
1249 void insert(const std::string& key, const char * const rawVal)
1251 this->insert(key.data(), rawVal);
1254 void insert(const std::string& key, const std::string& rawVal)
1256 this->insert(key.data(), rawVal.data());
1259 CommonArrayValue<bt_value> insertEmptyArray(const char *key);
1260 CommonArrayValue<bt_value> insertEmptyArray(const std::string& key);
1261 CommonMapValue<bt_value> insertEmptyMap(const char *key);
1262 CommonMapValue<bt_value> insertEmptyMap(const std::string& key);
1264 void forEach(const internal::CommonMapValueForEachUserFunc<ConstValue>& func) const
1266 internal::CommonMapValueSpec<const bt_value>::forEach(this->libObjPtr(), func);
1269 void forEach(const internal::CommonMapValueForEachUserFunc<CommonValue<LibObjT>>& func)
1271 internal::CommonMapValueSpec<LibObjT>::forEach(this->libObjPtr(), func);
1274 Shared shared() const noexcept
1276 return Shared {*this};
1280 void _handleInsertLibStatus(const bt_value_map_insert_entry_status status) const
1282 if (status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_MEMORY_ERROR) {
1283 throw LibMemoryError {};
1288 using MapValue = CommonMapValue<bt_value>;
1289 using ConstMapValue = CommonMapValue<const bt_value>;
1291 namespace internal {
1293 struct MapValueTypeDescr
1295 using Const = ConstMapValue;
1296 using NonConst = MapValue;
1300 struct TypeDescr<MapValue> : public MapValueTypeDescr
1305 struct TypeDescr<ConstMapValue> : public MapValueTypeDescr
1309 } /* namespace internal */
1311 template <typename LibObjT>
1312 CommonNullValue<LibObjT> CommonValue<LibObjT>::asNull() const noexcept
1314 BT_ASSERT_DBG(this->isNull());
1315 return CommonNullValue<LibObjT> {this->libObjPtr()};
1318 template <typename LibObjT>
1319 CommonBoolValue<LibObjT> CommonValue<LibObjT>::asBool() const noexcept
1321 BT_ASSERT_DBG(this->isBool());
1322 return CommonBoolValue<LibObjT> {this->libObjPtr()};
1325 template <typename LibObjT>
1326 CommonSignedIntegerValue<LibObjT> CommonValue<LibObjT>::asSignedInteger() const noexcept
1328 BT_ASSERT_DBG(this->isSignedInteger());
1329 return CommonSignedIntegerValue<LibObjT> {this->libObjPtr()};
1332 template <typename LibObjT>
1333 CommonUnsignedIntegerValue<LibObjT> CommonValue<LibObjT>::asUnsignedInteger() const noexcept
1335 BT_ASSERT_DBG(this->isUnsignedInteger());
1336 return CommonUnsignedIntegerValue<LibObjT> {this->libObjPtr()};
1339 template <typename LibObjT>
1340 CommonRealValue<LibObjT> CommonValue<LibObjT>::asReal() const noexcept
1342 BT_ASSERT_DBG(this->isReal());
1343 return CommonRealValue<LibObjT> {this->libObjPtr()};
1346 template <typename LibObjT>
1347 CommonStringValue<LibObjT> CommonValue<LibObjT>::asString() const noexcept
1349 BT_ASSERT_DBG(this->isString());
1350 return CommonStringValue<LibObjT> {this->libObjPtr()};
1353 template <typename LibObjT>
1354 CommonArrayValue<LibObjT> CommonValue<LibObjT>::asArray() const noexcept
1356 BT_ASSERT_DBG(this->isArray());
1357 return CommonArrayValue<LibObjT> {this->libObjPtr()};
1360 template <typename LibObjT>
1361 CommonMapValue<LibObjT> CommonValue<LibObjT>::asMap() const noexcept
1363 BT_ASSERT_DBG(this->isMap());
1364 return CommonMapValue<LibObjT> {this->libObjPtr()};
1367 template <typename LibObjT>
1368 ArrayValue CommonArrayValue<LibObjT>::appendEmptyArray()
1370 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1372 bt_value *libElemPtr;
1373 const auto status = bt_value_array_append_empty_array_element(this->libObjPtr(), &libElemPtr);
1375 this->_handleAppendLibStatus(status);
1376 return ArrayValue {libElemPtr};
1379 template <typename LibObjT>
1380 MapValue CommonArrayValue<LibObjT>::appendEmptyMap()
1382 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1384 bt_value *libElemPtr;
1385 const auto status = bt_value_array_append_empty_map_element(this->libObjPtr(), &libElemPtr);
1387 this->_handleAppendLibStatus(status);
1388 return MapValue {libElemPtr};
1391 template <typename LibObjT>
1392 ArrayValue CommonMapValue<LibObjT>::insertEmptyArray(const char * const key)
1394 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1396 bt_value *libEntryPtr;
1397 const auto status = bt_value_map_insert_empty_array_entry(this->libObjPtr(), key, &libEntryPtr);
1399 this->_handleInsertLibStatus(status);
1400 return ArrayValue {libEntryPtr};
1403 template <typename LibObjT>
1404 ArrayValue CommonMapValue<LibObjT>::insertEmptyArray(const std::string& key)
1406 return this->insertEmptyArray(key.data());
1409 template <typename LibObjT>
1410 MapValue CommonMapValue<LibObjT>::insertEmptyMap(const char * const key)
1412 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1414 bt_value *libEntryPtr;
1415 const auto status = bt_value_map_insert_empty_map_entry(this->libObjPtr(), key, &libEntryPtr);
1417 this->_handleInsertLibStatus(status);
1418 return MapValue {libEntryPtr};
1421 template <typename LibObjT>
1422 MapValue CommonMapValue<LibObjT>::insertEmptyMap(const std::string& key)
1424 return this->insertEmptyMap(key.data());
1427 inline BoolValue::Shared createValue(const bool rawVal)
1429 return BoolValue::create(rawVal);
1432 inline UnsignedIntegerValue::Shared createValue(const std::uint64_t rawVal)
1434 return UnsignedIntegerValue::create(rawVal);
1437 inline SignedIntegerValue::Shared createValue(const std::int64_t rawVal)
1439 return SignedIntegerValue::create(rawVal);
1442 inline RealValue::Shared createValue(const double rawVal)
1444 return RealValue::create(rawVal);
1447 inline StringValue::Shared createValue(const char * const rawVal)
1449 return StringValue::create(rawVal);
1452 inline StringValue::Shared createValue(const std::string& rawVal)
1454 return StringValue::create(rawVal);
1457 } /* namespace bt2 */
1459 #endif /* BABELTRACE_CPP_COMMON_BT2_VALUE_HPP */