From: Philippe Proulx Date: Thu, 17 Dec 2020 18:44:51 +0000 (-0500) Subject: Add C++ interface for the libbabeltrace2 `bt_field_class` API X-Git-Url: http://git.efficios.com/?p=babeltrace.git;a=commitdiff_plain;h=12435a68fc55fa763809f511465a1e6b2ec25e44 Add C++ interface for the libbabeltrace2 `bt_field_class` API This patch adds C++ wrappers for Babeltrace 2 field class objects. The class hierarchy is: FieldClass BitArrayFieldClass IntegerFieldClass UnsignedEnumerationFieldClass SignedEnumerationFieldClass StructureFieldClass ArrayFieldClass StaticArrayFieldClass DynamicArrayWithLengthFieldClass OptionFieldClass OptionWithSelectorFieldClass OptionWithBoolSelectorFieldClass OptionWithUnsignedIntegerSelectorFieldClass OptionWithSignedIntegerSelectorFieldClass VariantFieldClass VariantWithoutSelectorFieldClass VariantWithUnsignedIntegerSelectorFieldClass VariantWithSignedIntegerSelectorFieldClass ConstFieldClass ConstBitArrayFieldClass ConstIntegerFieldClass ConstUnsignedEnumerationFieldClass ConstSignedEnumerationFieldClass ConstStructureFieldClass ConstArrayFieldClass ConstStaticArrayFieldClass ConstDynamicArrayWithLengthFieldClass ConstOptionFieldClass ConstOptionWithSelectorFieldClass ConstOptionWithBoolSelectorFieldClass ConstOptionWithUnsignedIntegerSelectorFieldClass ConstOptionWithSignedIntegerSelectorFieldClass ConstVariantFieldClass ConstVariantWithoutSelectorFieldClass ConstVariantWithUnsignedIntegerSelectorFieldClass ConstVariantWithSignedIntegerSelectorFieldClass ConstUnsignedEnumerationFieldClassMapping ConstSignedEnumerationFieldClassMapping StructureFieldClassMember ConstStructureFieldClassMember VariantFieldClassOption ConstVariantFieldClassOption ConstVariantWithUnsignedIntegerSelectorFieldClassOption ConstVariantWithSignedIntegerSelectorFieldClassOption `ConstVariantWith*IntegerSelectorFieldClassOption` doesn't inherit `ConstVariantFieldClassOption` as they don't wrap the same pointer type: you need to call bt_field_class_variant_with_selector_field_integer_*_option_as_option_const() to obtain a `const bt_field_class_variant_option *` value. Therefore, you can call asBaseOption() to get a `ConstVariantFieldClassOption`. I also implemented name() and fieldClass() which call asBaseOption().name() and asBaseOption().fieldClass(). Implicitly convert from a mutable field class to a constant field class with converting constructors and assignment operators. Those new template classes follow the approach of other wrappers in `src/cpp-common/bt2`. Because `bt2::FieldClass::userAttributes()` needs to access the libbabeltrace2 pointer of the map value, `bt2::CommonValue` makes `bt2::FieldClass` a friend. Because `bt2::VariantWithUnsignedIntegerSelectorFieldClass::appendOption()` and `bt2::VariantWithSignedIntegerSelectorFieldClass::appendOption()` need to access the libbabeltrace2 pointer of the integer range set, `bt2::CommonIntegerRangeSet` makes those classes friends. Signed-off-by: Philippe Proulx Change-Id: I5244b603b1f43e61cfa52c4a5fb6b19e2cbac576 Reviewed-on: https://review.lttng.org/c/babeltrace/+/4612 --- diff --git a/src/cpp-common/bt2/field-class.hpp b/src/cpp-common/bt2/field-class.hpp new file mode 100644 index 00000000..a1cba0bf --- /dev/null +++ b/src/cpp-common/bt2/field-class.hpp @@ -0,0 +1,2159 @@ +/* + * Copyright (c) 2020 Philippe Proulx + * + * SPDX-License-Identifier: MIT + */ + +#ifndef BABELTRACE_CPP_COMMON_BT2_FIELD_CLASS_HPP +#define BABELTRACE_CPP_COMMON_BT2_FIELD_CLASS_HPP + +#include +#include +#include + +#include "common/assert.h" +#include "internal/borrowed-obj.hpp" +#include "internal/shared-obj.hpp" +#include "cpp-common/optional.hpp" +#include "cpp-common/string_view.hpp" +#include "lib-error.hpp" +#include "integer-range-set.hpp" +#include "field-path.hpp" + +namespace bt2 { + +namespace internal { + +struct FieldClassRefFuncs final +{ + static void get(const bt_field_class * const libObjPtr) + { + bt_field_class_get_ref(libObjPtr); + } + + static void put(const bt_field_class * const libObjPtr) + { + bt_field_class_put_ref(libObjPtr); + } +}; + +template +using SharedFieldClass = internal::SharedObj; + +template +struct CommonFieldClassSpec; + +// Functions specific to mutable field classes +template <> +struct CommonFieldClassSpec final +{ + static bt_value *userAttributes(bt_field_class * const libObjPtr) noexcept + { + return bt_field_class_borrow_user_attributes(libObjPtr); + } +}; + +// Functions specific to constant field classes +template <> +struct CommonFieldClassSpec final +{ + static const bt_value *userAttributes(const bt_field_class * const libObjPtr) noexcept + { + return bt_field_class_borrow_user_attributes_const(libObjPtr); + } +}; + +} // namespace internal + +template +class CommonBitArrayFieldClass; + +template +class CommonIntegerFieldClass; + +template +class ConstEnumerationFieldClassMapping; + +template +class CommonEnumerationFieldClass; + +template +class CommonStructureFieldClass; + +template +class CommonArrayFieldClass; + +template +class CommonStaticArrayFieldClass; + +template +class CommonDynamicArrayWithLengthFieldClass; + +template +class CommonOptionFieldClass; + +template +class CommonOptionWithSelectorFieldClass; + +template +class CommonOptionWithBoolSelectorFieldClass; + +template +class CommonVariantFieldClass; + +template +class CommonOptionWithIntegerSelectorFieldClass; + +template +class CommonVariantWithoutSelectorFieldClass; + +template +class ConstVariantWithIntegerSelectorFieldClassOption; + +template +class CommonVariantWithIntegerSelectorFieldClass; + +enum class FieldClassType +{ + BOOL = BT_FIELD_CLASS_TYPE_BOOL, + BIT_ARRAY = BT_FIELD_CLASS_TYPE_BIT_ARRAY, + UNSIGNED_INTEGER = BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER, + SIGNED_INTEGER = BT_FIELD_CLASS_TYPE_SIGNED_INTEGER, + UNSIGNED_ENUMERATION = BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION, + SIGNED_ENUMERATION = BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION, + SINGLE_PRECISION_REAL = BT_FIELD_CLASS_TYPE_SINGLE_PRECISION_REAL, + DOUBLE_PRECISION_REAL = BT_FIELD_CLASS_TYPE_DOUBLE_PRECISION_REAL, + STRING = BT_FIELD_CLASS_TYPE_STRING, + STRUCTURE = BT_FIELD_CLASS_TYPE_STRUCTURE, + STATIC_ARRAY = BT_FIELD_CLASS_TYPE_STATIC_ARRAY, + DYNAMIC_ARRAY_WITHOUT_LENGTH = BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITHOUT_LENGTH_FIELD, + DYNAMIC_ARRAY_WITH_LENGTH = BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITH_LENGTH_FIELD, + OPTION_WITHOUT_SELECTOR = BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR_FIELD, + OPTION_WITH_BOOL_SELECTOR = BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR_FIELD, + OPTION_WITH_UNSIGNED_INTEGER_SELECTOR = + BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD, + OPTION_WITH_SIGNED_INTEGER_SELECTOR = + BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR_FIELD, + VARIANT_WITHOUT_SELECTOR = BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR_FIELD, + VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR = + BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD, + VARIANT_WITH_SIGNED_INTEGER_SELECTOR = + BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR_FIELD, +}; + +template +class CommonFieldClass : public internal::BorrowedObj +{ + // Allow appendMember() to call `fc._libObjPtr()` + friend class CommonStructureFieldClass; + + // Allow appendOption() to call `fc._libObjPtr()` + friend class CommonVariantWithoutSelectorFieldClass; + + friend class CommonVariantWithIntegerSelectorFieldClass< + bt_field_class, + ConstVariantWithIntegerSelectorFieldClassOption< + const bt_field_class_variant_with_selector_field_integer_unsigned_option>>; + + friend class CommonVariantWithIntegerSelectorFieldClass< + bt_field_class, + ConstVariantWithIntegerSelectorFieldClassOption< + const bt_field_class_variant_with_selector_field_integer_signed_option>>; + +private: + using typename internal::BorrowedObj::_ThisBorrowedObj; + +protected: + using typename internal::BorrowedObj::_LibObjPtr; + using _ThisCommonFieldClass = CommonFieldClass; + +public: + using Shared = internal::SharedFieldClass, LibObjT>; + + using UserAttributes = + typename std::conditional::value, ConstMapValue, MapValue>::type; + + explicit CommonFieldClass(const _LibObjPtr libObjPtr) noexcept : _ThisBorrowedObj {libObjPtr} + { + } + + template + CommonFieldClass(const CommonFieldClass& fc) noexcept : _ThisBorrowedObj {fc} + { + } + + template + _ThisCommonFieldClass& operator=(const CommonFieldClass& fc) noexcept + { + _ThisBorrowedObj::operator=(fc); + return *this; + } + + FieldClassType type() const noexcept + { + return static_cast(bt_field_class_get_type(this->_libObjPtr())); + } + + bool isBool() const noexcept + { + return this->_libTypeIs(BT_FIELD_CLASS_TYPE_BOOL); + } + + bool isBitArray() const noexcept + { + return this->_libTypeIs(BT_FIELD_CLASS_TYPE_BIT_ARRAY); + } + + bool isInteger() const noexcept + { + return this->_libTypeIs(BT_FIELD_CLASS_TYPE_INTEGER); + } + + bool isUnsignedInteger() const noexcept + { + return this->_libTypeIs(BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER); + } + + bool isSignedInteger() const noexcept + { + return this->_libTypeIs(BT_FIELD_CLASS_TYPE_SIGNED_INTEGER); + } + + bool isEnumeration() const noexcept + { + return this->_libTypeIs(BT_FIELD_CLASS_TYPE_ENUMERATION); + } + + bool isUnsignedEnumeration() const noexcept + { + return this->_libTypeIs(BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION); + } + + bool isSignedEnumeration() const noexcept + { + return this->_libTypeIs(BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION); + } + + bool isSinglePrecisionReal() const noexcept + { + return this->_libTypeIs(BT_FIELD_CLASS_TYPE_SINGLE_PRECISION_REAL); + } + + bool isDoublePrecisionReal() const noexcept + { + return this->_libTypeIs(BT_FIELD_CLASS_TYPE_DOUBLE_PRECISION_REAL); + } + + bool isString() const noexcept + { + return this->_libTypeIs(BT_FIELD_CLASS_TYPE_STRING); + } + + bool isStructure() const noexcept + { + return this->_libTypeIs(BT_FIELD_CLASS_TYPE_STRUCTURE); + } + + bool isArray() const noexcept + { + return this->_libTypeIs(BT_FIELD_CLASS_TYPE_ARRAY); + } + + bool isStaticArray() const noexcept + { + return this->_libTypeIs(BT_FIELD_CLASS_TYPE_STATIC_ARRAY); + } + + bool isDynamicArray() const noexcept + { + return this->_libTypeIs(BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY); + } + + bool isDynamicArrayWithoutLength() const noexcept + { + return this->_libTypeIs(BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITHOUT_LENGTH_FIELD); + } + + bool isDynamicArrayWithLength() const noexcept + { + return this->_libTypeIs(BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY_WITH_LENGTH_FIELD); + } + + bool isOption() const noexcept + { + return this->_libTypeIs(BT_FIELD_CLASS_TYPE_OPTION); + } + + bool isOptionWithoutSelector() const noexcept + { + return this->_libTypeIs(BT_FIELD_CLASS_TYPE_OPTION_WITHOUT_SELECTOR_FIELD); + } + + bool isOptionWithSelector() const noexcept + { + return this->_libTypeIs(BT_FIELD_CLASS_TYPE_OPTION_WITH_SELECTOR_FIELD); + } + + bool isOptionWithBoolSelector() const noexcept + { + return this->_libTypeIs(BT_FIELD_CLASS_TYPE_OPTION_WITH_BOOL_SELECTOR_FIELD); + } + + bool isOptionWithIntegerSelector() const noexcept + { + return this->_libTypeIs(BT_FIELD_CLASS_TYPE_OPTION_WITH_INTEGER_SELECTOR_FIELD); + } + + bool isOptionWithUnsignedIntegerSelector() const noexcept + { + return this->_libTypeIs(BT_FIELD_CLASS_TYPE_OPTION_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD); + } + + bool isOptionWithSignedIntegerSelector() const noexcept + { + return this->_libTypeIs(BT_FIELD_CLASS_TYPE_OPTION_WITH_SIGNED_INTEGER_SELECTOR_FIELD); + } + + bool isVariant() const noexcept + { + return this->_libTypeIs(BT_FIELD_CLASS_TYPE_VARIANT); + } + + bool isVariantWithoutSelector() const noexcept + { + return this->_libTypeIs(BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR_FIELD); + } + + bool isVariantWithSelector() const noexcept + { + return this->_libTypeIs(BT_FIELD_CLASS_TYPE_VARIANT_WITH_SELECTOR_FIELD); + } + + bool isVariantWithIntegerSelector() const noexcept + { + return this->_libTypeIs(BT_FIELD_CLASS_TYPE_VARIANT_WITH_INTEGER_SELECTOR_FIELD); + } + + bool isVariantWithUnsignedIntegerSelector() const noexcept + { + return this->_libTypeIs(BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD); + } + + bool isVariantWithSignedIntegerSelector() const noexcept + { + return this->_libTypeIs(BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR_FIELD); + } + + CommonBitArrayFieldClass asBitArray() const noexcept; + CommonIntegerFieldClass asInteger() const noexcept; + + CommonEnumerationFieldClass> + asUnsignedEnumeration() const noexcept; + + CommonEnumerationFieldClass< + LibObjT, ConstEnumerationFieldClassMapping> + asSignedEnumeration() const noexcept; + + CommonStructureFieldClass asStructure() const noexcept; + CommonArrayFieldClass asArray() const noexcept; + CommonStaticArrayFieldClass asStaticArray() const noexcept; + CommonDynamicArrayWithLengthFieldClass asDynamicArrayWithLength() const noexcept; + CommonOptionFieldClass asOption() const noexcept; + CommonOptionWithSelectorFieldClass asOptionWithSelector() const noexcept; + CommonOptionWithBoolSelectorFieldClass asOptionWithBoolSelector() const noexcept; + + CommonOptionWithIntegerSelectorFieldClass + asOptionWithUnsignedIntegerSelector() const noexcept; + + CommonOptionWithIntegerSelectorFieldClass + asOptionWithSignedIntegerSelector() const noexcept; + + CommonVariantFieldClass asVariant() const noexcept; + CommonVariantWithoutSelectorFieldClass asVariantWithoutSelector() const noexcept; + + CommonVariantWithIntegerSelectorFieldClass< + LibObjT, ConstVariantWithIntegerSelectorFieldClassOption< + const bt_field_class_variant_with_selector_field_integer_unsigned_option>> + asVariantWithUnsignedIntegerSelector() const noexcept; + + CommonVariantWithIntegerSelectorFieldClass< + LibObjT, ConstVariantWithIntegerSelectorFieldClassOption< + const bt_field_class_variant_with_selector_field_integer_signed_option>> + asVariantWithSignedIntegerSelector() const noexcept; + + template + void userAttributes(const CommonMapValue& userAttrs) + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + bt_field_class_set_user_attributes(this->_libObjPtr(), userAttrs._libObjPtr()); + } + + ConstMapValue userAttributes() const noexcept + { + return ConstMapValue {internal::CommonFieldClassSpec::userAttributes( + this->_libObjPtr())}; + } + + UserAttributes userAttributes() noexcept + { + return UserAttributes { + internal::CommonFieldClassSpec::userAttributes(this->_libObjPtr())}; + } + + Shared shared() const noexcept + { + return Shared {*this}; + } + +protected: + bool _libTypeIs(const bt_field_class_type type) const noexcept + { + return bt_field_class_type_is(bt_field_class_get_type(this->_libObjPtr()), type); + } +}; + +using FieldClass = CommonFieldClass; +using ConstFieldClass = CommonFieldClass; + +template +class CommonBitArrayFieldClass final : public CommonFieldClass +{ +private: + using typename CommonFieldClass::_LibObjPtr; + using typename CommonFieldClass::_ThisCommonFieldClass; + +public: + using Shared = internal::SharedFieldClass, LibObjT>; + + explicit CommonBitArrayFieldClass(const _LibObjPtr libObjPtr) noexcept : + _ThisCommonFieldClass {libObjPtr} + { + BT_ASSERT_DBG(this->isBitArray()); + } + + template + CommonBitArrayFieldClass(const CommonBitArrayFieldClass& fc) noexcept : + _ThisCommonFieldClass {fc} + { + } + + template + CommonBitArrayFieldClass& + operator=(const CommonBitArrayFieldClass& fc) noexcept + { + _ThisCommonFieldClass::operator=(fc); + return *this; + } + + std::uint64_t length() const noexcept + { + return bt_field_class_bit_array_get_length(this->_libObjPtr()); + } + + Shared shared() const noexcept + { + return Shared {*this}; + } +}; + +using BitArrayFieldClass = CommonBitArrayFieldClass; +using ConstBitArrayFieldClass = CommonBitArrayFieldClass; + +enum class DisplayBase +{ + BINARY = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_BINARY, + OCTAL = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_OCTAL, + DECIMAL = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL, + HEXADECIMAL = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL, +}; + +template +class CommonIntegerFieldClass : public CommonFieldClass +{ +private: + using typename CommonFieldClass::_ThisCommonFieldClass; + +protected: + using typename CommonFieldClass::_LibObjPtr; + using _ThisCommonIntegerFieldClass = CommonIntegerFieldClass; + +public: + using Shared = internal::SharedFieldClass, LibObjT>; + + explicit CommonIntegerFieldClass(const _LibObjPtr libObjPtr) noexcept : + _ThisCommonFieldClass {libObjPtr} + { + BT_ASSERT_DBG(this->isInteger()); + } + + template + CommonIntegerFieldClass(const CommonIntegerFieldClass& fc) noexcept : + _ThisCommonFieldClass {fc} + { + } + + template + _ThisCommonIntegerFieldClass& + operator=(const CommonIntegerFieldClass& fc) noexcept + { + _ThisCommonFieldClass::operator=(fc); + return *this; + } + + void fieldValueRange(const std::uint64_t n) noexcept + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + bt_field_class_integer_get_field_value_range(this->_libObjPtr(), n); + } + + std::uint64_t fieldValueRange() const noexcept + { + return bt_field_class_integer_get_field_value_range(this->_libObjPtr()); + } + + void preferredDisplayBase(const DisplayBase base) noexcept + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + bt_field_class_integer_set_preferred_display_base( + this->_libObjPtr(), static_cast(base)); + } + + DisplayBase preferredDisplayBase() const noexcept + { + return static_cast( + bt_field_class_integer_get_preferred_display_base(this->_libObjPtr())); + } + + Shared shared() const noexcept + { + return Shared {*this}; + } +}; + +using IntegerFieldClass = CommonIntegerFieldClass; +using ConstIntegerFieldClass = CommonIntegerFieldClass; + +namespace internal { + +template +struct ConstEnumerationFieldClassMappingSpec; + +// Functions specific to unsigned enumeration field class mappings +template <> +struct ConstEnumerationFieldClassMappingSpec + final +{ + static const bt_integer_range_set_unsigned * + ranges(const bt_field_class_enumeration_unsigned_mapping * const libObjPtr) noexcept + { + return bt_field_class_enumeration_unsigned_mapping_borrow_ranges_const(libObjPtr); + } + + static const char * + label(const bt_field_class_enumeration_unsigned_mapping * const libObjPtr) noexcept + { + return bt_field_class_enumeration_mapping_get_label( + bt_field_class_enumeration_unsigned_mapping_as_mapping_const(libObjPtr)); + } +}; + +// Functions specific to signed enumeration field class mappings +template <> +struct ConstEnumerationFieldClassMappingSpec final +{ + static const bt_integer_range_set_signed * + ranges(const bt_field_class_enumeration_signed_mapping * const libObjPtr) noexcept + { + return bt_field_class_enumeration_signed_mapping_borrow_ranges_const(libObjPtr); + } + + static const char * + label(const bt_field_class_enumeration_signed_mapping * const libObjPtr) noexcept + { + return bt_field_class_enumeration_mapping_get_label( + bt_field_class_enumeration_signed_mapping_as_mapping_const(libObjPtr)); + } +}; + +} // namespace internal + +template +class ConstEnumerationFieldClassMapping final : public internal::BorrowedObj +{ +private: + using typename internal::BorrowedObj::_ThisBorrowedObj; + using typename internal::BorrowedObj::_LibObjPtr; + using _ThisConstEnumerationFieldClassMapping = ConstEnumerationFieldClassMapping; + +public: + using RangeSet = typename std::conditional< + std::is_same::value, + ConstUnsignedIntegerRangeSet, ConstSignedIntegerRangeSet>::type; + + explicit ConstEnumerationFieldClassMapping(const _LibObjPtr libObjPtr) noexcept : + _ThisBorrowedObj {libObjPtr} + { + } + + ConstEnumerationFieldClassMapping( + const _ThisConstEnumerationFieldClassMapping& mapping) noexcept : + _ThisBorrowedObj {mapping} + { + } + + _ThisConstEnumerationFieldClassMapping& + operator=(const _ThisConstEnumerationFieldClassMapping& mapping) noexcept + { + _ThisBorrowedObj::operator=(mapping); + return *this; + } + + RangeSet ranges() const noexcept + { + return RangeSet { + internal::ConstEnumerationFieldClassMappingSpec::ranges(this->_libObjPtr())}; + } + + bpstd::string_view label() const noexcept + { + return internal::ConstEnumerationFieldClassMappingSpec::label(this->_libObjPtr()); + } +}; + +using ConstUnsignedEnumerationFieldClassMapping = + ConstEnumerationFieldClassMapping; + +using ConstSignedEnumerationFieldClassMapping = + ConstEnumerationFieldClassMapping; + +namespace internal { + +template +struct CommonEnumerationFieldClassSpec; + +// Functions specific to unsigned enumeration field classes +template <> +struct CommonEnumerationFieldClassSpec final +{ + static const bt_field_class_enumeration_unsigned_mapping * + mappingByIndex(const bt_field_class * const libObjPtr, const std::uint64_t index) noexcept + { + return bt_field_class_enumeration_unsigned_borrow_mapping_by_index_const(libObjPtr, index); + } + + static const bt_field_class_enumeration_unsigned_mapping * + mappingByLabel(const bt_field_class * const libObjPtr, const char * const label) noexcept + { + return bt_field_class_enumeration_unsigned_borrow_mapping_by_label_const(libObjPtr, label); + } +}; + +// Functions specific to signed enumeration field classes +template <> +struct CommonEnumerationFieldClassSpec final +{ + static const bt_field_class_enumeration_signed_mapping * + mappingByIndex(const bt_field_class * const libObjPtr, const std::uint64_t index) noexcept + { + return bt_field_class_enumeration_signed_borrow_mapping_by_index_const(libObjPtr, index); + } + + static const bt_field_class_enumeration_signed_mapping * + mappingByLabel(const bt_field_class * const libObjPtr, const char * const label) noexcept + { + return bt_field_class_enumeration_signed_borrow_mapping_by_label_const(libObjPtr, label); + } +}; + +} // namespace internal + +template +class CommonEnumerationFieldClass final : public CommonIntegerFieldClass +{ +private: + using typename CommonFieldClass::_LibObjPtr; + using typename CommonIntegerFieldClass::_ThisCommonIntegerFieldClass; + using _ThisCommonEnumerationFieldClass = CommonEnumerationFieldClass; + +public: + using Shared = internal::SharedFieldClass<_ThisCommonEnumerationFieldClass, LibObjT>; + using Mapping = MappingT; + + explicit CommonEnumerationFieldClass(const _LibObjPtr libObjPtr) noexcept : + _ThisCommonIntegerFieldClass {libObjPtr} + { + BT_ASSERT_DBG(this->isEnumeration()); + } + + template + CommonEnumerationFieldClass( + const CommonEnumerationFieldClass& fc) noexcept : + _ThisCommonIntegerFieldClass {fc} + { + } + + template + _ThisCommonEnumerationFieldClass& + operator=(const CommonEnumerationFieldClass& fc) noexcept + { + _ThisCommonIntegerFieldClass::operator=(fc); + return *this; + } + + std::uint64_t size() const noexcept + { + return bt_field_class_enumeration_get_mapping_count(this->_libObjPtr()); + } + + Mapping operator[](const std::uint64_t index) const noexcept + { + return Mapping {internal::CommonEnumerationFieldClassSpec::mappingByIndex( + this->_libObjPtr(), index)}; + } + + nonstd::optional operator[](const char * const label) const noexcept + { + const auto libObjPtr = internal::CommonEnumerationFieldClassSpec::mappingByLabel( + this->_libObjPtr(), label); + + if (libObjPtr) { + return Mapping {libObjPtr}; + } + + return nonstd::nullopt; + } + + nonstd::optional operator[](const std::string& label) const noexcept + { + return (*this)[label.data()]; + } + + Shared shared() const noexcept + { + return Shared {*this}; + } +}; + +using UnsignedEnumerationFieldClass = + CommonEnumerationFieldClass; + +using ConstUnsignedEnumerationFieldClass = + CommonEnumerationFieldClass; + +using SignedEnumerationFieldClass = + CommonEnumerationFieldClass; + +using ConstSignedEnumerationFieldClass = + CommonEnumerationFieldClass; + +namespace internal { + +template +struct CommonStructureFieldClassMemberSpec; + +// Functions specific to mutable structure field class members +template <> +struct CommonStructureFieldClassMemberSpec final +{ + static bt_field_class *fieldClass(bt_field_class_structure_member * const libObjPtr) noexcept + { + return bt_field_class_structure_member_borrow_field_class(libObjPtr); + } +}; + +// Functions specific to constant structure field class members +template <> +struct CommonStructureFieldClassMemberSpec final +{ + static const bt_field_class * + fieldClass(const bt_field_class_structure_member * const libObjPtr) noexcept + { + return bt_field_class_structure_member_borrow_field_class_const(libObjPtr); + } +}; + +} // namespace internal + +template +class CommonStructureFieldClassMember final : public internal::BorrowedObj +{ +private: + using typename internal::BorrowedObj::_LibObjPtr; + using typename internal::BorrowedObj::_ThisBorrowedObj; + + using _FieldClass = + typename std::conditional::value, ConstFieldClass, FieldClass>::type; + +public: + explicit CommonStructureFieldClassMember(const _LibObjPtr libObjPtr) noexcept : + _ThisBorrowedObj {libObjPtr} + { + } + + template + CommonStructureFieldClassMember( + const CommonStructureFieldClassMember& fc) noexcept : + _ThisBorrowedObj {fc} + { + } + + template + CommonStructureFieldClassMember& + operator=(const CommonStructureFieldClassMember& fc) noexcept + { + _ThisBorrowedObj::operator=(fc); + return *this; + } + + bpstd::string_view name() const noexcept + { + return bt_field_class_structure_member_get_name(this->_libObjPtr()); + } + + ConstFieldClass fieldClass() const noexcept + { + return ConstFieldClass {internal::CommonStructureFieldClassMemberSpec< + const bt_field_class_structure_member>::fieldClass(this->_libObjPtr())}; + } + + _FieldClass fieldClass() noexcept + { + return _FieldClass { + internal::CommonStructureFieldClassMemberSpec::fieldClass(this->_libObjPtr())}; + } +}; + +using StructureFieldClassMember = CommonStructureFieldClassMember; + +using ConstStructureFieldClassMember = + CommonStructureFieldClassMember; + +namespace internal { + +template +struct CommonStructureFieldClassSpec; + +// Functions specific to mutable structure field classes +template <> +struct CommonStructureFieldClassSpec final +{ + static bt_field_class_structure_member *memberByIndex(bt_field_class * const libObjPtr, + const std::uint64_t index) noexcept + { + return bt_field_class_structure_borrow_member_by_index(libObjPtr, index); + } + + static bt_field_class_structure_member *memberByName(bt_field_class * const libObjPtr, + const char * const name) noexcept + { + return bt_field_class_structure_borrow_member_by_name(libObjPtr, name); + } +}; + +// Functions specific to constant structure field classes +template <> +struct CommonStructureFieldClassSpec final +{ + static const bt_field_class_structure_member * + memberByIndex(const bt_field_class * const libObjPtr, const std::uint64_t index) noexcept + { + return bt_field_class_structure_borrow_member_by_index_const(libObjPtr, index); + } + + static const bt_field_class_structure_member * + memberByName(const bt_field_class * const libObjPtr, const char * const name) noexcept + { + return bt_field_class_structure_borrow_member_by_name_const(libObjPtr, name); + } +}; + +} // namespace internal + +template +class CommonStructureFieldClass final : public CommonFieldClass +{ +private: + using typename CommonFieldClass::_LibObjPtr; + using typename CommonFieldClass::_ThisCommonFieldClass; + +public: + using Shared = internal::SharedFieldClass, LibObjT>; + + using Member = + typename std::conditional::value, ConstStructureFieldClassMember, + StructureFieldClassMember>::type; + + explicit CommonStructureFieldClass(const _LibObjPtr libObjPtr) noexcept : + _ThisCommonFieldClass {libObjPtr} + { + BT_ASSERT_DBG(this->isStructure()); + } + + template + CommonStructureFieldClass(const CommonStructureFieldClass& fc) noexcept : + _ThisCommonFieldClass {fc} + { + } + + template + CommonStructureFieldClass& + operator=(const CommonStructureFieldClass& fc) noexcept + { + _ThisCommonFieldClass::operator=(fc); + return *this; + } + + void appendMember(const char * const name, const FieldClass& fc) + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + const auto status = + bt_field_class_structure_append_member(this->_libObjPtr(), name, fc._libObjPtr()); + + if (status == BT_FIELD_CLASS_STRUCTURE_APPEND_MEMBER_STATUS_MEMORY_ERROR) { + throw LibMemoryError {}; + } + } + + void appendMember(const std::string& name, const FieldClass& fc) + { + this->appendMember(name.data(), fc); + } + + std::uint64_t size() const noexcept + { + return bt_field_class_structure_get_member_count(this->_libObjPtr()); + } + + ConstStructureFieldClassMember operator[](const std::uint64_t index) const noexcept + { + return ConstStructureFieldClassMember { + internal::CommonStructureFieldClassSpec::memberByIndex( + this->_libObjPtr(), index)}; + } + + Member operator[](const std::uint64_t index) noexcept + { + return Member {internal::CommonStructureFieldClassSpec::memberByIndex( + this->_libObjPtr(), index)}; + } + + nonstd::optional + operator[](const char * const name) const noexcept + { + const auto libObjPtr = + internal::CommonStructureFieldClassSpec::memberByName( + this->_libObjPtr(), name); + + if (libObjPtr) { + return ConstStructureFieldClassMember {libObjPtr}; + } + + return nonstd::nullopt; + } + + nonstd::optional + operator[](const std::string& name) const noexcept + { + return (*this)[name.data()]; + } + + nonstd::optional operator[](const char * const name) noexcept + { + const auto libObjPtr = internal::CommonStructureFieldClassSpec::memberByName( + this->_libObjPtr(), name); + + if (libObjPtr) { + return Member {libObjPtr}; + } + + return nonstd::nullopt; + } + + nonstd::optional operator[](const std::string& name) noexcept + { + return (*this)[name.data()]; + } + + Shared shared() const noexcept + { + return Shared {*this}; + } +}; + +using StructureFieldClass = CommonStructureFieldClass; +using ConstStructureFieldClass = CommonStructureFieldClass; + +namespace internal { + +template +struct CommonArrayFieldClassSpec; + +// Functions specific to mutable array field classes +template <> +struct CommonArrayFieldClassSpec final +{ + static bt_field_class *elementFieldClass(bt_field_class * const libObjPtr) noexcept + { + return bt_field_class_array_borrow_element_field_class(libObjPtr); + } +}; + +// Functions specific to constant array field classes +template <> +struct CommonArrayFieldClassSpec final +{ + static const bt_field_class *elementFieldClass(const bt_field_class * const libObjPtr) noexcept + { + return bt_field_class_array_borrow_element_field_class_const(libObjPtr); + } +}; + +} // namespace internal + +template +class CommonArrayFieldClass : public CommonFieldClass +{ +private: + using typename CommonFieldClass::_ThisCommonFieldClass; + + using _FieldClass = + typename std::conditional::value, ConstFieldClass, FieldClass>::type; + +protected: + using typename CommonFieldClass::_LibObjPtr; + using _ThisCommonArrayFieldClass = CommonArrayFieldClass; + +public: + using Shared = internal::SharedFieldClass, LibObjT>; + + explicit CommonArrayFieldClass(const _LibObjPtr libObjPtr) noexcept : + _ThisCommonFieldClass {libObjPtr} + { + BT_ASSERT_DBG(this->isArray()); + } + + template + CommonArrayFieldClass(const CommonArrayFieldClass& fc) noexcept : + _ThisCommonFieldClass {fc} + { + } + + template + _ThisCommonArrayFieldClass& operator=(const CommonArrayFieldClass& fc) noexcept + { + _ThisCommonFieldClass::operator=(fc); + return *this; + } + + ConstFieldClass elementFieldClass() const noexcept + { + return ConstFieldClass { + internal::CommonArrayFieldClassSpec::elementFieldClass( + this->_libObjPtr())}; + } + + _FieldClass elementFieldClass() noexcept + { + return _FieldClass { + internal::CommonArrayFieldClassSpec::elementFieldClass(this->_libObjPtr())}; + } + + Shared shared() const noexcept + { + return Shared {*this}; + } +}; + +using ArrayFieldClass = CommonArrayFieldClass; +using ConstArrayFieldClass = CommonArrayFieldClass; + +template +class CommonStaticArrayFieldClass final : public CommonArrayFieldClass +{ +private: + using typename CommonArrayFieldClass::_ThisCommonArrayFieldClass; + using typename CommonFieldClass::_LibObjPtr; + +public: + using Shared = internal::SharedFieldClass, LibObjT>; + + explicit CommonStaticArrayFieldClass(const _LibObjPtr libObjPtr) noexcept : + _ThisCommonArrayFieldClass {libObjPtr} + { + BT_ASSERT_DBG(this->isStaticArray()); + } + + template + CommonStaticArrayFieldClass(const CommonStaticArrayFieldClass& fc) noexcept : + _ThisCommonArrayFieldClass {fc} + { + } + + template + CommonStaticArrayFieldClass& + operator=(const CommonStaticArrayFieldClass& fc) noexcept + { + _ThisCommonArrayFieldClass::operator=(fc); + return *this; + } + + std::uint64_t length() const noexcept + { + return bt_field_class_array_static_get_length(this->_libObjPtr()); + } + + Shared shared() const noexcept + { + return Shared {*this}; + } +}; + +using StaticArrayFieldClass = CommonStaticArrayFieldClass; +using ConstStaticArrayFieldClass = CommonStaticArrayFieldClass; + +template +class CommonDynamicArrayWithLengthFieldClass final : public CommonArrayFieldClass +{ +private: + using typename CommonArrayFieldClass::_ThisCommonArrayFieldClass; + using typename CommonFieldClass::_LibObjPtr; + +public: + using Shared = + internal::SharedFieldClass, LibObjT>; + + explicit CommonDynamicArrayWithLengthFieldClass(const _LibObjPtr libObjPtr) noexcept : + _ThisCommonArrayFieldClass {libObjPtr} + { + BT_ASSERT_DBG(this->isDynamicArrayWithLength()); + } + + template + CommonDynamicArrayWithLengthFieldClass( + const CommonDynamicArrayWithLengthFieldClass& fc) noexcept : + _ThisCommonArrayFieldClass {fc} + { + } + + template + CommonDynamicArrayWithLengthFieldClass& + operator=(const CommonDynamicArrayWithLengthFieldClass& fc) noexcept + { + _ThisCommonArrayFieldClass::operator=(fc); + return *this; + } + + ConstFieldPath lengthFieldPath() const noexcept + { + return ConstFieldPath { + bt_field_class_array_dynamic_with_length_field_borrow_length_field_path_const( + this->_libObjPtr())}; + } + + Shared shared() const noexcept + { + return Shared {*this}; + } +}; + +using DynamicArrayWithLengthFieldClass = CommonDynamicArrayWithLengthFieldClass; + +using ConstDynamicArrayWithLengthFieldClass = + CommonDynamicArrayWithLengthFieldClass; + +namespace internal { + +template +struct CommonOptionFieldClassSpec; + +// Functions specific to mutable option field classes +template <> +struct CommonOptionFieldClassSpec final +{ + static bt_field_class *fieldClass(bt_field_class * const libObjPtr) noexcept + { + return bt_field_class_option_borrow_field_class(libObjPtr); + } +}; + +// Functions specific to constant option field classes +template <> +struct CommonOptionFieldClassSpec final +{ + static const bt_field_class *fieldClass(const bt_field_class * const libObjPtr) noexcept + { + return bt_field_class_option_borrow_field_class_const(libObjPtr); + } +}; + +} // namespace internal + +template +class CommonOptionFieldClass : public CommonFieldClass +{ +private: + using typename CommonFieldClass::_ThisCommonFieldClass; + + using _FieldClass = + typename std::conditional::value, ConstFieldClass, FieldClass>::type; + +protected: + using typename CommonFieldClass::_LibObjPtr; + using _ThisCommonOptionFieldClass = CommonOptionFieldClass; + +public: + using Shared = internal::SharedFieldClass, LibObjT>; + + explicit CommonOptionFieldClass(const _LibObjPtr libObjPtr) noexcept : + _ThisCommonFieldClass {libObjPtr} + { + BT_ASSERT_DBG(this->isOption()); + } + + template + CommonOptionFieldClass(const CommonOptionFieldClass& fc) noexcept : + _ThisCommonFieldClass {fc} + { + } + + template + _ThisCommonOptionFieldClass& operator=(const CommonOptionFieldClass& fc) noexcept + { + _ThisCommonFieldClass::operator=(fc); + return *this; + } + + ConstFieldClass fieldClass() const noexcept + { + return ConstFieldClass { + internal::CommonOptionFieldClassSpec::fieldClass( + this->_libObjPtr())}; + } + + _FieldClass fieldClass() noexcept + { + return _FieldClass { + internal::CommonOptionFieldClassSpec::fieldClass(this->_libObjPtr())}; + } + + Shared shared() const noexcept + { + return Shared {*this}; + } +}; + +using OptionFieldClass = CommonOptionFieldClass; +using ConstOptionFieldClass = CommonOptionFieldClass; + +template +class CommonOptionWithSelectorFieldClass : public CommonOptionFieldClass +{ +private: + using typename CommonOptionFieldClass::_ThisCommonOptionFieldClass; + +protected: + using typename CommonFieldClass::_LibObjPtr; + using _ThisCommonOptionWithSelectorFieldClass = CommonOptionWithSelectorFieldClass; + +public: + using Shared = internal::SharedFieldClass, LibObjT>; + + explicit CommonOptionWithSelectorFieldClass(const _LibObjPtr libObjPtr) noexcept : + _ThisCommonOptionFieldClass {libObjPtr} + { + BT_ASSERT_DBG(this->isOptionWithSelector()); + } + + template + CommonOptionWithSelectorFieldClass( + const CommonOptionWithSelectorFieldClass& fc) noexcept : + _ThisCommonOptionFieldClass {fc} + { + } + + template + _ThisCommonOptionWithSelectorFieldClass& + operator=(const CommonOptionWithSelectorFieldClass& fc) noexcept + { + _ThisCommonOptionFieldClass::operator=(fc); + return *this; + } + + ConstFieldPath selectorFieldPath() const noexcept + { + return ConstFieldPath { + bt_field_class_option_with_selector_field_borrow_selector_field_path_const( + this->_libObjPtr())}; + } + + Shared shared() const noexcept + { + return Shared {*this}; + } +}; + +using OptionWithSelectorFieldClass = CommonOptionWithSelectorFieldClass; +using ConstOptionWithSelectorFieldClass = CommonOptionWithSelectorFieldClass; + +template +class CommonOptionWithBoolSelectorFieldClass : public CommonOptionWithSelectorFieldClass +{ +private: + using typename CommonFieldClass::_LibObjPtr; + + using typename CommonOptionWithSelectorFieldClass< + LibObjT>::_ThisCommonOptionWithSelectorFieldClass; + +public: + using Shared = + internal::SharedFieldClass, LibObjT>; + + explicit CommonOptionWithBoolSelectorFieldClass(const _LibObjPtr libObjPtr) noexcept : + _ThisCommonOptionWithSelectorFieldClass {libObjPtr} + { + BT_ASSERT_DBG(this->isOptionWithBoolSelector()); + } + + template + CommonOptionWithBoolSelectorFieldClass( + const CommonOptionWithBoolSelectorFieldClass& fc) noexcept : + _ThisCommonOptionWithSelectorFieldClass {fc} + { + } + + template + CommonOptionWithBoolSelectorFieldClass& + operator=(const CommonOptionWithBoolSelectorFieldClass& fc) noexcept + { + _ThisCommonOptionWithSelectorFieldClass::operator=(fc); + return *this; + } + + bool selectorIsReversed() const noexcept + { + return bt_field_class_option_with_selector_field_bool_selector_is_reversed( + this->_libObjPtr()); + } + + Shared shared() const noexcept + { + return Shared {*this}; + } +}; + +using OptionWithBoolSelectorFieldClass = CommonOptionWithBoolSelectorFieldClass; + +using ConstOptionWithBoolSelectorFieldClass = + CommonOptionWithBoolSelectorFieldClass; + +namespace internal { + +template +struct CommonOptionWithIntegerSelectorFieldClassSpec; + +// Functions specific to option field classes with unsigned integer ranges +template <> +struct CommonOptionWithIntegerSelectorFieldClassSpec final +{ + static const bt_integer_range_set_unsigned * + ranges(const bt_field_class * const libObjPtr) noexcept + { + return bt_field_class_option_with_selector_field_integer_unsigned_borrow_selector_ranges_const( + libObjPtr); + } +}; + +// Functions specific to option field classes with signed ranges +template <> +struct CommonOptionWithIntegerSelectorFieldClassSpec final +{ + static const bt_integer_range_set_signed * + ranges(const bt_field_class * const libObjPtr) noexcept + { + return bt_field_class_option_with_selector_field_integer_signed_borrow_selector_ranges_const( + libObjPtr); + } +}; + +} // namespace internal + +template +class CommonOptionWithIntegerSelectorFieldClass : public CommonOptionWithSelectorFieldClass +{ +private: + using typename CommonFieldClass::_LibObjPtr; + + using typename CommonOptionWithSelectorFieldClass< + LibObjT>::_ThisCommonOptionWithSelectorFieldClass; + + using _ThisCommonOptionWithIntegerSelectorFieldClass = + CommonOptionWithIntegerSelectorFieldClass; + +public: + using Shared = + internal::SharedFieldClass<_ThisCommonOptionWithIntegerSelectorFieldClass, LibObjT>; + + using RangeSet = RangeSetT; + + explicit CommonOptionWithIntegerSelectorFieldClass(const _LibObjPtr libObjPtr) noexcept : + _ThisCommonOptionWithSelectorFieldClass {libObjPtr} + { + BT_ASSERT_DBG(this->isOptionWithIntegerSelector()); + } + + template + CommonOptionWithIntegerSelectorFieldClass( + const CommonOptionWithIntegerSelectorFieldClass& fc) noexcept : + _ThisCommonOptionWithSelectorFieldClass {fc} + { + } + + template + _ThisCommonOptionWithIntegerSelectorFieldClass& + operator=(const CommonOptionWithIntegerSelectorFieldClass& fc) noexcept + { + _ThisCommonOptionWithSelectorFieldClass::operator=(fc); + return *this; + } + + RangeSet ranges() const noexcept + { + return RangeSet {internal::CommonOptionWithIntegerSelectorFieldClassSpec::ranges( + this->_libObjPtr())}; + } + + Shared shared() const noexcept + { + return Shared {*this}; + } +}; + +using OptionWithUnsignedIntegerSelectorFieldClass = + CommonOptionWithIntegerSelectorFieldClass; + +using ConstOptionWithUnsignedIntegerSelectorFieldClass = + CommonOptionWithIntegerSelectorFieldClass; + +using OptionWithSignedIntegerSelectorFieldClass = + CommonOptionWithIntegerSelectorFieldClass; + +using ConstOptionWithSignedIntegerSelectorFieldClass = + CommonOptionWithIntegerSelectorFieldClass; + +namespace internal { + +template +struct CommonVariantFieldClassOptionSpec; + +// Functions specific to mutable variant field class options +template <> +struct CommonVariantFieldClassOptionSpec final +{ + static bt_field_class *fieldClass(bt_field_class_variant_option * const libObjPtr) noexcept + { + return bt_field_class_variant_option_borrow_field_class(libObjPtr); + } +}; + +// Functions specific to constant variant field class options +template <> +struct CommonVariantFieldClassOptionSpec final +{ + static const bt_field_class * + fieldClass(const bt_field_class_variant_option * const libObjPtr) noexcept + { + return bt_field_class_variant_option_borrow_field_class_const(libObjPtr); + } +}; + +} // namespace internal + +template +class CommonVariantFieldClassOption : public internal::BorrowedObj +{ +private: + using typename internal::BorrowedObj::_ThisBorrowedObj; + using typename internal::BorrowedObj::_LibObjPtr; + + using _FieldClass = + typename std::conditional::value, ConstFieldClass, FieldClass>::type; + +public: + explicit CommonVariantFieldClassOption(const _LibObjPtr libObjPtr) noexcept : + _ThisBorrowedObj {libObjPtr} + { + } + + template + CommonVariantFieldClassOption(const CommonVariantFieldClassOption& fc) noexcept : + _ThisBorrowedObj {fc} + { + } + + template + CommonVariantFieldClassOption& + operator=(const CommonVariantFieldClassOption& fc) noexcept + { + _ThisBorrowedObj::operator=(fc); + return *this; + } + + bpstd::string_view name() const noexcept + { + return bt_field_class_variant_option_get_name(this->_libObjPtr()); + } + + ConstFieldClass fieldClass() const noexcept + { + return ConstFieldClass {internal::CommonVariantFieldClassOptionSpec< + const bt_field_class_variant_option>::fieldClass(this->_libObjPtr())}; + } + + _FieldClass fieldClass() noexcept + { + return _FieldClass { + internal::CommonVariantFieldClassOptionSpec::fieldClass(this->_libObjPtr())}; + } +}; + +using VariantFieldClassOption = CommonVariantFieldClassOption; + +using ConstVariantFieldClassOption = + CommonVariantFieldClassOption; + +namespace internal { + +template +struct ConstVariantWithIntegerSelectorFieldClassOptionSpec; + +// Functions specific to variant field class options with unsigned integer selector +template <> +struct ConstVariantWithIntegerSelectorFieldClassOptionSpec< + const bt_field_class_variant_with_selector_field_integer_unsigned_option> + final +{ + static const bt_integer_range_set_unsigned * + ranges(const bt_field_class_variant_with_selector_field_integer_unsigned_option + * const libObjPtr) noexcept + { + return bt_field_class_variant_with_selector_field_integer_unsigned_option_borrow_ranges_const( + libObjPtr); + } + + static const bt_field_class_variant_option * + asBaseOption(const bt_field_class_variant_with_selector_field_integer_unsigned_option + * const libObjPtr) noexcept + { + return bt_field_class_variant_with_selector_field_integer_unsigned_option_as_option_const( + libObjPtr); + } +}; + +// Functions specific to variant field class options with signed integer selector +template <> +struct ConstVariantWithIntegerSelectorFieldClassOptionSpec< + const bt_field_class_variant_with_selector_field_integer_signed_option> + final +{ + static const bt_integer_range_set_signed * + ranges(const bt_field_class_variant_with_selector_field_integer_signed_option + * const libObjPtr) noexcept + { + return bt_field_class_variant_with_selector_field_integer_signed_option_borrow_ranges_const( + libObjPtr); + } + + static const bt_field_class_variant_option * + asBaseOption(const bt_field_class_variant_with_selector_field_integer_signed_option + * const libObjPtr) noexcept + { + return bt_field_class_variant_with_selector_field_integer_signed_option_as_option_const( + libObjPtr); + } +}; + +} // namespace internal + +template +class ConstVariantWithIntegerSelectorFieldClassOption : public internal::BorrowedObj +{ +private: + using typename internal::BorrowedObj::_ThisBorrowedObj; + using typename internal::BorrowedObj::_LibObjPtr; + using _Spec = internal::ConstVariantWithIntegerSelectorFieldClassOptionSpec; + +public: + using RangeSet = typename std::conditional< + std::is_same< + LibObjT, + const bt_field_class_variant_with_selector_field_integer_unsigned_option>::value, + ConstUnsignedIntegerRangeSet, ConstSignedIntegerRangeSet>::type; + + explicit ConstVariantWithIntegerSelectorFieldClassOption(const _LibObjPtr libObjPtr) noexcept : + _ThisBorrowedObj {libObjPtr} + { + } + + template + ConstVariantWithIntegerSelectorFieldClassOption( + const ConstVariantWithIntegerSelectorFieldClassOption& fc) noexcept : + _ThisBorrowedObj {fc} + { + } + + template + ConstVariantWithIntegerSelectorFieldClassOption& + operator=(const ConstVariantWithIntegerSelectorFieldClassOption& fc) noexcept + { + _ThisBorrowedObj::operator=(fc); + return *this; + } + + ConstVariantFieldClassOption asBaseOption() const noexcept + { + return ConstVariantFieldClassOption {_Spec::asBaseOption(this->_libObjPtr())}; + } + + bpstd::string_view name() const noexcept + { + return this->asBaseOption().name(); + } + + ConstFieldClass fieldClass() const noexcept + { + return this->asBaseOption().fieldClass(); + } + + RangeSet ranges() const noexcept + { + return RangeSet {_Spec::ranges(this->_libObjPtr())}; + } +}; + +using ConstVariantWithUnsignedIntegerSelectorFieldClassOption = + ConstVariantWithIntegerSelectorFieldClassOption< + const bt_field_class_variant_with_selector_field_integer_unsigned_option>; + +using ConstVariantWithSignedIntegerSelectorFieldClassOption = + ConstVariantWithIntegerSelectorFieldClassOption< + const bt_field_class_variant_with_selector_field_integer_signed_option>; + +namespace internal { + +template +struct CommonVariantFieldClassSpec; + +// Functions specific to mutable variant field classes +template <> +struct CommonVariantFieldClassSpec final +{ + static bt_field_class_variant_option *optionByIndex(bt_field_class * const libObjPtr, + const std::uint64_t index) noexcept + { + return bt_field_class_variant_borrow_option_by_index(libObjPtr, index); + } + + static bt_field_class_variant_option *optionByName(bt_field_class * const libObjPtr, + const char * const name) noexcept + { + return bt_field_class_variant_borrow_option_by_name(libObjPtr, name); + } +}; + +// Functions specific to constant variant field classes +template <> +struct CommonVariantFieldClassSpec final +{ + static const bt_field_class_variant_option * + optionByIndex(const bt_field_class * const libObjPtr, const std::uint64_t index) noexcept + { + return bt_field_class_variant_borrow_option_by_index_const(libObjPtr, index); + } + + static const bt_field_class_variant_option *optionByName(const bt_field_class * const libObjPtr, + const char * const name) noexcept + { + return bt_field_class_variant_borrow_option_by_name_const(libObjPtr, name); + } +}; + +} // namespace internal + +template +class CommonVariantFieldClass : public CommonFieldClass +{ +private: + using typename CommonFieldClass::_ThisCommonFieldClass; + +protected: + using typename CommonFieldClass::_LibObjPtr; + using _ThisCommonVariantFieldClass = CommonVariantFieldClass; + +public: + using Shared = internal::SharedFieldClass, LibObjT>; + + using Option = + typename std::conditional::value, ConstVariantFieldClassOption, + VariantFieldClassOption>::type; + + explicit CommonVariantFieldClass(const _LibObjPtr libObjPtr) noexcept : + _ThisCommonFieldClass {libObjPtr} + { + BT_ASSERT_DBG(this->isVariant()); + } + + template + CommonVariantFieldClass(const CommonVariantFieldClass& fc) noexcept : + _ThisCommonFieldClass {fc} + { + } + + template + _ThisCommonVariantFieldClass& + operator=(const CommonVariantFieldClass& fc) noexcept + { + _ThisCommonFieldClass::operator=(fc); + return *this; + } + + std::uint64_t size() const noexcept + { + return bt_field_class_variant_get_option_count(this->_libObjPtr()); + } + + ConstVariantFieldClassOption operator[](const std::uint64_t index) const noexcept + { + return ConstVariantFieldClassOption { + internal::CommonVariantFieldClassSpec::optionByIndex( + this->_libObjPtr(), index)}; + } + + Option operator[](const std::uint64_t index) noexcept + { + return Option {internal::CommonVariantFieldClassSpec::optionByIndex( + this->_libObjPtr(), index)}; + } + + nonstd::optional + operator[](const char * const name) const noexcept + { + const auto libObjPtr = + internal::CommonVariantFieldClassSpec::optionByName( + this->_libObjPtr(), name); + + if (libObjPtr) { + return ConstVariantFieldClassOption {libObjPtr}; + } + + return nonstd::nullopt; + } + + nonstd::optional + operator[](const std::string& name) const noexcept + { + return (*this)[name.data()]; + } + + nonstd::optional