From 6765a2a489b2b0444a66564e73f778d8d9d0cb95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Thu, 4 Jun 2026 22:38:57 +0200 Subject: [PATCH] Removed segmented iterator machinery --- include/boost/container/experimental/nest.hpp | 530 +----------------- test/nest_test.cpp | 340 ----------- 2 files changed, 3 insertions(+), 867 deletions(-) diff --git a/include/boost/container/experimental/nest.hpp b/include/boost/container/experimental/nest.hpp index 65801ad..15dde75 100644 --- a/include/boost/container/experimental/nest.hpp +++ b/include/boost/container/experimental/nest.hpp @@ -80,20 +80,9 @@ #include #endif -#if !defined(BOOST_CONTAINER_NEST_NO_PDEP) -# if defined(__BMI2__) -# define BOOST_CONTAINER_NEST_HAS_PDEP -# elif defined(BOOST_MSVC) && defined(__AVX2__) && (defined(_M_X64) || defined(_M_IX86)) -# define BOOST_CONTAINER_NEST_HAS_PDEP -# endif -#endif - -#if defined(BOOST_CONTAINER_NEST_HAS_PDEP) -# if defined(BOOST_MSVC) -# include -# else -# include -# endif +//_BitScanForward64 / _BitScanReverse64 used by the bit helpers below. +#if defined(BOOST_MSVC) && (defined(_M_X64) || defined(_M_ARM64)) +# include #endif #ifdef __has_builtin @@ -233,11 +222,6 @@ std::pair< nest_iterator, F > , nest_iterator , F); -struct segmented_iterator_tag; - -template -struct segmented_iterator_traits; - namespace nest_detail { ////////////////////////////////////////////// @@ -292,84 +276,6 @@ BOOST_CONTAINER_FORCEINLINE int unchecked_countl_zero(boost::uint64_t x) #endif } -// nth_set_bit: returns the bit-position of the nth set bit (0-indexed) in mask. -// Precondition: popcount(mask) > n >= 0. -// -// Two implementations selected at compile time: -// 1. BMI2 pdep + countr_zero (BOOST_CONTAINER_NEST_HAS_PDEP) -// 2. Binary search using popcount (default fallback) -// -// The default fallback halves the 64-bit mask with popcount at each step -// (branching variant). Define BOOST_CONTAINER_NEST_NTH_BIT_BRANCHLESS to -// select a branchless arithmetic variant of the same algorithm. - -#if defined(BOOST_CONTAINER_NEST_HAS_PDEP) - -BOOST_CONTAINER_FORCEINLINE int nth_set_bit(boost::uint64_t mask, int n) -{ - return unchecked_countr_zero(_pdep_u64(boost::uint64_t(1) << n, mask)); -} - -#elif defined(BOOST_CONTAINER_NEST_NTH_BIT_BRANCHLESS) - -inline int nth_set_bit(boost::uint64_t mask, int n) -{ - int pos = 0; - int c; - - c = boost::core::popcount(boost::uint64_t(mask & boost::uint64_t(0x00000000FFFFFFFFu))); - { const int s = (n >= c); pos += s * 32; mask >>= unsigned(s * 32); n -= s * c; } - - c = boost::core::popcount(boost::uint64_t(mask & boost::uint64_t(0x000000000000FFFFu))); - { const int s = (n >= c); pos += s * 16; mask >>= unsigned(s * 16); n -= s * c; } - - c = boost::core::popcount(boost::uint64_t(mask & boost::uint64_t(0x00000000000000FFu))); - { const int s = (n >= c); pos += s * 8; mask >>= unsigned(s * 8); n -= s * c; } - - c = boost::core::popcount(boost::uint64_t(mask & boost::uint64_t(0x000000000000000Fu))); - { const int s = (n >= c); pos += s * 4; mask >>= unsigned(s * 4); n -= s * c; } - - c = boost::core::popcount(boost::uint64_t(mask & boost::uint64_t(0x0000000000000003u))); - { const int s = (n >= c); pos += s * 2; mask >>= unsigned(s * 2); n -= s * c; } - - { const int s = (n > 0); pos += s; mask >>= unsigned(s); } - - return pos + unchecked_countr_zero(mask); -} - -#else - -inline int nth_set_bit(boost::uint64_t mask, int n) -{ - int pos = 0; - int c; - - c = boost::core::popcount(boost::uint64_t(mask & boost::uint64_t(0x00000000FFFFFFFFu))); - if (n >= c) { pos += 32; mask >>= 32; n -= c; } - - c = boost::core::popcount(boost::uint64_t(mask & boost::uint64_t(0x000000000000FFFFu))); - if (n >= c) { pos += 16; mask >>= 16; n -= c; } - - c = boost::core::popcount(boost::uint64_t(mask & boost::uint64_t(0x00000000000000FFu))); - if (n >= c) { pos += 8; mask >>= 8; n -= c; } - - c = boost::core::popcount(boost::uint64_t(mask & boost::uint64_t(0x000000000000000Fu))); - if (n >= c) { pos += 4; mask >>= 4; n -= c; } - - c = boost::core::popcount(boost::uint64_t(mask & boost::uint64_t(0x0000000000000003u))); - if (n >= c) { pos += 2; mask >>= 2; n -= c; } - - if (n > 0) { pos += 1; mask >>= 1; } - - return pos + unchecked_countr_zero(mask); -} - -#endif - - - - - ////////////////////////////////////////////// // @@ -872,7 +778,6 @@ public: private: template friend class nest_iterator; template friend class boost::container::nest; - template friend struct ::boost::container::segmented_iterator_traits; template friend std::pair< nest_iterator, FF > for_each_while @@ -909,370 +814,6 @@ private: int n; }; -////////////////////////////////////////////// -// -// nest_local_iterator -// -////////////////////////////////////////////// - -#define NEST_LOCAL_ITERATOR_FULL - -#if defined(NEST_LOCAL_ITERATOR_FULL) -template -class nest_local_iterator -{ - typedef typename boost::intrusive::pointer_traits::element_type element_type; - - typedef typename nest_detail::pointer_rebind::type void_pointer; - typedef nest_detail::block_base block_base_type; - typedef typename nest_detail::pointer_rebind::type>::type nonconst_pointer; - typedef nest_detail::block block_type; - typedef typename block_base_type::mask_type mask_type; - - BOOST_STATIC_CONSTEXPR std::size_t N = block_base_type::N; - BOOST_STATIC_CONSTEXPR mask_type full = block_base_type::full; - BOOST_STATIC_CONSTEXPR mask_type full_l = (full << 1); - -public: - typedef typename dtl::remove_const::type value_type; - typedef typename boost::intrusive::pointer_traits::difference_type difference_type; - typedef ValuePointer pointer; - typedef element_type& reference; - typedef std::random_access_iterator_tag iterator_category; - - typedef typename nest_detail::pointer_rebind::type block_base_pointer; - - nest_local_iterator() BOOST_NOEXCEPT - : pbb(), n(0) - {} - - nest_local_iterator(block_base_pointer pbb_, int n_) BOOST_NOEXCEPT - : pbb(pbb_), n(n_) - {} - - BOOST_CONTAINER_FORCEINLINE reference operator*() const BOOST_NOEXCEPT - { return static_cast(*pbb).data()[n]; } - - BOOST_CONTAINER_FORCEINLINE pointer operator->() const BOOST_NOEXCEPT - { return static_cast(*pbb).data() + n; } - - BOOST_CONTAINER_FORCEINLINE nest_local_iterator& operator++() BOOST_NOEXCEPT - { - BOOST_CONTAINER_ASSUME(n != (int)N); - const mask_type m = pbb->mask & (full_l << n); - n = m ? nest_detail::first_in_mask(m) : (int)N; - return *this; - } - - BOOST_CONTAINER_FORCEINLINE nest_local_iterator operator++(int) BOOST_NOEXCEPT - { nest_local_iterator tmp(*this); ++*this; return tmp; } - - BOOST_CONTAINER_FORCEINLINE nest_local_iterator& operator--() BOOST_NOEXCEPT - { - BOOST_CONTAINER_ASSUME(n != 0); - const mask_type m = pbb->mask & (full >> (int(N) - n)); - n = nest_detail::last_in_mask(m); - return *this; - } - - BOOST_CONTAINER_FORCEINLINE nest_local_iterator operator--(int) BOOST_NOEXCEPT - { nest_local_iterator tmp(*this); --*this; return tmp; } - - // random-access: advance by k occupied slots - BOOST_CONTAINER_FORCEINLINE nest_local_iterator& operator+=(difference_type k) BOOST_NOEXCEPT - { - const mask_type m = pbb->mask; - const mask_type lo = (n == int(N)) ? full : ((mask_type(1) << n) - 1); - const int idx = (int)boost::core::popcount(m & lo); - const int target = idx + (int)k; - const int total = (int)boost::core::popcount(m); - BOOST_CONTAINER_ASSUME(target >= 0 && target <= total); - n = (target >= total) ? (int)N : nest_detail::nth_set_bit(m, target); - return *this; - } - - BOOST_CONTAINER_FORCEINLINE nest_local_iterator& operator-=(difference_type k) BOOST_NOEXCEPT - { return *this += (-k); } - - BOOST_CONTAINER_FORCEINLINE - friend nest_local_iterator operator+(nest_local_iterator it, difference_type k) BOOST_NOEXCEPT - { it += k; return it; } - - BOOST_CONTAINER_FORCEINLINE - friend nest_local_iterator operator+(difference_type k, nest_local_iterator it) BOOST_NOEXCEPT - { it += k; return it; } - - BOOST_CONTAINER_FORCEINLINE - friend nest_local_iterator operator-(nest_local_iterator it, difference_type k) BOOST_NOEXCEPT - { it -= k; return it; } - - BOOST_CONTAINER_FORCEINLINE reference operator[](difference_type k) const BOOST_NOEXCEPT - { return *(*this + k); } - - // equality - BOOST_CONTAINER_FORCEINLINE - friend bool operator==(const nest_local_iterator& x, const nest_local_iterator& y) BOOST_NOEXCEPT - { return x.n == y.n; } - - BOOST_CONTAINER_FORCEINLINE - friend bool operator!=(const nest_local_iterator& x, const nest_local_iterator& y) BOOST_NOEXCEPT - { return x.n != y.n; } - - // ordering - BOOST_CONTAINER_FORCEINLINE - friend bool operator<(const nest_local_iterator& x, const nest_local_iterator& y) BOOST_NOEXCEPT - { return x.n < y.n; } - - BOOST_CONTAINER_FORCEINLINE - friend bool operator>(const nest_local_iterator& x, const nest_local_iterator& y) BOOST_NOEXCEPT - { return x.n > y.n; } - - BOOST_CONTAINER_FORCEINLINE - friend bool operator<=(const nest_local_iterator& x, const nest_local_iterator& y) BOOST_NOEXCEPT - { return x.n <= y.n; } - - BOOST_CONTAINER_FORCEINLINE - friend bool operator>=(const nest_local_iterator& x, const nest_local_iterator& y) BOOST_NOEXCEPT - { return x.n >= y.n; } - - // distance - BOOST_CONTAINER_FORCEINLINE - friend difference_type operator-(const nest_local_iterator& x, const nest_local_iterator& y) BOOST_NOEXCEPT - { - BOOST_CONTAINER_ASSUME(x.pbb == y.pbb); -#if 0 //Supporting negative difference would require additional checks - const mask_type m = x.pbb->mask; - const mask_type lo_x = (x.n == int(N)) ? full : ((mask_type(1) << x.n) - 1); - const mask_type lo_y = (y.n == int(N)) ? full : ((mask_type(1) << y.n) - 1); - return difference_type(boost::core::popcount(m & lo_x)) - - difference_type(boost::core::popcount(m & lo_y)); - #endif - const mask_type lo_x = (x.n == int(N)) ? full : ((mask_type(1) << x.n) - 1); - const mask_type lo_y = (y.n == int(N)) ? full : ((mask_type(1) << y.n) - 1); - const mask_type m = x.pbb->mask; - return boost::core::popcount(m & lo_x & (~lo_y)); - } - - BOOST_CONTAINER_FORCEINLINE block_base_pointer get_block() const BOOST_NOEXCEPT { return pbb; } - BOOST_CONTAINER_FORCEINLINE int get_slot() const BOOST_NOEXCEPT { return n; } - -private: - block_base_pointer pbb; - int n; -}; - -#else - -template -class nest_local_iterator -{ - typedef typename boost::intrusive::pointer_traits::element_type element_type; - - typedef typename nest_detail::pointer_rebind::type void_pointer; - typedef nest_detail::block_base block_base_type; - typedef typename nest_detail::pointer_rebind::type>::type nonconst_pointer; - typedef nest_detail::block block_type; - typedef typename block_base_type::mask_type mask_type; - - BOOST_STATIC_CONSTEXPR std::size_t N = block_base_type::N; - BOOST_STATIC_CONSTEXPR mask_type full = block_base_type::full; - BOOST_STATIC_CONSTEXPR mask_type full_l = (full << 1); - -public: - typedef typename dtl::remove_const::type value_type; - typedef typename boost::intrusive::pointer_traits::difference_type difference_type; - typedef ValuePointer pointer; - typedef element_type& reference; - typedef std::random_access_iterator_tag iterator_category; - - typedef typename nest_detail::pointer_rebind::type block_base_pointer; - - nest_local_iterator() BOOST_NOEXCEPT - : pos() - {} - - nest_local_iterator(block_base_pointer pbb_, int n_) BOOST_NOEXCEPT - : pos(static_cast(*pbb_).data()+n_), n(n_), mask(pbb_->mask) - {} - - BOOST_CONTAINER_FORCEINLINE reference operator*() const BOOST_NOEXCEPT - { return *pos; } - - BOOST_CONTAINER_FORCEINLINE pointer operator->() const BOOST_NOEXCEPT - { return pos; } - - BOOST_CONTAINER_FORCEINLINE nest_local_iterator& operator++() BOOST_NOEXCEPT - { - BOOST_CONTAINER_ASSUME(n != (int)N); - const mask_type m = mask & (full_l << n); - const int old_n = n; - n = m ? nest_detail::first_in_mask(m) : (int)N; - pos += (n - old_n); - return *this; - } - - BOOST_CONTAINER_FORCEINLINE nest_local_iterator operator++(int) BOOST_NOEXCEPT - { nest_local_iterator tmp(*this); ++*this; return tmp; } - - BOOST_CONTAINER_FORCEINLINE nest_local_iterator& operator--() BOOST_NOEXCEPT - { - BOOST_CONTAINER_ASSUME(n != 0); - const mask_type m = mask & (full >> (N - n)); - const int old_n = n; - n = nest_detail::last_in_mask(m); - pos -= (old_n - n); - return *this; - } - - BOOST_CONTAINER_FORCEINLINE nest_local_iterator operator--(int) BOOST_NOEXCEPT - { nest_local_iterator tmp(*this); --*this; return tmp; } - - // random-access: advance by k occupied slots - BOOST_CONTAINER_FORCEINLINE nest_local_iterator& operator+=(difference_type k) BOOST_NOEXCEPT - { - const mask_type m = mask; - const mask_type lo = (n == int(N)) ? full : ((mask_type(1) << n) - 1); - const int idx = (int)boost::core::popcount(m & lo); - const int target = idx + (int)k; - const int total = (int)boost::core::popcount(m); - BOOST_CONTAINER_ASSUME(target >= 0 && target <= total); - const int old_n = n; - n = (target >= total) ? (int)N : nest_detail::nth_set_bit(m, target); - pos += (n - old_n); - return *this; - } - - BOOST_CONTAINER_FORCEINLINE nest_local_iterator& operator-=(difference_type k) BOOST_NOEXCEPT - { return *this += (-k); } - - BOOST_CONTAINER_FORCEINLINE - friend nest_local_iterator operator+(nest_local_iterator it, difference_type k) BOOST_NOEXCEPT - { it += k; return it; } - - BOOST_CONTAINER_FORCEINLINE - friend nest_local_iterator operator+(difference_type k, nest_local_iterator it) BOOST_NOEXCEPT - { it += k; return it; } - - BOOST_CONTAINER_FORCEINLINE - friend nest_local_iterator operator-(nest_local_iterator it, difference_type k) BOOST_NOEXCEPT - { it -= k; return it; } - - BOOST_CONTAINER_FORCEINLINE reference operator[](difference_type k) const BOOST_NOEXCEPT - { return *(*this + k); } - - // equality - BOOST_CONTAINER_FORCEINLINE - friend bool operator==(const nest_local_iterator& x, const nest_local_iterator& y) BOOST_NOEXCEPT - { return x.n == y.n; } - - BOOST_CONTAINER_FORCEINLINE - friend bool operator!=(const nest_local_iterator& x, const nest_local_iterator& y) BOOST_NOEXCEPT - { return x.n != y.n; } - - // ordering - BOOST_CONTAINER_FORCEINLINE - friend bool operator<(const nest_local_iterator& x, const nest_local_iterator& y) BOOST_NOEXCEPT - { return x.n < y.n; } - - BOOST_CONTAINER_FORCEINLINE - friend bool operator>(const nest_local_iterator& x, const nest_local_iterator& y) BOOST_NOEXCEPT - { return x.n > y.n; } - - BOOST_CONTAINER_FORCEINLINE - friend bool operator<=(const nest_local_iterator& x, const nest_local_iterator& y) BOOST_NOEXCEPT - { return x.n <= y.n; } - - BOOST_CONTAINER_FORCEINLINE - friend bool operator>=(const nest_local_iterator& x, const nest_local_iterator& y) BOOST_NOEXCEPT - { return x.n >= y.n; } - - // distance - BOOST_CONTAINER_FORCEINLINE - friend difference_type operator-(const nest_local_iterator& x, const nest_local_iterator& y) BOOST_NOEXCEPT - { - BOOST_CONTAINER_ASSUME(x.mask == y.mask); - #if 0 - const mask_type m = x.mask; - const mask_type lo_x = (x.n == int(N)) ? full : ((mask_type(1) << x.n) - 1); - const mask_type lo_y = (y.n == int(N)) ? full : ((mask_type(1) << y.n) - 1); - return difference_type(boost::core::popcount(m & lo_x)) - - difference_type(boost::core::popcount(m & lo_y)); - #endif - BOOST_CONTAINER_ASSUME(x.n >= y.n); // Undefined behavior otherwise - const mask_type m = x.mask; - const mask_type lo_x = (x.n == int(N)) ? full : ((mask_type(1) << x.n) - 1); - const mask_type lo_y = (y.n == int(N)) ? full : ((mask_type(1) << y.n) - 1); - return boost::core::popcount(m & lo_x & (~lo_y)); - } - - //BOOST_CONTAINER_FORCEINLINE block_base_pointer get_block() const BOOST_NOEXCEPT { return pbb; } - BOOST_CONTAINER_FORCEINLINE int get_slot() const BOOST_NOEXCEPT { return n; } - -private: - pointer pos; - int n; - mask_type mask; -}; - -#endif //defined(NEST_LOCAL_ITERATOR_FULL) - -////////////////////////////////////////////// -// -// nest_segment_iterator -// -////////////////////////////////////////////// - -template -class nest_segment_iterator -{ - typedef typename nest_detail::pointer_rebind::type void_pointer; - typedef nest_detail::block_base block_base_type; - -public: - typedef void value_type; - typedef std::ptrdiff_t difference_type; - typedef void pointer; - typedef void reference; - typedef std::bidirectional_iterator_tag iterator_category; - - typedef typename nest_detail::pointer_rebind::type block_base_pointer; - - nest_segment_iterator() BOOST_NOEXCEPT - : pbb() - {} - - explicit nest_segment_iterator(block_base_pointer pbb_) BOOST_NOEXCEPT - : pbb(pbb_) - {} - - BOOST_CONTAINER_FORCEINLINE nest_segment_iterator& operator++() BOOST_NOEXCEPT - { pbb = pbb->next; return *this; } - - BOOST_CONTAINER_FORCEINLINE nest_segment_iterator operator++(int) BOOST_NOEXCEPT - { nest_segment_iterator tmp(*this); ++*this; return tmp; } - - BOOST_CONTAINER_FORCEINLINE nest_segment_iterator& operator--() BOOST_NOEXCEPT - { pbb = pbb->prev; return *this; } - - BOOST_CONTAINER_FORCEINLINE nest_segment_iterator operator--(int) BOOST_NOEXCEPT - { nest_segment_iterator tmp(*this); --*this; return tmp; } - - BOOST_CONTAINER_FORCEINLINE friend bool operator==( - const nest_segment_iterator& x, const nest_segment_iterator& y) BOOST_NOEXCEPT - { return x.pbb == y.pbb; } - - BOOST_CONTAINER_FORCEINLINE friend bool operator!=( - const nest_segment_iterator& x, const nest_segment_iterator& y) BOOST_NOEXCEPT - { return !(x == y); } - - BOOST_CONTAINER_FORCEINLINE block_base_pointer get_block() const BOOST_NOEXCEPT { return pbb; } - -private: - block_base_pointer pbb; -}; - namespace nest_detail { ////////////////////////////////////////////// @@ -1565,71 +1106,6 @@ struct ref_predicate_adaptor } // namespace nest_detail -//////////////////////////////////////////////////////////////////////////// -// -// Specialization of segmented_iterator_traits for nest::iterator -// -//////////////////////////////////////////////////////////////////////////// - -template -struct segmented_iterator_traits - < nest_iterator > -{ - typedef segmented_iterator_tag is_segmented_iterator; - typedef nest_iterator nest_iterator_type; - typedef nest_local_iterator local_iterator; - typedef nest_segment_iterator segment_iterator; - -private: - - typedef typename boost::intrusive::pointer_traits - ::element_type element_type; - typedef typename dtl::remove_const::type value_type; - - typedef typename nest_detail::pointer_rebind::type void_pointer; - typedef nest_detail::block_base block_base_type; - typedef typename nest_detail::pointer_rebind - ::type nonconst_pointer; - typedef nest_detail::block block_type; - typedef typename block_base_type::mask_type mask_type; - - BOOST_STATIC_CONSTEXPR std::size_t N = block_base_type::N; - - public: - - BOOST_CONTAINER_FORCEINLINE static segment_iterator segment(const nest_iterator_type &it) - { return segment_iterator(it.pbb); } - - BOOST_CONTAINER_FORCEINLINE static local_iterator local(const nest_iterator_type &it) - { return local_iterator(it.pbb, it.n); } - - BOOST_CONTAINER_FORCEINLINE static nest_iterator_type compose(segment_iterator s, const local_iterator& l) - { - int n = l.get_slot(); - if (BOOST_UNLIKELY(n == N)) { - ++s; - n = 0; - } - return nest_iterator_type(s.get_block(), n); - } - - BOOST_CONTAINER_FORCEINLINE static local_iterator begin(const segment_iterator &s) - { - typedef typename segment_iterator::block_base_pointer block_base_pointer; - block_base_pointer const bp = s.get_block(); - const mask_type m = bp->mask; - const int n = nest_detail::first_in_mask(m); - //Prefetch the eact line the - //returned local_iterator will dereference first instead of the - //unconditional slot-0 line. - BOOST_CONTAINER_NEST_PREFETCH_BLOCK_NTH(bp, n); - return local_iterator(bp, n); - } - - BOOST_CONTAINER_FORCEINLINE static local_iterator end(const segment_iterator &s) - { return local_iterator(s.get_block(), int(N)); } -}; - #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED template diff --git a/test/nest_test.cpp b/test/nest_test.cpp index 65ca4f3..6a6cedb 100644 --- a/test/nest_test.cpp +++ b/test/nest_test.cpp @@ -717,344 +717,6 @@ void test_initializer_list_operations() } #endif -void test_segment_iterator_operations() -{ - typedef nest nest_t; - typedef nest_t::iterator iterator; - typedef segmented_iterator_traits traits; - typedef traits::segment_iterator segment_iterator; - typedef traits::local_iterator local_iterator; - - nest_t h; - for (int i = 0; i < 200; ++i) - h.insert(i); - - segment_iterator seg_begin = traits::segment(h.begin()); - segment_iterator seg_end = traits::segment(h.end()); - - // Default construction compiles - { - segment_iterator s; - (void)s; - } - - // segment() + equality / inequality - { - segment_iterator s1 = traits::segment(h.begin()); - segment_iterator s2 = traits::segment(h.begin()); - BOOST_TEST(s1 == s2); - BOOST_TEST(!(s1 != s2)); - BOOST_TEST(s1 != seg_end); - BOOST_TEST(!(s1 == seg_end)); - } - - // Pre-increment returns reference to self and advances - { - segment_iterator s = seg_begin; - segment_iterator& ref = ++s; - BOOST_TEST(&ref == &s); - BOOST_TEST(s != seg_begin); - BOOST_TEST(s != seg_end); - } - - // Post-increment returns old value and advances - { - segment_iterator s = seg_begin; - segment_iterator old = s++; - BOOST_TEST(old == seg_begin); - segment_iterator expected = seg_begin; - ++expected; - BOOST_TEST(s == expected); - } - - // Pre-decrement returns reference to self and retreats - { - segment_iterator s = seg_begin; - ++s; - segment_iterator& ref = --s; - BOOST_TEST(&ref == &s); - BOOST_TEST(s == seg_begin); - } - - // Post-decrement returns old value and retreats - { - segment_iterator second = seg_begin; - ++second; - segment_iterator old = second--; - BOOST_TEST(second == seg_begin); - segment_iterator expected = seg_begin; - ++expected; - BOOST_TEST(old == expected); - } - - // Increment then decrement is identity - { - segment_iterator s = seg_begin; - ++s; ++s; - --s; --s; - BOOST_TEST(s == seg_begin); - } - - // Count segments (200 elements, 64 per block => at least 4 segments) - { - int num_segments = 0; - for (segment_iterator s = seg_begin; s != seg_end; ++s) - ++num_segments; - BOOST_TEST(num_segments >= 4); - } - - // Full segmented traversal yields all elements - { - int count = 0; - segment_iterator s = seg_begin; - local_iterator loc = traits::local(h.begin()); - while (s != seg_end) { - local_iterator loc_end = traits::end(s); - for (; loc != loc_end; ++loc) - ++count; - ++s; - if (s != seg_end) - loc = traits::begin(s); - } - BOOST_TEST_EQ(count, 200); - } - - // Reverse traversal over segments - { - int fwd_count = 0; - for (segment_iterator s = seg_begin; s != seg_end; ++s) - ++fwd_count; - - segment_iterator s = seg_end; - int rev_count = 0; - while (s != seg_begin) { - --s; - ++rev_count; - } - BOOST_TEST_EQ(fwd_count, rev_count); - } - -} - -void test_local_iterator_operations() -{ - typedef nest nest_t; - typedef nest_t::iterator iterator; - typedef segmented_iterator_traits traits; - typedef traits::segment_iterator segment_iterator; - typedef traits::local_iterator local_iterator; - - // ---- Dense case (no gaps in bitmask) ---- - nest_t h; - for (int i = 0; i < 200; ++i) - h.insert(i); - - segment_iterator seg = traits::segment(h.begin()); - - // Default construction compiles - { - local_iterator l; - (void)l; - } - - // begin() / end() of a segment - { - local_iterator b = traits::begin(seg); - local_iterator e = traits::end(seg); - BOOST_TEST(b != e); - } - - // operator* dereference - { - local_iterator b = traits::begin(seg); - int val = *b; - (void)val; - } - - // operator-> returns valid pointer - { - local_iterator b = traits::begin(seg); - BOOST_TEST(b.operator->() != 0); - BOOST_TEST_EQ(*b.operator->(), *b); - } - - // Equality / inequality - { - local_iterator b1 = traits::begin(seg); - local_iterator b2 = traits::begin(seg); - local_iterator e = traits::end(seg); - BOOST_TEST(b1 == b2); - BOOST_TEST(!(b1 != b2)); - BOOST_TEST(b1 != e); - BOOST_TEST(!(b1 == e)); - } - - // Pre-increment returns reference to self and advances - { - local_iterator b = traits::begin(seg); - local_iterator orig = b; - local_iterator& ref = ++b; - BOOST_TEST(&ref == &b); - BOOST_TEST(b != orig); - } - - // Post-increment returns old value - { - local_iterator b = traits::begin(seg); - local_iterator old = b++; - BOOST_TEST(old == traits::begin(seg)); - local_iterator expected = traits::begin(seg); - ++expected; - BOOST_TEST(b == expected); - } - - // Pre-decrement returns reference to self and retreats - { - local_iterator b = traits::begin(seg); - local_iterator second = b; - ++second; - local_iterator& ref = --second; - BOOST_TEST(&ref == &second); - BOOST_TEST(second == b); - } - - // Post-decrement returns old value - { - local_iterator b = traits::begin(seg); - local_iterator second = b; - ++second; - local_iterator old = second--; - BOOST_TEST(second == b); - local_iterator expected = b; - ++expected; - BOOST_TEST(old == expected); - } - - // Increment then decrement is identity - { - local_iterator b = traits::begin(seg); - ++b; ++b; ++b; - --b; --b; --b; - BOOST_TEST(b == traits::begin(seg)); - } - - // operator- (distance) on a dense (fully packed) block - { - local_iterator b = traits::begin(seg); - local_iterator e = traits::end(seg); - - int count = 0; - for (local_iterator tmp = b; tmp != e; ++tmp) - ++count; - - BOOST_TEST_EQ(e - b, count); - BOOST_TEST_EQ(b - b, 0); - BOOST_TEST_EQ(e - e, 0); - - local_iterator second = b; - ++second; - BOOST_TEST_EQ(second - b, 1); - } - - // operator- at intermediate positions - { - local_iterator b = traits::begin(seg); - local_iterator it = b; - for (int i = 0; i < 5; ++i) ++it; - BOOST_TEST_EQ(it - b, 5); - } - - // compose() round-trip: compose(segment(it), local(it)) == it - { - iterator it = h.begin(); - segment_iterator s = traits::segment(it); - local_iterator l = traits::local(it); - iterator composed = traits::compose(s, l); - BOOST_TEST(composed == it); - BOOST_TEST_EQ(*composed, *it); - } - - // compose() round-trip after advancing the nest iterator - { - iterator it = h.begin(); - ++it; ++it; ++it; - segment_iterator s = traits::segment(it); - local_iterator l = traits::local(it); - iterator composed = traits::compose(s, l); - BOOST_TEST(composed == it); - BOOST_TEST_EQ(*composed, *it); - } - - // local() gives an iterator that dereferences to the same value - { - iterator it = h.begin(); - local_iterator l = traits::local(it); - BOOST_TEST_EQ(*l, *it); - } - - // begin(seg) matches local(compose(seg, begin(seg))) - { - local_iterator b = traits::begin(seg); - iterator it = traits::compose(seg, b); - local_iterator l = traits::local(it); - BOOST_TEST(l == b); - } - - // ---- Sparse case (gaps in bitmask after erasures) ---- - { - nest_t h2; - for (int i = 0; i < 128; ++i) - h2.insert(i); - - int remaining = 128; - int erase_idx = 0; - for (iterator it = h2.begin(); it != h2.end(); ) { - if (erase_idx % 3 == 0) { - it = h2.erase(it); - --remaining; - } else { - ++it; - } - ++erase_idx; - } - BOOST_TEST_EQ(h2.size(), (nest_t::size_type)remaining); - - segment_iterator s = traits::segment(h2.begin()); - segment_iterator s_end = traits::segment(h2.end()); - - int total_count = 0; - local_iterator loc = traits::local(h2.begin()); - while (s != s_end) { - local_iterator lb = traits::begin(s); - local_iterator le = traits::end(s); - - int seg_count = 0; - for (local_iterator tmp = lb; tmp != le; ++tmp) - ++seg_count; - - // operator- must match the manual count - BOOST_TEST_EQ(le - lb, seg_count); - BOOST_TEST_EQ(lb - lb, 0); - - // Intermediate distances - if (seg_count >= 4) { - local_iterator mid = lb; - ++mid; ++mid; ++mid; - BOOST_TEST_EQ(mid - lb, 3); - BOOST_TEST_EQ(le - mid, seg_count - 3); - } - - for (; loc != le; ++loc) - ++total_count; - - ++s; - if (s != s_end) - loc = traits::begin(s); - } - BOOST_TEST_EQ(total_count, remaining); - } -} - int main() { test_default_construction(); @@ -1106,7 +768,5 @@ int main() #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) test_initializer_list_operations(); #endif - test_segment_iterator_operations(); - test_local_iterator_operations(); return boost::report_errors(); }