Add C++ interface for the libbabeltrace2 `bt_integer_range_set_*` API
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Thu, 17 Dec 2020 02:13:13 +0000 (21:13 -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 integer range set objects.

The four new available types are:

* `bt2::UnsignedIntegerRange`
* `bt2::ConstUnsignedIntegerRange`
* `bt2::SignedIntegerRange`
* `bt2::ConstSignedIntegerRange`

Implicitly convert from a mutable integer range set to a constant
integer range set with converting constructors and assignment operators.

All classes have the `Shared` type alias which is what the shared()
method returns. You can also implicitly convert from a shared mutable
integer range set to a shared constant integer range set.

The corresponding integer range type of any integer range set type `T`
is `T::Range`.

Borrow an integer range by index from the set with operator[]():

    auto myRange = myRangeSet[3];

Get the number of integer ranges in the set with the size() method.

Compare compatible integer range sets with operator==() and
operator!=().

Create a shared integer range set with the static create() methods, for
example:

    auto myRangeSet = bt2::SignedIntegerRangeSet::create();

Those methods can throw a `LibMemoryError` instance.

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

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

diff --git a/src/cpp-common/bt2/integer-range-set.hpp b/src/cpp-common/bt2/integer-range-set.hpp
new file mode 100644 (file)
index 0000000..52fc540
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2020 Philippe Proulx <pproulx@efficios.com>
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef BABELTRACE_CPP_COMMON_BT2_INTEGER_RANGE_SET_HPP
+#define BABELTRACE_CPP_COMMON_BT2_INTEGER_RANGE_SET_HPP
+
+#include <cstdint>
+#include <type_traits>
+#include <babeltrace2/babeltrace.h>
+
+#include "internal/borrowed-obj.hpp"
+#include "internal/utils.hpp"
+#include "integer-range.hpp"
+#include "lib-error.hpp"
+
+namespace bt2 {
+
+namespace internal {
+
+template <typename LibObjT>
+struct IntegerRangeSetRefFuncs;
+
+template <>
+struct IntegerRangeSetRefFuncs<const bt_integer_range_set_unsigned> final
+{
+    static void get(const bt_integer_range_set_unsigned * const libObjPtr)
+    {
+        bt_integer_range_set_unsigned_get_ref(libObjPtr);
+    }
+
+    static void put(const bt_integer_range_set_unsigned * const libObjPtr)
+    {
+        bt_integer_range_set_unsigned_get_ref(libObjPtr);
+    }
+};
+
+template <>
+struct IntegerRangeSetRefFuncs<const bt_integer_range_set_signed> final
+{
+    static void get(const bt_integer_range_set_signed * const libObjPtr)
+    {
+        bt_integer_range_set_signed_get_ref(libObjPtr);
+    }
+
+    static void put(const bt_integer_range_set_signed * const libObjPtr)
+    {
+        bt_integer_range_set_signed_get_ref(libObjPtr);
+    }
+};
+
+template <typename LibObjT>
+struct CommonIntegerRangeSetSpec;
+
+// Functions specific to unsigned integer range sets
+template <>
+struct CommonIntegerRangeSetSpec<const bt_integer_range_set_unsigned> final
+{
+    static std::uint64_t size(const bt_integer_range_set_unsigned * const libRangePtr) noexcept
+    {
+        return bt_integer_range_set_get_range_count(
+            bt_integer_range_set_unsigned_as_range_set_const(libRangePtr));
+    }
+
+    static const bt_integer_range_unsigned *
+    rangeByIndex(const bt_integer_range_set_unsigned * const libRangePtr,
+                 const std::uint64_t index) noexcept
+    {
+        return bt_integer_range_set_unsigned_borrow_range_by_index_const(libRangePtr, index);
+    }
+
+    static bool isEqual(const bt_integer_range_set_unsigned * const libRangePtrA,
+                        const bt_integer_range_set_unsigned * const libRangePtrB) noexcept
+    {
+        return static_cast<bool>(
+            bt_integer_range_set_unsigned_is_equal(libRangePtrA, libRangePtrB));
+    }
+
+    static bt_integer_range_set_add_range_status
+    addRange(bt_integer_range_set_unsigned * const libRangePtr, const std::uint64_t lower,
+             const std::uint64_t upper) noexcept
+    {
+        return bt_integer_range_set_unsigned_add_range(libRangePtr, lower, upper);
+    }
+
+    static bt_integer_range_set_unsigned *create() noexcept
+    {
+        return bt_integer_range_set_unsigned_create();
+    }
+};
+
+// Functions specific to signed integer range sets
+template <>
+struct CommonIntegerRangeSetSpec<const bt_integer_range_set_signed> final
+{
+    static std::uint64_t size(const bt_integer_range_set_signed * const libRangePtr) noexcept
+    {
+        return bt_integer_range_set_get_range_count(
+            bt_integer_range_set_signed_as_range_set_const(libRangePtr));
+    }
+
+    static const bt_integer_range_signed *
+    rangeByIndex(const bt_integer_range_set_signed * const libRangePtr,
+                 const std::uint64_t index) noexcept
+    {
+        return bt_integer_range_set_signed_borrow_range_by_index_const(libRangePtr, index);
+    }
+
+    static bool isEqual(const bt_integer_range_set_signed * const libRangePtrA,
+                        const bt_integer_range_set_signed * const libRangePtrB) noexcept
+    {
+        return static_cast<bool>(bt_integer_range_set_signed_is_equal(libRangePtrA, libRangePtrB));
+    }
+
+    static bt_integer_range_set_add_range_status
+    addRange(bt_integer_range_set_signed * const libRangePtr, const std::int64_t lower,
+             const std::int64_t upper) noexcept
+    {
+        return bt_integer_range_set_signed_add_range(libRangePtr, lower, upper);
+    }
+
+    static bt_integer_range_set_signed *create() noexcept
+    {
+        return bt_integer_range_set_signed_create();
+    }
+};
+
+} // namespace internal
+
+template <typename LibObjT>
+class CommonIntegerRangeSet final : public internal::BorrowedObj<LibObjT>
+{
+    // Allow operator==() to call `other._libObjPtr()`
+    friend class CommonIntegerRangeSet<bt_integer_range_set_unsigned>;
+    friend class CommonIntegerRangeSet<const bt_integer_range_set_unsigned>;
+    friend class CommonIntegerRangeSet<bt_integer_range_set_signed>;
+    friend class CommonIntegerRangeSet<const bt_integer_range_set_signed>;
+
+private:
+    using typename internal::BorrowedObj<LibObjT>::_ThisBorrowedObj;
+    using typename internal::BorrowedObj<LibObjT>::_LibObjPtr;
+    using _ConstLibObjT = typename std::add_const<LibObjT>::type;
+    using _RefFuncs = internal::IntegerRangeSetRefFuncs<_ConstLibObjT>;
+    using _Spec = internal::CommonIntegerRangeSetSpec<_ConstLibObjT>;
+    using _ThisCommonIntegerRangeSet = CommonIntegerRangeSet<LibObjT>;
+
+public:
+    using Shared = internal::SharedObj<_ThisCommonIntegerRangeSet, LibObjT, _RefFuncs>;
+
+    using Range = typename std::conditional<
+        std::is_same<_ConstLibObjT, const bt_integer_range_set_unsigned>::value,
+        ConstUnsignedIntegerRange, ConstSignedIntegerRange>::type;
+
+    using Value = typename Range::Value;
+
+    explicit CommonIntegerRangeSet(const _LibObjPtr libObjPtr) noexcept :
+        _ThisBorrowedObj {libObjPtr}
+    {
+    }
+
+    static Shared create()
+    {
+        const auto libObjPtr = _Spec::create();
+
+        internal::validateCreatedObjPtr(libObjPtr);
+        return Shared {_ThisCommonIntegerRangeSet {libObjPtr}};
+    }
+
+    template <typename OtherLibObjT>
+    CommonIntegerRangeSet(const CommonIntegerRangeSet<OtherLibObjT>& rangeSet) noexcept :
+        _ThisBorrowedObj {rangeSet}
+    {
+    }
+
+    template <typename OtherLibObjT>
+    _ThisCommonIntegerRangeSet&
+    operator=(const CommonIntegerRangeSet<OtherLibObjT>& rangeSet) noexcept
+    {
+        _ThisBorrowedObj::operator=(rangeSet);
+        return *this;
+    }
+
+    template <typename OtherLibObjT>
+    bool operator==(const CommonIntegerRangeSet<OtherLibObjT>& other) const noexcept
+    {
+        return _Spec::isEqual(this->_libObjPtr(), other._libObjPtr());
+    }
+
+    template <typename OtherLibObjT>
+    bool operator!=(const CommonIntegerRangeSet<OtherLibObjT>& other) const noexcept
+    {
+        return !(*this == other);
+    }
+
+    void addRange(const Value lower, const Value upper)
+    {
+        static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
+
+        const auto status = _Spec::addRange(this->_libObjPtr(), lower, upper);
+
+        if (status == BT_INTEGER_RANGE_SET_ADD_RANGE_STATUS_MEMORY_ERROR) {
+            throw LibMemoryError {};
+        }
+    }
+
+    std::uint64_t size() const noexcept
+    {
+        return _Spec::size(this->_libObjPtr());
+    }
+
+    Range operator[](const std::uint64_t index) const noexcept
+    {
+        return Range {_Spec::rangeByIndex(this->_libObjPtr(), index)};
+    }
+
+    Shared shared() const noexcept
+    {
+        return Shared {*this};
+    }
+};
+
+using UnsignedIntegerRangeSet = CommonIntegerRangeSet<bt_integer_range_set_unsigned>;
+using ConstUnsignedIntegerRangeSet = CommonIntegerRangeSet<const bt_integer_range_set_unsigned>;
+using SignedIntegerRangeSet = CommonIntegerRangeSet<bt_integer_range_set_signed>;
+using ConstSignedIntegerRangeSet = CommonIntegerRangeSet<const bt_integer_range_set_signed>;
+
+} // namespace bt2
+
+#endif // BABELTRACE_CPP_COMMON_BT2_INTEGER_RANGE_SET_HPP
This page took 0.026706 seconds and 4 git commands to generate.