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
12 #include <type_traits>
14 #include <babeltrace2/babeltrace.h>
16 #include "common/assert.h"
17 #include "common/common.h"
18 #include "cpp-common/optional.hpp"
19 #include "cpp-common/string_view.hpp"
21 #include "borrowed-object.hpp"
22 #include "common-iterator.hpp"
24 #include "internal/utils.hpp"
25 #include "shared-object.hpp"
30 struct ValueRefFuncs final
32 static void get(const bt_value * const libObjPtr) noexcept
34 bt_value_get_ref(libObjPtr);
37 static void put(const bt_value * const libObjPtr) noexcept
39 bt_value_put_ref(libObjPtr);
43 } /* namespace internal */
45 template <typename ObjT, typename LibObjT>
46 using SharedValue = SharedObject<ObjT, LibObjT, internal::ValueRefFuncs>;
48 template <typename LibObjT>
49 class CommonNullValue;
51 template <typename LibObjT>
52 class CommonBoolValue;
54 template <typename LibObjT>
55 class CommonUnsignedIntegerValue;
57 template <typename LibObjT>
58 class CommonSignedIntegerValue;
60 template <typename LibObjT>
61 class CommonRealValue;
63 template <typename LibObjT>
64 class CommonStringValue;
66 template <typename LibObjT>
67 class CommonArrayValue;
69 template <typename LibObjT>
74 NUL = BT_VALUE_TYPE_NULL,
75 BOOL = BT_VALUE_TYPE_BOOL,
76 UNSIGNED_INTEGER = BT_VALUE_TYPE_UNSIGNED_INTEGER,
77 SIGNED_INTEGER = BT_VALUE_TYPE_SIGNED_INTEGER,
78 REAL = BT_VALUE_TYPE_REAL,
79 STRING = BT_VALUE_TYPE_STRING,
80 ARRAY = BT_VALUE_TYPE_ARRAY,
81 MAP = BT_VALUE_TYPE_MAP,
84 template <typename LibObjT>
85 class CommonValue : public BorrowedObject<LibObjT>
88 using typename BorrowedObject<LibObjT>::_ThisBorrowedObject;
91 using typename BorrowedObject<LibObjT>::_LibObjPtr;
92 using _ThisCommonValue = CommonValue<LibObjT>;
95 using Shared = SharedValue<CommonValue<LibObjT>, LibObjT>;
97 explicit CommonValue(const _LibObjPtr libObjPtr) noexcept : _ThisBorrowedObject {libObjPtr}
101 template <typename OtherLibObjT>
102 CommonValue(const CommonValue<OtherLibObjT> val) noexcept : _ThisBorrowedObject {val}
106 template <typename OtherLibObjT>
107 _ThisCommonValue& operator=(const CommonValue<OtherLibObjT> val) noexcept
109 _ThisBorrowedObject::operator=(val);
113 CommonValue<const bt_value> asConst() const noexcept
115 return CommonValue<const bt_value> {*this};
118 ValueType type() const noexcept
120 return static_cast<ValueType>(bt_value_get_type(this->libObjPtr()));
123 bool isNull() const noexcept
125 return this->_libTypeIs(BT_VALUE_TYPE_NULL);
128 bool isBool() const noexcept
130 return this->_libTypeIs(BT_VALUE_TYPE_BOOL);
133 bool isInteger() const noexcept
135 return this->_libTypeIs(BT_VALUE_TYPE_INTEGER);
138 bool isUnsignedInteger() const noexcept
140 return this->_libTypeIs(BT_VALUE_TYPE_UNSIGNED_INTEGER);
143 bool isSignedInteger() const noexcept
145 return this->_libTypeIs(BT_VALUE_TYPE_SIGNED_INTEGER);
148 bool isReal() const noexcept
150 return this->_libTypeIs(BT_VALUE_TYPE_REAL);
153 bool isString() const noexcept
155 return this->_libTypeIs(BT_VALUE_TYPE_STRING);
158 bool isArray() const noexcept
160 return this->_libTypeIs(BT_VALUE_TYPE_ARRAY);
163 bool isMap() const noexcept
165 return this->_libTypeIs(BT_VALUE_TYPE_MAP);
168 template <typename OtherLibObjT>
169 bool operator==(const CommonValue<OtherLibObjT> other) const noexcept
171 return static_cast<bool>(bt_value_is_equal(this->libObjPtr(), other.libObjPtr()));
174 template <typename OtherLibObjT>
175 bool operator!=(const CommonValue<OtherLibObjT> other) const noexcept
177 return !(*this == other);
180 Shared shared() const noexcept
182 return Shared::createWithRef(*this);
185 template <typename ValueT>
186 ValueT as() const noexcept
188 return ValueT {this->libObjPtr()};
191 CommonNullValue<LibObjT> asNull() const noexcept;
192 CommonBoolValue<LibObjT> asBool() const noexcept;
193 CommonSignedIntegerValue<LibObjT> asSignedInteger() const noexcept;
194 CommonUnsignedIntegerValue<LibObjT> asUnsignedInteger() const noexcept;
195 CommonRealValue<LibObjT> asReal() const noexcept;
196 CommonStringValue<LibObjT> asString() const noexcept;
197 CommonArrayValue<LibObjT> asArray() const noexcept;
198 CommonMapValue<LibObjT> asMap() const noexcept;
201 bool _libTypeIs(const bt_value_type type) const noexcept
203 return bt_value_type_is(bt_value_get_type(this->libObjPtr()), type);
207 using Value = CommonValue<bt_value>;
208 using ConstValue = CommonValue<const bt_value>;
212 struct ValueTypeDescr
214 using Const = ConstValue;
215 using NonConst = Value;
219 struct TypeDescr<Value> : public ValueTypeDescr
224 struct TypeDescr<ConstValue> : public ValueTypeDescr
228 } /* namespace internal */
230 template <typename LibObjT>
231 class CommonNullValue final : public CommonValue<LibObjT>
234 using typename CommonValue<LibObjT>::_ThisCommonValue;
237 using Shared = SharedValue<CommonNullValue<LibObjT>, LibObjT>;
239 CommonNullValue() noexcept : _ThisCommonValue {bt_value_null}
243 template <typename OtherLibObjT>
244 CommonNullValue(const CommonNullValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
248 template <typename OtherLibObjT>
249 CommonNullValue<LibObjT>& operator=(const CommonNullValue<OtherLibObjT> val) noexcept
251 _ThisCommonValue::operator=(val);
255 CommonNullValue<const bt_value> asConst() const noexcept
257 return CommonNullValue<const bt_value> {*this};
260 Shared shared() const noexcept
262 return Shared::createWithRef(*this);
266 using NullValue = CommonNullValue<bt_value>;
267 using ConstNullValue = CommonNullValue<const bt_value>;
271 struct NullValueTypeDescr
273 using Const = ConstNullValue;
274 using NonConst = NullValue;
278 struct TypeDescr<NullValue> : public NullValueTypeDescr
283 struct TypeDescr<ConstNullValue> : public NullValueTypeDescr
287 } /* namespace internal */
289 template <typename LibObjT>
290 class CommonBoolValue final : public CommonValue<LibObjT>
293 using typename CommonValue<LibObjT>::_LibObjPtr;
294 using typename CommonValue<LibObjT>::_ThisCommonValue;
297 using Shared = SharedValue<CommonBoolValue<LibObjT>, LibObjT>;
300 explicit CommonBoolValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
302 BT_ASSERT_DBG(this->isBool());
305 template <typename OtherLibObjT>
306 CommonBoolValue(const CommonBoolValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
310 static Shared create(const Value rawVal = false)
312 const auto libObjPtr = bt_value_bool_create_init(static_cast<bt_bool>(rawVal));
314 internal::validateCreatedObjPtr(libObjPtr);
315 return CommonBoolValue::Shared::createWithoutRef(libObjPtr);
318 template <typename OtherLibObjT>
319 CommonBoolValue<LibObjT>& operator=(const CommonBoolValue<OtherLibObjT> val) noexcept
321 _ThisCommonValue::operator=(val);
325 CommonBoolValue<const bt_value> asConst() const noexcept
327 return CommonBoolValue<const bt_value> {*this};
330 CommonBoolValue<LibObjT> operator=(const Value rawVal) const noexcept
332 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
334 bt_value_bool_set(this->libObjPtr(), static_cast<bt_bool>(rawVal));
338 Value value() const noexcept
340 return static_cast<Value>(bt_value_bool_get(this->libObjPtr()));
343 operator Value() const noexcept
345 return this->value();
348 Shared shared() const noexcept
350 return Shared::createWithRef(*this);
354 using BoolValue = CommonBoolValue<bt_value>;
355 using ConstBoolValue = CommonBoolValue<const bt_value>;
359 struct BoolValueTypeDescr
361 using Const = ConstBoolValue;
362 using NonConst = BoolValue;
366 struct TypeDescr<BoolValue> : public BoolValueTypeDescr
371 struct TypeDescr<ConstBoolValue> : public BoolValueTypeDescr
375 } /* namespace internal */
377 template <typename LibObjT>
378 class CommonUnsignedIntegerValue final : public CommonValue<LibObjT>
381 using typename CommonValue<LibObjT>::_LibObjPtr;
382 using typename CommonValue<LibObjT>::_ThisCommonValue;
385 using Shared = SharedValue<CommonUnsignedIntegerValue<LibObjT>, LibObjT>;
386 using Value = std::uint64_t;
388 explicit CommonUnsignedIntegerValue(const _LibObjPtr libObjPtr) noexcept :
389 _ThisCommonValue {libObjPtr}
391 BT_ASSERT_DBG(this->isUnsignedInteger());
394 static Shared create(const Value rawVal = 0)
396 const auto libObjPtr = bt_value_integer_unsigned_create_init(rawVal);
398 internal::validateCreatedObjPtr(libObjPtr);
399 return CommonUnsignedIntegerValue::Shared::createWithoutRef(libObjPtr);
402 template <typename OtherLibObjT>
403 CommonUnsignedIntegerValue(const CommonUnsignedIntegerValue<OtherLibObjT> val) noexcept :
404 _ThisCommonValue {val}
408 template <typename OtherLibObjT>
409 CommonUnsignedIntegerValue<LibObjT>&
410 operator=(const CommonUnsignedIntegerValue<OtherLibObjT> val) noexcept
412 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
414 _ThisCommonValue::operator=(val);
418 CommonUnsignedIntegerValue<const bt_value> asConst() const noexcept
420 return CommonUnsignedIntegerValue<const bt_value> {*this};
423 CommonUnsignedIntegerValue<LibObjT> operator=(const Value rawVal) const noexcept
425 bt_value_integer_unsigned_set(this->libObjPtr(), rawVal);
429 Value value() const noexcept
431 return bt_value_integer_unsigned_get(this->libObjPtr());
434 operator Value() const noexcept
436 return this->value();
439 Shared shared() const noexcept
441 return Shared::createWithRef(*this);
445 using UnsignedIntegerValue = CommonUnsignedIntegerValue<bt_value>;
446 using ConstUnsignedIntegerValue = CommonUnsignedIntegerValue<const bt_value>;
450 struct UnsignedIntegerValueTypeDescr
452 using Const = ConstUnsignedIntegerValue;
453 using NonConst = UnsignedIntegerValue;
457 struct TypeDescr<UnsignedIntegerValue> : public UnsignedIntegerValueTypeDescr
462 struct TypeDescr<ConstUnsignedIntegerValue> : public UnsignedIntegerValueTypeDescr
466 } /* namespace internal */
468 template <typename LibObjT>
469 class CommonSignedIntegerValue final : public CommonValue<LibObjT>
472 using typename CommonValue<LibObjT>::_LibObjPtr;
473 using typename CommonValue<LibObjT>::_ThisCommonValue;
476 using Shared = SharedValue<CommonSignedIntegerValue<LibObjT>, LibObjT>;
477 using Value = std::int64_t;
479 explicit CommonSignedIntegerValue(const _LibObjPtr libObjPtr) noexcept :
480 _ThisCommonValue {libObjPtr}
482 BT_ASSERT_DBG(this->isSignedInteger());
485 static Shared create(const Value rawVal = 0)
487 const auto libObjPtr = bt_value_integer_signed_create_init(rawVal);
489 internal::validateCreatedObjPtr(libObjPtr);
490 return CommonSignedIntegerValue::Shared::createWithoutRef(libObjPtr);
493 template <typename OtherLibObjT>
494 CommonSignedIntegerValue(const CommonSignedIntegerValue<OtherLibObjT> val) noexcept :
495 _ThisCommonValue {val}
499 template <typename OtherLibObjT>
500 CommonSignedIntegerValue<LibObjT>
501 operator=(const CommonSignedIntegerValue<OtherLibObjT> val) noexcept
503 _ThisCommonValue::operator=(val);
507 CommonSignedIntegerValue<const bt_value> asConst() const noexcept
509 return CommonSignedIntegerValue<const bt_value> {*this};
512 CommonSignedIntegerValue<LibObjT> operator=(const Value rawVal) const noexcept
514 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
516 bt_value_integer_signed_set(this->libObjPtr(), rawVal);
520 Value value() const noexcept
522 return bt_value_integer_signed_get(this->libObjPtr());
525 operator Value() const noexcept
527 return this->value();
530 Shared shared() const noexcept
532 return Shared::createWithRef(*this);
536 using SignedIntegerValue = CommonSignedIntegerValue<bt_value>;
537 using ConstSignedIntegerValue = CommonSignedIntegerValue<const bt_value>;
541 struct SignedIntegerValueTypeDescr
543 using Const = ConstSignedIntegerValue;
544 using NonConst = SignedIntegerValue;
548 struct TypeDescr<SignedIntegerValue> : public SignedIntegerValueTypeDescr
553 struct TypeDescr<ConstSignedIntegerValue> : public SignedIntegerValueTypeDescr
557 } /* namespace internal */
559 template <typename LibObjT>
560 class CommonRealValue final : public CommonValue<LibObjT>
563 using typename CommonValue<LibObjT>::_LibObjPtr;
564 using typename CommonValue<LibObjT>::_ThisCommonValue;
567 using Shared = SharedValue<CommonRealValue<LibObjT>, LibObjT>;
568 using Value = double;
570 explicit CommonRealValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
572 BT_ASSERT_DBG(this->isReal());
575 static Shared create(const Value rawVal = 0)
577 const auto libObjPtr = bt_value_real_create_init(rawVal);
579 internal::validateCreatedObjPtr(libObjPtr);
580 return CommonRealValue::Shared::createWithoutRef(libObjPtr);
583 template <typename OtherLibObjT>
584 CommonRealValue(const CommonRealValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
588 template <typename OtherLibObjT>
589 CommonRealValue<LibObjT>& operator=(const CommonRealValue<OtherLibObjT> val) noexcept
591 _ThisCommonValue::operator=(val);
595 CommonRealValue<const bt_value> asConst() const noexcept
597 return CommonRealValue<const bt_value> {*this};
600 CommonRealValue<LibObjT> operator=(const Value rawVal) const noexcept
602 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
604 bt_value_real_set(this->libObjPtr(), rawVal);
608 Value value() const noexcept
610 return bt_value_real_get(this->libObjPtr());
613 operator Value() const noexcept
615 return this->value();
618 Shared shared() const noexcept
620 return Shared::createWithRef(*this);
624 using RealValue = CommonRealValue<bt_value>;
625 using ConstRealValue = CommonRealValue<const bt_value>;
629 struct RealValueTypeDescr
631 using Const = ConstRealValue;
632 using NonConst = RealValue;
636 struct TypeDescr<RealValue> : public RealValueTypeDescr
641 struct TypeDescr<ConstRealValue> : public RealValueTypeDescr
645 } /* namespace internal */
647 template <typename LibObjT>
648 class CommonStringValue final : public CommonValue<LibObjT>
651 using typename CommonValue<LibObjT>::_LibObjPtr;
652 using typename CommonValue<LibObjT>::_ThisCommonValue;
655 using Shared = SharedValue<CommonStringValue<LibObjT>, LibObjT>;
657 explicit CommonStringValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
659 BT_ASSERT_DBG(this->isString());
662 static Shared create(const char * const rawVal = "")
664 const auto libObjPtr = bt_value_string_create_init(rawVal);
666 internal::validateCreatedObjPtr(libObjPtr);
667 return CommonStringValue::Shared::createWithoutRef(libObjPtr);
670 static Shared create(const std::string& rawVal)
672 return CommonStringValue::create(rawVal.data());
675 template <typename OtherLibObjT>
676 CommonStringValue(const CommonStringValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
680 template <typename OtherLibObjT>
681 CommonStringValue<LibObjT>& operator=(const CommonStringValue<OtherLibObjT> val) noexcept
683 _ThisCommonValue::operator=(val);
687 CommonStringValue<const bt_value> asConst() const noexcept
689 return CommonStringValue<const bt_value> {*this};
692 CommonStringValue<LibObjT> operator=(const char * const rawVal) const
694 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
696 const auto status = bt_value_string_set(this->libObjPtr(), rawVal);
698 if (status == BT_VALUE_STRING_SET_STATUS_MEMORY_ERROR) {
699 throw MemoryError {};
705 CommonStringValue<LibObjT> operator=(const std::string& rawVal) const noexcept
707 return *this = rawVal.data();
710 bpstd::string_view value() const noexcept
712 return bt_value_string_get(this->libObjPtr());
715 Shared shared() const noexcept
717 return Shared::createWithRef(*this);
721 using StringValue = CommonStringValue<bt_value>;
722 using ConstStringValue = CommonStringValue<const bt_value>;
726 struct StringValueTypeDescr
728 using Const = ConstStringValue;
729 using NonConst = StringValue;
733 struct TypeDescr<StringValue> : public StringValueTypeDescr
738 struct TypeDescr<ConstStringValue> : public StringValueTypeDescr
742 template <typename LibObjT>
743 struct CommonArrayValueSpec;
745 /* Functions specific to mutable array values */
747 struct CommonArrayValueSpec<bt_value> final
749 static bt_value *elementByIndex(bt_value * const libValPtr, const std::uint64_t index) noexcept
751 return bt_value_array_borrow_element_by_index(libValPtr, index);
755 /* Functions specific to constant array values */
757 struct CommonArrayValueSpec<const bt_value> final
759 static const bt_value *elementByIndex(const bt_value * const libValPtr,
760 const std::uint64_t index) noexcept
762 return bt_value_array_borrow_element_by_index_const(libValPtr, index);
766 } /* namespace internal */
768 template <typename LibObjT>
769 class CommonArrayValue final : public CommonValue<LibObjT>
772 using typename CommonValue<LibObjT>::_LibObjPtr;
773 using typename CommonValue<LibObjT>::_ThisCommonValue;
776 using Shared = SharedValue<CommonArrayValue<LibObjT>, LibObjT>;
777 using Iterator = CommonIterator<CommonArrayValue<LibObjT>, CommonValue<LibObjT>>;
779 explicit CommonArrayValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
781 BT_ASSERT_DBG(this->isArray());
784 static Shared create()
786 const auto libObjPtr = bt_value_array_create();
788 internal::validateCreatedObjPtr(libObjPtr);
789 return CommonArrayValue::Shared::createWithoutRef(libObjPtr);
792 template <typename OtherLibObjT>
793 CommonArrayValue(const CommonArrayValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
797 template <typename OtherLibObjT>
798 CommonArrayValue<LibObjT>& operator=(const CommonArrayValue<OtherLibObjT> val) noexcept
800 _ThisCommonValue::operator=(val);
804 CommonArrayValue<const bt_value> asConst() const noexcept
806 return CommonArrayValue<const bt_value> {*this};
809 std::uint64_t length() const noexcept
811 return bt_value_array_get_length(this->libObjPtr());
814 Iterator begin() const noexcept
816 return Iterator {*this, 0};
819 Iterator end() const noexcept
821 return Iterator {*this, this->length()};
824 bool isEmpty() const noexcept
826 return this->length() == 0;
829 CommonValue<LibObjT> operator[](const std::uint64_t index) const noexcept
831 return CommonValue<LibObjT> {
832 internal::CommonArrayValueSpec<LibObjT>::elementByIndex(this->libObjPtr(), index)};
835 void append(const Value val) const
837 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
839 const auto status = bt_value_array_append_element(this->libObjPtr(), val.libObjPtr());
841 this->_handleAppendLibStatus(status);
844 void append(const bool rawVal) const
846 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
849 bt_value_array_append_bool_element(this->libObjPtr(), static_cast<bt_bool>(rawVal));
851 this->_handleAppendLibStatus(status);
854 void append(const std::uint64_t rawVal) const
856 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
859 bt_value_array_append_unsigned_integer_element(this->libObjPtr(), rawVal);
861 this->_handleAppendLibStatus(status);
864 void append(const std::int64_t rawVal) const
866 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
868 const auto status = bt_value_array_append_signed_integer_element(this->libObjPtr(), rawVal);
870 this->_handleAppendLibStatus(status);
873 void append(const double rawVal) const
875 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
877 const auto status = bt_value_array_append_real_element(this->libObjPtr(), rawVal);
879 this->_handleAppendLibStatus(status);
882 void append(const char * const rawVal) const
884 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
886 const auto status = bt_value_array_append_string_element(this->libObjPtr(), rawVal);
888 this->_handleAppendLibStatus(status);
891 void append(const std::string& rawVal) const
893 this->append(rawVal.data());
896 CommonArrayValue<bt_value> appendEmptyArray() const;
897 CommonMapValue<bt_value> appendEmptyMap() const;
899 void operator+=(const Value val) const
904 void operator+=(const bool rawVal) const
906 this->append(rawVal);
909 void operator+=(const std::uint64_t rawVal) const
911 this->append(rawVal);
914 void operator+=(const std::int64_t rawVal) const
916 this->append(rawVal);
919 void operator+=(const double rawVal) const
921 this->append(rawVal);
924 void operator+=(const char * const rawVal) const
926 this->append(rawVal);
929 void operator+=(const std::string& rawVal) const
931 this->append(rawVal);
934 Shared shared() const noexcept
936 return Shared::createWithRef(*this);
940 void _handleAppendLibStatus(const bt_value_array_append_element_status status) const
942 if (status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_MEMORY_ERROR) {
943 throw MemoryError {};
948 using ArrayValue = CommonArrayValue<bt_value>;
949 using ConstArrayValue = CommonArrayValue<const bt_value>;
953 struct ArrayValueTypeDescr
955 using Const = ConstArrayValue;
956 using NonConst = ArrayValue;
960 struct TypeDescr<ArrayValue> : public ArrayValueTypeDescr
965 struct TypeDescr<ConstArrayValue> : public ArrayValueTypeDescr
970 * Type of a user function passed to `CommonMapValue<ObjT>::forEach()`.
972 * First argument is the entry's key, second is its value.
974 template <typename ObjT>
975 using CommonMapValueForEachUserFunc = std::function<void(const bpstd::string_view&, ObjT)>;
978 * Template of a function to be passed to bt_value_map_foreach_entry()
979 * for bt_value_map_foreach_entry_const() which calls a user function.
981 * `userData` is casted to a `const` pointer to
982 * `CommonMapValueForEachUserFunc<ObjT>` (the user function to call).
984 * This function catches any exception which the user function throws
985 * and returns the `ErrorStatus` value. If there's no execption, this
986 * function returns the `OkStatus` value.
988 template <typename ObjT, typename LibObjT, typename LibStatusT, int OkStatus, int ErrorStatus>
989 LibStatusT mapValueForEachLibFunc(const char * const key, LibObjT * const libObjPtr,
990 void * const userData)
992 const auto& userFunc = *reinterpret_cast<const CommonMapValueForEachUserFunc<ObjT> *>(userData);
995 userFunc(key, ObjT {libObjPtr});
997 return static_cast<LibStatusT>(ErrorStatus);
1000 return static_cast<LibStatusT>(OkStatus);
1003 template <typename LibObjT>
1004 struct CommonMapValueSpec;
1006 /* Functions specific to mutable map values */
1008 struct CommonMapValueSpec<bt_value> final
1010 static bt_value *entryByKey(bt_value * const libValPtr, const char * const key) noexcept
1012 return bt_value_map_borrow_entry_value(libValPtr, key);
1015 static void forEach(bt_value * const libValPtr,
1016 const CommonMapValueForEachUserFunc<Value>& func)
1018 const auto status = bt_value_map_foreach_entry(
1020 mapValueForEachLibFunc<Value, bt_value, bt_value_map_foreach_entry_func_status,
1021 BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_OK,
1022 BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_ERROR>,
1023 const_cast<void *>(reinterpret_cast<const void *>(&func)));
1026 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_OK:
1028 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_USER_ERROR:
1029 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_ERROR:
1037 /* Functions specific to constant map values */
1039 struct CommonMapValueSpec<const bt_value> final
1041 static const bt_value *entryByKey(const bt_value * const libValPtr,
1042 const char * const key) noexcept
1044 return bt_value_map_borrow_entry_value_const(libValPtr, key);
1047 static void forEach(const bt_value * const libValPtr,
1048 const CommonMapValueForEachUserFunc<ConstValue>& func)
1050 const auto status = bt_value_map_foreach_entry_const(
1052 mapValueForEachLibFunc<ConstValue, const bt_value,
1053 bt_value_map_foreach_entry_const_func_status,
1054 BT_VALUE_MAP_FOREACH_ENTRY_CONST_FUNC_STATUS_OK,
1055 BT_VALUE_MAP_FOREACH_ENTRY_CONST_FUNC_STATUS_ERROR>,
1056 const_cast<void *>(reinterpret_cast<const void *>(&func)));
1059 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_OK:
1061 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_USER_ERROR:
1062 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_ERROR:
1070 } /* namespace internal */
1072 template <typename LibObjT>
1073 class CommonMapValue final : public CommonValue<LibObjT>
1076 using typename CommonValue<LibObjT>::_LibObjPtr;
1077 using typename CommonValue<LibObjT>::_ThisCommonValue;
1080 using Shared = SharedValue<CommonMapValue<LibObjT>, LibObjT>;
1082 explicit CommonMapValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
1084 BT_ASSERT_DBG(this->isMap());
1087 static Shared create()
1089 const auto libObjPtr = bt_value_map_create();
1091 internal::validateCreatedObjPtr(libObjPtr);
1092 return CommonMapValue::Shared::createWithoutRef(libObjPtr);
1095 template <typename OtherLibObjT>
1096 CommonMapValue(const CommonMapValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
1100 template <typename OtherLibObjT>
1101 CommonMapValue<LibObjT>& operator=(const CommonMapValue<OtherLibObjT> val) noexcept
1103 _ThisCommonValue::operator=(val);
1107 CommonMapValue<const bt_value> asConst() const noexcept
1109 return CommonMapValue<const bt_value> {*this};
1112 std::uint64_t length() const noexcept
1114 return bt_value_map_get_size(this->libObjPtr());
1117 bool isEmpty() const noexcept
1119 return this->length() == 0;
1122 nonstd::optional<CommonValue<LibObjT>> operator[](const char * const key) const noexcept
1124 const auto libObjPtr =
1125 internal::CommonMapValueSpec<LibObjT>::entryByKey(this->libObjPtr(), key);
1128 return nonstd::nullopt;
1131 return CommonValue<LibObjT> {libObjPtr};
1134 nonstd::optional<CommonValue<LibObjT>> operator[](const std::string& key) const noexcept
1136 return (*this)[key.data()];
1139 bool hasEntry(const char * const key) const noexcept
1141 return static_cast<bool>(bt_value_map_has_entry(this->libObjPtr(), key));
1144 bool hasEntry(const std::string& key) const noexcept
1146 return this->hasEntry(key.data());
1149 void insert(const char * const key, const Value val) const
1151 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1153 const auto status = bt_value_map_insert_entry(this->libObjPtr(), key, val.libObjPtr());
1155 this->_handleInsertLibStatus(status);
1158 void insert(const std::string& key, const Value val) const
1160 this->insert(key.data(), val);
1163 void insert(const char * const key, const bool rawVal) const
1165 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1168 bt_value_map_insert_bool_entry(this->libObjPtr(), key, static_cast<bt_bool>(rawVal));
1170 this->_handleInsertLibStatus(status);
1173 void insert(const std::string& key, const bool rawVal) const
1175 this->insert(key.data(), rawVal);
1178 void insert(const char * const key, const std::uint64_t rawVal) const
1180 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1183 bt_value_map_insert_unsigned_integer_entry(this->libObjPtr(), key, rawVal);
1185 this->_handleInsertLibStatus(status);
1188 void insert(const std::string& key, const std::uint64_t rawVal) const
1190 this->insert(key.data(), rawVal);
1193 void insert(const char * const key, const std::int64_t rawVal) const
1195 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1198 bt_value_map_insert_signed_integer_entry(this->libObjPtr(), key, rawVal);
1200 this->_handleInsertLibStatus(status);
1203 void insert(const std::string& key, const std::int64_t rawVal) const
1205 this->insert(key.data(), rawVal);
1208 void insert(const char * const key, const double rawVal) const
1210 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1212 const auto status = bt_value_map_insert_real_entry(this->libObjPtr(), key, rawVal);
1214 this->_handleInsertLibStatus(status);
1217 void insert(const std::string& key, const double rawVal) const
1219 this->insert(key.data(), rawVal);
1222 void insert(const char * const key, const char * const rawVal) const
1224 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1226 const auto status = bt_value_map_insert_string_entry(this->libObjPtr(), key, rawVal);
1228 this->_handleInsertLibStatus(status);
1231 void insert(const char * const key, const std::string& rawVal) const
1233 this->insert(key, rawVal.data());
1236 void insert(const std::string& key, const char * const rawVal) const
1238 this->insert(key.data(), rawVal);
1241 void insert(const std::string& key, const std::string& rawVal) const
1243 this->insert(key.data(), rawVal.data());
1246 CommonArrayValue<bt_value> insertEmptyArray(const char *key) const;
1247 CommonArrayValue<bt_value> insertEmptyArray(const std::string& key) const;
1248 CommonMapValue<bt_value> insertEmptyMap(const char *key) const;
1249 CommonMapValue<bt_value> insertEmptyMap(const std::string& key) const;
1251 void forEach(const internal::CommonMapValueForEachUserFunc<CommonValue<LibObjT>>& func) const
1253 internal::CommonMapValueSpec<LibObjT>::forEach(this->libObjPtr(), func);
1256 Shared shared() const noexcept
1258 return Shared::createWithRef(*this);
1262 void _handleInsertLibStatus(const bt_value_map_insert_entry_status status) const
1264 if (status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_MEMORY_ERROR) {
1265 throw MemoryError {};
1270 using MapValue = CommonMapValue<bt_value>;
1271 using ConstMapValue = CommonMapValue<const bt_value>;
1273 namespace internal {
1275 struct MapValueTypeDescr
1277 using Const = ConstMapValue;
1278 using NonConst = MapValue;
1282 struct TypeDescr<MapValue> : public MapValueTypeDescr
1287 struct TypeDescr<ConstMapValue> : public MapValueTypeDescr
1291 } /* namespace internal */
1293 template <typename LibObjT>
1294 CommonNullValue<LibObjT> CommonValue<LibObjT>::asNull() const noexcept
1296 BT_ASSERT_DBG(this->isNull());
1297 return CommonNullValue<LibObjT> {this->libObjPtr()};
1300 template <typename LibObjT>
1301 CommonBoolValue<LibObjT> CommonValue<LibObjT>::asBool() const noexcept
1303 BT_ASSERT_DBG(this->isBool());
1304 return CommonBoolValue<LibObjT> {this->libObjPtr()};
1307 template <typename LibObjT>
1308 CommonSignedIntegerValue<LibObjT> CommonValue<LibObjT>::asSignedInteger() const noexcept
1310 BT_ASSERT_DBG(this->isSignedInteger());
1311 return CommonSignedIntegerValue<LibObjT> {this->libObjPtr()};
1314 template <typename LibObjT>
1315 CommonUnsignedIntegerValue<LibObjT> CommonValue<LibObjT>::asUnsignedInteger() const noexcept
1317 BT_ASSERT_DBG(this->isUnsignedInteger());
1318 return CommonUnsignedIntegerValue<LibObjT> {this->libObjPtr()};
1321 template <typename LibObjT>
1322 CommonRealValue<LibObjT> CommonValue<LibObjT>::asReal() const noexcept
1324 BT_ASSERT_DBG(this->isReal());
1325 return CommonRealValue<LibObjT> {this->libObjPtr()};
1328 template <typename LibObjT>
1329 CommonStringValue<LibObjT> CommonValue<LibObjT>::asString() const noexcept
1331 BT_ASSERT_DBG(this->isString());
1332 return CommonStringValue<LibObjT> {this->libObjPtr()};
1335 template <typename LibObjT>
1336 CommonArrayValue<LibObjT> CommonValue<LibObjT>::asArray() const noexcept
1338 BT_ASSERT_DBG(this->isArray());
1339 return CommonArrayValue<LibObjT> {this->libObjPtr()};
1342 template <typename LibObjT>
1343 CommonMapValue<LibObjT> CommonValue<LibObjT>::asMap() const noexcept
1345 BT_ASSERT_DBG(this->isMap());
1346 return CommonMapValue<LibObjT> {this->libObjPtr()};
1349 template <typename LibObjT>
1350 ArrayValue CommonArrayValue<LibObjT>::appendEmptyArray() const
1352 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1354 bt_value *libElemPtr;
1355 const auto status = bt_value_array_append_empty_array_element(this->libObjPtr(), &libElemPtr);
1357 this->_handleAppendLibStatus(status);
1358 return ArrayValue {libElemPtr};
1361 template <typename LibObjT>
1362 MapValue CommonArrayValue<LibObjT>::appendEmptyMap() const
1364 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1366 bt_value *libElemPtr;
1367 const auto status = bt_value_array_append_empty_map_element(this->libObjPtr(), &libElemPtr);
1369 this->_handleAppendLibStatus(status);
1370 return MapValue {libElemPtr};
1373 template <typename LibObjT>
1374 ArrayValue CommonMapValue<LibObjT>::insertEmptyArray(const char * const key) const
1376 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1378 bt_value *libEntryPtr;
1379 const auto status = bt_value_map_insert_empty_array_entry(this->libObjPtr(), key, &libEntryPtr);
1381 this->_handleInsertLibStatus(status);
1382 return ArrayValue {libEntryPtr};
1385 template <typename LibObjT>
1386 ArrayValue CommonMapValue<LibObjT>::insertEmptyArray(const std::string& key) const
1388 return this->insertEmptyArray(key.data());
1391 template <typename LibObjT>
1392 MapValue CommonMapValue<LibObjT>::insertEmptyMap(const char * const key) const
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_map_entry(this->libObjPtr(), key, &libEntryPtr);
1399 this->_handleInsertLibStatus(status);
1400 return MapValue {libEntryPtr};
1403 template <typename LibObjT>
1404 MapValue CommonMapValue<LibObjT>::insertEmptyMap(const std::string& key) const
1406 return this->insertEmptyMap(key.data());
1409 inline BoolValue::Shared createValue(const bool rawVal)
1411 return BoolValue::create(rawVal);
1414 inline UnsignedIntegerValue::Shared createValue(const std::uint64_t rawVal)
1416 return UnsignedIntegerValue::create(rawVal);
1419 inline SignedIntegerValue::Shared createValue(const std::int64_t rawVal)
1421 return SignedIntegerValue::create(rawVal);
1424 inline RealValue::Shared createValue(const double rawVal)
1426 return RealValue::create(rawVal);
1429 inline StringValue::Shared createValue(const char * const rawVal)
1431 return StringValue::create(rawVal);
1434 inline StringValue::Shared createValue(const std::string& rawVal)
1436 return StringValue::create(rawVal);
1439 } /* namespace bt2 */
1441 #endif /* BABELTRACE_CPP_COMMON_BT2_VALUE_HPP */