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