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
10 #include <type_traits>
14 #include <babeltrace2/babeltrace.h>
16 #include "common/assert.h"
17 #include "common/common.h"
18 #include "common-iter.hpp"
19 #include "internal/borrowed-obj.hpp"
20 #include "internal/shared-obj.hpp"
21 #include "internal/utils.hpp"
22 #include "cpp-common/optional.hpp"
23 #include "cpp-common/string_view.hpp"
29 struct ValueRefFuncs final
31 static void get(const bt_value * const libObjPtr)
33 bt_value_get_ref(libObjPtr);
36 static void put(const bt_value * const libObjPtr)
38 bt_value_put_ref(libObjPtr);
42 template <typename ObjT, typename LibObjT>
43 using SharedValue = internal::SharedObj<ObjT, LibObjT, internal::ValueRefFuncs>;
45 } /* namespace internal */
47 template <typename LibObjT>
48 class CommonNullValue;
50 template <typename LibObjT>
51 class CommonBoolValue;
53 template <typename LibObjT>
54 class CommonUnsignedIntegerValue;
56 template <typename LibObjT>
57 class CommonSignedIntegerValue;
59 template <typename LibObjT>
60 class CommonRealValue;
62 template <typename LibObjT>
63 class CommonStringValue;
65 template <typename LibObjT>
66 class CommonArrayValue;
68 template <typename LibObjT>
73 NUL = BT_VALUE_TYPE_NULL,
74 BOOL = BT_VALUE_TYPE_BOOL,
75 UNSIGNED_INTEGER = BT_VALUE_TYPE_UNSIGNED_INTEGER,
76 SIGNED_INTEGER = BT_VALUE_TYPE_SIGNED_INTEGER,
77 REAL = BT_VALUE_TYPE_REAL,
78 STRING = BT_VALUE_TYPE_STRING,
79 ARRAY = BT_VALUE_TYPE_ARRAY,
80 MAP = BT_VALUE_TYPE_MAP,
83 template <typename LibObjT>
84 class CommonClockClass;
86 template <typename LibObjT>
87 class CommonFieldClass;
89 template <typename LibObjT>
90 class CommonTraceClass;
92 template <typename LibObjT>
93 class CommonStreamClass;
95 template <typename LibObjT>
96 class CommonEventClass;
98 template <typename LibObjT>
101 template <typename LibObjT>
102 class CommonValue : public internal::BorrowedObj<LibObjT>
104 /* Allow append() to call `val.libObjPtr()` */
105 friend class CommonArrayValue<bt_value>;
107 /* Allow insert() to call `val.libObjPtr()` */
108 friend class CommonMapValue<bt_value>;
110 /* Allow userAttributes() to call `val.libObjPtr()` */
111 friend class CommonClockClass<bt_clock_class>;
112 friend class CommonFieldClass<bt_field_class>;
113 friend class CommonTraceClass<bt_trace_class>;
114 friend class CommonStreamClass<bt_stream_class>;
115 friend class CommonEventClass<bt_event_class>;
116 friend class CommonStream<bt_stream>;
118 /* Allow operator==() to call `other.libObjPtr()` */
119 friend class CommonValue<bt_value>;
120 friend class CommonValue<const bt_value>;
123 using typename internal::BorrowedObj<LibObjT>::_ThisBorrowedObj;
126 using typename internal::BorrowedObj<LibObjT>::_LibObjPtr;
127 using _ThisCommonValue = CommonValue<LibObjT>;
130 using Shared = internal::SharedValue<CommonValue<LibObjT>, LibObjT>;
132 explicit CommonValue(const _LibObjPtr libObjPtr) noexcept : _ThisBorrowedObj {libObjPtr}
136 template <typename OtherLibObjT>
137 CommonValue(const CommonValue<OtherLibObjT>& val) noexcept : _ThisBorrowedObj {val}
141 template <typename OtherLibObjT>
142 _ThisCommonValue& operator=(const CommonValue<OtherLibObjT>& val) noexcept
144 _ThisBorrowedObj::operator=(val);
148 ValueType type() const noexcept
150 return static_cast<ValueType>(bt_value_get_type(this->libObjPtr()));
153 bool isNull() const noexcept
155 return this->_libTypeIs(BT_VALUE_TYPE_NULL);
158 bool isBool() const noexcept
160 return this->_libTypeIs(BT_VALUE_TYPE_BOOL);
163 bool isInteger() const noexcept
165 return this->_libTypeIs(BT_VALUE_TYPE_INTEGER);
168 bool isUnsignedInteger() const noexcept
170 return this->_libTypeIs(BT_VALUE_TYPE_UNSIGNED_INTEGER);
173 bool isSignedInteger() const noexcept
175 return this->_libTypeIs(BT_VALUE_TYPE_SIGNED_INTEGER);
178 bool isReal() const noexcept
180 return this->_libTypeIs(BT_VALUE_TYPE_REAL);
183 bool isString() const noexcept
185 return this->_libTypeIs(BT_VALUE_TYPE_STRING);
188 bool isArray() const noexcept
190 return this->_libTypeIs(BT_VALUE_TYPE_ARRAY);
193 bool isMap() const noexcept
195 return this->_libTypeIs(BT_VALUE_TYPE_MAP);
198 template <typename OtherLibObjT>
199 bool operator==(const CommonValue<OtherLibObjT>& other) const noexcept
201 return static_cast<bool>(bt_value_is_equal(this->libObjPtr(), other.libObjPtr()));
204 template <typename OtherLibObjT>
205 bool operator!=(const CommonValue<OtherLibObjT>& other) const noexcept
207 return !(*this == other);
210 Shared shared() const noexcept
212 return Shared::createWithRef(*this);
215 template <typename ValueT>
216 ValueT as() const noexcept
218 return ValueT {this->libObjPtr()};
221 CommonNullValue<LibObjT> asNull() const noexcept;
222 CommonBoolValue<LibObjT> asBool() const noexcept;
223 CommonSignedIntegerValue<LibObjT> asSignedInteger() const noexcept;
224 CommonUnsignedIntegerValue<LibObjT> asUnsignedInteger() const noexcept;
225 CommonRealValue<LibObjT> asReal() const noexcept;
226 CommonStringValue<LibObjT> asString() const noexcept;
227 CommonArrayValue<LibObjT> asArray() const noexcept;
228 CommonMapValue<LibObjT> asMap() const noexcept;
231 bool _libTypeIs(const bt_value_type type) const noexcept
233 return bt_value_type_is(bt_value_get_type(this->libObjPtr()), type);
237 using Value = CommonValue<bt_value>;
238 using ConstValue = CommonValue<const bt_value>;
242 struct ValueTypeDescr
244 using Const = ConstValue;
245 using NonConst = Value;
249 struct TypeDescr<Value> : public ValueTypeDescr
254 struct TypeDescr<ConstValue> : public ValueTypeDescr
258 } /* namespace internal */
260 template <typename LibObjT>
261 class CommonNullValue final : public CommonValue<LibObjT>
264 using typename CommonValue<LibObjT>::_ThisCommonValue;
267 using Shared = internal::SharedValue<CommonNullValue<LibObjT>, LibObjT>;
269 CommonNullValue() noexcept : _ThisCommonValue {bt_value_null}
273 template <typename OtherLibObjT>
274 CommonNullValue(const CommonNullValue<OtherLibObjT>& val) noexcept : _ThisCommonValue {val}
278 template <typename OtherLibObjT>
279 CommonNullValue<LibObjT>& operator=(const CommonNullValue<OtherLibObjT>& val) noexcept
281 _ThisCommonValue::operator=(val);
285 Shared shared() const noexcept
287 return Shared::createWithRef(*this);
291 using NullValue = CommonNullValue<bt_value>;
292 using ConstNullValue = CommonNullValue<const bt_value>;
296 struct NullValueTypeDescr
298 using Const = ConstNullValue;
299 using NonConst = NullValue;
303 struct TypeDescr<NullValue> : public NullValueTypeDescr
308 struct TypeDescr<ConstNullValue> : public NullValueTypeDescr
312 } /* namespace internal */
314 template <typename LibObjT>
315 class CommonBoolValue final : public CommonValue<LibObjT>
318 using typename CommonValue<LibObjT>::_LibObjPtr;
319 using typename CommonValue<LibObjT>::_ThisCommonValue;
322 using Shared = internal::SharedValue<CommonBoolValue<LibObjT>, LibObjT>;
325 explicit CommonBoolValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
327 BT_ASSERT_DBG(this->isBool());
330 template <typename OtherLibObjT>
331 CommonBoolValue(const CommonBoolValue<OtherLibObjT>& val) noexcept : _ThisCommonValue {val}
335 static Shared create(const Value rawVal = false)
337 const auto libObjPtr = bt_value_bool_create_init(static_cast<bt_bool>(rawVal));
339 internal::validateCreatedObjPtr(libObjPtr);
340 return CommonBoolValue::Shared::createWithoutRef(libObjPtr);
343 template <typename OtherLibObjT>
344 CommonBoolValue<LibObjT>& operator=(const CommonBoolValue<OtherLibObjT>& val) noexcept
346 _ThisCommonValue::operator=(val);
350 CommonBoolValue<LibObjT>& operator=(const Value rawVal) noexcept
352 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
354 bt_value_bool_set(this->libObjPtr(), static_cast<bt_bool>(rawVal));
358 Value value() const noexcept
360 return static_cast<Value>(bt_value_bool_get(this->libObjPtr()));
363 operator Value() const noexcept
365 return this->value();
368 Shared shared() const noexcept
370 return Shared::createWithRef(*this);
374 using BoolValue = CommonBoolValue<bt_value>;
375 using ConstBoolValue = CommonBoolValue<const bt_value>;
379 struct BoolValueTypeDescr
381 using Const = ConstBoolValue;
382 using NonConst = BoolValue;
386 struct TypeDescr<BoolValue> : public BoolValueTypeDescr
391 struct TypeDescr<ConstBoolValue> : public BoolValueTypeDescr
395 } /* namespace internal */
397 template <typename LibObjT>
398 class CommonUnsignedIntegerValue final : public CommonValue<LibObjT>
401 using typename CommonValue<LibObjT>::_LibObjPtr;
402 using typename CommonValue<LibObjT>::_ThisCommonValue;
405 using Shared = internal::SharedValue<CommonUnsignedIntegerValue<LibObjT>, LibObjT>;
406 using Value = std::uint64_t;
408 explicit CommonUnsignedIntegerValue(const _LibObjPtr libObjPtr) noexcept :
409 _ThisCommonValue {libObjPtr}
411 BT_ASSERT_DBG(this->isUnsignedInteger());
414 static Shared create(const Value rawVal = 0)
416 const auto libObjPtr = bt_value_integer_unsigned_create_init(rawVal);
418 internal::validateCreatedObjPtr(libObjPtr);
419 return CommonUnsignedIntegerValue::Shared::createWithoutRef(libObjPtr);
422 template <typename OtherLibObjT>
423 CommonUnsignedIntegerValue(const CommonUnsignedIntegerValue<OtherLibObjT>& val) noexcept :
424 _ThisCommonValue {val}
428 template <typename OtherLibObjT>
429 CommonUnsignedIntegerValue<LibObjT>&
430 operator=(const CommonUnsignedIntegerValue<OtherLibObjT>& val) noexcept
432 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
434 _ThisCommonValue::operator=(val);
438 CommonUnsignedIntegerValue<LibObjT>& operator=(const Value rawVal) noexcept
440 bt_value_integer_unsigned_set(this->libObjPtr(), rawVal);
444 Value value() const noexcept
446 return bt_value_integer_unsigned_get(this->libObjPtr());
449 operator Value() const noexcept
451 return this->value();
454 Shared shared() const noexcept
456 return Shared::createWithRef(*this);
460 using UnsignedIntegerValue = CommonUnsignedIntegerValue<bt_value>;
461 using ConstUnsignedIntegerValue = CommonUnsignedIntegerValue<const bt_value>;
465 struct UnsignedIntegerValueTypeDescr
467 using Const = ConstUnsignedIntegerValue;
468 using NonConst = UnsignedIntegerValue;
472 struct TypeDescr<UnsignedIntegerValue> : public UnsignedIntegerValueTypeDescr
477 struct TypeDescr<ConstUnsignedIntegerValue> : public UnsignedIntegerValueTypeDescr
481 } /* namespace internal */
483 template <typename LibObjT>
484 class CommonSignedIntegerValue final : public CommonValue<LibObjT>
487 using typename CommonValue<LibObjT>::_LibObjPtr;
488 using typename CommonValue<LibObjT>::_ThisCommonValue;
491 using Shared = internal::SharedValue<CommonSignedIntegerValue<LibObjT>, LibObjT>;
492 using Value = std::int64_t;
494 explicit CommonSignedIntegerValue(const _LibObjPtr libObjPtr) noexcept :
495 _ThisCommonValue {libObjPtr}
497 BT_ASSERT_DBG(this->isSignedInteger());
500 static Shared create(const Value rawVal = 0)
502 const auto libObjPtr = bt_value_integer_signed_create_init(rawVal);
504 internal::validateCreatedObjPtr(libObjPtr);
505 return CommonSignedIntegerValue::Shared::createWithoutRef(libObjPtr);
508 template <typename OtherLibObjT>
509 CommonSignedIntegerValue(const CommonSignedIntegerValue<OtherLibObjT>& val) noexcept :
510 _ThisCommonValue {val}
514 template <typename OtherLibObjT>
515 CommonSignedIntegerValue<LibObjT>&
516 operator=(const CommonSignedIntegerValue<OtherLibObjT>& val) noexcept
518 _ThisCommonValue::operator=(val);
522 CommonSignedIntegerValue<LibObjT>& operator=(const Value rawVal) noexcept
524 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
526 bt_value_integer_signed_set(this->libObjPtr(), rawVal);
530 Value value() const noexcept
532 return bt_value_integer_signed_get(this->libObjPtr());
535 operator Value() const noexcept
537 return this->value();
540 Shared shared() const noexcept
542 return Shared::createWithRef(*this);
546 using SignedIntegerValue = CommonSignedIntegerValue<bt_value>;
547 using ConstSignedIntegerValue = CommonSignedIntegerValue<const bt_value>;
551 struct SignedIntegerValueTypeDescr
553 using Const = ConstSignedIntegerValue;
554 using NonConst = SignedIntegerValue;
558 struct TypeDescr<SignedIntegerValue> : public SignedIntegerValueTypeDescr
563 struct TypeDescr<ConstSignedIntegerValue> : public SignedIntegerValueTypeDescr
567 } /* namespace internal */
569 template <typename LibObjT>
570 class CommonRealValue final : public CommonValue<LibObjT>
573 using typename CommonValue<LibObjT>::_LibObjPtr;
574 using typename CommonValue<LibObjT>::_ThisCommonValue;
577 using Shared = internal::SharedValue<CommonRealValue<LibObjT>, LibObjT>;
578 using Value = double;
580 explicit CommonRealValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
582 BT_ASSERT_DBG(this->isReal());
585 static Shared create(const Value rawVal = 0)
587 const auto libObjPtr = bt_value_real_create_init(rawVal);
589 internal::validateCreatedObjPtr(libObjPtr);
590 return CommonRealValue::Shared::createWithoutRef(libObjPtr);
593 template <typename OtherLibObjT>
594 CommonRealValue(const CommonRealValue<OtherLibObjT>& val) noexcept : _ThisCommonValue {val}
598 template <typename OtherLibObjT>
599 CommonRealValue<LibObjT>& operator=(const CommonRealValue<OtherLibObjT>& val) noexcept
601 _ThisCommonValue::operator=(val);
605 CommonRealValue<LibObjT>& operator=(const Value rawVal) noexcept
607 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
609 bt_value_real_set(this->libObjPtr(), rawVal);
613 Value value() const noexcept
615 return bt_value_real_get(this->libObjPtr());
618 operator Value() const noexcept
620 return this->value();
623 Shared shared() const noexcept
625 return Shared::createWithRef(*this);
629 using RealValue = CommonRealValue<bt_value>;
630 using ConstRealValue = CommonRealValue<const bt_value>;
634 struct RealValueTypeDescr
636 using Const = ConstRealValue;
637 using NonConst = RealValue;
641 struct TypeDescr<RealValue> : public RealValueTypeDescr
646 struct TypeDescr<ConstRealValue> : public RealValueTypeDescr
650 } /* namespace internal */
652 template <typename LibObjT>
653 class CommonStringValue final : public CommonValue<LibObjT>
656 using typename CommonValue<LibObjT>::_LibObjPtr;
657 using typename CommonValue<LibObjT>::_ThisCommonValue;
660 using Shared = internal::SharedValue<CommonStringValue<LibObjT>, LibObjT>;
662 explicit CommonStringValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
664 BT_ASSERT_DBG(this->isString());
667 static Shared create(const char * const rawVal = "")
669 const auto libObjPtr = bt_value_string_create_init(rawVal);
671 internal::validateCreatedObjPtr(libObjPtr);
672 return CommonStringValue::Shared::createWithoutRef(libObjPtr);
675 static Shared create(const std::string& rawVal)
677 return CommonStringValue::create(rawVal.data());
680 template <typename OtherLibObjT>
681 CommonStringValue(const CommonStringValue<OtherLibObjT>& val) noexcept : _ThisCommonValue {val}
685 template <typename OtherLibObjT>
686 CommonStringValue<LibObjT>& operator=(const CommonStringValue<OtherLibObjT>& val) noexcept
688 _ThisCommonValue::operator=(val);
692 CommonStringValue<LibObjT>& operator=(const char * const rawVal)
694 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
696 const auto status = bt_value_string_set(this->libObjPtr(), rawVal);
698 if (status == BT_VALUE_STRING_SET_STATUS_MEMORY_ERROR) {
699 throw MemoryError {};
705 CommonStringValue<LibObjT>& operator=(const std::string& rawVal) noexcept
707 return *this = rawVal.data();
710 bpstd::string_view value() const noexcept
712 return bt_value_string_get(this->libObjPtr());
715 Shared shared() const noexcept
717 return Shared::createWithRef(*this);
721 using StringValue = CommonStringValue<bt_value>;
722 using ConstStringValue = CommonStringValue<const bt_value>;
726 struct StringValueTypeDescr
728 using Const = ConstStringValue;
729 using NonConst = StringValue;
733 struct TypeDescr<StringValue> : public StringValueTypeDescr
738 struct TypeDescr<ConstStringValue> : public StringValueTypeDescr
742 template <typename LibObjT>
743 struct CommonArrayValueSpec;
745 /* Functions specific to mutable array values */
747 struct CommonArrayValueSpec<bt_value> final
749 static bt_value *elementByIndex(bt_value * const libValPtr, const std::uint64_t index) noexcept
751 return bt_value_array_borrow_element_by_index(libValPtr, index);
755 /* Functions specific to constant array values */
757 struct CommonArrayValueSpec<const bt_value> final
759 static const bt_value *elementByIndex(const bt_value * const libValPtr,
760 const std::uint64_t index) noexcept
762 return bt_value_array_borrow_element_by_index_const(libValPtr, index);
766 } /* namespace internal */
768 template <typename LibObjT>
769 class CommonArrayValue final : public CommonValue<LibObjT>
772 using typename CommonValue<LibObjT>::_LibObjPtr;
773 using typename CommonValue<LibObjT>::_ThisCommonValue;
776 using Shared = internal::SharedValue<CommonArrayValue<LibObjT>, LibObjT>;
777 using Iterator = CommonIterator<CommonArrayValue<LibObjT>, CommonValue<LibObjT>>;
779 explicit CommonArrayValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
781 BT_ASSERT_DBG(this->isArray());
784 static Shared create()
786 const auto libObjPtr = bt_value_array_create();
788 internal::validateCreatedObjPtr(libObjPtr);
789 return CommonArrayValue::Shared::createWithoutRef(libObjPtr);
792 template <typename OtherLibObjT>
793 CommonArrayValue(const CommonArrayValue<OtherLibObjT>& val) noexcept : _ThisCommonValue {val}
797 template <typename OtherLibObjT>
798 CommonArrayValue<LibObjT>& operator=(const CommonArrayValue<OtherLibObjT>& val) noexcept
800 _ThisCommonValue::operator=(val);
804 std::uint64_t length() const noexcept
806 return bt_value_array_get_length(this->libObjPtr());
809 /* Required by the `CommonIterator` template class */
810 std::uint64_t size() const noexcept
812 return this->length();
815 Iterator begin() const noexcept
817 return Iterator {*this, 0};
820 Iterator end() const noexcept
822 return Iterator {*this, this->length()};
825 bool isEmpty() const noexcept
827 return this->length() == 0;
830 ConstValue operator[](const std::uint64_t index) const noexcept
832 return ConstValue {internal::CommonArrayValueSpec<const bt_value>::elementByIndex(
833 this->libObjPtr(), index)};
836 CommonValue<LibObjT> operator[](const std::uint64_t index) noexcept
838 return CommonValue<LibObjT> {
839 internal::CommonArrayValueSpec<LibObjT>::elementByIndex(this->libObjPtr(), index)};
842 void append(const Value& val)
844 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
846 const auto status = bt_value_array_append_element(this->libObjPtr(), val.libObjPtr());
848 this->_handleAppendLibStatus(status);
851 void append(const bool rawVal)
853 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
856 bt_value_array_append_bool_element(this->libObjPtr(), static_cast<bt_bool>(rawVal));
858 this->_handleAppendLibStatus(status);
861 void append(const std::uint64_t rawVal)
863 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
866 bt_value_array_append_unsigned_integer_element(this->libObjPtr(), rawVal);
868 this->_handleAppendLibStatus(status);
871 void append(const std::int64_t rawVal)
873 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
875 const auto status = bt_value_array_append_signed_integer_element(this->libObjPtr(), rawVal);
877 this->_handleAppendLibStatus(status);
880 void append(const double rawVal)
882 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
884 const auto status = bt_value_array_append_real_element(this->libObjPtr(), rawVal);
886 this->_handleAppendLibStatus(status);
889 void append(const char * const rawVal)
891 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
893 const auto status = bt_value_array_append_string_element(this->libObjPtr(), rawVal);
895 this->_handleAppendLibStatus(status);
898 void append(const std::string& rawVal)
900 this->append(rawVal.data());
903 CommonArrayValue<bt_value> appendEmptyArray();
904 CommonMapValue<bt_value> appendEmptyMap();
906 void operator+=(const Value& val)
911 void operator+=(const bool rawVal)
913 this->append(rawVal);
916 void operator+=(const std::uint64_t rawVal)
918 this->append(rawVal);
921 void operator+=(const std::int64_t rawVal)
923 this->append(rawVal);
926 void operator+=(const double rawVal)
928 this->append(rawVal);
931 void operator+=(const char * const rawVal)
933 this->append(rawVal);
936 void operator+=(const std::string& rawVal)
938 this->append(rawVal);
941 Shared shared() const noexcept
943 return Shared::createWithRef(*this);
947 void _handleAppendLibStatus(const bt_value_array_append_element_status status) const
949 if (status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_MEMORY_ERROR) {
950 throw MemoryError {};
955 using ArrayValue = CommonArrayValue<bt_value>;
956 using ConstArrayValue = CommonArrayValue<const bt_value>;
960 struct ArrayValueTypeDescr
962 using Const = ConstArrayValue;
963 using NonConst = ArrayValue;
967 struct TypeDescr<ArrayValue> : public ArrayValueTypeDescr
972 struct TypeDescr<ConstArrayValue> : public ArrayValueTypeDescr
977 * Type of a user function passed to `CommonMapValue<ObjT>::forEach()`.
979 * First argument is the entry's key, second is its value.
981 template <typename ObjT>
982 using CommonMapValueForEachUserFunc = std::function<void(const bpstd::string_view&, ObjT)>;
985 * Template of a function to be passed to bt_value_map_foreach_entry()
986 * for bt_value_map_foreach_entry_const() which calls a user function.
988 * `userData` is casted to a `const` pointer to
989 * `CommonMapValueForEachUserFunc<ObjT>` (the user function to call).
991 * This function catches any exception which the user function throws
992 * and returns the `ErrorStatus` value. If there's no execption, this
993 * function returns the `OkStatus` value.
995 template <typename ObjT, typename LibObjT, typename LibStatusT, int OkStatus, int ErrorStatus>
996 LibStatusT mapValueForEachLibFunc(const char * const key, LibObjT * const libObjPtr,
997 void * const userData)
999 const auto& userFunc = *reinterpret_cast<const CommonMapValueForEachUserFunc<ObjT> *>(userData);
1002 userFunc(key, ObjT {libObjPtr});
1004 return static_cast<LibStatusT>(ErrorStatus);
1007 return static_cast<LibStatusT>(OkStatus);
1010 template <typename LibObjT>
1011 struct CommonMapValueSpec;
1013 /* Functions specific to mutable map values */
1015 struct CommonMapValueSpec<bt_value> final
1017 static bt_value *entryByKey(bt_value * const libValPtr, const char * const key) noexcept
1019 return bt_value_map_borrow_entry_value(libValPtr, key);
1022 static void forEach(bt_value * const libValPtr,
1023 const CommonMapValueForEachUserFunc<Value>& func)
1025 const auto status = bt_value_map_foreach_entry(
1027 mapValueForEachLibFunc<Value, bt_value, bt_value_map_foreach_entry_func_status,
1028 BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_OK,
1029 BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_ERROR>,
1030 const_cast<void *>(reinterpret_cast<const void *>(&func)));
1033 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_OK:
1035 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_USER_ERROR:
1036 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_ERROR:
1044 /* Functions specific to constant map values */
1046 struct CommonMapValueSpec<const bt_value> final
1048 static const bt_value *entryByKey(const bt_value * const libValPtr,
1049 const char * const key) noexcept
1051 return bt_value_map_borrow_entry_value_const(libValPtr, key);
1054 static void forEach(const bt_value * const libValPtr,
1055 const CommonMapValueForEachUserFunc<ConstValue>& func)
1057 const auto status = bt_value_map_foreach_entry_const(
1059 mapValueForEachLibFunc<ConstValue, const bt_value,
1060 bt_value_map_foreach_entry_const_func_status,
1061 BT_VALUE_MAP_FOREACH_ENTRY_CONST_FUNC_STATUS_OK,
1062 BT_VALUE_MAP_FOREACH_ENTRY_CONST_FUNC_STATUS_ERROR>,
1063 const_cast<void *>(reinterpret_cast<const void *>(&func)));
1066 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_OK:
1068 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_USER_ERROR:
1069 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_ERROR:
1077 } /* namespace internal */
1079 template <typename LibObjT>
1080 class CommonMapValue final : public CommonValue<LibObjT>
1083 using typename CommonValue<LibObjT>::_LibObjPtr;
1084 using typename CommonValue<LibObjT>::_ThisCommonValue;
1087 using Shared = internal::SharedValue<CommonMapValue<LibObjT>, LibObjT>;
1089 explicit CommonMapValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
1091 BT_ASSERT_DBG(this->isMap());
1094 static Shared create()
1096 const auto libObjPtr = bt_value_map_create();
1098 internal::validateCreatedObjPtr(libObjPtr);
1099 return CommonMapValue::Shared::createWithoutRef(libObjPtr);
1102 template <typename OtherLibObjT>
1103 CommonMapValue(const CommonMapValue<OtherLibObjT>& val) noexcept : _ThisCommonValue {val}
1107 template <typename OtherLibObjT>
1108 CommonMapValue<LibObjT>& operator=(const CommonMapValue<OtherLibObjT>& val) noexcept
1110 _ThisCommonValue::operator=(val);
1114 std::uint64_t size() const noexcept
1116 return bt_value_map_get_size(this->libObjPtr());
1119 bool isEmpty() const noexcept
1121 return this->size() == 0;
1124 nonstd::optional<ConstValue> operator[](const char * const key) const noexcept
1126 const auto libObjPtr =
1127 internal::CommonMapValueSpec<const bt_value>::entryByKey(this->libObjPtr(), key);
1130 return nonstd::nullopt;
1133 return ConstValue {libObjPtr};
1136 nonstd::optional<ConstValue> operator[](const std::string& key) const noexcept
1138 return (*this)[key.data()];
1141 nonstd::optional<CommonValue<LibObjT>> operator[](const char * const key) noexcept
1143 const auto libObjPtr =
1144 internal::CommonMapValueSpec<LibObjT>::entryByKey(this->libObjPtr(), key);
1147 return nonstd::nullopt;
1150 return CommonValue<LibObjT> {libObjPtr};
1153 nonstd::optional<CommonValue<LibObjT>> operator[](const std::string& key) noexcept
1155 return (*this)[key.data()];
1158 bool hasEntry(const char * const key) const noexcept
1160 return static_cast<bool>(bt_value_map_has_entry(this->libObjPtr(), key));
1163 bool hasEntry(const std::string& key) const noexcept
1165 return this->hasEntry(key.data());
1168 void insert(const char * const key, const Value& val)
1170 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1172 const auto status = bt_value_map_insert_entry(this->libObjPtr(), key, val.libObjPtr());
1174 this->_handleInsertLibStatus(status);
1177 void insert(const std::string& key, const Value& val)
1179 this->insert(key.data(), val);
1182 void insert(const char * const key, const bool rawVal)
1184 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1187 bt_value_map_insert_bool_entry(this->libObjPtr(), key, static_cast<bt_bool>(rawVal));
1189 this->_handleInsertLibStatus(status);
1192 void insert(const std::string& key, const bool rawVal)
1194 this->insert(key.data(), rawVal);
1197 void insert(const char * const key, const std::uint64_t rawVal)
1199 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1202 bt_value_map_insert_unsigned_integer_entry(this->libObjPtr(), key, rawVal);
1204 this->_handleInsertLibStatus(status);
1207 void insert(const std::string& key, const std::uint64_t rawVal)
1209 this->insert(key.data(), rawVal);
1212 void insert(const char * const key, const std::int64_t rawVal)
1214 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1217 bt_value_map_insert_signed_integer_entry(this->libObjPtr(), key, rawVal);
1219 this->_handleInsertLibStatus(status);
1222 void insert(const std::string& key, const std::int64_t rawVal)
1224 this->insert(key.data(), rawVal);
1227 void insert(const char * const key, const double rawVal)
1229 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1231 const auto status = bt_value_map_insert_real_entry(this->libObjPtr(), key, rawVal);
1233 this->_handleInsertLibStatus(status);
1236 void insert(const std::string& key, const double rawVal)
1238 this->insert(key.data(), rawVal);
1241 void insert(const char * const key, const char * const rawVal)
1243 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1245 const auto status = bt_value_map_insert_string_entry(this->libObjPtr(), key, rawVal);
1247 this->_handleInsertLibStatus(status);
1250 void insert(const char * const key, const std::string& rawVal)
1252 this->insert(key, rawVal.data());
1255 void insert(const std::string& key, const char * const rawVal)
1257 this->insert(key.data(), rawVal);
1260 void insert(const std::string& key, const std::string& rawVal)
1262 this->insert(key.data(), rawVal.data());
1265 CommonArrayValue<bt_value> insertEmptyArray(const char *key);
1266 CommonArrayValue<bt_value> insertEmptyArray(const std::string& key);
1267 CommonMapValue<bt_value> insertEmptyMap(const char *key);
1268 CommonMapValue<bt_value> insertEmptyMap(const std::string& key);
1270 void forEach(const internal::CommonMapValueForEachUserFunc<ConstValue>& func) const
1272 internal::CommonMapValueSpec<const bt_value>::forEach(this->libObjPtr(), func);
1275 void forEach(const internal::CommonMapValueForEachUserFunc<CommonValue<LibObjT>>& func)
1277 internal::CommonMapValueSpec<LibObjT>::forEach(this->libObjPtr(), func);
1280 Shared shared() const noexcept
1282 return Shared::createWithRef(*this);
1286 void _handleInsertLibStatus(const bt_value_map_insert_entry_status status) const
1288 if (status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_MEMORY_ERROR) {
1289 throw MemoryError {};
1294 using MapValue = CommonMapValue<bt_value>;
1295 using ConstMapValue = CommonMapValue<const bt_value>;
1297 namespace internal {
1299 struct MapValueTypeDescr
1301 using Const = ConstMapValue;
1302 using NonConst = MapValue;
1306 struct TypeDescr<MapValue> : public MapValueTypeDescr
1311 struct TypeDescr<ConstMapValue> : public MapValueTypeDescr
1315 } /* namespace internal */
1317 template <typename LibObjT>
1318 CommonNullValue<LibObjT> CommonValue<LibObjT>::asNull() const noexcept
1320 BT_ASSERT_DBG(this->isNull());
1321 return CommonNullValue<LibObjT> {this->libObjPtr()};
1324 template <typename LibObjT>
1325 CommonBoolValue<LibObjT> CommonValue<LibObjT>::asBool() const noexcept
1327 BT_ASSERT_DBG(this->isBool());
1328 return CommonBoolValue<LibObjT> {this->libObjPtr()};
1331 template <typename LibObjT>
1332 CommonSignedIntegerValue<LibObjT> CommonValue<LibObjT>::asSignedInteger() const noexcept
1334 BT_ASSERT_DBG(this->isSignedInteger());
1335 return CommonSignedIntegerValue<LibObjT> {this->libObjPtr()};
1338 template <typename LibObjT>
1339 CommonUnsignedIntegerValue<LibObjT> CommonValue<LibObjT>::asUnsignedInteger() const noexcept
1341 BT_ASSERT_DBG(this->isUnsignedInteger());
1342 return CommonUnsignedIntegerValue<LibObjT> {this->libObjPtr()};
1345 template <typename LibObjT>
1346 CommonRealValue<LibObjT> CommonValue<LibObjT>::asReal() const noexcept
1348 BT_ASSERT_DBG(this->isReal());
1349 return CommonRealValue<LibObjT> {this->libObjPtr()};
1352 template <typename LibObjT>
1353 CommonStringValue<LibObjT> CommonValue<LibObjT>::asString() const noexcept
1355 BT_ASSERT_DBG(this->isString());
1356 return CommonStringValue<LibObjT> {this->libObjPtr()};
1359 template <typename LibObjT>
1360 CommonArrayValue<LibObjT> CommonValue<LibObjT>::asArray() const noexcept
1362 BT_ASSERT_DBG(this->isArray());
1363 return CommonArrayValue<LibObjT> {this->libObjPtr()};
1366 template <typename LibObjT>
1367 CommonMapValue<LibObjT> CommonValue<LibObjT>::asMap() const noexcept
1369 BT_ASSERT_DBG(this->isMap());
1370 return CommonMapValue<LibObjT> {this->libObjPtr()};
1373 template <typename LibObjT>
1374 ArrayValue CommonArrayValue<LibObjT>::appendEmptyArray()
1376 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1378 bt_value *libElemPtr;
1379 const auto status = bt_value_array_append_empty_array_element(this->libObjPtr(), &libElemPtr);
1381 this->_handleAppendLibStatus(status);
1382 return ArrayValue {libElemPtr};
1385 template <typename LibObjT>
1386 MapValue CommonArrayValue<LibObjT>::appendEmptyMap()
1388 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1390 bt_value *libElemPtr;
1391 const auto status = bt_value_array_append_empty_map_element(this->libObjPtr(), &libElemPtr);
1393 this->_handleAppendLibStatus(status);
1394 return MapValue {libElemPtr};
1397 template <typename LibObjT>
1398 ArrayValue CommonMapValue<LibObjT>::insertEmptyArray(const char * const key)
1400 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1402 bt_value *libEntryPtr;
1403 const auto status = bt_value_map_insert_empty_array_entry(this->libObjPtr(), key, &libEntryPtr);
1405 this->_handleInsertLibStatus(status);
1406 return ArrayValue {libEntryPtr};
1409 template <typename LibObjT>
1410 ArrayValue CommonMapValue<LibObjT>::insertEmptyArray(const std::string& key)
1412 return this->insertEmptyArray(key.data());
1415 template <typename LibObjT>
1416 MapValue CommonMapValue<LibObjT>::insertEmptyMap(const char * const key)
1418 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1420 bt_value *libEntryPtr;
1421 const auto status = bt_value_map_insert_empty_map_entry(this->libObjPtr(), key, &libEntryPtr);
1423 this->_handleInsertLibStatus(status);
1424 return MapValue {libEntryPtr};
1427 template <typename LibObjT>
1428 MapValue CommonMapValue<LibObjT>::insertEmptyMap(const std::string& key)
1430 return this->insertEmptyMap(key.data());
1433 inline BoolValue::Shared createValue(const bool rawVal)
1435 return BoolValue::create(rawVal);
1438 inline UnsignedIntegerValue::Shared createValue(const std::uint64_t rawVal)
1440 return UnsignedIntegerValue::create(rawVal);
1443 inline SignedIntegerValue::Shared createValue(const std::int64_t rawVal)
1445 return SignedIntegerValue::create(rawVal);
1448 inline RealValue::Shared createValue(const double rawVal)
1450 return RealValue::create(rawVal);
1453 inline StringValue::Shared createValue(const char * const rawVal)
1455 return StringValue::create(rawVal);
1458 inline StringValue::Shared createValue(const std::string& rawVal)
1460 return StringValue::create(rawVal);
1463 } /* namespace bt2 */
1465 #endif /* BABELTRACE_CPP_COMMON_BT2_VALUE_HPP */