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 "internal/borrowed-obj.hpp"
19 #include "internal/shared-obj.hpp"
20 #include "internal/utils.hpp"
21 #include "cpp-common/optional.hpp"
22 #include "cpp-common/string_view.hpp"
23 #include "lib-error.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 {*this};
215 CommonNullValue<LibObjT> asNull() const noexcept;
216 CommonBoolValue<LibObjT> asBool() const noexcept;
217 CommonSignedIntegerValue<LibObjT> asSignedInteger() const noexcept;
218 CommonUnsignedIntegerValue<LibObjT> asUnsignedInteger() const noexcept;
219 CommonRealValue<LibObjT> asReal() const noexcept;
220 CommonStringValue<LibObjT> asString() const noexcept;
221 CommonArrayValue<LibObjT> asArray() const noexcept;
222 CommonMapValue<LibObjT> asMap() const noexcept;
225 bool _libTypeIs(const bt_value_type type) const noexcept
227 return bt_value_type_is(bt_value_get_type(this->_libObjPtr()), type);
231 using Value = CommonValue<bt_value>;
232 using ConstValue = CommonValue<const bt_value>;
234 template <typename LibObjT>
235 class CommonNullValue final : public CommonValue<LibObjT>
238 using typename CommonValue<LibObjT>::_ThisCommonValue;
241 using Shared = internal::SharedValue<CommonNullValue<LibObjT>, LibObjT>;
243 CommonNullValue() noexcept : _ThisCommonValue {bt_value_null}
247 template <typename OtherLibObjT>
248 CommonNullValue(const CommonNullValue<OtherLibObjT>& val) noexcept : _ThisCommonValue {val}
252 template <typename OtherLibObjT>
253 CommonNullValue<LibObjT>& operator=(const CommonNullValue<OtherLibObjT>& val) noexcept
255 _ThisCommonValue::operator=(val);
259 Shared shared() const noexcept
261 return Shared {*this};
265 using NullValue = CommonNullValue<bt_value>;
266 using ConstNullValue = CommonNullValue<const bt_value>;
268 template <typename LibObjT>
269 class CommonBoolValue final : public CommonValue<LibObjT>
272 using typename CommonValue<LibObjT>::_LibObjPtr;
273 using typename CommonValue<LibObjT>::_ThisCommonValue;
276 using Shared = internal::SharedValue<CommonBoolValue<LibObjT>, LibObjT>;
279 explicit CommonBoolValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
281 BT_ASSERT_DBG(this->isBool());
284 template <typename OtherLibObjT>
285 CommonBoolValue(const CommonBoolValue<OtherLibObjT>& val) noexcept : _ThisCommonValue {val}
289 static Shared create(const Value rawVal = false)
291 const auto libObjPtr = bt_value_bool_create_init(static_cast<bt_bool>(rawVal));
293 internal::validateCreatedObjPtr(libObjPtr);
294 return Shared {CommonBoolValue<LibObjT> {libObjPtr}};
297 template <typename OtherLibObjT>
298 CommonBoolValue<LibObjT>& operator=(const CommonBoolValue<OtherLibObjT>& val) noexcept
300 _ThisCommonValue::operator=(val);
304 CommonBoolValue<LibObjT>& operator=(const Value rawVal) noexcept
306 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
308 bt_value_bool_set(this->_libObjPtr(), static_cast<bt_bool>(rawVal));
312 Value value() const noexcept
314 return static_cast<Value>(bt_value_bool_get(this->_libObjPtr()));
317 operator Value() const noexcept
319 return this->value();
322 Shared shared() const noexcept
324 return Shared {*this};
328 using BoolValue = CommonBoolValue<bt_value>;
329 using ConstBoolValue = CommonBoolValue<const bt_value>;
331 template <typename LibObjT>
332 class CommonUnsignedIntegerValue final : public CommonValue<LibObjT>
335 using typename CommonValue<LibObjT>::_LibObjPtr;
336 using typename CommonValue<LibObjT>::_ThisCommonValue;
339 using Shared = internal::SharedValue<CommonUnsignedIntegerValue<LibObjT>, LibObjT>;
340 using Value = std::uint64_t;
342 explicit CommonUnsignedIntegerValue(const _LibObjPtr libObjPtr) noexcept :
343 _ThisCommonValue {libObjPtr}
345 BT_ASSERT_DBG(this->isUnsignedInteger());
348 static Shared create(const Value rawVal = 0)
350 const auto libObjPtr = bt_value_integer_unsigned_create_init(rawVal);
352 internal::validateCreatedObjPtr(libObjPtr);
353 return Shared {CommonUnsignedIntegerValue<LibObjT> {libObjPtr}};
356 template <typename OtherLibObjT>
357 CommonUnsignedIntegerValue(const CommonUnsignedIntegerValue<OtherLibObjT>& val) noexcept :
358 _ThisCommonValue {val}
362 template <typename OtherLibObjT>
363 CommonUnsignedIntegerValue<LibObjT>&
364 operator=(const CommonUnsignedIntegerValue<OtherLibObjT>& val) noexcept
366 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
368 _ThisCommonValue::operator=(val);
372 CommonUnsignedIntegerValue<LibObjT>& operator=(const Value rawVal) noexcept
374 bt_value_integer_unsigned_set(this->_libObjPtr(), rawVal);
378 Value value() const noexcept
380 return bt_value_integer_unsigned_get(this->_libObjPtr());
383 operator Value() const noexcept
385 return this->value();
388 Shared shared() const noexcept
390 return Shared {*this};
394 using UnsignedIntegerValue = CommonUnsignedIntegerValue<bt_value>;
395 using ConstUnsignedIntegerValue = CommonUnsignedIntegerValue<const bt_value>;
397 template <typename LibObjT>
398 class CommonSignedIntegerValue final : public CommonValue<LibObjT>
401 using typename CommonValue<LibObjT>::_LibObjPtr;
402 using typename CommonValue<LibObjT>::_ThisCommonValue;
405 using Shared = internal::SharedValue<CommonSignedIntegerValue<LibObjT>, LibObjT>;
406 using Value = std::int64_t;
408 explicit CommonSignedIntegerValue(const _LibObjPtr libObjPtr) noexcept :
409 _ThisCommonValue {libObjPtr}
411 BT_ASSERT_DBG(this->isSignedInteger());
414 static Shared create(const Value rawVal = 0)
416 const auto libObjPtr = bt_value_integer_signed_create_init(rawVal);
418 internal::validateCreatedObjPtr(libObjPtr);
419 return Shared {CommonSignedIntegerValue<LibObjT> {libObjPtr}};
422 template <typename OtherLibObjT>
423 CommonSignedIntegerValue(const CommonSignedIntegerValue<OtherLibObjT>& val) noexcept :
424 _ThisCommonValue {val}
428 template <typename OtherLibObjT>
429 CommonSignedIntegerValue<LibObjT>&
430 operator=(const CommonSignedIntegerValue<OtherLibObjT>& val) noexcept
432 _ThisCommonValue::operator=(val);
436 CommonSignedIntegerValue<LibObjT>& operator=(const Value rawVal) noexcept
438 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
440 bt_value_integer_signed_set(this->_libObjPtr(), rawVal);
444 Value value() const noexcept
446 return bt_value_integer_signed_get(this->_libObjPtr());
449 operator Value() const noexcept
451 return this->value();
454 Shared shared() const noexcept
456 return Shared {*this};
460 using SignedIntegerValue = CommonSignedIntegerValue<bt_value>;
461 using ConstSignedIntegerValue = CommonSignedIntegerValue<const bt_value>;
463 template <typename LibObjT>
464 class CommonRealValue final : public CommonValue<LibObjT>
467 using typename CommonValue<LibObjT>::_LibObjPtr;
468 using typename CommonValue<LibObjT>::_ThisCommonValue;
471 using Shared = internal::SharedValue<CommonRealValue<LibObjT>, LibObjT>;
472 using Value = double;
474 explicit CommonRealValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
476 BT_ASSERT_DBG(this->isReal());
479 static Shared create(const Value rawVal = 0)
481 const auto libObjPtr = bt_value_real_create_init(rawVal);
483 internal::validateCreatedObjPtr(libObjPtr);
484 return Shared {CommonRealValue<LibObjT> {libObjPtr}};
487 template <typename OtherLibObjT>
488 CommonRealValue(const CommonRealValue<OtherLibObjT>& val) noexcept : _ThisCommonValue {val}
492 template <typename OtherLibObjT>
493 CommonRealValue<LibObjT>& operator=(const CommonRealValue<OtherLibObjT>& val) noexcept
495 _ThisCommonValue::operator=(val);
499 CommonRealValue<LibObjT>& operator=(const Value rawVal) noexcept
501 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
503 bt_value_real_set(this->_libObjPtr(), rawVal);
507 Value value() const noexcept
509 return bt_value_real_get(this->_libObjPtr());
512 operator Value() const noexcept
514 return this->value();
517 Shared shared() const noexcept
519 return Shared {*this};
523 using RealValue = CommonRealValue<bt_value>;
524 using ConstRealValue = CommonRealValue<const bt_value>;
526 template <typename LibObjT>
527 class CommonStringValue final : public CommonValue<LibObjT>
530 using typename CommonValue<LibObjT>::_LibObjPtr;
531 using typename CommonValue<LibObjT>::_ThisCommonValue;
534 using Shared = internal::SharedValue<CommonStringValue<LibObjT>, LibObjT>;
536 explicit CommonStringValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
538 BT_ASSERT_DBG(this->isString());
541 static Shared create(const char * const rawVal = "")
543 const auto libObjPtr = bt_value_string_create_init(rawVal);
545 internal::validateCreatedObjPtr(libObjPtr);
546 return Shared {CommonStringValue<LibObjT> {libObjPtr}};
549 static Shared create(const std::string& rawVal)
551 return CommonStringValue<LibObjT>::create(rawVal.data());
554 template <typename OtherLibObjT>
555 CommonStringValue(const CommonStringValue<OtherLibObjT>& val) noexcept : _ThisCommonValue {val}
559 template <typename OtherLibObjT>
560 CommonStringValue<LibObjT>& operator=(const CommonStringValue<OtherLibObjT>& val) noexcept
562 _ThisCommonValue::operator=(val);
566 CommonStringValue<LibObjT>& operator=(const char * const rawVal)
568 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
570 const auto status = bt_value_string_set(this->_libObjPtr(), rawVal);
572 if (status == BT_VALUE_STRING_SET_STATUS_MEMORY_ERROR) {
573 throw LibMemoryError {};
579 CommonStringValue<LibObjT>& operator=(const std::string& rawVal) noexcept
581 return *this = rawVal.data();
584 bpstd::string_view value() const noexcept
586 return bt_value_string_get(this->_libObjPtr());
589 Shared shared() const noexcept
591 return Shared {*this};
595 using StringValue = CommonStringValue<bt_value>;
596 using ConstStringValue = CommonStringValue<const bt_value>;
600 template <typename LibObjT>
601 struct CommonArrayValueSpec;
603 // Functions specific to mutable array values
605 struct CommonArrayValueSpec<bt_value> final
607 static bt_value *elementByIndex(bt_value * const libValPtr, const std::uint64_t index) noexcept
609 return bt_value_array_borrow_element_by_index(libValPtr, index);
613 // Functions specific to constant array values
615 struct CommonArrayValueSpec<const bt_value> final
617 static const bt_value *elementByIndex(const bt_value * const libValPtr,
618 const std::uint64_t index) noexcept
620 return bt_value_array_borrow_element_by_index_const(libValPtr, index);
624 } // namespace internal
626 template <typename LibObjT>
627 class CommonArrayValueIterator
629 friend CommonArrayValue<LibObjT>;
631 using difference_type = std::ptrdiff_t;
632 using value_type = CommonValue<LibObjT>;
633 using pointer = value_type *;
634 using reference = value_type&;
635 using iterator_category = std::input_iterator_tag;
638 explicit CommonArrayValueIterator(const CommonArrayValue<LibObjT>& arrayVal,
639 const uint64_t idx) :
640 _mArrayVal {arrayVal},
643 this->_updateCurrentValue();
647 CommonArrayValueIterator(const CommonArrayValueIterator&) = default;
648 CommonArrayValueIterator(CommonArrayValueIterator&&) = default;
649 CommonArrayValueIterator& operator=(const CommonArrayValueIterator&) = default;
650 CommonArrayValueIterator& operator=(CommonArrayValueIterator&&) = default;
652 CommonArrayValueIterator& operator++() noexcept
655 this->_updateCurrentValue();
659 CommonArrayValueIterator operator++(int) noexcept
661 const auto tmp = *this;
667 bool operator==(const CommonArrayValueIterator& other) const noexcept
669 return _mIdx == other._mIdx;
672 bool operator!=(const CommonArrayValueIterator& other) const noexcept
674 return !(*this == other);
677 reference operator*() noexcept
682 pointer operator->() noexcept
684 return &(*_mCurrVal);
688 void _updateCurrentValue() noexcept
690 if (_mIdx < _mArrayVal.length()) {
691 _mCurrVal = _mArrayVal[_mIdx];
693 _mCurrVal = nonstd::nullopt;
697 nonstd::optional<CommonValue<LibObjT>> _mCurrVal;
698 CommonArrayValue<LibObjT> _mArrayVal;
702 template <typename LibObjT>
703 class CommonArrayValue final : public CommonValue<LibObjT>
706 using typename CommonValue<LibObjT>::_LibObjPtr;
707 using typename CommonValue<LibObjT>::_ThisCommonValue;
710 using Shared = internal::SharedValue<CommonArrayValue<LibObjT>, LibObjT>;
711 using Iterator = CommonArrayValueIterator<LibObjT>;
713 explicit CommonArrayValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
715 BT_ASSERT_DBG(this->isArray());
718 static Shared create()
720 const auto libObjPtr = bt_value_array_create();
722 internal::validateCreatedObjPtr(libObjPtr);
723 return Shared {CommonArrayValue<LibObjT> {libObjPtr}};
726 template <typename OtherLibObjT>
727 CommonArrayValue(const CommonArrayValue<OtherLibObjT>& val) noexcept : _ThisCommonValue {val}
731 template <typename OtherLibObjT>
732 CommonArrayValue<LibObjT>& operator=(const CommonArrayValue<OtherLibObjT>& val) noexcept
734 _ThisCommonValue::operator=(val);
738 std::uint64_t length() const noexcept
740 return bt_value_array_get_length(this->_libObjPtr());
743 Iterator begin() const noexcept
745 return Iterator {*this, 0};
748 Iterator end() const noexcept
750 return Iterator {*this, this->length()};
753 bool isEmpty() const noexcept
755 return this->length() == 0;
758 ConstValue operator[](const std::uint64_t index) const noexcept
760 return ConstValue {internal::CommonArrayValueSpec<const bt_value>::elementByIndex(
761 this->_libObjPtr(), index)};
764 CommonValue<LibObjT> operator[](const std::uint64_t index) noexcept
766 return CommonValue<LibObjT> {
767 internal::CommonArrayValueSpec<LibObjT>::elementByIndex(this->_libObjPtr(), index)};
770 void append(const Value& val)
772 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
774 const auto status = bt_value_array_append_element(this->_libObjPtr(), val._libObjPtr());
776 this->_handleAppendLibStatus(status);
779 void append(const bool rawVal)
781 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
784 bt_value_array_append_bool_element(this->_libObjPtr(), static_cast<bt_bool>(rawVal));
786 this->_handleAppendLibStatus(status);
789 void append(const std::uint64_t rawVal)
791 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
794 bt_value_array_append_unsigned_integer_element(this->_libObjPtr(), rawVal);
796 this->_handleAppendLibStatus(status);
799 void append(const std::int64_t rawVal)
801 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
804 bt_value_array_append_signed_integer_element(this->_libObjPtr(), rawVal);
806 this->_handleAppendLibStatus(status);
809 void append(const double rawVal)
811 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
813 const auto status = bt_value_array_append_real_element(this->_libObjPtr(), rawVal);
815 this->_handleAppendLibStatus(status);
818 void append(const char * const rawVal)
820 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
822 const auto status = bt_value_array_append_string_element(this->_libObjPtr(), rawVal);
824 this->_handleAppendLibStatus(status);
827 void append(const std::string& rawVal)
829 this->append(rawVal.data());
832 CommonArrayValue<bt_value> appendEmptyArray();
833 CommonMapValue<bt_value> appendEmptyMap();
835 void operator+=(const Value& val)
840 void operator+=(const bool rawVal)
842 this->append(rawVal);
845 void operator+=(const std::uint64_t rawVal)
847 this->append(rawVal);
850 void operator+=(const std::int64_t rawVal)
852 this->append(rawVal);
855 void operator+=(const double rawVal)
857 this->append(rawVal);
860 void operator+=(const char * const rawVal)
862 this->append(rawVal);
865 void operator+=(const std::string& rawVal)
867 this->append(rawVal);
870 Shared shared() const noexcept
872 return Shared {*this};
876 void _handleAppendLibStatus(const bt_value_array_append_element_status status) const
878 if (status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_MEMORY_ERROR) {
879 throw LibMemoryError {};
884 using ArrayValue = CommonArrayValue<bt_value>;
885 using ConstArrayValue = CommonArrayValue<const bt_value>;
890 * Type of a user function passed to `CommonMapValue<ObjT>::forEach()`.
892 * First argument is the entry's key, second is its value.
894 template <typename ObjT>
895 using CommonMapValueForEachUserFunc = std::function<void(const bpstd::string_view&, ObjT)>;
898 * Template of a function to be passed to bt_value_map_foreach_entry()
899 * for bt_value_map_foreach_entry_const() which calls a user function.
901 * `userData` is casted to a `const` pointer to
902 * `CommonMapValueForEachUserFunc<ObjT>` (the user function to call).
904 * This function catches any exception which the user function throws
905 * and returns the `ErrorStatus` value. If there's no execption, this
906 * function returns the `OkStatus` value.
908 template <typename ObjT, typename LibObjT, typename LibStatusT, int OkStatus, int ErrorStatus>
909 LibStatusT mapValueForEachLibFunc(const char * const key, LibObjT * const libObjPtr,
910 void * const userData)
912 const auto& userFunc = *reinterpret_cast<const CommonMapValueForEachUserFunc<ObjT> *>(userData);
915 userFunc(key, ObjT {libObjPtr});
917 return static_cast<LibStatusT>(ErrorStatus);
920 return static_cast<LibStatusT>(OkStatus);
923 template <typename LibObjT>
924 struct CommonMapValueSpec;
926 // Functions specific to mutable map values
928 struct CommonMapValueSpec<bt_value> final
930 static bt_value *entryByKey(bt_value * const libValPtr, const char * const key) noexcept
932 return bt_value_map_borrow_entry_value(libValPtr, key);
935 static void forEach(bt_value * const libValPtr,
936 const CommonMapValueForEachUserFunc<Value>& func)
938 const auto status = bt_value_map_foreach_entry(
940 mapValueForEachLibFunc<Value, bt_value, bt_value_map_foreach_entry_func_status,
941 BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_OK,
942 BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_ERROR>,
943 const_cast<void *>(reinterpret_cast<const void *>(&func)));
946 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_OK:
948 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_USER_ERROR:
949 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_ERROR:
957 // Functions specific to constant map values
959 struct CommonMapValueSpec<const bt_value> final
961 static const bt_value *entryByKey(const bt_value * const libValPtr,
962 const char * const key) noexcept
964 return bt_value_map_borrow_entry_value_const(libValPtr, key);
967 static void forEach(const bt_value * const libValPtr,
968 const CommonMapValueForEachUserFunc<ConstValue>& func)
970 const auto status = bt_value_map_foreach_entry_const(
972 mapValueForEachLibFunc<ConstValue, const bt_value,
973 bt_value_map_foreach_entry_const_func_status,
974 BT_VALUE_MAP_FOREACH_ENTRY_CONST_FUNC_STATUS_OK,
975 BT_VALUE_MAP_FOREACH_ENTRY_CONST_FUNC_STATUS_ERROR>,
976 const_cast<void *>(reinterpret_cast<const void *>(&func)));
979 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_OK:
981 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_USER_ERROR:
982 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_ERROR:
990 } // namespace internal
992 template <typename LibObjT>
993 class CommonMapValue final : public CommonValue<LibObjT>
996 using typename CommonValue<LibObjT>::_LibObjPtr;
997 using typename CommonValue<LibObjT>::_ThisCommonValue;
1000 using Shared = internal::SharedValue<CommonMapValue<LibObjT>, LibObjT>;
1002 explicit CommonMapValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
1004 BT_ASSERT_DBG(this->isMap());
1007 static Shared create()
1009 const auto libObjPtr = bt_value_map_create();
1011 internal::validateCreatedObjPtr(libObjPtr);
1012 return Shared {CommonMapValue<LibObjT> {libObjPtr}};
1015 template <typename OtherLibObjT>
1016 CommonMapValue(const CommonMapValue<OtherLibObjT>& val) noexcept : _ThisCommonValue {val}
1020 template <typename OtherLibObjT>
1021 CommonMapValue<LibObjT>& operator=(const CommonMapValue<OtherLibObjT>& val) noexcept
1023 _ThisCommonValue::operator=(val);
1027 std::uint64_t size() const noexcept
1029 return bt_value_map_get_size(this->_libObjPtr());
1032 bool isEmpty() const noexcept
1034 return this->size() == 0;
1037 nonstd::optional<ConstValue> operator[](const char * const key) const noexcept
1039 const auto libObjPtr =
1040 internal::CommonMapValueSpec<const bt_value>::entryByKey(this->_libObjPtr(), key);
1043 return nonstd::nullopt;
1046 return ConstValue {libObjPtr};
1049 nonstd::optional<ConstValue> operator[](const std::string& key) const noexcept
1051 return (*this)[key.data()];
1054 nonstd::optional<CommonValue<LibObjT>> operator[](const char * const key) noexcept
1056 const auto libObjPtr =
1057 internal::CommonMapValueSpec<LibObjT>::entryByKey(this->_libObjPtr(), key);
1060 return nonstd::nullopt;
1063 return CommonValue<LibObjT> {libObjPtr};
1066 nonstd::optional<CommonValue<LibObjT>> operator[](const std::string& key) noexcept
1068 return (*this)[key.data()];
1071 bool hasEntry(const char * const key) const noexcept
1073 return static_cast<bool>(bt_value_map_has_entry(this->_libObjPtr(), key));
1076 bool hasEntry(const std::string& key) const noexcept
1078 return this->hasEntry(key.data());
1081 void insert(const char * const key, const Value& val)
1083 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1085 const auto status = bt_value_map_insert_entry(this->_libObjPtr(), key, val._libObjPtr());
1087 this->_handleInsertLibStatus(status);
1090 void insert(const std::string& key, const Value& val)
1092 this->insert(key.data(), val);
1095 void insert(const char * const key, const bool rawVal)
1097 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1100 bt_value_map_insert_bool_entry(this->_libObjPtr(), key, static_cast<bt_bool>(rawVal));
1102 this->_handleInsertLibStatus(status);
1105 void insert(const std::string& key, const bool rawVal)
1107 this->insert(key.data(), rawVal);
1110 void insert(const char * const key, const std::uint64_t rawVal)
1112 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1115 bt_value_map_insert_unsigned_integer_entry(this->_libObjPtr(), key, rawVal);
1117 this->_handleInsertLibStatus(status);
1120 void insert(const std::string& key, const std::uint64_t rawVal)
1122 this->insert(key.data(), rawVal);
1125 void insert(const char * const key, const std::int64_t rawVal)
1127 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1130 bt_value_map_insert_signed_integer_entry(this->_libObjPtr(), key, rawVal);
1132 this->_handleInsertLibStatus(status);
1135 void insert(const std::string& key, const std::int64_t rawVal)
1137 this->insert(key.data(), rawVal);
1140 void insert(const char * const key, const double rawVal)
1142 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1144 const auto status = bt_value_map_insert_real_entry(this->_libObjPtr(), key, rawVal);
1146 this->_handleInsertLibStatus(status);
1149 void insert(const std::string& key, const double rawVal)
1151 this->insert(key.data(), rawVal);
1154 void insert(const char * const key, const char * const rawVal)
1156 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1158 const auto status = bt_value_map_insert_string_entry(this->_libObjPtr(), key, rawVal);
1160 this->_handleInsertLibStatus(status);
1163 void insert(const char * const key, const std::string& rawVal)
1165 this->insert(key, rawVal.data());
1168 void insert(const std::string& key, const char * const rawVal)
1170 this->insert(key.data(), rawVal);
1173 void insert(const std::string& key, const std::string& rawVal)
1175 this->insert(key.data(), rawVal.data());
1178 CommonArrayValue<bt_value> insertEmptyArray(const char *key);
1179 CommonArrayValue<bt_value> insertEmptyArray(const std::string& key);
1180 CommonMapValue<bt_value> insertEmptyMap(const char *key);
1181 CommonMapValue<bt_value> insertEmptyMap(const std::string& key);
1183 void forEach(const internal::CommonMapValueForEachUserFunc<ConstValue>& func) const
1185 internal::CommonMapValueSpec<const bt_value>::forEach(this->_libObjPtr(), func);
1188 void forEach(const internal::CommonMapValueForEachUserFunc<CommonValue<LibObjT>>& func)
1190 internal::CommonMapValueSpec<LibObjT>::forEach(this->_libObjPtr(), func);
1193 Shared shared() const noexcept
1195 return Shared {*this};
1199 void _handleInsertLibStatus(const bt_value_map_insert_entry_status status) const
1201 if (status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_MEMORY_ERROR) {
1202 throw LibMemoryError {};
1207 using MapValue = CommonMapValue<bt_value>;
1208 using ConstMapValue = CommonMapValue<const bt_value>;
1210 template <typename LibObjT>
1211 CommonNullValue<LibObjT> CommonValue<LibObjT>::asNull() const noexcept
1213 BT_ASSERT_DBG(this->isNull());
1214 return CommonNullValue<LibObjT> {this->_libObjPtr()};
1217 template <typename LibObjT>
1218 CommonBoolValue<LibObjT> CommonValue<LibObjT>::asBool() const noexcept
1220 BT_ASSERT_DBG(this->isBool());
1221 return CommonBoolValue<LibObjT> {this->_libObjPtr()};
1224 template <typename LibObjT>
1225 CommonSignedIntegerValue<LibObjT> CommonValue<LibObjT>::asSignedInteger() const noexcept
1227 BT_ASSERT_DBG(this->isSignedInteger());
1228 return CommonSignedIntegerValue<LibObjT> {this->_libObjPtr()};
1231 template <typename LibObjT>
1232 CommonUnsignedIntegerValue<LibObjT> CommonValue<LibObjT>::asUnsignedInteger() const noexcept
1234 BT_ASSERT_DBG(this->isUnsignedInteger());
1235 return CommonUnsignedIntegerValue<LibObjT> {this->_libObjPtr()};
1238 template <typename LibObjT>
1239 CommonRealValue<LibObjT> CommonValue<LibObjT>::asReal() const noexcept
1241 BT_ASSERT_DBG(this->isReal());
1242 return CommonRealValue<LibObjT> {this->_libObjPtr()};
1245 template <typename LibObjT>
1246 CommonStringValue<LibObjT> CommonValue<LibObjT>::asString() const noexcept
1248 BT_ASSERT_DBG(this->isString());
1249 return CommonStringValue<LibObjT> {this->_libObjPtr()};
1252 template <typename LibObjT>
1253 CommonArrayValue<LibObjT> CommonValue<LibObjT>::asArray() const noexcept
1255 BT_ASSERT_DBG(this->isArray());
1256 return CommonArrayValue<LibObjT> {this->_libObjPtr()};
1259 template <typename LibObjT>
1260 CommonMapValue<LibObjT> CommonValue<LibObjT>::asMap() const noexcept
1262 BT_ASSERT_DBG(this->isMap());
1263 return CommonMapValue<LibObjT> {this->_libObjPtr()};
1266 template <typename LibObjT>
1267 ArrayValue CommonArrayValue<LibObjT>::appendEmptyArray()
1269 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1271 bt_value *libElemPtr;
1272 const auto status = bt_value_array_append_empty_array_element(this->_libObjPtr(), &libElemPtr);
1274 this->_handleAppendLibStatus(status);
1275 return ArrayValue {libElemPtr};
1278 template <typename LibObjT>
1279 MapValue CommonArrayValue<LibObjT>::appendEmptyMap()
1281 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1283 bt_value *libElemPtr;
1284 const auto status = bt_value_array_append_empty_map_element(this->_libObjPtr(), &libElemPtr);
1286 this->_handleAppendLibStatus(status);
1287 return MapValue {libElemPtr};
1290 template <typename LibObjT>
1291 ArrayValue CommonMapValue<LibObjT>::insertEmptyArray(const char * const key)
1293 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1295 bt_value *libEntryPtr;
1297 bt_value_map_insert_empty_array_entry(this->_libObjPtr(), key, &libEntryPtr);
1299 this->_handleInsertLibStatus(status);
1300 return ArrayValue {libEntryPtr};
1303 template <typename LibObjT>
1304 ArrayValue CommonMapValue<LibObjT>::insertEmptyArray(const std::string& key)
1306 return this->insertEmptyArray(key.data());
1309 template <typename LibObjT>
1310 MapValue CommonMapValue<LibObjT>::insertEmptyMap(const char * const key)
1312 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1314 bt_value *libEntryPtr;
1315 const auto status = bt_value_map_insert_empty_map_entry(this->_libObjPtr(), key, &libEntryPtr);
1317 this->_handleInsertLibStatus(status);
1318 return MapValue {libEntryPtr};
1321 template <typename LibObjT>
1322 MapValue CommonMapValue<LibObjT>::insertEmptyMap(const std::string& key)
1324 return this->insertEmptyMap(key.data());
1327 inline BoolValue::Shared createValue(const bool rawVal)
1329 return BoolValue::create(rawVal);
1332 inline UnsignedIntegerValue::Shared createValue(const std::uint64_t rawVal)
1334 return UnsignedIntegerValue::create(rawVal);
1337 inline SignedIntegerValue::Shared createValue(const std::int64_t rawVal)
1339 return SignedIntegerValue::create(rawVal);
1342 inline RealValue::Shared createValue(const double rawVal)
1344 return RealValue::create(rawVal);
1347 inline StringValue::Shared createValue(const char * const rawVal)
1349 return StringValue::create(rawVal);
1352 inline StringValue::Shared createValue(const std::string& rawVal)
1354 return StringValue::create(rawVal);
1359 #endif // BABELTRACE_CPP_COMMON_BT2_VALUE_HPP