Add C++ interface for the libbabeltrace2 `bt_message` API
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Fri, 22 Jan 2021 14:23:02 +0000 (09:23 -0500)
committerPhilippe Proulx <eeppeliteloop@gmail.com>
Fri, 28 Jan 2022 16:22:26 +0000 (11:22 -0500)
This patch adds C++ wrappers for Babeltrace 2 message objects.

The class hierarchy is:

    Message
      StreamBeginningMessage
      StreamEndMessage
      PacketBeginningMessage
      PacketEndMessage
      EventMessage
      DiscardedEventsMessage
      DiscardedPacketsMessage
      MessageIteratorInactivityMessage
    ConstMessage
      ConstStreamBeginningMessage
      ConstStreamEndMessage
      ConstPacketBeginningMessage
      ConstPacketEndMessage
      ConstEventMessage
      ConstDiscardedEventsMessage
      ConstDiscardedPacketsMessage
      ConstMessageIteratorInactivityMessage

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`.

Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: If01ac4b2bbf8eb1ea400f8e5e7c2003b4844b80f
Reviewed-on: https://review.lttng.org/c/babeltrace/+/4735

src/cpp-common/bt2/message.hpp [new file with mode: 0644]

diff --git a/src/cpp-common/bt2/message.hpp b/src/cpp-common/bt2/message.hpp
new file mode 100644 (file)
index 0000000..65404f3
--- /dev/null
@@ -0,0 +1,996 @@
+/*
+ * Copyright (c) 2021 Philippe Proulx <pproulx@efficios.com>
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef BABELTRACE_CPP_COMMON_BT2_MESSAGE_HPP
+#define BABELTRACE_CPP_COMMON_BT2_MESSAGE_HPP
+
+#include <type_traits>
+#include <cstdint>
+#include <functional>
+#include <babeltrace2/babeltrace.h>
+
+#include "common/assert.h"
+#include "common/common.h"
+#include "internal/borrowed-obj.hpp"
+#include "internal/shared-obj.hpp"
+#include "internal/utils.hpp"
+#include "cpp-common/optional.hpp"
+#include "cpp-common/string_view.hpp"
+#include "lib-error.hpp"
+
+namespace bt2 {
+
+namespace internal {
+
+struct MessageRefFuncs final
+{
+    static void get(const bt_message * const libObjPtr)
+    {
+        bt_message_get_ref(libObjPtr);
+    }
+
+    static void put(const bt_message * const libObjPtr)
+    {
+        bt_message_put_ref(libObjPtr);
+    }
+};
+
+template <typename ObjT, typename LibObjT>
+using SharedMessage = internal::SharedObj<ObjT, LibObjT, internal::MessageRefFuncs>;
+
+} // namespace internal
+
+template <typename LibObjT>
+class CommonStreamBeginningMessage;
+
+template <typename LibObjT>
+class CommonStreamEndMessage;
+
+template <typename LibObjT>
+class CommonEventMessage;
+
+template <typename LibObjT>
+class CommonPacketBeginningMessage;
+
+template <typename LibObjT>
+class CommonPacketEndMessage;
+
+template <typename LibObjT>
+class CommonDiscardedEventsMessage;
+
+template <typename LibObjT>
+class CommonDiscardedPacketsMessage;
+
+template <typename LibObjT>
+class CommonMessageIteratorInactivityMessage;
+
+enum class MessageType
+{
+    STREAM_BEGINNING = BT_MESSAGE_TYPE_STREAM_BEGINNING,
+    STREAM_END = BT_MESSAGE_TYPE_STREAM_END,
+    EVENT = BT_MESSAGE_TYPE_EVENT,
+    PACKET_BEGINNING = BT_MESSAGE_TYPE_PACKET_BEGINNING,
+    PACKET_END = BT_MESSAGE_TYPE_PACKET_END,
+    DISCARDED_EVENTS = BT_MESSAGE_TYPE_DISCARDED_EVENTS,
+    DISCARDED_PACKETS = BT_MESSAGE_TYPE_DISCARDED_PACKETS,
+    MESSAGE_ITERATOR_INACTIVITY = BT_MESSAGE_TYPE_MESSAGE_ITERATOR_INACTIVITY,
+};
+
+template <typename LibObjT>
+class CommonMessage : public internal::BorrowedObj<LibObjT>
+{
+private:
+    using typename internal::BorrowedObj<LibObjT>::_ThisBorrowedObj;
+
+protected:
+    using typename internal::BorrowedObj<LibObjT>::_LibObjPtr;
+    using _ThisCommonMessage = CommonMessage<LibObjT>;
+
+public:
+    using Shared = internal::SharedMessage<CommonMessage<LibObjT>, LibObjT>;
+
+    explicit CommonMessage(const _LibObjPtr libObjPtr) noexcept : _ThisBorrowedObj {libObjPtr}
+    {
+    }
+
+    template <typename OtherLibObjT>
+    CommonMessage(const CommonMessage<OtherLibObjT>& val) noexcept : _ThisBorrowedObj {val}
+    {
+    }
+
+    template <typename OtherLibObjT>
+    _ThisCommonMessage& operator=(const CommonMessage<OtherLibObjT>& val) noexcept
+    {
+        _ThisBorrowedObj::operator=(val);
+        return *this;
+    }
+
+    MessageType type() const noexcept
+    {
+        return static_cast<MessageType>(bt_message_get_type(this->_libObjPtr()));
+    }
+
+    bool isStreamBeginning() const noexcept
+    {
+        return this->type() == MessageType::STREAM_BEGINNING;
+    }
+
+    bool isStreamEnd() const noexcept
+    {
+        return this->type() == MessageType::STREAM_END;
+    }
+
+    bool isEvent() const noexcept
+    {
+        return this->type() == MessageType::EVENT;
+    }
+
+    bool isPacketBeginning() const noexcept
+    {
+        return this->type() == MessageType::PACKET_BEGINNING;
+    }
+
+    bool isPacketEnd() const noexcept
+    {
+        return this->type() == MessageType::PACKET_END;
+    }
+
+    bool isDiscardedEvents() const noexcept
+    {
+        return this->type() == MessageType::DISCARDED_EVENTS;
+    }
+
+    bool isDiscardedPackets() const noexcept
+    {
+        return this->type() == MessageType::DISCARDED_PACKETS;
+    }
+
+    bool isMessageIteratorInactivity() const noexcept
+    {
+        return this->type() == MessageType::MESSAGE_ITERATOR_INACTIVITY;
+    }
+
+    Shared shared() const noexcept
+    {
+        return Shared {*this};
+    }
+
+    CommonStreamBeginningMessage<LibObjT> asStreamBeginning() const noexcept;
+    CommonStreamEndMessage<LibObjT> asStreamEnd() const noexcept;
+    CommonEventMessage<LibObjT> asEvent() const noexcept;
+    CommonPacketBeginningMessage<LibObjT> asPacketBeginning() const noexcept;
+    CommonPacketEndMessage<LibObjT> asPacketEnd() const noexcept;
+    CommonDiscardedEventsMessage<LibObjT> asDiscardedEvents() const noexcept;
+    CommonDiscardedPacketsMessage<LibObjT> asDiscardedPackets() const noexcept;
+    CommonMessageIteratorInactivityMessage<LibObjT> asMessageIteratorInactivity() const noexcept;
+};
+
+using Message = CommonMessage<bt_message>;
+using ConstMessage = CommonMessage<const bt_message>;
+
+namespace internal {
+
+template <typename LibObjT>
+struct CommonStreamBeginningMessageSpec;
+
+// Functions specific to mutable stream beginning messages
+template <>
+struct CommonStreamBeginningMessageSpec<bt_message> final
+{
+    static bt_stream *stream(bt_message * const libObjPtr) noexcept
+    {
+        return bt_message_stream_beginning_borrow_stream(libObjPtr);
+    }
+};
+
+// Functions specific to constant stream beginning messages
+template <>
+struct CommonStreamBeginningMessageSpec<const bt_message> final
+{
+    static const bt_stream *stream(const bt_message * const libObjPtr) noexcept
+    {
+        return bt_message_stream_beginning_borrow_stream_const(libObjPtr);
+    }
+};
+
+} // namespace internal
+
+template <typename LibObjT>
+class CommonStreamBeginningMessage final : public CommonMessage<LibObjT>
+{
+private:
+    using typename CommonMessage<LibObjT>::_LibObjPtr;
+    using typename CommonMessage<LibObjT>::_ThisCommonMessage;
+
+    using _Stream =
+        typename std::conditional<std::is_const<LibObjT>::value, CommonStream<const bt_stream>,
+                                  CommonStream<bt_stream>>::type;
+
+public:
+    using Shared = internal::SharedMessage<CommonStreamBeginningMessage<LibObjT>, LibObjT>;
+
+    explicit CommonStreamBeginningMessage(const _LibObjPtr libObjPtr) noexcept :
+        _ThisCommonMessage {libObjPtr}
+    {
+        BT_ASSERT_DBG(this->isStreamBeginning());
+    }
+
+    template <typename OtherLibObjT>
+    CommonStreamBeginningMessage(const CommonStreamBeginningMessage<OtherLibObjT>& val) noexcept :
+        _ThisCommonMessage {val}
+    {
+    }
+
+    template <typename OtherLibObjT>
+    CommonStreamBeginningMessage<LibObjT>&
+    operator=(const CommonStreamBeginningMessage<OtherLibObjT>& val) noexcept
+    {
+        _ThisCommonMessage::operator=(val);
+        return *this;
+    }
+
+    ConstStream stream() const noexcept
+    {
+        return ConstStream {internal::CommonStreamBeginningMessageSpec<const bt_message>::stream(
+            this->_libObjPtr())};
+    }
+
+    _Stream stream() noexcept
+    {
+        return _Stream {
+            internal::CommonStreamBeginningMessageSpec<LibObjT>::stream(this->_libObjPtr())};
+    }
+
+    void defaultClockSnapshot(const std::uint64_t val) noexcept
+    {
+        static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
+
+        bt_message_stream_beginning_set_default_clock_snapshot(this->_libObjPtr(), val);
+    }
+
+    nonstd::optional<ConstClockSnapshot> defaultClockSnapshot() const noexcept
+    {
+        const bt_clock_snapshot *libObjPtr;
+        const auto state = bt_message_stream_beginning_borrow_default_clock_snapshot_const(
+            this->_libObjPtr(), &libObjPtr);
+
+        if (state == BT_MESSAGE_STREAM_CLOCK_SNAPSHOT_STATE_KNOWN) {
+            return ConstClockSnapshot {libObjPtr};
+        }
+
+        return nonstd::nullopt;
+    }
+
+    Shared shared() const noexcept
+    {
+        return Shared {*this};
+    }
+};
+
+using StreamBeginningMessage = CommonStreamBeginningMessage<bt_message>;
+using ConstStreamBeginningMessage = CommonStreamBeginningMessage<const bt_message>;
+
+namespace internal {
+
+template <typename LibObjT>
+struct CommonStreamEndMessageSpec;
+
+// Functions specific to mutable stream end messages
+template <>
+struct CommonStreamEndMessageSpec<bt_message> final
+{
+    static bt_stream *stream(bt_message * const libObjPtr) noexcept
+    {
+        return bt_message_stream_end_borrow_stream(libObjPtr);
+    }
+};
+
+// Functions specific to constant stream end messages
+template <>
+struct CommonStreamEndMessageSpec<const bt_message> final
+{
+    static const bt_stream *stream(const bt_message * const libObjPtr) noexcept
+    {
+        return bt_message_stream_end_borrow_stream_const(libObjPtr);
+    }
+};
+
+} // namespace internal
+
+template <typename LibObjT>
+class CommonStreamEndMessage final : public CommonMessage<LibObjT>
+{
+private:
+    using typename CommonMessage<LibObjT>::_LibObjPtr;
+    using typename CommonMessage<LibObjT>::_ThisCommonMessage;
+
+    using _Stream =
+        typename std::conditional<std::is_const<LibObjT>::value, CommonStream<const bt_stream>,
+                                  CommonStream<bt_stream>>::type;
+
+public:
+    using Shared = internal::SharedMessage<CommonStreamEndMessage<LibObjT>, LibObjT>;
+
+    explicit CommonStreamEndMessage(const _LibObjPtr libObjPtr) noexcept :
+        _ThisCommonMessage {libObjPtr}
+    {
+        BT_ASSERT_DBG(this->isStreamEnd());
+    }
+
+    template <typename OtherLibObjT>
+    CommonStreamEndMessage(const CommonStreamEndMessage<OtherLibObjT>& val) noexcept :
+        _ThisCommonMessage {val}
+    {
+    }
+
+    template <typename OtherLibObjT>
+    CommonStreamEndMessage<LibObjT>&
+    operator=(const CommonStreamEndMessage<OtherLibObjT>& val) noexcept
+    {
+        _ThisCommonMessage::operator=(val);
+        return *this;
+    }
+
+    ConstStream stream() const noexcept
+    {
+        return ConstStream {
+            internal::CommonStreamEndMessageSpec<const bt_message>::stream(this->_libObjPtr())};
+    }
+
+    _Stream stream() noexcept
+    {
+        return _Stream {internal::CommonStreamEndMessageSpec<LibObjT>::stream(this->_libObjPtr())};
+    }
+
+    void defaultClockSnapshot(const std::uint64_t val) noexcept
+    {
+        static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
+
+        bt_message_stream_end_set_default_clock_snapshot(this->_libObjPtr(), val);
+    }
+
+    nonstd::optional<ConstClockSnapshot> defaultClockSnapshot() const noexcept
+    {
+        const bt_clock_snapshot *libObjPtr;
+        const auto state = bt_message_stream_end_borrow_default_clock_snapshot_const(
+            this->_libObjPtr(), &libObjPtr);
+
+        if (state == BT_MESSAGE_STREAM_CLOCK_SNAPSHOT_STATE_KNOWN) {
+            return ConstClockSnapshot {libObjPtr};
+        }
+
+        return nonstd::nullopt;
+    }
+
+    Shared shared() const noexcept
+    {
+        return Shared {*this};
+    }
+};
+
+using StreamEndMessage = CommonStreamEndMessage<bt_message>;
+using ConstStreamEndMessage = CommonStreamEndMessage<const bt_message>;
+
+namespace internal {
+
+template <typename LibObjT>
+struct CommonPacketBeginningMessageSpec;
+
+// Functions specific to mutable packet beginning messages
+template <>
+struct CommonPacketBeginningMessageSpec<bt_message> final
+{
+    static bt_packet *packet(bt_message * const libObjPtr) noexcept
+    {
+        return bt_message_packet_beginning_borrow_packet(libObjPtr);
+    }
+};
+
+// Functions specific to constant packet beginning messages
+template <>
+struct CommonPacketBeginningMessageSpec<const bt_message> final
+{
+    static const bt_packet *packet(const bt_message * const libObjPtr) noexcept
+    {
+        return bt_message_packet_beginning_borrow_packet_const(libObjPtr);
+    }
+};
+
+} // namespace internal
+
+template <typename LibObjT>
+class CommonPacketBeginningMessage final : public CommonMessage<LibObjT>
+{
+private:
+    using typename CommonMessage<LibObjT>::_LibObjPtr;
+    using typename CommonMessage<LibObjT>::_ThisCommonMessage;
+
+    using _Packet =
+        typename std::conditional<std::is_const<LibObjT>::value, CommonPacket<const bt_packet>,
+                                  CommonPacket<bt_packet>>::type;
+
+public:
+    using Shared = internal::SharedMessage<CommonPacketBeginningMessage<LibObjT>, LibObjT>;
+
+    explicit CommonPacketBeginningMessage(const _LibObjPtr libObjPtr) noexcept :
+        _ThisCommonMessage {libObjPtr}
+    {
+        BT_ASSERT_DBG(this->isPacketBeginning());
+    }
+
+    template <typename OtherLibObjT>
+    CommonPacketBeginningMessage(const CommonPacketBeginningMessage<OtherLibObjT>& val) noexcept :
+        _ThisCommonMessage {val}
+    {
+    }
+
+    template <typename OtherLibObjT>
+    CommonPacketBeginningMessage<LibObjT>&
+    operator=(const CommonPacketBeginningMessage<OtherLibObjT>& val) noexcept
+    {
+        _ThisCommonMessage::operator=(val);
+        return *this;
+    }
+
+    ConstPacket packet() const noexcept
+    {
+        return ConstPacket {internal::CommonPacketBeginningMessageSpec<const bt_message>::packet(
+            this->_libObjPtr())};
+    }
+
+    _Packet packet() noexcept
+    {
+        return _Packet {
+            internal::CommonPacketBeginningMessageSpec<LibObjT>::packet(this->_libObjPtr())};
+    }
+
+    void defaultClockSnapshot(const std::uint64_t val) noexcept
+    {
+        static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
+
+        bt_message_packet_beginning_set_default_clock_snapshot(this->_libObjPtr(), val);
+    }
+
+    ConstClockSnapshot defaultClockSnapshot() const noexcept
+    {
+        const auto libObjPtr =
+            bt_message_packet_beginning_borrow_default_clock_snapshot_const(this->_libObjPtr());
+
+        return ConstClockSnapshot {libObjPtr};
+    }
+
+    Shared shared() const noexcept
+    {
+        return Shared {*this};
+    }
+};
+
+using PacketBeginningMessage = CommonPacketBeginningMessage<bt_message>;
+using ConstPacketBeginningMessage = CommonPacketBeginningMessage<const bt_message>;
+
+namespace internal {
+
+template <typename LibObjT>
+struct CommonPacketEndMessageSpec;
+
+// Functions specific to mutable packet end messages
+template <>
+struct CommonPacketEndMessageSpec<bt_message> final
+{
+    static bt_packet *packet(bt_message * const libObjPtr) noexcept
+    {
+        return bt_message_packet_end_borrow_packet(libObjPtr);
+    }
+};
+
+// Functions specific to constant packet end messages
+template <>
+struct CommonPacketEndMessageSpec<const bt_message> final
+{
+    static const bt_packet *packet(const bt_message * const libObjPtr) noexcept
+    {
+        return bt_message_packet_end_borrow_packet_const(libObjPtr);
+    }
+};
+
+} // namespace internal
+
+template <typename LibObjT>
+class CommonPacketEndMessage final : public CommonMessage<LibObjT>
+{
+private:
+    using typename CommonMessage<LibObjT>::_LibObjPtr;
+    using typename CommonMessage<LibObjT>::_ThisCommonMessage;
+
+    using _Packet =
+        typename std::conditional<std::is_const<LibObjT>::value, CommonPacket<const bt_packet>,
+                                  CommonPacket<bt_packet>>::type;
+
+public:
+    using Shared = internal::SharedMessage<CommonPacketEndMessage<LibObjT>, LibObjT>;
+
+    explicit CommonPacketEndMessage(const _LibObjPtr libObjPtr) noexcept :
+        _ThisCommonMessage {libObjPtr}
+    {
+        BT_ASSERT_DBG(this->isPacketEnd());
+    }
+
+    template <typename OtherLibObjT>
+    CommonPacketEndMessage(const CommonPacketEndMessage<OtherLibObjT>& val) noexcept :
+        _ThisCommonMessage {val}
+    {
+    }
+
+    template <typename OtherLibObjT>
+    CommonPacketEndMessage<LibObjT>&
+    operator=(const CommonPacketEndMessage<OtherLibObjT>& val) noexcept
+    {
+        _ThisCommonMessage::operator=(val);
+        return *this;
+    }
+
+    ConstPacket packet() const noexcept
+    {
+        return ConstPacket {
+            internal::CommonPacketEndMessageSpec<const bt_message>::packet(this->_libObjPtr())};
+    }
+
+    _Packet packet() noexcept
+    {
+        return _Packet {internal::CommonPacketEndMessageSpec<LibObjT>::packet(this->_libObjPtr())};
+    }
+
+    void defaultClockSnapshot(const std::uint64_t val) noexcept
+    {
+        static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
+
+        bt_message_packet_end_set_default_clock_snapshot(this->_libObjPtr(), val);
+    }
+
+    ConstClockSnapshot defaultClockSnapshot() const noexcept
+    {
+        const auto libObjPtr =
+            bt_message_packet_end_borrow_default_clock_snapshot_const(this->_libObjPtr());
+
+        return ConstClockSnapshot {libObjPtr};
+    }
+
+    Shared shared() const noexcept
+    {
+        return Shared {*this};
+    }
+};
+
+using PacketEndMessage = CommonPacketEndMessage<bt_message>;
+using ConstPacketEndMessage = CommonPacketEndMessage<const bt_message>;
+
+namespace internal {
+
+template <typename LibObjT>
+struct CommonEventMessageSpec;
+
+// Functions specific to mutable event messages
+template <>
+struct CommonEventMessageSpec<bt_message> final
+{
+    static bt_event *event(bt_message * const libObjPtr) noexcept
+    {
+        return bt_message_event_borrow_event(libObjPtr);
+    }
+};
+
+// Functions specific to constant event messages
+template <>
+struct CommonEventMessageSpec<const bt_message> final
+{
+    static const bt_event *event(const bt_message * const libObjPtr) noexcept
+    {
+        return bt_message_event_borrow_event_const(libObjPtr);
+    }
+};
+
+} // namespace internal
+
+template <typename LibObjT>
+class CommonEventMessage final : public CommonMessage<LibObjT>
+{
+private:
+    using typename CommonMessage<LibObjT>::_LibObjPtr;
+    using typename CommonMessage<LibObjT>::_ThisCommonMessage;
+
+    using _Event =
+        typename std::conditional<std::is_const<LibObjT>::value, CommonEvent<const bt_event>,
+                                  CommonEvent<bt_event>>::type;
+
+public:
+    using Shared = internal::SharedMessage<CommonEventMessage<LibObjT>, LibObjT>;
+
+    explicit CommonEventMessage(const _LibObjPtr libObjPtr) noexcept :
+        _ThisCommonMessage {libObjPtr}
+    {
+        BT_ASSERT_DBG(this->isEvent());
+    }
+
+    template <typename OtherLibObjT>
+    CommonEventMessage(const CommonEventMessage<OtherLibObjT>& val) noexcept :
+        _ThisCommonMessage {val}
+    {
+    }
+
+    template <typename OtherLibObjT>
+    CommonEventMessage<LibObjT>& operator=(const CommonEventMessage<OtherLibObjT>& val) noexcept
+    {
+        _ThisCommonMessage::operator=(val);
+        return *this;
+    }
+
+    ConstEvent event() const noexcept
+    {
+        return ConstEvent {
+            internal::CommonEventMessageSpec<const bt_message>::event(this->_libObjPtr())};
+    }
+
+    _Event event() noexcept
+    {
+        return _Event {internal::CommonEventMessageSpec<LibObjT>::event(this->_libObjPtr())};
+    }
+
+    ConstClockSnapshot defaultClockSnapshot() const noexcept
+    {
+        const auto libObjPtr =
+            bt_message_event_borrow_default_clock_snapshot_const(this->_libObjPtr());
+
+        return ConstClockSnapshot {libObjPtr};
+    }
+
+    Shared shared() const noexcept
+    {
+        return Shared {*this};
+    }
+};
+
+using EventMessage = CommonEventMessage<bt_message>;
+using ConstEventMessage = CommonEventMessage<const bt_message>;
+
+namespace internal {
+
+template <typename LibObjT>
+struct CommonDiscardedEventsMessageSpec;
+
+// Functions specific to mutable discarded events messages
+template <>
+struct CommonDiscardedEventsMessageSpec<bt_message> final
+{
+    static bt_stream *stream(bt_message * const libObjPtr) noexcept
+    {
+        return bt_message_discarded_events_borrow_stream(libObjPtr);
+    }
+};
+
+// Functions specific to constant discarded events messages
+template <>
+struct CommonDiscardedEventsMessageSpec<const bt_message> final
+{
+    static const bt_stream *stream(const bt_message * const libObjPtr) noexcept
+    {
+        return bt_message_discarded_events_borrow_stream_const(libObjPtr);
+    }
+};
+
+} // namespace internal
+
+template <typename LibObjT>
+class CommonDiscardedEventsMessage final : public CommonMessage<LibObjT>
+{
+private:
+    using typename CommonMessage<LibObjT>::_LibObjPtr;
+    using typename CommonMessage<LibObjT>::_ThisCommonMessage;
+
+    using _Stream =
+        typename std::conditional<std::is_const<LibObjT>::value, CommonStream<const bt_stream>,
+                                  CommonStream<bt_stream>>::type;
+
+public:
+    using Shared = internal::SharedMessage<CommonDiscardedEventsMessage<LibObjT>, LibObjT>;
+
+    explicit CommonDiscardedEventsMessage(const _LibObjPtr libObjPtr) noexcept :
+        _ThisCommonMessage {libObjPtr}
+    {
+        BT_ASSERT_DBG(this->isDiscardedEvents());
+    }
+
+    template <typename OtherLibObjT>
+    CommonDiscardedEventsMessage(const CommonDiscardedEventsMessage<OtherLibObjT>& val) noexcept :
+        _ThisCommonMessage {val}
+    {
+    }
+
+    template <typename OtherLibObjT>
+    CommonDiscardedEventsMessage<LibObjT>&
+    operator=(const CommonDiscardedEventsMessage<OtherLibObjT>& val) noexcept
+    {
+        _ThisCommonMessage::operator=(val);
+        return *this;
+    }
+
+    ConstStream stream() const noexcept
+    {
+        return ConstStream {internal::CommonDiscardedEventsMessageSpec<const bt_message>::stream(
+            this->_libObjPtr())};
+    }
+
+    _Stream stream() noexcept
+    {
+        return _Stream {
+            internal::CommonDiscardedEventsMessageSpec<LibObjT>::stream(this->_libObjPtr())};
+    }
+
+    ConstClockSnapshot beginningDefaultClockSnapshot() const noexcept
+    {
+        const auto libObjPtr =
+            bt_message_discarded_events_borrow_beginning_default_clock_snapshot_const(
+                this->_libObjPtr());
+
+        return ConstClockSnapshot {libObjPtr};
+    }
+
+    ConstClockSnapshot endDefaultClockSnapshot() const noexcept
+    {
+        const auto libObjPtr =
+            bt_message_discarded_events_borrow_end_default_clock_snapshot_const(this->_libObjPtr());
+
+        return ConstClockSnapshot {libObjPtr};
+    }
+
+    void count(const std::uint64_t count) noexcept
+    {
+        static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
+
+        bt_message_discarded_events_set_count(this->_libObjPtr(), count);
+    }
+
+    nonstd::optional<std::uint64_t> count() const noexcept
+    {
+        std::uint64_t count;
+        const auto avail = bt_message_discarded_events_get_count(this->_libObjPtr(), &count);
+
+        if (avail) {
+            return count;
+        }
+
+        return nonstd::nullopt;
+    }
+
+    Shared shared() const noexcept
+    {
+        return Shared {*this};
+    }
+};
+
+using DiscardedEventsMessage = CommonDiscardedEventsMessage<bt_message>;
+using ConstDiscardedEventsMessage = CommonDiscardedEventsMessage<const bt_message>;
+
+namespace internal {
+
+template <typename LibObjT>
+struct CommonDiscardedPacketsMessageSpec;
+
+// Functions specific to mutable discarded packets messages
+template <>
+struct CommonDiscardedPacketsMessageSpec<bt_message> final
+{
+    static bt_stream *stream(bt_message * const libObjPtr) noexcept
+    {
+        return bt_message_discarded_packets_borrow_stream(libObjPtr);
+    }
+};
+
+// Functions specific to constant discarded packets messages
+template <>
+struct CommonDiscardedPacketsMessageSpec<const bt_message> final
+{
+    static const bt_stream *stream(const bt_message * const libObjPtr) noexcept
+    {
+        return bt_message_discarded_packets_borrow_stream_const(libObjPtr);
+    }
+};
+
+} // namespace internal
+
+template <typename LibObjT>
+class CommonDiscardedPacketsMessage final : public CommonMessage<LibObjT>
+{
+private:
+    using typename CommonMessage<LibObjT>::_LibObjPtr;
+    using typename CommonMessage<LibObjT>::_ThisCommonMessage;
+
+    using _Stream =
+        typename std::conditional<std::is_const<LibObjT>::value, CommonStream<const bt_stream>,
+                                  CommonStream<bt_stream>>::type;
+
+public:
+    using Shared = internal::SharedMessage<CommonDiscardedPacketsMessage<LibObjT>, LibObjT>;
+
+    explicit CommonDiscardedPacketsMessage(const _LibObjPtr libObjPtr) noexcept :
+        _ThisCommonMessage {libObjPtr}
+    {
+        BT_ASSERT_DBG(this->isDiscardedPackets());
+    }
+
+    template <typename OtherLibObjT>
+    CommonDiscardedPacketsMessage(const CommonDiscardedPacketsMessage<OtherLibObjT>& val) noexcept :
+        _ThisCommonMessage {val}
+    {
+    }
+
+    template <typename OtherLibObjT>
+    CommonDiscardedPacketsMessage<LibObjT>&
+    operator=(const CommonDiscardedPacketsMessage<OtherLibObjT>& val) noexcept
+    {
+        _ThisCommonMessage::operator=(val);
+        return *this;
+    }
+
+    ConstStream stream() const noexcept
+    {
+        return ConstStream {internal::CommonDiscardedPacketsMessageSpec<const bt_message>::stream(
+            this->_libObjPtr())};
+    }
+
+    _Stream stream() noexcept
+    {
+        return _Stream {
+            internal::CommonDiscardedPacketsMessageSpec<LibObjT>::stream(this->_libObjPtr())};
+    }
+
+    ConstClockSnapshot beginningDefaultClockSnapshot() const noexcept
+    {
+        const auto libObjPtr =
+            bt_message_discarded_packets_borrow_beginning_default_clock_snapshot_const(
+                this->_libObjPtr());
+
+        return ConstClockSnapshot {libObjPtr};
+    }
+
+    ConstClockSnapshot endDefaultClockSnapshot() const noexcept
+    {
+        const auto libObjPtr = bt_message_discarded_packets_borrow_end_default_clock_snapshot_const(
+            this->_libObjPtr());
+
+        return ConstClockSnapshot {libObjPtr};
+    }
+
+    void count(const std::uint64_t count) noexcept
+    {
+        static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
+
+        bt_message_discarded_packets_set_count(this->_libObjPtr(), count);
+    }
+
+    nonstd::optional<std::uint64_t> count() const noexcept
+    {
+        std::uint64_t count;
+        const auto avail = bt_message_discarded_packets_get_count(this->_libObjPtr(), &count);
+
+        if (avail) {
+            return count;
+        }
+
+        return nonstd::nullopt;
+    }
+
+    Shared shared() const noexcept
+    {
+        return Shared {*this};
+    }
+};
+
+using DiscardedPacketsMessage = CommonDiscardedPacketsMessage<bt_message>;
+using ConstDiscardedPacketsMessage = CommonDiscardedPacketsMessage<const bt_message>;
+
+template <typename LibObjT>
+class CommonMessageIteratorInactivityMessage final : public CommonMessage<LibObjT>
+{
+private:
+    using typename CommonMessage<LibObjT>::_LibObjPtr;
+    using typename CommonMessage<LibObjT>::_ThisCommonMessage;
+
+public:
+    using Shared =
+        internal::SharedMessage<CommonMessageIteratorInactivityMessage<LibObjT>, LibObjT>;
+
+    explicit CommonMessageIteratorInactivityMessage(const _LibObjPtr libObjPtr) noexcept :
+        _ThisCommonMessage {libObjPtr}
+    {
+        BT_ASSERT_DBG(this->isMessageIteratorInactivity());
+    }
+
+    template <typename OtherLibObjT>
+    CommonMessageIteratorInactivityMessage(
+        const CommonMessageIteratorInactivityMessage<OtherLibObjT>& val) noexcept :
+        _ThisCommonMessage {val}
+    {
+    }
+
+    template <typename OtherLibObjT>
+    CommonMessageIteratorInactivityMessage<LibObjT>&
+    operator=(const CommonMessageIteratorInactivityMessage<OtherLibObjT>& val) noexcept
+    {
+        _ThisCommonMessage::operator=(val);
+        return *this;
+    }
+
+    ConstClockSnapshot clockSnapshot() const noexcept
+    {
+        const auto libObjPtr =
+            bt_message_message_iterator_inactivity_borrow_clock_snapshot_const(this->_libObjPtr());
+
+        return ConstClockSnapshot {libObjPtr};
+    }
+
+    Shared shared() const noexcept
+    {
+        return Shared {*this};
+    }
+};
+
+using MessageIteratorInactivityMessage = CommonMessageIteratorInactivityMessage<bt_message>;
+using ConstMessageIteratorInactivityMessage =
+    CommonMessageIteratorInactivityMessage<const bt_message>;
+
+template <typename LibObjT>
+CommonStreamBeginningMessage<LibObjT> CommonMessage<LibObjT>::asStreamBeginning() const noexcept
+{
+    BT_ASSERT_DBG(this->isStreamBeginning());
+    return CommonStreamBeginningMessage<LibObjT> {this->_libObjPtr()};
+}
+
+template <typename LibObjT>
+CommonStreamEndMessage<LibObjT> CommonMessage<LibObjT>::asStreamEnd() const noexcept
+{
+    BT_ASSERT_DBG(this->isStreamEnd());
+    return CommonStreamEndMessage<LibObjT> {this->_libObjPtr()};
+}
+
+template <typename LibObjT>
+CommonPacketBeginningMessage<LibObjT> CommonMessage<LibObjT>::asPacketBeginning() const noexcept
+{
+    BT_ASSERT_DBG(this->isPacketBeginning());
+    return CommonPacketBeginningMessage<LibObjT> {this->_libObjPtr()};
+}
+
+template <typename LibObjT>
+CommonPacketEndMessage<LibObjT> CommonMessage<LibObjT>::asPacketEnd() const noexcept
+{
+    BT_ASSERT_DBG(this->isPacketEnd());
+    return CommonPacketEndMessage<LibObjT> {this->_libObjPtr()};
+}
+
+template <typename LibObjT>
+CommonEventMessage<LibObjT> CommonMessage<LibObjT>::asEvent() const noexcept
+{
+    BT_ASSERT_DBG(this->isEvent());
+    return CommonEventMessage<LibObjT> {this->_libObjPtr()};
+}
+
+template <typename LibObjT>
+CommonDiscardedEventsMessage<LibObjT> CommonMessage<LibObjT>::asDiscardedEvents() const noexcept
+{
+    BT_ASSERT_DBG(this->isDiscardedEvents());
+    return CommonDiscardedEventsMessage<LibObjT> {this->_libObjPtr()};
+}
+
+template <typename LibObjT>
+CommonMessageIteratorInactivityMessage<LibObjT>
+CommonMessage<LibObjT>::asMessageIteratorInactivity() const noexcept
+{
+    BT_ASSERT_DBG(this->isMessageIteratorInactivity());
+    return CommonMessageIteratorInactivityMessage<LibObjT> {this->_libObjPtr()};
+}
+
+} // namespace bt2
+
+#endif // BABELTRACE_CPP_COMMON_BT2_MESSAGE_HPP
This page took 0.032909 seconds and 4 git commands to generate.