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
13 #include <type_traits>
15 #include <babeltrace2/babeltrace.h>
17 #include "common/assert.h"
18 #include "common/common.h"
19 #include "cpp-common/optional.hpp"
20 #include "cpp-common/string_view.hpp"
22 #include "common-iter.hpp"
24 #include "internal/borrowed-obj.hpp"
25 #include "internal/shared-obj.hpp"
26 #include "internal/utils.hpp"
31 struct ValueRefFuncs final
33 static void get(const bt_value * const libObjPtr)
35 bt_value_get_ref(libObjPtr);
38 static void put(const bt_value * const libObjPtr)
40 bt_value_put_ref(libObjPtr);
44 template <typename ObjT, typename LibObjT>
45 using SharedValue = internal::SharedObj<ObjT, LibObjT, internal::ValueRefFuncs>;
47 } /* namespace internal */
49 template <typename LibObjT>
50 class CommonNullValue;
52 template <typename LibObjT>
53 class CommonBoolValue;
55 template <typename LibObjT>
56 class CommonUnsignedIntegerValue;
58 template <typename LibObjT>
59 class CommonSignedIntegerValue;
61 template <typename LibObjT>
62 class CommonRealValue;
64 template <typename LibObjT>
65 class CommonStringValue;
67 template <typename LibObjT>
68 class CommonArrayValue;
70 template <typename LibObjT>
75 NUL = BT_VALUE_TYPE_NULL,
76 BOOL = BT_VALUE_TYPE_BOOL,
77 UNSIGNED_INTEGER = BT_VALUE_TYPE_UNSIGNED_INTEGER,
78 SIGNED_INTEGER = BT_VALUE_TYPE_SIGNED_INTEGER,
79 REAL = BT_VALUE_TYPE_REAL,
80 STRING = BT_VALUE_TYPE_STRING,
81 ARRAY = BT_VALUE_TYPE_ARRAY,
82 MAP = BT_VALUE_TYPE_MAP,
85 template <typename LibObjT>
86 class CommonClockClass;
88 template <typename LibObjT>
89 class CommonFieldClass;
91 template <typename LibObjT>
92 class CommonTraceClass;
94 template <typename LibObjT>
95 class CommonStreamClass;
97 template <typename LibObjT>
98 class CommonEventClass;
100 template <typename LibObjT>
103 template <typename LibObjT>
104 class CommonValue : public internal::BorrowedObj<LibObjT>
106 /* Allow append() to call `val.libObjPtr()` */
107 friend class CommonArrayValue<bt_value>;
109 /* Allow insert() to call `val.libObjPtr()` */
110 friend class CommonMapValue<bt_value>;
112 /* Allow userAttributes() to call `val.libObjPtr()` */
113 friend class CommonClockClass<bt_clock_class>;
114 friend class CommonFieldClass<bt_field_class>;
115 friend class CommonTraceClass<bt_trace_class>;
116 friend class CommonStreamClass<bt_stream_class>;
117 friend class CommonEventClass<bt_event_class>;
118 friend class CommonStream<bt_stream>;
120 /* Allow operator==() to call `other.libObjPtr()` */
121 friend class CommonValue<bt_value>;
122 friend class CommonValue<const bt_value>;
125 using typename internal::BorrowedObj<LibObjT>::_ThisBorrowedObj;
128 using typename internal::BorrowedObj<LibObjT>::_LibObjPtr;
129 using _ThisCommonValue = CommonValue<LibObjT>;
132 using Shared = internal::SharedValue<CommonValue<LibObjT>, LibObjT>;
134 explicit CommonValue(const _LibObjPtr libObjPtr) noexcept : _ThisBorrowedObj {libObjPtr}
138 template <typename OtherLibObjT>
139 CommonValue(const CommonValue<OtherLibObjT> val) noexcept : _ThisBorrowedObj {val}
143 template <typename OtherLibObjT>
144 _ThisCommonValue& operator=(const CommonValue<OtherLibObjT> val) noexcept
146 _ThisBorrowedObj::operator=(val);
150 ValueType type() const noexcept
152 return static_cast<ValueType>(bt_value_get_type(this->libObjPtr()));
155 bool isNull() const noexcept
157 return this->_libTypeIs(BT_VALUE_TYPE_NULL);
160 bool isBool() const noexcept
162 return this->_libTypeIs(BT_VALUE_TYPE_BOOL);
165 bool isInteger() const noexcept
167 return this->_libTypeIs(BT_VALUE_TYPE_INTEGER);
170 bool isUnsignedInteger() const noexcept
172 return this->_libTypeIs(BT_VALUE_TYPE_UNSIGNED_INTEGER);
175 bool isSignedInteger() const noexcept
177 return this->_libTypeIs(BT_VALUE_TYPE_SIGNED_INTEGER);
180 bool isReal() const noexcept
182 return this->_libTypeIs(BT_VALUE_TYPE_REAL);
185 bool isString() const noexcept
187 return this->_libTypeIs(BT_VALUE_TYPE_STRING);
190 bool isArray() const noexcept
192 return this->_libTypeIs(BT_VALUE_TYPE_ARRAY);
195 bool isMap() const noexcept
197 return this->_libTypeIs(BT_VALUE_TYPE_MAP);
200 template <typename OtherLibObjT>
201 bool operator==(const CommonValue<OtherLibObjT> other) const noexcept
203 return static_cast<bool>(bt_value_is_equal(this->libObjPtr(), other.libObjPtr()));
206 template <typename OtherLibObjT>
207 bool operator!=(const CommonValue<OtherLibObjT> other) const noexcept
209 return !(*this == other);
212 Shared shared() const noexcept
214 return Shared::createWithRef(*this);
217 template <typename ValueT>
218 ValueT as() const noexcept
220 return ValueT {this->libObjPtr()};
223 CommonNullValue<LibObjT> asNull() const noexcept;
224 CommonBoolValue<LibObjT> asBool() const noexcept;
225 CommonSignedIntegerValue<LibObjT> asSignedInteger() const noexcept;
226 CommonUnsignedIntegerValue<LibObjT> asUnsignedInteger() const noexcept;
227 CommonRealValue<LibObjT> asReal() const noexcept;
228 CommonStringValue<LibObjT> asString() const noexcept;
229 CommonArrayValue<LibObjT> asArray() const noexcept;
230 CommonMapValue<LibObjT> asMap() const noexcept;
233 bool _libTypeIs(const bt_value_type type) const noexcept
235 return bt_value_type_is(bt_value_get_type(this->libObjPtr()), type);
239 using Value = CommonValue<bt_value>;
240 using ConstValue = CommonValue<const bt_value>;
244 struct ValueTypeDescr
246 using Const = ConstValue;
247 using NonConst = Value;
251 struct TypeDescr<Value> : public ValueTypeDescr
256 struct TypeDescr<ConstValue> : public ValueTypeDescr
260 } /* namespace internal */
262 template <typename LibObjT>
263 class CommonNullValue final : public CommonValue<LibObjT>
266 using typename CommonValue<LibObjT>::_ThisCommonValue;
269 using Shared = internal::SharedValue<CommonNullValue<LibObjT>, LibObjT>;
271 CommonNullValue() noexcept : _ThisCommonValue {bt_value_null}
275 template <typename OtherLibObjT>
276 CommonNullValue(const CommonNullValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
280 template <typename OtherLibObjT>
281 CommonNullValue<LibObjT>& operator=(const CommonNullValue<OtherLibObjT> val) noexcept
283 _ThisCommonValue::operator=(val);
287 Shared shared() const noexcept
289 return Shared::createWithRef(*this);
293 using NullValue = CommonNullValue<bt_value>;
294 using ConstNullValue = CommonNullValue<const bt_value>;
298 struct NullValueTypeDescr
300 using Const = ConstNullValue;
301 using NonConst = NullValue;
305 struct TypeDescr<NullValue> : public NullValueTypeDescr
310 struct TypeDescr<ConstNullValue> : public NullValueTypeDescr
314 } /* namespace internal */
316 template <typename LibObjT>
317 class CommonBoolValue final : public CommonValue<LibObjT>
320 using typename CommonValue<LibObjT>::_LibObjPtr;
321 using typename CommonValue<LibObjT>::_ThisCommonValue;
324 using Shared = internal::SharedValue<CommonBoolValue<LibObjT>, LibObjT>;
327 explicit CommonBoolValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
329 BT_ASSERT_DBG(this->isBool());
332 template <typename OtherLibObjT>
333 CommonBoolValue(const CommonBoolValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
337 static Shared create(const Value rawVal = false)
339 const auto libObjPtr = bt_value_bool_create_init(static_cast<bt_bool>(rawVal));
341 internal::validateCreatedObjPtr(libObjPtr);
342 return CommonBoolValue::Shared::createWithoutRef(libObjPtr);
345 template <typename OtherLibObjT>
346 CommonBoolValue<LibObjT>& operator=(const CommonBoolValue<OtherLibObjT> val) noexcept
348 _ThisCommonValue::operator=(val);
352 CommonBoolValue<LibObjT>& operator=(const Value rawVal) noexcept
354 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
356 bt_value_bool_set(this->libObjPtr(), static_cast<bt_bool>(rawVal));
360 Value value() const noexcept
362 return static_cast<Value>(bt_value_bool_get(this->libObjPtr()));
365 operator Value() const noexcept
367 return this->value();
370 Shared shared() const noexcept
372 return Shared::createWithRef(*this);
376 using BoolValue = CommonBoolValue<bt_value>;
377 using ConstBoolValue = CommonBoolValue<const bt_value>;
381 struct BoolValueTypeDescr
383 using Const = ConstBoolValue;
384 using NonConst = BoolValue;
388 struct TypeDescr<BoolValue> : public BoolValueTypeDescr
393 struct TypeDescr<ConstBoolValue> : public BoolValueTypeDescr
397 } /* namespace internal */
399 template <typename LibObjT>
400 class CommonUnsignedIntegerValue final : public CommonValue<LibObjT>
403 using typename CommonValue<LibObjT>::_LibObjPtr;
404 using typename CommonValue<LibObjT>::_ThisCommonValue;
407 using Shared = internal::SharedValue<CommonUnsignedIntegerValue<LibObjT>, LibObjT>;
408 using Value = std::uint64_t;
410 explicit CommonUnsignedIntegerValue(const _LibObjPtr libObjPtr) noexcept :
411 _ThisCommonValue {libObjPtr}
413 BT_ASSERT_DBG(this->isUnsignedInteger());
416 static Shared create(const Value rawVal = 0)
418 const auto libObjPtr = bt_value_integer_unsigned_create_init(rawVal);
420 internal::validateCreatedObjPtr(libObjPtr);
421 return CommonUnsignedIntegerValue::Shared::createWithoutRef(libObjPtr);
424 template <typename OtherLibObjT>
425 CommonUnsignedIntegerValue(const CommonUnsignedIntegerValue<OtherLibObjT> val) noexcept :
426 _ThisCommonValue {val}
430 template <typename OtherLibObjT>
431 CommonUnsignedIntegerValue<LibObjT>&
432 operator=(const CommonUnsignedIntegerValue<OtherLibObjT> val) noexcept
434 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
436 _ThisCommonValue::operator=(val);
440 CommonUnsignedIntegerValue<LibObjT>& operator=(const Value rawVal) noexcept
442 bt_value_integer_unsigned_set(this->libObjPtr(), rawVal);
446 Value value() const noexcept
448 return bt_value_integer_unsigned_get(this->libObjPtr());
451 operator Value() const noexcept
453 return this->value();
456 Shared shared() const noexcept
458 return Shared::createWithRef(*this);
462 using UnsignedIntegerValue = CommonUnsignedIntegerValue<bt_value>;
463 using ConstUnsignedIntegerValue = CommonUnsignedIntegerValue<const bt_value>;
467 struct UnsignedIntegerValueTypeDescr
469 using Const = ConstUnsignedIntegerValue;
470 using NonConst = UnsignedIntegerValue;
474 struct TypeDescr<UnsignedIntegerValue> : public UnsignedIntegerValueTypeDescr
479 struct TypeDescr<ConstUnsignedIntegerValue> : public UnsignedIntegerValueTypeDescr
483 } /* namespace internal */
485 template <typename LibObjT>
486 class CommonSignedIntegerValue final : public CommonValue<LibObjT>
489 using typename CommonValue<LibObjT>::_LibObjPtr;
490 using typename CommonValue<LibObjT>::_ThisCommonValue;
493 using Shared = internal::SharedValue<CommonSignedIntegerValue<LibObjT>, LibObjT>;
494 using Value = std::int64_t;
496 explicit CommonSignedIntegerValue(const _LibObjPtr libObjPtr) noexcept :
497 _ThisCommonValue {libObjPtr}
499 BT_ASSERT_DBG(this->isSignedInteger());
502 static Shared create(const Value rawVal = 0)
504 const auto libObjPtr = bt_value_integer_signed_create_init(rawVal);
506 internal::validateCreatedObjPtr(libObjPtr);
507 return CommonSignedIntegerValue::Shared::createWithoutRef(libObjPtr);
510 template <typename OtherLibObjT>
511 CommonSignedIntegerValue(const CommonSignedIntegerValue<OtherLibObjT> val) noexcept :
512 _ThisCommonValue {val}
516 template <typename OtherLibObjT>
517 CommonSignedIntegerValue<LibObjT>&
518 operator=(const CommonSignedIntegerValue<OtherLibObjT> val) noexcept
520 _ThisCommonValue::operator=(val);
524 CommonSignedIntegerValue<LibObjT>& operator=(const Value rawVal) noexcept
526 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
528 bt_value_integer_signed_set(this->libObjPtr(), rawVal);
532 Value value() const noexcept
534 return bt_value_integer_signed_get(this->libObjPtr());
537 operator Value() const noexcept
539 return this->value();
542 Shared shared() const noexcept
544 return Shared::createWithRef(*this);
548 using SignedIntegerValue = CommonSignedIntegerValue<bt_value>;
549 using ConstSignedIntegerValue = CommonSignedIntegerValue<const bt_value>;
553 struct SignedIntegerValueTypeDescr
555 using Const = ConstSignedIntegerValue;
556 using NonConst = SignedIntegerValue;
560 struct TypeDescr<SignedIntegerValue> : public SignedIntegerValueTypeDescr
565 struct TypeDescr<ConstSignedIntegerValue> : public SignedIntegerValueTypeDescr
569 } /* namespace internal */
571 template <typename LibObjT>
572 class CommonRealValue final : public CommonValue<LibObjT>
575 using typename CommonValue<LibObjT>::_LibObjPtr;
576 using typename CommonValue<LibObjT>::_ThisCommonValue;
579 using Shared = internal::SharedValue<CommonRealValue<LibObjT>, LibObjT>;
580 using Value = double;
582 explicit CommonRealValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
584 BT_ASSERT_DBG(this->isReal());
587 static Shared create(const Value rawVal = 0)
589 const auto libObjPtr = bt_value_real_create_init(rawVal);
591 internal::validateCreatedObjPtr(libObjPtr);
592 return CommonRealValue::Shared::createWithoutRef(libObjPtr);
595 template <typename OtherLibObjT>
596 CommonRealValue(const CommonRealValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
600 template <typename OtherLibObjT>
601 CommonRealValue<LibObjT>& operator=(const CommonRealValue<OtherLibObjT> val) noexcept
603 _ThisCommonValue::operator=(val);
607 CommonRealValue<LibObjT>& operator=(const Value rawVal) noexcept
609 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
611 bt_value_real_set(this->libObjPtr(), rawVal);
615 Value value() const noexcept
617 return bt_value_real_get(this->libObjPtr());
620 operator Value() const noexcept
622 return this->value();
625 Shared shared() const noexcept
627 return Shared::createWithRef(*this);
631 using RealValue = CommonRealValue<bt_value>;
632 using ConstRealValue = CommonRealValue<const bt_value>;
636 struct RealValueTypeDescr
638 using Const = ConstRealValue;
639 using NonConst = RealValue;
643 struct TypeDescr<RealValue> : public RealValueTypeDescr
648 struct TypeDescr<ConstRealValue> : public RealValueTypeDescr
652 } /* namespace internal */
654 template <typename LibObjT>
655 class CommonStringValue final : public CommonValue<LibObjT>
658 using typename CommonValue<LibObjT>::_LibObjPtr;
659 using typename CommonValue<LibObjT>::_ThisCommonValue;
662 using Shared = internal::SharedValue<CommonStringValue<LibObjT>, LibObjT>;
664 explicit CommonStringValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
666 BT_ASSERT_DBG(this->isString());
669 static Shared create(const char * const rawVal = "")
671 const auto libObjPtr = bt_value_string_create_init(rawVal);
673 internal::validateCreatedObjPtr(libObjPtr);
674 return CommonStringValue::Shared::createWithoutRef(libObjPtr);
677 static Shared create(const std::string& rawVal)
679 return CommonStringValue::create(rawVal.data());
682 template <typename OtherLibObjT>
683 CommonStringValue(const CommonStringValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
687 template <typename OtherLibObjT>
688 CommonStringValue<LibObjT>& operator=(const CommonStringValue<OtherLibObjT> val) noexcept
690 _ThisCommonValue::operator=(val);
694 CommonStringValue<LibObjT>& operator=(const char * const rawVal)
696 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
698 const auto status = bt_value_string_set(this->libObjPtr(), rawVal);
700 if (status == BT_VALUE_STRING_SET_STATUS_MEMORY_ERROR) {
701 throw MemoryError {};
707 CommonStringValue<LibObjT>& operator=(const std::string& rawVal) noexcept
709 return *this = rawVal.data();
712 bpstd::string_view value() const noexcept
714 return bt_value_string_get(this->libObjPtr());
717 Shared shared() const noexcept
719 return Shared::createWithRef(*this);
723 using StringValue = CommonStringValue<bt_value>;
724 using ConstStringValue = CommonStringValue<const bt_value>;
728 struct StringValueTypeDescr
730 using Const = ConstStringValue;
731 using NonConst = StringValue;
735 struct TypeDescr<StringValue> : public StringValueTypeDescr
740 struct TypeDescr<ConstStringValue> : public StringValueTypeDescr
744 template <typename LibObjT>
745 struct CommonArrayValueSpec;
747 /* Functions specific to mutable array values */
749 struct CommonArrayValueSpec<bt_value> final
751 static bt_value *elementByIndex(bt_value * const libValPtr, const std::uint64_t index) noexcept
753 return bt_value_array_borrow_element_by_index(libValPtr, index);
757 /* Functions specific to constant array values */
759 struct CommonArrayValueSpec<const bt_value> final
761 static const bt_value *elementByIndex(const bt_value * const libValPtr,
762 const std::uint64_t index) noexcept
764 return bt_value_array_borrow_element_by_index_const(libValPtr, index);
768 } /* namespace internal */
770 template <typename LibObjT>
771 class CommonArrayValue final : public CommonValue<LibObjT>
774 using typename CommonValue<LibObjT>::_LibObjPtr;
775 using typename CommonValue<LibObjT>::_ThisCommonValue;
778 using Shared = internal::SharedValue<CommonArrayValue<LibObjT>, LibObjT>;
779 using Iterator = CommonIterator<CommonArrayValue<LibObjT>, CommonValue<LibObjT>>;
781 explicit CommonArrayValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
783 BT_ASSERT_DBG(this->isArray());
786 static Shared create()
788 const auto libObjPtr = bt_value_array_create();
790 internal::validateCreatedObjPtr(libObjPtr);
791 return CommonArrayValue::Shared::createWithoutRef(libObjPtr);
794 template <typename OtherLibObjT>
795 CommonArrayValue(const CommonArrayValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
799 template <typename OtherLibObjT>
800 CommonArrayValue<LibObjT>& operator=(const CommonArrayValue<OtherLibObjT> val) noexcept
802 _ThisCommonValue::operator=(val);
806 std::uint64_t length() const noexcept
808 return bt_value_array_get_length(this->libObjPtr());
811 /* Required by the `CommonIterator` template class */
812 std::uint64_t size() const noexcept
814 return this->length();
817 Iterator begin() const noexcept
819 return Iterator {*this, 0};
822 Iterator end() const noexcept
824 return Iterator {*this, this->length()};
827 bool isEmpty() const noexcept
829 return this->length() == 0;
832 ConstValue operator[](const std::uint64_t index) const noexcept
834 return ConstValue {internal::CommonArrayValueSpec<const bt_value>::elementByIndex(
835 this->libObjPtr(), index)};
838 CommonValue<LibObjT> operator[](const std::uint64_t index) noexcept
840 return CommonValue<LibObjT> {
841 internal::CommonArrayValueSpec<LibObjT>::elementByIndex(this->libObjPtr(), index)};
844 void append(const Value val)
846 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
848 const auto status = bt_value_array_append_element(this->libObjPtr(), val.libObjPtr());
850 this->_handleAppendLibStatus(status);
853 void append(const bool rawVal)
855 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
858 bt_value_array_append_bool_element(this->libObjPtr(), static_cast<bt_bool>(rawVal));
860 this->_handleAppendLibStatus(status);
863 void append(const std::uint64_t rawVal)
865 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
868 bt_value_array_append_unsigned_integer_element(this->libObjPtr(), rawVal);
870 this->_handleAppendLibStatus(status);
873 void append(const std::int64_t rawVal)
875 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
877 const auto status = bt_value_array_append_signed_integer_element(this->libObjPtr(), rawVal);
879 this->_handleAppendLibStatus(status);
882 void append(const double rawVal)
884 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
886 const auto status = bt_value_array_append_real_element(this->libObjPtr(), rawVal);
888 this->_handleAppendLibStatus(status);
891 void append(const char * const rawVal)
893 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
895 const auto status = bt_value_array_append_string_element(this->libObjPtr(), rawVal);
897 this->_handleAppendLibStatus(status);
900 void append(const std::string& rawVal)
902 this->append(rawVal.data());
905 CommonArrayValue<bt_value> appendEmptyArray();
906 CommonMapValue<bt_value> appendEmptyMap();
908 void operator+=(const Value val)
913 void operator+=(const bool rawVal)
915 this->append(rawVal);
918 void operator+=(const std::uint64_t rawVal)
920 this->append(rawVal);
923 void operator+=(const std::int64_t rawVal)
925 this->append(rawVal);
928 void operator+=(const double rawVal)
930 this->append(rawVal);
933 void operator+=(const char * const rawVal)
935 this->append(rawVal);
938 void operator+=(const std::string& rawVal)
940 this->append(rawVal);
943 Shared shared() const noexcept
945 return Shared::createWithRef(*this);
949 void _handleAppendLibStatus(const bt_value_array_append_element_status status) const
951 if (status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_MEMORY_ERROR) {
952 throw MemoryError {};
957 using ArrayValue = CommonArrayValue<bt_value>;
958 using ConstArrayValue = CommonArrayValue<const bt_value>;
962 struct ArrayValueTypeDescr
964 using Const = ConstArrayValue;
965 using NonConst = ArrayValue;
969 struct TypeDescr<ArrayValue> : public ArrayValueTypeDescr
974 struct TypeDescr<ConstArrayValue> : public ArrayValueTypeDescr
979 * Type of a user function passed to `CommonMapValue<ObjT>::forEach()`.
981 * First argument is the entry's key, second is its value.
983 template <typename ObjT>
984 using CommonMapValueForEachUserFunc = std::function<void(const bpstd::string_view&, ObjT)>;
987 * Template of a function to be passed to bt_value_map_foreach_entry()
988 * for bt_value_map_foreach_entry_const() which calls a user function.
990 * `userData` is casted to a `const` pointer to
991 * `CommonMapValueForEachUserFunc<ObjT>` (the user function to call).
993 * This function catches any exception which the user function throws
994 * and returns the `ErrorStatus` value. If there's no execption, this
995 * function returns the `OkStatus` value.
997 template <typename ObjT, typename LibObjT, typename LibStatusT, int OkStatus, int ErrorStatus>
998 LibStatusT mapValueForEachLibFunc(const char * const key, LibObjT * const libObjPtr,
999 void * const userData)
1001 const auto& userFunc = *reinterpret_cast<const CommonMapValueForEachUserFunc<ObjT> *>(userData);
1004 userFunc(key, ObjT {libObjPtr});
1006 return static_cast<LibStatusT>(ErrorStatus);
1009 return static_cast<LibStatusT>(OkStatus);
1012 template <typename LibObjT>
1013 struct CommonMapValueSpec;
1015 /* Functions specific to mutable map values */
1017 struct CommonMapValueSpec<bt_value> final
1019 static bt_value *entryByKey(bt_value * const libValPtr, const char * const key) noexcept
1021 return bt_value_map_borrow_entry_value(libValPtr, key);
1024 static void forEach(bt_value * const libValPtr,
1025 const CommonMapValueForEachUserFunc<Value>& func)
1027 const auto status = bt_value_map_foreach_entry(
1029 mapValueForEachLibFunc<Value, bt_value, bt_value_map_foreach_entry_func_status,
1030 BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_OK,
1031 BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_ERROR>,
1032 const_cast<void *>(reinterpret_cast<const void *>(&func)));
1035 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_OK:
1037 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_USER_ERROR:
1038 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_ERROR:
1046 /* Functions specific to constant map values */
1048 struct CommonMapValueSpec<const bt_value> final
1050 static const bt_value *entryByKey(const bt_value * const libValPtr,
1051 const char * const key) noexcept
1053 return bt_value_map_borrow_entry_value_const(libValPtr, key);
1056 static void forEach(const bt_value * const libValPtr,
1057 const CommonMapValueForEachUserFunc<ConstValue>& func)
1059 const auto status = bt_value_map_foreach_entry_const(
1061 mapValueForEachLibFunc<ConstValue, const bt_value,
1062 bt_value_map_foreach_entry_const_func_status,
1063 BT_VALUE_MAP_FOREACH_ENTRY_CONST_FUNC_STATUS_OK,
1064 BT_VALUE_MAP_FOREACH_ENTRY_CONST_FUNC_STATUS_ERROR>,
1065 const_cast<void *>(reinterpret_cast<const void *>(&func)));
1068 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_OK:
1070 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_USER_ERROR:
1071 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_ERROR:
1079 } /* namespace internal */
1081 template <typename LibObjT>
1082 class CommonMapValue final : public CommonValue<LibObjT>
1085 using typename CommonValue<LibObjT>::_LibObjPtr;
1086 using typename CommonValue<LibObjT>::_ThisCommonValue;
1089 using Shared = internal::SharedValue<CommonMapValue<LibObjT>, LibObjT>;
1091 explicit CommonMapValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
1093 BT_ASSERT_DBG(this->isMap());
1096 static Shared create()
1098 const auto libObjPtr = bt_value_map_create();
1100 internal::validateCreatedObjPtr(libObjPtr);
1101 return CommonMapValue::Shared::createWithoutRef(libObjPtr);
1104 template <typename OtherLibObjT>
1105 CommonMapValue(const CommonMapValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
1109 template <typename OtherLibObjT>
1110 CommonMapValue<LibObjT>& operator=(const CommonMapValue<OtherLibObjT> val) noexcept
1112 _ThisCommonValue::operator=(val);
1116 std::uint64_t size() const noexcept
1118 return bt_value_map_get_size(this->libObjPtr());
1121 bool isEmpty() const noexcept
1123 return this->size() == 0;
1126 nonstd::optional<ConstValue> operator[](const char * const key) const noexcept
1128 const auto libObjPtr =
1129 internal::CommonMapValueSpec<const bt_value>::entryByKey(this->libObjPtr(), key);
1132 return nonstd::nullopt;
1135 return ConstValue {libObjPtr};
1138 nonstd::optional<ConstValue> operator[](const std::string& key) const noexcept
1140 return (*this)[key.data()];
1143 nonstd::optional<CommonValue<LibObjT>> operator[](const char * const key) noexcept
1145 const auto libObjPtr =
1146 internal::CommonMapValueSpec<LibObjT>::entryByKey(this->libObjPtr(), key);
1149 return nonstd::nullopt;
1152 return CommonValue<LibObjT> {libObjPtr};
1155 nonstd::optional<CommonValue<LibObjT>> operator[](const std::string& key) noexcept
1157 return (*this)[key.data()];
1160 bool hasEntry(const char * const key) const noexcept
1162 return static_cast<bool>(bt_value_map_has_entry(this->libObjPtr(), key));
1165 bool hasEntry(const std::string& key) const noexcept
1167 return this->hasEntry(key.data());
1170 void insert(const char * const key, const Value val)
1172 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1174 const auto status = bt_value_map_insert_entry(this->libObjPtr(), key, val.libObjPtr());
1176 this->_handleInsertLibStatus(status);
1179 void insert(const std::string& key, const Value val)
1181 this->insert(key.data(), val);
1184 void insert(const char * const key, const bool rawVal)
1186 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1189 bt_value_map_insert_bool_entry(this->libObjPtr(), key, static_cast<bt_bool>(rawVal));
1191 this->_handleInsertLibStatus(status);
1194 void insert(const std::string& key, const bool rawVal)
1196 this->insert(key.data(), rawVal);
1199 void insert(const char * const key, const std::uint64_t rawVal)
1201 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1204 bt_value_map_insert_unsigned_integer_entry(this->libObjPtr(), key, rawVal);
1206 this->_handleInsertLibStatus(status);
1209 void insert(const std::string& key, const std::uint64_t rawVal)
1211 this->insert(key.data(), rawVal);
1214 void insert(const char * const key, const std::int64_t rawVal)
1216 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1219 bt_value_map_insert_signed_integer_entry(this->libObjPtr(), key, rawVal);
1221 this->_handleInsertLibStatus(status);
1224 void insert(const std::string& key, const std::int64_t rawVal)
1226 this->insert(key.data(), rawVal);
1229 void insert(const char * const key, const double rawVal)
1231 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1233 const auto status = bt_value_map_insert_real_entry(this->libObjPtr(), key, rawVal);
1235 this->_handleInsertLibStatus(status);
1238 void insert(const std::string& key, const double rawVal)
1240 this->insert(key.data(), rawVal);
1243 void insert(const char * const key, const char * const rawVal)
1245 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1247 const auto status = bt_value_map_insert_string_entry(this->libObjPtr(), key, rawVal);
1249 this->_handleInsertLibStatus(status);
1252 void insert(const char * const key, const std::string& rawVal)
1254 this->insert(key, rawVal.data());
1257 void insert(const std::string& key, const char * const rawVal)
1259 this->insert(key.data(), rawVal);
1262 void insert(const std::string& key, const std::string& rawVal)
1264 this->insert(key.data(), rawVal.data());
1267 CommonArrayValue<bt_value> insertEmptyArray(const char *key);
1268 CommonArrayValue<bt_value> insertEmptyArray(const std::string& key);
1269 CommonMapValue<bt_value> insertEmptyMap(const char *key);
1270 CommonMapValue<bt_value> insertEmptyMap(const std::string& key);
1272 void forEach(const internal::CommonMapValueForEachUserFunc<ConstValue>& func) const
1274 internal::CommonMapValueSpec<const bt_value>::forEach(this->libObjPtr(), func);
1277 void forEach(const internal::CommonMapValueForEachUserFunc<CommonValue<LibObjT>>& func)
1279 internal::CommonMapValueSpec<LibObjT>::forEach(this->libObjPtr(), func);
1282 Shared shared() const noexcept
1284 return Shared::createWithRef(*this);
1288 void _handleInsertLibStatus(const bt_value_map_insert_entry_status status) const
1290 if (status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_MEMORY_ERROR) {
1291 throw MemoryError {};
1296 using MapValue = CommonMapValue<bt_value>;
1297 using ConstMapValue = CommonMapValue<const bt_value>;
1299 namespace internal {
1301 struct MapValueTypeDescr
1303 using Const = ConstMapValue;
1304 using NonConst = MapValue;
1308 struct TypeDescr<MapValue> : public MapValueTypeDescr
1313 struct TypeDescr<ConstMapValue> : public MapValueTypeDescr
1317 } /* namespace internal */
1319 template <typename LibObjT>
1320 CommonNullValue<LibObjT> CommonValue<LibObjT>::asNull() const noexcept
1322 BT_ASSERT_DBG(this->isNull());
1323 return CommonNullValue<LibObjT> {this->libObjPtr()};
1326 template <typename LibObjT>
1327 CommonBoolValue<LibObjT> CommonValue<LibObjT>::asBool() const noexcept
1329 BT_ASSERT_DBG(this->isBool());
1330 return CommonBoolValue<LibObjT> {this->libObjPtr()};
1333 template <typename LibObjT>
1334 CommonSignedIntegerValue<LibObjT> CommonValue<LibObjT>::asSignedInteger() const noexcept
1336 BT_ASSERT_DBG(this->isSignedInteger());
1337 return CommonSignedIntegerValue<LibObjT> {this->libObjPtr()};
1340 template <typename LibObjT>
1341 CommonUnsignedIntegerValue<LibObjT> CommonValue<LibObjT>::asUnsignedInteger() const noexcept
1343 BT_ASSERT_DBG(this->isUnsignedInteger());
1344 return CommonUnsignedIntegerValue<LibObjT> {this->libObjPtr()};
1347 template <typename LibObjT>
1348 CommonRealValue<LibObjT> CommonValue<LibObjT>::asReal() const noexcept
1350 BT_ASSERT_DBG(this->isReal());
1351 return CommonRealValue<LibObjT> {this->libObjPtr()};
1354 template <typename LibObjT>
1355 CommonStringValue<LibObjT> CommonValue<LibObjT>::asString() const noexcept
1357 BT_ASSERT_DBG(this->isString());
1358 return CommonStringValue<LibObjT> {this->libObjPtr()};
1361 template <typename LibObjT>
1362 CommonArrayValue<LibObjT> CommonValue<LibObjT>::asArray() const noexcept
1364 BT_ASSERT_DBG(this->isArray());
1365 return CommonArrayValue<LibObjT> {this->libObjPtr()};
1368 template <typename LibObjT>
1369 CommonMapValue<LibObjT> CommonValue<LibObjT>::asMap() const noexcept
1371 BT_ASSERT_DBG(this->isMap());
1372 return CommonMapValue<LibObjT> {this->libObjPtr()};
1375 template <typename LibObjT>
1376 ArrayValue CommonArrayValue<LibObjT>::appendEmptyArray()
1378 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1380 bt_value *libElemPtr;
1381 const auto status = bt_value_array_append_empty_array_element(this->libObjPtr(), &libElemPtr);
1383 this->_handleAppendLibStatus(status);
1384 return ArrayValue {libElemPtr};
1387 template <typename LibObjT>
1388 MapValue CommonArrayValue<LibObjT>::appendEmptyMap()
1390 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1392 bt_value *libElemPtr;
1393 const auto status = bt_value_array_append_empty_map_element(this->libObjPtr(), &libElemPtr);
1395 this->_handleAppendLibStatus(status);
1396 return MapValue {libElemPtr};
1399 template <typename LibObjT>
1400 ArrayValue CommonMapValue<LibObjT>::insertEmptyArray(const char * const key)
1402 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1404 bt_value *libEntryPtr;
1405 const auto status = bt_value_map_insert_empty_array_entry(this->libObjPtr(), key, &libEntryPtr);
1407 this->_handleInsertLibStatus(status);
1408 return ArrayValue {libEntryPtr};
1411 template <typename LibObjT>
1412 ArrayValue CommonMapValue<LibObjT>::insertEmptyArray(const std::string& key)
1414 return this->insertEmptyArray(key.data());
1417 template <typename LibObjT>
1418 MapValue CommonMapValue<LibObjT>::insertEmptyMap(const char * const key)
1420 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1422 bt_value *libEntryPtr;
1423 const auto status = bt_value_map_insert_empty_map_entry(this->libObjPtr(), key, &libEntryPtr);
1425 this->_handleInsertLibStatus(status);
1426 return MapValue {libEntryPtr};
1429 template <typename LibObjT>
1430 MapValue CommonMapValue<LibObjT>::insertEmptyMap(const std::string& key)
1432 return this->insertEmptyMap(key.data());
1435 inline BoolValue::Shared createValue(const bool rawVal)
1437 return BoolValue::create(rawVal);
1440 inline UnsignedIntegerValue::Shared createValue(const std::uint64_t rawVal)
1442 return UnsignedIntegerValue::create(rawVal);
1445 inline SignedIntegerValue::Shared createValue(const std::int64_t rawVal)
1447 return SignedIntegerValue::create(rawVal);
1450 inline RealValue::Shared createValue(const double rawVal)
1452 return RealValue::create(rawVal);
1455 inline StringValue::Shared createValue(const char * const rawVal)
1457 return StringValue::create(rawVal);
1460 inline StringValue::Shared createValue(const std::string& rawVal)
1462 return StringValue::create(rawVal);
1465 } /* namespace bt2 */
1467 #endif /* BABELTRACE_CPP_COMMON_BT2_VALUE_HPP */