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/bt2c/c-string-view.hpp"
19 #include "cpp-common/vendor/wise-enum/wise_enum.h"
21 #include "borrowed-object-iterator.hpp"
22 #include "borrowed-object.hpp"
24 #include "internal/utils.hpp"
25 #include "optional-borrowed-object.hpp"
26 #include "raw-value-proxy.hpp"
27 #include "shared-object.hpp"
32 struct ValueRefFuncs final
34 static void get(const bt_value * const libObjPtr) noexcept
36 bt_value_get_ref(libObjPtr);
39 static void put(const bt_value * const libObjPtr) noexcept
41 bt_value_put_ref(libObjPtr);
45 } /* namespace internal */
47 template <typename ObjT, typename LibObjT>
48 using SharedValue = SharedObject<ObjT, LibObjT, internal::ValueRefFuncs>;
50 template <typename LibObjT>
51 class CommonNullValue;
53 template <typename LibObjT>
54 class CommonBoolValue;
56 template <typename LibObjT>
57 class CommonUnsignedIntegerValue;
59 template <typename LibObjT>
60 class CommonSignedIntegerValue;
62 template <typename LibObjT>
63 class CommonRealValue;
65 template <typename LibObjT>
66 class CommonStringValue;
68 template <typename LibObjT>
69 class CommonArrayValue;
71 template <typename LibObjT>
74 /* clang-format off */
76 WISE_ENUM_CLASS(ValueType,
77 (Null, BT_VALUE_TYPE_NULL),
78 (Bool, BT_VALUE_TYPE_BOOL),
79 (UnsignedInteger, BT_VALUE_TYPE_UNSIGNED_INTEGER),
80 (SignedInteger, BT_VALUE_TYPE_SIGNED_INTEGER),
81 (Real, BT_VALUE_TYPE_REAL),
82 (String, BT_VALUE_TYPE_STRING),
83 (Array, BT_VALUE_TYPE_ARRAY),
84 (Map, BT_VALUE_TYPE_MAP));
88 template <typename ValueObjT>
89 class CommonValueRawValueProxy final
92 explicit CommonValueRawValueProxy(const ValueObjT obj) : _mObj {obj}
96 CommonValueRawValueProxy& operator=(bool rawVal) noexcept;
97 CommonValueRawValueProxy& operator=(std::int64_t rawVal) noexcept;
98 CommonValueRawValueProxy& operator=(std::uint64_t rawVal) noexcept;
99 CommonValueRawValueProxy& operator=(double rawVal) noexcept;
100 CommonValueRawValueProxy& operator=(const char *rawVal);
101 CommonValueRawValueProxy& operator=(bt2c::CStringView rawVal);
102 operator bool() const noexcept;
103 operator std::int64_t() const noexcept;
104 operator std::uint64_t() const noexcept;
105 operator double() const noexcept;
106 operator bt2c::CStringView() const noexcept;
112 template <typename LibObjT>
113 class CommonValue : public BorrowedObject<LibObjT>
116 using typename BorrowedObject<LibObjT>::_ThisBorrowedObject;
119 using _ThisCommonValue = CommonValue<LibObjT>;
122 using typename BorrowedObject<LibObjT>::LibObjPtr;
123 using Shared = SharedValue<CommonValue<LibObjT>, LibObjT>;
125 explicit CommonValue(const LibObjPtr libObjPtr) noexcept : _ThisBorrowedObject {libObjPtr}
129 template <typename OtherLibObjT>
130 CommonValue(const CommonValue<OtherLibObjT> val) noexcept : _ThisBorrowedObject {val}
134 template <typename OtherLibObjT>
135 _ThisCommonValue operator=(const CommonValue<OtherLibObjT> val) noexcept
137 _ThisBorrowedObject::operator=(val);
141 CommonValue<const bt_value> asConst() const noexcept
143 return CommonValue<const bt_value> {*this};
146 ValueType type() const noexcept
148 return static_cast<ValueType>(bt_value_get_type(this->libObjPtr()));
151 bool isNull() const noexcept
153 return this->_libTypeIs(BT_VALUE_TYPE_NULL);
156 bool isBool() const noexcept
158 return this->_libTypeIs(BT_VALUE_TYPE_BOOL);
161 bool isInteger() const noexcept
163 return this->_libTypeIs(BT_VALUE_TYPE_INTEGER);
166 bool isUnsignedInteger() const noexcept
168 return this->_libTypeIs(BT_VALUE_TYPE_UNSIGNED_INTEGER);
171 bool isSignedInteger() const noexcept
173 return this->_libTypeIs(BT_VALUE_TYPE_SIGNED_INTEGER);
176 bool isReal() const noexcept
178 return this->_libTypeIs(BT_VALUE_TYPE_REAL);
181 bool isString() const noexcept
183 return this->_libTypeIs(BT_VALUE_TYPE_STRING);
186 bool isArray() const noexcept
188 return this->_libTypeIs(BT_VALUE_TYPE_ARRAY);
191 bool isMap() const noexcept
193 return this->_libTypeIs(BT_VALUE_TYPE_MAP);
196 template <typename OtherLibObjT>
197 bool operator==(const CommonValue<OtherLibObjT> other) const noexcept
199 return static_cast<bool>(bt_value_is_equal(this->libObjPtr(), other.libObjPtr()));
202 template <typename OtherLibObjT>
203 bool operator!=(const CommonValue<OtherLibObjT> other) const noexcept
205 return !(*this == other);
208 CommonValueRawValueProxy<CommonValue> operator*() const noexcept
210 return CommonValueRawValueProxy<CommonValue> {*this};
213 std::uint64_t arrayLength() const noexcept
215 return this->asArray().length();
218 bool arrayIsEmpty() const noexcept
220 return this->asArray().isEmpty();
223 CommonValue<LibObjT> operator[](const std::uint64_t index) const noexcept
225 return this->asArray()[index];
228 template <typename T>
229 void append(T&& elem) const
231 this->asArray().append(std::forward<T>(elem));
234 CommonArrayValue<bt_value> appendEmptyArray() const;
235 CommonMapValue<bt_value> appendEmptyMap() const;
237 std::uint64_t mapLength() const noexcept
239 return this->asMap().length();
242 bool mapIsEmpty() const noexcept
244 return this->asMap().isEmpty();
247 template <typename KeyT>
248 OptionalBorrowedObject<CommonValue<LibObjT>> operator[](KeyT&& key) const noexcept
250 return this->asMap()[std::forward<KeyT>(key)];
253 template <typename KeyT>
254 bool hasEntry(KeyT&& key) const noexcept
256 return this->asMap().hasEntry(std::forward<KeyT>(key));
259 template <typename KeyT, typename ValT>
260 void insert(KeyT&& key, ValT&& val) const
262 this->asMap().insert(std::forward<KeyT>(key), std::forward<ValT>(val));
265 CommonArrayValue<bt_value> insertEmptyArray(bt2c::CStringView key) const;
266 CommonMapValue<bt_value> insertEmptyMap(bt2c::CStringView key) const;
268 Shared shared() const noexcept
270 return Shared::createWithRef(*this);
273 template <typename ValueT>
274 ValueT as() const noexcept
276 return ValueT {this->libObjPtr()};
279 CommonNullValue<LibObjT> asNull() const noexcept;
280 CommonBoolValue<LibObjT> asBool() const noexcept;
281 CommonSignedIntegerValue<LibObjT> asSignedInteger() const noexcept;
282 CommonUnsignedIntegerValue<LibObjT> asUnsignedInteger() const noexcept;
283 CommonRealValue<LibObjT> asReal() const noexcept;
284 CommonStringValue<LibObjT> asString() const noexcept;
285 CommonArrayValue<LibObjT> asArray() const noexcept;
286 CommonMapValue<LibObjT> asMap() const noexcept;
289 bool _libTypeIs(const bt_value_type type) const noexcept
291 return bt_value_type_is(bt_value_get_type(this->libObjPtr()), type);
295 using Value = CommonValue<bt_value>;
296 using ConstValue = CommonValue<const bt_value>;
298 template <typename ValueObjT>
299 CommonValueRawValueProxy<ValueObjT>&
300 CommonValueRawValueProxy<ValueObjT>::operator=(const bool rawVal) noexcept
302 _mObj.asBool().value(rawVal);
306 template <typename ValueObjT>
307 CommonValueRawValueProxy<ValueObjT>&
308 CommonValueRawValueProxy<ValueObjT>::operator=(const std::int64_t rawVal) noexcept
310 _mObj.asSignedInteger().value(rawVal);
314 template <typename ValueObjT>
315 CommonValueRawValueProxy<ValueObjT>&
316 CommonValueRawValueProxy<ValueObjT>::operator=(const std::uint64_t rawVal) noexcept
318 _mObj.asUnsignedInteger().value(rawVal);
322 template <typename ValueObjT>
323 CommonValueRawValueProxy<ValueObjT>&
324 CommonValueRawValueProxy<ValueObjT>::operator=(const double rawVal) noexcept
326 _mObj.asReal().value(rawVal);
330 template <typename ValueObjT>
331 CommonValueRawValueProxy<ValueObjT>&
332 CommonValueRawValueProxy<ValueObjT>::operator=(const char * const rawVal)
334 _mObj.asString().value(rawVal);
338 template <typename ValueObjT>
339 CommonValueRawValueProxy<ValueObjT>&
340 CommonValueRawValueProxy<ValueObjT>::operator=(const bt2c::CStringView rawVal)
342 _mObj.asString().value(rawVal);
346 template <typename ValueObjT>
347 CommonValueRawValueProxy<ValueObjT>::operator bool() const noexcept
349 return _mObj.asBool().value();
352 template <typename ValueObjT>
353 CommonValueRawValueProxy<ValueObjT>::operator std::int64_t() const noexcept
355 return _mObj.asSignedInteger().value();
358 template <typename ValueObjT>
359 CommonValueRawValueProxy<ValueObjT>::operator std::uint64_t() const noexcept
361 return _mObj.asUnsignedInteger().value();
364 template <typename ValueObjT>
365 CommonValueRawValueProxy<ValueObjT>::operator double() const noexcept
367 return _mObj.asReal().value();
370 template <typename ValueObjT>
371 CommonValueRawValueProxy<ValueObjT>::operator bt2c::CStringView() const noexcept
373 return _mObj.asString().value();
378 struct ValueTypeDescr
380 using Const = ConstValue;
381 using NonConst = Value;
385 struct TypeDescr<Value> : public ValueTypeDescr
390 struct TypeDescr<ConstValue> : public ValueTypeDescr
394 } /* namespace internal */
396 template <typename LibObjT>
397 class CommonNullValue final : public CommonValue<LibObjT>
400 using typename CommonValue<LibObjT>::_ThisCommonValue;
403 using Shared = SharedValue<CommonNullValue<LibObjT>, LibObjT>;
405 CommonNullValue() noexcept : _ThisCommonValue {bt_value_null}
409 template <typename OtherLibObjT>
410 CommonNullValue(const CommonNullValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
414 template <typename OtherLibObjT>
415 CommonNullValue<LibObjT> operator=(const CommonNullValue<OtherLibObjT> val) noexcept
417 _ThisCommonValue::operator=(val);
421 CommonNullValue<const bt_value> asConst() const noexcept
423 return CommonNullValue<const bt_value> {*this};
426 Shared shared() const noexcept
428 return Shared::createWithRef(*this);
432 using NullValue = CommonNullValue<bt_value>;
433 using ConstNullValue = CommonNullValue<const bt_value>;
437 struct NullValueTypeDescr
439 using Const = ConstNullValue;
440 using NonConst = NullValue;
444 struct TypeDescr<NullValue> : public NullValueTypeDescr
449 struct TypeDescr<ConstNullValue> : public NullValueTypeDescr
453 } /* namespace internal */
455 template <typename LibObjT>
456 class CommonBoolValue final : public CommonValue<LibObjT>
459 using typename CommonValue<LibObjT>::_ThisCommonValue;
462 using typename CommonValue<LibObjT>::LibObjPtr;
463 using Shared = SharedValue<CommonBoolValue<LibObjT>, LibObjT>;
466 explicit CommonBoolValue(const LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
468 BT_ASSERT_DBG(this->isBool());
471 template <typename OtherLibObjT>
472 CommonBoolValue(const CommonBoolValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
476 static Shared create(const Value rawVal = false)
478 const auto libObjPtr = bt_value_bool_create_init(static_cast<bt_bool>(rawVal));
480 internal::validateCreatedObjPtr(libObjPtr);
481 return CommonBoolValue::Shared::createWithoutRef(libObjPtr);
484 template <typename OtherLibObjT>
485 CommonBoolValue<LibObjT> operator=(const CommonBoolValue<OtherLibObjT> val) noexcept
487 _ThisCommonValue::operator=(val);
491 CommonBoolValue<const bt_value> asConst() const noexcept
493 return CommonBoolValue<const bt_value> {*this};
496 RawValueProxy<CommonBoolValue> operator*() const noexcept
498 return RawValueProxy<CommonBoolValue> {*this};
501 Value value() const noexcept
503 return static_cast<Value>(bt_value_bool_get(this->libObjPtr()));
506 CommonBoolValue value(const Value val) const noexcept
508 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstBoolValue`.");
510 bt_value_bool_set(this->libObjPtr(), static_cast<bt_bool>(val));
514 Shared shared() const noexcept
516 return Shared::createWithRef(*this);
520 using BoolValue = CommonBoolValue<bt_value>;
521 using ConstBoolValue = CommonBoolValue<const bt_value>;
525 struct BoolValueTypeDescr
527 using Const = ConstBoolValue;
528 using NonConst = BoolValue;
532 struct TypeDescr<BoolValue> : public BoolValueTypeDescr
537 struct TypeDescr<ConstBoolValue> : public BoolValueTypeDescr
541 } /* namespace internal */
543 template <typename LibObjT>
544 class CommonUnsignedIntegerValue final : public CommonValue<LibObjT>
547 using typename CommonValue<LibObjT>::_ThisCommonValue;
550 using typename CommonValue<LibObjT>::LibObjPtr;
551 using Shared = SharedValue<CommonUnsignedIntegerValue<LibObjT>, LibObjT>;
552 using Value = std::uint64_t;
554 explicit CommonUnsignedIntegerValue(const LibObjPtr libObjPtr) noexcept :
555 _ThisCommonValue {libObjPtr}
557 BT_ASSERT_DBG(this->isUnsignedInteger());
560 static Shared create(const Value rawVal = 0)
562 const auto libObjPtr = bt_value_integer_unsigned_create_init(rawVal);
564 internal::validateCreatedObjPtr(libObjPtr);
565 return CommonUnsignedIntegerValue::Shared::createWithoutRef(libObjPtr);
568 template <typename OtherLibObjT>
569 CommonUnsignedIntegerValue(const CommonUnsignedIntegerValue<OtherLibObjT> val) noexcept :
570 _ThisCommonValue {val}
574 template <typename OtherLibObjT>
575 CommonUnsignedIntegerValue<LibObjT>
576 operator=(const CommonUnsignedIntegerValue<OtherLibObjT> val) noexcept
578 _ThisCommonValue::operator=(val);
582 CommonUnsignedIntegerValue<const bt_value> asConst() const noexcept
584 return CommonUnsignedIntegerValue<const bt_value> {*this};
587 RawValueProxy<CommonUnsignedIntegerValue> operator*() const noexcept
589 return RawValueProxy<CommonUnsignedIntegerValue> {*this};
592 CommonUnsignedIntegerValue value(const Value val) const noexcept
594 static_assert(!std::is_const<LibObjT>::value,
595 "Not available with `bt2::ConstUnsignedIntegerValue`.");
597 bt_value_integer_unsigned_set(this->libObjPtr(), val);
601 Value value() const noexcept
603 return bt_value_integer_unsigned_get(this->libObjPtr());
606 Shared shared() const noexcept
608 return Shared::createWithRef(*this);
612 using UnsignedIntegerValue = CommonUnsignedIntegerValue<bt_value>;
613 using ConstUnsignedIntegerValue = CommonUnsignedIntegerValue<const bt_value>;
617 struct UnsignedIntegerValueTypeDescr
619 using Const = ConstUnsignedIntegerValue;
620 using NonConst = UnsignedIntegerValue;
624 struct TypeDescr<UnsignedIntegerValue> : public UnsignedIntegerValueTypeDescr
629 struct TypeDescr<ConstUnsignedIntegerValue> : public UnsignedIntegerValueTypeDescr
633 } /* namespace internal */
635 template <typename LibObjT>
636 class CommonSignedIntegerValue final : public CommonValue<LibObjT>
639 using typename CommonValue<LibObjT>::_ThisCommonValue;
642 using typename CommonValue<LibObjT>::LibObjPtr;
643 using Shared = SharedValue<CommonSignedIntegerValue<LibObjT>, LibObjT>;
644 using Value = std::int64_t;
646 explicit CommonSignedIntegerValue(const LibObjPtr libObjPtr) noexcept :
647 _ThisCommonValue {libObjPtr}
649 BT_ASSERT_DBG(this->isSignedInteger());
652 static Shared create(const Value rawVal = 0)
654 const auto libObjPtr = bt_value_integer_signed_create_init(rawVal);
656 internal::validateCreatedObjPtr(libObjPtr);
657 return CommonSignedIntegerValue::Shared::createWithoutRef(libObjPtr);
660 template <typename OtherLibObjT>
661 CommonSignedIntegerValue(const CommonSignedIntegerValue<OtherLibObjT> val) noexcept :
662 _ThisCommonValue {val}
666 template <typename OtherLibObjT>
667 CommonSignedIntegerValue<LibObjT>
668 operator=(const CommonSignedIntegerValue<OtherLibObjT> val) noexcept
670 _ThisCommonValue::operator=(val);
674 CommonSignedIntegerValue<const bt_value> asConst() const noexcept
676 return CommonSignedIntegerValue<const bt_value> {*this};
679 RawValueProxy<CommonSignedIntegerValue> operator*() const noexcept
681 return RawValueProxy<CommonSignedIntegerValue> {*this};
684 CommonSignedIntegerValue value(const Value val) const noexcept
686 static_assert(!std::is_const<LibObjT>::value,
687 "Not available with `bt2::ConstSignedIntegerValue`.");
689 bt_value_integer_signed_set(this->libObjPtr(), val);
693 Value value() const noexcept
695 return bt_value_integer_signed_get(this->libObjPtr());
698 Shared shared() const noexcept
700 return Shared::createWithRef(*this);
704 using SignedIntegerValue = CommonSignedIntegerValue<bt_value>;
705 using ConstSignedIntegerValue = CommonSignedIntegerValue<const bt_value>;
709 struct SignedIntegerValueTypeDescr
711 using Const = ConstSignedIntegerValue;
712 using NonConst = SignedIntegerValue;
716 struct TypeDescr<SignedIntegerValue> : public SignedIntegerValueTypeDescr
721 struct TypeDescr<ConstSignedIntegerValue> : public SignedIntegerValueTypeDescr
725 } /* namespace internal */
727 template <typename LibObjT>
728 class CommonRealValue final : public CommonValue<LibObjT>
731 using typename CommonValue<LibObjT>::_ThisCommonValue;
734 using typename CommonValue<LibObjT>::LibObjPtr;
735 using Shared = SharedValue<CommonRealValue<LibObjT>, LibObjT>;
736 using Value = double;
738 explicit CommonRealValue(const LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
740 BT_ASSERT_DBG(this->isReal());
743 static Shared create(const Value rawVal = 0)
745 const auto libObjPtr = bt_value_real_create_init(rawVal);
747 internal::validateCreatedObjPtr(libObjPtr);
748 return CommonRealValue::Shared::createWithoutRef(libObjPtr);
751 template <typename OtherLibObjT>
752 CommonRealValue(const CommonRealValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
756 template <typename OtherLibObjT>
757 CommonRealValue<LibObjT> operator=(const CommonRealValue<OtherLibObjT> val) noexcept
759 _ThisCommonValue::operator=(val);
763 CommonRealValue<const bt_value> asConst() const noexcept
765 return CommonRealValue<const bt_value> {*this};
768 RawValueProxy<CommonRealValue> operator*() const noexcept
770 return RawValueProxy<CommonRealValue> {*this};
773 CommonRealValue value(const Value val) const noexcept
775 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstRealValue`.");
777 bt_value_real_set(this->libObjPtr(), val);
781 Value value() const noexcept
783 return bt_value_real_get(this->libObjPtr());
786 Shared shared() const noexcept
788 return Shared::createWithRef(*this);
792 using RealValue = CommonRealValue<bt_value>;
793 using ConstRealValue = CommonRealValue<const bt_value>;
797 struct RealValueTypeDescr
799 using Const = ConstRealValue;
800 using NonConst = RealValue;
804 struct TypeDescr<RealValue> : public RealValueTypeDescr
809 struct TypeDescr<ConstRealValue> : public RealValueTypeDescr
813 } /* namespace internal */
815 template <typename LibObjT>
816 class CommonStringValue final : public CommonValue<LibObjT>
819 using typename CommonValue<LibObjT>::_ThisCommonValue;
822 using typename CommonValue<LibObjT>::LibObjPtr;
823 using Shared = SharedValue<CommonStringValue<LibObjT>, LibObjT>;
824 using Value = bt2c::CStringView;
826 explicit CommonStringValue(const LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
828 BT_ASSERT_DBG(this->isString());
831 static Shared create(const bt2c::CStringView rawVal = "")
833 const auto libObjPtr = bt_value_string_create_init(rawVal);
835 internal::validateCreatedObjPtr(libObjPtr);
836 return CommonStringValue::Shared::createWithoutRef(libObjPtr);
839 template <typename OtherLibObjT>
840 CommonStringValue(const CommonStringValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
844 template <typename OtherLibObjT>
845 CommonStringValue<LibObjT> operator=(const CommonStringValue<OtherLibObjT> val) noexcept
847 _ThisCommonValue::operator=(val);
851 CommonStringValue<const bt_value> asConst() const noexcept
853 return CommonStringValue<const bt_value> {*this};
856 RawValueProxy<CommonStringValue> operator*() const noexcept
858 return RawValueProxy<CommonStringValue> {*this};
861 CommonStringValue value(const Value val) const
863 static_assert(!std::is_const<LibObjT>::value,
864 "Not available with `bt2::ConstStringValue`.");
866 const auto status = bt_value_string_set(this->libObjPtr(), *val);
868 if (status == BT_VALUE_STRING_SET_STATUS_MEMORY_ERROR) {
869 throw MemoryError {};
875 Value value() const noexcept
877 return bt_value_string_get(this->libObjPtr());
880 Shared shared() const noexcept
882 return Shared::createWithRef(*this);
886 using StringValue = CommonStringValue<bt_value>;
887 using ConstStringValue = CommonStringValue<const bt_value>;
891 struct StringValueTypeDescr
893 using Const = ConstStringValue;
894 using NonConst = StringValue;
898 struct TypeDescr<StringValue> : public StringValueTypeDescr
903 struct TypeDescr<ConstStringValue> : public StringValueTypeDescr
907 template <typename LibObjT>
908 struct CommonArrayValueSpec;
910 /* Functions specific to mutable array values */
912 struct CommonArrayValueSpec<bt_value> final
914 static bt_value *elementByIndex(bt_value * const libValPtr, const std::uint64_t index) noexcept
916 return bt_value_array_borrow_element_by_index(libValPtr, index);
920 /* Functions specific to constant array values */
922 struct CommonArrayValueSpec<const bt_value> final
924 static const bt_value *elementByIndex(const bt_value * const libValPtr,
925 const std::uint64_t index) noexcept
927 return bt_value_array_borrow_element_by_index_const(libValPtr, index);
931 } /* namespace internal */
933 template <typename LibObjT>
934 class CommonArrayValue final : public CommonValue<LibObjT>
937 using typename CommonValue<LibObjT>::_ThisCommonValue;
940 using typename CommonValue<LibObjT>::LibObjPtr;
941 using Shared = SharedValue<CommonArrayValue<LibObjT>, LibObjT>;
942 using Iterator = BorrowedObjectIterator<CommonArrayValue<LibObjT>>;
944 explicit CommonArrayValue(const LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
946 BT_ASSERT_DBG(this->isArray());
949 static Shared create()
951 const auto libObjPtr = bt_value_array_create();
953 internal::validateCreatedObjPtr(libObjPtr);
954 return CommonArrayValue::Shared::createWithoutRef(libObjPtr);
957 template <typename OtherLibObjT>
958 CommonArrayValue(const CommonArrayValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
962 template <typename OtherLibObjT>
963 CommonArrayValue<LibObjT> operator=(const CommonArrayValue<OtherLibObjT> val) noexcept
965 _ThisCommonValue::operator=(val);
969 CommonArrayValue<const bt_value> asConst() const noexcept
971 return CommonArrayValue<const bt_value> {*this};
974 std::uint64_t length() const noexcept
976 return bt_value_array_get_length(this->libObjPtr());
979 Iterator begin() const noexcept
981 return Iterator {*this, 0};
984 Iterator end() const noexcept
986 return Iterator {*this, this->length()};
989 bool isEmpty() const noexcept
991 return this->length() == 0;
994 CommonValue<LibObjT> operator[](const std::uint64_t index) const noexcept
996 return CommonValue<LibObjT> {
997 internal::CommonArrayValueSpec<LibObjT>::elementByIndex(this->libObjPtr(), index)};
1000 CommonArrayValue append(const Value val) const
1002 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
1004 const auto status = bt_value_array_append_element(this->libObjPtr(), val.libObjPtr());
1006 this->_handleAppendLibStatus(status);
1010 CommonArrayValue append(const bool rawVal) const
1012 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
1015 bt_value_array_append_bool_element(this->libObjPtr(), static_cast<bt_bool>(rawVal));
1017 this->_handleAppendLibStatus(status);
1021 CommonArrayValue 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);
1032 CommonArrayValue append(const std::int64_t rawVal) const
1034 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
1036 const auto status = bt_value_array_append_signed_integer_element(this->libObjPtr(), rawVal);
1038 this->_handleAppendLibStatus(status);
1042 CommonArrayValue append(const double rawVal) const
1044 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
1046 const auto status = bt_value_array_append_real_element(this->libObjPtr(), rawVal);
1048 this->_handleAppendLibStatus(status);
1052 CommonArrayValue append(const char * const rawVal) const
1054 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
1056 const auto status = bt_value_array_append_string_element(this->libObjPtr(), rawVal);
1058 this->_handleAppendLibStatus(status);
1062 CommonArrayValue append(const bt2c::CStringView rawVal) const
1064 return this->append(rawVal.data());
1067 CommonArrayValue<bt_value> appendEmptyArray() const;
1068 CommonMapValue<bt_value> appendEmptyMap() const;
1070 void operator+=(const Value val) const
1075 void operator+=(const bool rawVal) const
1077 this->append(rawVal);
1080 void operator+=(const std::uint64_t rawVal) const
1082 this->append(rawVal);
1085 void operator+=(const std::int64_t rawVal) const
1087 this->append(rawVal);
1090 void operator+=(const double rawVal) const
1092 this->append(rawVal);
1095 void operator+=(const char * const rawVal) const
1097 this->append(rawVal);
1100 void operator+=(const bt2c::CStringView rawVal) const
1102 this->append(rawVal);
1105 Shared shared() const noexcept
1107 return Shared::createWithRef(*this);
1111 void _handleAppendLibStatus(const bt_value_array_append_element_status status) const
1113 if (status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_MEMORY_ERROR) {
1114 throw MemoryError {};
1119 using ArrayValue = CommonArrayValue<bt_value>;
1120 using ConstArrayValue = CommonArrayValue<const bt_value>;
1122 namespace internal {
1124 struct ArrayValueTypeDescr
1126 using Const = ConstArrayValue;
1127 using NonConst = ArrayValue;
1131 struct TypeDescr<ArrayValue> : public ArrayValueTypeDescr
1136 struct TypeDescr<ConstArrayValue> : public ArrayValueTypeDescr
1141 * Type of a user function passed to `CommonMapValue<ObjT>::forEach()`.
1143 * First argument is the entry's key, second is its value.
1145 template <typename ObjT>
1146 using CommonMapValueForEachUserFunc = std::function<void(bt2c::CStringView, ObjT)>;
1149 * Template of a function to be passed to bt_value_map_foreach_entry()
1150 * for bt_value_map_foreach_entry_const() which calls a user function.
1152 * `userData` is casted to a `const` pointer to
1153 * `CommonMapValueForEachUserFunc<ObjT>` (the user function to call).
1155 * This function catches any exception which the user function throws
1156 * and returns the `ErrorStatus` value. If there's no exception, this
1157 * function returns the `OkStatus` value.
1159 template <typename ObjT, typename LibObjT, typename LibStatusT, int OkStatus, int ErrorStatus>
1160 LibStatusT mapValueForEachLibFunc(const char * const key, LibObjT * const libObjPtr,
1161 void * const userData)
1163 const auto& userFunc = *reinterpret_cast<const CommonMapValueForEachUserFunc<ObjT> *>(userData);
1166 userFunc(key, ObjT {libObjPtr});
1168 return static_cast<LibStatusT>(ErrorStatus);
1171 return static_cast<LibStatusT>(OkStatus);
1174 template <typename LibObjT>
1175 struct CommonMapValueSpec;
1177 /* Functions specific to mutable map values */
1179 struct CommonMapValueSpec<bt_value> final
1181 static bt_value *entryByKey(bt_value * const libValPtr, const char * const key) noexcept
1183 return bt_value_map_borrow_entry_value(libValPtr, key);
1186 static void forEach(bt_value * const libValPtr,
1187 const CommonMapValueForEachUserFunc<Value>& func)
1189 const auto status = bt_value_map_foreach_entry(
1191 mapValueForEachLibFunc<Value, bt_value, bt_value_map_foreach_entry_func_status,
1192 BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_OK,
1193 BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_ERROR>,
1194 const_cast<void *>(reinterpret_cast<const void *>(&func)));
1197 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_OK:
1199 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_USER_ERROR:
1200 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_ERROR:
1208 /* Functions specific to constant map values */
1210 struct CommonMapValueSpec<const bt_value> final
1212 static const bt_value *entryByKey(const bt_value * const libValPtr,
1213 const char * const key) noexcept
1215 return bt_value_map_borrow_entry_value_const(libValPtr, key);
1218 static void forEach(const bt_value * const libValPtr,
1219 const CommonMapValueForEachUserFunc<ConstValue>& func)
1221 const auto status = bt_value_map_foreach_entry_const(
1223 mapValueForEachLibFunc<ConstValue, const bt_value,
1224 bt_value_map_foreach_entry_const_func_status,
1225 BT_VALUE_MAP_FOREACH_ENTRY_CONST_FUNC_STATUS_OK,
1226 BT_VALUE_MAP_FOREACH_ENTRY_CONST_FUNC_STATUS_ERROR>,
1227 const_cast<void *>(reinterpret_cast<const void *>(&func)));
1230 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_OK:
1232 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_USER_ERROR:
1233 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_ERROR:
1241 } /* namespace internal */
1243 template <typename LibObjT>
1244 class CommonMapValue final : public CommonValue<LibObjT>
1247 using typename CommonValue<LibObjT>::_ThisCommonValue;
1250 using typename CommonValue<LibObjT>::LibObjPtr;
1251 using Shared = SharedValue<CommonMapValue<LibObjT>, LibObjT>;
1253 explicit CommonMapValue(const LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
1255 BT_ASSERT_DBG(this->isMap());
1258 static Shared create()
1260 const auto libObjPtr = bt_value_map_create();
1262 internal::validateCreatedObjPtr(libObjPtr);
1263 return CommonMapValue::Shared::createWithoutRef(libObjPtr);
1266 template <typename OtherLibObjT>
1267 CommonMapValue(const CommonMapValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
1271 template <typename OtherLibObjT>
1272 CommonMapValue<LibObjT> operator=(const CommonMapValue<OtherLibObjT> val) noexcept
1274 _ThisCommonValue::operator=(val);
1278 CommonMapValue<const bt_value> asConst() const noexcept
1280 return CommonMapValue<const bt_value> {*this};
1283 std::uint64_t length() const noexcept
1285 return bt_value_map_get_size(this->libObjPtr());
1288 bool isEmpty() const noexcept
1290 return this->length() == 0;
1293 OptionalBorrowedObject<CommonValue<LibObjT>>
1294 operator[](const bt2c::CStringView key) const noexcept
1296 return internal::CommonMapValueSpec<LibObjT>::entryByKey(this->libObjPtr(), key);
1299 bool hasEntry(const bt2c::CStringView key) const noexcept
1301 return static_cast<bool>(bt_value_map_has_entry(this->libObjPtr(), key));
1304 CommonMapValue insert(const bt2c::CStringView key, const Value val) const
1306 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1308 const auto status = bt_value_map_insert_entry(this->libObjPtr(), key, val.libObjPtr());
1310 this->_handleInsertLibStatus(status);
1314 CommonMapValue insert(const bt2c::CStringView key, const bool rawVal) const
1316 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1319 bt_value_map_insert_bool_entry(this->libObjPtr(), key, static_cast<bt_bool>(rawVal));
1321 this->_handleInsertLibStatus(status);
1325 CommonMapValue insert(const bt2c::CStringView key, const std::uint64_t rawVal) const
1327 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1330 bt_value_map_insert_unsigned_integer_entry(this->libObjPtr(), key, rawVal);
1332 this->_handleInsertLibStatus(status);
1336 CommonMapValue insert(const bt2c::CStringView key, const std::int64_t rawVal) const
1338 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1341 bt_value_map_insert_signed_integer_entry(this->libObjPtr(), key, rawVal);
1343 this->_handleInsertLibStatus(status);
1347 CommonMapValue insert(const bt2c::CStringView key, const double rawVal) const
1349 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1351 const auto status = bt_value_map_insert_real_entry(this->libObjPtr(), key, rawVal);
1353 this->_handleInsertLibStatus(status);
1357 CommonMapValue insert(const bt2c::CStringView key, const char *rawVal) const
1359 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1361 const auto status = bt_value_map_insert_string_entry(this->libObjPtr(), key, rawVal);
1363 this->_handleInsertLibStatus(status);
1367 CommonMapValue insert(const bt2c::CStringView key, const bt2c::CStringView rawVal) const
1369 return this->insert(key, rawVal.data());
1372 CommonArrayValue<bt_value> insertEmptyArray(bt2c::CStringView key) const;
1373 CommonMapValue<bt_value> insertEmptyMap(bt2c::CStringView key) const;
1376 forEach(const internal::CommonMapValueForEachUserFunc<CommonValue<LibObjT>>& func) const
1378 internal::CommonMapValueSpec<LibObjT>::forEach(this->libObjPtr(), func);
1382 Shared shared() const noexcept
1384 return Shared::createWithRef(*this);
1388 void _handleInsertLibStatus(const bt_value_map_insert_entry_status status) const
1390 if (status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_MEMORY_ERROR) {
1391 throw MemoryError {};
1396 using MapValue = CommonMapValue<bt_value>;
1397 using ConstMapValue = CommonMapValue<const bt_value>;
1399 namespace internal {
1401 struct MapValueTypeDescr
1403 using Const = ConstMapValue;
1404 using NonConst = MapValue;
1408 struct TypeDescr<MapValue> : public MapValueTypeDescr
1413 struct TypeDescr<ConstMapValue> : public MapValueTypeDescr
1417 } /* namespace internal */
1419 template <typename LibObjT>
1420 ArrayValue CommonValue<LibObjT>::appendEmptyArray() const
1422 return this->asArray().appendEmptyArray();
1425 template <typename LibObjT>
1426 MapValue CommonValue<LibObjT>::appendEmptyMap() const
1428 return this->asArray().appendEmptyMap();
1431 template <typename LibObjT>
1432 ArrayValue CommonValue<LibObjT>::insertEmptyArray(const bt2c::CStringView key) const
1434 return this->asMap().insertEmptyArray(key);
1437 template <typename LibObjT>
1438 MapValue CommonValue<LibObjT>::insertEmptyMap(const bt2c::CStringView key) const
1440 return this->asMap().insertEmptyMap(key);
1443 template <typename LibObjT>
1444 CommonNullValue<LibObjT> CommonValue<LibObjT>::asNull() const noexcept
1446 BT_ASSERT_DBG(this->isNull());
1447 return CommonNullValue<LibObjT> {};
1450 template <typename LibObjT>
1451 CommonBoolValue<LibObjT> CommonValue<LibObjT>::asBool() const noexcept
1453 return CommonBoolValue<LibObjT> {this->libObjPtr()};
1456 template <typename LibObjT>
1457 CommonSignedIntegerValue<LibObjT> CommonValue<LibObjT>::asSignedInteger() const noexcept
1459 return CommonSignedIntegerValue<LibObjT> {this->libObjPtr()};
1462 template <typename LibObjT>
1463 CommonUnsignedIntegerValue<LibObjT> CommonValue<LibObjT>::asUnsignedInteger() const noexcept
1465 return CommonUnsignedIntegerValue<LibObjT> {this->libObjPtr()};
1468 template <typename LibObjT>
1469 CommonRealValue<LibObjT> CommonValue<LibObjT>::asReal() const noexcept
1471 return CommonRealValue<LibObjT> {this->libObjPtr()};
1474 template <typename LibObjT>
1475 CommonStringValue<LibObjT> CommonValue<LibObjT>::asString() const noexcept
1477 return CommonStringValue<LibObjT> {this->libObjPtr()};
1480 template <typename LibObjT>
1481 CommonArrayValue<LibObjT> CommonValue<LibObjT>::asArray() const noexcept
1483 return CommonArrayValue<LibObjT> {this->libObjPtr()};
1486 template <typename LibObjT>
1487 CommonMapValue<LibObjT> CommonValue<LibObjT>::asMap() const noexcept
1489 return CommonMapValue<LibObjT> {this->libObjPtr()};
1492 template <typename LibObjT>
1493 ArrayValue CommonArrayValue<LibObjT>::appendEmptyArray() const
1495 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
1497 bt_value *libElemPtr;
1498 const auto status = bt_value_array_append_empty_array_element(this->libObjPtr(), &libElemPtr);
1500 this->_handleAppendLibStatus(status);
1501 return ArrayValue {libElemPtr};
1504 template <typename LibObjT>
1505 MapValue CommonArrayValue<LibObjT>::appendEmptyMap() const
1507 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
1509 bt_value *libElemPtr;
1510 const auto status = bt_value_array_append_empty_map_element(this->libObjPtr(), &libElemPtr);
1512 this->_handleAppendLibStatus(status);
1513 return MapValue {libElemPtr};
1516 template <typename LibObjT>
1517 ArrayValue CommonMapValue<LibObjT>::insertEmptyArray(const bt2c::CStringView key) const
1519 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1521 bt_value *libEntryPtr;
1522 const auto status = bt_value_map_insert_empty_array_entry(this->libObjPtr(), key, &libEntryPtr);
1524 this->_handleInsertLibStatus(status);
1525 return ArrayValue {libEntryPtr};
1528 template <typename LibObjT>
1529 MapValue CommonMapValue<LibObjT>::insertEmptyMap(const bt2c::CStringView key) const
1531 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1533 bt_value *libEntryPtr;
1534 const auto status = bt_value_map_insert_empty_map_entry(this->libObjPtr(), key, &libEntryPtr);
1536 this->_handleInsertLibStatus(status);
1537 return MapValue {libEntryPtr};
1540 inline BoolValue::Shared createValue(const bool rawVal)
1542 return BoolValue::create(rawVal);
1545 inline UnsignedIntegerValue::Shared createValue(const std::uint64_t rawVal)
1547 return UnsignedIntegerValue::create(rawVal);
1550 inline SignedIntegerValue::Shared createValue(const std::int64_t rawVal)
1552 return SignedIntegerValue::create(rawVal);
1555 inline RealValue::Shared createValue(const double rawVal)
1557 return RealValue::create(rawVal);
1560 inline StringValue::Shared createValue(const char * const rawVal)
1562 return StringValue::create(rawVal);
1565 inline StringValue::Shared createValue(const bt2c::CStringView rawVal)
1567 return StringValue::create(rawVal);
1570 } /* namespace bt2 */
1572 #endif /* BABELTRACE_CPP_COMMON_BT2_VALUE_HPP */