2 * Copyright (c) 2020 Philippe Proulx <pproulx@efficios.com>
4 * SPDX-License-Identifier: MIT
7 #ifndef BABELTRACE_CPP_COMMON_BT2_INTEGER_RANGE_SET_HPP
8 #define BABELTRACE_CPP_COMMON_BT2_INTEGER_RANGE_SET_HPP
11 #include <type_traits>
12 #include <babeltrace2/babeltrace.h>
14 #include "internal/borrowed-obj.hpp"
15 #include "internal/utils.hpp"
16 #include "integer-range.hpp"
17 #include "lib-error.hpp"
23 template <typename LibObjT>
24 struct IntegerRangeSetRefFuncs;
27 struct IntegerRangeSetRefFuncs<const bt_integer_range_set_unsigned> final
29 static void get(const bt_integer_range_set_unsigned * const libObjPtr)
31 bt_integer_range_set_unsigned_get_ref(libObjPtr);
34 static void put(const bt_integer_range_set_unsigned * const libObjPtr)
36 bt_integer_range_set_unsigned_get_ref(libObjPtr);
41 struct IntegerRangeSetRefFuncs<const bt_integer_range_set_signed> final
43 static void get(const bt_integer_range_set_signed * const libObjPtr)
45 bt_integer_range_set_signed_get_ref(libObjPtr);
48 static void put(const bt_integer_range_set_signed * const libObjPtr)
50 bt_integer_range_set_signed_get_ref(libObjPtr);
54 template <typename LibObjT>
55 struct CommonIntegerRangeSetSpec;
57 // Functions specific to unsigned integer range sets
59 struct CommonIntegerRangeSetSpec<const bt_integer_range_set_unsigned> final
61 static std::uint64_t size(const bt_integer_range_set_unsigned * const libRangePtr) noexcept
63 return bt_integer_range_set_get_range_count(
64 bt_integer_range_set_unsigned_as_range_set_const(libRangePtr));
67 static const bt_integer_range_unsigned *
68 rangeByIndex(const bt_integer_range_set_unsigned * const libRangePtr,
69 const std::uint64_t index) noexcept
71 return bt_integer_range_set_unsigned_borrow_range_by_index_const(libRangePtr, index);
74 static bool isEqual(const bt_integer_range_set_unsigned * const libRangePtrA,
75 const bt_integer_range_set_unsigned * const libRangePtrB) noexcept
77 return static_cast<bool>(
78 bt_integer_range_set_unsigned_is_equal(libRangePtrA, libRangePtrB));
81 static bt_integer_range_set_add_range_status
82 addRange(bt_integer_range_set_unsigned * const libRangePtr, const std::uint64_t lower,
83 const std::uint64_t upper) noexcept
85 return bt_integer_range_set_unsigned_add_range(libRangePtr, lower, upper);
88 static bt_integer_range_set_unsigned *create() noexcept
90 return bt_integer_range_set_unsigned_create();
94 // Functions specific to signed integer range sets
96 struct CommonIntegerRangeSetSpec<const bt_integer_range_set_signed> final
98 static std::uint64_t size(const bt_integer_range_set_signed * const libRangePtr) noexcept
100 return bt_integer_range_set_get_range_count(
101 bt_integer_range_set_signed_as_range_set_const(libRangePtr));
104 static const bt_integer_range_signed *
105 rangeByIndex(const bt_integer_range_set_signed * const libRangePtr,
106 const std::uint64_t index) noexcept
108 return bt_integer_range_set_signed_borrow_range_by_index_const(libRangePtr, index);
111 static bool isEqual(const bt_integer_range_set_signed * const libRangePtrA,
112 const bt_integer_range_set_signed * const libRangePtrB) noexcept
114 return static_cast<bool>(bt_integer_range_set_signed_is_equal(libRangePtrA, libRangePtrB));
117 static bt_integer_range_set_add_range_status
118 addRange(bt_integer_range_set_signed * const libRangePtr, const std::int64_t lower,
119 const std::int64_t upper) noexcept
121 return bt_integer_range_set_signed_add_range(libRangePtr, lower, upper);
124 static bt_integer_range_set_signed *create() noexcept
126 return bt_integer_range_set_signed_create();
130 } // namespace internal
132 template <typename LibObjT>
133 class CommonIntegerRangeSet final : public internal::BorrowedObj<LibObjT>
135 // Allow operator==() to call `other._libObjPtr()`
136 friend class CommonIntegerRangeSet<bt_integer_range_set_unsigned>;
137 friend class CommonIntegerRangeSet<const bt_integer_range_set_unsigned>;
138 friend class CommonIntegerRangeSet<bt_integer_range_set_signed>;
139 friend class CommonIntegerRangeSet<const bt_integer_range_set_signed>;
142 using typename internal::BorrowedObj<LibObjT>::_ThisBorrowedObj;
143 using typename internal::BorrowedObj<LibObjT>::_LibObjPtr;
144 using _ConstLibObjT = typename std::add_const<LibObjT>::type;
145 using _RefFuncs = internal::IntegerRangeSetRefFuncs<_ConstLibObjT>;
146 using _Spec = internal::CommonIntegerRangeSetSpec<_ConstLibObjT>;
147 using _ThisCommonIntegerRangeSet = CommonIntegerRangeSet<LibObjT>;
150 using Shared = internal::SharedObj<_ThisCommonIntegerRangeSet, LibObjT, _RefFuncs>;
152 using Range = typename std::conditional<
153 std::is_same<_ConstLibObjT, const bt_integer_range_set_unsigned>::value,
154 ConstUnsignedIntegerRange, ConstSignedIntegerRange>::type;
156 using Value = typename Range::Value;
158 explicit CommonIntegerRangeSet(const _LibObjPtr libObjPtr) noexcept :
159 _ThisBorrowedObj {libObjPtr}
163 static Shared create()
165 const auto libObjPtr = _Spec::create();
167 internal::validateCreatedObjPtr(libObjPtr);
168 return Shared {_ThisCommonIntegerRangeSet {libObjPtr}};
171 template <typename OtherLibObjT>
172 CommonIntegerRangeSet(const CommonIntegerRangeSet<OtherLibObjT>& rangeSet) noexcept :
173 _ThisBorrowedObj {rangeSet}
177 template <typename OtherLibObjT>
178 _ThisCommonIntegerRangeSet&
179 operator=(const CommonIntegerRangeSet<OtherLibObjT>& rangeSet) noexcept
181 _ThisBorrowedObj::operator=(rangeSet);
185 template <typename OtherLibObjT>
186 bool operator==(const CommonIntegerRangeSet<OtherLibObjT>& other) const noexcept
188 return _Spec::isEqual(this->_libObjPtr(), other._libObjPtr());
191 template <typename OtherLibObjT>
192 bool operator!=(const CommonIntegerRangeSet<OtherLibObjT>& other) const noexcept
194 return !(*this == other);
197 void addRange(const Value lower, const Value upper)
199 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
201 const auto status = _Spec::addRange(this->_libObjPtr(), lower, upper);
203 if (status == BT_INTEGER_RANGE_SET_ADD_RANGE_STATUS_MEMORY_ERROR) {
204 throw LibMemoryError {};
208 std::uint64_t size() const noexcept
210 return _Spec::size(this->_libObjPtr());
213 Range operator[](const std::uint64_t index) const noexcept
215 return Range {_Spec::rangeByIndex(this->_libObjPtr(), index)};
218 Shared shared() const noexcept
220 return Shared {*this};
224 using UnsignedIntegerRangeSet = CommonIntegerRangeSet<bt_integer_range_set_unsigned>;
225 using ConstUnsignedIntegerRangeSet = CommonIntegerRangeSet<const bt_integer_range_set_unsigned>;
226 using SignedIntegerRangeSet = CommonIntegerRangeSet<bt_integer_range_set_signed>;
227 using ConstSignedIntegerRangeSet = CommonIntegerRangeSet<const bt_integer_range_set_signed>;
231 #endif // BABELTRACE_CPP_COMMON_BT2_INTEGER_RANGE_SET_HPP