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-iterator.hpp"
22 #include "borrowed-object.hpp"
24 #include "internal/utils.hpp"
25 #include "raw-value-proxy.hpp"
26 #include "shared-object.hpp"
31 struct ValueRefFuncs final
33 static void get(const bt_value * const libObjPtr) noexcept
35 bt_value_get_ref(libObjPtr);
38 static void put(const bt_value * const libObjPtr) noexcept
40 bt_value_put_ref(libObjPtr);
44 } /* namespace internal */
46 template <typename ObjT, typename LibObjT>
47 using SharedValue = SharedObject<ObjT, LibObjT, internal::ValueRefFuncs>;
49 template <typename LibObjT>
50 class CommonNullValue;
52 template <typename LibObjT>
53 class CommonBoolValue;
55 template <typename LibObjT>
56 class CommonUnsignedIntegerValue;
58 template <typename LibObjT>
59 class CommonSignedIntegerValue;
61 template <typename LibObjT>
62 class CommonRealValue;
64 template <typename LibObjT>
65 class CommonStringValue;
67 template <typename LibObjT>
68 class CommonArrayValue;
70 template <typename LibObjT>
75 NUL = BT_VALUE_TYPE_NULL,
76 BOOL = BT_VALUE_TYPE_BOOL,
77 UNSIGNED_INTEGER = BT_VALUE_TYPE_UNSIGNED_INTEGER,
78 SIGNED_INTEGER = BT_VALUE_TYPE_SIGNED_INTEGER,
79 REAL = BT_VALUE_TYPE_REAL,
80 STRING = BT_VALUE_TYPE_STRING,
81 ARRAY = BT_VALUE_TYPE_ARRAY,
82 MAP = BT_VALUE_TYPE_MAP,
85 template <typename ValueObjT>
86 class CommonValueRawValueProxy final
89 explicit CommonValueRawValueProxy(const ValueObjT obj) : _mObj {obj}
93 CommonValueRawValueProxy& operator=(bool rawVal) noexcept;
94 CommonValueRawValueProxy& operator=(std::int64_t rawVal) noexcept;
95 CommonValueRawValueProxy& operator=(std::uint64_t rawVal) noexcept;
96 CommonValueRawValueProxy& operator=(double rawVal) noexcept;
97 CommonValueRawValueProxy& operator=(const char *rawVal);
98 CommonValueRawValueProxy& operator=(const std::string& rawVal);
99 operator bool() const noexcept;
100 operator std::int64_t() const noexcept;
101 operator std::uint64_t() const noexcept;
102 operator double() const noexcept;
103 operator const char *() const noexcept;
109 template <typename LibObjT>
110 class CommonValue : public BorrowedObject<LibObjT>
113 using typename BorrowedObject<LibObjT>::_ThisBorrowedObject;
116 using typename BorrowedObject<LibObjT>::_LibObjPtr;
117 using _ThisCommonValue = CommonValue<LibObjT>;
120 using Shared = SharedValue<CommonValue<LibObjT>, LibObjT>;
122 explicit CommonValue(const _LibObjPtr libObjPtr) noexcept : _ThisBorrowedObject {libObjPtr}
126 template <typename OtherLibObjT>
127 CommonValue(const CommonValue<OtherLibObjT> val) noexcept : _ThisBorrowedObject {val}
131 template <typename OtherLibObjT>
132 _ThisCommonValue& operator=(const CommonValue<OtherLibObjT> val) noexcept
134 _ThisBorrowedObject::operator=(val);
138 CommonValue<const bt_value> asConst() const noexcept
140 return CommonValue<const bt_value> {*this};
143 ValueType type() const noexcept
145 return static_cast<ValueType>(bt_value_get_type(this->libObjPtr()));
148 bool isNull() const noexcept
150 return this->_libTypeIs(BT_VALUE_TYPE_NULL);
153 bool isBool() const noexcept
155 return this->_libTypeIs(BT_VALUE_TYPE_BOOL);
158 bool isInteger() const noexcept
160 return this->_libTypeIs(BT_VALUE_TYPE_INTEGER);
163 bool isUnsignedInteger() const noexcept
165 return this->_libTypeIs(BT_VALUE_TYPE_UNSIGNED_INTEGER);
168 bool isSignedInteger() const noexcept
170 return this->_libTypeIs(BT_VALUE_TYPE_SIGNED_INTEGER);
173 bool isReal() const noexcept
175 return this->_libTypeIs(BT_VALUE_TYPE_REAL);
178 bool isString() const noexcept
180 return this->_libTypeIs(BT_VALUE_TYPE_STRING);
183 bool isArray() const noexcept
185 return this->_libTypeIs(BT_VALUE_TYPE_ARRAY);
188 bool isMap() const noexcept
190 return this->_libTypeIs(BT_VALUE_TYPE_MAP);
193 template <typename OtherLibObjT>
194 bool operator==(const CommonValue<OtherLibObjT> other) const noexcept
196 return static_cast<bool>(bt_value_is_equal(this->libObjPtr(), other.libObjPtr()));
199 template <typename OtherLibObjT>
200 bool operator!=(const CommonValue<OtherLibObjT> other) const noexcept
202 return !(*this == other);
205 CommonValueRawValueProxy<CommonValue> operator*() const noexcept
207 return CommonValueRawValueProxy<CommonValue> {*this};
210 std::uint64_t arrayLength() const noexcept
212 return this->asArray().length();
215 bool arrayIsEmpty() const noexcept
217 return this->asArray().isEmpty();
220 CommonValue<LibObjT> operator[](const std::uint64_t index) const noexcept
222 return this->asArray()[index];
225 template <typename T>
226 void append(T&& elem) const
228 this->asArray().append(std::forward<T>(elem));
231 CommonArrayValue<bt_value> appendEmptyArray() const;
232 CommonMapValue<bt_value> appendEmptyMap() const;
234 std::uint64_t mapLength() const noexcept
236 return this->asMap().length();
239 bool mapIsEmpty() const noexcept
241 return this->asMap().isEmpty();
244 template <typename KeyT>
245 nonstd::optional<CommonValue<LibObjT>> operator[](KeyT&& key) const noexcept
247 return this->asMap()[std::forward<KeyT>(key)];
250 template <typename KeyT>
251 bool hasEntry(KeyT&& key) const noexcept
253 return this->asMap().hasEntry(std::forward<KeyT>(key));
256 template <typename KeyT, typename ValT>
257 void insert(KeyT&& key, ValT&& val) const
259 this->asMap().insert(std::forward<KeyT>(key), std::forward<ValT>(val));
262 CommonArrayValue<bt_value> insertEmptyArray(const char *key) const;
263 CommonArrayValue<bt_value> insertEmptyArray(const std::string& key) const;
264 CommonMapValue<bt_value> insertEmptyMap(const char *key) const;
265 CommonMapValue<bt_value> insertEmptyMap(const std::string& key) const;
267 Shared shared() const noexcept
269 return Shared::createWithRef(*this);
272 template <typename ValueT>
273 ValueT as() const noexcept
275 return ValueT {this->libObjPtr()};
278 CommonNullValue<LibObjT> asNull() const noexcept;
279 CommonBoolValue<LibObjT> asBool() const noexcept;
280 CommonSignedIntegerValue<LibObjT> asSignedInteger() const noexcept;
281 CommonUnsignedIntegerValue<LibObjT> asUnsignedInteger() const noexcept;
282 CommonRealValue<LibObjT> asReal() const noexcept;
283 CommonStringValue<LibObjT> asString() const noexcept;
284 CommonArrayValue<LibObjT> asArray() const noexcept;
285 CommonMapValue<LibObjT> asMap() const noexcept;
288 bool _libTypeIs(const bt_value_type type) const noexcept
290 return bt_value_type_is(bt_value_get_type(this->libObjPtr()), type);
294 using Value = CommonValue<bt_value>;
295 using ConstValue = CommonValue<const bt_value>;
297 template <typename ValueObjT>
298 CommonValueRawValueProxy<ValueObjT>&
299 CommonValueRawValueProxy<ValueObjT>::operator=(const bool rawVal) noexcept
301 _mObj.asBool().value(rawVal);
305 template <typename ValueObjT>
306 CommonValueRawValueProxy<ValueObjT>&
307 CommonValueRawValueProxy<ValueObjT>::operator=(const std::int64_t rawVal) noexcept
309 _mObj.asSignedInteger().value(rawVal);
313 template <typename ValueObjT>
314 CommonValueRawValueProxy<ValueObjT>&
315 CommonValueRawValueProxy<ValueObjT>::operator=(const std::uint64_t rawVal) noexcept
317 _mObj.asUnsignedInteger().value(rawVal);
321 template <typename ValueObjT>
322 CommonValueRawValueProxy<ValueObjT>&
323 CommonValueRawValueProxy<ValueObjT>::operator=(const double rawVal) noexcept
325 _mObj.asReal().value(rawVal);
329 template <typename ValueObjT>
330 CommonValueRawValueProxy<ValueObjT>&
331 CommonValueRawValueProxy<ValueObjT>::operator=(const char * const rawVal)
333 _mObj.asString().value(rawVal);
337 template <typename ValueObjT>
338 CommonValueRawValueProxy<ValueObjT>&
339 CommonValueRawValueProxy<ValueObjT>::operator=(const std::string& rawVal)
341 return *this = rawVal.data();
344 template <typename ValueObjT>
345 CommonValueRawValueProxy<ValueObjT>::operator bool() const noexcept
347 return _mObj.asBool().value();
350 template <typename ValueObjT>
351 CommonValueRawValueProxy<ValueObjT>::operator std::int64_t() const noexcept
353 return _mObj.asSignedInteger().value();
356 template <typename ValueObjT>
357 CommonValueRawValueProxy<ValueObjT>::operator std::uint64_t() const noexcept
359 return _mObj.asUnsignedInteger().value();
362 template <typename ValueObjT>
363 CommonValueRawValueProxy<ValueObjT>::operator double() const noexcept
365 return _mObj.asReal().value();
368 template <typename ValueObjT>
369 CommonValueRawValueProxy<ValueObjT>::operator const char *() const noexcept
371 return _mObj.asString().value();
376 struct ValueTypeDescr
378 using Const = ConstValue;
379 using NonConst = Value;
383 struct TypeDescr<Value> : public ValueTypeDescr
388 struct TypeDescr<ConstValue> : public ValueTypeDescr
392 } /* namespace internal */
394 template <typename LibObjT>
395 class CommonNullValue final : public CommonValue<LibObjT>
398 using typename CommonValue<LibObjT>::_ThisCommonValue;
401 using Shared = SharedValue<CommonNullValue<LibObjT>, LibObjT>;
403 CommonNullValue() noexcept : _ThisCommonValue {bt_value_null}
407 template <typename OtherLibObjT>
408 CommonNullValue(const CommonNullValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
412 template <typename OtherLibObjT>
413 CommonNullValue<LibObjT>& operator=(const CommonNullValue<OtherLibObjT> val) noexcept
415 _ThisCommonValue::operator=(val);
419 CommonNullValue<const bt_value> asConst() const noexcept
421 return CommonNullValue<const bt_value> {*this};
424 Shared shared() const noexcept
426 return Shared::createWithRef(*this);
430 using NullValue = CommonNullValue<bt_value>;
431 using ConstNullValue = CommonNullValue<const bt_value>;
435 struct NullValueTypeDescr
437 using Const = ConstNullValue;
438 using NonConst = NullValue;
442 struct TypeDescr<NullValue> : public NullValueTypeDescr
447 struct TypeDescr<ConstNullValue> : public NullValueTypeDescr
451 } /* namespace internal */
453 template <typename LibObjT>
454 class CommonBoolValue final : public CommonValue<LibObjT>
457 using typename CommonValue<LibObjT>::_LibObjPtr;
458 using typename CommonValue<LibObjT>::_ThisCommonValue;
461 using Shared = SharedValue<CommonBoolValue<LibObjT>, LibObjT>;
464 explicit CommonBoolValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
466 BT_ASSERT_DBG(this->isBool());
469 template <typename OtherLibObjT>
470 CommonBoolValue(const CommonBoolValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
474 static Shared create(const Value rawVal = false)
476 const auto libObjPtr = bt_value_bool_create_init(static_cast<bt_bool>(rawVal));
478 internal::validateCreatedObjPtr(libObjPtr);
479 return CommonBoolValue::Shared::createWithoutRef(libObjPtr);
482 template <typename OtherLibObjT>
483 CommonBoolValue<LibObjT>& operator=(const CommonBoolValue<OtherLibObjT> val) noexcept
485 _ThisCommonValue::operator=(val);
489 CommonBoolValue<const bt_value> asConst() const noexcept
491 return CommonBoolValue<const bt_value> {*this};
494 RawValueProxy<CommonBoolValue> operator*() const noexcept
496 return RawValueProxy<CommonBoolValue> {*this};
499 Value value() const noexcept
501 return static_cast<Value>(bt_value_bool_get(this->libObjPtr()));
504 void value(const Value val) const noexcept
506 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstBoolValue`.");
508 bt_value_bool_set(this->libObjPtr(), static_cast<bt_bool>(val));
511 Shared shared() const noexcept
513 return Shared::createWithRef(*this);
517 using BoolValue = CommonBoolValue<bt_value>;
518 using ConstBoolValue = CommonBoolValue<const bt_value>;
522 struct BoolValueTypeDescr
524 using Const = ConstBoolValue;
525 using NonConst = BoolValue;
529 struct TypeDescr<BoolValue> : public BoolValueTypeDescr
534 struct TypeDescr<ConstBoolValue> : public BoolValueTypeDescr
538 } /* namespace internal */
540 template <typename LibObjT>
541 class CommonUnsignedIntegerValue final : public CommonValue<LibObjT>
544 using typename CommonValue<LibObjT>::_LibObjPtr;
545 using typename CommonValue<LibObjT>::_ThisCommonValue;
548 using Shared = SharedValue<CommonUnsignedIntegerValue<LibObjT>, LibObjT>;
549 using Value = std::uint64_t;
551 explicit CommonUnsignedIntegerValue(const _LibObjPtr libObjPtr) noexcept :
552 _ThisCommonValue {libObjPtr}
554 BT_ASSERT_DBG(this->isUnsignedInteger());
557 static Shared create(const Value rawVal = 0)
559 const auto libObjPtr = bt_value_integer_unsigned_create_init(rawVal);
561 internal::validateCreatedObjPtr(libObjPtr);
562 return CommonUnsignedIntegerValue::Shared::createWithoutRef(libObjPtr);
565 template <typename OtherLibObjT>
566 CommonUnsignedIntegerValue(const CommonUnsignedIntegerValue<OtherLibObjT> val) noexcept :
567 _ThisCommonValue {val}
571 template <typename OtherLibObjT>
572 CommonUnsignedIntegerValue<LibObjT>&
573 operator=(const CommonUnsignedIntegerValue<OtherLibObjT> val) noexcept
575 _ThisCommonValue::operator=(val);
579 CommonUnsignedIntegerValue<const bt_value> asConst() const noexcept
581 return CommonUnsignedIntegerValue<const bt_value> {*this};
584 RawValueProxy<CommonUnsignedIntegerValue> operator*() const noexcept
586 return RawValueProxy<CommonUnsignedIntegerValue> {*this};
589 void value(const Value val) const noexcept
591 static_assert(!std::is_const<LibObjT>::value,
592 "Not available with `bt2::ConstUnsignedIntegerValue`.");
594 bt_value_integer_unsigned_set(this->libObjPtr(), val);
597 Value value() const noexcept
599 return bt_value_integer_unsigned_get(this->libObjPtr());
602 Shared shared() const noexcept
604 return Shared::createWithRef(*this);
608 using UnsignedIntegerValue = CommonUnsignedIntegerValue<bt_value>;
609 using ConstUnsignedIntegerValue = CommonUnsignedIntegerValue<const bt_value>;
613 struct UnsignedIntegerValueTypeDescr
615 using Const = ConstUnsignedIntegerValue;
616 using NonConst = UnsignedIntegerValue;
620 struct TypeDescr<UnsignedIntegerValue> : public UnsignedIntegerValueTypeDescr
625 struct TypeDescr<ConstUnsignedIntegerValue> : public UnsignedIntegerValueTypeDescr
629 } /* namespace internal */
631 template <typename LibObjT>
632 class CommonSignedIntegerValue final : public CommonValue<LibObjT>
635 using typename CommonValue<LibObjT>::_LibObjPtr;
636 using typename CommonValue<LibObjT>::_ThisCommonValue;
639 using Shared = SharedValue<CommonSignedIntegerValue<LibObjT>, LibObjT>;
640 using Value = std::int64_t;
642 explicit CommonSignedIntegerValue(const _LibObjPtr libObjPtr) noexcept :
643 _ThisCommonValue {libObjPtr}
645 BT_ASSERT_DBG(this->isSignedInteger());
648 static Shared create(const Value rawVal = 0)
650 const auto libObjPtr = bt_value_integer_signed_create_init(rawVal);
652 internal::validateCreatedObjPtr(libObjPtr);
653 return CommonSignedIntegerValue::Shared::createWithoutRef(libObjPtr);
656 template <typename OtherLibObjT>
657 CommonSignedIntegerValue(const CommonSignedIntegerValue<OtherLibObjT> val) noexcept :
658 _ThisCommonValue {val}
662 template <typename OtherLibObjT>
663 CommonSignedIntegerValue<LibObjT>
664 operator=(const CommonSignedIntegerValue<OtherLibObjT> val) noexcept
666 _ThisCommonValue::operator=(val);
670 CommonSignedIntegerValue<const bt_value> asConst() const noexcept
672 return CommonSignedIntegerValue<const bt_value> {*this};
675 RawValueProxy<CommonSignedIntegerValue> operator*() const noexcept
677 return RawValueProxy<CommonSignedIntegerValue> {*this};
680 void value(const Value val) const noexcept
682 static_assert(!std::is_const<LibObjT>::value,
683 "Not available with `bt2::ConstSignedIntegerValue`.");
685 bt_value_integer_signed_set(this->libObjPtr(), val);
688 Value value() const noexcept
690 return bt_value_integer_signed_get(this->libObjPtr());
693 Shared shared() const noexcept
695 return Shared::createWithRef(*this);
699 using SignedIntegerValue = CommonSignedIntegerValue<bt_value>;
700 using ConstSignedIntegerValue = CommonSignedIntegerValue<const bt_value>;
704 struct SignedIntegerValueTypeDescr
706 using Const = ConstSignedIntegerValue;
707 using NonConst = SignedIntegerValue;
711 struct TypeDescr<SignedIntegerValue> : public SignedIntegerValueTypeDescr
716 struct TypeDescr<ConstSignedIntegerValue> : public SignedIntegerValueTypeDescr
720 } /* namespace internal */
722 template <typename LibObjT>
723 class CommonRealValue final : public CommonValue<LibObjT>
726 using typename CommonValue<LibObjT>::_LibObjPtr;
727 using typename CommonValue<LibObjT>::_ThisCommonValue;
730 using Shared = SharedValue<CommonRealValue<LibObjT>, LibObjT>;
731 using Value = double;
733 explicit CommonRealValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
735 BT_ASSERT_DBG(this->isReal());
738 static Shared create(const Value rawVal = 0)
740 const auto libObjPtr = bt_value_real_create_init(rawVal);
742 internal::validateCreatedObjPtr(libObjPtr);
743 return CommonRealValue::Shared::createWithoutRef(libObjPtr);
746 template <typename OtherLibObjT>
747 CommonRealValue(const CommonRealValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
751 template <typename OtherLibObjT>
752 CommonRealValue<LibObjT>& operator=(const CommonRealValue<OtherLibObjT> val) noexcept
754 _ThisCommonValue::operator=(val);
758 CommonRealValue<const bt_value> asConst() const noexcept
760 return CommonRealValue<const bt_value> {*this};
763 RawValueProxy<CommonRealValue> operator*() const noexcept
765 return RawValueProxy<CommonRealValue> {*this};
768 void value(const Value val) const noexcept
770 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstRealValue`.");
772 bt_value_real_set(this->libObjPtr(), val);
775 Value value() const noexcept
777 return bt_value_real_get(this->libObjPtr());
780 Shared shared() const noexcept
782 return Shared::createWithRef(*this);
786 using RealValue = CommonRealValue<bt_value>;
787 using ConstRealValue = CommonRealValue<const bt_value>;
791 struct RealValueTypeDescr
793 using Const = ConstRealValue;
794 using NonConst = RealValue;
798 struct TypeDescr<RealValue> : public RealValueTypeDescr
803 struct TypeDescr<ConstRealValue> : public RealValueTypeDescr
807 } /* namespace internal */
809 template <typename LibObjT>
810 class CommonStringValue final : public CommonValue<LibObjT>
813 using typename CommonValue<LibObjT>::_LibObjPtr;
814 using typename CommonValue<LibObjT>::_ThisCommonValue;
817 using Shared = SharedValue<CommonStringValue<LibObjT>, LibObjT>;
818 using Value = const char *;
820 explicit CommonStringValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
822 BT_ASSERT_DBG(this->isString());
825 static Shared create(const char * const rawVal = "")
827 const auto libObjPtr = bt_value_string_create_init(rawVal);
829 internal::validateCreatedObjPtr(libObjPtr);
830 return CommonStringValue::Shared::createWithoutRef(libObjPtr);
833 static Shared create(const std::string& rawVal)
835 return CommonStringValue::create(rawVal.data());
838 template <typename OtherLibObjT>
839 CommonStringValue(const CommonStringValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
843 template <typename OtherLibObjT>
844 CommonStringValue<LibObjT>& operator=(const CommonStringValue<OtherLibObjT> val) noexcept
846 _ThisCommonValue::operator=(val);
850 CommonStringValue<const bt_value> asConst() const noexcept
852 return CommonStringValue<const bt_value> {*this};
855 RawStringValueProxy<CommonStringValue> operator*() const noexcept
857 return RawStringValueProxy<CommonStringValue> {*this};
860 void value(const Value val) const
862 static_assert(!std::is_const<LibObjT>::value,
863 "Not available with `bt2::ConstStringValue`.");
865 const auto status = bt_value_string_set(this->libObjPtr(), val);
867 if (status == BT_VALUE_STRING_SET_STATUS_MEMORY_ERROR) {
868 throw MemoryError {};
872 void value(const std::string& val) const
874 this->value(val.data());
877 const char *value() const noexcept
879 return bt_value_string_get(this->libObjPtr());
882 Shared shared() const noexcept
884 return Shared::createWithRef(*this);
888 using StringValue = CommonStringValue<bt_value>;
889 using ConstStringValue = CommonStringValue<const bt_value>;
893 struct StringValueTypeDescr
895 using Const = ConstStringValue;
896 using NonConst = StringValue;
900 struct TypeDescr<StringValue> : public StringValueTypeDescr
905 struct TypeDescr<ConstStringValue> : public StringValueTypeDescr
909 template <typename LibObjT>
910 struct CommonArrayValueSpec;
912 /* Functions specific to mutable array values */
914 struct CommonArrayValueSpec<bt_value> final
916 static bt_value *elementByIndex(bt_value * const libValPtr, const std::uint64_t index) noexcept
918 return bt_value_array_borrow_element_by_index(libValPtr, index);
922 /* Functions specific to constant array values */
924 struct CommonArrayValueSpec<const bt_value> final
926 static const bt_value *elementByIndex(const bt_value * const libValPtr,
927 const std::uint64_t index) noexcept
929 return bt_value_array_borrow_element_by_index_const(libValPtr, index);
933 } /* namespace internal */
935 template <typename LibObjT>
936 class CommonArrayValue final : public CommonValue<LibObjT>
939 using typename CommonValue<LibObjT>::_LibObjPtr;
940 using typename CommonValue<LibObjT>::_ThisCommonValue;
943 using Shared = SharedValue<CommonArrayValue<LibObjT>, LibObjT>;
944 using Iterator = BorrowedObjectIterator<CommonArrayValue<LibObjT>>;
946 explicit CommonArrayValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
948 BT_ASSERT_DBG(this->isArray());
951 static Shared create()
953 const auto libObjPtr = bt_value_array_create();
955 internal::validateCreatedObjPtr(libObjPtr);
956 return CommonArrayValue::Shared::createWithoutRef(libObjPtr);
959 template <typename OtherLibObjT>
960 CommonArrayValue(const CommonArrayValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
964 template <typename OtherLibObjT>
965 CommonArrayValue<LibObjT>& operator=(const CommonArrayValue<OtherLibObjT> val) noexcept
967 _ThisCommonValue::operator=(val);
971 CommonArrayValue<const bt_value> asConst() const noexcept
973 return CommonArrayValue<const bt_value> {*this};
976 std::uint64_t length() const noexcept
978 return bt_value_array_get_length(this->libObjPtr());
981 Iterator begin() const noexcept
983 return Iterator {*this, 0};
986 Iterator end() const noexcept
988 return Iterator {*this, this->length()};
991 bool isEmpty() const noexcept
993 return this->length() == 0;
996 CommonValue<LibObjT> operator[](const std::uint64_t index) const noexcept
998 return CommonValue<LibObjT> {
999 internal::CommonArrayValueSpec<LibObjT>::elementByIndex(this->libObjPtr(), index)};
1002 void append(const Value val) const
1004 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
1006 const auto status = bt_value_array_append_element(this->libObjPtr(), val.libObjPtr());
1008 this->_handleAppendLibStatus(status);
1011 void append(const bool rawVal) const
1013 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
1016 bt_value_array_append_bool_element(this->libObjPtr(), static_cast<bt_bool>(rawVal));
1018 this->_handleAppendLibStatus(status);
1021 void append(const std::uint64_t rawVal) const
1023 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
1026 bt_value_array_append_unsigned_integer_element(this->libObjPtr(), rawVal);
1028 this->_handleAppendLibStatus(status);
1031 void append(const std::int64_t rawVal) const
1033 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
1035 const auto status = bt_value_array_append_signed_integer_element(this->libObjPtr(), rawVal);
1037 this->_handleAppendLibStatus(status);
1040 void append(const double rawVal) const
1042 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
1044 const auto status = bt_value_array_append_real_element(this->libObjPtr(), rawVal);
1046 this->_handleAppendLibStatus(status);
1049 void append(const char * const rawVal) const
1051 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
1053 const auto status = bt_value_array_append_string_element(this->libObjPtr(), rawVal);
1055 this->_handleAppendLibStatus(status);
1058 void append(const std::string& rawVal) const
1060 this->append(rawVal.data());
1063 CommonArrayValue<bt_value> appendEmptyArray() const;
1064 CommonMapValue<bt_value> appendEmptyMap() const;
1066 void operator+=(const Value val) const
1071 void operator+=(const bool rawVal) const
1073 this->append(rawVal);
1076 void operator+=(const std::uint64_t rawVal) const
1078 this->append(rawVal);
1081 void operator+=(const std::int64_t rawVal) const
1083 this->append(rawVal);
1086 void operator+=(const double rawVal) const
1088 this->append(rawVal);
1091 void operator+=(const char * const rawVal) const
1093 this->append(rawVal);
1096 void operator+=(const std::string& rawVal) const
1098 this->append(rawVal);
1101 Shared shared() const noexcept
1103 return Shared::createWithRef(*this);
1107 void _handleAppendLibStatus(const bt_value_array_append_element_status status) const
1109 if (status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_MEMORY_ERROR) {
1110 throw MemoryError {};
1115 using ArrayValue = CommonArrayValue<bt_value>;
1116 using ConstArrayValue = CommonArrayValue<const bt_value>;
1118 namespace internal {
1120 struct ArrayValueTypeDescr
1122 using Const = ConstArrayValue;
1123 using NonConst = ArrayValue;
1127 struct TypeDescr<ArrayValue> : public ArrayValueTypeDescr
1132 struct TypeDescr<ConstArrayValue> : public ArrayValueTypeDescr
1137 * Type of a user function passed to `CommonMapValue<ObjT>::forEach()`.
1139 * First argument is the entry's key, second is its value.
1141 template <typename ObjT>
1142 using CommonMapValueForEachUserFunc = std::function<void(const bpstd::string_view&, ObjT)>;
1145 * Template of a function to be passed to bt_value_map_foreach_entry()
1146 * for bt_value_map_foreach_entry_const() which calls a user function.
1148 * `userData` is casted to a `const` pointer to
1149 * `CommonMapValueForEachUserFunc<ObjT>` (the user function to call).
1151 * This function catches any exception which the user function throws
1152 * and returns the `ErrorStatus` value. If there's no execption, this
1153 * function returns the `OkStatus` value.
1155 template <typename ObjT, typename LibObjT, typename LibStatusT, int OkStatus, int ErrorStatus>
1156 LibStatusT mapValueForEachLibFunc(const char * const key, LibObjT * const libObjPtr,
1157 void * const userData)
1159 const auto& userFunc = *reinterpret_cast<const CommonMapValueForEachUserFunc<ObjT> *>(userData);
1162 userFunc(key, ObjT {libObjPtr});
1164 return static_cast<LibStatusT>(ErrorStatus);
1167 return static_cast<LibStatusT>(OkStatus);
1170 template <typename LibObjT>
1171 struct CommonMapValueSpec;
1173 /* Functions specific to mutable map values */
1175 struct CommonMapValueSpec<bt_value> final
1177 static bt_value *entryByKey(bt_value * const libValPtr, const char * const key) noexcept
1179 return bt_value_map_borrow_entry_value(libValPtr, key);
1182 static void forEach(bt_value * const libValPtr,
1183 const CommonMapValueForEachUserFunc<Value>& func)
1185 const auto status = bt_value_map_foreach_entry(
1187 mapValueForEachLibFunc<Value, bt_value, bt_value_map_foreach_entry_func_status,
1188 BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_OK,
1189 BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_ERROR>,
1190 const_cast<void *>(reinterpret_cast<const void *>(&func)));
1193 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_OK:
1195 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_USER_ERROR:
1196 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_ERROR:
1204 /* Functions specific to constant map values */
1206 struct CommonMapValueSpec<const bt_value> final
1208 static const bt_value *entryByKey(const bt_value * const libValPtr,
1209 const char * const key) noexcept
1211 return bt_value_map_borrow_entry_value_const(libValPtr, key);
1214 static void forEach(const bt_value * const libValPtr,
1215 const CommonMapValueForEachUserFunc<ConstValue>& func)
1217 const auto status = bt_value_map_foreach_entry_const(
1219 mapValueForEachLibFunc<ConstValue, const bt_value,
1220 bt_value_map_foreach_entry_const_func_status,
1221 BT_VALUE_MAP_FOREACH_ENTRY_CONST_FUNC_STATUS_OK,
1222 BT_VALUE_MAP_FOREACH_ENTRY_CONST_FUNC_STATUS_ERROR>,
1223 const_cast<void *>(reinterpret_cast<const void *>(&func)));
1226 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_OK:
1228 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_USER_ERROR:
1229 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_ERROR:
1237 } /* namespace internal */
1239 template <typename LibObjT>
1240 class CommonMapValue final : public CommonValue<LibObjT>
1243 using typename CommonValue<LibObjT>::_LibObjPtr;
1244 using typename CommonValue<LibObjT>::_ThisCommonValue;
1247 using Shared = SharedValue<CommonMapValue<LibObjT>, LibObjT>;
1249 explicit CommonMapValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
1251 BT_ASSERT_DBG(this->isMap());
1254 static Shared create()
1256 const auto libObjPtr = bt_value_map_create();
1258 internal::validateCreatedObjPtr(libObjPtr);
1259 return CommonMapValue::Shared::createWithoutRef(libObjPtr);
1262 template <typename OtherLibObjT>
1263 CommonMapValue(const CommonMapValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
1267 template <typename OtherLibObjT>
1268 CommonMapValue<LibObjT>& operator=(const CommonMapValue<OtherLibObjT> val) noexcept
1270 _ThisCommonValue::operator=(val);
1274 CommonMapValue<const bt_value> asConst() const noexcept
1276 return CommonMapValue<const bt_value> {*this};
1279 std::uint64_t length() const noexcept
1281 return bt_value_map_get_size(this->libObjPtr());
1284 bool isEmpty() const noexcept
1286 return this->length() == 0;
1289 nonstd::optional<CommonValue<LibObjT>> operator[](const char * const key) const noexcept
1291 const auto libObjPtr =
1292 internal::CommonMapValueSpec<LibObjT>::entryByKey(this->libObjPtr(), key);
1295 return nonstd::nullopt;
1298 return CommonValue<LibObjT> {libObjPtr};
1301 nonstd::optional<CommonValue<LibObjT>> operator[](const std::string& key) const noexcept
1303 return (*this)[key.data()];
1306 bool hasEntry(const char * const key) const noexcept
1308 return static_cast<bool>(bt_value_map_has_entry(this->libObjPtr(), key));
1311 bool hasEntry(const std::string& key) const noexcept
1313 return this->hasEntry(key.data());
1316 void insert(const char * const key, const Value val) const
1318 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1320 const auto status = bt_value_map_insert_entry(this->libObjPtr(), key, val.libObjPtr());
1322 this->_handleInsertLibStatus(status);
1325 void insert(const std::string& key, const Value val) const
1327 this->insert(key.data(), val);
1330 void insert(const char * const key, const bool rawVal) const
1332 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1335 bt_value_map_insert_bool_entry(this->libObjPtr(), key, static_cast<bt_bool>(rawVal));
1337 this->_handleInsertLibStatus(status);
1340 void insert(const std::string& key, const bool rawVal) const
1342 this->insert(key.data(), rawVal);
1345 void insert(const char * const key, const std::uint64_t rawVal) const
1347 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1350 bt_value_map_insert_unsigned_integer_entry(this->libObjPtr(), key, rawVal);
1352 this->_handleInsertLibStatus(status);
1355 void insert(const std::string& key, const std::uint64_t rawVal) const
1357 this->insert(key.data(), rawVal);
1360 void insert(const char * const key, const std::int64_t rawVal) const
1362 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1365 bt_value_map_insert_signed_integer_entry(this->libObjPtr(), key, rawVal);
1367 this->_handleInsertLibStatus(status);
1370 void insert(const std::string& key, const std::int64_t rawVal) const
1372 this->insert(key.data(), rawVal);
1375 void insert(const char * const key, const double rawVal) const
1377 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1379 const auto status = bt_value_map_insert_real_entry(this->libObjPtr(), key, rawVal);
1381 this->_handleInsertLibStatus(status);
1384 void insert(const std::string& key, const double rawVal) const
1386 this->insert(key.data(), rawVal);
1389 void insert(const char * const key, const char * const rawVal) const
1391 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1393 const auto status = bt_value_map_insert_string_entry(this->libObjPtr(), key, rawVal);
1395 this->_handleInsertLibStatus(status);
1398 void insert(const char * const key, const std::string& rawVal) const
1400 this->insert(key, rawVal.data());
1403 void insert(const std::string& key, const char * const rawVal) const
1405 this->insert(key.data(), rawVal);
1408 void insert(const std::string& key, const std::string& rawVal) const
1410 this->insert(key.data(), rawVal.data());
1413 CommonArrayValue<bt_value> insertEmptyArray(const char *key) const;
1414 CommonArrayValue<bt_value> insertEmptyArray(const std::string& key) const;
1415 CommonMapValue<bt_value> insertEmptyMap(const char *key) const;
1416 CommonMapValue<bt_value> insertEmptyMap(const std::string& key) const;
1418 void forEach(const internal::CommonMapValueForEachUserFunc<CommonValue<LibObjT>>& func) const
1420 internal::CommonMapValueSpec<LibObjT>::forEach(this->libObjPtr(), func);
1423 Shared shared() const noexcept
1425 return Shared::createWithRef(*this);
1429 void _handleInsertLibStatus(const bt_value_map_insert_entry_status status) const
1431 if (status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_MEMORY_ERROR) {
1432 throw MemoryError {};
1437 using MapValue = CommonMapValue<bt_value>;
1438 using ConstMapValue = CommonMapValue<const bt_value>;
1440 namespace internal {
1442 struct MapValueTypeDescr
1444 using Const = ConstMapValue;
1445 using NonConst = MapValue;
1449 struct TypeDescr<MapValue> : public MapValueTypeDescr
1454 struct TypeDescr<ConstMapValue> : public MapValueTypeDescr
1458 } /* namespace internal */
1460 template <typename LibObjT>
1461 ArrayValue CommonValue<LibObjT>::appendEmptyArray() const
1463 return this->asArray().appendEmptyArray();
1466 template <typename LibObjT>
1467 MapValue CommonValue<LibObjT>::appendEmptyMap() const
1469 return this->asArray().appendEmptyMap();
1472 template <typename LibObjT>
1473 ArrayValue CommonValue<LibObjT>::insertEmptyArray(const char * const key) const
1475 return this->asMap().insertEmptyArray(key);
1478 template <typename LibObjT>
1479 ArrayValue CommonValue<LibObjT>::insertEmptyArray(const std::string& key) const
1481 return this->asMap().insertEmptyArray(key);
1484 template <typename LibObjT>
1485 MapValue CommonValue<LibObjT>::insertEmptyMap(const char * const key) const
1487 return this->asMap().insertEmptyMap(key);
1490 template <typename LibObjT>
1491 MapValue CommonValue<LibObjT>::insertEmptyMap(const std::string& key) const
1493 return this->asMap().insertEmptyMap(key);
1496 template <typename LibObjT>
1497 CommonNullValue<LibObjT> CommonValue<LibObjT>::asNull() const noexcept
1499 BT_ASSERT_DBG(this->isNull());
1500 return CommonNullValue<LibObjT> {this->libObjPtr()};
1503 template <typename LibObjT>
1504 CommonBoolValue<LibObjT> CommonValue<LibObjT>::asBool() const noexcept
1506 BT_ASSERT_DBG(this->isBool());
1507 return CommonBoolValue<LibObjT> {this->libObjPtr()};
1510 template <typename LibObjT>
1511 CommonSignedIntegerValue<LibObjT> CommonValue<LibObjT>::asSignedInteger() const noexcept
1513 BT_ASSERT_DBG(this->isSignedInteger());
1514 return CommonSignedIntegerValue<LibObjT> {this->libObjPtr()};
1517 template <typename LibObjT>
1518 CommonUnsignedIntegerValue<LibObjT> CommonValue<LibObjT>::asUnsignedInteger() const noexcept
1520 BT_ASSERT_DBG(this->isUnsignedInteger());
1521 return CommonUnsignedIntegerValue<LibObjT> {this->libObjPtr()};
1524 template <typename LibObjT>
1525 CommonRealValue<LibObjT> CommonValue<LibObjT>::asReal() const noexcept
1527 BT_ASSERT_DBG(this->isReal());
1528 return CommonRealValue<LibObjT> {this->libObjPtr()};
1531 template <typename LibObjT>
1532 CommonStringValue<LibObjT> CommonValue<LibObjT>::asString() const noexcept
1534 BT_ASSERT_DBG(this->isString());
1535 return CommonStringValue<LibObjT> {this->libObjPtr()};
1538 template <typename LibObjT>
1539 CommonArrayValue<LibObjT> CommonValue<LibObjT>::asArray() const noexcept
1541 BT_ASSERT_DBG(this->isArray());
1542 return CommonArrayValue<LibObjT> {this->libObjPtr()};
1545 template <typename LibObjT>
1546 CommonMapValue<LibObjT> CommonValue<LibObjT>::asMap() const noexcept
1548 BT_ASSERT_DBG(this->isMap());
1549 return CommonMapValue<LibObjT> {this->libObjPtr()};
1552 template <typename LibObjT>
1553 ArrayValue CommonArrayValue<LibObjT>::appendEmptyArray() const
1555 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
1557 bt_value *libElemPtr;
1558 const auto status = bt_value_array_append_empty_array_element(this->libObjPtr(), &libElemPtr);
1560 this->_handleAppendLibStatus(status);
1561 return ArrayValue {libElemPtr};
1564 template <typename LibObjT>
1565 MapValue CommonArrayValue<LibObjT>::appendEmptyMap() const
1567 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
1569 bt_value *libElemPtr;
1570 const auto status = bt_value_array_append_empty_map_element(this->libObjPtr(), &libElemPtr);
1572 this->_handleAppendLibStatus(status);
1573 return MapValue {libElemPtr};
1576 template <typename LibObjT>
1577 ArrayValue CommonMapValue<LibObjT>::insertEmptyArray(const char * const key) const
1579 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1581 bt_value *libEntryPtr;
1582 const auto status = bt_value_map_insert_empty_array_entry(this->libObjPtr(), key, &libEntryPtr);
1584 this->_handleInsertLibStatus(status);
1585 return ArrayValue {libEntryPtr};
1588 template <typename LibObjT>
1589 ArrayValue CommonMapValue<LibObjT>::insertEmptyArray(const std::string& key) const
1591 return this->insertEmptyArray(key.data());
1594 template <typename LibObjT>
1595 MapValue CommonMapValue<LibObjT>::insertEmptyMap(const char * const key) const
1597 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1599 bt_value *libEntryPtr;
1600 const auto status = bt_value_map_insert_empty_map_entry(this->libObjPtr(), key, &libEntryPtr);
1602 this->_handleInsertLibStatus(status);
1603 return MapValue {libEntryPtr};
1606 template <typename LibObjT>
1607 MapValue CommonMapValue<LibObjT>::insertEmptyMap(const std::string& key) const
1609 return this->insertEmptyMap(key.data());
1612 inline BoolValue::Shared createValue(const bool rawVal)
1614 return BoolValue::create(rawVal);
1617 inline UnsignedIntegerValue::Shared createValue(const std::uint64_t rawVal)
1619 return UnsignedIntegerValue::create(rawVal);
1622 inline SignedIntegerValue::Shared createValue(const std::int64_t rawVal)
1624 return SignedIntegerValue::create(rawVal);
1627 inline RealValue::Shared createValue(const double rawVal)
1629 return RealValue::create(rawVal);
1632 inline StringValue::Shared createValue(const char * const rawVal)
1634 return StringValue::create(rawVal);
1637 inline StringValue::Shared createValue(const std::string& rawVal)
1639 return StringValue::create(rawVal);
1642 } /* namespace bt2 */
1644 #endif /* BABELTRACE_CPP_COMMON_BT2_VALUE_HPP */