36 using reference_type = std::conditional_t<Is_Const, const SmallBitset&, SmallBitset&>;
44 operator bool()
const {
return (
S_.bits_ >>
offset_) & 0b1; }
46 template <
bool C_ = Is_Const>
51 static_assert(not
Is_Const,
"can only assign to proxy of non-const SmallBitset");
106 const unsigned lz = std::countl_zero(
bits_);
107 return CHAR_BIT *
sizeof(
bits_) - 1UL - lz;
121 return SmallBitset((uint64_t(1) << n) - uint64_t(1));
161 std::size_t
size()
const {
return std::popcount(
bits_); }
169 unsigned lz = std::countl_zero(
bits_);
184 explicit operator uint64_t()
const {
return bits_; }
185 explicit operator bool()
const {
return not
empty(); }
250 for (uint64_t i =
CAPACITY; i --> 0;)
257 for (uint64_t i =
size; i --> 0;)
261 void dump(std::ostream &out)
const;
285 std::unique_ptr<value_type[]>
arr_;
300 template<
typename InputIt>
305 for (
auto it =
begin; it !=
end; ++it)
313 for (std::size_t i = 0; i != other.
size(); ++i)
367 for (std::size_t i = 0; i !=
size(); ++i) {
368 if ((*
this)[i] != other[i])
382 is_allocator Allocator = malloc_allocator
420 using pointer = std::conditional_t<Is_Const, const T*, T*>;
421 using reference = std::conditional_t<Is_Const, const T&, T&>;
434 prev_ =
reinterpret_cast<std::uintptr_t
>(curr);
442 M_insist(prev,
"cannot retreat past the beginning");
454 return this->node_ == other.
node_ and this->prev_ == other.
prev_;
476 template<is_allocator A = allocator_type>
481 template<
typename InputIt>
485 for (
auto it =
begin; it !=
end; ++it)
528 template<
typename... Args>
536 prev->
ptrxor_ ^=
reinterpret_cast<std::uintptr_t
>(pos.
node_) ^
reinterpret_cast<std::uintptr_t
>(node);
548 template<
typename... Args>
554 template<
typename... Args>
569 while (count--) it =
insert(it, value);
573 template<
typename InputIt,
574 typename =
decltype(*std::declval<InputIt&>(), std::declval<InputIt&>()++, void())>
582 while (first != last) it =
insert(++it, *first++);
588 return insert(pos, ilist.begin(), ilist.end());
597 prev->
ptrxor_ ^=
reinterpret_cast<std::uintptr_t
>(pos.
node_) ^
reinterpret_cast<std::uintptr_t
>(next);
601 next->
ptrxor_ ^=
reinterpret_cast<std::uintptr_t
>(pos.
node_) ^
reinterpret_cast<std::uintptr_t
>(prev);
639 for (
auto it = L.cbegin(); it != L.cend(); ++it) {
640 if (it != L.cbegin()) out <<
" <-> ";
641 if constexpr (
is_streamable<std::ostream&,
decltype(*it)>::value)
646 return out <<
" <-+";
650 std::ostringstream oss;
655 void dump(std::ostream &out)
const { out << *
this << std::endl; }
670 static constexpr bool reversible =
requires {
typename std::reverse_iterator<It>; }
and
671 requires (It it) { std::make_reverse_iterator(it); };
678 range(It begin, It end) : begin_(begin), end_(end) { }
680 bool empty()
const {
return begin() == end(); }
681 std::size_t
size()
const {
return std::distance(begin(), end()); }
684 It
end()
const {
return end_; }
686 It
cend()
const {
return end_; }
688 std::reverse_iterator<It>
rbegin() const requires reversible {
return std::make_reverse_iterator(end_); }
689 std::reverse_iterator<It>
rend() const requires reversible {
return std::make_reverse_iterator(begin_); }
690 std::reverse_iterator<It>
crbegin() const requires reversible {
return std::make_reverse_iterator(end_); }
691 std::reverse_iterator<It>
crend() const requires reversible {
return std::make_reverse_iterator(begin_); }
699template<
typename It,
typename Fn,
bool OwnsProjection = true>
702template<
typename It,
typename ReturnType,
bool OwnsProjection>
714 std::conditional_t<OwnsProjection, projection_type, const projection_type&>
project_;
721 return this->it_ == other.it_;
724 return this->it_ != other.it_;
737 requires requires (It it) { { it - it } -> std::convertible_to<difference_type>; } {
738 return this->it_ - other.it_;
746template<
typename It,
typename Fn>
749template<
typename It,
typename Fn>
752template<
typename It,
typename ReturnType>
753struct view<It, ReturnType&(It)>
766 template<
typename Fn>
768 template<
typename Fn>
769 view(It begin, It end, Fn &&fn) : range_(begin, end), project_(
std::forward<Fn>(fn)) { }
776template<
typename It,
typename Fn>
778template<
typename It,
typename Fn>
782template<
typename T,
typename Compare = std::less<T>>
799 auto end()
const {
return v_.end(); }
813 return pos !=
end()
and *pos == value;
820 template<
typename InsertIt>
821 void insert(InsertIt first, InsertIt last) {
822 while (first != last)
840 M_insist(k <= n,
"invalid enumeration");
841 M_insist(n < 64,
"n exceeds range");
850 M_insist(n < 64,
"n exceeds range");
860 const uint64_t s(
set_);
862 const uint64_t c = _blsi_u64(s);
864 const uint64_t c = s & -s;
866 const uint64_t r = s + c;
867 const uint64_t
m = r ^ s;
869 const uint64_t l = _pext_u64(
m,
m);
871 const uint64_t l = (1UL << __builtin_popcount(
m)) - 1UL;
902 operator bool()
const {
return bool(
GH_); }
bool M_EXPORT subset(const Container &subset, const Set &set)
Checks whether subset is a subset of set.
SmallBitset least_subset(SmallBitset S)
Returns the least subset of a given set, i.e. the set represented by the lowest 1 bit.
void M_EXPORT setbit(T *bytes, bool value, uint32_t n)
SmallBitset next_subset(SmallBitset subset, SmallBitset set)
Returns the next subset of a given subset and `set.
Enumerate all subsets of size k based on superset of size n.
static GospersHack enumerate_from(SmallBitset set, uint64_t n)
Create an instance of GospersHack that enumerates all remaining subsets of a set of n elements,...
static GospersHack enumerate_all(uint64_t k, uint64_t n)
Create an instance of GospersHack that enumerates all subsets of size k of a set of n elements.
SmallBitset operator*() const
Returns the current subset.
GospersHack & operator++()
Advance to the next subset.
A proxy to access single elements in SmallBitset.
Proxy & operator=(bool val)
std::conditional_t< Is_Const, const SmallBitset &, SmallBitset & > reference_type
Proxy & operator=(const Proxy &other)
static constexpr bool Is_Const
Proxy(reference_type S, std::size_t offset)
SmallBitset as_set() const
bool operator!=(iterator other) const
std::size_t operator*() const
bool operator==(iterator other) const
reverse_iterator & operator++()
bool operator!=(reverse_iterator other) const
std::size_t operator*() const
SmallBitset as_set() const
bool operator==(reverse_iterator other) const
reverse_iterator(uint64_t bits)
reverse_iterator operator++(int)
Implements a small and efficient set over integers in the range of 0 to 63 (including).
bool is_singleton() const
void print_fixed_length(std::ostream &out, std::size_t size) const
Print a textual representation of this with size bits to out.
SmallBitset hi() const
Returns the highest set bit as a SmallBitset.
Proxy< true > operator()(std::size_t offset) const
Returns the offset-th bit.
constexpr std::size_t capacity()
Returns the maximum capacity.
friend SmallBitset operator|(SmallBitset left, SmallBitset right)
Returns the union of left and right, i.e. left ∪ right.
M_LCOV_EXCL_START friend std::ostream & operator<<(std::ostream &out, SmallBitset s)
Write a textual representation of s to out.
SmallBitset(uint64_t bits)
SmallBitset mask_to_lo() const
Returns a mask up to and including the lowest set bit.
bool operator!=(SmallBitset other) const
Proxy< false > at(std::size_t offset)
Returns a proxy to the bit at offset offset.
SmallBitset operator~() const
Inverts all bits in the bitset.
friend SmallBitset operator-(SmallBitset left, SmallBitset right)
Returns the set where the elements of right have been subtracted from left, i.e. left - right.
friend SmallBitset operator&(SmallBitset left, SmallBitset right)
Returns the intersection of left and right, i.e. left ∩ right.
SmallBitset & operator++()
Treat this SmallBitset as an element of the power set of 2^n bits, where n is the number of bits that...
SmallBitset & operator|=(SmallBitset other)
static SmallBitset All(std::size_t n)
Factory method for creating a SmallBitset with first n bits set.
SmallBitset & operator&=(SmallBitset other)
std::size_t size() const
Returns the number of elements in this SmallBitset.
Proxy< true > at(std::size_t offset) const
Returns a proxy to the bit at offset offset.
friend SmallBitset subtract(SmallBitset left, SmallBitset right)
Returns the set where the elements of right have been subtracted from left, i.e. left - right.
bool empty() const
Returns true if there are no elements in this SmallBitset.
friend SmallBitset intersect(SmallBitset left, SmallBitset right)
Returns the intersection of left and right, i.e. left ∩ right.
Proxy< false > operator()(std::size_t offset)
Returns the offset-th bit.
static SmallBitset Singleton(std::size_t n)
Factory method for creating a Singleton Smallbitset with n -th bit set.
SmallBitset operator--(int)
Treat this SmallBitset as an element of the power set of 2^n bits, where n is the number of bits that...
Proxy< false > operator[](std::size_t offset)
Returns the offset-th bit.
Proxy< true > operator[](std::size_t offset) const
Returns the offset-th bit.
SmallBitset & operator--()
Treat this SmallBitset as an element of the power set of 2^n bits, where n is the number of bits that...
bool operator==(SmallBitset other) const
uint64_t bits_
the bit vector representing the set
friend SmallBitset unify(SmallBitset left, SmallBitset right)
Returns the union of left and right, i.e. left ∪ right.
SmallBitset operator++(int)
Treat this SmallBitset as an element of the power set of 2^n bits, where n is the number of bits that...
SmallBitset singleton_to_lo_mask() const
Converts a singleton set to a mask up to – but not including – the single, set bit.
SmallBitset & operator-=(SmallBitset other)
static constexpr std::size_t CAPACITY
the maximum capacity of a SmallBitset
bool is_subset(SmallBitset other) const
Returns true if the set represented by this is a subset of other, i.e. this ⊆ other.
This class efficiently enumerates all subsets of a given size.
SmallBitset operator*() const
SubsetEnumerator & operator++()
GospersHack GH_
used to enumerate the power set of numbers 0 to n-1
SubsetEnumerator(SmallBitset set, uint64_t size)
SmallBitset set_
the set to compute the power set of
std::bidirectional_iterator_tag iterator_category
the_iterator operator++(int)
the_iterator(node_type *node, std::uintptr_t prev)
the_iterator & operator--()
the_iterator operator--(int)
reference operator*() const
the_iterator & operator++()
bool operator==(const the_iterator &other) const
std::ptrdiff_t difference_type
bool operator!=(const the_iterator &other) const
std::conditional_t< Is_Const, const T &, T & > reference
static constexpr bool Is_Const
pointer operator->() const
Implements a doubly-linked list with an overhead of just a single pointer per element.
const_reference_type front() const
const_iterator crend() const
void push_back(const value_type &value)
size_type size_
the number of elements/nodes in the list
node_type * allocate_node()
allocator_type & get_allocator() const noexcept
doubly_linked_list(const doubly_linked_list &other)
doubly_linked_list(InputIt begin, InputIt end, allocator_type &&allocator=allocator_type())
M_LCOV_EXCL_START friend std::ostream & operator<<(std::ostream &out, const doubly_linked_list &L)
iterator insert(const_iterator pos, size_type count, const value_type &value)
const_iterator rend() const
iterator erase(iterator pos)
const_iterator begin() const
the_iterator< true > const_iterator
void deallocate_node(node_type *ptr)
iterator erase(const_iterator pos)
const_iterator rbegin() const
friend void swap(doubly_linked_list &first, doubly_linked_list &second)
doubly_linked_list(A &&allocator)
const_iterator cend() const
node_type * tail_
points to the last node
const_reference_type back() const
iterator insert(const_iterator pos, const value_type &value)
doubly_linked_list & operator=(doubly_linked_list other)
void push_front(const value_type &value)
iterator insert(const_iterator pos, value_type &&value)
void push_front(value_type &&value)
const T & const_reference_type
doubly_linked_list(doubly_linked_list &&other)
size_type max_size() const
iterator emplace(const_iterator pos, Args &&... args)
void push_back(value_type &&value)
friend std::string to_string(const doubly_linked_list &L)
node_type * head_
points to the first node
iterator insert(const_iterator pos, std::initializer_list< value_type > ilist)
const_iterator end() const
const_iterator crbegin() const
const_iterator cbegin() const
reference_type emplace_back(Args &&... args)
reference_type emplace_front(Args &&... args)
the_iterator< false > iterator
iterator insert(const_iterator pos, InputIt first, InputIt last)
void dump(std::ostream &out) const
allocator_type allocator_
the memory allocator
Implements an array of dynamic but fixed size.
value_type & at(std::size_t pos)
Returns a reference to the element at position pos.
const_iterator end() const
dyn_array(dyn_array &&)=default
value_type & operator[](std::size_t pos)
Returns a reference to the element at position pos.
bool operator!=(const dyn_array &other) const
Returns false iff the contents of this and other are equal, that is, they have the same number of ele...
const value_type * const_iterator
const value_type & at(std::size_t pos) const
Returns a reference to the element at position pos.
const value_type * data() const
Returns a pointer to the beginning of the array.
dyn_array & operator=(dyn_array &&)=default
std::unique_ptr< value_type[]> arr_
dyn_array(const dyn_array &other)
Copy-constructs an array.
dyn_array(std::size_t size)
Constructs an array of size size.
const value_type & operator[](std::size_t pos) const
Returns a reference to the element at position pos.
const_iterator cend() const
size_type size() const
Returns the size of this array, i.e.
value_type * data()
Returns a pointer to the beginning of the array.
dyn_array()
Constructs an array of size 0.
const_iterator begin() const
dyn_array(InputIt begin, InputIt end)
Constructs an array with the elements in range [begin, end).
bool operator==(const dyn_array &other) const
Returns true iff the contents of this and other are equal, that is, they have the same number of elem...
const_iterator cbegin() const
Signals that an index-based or key-based access was out of range.
projecting_iterator operator++(int)
std::random_access_iterator_tag iterator_category
std::conditional_t< OwnsProjection, projection_type, const projection_type & > project_
bool operator==(projecting_iterator other) const
std::function< ReturnType &(It)> projection_type
projecting_iterator & operator--()
reference operator*() const
projecting_iterator(It it, const projection_type &project)
typename It::difference_type difference_type
pointer operator->() const
projecting_iterator & operator++()
bool operator!=(projecting_iterator other) const
projecting_iterator operator--(int)
difference_type operator-(projecting_iterator other) const
projecting_iterator & operator+=(int offset)
projecting_iterator & operator-=(int offset)
projecting_iterator(It it, projection_type project)
std::reverse_iterator< It > crend() const
std::reverse_iterator< It > rbegin() const
range< std::reverse_iterator< It > > reverse() const
Returns this range reversed.
std::reverse_iterator< It > rend() const
std::reverse_iterator< It > crbegin() const
A sorted list of elements.
bool contains(const T &value) const
Returns true iff this sorted_vector contains an element that is equal to value.
vector_type v_
the internal container of elements
std::vector< T > vector_type
the type of the internal container of elements
void insert(InsertIt first, InsertIt last)
Inserts elements in the range from first (including) to last (excluding) into this `sorted_vector.
sorted_vector(Compare comp=Compare())
auto reserve(size_type new_cap)
Reserves space for new_cap elements in this sorted_vector.
auto empty() const
Returns true iff the sorted_vector has no elements.
typename vector_type::size_type size_type
auto insert(T value)
Inserts value into this sorted_vector.
auto size() const
Returns the number of elements in this sorted_vector.
view(It begin, It end, Fn &&fn)
view(range< It > range, Fn &&fn)
projecting_iterator_type begin() const
std::function< ReturnType &(It)> projection_type
view(range< It > range, projection_type project)
view(It begin, It end, projection_type project)
projecting_iterator_type end() const