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, "Not available with `bt2::ConstBoolValue`.");
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,
413 "Not available with `bt2::ConstUnsignedIntegerValue`.");
415 _ThisCommonValue::operator=(val);
419 CommonUnsignedIntegerValue<const bt_value> asConst() const noexcept
421 return CommonUnsignedIntegerValue<const bt_value> {*this};
424 CommonUnsignedIntegerValue<LibObjT> operator=(const Value rawVal) const noexcept
426 bt_value_integer_unsigned_set(this->libObjPtr(), rawVal);
430 Value value() const noexcept
432 return bt_value_integer_unsigned_get(this->libObjPtr());
435 operator Value() const noexcept
437 return this->value();
440 Shared shared() const noexcept
442 return Shared::createWithRef(*this);
446 using UnsignedIntegerValue = CommonUnsignedIntegerValue<bt_value>;
447 using ConstUnsignedIntegerValue = CommonUnsignedIntegerValue<const bt_value>;
451 struct UnsignedIntegerValueTypeDescr
453 using Const = ConstUnsignedIntegerValue;
454 using NonConst = UnsignedIntegerValue;
458 struct TypeDescr<UnsignedIntegerValue> : public UnsignedIntegerValueTypeDescr
463 struct TypeDescr<ConstUnsignedIntegerValue> : public UnsignedIntegerValueTypeDescr
467 } /* namespace internal */
469 template <typename LibObjT>
470 class CommonSignedIntegerValue final : public CommonValue<LibObjT>
473 using typename CommonValue<LibObjT>::_LibObjPtr;
474 using typename CommonValue<LibObjT>::_ThisCommonValue;
477 using Shared = SharedValue<CommonSignedIntegerValue<LibObjT>, LibObjT>;
478 using Value = std::int64_t;
480 explicit CommonSignedIntegerValue(const _LibObjPtr libObjPtr) noexcept :
481 _ThisCommonValue {libObjPtr}
483 BT_ASSERT_DBG(this->isSignedInteger());
486 static Shared create(const Value rawVal = 0)
488 const auto libObjPtr = bt_value_integer_signed_create_init(rawVal);
490 internal::validateCreatedObjPtr(libObjPtr);
491 return CommonSignedIntegerValue::Shared::createWithoutRef(libObjPtr);
494 template <typename OtherLibObjT>
495 CommonSignedIntegerValue(const CommonSignedIntegerValue<OtherLibObjT> val) noexcept :
496 _ThisCommonValue {val}
500 template <typename OtherLibObjT>
501 CommonSignedIntegerValue<LibObjT>
502 operator=(const CommonSignedIntegerValue<OtherLibObjT> val) noexcept
504 _ThisCommonValue::operator=(val);
508 CommonSignedIntegerValue<const bt_value> asConst() const noexcept
510 return CommonSignedIntegerValue<const bt_value> {*this};
513 CommonSignedIntegerValue<LibObjT> operator=(const Value rawVal) const noexcept
515 static_assert(!std::is_const<LibObjT>::value,
516 "Not available with `bt2::ConstSignedIntegerValue`.");
518 bt_value_integer_signed_set(this->libObjPtr(), rawVal);
522 Value value() const noexcept
524 return bt_value_integer_signed_get(this->libObjPtr());
527 operator Value() const noexcept
529 return this->value();
532 Shared shared() const noexcept
534 return Shared::createWithRef(*this);
538 using SignedIntegerValue = CommonSignedIntegerValue<bt_value>;
539 using ConstSignedIntegerValue = CommonSignedIntegerValue<const bt_value>;
543 struct SignedIntegerValueTypeDescr
545 using Const = ConstSignedIntegerValue;
546 using NonConst = SignedIntegerValue;
550 struct TypeDescr<SignedIntegerValue> : public SignedIntegerValueTypeDescr
555 struct TypeDescr<ConstSignedIntegerValue> : public SignedIntegerValueTypeDescr
559 } /* namespace internal */
561 template <typename LibObjT>
562 class CommonRealValue final : public CommonValue<LibObjT>
565 using typename CommonValue<LibObjT>::_LibObjPtr;
566 using typename CommonValue<LibObjT>::_ThisCommonValue;
569 using Shared = SharedValue<CommonRealValue<LibObjT>, LibObjT>;
570 using Value = double;
572 explicit CommonRealValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
574 BT_ASSERT_DBG(this->isReal());
577 static Shared create(const Value rawVal = 0)
579 const auto libObjPtr = bt_value_real_create_init(rawVal);
581 internal::validateCreatedObjPtr(libObjPtr);
582 return CommonRealValue::Shared::createWithoutRef(libObjPtr);
585 template <typename OtherLibObjT>
586 CommonRealValue(const CommonRealValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
590 template <typename OtherLibObjT>
591 CommonRealValue<LibObjT>& operator=(const CommonRealValue<OtherLibObjT> val) noexcept
593 _ThisCommonValue::operator=(val);
597 CommonRealValue<const bt_value> asConst() const noexcept
599 return CommonRealValue<const bt_value> {*this};
602 CommonRealValue<LibObjT> operator=(const Value rawVal) const noexcept
604 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstRealValue`.");
606 bt_value_real_set(this->libObjPtr(), rawVal);
610 Value value() const noexcept
612 return bt_value_real_get(this->libObjPtr());
615 operator Value() const noexcept
617 return this->value();
620 Shared shared() const noexcept
622 return Shared::createWithRef(*this);
626 using RealValue = CommonRealValue<bt_value>;
627 using ConstRealValue = CommonRealValue<const bt_value>;
631 struct RealValueTypeDescr
633 using Const = ConstRealValue;
634 using NonConst = RealValue;
638 struct TypeDescr<RealValue> : public RealValueTypeDescr
643 struct TypeDescr<ConstRealValue> : public RealValueTypeDescr
647 } /* namespace internal */
649 template <typename LibObjT>
650 class CommonStringValue final : public CommonValue<LibObjT>
653 using typename CommonValue<LibObjT>::_LibObjPtr;
654 using typename CommonValue<LibObjT>::_ThisCommonValue;
657 using Shared = SharedValue<CommonStringValue<LibObjT>, LibObjT>;
659 explicit CommonStringValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
661 BT_ASSERT_DBG(this->isString());
664 static Shared create(const char * const rawVal = "")
666 const auto libObjPtr = bt_value_string_create_init(rawVal);
668 internal::validateCreatedObjPtr(libObjPtr);
669 return CommonStringValue::Shared::createWithoutRef(libObjPtr);
672 static Shared create(const std::string& rawVal)
674 return CommonStringValue::create(rawVal.data());
677 template <typename OtherLibObjT>
678 CommonStringValue(const CommonStringValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
682 template <typename OtherLibObjT>
683 CommonStringValue<LibObjT>& operator=(const CommonStringValue<OtherLibObjT> val) noexcept
685 _ThisCommonValue::operator=(val);
689 CommonStringValue<const bt_value> asConst() const noexcept
691 return CommonStringValue<const bt_value> {*this};
694 CommonStringValue<LibObjT> operator=(const char * const rawVal) const
696 static_assert(!std::is_const<LibObjT>::value,
697 "Not available with `bt2::ConstStringValue`.");
699 const auto status = bt_value_string_set(this->libObjPtr(), rawVal);
701 if (status == BT_VALUE_STRING_SET_STATUS_MEMORY_ERROR) {
702 throw MemoryError {};
708 CommonStringValue<LibObjT> operator=(const std::string& rawVal) const noexcept
710 return *this = rawVal.data();
713 bpstd::string_view value() const noexcept
715 return bt_value_string_get(this->libObjPtr());
718 Shared shared() const noexcept
720 return Shared::createWithRef(*this);
724 using StringValue = CommonStringValue<bt_value>;
725 using ConstStringValue = CommonStringValue<const bt_value>;
729 struct StringValueTypeDescr
731 using Const = ConstStringValue;
732 using NonConst = StringValue;
736 struct TypeDescr<StringValue> : public StringValueTypeDescr
741 struct TypeDescr<ConstStringValue> : public StringValueTypeDescr
745 template <typename LibObjT>
746 struct CommonArrayValueSpec;
748 /* Functions specific to mutable array values */
750 struct CommonArrayValueSpec<bt_value> final
752 static bt_value *elementByIndex(bt_value * const libValPtr, const std::uint64_t index) noexcept
754 return bt_value_array_borrow_element_by_index(libValPtr, index);
758 /* Functions specific to constant array values */
760 struct CommonArrayValueSpec<const bt_value> final
762 static const bt_value *elementByIndex(const bt_value * const libValPtr,
763 const std::uint64_t index) noexcept
765 return bt_value_array_borrow_element_by_index_const(libValPtr, index);
769 } /* namespace internal */
771 template <typename LibObjT>
772 class CommonArrayValue final : public CommonValue<LibObjT>
775 using typename CommonValue<LibObjT>::_LibObjPtr;
776 using typename CommonValue<LibObjT>::_ThisCommonValue;
779 using Shared = SharedValue<CommonArrayValue<LibObjT>, LibObjT>;
780 using Iterator = CommonIterator<CommonArrayValue<LibObjT>, CommonValue<LibObjT>>;
782 explicit CommonArrayValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
784 BT_ASSERT_DBG(this->isArray());
787 static Shared create()
789 const auto libObjPtr = bt_value_array_create();
791 internal::validateCreatedObjPtr(libObjPtr);
792 return CommonArrayValue::Shared::createWithoutRef(libObjPtr);
795 template <typename OtherLibObjT>
796 CommonArrayValue(const CommonArrayValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
800 template <typename OtherLibObjT>
801 CommonArrayValue<LibObjT>& operator=(const CommonArrayValue<OtherLibObjT> val) noexcept
803 _ThisCommonValue::operator=(val);
807 CommonArrayValue<const bt_value> asConst() const noexcept
809 return CommonArrayValue<const bt_value> {*this};
812 std::uint64_t length() const noexcept
814 return bt_value_array_get_length(this->libObjPtr());
817 Iterator begin() const noexcept
819 return Iterator {*this, 0};
822 Iterator end() const noexcept
824 return Iterator {*this, this->length()};
827 bool isEmpty() const noexcept
829 return this->length() == 0;
832 CommonValue<LibObjT> operator[](const std::uint64_t index) const noexcept
834 return CommonValue<LibObjT> {
835 internal::CommonArrayValueSpec<LibObjT>::elementByIndex(this->libObjPtr(), index)};
838 void append(const Value val) const
840 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
842 const auto status = bt_value_array_append_element(this->libObjPtr(), val.libObjPtr());
844 this->_handleAppendLibStatus(status);
847 void append(const bool rawVal) const
849 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
852 bt_value_array_append_bool_element(this->libObjPtr(), static_cast<bt_bool>(rawVal));
854 this->_handleAppendLibStatus(status);
857 void append(const std::uint64_t rawVal) const
859 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
862 bt_value_array_append_unsigned_integer_element(this->libObjPtr(), rawVal);
864 this->_handleAppendLibStatus(status);
867 void append(const std::int64_t rawVal) const
869 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
871 const auto status = bt_value_array_append_signed_integer_element(this->libObjPtr(), rawVal);
873 this->_handleAppendLibStatus(status);
876 void append(const double rawVal) const
878 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
880 const auto status = bt_value_array_append_real_element(this->libObjPtr(), rawVal);
882 this->_handleAppendLibStatus(status);
885 void append(const char * const rawVal) const
887 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
889 const auto status = bt_value_array_append_string_element(this->libObjPtr(), rawVal);
891 this->_handleAppendLibStatus(status);
894 void append(const std::string& rawVal) const
896 this->append(rawVal.data());
899 CommonArrayValue<bt_value> appendEmptyArray() const;
900 CommonMapValue<bt_value> appendEmptyMap() const;
902 void operator+=(const Value val) const
907 void operator+=(const bool rawVal) const
909 this->append(rawVal);
912 void operator+=(const std::uint64_t rawVal) const
914 this->append(rawVal);
917 void operator+=(const std::int64_t rawVal) const
919 this->append(rawVal);
922 void operator+=(const double rawVal) const
924 this->append(rawVal);
927 void operator+=(const char * const rawVal) const
929 this->append(rawVal);
932 void operator+=(const std::string& rawVal) const
934 this->append(rawVal);
937 Shared shared() const noexcept
939 return Shared::createWithRef(*this);
943 void _handleAppendLibStatus(const bt_value_array_append_element_status status) const
945 if (status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_MEMORY_ERROR) {
946 throw MemoryError {};
951 using ArrayValue = CommonArrayValue<bt_value>;
952 using ConstArrayValue = CommonArrayValue<const bt_value>;
956 struct ArrayValueTypeDescr
958 using Const = ConstArrayValue;
959 using NonConst = ArrayValue;
963 struct TypeDescr<ArrayValue> : public ArrayValueTypeDescr
968 struct TypeDescr<ConstArrayValue> : public ArrayValueTypeDescr
973 * Type of a user function passed to `CommonMapValue<ObjT>::forEach()`.
975 * First argument is the entry's key, second is its value.
977 template <typename ObjT>
978 using CommonMapValueForEachUserFunc = std::function<void(const bpstd::string_view&, ObjT)>;
981 * Template of a function to be passed to bt_value_map_foreach_entry()
982 * for bt_value_map_foreach_entry_const() which calls a user function.
984 * `userData` is casted to a `const` pointer to
985 * `CommonMapValueForEachUserFunc<ObjT>` (the user function to call).
987 * This function catches any exception which the user function throws
988 * and returns the `ErrorStatus` value. If there's no execption, this
989 * function returns the `OkStatus` value.
991 template <typename ObjT, typename LibObjT, typename LibStatusT, int OkStatus, int ErrorStatus>
992 LibStatusT mapValueForEachLibFunc(const char * const key, LibObjT * const libObjPtr,
993 void * const userData)
995 const auto& userFunc = *reinterpret_cast<const CommonMapValueForEachUserFunc<ObjT> *>(userData);
998 userFunc(key, ObjT {libObjPtr});
1000 return static_cast<LibStatusT>(ErrorStatus);
1003 return static_cast<LibStatusT>(OkStatus);
1006 template <typename LibObjT>
1007 struct CommonMapValueSpec;
1009 /* Functions specific to mutable map values */
1011 struct CommonMapValueSpec<bt_value> final
1013 static bt_value *entryByKey(bt_value * const libValPtr, const char * const key) noexcept
1015 return bt_value_map_borrow_entry_value(libValPtr, key);
1018 static void forEach(bt_value * const libValPtr,
1019 const CommonMapValueForEachUserFunc<Value>& func)
1021 const auto status = bt_value_map_foreach_entry(
1023 mapValueForEachLibFunc<Value, bt_value, bt_value_map_foreach_entry_func_status,
1024 BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_OK,
1025 BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_ERROR>,
1026 const_cast<void *>(reinterpret_cast<const void *>(&func)));
1029 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_OK:
1031 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_USER_ERROR:
1032 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_ERROR:
1040 /* Functions specific to constant map values */
1042 struct CommonMapValueSpec<const bt_value> final
1044 static const bt_value *entryByKey(const bt_value * const libValPtr,
1045 const char * const key) noexcept
1047 return bt_value_map_borrow_entry_value_const(libValPtr, key);
1050 static void forEach(const bt_value * const libValPtr,
1051 const CommonMapValueForEachUserFunc<ConstValue>& func)
1053 const auto status = bt_value_map_foreach_entry_const(
1055 mapValueForEachLibFunc<ConstValue, const bt_value,
1056 bt_value_map_foreach_entry_const_func_status,
1057 BT_VALUE_MAP_FOREACH_ENTRY_CONST_FUNC_STATUS_OK,
1058 BT_VALUE_MAP_FOREACH_ENTRY_CONST_FUNC_STATUS_ERROR>,
1059 const_cast<void *>(reinterpret_cast<const void *>(&func)));
1062 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_OK:
1064 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_USER_ERROR:
1065 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_ERROR:
1073 } /* namespace internal */
1075 template <typename LibObjT>
1076 class CommonMapValue final : public CommonValue<LibObjT>
1079 using typename CommonValue<LibObjT>::_LibObjPtr;
1080 using typename CommonValue<LibObjT>::_ThisCommonValue;
1083 using Shared = SharedValue<CommonMapValue<LibObjT>, LibObjT>;
1085 explicit CommonMapValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
1087 BT_ASSERT_DBG(this->isMap());
1090 static Shared create()
1092 const auto libObjPtr = bt_value_map_create();
1094 internal::validateCreatedObjPtr(libObjPtr);
1095 return CommonMapValue::Shared::createWithoutRef(libObjPtr);
1098 template <typename OtherLibObjT>
1099 CommonMapValue(const CommonMapValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
1103 template <typename OtherLibObjT>
1104 CommonMapValue<LibObjT>& operator=(const CommonMapValue<OtherLibObjT> val) noexcept
1106 _ThisCommonValue::operator=(val);
1110 CommonMapValue<const bt_value> asConst() const noexcept
1112 return CommonMapValue<const bt_value> {*this};
1115 std::uint64_t length() const noexcept
1117 return bt_value_map_get_size(this->libObjPtr());
1120 bool isEmpty() const noexcept
1122 return this->length() == 0;
1125 nonstd::optional<CommonValue<LibObjT>> operator[](const char * const key) const noexcept
1127 const auto libObjPtr =
1128 internal::CommonMapValueSpec<LibObjT>::entryByKey(this->libObjPtr(), key);
1131 return nonstd::nullopt;
1134 return CommonValue<LibObjT> {libObjPtr};
1137 nonstd::optional<CommonValue<LibObjT>> operator[](const std::string& key) const noexcept
1139 return (*this)[key.data()];
1142 bool hasEntry(const char * const key) const noexcept
1144 return static_cast<bool>(bt_value_map_has_entry(this->libObjPtr(), key));
1147 bool hasEntry(const std::string& key) const noexcept
1149 return this->hasEntry(key.data());
1152 void insert(const char * const key, const Value val) const
1154 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1156 const auto status = bt_value_map_insert_entry(this->libObjPtr(), key, val.libObjPtr());
1158 this->_handleInsertLibStatus(status);
1161 void insert(const std::string& key, const Value val) const
1163 this->insert(key.data(), val);
1166 void insert(const char * const key, const bool rawVal) const
1168 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1171 bt_value_map_insert_bool_entry(this->libObjPtr(), key, static_cast<bt_bool>(rawVal));
1173 this->_handleInsertLibStatus(status);
1176 void insert(const std::string& key, const bool rawVal) const
1178 this->insert(key.data(), rawVal);
1181 void insert(const char * const key, const std::uint64_t rawVal) const
1183 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1186 bt_value_map_insert_unsigned_integer_entry(this->libObjPtr(), key, rawVal);
1188 this->_handleInsertLibStatus(status);
1191 void insert(const std::string& key, const std::uint64_t rawVal) const
1193 this->insert(key.data(), rawVal);
1196 void insert(const char * const key, const std::int64_t rawVal) const
1198 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1201 bt_value_map_insert_signed_integer_entry(this->libObjPtr(), key, rawVal);
1203 this->_handleInsertLibStatus(status);
1206 void insert(const std::string& key, const std::int64_t rawVal) const
1208 this->insert(key.data(), rawVal);
1211 void insert(const char * const key, const double rawVal) const
1213 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1215 const auto status = bt_value_map_insert_real_entry(this->libObjPtr(), key, rawVal);
1217 this->_handleInsertLibStatus(status);
1220 void insert(const std::string& key, const double rawVal) const
1222 this->insert(key.data(), rawVal);
1225 void insert(const char * const key, const char * const rawVal) const
1227 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1229 const auto status = bt_value_map_insert_string_entry(this->libObjPtr(), key, rawVal);
1231 this->_handleInsertLibStatus(status);
1234 void insert(const char * const key, const std::string& rawVal) const
1236 this->insert(key, rawVal.data());
1239 void insert(const std::string& key, const char * const rawVal) const
1241 this->insert(key.data(), rawVal);
1244 void insert(const std::string& key, const std::string& rawVal) const
1246 this->insert(key.data(), rawVal.data());
1249 CommonArrayValue<bt_value> insertEmptyArray(const char *key) const;
1250 CommonArrayValue<bt_value> insertEmptyArray(const std::string& key) const;
1251 CommonMapValue<bt_value> insertEmptyMap(const char *key) const;
1252 CommonMapValue<bt_value> insertEmptyMap(const std::string& key) const;
1254 void forEach(const internal::CommonMapValueForEachUserFunc<CommonValue<LibObjT>>& func) const
1256 internal::CommonMapValueSpec<LibObjT>::forEach(this->libObjPtr(), func);
1259 Shared shared() const noexcept
1261 return Shared::createWithRef(*this);
1265 void _handleInsertLibStatus(const bt_value_map_insert_entry_status status) const
1267 if (status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_MEMORY_ERROR) {
1268 throw MemoryError {};
1273 using MapValue = CommonMapValue<bt_value>;
1274 using ConstMapValue = CommonMapValue<const bt_value>;
1276 namespace internal {
1278 struct MapValueTypeDescr
1280 using Const = ConstMapValue;
1281 using NonConst = MapValue;
1285 struct TypeDescr<MapValue> : public MapValueTypeDescr
1290 struct TypeDescr<ConstMapValue> : public MapValueTypeDescr
1294 } /* namespace internal */
1296 template <typename LibObjT>
1297 CommonNullValue<LibObjT> CommonValue<LibObjT>::asNull() const noexcept
1299 BT_ASSERT_DBG(this->isNull());
1300 return CommonNullValue<LibObjT> {this->libObjPtr()};
1303 template <typename LibObjT>
1304 CommonBoolValue<LibObjT> CommonValue<LibObjT>::asBool() const noexcept
1306 BT_ASSERT_DBG(this->isBool());
1307 return CommonBoolValue<LibObjT> {this->libObjPtr()};
1310 template <typename LibObjT>
1311 CommonSignedIntegerValue<LibObjT> CommonValue<LibObjT>::asSignedInteger() const noexcept
1313 BT_ASSERT_DBG(this->isSignedInteger());
1314 return CommonSignedIntegerValue<LibObjT> {this->libObjPtr()};
1317 template <typename LibObjT>
1318 CommonUnsignedIntegerValue<LibObjT> CommonValue<LibObjT>::asUnsignedInteger() const noexcept
1320 BT_ASSERT_DBG(this->isUnsignedInteger());
1321 return CommonUnsignedIntegerValue<LibObjT> {this->libObjPtr()};
1324 template <typename LibObjT>
1325 CommonRealValue<LibObjT> CommonValue<LibObjT>::asReal() const noexcept
1327 BT_ASSERT_DBG(this->isReal());
1328 return CommonRealValue<LibObjT> {this->libObjPtr()};
1331 template <typename LibObjT>
1332 CommonStringValue<LibObjT> CommonValue<LibObjT>::asString() const noexcept
1334 BT_ASSERT_DBG(this->isString());
1335 return CommonStringValue<LibObjT> {this->libObjPtr()};
1338 template <typename LibObjT>
1339 CommonArrayValue<LibObjT> CommonValue<LibObjT>::asArray() const noexcept
1341 BT_ASSERT_DBG(this->isArray());
1342 return CommonArrayValue<LibObjT> {this->libObjPtr()};
1345 template <typename LibObjT>
1346 CommonMapValue<LibObjT> CommonValue<LibObjT>::asMap() const noexcept
1348 BT_ASSERT_DBG(this->isMap());
1349 return CommonMapValue<LibObjT> {this->libObjPtr()};
1352 template <typename LibObjT>
1353 ArrayValue CommonArrayValue<LibObjT>::appendEmptyArray() const
1355 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
1357 bt_value *libElemPtr;
1358 const auto status = bt_value_array_append_empty_array_element(this->libObjPtr(), &libElemPtr);
1360 this->_handleAppendLibStatus(status);
1361 return ArrayValue {libElemPtr};
1364 template <typename LibObjT>
1365 MapValue CommonArrayValue<LibObjT>::appendEmptyMap() const
1367 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
1369 bt_value *libElemPtr;
1370 const auto status = bt_value_array_append_empty_map_element(this->libObjPtr(), &libElemPtr);
1372 this->_handleAppendLibStatus(status);
1373 return MapValue {libElemPtr};
1376 template <typename LibObjT>
1377 ArrayValue CommonMapValue<LibObjT>::insertEmptyArray(const char * const key) const
1379 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1381 bt_value *libEntryPtr;
1382 const auto status = bt_value_map_insert_empty_array_entry(this->libObjPtr(), key, &libEntryPtr);
1384 this->_handleInsertLibStatus(status);
1385 return ArrayValue {libEntryPtr};
1388 template <typename LibObjT>
1389 ArrayValue CommonMapValue<LibObjT>::insertEmptyArray(const std::string& key) const
1391 return this->insertEmptyArray(key.data());
1394 template <typename LibObjT>
1395 MapValue CommonMapValue<LibObjT>::insertEmptyMap(const char * const key) const
1397 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1399 bt_value *libEntryPtr;
1400 const auto status = bt_value_map_insert_empty_map_entry(this->libObjPtr(), key, &libEntryPtr);
1402 this->_handleInsertLibStatus(status);
1403 return MapValue {libEntryPtr};
1406 template <typename LibObjT>
1407 MapValue CommonMapValue<LibObjT>::insertEmptyMap(const std::string& key) const
1409 return this->insertEmptyMap(key.data());
1412 inline BoolValue::Shared createValue(const bool rawVal)
1414 return BoolValue::create(rawVal);
1417 inline UnsignedIntegerValue::Shared createValue(const std::uint64_t rawVal)
1419 return UnsignedIntegerValue::create(rawVal);
1422 inline SignedIntegerValue::Shared createValue(const std::int64_t rawVal)
1424 return SignedIntegerValue::create(rawVal);
1427 inline RealValue::Shared createValue(const double rawVal)
1429 return RealValue::create(rawVal);
1432 inline StringValue::Shared createValue(const char * const rawVal)
1434 return StringValue::create(rawVal);
1437 inline StringValue::Shared createValue(const std::string& rawVal)
1439 return StringValue::create(rawVal);
1442 } /* namespace bt2 */
1444 #endif /* BABELTRACE_CPP_COMMON_BT2_VALUE_HPP */