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>
13 #include <babeltrace2/babeltrace.h>
15 #include "common/assert.h"
16 #include "common/common.h"
17 #include "internal/borrowed-obj.hpp"
18 #include "internal/shared-obj.hpp"
19 #include "internal/utils.hpp"
20 #include "cpp-common/optional.hpp"
21 #include "cpp-common/string_view.hpp"
22 #include "lib-error.hpp"
28 struct ValueRefFuncs final
30 static void get(const bt_value * const libObjPtr)
32 bt_value_get_ref(libObjPtr);
35 static void put(const bt_value * const libObjPtr)
37 bt_value_put_ref(libObjPtr);
41 template <typename ObjT, typename LibObjT>
42 using SharedValue = internal::SharedObj<ObjT, LibObjT, internal::ValueRefFuncs>;
44 } // namespace internal
46 template <typename LibObjT>
47 class CommonNullValue;
49 template <typename LibObjT>
50 class CommonBoolValue;
52 template <typename LibObjT>
53 class CommonUnsignedIntegerValue;
55 template <typename LibObjT>
56 class CommonSignedIntegerValue;
58 template <typename LibObjT>
59 class CommonRealValue;
61 template <typename LibObjT>
62 class CommonStringValue;
64 template <typename LibObjT>
65 class CommonArrayValue;
67 template <typename LibObjT>
72 NUL = BT_VALUE_TYPE_NULL,
73 BOOL = BT_VALUE_TYPE_BOOL,
74 UNSIGNED_INTEGER = BT_VALUE_TYPE_UNSIGNED_INTEGER,
75 SIGNED_INTEGER = BT_VALUE_TYPE_SIGNED_INTEGER,
76 REAL = BT_VALUE_TYPE_REAL,
77 STRING = BT_VALUE_TYPE_STRING,
78 ARRAY = BT_VALUE_TYPE_ARRAY,
79 MAP = BT_VALUE_TYPE_MAP,
82 template <typename LibObjT>
83 class CommonClockClass;
85 template <typename LibObjT>
86 class CommonFieldClass;
88 template <typename LibObjT>
89 class CommonValue : public internal::BorrowedObj<LibObjT>
91 // Allow append() to call `val._libObjPtr()`
92 friend class CommonArrayValue<bt_value>;
94 // Allow insert() to call `val._libObjPtr()`
95 friend class CommonMapValue<bt_value>;
97 // Allow userAttributes() to call `val._libObjPtr()`
98 friend class CommonClockClass<bt_clock_class>;
99 friend class CommonFieldClass<bt_field_class>;
101 // Allow operator==() to call `other._libObjPtr()`
102 friend class CommonValue<bt_value>;
103 friend class CommonValue<const bt_value>;
106 using typename internal::BorrowedObj<LibObjT>::_ThisBorrowedObj;
109 using typename internal::BorrowedObj<LibObjT>::_LibObjPtr;
110 using _ThisCommonValue = CommonValue<LibObjT>;
113 using Shared = internal::SharedValue<CommonValue<LibObjT>, LibObjT>;
115 explicit CommonValue(const _LibObjPtr libObjPtr) noexcept : _ThisBorrowedObj {libObjPtr}
119 template <typename OtherLibObjT>
120 CommonValue(const CommonValue<OtherLibObjT>& val) noexcept : _ThisBorrowedObj {val}
124 template <typename OtherLibObjT>
125 _ThisCommonValue& operator=(const CommonValue<OtherLibObjT>& val) noexcept
127 _ThisBorrowedObj::operator=(val);
131 ValueType type() const noexcept
133 return static_cast<ValueType>(bt_value_get_type(this->_libObjPtr()));
136 bool isNull() const noexcept
138 return this->_libTypeIs(BT_VALUE_TYPE_NULL);
141 bool isBool() const noexcept
143 return this->_libTypeIs(BT_VALUE_TYPE_BOOL);
146 bool isInteger() const noexcept
148 return this->_libTypeIs(BT_VALUE_TYPE_INTEGER);
151 bool isUnsignedInteger() const noexcept
153 return this->_libTypeIs(BT_VALUE_TYPE_UNSIGNED_INTEGER);
156 bool isSignedInteger() const noexcept
158 return this->_libTypeIs(BT_VALUE_TYPE_SIGNED_INTEGER);
161 bool isReal() const noexcept
163 return this->_libTypeIs(BT_VALUE_TYPE_REAL);
166 bool isString() const noexcept
168 return this->_libTypeIs(BT_VALUE_TYPE_STRING);
171 bool isArray() const noexcept
173 return this->_libTypeIs(BT_VALUE_TYPE_ARRAY);
176 bool isMap() const noexcept
178 return this->_libTypeIs(BT_VALUE_TYPE_MAP);
181 template <typename OtherLibObjT>
182 bool operator==(const CommonValue<OtherLibObjT>& other) const noexcept
184 return static_cast<bool>(bt_value_is_equal(this->_libObjPtr(), other._libObjPtr()));
187 template <typename OtherLibObjT>
188 bool operator!=(const CommonValue<OtherLibObjT>& other) const noexcept
190 return !(*this == other);
193 Shared shared() const noexcept
195 return Shared {*this};
198 CommonNullValue<LibObjT> asNull() const noexcept;
199 CommonBoolValue<LibObjT> asBool() const noexcept;
200 CommonSignedIntegerValue<LibObjT> asSignedInteger() const noexcept;
201 CommonUnsignedIntegerValue<LibObjT> asUnsignedInteger() const noexcept;
202 CommonRealValue<LibObjT> asReal() const noexcept;
203 CommonStringValue<LibObjT> asString() const noexcept;
204 CommonArrayValue<LibObjT> asArray() const noexcept;
205 CommonMapValue<LibObjT> asMap() const noexcept;
208 bool _libTypeIs(const bt_value_type type) const noexcept
210 return bt_value_type_is(bt_value_get_type(this->_libObjPtr()), type);
214 using Value = CommonValue<bt_value>;
215 using ConstValue = CommonValue<const bt_value>;
217 template <typename LibObjT>
218 class CommonNullValue final : public CommonValue<LibObjT>
221 using typename CommonValue<LibObjT>::_ThisCommonValue;
224 using Shared = internal::SharedValue<CommonNullValue<LibObjT>, LibObjT>;
226 CommonNullValue() noexcept : _ThisCommonValue {bt_value_null}
230 template <typename OtherLibObjT>
231 CommonNullValue(const CommonNullValue<OtherLibObjT>& val) noexcept : _ThisCommonValue {val}
235 template <typename OtherLibObjT>
236 CommonNullValue<LibObjT>& operator=(const CommonNullValue<OtherLibObjT>& val) noexcept
238 _ThisCommonValue::operator=(val);
242 Shared shared() const noexcept
244 return Shared {*this};
248 using NullValue = CommonNullValue<bt_value>;
249 using ConstNullValue = CommonNullValue<const bt_value>;
251 template <typename LibObjT>
252 class CommonBoolValue final : public CommonValue<LibObjT>
255 using typename CommonValue<LibObjT>::_LibObjPtr;
256 using typename CommonValue<LibObjT>::_ThisCommonValue;
259 using Shared = internal::SharedValue<CommonBoolValue<LibObjT>, LibObjT>;
262 explicit CommonBoolValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
264 BT_ASSERT_DBG(this->isBool());
267 template <typename OtherLibObjT>
268 CommonBoolValue(const CommonBoolValue<OtherLibObjT>& val) noexcept : _ThisCommonValue {val}
272 static Shared create(const Value rawVal = false)
274 const auto libObjPtr = bt_value_bool_create_init(static_cast<bt_bool>(rawVal));
276 internal::validateCreatedObjPtr(libObjPtr);
277 return Shared {CommonBoolValue<LibObjT> {libObjPtr}};
280 template <typename OtherLibObjT>
281 CommonBoolValue<LibObjT>& operator=(const CommonBoolValue<OtherLibObjT>& val) noexcept
283 _ThisCommonValue::operator=(val);
287 CommonBoolValue<LibObjT>& operator=(const Value rawVal) noexcept
289 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
291 bt_value_bool_set(this->_libObjPtr(), static_cast<bt_bool>(rawVal));
295 Value value() const noexcept
297 return static_cast<Value>(bt_value_bool_get(this->_libObjPtr()));
300 operator Value() const noexcept
302 return this->value();
305 Shared shared() const noexcept
307 return Shared {*this};
311 using BoolValue = CommonBoolValue<bt_value>;
312 using ConstBoolValue = CommonBoolValue<const bt_value>;
314 template <typename LibObjT>
315 class CommonUnsignedIntegerValue final : public CommonValue<LibObjT>
318 using typename CommonValue<LibObjT>::_LibObjPtr;
319 using typename CommonValue<LibObjT>::_ThisCommonValue;
322 using Shared = internal::SharedValue<CommonUnsignedIntegerValue<LibObjT>, LibObjT>;
323 using Value = std::uint64_t;
325 explicit CommonUnsignedIntegerValue(const _LibObjPtr libObjPtr) noexcept :
326 _ThisCommonValue {libObjPtr}
328 BT_ASSERT_DBG(this->isUnsignedInteger());
331 static Shared create(const Value rawVal = 0)
333 const auto libObjPtr = bt_value_integer_unsigned_create_init(rawVal);
335 internal::validateCreatedObjPtr(libObjPtr);
336 return Shared {CommonUnsignedIntegerValue<LibObjT> {libObjPtr}};
339 template <typename OtherLibObjT>
340 CommonUnsignedIntegerValue(const CommonUnsignedIntegerValue<OtherLibObjT>& val) noexcept :
341 _ThisCommonValue {val}
345 template <typename OtherLibObjT>
346 CommonUnsignedIntegerValue<LibObjT>&
347 operator=(const CommonUnsignedIntegerValue<OtherLibObjT>& val) noexcept
349 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
351 _ThisCommonValue::operator=(val);
355 CommonUnsignedIntegerValue<LibObjT>& operator=(const Value rawVal) noexcept
357 bt_value_integer_unsigned_set(this->_libObjPtr(), rawVal);
361 Value value() const noexcept
363 return bt_value_integer_unsigned_get(this->_libObjPtr());
366 operator Value() const noexcept
368 return this->value();
371 Shared shared() const noexcept
373 return Shared {*this};
377 using UnsignedIntegerValue = CommonUnsignedIntegerValue<bt_value>;
378 using ConstUnsignedIntegerValue = CommonUnsignedIntegerValue<const bt_value>;
380 template <typename LibObjT>
381 class CommonSignedIntegerValue final : public CommonValue<LibObjT>
384 using typename CommonValue<LibObjT>::_LibObjPtr;
385 using typename CommonValue<LibObjT>::_ThisCommonValue;
388 using Shared = internal::SharedValue<CommonSignedIntegerValue<LibObjT>, LibObjT>;
389 using Value = std::int64_t;
391 explicit CommonSignedIntegerValue(const _LibObjPtr libObjPtr) noexcept :
392 _ThisCommonValue {libObjPtr}
394 BT_ASSERT_DBG(this->isSignedInteger());
397 static Shared create(const Value rawVal = 0)
399 const auto libObjPtr = bt_value_integer_signed_create_init(rawVal);
401 internal::validateCreatedObjPtr(libObjPtr);
402 return Shared {CommonSignedIntegerValue<LibObjT> {libObjPtr}};
405 template <typename OtherLibObjT>
406 CommonSignedIntegerValue(const CommonSignedIntegerValue<OtherLibObjT>& val) noexcept :
407 _ThisCommonValue {val}
411 template <typename OtherLibObjT>
412 CommonSignedIntegerValue<LibObjT>&
413 operator=(const CommonSignedIntegerValue<OtherLibObjT>& val) noexcept
415 _ThisCommonValue::operator=(val);
419 CommonSignedIntegerValue<LibObjT>& operator=(const Value rawVal) noexcept
421 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
423 bt_value_integer_signed_set(this->_libObjPtr(), rawVal);
427 Value value() const noexcept
429 return bt_value_integer_signed_get(this->_libObjPtr());
432 operator Value() const noexcept
434 return this->value();
437 Shared shared() const noexcept
439 return Shared {*this};
443 using SignedIntegerValue = CommonSignedIntegerValue<bt_value>;
444 using ConstSignedIntegerValue = CommonSignedIntegerValue<const bt_value>;
446 template <typename LibObjT>
447 class CommonRealValue final : public CommonValue<LibObjT>
450 using typename CommonValue<LibObjT>::_LibObjPtr;
451 using typename CommonValue<LibObjT>::_ThisCommonValue;
454 using Shared = internal::SharedValue<CommonRealValue<LibObjT>, LibObjT>;
455 using Value = double;
457 explicit CommonRealValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
459 BT_ASSERT_DBG(this->isReal());
462 static Shared create(const Value rawVal = 0)
464 const auto libObjPtr = bt_value_real_create_init(rawVal);
466 internal::validateCreatedObjPtr(libObjPtr);
467 return Shared {CommonRealValue<LibObjT> {libObjPtr}};
470 template <typename OtherLibObjT>
471 CommonRealValue(const CommonRealValue<OtherLibObjT>& val) noexcept : _ThisCommonValue {val}
475 template <typename OtherLibObjT>
476 CommonRealValue<LibObjT>& operator=(const CommonRealValue<OtherLibObjT>& val) noexcept
478 _ThisCommonValue::operator=(val);
482 CommonRealValue<LibObjT>& operator=(const Value rawVal) noexcept
484 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
486 bt_value_real_set(this->_libObjPtr(), rawVal);
490 Value value() const noexcept
492 return bt_value_real_get(this->_libObjPtr());
495 operator Value() const noexcept
497 return this->value();
500 Shared shared() const noexcept
502 return Shared {*this};
506 using RealValue = CommonRealValue<bt_value>;
507 using ConstRealValue = CommonRealValue<const bt_value>;
509 template <typename LibObjT>
510 class CommonStringValue final : public CommonValue<LibObjT>
513 using typename CommonValue<LibObjT>::_LibObjPtr;
514 using typename CommonValue<LibObjT>::_ThisCommonValue;
517 using Shared = internal::SharedValue<CommonStringValue<LibObjT>, LibObjT>;
519 explicit CommonStringValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
521 BT_ASSERT_DBG(this->isString());
524 static Shared create(const char * const rawVal = "")
526 const auto libObjPtr = bt_value_string_create_init(rawVal);
528 internal::validateCreatedObjPtr(libObjPtr);
529 return Shared {CommonStringValue<LibObjT> {libObjPtr}};
532 static Shared create(const std::string& rawVal)
534 return CommonStringValue<LibObjT>::create(rawVal.data());
537 template <typename OtherLibObjT>
538 CommonStringValue(const CommonStringValue<OtherLibObjT>& val) noexcept : _ThisCommonValue {val}
542 template <typename OtherLibObjT>
543 CommonStringValue<LibObjT>& operator=(const CommonStringValue<OtherLibObjT>& val) noexcept
545 _ThisCommonValue::operator=(val);
549 CommonStringValue<LibObjT>& operator=(const char * const rawVal)
551 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
553 const auto status = bt_value_string_set(this->_libObjPtr(), rawVal);
555 if (status == BT_VALUE_STRING_SET_STATUS_MEMORY_ERROR) {
556 throw LibMemoryError {};
562 CommonStringValue<LibObjT>& operator=(const std::string& rawVal) noexcept
564 return *this = rawVal.data();
567 bpstd::string_view value() const noexcept
569 return bt_value_string_get(this->_libObjPtr());
572 Shared shared() const noexcept
574 return Shared {*this};
578 using StringValue = CommonStringValue<bt_value>;
579 using ConstStringValue = CommonStringValue<const bt_value>;
583 template <typename LibObjT>
584 struct CommonArrayValueSpec;
586 // Functions specific to mutable array values
588 struct CommonArrayValueSpec<bt_value> final
590 static bt_value *elementByIndex(bt_value * const libValPtr, const std::uint64_t index) noexcept
592 return bt_value_array_borrow_element_by_index(libValPtr, index);
596 // Functions specific to constant array values
598 struct CommonArrayValueSpec<const bt_value> final
600 static const bt_value *elementByIndex(const bt_value * const libValPtr,
601 const std::uint64_t index) noexcept
603 return bt_value_array_borrow_element_by_index_const(libValPtr, index);
607 } // namespace internal
609 template <typename LibObjT>
610 class CommonArrayValue final : public CommonValue<LibObjT>
613 using typename CommonValue<LibObjT>::_LibObjPtr;
614 using typename CommonValue<LibObjT>::_ThisCommonValue;
617 using Shared = internal::SharedValue<CommonArrayValue<LibObjT>, LibObjT>;
619 explicit CommonArrayValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
621 BT_ASSERT_DBG(this->isArray());
624 static Shared create()
626 const auto libObjPtr = bt_value_array_create();
628 internal::validateCreatedObjPtr(libObjPtr);
629 return Shared {CommonArrayValue<LibObjT> {libObjPtr}};
632 template <typename OtherLibObjT>
633 CommonArrayValue(const CommonArrayValue<OtherLibObjT>& val) noexcept : _ThisCommonValue {val}
637 template <typename OtherLibObjT>
638 CommonArrayValue<LibObjT>& operator=(const CommonArrayValue<OtherLibObjT>& val) noexcept
640 _ThisCommonValue::operator=(val);
644 std::uint64_t length() const noexcept
646 return bt_value_array_get_length(this->_libObjPtr());
649 bool isEmpty() const noexcept
651 return this->length() == 0;
654 ConstValue operator[](const std::uint64_t index) const noexcept
656 return ConstValue {internal::CommonArrayValueSpec<const bt_value>::elementByIndex(
657 this->_libObjPtr(), index)};
660 CommonValue<LibObjT> operator[](const std::uint64_t index) noexcept
662 return CommonValue<LibObjT> {
663 internal::CommonArrayValueSpec<LibObjT>::elementByIndex(this->_libObjPtr(), index)};
666 void append(const Value& val)
668 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
670 const auto status = bt_value_array_append_element(this->_libObjPtr(), val._libObjPtr());
672 this->_handleAppendLibStatus(status);
675 void append(const bool rawVal)
677 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
680 bt_value_array_append_bool_element(this->_libObjPtr(), static_cast<bt_bool>(rawVal));
682 this->_handleAppendLibStatus(status);
685 void append(const std::uint64_t rawVal)
687 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
690 bt_value_array_append_unsigned_integer_element(this->_libObjPtr(), rawVal);
692 this->_handleAppendLibStatus(status);
695 void append(const std::int64_t rawVal)
697 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
700 bt_value_array_append_signed_integer_element(this->_libObjPtr(), rawVal);
702 this->_handleAppendLibStatus(status);
705 void append(const double rawVal)
707 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
709 const auto status = bt_value_array_append_real_element(this->_libObjPtr(), rawVal);
711 this->_handleAppendLibStatus(status);
714 void append(const char * const rawVal)
716 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
718 const auto status = bt_value_array_append_string_element(this->_libObjPtr(), rawVal);
720 this->_handleAppendLibStatus(status);
723 void append(const std::string& rawVal)
725 this->append(rawVal.data());
728 CommonArrayValue<bt_value> appendEmptyArray();
729 CommonMapValue<bt_value> appendEmptyMap();
731 void operator+=(const Value& val)
736 void operator+=(const bool rawVal)
738 this->append(rawVal);
741 void operator+=(const std::uint64_t rawVal)
743 this->append(rawVal);
746 void operator+=(const std::int64_t rawVal)
748 this->append(rawVal);
751 void operator+=(const double rawVal)
753 this->append(rawVal);
756 void operator+=(const char * const rawVal)
758 this->append(rawVal);
761 void operator+=(const std::string& rawVal)
763 this->append(rawVal);
766 Shared shared() const noexcept
768 return Shared {*this};
772 void _handleAppendLibStatus(const bt_value_array_append_element_status status) const
774 if (status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_MEMORY_ERROR) {
775 throw LibMemoryError {};
780 using ArrayValue = CommonArrayValue<bt_value>;
781 using ConstArrayValue = CommonArrayValue<const bt_value>;
786 * Type of a user function passed to `CommonMapValue<ObjT>::forEach()`.
788 * First argument is the entry's key, second is its value.
790 template <typename ObjT>
791 using CommonMapValueForEachUserFunc = std::function<void(const bpstd::string_view&, ObjT)>;
794 * Template of a function to be passed to bt_value_map_foreach_entry()
795 * for bt_value_map_foreach_entry_const() which calls a user function.
797 * `userData` is casted to a `const` pointer to
798 * `CommonMapValueForEachUserFunc<ObjT>` (the user function to call).
800 * This function catches any exception which the user function throws
801 * and returns the `ErrorStatus` value. If there's no execption, this
802 * function returns the `OkStatus` value.
804 template <typename ObjT, typename LibObjT, typename LibStatusT, int OkStatus, int ErrorStatus>
805 LibStatusT mapValueForEachLibFunc(const char * const key, LibObjT * const libObjPtr,
806 void * const userData)
808 const auto& userFunc = *reinterpret_cast<const CommonMapValueForEachUserFunc<ObjT> *>(userData);
811 userFunc(key, ObjT {libObjPtr});
813 return static_cast<LibStatusT>(ErrorStatus);
816 return static_cast<LibStatusT>(OkStatus);
819 template <typename LibObjT>
820 struct CommonMapValueSpec;
822 // Functions specific to mutable map values
824 struct CommonMapValueSpec<bt_value> final
826 static bt_value *entryByKey(bt_value * const libValPtr, const char * const key) noexcept
828 return bt_value_map_borrow_entry_value(libValPtr, key);
831 static void forEach(bt_value * const libValPtr,
832 const CommonMapValueForEachUserFunc<Value>& func)
834 const auto status = bt_value_map_foreach_entry(
836 mapValueForEachLibFunc<Value, bt_value, bt_value_map_foreach_entry_func_status,
837 BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_OK,
838 BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_ERROR>,
839 const_cast<void *>(reinterpret_cast<const void *>(&func)));
842 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_OK:
844 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_USER_ERROR:
845 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_ERROR:
853 // Functions specific to constant map values
855 struct CommonMapValueSpec<const bt_value> final
857 static const bt_value *entryByKey(const bt_value * const libValPtr,
858 const char * const key) noexcept
860 return bt_value_map_borrow_entry_value_const(libValPtr, key);
863 static void forEach(const bt_value * const libValPtr,
864 const CommonMapValueForEachUserFunc<ConstValue>& func)
866 const auto status = bt_value_map_foreach_entry_const(
868 mapValueForEachLibFunc<ConstValue, const bt_value,
869 bt_value_map_foreach_entry_const_func_status,
870 BT_VALUE_MAP_FOREACH_ENTRY_CONST_FUNC_STATUS_OK,
871 BT_VALUE_MAP_FOREACH_ENTRY_CONST_FUNC_STATUS_ERROR>,
872 const_cast<void *>(reinterpret_cast<const void *>(&func)));
875 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_OK:
877 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_USER_ERROR:
878 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_ERROR:
886 } // namespace internal
888 template <typename LibObjT>
889 class CommonMapValue final : public CommonValue<LibObjT>
892 using typename CommonValue<LibObjT>::_LibObjPtr;
893 using typename CommonValue<LibObjT>::_ThisCommonValue;
896 using Shared = internal::SharedValue<CommonMapValue<LibObjT>, LibObjT>;
898 explicit CommonMapValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
900 BT_ASSERT_DBG(this->isMap());
903 static Shared create()
905 const auto libObjPtr = bt_value_map_create();
907 internal::validateCreatedObjPtr(libObjPtr);
908 return Shared {CommonMapValue<LibObjT> {libObjPtr}};
911 template <typename OtherLibObjT>
912 CommonMapValue(const CommonMapValue<OtherLibObjT>& val) noexcept : _ThisCommonValue {val}
916 template <typename OtherLibObjT>
917 CommonMapValue<LibObjT>& operator=(const CommonMapValue<OtherLibObjT>& val) noexcept
919 _ThisCommonValue::operator=(val);
923 std::uint64_t size() const noexcept
925 return bt_value_map_get_size(this->_libObjPtr());
928 bool isEmpty() const noexcept
930 return this->size() == 0;
933 nonstd::optional<ConstValue> operator[](const char * const key) const noexcept
935 const auto libObjPtr =
936 internal::CommonMapValueSpec<const bt_value>::entryByKey(this->_libObjPtr(), key);
939 return nonstd::nullopt;
942 return ConstValue {libObjPtr};
945 nonstd::optional<ConstValue> operator[](const std::string& key) const noexcept
947 return (*this)[key.data()];
950 nonstd::optional<CommonValue<LibObjT>> operator[](const char * const key) noexcept
952 const auto libObjPtr =
953 internal::CommonMapValueSpec<LibObjT>::entryByKey(this->_libObjPtr(), key);
956 return nonstd::nullopt;
959 return CommonValue<LibObjT> {libObjPtr};
962 nonstd::optional<CommonValue<LibObjT>> operator[](const std::string& key) noexcept
964 return (*this)[key.data()];
967 bool hasEntry(const char * const key) const noexcept
969 return static_cast<bool>(bt_value_map_has_entry(this->_libObjPtr(), key));
972 bool hasEntry(const std::string& key) const noexcept
974 return this->hasEntry(key.data());
977 void insert(const char * const key, const Value& val)
979 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
981 const auto status = bt_value_map_insert_entry(this->_libObjPtr(), key, val._libObjPtr());
983 this->_handleInsertLibStatus(status);
986 void insert(const std::string& key, const Value& val)
988 this->insert(key.data(), val);
991 void insert(const char * const key, const bool rawVal)
993 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
996 bt_value_map_insert_bool_entry(this->_libObjPtr(), key, static_cast<bt_bool>(rawVal));
998 this->_handleInsertLibStatus(status);
1001 void insert(const std::string& key, const bool rawVal)
1003 this->insert(key.data(), rawVal);
1006 void insert(const char * const key, const std::uint64_t rawVal)
1008 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1011 bt_value_map_insert_unsigned_integer_entry(this->_libObjPtr(), key, rawVal);
1013 this->_handleInsertLibStatus(status);
1016 void insert(const std::string& key, const std::uint64_t rawVal)
1018 this->insert(key.data(), rawVal);
1021 void insert(const char * const key, const std::int64_t rawVal)
1023 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1026 bt_value_map_insert_signed_integer_entry(this->_libObjPtr(), key, rawVal);
1028 this->_handleInsertLibStatus(status);
1031 void insert(const std::string& key, const std::int64_t rawVal)
1033 this->insert(key.data(), rawVal);
1036 void insert(const char * const key, const double rawVal)
1038 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1040 const auto status = bt_value_map_insert_real_entry(this->_libObjPtr(), key, rawVal);
1042 this->_handleInsertLibStatus(status);
1045 void insert(const std::string& key, const double rawVal)
1047 this->insert(key.data(), rawVal);
1050 void insert(const char * const key, const char * const rawVal)
1052 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1054 const auto status = bt_value_map_insert_string_entry(this->_libObjPtr(), key, rawVal);
1056 this->_handleInsertLibStatus(status);
1059 void insert(const char * const key, const std::string& rawVal)
1061 this->insert(key, rawVal.data());
1064 void insert(const std::string& key, const char * const rawVal)
1066 this->insert(key.data(), rawVal);
1069 void insert(const std::string& key, const std::string& rawVal)
1071 this->insert(key.data(), rawVal.data());
1074 CommonArrayValue<bt_value> insertEmptyArray(const char *key);
1075 CommonArrayValue<bt_value> insertEmptyArray(const std::string& key);
1076 CommonMapValue<bt_value> insertEmptyMap(const char *key);
1077 CommonMapValue<bt_value> insertEmptyMap(const std::string& key);
1079 void forEach(const internal::CommonMapValueForEachUserFunc<ConstValue>& func) const
1081 internal::CommonMapValueSpec<const bt_value>::forEach(this->_libObjPtr(), func);
1084 void forEach(const internal::CommonMapValueForEachUserFunc<CommonValue<LibObjT>>& func)
1086 internal::CommonMapValueSpec<LibObjT>::forEach(this->_libObjPtr(), func);
1089 Shared shared() const noexcept
1091 return Shared {*this};
1095 void _handleInsertLibStatus(const bt_value_map_insert_entry_status status) const
1097 if (status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_MEMORY_ERROR) {
1098 throw LibMemoryError {};
1103 using MapValue = CommonMapValue<bt_value>;
1104 using ConstMapValue = CommonMapValue<const bt_value>;
1106 template <typename LibObjT>
1107 CommonNullValue<LibObjT> CommonValue<LibObjT>::asNull() const noexcept
1109 BT_ASSERT_DBG(this->isNull());
1110 return CommonNullValue<LibObjT> {this->_libObjPtr()};
1113 template <typename LibObjT>
1114 CommonBoolValue<LibObjT> CommonValue<LibObjT>::asBool() const noexcept
1116 BT_ASSERT_DBG(this->isBool());
1117 return CommonBoolValue<LibObjT> {this->_libObjPtr()};
1120 template <typename LibObjT>
1121 CommonSignedIntegerValue<LibObjT> CommonValue<LibObjT>::asSignedInteger() const noexcept
1123 BT_ASSERT_DBG(this->isSignedInteger());
1124 return CommonSignedIntegerValue<LibObjT> {this->_libObjPtr()};
1127 template <typename LibObjT>
1128 CommonUnsignedIntegerValue<LibObjT> CommonValue<LibObjT>::asUnsignedInteger() const noexcept
1130 BT_ASSERT_DBG(this->isUnsignedInteger());
1131 return CommonUnsignedIntegerValue<LibObjT> {this->_libObjPtr()};
1134 template <typename LibObjT>
1135 CommonRealValue<LibObjT> CommonValue<LibObjT>::asReal() const noexcept
1137 BT_ASSERT_DBG(this->isReal());
1138 return CommonRealValue<LibObjT> {this->_libObjPtr()};
1141 template <typename LibObjT>
1142 CommonStringValue<LibObjT> CommonValue<LibObjT>::asString() const noexcept
1144 BT_ASSERT_DBG(this->isString());
1145 return CommonStringValue<LibObjT> {this->_libObjPtr()};
1148 template <typename LibObjT>
1149 CommonArrayValue<LibObjT> CommonValue<LibObjT>::asArray() const noexcept
1151 BT_ASSERT_DBG(this->isArray());
1152 return CommonArrayValue<LibObjT> {this->_libObjPtr()};
1155 template <typename LibObjT>
1156 CommonMapValue<LibObjT> CommonValue<LibObjT>::asMap() const noexcept
1158 BT_ASSERT_DBG(this->isMap());
1159 return CommonMapValue<LibObjT> {this->_libObjPtr()};
1162 template <typename LibObjT>
1163 ArrayValue CommonArrayValue<LibObjT>::appendEmptyArray()
1165 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1167 bt_value *libElemPtr;
1168 const auto status = bt_value_array_append_empty_array_element(this->_libObjPtr(), &libElemPtr);
1170 this->_handleAppendLibStatus(status);
1171 return ArrayValue {libElemPtr};
1174 template <typename LibObjT>
1175 MapValue CommonArrayValue<LibObjT>::appendEmptyMap()
1177 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1179 bt_value *libElemPtr;
1180 const auto status = bt_value_array_append_empty_map_element(this->_libObjPtr(), &libElemPtr);
1182 this->_handleAppendLibStatus(status);
1183 return MapValue {libElemPtr};
1186 template <typename LibObjT>
1187 ArrayValue CommonMapValue<LibObjT>::insertEmptyArray(const char * const key)
1189 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1191 bt_value *libEntryPtr;
1193 bt_value_map_insert_empty_array_entry(this->_libObjPtr(), key, &libEntryPtr);
1195 this->_handleInsertLibStatus(status);
1196 return ArrayValue {libEntryPtr};
1199 template <typename LibObjT>
1200 ArrayValue CommonMapValue<LibObjT>::insertEmptyArray(const std::string& key)
1202 return this->insertEmptyArray(key.data());
1205 template <typename LibObjT>
1206 MapValue CommonMapValue<LibObjT>::insertEmptyMap(const char * const key)
1208 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1210 bt_value *libEntryPtr;
1211 const auto status = bt_value_map_insert_empty_map_entry(this->_libObjPtr(), key, &libEntryPtr);
1213 this->_handleInsertLibStatus(status);
1214 return MapValue {libEntryPtr};
1217 template <typename LibObjT>
1218 MapValue CommonMapValue<LibObjT>::insertEmptyMap(const std::string& key)
1220 return this->insertEmptyMap(key.data());
1223 inline BoolValue::Shared createValue(const bool rawVal)
1225 return BoolValue::create(rawVal);
1228 inline UnsignedIntegerValue::Shared createValue(const std::uint64_t rawVal)
1230 return UnsignedIntegerValue::create(rawVal);
1233 inline SignedIntegerValue::Shared createValue(const std::int64_t rawVal)
1235 return SignedIntegerValue::create(rawVal);
1238 inline RealValue::Shared createValue(const double rawVal)
1240 return RealValue::create(rawVal);
1243 inline StringValue::Shared createValue(const char * const rawVal)
1245 return StringValue::create(rawVal);
1248 inline StringValue::Shared createValue(const std::string& rawVal)
1250 return StringValue::create(rawVal);
1255 #endif // BABELTRACE_CPP_COMMON_BT2_VALUE_HPP