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/bt2c/c-string-view.hpp"
20 #include "borrowed-object-iterator.hpp"
21 #include "borrowed-object.hpp"
23 #include "internal/utils.hpp"
24 #include "optional-borrowed-object.hpp"
25 #include "raw-value-proxy.hpp"
26 #include "shared-object.hpp"
31 struct ValueRefFuncs final
33 static void get(const bt_value * const libObjPtr) noexcept
35 bt_value_get_ref(libObjPtr);
38 static void put(const bt_value * const libObjPtr) noexcept
40 bt_value_put_ref(libObjPtr);
44 } /* namespace internal */
46 template <typename ObjT, typename LibObjT>
47 using SharedValue = SharedObject<ObjT, LibObjT, internal::ValueRefFuncs>;
49 template <typename LibObjT>
50 class CommonNullValue;
52 template <typename LibObjT>
53 class CommonBoolValue;
55 template <typename LibObjT>
56 class CommonUnsignedIntegerValue;
58 template <typename LibObjT>
59 class CommonSignedIntegerValue;
61 template <typename LibObjT>
62 class CommonRealValue;
64 template <typename LibObjT>
65 class CommonStringValue;
67 template <typename LibObjT>
68 class CommonArrayValue;
70 template <typename LibObjT>
75 NUL = BT_VALUE_TYPE_NULL,
76 BOOL = BT_VALUE_TYPE_BOOL,
77 UNSIGNED_INTEGER = BT_VALUE_TYPE_UNSIGNED_INTEGER,
78 SIGNED_INTEGER = BT_VALUE_TYPE_SIGNED_INTEGER,
79 REAL = BT_VALUE_TYPE_REAL,
80 STRING = BT_VALUE_TYPE_STRING,
81 ARRAY = BT_VALUE_TYPE_ARRAY,
82 MAP = BT_VALUE_TYPE_MAP,
85 template <typename ValueObjT>
86 class CommonValueRawValueProxy final
89 explicit CommonValueRawValueProxy(const ValueObjT obj) : _mObj {obj}
93 CommonValueRawValueProxy& operator=(bool rawVal) noexcept;
94 CommonValueRawValueProxy& operator=(std::int64_t rawVal) noexcept;
95 CommonValueRawValueProxy& operator=(std::uint64_t rawVal) noexcept;
96 CommonValueRawValueProxy& operator=(double rawVal) noexcept;
97 CommonValueRawValueProxy& operator=(const char *rawVal);
98 CommonValueRawValueProxy& operator=(const std::string& rawVal);
99 operator bool() const noexcept;
100 operator std::int64_t() const noexcept;
101 operator std::uint64_t() const noexcept;
102 operator double() const noexcept;
103 operator const char *() const noexcept;
104 operator bt2c::CStringView() const noexcept;
110 template <typename LibObjT>
111 class CommonValue : public BorrowedObject<LibObjT>
114 using typename BorrowedObject<LibObjT>::_ThisBorrowedObject;
117 using _ThisCommonValue = CommonValue<LibObjT>;
120 using typename BorrowedObject<LibObjT>::LibObjPtr;
121 using Shared = SharedValue<CommonValue<LibObjT>, LibObjT>;
123 explicit CommonValue(const LibObjPtr libObjPtr) noexcept : _ThisBorrowedObject {libObjPtr}
127 template <typename OtherLibObjT>
128 CommonValue(const CommonValue<OtherLibObjT> val) noexcept : _ThisBorrowedObject {val}
132 template <typename OtherLibObjT>
133 _ThisCommonValue operator=(const CommonValue<OtherLibObjT> val) noexcept
135 _ThisBorrowedObject::operator=(val);
139 CommonValue<const bt_value> asConst() const noexcept
141 return CommonValue<const bt_value> {*this};
144 ValueType type() const noexcept
146 return static_cast<ValueType>(bt_value_get_type(this->libObjPtr()));
149 bool isNull() const noexcept
151 return this->_libTypeIs(BT_VALUE_TYPE_NULL);
154 bool isBool() const noexcept
156 return this->_libTypeIs(BT_VALUE_TYPE_BOOL);
159 bool isInteger() const noexcept
161 return this->_libTypeIs(BT_VALUE_TYPE_INTEGER);
164 bool isUnsignedInteger() const noexcept
166 return this->_libTypeIs(BT_VALUE_TYPE_UNSIGNED_INTEGER);
169 bool isSignedInteger() const noexcept
171 return this->_libTypeIs(BT_VALUE_TYPE_SIGNED_INTEGER);
174 bool isReal() const noexcept
176 return this->_libTypeIs(BT_VALUE_TYPE_REAL);
179 bool isString() const noexcept
181 return this->_libTypeIs(BT_VALUE_TYPE_STRING);
184 bool isArray() const noexcept
186 return this->_libTypeIs(BT_VALUE_TYPE_ARRAY);
189 bool isMap() const noexcept
191 return this->_libTypeIs(BT_VALUE_TYPE_MAP);
194 template <typename OtherLibObjT>
195 bool operator==(const CommonValue<OtherLibObjT> other) const noexcept
197 return static_cast<bool>(bt_value_is_equal(this->libObjPtr(), other.libObjPtr()));
200 template <typename OtherLibObjT>
201 bool operator!=(const CommonValue<OtherLibObjT> other) const noexcept
203 return !(*this == other);
206 CommonValueRawValueProxy<CommonValue> operator*() const noexcept
208 return CommonValueRawValueProxy<CommonValue> {*this};
211 std::uint64_t arrayLength() const noexcept
213 return this->asArray().length();
216 bool arrayIsEmpty() const noexcept
218 return this->asArray().isEmpty();
221 CommonValue<LibObjT> operator[](const std::uint64_t index) const noexcept
223 return this->asArray()[index];
226 template <typename T>
227 void append(T&& elem) const
229 this->asArray().append(std::forward<T>(elem));
232 CommonArrayValue<bt_value> appendEmptyArray() const;
233 CommonMapValue<bt_value> appendEmptyMap() const;
235 std::uint64_t mapLength() const noexcept
237 return this->asMap().length();
240 bool mapIsEmpty() const noexcept
242 return this->asMap().isEmpty();
245 template <typename KeyT>
246 OptionalBorrowedObject<CommonValue<LibObjT>> operator[](KeyT&& key) const noexcept
248 return this->asMap()[std::forward<KeyT>(key)];
251 template <typename KeyT>
252 bool hasEntry(KeyT&& key) const noexcept
254 return this->asMap().hasEntry(std::forward<KeyT>(key));
257 template <typename KeyT, typename ValT>
258 void insert(KeyT&& key, ValT&& val) const
260 this->asMap().insert(std::forward<KeyT>(key), std::forward<ValT>(val));
263 CommonArrayValue<bt_value> insertEmptyArray(const char *key) const;
264 CommonArrayValue<bt_value> insertEmptyArray(const std::string& key) const;
265 CommonMapValue<bt_value> insertEmptyMap(const char *key) const;
266 CommonMapValue<bt_value> insertEmptyMap(const std::string& key) const;
268 Shared shared() const noexcept
270 return Shared::createWithRef(*this);
273 template <typename ValueT>
274 ValueT as() const noexcept
276 return ValueT {this->libObjPtr()};
279 CommonNullValue<LibObjT> asNull() const noexcept;
280 CommonBoolValue<LibObjT> asBool() const noexcept;
281 CommonSignedIntegerValue<LibObjT> asSignedInteger() const noexcept;
282 CommonUnsignedIntegerValue<LibObjT> asUnsignedInteger() const noexcept;
283 CommonRealValue<LibObjT> asReal() const noexcept;
284 CommonStringValue<LibObjT> asString() const noexcept;
285 CommonArrayValue<LibObjT> asArray() const noexcept;
286 CommonMapValue<LibObjT> asMap() const noexcept;
289 bool _libTypeIs(const bt_value_type type) const noexcept
291 return bt_value_type_is(bt_value_get_type(this->libObjPtr()), type);
295 using Value = CommonValue<bt_value>;
296 using ConstValue = CommonValue<const bt_value>;
298 template <typename ValueObjT>
299 CommonValueRawValueProxy<ValueObjT>&
300 CommonValueRawValueProxy<ValueObjT>::operator=(const bool rawVal) noexcept
302 _mObj.asBool().value(rawVal);
306 template <typename ValueObjT>
307 CommonValueRawValueProxy<ValueObjT>&
308 CommonValueRawValueProxy<ValueObjT>::operator=(const std::int64_t rawVal) noexcept
310 _mObj.asSignedInteger().value(rawVal);
314 template <typename ValueObjT>
315 CommonValueRawValueProxy<ValueObjT>&
316 CommonValueRawValueProxy<ValueObjT>::operator=(const std::uint64_t rawVal) noexcept
318 _mObj.asUnsignedInteger().value(rawVal);
322 template <typename ValueObjT>
323 CommonValueRawValueProxy<ValueObjT>&
324 CommonValueRawValueProxy<ValueObjT>::operator=(const double rawVal) noexcept
326 _mObj.asReal().value(rawVal);
330 template <typename ValueObjT>
331 CommonValueRawValueProxy<ValueObjT>&
332 CommonValueRawValueProxy<ValueObjT>::operator=(const char * const rawVal)
334 _mObj.asString().value(rawVal);
338 template <typename ValueObjT>
339 CommonValueRawValueProxy<ValueObjT>&
340 CommonValueRawValueProxy<ValueObjT>::operator=(const std::string& rawVal)
342 _mObj.asString().value(rawVal);
346 template <typename ValueObjT>
347 CommonValueRawValueProxy<ValueObjT>::operator bool() const noexcept
349 return _mObj.asBool().value();
352 template <typename ValueObjT>
353 CommonValueRawValueProxy<ValueObjT>::operator std::int64_t() const noexcept
355 return _mObj.asSignedInteger().value();
358 template <typename ValueObjT>
359 CommonValueRawValueProxy<ValueObjT>::operator std::uint64_t() const noexcept
361 return _mObj.asUnsignedInteger().value();
364 template <typename ValueObjT>
365 CommonValueRawValueProxy<ValueObjT>::operator double() const noexcept
367 return _mObj.asReal().value();
370 template <typename ValueObjT>
371 CommonValueRawValueProxy<ValueObjT>::operator const char *() const noexcept
373 return _mObj.asString().value();
376 template <typename ValueObjT>
377 CommonValueRawValueProxy<ValueObjT>::operator bt2c::CStringView() const noexcept
379 return _mObj.asString().value();
384 struct ValueTypeDescr
386 using Const = ConstValue;
387 using NonConst = Value;
391 struct TypeDescr<Value> : public ValueTypeDescr
396 struct TypeDescr<ConstValue> : public ValueTypeDescr
400 } /* namespace internal */
402 template <typename LibObjT>
403 class CommonNullValue final : public CommonValue<LibObjT>
406 using typename CommonValue<LibObjT>::_ThisCommonValue;
409 using Shared = SharedValue<CommonNullValue<LibObjT>, LibObjT>;
411 CommonNullValue() noexcept : _ThisCommonValue {bt_value_null}
415 template <typename OtherLibObjT>
416 CommonNullValue(const CommonNullValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
420 template <typename OtherLibObjT>
421 CommonNullValue<LibObjT> operator=(const CommonNullValue<OtherLibObjT> val) noexcept
423 _ThisCommonValue::operator=(val);
427 CommonNullValue<const bt_value> asConst() const noexcept
429 return CommonNullValue<const bt_value> {*this};
432 Shared shared() const noexcept
434 return Shared::createWithRef(*this);
438 using NullValue = CommonNullValue<bt_value>;
439 using ConstNullValue = CommonNullValue<const bt_value>;
443 struct NullValueTypeDescr
445 using Const = ConstNullValue;
446 using NonConst = NullValue;
450 struct TypeDescr<NullValue> : public NullValueTypeDescr
455 struct TypeDescr<ConstNullValue> : public NullValueTypeDescr
459 } /* namespace internal */
461 template <typename LibObjT>
462 class CommonBoolValue final : public CommonValue<LibObjT>
465 using typename CommonValue<LibObjT>::_ThisCommonValue;
468 using typename CommonValue<LibObjT>::LibObjPtr;
469 using Shared = SharedValue<CommonBoolValue<LibObjT>, LibObjT>;
472 explicit CommonBoolValue(const LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
474 BT_ASSERT_DBG(this->isBool());
477 template <typename OtherLibObjT>
478 CommonBoolValue(const CommonBoolValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
482 static Shared create(const Value rawVal = false)
484 const auto libObjPtr = bt_value_bool_create_init(static_cast<bt_bool>(rawVal));
486 internal::validateCreatedObjPtr(libObjPtr);
487 return CommonBoolValue::Shared::createWithoutRef(libObjPtr);
490 template <typename OtherLibObjT>
491 CommonBoolValue<LibObjT> operator=(const CommonBoolValue<OtherLibObjT> val) noexcept
493 _ThisCommonValue::operator=(val);
497 CommonBoolValue<const bt_value> asConst() const noexcept
499 return CommonBoolValue<const bt_value> {*this};
502 RawValueProxy<CommonBoolValue> operator*() const noexcept
504 return RawValueProxy<CommonBoolValue> {*this};
507 Value value() const noexcept
509 return static_cast<Value>(bt_value_bool_get(this->libObjPtr()));
512 void value(const Value val) const noexcept
514 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstBoolValue`.");
516 bt_value_bool_set(this->libObjPtr(), static_cast<bt_bool>(val));
519 Shared shared() const noexcept
521 return Shared::createWithRef(*this);
525 using BoolValue = CommonBoolValue<bt_value>;
526 using ConstBoolValue = CommonBoolValue<const bt_value>;
530 struct BoolValueTypeDescr
532 using Const = ConstBoolValue;
533 using NonConst = BoolValue;
537 struct TypeDescr<BoolValue> : public BoolValueTypeDescr
542 struct TypeDescr<ConstBoolValue> : public BoolValueTypeDescr
546 } /* namespace internal */
548 template <typename LibObjT>
549 class CommonUnsignedIntegerValue final : public CommonValue<LibObjT>
552 using typename CommonValue<LibObjT>::_ThisCommonValue;
555 using typename CommonValue<LibObjT>::LibObjPtr;
556 using Shared = SharedValue<CommonUnsignedIntegerValue<LibObjT>, LibObjT>;
557 using Value = std::uint64_t;
559 explicit CommonUnsignedIntegerValue(const LibObjPtr libObjPtr) noexcept :
560 _ThisCommonValue {libObjPtr}
562 BT_ASSERT_DBG(this->isUnsignedInteger());
565 static Shared create(const Value rawVal = 0)
567 const auto libObjPtr = bt_value_integer_unsigned_create_init(rawVal);
569 internal::validateCreatedObjPtr(libObjPtr);
570 return CommonUnsignedIntegerValue::Shared::createWithoutRef(libObjPtr);
573 template <typename OtherLibObjT>
574 CommonUnsignedIntegerValue(const CommonUnsignedIntegerValue<OtherLibObjT> val) noexcept :
575 _ThisCommonValue {val}
579 template <typename OtherLibObjT>
580 CommonUnsignedIntegerValue<LibObjT>
581 operator=(const CommonUnsignedIntegerValue<OtherLibObjT> val) noexcept
583 _ThisCommonValue::operator=(val);
587 CommonUnsignedIntegerValue<const bt_value> asConst() const noexcept
589 return CommonUnsignedIntegerValue<const bt_value> {*this};
592 RawValueProxy<CommonUnsignedIntegerValue> operator*() const noexcept
594 return RawValueProxy<CommonUnsignedIntegerValue> {*this};
597 void value(const Value val) const noexcept
599 static_assert(!std::is_const<LibObjT>::value,
600 "Not available with `bt2::ConstUnsignedIntegerValue`.");
602 bt_value_integer_unsigned_set(this->libObjPtr(), val);
605 Value value() const noexcept
607 return bt_value_integer_unsigned_get(this->libObjPtr());
610 Shared shared() const noexcept
612 return Shared::createWithRef(*this);
616 using UnsignedIntegerValue = CommonUnsignedIntegerValue<bt_value>;
617 using ConstUnsignedIntegerValue = CommonUnsignedIntegerValue<const bt_value>;
621 struct UnsignedIntegerValueTypeDescr
623 using Const = ConstUnsignedIntegerValue;
624 using NonConst = UnsignedIntegerValue;
628 struct TypeDescr<UnsignedIntegerValue> : public UnsignedIntegerValueTypeDescr
633 struct TypeDescr<ConstUnsignedIntegerValue> : public UnsignedIntegerValueTypeDescr
637 } /* namespace internal */
639 template <typename LibObjT>
640 class CommonSignedIntegerValue final : public CommonValue<LibObjT>
643 using typename CommonValue<LibObjT>::_ThisCommonValue;
646 using typename CommonValue<LibObjT>::LibObjPtr;
647 using Shared = SharedValue<CommonSignedIntegerValue<LibObjT>, LibObjT>;
648 using Value = std::int64_t;
650 explicit CommonSignedIntegerValue(const LibObjPtr libObjPtr) noexcept :
651 _ThisCommonValue {libObjPtr}
653 BT_ASSERT_DBG(this->isSignedInteger());
656 static Shared create(const Value rawVal = 0)
658 const auto libObjPtr = bt_value_integer_signed_create_init(rawVal);
660 internal::validateCreatedObjPtr(libObjPtr);
661 return CommonSignedIntegerValue::Shared::createWithoutRef(libObjPtr);
664 template <typename OtherLibObjT>
665 CommonSignedIntegerValue(const CommonSignedIntegerValue<OtherLibObjT> val) noexcept :
666 _ThisCommonValue {val}
670 template <typename OtherLibObjT>
671 CommonSignedIntegerValue<LibObjT>
672 operator=(const CommonSignedIntegerValue<OtherLibObjT> val) noexcept
674 _ThisCommonValue::operator=(val);
678 CommonSignedIntegerValue<const bt_value> asConst() const noexcept
680 return CommonSignedIntegerValue<const bt_value> {*this};
683 RawValueProxy<CommonSignedIntegerValue> operator*() const noexcept
685 return RawValueProxy<CommonSignedIntegerValue> {*this};
688 void value(const Value val) const noexcept
690 static_assert(!std::is_const<LibObjT>::value,
691 "Not available with `bt2::ConstSignedIntegerValue`.");
693 bt_value_integer_signed_set(this->libObjPtr(), val);
696 Value value() const noexcept
698 return bt_value_integer_signed_get(this->libObjPtr());
701 Shared shared() const noexcept
703 return Shared::createWithRef(*this);
707 using SignedIntegerValue = CommonSignedIntegerValue<bt_value>;
708 using ConstSignedIntegerValue = CommonSignedIntegerValue<const bt_value>;
712 struct SignedIntegerValueTypeDescr
714 using Const = ConstSignedIntegerValue;
715 using NonConst = SignedIntegerValue;
719 struct TypeDescr<SignedIntegerValue> : public SignedIntegerValueTypeDescr
724 struct TypeDescr<ConstSignedIntegerValue> : public SignedIntegerValueTypeDescr
728 } /* namespace internal */
730 template <typename LibObjT>
731 class CommonRealValue final : public CommonValue<LibObjT>
734 using typename CommonValue<LibObjT>::_ThisCommonValue;
737 using typename CommonValue<LibObjT>::LibObjPtr;
738 using Shared = SharedValue<CommonRealValue<LibObjT>, LibObjT>;
739 using Value = double;
741 explicit CommonRealValue(const LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
743 BT_ASSERT_DBG(this->isReal());
746 static Shared create(const Value rawVal = 0)
748 const auto libObjPtr = bt_value_real_create_init(rawVal);
750 internal::validateCreatedObjPtr(libObjPtr);
751 return CommonRealValue::Shared::createWithoutRef(libObjPtr);
754 template <typename OtherLibObjT>
755 CommonRealValue(const CommonRealValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
759 template <typename OtherLibObjT>
760 CommonRealValue<LibObjT> operator=(const CommonRealValue<OtherLibObjT> val) noexcept
762 _ThisCommonValue::operator=(val);
766 CommonRealValue<const bt_value> asConst() const noexcept
768 return CommonRealValue<const bt_value> {*this};
771 RawValueProxy<CommonRealValue> operator*() const noexcept
773 return RawValueProxy<CommonRealValue> {*this};
776 void value(const Value val) const noexcept
778 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstRealValue`.");
780 bt_value_real_set(this->libObjPtr(), val);
783 Value value() const noexcept
785 return bt_value_real_get(this->libObjPtr());
788 Shared shared() const noexcept
790 return Shared::createWithRef(*this);
794 using RealValue = CommonRealValue<bt_value>;
795 using ConstRealValue = CommonRealValue<const bt_value>;
799 struct RealValueTypeDescr
801 using Const = ConstRealValue;
802 using NonConst = RealValue;
806 struct TypeDescr<RealValue> : public RealValueTypeDescr
811 struct TypeDescr<ConstRealValue> : public RealValueTypeDescr
815 } /* namespace internal */
817 template <typename LibObjT>
818 class CommonStringValue final : public CommonValue<LibObjT>
821 using typename CommonValue<LibObjT>::_ThisCommonValue;
824 using typename CommonValue<LibObjT>::LibObjPtr;
825 using Shared = SharedValue<CommonStringValue<LibObjT>, LibObjT>;
826 using Value = bt2c::CStringView;
828 explicit CommonStringValue(const LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
830 BT_ASSERT_DBG(this->isString());
833 static Shared create(const char * const rawVal = "")
835 const auto libObjPtr = bt_value_string_create_init(rawVal);
837 internal::validateCreatedObjPtr(libObjPtr);
838 return CommonStringValue::Shared::createWithoutRef(libObjPtr);
841 static Shared create(const std::string& rawVal)
843 return CommonStringValue::create(rawVal.data());
846 template <typename OtherLibObjT>
847 CommonStringValue(const CommonStringValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
851 template <typename OtherLibObjT>
852 CommonStringValue<LibObjT> operator=(const CommonStringValue<OtherLibObjT> val) noexcept
854 _ThisCommonValue::operator=(val);
858 CommonStringValue<const bt_value> asConst() const noexcept
860 return CommonStringValue<const bt_value> {*this};
863 RawStringValueProxy<CommonStringValue> operator*() const noexcept
865 return RawStringValueProxy<CommonStringValue> {*this};
868 void value(const Value val) const
870 static_assert(!std::is_const<LibObjT>::value,
871 "Not available with `bt2::ConstStringValue`.");
873 const auto status = bt_value_string_set(this->libObjPtr(), *val);
875 if (status == BT_VALUE_STRING_SET_STATUS_MEMORY_ERROR) {
876 throw MemoryError {};
880 void value(const char * const val) const
882 this->value(bt2c::CStringView {val});
885 void value(const std::string& val) const
887 this->value(bt2c::CStringView {val.data()});
890 Value value() const noexcept
892 return bt_value_string_get(this->libObjPtr());
895 Shared shared() const noexcept
897 return Shared::createWithRef(*this);
901 using StringValue = CommonStringValue<bt_value>;
902 using ConstStringValue = CommonStringValue<const bt_value>;
906 struct StringValueTypeDescr
908 using Const = ConstStringValue;
909 using NonConst = StringValue;
913 struct TypeDescr<StringValue> : public StringValueTypeDescr
918 struct TypeDescr<ConstStringValue> : public StringValueTypeDescr
922 template <typename LibObjT>
923 struct CommonArrayValueSpec;
925 /* Functions specific to mutable array values */
927 struct CommonArrayValueSpec<bt_value> final
929 static bt_value *elementByIndex(bt_value * const libValPtr, const std::uint64_t index) noexcept
931 return bt_value_array_borrow_element_by_index(libValPtr, index);
935 /* Functions specific to constant array values */
937 struct CommonArrayValueSpec<const bt_value> final
939 static const bt_value *elementByIndex(const bt_value * const libValPtr,
940 const std::uint64_t index) noexcept
942 return bt_value_array_borrow_element_by_index_const(libValPtr, index);
946 } /* namespace internal */
948 template <typename LibObjT>
949 class CommonArrayValue final : public CommonValue<LibObjT>
952 using typename CommonValue<LibObjT>::_ThisCommonValue;
955 using typename CommonValue<LibObjT>::LibObjPtr;
956 using Shared = SharedValue<CommonArrayValue<LibObjT>, LibObjT>;
957 using Iterator = BorrowedObjectIterator<CommonArrayValue<LibObjT>>;
959 explicit CommonArrayValue(const LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
961 BT_ASSERT_DBG(this->isArray());
964 static Shared create()
966 const auto libObjPtr = bt_value_array_create();
968 internal::validateCreatedObjPtr(libObjPtr);
969 return CommonArrayValue::Shared::createWithoutRef(libObjPtr);
972 template <typename OtherLibObjT>
973 CommonArrayValue(const CommonArrayValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
977 template <typename OtherLibObjT>
978 CommonArrayValue<LibObjT> operator=(const CommonArrayValue<OtherLibObjT> val) noexcept
980 _ThisCommonValue::operator=(val);
984 CommonArrayValue<const bt_value> asConst() const noexcept
986 return CommonArrayValue<const bt_value> {*this};
989 std::uint64_t length() const noexcept
991 return bt_value_array_get_length(this->libObjPtr());
994 Iterator begin() const noexcept
996 return Iterator {*this, 0};
999 Iterator end() const noexcept
1001 return Iterator {*this, this->length()};
1004 bool isEmpty() const noexcept
1006 return this->length() == 0;
1009 CommonValue<LibObjT> operator[](const std::uint64_t index) const noexcept
1011 return CommonValue<LibObjT> {
1012 internal::CommonArrayValueSpec<LibObjT>::elementByIndex(this->libObjPtr(), index)};
1015 void append(const Value val) const
1017 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
1019 const auto status = bt_value_array_append_element(this->libObjPtr(), val.libObjPtr());
1021 this->_handleAppendLibStatus(status);
1024 void append(const bool rawVal) const
1026 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
1029 bt_value_array_append_bool_element(this->libObjPtr(), static_cast<bt_bool>(rawVal));
1031 this->_handleAppendLibStatus(status);
1034 void append(const std::uint64_t rawVal) const
1036 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
1039 bt_value_array_append_unsigned_integer_element(this->libObjPtr(), rawVal);
1041 this->_handleAppendLibStatus(status);
1044 void append(const std::int64_t rawVal) const
1046 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
1048 const auto status = bt_value_array_append_signed_integer_element(this->libObjPtr(), rawVal);
1050 this->_handleAppendLibStatus(status);
1053 void append(const double rawVal) const
1055 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
1057 const auto status = bt_value_array_append_real_element(this->libObjPtr(), rawVal);
1059 this->_handleAppendLibStatus(status);
1062 void append(const char * const rawVal) const
1064 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
1066 const auto status = bt_value_array_append_string_element(this->libObjPtr(), rawVal);
1068 this->_handleAppendLibStatus(status);
1071 void append(const std::string& rawVal) const
1073 this->append(rawVal.data());
1076 CommonArrayValue<bt_value> appendEmptyArray() const;
1077 CommonMapValue<bt_value> appendEmptyMap() const;
1079 void operator+=(const Value val) const
1084 void operator+=(const bool rawVal) const
1086 this->append(rawVal);
1089 void operator+=(const std::uint64_t rawVal) const
1091 this->append(rawVal);
1094 void operator+=(const std::int64_t rawVal) const
1096 this->append(rawVal);
1099 void operator+=(const double rawVal) const
1101 this->append(rawVal);
1104 void operator+=(const char * const rawVal) const
1106 this->append(rawVal);
1109 void operator+=(const std::string& rawVal) const
1111 this->append(rawVal);
1114 Shared shared() const noexcept
1116 return Shared::createWithRef(*this);
1120 void _handleAppendLibStatus(const bt_value_array_append_element_status status) const
1122 if (status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_MEMORY_ERROR) {
1123 throw MemoryError {};
1128 using ArrayValue = CommonArrayValue<bt_value>;
1129 using ConstArrayValue = CommonArrayValue<const bt_value>;
1131 namespace internal {
1133 struct ArrayValueTypeDescr
1135 using Const = ConstArrayValue;
1136 using NonConst = ArrayValue;
1140 struct TypeDescr<ArrayValue> : public ArrayValueTypeDescr
1145 struct TypeDescr<ConstArrayValue> : public ArrayValueTypeDescr
1150 * Type of a user function passed to `CommonMapValue<ObjT>::forEach()`.
1152 * First argument is the entry's key, second is its value.
1154 template <typename ObjT>
1155 using CommonMapValueForEachUserFunc = std::function<void(bt2c::CStringView, ObjT)>;
1158 * Template of a function to be passed to bt_value_map_foreach_entry()
1159 * for bt_value_map_foreach_entry_const() which calls a user function.
1161 * `userData` is casted to a `const` pointer to
1162 * `CommonMapValueForEachUserFunc<ObjT>` (the user function to call).
1164 * This function catches any exception which the user function throws
1165 * and returns the `ErrorStatus` value. If there's no exception, this
1166 * function returns the `OkStatus` value.
1168 template <typename ObjT, typename LibObjT, typename LibStatusT, int OkStatus, int ErrorStatus>
1169 LibStatusT mapValueForEachLibFunc(const char * const key, LibObjT * const libObjPtr,
1170 void * const userData)
1172 const auto& userFunc = *reinterpret_cast<const CommonMapValueForEachUserFunc<ObjT> *>(userData);
1175 userFunc(key, ObjT {libObjPtr});
1177 return static_cast<LibStatusT>(ErrorStatus);
1180 return static_cast<LibStatusT>(OkStatus);
1183 template <typename LibObjT>
1184 struct CommonMapValueSpec;
1186 /* Functions specific to mutable map values */
1188 struct CommonMapValueSpec<bt_value> final
1190 static bt_value *entryByKey(bt_value * const libValPtr, const char * const key) noexcept
1192 return bt_value_map_borrow_entry_value(libValPtr, key);
1195 static void forEach(bt_value * const libValPtr,
1196 const CommonMapValueForEachUserFunc<Value>& func)
1198 const auto status = bt_value_map_foreach_entry(
1200 mapValueForEachLibFunc<Value, bt_value, bt_value_map_foreach_entry_func_status,
1201 BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_OK,
1202 BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_ERROR>,
1203 const_cast<void *>(reinterpret_cast<const void *>(&func)));
1206 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_OK:
1208 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_USER_ERROR:
1209 case BT_VALUE_MAP_FOREACH_ENTRY_STATUS_ERROR:
1217 /* Functions specific to constant map values */
1219 struct CommonMapValueSpec<const bt_value> final
1221 static const bt_value *entryByKey(const bt_value * const libValPtr,
1222 const char * const key) noexcept
1224 return bt_value_map_borrow_entry_value_const(libValPtr, key);
1227 static void forEach(const bt_value * const libValPtr,
1228 const CommonMapValueForEachUserFunc<ConstValue>& func)
1230 const auto status = bt_value_map_foreach_entry_const(
1232 mapValueForEachLibFunc<ConstValue, const bt_value,
1233 bt_value_map_foreach_entry_const_func_status,
1234 BT_VALUE_MAP_FOREACH_ENTRY_CONST_FUNC_STATUS_OK,
1235 BT_VALUE_MAP_FOREACH_ENTRY_CONST_FUNC_STATUS_ERROR>,
1236 const_cast<void *>(reinterpret_cast<const void *>(&func)));
1239 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_OK:
1241 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_USER_ERROR:
1242 case BT_VALUE_MAP_FOREACH_ENTRY_CONST_STATUS_ERROR:
1250 } /* namespace internal */
1252 template <typename LibObjT>
1253 class CommonMapValue final : public CommonValue<LibObjT>
1256 using typename CommonValue<LibObjT>::_ThisCommonValue;
1259 using typename CommonValue<LibObjT>::LibObjPtr;
1260 using Shared = SharedValue<CommonMapValue<LibObjT>, LibObjT>;
1262 explicit CommonMapValue(const LibObjPtr libObjPtr) noexcept : _ThisCommonValue {libObjPtr}
1264 BT_ASSERT_DBG(this->isMap());
1267 static Shared create()
1269 const auto libObjPtr = bt_value_map_create();
1271 internal::validateCreatedObjPtr(libObjPtr);
1272 return CommonMapValue::Shared::createWithoutRef(libObjPtr);
1275 template <typename OtherLibObjT>
1276 CommonMapValue(const CommonMapValue<OtherLibObjT> val) noexcept : _ThisCommonValue {val}
1280 template <typename OtherLibObjT>
1281 CommonMapValue<LibObjT> operator=(const CommonMapValue<OtherLibObjT> val) noexcept
1283 _ThisCommonValue::operator=(val);
1287 CommonMapValue<const bt_value> asConst() const noexcept
1289 return CommonMapValue<const bt_value> {*this};
1292 std::uint64_t length() const noexcept
1294 return bt_value_map_get_size(this->libObjPtr());
1297 bool isEmpty() const noexcept
1299 return this->length() == 0;
1302 OptionalBorrowedObject<CommonValue<LibObjT>> operator[](const char * const key) const noexcept
1304 return internal::CommonMapValueSpec<LibObjT>::entryByKey(this->libObjPtr(), key);
1307 OptionalBorrowedObject<CommonValue<LibObjT>> operator[](const std::string& key) const noexcept
1309 return (*this)[key.data()];
1312 bool hasEntry(const char * const key) const noexcept
1314 return static_cast<bool>(bt_value_map_has_entry(this->libObjPtr(), key));
1317 bool hasEntry(const std::string& key) const noexcept
1319 return this->hasEntry(key.data());
1322 void insert(const char * const key, const Value val) const
1324 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1326 const auto status = bt_value_map_insert_entry(this->libObjPtr(), key, val.libObjPtr());
1328 this->_handleInsertLibStatus(status);
1331 void insert(const std::string& key, const Value val) const
1333 this->insert(key.data(), val);
1336 void insert(const char * const key, const bool rawVal) const
1338 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1341 bt_value_map_insert_bool_entry(this->libObjPtr(), key, static_cast<bt_bool>(rawVal));
1343 this->_handleInsertLibStatus(status);
1346 void insert(const std::string& key, const bool rawVal) const
1348 this->insert(key.data(), rawVal);
1351 void insert(const char * const key, const std::uint64_t rawVal) const
1353 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1356 bt_value_map_insert_unsigned_integer_entry(this->libObjPtr(), key, rawVal);
1358 this->_handleInsertLibStatus(status);
1361 void insert(const std::string& key, const std::uint64_t rawVal) const
1363 this->insert(key.data(), rawVal);
1366 void insert(const char * const key, const std::int64_t rawVal) const
1368 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1371 bt_value_map_insert_signed_integer_entry(this->libObjPtr(), key, rawVal);
1373 this->_handleInsertLibStatus(status);
1376 void insert(const std::string& key, const std::int64_t rawVal) const
1378 this->insert(key.data(), rawVal);
1381 void insert(const char * const key, const double rawVal) const
1383 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1385 const auto status = bt_value_map_insert_real_entry(this->libObjPtr(), key, rawVal);
1387 this->_handleInsertLibStatus(status);
1390 void insert(const std::string& key, const double rawVal) const
1392 this->insert(key.data(), rawVal);
1395 void insert(const char * const key, const char * const rawVal) const
1397 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1399 const auto status = bt_value_map_insert_string_entry(this->libObjPtr(), key, rawVal);
1401 this->_handleInsertLibStatus(status);
1404 void insert(const char * const key, const std::string& rawVal) const
1406 this->insert(key, rawVal.data());
1409 void insert(const std::string& key, const char * const rawVal) const
1411 this->insert(key.data(), rawVal);
1414 void insert(const std::string& key, const std::string& rawVal) const
1416 this->insert(key.data(), rawVal.data());
1419 CommonArrayValue<bt_value> insertEmptyArray(const char *key) const;
1420 CommonArrayValue<bt_value> insertEmptyArray(const std::string& key) const;
1421 CommonMapValue<bt_value> insertEmptyMap(const char *key) const;
1422 CommonMapValue<bt_value> insertEmptyMap(const std::string& key) const;
1424 void forEach(const internal::CommonMapValueForEachUserFunc<CommonValue<LibObjT>>& func) const
1426 internal::CommonMapValueSpec<LibObjT>::forEach(this->libObjPtr(), func);
1429 Shared shared() const noexcept
1431 return Shared::createWithRef(*this);
1435 void _handleInsertLibStatus(const bt_value_map_insert_entry_status status) const
1437 if (status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_MEMORY_ERROR) {
1438 throw MemoryError {};
1443 using MapValue = CommonMapValue<bt_value>;
1444 using ConstMapValue = CommonMapValue<const bt_value>;
1446 namespace internal {
1448 struct MapValueTypeDescr
1450 using Const = ConstMapValue;
1451 using NonConst = MapValue;
1455 struct TypeDescr<MapValue> : public MapValueTypeDescr
1460 struct TypeDescr<ConstMapValue> : public MapValueTypeDescr
1464 } /* namespace internal */
1466 template <typename LibObjT>
1467 ArrayValue CommonValue<LibObjT>::appendEmptyArray() const
1469 return this->asArray().appendEmptyArray();
1472 template <typename LibObjT>
1473 MapValue CommonValue<LibObjT>::appendEmptyMap() const
1475 return this->asArray().appendEmptyMap();
1478 template <typename LibObjT>
1479 ArrayValue CommonValue<LibObjT>::insertEmptyArray(const char * const key) const
1481 return this->asMap().insertEmptyArray(key);
1484 template <typename LibObjT>
1485 ArrayValue CommonValue<LibObjT>::insertEmptyArray(const std::string& key) const
1487 return this->asMap().insertEmptyArray(key);
1490 template <typename LibObjT>
1491 MapValue CommonValue<LibObjT>::insertEmptyMap(const char * const key) const
1493 return this->asMap().insertEmptyMap(key);
1496 template <typename LibObjT>
1497 MapValue CommonValue<LibObjT>::insertEmptyMap(const std::string& key) const
1499 return this->asMap().insertEmptyMap(key);
1502 template <typename LibObjT>
1503 CommonNullValue<LibObjT> CommonValue<LibObjT>::asNull() const noexcept
1505 BT_ASSERT_DBG(this->isNull());
1506 return CommonNullValue<LibObjT> {this->libObjPtr()};
1509 template <typename LibObjT>
1510 CommonBoolValue<LibObjT> CommonValue<LibObjT>::asBool() const noexcept
1512 BT_ASSERT_DBG(this->isBool());
1513 return CommonBoolValue<LibObjT> {this->libObjPtr()};
1516 template <typename LibObjT>
1517 CommonSignedIntegerValue<LibObjT> CommonValue<LibObjT>::asSignedInteger() const noexcept
1519 BT_ASSERT_DBG(this->isSignedInteger());
1520 return CommonSignedIntegerValue<LibObjT> {this->libObjPtr()};
1523 template <typename LibObjT>
1524 CommonUnsignedIntegerValue<LibObjT> CommonValue<LibObjT>::asUnsignedInteger() const noexcept
1526 BT_ASSERT_DBG(this->isUnsignedInteger());
1527 return CommonUnsignedIntegerValue<LibObjT> {this->libObjPtr()};
1530 template <typename LibObjT>
1531 CommonRealValue<LibObjT> CommonValue<LibObjT>::asReal() const noexcept
1533 BT_ASSERT_DBG(this->isReal());
1534 return CommonRealValue<LibObjT> {this->libObjPtr()};
1537 template <typename LibObjT>
1538 CommonStringValue<LibObjT> CommonValue<LibObjT>::asString() const noexcept
1540 BT_ASSERT_DBG(this->isString());
1541 return CommonStringValue<LibObjT> {this->libObjPtr()};
1544 template <typename LibObjT>
1545 CommonArrayValue<LibObjT> CommonValue<LibObjT>::asArray() const noexcept
1547 BT_ASSERT_DBG(this->isArray());
1548 return CommonArrayValue<LibObjT> {this->libObjPtr()};
1551 template <typename LibObjT>
1552 CommonMapValue<LibObjT> CommonValue<LibObjT>::asMap() const noexcept
1554 BT_ASSERT_DBG(this->isMap());
1555 return CommonMapValue<LibObjT> {this->libObjPtr()};
1558 template <typename LibObjT>
1559 ArrayValue CommonArrayValue<LibObjT>::appendEmptyArray() const
1561 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
1563 bt_value *libElemPtr;
1564 const auto status = bt_value_array_append_empty_array_element(this->libObjPtr(), &libElemPtr);
1566 this->_handleAppendLibStatus(status);
1567 return ArrayValue {libElemPtr};
1570 template <typename LibObjT>
1571 MapValue CommonArrayValue<LibObjT>::appendEmptyMap() const
1573 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstArrayValue`.");
1575 bt_value *libElemPtr;
1576 const auto status = bt_value_array_append_empty_map_element(this->libObjPtr(), &libElemPtr);
1578 this->_handleAppendLibStatus(status);
1579 return MapValue {libElemPtr};
1582 template <typename LibObjT>
1583 ArrayValue CommonMapValue<LibObjT>::insertEmptyArray(const char * const key) const
1585 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1587 bt_value *libEntryPtr;
1588 const auto status = bt_value_map_insert_empty_array_entry(this->libObjPtr(), key, &libEntryPtr);
1590 this->_handleInsertLibStatus(status);
1591 return ArrayValue {libEntryPtr};
1594 template <typename LibObjT>
1595 ArrayValue CommonMapValue<LibObjT>::insertEmptyArray(const std::string& key) const
1597 return this->insertEmptyArray(key.data());
1600 template <typename LibObjT>
1601 MapValue CommonMapValue<LibObjT>::insertEmptyMap(const char * const key) const
1603 static_assert(!std::is_const<LibObjT>::value, "Not available with `bt2::ConstMapValue`.");
1605 bt_value *libEntryPtr;
1606 const auto status = bt_value_map_insert_empty_map_entry(this->libObjPtr(), key, &libEntryPtr);
1608 this->_handleInsertLibStatus(status);
1609 return MapValue {libEntryPtr};
1612 template <typename LibObjT>
1613 MapValue CommonMapValue<LibObjT>::insertEmptyMap(const std::string& key) const
1615 return this->insertEmptyMap(key.data());
1618 inline BoolValue::Shared createValue(const bool rawVal)
1620 return BoolValue::create(rawVal);
1623 inline UnsignedIntegerValue::Shared createValue(const std::uint64_t rawVal)
1625 return UnsignedIntegerValue::create(rawVal);
1628 inline SignedIntegerValue::Shared createValue(const std::int64_t rawVal)
1630 return SignedIntegerValue::create(rawVal);
1633 inline RealValue::Shared createValue(const double rawVal)
1635 return RealValue::create(rawVal);
1638 inline StringValue::Shared createValue(const char * const rawVal)
1640 return StringValue::create(rawVal);
1643 inline StringValue::Shared createValue(const std::string& rawVal)
1645 return StringValue::create(rawVal);
1648 } /* namespace bt2 */
1650 #endif /* BABELTRACE_CPP_COMMON_BT2_VALUE_HPP */