Document the new DPF surfaces in one command set, and test the field, half-tree, and multipoint edges.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
0d8a5a8131
commit
0dff6df8ed
250 changed files with 12199 additions and 1981 deletions
|
|
@ -1,6 +1,5 @@
|
|||
/// @file dpf/bit_array.hpp
|
||||
/// @brief
|
||||
/// @details
|
||||
/// @brief Packed bit arrays, static and dynamic, with bit proxies and iterators.
|
||||
/// @author Ryan Henry <ryan.henry@ucalgary.ca>
|
||||
/// @copyright Copyright (c) 2019-2024 Ryan Henry and [others](@ref authors)
|
||||
/// @license Released under a GNU General Public v2.0 (GPLv2) license;
|
||||
|
|
@ -68,6 +67,8 @@ class const_bit_iterator; // forward reference
|
|||
/// @brief a base class for classes representing a sequence of bits
|
||||
/// @details A `bit_array` represents a sequence of bits. The underlying
|
||||
/// storage is an array of integers of type `dpf::bit_array::word_type`.
|
||||
/// @tparam ConcreteBitArrayT concrete bit array type
|
||||
/// @tparam WordT word used to pack bits
|
||||
template <typename ConcreteBitArrayT, typename WordT = psnip_uint64_t>
|
||||
class bit_array_base
|
||||
{
|
||||
|
|
@ -143,10 +144,12 @@ class bit_array_base
|
|||
~bit_array_base() = default;
|
||||
|
||||
/// @brief default copy assignment
|
||||
/// @return `*this`
|
||||
inline constexpr
|
||||
bit_array_base & operator=(const bit_array_base &) = default;
|
||||
|
||||
/// @brief defaulted move assignment
|
||||
/// @return `*this`
|
||||
HEDLEY_NO_THROW
|
||||
inline constexpr
|
||||
bit_array_base & operator=(bit_array_base &&) noexcept = default;
|
||||
|
|
@ -202,7 +205,7 @@ class bit_array_base
|
|||
/// significant to most significant)
|
||||
/// @note Unlike `test` and `at`, does not throw exceptions: the behavior
|
||||
/// is undefined if `pos` is out of bounds
|
||||
/// @returns an object of type `dpf::bit_array_base::reference`, which
|
||||
/// @return an object of type `dpf::bit_array_base::reference`, which
|
||||
/// allows writing to the requested bit
|
||||
/// @complexity `O(1)`
|
||||
HEDLEY_NO_THROW
|
||||
|
|
@ -215,9 +218,9 @@ class bit_array_base
|
|||
/// @details accesses the bit at position `pos`
|
||||
/// @param pos the 0-based position of the bit to return (least
|
||||
/// significant to most significant)
|
||||
/// @return the value of the requested bit
|
||||
/// @note Unlike `test` and `at`, does not throw exceptions: the behavior
|
||||
/// is undefined if `pos` is out of bounds
|
||||
/// @returns the value of the requested bit
|
||||
/// @complexity `O(1)`
|
||||
HEDLEY_NO_THROW
|
||||
inline constexpr const_reference operator[](size_type pos) const noexcept
|
||||
|
|
@ -235,7 +238,7 @@ class bit_array_base
|
|||
/// significant to most significant)
|
||||
/// @throws std::out_of_range if `pos` does not correspond to a valid
|
||||
/// position within the `bit_array_base`
|
||||
/// @returns an object of type `dpf::bit_array_base::reference`, which
|
||||
/// @return an object of type `dpf::bit_array_base::reference`, which
|
||||
/// allows writing to the requested bit
|
||||
/// @complexity `O(1)`
|
||||
constexpr reference at(size_type pos)
|
||||
|
|
@ -249,9 +252,9 @@ class bit_array_base
|
|||
/// @details accesses the bit at position `pos`
|
||||
/// @param pos the 0-based position of the bit to return (least
|
||||
/// significant to most significant)
|
||||
/// @return the value of the requested bit
|
||||
/// @throws std::out_of_range if `pos` does not correspond to a valid
|
||||
/// position within the `bit_array_base`
|
||||
/// @returns the value of the requested bit
|
||||
/// @complexity `O(1)`
|
||||
constexpr const_reference at(size_type pos) const
|
||||
{
|
||||
|
|
@ -264,7 +267,7 @@ class bit_array_base
|
|||
|
||||
/// @brief returns an iterator to the first bit
|
||||
/// @{
|
||||
/// @returns iterator to the first element
|
||||
/// @return iterator to the first element
|
||||
/// @complexity `O(1)`
|
||||
HEDLEY_NO_THROW
|
||||
constexpr iterator begin() noexcept
|
||||
|
|
@ -273,7 +276,7 @@ class bit_array_base
|
|||
if (p == nullptr) return iterator{};
|
||||
return iterator{p, word_type(1)};
|
||||
}
|
||||
/// @returns iterator to the first element
|
||||
/// @return iterator to the first element
|
||||
/// @complexity `O(1)`
|
||||
HEDLEY_NO_THROW
|
||||
constexpr const_iterator begin() const noexcept
|
||||
|
|
@ -282,7 +285,7 @@ class bit_array_base
|
|||
if (p == nullptr) return const_iterator{};
|
||||
return const_iterator{p, word_type(1)};
|
||||
}
|
||||
/// @returns iterator to the first element
|
||||
/// @return iterator to the first element
|
||||
/// @complexity `O(1)`
|
||||
HEDLEY_NO_THROW
|
||||
constexpr const_iterator cbegin() const noexcept
|
||||
|
|
@ -293,7 +296,7 @@ class bit_array_base
|
|||
|
||||
/// @brief returns an iterator to the end (one past the last bit)
|
||||
/// @{
|
||||
/// @returns iterator to the element following the last element
|
||||
/// @return iterator to the element following the last element
|
||||
/// @complexity `O(1)`
|
||||
HEDLEY_NO_THROW
|
||||
constexpr iterator end() noexcept
|
||||
|
|
@ -303,7 +306,7 @@ class bit_array_base
|
|||
return iterator{p + (size() >> lg_bits_per_word),
|
||||
static_cast<word_type>(word_type(1) << (size() % bits_per_word))};
|
||||
}
|
||||
/// @returns iterator to the element following the last element
|
||||
/// @return iterator to the element following the last element
|
||||
/// @complexity `O(1)`
|
||||
HEDLEY_NO_THROW
|
||||
constexpr const_iterator end() const noexcept
|
||||
|
|
@ -313,7 +316,7 @@ class bit_array_base
|
|||
return const_iterator{p + (size() >> lg_bits_per_word),
|
||||
static_cast<word_type>(word_type(1) << (size() % bits_per_word))};
|
||||
}
|
||||
/// @returns iterator to the element following the last element
|
||||
/// @return iterator to the element following the last element
|
||||
/// @complexity `O(1)`
|
||||
HEDLEY_NO_THROW
|
||||
constexpr const_iterator cend() const noexcept
|
||||
|
|
@ -325,7 +328,7 @@ class bit_array_base
|
|||
/// @brief checks if the specified bit is set to `true`
|
||||
/// @param pos the 0-based position of the bit to return (least
|
||||
/// significant to most significant)
|
||||
/// @returns `true` if the requested bit is set, `false` otherwise
|
||||
/// @return `true` if the requested bit is set, `false` otherwise
|
||||
/// @complexity `O(1)`
|
||||
bool test(size_type pos) const
|
||||
{
|
||||
|
|
@ -357,10 +360,9 @@ class bit_array_base
|
|||
}
|
||||
|
||||
/// @details checks if all bits in a range are set to `true`
|
||||
/// @param first,last the range of elements under consideration
|
||||
/// @tparam Iterator an iterator type
|
||||
/// @return `true` if all of the bits in the given range are set to
|
||||
/// `true`, otherwise `false`
|
||||
/// @param first,last the range of elements under consideration
|
||||
/// @return `true` if all of the bits in the given range are set to `true`, otherwise `false`
|
||||
/// @complexity `O(last-first)`
|
||||
template <typename Iterator>
|
||||
HEDLEY_NO_THROW
|
||||
|
|
@ -394,10 +396,9 @@ class bit_array_base
|
|||
}
|
||||
|
||||
/// @details checks if any bits in a range are set to `true`
|
||||
/// @param first,last the range of elements under consideration
|
||||
/// @tparam Iterator an iterator type
|
||||
/// @return `true` if any of the bits in the given range are set to
|
||||
/// `true`, otherwise `false`
|
||||
/// @param first,last the range of elements under consideration
|
||||
/// @return `true` if any of the bits in the given range are set to `true`, otherwise `false`
|
||||
/// @complexity `O(last-first)`
|
||||
template <typename Iterator>
|
||||
HEDLEY_NO_THROW
|
||||
|
|
@ -422,10 +423,9 @@ class bit_array_base
|
|||
}
|
||||
|
||||
/// @details checks if none bits in a range are set to `true`
|
||||
/// @param first,last the range of elements under consideration
|
||||
/// @tparam Iterator an iterator type
|
||||
/// @return `true` if none of the bits in the given range are set to
|
||||
/// `true`, otherwise `false`
|
||||
/// @param first,last the range of elements under consideration
|
||||
/// @return `true` if none of the bits in the given range are set to `true`, otherwise `false`
|
||||
/// @complexity `O(last-first)`
|
||||
template <typename Iterator>
|
||||
HEDLEY_NO_THROW
|
||||
|
|
@ -438,7 +438,7 @@ class bit_array_base
|
|||
/// @brief returns the number of bits set to `true`
|
||||
/// @{
|
||||
/// @details counts the number of bits that are set to `true`
|
||||
/// @returns the number of bits set to `true`
|
||||
/// @return the number of bits set to `true`
|
||||
/// @complexity `O(size())`
|
||||
HEDLEY_NO_THROW
|
||||
size_type count() const noexcept
|
||||
|
|
@ -456,8 +456,8 @@ class bit_array_base
|
|||
return sum;
|
||||
}
|
||||
/// @details counts the number of bits in a range that are set to `true`
|
||||
/// @param first,last the range of elements under consideration
|
||||
/// @tparam Iterator an iterator type
|
||||
/// @param first,last the range of elements under consideration
|
||||
/// @return the number of bits in the given range that are set to `true`
|
||||
/// @complexity `O(last-first)`
|
||||
template <typename Iterator>
|
||||
|
|
@ -477,7 +477,7 @@ class bit_array_base
|
|||
/// @brief returns the parity of all stored bits
|
||||
/// @{
|
||||
/// @details counts the parity of all stored bits
|
||||
/// @returns the parity of all stored bits
|
||||
/// @return the parity of all stored bits
|
||||
/// @complexity `O(size())`
|
||||
HEDLEY_NO_THROW
|
||||
size_type parity() const noexcept
|
||||
|
|
@ -496,8 +496,8 @@ class bit_array_base
|
|||
}
|
||||
|
||||
/// @details counts the parity of bits in a range
|
||||
/// @param first,last the range of elements under consideration
|
||||
/// @tparam Iterator an iterator type
|
||||
/// @param first,last the range of elements under consideration
|
||||
/// @return the parity of all bits in the given range
|
||||
/// @complexity `O(last-first)`
|
||||
template <typename Iterator>
|
||||
|
|
@ -515,7 +515,7 @@ class bit_array_base
|
|||
/// @}
|
||||
|
||||
/// @brief returns the number of bits
|
||||
/// @returns number of bits that the `bit_array_base` holds
|
||||
/// @return number of bits that the `bit_array_base` holds
|
||||
/// @complexity `O(1)`
|
||||
HEDLEY_NO_THROW
|
||||
HEDLEY_PURE
|
||||
|
|
@ -633,9 +633,12 @@ class bit_array_base
|
|||
/// contains `size()` characters with the first character
|
||||
/// corresponding to the last `(size()-1th)` bit and the last
|
||||
/// character corresponding tot he first `(0th)` bit.
|
||||
/// @tparam CharT character type
|
||||
/// @tparam Traits character traits
|
||||
/// @tparam Allocator allocator type
|
||||
/// @param zero character to use to represent `false`/`0` (default: ``CharT('0')``)
|
||||
/// @param one character to use to represent `true`/`1` (default: ``CharT('1')``)
|
||||
/// @returns the converted string
|
||||
/// @return the converted string
|
||||
/// @throws May throw `std::bad_alloc` from the `std::string` constructor.
|
||||
/// @complexity `O(size())`
|
||||
template <typename CharT = char,
|
||||
|
|
@ -731,6 +734,9 @@ class bit_array_base
|
|||
|
||||
/// @brief XOR. Exact match so `bit_reference - bit_reference` is not
|
||||
/// ambiguous with integer subtraction of the proxy.
|
||||
/// @param lhs the left-hand operand
|
||||
/// @param rhs the right-hand operand
|
||||
/// @return XOR
|
||||
friend constexpr dpf::bit operator-(bit_reference lhs, bit_reference rhs) noexcept
|
||||
{
|
||||
return static_cast<dpf::bit>(static_cast<bool>(lhs) ^ static_cast<bool>(rhs));
|
||||
|
|
@ -746,7 +752,7 @@ class bit_array_base
|
|||
/// @{
|
||||
/// @details sets `*this` to the result of binary AND on `*this` and `b`
|
||||
/// @param b the other bit
|
||||
/// @returns `*this`
|
||||
/// @return `*this`
|
||||
/// @complexity `O(1)`
|
||||
HEDLEY_NO_THROW
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
|
|
@ -758,7 +764,7 @@ class bit_array_base
|
|||
|
||||
/// @details sets `*this` to the result of binary OR on `*this` and `b`
|
||||
/// @param b the other bit
|
||||
/// @returns `*this`
|
||||
/// @return `*this`
|
||||
/// @complexity `O(1)`
|
||||
HEDLEY_NO_THROW
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
|
|
@ -770,7 +776,7 @@ class bit_array_base
|
|||
|
||||
/// @details sets `*this` to the result of binary XOR on `*this` and `b`
|
||||
/// @param b the other bit
|
||||
/// @returns `*this`
|
||||
/// @return `*this`
|
||||
/// @complexity `O(1)`
|
||||
HEDLEY_NO_THROW
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
|
|
@ -780,8 +786,8 @@ class bit_array_base
|
|||
return *this;
|
||||
}
|
||||
|
||||
/// @details returns a temporary copy of `*this` with its value
|
||||
/// flipped (binary NOT)
|
||||
/// @details returns a temporary copy of `*this` with its value flipped (binary NOT)
|
||||
/// @return the flipped bit
|
||||
/// @complexity `O(1)`
|
||||
HEDLEY_NO_THROW
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
|
|
@ -792,7 +798,7 @@ class bit_array_base
|
|||
/// @}
|
||||
|
||||
/// @brief sets to the referenced bit to 1
|
||||
/// @returns `*this`
|
||||
/// @return `*this`
|
||||
/// @complexity `O(1)`
|
||||
HEDLEY_NO_THROW
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
|
|
@ -805,7 +811,7 @@ class bit_array_base
|
|||
}
|
||||
|
||||
/// @brief unsets the referenced bit to 0
|
||||
/// @returns `*this`
|
||||
/// @return `*this`
|
||||
/// @complexity `O(1)`
|
||||
HEDLEY_NO_THROW
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
|
|
@ -818,7 +824,8 @@ class bit_array_base
|
|||
}
|
||||
|
||||
/// @brief assigns `b ? 1 : 0` to the referenced bit
|
||||
/// @returns `*this`
|
||||
/// @param b the `b`
|
||||
/// @return `*this`
|
||||
/// @complexity `O(1)`
|
||||
HEDLEY_NO_THROW
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
|
|
@ -832,7 +839,7 @@ class bit_array_base
|
|||
}
|
||||
|
||||
/// @brief flips the referenced bit
|
||||
/// @returns `*this`
|
||||
/// @return `*this`
|
||||
/// @complexity `O(1)`
|
||||
HEDLEY_NO_THROW
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
|
|
@ -846,6 +853,8 @@ class bit_array_base
|
|||
|
||||
/// @brief Exchange the bits named by two proxies, including temporaries
|
||||
/// returned from `operator[]` and `operator*`.
|
||||
/// @param a the `a`
|
||||
/// @param b the `b`
|
||||
HEDLEY_NO_THROW
|
||||
friend constexpr void swap(bit_reference a, bit_reference b) noexcept
|
||||
{
|
||||
|
|
@ -897,6 +906,8 @@ class bit_array_base
|
|||
static constexpr word_type sentinel = ~word_type(0);
|
||||
|
||||
/// @brief Low `n` bits set. `n == 0` yields 0. `n >= bits_per_word` yields all ones.
|
||||
/// @param n the `n`
|
||||
/// @return Low `n` bits set
|
||||
HEDLEY_NO_THROW
|
||||
static constexpr word_type low_bits_mask(size_type n) noexcept
|
||||
{
|
||||
|
|
@ -913,6 +924,8 @@ class bit_array_base
|
|||
}
|
||||
|
||||
/// @brief Bits strictly below the single set bit in `mask`.
|
||||
/// @param mask the bit mask
|
||||
/// @return Bits strictly below the single set bit in `mask`
|
||||
HEDLEY_NO_THROW
|
||||
static constexpr word_type bits_below(word_type mask) noexcept
|
||||
{
|
||||
|
|
@ -920,6 +933,8 @@ class bit_array_base
|
|||
}
|
||||
|
||||
/// @brief Bits at and above the single set bit in `mask`.
|
||||
/// @param mask the bit mask
|
||||
/// @return Bits at and above the single set bit in `mask`
|
||||
HEDLEY_NO_THROW
|
||||
static constexpr word_type bits_at_and_above(word_type mask) noexcept
|
||||
{
|
||||
|
|
@ -929,6 +944,11 @@ class bit_array_base
|
|||
/// @brief Invoke `fn(masked_bits, relevant_mask)` for each limb touched by
|
||||
/// `[first, last)`. Does not dereference a one-past-the-end word.
|
||||
/// `fn` returns false to stop early.
|
||||
/// @tparam Iterator iterator type
|
||||
/// @tparam Fn fn
|
||||
/// @param first the first element of the range
|
||||
/// @param last the past-the-end element of the range
|
||||
/// @param fn the `fn`
|
||||
template <typename Iterator, typename Fn>
|
||||
void for_each_span(Iterator first, Iterator last, Fn fn) const
|
||||
{
|
||||
|
|
@ -975,6 +995,8 @@ class bit_array_base
|
|||
|
||||
/// @brief a base class provided to simplify the definition of
|
||||
/// `bit_iterator` and `const_bit_iterator`
|
||||
/// @tparam ConcreteBitArrayT concrete bit array type
|
||||
/// @tparam WordT word used to pack bits
|
||||
template <typename ConcreteBitArrayT,
|
||||
typename WordT>
|
||||
class bit_iterator_base
|
||||
|
|
@ -1461,6 +1483,7 @@ class alignas(utils::max_align_v) static_bit_array final
|
|||
}
|
||||
|
||||
/// @brief constructs a `static_bit_array` from the low bits of `val`
|
||||
/// @param val the `val`
|
||||
inline constexpr explicit static_bit_array(std::size_t val)
|
||||
: data_{}
|
||||
{
|
||||
|
|
@ -1503,7 +1526,7 @@ class alignas(utils::max_align_v) static_bit_array final
|
|||
}
|
||||
|
||||
/// @brief returns the number of bits
|
||||
/// @returns number of bits that the `static_bit_array` holds
|
||||
/// @return number of bits that the `static_bit_array` holds
|
||||
/// @complexity `O(1)`
|
||||
HEDLEY_NO_THROW
|
||||
HEDLEY_PURE
|
||||
|
|
@ -1534,6 +1557,8 @@ class dynamic_bit_array
|
|||
using unique_ptr = typename allocator::unique_ptr;
|
||||
public:
|
||||
/// @brief constructs a zeroed `dynamic_bit_array` that holds `nbits` bits
|
||||
/// @param nbits the width in bits
|
||||
/// @param alloc the `alloc`
|
||||
/// @throws std::bad_alloc if allocating storage fails
|
||||
inline explicit dynamic_bit_array(std::size_t nbits,
|
||||
allocator alloc = allocator{})
|
||||
|
|
@ -1605,6 +1630,7 @@ class dynamic_bit_array
|
|||
}
|
||||
|
||||
/// @brief direct access to the underlying data array
|
||||
/// @param i the `i`
|
||||
/// @return a pointer to the start of the data array
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
HEDLEY_NO_THROW
|
||||
|
|
@ -1625,6 +1651,7 @@ class dynamic_bit_array
|
|||
}
|
||||
|
||||
/// @brief direct access to the underlying data array
|
||||
/// @param i the `i`
|
||||
/// @return a pointer to the start of the data array
|
||||
HEDLEY_ALWAYS_INLINE
|
||||
HEDLEY_NO_THROW
|
||||
|
|
@ -1643,7 +1670,7 @@ class dynamic_bit_array
|
|||
}
|
||||
|
||||
/// @brief returns the number of bits
|
||||
/// @returns number of bits that the `dynamic_bit_array` holds
|
||||
/// @return number of bits that the `dynamic_bit_array` holds
|
||||
/// @complexity `O(1)`
|
||||
HEDLEY_NO_THROW
|
||||
HEDLEY_PURE
|
||||
|
|
@ -1654,7 +1681,7 @@ class dynamic_bit_array
|
|||
}
|
||||
|
||||
private:
|
||||
/// Store zeros through `volatile` so the wipe is not deleted as a dead store.
|
||||
/// @brief Store zeros through `volatile` so the wipe is not deleted as a dead store.
|
||||
HEDLEY_NO_THROW
|
||||
void wipe() noexcept
|
||||
{
|
||||
|
|
@ -1671,7 +1698,10 @@ class dynamic_bit_array
|
|||
unique_ptr data_;
|
||||
};
|
||||
|
||||
/// @brief
|
||||
/// @brief Exchanges the bits named by two `dynamic_bit_array` proxies.
|
||||
/// @tparam WordT word used to pack bits
|
||||
/// @param lhs the left-hand operand
|
||||
/// @param rhs the right-hand operand
|
||||
template <typename WordT>
|
||||
HEDLEY_NO_THROW
|
||||
inline constexpr void swap(typename dynamic_bit_array<WordT>::reference lhs,
|
||||
|
|
@ -1682,6 +1712,11 @@ inline constexpr void swap(typename dynamic_bit_array<WordT>::reference lhs,
|
|||
rhs = tmp;
|
||||
}
|
||||
|
||||
/// @brief Exchanges the bits named by two `static_bit_array` proxies.
|
||||
/// @tparam Nbits width in bits
|
||||
/// @tparam WordT word used to pack bits
|
||||
/// @param lhs the left-hand operand
|
||||
/// @param rhs the right-hand operand
|
||||
template <std::size_t Nbits,
|
||||
typename WordT>
|
||||
HEDLEY_NO_THROW
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue