2 * Copyright (c) 2020 Philippe Proulx <pproulx@efficios.com>
4 * SPDX-License-Identifier: MIT
7 #ifndef BABELTRACE_CPP_COMMON_BT2_VALUE_HPP
8 #define BABELTRACE_CPP_COMMON_BT2_VALUE_HPP
10 #include <type_traits>
14 #include <babeltrace2/babeltrace.h>
16 #include "common/assert.h"
17 #include "common/common.h"
18 #include "common-iter.hpp"
19 #include "internal/borrowed-obj.hpp"
20 #include "internal/shared-obj.hpp"
21 #include "internal/utils.hpp"
22 #include "cpp-common/optional.hpp"
23 #include "cpp-common/string_view.hpp"
24 #include "lib-error.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 template <typename ObjT, typename LibObjT>
44 using SharedValue = internal::SharedObj<ObjT, LibObjT, internal::ValueRefFuncs>;
46 } /* namespace internal */
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 internal::BorrowedObj<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 internal::BorrowedObj<LibObjT>::_ThisBorrowedObj;
127 using typename internal::BorrowedObj<LibObjT>::_LibObjPtr;
128 using _ThisCommonValue = CommonValue<LibObjT>;
131 using Shared = internal::SharedValue<CommonValue<LibObjT>, LibObjT>;
133 explicit CommonValue(const _LibObjPtr libObjPtr) noexcept : _ThisBorrowedObj {libObjPtr}
137 template <typename OtherLibObjT>
138 CommonValue(const CommonValue<OtherLibObjT>& val) noexcept : _ThisBorrowedObj {val}
142 template <typename OtherLibObjT>
143 _ThisCommonValue& operator=(const CommonValue<OtherLibObjT>& val) noexcept
145 _ThisBorrowedObj::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 {*this};
216 CommonNullValue<LibObjT> asNull() const noexcept;
217 CommonBoolValue<LibObjT> asBool() const noexcept;
218 CommonSignedIntegerValue<LibObjT> asSignedInteger() const noexcept;
219 CommonUnsignedIntegerValue<LibObjT> asUnsignedInteger() const noexcept;
220 CommonRealValue<LibObjT> asReal() const noexcept;
221 CommonStringValue<LibObjT> asString() const noexcept;
222 CommonArrayValue<LibObjT> asArray() const noexcept;
223 CommonMapValue<LibObjT> asMap() const noexcept;
226 bool _libTypeIs(const bt_value_type type) const noexcept
228 return bt_value_type_is(bt_value_get_type(this->_libObjPtr()), type);
232 using Value = CommonValue<bt_value>;
233 using ConstValue = CommonValue<const bt_value>;
235 template <typename LibObjT>
236 class CommonNullValue final : public CommonValue<LibObjT>
239 using typename CommonValue<LibObjT>::_ThisCommonValue;
242 using Shared = internal::SharedValue<CommonNullValue<LibObjT>, LibObjT>;
244 CommonNullValue() noexcept : _ThisCommonValue {bt_value_null}
248 template <typename OtherLibObjT>
249 CommonNullValue(const CommonNullValue<OtherLibObjT>& val) noexcept : _ThisCommonValue {val}
253 template <typename OtherLibObjT>
254 CommonNullValue<LibObjT>& operator=(const CommonNullValue<OtherLibObjT>& val) noexcept
256 _ThisCommonValue::operator=(val);
260 Shared shared() const noexcept
262 return Shared {*this};
266 using NullValue = CommonNullValue<bt_value>;
267 using ConstNullValue = CommonNullValue<const bt_value>;
269 template <typename LibObjT>
270 class CommonBoolValue final : public CommonValue<LibObjT>
273 using typename CommonValue<LibObjT>::_LibObjPtr;
274 using typename CommonValue<LibObjT>::_ThisCommonValue;
277 using Shared = internal::SharedValue<CommonBoolValue<LibObjT>, LibObjT>;
280 explicit CommonBoolValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
282 BT_ASSERT_DBG(this->isBool());
285 template <typename OtherLibObjT>
286 CommonBoolValue(const CommonBoolValue<OtherLibObjT>& val) noexcept : _ThisCommonValue {val}
290 static Shared create(const Value rawVal = false)
292 const auto libObjPtr = bt_value_bool_create_init(static_cast<bt_bool>(rawVal));
294 internal::validateCreatedObjPtr(libObjPtr);
295 return Shared {CommonBoolValue<LibObjT> {libObjPtr}};
298 template <typename OtherLibObjT>
299 CommonBoolValue<LibObjT>& operator=(const CommonBoolValue<OtherLibObjT>& val) noexcept
301 _ThisCommonValue::operator=(val);
305 CommonBoolValue<LibObjT>& operator=(const Value rawVal) noexcept
307 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
309 bt_value_bool_set(this->_libObjPtr(), static_cast<bt_bool>(rawVal));
313 Value value() const noexcept
315 return static_cast<Value>(bt_value_bool_get(this->_libObjPtr()));
318 operator Value() const noexcept
320 return this->value();
323 Shared shared() const noexcept
325 return Shared {*this};
329 using BoolValue = CommonBoolValue<bt_value>;
330 using ConstBoolValue = CommonBoolValue<const bt_value>;
332 template <typename LibObjT>
333 class CommonUnsignedIntegerValue final : public CommonValue<LibObjT>
336 using typename CommonValue<LibObjT>::_LibObjPtr;
337 using typename CommonValue<LibObjT>::_ThisCommonValue;
340 using Shared = internal::SharedValue<CommonUnsignedIntegerValue<LibObjT>, LibObjT>;
341 using Value = std::uint64_t;
343 explicit CommonUnsignedIntegerValue(const _LibObjPtr libObjPtr) noexcept :
344 _ThisCommonValue {libObjPtr}
346 BT_ASSERT_DBG(this->isUnsignedInteger());
349 static Shared create(const Value rawVal = 0)
351 const auto libObjPtr = bt_value_integer_unsigned_create_init(rawVal);
353 internal::validateCreatedObjPtr(libObjPtr);
354 return Shared {CommonUnsignedIntegerValue<LibObjT> {libObjPtr}};
357 template <typename OtherLibObjT>
358 CommonUnsignedIntegerValue(const CommonUnsignedIntegerValue<OtherLibObjT>& val) noexcept :
359 _ThisCommonValue {val}
363 template <typename OtherLibObjT>
364 CommonUnsignedIntegerValue<LibObjT>&
365 operator=(const CommonUnsignedIntegerValue<OtherLibObjT>& val) noexcept
367 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
369 _ThisCommonValue::operator=(val);
373 CommonUnsignedIntegerValue<LibObjT>& operator=(const Value rawVal) noexcept
375 bt_value_integer_unsigned_set(this->_libObjPtr(), rawVal);
379 Value value() const noexcept
381 return bt_value_integer_unsigned_get(this->_libObjPtr());
384 operator Value() const noexcept
386 return this->value();
389 Shared shared() const noexcept
391 return Shared {*this};
395 using UnsignedIntegerValue = CommonUnsignedIntegerValue<bt_value>;
396 using ConstUnsignedIntegerValue = CommonUnsignedIntegerValue<const bt_value>;
398 template <typename LibObjT>
399 class CommonSignedIntegerValue final : public CommonValue<LibObjT>
402 using typename CommonValue<LibObjT>::_LibObjPtr;
403 using typename CommonValue<LibObjT>::_ThisCommonValue;
406 using Shared = internal::SharedValue<CommonSignedIntegerValue<LibObjT>, LibObjT>;
407 using Value = std::int64_t;
409 explicit CommonSignedIntegerValue(const _LibObjPtr libObjPtr) noexcept :
410 _ThisCommonValue {libObjPtr}
412 BT_ASSERT_DBG(this->isSignedInteger());
415 static Shared create(const Value rawVal = 0)
417 const auto libObjPtr = bt_value_integer_signed_create_init(rawVal);
419 internal::validateCreatedObjPtr(libObjPtr);
420 return Shared {CommonSignedIntegerValue<LibObjT> {libObjPtr}};
423 template <typename OtherLibObjT>
424 CommonSignedIntegerValue(const CommonSignedIntegerValue<OtherLibObjT>& val) noexcept :
425 _ThisCommonValue {val}
429 template <typename OtherLibObjT>
430 CommonSignedIntegerValue<LibObjT>&
431 operator=(const CommonSignedIntegerValue<OtherLibObjT>& val) noexcept
433 _ThisCommonValue::operator=(val);
437 CommonSignedIntegerValue<LibObjT>& operator=(const Value rawVal) noexcept
439 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
441 bt_value_integer_signed_set(this->_libObjPtr(), rawVal);
445 Value value() const noexcept
447 return bt_value_integer_signed_get(this->_libObjPtr());
450 operator Value() const noexcept
452 return this->value();
455 Shared shared() const noexcept
457 return Shared {*this};
461 using SignedIntegerValue = CommonSignedIntegerValue<bt_value>;
462 using ConstSignedIntegerValue = CommonSignedIntegerValue<const bt_value>;
464 template <typename LibObjT>
465 class CommonRealValue final : public CommonValue<LibObjT>
468 using typename CommonValue<LibObjT>::_LibObjPtr;
469 using typename CommonValue<LibObjT>::_ThisCommonValue;
472 using Shared = internal::SharedValue<CommonRealValue<LibObjT>, LibObjT>;
473 using Value = double;
475 explicit CommonRealValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
477 BT_ASSERT_DBG(this->isReal());
480 static Shared create(const Value rawVal = 0)
482 const auto libObjPtr = bt_value_real_create_init(rawVal);
484 internal::validateCreatedObjPtr(libObjPtr);
485 return Shared {CommonRealValue<LibObjT> {libObjPtr}};
488 template <typename OtherLibObjT>
489 CommonRealValue(const CommonRealValue<OtherLibObjT>& val) noexcept : _ThisCommonValue {val}
493 template <typename OtherLibObjT>
494 CommonRealValue<LibObjT>& operator=(const CommonRealValue<OtherLibObjT>& val) noexcept
496 _ThisCommonValue::operator=(val);
500 CommonRealValue<LibObjT>& operator=(const Value rawVal) noexcept
502 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
504 bt_value_real_set(this->_libObjPtr(), rawVal);
508 Value value() const noexcept
510 return bt_value_real_get(this->_libObjPtr());
513 operator Value() const noexcept
515 return this->value();
518 Shared shared() const noexcept
520 return Shared {*this};
524 using RealValue = CommonRealValue<bt_value>;
525 using ConstRealValue = CommonRealValue<const bt_value>;
527 template <typename LibObjT>
528 class CommonStringValue final : public CommonValue<LibObjT>
531 using typename CommonValue<LibObjT>::_LibObjPtr;
532 using typename CommonValue<LibObjT>::_ThisCommonValue;
535 using Shared = internal::SharedValue<CommonStringValue<LibObjT>, LibObjT>;
537 explicit CommonStringValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
539 BT_ASSERT_DBG(this->isString());
542 static Shared create(const char * const rawVal = "")
544 const auto libObjPtr = bt_value_string_create_init(rawVal);
546 internal::validateCreatedObjPtr(libObjPtr);
547 return Shared {CommonStringValue<LibObjT> {libObjPtr}};
550 static Shared create(const std::string& rawVal)
552 return CommonStringValue<LibObjT>::create(rawVal.data());
555 template <typename OtherLibObjT>
556 CommonStringValue(const CommonStringValue<OtherLibObjT>& val) noexcept : _ThisCommonValue {val}
560 template <typename OtherLibObjT>
561 CommonStringValue<LibObjT>& operator=(const CommonStringValue<OtherLibObjT>& val) noexcept
563 _ThisCommonValue::operator=(val);
567 CommonStringValue<LibObjT>& operator=(const char * const rawVal)
569 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
571 const auto status = bt_value_string_set(this->_libObjPtr(), rawVal);
573 if (status == BT_VALUE_STRING_SET_STATUS_MEMORY_ERROR) {
574 throw LibMemoryError {};
580 CommonStringValue<LibObjT>& operator=(const std::string& rawVal) noexcept
582 return *this = rawVal.data();
585 bpstd::string_view value() const noexcept
587 return bt_value_string_get(this->_libObjPtr());
590 Shared shared() const noexcept
592 return Shared {*this};
596 using StringValue = CommonStringValue<bt_value>;
597 using ConstStringValue = CommonStringValue<const bt_value>;
601 template <typename LibObjT>
602 struct CommonArrayValueSpec;
604 /* Functions specific to mutable array values */
606 struct CommonArrayValueSpec<bt_value> final
608 static bt_value *elementByIndex(bt_value * const libValPtr, const std::uint64_t index) noexcept
610 return bt_value_array_borrow_element_by_index(libValPtr, index);
614 /* Functions specific to constant array values */
616 struct CommonArrayValueSpec<const bt_value> final
618 static const bt_value *elementByIndex(const bt_value * const libValPtr,
619 const std::uint64_t index) noexcept
621 return bt_value_array_borrow_element_by_index_const(libValPtr, index);
625 } /* namespace internal */
627 template <typename LibObjT>
628 class CommonArrayValue final : public CommonValue<LibObjT>
631 using typename CommonValue<LibObjT>::_LibObjPtr;
632 using typename CommonValue<LibObjT>::_ThisCommonValue;
635 using Shared = internal::SharedValue<CommonArrayValue<LibObjT>, LibObjT>;
636 using Iterator = CommonIterator<CommonArrayValue<LibObjT>, CommonValue<LibObjT>>;
638 explicit CommonArrayValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
640 BT_ASSERT_DBG(this->isArray());
643 static Shared create()
645 const auto libObjPtr = bt_value_array_create();
647 internal::validateCreatedObjPtr(libObjPtr);
648 return Shared {CommonArrayValue<LibObjT> {libObjPtr}};
651 template <typename OtherLibObjT>
652 CommonArrayValue(const CommonArrayValue<OtherLibObjT>& val) noexcept : _ThisCommonValue {val}
656 template <typename OtherLibObjT>
657 CommonArrayValue<LibObjT>& operator=(const CommonArrayValue<OtherLibObjT>& val) noexcept
659 _ThisCommonValue::operator=(val);
663 std::uint64_t length() const noexcept
665 return bt_value_array_get_length(this->_libObjPtr());
668 /* Required by the `CommonIterator` template class */
669 std::uint64_t size() const noexcept
671 return this->length();
674 Iterator begin() const noexcept
676 return Iterator {*this, 0};
679 Iterator end() const noexcept
681 return Iterator {*this, this->length()};
684 bool isEmpty() const noexcept
686 return this->length() == 0;
689 ConstValue operator[](const std::uint64_t index) const noexcept
691 return ConstValue {internal::CommonArrayValueSpec<const bt_value>::elementByIndex(
692 this->_libObjPtr(), index)};
695 CommonValue<LibObjT> operator[](const std::uint64_t index) noexcept
697 return CommonValue<LibObjT> {
698 internal::CommonArrayValueSpec<LibObjT>::elementByIndex(this->_libObjPtr(), index)};
701 void append(const Value& val)
703 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
705 const auto status = bt_value_array_append_element(this->_libObjPtr(), val._libObjPtr());
707 this->_handleAppendLibStatus(status);
710 void append(const bool rawVal)
712 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
715 bt_value_array_append_bool_element(this->_libObjPtr(), static_cast<bt_bool>(rawVal));
717 this->_handleAppendLibStatus(status);
720 void append(const std::uint64_t rawVal)
722 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
725 bt_value_array_append_unsigned_integer_element(this->_libObjPtr(), rawVal);
727 this->_handleAppendLibStatus(status);
730 void append(const std::int64_t rawVal)
732 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
735 bt_value_array_append_signed_integer_element(this->_libObjPtr(), rawVal);
737 this->_handleAppendLibStatus(status);
740 void append(const double rawVal)
742 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
744 const auto status = bt_value_array_append_real_element(this->_libObjPtr(), rawVal);
746 this->_handleAppendLibStatus(status);
749 void append(const char * const rawVal)
751 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
753 const auto status = bt_value_array_append_string_element(this->_libObjPtr(), rawVal);
755 this->_handleAppendLibStatus(status);
758 void append(const std::string& rawVal)
760 this->append(rawVal.data());
763 CommonArrayValue<bt_value> appendEmptyArray();
764 CommonMapValue<bt_value> appendEmptyMap();
766 void operator+=(const Value& val)
771 void operator+=(const bool rawVal)
773 this->append(rawVal);
776 void operator+=(const std::uint64_t rawVal)
778 this->append(rawVal);
781 void operator+=(const std::int64_t rawVal)
783 this->append(rawVal);
786 void operator+=(const double rawVal)
788 this->append(rawVal);
791 void operator+=(const char * const rawVal)
793 this->append(rawVal);
796 void operator+=(const std::string& rawVal)
798 this->append(rawVal);
801 Shared shared() const noexcept
803 return Shared {*this};
807 void _handleAppendLibStatus(const bt_value_array_append_element_status status) const
809 if (status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_MEMORY_ERROR) {
810 throw LibMemoryError {};
815 using ArrayValue = CommonArrayValue<bt_value>;
816 using ConstArrayValue = CommonArrayValue<const bt_value>;
821 * Type of a user function passed to `CommonMapValue<ObjT>::forEach()`.
823 * First argument is the entry's key, second is its value.
825 template <typename ObjT>
826 using CommonMapValueForEachUserFunc = std::function<void(const bpstd::string_view&, ObjT)>;
829 * Template of a function to be passed to bt_value_map_foreach_entry()
830 * for bt_value_map_foreach_entry_const() which calls a user function.
832 * `userData` is casted to a `const` pointer to
833 * `CommonMapValueForEachUserFunc<ObjT>` (the user function to call).
835 * This function catches any exception which the user function throws
836 * and returns the `ErrorStatus` value. If there's no execption, this
837 * function returns the `OkStatus` value.
839 template <typename ObjT, typename LibObjT, typename LibStatusT, int OkStatus, int ErrorStatus>
840 LibStatusT mapValueForEachLibFunc(const char * const key, LibObjT * const libObjPtr,
841 void * const userData)
843 const auto& userFunc = *reinterpret_cast<const CommonMapValueForEachUserFunc<ObjT> *>(userData);
846 userFunc(key, ObjT {libObjPtr});
848 return static_cast<LibStatusT>(ErrorStatus);
851 return static_cast<LibStatusT>(OkStatus);
854 template <typename LibObjT>
855 struct CommonMapValueSpec;
857 /* Functions specific to mutable map values */
859 struct CommonMapValueSpec<bt_value> final
861 static bt_value *entryByKey(bt_value * const libValPtr, const char * const key) noexcept
863 return bt_value_map_borrow_entry_value(libValPtr, key);
866 static void forEach(bt_value * const libValPtr,
867 const CommonMapValueForEachUserFunc<Value>& func)
869 const auto status = bt_value_map_foreach_entry(
871 mapValueForEachLibFunc<Value, bt_value, bt_value_map_foreach_entry_func_status,
872 BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_OK,
873 BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_ERROR>,
874 const_cast<void *>(reinterpret_cast<const void *>(&func)));
877 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_OK:
879 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_USER_ERROR:
880 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_ERROR:
888 /* Functions specific to constant map values */
890 struct CommonMapValueSpec<const bt_value> final
892 static const bt_value *entryByKey(const bt_value * const libValPtr,
893 const char * const key) noexcept
895 return bt_value_map_borrow_entry_value_const(libValPtr, key);
898 static void forEach(const bt_value * const libValPtr,
899 const CommonMapValueForEachUserFunc<ConstValue>& func)
901 const auto status = bt_value_map_foreach_entry_const(
903 mapValueForEachLibFunc<ConstValue, const bt_value,
904 bt_value_map_foreach_entry_const_func_status,
905 BT_VALUE_MAP_FOREACH_ENTRY_CONST_FUNC_STATUS_OK,
906 BT_VALUE_MAP_FOREACH_ENTRY_CONST_FUNC_STATUS_ERROR>,
907 const_cast<void *>(reinterpret_cast<const void *>(&func)));
910 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_OK:
912 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_USER_ERROR:
913 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_ERROR:
921 } /* namespace internal */
923 template <typename LibObjT>
924 class CommonMapValue final : public CommonValue<LibObjT>
927 using typename CommonValue<LibObjT>::_LibObjPtr;
928 using typename CommonValue<LibObjT>::_ThisCommonValue;
931 using Shared = internal::SharedValue<CommonMapValue<LibObjT>, LibObjT>;
933 explicit CommonMapValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
935 BT_ASSERT_DBG(this->isMap());
938 static Shared create()
940 const auto libObjPtr = bt_value_map_create();
942 internal::validateCreatedObjPtr(libObjPtr);
943 return Shared {CommonMapValue<LibObjT> {libObjPtr}};
946 template <typename OtherLibObjT>
947 CommonMapValue(const CommonMapValue<OtherLibObjT>& val) noexcept : _ThisCommonValue {val}
951 template <typename OtherLibObjT>
952 CommonMapValue<LibObjT>& operator=(const CommonMapValue<OtherLibObjT>& val) noexcept
954 _ThisCommonValue::operator=(val);
958 std::uint64_t size() const noexcept
960 return bt_value_map_get_size(this->_libObjPtr());
963 bool isEmpty() const noexcept
965 return this->size() == 0;
968 nonstd::optional<ConstValue> operator[](const char * const key) const noexcept
970 const auto libObjPtr =
971 internal::CommonMapValueSpec<const bt_value>::entryByKey(this->_libObjPtr(), key);
974 return nonstd::nullopt;
977 return ConstValue {libObjPtr};
980 nonstd::optional<ConstValue> operator[](const std::string& key) const noexcept
982 return (*this)[key.data()];
985 nonstd::optional<CommonValue<LibObjT>> operator[](const char * const key) noexcept
987 const auto libObjPtr =
988 internal::CommonMapValueSpec<LibObjT>::entryByKey(this->_libObjPtr(), key);
991 return nonstd::nullopt;
994 return CommonValue<LibObjT> {libObjPtr};
997 nonstd::optional<CommonValue<LibObjT>> operator[](const std::string& key) noexcept
999 return (*this)[key.data()];
1002 bool hasEntry(const char * const key) const noexcept
1004 return static_cast<bool>(bt_value_map_has_entry(this->_libObjPtr(), key));
1007 bool hasEntry(const std::string& key) const noexcept
1009 return this->hasEntry(key.data());
1012 void insert(const char * const key, const Value& val)
1014 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1016 const auto status = bt_value_map_insert_entry(this->_libObjPtr(), key, val._libObjPtr());
1018 this->_handleInsertLibStatus(status);
1021 void insert(const std::string& key, const Value& val)
1023 this->insert(key.data(), val);
1026 void insert(const char * const key, const bool rawVal)
1028 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1031 bt_value_map_insert_bool_entry(this->_libObjPtr(), key, static_cast<bt_bool>(rawVal));
1033 this->_handleInsertLibStatus(status);
1036 void insert(const std::string& key, const bool rawVal)
1038 this->insert(key.data(), rawVal);
1041 void insert(const char * const key, const std::uint64_t rawVal)
1043 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1046 bt_value_map_insert_unsigned_integer_entry(this->_libObjPtr(), key, rawVal);
1048 this->_handleInsertLibStatus(status);
1051 void insert(const std::string& key, const std::uint64_t rawVal)
1053 this->insert(key.data(), rawVal);
1056 void insert(const char * const key, const std::int64_t rawVal)
1058 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1061 bt_value_map_insert_signed_integer_entry(this->_libObjPtr(), key, rawVal);
1063 this->_handleInsertLibStatus(status);
1066 void insert(const std::string& key, const std::int64_t rawVal)
1068 this->insert(key.data(), rawVal);
1071 void insert(const char * const key, const double rawVal)
1073 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1075 const auto status = bt_value_map_insert_real_entry(this->_libObjPtr(), key, rawVal);
1077 this->_handleInsertLibStatus(status);
1080 void insert(const std::string& key, const double rawVal)
1082 this->insert(key.data(), rawVal);
1085 void insert(const char * const key, const char * const rawVal)
1087 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1089 const auto status = bt_value_map_insert_string_entry(this->_libObjPtr(), key, rawVal);
1091 this->_handleInsertLibStatus(status);
1094 void insert(const char * const key, const std::string& rawVal)
1096 this->insert(key, rawVal.data());
1099 void insert(const std::string& key, const char * const rawVal)
1101 this->insert(key.data(), rawVal);
1104 void insert(const std::string& key, const std::string& rawVal)
1106 this->insert(key.data(), rawVal.data());
1109 CommonArrayValue<bt_value> insertEmptyArray(const char *key);
1110 CommonArrayValue<bt_value> insertEmptyArray(const std::string& key);
1111 CommonMapValue<bt_value> insertEmptyMap(const char *key);
1112 CommonMapValue<bt_value> insertEmptyMap(const std::string& key);
1114 void forEach(const internal::CommonMapValueForEachUserFunc<ConstValue>& func) const
1116 internal::CommonMapValueSpec<const bt_value>::forEach(this->_libObjPtr(), func);
1119 void forEach(const internal::CommonMapValueForEachUserFunc<CommonValue<LibObjT>>& func)
1121 internal::CommonMapValueSpec<LibObjT>::forEach(this->_libObjPtr(), func);
1124 Shared shared() const noexcept
1126 return Shared {*this};
1130 void _handleInsertLibStatus(const bt_value_map_insert_entry_status status) const
1132 if (status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_MEMORY_ERROR) {
1133 throw LibMemoryError {};
1138 using MapValue = CommonMapValue<bt_value>;
1139 using ConstMapValue = CommonMapValue<const bt_value>;
1141 template <typename LibObjT>
1142 CommonNullValue<LibObjT> CommonValue<LibObjT>::asNull() const noexcept
1144 BT_ASSERT_DBG(this->isNull());
1145 return CommonNullValue<LibObjT> {this->_libObjPtr()};
1148 template <typename LibObjT>
1149 CommonBoolValue<LibObjT> CommonValue<LibObjT>::asBool() const noexcept
1151 BT_ASSERT_DBG(this->isBool());
1152 return CommonBoolValue<LibObjT> {this->_libObjPtr()};
1155 template <typename LibObjT>
1156 CommonSignedIntegerValue<LibObjT> CommonValue<LibObjT>::asSignedInteger() const noexcept
1158 BT_ASSERT_DBG(this->isSignedInteger());
1159 return CommonSignedIntegerValue<LibObjT> {this->_libObjPtr()};
1162 template <typename LibObjT>
1163 CommonUnsignedIntegerValue<LibObjT> CommonValue<LibObjT>::asUnsignedInteger() const noexcept
1165 BT_ASSERT_DBG(this->isUnsignedInteger());
1166 return CommonUnsignedIntegerValue<LibObjT> {this->_libObjPtr()};
1169 template <typename LibObjT>
1170 CommonRealValue<LibObjT> CommonValue<LibObjT>::asReal() const noexcept
1172 BT_ASSERT_DBG(this->isReal());
1173 return CommonRealValue<LibObjT> {this->_libObjPtr()};
1176 template <typename LibObjT>
1177 CommonStringValue<LibObjT> CommonValue<LibObjT>::asString() const noexcept
1179 BT_ASSERT_DBG(this->isString());
1180 return CommonStringValue<LibObjT> {this->_libObjPtr()};
1183 template <typename LibObjT>
1184 CommonArrayValue<LibObjT> CommonValue<LibObjT>::asArray() const noexcept
1186 BT_ASSERT_DBG(this->isArray());
1187 return CommonArrayValue<LibObjT> {this->_libObjPtr()};
1190 template <typename LibObjT>
1191 CommonMapValue<LibObjT> CommonValue<LibObjT>::asMap() const noexcept
1193 BT_ASSERT_DBG(this->isMap());
1194 return CommonMapValue<LibObjT> {this->_libObjPtr()};
1197 template <typename LibObjT>
1198 ArrayValue CommonArrayValue<LibObjT>::appendEmptyArray()
1200 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1202 bt_value *libElemPtr;
1203 const auto status = bt_value_array_append_empty_array_element(this->_libObjPtr(), &libElemPtr);
1205 this->_handleAppendLibStatus(status);
1206 return ArrayValue {libElemPtr};
1209 template <typename LibObjT>
1210 MapValue CommonArrayValue<LibObjT>::appendEmptyMap()
1212 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1214 bt_value *libElemPtr;
1215 const auto status = bt_value_array_append_empty_map_element(this->_libObjPtr(), &libElemPtr);
1217 this->_handleAppendLibStatus(status);
1218 return MapValue {libElemPtr};
1221 template <typename LibObjT>
1222 ArrayValue CommonMapValue<LibObjT>::insertEmptyArray(const char * const key)
1224 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1226 bt_value *libEntryPtr;
1228 bt_value_map_insert_empty_array_entry(this->_libObjPtr(), key, &libEntryPtr);
1230 this->_handleInsertLibStatus(status);
1231 return ArrayValue {libEntryPtr};
1234 template <typename LibObjT>
1235 ArrayValue CommonMapValue<LibObjT>::insertEmptyArray(const std::string& key)
1237 return this->insertEmptyArray(key.data());
1240 template <typename LibObjT>
1241 MapValue CommonMapValue<LibObjT>::insertEmptyMap(const char * const key)
1243 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1245 bt_value *libEntryPtr;
1246 const auto status = bt_value_map_insert_empty_map_entry(this->_libObjPtr(), key, &libEntryPtr);
1248 this->_handleInsertLibStatus(status);
1249 return MapValue {libEntryPtr};
1252 template <typename LibObjT>
1253 MapValue CommonMapValue<LibObjT>::insertEmptyMap(const std::string& key)
1255 return this->insertEmptyMap(key.data());
1258 inline BoolValue::Shared createValue(const bool rawVal)
1260 return BoolValue::create(rawVal);
1263 inline UnsignedIntegerValue::Shared createValue(const std::uint64_t rawVal)
1265 return UnsignedIntegerValue::create(rawVal);
1268 inline SignedIntegerValue::Shared createValue(const std::int64_t rawVal)
1270 return SignedIntegerValue::create(rawVal);
1273 inline RealValue::Shared createValue(const double rawVal)
1275 return RealValue::create(rawVal);
1278 inline StringValue::Shared createValue(const char * const rawVal)
1280 return StringValue::create(rawVal);
1283 inline StringValue::Shared createValue(const std::string& rawVal)
1285 return StringValue::create(rawVal);
1288 } /* namespace bt2 */
1290 #endif /* BABELTRACE_CPP_COMMON_BT2_VALUE_HPP */