From: Philippe Proulx Date: Thu, 14 Jan 2021 20:07:52 +0000 (-0500) Subject: Add missing C++ interface for the libbabeltrace2 trace IR API X-Git-Url: http://git.efficios.com/?p=babeltrace.git;a=commitdiff_plain;h=74fc764df204365c04acdff600bc6268fde5984a Add missing C++ interface for the libbabeltrace2 trace IR API This patch adds C++ wrappers for the following Babeltrace 2 objects: * Event * Packet * Stream * Trace * Event class * Stream class * Trace class Those are the missing wrappers to complete trace IR API wrapping within `src/cpp-common/bt2`. I used a single file (`src/cpp-common/bt2/trace-ir.hpp`) to implement those wrappers as there are many interdependencies between them. For example, you can borrow the parent stream class S of an event class E while you can also borrow E from S. This means some methods need to be implemented after the full definitions of classes on which they depend. Doing this in dedicated files while also making sure that you can include any header in any order is not straightforward. With this patch, simply include `cpp-common/bt2/trace-ir.hpp` to get the whole trace IR C++ API. Implicitly convert from a mutable object 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`. Many of the new common classes become friends of `bt2::CommonFieldClass`, `bt2::CommonValue`, and `bt2::CommonIntegerRangeSet` to access their _libObjPtr() method. The new creation methods are: * Create a packet with bt2::Stream::createPacket(). * Create a stream with bt2::StreamClass::instantiate(). * Create a trace with bt2::TraceClass::instantiate(). * Create an event class with bt2::StreamClass::createEventClass(). * Create a stream class with bt2::TraceClass::createStreamClass(). * Create a field class with one of the bt2::TraceClass::create*FieldClass() methods. Access the class of an event/stream/trace object with its cls() method. As of this patch, you cannot create a trace class. This will be possible when we add a self component wrapper. This patch doesn't wrap the trace and trace class destruction listener APIs. Signed-off-by: Philippe Proulx Change-Id: I1f2977b0c5d5eba35b468a9748216f2201f205dd Reviewed-on: https://review.lttng.org/c/babeltrace/+/4688 --- diff --git a/src/cpp-common/bt2/field-class.hpp b/src/cpp-common/bt2/field-class.hpp index a1cba0bf..787a8cb3 100644 --- a/src/cpp-common/bt2/field-class.hpp +++ b/src/cpp-common/bt2/field-class.hpp @@ -113,6 +113,15 @@ class ConstVariantWithIntegerSelectorFieldClassOption; template class CommonVariantWithIntegerSelectorFieldClass; +template +class CommonEventClass; + +template +class CommonStreamClass; + +template +class CommonTraceClass; + enum class FieldClassType { BOOL = BT_FIELD_CLASS_TYPE_BOOL, @@ -160,6 +169,13 @@ class CommonFieldClass : public internal::BorrowedObj ConstVariantWithIntegerSelectorFieldClassOption< const bt_field_class_variant_with_selector_field_integer_signed_option>>; + // Allow *FieldClass() to call `fc._libObjPtr()` + friend class CommonEventClass; + friend class CommonStreamClass; + + // Allow create*FieldClass() to call `fc._libObjPtr()` + friend class CommonTraceClass; + private: using typename internal::BorrowedObj::_ThisBorrowedObj; diff --git a/src/cpp-common/bt2/integer-range-set.hpp b/src/cpp-common/bt2/integer-range-set.hpp index 8d686496..a56a4566 100644 --- a/src/cpp-common/bt2/integer-range-set.hpp +++ b/src/cpp-common/bt2/integer-range-set.hpp @@ -135,6 +135,9 @@ class ConstVariantWithIntegerSelectorFieldClassOption; template class CommonVariantWithIntegerSelectorFieldClass; +template +class CommonTraceClass; + template class CommonIntegerRangeSet final : public internal::BorrowedObj { @@ -155,6 +158,9 @@ class CommonIntegerRangeSet final : public internal::BorrowedObj ConstVariantWithIntegerSelectorFieldClassOption< const bt_field_class_variant_with_selector_field_integer_signed_option>>; + // Allow create*FieldClass() to call `ranges._libObjPtr()` + friend class CommonTraceClass; + private: using typename internal::BorrowedObj::_ThisBorrowedObj; using typename internal::BorrowedObj::_LibObjPtr; diff --git a/src/cpp-common/bt2/trace-ir.hpp b/src/cpp-common/bt2/trace-ir.hpp new file mode 100644 index 00000000..dd79fc44 --- /dev/null +++ b/src/cpp-common/bt2/trace-ir.hpp @@ -0,0 +1,2207 @@ +/* + * Copyright (c) 2020-2021 Philippe Proulx + * + * SPDX-License-Identifier: MIT + */ + +#ifndef BABELTRACE_CPP_COMMON_BT2_TRACE_IR_HPP +#define BABELTRACE_CPP_COMMON_BT2_TRACE_IR_HPP + +#include +#include +#include + +#include "internal/borrowed-obj.hpp" +#include "cpp-common/optional.hpp" +#include "cpp-common/string_view.hpp" +#include "clock-class.hpp" +#include "clock-snapshot.hpp" +#include "field-class.hpp" +#include "field.hpp" +#include "value.hpp" +#include "internal/utils.hpp" + +namespace bt2 { + +template +class CommonEvent; + +template +class CommonPacket; + +template +class CommonStream; + +template +class CommonTrace; + +template +class CommonEventClass; + +template +class CommonStreamClass; + +template +class CommonTraceClass; + +namespace internal { + +template +struct CommonEventSpec; + +// Functions specific to mutable events +template <> +struct CommonEventSpec final +{ + static bt_event_class *cls(bt_event * const libObjPtr) noexcept + { + return bt_event_borrow_class(libObjPtr); + } + + static bt_stream *stream(bt_event * const libObjPtr) noexcept + { + return bt_event_borrow_stream(libObjPtr); + } + + static bt_packet *packet(bt_event * const libObjPtr) noexcept + { + return bt_event_borrow_packet(libObjPtr); + } + + static bt_field *payloadField(bt_event * const libObjPtr) noexcept + { + return bt_event_borrow_payload_field(libObjPtr); + } + + static bt_field *specificContextField(bt_event * const libObjPtr) noexcept + { + return bt_event_borrow_specific_context_field(libObjPtr); + } + + static bt_field *commonContextField(bt_event * const libObjPtr) noexcept + { + return bt_event_borrow_common_context_field(libObjPtr); + } +}; + +// Functions specific to constant events +template <> +struct CommonEventSpec final +{ + static const bt_event_class *cls(const bt_event * const libObjPtr) noexcept + { + return bt_event_borrow_class_const(libObjPtr); + } + + static const bt_stream *stream(const bt_event * const libObjPtr) noexcept + { + return bt_event_borrow_stream_const(libObjPtr); + } + + static const bt_packet *packet(const bt_event * const libObjPtr) noexcept + { + return bt_event_borrow_packet_const(libObjPtr); + } + + static const bt_field *payloadField(const bt_event * const libObjPtr) noexcept + { + return bt_event_borrow_payload_field_const(libObjPtr); + } + + static const bt_field *specificContextField(const bt_event * const libObjPtr) noexcept + { + return bt_event_borrow_specific_context_field_const(libObjPtr); + } + + static const bt_field *commonContextField(const bt_event * const libObjPtr) noexcept + { + return bt_event_borrow_common_context_field_const(libObjPtr); + } +}; + +} // namespace internal + +template +class CommonEvent final : public internal::BorrowedObj +{ +private: + using typename internal::BorrowedObj::_ThisBorrowedObj; + using typename internal::BorrowedObj::_LibObjPtr; + using _ConstSpec = internal::CommonEventSpec; + using _Spec = internal::CommonEventSpec; + + using _Packet = + typename std::conditional::value, CommonPacket, + CommonPacket>::type; + + using _Stream = + typename std::conditional::value, CommonStream, + CommonStream>::type; + + using _StructureField = typename std::conditional::value, + ConstStructureField, StructureField>::type; + +public: + using Class = typename std::conditional::value, + CommonEventClass, + CommonEventClass>::type; + + explicit CommonEvent(const _LibObjPtr libObjPtr) noexcept : _ThisBorrowedObj {libObjPtr} + { + } + + template + CommonEvent(const CommonEvent& event) noexcept : _ThisBorrowedObj {event} + { + } + + template + CommonEvent& operator=(const CommonEvent& event) noexcept + { + _ThisBorrowedObj::operator=(event); + return *this; + } + + CommonEventClass cls() const noexcept; + Class cls() noexcept; + CommonStream stream() const noexcept; + _Stream stream() noexcept; + nonstd::optional> packet() const noexcept; + nonstd::optional<_Packet> packet() noexcept; + + nonstd::optional payloadField() const noexcept + { + const auto libObjPtr = _ConstSpec::payloadField(this->_libObjPtr()); + + if (libObjPtr) { + return ConstStructureField {libObjPtr}; + } + + return nonstd::nullopt; + } + + nonstd::optional<_StructureField> payloadField() noexcept + { + const auto libObjPtr = _Spec::payloadField(this->_libObjPtr()); + + if (libObjPtr) { + return _StructureField {libObjPtr}; + } + + return nonstd::nullopt; + } + + nonstd::optional specificContextField() const noexcept + { + const auto libObjPtr = _ConstSpec::specificContextField(this->_libObjPtr()); + + if (libObjPtr) { + return ConstStructureField {libObjPtr}; + } + + return nonstd::nullopt; + } + + nonstd::optional<_StructureField> specificContextField() noexcept + { + const auto libObjPtr = _Spec::specificContextField(this->_libObjPtr()); + + if (libObjPtr) { + return _StructureField {libObjPtr}; + } + + return nonstd::nullopt; + } + + nonstd::optional commonContextField() const noexcept + { + const auto libObjPtr = _ConstSpec::commonContextField(this->_libObjPtr()); + + if (libObjPtr) { + return ConstStructureField {libObjPtr}; + } + + return nonstd::nullopt; + } + + nonstd::optional<_StructureField> commonContextField() noexcept + { + const auto libObjPtr = _Spec::commonContextField(this->_libObjPtr()); + + if (libObjPtr) { + return _StructureField {libObjPtr}; + } + + return nonstd::nullopt; + } +}; + +using Event = CommonEvent; +using ConstEvent = CommonEvent; + +namespace internal { + +struct PacketRefFuncs final +{ + static void get(const bt_packet * const libObjPtr) + { + bt_packet_get_ref(libObjPtr); + } + + static void put(const bt_packet * const libObjPtr) + { + bt_packet_put_ref(libObjPtr); + } +}; + +template +struct CommonPacketSpec; + +// Functions specific to mutable packets +template <> +struct CommonPacketSpec final +{ + static bt_stream *stream(bt_packet * const libObjPtr) noexcept + { + return bt_packet_borrow_stream(libObjPtr); + } + + static bt_field *contextField(bt_packet * const libObjPtr) noexcept + { + return bt_packet_borrow_context_field(libObjPtr); + } +}; + +// Functions specific to constant packets +template <> +struct CommonPacketSpec final +{ + static const bt_stream *stream(const bt_packet * const libObjPtr) noexcept + { + return bt_packet_borrow_stream_const(libObjPtr); + } + + static const bt_field *contextField(const bt_packet * const libObjPtr) noexcept + { + return bt_packet_borrow_context_field_const(libObjPtr); + } +}; + +} // namespace internal + +template +class CommonPacket final : public internal::BorrowedObj +{ +private: + using typename internal::BorrowedObj::_ThisBorrowedObj; + using typename internal::BorrowedObj::_LibObjPtr; + using _ConstSpec = internal::CommonPacketSpec; + using _Spec = internal::CommonPacketSpec; + using _ThisCommonPacket = CommonPacket; + + using _Stream = + typename std::conditional::value, CommonStream, + CommonStream>::type; + + using _StructureField = typename std::conditional::value, + ConstStructureField, StructureField>::type; + +public: + using Shared = internal::SharedObj<_ThisCommonPacket, LibObjT, internal::PacketRefFuncs>; + + explicit CommonPacket(const _LibObjPtr libObjPtr) noexcept : _ThisBorrowedObj {libObjPtr} + { + } + + template + CommonPacket(const CommonPacket& packet) noexcept : _ThisBorrowedObj {packet} + { + } + + template + _ThisCommonPacket& operator=(const CommonPacket& packet) noexcept + { + _ThisBorrowedObj::operator=(packet); + return *this; + } + + CommonStream stream() const noexcept; + _Stream stream() noexcept; + + nonstd::optional contextField() const noexcept + { + const auto libObjPtr = _ConstSpec::contextField(this->_libObjPtr()); + + if (libObjPtr) { + return ConstStructureField {libObjPtr}; + } + + return nonstd::nullopt; + } + + nonstd::optional<_StructureField> contextField() noexcept + { + const auto libObjPtr = _Spec::contextField(this->_libObjPtr()); + + if (libObjPtr) { + return _StructureField {libObjPtr}; + } + + return nonstd::nullopt; + } + + Shared shared() const noexcept + { + return Shared {*this}; + } +}; + +using Packet = CommonPacket; +using ConstPacket = CommonPacket; + +template +nonstd::optional CommonEvent::packet() const noexcept +{ + const auto libObjPtr = _ConstSpec::packet(this->_libObjPtr()); + + if (libObjPtr) { + return ConstPacket {libObjPtr}; + } + + return nonstd::nullopt; +} + +template +nonstd::optional::_Packet> CommonEvent::packet() noexcept +{ + const auto libObjPtr = _Spec::packet(this->_libObjPtr()); + + if (libObjPtr) { + return _Packet {libObjPtr}; + } + + return nonstd::nullopt; +} + +namespace internal { + +struct StreamRefFuncs final +{ + static void get(const bt_stream * const libObjPtr) + { + bt_stream_get_ref(libObjPtr); + } + + static void put(const bt_stream * const libObjPtr) + { + bt_stream_put_ref(libObjPtr); + } +}; + +template +struct CommonStreamSpec; + +// Functions specific to mutable streams +template <> +struct CommonStreamSpec final +{ + static bt_stream_class *cls(bt_stream * const libObjPtr) noexcept + { + return bt_stream_borrow_class(libObjPtr); + } + + static bt_trace *trace(bt_stream * const libObjPtr) noexcept + { + return bt_stream_borrow_trace(libObjPtr); + } + + static bt_value *userAttributes(bt_stream * const libObjPtr) noexcept + { + return bt_stream_borrow_user_attributes(libObjPtr); + } +}; + +// Functions specific to constant streams +template <> +struct CommonStreamSpec final +{ + static const bt_stream_class *cls(const bt_stream * const libObjPtr) noexcept + { + return bt_stream_borrow_class_const(libObjPtr); + } + + static const bt_trace *trace(const bt_stream * const libObjPtr) noexcept + { + return bt_stream_borrow_trace_const(libObjPtr); + } + + static const bt_value *userAttributes(const bt_stream * const libObjPtr) noexcept + { + return bt_stream_borrow_user_attributes_const(libObjPtr); + } +}; + +} // namespace internal + +template +class CommonStream final : public internal::BorrowedObj +{ +private: + using typename internal::BorrowedObj::_ThisBorrowedObj; + using typename internal::BorrowedObj::_LibObjPtr; + using _ConstSpec = internal::CommonStreamSpec; + using _Spec = internal::CommonStreamSpec; + using _ThisCommonStream = CommonStream; + + using _Trace = + typename std::conditional::value, CommonTrace, + CommonTrace>::type; + +public: + using Shared = internal::SharedObj<_ThisCommonStream, LibObjT, internal::StreamRefFuncs>; + + using Class = typename std::conditional::value, + CommonStreamClass, + CommonStreamClass>::type; + + using UserAttributes = + typename std::conditional::value, ConstMapValue, MapValue>::type; + + explicit CommonStream(const _LibObjPtr libObjPtr) noexcept : _ThisBorrowedObj {libObjPtr} + { + } + + template + CommonStream(const CommonStream& stream) noexcept : _ThisBorrowedObj {stream} + { + } + + template + _ThisCommonStream& operator=(const CommonStream& stream) noexcept + { + _ThisBorrowedObj::operator=(stream); + return *this; + } + + Packet::Shared createPacket() + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + const auto libObjPtr = bt_packet_create(this->_libObjPtr()); + + internal::validateCreatedObjPtr(libObjPtr); + return Packet::Shared {Packet {libObjPtr}}; + } + + CommonStreamClass cls() const noexcept; + Class cls() noexcept; + CommonTrace trace() const noexcept; + _Trace trace() noexcept; + + std::uint64_t id() const noexcept + { + return bt_stream_get_id(this->_libObjPtr()); + } + + void name(const char * const name) + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + const auto status = bt_stream_set_name(this->_libObjPtr(), name); + + if (status == BT_STREAM_SET_NAME_STATUS_MEMORY_ERROR) { + throw LibMemoryError {}; + } + } + + void name(const std::string& name) + { + this->name(name.data()); + } + + nonstd::optional name() const noexcept + { + const auto name = bt_stream_get_name(this->_libObjPtr()); + + if (name) { + return name; + } + + return nonstd::nullopt; + } + + template + void userAttributes(const CommonMapValue& userAttrs) + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + bt_stream_set_user_attributes(this->_libObjPtr(), userAttrs._libObjPtr()); + } + + ConstMapValue userAttributes() const noexcept + { + return ConstMapValue {_ConstSpec::userAttributes(this->_libObjPtr())}; + } + + UserAttributes userAttributes() noexcept + { + return UserAttributes {_Spec::userAttributes(this->_libObjPtr())}; + } + + Shared shared() const noexcept + { + return Shared {*this}; + } +}; + +using Stream = CommonStream; +using ConstStream = CommonStream; + +template +ConstStream CommonEvent::stream() const noexcept +{ + return ConstStream {_ConstSpec::stream(this->_libObjPtr())}; +} + +template +typename CommonEvent::_Stream CommonEvent::stream() noexcept +{ + return _Stream {_Spec::stream(this->_libObjPtr())}; +} + +template +ConstStream CommonPacket::stream() const noexcept +{ + return ConstStream {_ConstSpec::stream(this->_libObjPtr())}; +} + +template +typename CommonPacket::_Stream CommonPacket::stream() noexcept +{ + return _Stream {_Spec::stream(this->_libObjPtr())}; +} + +namespace internal { + +struct TraceRefFuncs final +{ + static void get(const bt_trace * const libObjPtr) + { + bt_trace_get_ref(libObjPtr); + } + + static void put(const bt_trace * const libObjPtr) + { + bt_trace_put_ref(libObjPtr); + } +}; + +template +struct CommonTraceSpec; + +// Functions specific to mutable traces +template <> +struct CommonTraceSpec final +{ + static bt_trace_class *cls(bt_trace * const libObjPtr) noexcept + { + return bt_trace_borrow_class(libObjPtr); + } + + static bt_stream *streamByIndex(bt_trace * const libObjPtr, const std::uint64_t index) noexcept + { + return bt_trace_borrow_stream_by_index(libObjPtr, index); + } + + static bt_stream *streamById(bt_trace * const libObjPtr, const std::uint64_t id) noexcept + { + return bt_trace_borrow_stream_by_id(libObjPtr, id); + } + + static bt_value *userAttributes(bt_trace * const libObjPtr) noexcept + { + return bt_trace_borrow_user_attributes(libObjPtr); + } +}; + +// Functions specific to constant traces +template <> +struct CommonTraceSpec final +{ + static const bt_trace_class *cls(const bt_trace * const libObjPtr) noexcept + { + return bt_trace_borrow_class_const(libObjPtr); + } + + static const bt_stream *streamByIndex(const bt_trace * const libObjPtr, + const std::uint64_t index) noexcept + { + return bt_trace_borrow_stream_by_index_const(libObjPtr, index); + } + + static const bt_stream *streamById(const bt_trace * const libObjPtr, + const std::uint64_t id) noexcept + { + return bt_trace_borrow_stream_by_id_const(libObjPtr, id); + } + + static const bt_value *userAttributes(const bt_trace * const libObjPtr) noexcept + { + return bt_trace_borrow_user_attributes_const(libObjPtr); + } +}; + +} // namespace internal + +template +class CommonTrace final : public internal::BorrowedObj +{ + // Allow instantiate() to call `trace._libObjPtr()` + friend class CommonStreamClass; + +private: + using typename internal::BorrowedObj::_ThisBorrowedObj; + using typename internal::BorrowedObj::_LibObjPtr; + using _ConstSpec = internal::CommonTraceSpec; + using _Spec = internal::CommonTraceSpec; + using _ThisCommonTrace = CommonTrace; + + using _Stream = + typename std::conditional::value, CommonStream, + CommonStream>::type; + +public: + using Shared = internal::SharedObj<_ThisCommonTrace, LibObjT, internal::TraceRefFuncs>; + + using Class = typename std::conditional::value, + CommonTraceClass, + CommonTraceClass>::type; + + using UserAttributes = + typename std::conditional::value, ConstMapValue, MapValue>::type; + + struct ConstEnvironmentEntry + { + bpstd::string_view name; + ConstValue value; + }; + + explicit CommonTrace(const _LibObjPtr libObjPtr) noexcept : _ThisBorrowedObj {libObjPtr} + { + } + + template + CommonTrace(const CommonTrace& trace) noexcept : _ThisBorrowedObj {trace} + { + } + + template + _ThisCommonTrace& operator=(const CommonTrace& trace) noexcept + { + _ThisBorrowedObj::operator=(trace); + return *this; + } + + CommonTraceClass cls() const noexcept; + Class cls() noexcept; + + void name(const char * const name) + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + const auto status = bt_trace_set_name(this->_libObjPtr(), name); + + if (status == BT_TRACE_SET_NAME_STATUS_MEMORY_ERROR) { + throw LibMemoryError {}; + } + } + + void name(const std::string& name) + { + this->name(name.data()); + } + + nonstd::optional name() const noexcept + { + const auto name = bt_trace_get_name(this->_libObjPtr()); + + if (name) { + return name; + } + + return nonstd::nullopt; + } + + void uuid(const std::uint8_t * const uuid) noexcept + { + bt_trace_set_uuid(this->_libObjPtr(), uuid); + } + + nonstd::optional uuid() const noexcept + { + const auto uuid = bt_trace_get_uuid(this->_libObjPtr()); + + if (uuid) { + return bt2_common::UuidView {uuid}; + } + + return nonstd::nullopt; + } + + std::uint64_t size() const noexcept + { + return bt_trace_get_stream_count(this->_libObjPtr()); + } + + ConstStream operator[](const std::uint64_t index) const noexcept + { + return ConstStream {_ConstSpec::streamByIndex(this->_libObjPtr(), index)}; + } + + _Stream operator[](const std::uint64_t index) noexcept + { + return _Stream {_Spec::streamByIndex(this->_libObjPtr(), index)}; + } + + nonstd::optional streamById(const std::uint64_t id) const noexcept + { + const auto libObjPtr = _ConstSpec::streamById(this->_libObjPtr(), id); + + if (libObjPtr) { + return ConstStream {libObjPtr}; + } + + return nonstd::nullopt; + } + + nonstd::optional<_Stream> streamById(const std::uint64_t id) noexcept + { + const auto libObjPtr = _Spec::streamById(this->_libObjPtr(), id); + + if (libObjPtr) { + return _Stream {libObjPtr}; + } + + return nonstd::nullopt; + } + + void environmentEntry(const char * const name, const std::int64_t val) + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + const auto status = bt_trace_set_environment_entry_integer(this->_libObjPtr(), name, val); + + if (status == BT_TRACE_SET_ENVIRONMENT_ENTRY_STATUS_MEMORY_ERROR) { + throw LibMemoryError {}; + } + } + + void environmentEntry(const std::string& name, const std::int64_t val) + { + this->environmentEntry(name.data(), val); + } + + void environmentEntry(const char * const name, const char * const val) + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + const auto status = bt_trace_set_environment_entry_string(this->_libObjPtr(), name, val); + + if (status == BT_TRACE_SET_ENVIRONMENT_ENTRY_STATUS_MEMORY_ERROR) { + throw LibMemoryError {}; + } + } + + void environmentEntry(const std::string& name, const char * const val) + { + this->environmentEntry(name.data(), val); + } + + void environmentEntry(const char * const name, const std::string& val) + { + this->environmentEntry(name, val.data()); + } + + void environmentEntry(const std::string& name, const std::string& val) + { + this->environmentEntry(name.data(), val.data()); + } + + std::uint64_t environmentSize() const noexcept + { + return bt_trace_get_environment_entry_count(this->_libObjPtr()); + } + + ConstEnvironmentEntry environmentEntry(const std::uint64_t index) const noexcept + { + const char *name; + const bt_value *libObjPtr; + + bt_trace_borrow_environment_entry_by_index_const(this->_libObjPtr(), index, &name, + &libObjPtr); + return ConstEnvironmentEntry {name, ConstValue {libObjPtr}}; + } + + nonstd::optional environmentEntry(const char * const name) const noexcept + { + const auto libObjPtr = + bt_trace_borrow_environment_entry_value_by_name_const(this->_libObjPtr(), name); + + if (libObjPtr) { + return ConstValue {libObjPtr}; + } + + return nonstd::nullopt; + } + + nonstd::optional environmentEntry(const std::string& name) const noexcept + { + return this->environmentEntry(name.data()); + } + + template + void userAttributes(const CommonMapValue& userAttrs) + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + bt_trace_set_user_attributes(this->_libObjPtr(), userAttrs._libObjPtr()); + } + + ConstMapValue userAttributes() const noexcept + { + return ConstMapValue {_ConstSpec::userAttributes(this->_libObjPtr())}; + } + + UserAttributes userAttributes() noexcept + { + return UserAttributes {_Spec::userAttributes(this->_libObjPtr())}; + } + + Shared shared() const noexcept + { + return Shared {*this}; + } +}; + +using Trace = CommonTrace; +using ConstTrace = CommonTrace; + +template +ConstTrace CommonStream::trace() const noexcept +{ + return ConstTrace {_ConstSpec::trace(this->_libObjPtr())}; +} + +template +typename CommonStream::_Trace CommonStream::trace() noexcept +{ + return _Trace {_Spec::trace(this->_libObjPtr())}; +} + +namespace internal { + +struct EventClassRefFuncs final +{ + static void get(const bt_event_class * const libObjPtr) + { + bt_event_class_get_ref(libObjPtr); + } + + static void put(const bt_event_class * const libObjPtr) + { + bt_event_class_put_ref(libObjPtr); + } +}; + +template +struct CommonEventClassSpec; + +// Functions specific to mutable event classes +template <> +struct CommonEventClassSpec final +{ + static bt_stream_class *streamClass(bt_event_class * const libObjPtr) noexcept + { + return bt_event_class_borrow_stream_class(libObjPtr); + } + + static bt_field_class *payloadFieldClass(bt_event_class * const libObjPtr) noexcept + { + return bt_event_class_borrow_payload_field_class(libObjPtr); + } + + static bt_field_class *specificContextFieldClass(bt_event_class * const libObjPtr) noexcept + { + return bt_event_class_borrow_specific_context_field_class(libObjPtr); + } + + static bt_value *userAttributes(bt_event_class * const libObjPtr) noexcept + { + return bt_event_class_borrow_user_attributes(libObjPtr); + } +}; + +// Functions specific to constant event classes +template <> +struct CommonEventClassSpec final +{ + static const bt_stream_class *streamClass(const bt_event_class * const libObjPtr) noexcept + { + return bt_event_class_borrow_stream_class_const(libObjPtr); + } + + static const bt_field_class *payloadFieldClass(const bt_event_class * const libObjPtr) noexcept + { + return bt_event_class_borrow_payload_field_class_const(libObjPtr); + } + + static const bt_field_class * + specificContextFieldClass(const bt_event_class * const libObjPtr) noexcept + { + return bt_event_class_borrow_specific_context_field_class_const(libObjPtr); + } + + static const bt_value *userAttributes(const bt_event_class * const libObjPtr) noexcept + { + return bt_event_class_borrow_user_attributes_const(libObjPtr); + } +}; + +} // namespace internal + +template +class CommonEventClass final : public internal::BorrowedObj +{ +private: + using typename internal::BorrowedObj::_ThisBorrowedObj; + using typename internal::BorrowedObj::_LibObjPtr; + using _ConstSpec = internal::CommonEventClassSpec; + using _Spec = internal::CommonEventClassSpec; + using _ThisCommonEventClass = CommonEventClass; + + using _StreamClass = typename std::conditional::value, + CommonStreamClass, + CommonStreamClass>::type; + + using _StructureFieldClass = + typename std::conditional::value, ConstStructureFieldClass, + StructureFieldClass>::type; + +public: + using Shared = + internal::SharedObj<_ThisCommonEventClass, LibObjT, internal::EventClassRefFuncs>; + + using UserAttributes = + typename std::conditional::value, ConstMapValue, MapValue>::type; + + enum class LogLevel + { + EMERGENCY = BT_EVENT_CLASS_LOG_LEVEL_EMERGENCY, + ALERT = BT_EVENT_CLASS_LOG_LEVEL_ALERT, + CRITICAL = BT_EVENT_CLASS_LOG_LEVEL_CRITICAL, + ERROR = BT_EVENT_CLASS_LOG_LEVEL_ERROR, + WARNING = BT_EVENT_CLASS_LOG_LEVEL_WARNING, + NOTICE = BT_EVENT_CLASS_LOG_LEVEL_NOTICE, + INFO = BT_EVENT_CLASS_LOG_LEVEL_INFO, + DEBUG_SYSTEM = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM, + DEBUG_PROGRAM = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM, + DEBUG_PROCESS = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS, + DEBUG_MODULE = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE, + DEBUG_UNIT = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT, + DEBUG_FUNCTION = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION, + DEBUG_LINE = BT_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE, + DEBUG = BT_EVENT_CLASS_LOG_LEVEL_DEBUG, + }; + + explicit CommonEventClass(const _LibObjPtr libObjPtr) noexcept : _ThisBorrowedObj {libObjPtr} + { + } + + template + CommonEventClass(const CommonEventClass& eventClass) noexcept : + _ThisBorrowedObj {eventClass} + { + } + + template + _ThisCommonEventClass& operator=(const CommonEventClass& eventClass) noexcept + { + _ThisBorrowedObj::operator=(eventClass); + return *this; + } + + CommonStreamClass streamClass() const noexcept; + _StreamClass streamClass() noexcept; + + std::uint64_t id() const noexcept + { + return bt_event_class_get_id(this->_libObjPtr()); + } + + void name(const char * const name) + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + const auto status = bt_event_class_set_name(this->_libObjPtr(), name); + + if (status == BT_EVENT_CLASS_SET_NAME_STATUS_MEMORY_ERROR) { + throw LibMemoryError {}; + } + } + + void name(const std::string& name) + { + this->name(name.data()); + } + + nonstd::optional name() const noexcept + { + const auto name = bt_event_class_get_name(this->_libObjPtr()); + + if (name) { + return name; + } + + return nonstd::nullopt; + } + + void logLevel(const LogLevel logLevel) noexcept + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + bt_event_class_set_log_level(this->_libObjPtr(), + static_cast(logLevel)); + } + + nonstd::optional logLevel() const noexcept + { + bt_event_class_log_level libLogLevel; + const auto avail = bt_event_class_get_log_level(this->_libObjPtr(), &libLogLevel); + + if (avail == BT_PROPERTY_AVAILABILITY_AVAILABLE) { + return static_cast(libLogLevel); + } + + return nonstd::nullopt; + } + + void emfUri(const char * const emfUri) + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + const auto status = bt_event_class_set_emf_uri(this->_libObjPtr(), emfUri); + + if (status == BT_EVENT_CLASS_SET_EMF_URI_STATUS_MEMORY_ERROR) { + throw LibMemoryError {}; + } + } + + void emfUri(const std::string& emfUri) + { + this->emfUri(emfUri.data()); + } + + nonstd::optional emfUri() const noexcept + { + const auto emfUri = bt_event_class_get_emf_uri(this->_libObjPtr()); + + if (emfUri) { + return emfUri; + } + + return nonstd::nullopt; + } + + void payloadFieldClass(const StructureFieldClass& fc) + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + const auto status = + bt_event_class_set_payload_field_class(this->_libObjPtr(), fc._libObjPtr()); + + if (status == BT_EVENT_CLASS_SET_FIELD_CLASS_STATUS_MEMORY_ERROR) { + throw LibMemoryError {}; + } + } + + nonstd::optional payloadFieldClass() const noexcept + { + const auto libObjPtr = _ConstSpec::payloadFieldClass(this->_libObjPtr()); + + if (libObjPtr) { + return ConstStructureFieldClass {libObjPtr}; + } + + return nonstd::nullopt; + } + + nonstd::optional<_StructureFieldClass> payloadFieldClass() noexcept + { + const auto libObjPtr = _Spec::payloadFieldClass(this->_libObjPtr()); + + if (libObjPtr) { + return _StructureFieldClass {libObjPtr}; + } + + return nonstd::nullopt; + } + + void specificContextFieldClass(const StructureFieldClass& fc) + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + const auto status = + bt_event_class_set_specificContext_field_class(this->_libObjPtr(), fc._libObjPtr()); + + if (status == BT_EVENT_CLASS_SET_FIELD_CLASS_STATUS_MEMORY_ERROR) { + throw LibMemoryError {}; + } + } + + nonstd::optional specificContextFieldClass() const noexcept + { + const auto libObjPtr = _ConstSpec::specificContextFieldClass(this->_libObjPtr()); + + if (libObjPtr) { + return ConstStructureFieldClass {libObjPtr}; + } + + return nonstd::nullopt; + } + + nonstd::optional<_StructureFieldClass> specificContextFieldClass() noexcept + { + const auto libObjPtr = _Spec::specificContextFieldClass(this->_libObjPtr()); + + if (libObjPtr) { + return _StructureFieldClass {libObjPtr}; + } + + return nonstd::nullopt; + } + + template + void userAttributes(const CommonMapValue& userAttrs) + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + bt_event_class_set_user_attributes(this->_libObjPtr(), userAttrs._libObjPtr()); + } + + ConstMapValue userAttributes() const noexcept + { + return ConstMapValue {_ConstSpec::userAttributes(this->_libObjPtr())}; + } + + UserAttributes userAttributes() noexcept + { + return UserAttributes {_Spec::userAttributes(this->_libObjPtr())}; + } + + Shared shared() const noexcept + { + return Shared {*this}; + } +}; + +using EventClass = CommonEventClass; +using ConstEventClass = CommonEventClass; + +template +ConstEventClass CommonEvent::cls() const noexcept +{ + return ConstEventClass {_ConstSpec::cls(this->_libObjPtr())}; +} + +template +typename CommonEvent::Class CommonEvent::cls() noexcept +{ + return Class {_Spec::cls(this->_libObjPtr())}; +} + +namespace internal { + +struct StreamClassRefFuncs final +{ + static void get(const bt_stream_class * const libObjPtr) + { + bt_stream_class_get_ref(libObjPtr); + } + + static void put(const bt_stream_class * const libObjPtr) + { + bt_stream_class_put_ref(libObjPtr); + } +}; + +template +struct CommonStreamClassSpec; + +// Functions specific to mutable stream classes +template <> +struct CommonStreamClassSpec final +{ + static bt_trace_class *traceClass(bt_stream_class * const libObjPtr) noexcept + { + return bt_stream_class_borrow_trace_class(libObjPtr); + } + + static bt_event_class *eventClassByIndex(bt_stream_class * const libObjPtr, + const std::uint64_t index) noexcept + { + return bt_stream_class_borrow_event_class_by_index(libObjPtr, index); + } + + static bt_event_class *eventClassById(bt_stream_class * const libObjPtr, + const std::uint64_t id) noexcept + { + return bt_stream_class_borrow_event_class_by_id(libObjPtr, id); + } + + static bt_clock_class *defaultClockClass(bt_stream_class * const libObjPtr) noexcept + { + return bt_stream_class_borrow_default_clock_class(libObjPtr); + } + + static bt_field_class *packetContextFieldClass(bt_stream_class * const libObjPtr) noexcept + { + return bt_stream_class_borrow_packet_context_field_class(libObjPtr); + } + + static bt_field_class *eventCommonContextFieldClass(bt_stream_class * const libObjPtr) noexcept + { + return bt_stream_class_borrow_event_common_context_field_class(libObjPtr); + } + + static bt_value *userAttributes(bt_stream_class * const libObjPtr) noexcept + { + return bt_stream_class_borrow_user_attributes(libObjPtr); + } +}; + +// Functions specific to constant stream classes +template <> +struct CommonStreamClassSpec final +{ + static const bt_trace_class *traceClass(const bt_stream_class * const libObjPtr) noexcept + { + return bt_stream_class_borrow_trace_class_const(libObjPtr); + } + + static const bt_event_class *eventClassByIndex(const bt_stream_class * const libObjPtr, + const std::uint64_t index) noexcept + { + return bt_stream_class_borrow_event_class_by_index_const(libObjPtr, index); + } + + static const bt_event_class *eventClassById(const bt_stream_class * const libObjPtr, + const std::uint64_t id) noexcept + { + return bt_stream_class_borrow_event_class_by_id_const(libObjPtr, id); + } + + static const bt_clock_class *defaultClockClass(const bt_stream_class * const libObjPtr) noexcept + { + return bt_stream_class_borrow_default_clock_class_const(libObjPtr); + } + + static const bt_field_class * + packetContextFieldClass(const bt_stream_class * const libObjPtr) noexcept + { + return bt_stream_class_borrow_packet_context_field_class_const(libObjPtr); + } + + static const bt_field_class * + eventCommonContextFieldClass(const bt_stream_class * const libObjPtr) noexcept + { + return bt_stream_class_borrow_event_common_context_field_class_const(libObjPtr); + } + + static const bt_value *userAttributes(const bt_stream_class * const libObjPtr) noexcept + { + return bt_stream_class_borrow_user_attributes_const(libObjPtr); + } +}; + +} // namespace internal + +template +class CommonStreamClass final : public internal::BorrowedObj +{ +private: + using typename internal::BorrowedObj::_ThisBorrowedObj; + using typename internal::BorrowedObj::_LibObjPtr; + using _ConstSpec = internal::CommonStreamClassSpec; + using _Spec = internal::CommonStreamClassSpec; + using _ThisCommonStreamClass = CommonStreamClass; + + using _TraceClass = typename std::conditional::value, + CommonTraceClass, + CommonTraceClass>::type; + + using _EventClass = typename std::conditional::value, + CommonEventClass, + CommonEventClass>::type; + + using _StructureFieldClass = + typename std::conditional::value, ConstStructureFieldClass, + StructureFieldClass>::type; + + using _ClockClass = + typename std::conditional::value, ConstClockClass, ClockClass>::type; + +public: + using Shared = + internal::SharedObj<_ThisCommonStreamClass, LibObjT, internal::StreamClassRefFuncs>; + + using UserAttributes = + typename std::conditional::value, ConstMapValue, MapValue>::type; + + explicit CommonStreamClass(const _LibObjPtr libObjPtr) noexcept : _ThisBorrowedObj {libObjPtr} + { + } + + template + CommonStreamClass(const CommonStreamClass& streamClass) noexcept : + _ThisBorrowedObj {streamClass} + { + } + + template + _ThisCommonStreamClass& operator=(const CommonStreamClass& streamClass) noexcept + { + _ThisBorrowedObj::operator=(streamClass); + return *this; + } + + Stream::Shared instantiate(const Trace& trace) + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + const auto libObjPtr = bt_stream_create(this->_libObjPtr(), trace._libObjPtr()); + + internal::validateCreatedObjPtr(libObjPtr); + return Stream::Shared {Stream {libObjPtr}}; + } + + Stream::Shared instantiate(const Trace& trace, const std::uint64_t id) + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + const auto libObjPtr = bt_stream_create_with_id(this->_libObjPtr(), trace._libObjPtr(), id); + + internal::validateCreatedObjPtr(libObjPtr); + return Stream::Shared {Stream {libObjPtr}}; + } + + EventClass::Shared createEventClass() + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + const auto libObjPtr = bt_event_class_create(this->_libObjPtr()); + + internal::validateCreatedObjPtr(libObjPtr); + return EventClass::Shared {EventClass {libObjPtr}}; + } + + EventClass::Shared createEventClass(const std::uint64_t id) + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + const auto libObjPtr = bt_event_class_create_with_id(this->_libObjPtr(), id); + + internal::validateCreatedObjPtr(libObjPtr); + return EventClass::Shared {EventClass {libObjPtr}}; + } + + CommonTraceClass traceClass() const noexcept; + _TraceClass traceClass() noexcept; + + std::uint64_t id() const noexcept + { + return bt_stream_class_get_id(this->_libObjPtr()); + } + + void name(const char * const name) + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + const auto status = bt_stream_class_set_name(this->_libObjPtr(), name); + + if (status == BT_STREAM_CLASS_SET_NAME_STATUS_MEMORY_ERROR) { + throw LibMemoryError {}; + } + } + + void name(const std::string& name) + { + this->name(name.data()); + } + + nonstd::optional name() const noexcept + { + const auto name = bt_stream_class_get_name(this->_libObjPtr()); + + if (name) { + return name; + } + + return nonstd::nullopt; + } + + void assignsAutomaticEventClassId(const bool val) noexcept + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + bt_stream_class_set_assigns_automatic_event_class_id(this->_libObjPtr(), + static_cast(val)); + } + + bool assignsAutomaticEventClassId() const noexcept + { + return static_cast( + bt_stream_class_assigns_automatic_event_class_id(this->_libObjPtr())); + } + + void assignsAutomaticStreamId(const bool val) noexcept + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + bt_stream_class_set_assigns_automatic_stream_id(this->_libObjPtr(), + static_cast(val)); + } + + bool assignsAutomaticStreamId() const noexcept + { + return static_cast(bt_stream_class_assigns_automatic_stream_id(this->_libObjPtr())); + } + + void supportsPackets(const bool supportsPackets, const bool withBeginningDefaultClkSnapshot, + const bool withEndDefaultClkSnapshot) noexcept + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + bt_stream_class_set_supports_packets(this->_libObjPtr(), + static_cast(supportsPackets), + static_cast(withBeginningDefaultClkSnapshot), + static_cast(withEndDefaultClkSnapshot)); + } + + bool supportsPackets() const noexcept + { + return static_cast(bt_stream_class_supports_packets(this->_libObjPtr())); + } + + bool packetsHaveBeginningClockSnapshot() const noexcept + { + return static_cast( + bt_stream_class_packets_have_beginning_default_clock_snapshot(this->_libObjPtr())); + } + + bool packetsHaveEndClockSnapshot() const noexcept + { + return static_cast( + bt_stream_class_packets_have_end_default_clock_snapshot(this->_libObjPtr())); + } + + void supportsDiscardedEvents(const bool supportsDiscardedEvents, + const bool withDefaultClkSnapshots) noexcept + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + bt_stream_class_set_supports_discarded_events( + this->_libObjPtr(), static_cast(supportsPackets), + static_cast(withDefaultClkSnapshots)); + } + + bool supportsDiscardedEvents() const noexcept + { + return static_cast(bt_stream_class_supports_discarded_events(this->_libObjPtr())); + } + + bool discardedEventsHaveDefaultClockSnapshots() const noexcept + { + return static_cast( + bt_stream_class_discarded_events_have_default_clock_snapshots(this->_libObjPtr())); + } + + void supportsDiscardedPackets(const bool supportsDiscardedPackets, + const bool withDefaultClkSnapshots) noexcept + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + bt_stream_class_set_supports_discarded_packets( + this->_libObjPtr(), static_cast(supportsPackets), + static_cast(withDefaultClkSnapshots)); + } + + bool supportsDiscardedPackets() const noexcept + { + return static_cast(bt_stream_class_supports_discarded_packets(this->_libObjPtr())); + } + + bool discardedPacketsHaveDefaultClockSnapshots() const noexcept + { + return static_cast( + bt_stream_class_discarded_packets_have_default_clock_snapshots(this->_libObjPtr())); + } + + void defaultClockClass(const ClockClass& clkCls) + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + const auto status = + bt_stream_class_set_default_clock_class(this->_libObjPtr(), clkCls._libObjPtr()); + + BT_ASSERT(status == BT_STREAM_CLASS_SET_DEFAULT_CLOCK_CLASS_STATUS_OK); + } + + nonstd::optional defaultClockClass() const noexcept + { + const auto libObjPtr = _ConstSpec::defaultClockClass(this->_libObjPtr()); + + if (libObjPtr) { + return ConstClockClass {libObjPtr}; + } + + return nonstd::nullopt; + } + + nonstd::optional<_ClockClass> defaultClockClass() noexcept + { + const auto libObjPtr = _Spec::defaultClockClass(this->_libObjPtr()); + + if (libObjPtr) { + return _ClockClass {libObjPtr}; + } + + return nonstd::nullopt; + } + + std::uint64_t size() const noexcept + { + return bt_stream_class_get_event_class_count(this->_libObjPtr()); + } + + ConstEventClass operator[](const std::uint64_t index) const noexcept + { + return ConstEventClass {_ConstSpec::eventClassByIndex(this->_libObjPtr(), index)}; + } + + _EventClass operator[](const std::uint64_t index) noexcept + { + return _EventClass {_Spec::eventClassByIndex(this->_libObjPtr(), index)}; + } + + nonstd::optional eventClassById(const std::uint64_t id) const noexcept + { + const auto libObjPtr = _ConstSpec::eventClassById(this->_libObjPtr(), id); + + if (libObjPtr) { + return ConstEventClass {libObjPtr}; + } + + return nonstd::nullopt; + } + + nonstd::optional<_EventClass> eventClassById(const std::uint64_t id) noexcept + { + const auto libObjPtr = _Spec::eventClassById(this->_libObjPtr(), id); + + if (libObjPtr) { + return _EventClass {libObjPtr}; + } + + return nonstd::nullopt; + } + + void packetContextFieldClass(const StructureFieldClass& fc) + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + const auto status = + bt_stream_class_set_payload_field_class(this->_libObjPtr(), fc._libObjPtr()); + + if (status == BT_EVENT_CLASS_SET_FIELD_CLASS_STATUS_MEMORY_ERROR) { + throw LibMemoryError {}; + } + } + + nonstd::optional packetContextFieldClass() const noexcept + { + const auto libObjPtr = _ConstSpec::packetContextFieldClass(this->_libObjPtr()); + + if (libObjPtr) { + return ConstStructureFieldClass {libObjPtr}; + } + + return nonstd::nullopt; + } + + nonstd::optional<_StructureFieldClass> packetContextFieldClass() noexcept + { + const auto libObjPtr = _Spec::packetContextFieldClass(this->_libObjPtr()); + + if (libObjPtr) { + return _StructureFieldClass {libObjPtr}; + } + + return nonstd::nullopt; + } + + void eventCommonContextFieldClass(const StructureFieldClass& fc) + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + const auto status = + bt_stream_class_set_specificContext_field_class(this->_libObjPtr(), fc._libObjPtr()); + + if (status == BT_EVENT_CLASS_SET_FIELD_CLASS_STATUS_MEMORY_ERROR) { + throw LibMemoryError {}; + } + } + + nonstd::optional eventCommonContextFieldClass() const noexcept + { + const auto libObjPtr = _ConstSpec::eventCommonContextFieldClass(this->_libObjPtr()); + + if (libObjPtr) { + return ConstStructureFieldClass {libObjPtr}; + } + + return nonstd::nullopt; + } + + nonstd::optional<_StructureFieldClass> eventCommonContextFieldClass() noexcept + { + const auto libObjPtr = _Spec::eventCommonContextFieldClass(this->_libObjPtr()); + + if (libObjPtr) { + return _StructureFieldClass {libObjPtr}; + } + + return nonstd::nullopt; + } + + template + void userAttributes(const CommonMapValue& userAttrs) + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + bt_stream_class_set_user_attributes(this->_libObjPtr(), userAttrs._libObjPtr()); + } + + ConstMapValue userAttributes() const noexcept + { + return ConstMapValue {_ConstSpec::userAttributes(this->_libObjPtr())}; + } + + UserAttributes userAttributes() noexcept + { + return UserAttributes {_Spec::userAttributes(this->_libObjPtr())}; + } + + Shared shared() const noexcept + { + return Shared {*this}; + } +}; + +using StreamClass = CommonStreamClass; +using ConstStreamClass = CommonStreamClass; + +template +ConstStreamClass CommonEventClass::streamClass() const noexcept +{ + return ConstStreamClass {_ConstSpec::streamClass(this->_libObjPtr())}; +} + +template +typename CommonEventClass::_StreamClass CommonEventClass::streamClass() noexcept +{ + return _StreamClass {_Spec::streamClass(this->_libObjPtr())}; +} + +template +ConstStreamClass CommonStream::cls() const noexcept +{ + return ConstStreamClass {_ConstSpec::cls(this->_libObjPtr())}; +} + +template +typename CommonStream::Class CommonStream::cls() noexcept +{ + return Class {_Spec::cls(this->_libObjPtr())}; +} + +namespace internal { + +struct TraceClassRefFuncs final +{ + static void get(const bt_trace_class * const libObjPtr) + { + bt_trace_class_get_ref(libObjPtr); + } + + static void put(const bt_trace_class * const libObjPtr) + { + bt_trace_class_put_ref(libObjPtr); + } +}; + +template +struct CommonTraceClassSpec; + +// Functions specific to mutable stream classes +template <> +struct CommonTraceClassSpec final +{ + static bt_stream_class *streamClassByIndex(bt_trace_class * const libObjPtr, + const std::uint64_t index) noexcept + { + return bt_trace_class_borrow_stream_class_by_index(libObjPtr, index); + } + + static bt_stream_class *streamClassById(bt_trace_class * const libObjPtr, + const std::uint64_t id) noexcept + { + return bt_trace_class_borrow_stream_class_by_id(libObjPtr, id); + } + + static bt_value *userAttributes(bt_trace_class * const libObjPtr) noexcept + { + return bt_trace_class_borrow_user_attributes(libObjPtr); + } +}; + +// Functions specific to constant stream classes +template <> +struct CommonTraceClassSpec final +{ + static const bt_stream_class *streamClassByIndex(const bt_trace_class * const libObjPtr, + const std::uint64_t index) noexcept + { + return bt_trace_class_borrow_stream_class_by_index_const(libObjPtr, index); + } + + static const bt_stream_class *streamClassById(const bt_trace_class * const libObjPtr, + const std::uint64_t id) noexcept + { + return bt_trace_class_borrow_stream_class_by_id_const(libObjPtr, id); + } + + static const bt_value *userAttributes(const bt_trace_class * const libObjPtr) noexcept + { + return bt_trace_class_borrow_user_attributes_const(libObjPtr); + } +}; + +} // namespace internal + +template +class CommonTraceClass final : public internal::BorrowedObj +{ +private: + using typename internal::BorrowedObj::_ThisBorrowedObj; + using typename internal::BorrowedObj::_LibObjPtr; + using _ConstSpec = internal::CommonTraceClassSpec; + using _Spec = internal::CommonTraceClassSpec; + using _ThisCommonTraceClass = CommonTraceClass; + + using _StreamClass = typename std::conditional::value, + CommonStreamClass, + CommonStreamClass>::type; + +public: + using Shared = + internal::SharedObj<_ThisCommonTraceClass, LibObjT, internal::TraceClassRefFuncs>; + + using UserAttributes = + typename std::conditional::value, ConstMapValue, MapValue>::type; + + explicit CommonTraceClass(const _LibObjPtr libObjPtr) noexcept : _ThisBorrowedObj {libObjPtr} + { + } + + template + CommonTraceClass(const CommonTraceClass& traceClass) noexcept : + _ThisBorrowedObj {traceClass} + { + } + + template + _ThisCommonTraceClass& operator=(const CommonTraceClass& traceClass) noexcept + { + _ThisBorrowedObj::operator=(traceClass); + return *this; + } + + Trace::Shared instantiate(const Trace& trace) + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + const auto libObjPtr = bt_trace_create(this->_libObjPtr()); + + internal::validateCreatedObjPtr(libObjPtr); + return Trace::Shared {Trace {libObjPtr}}; + } + + StreamClass::Shared createStreamClass() + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + const auto libObjPtr = bt_stream_class_create(this->_libObjPtr()); + + internal::validateCreatedObjPtr(libObjPtr); + return StreamClass::Shared {StreamClass {libObjPtr}}; + } + + StreamClass::Shared createStreamClass(const std::uint64_t id) + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + const auto libObjPtr = bt_stream_class_create_with_id(this->_libObjPtr(), id); + + internal::validateCreatedObjPtr(libObjPtr); + return StreamClass::Shared {StreamClass {libObjPtr}}; + } + + FieldClass::Shared createBoolFieldClass() + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + const auto libObjPtr = bt_field_class_bool_create(this->_libObjPtr()); + + internal::validateCreatedObjPtr(libObjPtr); + return FieldClass::Shared {FieldClass {libObjPtr}}; + } + + BitArrayFieldClass::Shared createBitArrayFieldClass(const std::uint64_t length) + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + const auto libObjPtr = bt_field_class_bit_array_create(this->_libObjPtr(), length); + + internal::validateCreatedObjPtr(libObjPtr); + return BitArrayFieldClass::Shared {BitArrayFieldClass {libObjPtr}}; + } + + IntegerFieldClass::Shared createUnsignedIntegerFieldClass() + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + const auto libObjPtr = bt_field_class_integer_unsigned_create(this->_libObjPtr()); + + internal::validateCreatedObjPtr(libObjPtr); + return IntegerFieldClass::Shared {IntegerFieldClass {libObjPtr}}; + } + + IntegerFieldClass::Shared createSignedIntegerFieldClass() + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + const auto libObjPtr = bt_field_class_integer_signed_create(this->_libObjPtr()); + + internal::validateCreatedObjPtr(libObjPtr); + return IntegerFieldClass::Shared {IntegerFieldClass {libObjPtr}}; + } + + UnsignedEnumerationFieldClass::Shared createUnsignedEnumerationFieldClass() + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + const auto libObjPtr = bt_field_class_enumeration_unsigned_create(this->_libObjPtr()); + + internal::validateCreatedObjPtr(libObjPtr); + return UnsignedEnumerationFieldClass::Shared {UnsignedEnumerationFieldClass {libObjPtr}}; + } + + SignedEnumerationFieldClass::Shared createSignedEnumerationFieldClass() + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + const auto libObjPtr = bt_field_class_enumeration_signed_create(this->_libObjPtr()); + + internal::validateCreatedObjPtr(libObjPtr); + return SignedEnumerationFieldClass::Shared {SignedEnumerationFieldClass {libObjPtr}}; + } + + FieldClass::Shared createSinglePrecisionRealFieldClass() + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + const auto libObjPtr = bt_field_class_real_single_precision_create(this->_libObjPtr()); + + internal::validateCreatedObjPtr(libObjPtr); + return FieldClass::Shared {FieldClass {libObjPtr}}; + } + + FieldClass::Shared createDoublePrecisionRealFieldClass() + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + const auto libObjPtr = bt_field_class_real_double_precision_create(this->_libObjPtr()); + + internal::validateCreatedObjPtr(libObjPtr); + return FieldClass::Shared {FieldClass {libObjPtr}}; + } + + FieldClass::Shared createStringFieldClass() + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + const auto libObjPtr = bt_field_class_string_create(this->_libObjPtr()); + + internal::validateCreatedObjPtr(libObjPtr); + return FieldClass::Shared {FieldClass {libObjPtr}}; + } + + StaticArrayFieldClass::Shared createStaticArrayFieldClass(const FieldClass& elementFieldClass, + const std::uint64_t length) + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + const auto libObjPtr = bt_field_class_array_static_create( + this->_libObjPtr(), elementFieldClass._libObjPtr(), length); + + internal::validateCreatedObjPtr(libObjPtr); + return StaticArrayFieldClass::Shared {StaticArrayFieldClass {libObjPtr}}; + } + + ArrayFieldClass::Shared createDynamicArrayFieldClass(const FieldClass& elementFieldClass) + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + const auto libObjPtr = bt_field_class_array_dynamic_create( + this->_libObjPtr(), elementFieldClass._libObjPtr(), nullptr); + + internal::validateCreatedObjPtr(libObjPtr); + return ArrayFieldClass::Shared {ArrayFieldClass {libObjPtr}}; + } + + DynamicArrayWithLengthFieldClass::Shared + createDynamicArrayFieldClass(const FieldClass& elementFieldClass, + const IntegerFieldClass& lengthFieldClass) + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + const auto libObjPtr = bt_field_class_array_dynamic_create( + this->_libObjPtr(), elementFieldClass._libObjPtr(), lengthFieldClass._libObjPtr()); + + internal::validateCreatedObjPtr(libObjPtr); + return DynamicArrayWithLengthFieldClass::Shared { + DynamicArrayWithLengthFieldClass {libObjPtr}}; + } + + StructureFieldClass::Shared createStructureFieldClass(const std::uint64_t length) + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + const auto libObjPtr = bt_field_class_structure_create(this->_libObjPtr(), length); + + internal::validateCreatedObjPtr(libObjPtr); + return StructureFieldClass::Shared {StructureFieldClass {libObjPtr}}; + } + + OptionFieldClass::Shared createOptionFieldClass(const FieldClass& optionalFieldClass) + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + const auto libObjPtr = bt_field_class_option_without_selector_create( + this->_libObjPtr(), optionalFieldClass._libObjPtr()); + + internal::validateCreatedObjPtr(libObjPtr); + return OptionFieldClass::Shared {OptionFieldClass {libObjPtr}}; + } + + OptionWithBoolSelectorFieldClass::Shared + createOptionWithBoolSelectorFieldClass(const FieldClass& optionalFieldClass, + const FieldClass& selectorFieldClass) + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + const auto libObjPtr = bt_field_class_option_with_selector_field_bool_create( + this->_libObjPtr(), optionalFieldClass._libObjPtr(), selectorFieldClass._libObjPtr()); + + internal::validateCreatedObjPtr(libObjPtr); + return OptionWithBoolSelectorFieldClass::Shared { + OptionWithBoolSelectorFieldClass {libObjPtr}}; + } + + OptionWithUnsignedIntegerSelectorFieldClass::Shared + createOptionWithUnsignedIntegerSelectorFieldClass(const FieldClass& optionalFieldClass, + const IntegerFieldClass& selectorFieldClass, + const ConstUnsignedIntegerRangeSet& ranges) + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + const auto libObjPtr = bt_field_class_option_with_selector_field_integer_unsigned_create( + this->_libObjPtr(), optionalFieldClass._libObjPtr(), selectorFieldClass._libObjPtr(), + ranges._libObjPtr()); + + internal::validateCreatedObjPtr(libObjPtr); + return OptionWithUnsignedIntegerSelectorFieldClass::Shared { + OptionWithUnsignedIntegerSelectorFieldClass {libObjPtr}}; + } + + OptionWithSignedIntegerSelectorFieldClass::Shared + createOptionWithSignedIntegerSelectorFieldClass(const FieldClass& optionalFieldClass, + const IntegerFieldClass& selectorFieldClass, + const ConstSignedIntegerRangeSet& ranges) + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + const auto libObjPtr = bt_field_class_option_with_selector_field_integer_signed_create( + this->_libObjPtr(), optionalFieldClass._libObjPtr(), selectorFieldClass._libObjPtr(), + ranges._libObjPtr()); + + internal::validateCreatedObjPtr(libObjPtr); + return OptionWithSignedIntegerSelectorFieldClass::Shared { + OptionWithSignedIntegerSelectorFieldClass {libObjPtr}}; + } + + VariantWithoutSelectorFieldClass::Shared createVariantFieldClass() + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + const auto libObjPtr = bt_field_class_variant_create(this->_libObjPtr()); + + internal::validateCreatedObjPtr(libObjPtr); + return VariantWithoutSelectorFieldClass::Shared { + VariantWithoutSelectorFieldClass {libObjPtr}}; + } + + VariantWithUnsignedIntegerSelectorFieldClass::Shared + createVariantWithUnsignedIntegerSelectorFieldClass(const IntegerFieldClass& selectorFieldClass) + { + return VariantWithUnsignedIntegerSelectorFieldClass::Shared { + VariantWithUnsignedIntegerSelectorFieldClass { + this->_createVariantWithIntegerSelectorFieldClass(selectorFieldClass)}}; + } + + VariantWithSignedIntegerSelectorFieldClass::Shared + createVariantWithSignedIntegerSelectorFieldClass(const IntegerFieldClass& selectorFieldClass) + { + return VariantWithSignedIntegerSelectorFieldClass::Shared { + VariantWithSignedIntegerSelectorFieldClass { + this->_createVariantWithIntegerSelectorFieldClass(selectorFieldClass)}}; + } + + void assignsAutomaticStreamClassId(const bool val) noexcept + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + bt_trace_class_set_assigns_automatic_stream_class_id(this->_libObjPtr(), + static_cast(val)); + } + + bool assignsAutomaticStreamClassId() const noexcept + { + return static_cast( + bt_trace_class_assigns_automatic_stream_class_id(this->_libObjPtr())); + } + + std::uint64_t size() const noexcept + { + return bt_trace_class_get_stream_class_count(this->_libObjPtr()); + } + + ConstStreamClass operator[](const std::uint64_t index) const noexcept + { + return ConstStreamClass {_ConstSpec::streamClassByIndex(this->_libObjPtr(), index)}; + } + + _StreamClass operator[](const std::uint64_t index) noexcept + { + return _StreamClass {_Spec::streamClassByIndex(this->_libObjPtr(), index)}; + } + + nonstd::optional streamClassById(const std::uint64_t id) const noexcept + { + const auto libObjPtr = _ConstSpec::streamClassById(this->_libObjPtr(), id); + + if (libObjPtr) { + return ConstStreamClass {libObjPtr}; + } + + return nonstd::nullopt; + } + + nonstd::optional<_StreamClass> streamClassById(const std::uint64_t id) noexcept + { + const auto libObjPtr = _Spec::streamClassById(this->_libObjPtr(), id); + + if (libObjPtr) { + return _StreamClass {libObjPtr}; + } + + return nonstd::nullopt; + } + + template + void userAttributes(const CommonMapValue& userAttrs) + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + bt_trace_class_set_user_attributes(this->_libObjPtr(), userAttrs._libObjPtr()); + } + + ConstMapValue userAttributes() const noexcept + { + return ConstMapValue {_ConstSpec::userAttributes(this->_libObjPtr())}; + } + + UserAttributes userAttributes() noexcept + { + return UserAttributes {_Spec::userAttributes(this->_libObjPtr())}; + } + + Shared shared() const noexcept + { + return Shared {*this}; + } + +private: + bt_field_class * + _createVariantWithIntegerSelectorFieldClass(const IntegerFieldClass& selectorFieldClass) + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + const auto libObjPtr = + bt_field_class_variant_create(this->_libObjPtr(), selectorFieldClass._libObjPtr()); + + internal::validateCreatedObjPtr(libObjPtr); + return libObjPtr; + } +}; + +using TraceClass = CommonTraceClass; +using ConstTraceClass = CommonTraceClass; + +template +ConstTraceClass CommonStreamClass::traceClass() const noexcept +{ + return ConstTraceClass {_ConstSpec::traceClass(this->_libObjPtr())}; +} + +template +typename CommonStreamClass::_TraceClass CommonStreamClass::traceClass() noexcept +{ + return _TraceClass {_Spec::traceClass(this->_libObjPtr())}; +} + +template +ConstTraceClass CommonTrace::cls() const noexcept +{ + return ConstTraceClass {_ConstSpec::cls(this->_libObjPtr())}; +} + +template +typename CommonTrace::Class CommonTrace::cls() noexcept +{ + return Class {_Spec::cls(this->_libObjPtr())}; +} + +} // namespace bt2 + +#endif // BABELTRACE_CPP_COMMON_BT2_TRACE_IR_HPP diff --git a/src/cpp-common/bt2/value.hpp b/src/cpp-common/bt2/value.hpp index 816a5454..4b34a16e 100644 --- a/src/cpp-common/bt2/value.hpp +++ b/src/cpp-common/bt2/value.hpp @@ -85,6 +85,18 @@ class CommonClockClass; template class CommonFieldClass; +template +class CommonTraceClass; + +template +class CommonStreamClass; + +template +class CommonEventClass; + +template +class CommonStream; + template class CommonValue : public internal::BorrowedObj { @@ -97,6 +109,10 @@ class CommonValue : public internal::BorrowedObj // Allow userAttributes() to call `val._libObjPtr()` friend class CommonClockClass; friend class CommonFieldClass; + friend class CommonTraceClass; + friend class CommonStreamClass; + friend class CommonEventClass; + friend class CommonStream; // Allow operator==() to call `other._libObjPtr()` friend class CommonValue;