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.hpp"
22 #include "common-iterator.hpp"
24 #include "internal/utils.hpp"
25 #include "shared-object.hpp"
30 struct ValueRefFuncs final
32 static void get(const bt_value * const libObjPtr)
34 bt_value_get_ref(libObjPtr);
37 static void put(const bt_value * const libObjPtr)
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 CommonClockClass;
87 template <typename LibObjT>
88 class CommonFieldClass;
90 template <typename LibObjT>
91 class CommonTraceClass;
93 template <typename LibObjT>
94 class CommonStreamClass;
96 template <typename LibObjT>
97 class CommonEventClass;
99 template <typename LibObjT>
102 template <typename LibObjT>
103 class CommonValue : public BorrowedObject<LibObjT>
105 /* Allow append() to call `val.libObjPtr()` */
106 friend class CommonArrayValue<bt_value>;
108 /* Allow insert() to call `val.libObjPtr()` */
109 friend class CommonMapValue<bt_value>;
111 /* Allow userAttributes() to call `val.libObjPtr()` */
112 friend class CommonClockClass<bt_clock_class>;
113 friend class CommonFieldClass<bt_field_class>;
114 friend class CommonTraceClass<bt_trace_class>;
115 friend class CommonStreamClass<bt_stream_class>;
116 friend class CommonEventClass<bt_event_class>;
117 friend class CommonStream<bt_stream>;
119 /* Allow operator==() to call `other.libObjPtr()` */
120 friend class CommonValue<bt_value>;
121 friend class CommonValue<const bt_value>;
124 using typename BorrowedObject<LibObjT>::_ThisBorrowedObject;
127 using typename BorrowedObject<LibObjT>::_LibObjPtr;
128 using _ThisCommonValue = CommonValue<LibObjT>;
131 using Shared = SharedValue<CommonValue<LibObjT>, LibObjT>;
133 explicit CommonValue(const _LibObjPtr libObjPtr) noexcept : _ThisBorrowedObject {libObjPtr}
137 template <typename OtherLibObjT>
138 CommonValue(const CommonValue<OtherLibObjT> val) noexcept : _ThisBorrowedObject {val}
142 template <typename OtherLibObjT>
143 _ThisCommonValue& operator=(const CommonValue<OtherLibObjT> val) noexcept
145 _ThisBorrowedObject::operator=(val);
149 ValueType type() const noexcept
151 return static_cast<ValueType>(bt_value_get_type(this->libObjPtr()));
154 bool isNull() const noexcept
156 return this->_libTypeIs(BT_VALUE_TYPE_NULL);
159 bool isBool() const noexcept
161 return this->_libTypeIs(BT_VALUE_TYPE_BOOL);
164 bool isInteger() const noexcept
166 return this->_libTypeIs(BT_VALUE_TYPE_INTEGER);
169 bool isUnsignedInteger() const noexcept
171 return this->_libTypeIs(BT_VALUE_TYPE_UNSIGNED_INTEGER);
174 bool isSignedInteger() const noexcept
176 return this->_libTypeIs(BT_VALUE_TYPE_SIGNED_INTEGER);
179 bool isReal() const noexcept
181 return this->_libTypeIs(BT_VALUE_TYPE_REAL);
184 bool isString() const noexcept
186 return this->_libTypeIs(BT_VALUE_TYPE_STRING);
189 bool isArray() const noexcept
191 return this->_libTypeIs(BT_VALUE_TYPE_ARRAY);
194 bool isMap() const noexcept
196 return this->_libTypeIs(BT_VALUE_TYPE_MAP);
199 template <typename OtherLibObjT>
200 bool operator==(const CommonValue<OtherLibObjT> other) const noexcept
202 return static_cast<bool>(bt_value_is_equal(this->libObjPtr(), other.libObjPtr()));
205 template <typename OtherLibObjT>
206 bool operator!=(const CommonValue<OtherLibObjT> other) const noexcept
208 return !(*this == other);
211 Shared shared() const noexcept
213 return Shared::createWithRef(*this);
216 template <typename ValueT>
217 ValueT as() const noexcept
219 return ValueT {this->libObjPtr()};
222 CommonNullValue<LibObjT> asNull() const noexcept;
223 CommonBoolValue<LibObjT> asBool() const noexcept;
224 CommonSignedIntegerValue<LibObjT> asSignedInteger() const noexcept;
225 CommonUnsignedIntegerValue<LibObjT> asUnsignedInteger() const noexcept;
226 CommonRealValue<LibObjT> asReal() const noexcept;
227 CommonStringValue<LibObjT> asString() const noexcept;
228 CommonArrayValue<LibObjT> asArray() const noexcept;
229 CommonMapValue<LibObjT> asMap() const noexcept;
232 bool _libTypeIs(const bt_value_type type) const noexcept
234 return bt_value_type_is(bt_value_get_type(this->libObjPtr()), type);
238 using Value = CommonValue<bt_value>;
239 using ConstValue = CommonValue<const bt_value>;
243 struct ValueTypeDescr
245 using Const = ConstValue;
246 using NonConst = Value;
250 struct TypeDescr<Value> : public ValueTypeDescr
255 struct TypeDescr<ConstValue> : public ValueTypeDescr
259 } /* namespace internal */
261 template <typename LibObjT>
262 class CommonNullValue final : public CommonValue<LibObjT>
265 using typename CommonValue<LibObjT>::_ThisCommonValue;
268 using Shared = SharedValue<CommonNullValue<LibObjT>, LibObjT>;
270 CommonNullValue() noexcept : _ThisCommonValue {bt_value_null}
274 template <typename OtherLibObjT>
275 CommonNullValue(const CommonNullValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
279 template <typename OtherLibObjT>
280 CommonNullValue<LibObjT>& operator=(const CommonNullValue<OtherLibObjT> val) noexcept
282 _ThisCommonValue::operator=(val);
286 Shared shared() const noexcept
288 return Shared::createWithRef(*this);
292 using NullValue = CommonNullValue<bt_value>;
293 using ConstNullValue = CommonNullValue<const bt_value>;
297 struct NullValueTypeDescr
299 using Const = ConstNullValue;
300 using NonConst = NullValue;
304 struct TypeDescr<NullValue> : public NullValueTypeDescr
309 struct TypeDescr<ConstNullValue> : public NullValueTypeDescr
313 } /* namespace internal */
315 template <typename LibObjT>
316 class CommonBoolValue final : public CommonValue<LibObjT>
319 using typename CommonValue<LibObjT>::_LibObjPtr;
320 using typename CommonValue<LibObjT>::_ThisCommonValue;
323 using Shared = SharedValue<CommonBoolValue<LibObjT>, LibObjT>;
326 explicit CommonBoolValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
328 BT_ASSERT_DBG(this->isBool());
331 template <typename OtherLibObjT>
332 CommonBoolValue(const CommonBoolValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
336 static Shared create(const Value rawVal = false)
338 const auto libObjPtr = bt_value_bool_create_init(static_cast<bt_bool>(rawVal));
340 internal::validateCreatedObjPtr(libObjPtr);
341 return CommonBoolValue::Shared::createWithoutRef(libObjPtr);
344 template <typename OtherLibObjT>
345 CommonBoolValue<LibObjT>& operator=(const CommonBoolValue<OtherLibObjT> val) noexcept
347 _ThisCommonValue::operator=(val);
351 CommonBoolValue<LibObjT>& operator=(const Value rawVal) noexcept
353 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
355 bt_value_bool_set(this->libObjPtr(), static_cast<bt_bool>(rawVal));
359 Value value() const noexcept
361 return static_cast<Value>(bt_value_bool_get(this->libObjPtr()));
364 operator Value() const noexcept
366 return this->value();
369 Shared shared() const noexcept
371 return Shared::createWithRef(*this);
375 using BoolValue = CommonBoolValue<bt_value>;
376 using ConstBoolValue = CommonBoolValue<const bt_value>;
380 struct BoolValueTypeDescr
382 using Const = ConstBoolValue;
383 using NonConst = BoolValue;
387 struct TypeDescr<BoolValue> : public BoolValueTypeDescr
392 struct TypeDescr<ConstBoolValue> : public BoolValueTypeDescr
396 } /* namespace internal */
398 template <typename LibObjT>
399 class CommonUnsignedIntegerValue final : public CommonValue<LibObjT>
402 using typename CommonValue<LibObjT>::_LibObjPtr;
403 using typename CommonValue<LibObjT>::_ThisCommonValue;
406 using Shared = SharedValue<CommonUnsignedIntegerValue<LibObjT>, LibObjT>;
407 using Value = std::uint64_t;
409 explicit CommonUnsignedIntegerValue(const _LibObjPtr libObjPtr) noexcept :
410 _ThisCommonValue {libObjPtr}
412 BT_ASSERT_DBG(this->isUnsignedInteger());
415 static Shared create(const Value rawVal = 0)
417 const auto libObjPtr = bt_value_integer_unsigned_create_init(rawVal);
419 internal::validateCreatedObjPtr(libObjPtr);
420 return CommonUnsignedIntegerValue::Shared::createWithoutRef(libObjPtr);
423 template <typename OtherLibObjT>
424 CommonUnsignedIntegerValue(const CommonUnsignedIntegerValue<OtherLibObjT> val) noexcept :
425 _ThisCommonValue {val}
429 template <typename OtherLibObjT>
430 CommonUnsignedIntegerValue<LibObjT>&
431 operator=(const CommonUnsignedIntegerValue<OtherLibObjT> val) noexcept
433 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
435 _ThisCommonValue::operator=(val);
439 CommonUnsignedIntegerValue<LibObjT>& operator=(const Value rawVal) noexcept
441 bt_value_integer_unsigned_set(this->libObjPtr(), rawVal);
445 Value value() const noexcept
447 return bt_value_integer_unsigned_get(this->libObjPtr());
450 operator Value() const noexcept
452 return this->value();
455 Shared shared() const noexcept
457 return Shared::createWithRef(*this);
461 using UnsignedIntegerValue = CommonUnsignedIntegerValue<bt_value>;
462 using ConstUnsignedIntegerValue = CommonUnsignedIntegerValue<const bt_value>;
466 struct UnsignedIntegerValueTypeDescr
468 using Const = ConstUnsignedIntegerValue;
469 using NonConst = UnsignedIntegerValue;
473 struct TypeDescr<UnsignedIntegerValue> : public UnsignedIntegerValueTypeDescr
478 struct TypeDescr<ConstUnsignedIntegerValue> : public UnsignedIntegerValueTypeDescr
482 } /* namespace internal */
484 template <typename LibObjT>
485 class CommonSignedIntegerValue final : public CommonValue<LibObjT>
488 using typename CommonValue<LibObjT>::_LibObjPtr;
489 using typename CommonValue<LibObjT>::_ThisCommonValue;
492 using Shared = SharedValue<CommonSignedIntegerValue<LibObjT>, LibObjT>;
493 using Value = std::int64_t;
495 explicit CommonSignedIntegerValue(const _LibObjPtr libObjPtr) noexcept :
496 _ThisCommonValue {libObjPtr}
498 BT_ASSERT_DBG(this->isSignedInteger());
501 static Shared create(const Value rawVal = 0)
503 const auto libObjPtr = bt_value_integer_signed_create_init(rawVal);
505 internal::validateCreatedObjPtr(libObjPtr);
506 return CommonSignedIntegerValue::Shared::createWithoutRef(libObjPtr);
509 template <typename OtherLibObjT>
510 CommonSignedIntegerValue(const CommonSignedIntegerValue<OtherLibObjT> val) noexcept :
511 _ThisCommonValue {val}
515 template <typename OtherLibObjT>
516 CommonSignedIntegerValue<LibObjT>&
517 operator=(const CommonSignedIntegerValue<OtherLibObjT> val) noexcept
519 _ThisCommonValue::operator=(val);
523 CommonSignedIntegerValue<LibObjT>& operator=(const Value rawVal) noexcept
525 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
527 bt_value_integer_signed_set(this->libObjPtr(), rawVal);
531 Value value() const noexcept
533 return bt_value_integer_signed_get(this->libObjPtr());
536 operator Value() const noexcept
538 return this->value();
541 Shared shared() const noexcept
543 return Shared::createWithRef(*this);
547 using SignedIntegerValue = CommonSignedIntegerValue<bt_value>;
548 using ConstSignedIntegerValue = CommonSignedIntegerValue<const bt_value>;
552 struct SignedIntegerValueTypeDescr
554 using Const = ConstSignedIntegerValue;
555 using NonConst = SignedIntegerValue;
559 struct TypeDescr<SignedIntegerValue> : public SignedIntegerValueTypeDescr
564 struct TypeDescr<ConstSignedIntegerValue> : public SignedIntegerValueTypeDescr
568 } /* namespace internal */
570 template <typename LibObjT>
571 class CommonRealValue final : public CommonValue<LibObjT>
574 using typename CommonValue<LibObjT>::_LibObjPtr;
575 using typename CommonValue<LibObjT>::_ThisCommonValue;
578 using Shared = SharedValue<CommonRealValue<LibObjT>, LibObjT>;
579 using Value = double;
581 explicit CommonRealValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
583 BT_ASSERT_DBG(this->isReal());
586 static Shared create(const Value rawVal = 0)
588 const auto libObjPtr = bt_value_real_create_init(rawVal);
590 internal::validateCreatedObjPtr(libObjPtr);
591 return CommonRealValue::Shared::createWithoutRef(libObjPtr);
594 template <typename OtherLibObjT>
595 CommonRealValue(const CommonRealValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
599 template <typename OtherLibObjT>
600 CommonRealValue<LibObjT>& operator=(const CommonRealValue<OtherLibObjT> val) noexcept
602 _ThisCommonValue::operator=(val);
606 CommonRealValue<LibObjT>& operator=(const Value rawVal) noexcept
608 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
610 bt_value_real_set(this->libObjPtr(), rawVal);
614 Value value() const noexcept
616 return bt_value_real_get(this->libObjPtr());
619 operator Value() const noexcept
621 return this->value();
624 Shared shared() const noexcept
626 return Shared::createWithRef(*this);
630 using RealValue = CommonRealValue<bt_value>;
631 using ConstRealValue = CommonRealValue<const bt_value>;
635 struct RealValueTypeDescr
637 using Const = ConstRealValue;
638 using NonConst = RealValue;
642 struct TypeDescr<RealValue> : public RealValueTypeDescr
647 struct TypeDescr<ConstRealValue> : public RealValueTypeDescr
651 } /* namespace internal */
653 template <typename LibObjT>
654 class CommonStringValue final : public CommonValue<LibObjT>
657 using typename CommonValue<LibObjT>::_LibObjPtr;
658 using typename CommonValue<LibObjT>::_ThisCommonValue;
661 using Shared = SharedValue<CommonStringValue<LibObjT>, LibObjT>;
663 explicit CommonStringValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
665 BT_ASSERT_DBG(this->isString());
668 static Shared create(const char * const rawVal = "")
670 const auto libObjPtr = bt_value_string_create_init(rawVal);
672 internal::validateCreatedObjPtr(libObjPtr);
673 return CommonStringValue::Shared::createWithoutRef(libObjPtr);
676 static Shared create(const std::string& rawVal)
678 return CommonStringValue::create(rawVal.data());
681 template <typename OtherLibObjT>
682 CommonStringValue(const CommonStringValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
686 template <typename OtherLibObjT>
687 CommonStringValue<LibObjT>& operator=(const CommonStringValue<OtherLibObjT> val) noexcept
689 _ThisCommonValue::operator=(val);
693 CommonStringValue<LibObjT>& operator=(const char * const rawVal)
695 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
697 const auto status = bt_value_string_set(this->libObjPtr(), rawVal);
699 if (status == BT_VALUE_STRING_SET_STATUS_MEMORY_ERROR) {
700 throw MemoryError {};
706 CommonStringValue<LibObjT>& operator=(const std::string& rawVal) noexcept
708 return *this = rawVal.data();
711 bpstd::string_view value() const noexcept
713 return bt_value_string_get(this->libObjPtr());
716 Shared shared() const noexcept
718 return Shared::createWithRef(*this);
722 using StringValue = CommonStringValue<bt_value>;
723 using ConstStringValue = CommonStringValue<const bt_value>;
727 struct StringValueTypeDescr
729 using Const = ConstStringValue;
730 using NonConst = StringValue;
734 struct TypeDescr<StringValue> : public StringValueTypeDescr
739 struct TypeDescr<ConstStringValue> : public StringValueTypeDescr
743 template <typename LibObjT>
744 struct CommonArrayValueSpec;
746 /* Functions specific to mutable array values */
748 struct CommonArrayValueSpec<bt_value> final
750 static bt_value *elementByIndex(bt_value * const libValPtr, const std::uint64_t index) noexcept
752 return bt_value_array_borrow_element_by_index(libValPtr, index);
756 /* Functions specific to constant array values */
758 struct CommonArrayValueSpec<const bt_value> final
760 static const bt_value *elementByIndex(const bt_value * const libValPtr,
761 const std::uint64_t index) noexcept
763 return bt_value_array_borrow_element_by_index_const(libValPtr, index);
767 } /* namespace internal */
769 template <typename LibObjT>
770 class CommonArrayValue final : public CommonValue<LibObjT>
773 using typename CommonValue<LibObjT>::_LibObjPtr;
774 using typename CommonValue<LibObjT>::_ThisCommonValue;
777 using Shared = SharedValue<CommonArrayValue<LibObjT>, LibObjT>;
778 using Iterator = CommonIterator<CommonArrayValue<LibObjT>, CommonValue<LibObjT>>;
780 explicit CommonArrayValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
782 BT_ASSERT_DBG(this->isArray());
785 static Shared create()
787 const auto libObjPtr = bt_value_array_create();
789 internal::validateCreatedObjPtr(libObjPtr);
790 return CommonArrayValue::Shared::createWithoutRef(libObjPtr);
793 template <typename OtherLibObjT>
794 CommonArrayValue(const CommonArrayValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
798 template <typename OtherLibObjT>
799 CommonArrayValue<LibObjT>& operator=(const CommonArrayValue<OtherLibObjT> val) noexcept
801 _ThisCommonValue::operator=(val);
805 std::uint64_t length() const noexcept
807 return bt_value_array_get_length(this->libObjPtr());
810 /* Required by the `CommonIterator` template class */
811 std::uint64_t size() const noexcept
813 return this->length();
816 Iterator begin() const noexcept
818 return Iterator {*this, 0};
821 Iterator end() const noexcept
823 return Iterator {*this, this->length()};
826 bool isEmpty() const noexcept
828 return this->length() == 0;
831 ConstValue operator[](const std::uint64_t index) const noexcept
833 return ConstValue {internal::CommonArrayValueSpec<const bt_value>::elementByIndex(
834 this->libObjPtr(), index)};
837 CommonValue<LibObjT> operator[](const std::uint64_t index) noexcept
839 return CommonValue<LibObjT> {
840 internal::CommonArrayValueSpec<LibObjT>::elementByIndex(this->libObjPtr(), index)};
843 void append(const Value val)
845 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
847 const auto status = bt_value_array_append_element(this->libObjPtr(), val.libObjPtr());
849 this->_handleAppendLibStatus(status);
852 void append(const bool rawVal)
854 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
857 bt_value_array_append_bool_element(this->libObjPtr(), static_cast<bt_bool>(rawVal));
859 this->_handleAppendLibStatus(status);
862 void append(const std::uint64_t rawVal)
864 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
867 bt_value_array_append_unsigned_integer_element(this->libObjPtr(), rawVal);
869 this->_handleAppendLibStatus(status);
872 void append(const std::int64_t rawVal)
874 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
876 const auto status = bt_value_array_append_signed_integer_element(this->libObjPtr(), rawVal);
878 this->_handleAppendLibStatus(status);
881 void append(const double rawVal)
883 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
885 const auto status = bt_value_array_append_real_element(this->libObjPtr(), rawVal);
887 this->_handleAppendLibStatus(status);
890 void append(const char * const rawVal)
892 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
894 const auto status = bt_value_array_append_string_element(this->libObjPtr(), rawVal);
896 this->_handleAppendLibStatus(status);
899 void append(const std::string& rawVal)
901 this->append(rawVal.data());
904 CommonArrayValue<bt_value> appendEmptyArray();
905 CommonMapValue<bt_value> appendEmptyMap();
907 void operator+=(const Value val)
912 void operator+=(const bool rawVal)
914 this->append(rawVal);
917 void operator+=(const std::uint64_t rawVal)
919 this->append(rawVal);
922 void operator+=(const std::int64_t rawVal)
924 this->append(rawVal);
927 void operator+=(const double rawVal)
929 this->append(rawVal);
932 void operator+=(const char * const rawVal)
934 this->append(rawVal);
937 void operator+=(const std::string& rawVal)
939 this->append(rawVal);
942 Shared shared() const noexcept
944 return Shared::createWithRef(*this);
948 void _handleAppendLibStatus(const bt_value_array_append_element_status status) const
950 if (status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_MEMORY_ERROR) {
951 throw MemoryError {};
956 using ArrayValue = CommonArrayValue<bt_value>;
957 using ConstArrayValue = CommonArrayValue<const bt_value>;
961 struct ArrayValueTypeDescr
963 using Const = ConstArrayValue;
964 using NonConst = ArrayValue;
968 struct TypeDescr<ArrayValue> : public ArrayValueTypeDescr
973 struct TypeDescr<ConstArrayValue> : public ArrayValueTypeDescr
978 * Type of a user function passed to `CommonMapValue<ObjT>::forEach()`.
980 * First argument is the entry's key, second is its value.
982 template <typename ObjT>
983 using CommonMapValueForEachUserFunc = std::function<void(const bpstd::string_view&, ObjT)>;
986 * Template of a function to be passed to bt_value_map_foreach_entry()
987 * for bt_value_map_foreach_entry_const() which calls a user function.
989 * `userData` is casted to a `const` pointer to
990 * `CommonMapValueForEachUserFunc<ObjT>` (the user function to call).
992 * This function catches any exception which the user function throws
993 * and returns the `ErrorStatus` value. If there's no execption, this
994 * function returns the `OkStatus` value.
996 template <typename ObjT, typename LibObjT, typename LibStatusT, int OkStatus, int ErrorStatus>
997 LibStatusT mapValueForEachLibFunc(const char * const key, LibObjT * const libObjPtr,
998 void * const userData)
1000 const auto& userFunc = *reinterpret_cast<const CommonMapValueForEachUserFunc<ObjT> *>(userData);
1003 userFunc(key, ObjT {libObjPtr});
1005 return static_cast<LibStatusT>(ErrorStatus);
1008 return static_cast<LibStatusT>(OkStatus);
1011 template <typename LibObjT>
1012 struct CommonMapValueSpec;
1014 /* Functions specific to mutable map values */
1016 struct CommonMapValueSpec<bt_value> final
1018 static bt_value *entryByKey(bt_value * const libValPtr, const char * const key) noexcept
1020 return bt_value_map_borrow_entry_value(libValPtr, key);
1023 static void forEach(bt_value * const libValPtr,
1024 const CommonMapValueForEachUserFunc<Value>& func)
1026 const auto status = bt_value_map_foreach_entry(
1028 mapValueForEachLibFunc<Value, bt_value, bt_value_map_foreach_entry_func_status,
1029 BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_OK,
1030 BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_ERROR>,
1031 const_cast<void *>(reinterpret_cast<const void *>(&func)));
1034 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_OK:
1036 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_USER_ERROR:
1037 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_ERROR:
1045 /* Functions specific to constant map values */
1047 struct CommonMapValueSpec<const bt_value> final
1049 static const bt_value *entryByKey(const bt_value * const libValPtr,
1050 const char * const key) noexcept
1052 return bt_value_map_borrow_entry_value_const(libValPtr, key);
1055 static void forEach(const bt_value * const libValPtr,
1056 const CommonMapValueForEachUserFunc<ConstValue>& func)
1058 const auto status = bt_value_map_foreach_entry_const(
1060 mapValueForEachLibFunc<ConstValue, const bt_value,
1061 bt_value_map_foreach_entry_const_func_status,
1062 BT_VALUE_MAP_FOREACH_ENTRY_CONST_FUNC_STATUS_OK,
1063 BT_VALUE_MAP_FOREACH_ENTRY_CONST_FUNC_STATUS_ERROR>,
1064 const_cast<void *>(reinterpret_cast<const void *>(&func)));
1067 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_OK:
1069 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_USER_ERROR:
1070 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_ERROR:
1078 } /* namespace internal */
1080 template <typename LibObjT>
1081 class CommonMapValue final : public CommonValue<LibObjT>
1084 using typename CommonValue<LibObjT>::_LibObjPtr;
1085 using typename CommonValue<LibObjT>::_ThisCommonValue;
1088 using Shared = SharedValue<CommonMapValue<LibObjT>, LibObjT>;
1090 explicit CommonMapValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
1092 BT_ASSERT_DBG(this->isMap());
1095 static Shared create()
1097 const auto libObjPtr = bt_value_map_create();
1099 internal::validateCreatedObjPtr(libObjPtr);
1100 return CommonMapValue::Shared::createWithoutRef(libObjPtr);
1103 template <typename OtherLibObjT>
1104 CommonMapValue(const CommonMapValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
1108 template <typename OtherLibObjT>
1109 CommonMapValue<LibObjT>& operator=(const CommonMapValue<OtherLibObjT> val) noexcept
1111 _ThisCommonValue::operator=(val);
1115 std::uint64_t size() const noexcept
1117 return bt_value_map_get_size(this->libObjPtr());
1120 bool isEmpty() const noexcept
1122 return this->size() == 0;
1125 nonstd::optional<ConstValue> operator[](const char * const key) const noexcept
1127 const auto libObjPtr =
1128 internal::CommonMapValueSpec<const bt_value>::entryByKey(this->libObjPtr(), key);
1131 return nonstd::nullopt;
1134 return ConstValue {libObjPtr};
1137 nonstd::optional<ConstValue> operator[](const std::string& key) const noexcept
1139 return (*this)[key.data()];
1142 nonstd::optional<CommonValue<LibObjT>> operator[](const char * const key) noexcept
1144 const auto libObjPtr =
1145 internal::CommonMapValueSpec<LibObjT>::entryByKey(this->libObjPtr(), key);
1148 return nonstd::nullopt;
1151 return CommonValue<LibObjT> {libObjPtr};
1154 nonstd::optional<CommonValue<LibObjT>> operator[](const std::string& key) noexcept
1156 return (*this)[key.data()];
1159 bool hasEntry(const char * const key) const noexcept
1161 return static_cast<bool>(bt_value_map_has_entry(this->libObjPtr(), key));
1164 bool hasEntry(const std::string& key) const noexcept
1166 return this->hasEntry(key.data());
1169 void insert(const char * const key, const Value val)
1171 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1173 const auto status = bt_value_map_insert_entry(this->libObjPtr(), key, val.libObjPtr());
1175 this->_handleInsertLibStatus(status);
1178 void insert(const std::string& key, const Value val)
1180 this->insert(key.data(), val);
1183 void insert(const char * const key, const bool rawVal)
1185 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1188 bt_value_map_insert_bool_entry(this->libObjPtr(), key, static_cast<bt_bool>(rawVal));
1190 this->_handleInsertLibStatus(status);
1193 void insert(const std::string& key, const bool rawVal)
1195 this->insert(key.data(), rawVal);
1198 void insert(const char * const key, const std::uint64_t rawVal)
1200 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1203 bt_value_map_insert_unsigned_integer_entry(this->libObjPtr(), key, rawVal);
1205 this->_handleInsertLibStatus(status);
1208 void insert(const std::string& key, const std::uint64_t rawVal)
1210 this->insert(key.data(), rawVal);
1213 void insert(const char * const key, const std::int64_t rawVal)
1215 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1218 bt_value_map_insert_signed_integer_entry(this->libObjPtr(), key, rawVal);
1220 this->_handleInsertLibStatus(status);
1223 void insert(const std::string& key, const std::int64_t rawVal)
1225 this->insert(key.data(), rawVal);
1228 void insert(const char * const key, const double rawVal)
1230 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1232 const auto status = bt_value_map_insert_real_entry(this->libObjPtr(), key, rawVal);
1234 this->_handleInsertLibStatus(status);
1237 void insert(const std::string& key, const double rawVal)
1239 this->insert(key.data(), rawVal);
1242 void insert(const char * const key, const char * const rawVal)
1244 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1246 const auto status = bt_value_map_insert_string_entry(this->libObjPtr(), key, rawVal);
1248 this->_handleInsertLibStatus(status);
1251 void insert(const char * const key, const std::string& rawVal)
1253 this->insert(key, rawVal.data());
1256 void insert(const std::string& key, const char * const rawVal)
1258 this->insert(key.data(), rawVal);
1261 void insert(const std::string& key, const std::string& rawVal)
1263 this->insert(key.data(), rawVal.data());
1266 CommonArrayValue<bt_value> insertEmptyArray(const char *key);
1267 CommonArrayValue<bt_value> insertEmptyArray(const std::string& key);
1268 CommonMapValue<bt_value> insertEmptyMap(const char *key);
1269 CommonMapValue<bt_value> insertEmptyMap(const std::string& key);
1271 void forEach(const internal::CommonMapValueForEachUserFunc<ConstValue>& func) const
1273 internal::CommonMapValueSpec<const bt_value>::forEach(this->libObjPtr(), func);
1276 void forEach(const internal::CommonMapValueForEachUserFunc<CommonValue<LibObjT>>& func)
1278 internal::CommonMapValueSpec<LibObjT>::forEach(this->libObjPtr(), func);
1281 Shared shared() const noexcept
1283 return Shared::createWithRef(*this);
1287 void _handleInsertLibStatus(const bt_value_map_insert_entry_status status) const
1289 if (status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_MEMORY_ERROR) {
1290 throw MemoryError {};
1295 using MapValue = CommonMapValue<bt_value>;
1296 using ConstMapValue = CommonMapValue<const bt_value>;
1298 namespace internal {
1300 struct MapValueTypeDescr
1302 using Const = ConstMapValue;
1303 using NonConst = MapValue;
1307 struct TypeDescr<MapValue> : public MapValueTypeDescr
1312 struct TypeDescr<ConstMapValue> : public MapValueTypeDescr
1316 } /* namespace internal */
1318 template <typename LibObjT>
1319 CommonNullValue<LibObjT> CommonValue<LibObjT>::asNull() const noexcept
1321 BT_ASSERT_DBG(this->isNull());
1322 return CommonNullValue<LibObjT> {this->libObjPtr()};
1325 template <typename LibObjT>
1326 CommonBoolValue<LibObjT> CommonValue<LibObjT>::asBool() const noexcept
1328 BT_ASSERT_DBG(this->isBool());
1329 return CommonBoolValue<LibObjT> {this->libObjPtr()};
1332 template <typename LibObjT>
1333 CommonSignedIntegerValue<LibObjT> CommonValue<LibObjT>::asSignedInteger() const noexcept
1335 BT_ASSERT_DBG(this->isSignedInteger());
1336 return CommonSignedIntegerValue<LibObjT> {this->libObjPtr()};
1339 template <typename LibObjT>
1340 CommonUnsignedIntegerValue<LibObjT> CommonValue<LibObjT>::asUnsignedInteger() const noexcept
1342 BT_ASSERT_DBG(this->isUnsignedInteger());
1343 return CommonUnsignedIntegerValue<LibObjT> {this->libObjPtr()};
1346 template <typename LibObjT>
1347 CommonRealValue<LibObjT> CommonValue<LibObjT>::asReal() const noexcept
1349 BT_ASSERT_DBG(this->isReal());
1350 return CommonRealValue<LibObjT> {this->libObjPtr()};
1353 template <typename LibObjT>
1354 CommonStringValue<LibObjT> CommonValue<LibObjT>::asString() const noexcept
1356 BT_ASSERT_DBG(this->isString());
1357 return CommonStringValue<LibObjT> {this->libObjPtr()};
1360 template <typename LibObjT>
1361 CommonArrayValue<LibObjT> CommonValue<LibObjT>::asArray() const noexcept
1363 BT_ASSERT_DBG(this->isArray());
1364 return CommonArrayValue<LibObjT> {this->libObjPtr()};
1367 template <typename LibObjT>
1368 CommonMapValue<LibObjT> CommonValue<LibObjT>::asMap() const noexcept
1370 BT_ASSERT_DBG(this->isMap());
1371 return CommonMapValue<LibObjT> {this->libObjPtr()};
1374 template <typename LibObjT>
1375 ArrayValue CommonArrayValue<LibObjT>::appendEmptyArray()
1377 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1379 bt_value *libElemPtr;
1380 const auto status = bt_value_array_append_empty_array_element(this->libObjPtr(), &libElemPtr);
1382 this->_handleAppendLibStatus(status);
1383 return ArrayValue {libElemPtr};
1386 template <typename LibObjT>
1387 MapValue CommonArrayValue<LibObjT>::appendEmptyMap()
1389 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1391 bt_value *libElemPtr;
1392 const auto status = bt_value_array_append_empty_map_element(this->libObjPtr(), &libElemPtr);
1394 this->_handleAppendLibStatus(status);
1395 return MapValue {libElemPtr};
1398 template <typename LibObjT>
1399 ArrayValue CommonMapValue<LibObjT>::insertEmptyArray(const char * const key)
1401 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1403 bt_value *libEntryPtr;
1404 const auto status = bt_value_map_insert_empty_array_entry(this->libObjPtr(), key, &libEntryPtr);
1406 this->_handleInsertLibStatus(status);
1407 return ArrayValue {libEntryPtr};
1410 template <typename LibObjT>
1411 ArrayValue CommonMapValue<LibObjT>::insertEmptyArray(const std::string& key)
1413 return this->insertEmptyArray(key.data());
1416 template <typename LibObjT>
1417 MapValue CommonMapValue<LibObjT>::insertEmptyMap(const char * const key)
1419 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1421 bt_value *libEntryPtr;
1422 const auto status = bt_value_map_insert_empty_map_entry(this->libObjPtr(), key, &libEntryPtr);
1424 this->_handleInsertLibStatus(status);
1425 return MapValue {libEntryPtr};
1428 template <typename LibObjT>
1429 MapValue CommonMapValue<LibObjT>::insertEmptyMap(const std::string& key)
1431 return this->insertEmptyMap(key.data());
1434 inline BoolValue::Shared createValue(const bool rawVal)
1436 return BoolValue::create(rawVal);
1439 inline UnsignedIntegerValue::Shared createValue(const std::uint64_t rawVal)
1441 return UnsignedIntegerValue::create(rawVal);
1444 inline SignedIntegerValue::Shared createValue(const std::int64_t rawVal)
1446 return SignedIntegerValue::create(rawVal);
1449 inline RealValue::Shared createValue(const double rawVal)
1451 return RealValue::create(rawVal);
1454 inline StringValue::Shared createValue(const char * const rawVal)
1456 return StringValue::create(rawVal);
1459 inline StringValue::Shared createValue(const std::string& rawVal)
1461 return StringValue::create(rawVal);
1464 } /* namespace bt2 */
1466 #endif /* BABELTRACE_CPP_COMMON_BT2_VALUE_HPP */