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
12 #include <type_traits>
14 #include <babeltrace2/babeltrace.h>
16 #include "common/assert.h"
17 #include "common/common.h"
18 #include "cpp-common/bt2s/optional.hpp"
20 #include "borrowed-object-iterator.hpp"
21 #include "borrowed-object.hpp"
23 #include "internal/utils.hpp"
24 #include "raw-value-proxy.hpp"
25 #include "shared-object.hpp"
30 struct ValueRefFuncs final
32 static void get(const bt_value * const libObjPtr) noexcept
34 bt_value_get_ref(libObjPtr);
37 static void put(const bt_value * const libObjPtr) noexcept
39 bt_value_put_ref(libObjPtr);
43 } /* namespace internal */
45 template <typename ObjT, typename LibObjT>
46 using SharedValue = SharedObject<ObjT, LibObjT, internal::ValueRefFuncs>;
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 ValueObjT>
85 class CommonValueRawValueProxy final
88 explicit CommonValueRawValueProxy(const ValueObjT obj) : _mObj {obj}
92 CommonValueRawValueProxy& operator=(bool rawVal) noexcept;
93 CommonValueRawValueProxy& operator=(std::int64_t rawVal) noexcept;
94 CommonValueRawValueProxy& operator=(std::uint64_t rawVal) noexcept;
95 CommonValueRawValueProxy& operator=(double rawVal) noexcept;
96 CommonValueRawValueProxy& operator=(const char *rawVal);
97 CommonValueRawValueProxy& operator=(const std::string& rawVal);
98 operator bool() const noexcept;
99 operator std::int64_t() const noexcept;
100 operator std::uint64_t() const noexcept;
101 operator double() const noexcept;
102 operator const char *() const noexcept;
108 template <typename LibObjT>
109 class CommonValue : public BorrowedObject<LibObjT>
112 using typename BorrowedObject<LibObjT>::_ThisBorrowedObject;
115 using typename BorrowedObject<LibObjT>::_LibObjPtr;
116 using _ThisCommonValue = CommonValue<LibObjT>;
119 using Shared = SharedValue<CommonValue<LibObjT>, LibObjT>;
121 explicit CommonValue(const _LibObjPtr libObjPtr) noexcept : _ThisBorrowedObject {libObjPtr}
125 template <typename OtherLibObjT>
126 CommonValue(const CommonValue<OtherLibObjT> val) noexcept : _ThisBorrowedObject {val}
130 template <typename OtherLibObjT>
131 _ThisCommonValue operator=(const CommonValue<OtherLibObjT> val) noexcept
133 _ThisBorrowedObject::operator=(val);
137 CommonValue<const bt_value> asConst() const noexcept
139 return CommonValue<const bt_value> {*this};
142 ValueType type() const noexcept
144 return static_cast<ValueType>(bt_value_get_type(this->libObjPtr()));
147 bool isNull() const noexcept
149 return this->_libTypeIs(BT_VALUE_TYPE_NULL);
152 bool isBool() const noexcept
154 return this->_libTypeIs(BT_VALUE_TYPE_BOOL);
157 bool isInteger() const noexcept
159 return this->_libTypeIs(BT_VALUE_TYPE_INTEGER);
162 bool isUnsignedInteger() const noexcept
164 return this->_libTypeIs(BT_VALUE_TYPE_UNSIGNED_INTEGER);
167 bool isSignedInteger() const noexcept
169 return this->_libTypeIs(BT_VALUE_TYPE_SIGNED_INTEGER);
172 bool isReal() const noexcept
174 return this->_libTypeIs(BT_VALUE_TYPE_REAL);
177 bool isString() const noexcept
179 return this->_libTypeIs(BT_VALUE_TYPE_STRING);
182 bool isArray() const noexcept
184 return this->_libTypeIs(BT_VALUE_TYPE_ARRAY);
187 bool isMap() const noexcept
189 return this->_libTypeIs(BT_VALUE_TYPE_MAP);
192 template <typename OtherLibObjT>
193 bool operator==(const CommonValue<OtherLibObjT> other) const noexcept
195 return static_cast<bool>(bt_value_is_equal(this->libObjPtr(), other.libObjPtr()));
198 template <typename OtherLibObjT>
199 bool operator!=(const CommonValue<OtherLibObjT> other) const noexcept
201 return !(*this == other);
204 CommonValueRawValueProxy<CommonValue> operator*() const noexcept
206 return CommonValueRawValueProxy<CommonValue> {*this};
209 std::uint64_t arrayLength() const noexcept
211 return this->asArray().length();
214 bool arrayIsEmpty() const noexcept
216 return this->asArray().isEmpty();
219 CommonValue<LibObjT> operator[](const std::uint64_t index) const noexcept
221 return this->asArray()[index];
224 template <typename T>
225 void append(T&& elem) const
227 this->asArray().append(std::forward<T>(elem));
230 CommonArrayValue<bt_value> appendEmptyArray() const;
231 CommonMapValue<bt_value> appendEmptyMap() const;
233 std::uint64_t mapLength() const noexcept
235 return this->asMap().length();
238 bool mapIsEmpty() const noexcept
240 return this->asMap().isEmpty();
243 template <typename KeyT>
244 bt2s::optional<CommonValue<LibObjT>> operator[](KeyT&& key) const noexcept
246 return this->asMap()[std::forward<KeyT>(key)];
249 template <typename KeyT>
250 bool hasEntry(KeyT&& key) const noexcept
252 return this->asMap().hasEntry(std::forward<KeyT>(key));
255 template <typename KeyT, typename ValT>
256 void insert(KeyT&& key, ValT&& val) const
258 this->asMap().insert(std::forward<KeyT>(key), std::forward<ValT>(val));
261 CommonArrayValue<bt_value> insertEmptyArray(const char *key) const;
262 CommonArrayValue<bt_value> insertEmptyArray(const std::string& key) const;
263 CommonMapValue<bt_value> insertEmptyMap(const char *key) const;
264 CommonMapValue<bt_value> insertEmptyMap(const std::string& key) const;
266 Shared shared() const noexcept
268 return Shared::createWithRef(*this);
271 template <typename ValueT>
272 ValueT as() const noexcept
274 return ValueT {this->libObjPtr()};
277 CommonNullValue<LibObjT> asNull() const noexcept;
278 CommonBoolValue<LibObjT> asBool() const noexcept;
279 CommonSignedIntegerValue<LibObjT> asSignedInteger() const noexcept;
280 CommonUnsignedIntegerValue<LibObjT> asUnsignedInteger() const noexcept;
281 CommonRealValue<LibObjT> asReal() const noexcept;
282 CommonStringValue<LibObjT> asString() const noexcept;
283 CommonArrayValue<LibObjT> asArray() const noexcept;
284 CommonMapValue<LibObjT> asMap() const noexcept;
287 bool _libTypeIs(const bt_value_type type) const noexcept
289 return bt_value_type_is(bt_value_get_type(this->libObjPtr()), type);
293 using Value = CommonValue<bt_value>;
294 using ConstValue = CommonValue<const bt_value>;
296 template <typename ValueObjT>
297 CommonValueRawValueProxy<ValueObjT>&
298 CommonValueRawValueProxy<ValueObjT>::operator=(const bool rawVal) noexcept
300 _mObj.asBool().value(rawVal);
304 template <typename ValueObjT>
305 CommonValueRawValueProxy<ValueObjT>&
306 CommonValueRawValueProxy<ValueObjT>::operator=(const std::int64_t rawVal) noexcept
308 _mObj.asSignedInteger().value(rawVal);
312 template <typename ValueObjT>
313 CommonValueRawValueProxy<ValueObjT>&
314 CommonValueRawValueProxy<ValueObjT>::operator=(const std::uint64_t rawVal) noexcept
316 _mObj.asUnsignedInteger().value(rawVal);
320 template <typename ValueObjT>
321 CommonValueRawValueProxy<ValueObjT>&
322 CommonValueRawValueProxy<ValueObjT>::operator=(const double rawVal) noexcept
324 _mObj.asReal().value(rawVal);
328 template <typename ValueObjT>
329 CommonValueRawValueProxy<ValueObjT>&
330 CommonValueRawValueProxy<ValueObjT>::operator=(const char * const rawVal)
332 _mObj.asString().value(rawVal);
336 template <typename ValueObjT>
337 CommonValueRawValueProxy<ValueObjT>&
338 CommonValueRawValueProxy<ValueObjT>::operator=(const std::string& rawVal)
340 return *this = rawVal.data();
343 template <typename ValueObjT>
344 CommonValueRawValueProxy<ValueObjT>::operator bool() const noexcept
346 return _mObj.asBool().value();
349 template <typename ValueObjT>
350 CommonValueRawValueProxy<ValueObjT>::operator std::int64_t() const noexcept
352 return _mObj.asSignedInteger().value();
355 template <typename ValueObjT>
356 CommonValueRawValueProxy<ValueObjT>::operator std::uint64_t() const noexcept
358 return _mObj.asUnsignedInteger().value();
361 template <typename ValueObjT>
362 CommonValueRawValueProxy<ValueObjT>::operator double() const noexcept
364 return _mObj.asReal().value();
367 template <typename ValueObjT>
368 CommonValueRawValueProxy<ValueObjT>::operator const char *() const noexcept
370 return _mObj.asString().value();
375 struct ValueTypeDescr
377 using Const = ConstValue;
378 using NonConst = Value;
382 struct TypeDescr<Value> : public ValueTypeDescr
387 struct TypeDescr<ConstValue> : public ValueTypeDescr
391 } /* namespace internal */
393 template <typename LibObjT>
394 class CommonNullValue final : public CommonValue<LibObjT>
397 using typename CommonValue<LibObjT>::_ThisCommonValue;
400 using Shared = SharedValue<CommonNullValue<LibObjT>, LibObjT>;
402 CommonNullValue() noexcept : _ThisCommonValue {bt_value_null}
406 template <typename OtherLibObjT>
407 CommonNullValue(const CommonNullValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
411 template <typename OtherLibObjT>
412 CommonNullValue<LibObjT> operator=(const CommonNullValue<OtherLibObjT> val) noexcept
414 _ThisCommonValue::operator=(val);
418 CommonNullValue<const bt_value> asConst() const noexcept
420 return CommonNullValue<const bt_value> {*this};
423 Shared shared() const noexcept
425 return Shared::createWithRef(*this);
429 using NullValue = CommonNullValue<bt_value>;
430 using ConstNullValue = CommonNullValue<const bt_value>;
434 struct NullValueTypeDescr
436 using Const = ConstNullValue;
437 using NonConst = NullValue;
441 struct TypeDescr<NullValue> : public NullValueTypeDescr
446 struct TypeDescr<ConstNullValue> : public NullValueTypeDescr
450 } /* namespace internal */
452 template <typename LibObjT>
453 class CommonBoolValue final : public CommonValue<LibObjT>
456 using typename CommonValue<LibObjT>::_LibObjPtr;
457 using typename CommonValue<LibObjT>::_ThisCommonValue;
460 using Shared = SharedValue<CommonBoolValue<LibObjT>, LibObjT>;
463 explicit CommonBoolValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
465 BT_ASSERT_DBG(this->isBool());
468 template <typename OtherLibObjT>
469 CommonBoolValue(const CommonBoolValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
473 static Shared create(const Value rawVal = false)
475 const auto libObjPtr = bt_value_bool_create_init(static_cast<bt_bool>(rawVal));
477 internal::validateCreatedObjPtr(libObjPtr);
478 return CommonBoolValue::Shared::createWithoutRef(libObjPtr);
481 template <typename OtherLibObjT>
482 CommonBoolValue<LibObjT> operator=(const CommonBoolValue<OtherLibObjT> val) noexcept
484 _ThisCommonValue::operator=(val);
488 CommonBoolValue<const bt_value> asConst() const noexcept
490 return CommonBoolValue<const bt_value> {*this};
493 RawValueProxy<CommonBoolValue> operator*() const noexcept
495 return RawValueProxy<CommonBoolValue> {*this};
498 Value value() const noexcept
500 return static_cast<Value>(bt_value_bool_get(this->libObjPtr()));
503 void value(const Value val) const noexcept
505 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstBoolValue`.");
507 bt_value_bool_set(this->libObjPtr(), static_cast<bt_bool>(val));
510 Shared shared() const noexcept
512 return Shared::createWithRef(*this);
516 using BoolValue = CommonBoolValue<bt_value>;
517 using ConstBoolValue = CommonBoolValue<const bt_value>;
521 struct BoolValueTypeDescr
523 using Const = ConstBoolValue;
524 using NonConst = BoolValue;
528 struct TypeDescr<BoolValue> : public BoolValueTypeDescr
533 struct TypeDescr<ConstBoolValue> : public BoolValueTypeDescr
537 } /* namespace internal */
539 template <typename LibObjT>
540 class CommonUnsignedIntegerValue final : public CommonValue<LibObjT>
543 using typename CommonValue<LibObjT>::_LibObjPtr;
544 using typename CommonValue<LibObjT>::_ThisCommonValue;
547 using Shared = SharedValue<CommonUnsignedIntegerValue<LibObjT>, LibObjT>;
548 using Value = std::uint64_t;
550 explicit CommonUnsignedIntegerValue(const _LibObjPtr libObjPtr) noexcept :
551 _ThisCommonValue {libObjPtr}
553 BT_ASSERT_DBG(this->isUnsignedInteger());
556 static Shared create(const Value rawVal = 0)
558 const auto libObjPtr = bt_value_integer_unsigned_create_init(rawVal);
560 internal::validateCreatedObjPtr(libObjPtr);
561 return CommonUnsignedIntegerValue::Shared::createWithoutRef(libObjPtr);
564 template <typename OtherLibObjT>
565 CommonUnsignedIntegerValue(const CommonUnsignedIntegerValue<OtherLibObjT> val) noexcept :
566 _ThisCommonValue {val}
570 template <typename OtherLibObjT>
571 CommonUnsignedIntegerValue<LibObjT>
572 operator=(const CommonUnsignedIntegerValue<OtherLibObjT> val) noexcept
574 _ThisCommonValue::operator=(val);
578 CommonUnsignedIntegerValue<const bt_value> asConst() const noexcept
580 return CommonUnsignedIntegerValue<const bt_value> {*this};
583 RawValueProxy<CommonUnsignedIntegerValue> operator*() const noexcept
585 return RawValueProxy<CommonUnsignedIntegerValue> {*this};
588 void value(const Value val) const noexcept
590 static_assert(!std::is_const<LibObjT>::value,
591 "Not available with `bt2::ConstUnsignedIntegerValue`.");
593 bt_value_integer_unsigned_set(this->libObjPtr(), val);
596 Value value() const noexcept
598 return bt_value_integer_unsigned_get(this->libObjPtr());
601 Shared shared() const noexcept
603 return Shared::createWithRef(*this);
607 using UnsignedIntegerValue = CommonUnsignedIntegerValue<bt_value>;
608 using ConstUnsignedIntegerValue = CommonUnsignedIntegerValue<const bt_value>;
612 struct UnsignedIntegerValueTypeDescr
614 using Const = ConstUnsignedIntegerValue;
615 using NonConst = UnsignedIntegerValue;
619 struct TypeDescr<UnsignedIntegerValue> : public UnsignedIntegerValueTypeDescr
624 struct TypeDescr<ConstUnsignedIntegerValue> : public UnsignedIntegerValueTypeDescr
628 } /* namespace internal */
630 template <typename LibObjT>
631 class CommonSignedIntegerValue final : public CommonValue<LibObjT>
634 using typename CommonValue<LibObjT>::_LibObjPtr;
635 using typename CommonValue<LibObjT>::_ThisCommonValue;
638 using Shared = SharedValue<CommonSignedIntegerValue<LibObjT>, LibObjT>;
639 using Value = std::int64_t;
641 explicit CommonSignedIntegerValue(const _LibObjPtr libObjPtr) noexcept :
642 _ThisCommonValue {libObjPtr}
644 BT_ASSERT_DBG(this->isSignedInteger());
647 static Shared create(const Value rawVal = 0)
649 const auto libObjPtr = bt_value_integer_signed_create_init(rawVal);
651 internal::validateCreatedObjPtr(libObjPtr);
652 return CommonSignedIntegerValue::Shared::createWithoutRef(libObjPtr);
655 template <typename OtherLibObjT>
656 CommonSignedIntegerValue(const CommonSignedIntegerValue<OtherLibObjT> val) noexcept :
657 _ThisCommonValue {val}
661 template <typename OtherLibObjT>
662 CommonSignedIntegerValue<LibObjT>
663 operator=(const CommonSignedIntegerValue<OtherLibObjT> val) noexcept
665 _ThisCommonValue::operator=(val);
669 CommonSignedIntegerValue<const bt_value> asConst() const noexcept
671 return CommonSignedIntegerValue<const bt_value> {*this};
674 RawValueProxy<CommonSignedIntegerValue> operator*() const noexcept
676 return RawValueProxy<CommonSignedIntegerValue> {*this};
679 void value(const Value val) const noexcept
681 static_assert(!std::is_const<LibObjT>::value,
682 "Not available with `bt2::ConstSignedIntegerValue`.");
684 bt_value_integer_signed_set(this->libObjPtr(), val);
687 Value value() const noexcept
689 return bt_value_integer_signed_get(this->libObjPtr());
692 Shared shared() const noexcept
694 return Shared::createWithRef(*this);
698 using SignedIntegerValue = CommonSignedIntegerValue<bt_value>;
699 using ConstSignedIntegerValue = CommonSignedIntegerValue<const bt_value>;
703 struct SignedIntegerValueTypeDescr
705 using Const = ConstSignedIntegerValue;
706 using NonConst = SignedIntegerValue;
710 struct TypeDescr<SignedIntegerValue> : public SignedIntegerValueTypeDescr
715 struct TypeDescr<ConstSignedIntegerValue> : public SignedIntegerValueTypeDescr
719 } /* namespace internal */
721 template <typename LibObjT>
722 class CommonRealValue final : public CommonValue<LibObjT>
725 using typename CommonValue<LibObjT>::_LibObjPtr;
726 using typename CommonValue<LibObjT>::_ThisCommonValue;
729 using Shared = SharedValue<CommonRealValue<LibObjT>, LibObjT>;
730 using Value = double;
732 explicit CommonRealValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
734 BT_ASSERT_DBG(this->isReal());
737 static Shared create(const Value rawVal = 0)
739 const auto libObjPtr = bt_value_real_create_init(rawVal);
741 internal::validateCreatedObjPtr(libObjPtr);
742 return CommonRealValue::Shared::createWithoutRef(libObjPtr);
745 template <typename OtherLibObjT>
746 CommonRealValue(const CommonRealValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
750 template <typename OtherLibObjT>
751 CommonRealValue<LibObjT> operator=(const CommonRealValue<OtherLibObjT> val) noexcept
753 _ThisCommonValue::operator=(val);
757 CommonRealValue<const bt_value> asConst() const noexcept
759 return CommonRealValue<const bt_value> {*this};
762 RawValueProxy<CommonRealValue> operator*() const noexcept
764 return RawValueProxy<CommonRealValue> {*this};
767 void value(const Value val) const noexcept
769 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstRealValue`.");
771 bt_value_real_set(this->libObjPtr(), val);
774 Value value() const noexcept
776 return bt_value_real_get(this->libObjPtr());
779 Shared shared() const noexcept
781 return Shared::createWithRef(*this);
785 using RealValue = CommonRealValue<bt_value>;
786 using ConstRealValue = CommonRealValue<const bt_value>;
790 struct RealValueTypeDescr
792 using Const = ConstRealValue;
793 using NonConst = RealValue;
797 struct TypeDescr<RealValue> : public RealValueTypeDescr
802 struct TypeDescr<ConstRealValue> : public RealValueTypeDescr
806 } /* namespace internal */
808 template <typename LibObjT>
809 class CommonStringValue final : public CommonValue<LibObjT>
812 using typename CommonValue<LibObjT>::_LibObjPtr;
813 using typename CommonValue<LibObjT>::_ThisCommonValue;
816 using Shared = SharedValue<CommonStringValue<LibObjT>, LibObjT>;
817 using Value = const char *;
819 explicit CommonStringValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
821 BT_ASSERT_DBG(this->isString());
824 static Shared create(const char * const rawVal = "")
826 const auto libObjPtr = bt_value_string_create_init(rawVal);
828 internal::validateCreatedObjPtr(libObjPtr);
829 return CommonStringValue::Shared::createWithoutRef(libObjPtr);
832 static Shared create(const std::string& rawVal)
834 return CommonStringValue::create(rawVal.data());
837 template <typename OtherLibObjT>
838 CommonStringValue(const CommonStringValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
842 template <typename OtherLibObjT>
843 CommonStringValue<LibObjT> operator=(const CommonStringValue<OtherLibObjT> val) noexcept
845 _ThisCommonValue::operator=(val);
849 CommonStringValue<const bt_value> asConst() const noexcept
851 return CommonStringValue<const bt_value> {*this};
854 RawStringValueProxy<CommonStringValue> operator*() const noexcept
856 return RawStringValueProxy<CommonStringValue> {*this};
859 void value(const Value val) const
861 static_assert(!std::is_const<LibObjT>::value,
862 "Not available with `bt2::ConstStringValue`.");
864 const auto status = bt_value_string_set(this->libObjPtr(), val);
866 if (status == BT_VALUE_STRING_SET_STATUS_MEMORY_ERROR) {
867 throw MemoryError {};
871 void value(const std::string& val) const
873 this->value(val.data());
876 const char *value() const noexcept
878 return bt_value_string_get(this->libObjPtr());
881 Shared shared() const noexcept
883 return Shared::createWithRef(*this);
887 using StringValue = CommonStringValue<bt_value>;
888 using ConstStringValue = CommonStringValue<const bt_value>;
892 struct StringValueTypeDescr
894 using Const = ConstStringValue;
895 using NonConst = StringValue;
899 struct TypeDescr<StringValue> : public StringValueTypeDescr
904 struct TypeDescr<ConstStringValue> : public StringValueTypeDescr
908 template <typename LibObjT>
909 struct CommonArrayValueSpec;
911 /* Functions specific to mutable array values */
913 struct CommonArrayValueSpec<bt_value> final
915 static bt_value *elementByIndex(bt_value * const libValPtr, const std::uint64_t index) noexcept
917 return bt_value_array_borrow_element_by_index(libValPtr, index);
921 /* Functions specific to constant array values */
923 struct CommonArrayValueSpec<const bt_value> final
925 static const bt_value *elementByIndex(const bt_value * const libValPtr,
926 const std::uint64_t index) noexcept
928 return bt_value_array_borrow_element_by_index_const(libValPtr, index);
932 } /* namespace internal */
934 template <typename LibObjT>
935 class CommonArrayValue final : public CommonValue<LibObjT>
938 using typename CommonValue<LibObjT>::_LibObjPtr;
939 using typename CommonValue<LibObjT>::_ThisCommonValue;
942 using Shared = SharedValue<CommonArrayValue<LibObjT>, LibObjT>;
943 using Iterator = BorrowedObjectIterator<CommonArrayValue<LibObjT>>;
945 explicit CommonArrayValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
947 BT_ASSERT_DBG(this->isArray());
950 static Shared create()
952 const auto libObjPtr = bt_value_array_create();
954 internal::validateCreatedObjPtr(libObjPtr);
955 return CommonArrayValue::Shared::createWithoutRef(libObjPtr);
958 template <typename OtherLibObjT>
959 CommonArrayValue(const CommonArrayValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
963 template <typename OtherLibObjT>
964 CommonArrayValue<LibObjT> operator=(const CommonArrayValue<OtherLibObjT> val) noexcept
966 _ThisCommonValue::operator=(val);
970 CommonArrayValue<const bt_value> asConst() const noexcept
972 return CommonArrayValue<const bt_value> {*this};
975 std::uint64_t length() const noexcept
977 return bt_value_array_get_length(this->libObjPtr());
980 Iterator begin() const noexcept
982 return Iterator {*this, 0};
985 Iterator end() const noexcept
987 return Iterator {*this, this->length()};
990 bool isEmpty() const noexcept
992 return this->length() == 0;
995 CommonValue<LibObjT> operator[](const std::uint64_t index) const noexcept
997 return CommonValue<LibObjT> {
998 internal::CommonArrayValueSpec<LibObjT>::elementByIndex(this->libObjPtr(), index)};
1001 void append(const Value val) const
1003 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
1005 const auto status = bt_value_array_append_element(this->libObjPtr(), val.libObjPtr());
1007 this->_handleAppendLibStatus(status);
1010 void append(const bool rawVal) const
1012 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
1015 bt_value_array_append_bool_element(this->libObjPtr(), static_cast<bt_bool>(rawVal));
1017 this->_handleAppendLibStatus(status);
1020 void append(const std::uint64_t rawVal) const
1022 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
1025 bt_value_array_append_unsigned_integer_element(this->libObjPtr(), rawVal);
1027 this->_handleAppendLibStatus(status);
1030 void append(const std::int64_t rawVal) const
1032 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
1034 const auto status = bt_value_array_append_signed_integer_element(this->libObjPtr(), rawVal);
1036 this->_handleAppendLibStatus(status);
1039 void append(const double rawVal) const
1041 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
1043 const auto status = bt_value_array_append_real_element(this->libObjPtr(), rawVal);
1045 this->_handleAppendLibStatus(status);
1048 void append(const char * const rawVal) const
1050 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
1052 const auto status = bt_value_array_append_string_element(this->libObjPtr(), rawVal);
1054 this->_handleAppendLibStatus(status);
1057 void append(const std::string& rawVal) const
1059 this->append(rawVal.data());
1062 CommonArrayValue<bt_value> appendEmptyArray() const;
1063 CommonMapValue<bt_value> appendEmptyMap() const;
1065 void operator+=(const Value val) const
1070 void operator+=(const bool rawVal) const
1072 this->append(rawVal);
1075 void operator+=(const std::uint64_t rawVal) const
1077 this->append(rawVal);
1080 void operator+=(const std::int64_t rawVal) const
1082 this->append(rawVal);
1085 void operator+=(const double rawVal) const
1087 this->append(rawVal);
1090 void operator+=(const char * const rawVal) const
1092 this->append(rawVal);
1095 void operator+=(const std::string& rawVal) const
1097 this->append(rawVal);
1100 Shared shared() const noexcept
1102 return Shared::createWithRef(*this);
1106 void _handleAppendLibStatus(const bt_value_array_append_element_status status) const
1108 if (status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_MEMORY_ERROR) {
1109 throw MemoryError {};
1114 using ArrayValue = CommonArrayValue<bt_value>;
1115 using ConstArrayValue = CommonArrayValue<const bt_value>;
1117 namespace internal {
1119 struct ArrayValueTypeDescr
1121 using Const = ConstArrayValue;
1122 using NonConst = ArrayValue;
1126 struct TypeDescr<ArrayValue> : public ArrayValueTypeDescr
1131 struct TypeDescr<ConstArrayValue> : public ArrayValueTypeDescr
1136 * Type of a user function passed to `CommonMapValue<ObjT>::forEach()`.
1138 * First argument is the entry's key, second is its value.
1140 template <typename ObjT>
1141 using CommonMapValueForEachUserFunc = std::function<void(const char *, ObjT)>;
1144 * Template of a function to be passed to bt_value_map_foreach_entry()
1145 * for bt_value_map_foreach_entry_const() which calls a user function.
1147 * `userData` is casted to a `const` pointer to
1148 * `CommonMapValueForEachUserFunc<ObjT>` (the user function to call).
1150 * This function catches any exception which the user function throws
1151 * and returns the `ErrorStatus` value. If there's no execption, this
1152 * function returns the `OkStatus` value.
1154 template <typename ObjT, typename LibObjT, typename LibStatusT, int OkStatus, int ErrorStatus>
1155 LibStatusT mapValueForEachLibFunc(const char * const key, LibObjT * const libObjPtr,
1156 void * const userData)
1158 const auto& userFunc = *reinterpret_cast<const CommonMapValueForEachUserFunc<ObjT> *>(userData);
1161 userFunc(key, ObjT {libObjPtr});
1163 return static_cast<LibStatusT>(ErrorStatus);
1166 return static_cast<LibStatusT>(OkStatus);
1169 template <typename LibObjT>
1170 struct CommonMapValueSpec;
1172 /* Functions specific to mutable map values */
1174 struct CommonMapValueSpec<bt_value> final
1176 static bt_value *entryByKey(bt_value * const libValPtr, const char * const key) noexcept
1178 return bt_value_map_borrow_entry_value(libValPtr, key);
1181 static void forEach(bt_value * const libValPtr,
1182 const CommonMapValueForEachUserFunc<Value>& func)
1184 const auto status = bt_value_map_foreach_entry(
1186 mapValueForEachLibFunc<Value, bt_value, bt_value_map_foreach_entry_func_status,
1187 BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_OK,
1188 BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_ERROR>,
1189 const_cast<void *>(reinterpret_cast<const void *>(&func)));
1192 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_OK:
1194 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_USER_ERROR:
1195 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_ERROR:
1203 /* Functions specific to constant map values */
1205 struct CommonMapValueSpec<const bt_value> final
1207 static const bt_value *entryByKey(const bt_value * const libValPtr,
1208 const char * const key) noexcept
1210 return bt_value_map_borrow_entry_value_const(libValPtr, key);
1213 static void forEach(const bt_value * const libValPtr,
1214 const CommonMapValueForEachUserFunc<ConstValue>& func)
1216 const auto status = bt_value_map_foreach_entry_const(
1218 mapValueForEachLibFunc<ConstValue, const bt_value,
1219 bt_value_map_foreach_entry_const_func_status,
1220 BT_VALUE_MAP_FOREACH_ENTRY_CONST_FUNC_STATUS_OK,
1221 BT_VALUE_MAP_FOREACH_ENTRY_CONST_FUNC_STATUS_ERROR>,
1222 const_cast<void *>(reinterpret_cast<const void *>(&func)));
1225 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_OK:
1227 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_USER_ERROR:
1228 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_ERROR:
1236 } /* namespace internal */
1238 template <typename LibObjT>
1239 class CommonMapValue final : public CommonValue<LibObjT>
1242 using typename CommonValue<LibObjT>::_LibObjPtr;
1243 using typename CommonValue<LibObjT>::_ThisCommonValue;
1246 using Shared = SharedValue<CommonMapValue<LibObjT>, LibObjT>;
1248 explicit CommonMapValue(const _LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
1250 BT_ASSERT_DBG(this->isMap());
1253 static Shared create()
1255 const auto libObjPtr = bt_value_map_create();
1257 internal::validateCreatedObjPtr(libObjPtr);
1258 return CommonMapValue::Shared::createWithoutRef(libObjPtr);
1261 template <typename OtherLibObjT>
1262 CommonMapValue(const CommonMapValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
1266 template <typename OtherLibObjT>
1267 CommonMapValue<LibObjT> operator=(const CommonMapValue<OtherLibObjT> val) noexcept
1269 _ThisCommonValue::operator=(val);
1273 CommonMapValue<const bt_value> asConst() const noexcept
1275 return CommonMapValue<const bt_value> {*this};
1278 std::uint64_t length() const noexcept
1280 return bt_value_map_get_size(this->libObjPtr());
1283 bool isEmpty() const noexcept
1285 return this->length() == 0;
1288 bt2s::optional<CommonValue<LibObjT>> operator[](const char * const key) const noexcept
1290 const auto libObjPtr =
1291 internal::CommonMapValueSpec<LibObjT>::entryByKey(this->libObjPtr(), key);
1294 return bt2s::nullopt;
1297 return CommonValue<LibObjT> {libObjPtr};
1300 bt2s::optional<CommonValue<LibObjT>> operator[](const std::string& key) const noexcept
1302 return (*this)[key.data()];
1305 bool hasEntry(const char * const key) const noexcept
1307 return static_cast<bool>(bt_value_map_has_entry(this->libObjPtr(), key));
1310 bool hasEntry(const std::string& key) const noexcept
1312 return this->hasEntry(key.data());
1315 void insert(const char * const key, const Value val) const
1317 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1319 const auto status = bt_value_map_insert_entry(this->libObjPtr(), key, val.libObjPtr());
1321 this->_handleInsertLibStatus(status);
1324 void insert(const std::string& key, const Value val) const
1326 this->insert(key.data(), val);
1329 void insert(const char * const key, const bool rawVal) const
1331 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1334 bt_value_map_insert_bool_entry(this->libObjPtr(), key, static_cast<bt_bool>(rawVal));
1336 this->_handleInsertLibStatus(status);
1339 void insert(const std::string& key, const bool rawVal) const
1341 this->insert(key.data(), rawVal);
1344 void insert(const char * const key, const std::uint64_t rawVal) const
1346 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1349 bt_value_map_insert_unsigned_integer_entry(this->libObjPtr(), key, rawVal);
1351 this->_handleInsertLibStatus(status);
1354 void insert(const std::string& key, const std::uint64_t rawVal) const
1356 this->insert(key.data(), rawVal);
1359 void insert(const char * const key, const std::int64_t rawVal) const
1361 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1364 bt_value_map_insert_signed_integer_entry(this->libObjPtr(), key, rawVal);
1366 this->_handleInsertLibStatus(status);
1369 void insert(const std::string& key, const std::int64_t rawVal) const
1371 this->insert(key.data(), rawVal);
1374 void insert(const char * const key, const double rawVal) const
1376 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1378 const auto status = bt_value_map_insert_real_entry(this->libObjPtr(), key, rawVal);
1380 this->_handleInsertLibStatus(status);
1383 void insert(const std::string& key, const double rawVal) const
1385 this->insert(key.data(), rawVal);
1388 void insert(const char * const key, const char * const rawVal) const
1390 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1392 const auto status = bt_value_map_insert_string_entry(this->libObjPtr(), key, rawVal);
1394 this->_handleInsertLibStatus(status);
1397 void insert(const char * const key, const std::string& rawVal) const
1399 this->insert(key, rawVal.data());
1402 void insert(const std::string& key, const char * const rawVal) const
1404 this->insert(key.data(), rawVal);
1407 void insert(const std::string& key, const std::string& rawVal) const
1409 this->insert(key.data(), rawVal.data());
1412 CommonArrayValue<bt_value> insertEmptyArray(const char *key) const;
1413 CommonArrayValue<bt_value> insertEmptyArray(const std::string& key) const;
1414 CommonMapValue<bt_value> insertEmptyMap(const char *key) const;
1415 CommonMapValue<bt_value> insertEmptyMap(const std::string& key) const;
1417 void forEach(const internal::CommonMapValueForEachUserFunc<CommonValue<LibObjT>>& func) const
1419 internal::CommonMapValueSpec<LibObjT>::forEach(this->libObjPtr(), func);
1422 Shared shared() const noexcept
1424 return Shared::createWithRef(*this);
1428 void _handleInsertLibStatus(const bt_value_map_insert_entry_status status) const
1430 if (status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_MEMORY_ERROR) {
1431 throw MemoryError {};
1436 using MapValue = CommonMapValue<bt_value>;
1437 using ConstMapValue = CommonMapValue<const bt_value>;
1439 namespace internal {
1441 struct MapValueTypeDescr
1443 using Const = ConstMapValue;
1444 using NonConst = MapValue;
1448 struct TypeDescr<MapValue> : public MapValueTypeDescr
1453 struct TypeDescr<ConstMapValue> : public MapValueTypeDescr
1457 } /* namespace internal */
1459 template <typename LibObjT>
1460 ArrayValue CommonValue<LibObjT>::appendEmptyArray() const
1462 return this->asArray().appendEmptyArray();
1465 template <typename LibObjT>
1466 MapValue CommonValue<LibObjT>::appendEmptyMap() const
1468 return this->asArray().appendEmptyMap();
1471 template <typename LibObjT>
1472 ArrayValue CommonValue<LibObjT>::insertEmptyArray(const char * const key) const
1474 return this->asMap().insertEmptyArray(key);
1477 template <typename LibObjT>
1478 ArrayValue CommonValue<LibObjT>::insertEmptyArray(const std::string& key) const
1480 return this->asMap().insertEmptyArray(key);
1483 template <typename LibObjT>
1484 MapValue CommonValue<LibObjT>::insertEmptyMap(const char * const key) const
1486 return this->asMap().insertEmptyMap(key);
1489 template <typename LibObjT>
1490 MapValue CommonValue<LibObjT>::insertEmptyMap(const std::string& key) const
1492 return this->asMap().insertEmptyMap(key);
1495 template <typename LibObjT>
1496 CommonNullValue<LibObjT> CommonValue<LibObjT>::asNull() const noexcept
1498 BT_ASSERT_DBG(this->isNull());
1499 return CommonNullValue<LibObjT> {this->libObjPtr()};
1502 template <typename LibObjT>
1503 CommonBoolValue<LibObjT> CommonValue<LibObjT>::asBool() const noexcept
1505 BT_ASSERT_DBG(this->isBool());
1506 return CommonBoolValue<LibObjT> {this->libObjPtr()};
1509 template <typename LibObjT>
1510 CommonSignedIntegerValue<LibObjT> CommonValue<LibObjT>::asSignedInteger() const noexcept
1512 BT_ASSERT_DBG(this->isSignedInteger());
1513 return CommonSignedIntegerValue<LibObjT> {this->libObjPtr()};
1516 template <typename LibObjT>
1517 CommonUnsignedIntegerValue<LibObjT> CommonValue<LibObjT>::asUnsignedInteger() const noexcept
1519 BT_ASSERT_DBG(this->isUnsignedInteger());
1520 return CommonUnsignedIntegerValue<LibObjT> {this->libObjPtr()};
1523 template <typename LibObjT>
1524 CommonRealValue<LibObjT> CommonValue<LibObjT>::asReal() const noexcept
1526 BT_ASSERT_DBG(this->isReal());
1527 return CommonRealValue<LibObjT> {this->libObjPtr()};
1530 template <typename LibObjT>
1531 CommonStringValue<LibObjT> CommonValue<LibObjT>::asString() const noexcept
1533 BT_ASSERT_DBG(this->isString());
1534 return CommonStringValue<LibObjT> {this->libObjPtr()};
1537 template <typename LibObjT>
1538 CommonArrayValue<LibObjT> CommonValue<LibObjT>::asArray() const noexcept
1540 BT_ASSERT_DBG(this->isArray());
1541 return CommonArrayValue<LibObjT> {this->libObjPtr()};
1544 template <typename LibObjT>
1545 CommonMapValue<LibObjT> CommonValue<LibObjT>::asMap() const noexcept
1547 BT_ASSERT_DBG(this->isMap());
1548 return CommonMapValue<LibObjT> {this->libObjPtr()};
1551 template <typename LibObjT>
1552 ArrayValue CommonArrayValue<LibObjT>::appendEmptyArray() const
1554 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
1556 bt_value *libElemPtr;
1557 const auto status = bt_value_array_append_empty_array_element(this->libObjPtr(), &libElemPtr);
1559 this->_handleAppendLibStatus(status);
1560 return ArrayValue {libElemPtr};
1563 template <typename LibObjT>
1564 MapValue CommonArrayValue<LibObjT>::appendEmptyMap() const
1566 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
1568 bt_value *libElemPtr;
1569 const auto status = bt_value_array_append_empty_map_element(this->libObjPtr(), &libElemPtr);
1571 this->_handleAppendLibStatus(status);
1572 return MapValue {libElemPtr};
1575 template <typename LibObjT>
1576 ArrayValue CommonMapValue<LibObjT>::insertEmptyArray(const char * const key) const
1578 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1580 bt_value *libEntryPtr;
1581 const auto status = bt_value_map_insert_empty_array_entry(this->libObjPtr(), key, &libEntryPtr);
1583 this->_handleInsertLibStatus(status);
1584 return ArrayValue {libEntryPtr};
1587 template <typename LibObjT>
1588 ArrayValue CommonMapValue<LibObjT>::insertEmptyArray(const std::string& key) const
1590 return this->insertEmptyArray(key.data());
1593 template <typename LibObjT>
1594 MapValue CommonMapValue<LibObjT>::insertEmptyMap(const char * const key) const
1596 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1598 bt_value *libEntryPtr;
1599 const auto status = bt_value_map_insert_empty_map_entry(this->libObjPtr(), key, &libEntryPtr);
1601 this->_handleInsertLibStatus(status);
1602 return MapValue {libEntryPtr};
1605 template <typename LibObjT>
1606 MapValue CommonMapValue<LibObjT>::insertEmptyMap(const std::string& key) const
1608 return this->insertEmptyMap(key.data());
1611 inline BoolValue::Shared createValue(const bool rawVal)
1613 return BoolValue::create(rawVal);
1616 inline UnsignedIntegerValue::Shared createValue(const std::uint64_t rawVal)
1618 return UnsignedIntegerValue::create(rawVal);
1621 inline SignedIntegerValue::Shared createValue(const std::int64_t rawVal)
1623 return SignedIntegerValue::create(rawVal);
1626 inline RealValue::Shared createValue(const double rawVal)
1628 return RealValue::create(rawVal);
1631 inline StringValue::Shared createValue(const char * const rawVal)
1633 return StringValue::create(rawVal);
1636 inline StringValue::Shared createValue(const std::string& rawVal)
1638 return StringValue::create(rawVal);
1641 } /* namespace bt2 */
1643 #endif /* BABELTRACE_CPP_COMMON_BT2_VALUE_HPP */