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 CommonTraceClass;
91 template <typename LibObjT>
92 class CommonStreamClass;
94 template <typename LibObjT>
95 class CommonEventClass;
97 template <typename LibObjT>
100 template <typename LibObjT>
101 class CommonValue : public internal::BorrowedObj<LibObjT>
103 // Allow append() to call `val._libObjPtr()`
104 friend class CommonArrayValue<bt_value>;
106 // Allow insert() to call `val._libObjPtr()`
107 friend class CommonMapValue<bt_value>;
109 // Allow userAttributes() to call `val._libObjPtr()`
110 friend class CommonClockClass<bt_clock_class>;
111 friend class CommonFieldClass<bt_field_class>;
112 friend class CommonTraceClass<bt_trace_class>;
113 friend class CommonStreamClass<bt_stream_class>;
114 friend class CommonEventClass<bt_event_class>;
115 friend class CommonStream<bt_stream>;
117 // Allow operator==() to call `other._libObjPtr()`
118 friend class CommonValue<bt_value>;
119 friend class CommonValue<const bt_value>;
122 using typename internal::BorrowedObj<LibObjT>::_ThisBorrowedObj;
125 using typename internal::BorrowedObj<LibObjT>::_LibObjPtr;
126 using _ThisCommonValue = CommonValue<LibObjT>;
129 using Shared = internal::SharedValue<CommonValue<LibObjT>, LibObjT>;
131 explicit CommonValue(const _LibObjPtr libObjPtr) noexcept : _ThisBorrowedObj {libObjPtr}
135 template <typename OtherLibObjT>
136 CommonValue(const CommonValue<OtherLibObjT>& val) noexcept : _ThisBorrowedObj {val}
140 template <typename OtherLibObjT>
141 _ThisCommonValue& operator=(const CommonValue<OtherLibObjT>& val) noexcept
143 _ThisBorrowedObj::operator=(val);
147 ValueType type() const noexcept
149 return static_cast<ValueType>(bt_value_get_type(this->_libObjPtr()));
152 bool isNull() const noexcept
154 return this->_libTypeIs(BT_VALUE_TYPE_NULL);
157 bool isBool() const noexcept
159 return this->_libTypeIs(BT_VALUE_TYPE_BOOL);
162 bool isInteger() const noexcept
164 return this->_libTypeIs(BT_VALUE_TYPE_INTEGER);
167 bool isUnsignedInteger() const noexcept
169 return this->_libTypeIs(BT_VALUE_TYPE_UNSIGNED_INTEGER);
172 bool isSignedInteger() const noexcept
174 return this->_libTypeIs(BT_VALUE_TYPE_SIGNED_INTEGER);
177 bool isReal() const noexcept
179 return this->_libTypeIs(BT_VALUE_TYPE_REAL);
182 bool isString() const noexcept
184 return this->_libTypeIs(BT_VALUE_TYPE_STRING);
187 bool isArray() const noexcept
189 return this->_libTypeIs(BT_VALUE_TYPE_ARRAY);
192 bool isMap() const noexcept
194 return this->_libTypeIs(BT_VALUE_TYPE_MAP);
197 template <typename OtherLibObjT>
198 bool operator==(const CommonValue<OtherLibObjT>& other) const noexcept
200 return static_cast<bool>(bt_value_is_equal(this->_libObjPtr(), other._libObjPtr()));
203 template <typename OtherLibObjT>
204 bool operator!=(const CommonValue<OtherLibObjT>& other) const noexcept
206 return !(*this == other);
209 Shared shared() const noexcept
211 return Shared {*this};
214 CommonNullValue<LibObjT> asNull() const noexcept;
215 CommonBoolValue<LibObjT> asBool() const noexcept;
216 CommonSignedIntegerValue<LibObjT> asSignedInteger() const noexcept;
217 CommonUnsignedIntegerValue<LibObjT> asUnsignedInteger() const noexcept;
218 CommonRealValue<LibObjT> asReal() const noexcept;
219 CommonStringValue<LibObjT> asString() const noexcept;
220 CommonArrayValue<LibObjT> asArray() const noexcept;
221 CommonMapValue<LibObjT> asMap() const noexcept;
224 bool _libTypeIs(const bt_value_type type) const noexcept
226 return bt_value_type_is(bt_value_get_type(this->_libObjPtr()), type);
230 using Value = CommonValue<bt_value>;
231 using ConstValue = CommonValue<const bt_value>;
233 template <typename LibObjT>
234 class CommonNullValue final : public CommonValue<LibObjT>
237 using typename CommonValue<LibObjT>::_ThisCommonValue;
240 using Shared = internal::SharedValue<CommonNullValue<LibObjT>, LibObjT>;
242 CommonNullValue() noexcept : _ThisCommonValue {bt_value_null}
246 template <typename OtherLibObjT>
247 CommonNullValue(const CommonNullValue<OtherLibObjT>& val) noexcept : _ThisCommonValue {val}
251 template <typename OtherLibObjT>
252 CommonNullValue<LibObjT>& operator=(const CommonNullValue<OtherLibObjT>& val) noexcept
254 _ThisCommonValue::operator=(val);
258 Shared shared() const noexcept
260 return Shared {*this};
264 using NullValue = CommonNullValue<bt_value>;
265 using ConstNullValue = CommonNullValue<const bt_value>;
267 template <typename LibObjT>
268 class CommonBoolValue final : public CommonValue<LibObjT>
271 using typename CommonValue<LibObjT>::_LibObjPtr;
272 using typename CommonValue<LibObjT>::_ThisCommonValue;
275 using Shared = internal::SharedValue<CommonBoolValue<LibObjT>, LibObjT>;
278 explicit CommonBoolValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
280 BT_ASSERT_DBG(this->isBool());
283 template <typename OtherLibObjT>
284 CommonBoolValue(const CommonBoolValue<OtherLibObjT>& val) noexcept : _ThisCommonValue {val}
288 static Shared create(const Value rawVal = false)
290 const auto libObjPtr = bt_value_bool_create_init(static_cast<bt_bool>(rawVal));
292 internal::validateCreatedObjPtr(libObjPtr);
293 return Shared {CommonBoolValue<LibObjT> {libObjPtr}};
296 template <typename OtherLibObjT>
297 CommonBoolValue<LibObjT>& operator=(const CommonBoolValue<OtherLibObjT>& val) noexcept
299 _ThisCommonValue::operator=(val);
303 CommonBoolValue<LibObjT>& operator=(const Value rawVal) noexcept
305 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
307 bt_value_bool_set(this->_libObjPtr(), static_cast<bt_bool>(rawVal));
311 Value value() const noexcept
313 return static_cast<Value>(bt_value_bool_get(this->_libObjPtr()));
316 operator Value() const noexcept
318 return this->value();
321 Shared shared() const noexcept
323 return Shared {*this};
327 using BoolValue = CommonBoolValue<bt_value>;
328 using ConstBoolValue = CommonBoolValue<const bt_value>;
330 template <typename LibObjT>
331 class CommonUnsignedIntegerValue final : public CommonValue<LibObjT>
334 using typename CommonValue<LibObjT>::_LibObjPtr;
335 using typename CommonValue<LibObjT>::_ThisCommonValue;
338 using Shared = internal::SharedValue<CommonUnsignedIntegerValue<LibObjT>, LibObjT>;
339 using Value = std::uint64_t;
341 explicit CommonUnsignedIntegerValue(const _LibObjPtr libObjPtr) noexcept :
342 _ThisCommonValue {libObjPtr}
344 BT_ASSERT_DBG(this->isUnsignedInteger());
347 static Shared create(const Value rawVal = 0)
349 const auto libObjPtr = bt_value_integer_unsigned_create_init(rawVal);
351 internal::validateCreatedObjPtr(libObjPtr);
352 return Shared {CommonUnsignedIntegerValue<LibObjT> {libObjPtr}};
355 template <typename OtherLibObjT>
356 CommonUnsignedIntegerValue(const CommonUnsignedIntegerValue<OtherLibObjT>& val) noexcept :
357 _ThisCommonValue {val}
361 template <typename OtherLibObjT>
362 CommonUnsignedIntegerValue<LibObjT>&
363 operator=(const CommonUnsignedIntegerValue<OtherLibObjT>& val) noexcept
365 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
367 _ThisCommonValue::operator=(val);
371 CommonUnsignedIntegerValue<LibObjT>& operator=(const Value rawVal) noexcept
373 bt_value_integer_unsigned_set(this->_libObjPtr(), rawVal);
377 Value value() const noexcept
379 return bt_value_integer_unsigned_get(this->_libObjPtr());
382 operator Value() const noexcept
384 return this->value();
387 Shared shared() const noexcept
389 return Shared {*this};
393 using UnsignedIntegerValue = CommonUnsignedIntegerValue<bt_value>;
394 using ConstUnsignedIntegerValue = CommonUnsignedIntegerValue<const bt_value>;
396 template <typename LibObjT>
397 class CommonSignedIntegerValue final : public CommonValue<LibObjT>
400 using typename CommonValue<LibObjT>::_LibObjPtr;
401 using typename CommonValue<LibObjT>::_ThisCommonValue;
404 using Shared = internal::SharedValue<CommonSignedIntegerValue<LibObjT>, LibObjT>;
405 using Value = std::int64_t;
407 explicit CommonSignedIntegerValue(const _LibObjPtr libObjPtr) noexcept :
408 _ThisCommonValue {libObjPtr}
410 BT_ASSERT_DBG(this->isSignedInteger());
413 static Shared create(const Value rawVal = 0)
415 const auto libObjPtr = bt_value_integer_signed_create_init(rawVal);
417 internal::validateCreatedObjPtr(libObjPtr);
418 return Shared {CommonSignedIntegerValue<LibObjT> {libObjPtr}};
421 template <typename OtherLibObjT>
422 CommonSignedIntegerValue(const CommonSignedIntegerValue<OtherLibObjT>& val) noexcept :
423 _ThisCommonValue {val}
427 template <typename OtherLibObjT>
428 CommonSignedIntegerValue<LibObjT>&
429 operator=(const CommonSignedIntegerValue<OtherLibObjT>& val) noexcept
431 _ThisCommonValue::operator=(val);
435 CommonSignedIntegerValue<LibObjT>& operator=(const Value rawVal) noexcept
437 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
439 bt_value_integer_signed_set(this->_libObjPtr(), rawVal);
443 Value value() const noexcept
445 return bt_value_integer_signed_get(this->_libObjPtr());
448 operator Value() const noexcept
450 return this->value();
453 Shared shared() const noexcept
455 return Shared {*this};
459 using SignedIntegerValue = CommonSignedIntegerValue<bt_value>;
460 using ConstSignedIntegerValue = CommonSignedIntegerValue<const bt_value>;
462 template <typename LibObjT>
463 class CommonRealValue final : public CommonValue<LibObjT>
466 using typename CommonValue<LibObjT>::_LibObjPtr;
467 using typename CommonValue<LibObjT>::_ThisCommonValue;
470 using Shared = internal::SharedValue<CommonRealValue<LibObjT>, LibObjT>;
471 using Value = double;
473 explicit CommonRealValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
475 BT_ASSERT_DBG(this->isReal());
478 static Shared create(const Value rawVal = 0)
480 const auto libObjPtr = bt_value_real_create_init(rawVal);
482 internal::validateCreatedObjPtr(libObjPtr);
483 return Shared {CommonRealValue<LibObjT> {libObjPtr}};
486 template <typename OtherLibObjT>
487 CommonRealValue(const CommonRealValue<OtherLibObjT>& val) noexcept : _ThisCommonValue {val}
491 template <typename OtherLibObjT>
492 CommonRealValue<LibObjT>& operator=(const CommonRealValue<OtherLibObjT>& val) noexcept
494 _ThisCommonValue::operator=(val);
498 CommonRealValue<LibObjT>& operator=(const Value rawVal) noexcept
500 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
502 bt_value_real_set(this->_libObjPtr(), rawVal);
506 Value value() const noexcept
508 return bt_value_real_get(this->_libObjPtr());
511 operator Value() const noexcept
513 return this->value();
516 Shared shared() const noexcept
518 return Shared {*this};
522 using RealValue = CommonRealValue<bt_value>;
523 using ConstRealValue = CommonRealValue<const bt_value>;
525 template <typename LibObjT>
526 class CommonStringValue final : public CommonValue<LibObjT>
529 using typename CommonValue<LibObjT>::_LibObjPtr;
530 using typename CommonValue<LibObjT>::_ThisCommonValue;
533 using Shared = internal::SharedValue<CommonStringValue<LibObjT>, LibObjT>;
535 explicit CommonStringValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
537 BT_ASSERT_DBG(this->isString());
540 static Shared create(const char * const rawVal = "")
542 const auto libObjPtr = bt_value_string_create_init(rawVal);
544 internal::validateCreatedObjPtr(libObjPtr);
545 return Shared {CommonStringValue<LibObjT> {libObjPtr}};
548 static Shared create(const std::string& rawVal)
550 return CommonStringValue<LibObjT>::create(rawVal.data());
553 template <typename OtherLibObjT>
554 CommonStringValue(const CommonStringValue<OtherLibObjT>& val) noexcept : _ThisCommonValue {val}
558 template <typename OtherLibObjT>
559 CommonStringValue<LibObjT>& operator=(const CommonStringValue<OtherLibObjT>& val) noexcept
561 _ThisCommonValue::operator=(val);
565 CommonStringValue<LibObjT>& operator=(const char * const rawVal)
567 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
569 const auto status = bt_value_string_set(this->_libObjPtr(), rawVal);
571 if (status == BT_VALUE_STRING_SET_STATUS_MEMORY_ERROR) {
572 throw LibMemoryError {};
578 CommonStringValue<LibObjT>& operator=(const std::string& rawVal) noexcept
580 return *this = rawVal.data();
583 bpstd::string_view value() const noexcept
585 return bt_value_string_get(this->_libObjPtr());
588 Shared shared() const noexcept
590 return Shared {*this};
594 using StringValue = CommonStringValue<bt_value>;
595 using ConstStringValue = CommonStringValue<const bt_value>;
599 template <typename LibObjT>
600 struct CommonArrayValueSpec;
602 // Functions specific to mutable array values
604 struct CommonArrayValueSpec<bt_value> final
606 static bt_value *elementByIndex(bt_value * const libValPtr, const std::uint64_t index) noexcept
608 return bt_value_array_borrow_element_by_index(libValPtr, index);
612 // Functions specific to constant array values
614 struct CommonArrayValueSpec<const bt_value> final
616 static const bt_value *elementByIndex(const bt_value * const libValPtr,
617 const std::uint64_t index) noexcept
619 return bt_value_array_borrow_element_by_index_const(libValPtr, index);
623 } // namespace internal
625 template <typename LibObjT>
626 class CommonArrayValue final : public CommonValue<LibObjT>
629 using typename CommonValue<LibObjT>::_LibObjPtr;
630 using typename CommonValue<LibObjT>::_ThisCommonValue;
633 using Shared = internal::SharedValue<CommonArrayValue<LibObjT>, LibObjT>;
635 explicit CommonArrayValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
637 BT_ASSERT_DBG(this->isArray());
640 static Shared create()
642 const auto libObjPtr = bt_value_array_create();
644 internal::validateCreatedObjPtr(libObjPtr);
645 return Shared {CommonArrayValue<LibObjT> {libObjPtr}};
648 template <typename OtherLibObjT>
649 CommonArrayValue(const CommonArrayValue<OtherLibObjT>& val) noexcept : _ThisCommonValue {val}
653 template <typename OtherLibObjT>
654 CommonArrayValue<LibObjT>& operator=(const CommonArrayValue<OtherLibObjT>& val) noexcept
656 _ThisCommonValue::operator=(val);
660 std::uint64_t length() const noexcept
662 return bt_value_array_get_length(this->_libObjPtr());
665 bool isEmpty() const noexcept
667 return this->length() == 0;
670 ConstValue operator[](const std::uint64_t index) const noexcept
672 return ConstValue {internal::CommonArrayValueSpec<const bt_value>::elementByIndex(
673 this->_libObjPtr(), index)};
676 CommonValue<LibObjT> operator[](const std::uint64_t index) noexcept
678 return CommonValue<LibObjT> {
679 internal::CommonArrayValueSpec<LibObjT>::elementByIndex(this->_libObjPtr(), index)};
682 void append(const Value& val)
684 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
686 const auto status = bt_value_array_append_element(this->_libObjPtr(), val._libObjPtr());
688 this->_handleAppendLibStatus(status);
691 void append(const bool rawVal)
693 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
696 bt_value_array_append_bool_element(this->_libObjPtr(), static_cast<bt_bool>(rawVal));
698 this->_handleAppendLibStatus(status);
701 void append(const std::uint64_t rawVal)
703 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
706 bt_value_array_append_unsigned_integer_element(this->_libObjPtr(), rawVal);
708 this->_handleAppendLibStatus(status);
711 void append(const std::int64_t rawVal)
713 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
716 bt_value_array_append_signed_integer_element(this->_libObjPtr(), rawVal);
718 this->_handleAppendLibStatus(status);
721 void append(const double rawVal)
723 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
725 const auto status = bt_value_array_append_real_element(this->_libObjPtr(), rawVal);
727 this->_handleAppendLibStatus(status);
730 void append(const char * const rawVal)
732 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
734 const auto status = bt_value_array_append_string_element(this->_libObjPtr(), rawVal);
736 this->_handleAppendLibStatus(status);
739 void append(const std::string& rawVal)
741 this->append(rawVal.data());
744 CommonArrayValue<bt_value> appendEmptyArray();
745 CommonMapValue<bt_value> appendEmptyMap();
747 void operator+=(const Value& val)
752 void operator+=(const bool rawVal)
754 this->append(rawVal);
757 void operator+=(const std::uint64_t rawVal)
759 this->append(rawVal);
762 void operator+=(const std::int64_t rawVal)
764 this->append(rawVal);
767 void operator+=(const double rawVal)
769 this->append(rawVal);
772 void operator+=(const char * const rawVal)
774 this->append(rawVal);
777 void operator+=(const std::string& rawVal)
779 this->append(rawVal);
782 Shared shared() const noexcept
784 return Shared {*this};
788 void _handleAppendLibStatus(const bt_value_array_append_element_status status) const
790 if (status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_MEMORY_ERROR) {
791 throw LibMemoryError {};
796 using ArrayValue = CommonArrayValue<bt_value>;
797 using ConstArrayValue = CommonArrayValue<const bt_value>;
802 * Type of a user function passed to `CommonMapValue<ObjT>::forEach()`.
804 * First argument is the entry's key, second is its value.
806 template <typename ObjT>
807 using CommonMapValueForEachUserFunc = std::function<void(const bpstd::string_view&, ObjT)>;
810 * Template of a function to be passed to bt_value_map_foreach_entry()
811 * for bt_value_map_foreach_entry_const() which calls a user function.
813 * `userData` is casted to a `const` pointer to
814 * `CommonMapValueForEachUserFunc<ObjT>` (the user function to call).
816 * This function catches any exception which the user function throws
817 * and returns the `ErrorStatus` value. If there's no execption, this
818 * function returns the `OkStatus` value.
820 template <typename ObjT, typename LibObjT, typename LibStatusT, int OkStatus, int ErrorStatus>
821 LibStatusT mapValueForEachLibFunc(const char * const key, LibObjT * const libObjPtr,
822 void * const userData)
824 const auto& userFunc = *reinterpret_cast<const CommonMapValueForEachUserFunc<ObjT> *>(userData);
827 userFunc(key, ObjT {libObjPtr});
829 return static_cast<LibStatusT>(ErrorStatus);
832 return static_cast<LibStatusT>(OkStatus);
835 template <typename LibObjT>
836 struct CommonMapValueSpec;
838 // Functions specific to mutable map values
840 struct CommonMapValueSpec<bt_value> final
842 static bt_value *entryByKey(bt_value * const libValPtr, const char * const key) noexcept
844 return bt_value_map_borrow_entry_value(libValPtr, key);
847 static void forEach(bt_value * const libValPtr,
848 const CommonMapValueForEachUserFunc<Value>& func)
850 const auto status = bt_value_map_foreach_entry(
852 mapValueForEachLibFunc<Value, bt_value, bt_value_map_foreach_entry_func_status,
853 BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_OK,
854 BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_ERROR>,
855 const_cast<void *>(reinterpret_cast<const void *>(&func)));
858 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_OK:
860 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_USER_ERROR:
861 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_ERROR:
869 // Functions specific to constant map values
871 struct CommonMapValueSpec<const bt_value> final
873 static const bt_value *entryByKey(const bt_value * const libValPtr,
874 const char * const key) noexcept
876 return bt_value_map_borrow_entry_value_const(libValPtr, key);
879 static void forEach(const bt_value * const libValPtr,
880 const CommonMapValueForEachUserFunc<ConstValue>& func)
882 const auto status = bt_value_map_foreach_entry_const(
884 mapValueForEachLibFunc<ConstValue, const bt_value,
885 bt_value_map_foreach_entry_const_func_status,
886 BT_VALUE_MAP_FOREACH_ENTRY_CONST_FUNC_STATUS_OK,
887 BT_VALUE_MAP_FOREACH_ENTRY_CONST_FUNC_STATUS_ERROR>,
888 const_cast<void *>(reinterpret_cast<const void *>(&func)));
891 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_OK:
893 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_USER_ERROR:
894 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_ERROR:
902 } // namespace internal
904 template <typename LibObjT>
905 class CommonMapValue final : public CommonValue<LibObjT>
908 using typename CommonValue<LibObjT>::_LibObjPtr;
909 using typename CommonValue<LibObjT>::_ThisCommonValue;
912 using Shared = internal::SharedValue<CommonMapValue<LibObjT>, LibObjT>;
914 explicit CommonMapValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
916 BT_ASSERT_DBG(this->isMap());
919 static Shared create()
921 const auto libObjPtr = bt_value_map_create();
923 internal::validateCreatedObjPtr(libObjPtr);
924 return Shared {CommonMapValue<LibObjT> {libObjPtr}};
927 template <typename OtherLibObjT>
928 CommonMapValue(const CommonMapValue<OtherLibObjT>& val) noexcept : _ThisCommonValue {val}
932 template <typename OtherLibObjT>
933 CommonMapValue<LibObjT>& operator=(const CommonMapValue<OtherLibObjT>& val) noexcept
935 _ThisCommonValue::operator=(val);
939 std::uint64_t size() const noexcept
941 return bt_value_map_get_size(this->_libObjPtr());
944 bool isEmpty() const noexcept
946 return this->size() == 0;
949 nonstd::optional<ConstValue> operator[](const char * const key) const noexcept
951 const auto libObjPtr =
952 internal::CommonMapValueSpec<const bt_value>::entryByKey(this->_libObjPtr(), key);
955 return nonstd::nullopt;
958 return ConstValue {libObjPtr};
961 nonstd::optional<ConstValue> operator[](const std::string& key) const noexcept
963 return (*this)[key.data()];
966 nonstd::optional<CommonValue<LibObjT>> operator[](const char * const key) noexcept
968 const auto libObjPtr =
969 internal::CommonMapValueSpec<LibObjT>::entryByKey(this->_libObjPtr(), key);
972 return nonstd::nullopt;
975 return CommonValue<LibObjT> {libObjPtr};
978 nonstd::optional<CommonValue<LibObjT>> operator[](const std::string& key) noexcept
980 return (*this)[key.data()];
983 bool hasEntry(const char * const key) const noexcept
985 return static_cast<bool>(bt_value_map_has_entry(this->_libObjPtr(), key));
988 bool hasEntry(const std::string& key) const noexcept
990 return this->hasEntry(key.data());
993 void insert(const char * const key, const Value& val)
995 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
997 const auto status = bt_value_map_insert_entry(this->_libObjPtr(), key, val._libObjPtr());
999 this->_handleInsertLibStatus(status);
1002 void insert(const std::string& key, const Value& val)
1004 this->insert(key.data(), val);
1007 void insert(const char * const key, const bool rawVal)
1009 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1012 bt_value_map_insert_bool_entry(this->_libObjPtr(), key, static_cast<bt_bool>(rawVal));
1014 this->_handleInsertLibStatus(status);
1017 void insert(const std::string& key, const bool rawVal)
1019 this->insert(key.data(), rawVal);
1022 void insert(const char * const key, const std::uint64_t rawVal)
1024 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1027 bt_value_map_insert_unsigned_integer_entry(this->_libObjPtr(), key, rawVal);
1029 this->_handleInsertLibStatus(status);
1032 void insert(const std::string& key, const std::uint64_t rawVal)
1034 this->insert(key.data(), rawVal);
1037 void insert(const char * const key, const std::int64_t rawVal)
1039 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1042 bt_value_map_insert_signed_integer_entry(this->_libObjPtr(), key, rawVal);
1044 this->_handleInsertLibStatus(status);
1047 void insert(const std::string& key, const std::int64_t rawVal)
1049 this->insert(key.data(), rawVal);
1052 void insert(const char * const key, const double rawVal)
1054 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1056 const auto status = bt_value_map_insert_real_entry(this->_libObjPtr(), key, rawVal);
1058 this->_handleInsertLibStatus(status);
1061 void insert(const std::string& key, const double rawVal)
1063 this->insert(key.data(), rawVal);
1066 void insert(const char * const key, const char * const rawVal)
1068 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1070 const auto status = bt_value_map_insert_string_entry(this->_libObjPtr(), key, rawVal);
1072 this->_handleInsertLibStatus(status);
1075 void insert(const char * const key, const std::string& rawVal)
1077 this->insert(key, rawVal.data());
1080 void insert(const std::string& key, const char * const rawVal)
1082 this->insert(key.data(), rawVal);
1085 void insert(const std::string& key, const std::string& rawVal)
1087 this->insert(key.data(), rawVal.data());
1090 CommonArrayValue<bt_value> insertEmptyArray(const char *key);
1091 CommonArrayValue<bt_value> insertEmptyArray(const std::string& key);
1092 CommonMapValue<bt_value> insertEmptyMap(const char *key);
1093 CommonMapValue<bt_value> insertEmptyMap(const std::string& key);
1095 void forEach(const internal::CommonMapValueForEachUserFunc<ConstValue>& func) const
1097 internal::CommonMapValueSpec<const bt_value>::forEach(this->_libObjPtr(), func);
1100 void forEach(const internal::CommonMapValueForEachUserFunc<CommonValue<LibObjT>>& func)
1102 internal::CommonMapValueSpec<LibObjT>::forEach(this->_libObjPtr(), func);
1105 Shared shared() const noexcept
1107 return Shared {*this};
1111 void _handleInsertLibStatus(const bt_value_map_insert_entry_status status) const
1113 if (status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_MEMORY_ERROR) {
1114 throw LibMemoryError {};
1119 using MapValue = CommonMapValue<bt_value>;
1120 using ConstMapValue = CommonMapValue<const bt_value>;
1122 template <typename LibObjT>
1123 CommonNullValue<LibObjT> CommonValue<LibObjT>::asNull() const noexcept
1125 BT_ASSERT_DBG(this->isNull());
1126 return CommonNullValue<LibObjT> {this->_libObjPtr()};
1129 template <typename LibObjT>
1130 CommonBoolValue<LibObjT> CommonValue<LibObjT>::asBool() const noexcept
1132 BT_ASSERT_DBG(this->isBool());
1133 return CommonBoolValue<LibObjT> {this->_libObjPtr()};
1136 template <typename LibObjT>
1137 CommonSignedIntegerValue<LibObjT> CommonValue<LibObjT>::asSignedInteger() const noexcept
1139 BT_ASSERT_DBG(this->isSignedInteger());
1140 return CommonSignedIntegerValue<LibObjT> {this->_libObjPtr()};
1143 template <typename LibObjT>
1144 CommonUnsignedIntegerValue<LibObjT> CommonValue<LibObjT>::asUnsignedInteger() const noexcept
1146 BT_ASSERT_DBG(this->isUnsignedInteger());
1147 return CommonUnsignedIntegerValue<LibObjT> {this->_libObjPtr()};
1150 template <typename LibObjT>
1151 CommonRealValue<LibObjT> CommonValue<LibObjT>::asReal() const noexcept
1153 BT_ASSERT_DBG(this->isReal());
1154 return CommonRealValue<LibObjT> {this->_libObjPtr()};
1157 template <typename LibObjT>
1158 CommonStringValue<LibObjT> CommonValue<LibObjT>::asString() const noexcept
1160 BT_ASSERT_DBG(this->isString());
1161 return CommonStringValue<LibObjT> {this->_libObjPtr()};
1164 template <typename LibObjT>
1165 CommonArrayValue<LibObjT> CommonValue<LibObjT>::asArray() const noexcept
1167 BT_ASSERT_DBG(this->isArray());
1168 return CommonArrayValue<LibObjT> {this->_libObjPtr()};
1171 template <typename LibObjT>
1172 CommonMapValue<LibObjT> CommonValue<LibObjT>::asMap() const noexcept
1174 BT_ASSERT_DBG(this->isMap());
1175 return CommonMapValue<LibObjT> {this->_libObjPtr()};
1178 template <typename LibObjT>
1179 ArrayValue CommonArrayValue<LibObjT>::appendEmptyArray()
1181 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1183 bt_value *libElemPtr;
1184 const auto status = bt_value_array_append_empty_array_element(this->_libObjPtr(), &libElemPtr);
1186 this->_handleAppendLibStatus(status);
1187 return ArrayValue {libElemPtr};
1190 template <typename LibObjT>
1191 MapValue CommonArrayValue<LibObjT>::appendEmptyMap()
1193 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1195 bt_value *libElemPtr;
1196 const auto status = bt_value_array_append_empty_map_element(this->_libObjPtr(), &libElemPtr);
1198 this->_handleAppendLibStatus(status);
1199 return MapValue {libElemPtr};
1202 template <typename LibObjT>
1203 ArrayValue CommonMapValue<LibObjT>::insertEmptyArray(const char * const key)
1205 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1207 bt_value *libEntryPtr;
1209 bt_value_map_insert_empty_array_entry(this->_libObjPtr(), key, &libEntryPtr);
1211 this->_handleInsertLibStatus(status);
1212 return ArrayValue {libEntryPtr};
1215 template <typename LibObjT>
1216 ArrayValue CommonMapValue<LibObjT>::insertEmptyArray(const std::string& key)
1218 return this->insertEmptyArray(key.data());
1221 template <typename LibObjT>
1222 MapValue CommonMapValue<LibObjT>::insertEmptyMap(const char * const key)
1224 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
1226 bt_value *libEntryPtr;
1227 const auto status = bt_value_map_insert_empty_map_entry(this->_libObjPtr(), key, &libEntryPtr);
1229 this->_handleInsertLibStatus(status);
1230 return MapValue {libEntryPtr};
1233 template <typename LibObjT>
1234 MapValue CommonMapValue<LibObjT>::insertEmptyMap(const std::string& key)
1236 return this->insertEmptyMap(key.data());
1239 inline BoolValue::Shared createValue(const bool rawVal)
1241 return BoolValue::create(rawVal);
1244 inline UnsignedIntegerValue::Shared createValue(const std::uint64_t rawVal)
1246 return UnsignedIntegerValue::create(rawVal);
1249 inline SignedIntegerValue::Shared createValue(const std::int64_t rawVal)
1251 return SignedIntegerValue::create(rawVal);
1254 inline RealValue::Shared createValue(const double rawVal)
1256 return RealValue::create(rawVal);
1259 inline StringValue::Shared createValue(const char * const rawVal)
1261 return StringValue::create(rawVal);
1264 inline StringValue::Shared createValue(const std::string& rawVal)
1266 return StringValue::create(rawVal);
1271 #endif // BABELTRACE_CPP_COMMON_BT2_VALUE_HPP