3a05e1d3b8bc29df0dd58463481619ea4b986086
[babeltrace.git] / src / cpp-common / bt2 / integer-range-set.hpp
1 /*
2 * Copyright (c) 2020 Philippe Proulx <pproulx@efficios.com>
3 *
4 * SPDX-License-Identifier: MIT
5 */
6
7 #ifndef BABELTRACE_CPP_COMMON_BT2_INTEGER_RANGE_SET_HPP
8 #define BABELTRACE_CPP_COMMON_BT2_INTEGER_RANGE_SET_HPP
9
10 #include <cstdint>
11 #include <type_traits>
12
13 #include <babeltrace2/babeltrace.h>
14
15 #include "borrowed-object.hpp"
16 #include "common-iter.hpp"
17 #include "exc.hpp"
18 #include "integer-range.hpp"
19 #include "internal/utils.hpp"
20 #include "shared-obj.hpp"
21
22 namespace bt2 {
23
24 namespace internal {
25
26 template <typename LibObjT>
27 struct IntegerRangeSetRefFuncs;
28
29 template <>
30 struct IntegerRangeSetRefFuncs<const bt_integer_range_set_unsigned> final
31 {
32 static void get(const bt_integer_range_set_unsigned * const libObjPtr)
33 {
34 bt_integer_range_set_unsigned_get_ref(libObjPtr);
35 }
36
37 static void put(const bt_integer_range_set_unsigned * const libObjPtr)
38 {
39 bt_integer_range_set_unsigned_put_ref(libObjPtr);
40 }
41 };
42
43 template <>
44 struct IntegerRangeSetRefFuncs<const bt_integer_range_set_signed> final
45 {
46 static void get(const bt_integer_range_set_signed * const libObjPtr)
47 {
48 bt_integer_range_set_signed_get_ref(libObjPtr);
49 }
50
51 static void put(const bt_integer_range_set_signed * const libObjPtr)
52 {
53 bt_integer_range_set_signed_put_ref(libObjPtr);
54 }
55 };
56
57 template <typename LibObjT>
58 struct CommonIntegerRangeSetSpec;
59
60 /* Functions specific to unsigned integer range sets */
61 template <>
62 struct CommonIntegerRangeSetSpec<const bt_integer_range_set_unsigned> final
63 {
64 static std::uint64_t size(const bt_integer_range_set_unsigned * const libRangePtr) noexcept
65 {
66 return bt_integer_range_set_get_range_count(
67 bt_integer_range_set_unsigned_as_range_set_const(libRangePtr));
68 }
69
70 static const bt_integer_range_unsigned *
71 rangeByIndex(const bt_integer_range_set_unsigned * const libRangePtr,
72 const std::uint64_t index) noexcept
73 {
74 return bt_integer_range_set_unsigned_borrow_range_by_index_const(libRangePtr, index);
75 }
76
77 static bool isEqual(const bt_integer_range_set_unsigned * const libRangePtrA,
78 const bt_integer_range_set_unsigned * const libRangePtrB) noexcept
79 {
80 return static_cast<bool>(
81 bt_integer_range_set_unsigned_is_equal(libRangePtrA, libRangePtrB));
82 }
83
84 static bt_integer_range_set_add_range_status
85 addRange(bt_integer_range_set_unsigned * const libRangePtr, const std::uint64_t lower,
86 const std::uint64_t upper) noexcept
87 {
88 return bt_integer_range_set_unsigned_add_range(libRangePtr, lower, upper);
89 }
90
91 static bt_integer_range_set_unsigned *create() noexcept
92 {
93 return bt_integer_range_set_unsigned_create();
94 }
95 };
96
97 /* Functions specific to signed integer range sets */
98 template <>
99 struct CommonIntegerRangeSetSpec<const bt_integer_range_set_signed> final
100 {
101 static std::uint64_t size(const bt_integer_range_set_signed * const libRangePtr) noexcept
102 {
103 return bt_integer_range_set_get_range_count(
104 bt_integer_range_set_signed_as_range_set_const(libRangePtr));
105 }
106
107 static const bt_integer_range_signed *
108 rangeByIndex(const bt_integer_range_set_signed * const libRangePtr,
109 const std::uint64_t index) noexcept
110 {
111 return bt_integer_range_set_signed_borrow_range_by_index_const(libRangePtr, index);
112 }
113
114 static bool isEqual(const bt_integer_range_set_signed * const libRangePtrA,
115 const bt_integer_range_set_signed * const libRangePtrB) noexcept
116 {
117 return static_cast<bool>(bt_integer_range_set_signed_is_equal(libRangePtrA, libRangePtrB));
118 }
119
120 static bt_integer_range_set_add_range_status
121 addRange(bt_integer_range_set_signed * const libRangePtr, const std::int64_t lower,
122 const std::int64_t upper) noexcept
123 {
124 return bt_integer_range_set_signed_add_range(libRangePtr, lower, upper);
125 }
126
127 static bt_integer_range_set_signed *create() noexcept
128 {
129 return bt_integer_range_set_signed_create();
130 }
131 };
132
133 } /* namespace internal */
134
135 template <typename LibObjT>
136 class ConstVariantWithIntegerSelectorFieldClassOption;
137
138 template <typename LibObjT, typename RangeSetT>
139 class CommonVariantWithIntegerSelectorFieldClass;
140
141 template <typename LibObjT>
142 class CommonTraceClass;
143
144 template <typename LibObjT>
145 class CommonIntegerRangeSet final : public BorrowedObject<LibObjT>
146 {
147 /* Allow operator==() to call `other.libObjPtr()` */
148 friend class CommonIntegerRangeSet<bt_integer_range_set_unsigned>;
149 friend class CommonIntegerRangeSet<const bt_integer_range_set_unsigned>;
150 friend class CommonIntegerRangeSet<bt_integer_range_set_signed>;
151 friend class CommonIntegerRangeSet<const bt_integer_range_set_signed>;
152
153 /* Allow appendOption() to call `ranges.libObjPtr()` */
154 friend class CommonVariantWithIntegerSelectorFieldClass<
155 bt_field_class,
156 ConstVariantWithIntegerSelectorFieldClassOption<
157 const bt_field_class_variant_with_selector_field_integer_unsigned_option>>;
158
159 friend class CommonVariantWithIntegerSelectorFieldClass<
160 bt_field_class,
161 ConstVariantWithIntegerSelectorFieldClassOption<
162 const bt_field_class_variant_with_selector_field_integer_signed_option>>;
163
164 /* Allow create*FieldClass() to call `ranges.libObjPtr()` */
165 friend class CommonTraceClass<bt_trace_class>;
166
167 private:
168 using typename BorrowedObject<LibObjT>::_ThisBorrowedObject;
169 using typename BorrowedObject<LibObjT>::_LibObjPtr;
170 using _ConstLibObjT = typename std::add_const<LibObjT>::type;
171 using _RefFuncs = internal::IntegerRangeSetRefFuncs<_ConstLibObjT>;
172 using _Spec = internal::CommonIntegerRangeSetSpec<_ConstLibObjT>;
173 using _ThisCommonIntegerRangeSet = CommonIntegerRangeSet<LibObjT>;
174
175 public:
176 using Shared = SharedObj<_ThisCommonIntegerRangeSet, LibObjT, _RefFuncs>;
177
178 using Range = typename std::conditional<
179 std::is_same<_ConstLibObjT, const bt_integer_range_set_unsigned>::value,
180 ConstUnsignedIntegerRange, ConstSignedIntegerRange>::type;
181
182 using Value = typename Range::Value;
183 using Iterator = CommonIterator<CommonIntegerRangeSet, Range>;
184
185 explicit CommonIntegerRangeSet(const _LibObjPtr libObjPtr) noexcept :
186 _ThisBorrowedObject {libObjPtr}
187 {
188 }
189
190 static Shared create()
191 {
192 const auto libObjPtr = _Spec::create();
193
194 internal::validateCreatedObjPtr(libObjPtr);
195 return CommonIntegerRangeSet::Shared::createWithoutRef(libObjPtr);
196 }
197
198 template <typename OtherLibObjT>
199 CommonIntegerRangeSet(const CommonIntegerRangeSet<OtherLibObjT> rangeSet) noexcept :
200 _ThisBorrowedObject {rangeSet}
201 {
202 }
203
204 template <typename OtherLibObjT>
205 _ThisCommonIntegerRangeSet&
206 operator=(const CommonIntegerRangeSet<OtherLibObjT> rangeSet) noexcept
207 {
208 _ThisBorrowedObject::operator=(rangeSet);
209 return *this;
210 }
211
212 template <typename OtherLibObjT>
213 bool operator==(const CommonIntegerRangeSet<OtherLibObjT> other) const noexcept
214 {
215 return _Spec::isEqual(this->libObjPtr(), other.libObjPtr());
216 }
217
218 template <typename OtherLibObjT>
219 bool operator!=(const CommonIntegerRangeSet<OtherLibObjT> other) const noexcept
220 {
221 return !(*this == other);
222 }
223
224 void addRange(const Value lower, const Value upper)
225 {
226 static_assert(!std::is_const<LibObjT>::value, "`LibObjT` must NOT be `const`.");
227
228 const auto status = _Spec::addRange(this->libObjPtr(), lower, upper);
229
230 if (status == BT_INTEGER_RANGE_SET_ADD_RANGE_STATUS_MEMORY_ERROR) {
231 throw MemoryError {};
232 }
233 }
234
235 std::uint64_t size() const noexcept
236 {
237 return _Spec::size(this->libObjPtr());
238 }
239
240 Range operator[](const std::uint64_t index) const noexcept
241 {
242 return Range {_Spec::rangeByIndex(this->libObjPtr(), index)};
243 }
244
245 Iterator begin() const noexcept
246 {
247 return Iterator {*this, 0};
248 }
249
250 Iterator end() const noexcept
251 {
252 return Iterator {*this, this->size()};
253 }
254
255 Shared shared() const noexcept
256 {
257 return Shared::createWithRef(*this);
258 }
259 };
260
261 using UnsignedIntegerRangeSet = CommonIntegerRangeSet<bt_integer_range_set_unsigned>;
262 using ConstUnsignedIntegerRangeSet = CommonIntegerRangeSet<const bt_integer_range_set_unsigned>;
263 using SignedIntegerRangeSet = CommonIntegerRangeSet<bt_integer_range_set_signed>;
264 using ConstSignedIntegerRangeSet = CommonIntegerRangeSet<const bt_integer_range_set_signed>;
265
266 namespace internal {
267
268 struct UnsignedIntegerRangeSetTypeDescr
269 {
270 using Const = ConstUnsignedIntegerRangeSet;
271 using NonConst = UnsignedIntegerRangeSet;
272 };
273
274 template <>
275 struct TypeDescr<UnsignedIntegerRangeSet> : public UnsignedIntegerRangeSetTypeDescr
276 {
277 };
278
279 template <>
280 struct TypeDescr<ConstUnsignedIntegerRangeSet> : public UnsignedIntegerRangeSetTypeDescr
281 {
282 };
283
284 struct SignedIntegerRangeSetTypeDescr
285 {
286 using Const = ConstSignedIntegerRangeSet;
287 using NonConst = SignedIntegerRangeSet;
288 };
289
290 template <>
291 struct TypeDescr<SignedIntegerRangeSet> : public SignedIntegerRangeSetTypeDescr
292 {
293 };
294
295 template <>
296 struct TypeDescr<ConstSignedIntegerRangeSet> : public SignedIntegerRangeSetTypeDescr
297 {
298 };
299
300 } /* namespace internal */
301 } /* namespace bt2 */
302
303 #endif /* BABELTRACE_CPP_COMMON_BT2_INTEGER_RANGE_SET_HPP */
This page took 0.034539 seconds and 3 git commands to generate.