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`.");
734 const auto status = bt_value_array_append_signed_integer_element(this->libObjPtr(), rawVal);
736 this->_handleAppendLibStatus(status);
739 void append(const double rawVal)
741 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
743 const auto status = bt_value_array_append_real_element(this->libObjPtr(), rawVal);
745 this->_handleAppendLibStatus(status);
748 void append(const char * const rawVal)
750 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
752 const auto status = bt_value_array_append_string_element(this->libObjPtr(), rawVal);
754 this->_handleAppendLibStatus(status);
757 void append(const std::string& rawVal)
759 this->append(rawVal.data());
762 CommonArrayValue<bt_value> appendEmptyArray();
763 CommonMapValue<bt_value> appendEmptyMap();
765 void operator+=(const Value& val)
770 void operator+=(const bool rawVal)
772 this->append(rawVal);
775 void operator+=(const std::uint64_t rawVal)
777 this->append(rawVal);
780 void operator+=(const std::int64_t rawVal)
782 this->append(rawVal);
785 void operator+=(const double rawVal)
787 this->append(rawVal);
790 void operator+=(const char * const rawVal)
792 this->append(rawVal);
795 void operator+=(const std::string& rawVal)
797 this->append(rawVal);
800 Shared shared() const noexcept
802 return Shared {*this};
806 void _handleAppendLibStatus(const bt_value_array_append_element_status status) const
808 if (status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_MEMORY_ERROR) {
809 throw LibMemoryError {};
814 using ArrayValue = CommonArrayValue<bt_value>;
815 using ConstArrayValue = CommonArrayValue<const bt_value>;
820 * Type of a user function passed to `CommonMapValue<ObjT>::forEach()`.
822 * First argument is the entry's key, second is its value.
824 template <typename ObjT>
825 using CommonMapValueForEachUserFunc = std::function<void(const bpstd::string_view&, ObjT)>;
828 * Template of a function to be passed to bt_value_map_foreach_entry()
829 * for bt_value_map_foreach_entry_const() which calls a user function.
831 * `userData` is casted to a `const` pointer to
832 * `CommonMapValueForEachUserFunc<ObjT>` (the user function to call).
834 * This function catches any exception which the user function throws
835 * and returns the `ErrorStatus` value. If there's no execption, this
836 * function returns the `OkStatus` value.
838 template <typename ObjT, typename LibObjT, typename LibStatusT, int OkStatus, int ErrorStatus>
839 LibStatusT mapValueForEachLibFunc(const char * const key, LibObjT * const libObjPtr,
840 void * const userData)
842 const auto& userFunc = *reinterpret_cast<const CommonMapValueForEachUserFunc<ObjT> *>(userData);
845 userFunc(key, ObjT {libObjPtr});
847 return static_cast<LibStatusT>(ErrorStatus);
850 return static_cast<LibStatusT>(OkStatus);
853 template <typename LibObjT>
854 struct CommonMapValueSpec;
856 /* Functions specific to mutable map values */
858 struct CommonMapValueSpec<bt_value> final
860 static bt_value *entryByKey(bt_value * const libValPtr, const char * const key) noexcept
862 return bt_value_map_borrow_entry_value(libValPtr, key);
865 static void forEach(bt_value * const libValPtr,
866 const CommonMapValueForEachUserFunc<Value>& func)
868 const auto status = bt_value_map_foreach_entry(
870 mapValueForEachLibFunc<Value, bt_value, bt_value_map_foreach_entry_func_status,
871 BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_OK,
872 BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_ERROR>,
873 const_cast<void *>(reinterpret_cast<const void *>(&func)));
876 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_OK:
878 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_USER_ERROR:
879 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_ERROR:
887 /* Functions specific to constant map values */
889 struct CommonMapValueSpec<const bt_value> final
891 static const bt_value *entryByKey(const bt_value * const libValPtr,
892 const char * const key) noexcept
894 return bt_value_map_borrow_entry_value_const(libValPtr, key);
897 static void forEach(const bt_value * const libValPtr,
898 const CommonMapValueForEachUserFunc<ConstValue>& func)
900 const auto status = bt_value_map_foreach_entry_const(
902 mapValueForEachLibFunc<ConstValue, const bt_value,
903 bt_value_map_foreach_entry_const_func_status,
904 BT_VALUE_MAP_FOREACH_ENTRY_CONST_FUNC_STATUS_OK,
905 BT_VALUE_MAP_FOREACH_ENTRY_CONST_FUNC_STATUS_ERROR>,
906 const_cast<void *>(reinterpret_cast<const void *>(&func)));
909 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_OK:
911 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_USER_ERROR:
912 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_ERROR:
920 } /* namespace internal */
922 template <typename LibObjT>
923 class CommonMapValue final : public CommonValue<LibObjT>
926 using typename CommonValue<LibObjT>::_LibObjPtr;
927 using typename CommonValue<LibObjT>::_ThisCommonValue;
930 using Shared = internal::SharedValue<CommonMapValue<LibObjT>, LibObjT>;
932 explicit CommonMapValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
934 BT_ASSERT_DBG(this->isMap());
937 static Shared create()
939 const auto libObjPtr = bt_value_map_create();
941 internal::validateCreatedObjPtr(libObjPtr);
942 return Shared {CommonMapValue<LibObjT> {libObjPtr}};
945 template <typename OtherLibObjT>
946 CommonMapValue(const CommonMapValue<OtherLibObjT>& val) noexcept : _ThisCommonValue {val}
950 template <typename OtherLibObjT>
951 CommonMapValue<LibObjT>& operator=(const CommonMapValue<OtherLibObjT>& val) noexcept
953 _ThisCommonValue::operator=(val);
957 std::uint64_t size() const noexcept
959 return bt_value_map_get_size(this->libObjPtr());
962 bool isEmpty() const noexcept
964 return this->size() == 0;
967 nonstd::optional<ConstValue> operator[](const char * const key) const noexcept
969 const auto libObjPtr =
970 internal::CommonMapValueSpec<const bt_value>::entryByKey(this->libObjPtr(), key);
973 return nonstd::nullopt;
976 return ConstValue {libObjPtr};
979 nonstd::optional<ConstValue> operator[](const std::string& key) const noexcept
981 return (*this)[key.data()];
984 nonstd::optional<CommonValue<LibObjT>> operator[](const char * const key) noexcept
986 const auto libObjPtr =
987 internal::CommonMapValueSpec<LibObjT>::entryByKey(this->libObjPtr(), key);
990 return nonstd::nullopt;
993 return CommonValue<LibObjT> {libObjPtr};
996 nonstd::optional<CommonValue<LibObjT>> operator[](const std::string& key) noexcept
998 return (*this)[key.data()];
1001 bool hasEntry(const char * const key) const noexcept
1003 return static_cast<bool>(bt_value_map_has_entry(this->libObjPtr(), key));
1006 bool hasEntry(const std::string& key) const noexcept
1008 return this->hasEntry(key.data());
1011 void insert(const char * const key, const Value& val)
1013 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1015 const auto status = bt_value_map_insert_entry(this->libObjPtr(), key, val.libObjPtr());
1017 this->_handleInsertLibStatus(status);
1020 void insert(const std::string& key, const Value& val)
1022 this->insert(key.data(), val);
1025 void insert(const char * const key, const bool rawVal)
1027 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1030 bt_value_map_insert_bool_entry(this->libObjPtr(), key, static_cast<bt_bool>(rawVal));
1032 this->_handleInsertLibStatus(status);
1035 void insert(const std::string& key, const bool rawVal)
1037 this->insert(key.data(), rawVal);
1040 void insert(const char * const key, const std::uint64_t rawVal)
1042 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1045 bt_value_map_insert_unsigned_integer_entry(this->libObjPtr(), key, rawVal);
1047 this->_handleInsertLibStatus(status);
1050 void insert(const std::string& key, const std::uint64_t rawVal)
1052 this->insert(key.data(), rawVal);
1055 void insert(const char * const key, const std::int64_t rawVal)
1057 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1060 bt_value_map_insert_signed_integer_entry(this->libObjPtr(), key, rawVal);
1062 this->_handleInsertLibStatus(status);
1065 void insert(const std::string& key, const std::int64_t rawVal)
1067 this->insert(key.data(), rawVal);
1070 void insert(const char * const key, const double rawVal)
1072 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1074 const auto status = bt_value_map_insert_real_entry(this->libObjPtr(), key, rawVal);
1076 this->_handleInsertLibStatus(status);
1079 void insert(const std::string& key, const double rawVal)
1081 this->insert(key.data(), rawVal);
1084 void insert(const char * const key, const char * const rawVal)
1086 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1088 const auto status = bt_value_map_insert_string_entry(this->libObjPtr(), key, rawVal);
1090 this->_handleInsertLibStatus(status);
1093 void insert(const char * const key, const std::string& rawVal)
1095 this->insert(key, rawVal.data());
1098 void insert(const std::string& key, const char * const rawVal)
1100 this->insert(key.data(), rawVal);
1103 void insert(const std::string& key, const std::string& rawVal)
1105 this->insert(key.data(), rawVal.data());
1108 CommonArrayValue<bt_value> insertEmptyArray(const char *key);
1109 CommonArrayValue<bt_value> insertEmptyArray(const std::string& key);
1110 CommonMapValue<bt_value> insertEmptyMap(const char *key);
1111 CommonMapValue<bt_value> insertEmptyMap(const std::string& key);
1113 void forEach(const internal::CommonMapValueForEachUserFunc<ConstValue>& func) const
1115 internal::CommonMapValueSpec<const bt_value>::forEach(this->libObjPtr(), func);
1118 void forEach(const internal::CommonMapValueForEachUserFunc<CommonValue<LibObjT>>& func)
1120 internal::CommonMapValueSpec<LibObjT>::forEach(this->libObjPtr(), func);
1123 Shared shared() const noexcept
1125 return Shared {*this};
1129 void _handleInsertLibStatus(const bt_value_map_insert_entry_status status) const
1131 if (status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_MEMORY_ERROR) {
1132 throw LibMemoryError {};
1137 using MapValue = CommonMapValue<bt_value>;
1138 using ConstMapValue = CommonMapValue<const bt_value>;
1140 template <typename LibObjT>
1141 CommonNullValue<LibObjT> CommonValue<LibObjT>::asNull() const noexcept
1143 BT_ASSERT_DBG(this->isNull());
1144 return CommonNullValue<LibObjT> {this->libObjPtr()};
1147 template <typename LibObjT>
1148 CommonBoolValue<LibObjT> CommonValue<LibObjT>::asBool() const noexcept
1150 BT_ASSERT_DBG(this->isBool());
1151 return CommonBoolValue<LibObjT> {this->libObjPtr()};
1154 template <typename LibObjT>
1155 CommonSignedIntegerValue<LibObjT> CommonValue<LibObjT>::asSignedInteger() const noexcept
1157 BT_ASSERT_DBG(this->isSignedInteger());
1158 return CommonSignedIntegerValue<LibObjT> {this->libObjPtr()};
1161 template <typename LibObjT>
1162 CommonUnsignedIntegerValue<LibObjT> CommonValue<LibObjT>::asUnsignedInteger() const noexcept
1164 BT_ASSERT_DBG(this->isUnsignedInteger());
1165 return CommonUnsignedIntegerValue<LibObjT> {this->libObjPtr()};
1168 template <typename LibObjT>
1169 CommonRealValue<LibObjT> CommonValue<LibObjT>::asReal() const noexcept
1171 BT_ASSERT_DBG(this->isReal());
1172 return CommonRealValue<LibObjT> {this->libObjPtr()};
1175 template <typename LibObjT>
1176 CommonStringValue<LibObjT> CommonValue<LibObjT>::asString() const noexcept
1178 BT_ASSERT_DBG(this->isString());
1179 return CommonStringValue<LibObjT> {this->libObjPtr()};
1182 template <typename LibObjT>
1183 CommonArrayValue<LibObjT> CommonValue<LibObjT>::asArray() const noexcept
1185 BT_ASSERT_DBG(this->isArray());
1186 return CommonArrayValue<LibObjT> {this->libObjPtr()};
1189 template <typename LibObjT>
1190 CommonMapValue<LibObjT> CommonValue<LibObjT>::asMap() const noexcept
1192 BT_ASSERT_DBG(this->isMap());
1193 return CommonMapValue<LibObjT> {this->libObjPtr()};
1196 template <typename LibObjT>
1197 ArrayValue CommonArrayValue<LibObjT>::appendEmptyArray()
1199 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1201 bt_value *libElemPtr;
1202 const auto status = bt_value_array_append_empty_array_element(this->libObjPtr(), &libElemPtr);
1204 this->_handleAppendLibStatus(status);
1205 return ArrayValue {libElemPtr};
1208 template <typename LibObjT>
1209 MapValue CommonArrayValue<LibObjT>::appendEmptyMap()
1211 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1213 bt_value *libElemPtr;
1214 const auto status = bt_value_array_append_empty_map_element(this->libObjPtr(), &libElemPtr);
1216 this->_handleAppendLibStatus(status);
1217 return MapValue {libElemPtr};
1220 template <typename LibObjT>
1221 ArrayValue CommonMapValue<LibObjT>::insertEmptyArray(const char * const key)
1223 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1225 bt_value *libEntryPtr;
1226 const auto status = bt_value_map_insert_empty_array_entry(this->libObjPtr(), key, &libEntryPtr);
1228 this->_handleInsertLibStatus(status);
1229 return ArrayValue {libEntryPtr};
1232 template <typename LibObjT>
1233 ArrayValue CommonMapValue<LibObjT>::insertEmptyArray(const std::string& key)
1235 return this->insertEmptyArray(key.data());
1238 template <typename LibObjT>
1239 MapValue CommonMapValue<LibObjT>::insertEmptyMap(const char * const key)
1241 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1243 bt_value *libEntryPtr;
1244 const auto status = bt_value_map_insert_empty_map_entry(this->libObjPtr(), key, &libEntryPtr);
1246 this->_handleInsertLibStatus(status);
1247 return MapValue {libEntryPtr};
1250 template <typename LibObjT>
1251 MapValue CommonMapValue<LibObjT>::insertEmptyMap(const std::string& key)
1253 return this->insertEmptyMap(key.data());
1256 inline BoolValue::Shared createValue(const bool rawVal)
1258 return BoolValue::create(rawVal);
1261 inline UnsignedIntegerValue::Shared createValue(const std::uint64_t rawVal)
1263 return UnsignedIntegerValue::create(rawVal);
1266 inline SignedIntegerValue::Shared createValue(const std::int64_t rawVal)
1268 return SignedIntegerValue::create(rawVal);
1271 inline RealValue::Shared createValue(const double rawVal)
1273 return RealValue::create(rawVal);
1276 inline StringValue::Shared createValue(const char * const rawVal)
1278 return StringValue::create(rawVal);
1281 inline StringValue::Shared createValue(const std::string& rawVal)
1283 return StringValue::create(rawVal);
1286 } /* namespace bt2 */
1288 #endif /* BABELTRACE_CPP_COMMON_BT2_VALUE_HPP */