42#include <cereal/cereal.hpp>
43#include <cereal/macros.hpp>
44#include <cereal/specialize.hpp>
46#include <hibf/cereal/concepts.hpp>
47#include <hibf/contrib/aligned_allocator.hpp>
66 typename std::allocator_traits<
67 seqan::hibf::contrib::aligned_allocator<bool, 64u>>::template rebind_alloc<uint64_t>>
71 using allocator_t = seqan::hibf::contrib::aligned_allocator<bool, 64u>;
77 using chunk_type = uint64_t;
90 template <
bool is_const>
100 maybe_const_chunk_type * _chunk{};
101 chunk_type _chunk_mask{};
108 constexpr bit_reference(maybe_const_chunk_type * chunk,
size_type const local_chunk_position) noexcept :
110 _chunk_mask{
static_cast<chunk_type
>(1) << to_local_chunk_position(local_chunk_position)}
117 bit_reference() =
delete;
118 bit_reference(bit_reference
const & other) =
default;
119 bit_reference(bit_reference && other) =
default;
120 bit_reference & operator=(bit_reference
const & other)
125 bit_reference & operator=(bit_reference && other)
noexcept
135 constexpr bit_reference & operator=(
bool const bit)
noexcept
137 bit ? set() : clear();
145 constexpr bit_reference
const & operator=(
bool const bit)
const noexcept
148 bit ? set() : clear();
154 constexpr operator bool()
const noexcept
156 return *_chunk & _chunk_mask;
160 constexpr bit_reference & flip()
noexcept
162 (*this) ? clear() : set();
168 constexpr void set()
noexcept
170 *_chunk |= _chunk_mask;
174 constexpr void clear()
noexcept
176 *_chunk &= ~_chunk_mask;
183 template <
bool is_const>
189 friend class bit_iterator;
194 maybe_const_chunk_type * _chunk{};
202 using reference = bit_reference<is_const>;
203 using pointer = void;
212 bit_iterator() =
default;
218 explicit constexpr bit_iterator(maybe_const_chunk_type * chunk) noexcept : _chunk{chunk}, _chunk_position{0}
225 constexpr bit_iterator(bit_iterator<!is_const>
const & other)
noexcept
227 : _chunk{other._chunk}, _chunk_position{other._chunk_position}
235 constexpr reference operator*()
const noexcept
237 return reference{_chunk, _chunk_position};
243 return *((*this) + count);
251 constexpr bit_iterator & operator++()
noexcept
253 _chunk += !
static_cast<bool>(to_local_chunk_position(++_chunk_position));
258 constexpr bit_iterator operator++(
int)
noexcept
260 bit_iterator tmp{*
this};
266 constexpr bit_iterator & operator+=(
difference_type const count)
noexcept
275 size_type updated_count = modulo_mask - to_local_chunk_position(_chunk_position) - count;
276 _chunk_position = modulo_mask - to_local_chunk_position(updated_count);
277 _chunk -= to_chunk_position(updated_count);
282 _chunk += to_chunk_position(to_local_chunk_position(_chunk_position) + count);
283 _chunk_position = to_local_chunk_position(_chunk_position + count);
290 constexpr bit_iterator operator+(
difference_type const count)
const noexcept
292 bit_iterator tmp{*
this};
297 friend constexpr bit_iterator operator+(
difference_type const count, bit_iterator rhs)
noexcept
303 constexpr bit_iterator & operator--()
noexcept
305 _chunk -= !
static_cast<bool>(to_local_chunk_position(--_chunk_position));
310 constexpr bit_iterator operator--(
int)
noexcept
312 bit_iterator tmp{*
this};
318 constexpr bit_iterator & operator-=(
difference_type const count)
noexcept
320 return *
this += -count;
324 constexpr bit_iterator operator-(
difference_type const count)
const noexcept
326 bit_iterator tmp{*
this};
331 template <
bool is_const_other>
332 constexpr difference_type operator-(bit_iterator<is_const_other> rhs)
const noexcept
334 return ((_chunk - rhs._chunk) << division_mask) -
335 to_local_chunk_position(rhs._chunk_position) +
336 to_local_chunk_position(_chunk_position);
344 template <
bool is_const_other>
345 bool operator==(bit_iterator<is_const_other>
const & rhs)
const
347 return _chunk == rhs._chunk
348 && (to_local_chunk_position(_chunk_position) == to_local_chunk_position(rhs._chunk_position));
352 template <
bool is_const_other>
355 if (
std::strong_ordering order = _chunk <=> rhs._chunk; order == std::strong_ordering::equivalent)
356 return to_local_chunk_position(_chunk_position) <=> to_local_chunk_position(rhs._chunk_position);
387 static constexpr size_type chunk_size =
sizeof(chunk_type) * CHAR_BIT;
389 static constexpr size_type modulo_mask = chunk_size - 1u;
471 template <std::input_iterator iterator_t, std::sentinel_for<iterator_t> sentinel_t>
473 constexpr void assign(iterator_t first, sentinel_t last)
477 tmp.
reserve(std::ranges::distance(first, last));
483 set_new_size(std::ranges::distance(
begin(),
end()));
473 constexpr void assign(iterator_t first, sentinel_t last) {
…}
534 [value = fill_chunk(bit)](chunk_type & chunk)
547 assert(position <
size());
549 return *std::ranges::next(
begin(), position);
555 assert(position <
size());
557 return *std::ranges::next(
begin(), position);
580 return (*
this)[
size() - 1u];
588 return (*
this)[
size() - 1u];
592 constexpr bool all() const noexcept
594 constexpr chunk_type mask = ~static_cast<chunk_type>(0);
596 [](chunk_type
const & chunk)
598 return chunk == mask;
592 constexpr bool all() const noexcept {
…}
603 constexpr bool any() const noexcept
605 constexpr chunk_type mask =
static_cast<chunk_type
>(0);
607 [](chunk_type
const & chunk)
603 constexpr bool any() const noexcept {
…}
614 constexpr bool none() const noexcept
614 constexpr bool none() const noexcept {
…}
630 constexpr bool empty() const noexcept
630 constexpr bool empty() const noexcept {
…}
690 size_t const new_size =
size() + 1u;
693 set_new_size(new_size);
702 size_t const old_size =
size();
706 if (bit &&
size() > old_size)
720 assert(rhs.size() ==
size());
722 return binary_transform_impl(rhs,
723 [](
auto const & left_chunk,
auto const & right_chunk)
725 return left_chunk & right_chunk;
732 assert(rhs.size() ==
size());
734 return binary_transform_impl(rhs,
735 [](
auto const & left_chunk,
auto const & right_chunk)
737 return left_chunk | right_chunk;
744 assert(rhs.size() ==
size());
746 return binary_transform_impl(rhs,
747 [](
auto const & left_chunk,
auto const & right_chunk)
749 return left_chunk ^ right_chunk;
758 tmp.binary_transform_impl(*
this,
759 [](
auto const &,
auto const & right_chunk)
788 assert(rhs.size() ==
size());
790 return binary_transform_impl(rhs,
791 [](
auto const & left_chunk,
auto const & right_chunk)
793 return left_chunk & ~right_chunk;
801 [](chunk_type & chunk)
813 if (position >=
size())
817 (*this)[position].flip();
886 template <cereal_archive archive_t>
887 void CEREAL_LOAD_FUNCTION_NAME(archive_t & archive)
893 size_t const vector_size = host_size_impl(_size);
895 resize_for_overwrite(vector_size);
899 for (
auto && v : *as_base())
904 archive(cereal::binary_data(data(), vector_size *
sizeof(chunk_type)));
887 void CEREAL_LOAD_FUNCTION_NAME(archive_t & archive) {
…}
909 template <cereal_archive archive_t>
910 void CEREAL_SAVE_FUNCTION_NAME(archive_t & archive)
const
919 for (
auto && v : *as_base())
924 archive(cereal::binary_data(data(),
base_t::size() *
sizeof(chunk_type)));
910 void CEREAL_SAVE_FUNCTION_NAME(archive_t & archive)
const {
…}
931#ifndef HIBF_UNINITIALISED_RESIZE
939# if defined(_LIBCPP_VERSION)
940 inline void resize_for_overwrite(
size_t const size)
944 using allocator_t =
typename base_t::allocator_type;
952 static_assert(
sizeof(fake_vector) ==
sizeof(base_t));
953 static_assert(
alignof(fake_vector) ==
alignof(base_t));
959# ifndef _LIBCPP_HAS_NO_ASAN
960 __sanitizer_annotate_contiguous_container(
base_t::data(),
966 fake_vector & vec =
reinterpret_cast<fake_vector &
>(*this);
967 vec.end = vec.begin +
size;
976 this->_M_impl._M_finish = this->_M_impl._M_start +
size;
982 template <
typename binary_operator_t>
983 constexpr bit_vector & binary_transform_impl(
bit_vector const & rhs, binary_operator_t && op)
noexcept
985 chunk_type *
const lhs_data = data();
986 chunk_type
const *
const rhs_data = rhs.data();
989 for (
size_t i = 0; i <
size; ++i)
990 lhs_data[i] = op(lhs_data[i], rhs_data[i]);
999 return chunks_needed(count);
1003 constexpr void set_new_size(
size_type const new_size)
noexcept
1009 constexpr base_t
const * as_base() const noexcept
1011 return static_cast<base_t
const *
>(
this);
1015 constexpr base_t * as_base() noexcept
1017 return static_cast<base_t *
>(
this);
1023 return (count + 63u) >> 6;
1027 constexpr chunk_type fill_chunk(
bool const bit)
const noexcept
1029 return (bit) ? ~chunk_type{} : chunk_type{};
1033 static constexpr size_type to_local_chunk_position(
size_type const position)
noexcept
1035 return position & modulo_mask;
1041 return position >> division_mask;
1057template <
typename archive_t>
1058struct specialize<archive_t, seqan::hibf::bit_vector, cereal::specialization::member_load_save>
T back_inserter(T... args)
An bit vector.
Definition bit_vector.hpp:68
constexpr void resize(size_type const count, bool const bit={})
Changes the number of elements stored, where additional copies of bit are appended.
Definition bit_vector.hpp:698
constexpr reference back() noexcept
Access the last element.
Definition bit_vector.hpp:576
constexpr void swap(bit_vector &other) noexcept
Exchanges the contents of the container with those of others.
Definition bit_vector.hpp:822
allocator_t allocator_type
The allocator type to use.
Definition bit_vector.hpp:382
constexpr bit_vector operator~() const noexcept
Performs binary NOT.
Definition bit_vector.hpp:754
constexpr bit_vector & flip(size_type position)
Flips the bit at the given position.
Definition bit_vector.hpp:809
constexpr reference operator[](size_type const position) noexcept
Access specified element.
Definition bit_vector.hpp:545
constexpr bit_vector(allocator_type const &alloc=allocator_type{})
The default constructor which optionally sets the allocator.
Definition bit_vector.hpp:401
constexpr friend bit_vector operator|(bit_vector lhs, bit_vector const &rhs) noexcept
Performs binary OR.
Definition bit_vector.hpp:774
constexpr bit_vector(size_type const count, bool const bit, allocator_type const &alloc=allocator_type{})
Constructs the bit vector with count copies of elements with value bit.
Definition bit_vector.hpp:416
constexpr bit_vector & and_not(bit_vector const &rhs) noexcept
Computes the bitwise a &= ~b operator without an additional copy.
Definition bit_vector.hpp:786
constexpr size_type size() const noexcept
Returns the number of elements.
Definition bit_vector.hpp:624
constexpr bit_vector(std::initializer_list< bool > list, allocator_type const &alloc=allocator_type{})
Constructs the container initialised with the elements in list.
Definition bit_vector.hpp:426
bit_iterator< false > iterator
The iterator over the bits.
Definition bit_vector.hpp:368
constexpr bit_vector(bit_vector &&)=default
Default.
constexpr const_reference back() const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition bit_vector.hpp:584
constexpr iterator end() noexcept
Returns an iterator to the end.
Definition bit_vector.hpp:851
constexpr friend bit_vector operator^(bit_vector lhs, bit_vector const &rhs) noexcept
Performs binary XOR.
Definition bit_vector.hpp:780
constexpr bit_vector(bit_vector const &)=default
Default.
constexpr ~bit_vector()=default
Default.
constexpr const_iterator cend() const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition bit_vector.hpp:863
constexpr iterator begin() noexcept
Returns an iterator to the beginning.
Definition bit_vector.hpp:833
constexpr bit_vector & flip() noexcept
Flips all bits in-place.
Definition bit_vector.hpp:798
constexpr bool any() const noexcept
Checks if any bit is set to true.
Definition bit_vector.hpp:603
constexpr bool none() const noexcept
Checks if none of the bits is set to true.
Definition bit_vector.hpp:614
constexpr friend bit_vector operator&(bit_vector lhs, bit_vector const &rhs) noexcept
Performs binary AND.
Definition bit_vector.hpp:768
constexpr bit_vector(size_type const count, allocator_type const &alloc=allocator_type{})
Constructs the container with count default-inserted instances of bool. No copies are made.
Definition bit_vector.hpp:438
constexpr const_iterator end() const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition bit_vector.hpp:857
constexpr bit_vector & operator=(bit_vector &&)=default
Default.
bit_iterator< true > const_iterator
The const iterator over the bits.
Definition bit_vector.hpp:370
constexpr void assign(size_type const count, bool const bit)
Assigns values to the container.
Definition bit_vector.hpp:530
constexpr void assign(std::initializer_list< bool > const &ilist)
Assigns values to the container.
Definition bit_vector.hpp:505
constexpr bool all() const noexcept
Checks if all bits are set to true.
Definition bit_vector.hpp:592
constexpr const_iterator begin() const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition bit_vector.hpp:839
constexpr void push_back(bool bit)
Adds an element to the end.
Definition bit_vector.hpp:688
size_t size_type
The size_type.
Definition bit_vector.hpp:378
constexpr bit_vector & operator|=(bit_vector const &rhs) noexcept
Performs binary OR between this and rhs.
Definition bit_vector.hpp:730
constexpr bool empty() const noexcept
Checks wether the container is empty.
Definition bit_vector.hpp:630
constexpr bit_vector & operator=(bit_vector const &)=default
Default.
constexpr void assign(iterator_t first, sentinel_t last)
Assigns values to the container.
Definition bit_vector.hpp:473
constexpr const_iterator cbegin() const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition bit_vector.hpp:845
constexpr bit_vector & operator^=(bit_vector const &rhs) noexcept
Performs binary XOR between this and rhs.
Definition bit_vector.hpp:742
constexpr void reserve(size_type const new_capacity)
Reserves storage.
Definition bit_vector.hpp:658
constexpr bit_vector & operator&=(bit_vector const &rhs) noexcept
Performs binary AND between this and rhs.
Definition bit_vector.hpp:718
constexpr void clear() noexcept
Erases all elements. After this call, size() returns zero. capacity() remains unchanged.
Definition bit_vector.hpp:711
constexpr size_type capacity() const noexcept
Returns the capacity.
Definition bit_vector.hpp:636
constexpr const_reference operator[](size_type const position) const noexcept
Access specified element.
Definition bit_vector.hpp:553
Definition concepts.hpp:27