From aa579d1f20d6ec9477d4b27dee2f81369df15948 Mon Sep 17 00:00:00 2001 From: Peter McLean Date: Sun, 22 Jun 2025 08:08:03 -0400 Subject: [PATCH 1/3] Make bit::bit_array an alias of bit::array --- include/bitlib/bit-algorithms/accumulate.hpp | 2 +- .../bitlib/bit-algorithms/to_from_string.hpp | 164 ++++++++++++++++++ include/bitlib/bit-algorithms/to_string.hpp | 4 +- include/bitlib/bit-containers/bit_array.hpp | 90 ++++++---- .../bitlib/bit-containers/bit_array_base.hpp | 21 ++- .../bit_array_dynamic_extent.hpp | 66 +++---- .../bitlib/bit-containers/bit_array_ref.hpp | 58 ++++--- include/bitlib/bit-containers/bit_literal.hpp | 13 +- include/bitlib/bit-containers/bit_span.hpp | 11 +- test/src/test-array.cpp | 80 ++++----- test/src/test-count_leading.cpp | 2 +- test/src/test-to_string.cpp | 4 +- 12 files changed, 353 insertions(+), 162 deletions(-) create mode 100644 include/bitlib/bit-algorithms/to_from_string.hpp diff --git a/include/bitlib/bit-algorithms/accumulate.hpp b/include/bitlib/bit-algorithms/accumulate.hpp index 1e5e46cc..f01c0833 100644 --- a/include/bitlib/bit-algorithms/accumulate.hpp +++ b/include/bitlib/bit-algorithms/accumulate.hpp @@ -1,4 +1,4 @@ -// ================================= BIT_ARRAY_REF =================================== // +// ================================= array_REF =================================== // // Project: The Experimental Bit Algorithms Library // \file accumulate.hpp // Description: Implementation of accumulate diff --git a/include/bitlib/bit-algorithms/to_from_string.hpp b/include/bitlib/bit-algorithms/to_from_string.hpp new file mode 100644 index 00000000..faf98b0e --- /dev/null +++ b/include/bitlib/bit-algorithms/to_from_string.hpp @@ -0,0 +1,164 @@ +// ================================= array_REF =================================== // +// Project: The Experimental Bit Algorithms Library +// \file to_string.hpp +// Description: Implementation of array_ref +// Creator: Vincent Reverdy +// Contributor: Peter McLean [2025] +// License: BSD 3-Clause License +// ========================================================================== // + +#ifndef _BIT_TO_STRING_HPP_INCLUDED +#define _BIT_TO_STRING_HPP_INCLUDED + +#include + +#include "bitlib/bit-algorithms/accumulate.hpp" +#include "bitlib/bit-algorithms/count.hpp" +#include "bitlib/bit-containers/array_dynamic_extent.hpp" +#include "bitlib/bit-containers/bit_vector.hpp" +#include "bitlib/bit_concepts.hpp" + +namespace bit { + +namespace string { + +template +constexpr auto make_digit_map() { + static_assert((Base >= 2) && ((Base & (Base - 1)) == 0), "Base must be power of 2 >= 2"); + static_assert(Base <= 64, "Base too large for simple char mapping"); + + std::array map = {}; + for (std::size_t i = 0; i < Base; ++i) { + map[i] = (i < 10) ? ('0' + i) : ('A' + (i - 10)); + } + return map; +} + +template +constexpr auto make_from_digit_map() { + static_assert((Base >= 2) && ((Base & (Base - 1)) == 0), "Base must be power of 2 >= 2"); + static_assert(Base <= 64, "Base too large for simple char mapping"); + + std::array map = {}; + for (std::size_t i = 0; i < 128; ++i) { + map[i] = ~0; + if (i >= '0' && i <= '9') { + map[i] = i - '0'; + } + if (i >= 'a' && i <= 'z') { + map[i] = (i - 'a') + 10; + } + if (i >= 'A' && i <= 'Z') { + map[i] = (i - 'A') + 10; + } + } + return map; +} + +struct metadata_t { + size_t base; + bool is_signed; + std::endian endian; + bool str_sign_extend_zeros; +}; + +constexpr metadata_t typical(size_t base = 10, bool str_sign_extend_zeros = false) { + return { + .base = base, + .is_signed = false, + .endian = std::endian::big, + .str_sign_extend_zeros = str_sign_extend_zeros}; +} + +} // namespace string + +template +constexpr std::string to_string(const bit_iterator& first, const bit_iterator& last, std::string prefix = "") { + static_assert(meta.endian == std::endian::big, "Only bit big endian support (MSB on the left)"); + if constexpr (std::has_single_bit(meta.base)) { + constexpr const auto base_bits = std::bit_width(meta.base - 1); + + int skip_leading_bits = meta.str_sign_extend_zeros ? 0 : count_msb(first, last, bit0); + + int str_len = (distance(first, last) - skip_leading_bits); + str_len += (0 != (str_len % base_bits)); + std::string& str = prefix; + str.resize(str.length() + str_len); + + static constexpr auto base_digits = string::make_digit_map(); + + return accumulate( + policy::AccumulateNoInitialSubword{}, + first, last - skip_leading_bits, (str.data() + str_len), + [](char* acc, auto word, const size_t bits = bitsof()) { + const int characters = ((bits + base_bits - 1) / base_bits); + acc -= characters; + for (int i = characters - 1; i >= 0; i--) { + acc[i] = base_digits[word & (meta.base - 1)]; + word >>= base_bits; + } + return acc; + }); + } else { + return "not_implented_yet"; + } +} + +template +constexpr std::string to_string(const bit_sized_range auto& bits, std::string prefix = "") { + return to_string(bits.begin(), bits.end(), prefix); +} + +template , typename RandomAccessIt> +constexpr void from_string( + Policy, + const char* str_first, const char* str_last, + bit_iterator bit_first, bit_iterator bit_last) { + const auto str_len = str_last - str_first; +} + +template +constexpr bit_vector<> from_string(const char* first, const char* last) { + static_assert(meta.endian == std::endian::big, "Only bit big endian support (MSB on the left)"); + if constexpr (std::has_single_bit(meta.base)) { + constexpr const auto base_bits = std::bit_width(meta.base - 1); + static constexpr auto base_from_digits = string::make_from_digit_map(); + + bit_vector<> vec; + + last--; + while (last >= first) { + uint64_t work = 0; + size_t bits = 0; + for (; (bits < bitsof()) && (last >= first); last--) { + char c = *last; + // TODO: This should be a policy + if (c >= base_from_digits.size()) { + continue; + } + auto digit = base_from_digits[c]; + // TODO: This should be a policy + if (~0 == digit) { + continue; + } + work |= (digit << bits); + bits += base_bits; + } + if (bits) { + vec.append_range(array<>(bits, work)); + } + } + return vec; + } else { + //from_string base 10 not implemented yet; + } +} + +template +constexpr bit_vector<> from_string(const std::string& str) { + return from_string(str.c_str(), str.c_str() + str.length()); +} + +} // namespace bit + +#endif // _BIT_TO_STRING_HPP_INCLUDED \ No newline at end of file diff --git a/include/bitlib/bit-algorithms/to_string.hpp b/include/bitlib/bit-algorithms/to_string.hpp index cb31c8d7..61d488b7 100644 --- a/include/bitlib/bit-algorithms/to_string.hpp +++ b/include/bitlib/bit-algorithms/to_string.hpp @@ -1,7 +1,7 @@ -// ================================= BIT_ARRAY_REF =================================== // +// ================================= array_REF =================================== // // Project: The Experimental Bit Algorithms Library // \file to_string.hpp -// Description: Implementation of bit_array_ref +// Description: Implementation of array_ref // Creator: Vincent Reverdy // Contributor: Peter McLean [2025] // License: BSD 3-Clause License diff --git a/include/bitlib/bit-containers/bit_array.hpp b/include/bitlib/bit-containers/bit_array.hpp index a46a3c0b..12de75be 100644 --- a/include/bitlib/bit-containers/bit_array.hpp +++ b/include/bitlib/bit-containers/bit_array.hpp @@ -30,7 +30,26 @@ #include "bitlib/bit_concepts.hpp" namespace bit { -// ========================================================================== // + +template , + std::conditional_t< + (N == std::dynamic_extent), + std::uintptr_t, + ceil_integral>, + T>, + typename Policy = policy::typical> +class array; + +template >, + typename Policy = policy::typical> +using bit_array = array; namespace detail { @@ -38,7 +57,7 @@ template constexpr size_t Words() { return (N * bitsof() + bitsof() - 1) / bitsof(); } template -struct bit_array_iterator_types { +struct array_iterator_types { using iterator = typename std::conditional, bit_iterator()>::iterator>, typename std::array()>::iterator>::type; @@ -49,13 +68,10 @@ struct bit_array_iterator_types { }; } // namespace detail -template >, - typename Policy = policy::typical> -class bit_array : public bit_array_base, T, N, W, Policy, detail::bit_array_iterator_types> { +template +class array : public array_base, T, N, W, Policy, detail::array_iterator_types> { public: - using base = bit_array_base, T, N, W, Policy, detail::bit_array_iterator_types>; + using base = array_base, T, N, W, Policy, detail::array_iterator_types>; using base::end; using typename base::const_iterator; using typename base::const_pointer; @@ -82,47 +98,47 @@ class bit_array : public bit_array_base, T, N, W, Policy, det /* * Constructors, copies and moves... */ - constexpr bit_array() noexcept : storage{} {} + constexpr array() noexcept : storage{} {} - constexpr bit_array(value_type bit_val) { + constexpr array(value_type bit_val) { this->fill(bit_val); } template - constexpr bit_array(const U& integral) { + constexpr array(const U& integral) { this->from_integral(integral); } - constexpr bit_array(const bit_array& other) noexcept + constexpr array(const array& other) noexcept : storage(other.storage) {} - constexpr bit_array(const bit_array&& other) noexcept + constexpr array(const array&& other) noexcept : storage(other.storage) {} - constexpr bit_array(const bit_sized_range auto& other) { + constexpr array(const bit_sized_range auto& other) { if (other.size() != this->size()) [[unlikely]] { - throw std::invalid_argument("other bit_range contains an invalid number of bits for bit_array."); + throw std::invalid_argument("other bit_range contains an invalid number of bits for array."); } ::bit::copy(other.begin(), other.end(), this->begin()); }; - constexpr bit_array(const std::initializer_list init) + constexpr array(const std::initializer_list init) requires(!std::is_same_v) { if (init.size() != bitsof(*this)) [[unlikely]] { - throw std::invalid_argument("initialize_list contains an invalid number of bits for bit_array."); + throw std::invalid_argument("initialize_list contains an invalid number of bits for array."); } std::copy(init.begin(), init.end(), this->begin()); } - constexpr bit_array(const std::initializer_list init) { + constexpr array(const std::initializer_list init) { if (init.size() != bitsof(*this)) [[unlikely]] { - throw std::invalid_argument("initialize_list contains an invalid number of bits for bit_array."); + throw std::invalid_argument("initialize_list contains an invalid number of bits for array."); } std::copy(init.begin(), init.end(), this->begin()); } - constexpr bit_array(const std::initializer_list init) : storage{} { + constexpr array(const std::initializer_list init) : storage{} { // Make sure we handle the case where init.size() != Words auto it = init.begin(); for (size_type i = 0; i < std::min(Words(N), init.size()); ++i, ++it) { @@ -130,11 +146,11 @@ class bit_array : public bit_array_base, T, N, W, Policy, det } } - constexpr bit_array(const std::string_view s) + constexpr array(const std::string_view s) requires(std::is_same_v) { if (bitsof(*this) != static_cast(std::count(s.begin(), s.end(), '0') + std::count(s.begin(), s.end(), '1'))) [[unlikely]] { - throw std::invalid_argument("String contains an invalid number of bits for bit_array."); + throw std::invalid_argument("String contains an invalid number of bits for array."); }; size_type i = 0; for (char c : s) { @@ -146,21 +162,21 @@ class bit_array : public bit_array_base, T, N, W, Policy, det } } - ~bit_array() = default; + ~array() = default; /* * Assignment */ - constexpr bit_array& operator=(const bit_array& other) = default; + constexpr array& operator=(const array& other) = default; - constexpr bit_array& operator=(const bit_sized_range auto& other) { + constexpr array& operator=(const bit_sized_range auto& other) { if (other.size() != this->size()) [[unlikely]] { - throw std::invalid_argument("other bit_sized_range contains an invalid number of bits for bit_array."); + throw std::invalid_argument("other bit_sized_range contains an invalid number of bits for array."); } ::bit::copy(other.begin(), other.end(), this->begin()); return *this; }; - constexpr bit_array& operator=(bit_array&& other) noexcept { + constexpr array& operator=(array&& other) noexcept { std::copy(other.storage.begin(), other.storage.end(), storage.begin()); return *this; } @@ -194,7 +210,7 @@ class bit_array : public bit_array_base, T, N, W, Policy, det /* * Operations */ - constexpr void swap(bit_array& other) noexcept { + constexpr void swap(array& other) noexcept { std::swap(this->storage, other.storage); } @@ -205,11 +221,11 @@ class bit_array : public bit_array_base, T, N, W, Policy, det } }; -static_assert(bit_range>, "bit_array does not satisfy bit_range concept!"); -static_assert(bit_sized_range>, "bit_array does not satisfy bit_sized_range concept!"); +static_assert(bit_range>, "array does not satisfy bit_range concept!"); +static_assert(bit_sized_range>, "array does not satisfy bit_sized_range concept!"); #ifdef CONTIGUOUS_RANGE -static_assert(bit_contiguous_range>, "bit_array does not satisfy bit_contiguous_range concept!"); -static_assert(bit_contiguous_sized_range>, "bit_array does not satisfy bit_contiguous_sized_range concept!"); +static_assert(bit_contiguous_range>, "array does not satisfy bit_contiguous_range concept!"); +static_assert(bit_contiguous_sized_range>, "array does not satisfy bit_contiguous_sized_range concept!"); #endif #if 0 @@ -217,18 +233,18 @@ static_assert(bit_contiguous_sized_range>, "bit_array does not sat // CTAD guide for the constructor taking a word_type&, // deducing Extent as bitsof(). template -bit_array(word_type&) -> bit_array()>; +array(word_type&) -> array()>; template -bit_array(word_type*) -> bit_array()>; +array(word_type*) -> array()>; // CTAD guide for the constructor taking a word_type* and a size, // which should always be used when Extent is std::dynamic_extent. template -bit_array(word_type&, std::size_t) -> bit_array; +array(word_type&, std::size_t) -> array; template -bit_array(word_type*, std::size_t) -> bit_array; +array(word_type*, std::size_t) -> array; #endif } // namespace bit -#endif // _BIT_ARRAY_HPP_INCLUDED \ No newline at end of file +#endif // _array_HPP_INCLUDED \ No newline at end of file diff --git a/include/bitlib/bit-containers/bit_array_base.hpp b/include/bitlib/bit-containers/bit_array_base.hpp index ed3f432b..a1599d34 100644 --- a/include/bitlib/bit-containers/bit_array_base.hpp +++ b/include/bitlib/bit-containers/bit_array_base.hpp @@ -30,19 +30,19 @@ namespace bit { template -class bit_array_ref; +class array_ref; template -class bit_array; +class array; /** - * @brief Base class template for bit_array implementations + * @brief Base class template for array implementations * * This is a CRTP (Curiously Recurring Template Pattern) base class that provides - * common functionality for bit_array variants. + * common functionality for array variants. * * @tparam Derived The derived class (CRTP pattern) * @tparam T The value type (typically bit_value) @@ -52,7 +52,7 @@ class bit_array; * @tparam Iterators A struct that provides iterator and const_iterator types */ template -class bit_array_base { +class array_base { protected: constexpr Derived& derived() noexcept { return static_cast(*this); @@ -161,17 +161,17 @@ class bit_array_base { } /** - * @brief Slice operations - returns a bit_array_ref + * @brief Slice operations - returns a array_ref */ constexpr auto operator()(size_type offset, size_type right) const noexcept { - return bit_array_ref(&this->at(offset), right - offset); + return array_ref(&this->at(offset), right - offset); } /** - * @brief Slice operations - returns a bit_array_ref + * @brief Slice operations - returns a array_ref */ constexpr auto operator()(size_type offset, size_type right) noexcept { - return bit_array_ref(&this->at(offset), right - offset); + return array_ref(&this->at(offset), right - offset); } // Common operations @@ -210,7 +210,7 @@ class bit_array_base { return integral; } - using compatible_bitarray = bit_array; + using compatible_bitarray = array; constexpr compatible_bitarray operator~() { compatible_bitarray result(derived().size()); @@ -295,4 +295,3 @@ constexpr bool operator==(const bit_sized_range auto& lhs, const bit_sized_range } // namespace bit #endif // _BIT_ARRAY_BASE_HPP_INCLUDED - // ========================================================================== // diff --git a/include/bitlib/bit-containers/bit_array_dynamic_extent.hpp b/include/bitlib/bit-containers/bit_array_dynamic_extent.hpp index 53544db2..870e4395 100644 --- a/include/bitlib/bit-containers/bit_array_dynamic_extent.hpp +++ b/include/bitlib/bit-containers/bit_array_dynamic_extent.hpp @@ -1,6 +1,6 @@ // ================================= BIT_ARRAY =================================== // // Project: The Experimental Bit Algorithms Library -// \file bit_array.hpp +// \file bit_array_dynamic_extent.hpp // Description: Implementation of bit_array // Creator: Vincent Reverdy // Contributor: Peter McLean [2025] @@ -30,7 +30,7 @@ namespace bit { namespace detail { template -struct bit_array_dextent_iterator_types { +struct array_dextent_iterator_types { using iterator = typename std::conditional, bit_iterator, word_type*>::type; @@ -40,10 +40,10 @@ struct bit_array_dextent_iterator_types { }; } // namespace detail template -class bit_array - : public bit_array_base, T, std::dynamic_extent, W, Policy, detail::bit_array_dextent_iterator_types> { +class array + : public array_base, T, std::dynamic_extent, W, Policy, detail::array_dextent_iterator_types> { public: - using base = bit_array_base, T, std::dynamic_extent, W, Policy, detail::bit_array_dextent_iterator_types>; + using base = array_base, T, std::dynamic_extent, W, Policy, detail::array_dextent_iterator_types>; using base::end; using typename base::const_iterator; using typename base::const_pointer; @@ -138,7 +138,7 @@ class bit_array }; public: - ~bit_array() { + ~array() { if (size() > FixedBits) { storage.m_allocator.deallocate(storage.pointer, Words(size())); } else { @@ -151,50 +151,50 @@ class bit_array /* * Constructors, copies and moves... */ - bit_array() = delete; + array() = delete; - constexpr bit_array(const size_type size, const Allocator& allocator = Allocator()) + constexpr array(const size_type size, const Allocator& allocator = Allocator()) : m_size(size), storage(Words(size), allocator) { } template - constexpr bit_array(const size_type size, const U& integral, const Allocator& allocator = Allocator()) + constexpr array(const size_type size, const U& integral, const Allocator& allocator = Allocator()) : m_size(size), storage(Words(size), allocator, detail::uninitialized) { this->from_integral(integral); } - constexpr bit_array(const size_type size, const word_type val, const Allocator& allocator = Allocator()) + constexpr array(const size_type size, const word_type val, const Allocator& allocator = Allocator()) : m_size(size), storage(Words(size), val, allocator) { } - constexpr bit_array(const size_type size, const value_type bit_val, const Allocator& allocator = Allocator()) + constexpr array(const size_type size, const value_type bit_val, const Allocator& allocator = Allocator()) requires(!std::is_same::value) : m_size(size), storage(Words(size), allocator, detail::uninitialized) { this->fill(bit_val); } - constexpr bit_array(const bit_array& other) + constexpr array(const array& other) : m_size(other.size()), storage(Words(size()), other.storage) { } - constexpr bit_array(const bit_array& other, const Allocator& allocator) + constexpr array(const array& other, const Allocator& allocator) : m_size(other.size()), storage(Words(size()), other.storage, allocator) { } - constexpr bit_array(const bit_sized_range auto& other, const Allocator& allocator = Allocator()) - : bit_array(other.size(), allocator, detail::uninitialized) { + constexpr array(const bit_sized_range auto& other, const Allocator& allocator = Allocator()) + : array(other.size(), allocator, detail::uninitialized) { ::bit::copy(other.begin(), other.end(), this->begin()); } - constexpr bit_array(bit_array&& other) + constexpr array(array&& other) : m_size(other.size()), storage(Words(size()), std::move(other.storage)) { } - constexpr bit_array(bit_array&& other, const Allocator& allocator) + constexpr array(array&& other, const Allocator& allocator) : m_size(other.size()), storage(Words(size()), std::move(other.storage), allocator) { } - constexpr bit_array(const std::initializer_list init, const Allocator& allocator = Allocator()) + constexpr array(const std::initializer_list init, const Allocator& allocator = Allocator()) requires(!std::is_same_v) : m_size(init.size()), storage(Words(size()), allocator, detail::uninitialized) { std::copy(init.begin(), init.end(), this->begin()); @@ -203,7 +203,7 @@ class bit_array #if 0 No known conversion from bool to bit_value bit_value has explicit constructor from bool to bit_value so this doesnt work - constexpr bit_array::bit_array(const std::initializer_list init) + constexpr array::array(const std::initializer_list init) : storage(std::make_unique(Words(init.size()))), m_size(init.size()) { std::copy(init.begin(), init.end(), this->begin()); @@ -211,12 +211,12 @@ class bit_array #endif template - constexpr bit_array(const std::initializer_list init, const Allocator& allocator = Allocator()) + constexpr array(const std::initializer_list init, const Allocator& allocator = Allocator()) : m_size(bitsof() * init.size()), storage(Words(size()), allocator, detail::uninitialized) { std::copy(init.begin(), init.end(), data()); } - constexpr bit_array(const std::string_view s, const Allocator& allocator = Allocator()) + constexpr array(const std::string_view s, const Allocator& allocator = Allocator()) requires(std::is_same_v) : m_size(std::count(s.begin(), s.end(), '0') + std::count(s.begin(), s.end(), '1')), storage(Words(size()), allocator, detail::uninitialized) { size_type i = 0; @@ -232,9 +232,9 @@ class bit_array /* * Assignment */ - constexpr bit_array& operator=(const bit_array& other) { + constexpr array& operator=(const array& other) { if (nullptr == data() || size() != other.size()) { - throw std::invalid_argument("Cannot reassign bit_array size"); + throw std::invalid_argument("Cannot reassign array size"); } if (this == &other) [[unlikely]] { return *this; @@ -243,19 +243,19 @@ class bit_array return *this; } - constexpr bit_array& operator=(const bit_sized_range auto& other) { + constexpr array& operator=(const bit_sized_range auto& other) { if (other.size() != this->size()) [[unlikely]] { - throw std::invalid_argument("other bit_range contains an invalid number of bits for bit_array."); + throw std::invalid_argument("other bit_range contains an invalid number of bits for array."); } ::bit::copy(other.begin(), other.end(), this->begin()); return *this; }; - constexpr bit_array& operator=(bit_array&& other) { + constexpr array& operator=(array&& other) { if (nullptr == data() || size() != other.size()) { - throw std::invalid_argument("Cannot reassign bit_array size"); + throw std::invalid_argument("Cannot reassign array size"); } - bit_array temp(std::move(other)); + array temp(std::move(other)); swap(temp); return *this; } @@ -308,7 +308,7 @@ class bit_array /* * Operations */ - constexpr void swap(bit_array& other) noexcept { + constexpr void swap(array& other) noexcept { assert(size() == other.size()); if (size() > FixedBits) { std::swap(this->storage.pointer, other.storage.pointer); @@ -320,11 +320,11 @@ class bit_array } }; -static_assert(bit_range>, "bit_array<> does not satisfy bit_contiguous_range concept!"); -static_assert(bit_sized_range>, "bit_array<> does not satisfy bit_contiguous_sized_range concept!"); +static_assert(bit_range>, "array<> does not satisfy bit_contiguous_range concept!"); +static_assert(bit_sized_range>, "array<> does not satisfy bit_contiguous_sized_range concept!"); #ifdef CONTIGUOUS_RANGE -static_assert(bit_contiguous_range>, "bit_array<> does not satisfy bit_contiguous_range concept!"); -static_assert(bit_contiguous_sized_range>, "bit_array<> does not satisfy bit_contiguous_sized_range concept!"); +static_assert(bit_contiguous_range>, "array<> does not satisfy bit_contiguous_range concept!"); +static_assert(bit_contiguous_sized_range>, "array<> does not satisfy bit_contiguous_sized_range concept!"); #endif // ========================================================================== // diff --git a/include/bitlib/bit-containers/bit_array_ref.hpp b/include/bitlib/bit-containers/bit_array_ref.hpp index c19a6e3c..763001ba 100644 --- a/include/bitlib/bit-containers/bit_array_ref.hpp +++ b/include/bitlib/bit-containers/bit_array_ref.hpp @@ -26,9 +26,15 @@ namespace bit { +template > +class array_ref; + +template > +using bit_array_ref = array_ref; + namespace detail { template -struct bit_array_ref_iterator_types { +struct array_ref_iterator_types { using iterator = bit_iterator; using const_iterator = bit_iterator; }; @@ -36,18 +42,18 @@ struct bit_array_ref_iterator_types { /** * @brief A non-owning reference to a bit array * - * Similar to bit_array_dynamic_extent but does not allocate or deallocate memory. + * Similar to array_dynamic_extent but does not allocate or deallocate memory. * The pointer and size are const class members and cannot be re-bound. * Assignment operations always copy content and can't rebind the pointer/size. * * @tparam T The value type (typically bit_value) * @tparam W The word type used for storage */ -template > -class bit_array_ref - : public bit_array_base, T, std::dynamic_extent, W, Policy, detail::bit_array_ref_iterator_types> { +template +class array_ref + : public array_base, T, std::dynamic_extent, W, Policy, detail::array_ref_iterator_types> { public: - using base = bit_array_base, T, std::dynamic_extent, W, Policy, detail::bit_array_ref_iterator_types>; + using base = array_base, T, std::dynamic_extent, W, Policy, detail::array_ref_iterator_types>; using base::end; using typename base::const_iterator; using typename base::const_pointer; @@ -66,7 +72,7 @@ class bit_array_ref public: // Constructors - bit_array_ref() = delete; + array_ref() = delete; /** * @brief Constructs a non-owning reference to a bit array @@ -74,7 +80,7 @@ class bit_array_ref * @param storage Pointer to the storage * @param size Number of bits */ - constexpr bit_array_ref(word_type* storage, size_type size) + constexpr array_ref(word_type* storage, size_type size) : m_storage(storage), m_size(size) { } @@ -85,7 +91,7 @@ class bit_array_ref * @param storage bit_pointer to the storage * @param size Number of bits */ - constexpr bit_array_ref(bit_pointer storage, size_type size) + constexpr array_ref(bit_pointer storage, size_type size) : m_storage(storage), m_size(size) { } @@ -95,7 +101,7 @@ class bit_array_ref * * @param other bit_sized_range */ - constexpr bit_array_ref(bit_range auto& other, size_type size) + constexpr array_ref(bit_range auto& other, size_type size) : m_storage(&(*other.begin())), m_size(size) { assert(size <= (other.end() - other.begin())); @@ -106,7 +112,7 @@ class bit_array_ref * * @param other bit_sized_range */ - constexpr bit_array_ref(const bit_range auto& other, size_type size) + constexpr array_ref(const bit_range auto& other, size_type size) requires(std::is_const_v) : m_storage(&(*other.begin())), m_size(size) { @@ -116,19 +122,19 @@ class bit_array_ref /** * @brief Copy constructor */ - constexpr bit_array_ref(const bit_array_ref& other) = default; + constexpr array_ref(const array_ref& other) = default; /** * @brief Move constructor */ - constexpr bit_array_ref(bit_array_ref&& other) = default; + constexpr array_ref(array_ref&& other) = default; /** * @brief Range Assignment operator - copies content but doesn't rebind */ - constexpr bit_array_ref& operator=(const bit_sized_range auto& other) { + constexpr array_ref& operator=(const bit_sized_range auto& other) { if (m_size != other.size()) { - throw std::invalid_argument("Cannot assign from bit_array_ref of different size"); + throw std::invalid_argument("Cannot assign from array_ref of different size"); } ::bit::copy(other.begin(), other.end(), this->begin()); return *this; @@ -137,10 +143,10 @@ class bit_array_ref /** * @brief Copy Assignment operator - copies content but doesn't rebind */ - constexpr bit_array_ref& operator=(const bit_array_ref& other) { + constexpr array_ref& operator=(const array_ref& other) { if (this != &other) { if (m_size != other.m_size) { - throw std::invalid_argument("Cannot assign from bit_array_ref of different size"); + throw std::invalid_argument("Cannot assign from array_ref of different size"); } ::bit::copy(other.begin(), other.end(), this->begin()); } @@ -150,10 +156,10 @@ class bit_array_ref /** * @brief Move assignment operator - copies content but doesn't rebind */ - constexpr bit_array_ref& operator=(bit_array_ref&& other) { + constexpr array_ref& operator=(array_ref&& other) { if (this != &other) { if (m_size != other.size()) { - throw std::invalid_argument("Cannot assign from bit_array_ref of different size"); + throw std::invalid_argument("Cannot assign from array_ref of different size"); } ::bit::copy(other.begin(), other.end(), this->begin()); } @@ -163,7 +169,7 @@ class bit_array_ref /** * @brief No destructor needed as we don't own the memory */ - ~bit_array_ref() = default; + ~array_ref() = default; /* * Iterators @@ -186,19 +192,19 @@ class bit_array_ref /* * Operations */ - constexpr void swap(bit_array_ref& other) { + constexpr void swap(array_ref& other) { if (m_size != other.m_size) { - throw std::invalid_argument("Cannot swap bit_array_ref of different sizes"); + throw std::invalid_argument("Cannot swap array_ref of different sizes"); } swap_ranges(begin(), end(), other.begin()); } }; -static_assert(bit_range>, "bit_array_ref<> does not satisfy bit_range concept!"); -static_assert(bit_sized_range>, "bit_array_ref<> does not satisfy bit_sized_range concept!"); +static_assert(bit_range>, "array_ref<> does not satisfy bit_range concept!"); +static_assert(bit_sized_range>, "array_ref<> does not satisfy bit_sized_range concept!"); #ifdef CONTIGUOUS_RANGE -static_assert(bit_contiguous_range>, "bit_array_ref<> does not satisfy bit_contiguous_range concept!"); -static_assert(bit_contiguous_sized_range>, "bit_array_ref<> does not satisfy bit_contiguous_sized_range concept!"); +static_assert(bit_contiguous_range>, "array_ref<> does not satisfy bit_contiguous_range concept!"); +static_assert(bit_contiguous_sized_range>, "array_ref<> does not satisfy bit_contiguous_sized_range concept!"); #endif // ========================================================================== // diff --git a/include/bitlib/bit-containers/bit_literal.hpp b/include/bitlib/bit-containers/bit_literal.hpp index cb809f68..cc579939 100644 --- a/include/bitlib/bit-containers/bit_literal.hpp +++ b/include/bitlib/bit-containers/bit_literal.hpp @@ -1,7 +1,7 @@ -// ================================= BIT_ARRAY =================================== // +// ================================= array =================================== // // Project: The Experimental Bit Algorithms Library // \file bit_literal.hpp -// Description: Implementation of bit_array user defined literal +// Description: Implementation of array user defined literal // Creator: Vincent Reverdy // Contributor: Peter McLean [2025] // License: BSD 3-Clause License @@ -20,10 +20,13 @@ namespace bit { +class bit_value; + template -class bit_array; +class array; -class bit_value; +template +using bit_array = array; // ========================================================================== // template @@ -118,7 +121,7 @@ constexpr auto operator""_b() { (((1ull << bits) - 1ull) >= num), "bit literal size prefix has too few bits to represent the given value"); using word_type = bit::ceil_integral; - return bit::bit_array>(static_cast(num)); + return bit::bit_array>(static_cast(num)); } #endif // _BIT_LITERAL_HPP_INCLUDED diff --git a/include/bitlib/bit-containers/bit_span.hpp b/include/bitlib/bit-containers/bit_span.hpp index 346ac854..1d7cb4e6 100644 --- a/include/bitlib/bit-containers/bit_span.hpp +++ b/include/bitlib/bit-containers/bit_span.hpp @@ -18,7 +18,10 @@ namespace bit { template -class bit_array_ref; +class array_ref; + +template > +using bit_array_ref = array_ref; // Helper storage: for a fixed extent no runtime size is stored. template @@ -131,7 +134,7 @@ class bit_span : private bit_span_storage { constexpr bit_span subspan(size_type offset, size_type count = std::dynamic_extent) const noexcept requires(Extent == std::dynamic_extent); - constexpr bit_array_ref operator()(size_type begin, size_type end) const noexcept; + constexpr bit_array_ref operator()(size_type begin, size_type end) const noexcept; template constexpr bit_span first() const noexcept @@ -306,8 +309,8 @@ constexpr bit_span bit_span -constexpr bit_array_ref bit_span::operator()(size_type begin, size_type end) const noexcept { - return bit_array_ref(&(this->begin()[begin]), end - begin); +constexpr bit_array_ref bit_span::operator()(size_type begin, size_type end) const noexcept { + return bit_array_ref(&(this->begin()[begin]), end - begin); } template diff --git a/test/src/test-array.cpp b/test/src/test-array.cpp index d7b60752..fc532b28 100644 --- a/test/src/test-array.cpp +++ b/test/src/test-array.cpp @@ -14,7 +14,7 @@ */ // Tests the default c'tor. TEST(ArrayTest, DefaultConstructor) { - bit::bit_array barr(bit::bit0); + bit::bit_array<11> barr(bit::bit0); EXPECT_EQ(2, sizeof(barr)); EXPECT_EQ(11u, barr.size()); EXPECT_EQ(bit::bit0, barr[0]); @@ -31,14 +31,14 @@ TEST(ArrayTest, DefaultConstructor) { } TEST(ArrayTest, BitsOf) { - bit::bit_array barr(bit::bit0); + bit::bit_array<11> barr(bit::bit0); EXPECT_EQ(11u, bitsof(barr)); - EXPECT_EQ(11u, bitsof(bit::bit_array())); + EXPECT_EQ(11u, bitsof(bit::bit_array<11>())); } TEST(ArrayTest, BasicIteration) { // <-- LSB, apparently 🙄 - bit::bit_array barr("0110_0101_110"); + bit::bit_array<11> barr("0110_0101_110"); int i = 0; for (const auto& bbit : barr) { switch (10 - i++) { @@ -58,7 +58,7 @@ TEST(ArrayTest, BasicIteration) { } TEST(ArrayTest, ZeroSize) { - bit::bit_array barr{}; + bit::bit_array<0> barr{}; std::array foo{}; EXPECT_EQ(sizeof(foo), sizeof(barr)); EXPECT_EQ(0, bitsof(barr)); @@ -66,7 +66,7 @@ TEST(ArrayTest, ZeroSize) { // Test that the default constructor initializes all bits to false. TEST(ArrayTest, DefaultInitialization) { - bit::bit_array ba; + bit::bit_array<8> ba; for (size_t i = 0; i < ba.size(); ++i) { EXPECT_FALSE(ba[i]) << "Bit " << i << " should be false by default"; } @@ -74,7 +74,7 @@ TEST(ArrayTest, DefaultInitialization) { // Test the fill() method. TEST(ArrayTest, FillMethod) { - bit::bit_array ba; + bit::bit_array<10> ba; ba.fill(bit::bit_value(true)); for (size_t i = 0; i < ba.size(); ++i) { EXPECT_TRUE(ba[i]) << "Bit " << i << " should be true after fill(true)"; @@ -87,7 +87,7 @@ TEST(ArrayTest, FillMethod) { // Test element access via operator[] and at(), including out-of-range checking. TEST(ArrayTest, ElementAccess) { - bit::bit_array ba; + bit::bit_array<5> ba; ba.fill(bit::bit_value(false)); ba[2] = bit::bit_value(true); EXPECT_TRUE(ba.at(2)); @@ -96,7 +96,7 @@ TEST(ArrayTest, ElementAccess) { // Test front() and back() member functions. TEST(ArrayTest, FrontBackAccess) { - bit::bit_array ba; + bit::bit_array<4> ba; ba.fill(bit::bit_value(false)); ba.front() = bit::bit_value(true); ba.back() = bit::bit_value(true); @@ -106,7 +106,7 @@ TEST(ArrayTest, FrontBackAccess) { // Test iterator functionality (both non-const and range-based). TEST(ArrayTest, IteratorFunctionality) { - bit::bit_array ba; + bit::bit_array<4> ba; ba.fill(bit::bit_value(false)); int index = 0; for (auto it = ba.begin(); it != ba.end(); ++it) { @@ -121,9 +121,9 @@ TEST(ArrayTest, IteratorFunctionality) { // Test const_iterator functionality. TEST(ArrayTest, ConstIteratorFunctionality) { - bit::bit_array ba; + bit::bit_array<4> ba; ba.fill(bit::bit_value(true)); - const bit::bit_array& const_ba = ba; + const bit::bit_array<4>& const_ba = ba; for (auto it = const_ba.begin(); it != const_ba.end(); ++it) { EXPECT_TRUE(*it); } @@ -131,7 +131,7 @@ TEST(ArrayTest, ConstIteratorFunctionality) { // Test the swap() member function. TEST(ArrayTest, SwapFunctionality) { - bit::bit_array ba1, ba2; + bit::bit_array<4> ba1, ba2; ba1.fill(bit::bit_value(false)); ba2.fill(bit::bit_value(true)); ba1.swap(ba2); @@ -143,18 +143,18 @@ TEST(ArrayTest, SwapFunctionality) { // Test comparison operators (== and !=). TEST(ArrayTest, ComparisonOperators) { - bit::bit_array ba1 = {bit::bit1, bit::bit1, bit::bit0, bit::bit0, bit::bit1}; - bit::bit_array ba2 = {bit::bit1, bit::bit1, bit::bit0, bit::bit0, bit::bit1}; + bit::bit_array<5> ba1 = {bit::bit1, bit::bit1, bit::bit0, bit::bit0, bit::bit1}; + bit::bit_array<5> ba2 = {bit::bit1, bit::bit1, bit::bit0, bit::bit0, bit::bit1}; EXPECT_EQ(ba1, ba2); ba2[2] = bit::bit_value(true); // Change one element EXPECT_NE(ba1, ba2); - bit::bit_array ba3{bit::bit1, bit::bit1, bit::bit1, bit::bit0, bit::bit0, bit::bit1}; + bit::bit_array ba3{bit::bit1, bit::bit1, bit::bit1, bit::bit0, bit::bit0, bit::bit1}; EXPECT_NE(ba1, ba3); } // Test the data() method to access the underlying storage. TEST(ArrayTest, DataAccess) { - bit::bit_array ba; + bit::bit_array<8> ba; ba.fill(bit::bit_value(false)); // Assume data() returns a pointer to a boolean array. uint8_t* data_ptr = ba.data(); @@ -165,18 +165,18 @@ TEST(ArrayTest, DataAccess) { // Test size() and empty() functions. TEST(ArrayTest, SizeAndEmpty) { - bit::bit_array ba_empty; + bit::bit_array<0> ba_empty; EXPECT_EQ(ba_empty.size(), 0); EXPECT_TRUE(ba_empty.empty()); - bit::bit_array ba; + bit::bit_array<5> ba; EXPECT_EQ(ba.size(), 5); EXPECT_FALSE(ba.empty()); } // Test initializer list construction. TEST(ArrayTest, InitializerListConstruction) { - bit::bit_array ba = {bit::bit1, bit::bit0, bit::bit1}; + bit::bit_array<3> ba = {bit::bit1, bit::bit0, bit::bit1}; EXPECT_TRUE(ba[0]); EXPECT_FALSE(ba[1]); EXPECT_TRUE(ba[2]); @@ -184,19 +184,19 @@ TEST(ArrayTest, InitializerListConstruction) { // Test copy constructor and copy assignment operator. TEST(ArrayTest, CopyAndAssignment) { - bit::bit_array ba1 = {bit::bit1, bit::bit0, bit::bit1, bit::bit0, bit::bit1}; - bit::bit_array ba_copy(ba1); + bit::bit_array<5> ba1 = {bit::bit1, bit::bit0, bit::bit1, bit::bit0, bit::bit1}; + bit::bit_array<5> ba_copy(ba1); EXPECT_EQ(ba1, ba_copy); - bit::bit_array ba_assigned; + bit::bit_array<5> ba_assigned; ba_assigned = ba1; EXPECT_EQ(ba1, ba_assigned); } // Test move semantics (move constructor and move assignment), if implemented. TEST(ArrayTest, MoveSemantics) { - bit::bit_array ba1 = {bit::bit1, bit::bit0, bit::bit1, bit::bit0, bit::bit1}; - bit::bit_array ba_moved(std::move(ba1)); + bit::bit_array<5> ba1 = {bit::bit1, bit::bit0, bit::bit1, bit::bit0, bit::bit1}; + bit::bit_array<5> ba_moved(std::move(ba1)); // We test the moved-to container's values. The moved-from object is valid but unspecified. EXPECT_TRUE(ba_moved[0]); EXPECT_FALSE(ba_moved[1]); @@ -204,7 +204,7 @@ TEST(ArrayTest, MoveSemantics) { EXPECT_FALSE(ba_moved[3]); EXPECT_TRUE(ba_moved[4]); - bit::bit_array ba2 = {bit::bit0, bit::bit0, bit::bit0, bit::bit0, bit::bit0}; + bit::bit_array<5> ba2 = {bit::bit0, bit::bit0, bit::bit0, bit::bit0, bit::bit0}; ba2 = std::move(ba_moved); EXPECT_TRUE(ba2[0]); EXPECT_FALSE(ba2[1]); @@ -214,15 +214,15 @@ TEST(ArrayTest, MoveSemantics) { } TEST(ArrayTest, Throws) { - bit::bit_array ba1{bit::bit1, bit::bit0, bit::bit1, bit::bit0, bit::bit1}; + bit::bit_array<5> ba1{bit::bit1, bit::bit0, bit::bit1, bit::bit0, bit::bit1}; EXPECT_THROW(ba1.at(5), std::out_of_range); - bit::bit_array ba2{bit::bit1, bit::bit0, bit::bit1, bit::bit0, bit::bit1}; - bit::bit_array ba3(ba2); + bit::bit_array ba2{bit::bit1, bit::bit0, bit::bit1, bit::bit0, bit::bit1}; + bit::bit_array<5> ba3(ba2); EXPECT_EQ(ba1, ba3); EXPECT_EQ(ba1, ba2); - bit::bit_array ba4{bit::bit1, bit::bit1, bit::bit0, bit::bit1, bit::bit0, bit::bit1}; + bit::bit_array ba4{bit::bit1, bit::bit1, bit::bit0, bit::bit1, bit::bit0, bit::bit1}; - using barr5 = bit::bit_array; // command in template messes up gtest macro + using barr5 = bit::bit_array<5>; // command in template messes up gtest macro EXPECT_THROW(barr5{ba4}, std::invalid_argument) << "Copy constructor must take the same size"; EXPECT_THROW(barr5{bit::bit0}, std::invalid_argument) << "Initializer list must be the correct size"; @@ -245,7 +245,7 @@ TEST(BitArrayDynamicTest, Throws) { // Test Suite for bit::bit_array<> // -// As bit_array<> is dynamic, bitsof will not return the number stored bits +// As array<> is dynamic, bitsof will not return the number stored bits // the class contains a size_t and a pointer TEST(BitArrayDynamicTest, Bitsof) { bit::bit_array<> arr(23, bit::bit1); @@ -278,13 +278,13 @@ TEST(BitArrayDynamicTest, CopyConstructorCopiesContent) { // Test copy constructor and copy assignment operator. TEST(BitArrayDynamicTest, CopyAndAssignment) { - bit::bit_array ba1{bit::bit1, bit::bit0, bit::bit1, bit::bit0, bit::bit1}; - bit::bit_array ba_copy(ba1); + bit::bit_array ba1{bit::bit1, bit::bit0, bit::bit1, bit::bit0, bit::bit1}; + bit::bit_array ba_copy(ba1); EXPECT_EQ(ba1, ba_copy); - bit::bit_array ba2{bit::bit1, bit::bit1, bit::bit0, bit::bit1, bit::bit0, bit::bit1}; + bit::bit_array ba2{bit::bit1, bit::bit1, bit::bit0, bit::bit1, bit::bit0, bit::bit1}; EXPECT_THROW(ba1 = ba2, std::invalid_argument) << "Copy assignment from invalid size should throw"; - EXPECT_THROW(ba1 = ba2(0, 6), std::invalid_argument) << "Assign from bit_sized_range (bit_array_ref) of unequal size should throw"; + EXPECT_THROW(ba1 = ba2(0, 6), std::invalid_argument) << "Assign from bit_sized_range (array_ref) of unequal size should throw"; } TEST(BitArrayDynamicTest, MoveConstructorMovesContent) { @@ -314,7 +314,7 @@ TEST(BitArrayDynamicTest, InitializerListWordTypeConstructorWorks) { // For this test, we assume that the initializer list for WordType initializes the underlying storage. // Here we use two bytes as an example. std::initializer_list init = {0b10101010, 0b01010101}; - bit::bit_array arr(init); + bit::bit_array arr(init); // Assuming each std::uint8_t provides 8 bits, we expect the size to be the number of initializer elements * 8. EXPECT_EQ(arr.size(), init.size() * 8u); // Check that the underlying storage matches the initializer values. @@ -459,12 +459,12 @@ TEST(BitArrayDynamicTest, StringConstructor) { // Test comparison operators (== and !=). TEST(BitArrayDynamicTest, ComparisonOperators) { - bit::bit_array ba1{bit::bit1, bit::bit1, bit::bit0, bit::bit0, bit::bit1}; - bit::bit_array ba2{bit::bit1, bit::bit1, bit::bit0, bit::bit0, bit::bit1}; + bit::bit_array ba1{bit::bit1, bit::bit1, bit::bit0, bit::bit0, bit::bit1}; + bit::bit_array ba2{bit::bit1, bit::bit1, bit::bit0, bit::bit0, bit::bit1}; EXPECT_EQ(ba1, ba2); ba2[2] = bit::bit_value(true); // Change one element EXPECT_NE(ba1, ba2); - bit::bit_array ba3{bit::bit0, bit::bit1, bit::bit1, bit::bit0, bit::bit0, bit::bit1}; + bit::bit_array ba3{bit::bit0, bit::bit1, bit::bit1, bit::bit0, bit::bit0, bit::bit1}; EXPECT_NE(ba1, ba3); } diff --git a/test/src/test-count_leading.cpp b/test/src/test-count_leading.cpp index 0eb85bae..254b4dec 100644 --- a/test/src/test-count_leading.cpp +++ b/test/src/test-count_leading.cpp @@ -11,7 +11,7 @@ #include "gtest/gtest.h" TEST(CountLeading, CountLeadingZeroes) { - auto num = bit::bit_array(bit::bit0); + auto num = bit::bit_array<128>(bit::bit0); auto clz = bit::count_msb(num.begin(), num.end(), bit::bit0); std::cout << "Count leading zeroes: " << clz << std::endl; EXPECT_EQ(clz, 128); diff --git a/test/src/test-to_string.cpp b/test/src/test-to_string.cpp index 8ed62903..65ffc50d 100644 --- a/test/src/test-to_string.cpp +++ b/test/src/test-to_string.cpp @@ -2,10 +2,10 @@ #include #include -#include "bitlib/bit-containers/bit_array.hpp" -#include "bitlib/bit-containers/bit_array_dynamic_extent.hpp" #include "bitlib/bit-algorithms/count.hpp" #include "bitlib/bit-algorithms/to_string.hpp" +#include "bitlib/bit-containers/bit_array.hpp" +#include "bitlib/bit-containers/bit_array_dynamic_extent.hpp" #include "fixtures.hpp" // Third-party libraries From a9979881d100794a73cebc1d5c98f02d6783ee7b Mon Sep 17 00:00:00 2001 From: Peter McLean Date: Tue, 24 Jun 2025 19:26:50 -0400 Subject: [PATCH 2/3] Missing cstdint include --- include/bitlib/bit-algorithms/to_string.hpp | 1 + include/bitlib/bit_concepts.hpp | 1 + 2 files changed, 2 insertions(+) diff --git a/include/bitlib/bit-algorithms/to_string.hpp b/include/bitlib/bit-algorithms/to_string.hpp index 61d488b7..be9050d3 100644 --- a/include/bitlib/bit-algorithms/to_string.hpp +++ b/include/bitlib/bit-algorithms/to_string.hpp @@ -11,6 +11,7 @@ #define _BIT_TO_STRING_HPP_INCLUDED #include +#include #include "bitlib/bit-algorithms/accumulate.hpp" #include "bitlib/bit-algorithms/count.hpp" diff --git a/include/bitlib/bit_concepts.hpp b/include/bitlib/bit_concepts.hpp index 01f3c14d..027a8a41 100644 --- a/include/bitlib/bit_concepts.hpp +++ b/include/bitlib/bit_concepts.hpp @@ -2,6 +2,7 @@ #define _BIT_CONCEPTS_HPP_INCLUDED #include +#include #include #include From 91cc8c1da7cf63ce92c6fe654935a45be53a79d5 Mon Sep 17 00:00:00 2001 From: Peter McLean Date: Tue, 24 Jun 2025 19:38:01 -0400 Subject: [PATCH 3/3] Refactor includes w.r.t bit_span --- include/bitlib/bit-containers/bit_array.hpp | 1 - include/bitlib/bit-containers/bit_array_base.hpp | 1 - include/bitlib/bit-containers/bit_array_dynamic_extent.hpp | 1 - include/bitlib/bit-containers/bit_array_ref.hpp | 1 - include/bitlib/bit-containers/bit_span.hpp | 7 +------ include/bitlib/bit-containers/bit_vector.hpp | 1 - 6 files changed, 1 insertion(+), 11 deletions(-) diff --git a/include/bitlib/bit-containers/bit_array.hpp b/include/bitlib/bit-containers/bit_array.hpp index 12de75be..23263fc0 100644 --- a/include/bitlib/bit-containers/bit_array.hpp +++ b/include/bitlib/bit-containers/bit_array.hpp @@ -25,7 +25,6 @@ #include "bitlib/bit-containers/bit_array_base.hpp" #include "bitlib/bit-containers/bit_bitsof.hpp" #include "bitlib/bit-containers/bit_policy.hpp" -#include "bitlib/bit-containers/bit_span.hpp" #include "bitlib/bit-iterator/bit.hpp" #include "bitlib/bit_concepts.hpp" diff --git a/include/bitlib/bit-containers/bit_array_base.hpp b/include/bitlib/bit-containers/bit_array_base.hpp index a1599d34..af75d2bc 100644 --- a/include/bitlib/bit-containers/bit_array_base.hpp +++ b/include/bitlib/bit-containers/bit_array_base.hpp @@ -24,7 +24,6 @@ #include "bitlib/bit-algorithms/bit_algorithm.hpp" #include "bitlib/bit-containers/bit_bitsof.hpp" #include "bitlib/bit-containers/bit_policy.hpp" -#include "bitlib/bit-containers/bit_span.hpp" #include "bitlib/bit-iterator/bit.hpp" namespace bit { diff --git a/include/bitlib/bit-containers/bit_array_dynamic_extent.hpp b/include/bitlib/bit-containers/bit_array_dynamic_extent.hpp index 870e4395..57907fbd 100644 --- a/include/bitlib/bit-containers/bit_array_dynamic_extent.hpp +++ b/include/bitlib/bit-containers/bit_array_dynamic_extent.hpp @@ -22,7 +22,6 @@ #include "bitlib/bit-containers/bit_array_base.hpp" #include "bitlib/bit-containers/bit_bitsof.hpp" #include "bitlib/bit-containers/bit_policy.hpp" -#include "bitlib/bit-containers/bit_span.hpp" #include "bitlib/bit-iterator/bit.hpp" #include "bitlib/bit_concepts.hpp" diff --git a/include/bitlib/bit-containers/bit_array_ref.hpp b/include/bitlib/bit-containers/bit_array_ref.hpp index 763001ba..5706b6e0 100644 --- a/include/bitlib/bit-containers/bit_array_ref.hpp +++ b/include/bitlib/bit-containers/bit_array_ref.hpp @@ -20,7 +20,6 @@ #include "bitlib/bit-containers/bit_array_base.hpp" #include "bitlib/bit-containers/bit_bitsof.hpp" #include "bitlib/bit-containers/bit_policy.hpp" -#include "bitlib/bit-containers/bit_span.hpp" #include "bitlib/bit-iterator/bit.hpp" #include "bitlib/bit_concepts.hpp" diff --git a/include/bitlib/bit-containers/bit_span.hpp b/include/bitlib/bit-containers/bit_span.hpp index 1d7cb4e6..d7afe202 100644 --- a/include/bitlib/bit-containers/bit_span.hpp +++ b/include/bitlib/bit-containers/bit_span.hpp @@ -11,18 +11,13 @@ #include // Project sources #include "bitlib/bit-algorithms/bit_algorithm.hpp" +#include "bitlib/bit-containers/bit_array_ref.hpp" #include "bitlib/bit-containers/bit_bitsof.hpp" #include "bitlib/bit-containers/bit_policy.hpp" #include "bitlib/bit-iterator/bit.hpp" namespace bit { -template -class array_ref; - -template > -using bit_array_ref = array_ref; - // Helper storage: for a fixed extent no runtime size is stored. template struct bit_span_storage { diff --git a/include/bitlib/bit-containers/bit_vector.hpp b/include/bitlib/bit-containers/bit_vector.hpp index a3fa9285..147a62ea 100644 --- a/include/bitlib/bit-containers/bit_vector.hpp +++ b/include/bitlib/bit-containers/bit_vector.hpp @@ -22,7 +22,6 @@ #include // Project sources #include "bitlib/bit-algorithms/bit_algorithm.hpp" -#include "bitlib/bit-containers/bit_span.hpp" #include "bitlib/bit-iterator/bit.hpp" #include "bitlib/bit_concepts.hpp"