sparrow ..
Loading...
Searching...
No Matches
dynamic_bitset.hpp
Go to the documentation of this file.
1// Copyright 2024 Man Group Operations Limited
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#pragma once
16
17#include <type_traits>
18
22
23namespace sparrow
24{
55 template <std::integral T>
56 class dynamic_bitset : public dynamic_bitset_base<buffer<T>>
57 {
58 public:
59
62 using default_allocator = typename storage_type::default_allocator;
66
88 template <std::ranges::input_range R, allocator A = default_allocator>
89 requires std::convertible_to<std::ranges::range_value_t<R>, value_type>
90 constexpr explicit dynamic_bitset(const R& r, const A& a = A())
91 : dynamic_bitset(std::ranges::size(r), true, a)
92 {
93 std::size_t i = 0;
94 for (auto value : r)
95 {
96 if (!value)
97 {
98 this->set(i, false);
99 }
100 i++;
101 }
102 }
103
110 template <class A = default_allocator>
111 requires(not std::same_as<A, dynamic_bitset<T>> and allocator<A>)
112 constexpr dynamic_bitset(const A& a = A());
113
122 template <allocator A = default_allocator>
123 constexpr explicit dynamic_bitset(size_type n, const A& a = A());
124
134 template <allocator A = default_allocator>
135 constexpr dynamic_bitset(size_type n, value_type v, const A& a = A());
136
152 template <allocator A = default_allocator>
153 constexpr dynamic_bitset(block_type* p, size_type n, const A& a = A());
154
170 template <allocator A = default_allocator>
171 constexpr dynamic_bitset(block_type* p, size_type n, size_type null_count, const A& a = A());
172
173 constexpr ~dynamic_bitset() = default;
174 constexpr dynamic_bitset(const dynamic_bitset&) = default;
175 constexpr dynamic_bitset(dynamic_bitset&&) noexcept = default;
176
177 template <allocator A>
178 constexpr dynamic_bitset(const dynamic_bitset& rhs, const A& a);
179
180 template <allocator A>
181 constexpr dynamic_bitset(dynamic_bitset&& rhs, const A& a);
182
183 constexpr dynamic_bitset& operator=(const dynamic_bitset&) = default;
184 constexpr dynamic_bitset& operator=(dynamic_bitset&&) noexcept = default;
185
186 // Inherit container-like operations from base class
187 using base_type::clear;
188 using base_type::emplace;
189 using base_type::erase;
190 using base_type::insert;
191 using base_type::pop_back;
192 using base_type::push_back;
193 using base_type::resize;
194 };
195
196 template <std::integral T>
197 template <class A>
198 requires(not std::same_as<A, dynamic_bitset<T>> and allocator<A>)
199 constexpr dynamic_bitset<T>::dynamic_bitset(const A& a)
200 : base_type(storage_type(a), 0u)
201 {
203 }
204
205 template <std::integral T>
206 template <allocator A>
208 : dynamic_bitset(n, false, a)
209 {
211 }
212
213 template <std::integral T>
214 template <allocator A>
216 : base_type(
217 storage_type(this->compute_block_count(n), value ? block_type(~block_type(0)) : block_type(0), a),
218 n,
219 value ? 0u : n
220 )
221 {
223 }
224
225 template <std::integral T>
226 template <allocator A>
228 : base_type(storage_type(p, p != nullptr ? this->compute_block_count(n) : 0, a), n)
229 {
231 }
232
233 template <std::integral T>
234 template <allocator A>
241
242 template <std::integral T>
243 template <allocator A>
244 constexpr dynamic_bitset<T>::dynamic_bitset(const dynamic_bitset& rhs, const A& a)
245 : base_type(storage_type(rhs, a))
246 {
247 }
248
249 template <std::integral T>
250 template <allocator A>
252 : base_type(storage_type(std::move(rhs), a))
253 {
254 }
255
270
271 namespace detail
272 {
274
275 inline validity_bitmap ensure_validity_bitmap_impl(std::size_t size, const validity_bitmap& bitmap)
276 {
277 if (bitmap.size() == 0)
278 {
279 return {size, true};
280 }
281 return bitmap; // copy
282 }
283
285 {
286 if (bitmap.size() == 0)
287 {
288 bitmap.resize(size, true);
289 }
290 return std::move(bitmap);
291 }
292
293 // range of booleans
294 template <std::ranges::input_range R>
295 requires(std::same_as<std::ranges::range_value_t<R>, bool>)
296 validity_bitmap ensure_validity_bitmap_impl(std::size_t size, R&& range)
297 {
298 SPARROW_ASSERT_TRUE(size == range_size(range) || range_size(range) == 0);
299 validity_bitmap bitmap(size, true);
300 std::size_t i = 0;
301 for (auto value : range)
302 {
303 if (!value)
304 {
305 bitmap.set(i, false);
306 }
307 i++;
308 }
309 return bitmap;
310 }
311
312 // range of indices / integers (but not booleans)
313 template <std::ranges::input_range R>
314 requires(
315 std::unsigned_integral<std::ranges::range_value_t<R>>
316 && !std::same_as<std::ranges::range_value_t<R>, bool>
317 && !std::same_as<std::decay_t<R>, validity_bitmap>
318 )
319 validity_bitmap ensure_validity_bitmap_impl(std::size_t size, R&& range_of_indices)
320 {
321 validity_bitmap bitmap(size, true);
322 for (auto index : range_of_indices)
323 {
324 bitmap.set(index, false);
325 }
326 return bitmap;
327 }
328 } // namespace detail
329
343 template <class T>
344 concept validity_bitmap_input = (std::same_as<T, validity_bitmap> || std::same_as<T, const validity_bitmap&>
345 || (std::ranges::input_range<T>
346 && std::same_as<std::ranges::range_value_t<T>, bool>)
347 || (std::ranges::input_range<T>
348 && std::unsigned_integral<std::ranges::range_value_t<T>>) )
349 && (!std::same_as<std::remove_cvref_t<T>, std::string>
350 && !std::same_as<std::remove_cvref_t<T>, std::string_view>
351 && !std::same_as<std::decay_t<T>, const char*>);
352
383 template <validity_bitmap_input R>
384 validity_bitmap ensure_validity_bitmap(std::size_t size, R&& validity_input)
385 {
386 return detail::ensure_validity_bitmap_impl(size, std::forward<R>(validity_input));
387 }
388
389} // namespace sparrow
typename storage_type_without_cvrefpointer::value_type block_type
size_type count_non_null() const noexcept
typename storage_type_without_cvrefpointer::size_type size_type
constexpr size_type null_count() const noexcept
static constexpr size_type compute_block_count(size_type bits_count) noexcept
constexpr size_type size() const noexcept
constexpr void set(size_type pos, value_type value)
constexpr dynamic_bitset_base(storage_type buffer, size_type size)
A dynamic size sequence of bits with efficient storage and manipulation operations.
constexpr dynamic_bitset(dynamic_bitset &&) noexcept=default
typename storage_type::default_allocator default_allocator
Type of default allocator.
constexpr dynamic_bitset(block_type *p, size_type n, size_type null_count, const A &a=A())
Constructs a bitset using existing memory with null count tracking.
constexpr void clear() noexcept
constexpr void resize(size_type n, value_type b=false)
typename base_type::block_type block_type
Type of each storage block (same as T)
constexpr dynamic_bitset(const dynamic_bitset &)=default
constexpr dynamic_bitset(const R &r, const A &a=A())
Constructs a dynamic_bitset from an input range of convertible values.
constexpr dynamic_bitset(size_type n, const A &a=A())
Constructs a bitset with n bits, all initialized to false.
constexpr void push_back(value_type value)
constexpr dynamic_bitset(size_type n, value_type v, const A &a=A())
Constructs a bitset with n bits, all initialized to the specified value.
constexpr iterator erase(const_iterator pos)
dynamic_bitset_base< buffer< T > > base_type
Base class type.
typename base_type::storage_type storage_type
Underlying storage container type.
constexpr iterator insert(const_iterator pos, value_type value)
constexpr iterator emplace(const_iterator pos, value_type value)
constexpr dynamic_bitset(block_type *p, size_type n, const A &a=A())
Constructs a bitset using existing memory.
typename base_type::value_type value_type
Type of individual bit values (bool)
typename base_type::size_type size_type
Type used for sizes and indices.
constexpr dynamic_bitset(const A &a=A())
Default constructor.
constexpr ~dynamic_bitset()=default
Concept defining valid input types for validity bitmap creation.
#define SPARROW_ASSERT_TRUE(expr__)
sparrow::validity_bitmap validity_bitmap
validity_bitmap ensure_validity_bitmap_impl(std::size_t size, const validity_bitmap &bitmap)
constexpr std::size_t range_size(R &&r)
Definition ranges.hpp:32
dynamic_bitset< std::uint8_t > validity_bitmap
Type alias for a validity bitmap using 8-bit storage blocks.
validity_bitmap ensure_validity_bitmap(std::size_t size, R &&validity_input)
Ensures a validity bitmap of the specified size from various input types.