From 453ce17cabbd6cdab30ef729478830604f91b356 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Mon, 6 Jul 2026 01:08:27 +0200 Subject: [PATCH] Implement optimization for random access iterators in segmented_copy_if: a 32 bit fixed loop is implemented in case there is room for non-checked stores with a final loop --- .../experimental/segmented_copy_if.hpp | 60 +++++++++++-------- 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/include/boost/container/experimental/segmented_copy_if.hpp b/include/boost/container/experimental/segmented_copy_if.hpp index 76a7907..3338561 100644 --- a/include/boost/container/experimental/segmented_copy_if.hpp +++ b/include/boost/container/experimental/segmented_copy_if.hpp @@ -70,39 +70,47 @@ segmented_copy_if_dst_bounded { typedef typename iterator_traits::difference_type difference_type; - difference_type src_n = last - first; - difference_type dst_n = difference_type(dst_last - dst_first); - (void)src_tag; - RASrcIter cur = first; + RASrcIter cur = first; RADstIter dst_cur = dst_first; - if(src_n <= dst_n) { - // Whole source fits the remaining destination capacity: lean pass, - // no destination-full check (mirrors the original single-chunk kernel). - BOOST_CONTAINER_SEGMENTED_UNROLL(4) - while(src_n) { - --src_n; - if(pred(*cur)) { - *dst_cur = *cur; - ++dst_cur; + + const difference_type B = 32; + difference_type avail = last - cur; + for(;;) { + difference_type room = dst_last - dst_cur; + difference_type chunk = room < avail ? room : avail; + if(chunk == 0) + goto end; + if(chunk >= B) { + avail -= B; + chunk = B; + BOOST_CONTAINER_SEGMENTED_AUTO_UNROLL + while(chunk) { + --chunk; + if(pred(*cur)) { + *dst_cur = *cur; + ++dst_cur; + } + ++cur; } - ++cur; + } + else{ + break; } } - else { - // Source spans more than the destination segment: single bounded pass, - // check the destination only on a hit -- avoids repeated chunk set-ups. - BOOST_CONTAINER_SEGMENTED_UNROLL(4) - while(cur != last) { - if(pred(*cur)) { - if(dst_cur == dst_last) - break; - *dst_cur = *cur; - ++dst_cur; - } - ++cur; + + BOOST_CONTAINER_SEGMENTED_UNROLL(4) + while(cur != last) { + if(pred(*cur)) { + if (dst_cur == dst_last) + break; + *dst_cur = *cur; + ++dst_cur; } + ++cur; } + end: + return segduo(cur, dst_cur); }