From 02d00901779cc1ae2d75de96ce32053440bfe0b4 Mon Sep 17 00:00:00 2001 From: Patrick Roberts Date: Mon, 1 Jun 2026 12:28:57 -0500 Subject: [PATCH] Apply fusion optimization to input iterator --- include/beman/any_view/any_view.hpp | 16 ------- include/beman/any_view/detail/iterator.hpp | 4 +- .../any_view/detail/polymorphic_iterator.hpp | 43 +++++++++++-------- tests/beman/any_view/constexpr.test.cpp | 16 +++++-- 4 files changed, 41 insertions(+), 38 deletions(-) diff --git a/include/beman/any_view/any_view.hpp b/include/beman/any_view/any_view.hpp index 435cf83..a6e5bd1 100644 --- a/include/beman/any_view/any_view.hpp +++ b/include/beman/any_view/any_view.hpp @@ -8,22 +8,6 @@ #include namespace beman::any_view { -namespace detail { - -template -struct rvalue_ref { - using type = T; -}; - -template -struct rvalue_ref { - using type = T&&; -}; - -template -using rvalue_ref_t = typename rvalue_ref::type; - -} // namespace detail template , std::i static constexpr bool random_access = flag_is_set; static constexpr bool contiguous = flag_is_set; - // do not cache an iterator reference without multi-pass guarantee - using cache_type = std::conditional_t, no_cache>; + using cache_type = + std::conditional_t, RValueRefT>, iter_cache_t, no_cache>; using polymorphic_type = polymorphic_iterator; static constexpr bool has_cache = not std::is_same_v; diff --git a/include/beman/any_view/detail/polymorphic_iterator.hpp b/include/beman/any_view/detail/polymorphic_iterator.hpp index 8ee76a7..8cc7839 100644 --- a/include/beman/any_view/detail/polymorphic_iterator.hpp +++ b/include/beman/any_view/detail/polymorphic_iterator.hpp @@ -227,29 +227,38 @@ struct subtract_t : symmetric_binary_protocol { // inplace storage sufficient for two pointers using iterator_storage = small_storage<2 * sizeof(void*)>; -template -struct input_protocol : inherit, - destroy_t, - dereference_t, - iter_move_t, - increment_t, - sentinel_compare_t> {}; - template concept has_cache = not std::same_as, no_cache>; -template -struct forward_cache_protocol : inherit<> {}; +template +struct rvalue_ref { + using type = T; +}; -template -struct forward_cache_protocol : inherit, next_t> {}; +template +struct rvalue_ref { + using type = T&&; +}; + +template +using rvalue_ref_t = typename rvalue_ref::type; + +template +struct input_cache_protocol : inherit, iter_move_t, increment_t> {}; + +template + requires convertible_to_borrowed, RValueRefT> +struct input_cache_protocol : inherit, next_t> {}; + +template +struct input_protocol : inherit, + destroy_t, + input_cache_protocol, + sentinel_compare_t> {}; template -struct forward_protocol : inherit, - copy_t, - forward_cache_protocol, - type_t, - equality_compare_t> {}; +struct forward_protocol + : inherit, copy_t, type_t, equality_compare_t> {}; template struct bidirectional_cache_protocol : inherit {}; diff --git a/tests/beman/any_view/constexpr.test.cpp b/tests/beman/any_view/constexpr.test.cpp index 2bae2d0..be70b4a 100644 --- a/tests/beman/any_view/constexpr.test.cpp +++ b/tests/beman/any_view/constexpr.test.cpp @@ -65,10 +65,20 @@ TEST(ConstexprTest, sort_vector) { EXPECT_TRUE(sort(std::vector{6, 8, 7, 5, 3, 0, 9})); } +template +struct non_trivially_copyable { + T value; + + non_trivially_copyable(const non_trivially_copyable&); +}; + +template +non_trivially_copyable::non_trivially_copyable(const non_trivially_copyable&) = default; + constexpr auto set_front(any_view view, int value) { - // forward iterator of lvalue reference uses cache object to fuse virtual dispatches - static_assert(sizeof(std::ranges::iterator_t>) == - sizeof(std::ranges::iterator_t>) + sizeof(int*)); + // lvalue reference uses cache object to fuse virtual dispatches + static_assert(sizeof(std::ranges::iterator_t>) == + sizeof(std::ranges::iterator_t>>) + sizeof(int*)); auto& ref = view.front(); // even with cache object, lifetime of reference is not tied to lifetime of iterator