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 "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 CommonValue<LibObjT> operator=(const bool rawVal) const noexcept
182 this->asBool() = rawVal;
186 CommonValue<LibObjT> operator=(const std::uint64_t rawVal) const noexcept
188 this->asUnsignedInteger() = rawVal;
192 CommonValue<LibObjT> operator=(const std::int64_t rawVal) const noexcept
194 this->asSignedInteger() = rawVal;
198 CommonValue<LibObjT> operator=(const double rawVal) const noexcept
200 this->asReal() = rawVal;
204 CommonValue<LibObjT> operator=(const char * const rawVal) const noexcept
206 this->asString() = rawVal;
210 CommonValue<LibObjT> operator=(const std::string& rawVal) const noexcept
212 this->asString() = rawVal;
216 std::uint64_t arrayLength() const noexcept
218 return this->asArray().length();
221 bool arrayIsEmpty() const noexcept
223 return this->asArray().isEmpty();
226 CommonValue<LibObjT> operator[](const std::uint64_t index) const noexcept
228 return this->asArray()[index];
231 template <typename T>
232 void append(T&& elem) const
234 this->asArray().append(std::forward<T>(elem));
237 CommonArrayValue<bt_value> appendEmptyArray() const;
238 CommonMapValue<bt_value> appendEmptyMap() const;
240 std::uint64_t mapLength() const noexcept
242 return this->asMap().length();
245 bool mapIsEmpty() const noexcept
247 return this->asMap().isEmpty();
250 template <typename KeyT>
251 nonstd::optional<CommonValue<LibObjT>> operator[](KeyT&& key) const noexcept
253 return this->asMap()[std::forward<KeyT>(key)];
256 template <typename KeyT>
257 bool hasEntry(KeyT&& key) const noexcept
259 return this->asMap().hasEntry(std::forward<KeyT>(key));
262 template <typename KeyT, typename ValT>
263 void insert(KeyT&& key, ValT&& val) const
265 this->asMap().insert(std::forward<KeyT>(key), std::forward<ValT>(val));
268 CommonArrayValue<bt_value> insertEmptyArray(const char *key) const;
269 CommonArrayValue<bt_value> insertEmptyArray(const std::string& key) const;
270 CommonMapValue<bt_value> insertEmptyMap(const char *key) const;
271 CommonMapValue<bt_value> insertEmptyMap(const std::string& key) const;
273 Shared shared() const noexcept
275 return Shared::createWithRef(*this);
278 template <typename ValueT>
279 ValueT as() const noexcept
281 return ValueT {this->libObjPtr()};
284 CommonNullValue<LibObjT> asNull() const noexcept;
285 CommonBoolValue<LibObjT> asBool() const noexcept;
286 CommonSignedIntegerValue<LibObjT> asSignedInteger() const noexcept;
287 CommonUnsignedIntegerValue<LibObjT> asUnsignedInteger() const noexcept;
288 CommonRealValue<LibObjT> asReal() const noexcept;
289 CommonStringValue<LibObjT> asString() const noexcept;
290 CommonArrayValue<LibObjT> asArray() const noexcept;
291 CommonMapValue<LibObjT> asMap() const noexcept;
294 bool _libTypeIs(const bt_value_type type) const noexcept
296 return bt_value_type_is(bt_value_get_type(this->libObjPtr()), type);
300 using Value = CommonValue<bt_value>;
301 using ConstValue = CommonValue<const bt_value>;
305 struct ValueTypeDescr
307 using Const = ConstValue;
308 using NonConst = Value;
312 struct TypeDescr<Value> : public ValueTypeDescr
317 struct TypeDescr<ConstValue> : public ValueTypeDescr
321 } /* namespace internal */
323 template <typename LibObjT>
324 class CommonNullValue final : public CommonValue<LibObjT>
327 using typename CommonValue<LibObjT>::_ThisCommonValue;
330 using Shared = SharedValue<CommonNullValue<LibObjT>, LibObjT>;
332 CommonNullValue() noexcept : _ThisCommonValue {bt_value_null}
336 template <typename OtherLibObjT>
337 CommonNullValue(const CommonNullValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
341 template <typename OtherLibObjT>
342 CommonNullValue<LibObjT>& operator=(const CommonNullValue<OtherLibObjT> val) noexcept
344 _ThisCommonValue::operator=(val);
348 CommonNullValue<const bt_value> asConst() const noexcept
350 return CommonNullValue<const bt_value> {*this};
353 Shared shared() const noexcept
355 return Shared::createWithRef(*this);
359 using NullValue = CommonNullValue<bt_value>;
360 using ConstNullValue = CommonNullValue<const bt_value>;
364 struct NullValueTypeDescr
366 using Const = ConstNullValue;
367 using NonConst = NullValue;
371 struct TypeDescr<NullValue> : public NullValueTypeDescr
376 struct TypeDescr<ConstNullValue> : public NullValueTypeDescr
380 } /* namespace internal */
382 template <typename LibObjT>
383 class CommonBoolValue final : public CommonValue<LibObjT>
386 using typename CommonValue<LibObjT>::_LibObjPtr;
387 using typename CommonValue<LibObjT>::_ThisCommonValue;
390 using Shared = SharedValue<CommonBoolValue<LibObjT>, LibObjT>;
393 explicit CommonBoolValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
395 BT_ASSERT_DBG(this->isBool());
398 template <typename OtherLibObjT>
399 CommonBoolValue(const CommonBoolValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
403 static Shared create(const Value rawVal = false)
405 const auto libObjPtr = bt_value_bool_create_init(static_cast<bt_bool>(rawVal));
407 internal::validateCreatedObjPtr(libObjPtr);
408 return CommonBoolValue::Shared::createWithoutRef(libObjPtr);
411 template <typename OtherLibObjT>
412 CommonBoolValue<LibObjT>& operator=(const CommonBoolValue<OtherLibObjT> val) noexcept
414 _ThisCommonValue::operator=(val);
418 CommonBoolValue<const bt_value> asConst() const noexcept
420 return CommonBoolValue<const bt_value> {*this};
423 CommonBoolValue<LibObjT> operator=(const Value rawVal) const noexcept
425 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstBoolValue`.");
427 bt_value_bool_set(this->libObjPtr(), static_cast<bt_bool>(rawVal));
431 Value value() const noexcept
433 return static_cast<Value>(bt_value_bool_get(this->libObjPtr()));
436 operator Value() const noexcept
438 return this->value();
441 Shared shared() const noexcept
443 return Shared::createWithRef(*this);
447 using BoolValue = CommonBoolValue<bt_value>;
448 using ConstBoolValue = CommonBoolValue<const bt_value>;
452 struct BoolValueTypeDescr
454 using Const = ConstBoolValue;
455 using NonConst = BoolValue;
459 struct TypeDescr<BoolValue> : public BoolValueTypeDescr
464 struct TypeDescr<ConstBoolValue> : public BoolValueTypeDescr
468 } /* namespace internal */
470 template <typename LibObjT>
471 class CommonUnsignedIntegerValue final : public CommonValue<LibObjT>
474 using typename CommonValue<LibObjT>::_LibObjPtr;
475 using typename CommonValue<LibObjT>::_ThisCommonValue;
478 using Shared = SharedValue<CommonUnsignedIntegerValue<LibObjT>, LibObjT>;
479 using Value = std::uint64_t;
481 explicit CommonUnsignedIntegerValue(const _LibObjPtr libObjPtr) noexcept :
482 _ThisCommonValue {libObjPtr}
484 BT_ASSERT_DBG(this->isUnsignedInteger());
487 static Shared create(const Value rawVal = 0)
489 const auto libObjPtr = bt_value_integer_unsigned_create_init(rawVal);
491 internal::validateCreatedObjPtr(libObjPtr);
492 return CommonUnsignedIntegerValue::Shared::createWithoutRef(libObjPtr);
495 template <typename OtherLibObjT>
496 CommonUnsignedIntegerValue(const CommonUnsignedIntegerValue<OtherLibObjT> val) noexcept :
497 _ThisCommonValue {val}
501 template <typename OtherLibObjT>
502 CommonUnsignedIntegerValue<LibObjT>&
503 operator=(const CommonUnsignedIntegerValue<OtherLibObjT> val) noexcept
505 _ThisCommonValue::operator=(val);
509 CommonUnsignedIntegerValue<const bt_value> asConst() const noexcept
511 return CommonUnsignedIntegerValue<const bt_value> {*this};
514 CommonUnsignedIntegerValue<LibObjT> operator=(const Value rawVal) const noexcept
516 static_assert(!std::is_const<LibObjT>::value,
517 "Not available with `bt2::ConstUnsignedIntegerValue`.");
519 bt_value_integer_unsigned_set(this->libObjPtr(), rawVal);
523 Value value() const noexcept
525 return bt_value_integer_unsigned_get(this->libObjPtr());
528 operator Value() const noexcept
530 return this->value();
533 Shared shared() const noexcept
535 return Shared::createWithRef(*this);
539 using UnsignedIntegerValue = CommonUnsignedIntegerValue<bt_value>;
540 using ConstUnsignedIntegerValue = CommonUnsignedIntegerValue<const bt_value>;
544 struct UnsignedIntegerValueTypeDescr
546 using Const = ConstUnsignedIntegerValue;
547 using NonConst = UnsignedIntegerValue;
551 struct TypeDescr<UnsignedIntegerValue> : public UnsignedIntegerValueTypeDescr
556 struct TypeDescr<ConstUnsignedIntegerValue> : public UnsignedIntegerValueTypeDescr
560 } /* namespace internal */
562 template <typename LibObjT>
563 class CommonSignedIntegerValue final : public CommonValue<LibObjT>
566 using typename CommonValue<LibObjT>::_LibObjPtr;
567 using typename CommonValue<LibObjT>::_ThisCommonValue;
570 using Shared = SharedValue<CommonSignedIntegerValue<LibObjT>, LibObjT>;
571 using Value = std::int64_t;
573 explicit CommonSignedIntegerValue(const _LibObjPtr libObjPtr) noexcept :
574 _ThisCommonValue {libObjPtr}
576 BT_ASSERT_DBG(this->isSignedInteger());
579 static Shared create(const Value rawVal = 0)
581 const auto libObjPtr = bt_value_integer_signed_create_init(rawVal);
583 internal::validateCreatedObjPtr(libObjPtr);
584 return CommonSignedIntegerValue::Shared::createWithoutRef(libObjPtr);
587 template <typename OtherLibObjT>
588 CommonSignedIntegerValue(const CommonSignedIntegerValue<OtherLibObjT> val) noexcept :
589 _ThisCommonValue {val}
593 template <typename OtherLibObjT>
594 CommonSignedIntegerValue<LibObjT>
595 operator=(const CommonSignedIntegerValue<OtherLibObjT> val) noexcept
597 _ThisCommonValue::operator=(val);
601 CommonSignedIntegerValue<const bt_value> asConst() const noexcept
603 return CommonSignedIntegerValue<const bt_value> {*this};
606 CommonSignedIntegerValue<LibObjT> operator=(const Value rawVal) const noexcept
608 static_assert(!std::is_const<LibObjT>::value,
609 "Not available with `bt2::ConstSignedIntegerValue`.");
611 bt_value_integer_signed_set(this->libObjPtr(), rawVal);
615 Value value() const noexcept
617 return bt_value_integer_signed_get(this->libObjPtr());
620 operator Value() const noexcept
622 return this->value();
625 Shared shared() const noexcept
627 return Shared::createWithRef(*this);
631 using SignedIntegerValue = CommonSignedIntegerValue<bt_value>;
632 using ConstSignedIntegerValue = CommonSignedIntegerValue<const bt_value>;
636 struct SignedIntegerValueTypeDescr
638 using Const = ConstSignedIntegerValue;
639 using NonConst = SignedIntegerValue;
643 struct TypeDescr<SignedIntegerValue> : public SignedIntegerValueTypeDescr
648 struct TypeDescr<ConstSignedIntegerValue> : public SignedIntegerValueTypeDescr
652 } /* namespace internal */
654 template <typename LibObjT>
655 class CommonRealValue final : public CommonValue<LibObjT>
658 using typename CommonValue<LibObjT>::_LibObjPtr;
659 using typename CommonValue<LibObjT>::_ThisCommonValue;
662 using Shared = SharedValue<CommonRealValue<LibObjT>, LibObjT>;
663 using Value = double;
665 explicit CommonRealValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
667 BT_ASSERT_DBG(this->isReal());
670 static Shared create(const Value rawVal = 0)
672 const auto libObjPtr = bt_value_real_create_init(rawVal);
674 internal::validateCreatedObjPtr(libObjPtr);
675 return CommonRealValue::Shared::createWithoutRef(libObjPtr);
678 template <typename OtherLibObjT>
679 CommonRealValue(const CommonRealValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
683 template <typename OtherLibObjT>
684 CommonRealValue<LibObjT>& operator=(const CommonRealValue<OtherLibObjT> val) noexcept
686 _ThisCommonValue::operator=(val);
690 CommonRealValue<const bt_value> asConst() const noexcept
692 return CommonRealValue<const bt_value> {*this};
695 CommonRealValue<LibObjT> operator=(const Value rawVal) const noexcept
697 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstRealValue`.");
699 bt_value_real_set(this->libObjPtr(), rawVal);
703 Value value() const noexcept
705 return bt_value_real_get(this->libObjPtr());
708 operator Value() const noexcept
710 return this->value();
713 Shared shared() const noexcept
715 return Shared::createWithRef(*this);
719 using RealValue = CommonRealValue<bt_value>;
720 using ConstRealValue = CommonRealValue<const bt_value>;
724 struct RealValueTypeDescr
726 using Const = ConstRealValue;
727 using NonConst = RealValue;
731 struct TypeDescr<RealValue> : public RealValueTypeDescr
736 struct TypeDescr<ConstRealValue> : public RealValueTypeDescr
740 } /* namespace internal */
742 template <typename LibObjT>
743 class CommonStringValue final : public CommonValue<LibObjT>
746 using typename CommonValue<LibObjT>::_LibObjPtr;
747 using typename CommonValue<LibObjT>::_ThisCommonValue;
750 using Shared = SharedValue<CommonStringValue<LibObjT>, LibObjT>;
752 explicit CommonStringValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
754 BT_ASSERT_DBG(this->isString());
757 static Shared create(const char * const rawVal = "")
759 const auto libObjPtr = bt_value_string_create_init(rawVal);
761 internal::validateCreatedObjPtr(libObjPtr);
762 return CommonStringValue::Shared::createWithoutRef(libObjPtr);
765 static Shared create(const std::string& rawVal)
767 return CommonStringValue::create(rawVal.data());
770 template <typename OtherLibObjT>
771 CommonStringValue(const CommonStringValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
775 template <typename OtherLibObjT>
776 CommonStringValue<LibObjT>& operator=(const CommonStringValue<OtherLibObjT> val) noexcept
778 _ThisCommonValue::operator=(val);
782 CommonStringValue<const bt_value> asConst() const noexcept
784 return CommonStringValue<const bt_value> {*this};
787 CommonStringValue<LibObjT> operator=(const char * const rawVal) const
789 static_assert(!std::is_const<LibObjT>::value,
790 "Not available with `bt2::ConstStringValue`.");
792 const auto status = bt_value_string_set(this->libObjPtr(), rawVal);
794 if (status == BT_VALUE_STRING_SET_STATUS_MEMORY_ERROR) {
795 throw MemoryError {};
801 CommonStringValue<LibObjT> operator=(const std::string& rawVal) const noexcept
803 return *this = rawVal.data();
806 bpstd::string_view value() const noexcept
808 return bt_value_string_get(this->libObjPtr());
811 Shared shared() const noexcept
813 return Shared::createWithRef(*this);
817 using StringValue = CommonStringValue<bt_value>;
818 using ConstStringValue = CommonStringValue<const bt_value>;
822 struct StringValueTypeDescr
824 using Const = ConstStringValue;
825 using NonConst = StringValue;
829 struct TypeDescr<StringValue> : public StringValueTypeDescr
834 struct TypeDescr<ConstStringValue> : public StringValueTypeDescr
838 template <typename LibObjT>
839 struct CommonArrayValueSpec;
841 /* Functions specific to mutable array values */
843 struct CommonArrayValueSpec<bt_value> final
845 static bt_value *elementByIndex(bt_value * const libValPtr, const std::uint64_t index) noexcept
847 return bt_value_array_borrow_element_by_index(libValPtr, index);
851 /* Functions specific to constant array values */
853 struct CommonArrayValueSpec<const bt_value> final
855 static const bt_value *elementByIndex(const bt_value * const libValPtr,
856 const std::uint64_t index) noexcept
858 return bt_value_array_borrow_element_by_index_const(libValPtr, index);
862 } /* namespace internal */
864 template <typename LibObjT>
865 class CommonArrayValue final : public CommonValue<LibObjT>
868 using typename CommonValue<LibObjT>::_LibObjPtr;
869 using typename CommonValue<LibObjT>::_ThisCommonValue;
872 using Shared = SharedValue<CommonArrayValue<LibObjT>, LibObjT>;
873 using Iterator = BorrowedObjectIterator<CommonArrayValue<LibObjT>>;
875 explicit CommonArrayValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
877 BT_ASSERT_DBG(this->isArray());
880 static Shared create()
882 const auto libObjPtr = bt_value_array_create();
884 internal::validateCreatedObjPtr(libObjPtr);
885 return CommonArrayValue::Shared::createWithoutRef(libObjPtr);
888 template <typename OtherLibObjT>
889 CommonArrayValue(const CommonArrayValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
893 template <typename OtherLibObjT>
894 CommonArrayValue<LibObjT>& operator=(const CommonArrayValue<OtherLibObjT> val) noexcept
896 _ThisCommonValue::operator=(val);
900 CommonArrayValue<const bt_value> asConst() const noexcept
902 return CommonArrayValue<const bt_value> {*this};
905 std::uint64_t length() const noexcept
907 return bt_value_array_get_length(this->libObjPtr());
910 Iterator begin() const noexcept
912 return Iterator {*this, 0};
915 Iterator end() const noexcept
917 return Iterator {*this, this->length()};
920 bool isEmpty() const noexcept
922 return this->length() == 0;
925 CommonValue<LibObjT> operator[](const std::uint64_t index) const noexcept
927 return CommonValue<LibObjT> {
928 internal::CommonArrayValueSpec<LibObjT>::elementByIndex(this->libObjPtr(), index)};
931 void append(const Value val) const
933 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
935 const auto status = bt_value_array_append_element(this->libObjPtr(), val.libObjPtr());
937 this->_handleAppendLibStatus(status);
940 void append(const bool rawVal) const
942 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
945 bt_value_array_append_bool_element(this->libObjPtr(), static_cast<bt_bool>(rawVal));
947 this->_handleAppendLibStatus(status);
950 void append(const std::uint64_t rawVal) const
952 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
955 bt_value_array_append_unsigned_integer_element(this->libObjPtr(), rawVal);
957 this->_handleAppendLibStatus(status);
960 void append(const std::int64_t rawVal) const
962 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
964 const auto status = bt_value_array_append_signed_integer_element(this->libObjPtr(), rawVal);
966 this->_handleAppendLibStatus(status);
969 void append(const double rawVal) const
971 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
973 const auto status = bt_value_array_append_real_element(this->libObjPtr(), rawVal);
975 this->_handleAppendLibStatus(status);
978 void append(const char * const rawVal) const
980 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
982 const auto status = bt_value_array_append_string_element(this->libObjPtr(), rawVal);
984 this->_handleAppendLibStatus(status);
987 void append(const std::string& rawVal) const
989 this->append(rawVal.data());
992 CommonArrayValue<bt_value> appendEmptyArray() const;
993 CommonMapValue<bt_value> appendEmptyMap() const;
995 void operator+=(const Value val) const
1000 void operator+=(const bool rawVal) const
1002 this->append(rawVal);
1005 void operator+=(const std::uint64_t rawVal) const
1007 this->append(rawVal);
1010 void operator+=(const std::int64_t rawVal) const
1012 this->append(rawVal);
1015 void operator+=(const double rawVal) const
1017 this->append(rawVal);
1020 void operator+=(const char * const rawVal) const
1022 this->append(rawVal);
1025 void operator+=(const std::string& rawVal) const
1027 this->append(rawVal);
1030 Shared shared() const noexcept
1032 return Shared::createWithRef(*this);
1036 void _handleAppendLibStatus(const bt_value_array_append_element_status status) const
1038 if (status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_MEMORY_ERROR) {
1039 throw MemoryError {};
1044 using ArrayValue = CommonArrayValue<bt_value>;
1045 using ConstArrayValue = CommonArrayValue<const bt_value>;
1047 namespace internal {
1049 struct ArrayValueTypeDescr
1051 using Const = ConstArrayValue;
1052 using NonConst = ArrayValue;
1056 struct TypeDescr<ArrayValue> : public ArrayValueTypeDescr
1061 struct TypeDescr<ConstArrayValue> : public ArrayValueTypeDescr
1066 * Type of a user function passed to `CommonMapValue<ObjT>::forEach()`.
1068 * First argument is the entry's key, second is its value.
1070 template <typename ObjT>
1071 using CommonMapValueForEachUserFunc = std::function<void(const bpstd::string_view&, ObjT)>;
1074 * Template of a function to be passed to bt_value_map_foreach_entry()
1075 * for bt_value_map_foreach_entry_const() which calls a user function.
1077 * `userData` is casted to a `const` pointer to
1078 * `CommonMapValueForEachUserFunc<ObjT>` (the user function to call).
1080 * This function catches any exception which the user function throws
1081 * and returns the `ErrorStatus` value. If there's no execption, this
1082 * function returns the `OkStatus` value.
1084 template <typename ObjT, typename LibObjT, typename LibStatusT, int OkStatus, int ErrorStatus>
1085 LibStatusT mapValueForEachLibFunc(const char * const key, LibObjT * const libObjPtr,
1086 void * const userData)
1088 const auto& userFunc = *reinterpret_cast<const CommonMapValueForEachUserFunc<ObjT> *>(userData);
1091 userFunc(key, ObjT {libObjPtr});
1093 return static_cast<LibStatusT>(ErrorStatus);
1096 return static_cast<LibStatusT>(OkStatus);
1099 template <typename LibObjT>
1100 struct CommonMapValueSpec;
1102 /* Functions specific to mutable map values */
1104 struct CommonMapValueSpec<bt_value> final
1106 static bt_value *entryByKey(bt_value * const libValPtr, const char * const key) noexcept
1108 return bt_value_map_borrow_entry_value(libValPtr, key);
1111 static void forEach(bt_value * const libValPtr,
1112 const CommonMapValueForEachUserFunc<Value>& func)
1114 const auto status = bt_value_map_foreach_entry(
1116 mapValueForEachLibFunc<Value, bt_value, bt_value_map_foreach_entry_func_status,
1117 BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_OK,
1118 BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_ERROR>,
1119 const_cast<void *>(reinterpret_cast<const void *>(&func)));
1122 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_OK:
1124 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_USER_ERROR:
1125 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_ERROR:
1133 /* Functions specific to constant map values */
1135 struct CommonMapValueSpec<const bt_value> final
1137 static const bt_value *entryByKey(const bt_value * const libValPtr,
1138 const char * const key) noexcept
1140 return bt_value_map_borrow_entry_value_const(libValPtr, key);
1143 static void forEach(const bt_value * const libValPtr,
1144 const CommonMapValueForEachUserFunc<ConstValue>& func)
1146 const auto status = bt_value_map_foreach_entry_const(
1148 mapValueForEachLibFunc<ConstValue, const bt_value,
1149 bt_value_map_foreach_entry_const_func_status,
1150 BT_VALUE_MAP_FOREACH_ENTRY_CONST_FUNC_STATUS_OK,
1151 BT_VALUE_MAP_FOREACH_ENTRY_CONST_FUNC_STATUS_ERROR>,
1152 const_cast<void *>(reinterpret_cast<const void *>(&func)));
1155 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_OK:
1157 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_USER_ERROR:
1158 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_ERROR:
1166 } /* namespace internal */
1168 template <typename LibObjT>
1169 class CommonMapValue final : public CommonValue<LibObjT>
1172 using typename CommonValue<LibObjT>::_LibObjPtr;
1173 using typename CommonValue<LibObjT>::_ThisCommonValue;
1176 using Shared = SharedValue<CommonMapValue<LibObjT>, LibObjT>;
1178 explicit CommonMapValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
1180 BT_ASSERT_DBG(this->isMap());
1183 static Shared create()
1185 const auto libObjPtr = bt_value_map_create();
1187 internal::validateCreatedObjPtr(libObjPtr);
1188 return CommonMapValue::Shared::createWithoutRef(libObjPtr);
1191 template <typename OtherLibObjT>
1192 CommonMapValue(const CommonMapValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
1196 template <typename OtherLibObjT>
1197 CommonMapValue<LibObjT>& operator=(const CommonMapValue<OtherLibObjT> val) noexcept
1199 _ThisCommonValue::operator=(val);
1203 CommonMapValue<const bt_value> asConst() const noexcept
1205 return CommonMapValue<const bt_value> {*this};
1208 std::uint64_t length() const noexcept
1210 return bt_value_map_get_size(this->libObjPtr());
1213 bool isEmpty() const noexcept
1215 return this->length() == 0;
1218 nonstd::optional<CommonValue<LibObjT>> operator[](const char * const key) const noexcept
1220 const auto libObjPtr =
1221 internal::CommonMapValueSpec<LibObjT>::entryByKey(this->libObjPtr(), key);
1224 return nonstd::nullopt;
1227 return CommonValue<LibObjT> {libObjPtr};
1230 nonstd::optional<CommonValue<LibObjT>> operator[](const std::string& key) const noexcept
1232 return (*this)[key.data()];
1235 bool hasEntry(const char * const key) const noexcept
1237 return static_cast<bool>(bt_value_map_has_entry(this->libObjPtr(), key));
1240 bool hasEntry(const std::string& key) const noexcept
1242 return this->hasEntry(key.data());
1245 void insert(const char * const key, const Value val) const
1247 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1249 const auto status = bt_value_map_insert_entry(this->libObjPtr(), key, val.libObjPtr());
1251 this->_handleInsertLibStatus(status);
1254 void insert(const std::string& key, const Value val) const
1256 this->insert(key.data(), val);
1259 void insert(const char * const key, const bool rawVal) const
1261 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1264 bt_value_map_insert_bool_entry(this->libObjPtr(), key, static_cast<bt_bool>(rawVal));
1266 this->_handleInsertLibStatus(status);
1269 void insert(const std::string& key, const bool rawVal) const
1271 this->insert(key.data(), rawVal);
1274 void insert(const char * const key, const std::uint64_t rawVal) const
1276 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1279 bt_value_map_insert_unsigned_integer_entry(this->libObjPtr(), key, rawVal);
1281 this->_handleInsertLibStatus(status);
1284 void insert(const std::string& key, const std::uint64_t rawVal) const
1286 this->insert(key.data(), rawVal);
1289 void insert(const char * const key, const std::int64_t rawVal) const
1291 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1294 bt_value_map_insert_signed_integer_entry(this->libObjPtr(), key, rawVal);
1296 this->_handleInsertLibStatus(status);
1299 void insert(const std::string& key, const std::int64_t rawVal) const
1301 this->insert(key.data(), rawVal);
1304 void insert(const char * const key, const double rawVal) const
1306 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1308 const auto status = bt_value_map_insert_real_entry(this->libObjPtr(), key, rawVal);
1310 this->_handleInsertLibStatus(status);
1313 void insert(const std::string& key, const double rawVal) const
1315 this->insert(key.data(), rawVal);
1318 void insert(const char * const key, const char * const rawVal) const
1320 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1322 const auto status = bt_value_map_insert_string_entry(this->libObjPtr(), key, rawVal);
1324 this->_handleInsertLibStatus(status);
1327 void insert(const char * const key, const std::string& rawVal) const
1329 this->insert(key, rawVal.data());
1332 void insert(const std::string& key, const char * const rawVal) const
1334 this->insert(key.data(), rawVal);
1337 void insert(const std::string& key, const std::string& rawVal) const
1339 this->insert(key.data(), rawVal.data());
1342 CommonArrayValue<bt_value> insertEmptyArray(const char *key) const;
1343 CommonArrayValue<bt_value> insertEmptyArray(const std::string& key) const;
1344 CommonMapValue<bt_value> insertEmptyMap(const char *key) const;
1345 CommonMapValue<bt_value> insertEmptyMap(const std::string& key) const;
1347 void forEach(const internal::CommonMapValueForEachUserFunc<CommonValue<LibObjT>>& func) const
1349 internal::CommonMapValueSpec<LibObjT>::forEach(this->libObjPtr(), func);
1352 Shared shared() const noexcept
1354 return Shared::createWithRef(*this);
1358 void _handleInsertLibStatus(const bt_value_map_insert_entry_status status) const
1360 if (status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_MEMORY_ERROR) {
1361 throw MemoryError {};
1366 using MapValue = CommonMapValue<bt_value>;
1367 using ConstMapValue = CommonMapValue<const bt_value>;
1369 namespace internal {
1371 struct MapValueTypeDescr
1373 using Const = ConstMapValue;
1374 using NonConst = MapValue;
1378 struct TypeDescr<MapValue> : public MapValueTypeDescr
1383 struct TypeDescr<ConstMapValue> : public MapValueTypeDescr
1387 } /* namespace internal */
1389 template <typename LibObjT>
1390 ArrayValue CommonValue<LibObjT>::appendEmptyArray() const
1392 return this->asArray().appendEmptyArray();
1395 template <typename LibObjT>
1396 MapValue CommonValue<LibObjT>::appendEmptyMap() const
1398 return this->asArray().appendEmptyMap();
1401 template <typename LibObjT>
1402 ArrayValue CommonValue<LibObjT>::insertEmptyArray(const char * const key) const
1404 return this->asMap().insertEmptyArray(key);
1407 template <typename LibObjT>
1408 ArrayValue CommonValue<LibObjT>::insertEmptyArray(const std::string& key) const
1410 return this->asMap().insertEmptyArray(key);
1413 template <typename LibObjT>
1414 MapValue CommonValue<LibObjT>::insertEmptyMap(const char * const key) const
1416 return this->asMap().insertEmptyMap(key);
1419 template <typename LibObjT>
1420 MapValue CommonValue<LibObjT>::insertEmptyMap(const std::string& key) const
1422 return this->asMap().insertEmptyMap(key);
1425 template <typename LibObjT>
1426 CommonNullValue<LibObjT> CommonValue<LibObjT>::asNull() const noexcept
1428 BT_ASSERT_DBG(this->isNull());
1429 return CommonNullValue<LibObjT> {this->libObjPtr()};
1432 template <typename LibObjT>
1433 CommonBoolValue<LibObjT> CommonValue<LibObjT>::asBool() const noexcept
1435 BT_ASSERT_DBG(this->isBool());
1436 return CommonBoolValue<LibObjT> {this->libObjPtr()};
1439 template <typename LibObjT>
1440 CommonSignedIntegerValue<LibObjT> CommonValue<LibObjT>::asSignedInteger() const noexcept
1442 BT_ASSERT_DBG(this->isSignedInteger());
1443 return CommonSignedIntegerValue<LibObjT> {this->libObjPtr()};
1446 template <typename LibObjT>
1447 CommonUnsignedIntegerValue<LibObjT> CommonValue<LibObjT>::asUnsignedInteger() const noexcept
1449 BT_ASSERT_DBG(this->isUnsignedInteger());
1450 return CommonUnsignedIntegerValue<LibObjT> {this->libObjPtr()};
1453 template <typename LibObjT>
1454 CommonRealValue<LibObjT> CommonValue<LibObjT>::asReal() const noexcept
1456 BT_ASSERT_DBG(this->isReal());
1457 return CommonRealValue<LibObjT> {this->libObjPtr()};
1460 template <typename LibObjT>
1461 CommonStringValue<LibObjT> CommonValue<LibObjT>::asString() const noexcept
1463 BT_ASSERT_DBG(this->isString());
1464 return CommonStringValue<LibObjT> {this->libObjPtr()};
1467 template <typename LibObjT>
1468 CommonArrayValue<LibObjT> CommonValue<LibObjT>::asArray() const noexcept
1470 BT_ASSERT_DBG(this->isArray());
1471 return CommonArrayValue<LibObjT> {this->libObjPtr()};
1474 template <typename LibObjT>
1475 CommonMapValue<LibObjT> CommonValue<LibObjT>::asMap() const noexcept
1477 BT_ASSERT_DBG(this->isMap());
1478 return CommonMapValue<LibObjT> {this->libObjPtr()};
1481 template <typename LibObjT>
1482 ArrayValue CommonArrayValue<LibObjT>::appendEmptyArray() const
1484 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
1486 bt_value *libElemPtr;
1487 const auto status = bt_value_array_append_empty_array_element(this->libObjPtr(), &libElemPtr);
1489 this->_handleAppendLibStatus(status);
1490 return ArrayValue {libElemPtr};
1493 template <typename LibObjT>
1494 MapValue CommonArrayValue<LibObjT>::appendEmptyMap() const
1496 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
1498 bt_value *libElemPtr;
1499 const auto status = bt_value_array_append_empty_map_element(this->libObjPtr(), &libElemPtr);
1501 this->_handleAppendLibStatus(status);
1502 return MapValue {libElemPtr};
1505 template <typename LibObjT>
1506 ArrayValue CommonMapValue<LibObjT>::insertEmptyArray(const char * const key) const
1508 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1510 bt_value *libEntryPtr;
1511 const auto status = bt_value_map_insert_empty_array_entry(this->libObjPtr(), key, &libEntryPtr);
1513 this->_handleInsertLibStatus(status);
1514 return ArrayValue {libEntryPtr};
1517 template <typename LibObjT>
1518 ArrayValue CommonMapValue<LibObjT>::insertEmptyArray(const std::string& key) const
1520 return this->insertEmptyArray(key.data());
1523 template <typename LibObjT>
1524 MapValue CommonMapValue<LibObjT>::insertEmptyMap(const char * const key) const
1526 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1528 bt_value *libEntryPtr;
1529 const auto status = bt_value_map_insert_empty_map_entry(this->libObjPtr(), key, &libEntryPtr);
1531 this->_handleInsertLibStatus(status);
1532 return MapValue {libEntryPtr};
1535 template <typename LibObjT>
1536 MapValue CommonMapValue<LibObjT>::insertEmptyMap(const std::string& key) const
1538 return this->insertEmptyMap(key.data());
1541 inline BoolValue::Shared createValue(const bool rawVal)
1543 return BoolValue::create(rawVal);
1546 inline UnsignedIntegerValue::Shared createValue(const std::uint64_t rawVal)
1548 return UnsignedIntegerValue::create(rawVal);
1551 inline SignedIntegerValue::Shared createValue(const std::int64_t rawVal)
1553 return SignedIntegerValue::create(rawVal);
1556 inline RealValue::Shared createValue(const double rawVal)
1558 return RealValue::create(rawVal);
1561 inline StringValue::Shared createValue(const char * const rawVal)
1563 return StringValue::create(rawVal);
1566 inline StringValue::Shared createValue(const std::string& rawVal)
1568 return StringValue::create(rawVal);
1571 } /* namespace bt2 */
1573 #endif /* BABELTRACE_CPP_COMMON_BT2_VALUE_HPP */