diff --git a/include/sparrow/dynamic_bitset.hpp b/include/sparrow/dynamic_bitset.hpp index 4113535d..af45b373 100644 --- a/include/sparrow/dynamic_bitset.hpp +++ b/include/sparrow/dynamic_bitset.hpp @@ -62,7 +62,7 @@ namespace sparrow size_type size() const noexcept; size_type null_count() const noexcept; - bool test(size_type pos) const; + const_reference test(size_type pos) const; void set(size_type pos, value_type value); reference operator[](size_type i); @@ -221,7 +221,7 @@ namespace sparrow void assign(bool) noexcept; void set() noexcept; void reset() noexcept; - + bitset_type& m_bitset; block_type& m_block; block_type m_mask; @@ -274,7 +274,7 @@ namespace sparrow mpl::constify_t, std::contiguous_iterator_tag, std::conditional_t> - >; + >; using reference = typename base_type::reference; using difference_type = typename base_type::difference_type; @@ -297,7 +297,7 @@ namespace sparrow friend class iterator_access; }; - + /************************************** * dynamic_bitset_base implementation * **************************************/ @@ -631,7 +631,7 @@ namespace sparrow } return *this; } - + template auto bitset_reference::operator|=(bool rhs) noexcept -> self_type& { @@ -641,7 +641,7 @@ namespace sparrow } return *this; } - + template auto bitset_reference::operator^=(bool rhs) noexcept -> self_type& { @@ -708,7 +708,7 @@ namespace sparrow { assert(m_index < bitset_type::s_bits_per_block); } - + template auto bitset_iterator::dereference() const -> reference { diff --git a/include/sparrow/fixed_size_layout.hpp b/include/sparrow/fixed_size_layout.hpp index f4538b99..afb89527 100644 --- a/include/sparrow/fixed_size_layout.hpp +++ b/include/sparrow/fixed_size_layout.hpp @@ -32,7 +32,7 @@ namespace sparrow * @tparam T The type of the elements in the layout's data buffer. * @tparam is_const A boolean indicating whether the iterator is const. * - * @note This class is not thread-safe, exception-safe, copyable, movable, equality comparable. + * @note This class is copyable and movable. */ template class fixed_size_layout_value_iterator @@ -66,7 +66,7 @@ namespace sparrow void increment(); void decrement(); void advance(difference_type n); - difference_type distance_to(const self_type& rhs) const; + difference_type distance_to(const self_type& hs) const; bool equal(const self_type& rhs) const; bool less_than(const self_type& rhs) const; @@ -94,9 +94,12 @@ namespace sparrow using self_type = fixed_size_layout; using inner_value_type = T; - using value_type = std::optional; using inner_reference = inner_value_type&; using inner_const_reference = const inner_reference; + using bitmap_type = array_data::bitmap_type; + using bitmap_reference = typename bitmap_type::reference; + using bitmap_const_reference = typename bitmap_type::const_reference; + using value_type = std::optional; using reference = reference_proxy; using const_reference = const_reference_proxy; using pointer = inner_value_type*; @@ -113,6 +116,9 @@ namespace sparrow using const_bitmap_range = std::ranges::subrange; using const_value_range = std::ranges::subrange; + using bitmap_range = std::ranges::subrange; + using value_range = std::ranges::subrange; + // TODO: implement with `begin` and `end` once the iterator is available. // using iterator = reference_proxy::iterator; // using const_iterator = const_reference_proxy::iterator; @@ -124,6 +130,9 @@ namespace sparrow reference operator[](size_type i); const_reference operator[](size_type i) const; + bitmap_range bitmap(); + value_range values(); + const_bitmap_range bitmap() const; const_value_range values() const; @@ -134,7 +143,8 @@ namespace sparrow pointer data(); const_pointer data() const; - bool has_value(size_type i) const; + bitmap_reference has_value(size_type i); + bitmap_const_reference has_value(size_type i) const; inner_reference value(size_type i); inner_const_reference value(size_type i) const; @@ -197,22 +207,22 @@ namespace sparrow template bool fixed_size_layout_value_iterator::equal(const self_type& rhs) const { - return distance_to(rhs) == 0; + return rhs.m_pointer == m_pointer; } template bool fixed_size_layout_value_iterator::less_than(const self_type& rhs) const { - return distance_to(rhs) > 0; + return m_pointer < rhs.m_pointer; } /************************************ * fixed_size_layout implementation * - * *********************************/ + ***********************************/ template fixed_size_layout::fixed_size_layout(array_data ad) - : m_data(ad) + : m_data(std::move(ad)) { // We only require the presence of the bitmap and the first buffer. assert(m_data.buffers.size() > 0); @@ -245,14 +255,26 @@ namespace sparrow auto fixed_size_layout::operator[](size_type i) -> reference { assert(i < size()); - return reference(*this, i); + return reference(value(i), has_value(i)); } template auto fixed_size_layout::operator[](size_type i) const -> const_reference { assert(i < size()); - return const_reference(*this, i); + return const_reference(value(i), has_value(i)); + } + + template + auto fixed_size_layout::bitmap() -> bitmap_range + { + return std::ranges::subrange(bitmap_begin(), bitmap_end()); + } + + template + auto fixed_size_layout::values() -> value_range + { + return std::ranges::subrange(value_begin(), value_end()); } template @@ -268,10 +290,17 @@ namespace sparrow } template - auto fixed_size_layout::has_value(size_type i) const -> bool + auto fixed_size_layout::has_value(size_type i) -> bitmap_reference + { + assert(i < size()); + return m_data.bitmap[i]; + } + + template + auto fixed_size_layout::has_value(size_type i) const -> bitmap_const_reference { assert(i < size()); - return m_data.bitmap.test(i); + return m_data.bitmap[i]; } template @@ -283,7 +312,7 @@ namespace sparrow template auto fixed_size_layout::value_end() -> value_iterator { - return value_iterator{data() + self_type::size()}; + return value_iterator{data() + size()}; } template @@ -295,7 +324,7 @@ namespace sparrow template auto fixed_size_layout::value_cend() const -> const_value_iterator { - return const_value_iterator{data() + self_type::size()}; + return const_value_iterator{data() + size()}; } template @@ -307,7 +336,7 @@ namespace sparrow template auto fixed_size_layout::bitmap_end() -> bitmap_iterator { - return m_data.bitmap.begin() + self_type::size(); + return m_data.bitmap.begin() + size(); } template @@ -319,7 +348,7 @@ namespace sparrow template auto fixed_size_layout::bitmap_cend() const -> const_bitmap_iterator { - return m_data.bitmap.cbegin() + self_type::size(); + return m_data.bitmap.cbegin() + size(); } template diff --git a/test/test_layout.cpp b/test/test_layout.cpp index 2b64f7cc..e1038f4b 100644 --- a/test/test_layout.cpp +++ b/test/test_layout.cpp @@ -35,7 +35,7 @@ namespace sparrow array_data ad; ad.type = data_descriptor(data_type::UINT8); - ad.bitmap = dynamic_bitset(n); + ad.bitmap = dynamic_bitset(n, true); buffer b(n); std::iota(b.begin(), b.end(), 0); @@ -55,9 +55,39 @@ namespace sparrow array_data ad = make_test_array_data(); layout_test_type lt(ad); REQUIRE(lt.size() == ad.length); + + for (std::size_t i = 0; i < lt.size(); ++i) + { + CHECK_EQ(lt[i].value(), ad.buffers[0][i]); + } + } + + TEST_CASE("value_iterator_ordering") + { + layout_test_type lt(make_test_array_data()); + auto lt_values = lt.values(); + layout_test_type::value_iterator iter = lt_values.begin(); + // TODO: Allow coercion of iterator to const_iterator. + // layout_test_type::const_value_iterator citer = lt_values.begin(); + REQUIRE(iter < lt_values.end()); + // REQUIRE(citer < lt_values.end()); } - } - // TODO: Test the iterators once they are implemented. + TEST_CASE("value_iterator_equality") + { + layout_test_type lt(make_test_array_data()); + auto lt_values = lt.values(); + layout_test_type::value_iterator iter = lt_values.begin(); + // TODO: Allow coercion of iterator to const_iterator. + // layout_test_type::const_value_iterator citer = lt_values.begin(); + for (std::size_t i = 0; i < lt.size(); ++i) + { + CHECK_EQ(*iter++, lt[i]); + // CHECK_EQ(*citer++, lt[i]); + } + CHECK_EQ(iter, lt_values.end()); + // CHECK_EQ(citer, lt_values.end()); + } + } }