From 704a6dbe33b094c0639aacadc81be8fa43d20bc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Sun, 29 Mar 2026 19:07:08 +0200 Subject: [PATCH] Unroll segmented_transform --- .../experimental/segmented_transform.hpp | 54 +++++++++++++++---- 1 file changed, 45 insertions(+), 9 deletions(-) diff --git a/include/boost/container/experimental/segmented_transform.hpp b/include/boost/container/experimental/segmented_transform.hpp index ab441cc..ba44646 100644 --- a/include/boost/container/experimental/segmented_transform.hpp +++ b/include/boost/container/experimental/segmented_transform.hpp @@ -21,6 +21,7 @@ #include #include #include +#include namespace boost { namespace container { @@ -30,21 +31,56 @@ OutIter segmented_transform(InIter first, Sent last, OutIter result, UnaryOp op) namespace detail_algo { +#if defined(BOOST_CONTAINER_SEGMENTED_LOOP_UNROLLING) -template +template +OutIter segmented_transform_dispatch + (InIter first, InIter last, OutIter result, UnaryOp op, const non_segmented_iterator_tag &, const std::random_access_iterator_tag &) +{ + typedef typename iterator_traits::difference_type difference_type; + difference_type n = last - first; + + while(n >= difference_type(4)) { + *result = op(*first); ++first; ++result; + *result = op(*first); ++first; ++result; + *result = op(*first); ++first; ++result; + *result = op(*first); ++first; ++result; + n -= 4; + } + + switch (n % 4) { + case 3: + *result = op(*first); ++first; ++result; + BOOST_FALLTHROUGH; + case 2: + *result = op(*first); ++first; ++result; + BOOST_FALLTHROUGH; + case 1: + *result = op(*first); ++first; ++result; + BOOST_FALLTHROUGH; + default: + break; + } + return result; +} + +#endif //BOOST_CONTAINER_SEGMENTED_LOOP_UNROLLING + + +template typename algo_enable_if_c< !Tag::value || is_sentinel::value, OutIter>::type segmented_transform_dispatch - (InIter first, Sent last, OutIter result, UnaryOp op, Tag) + (InIter first, Sent last, OutIter result, UnaryOp op, Tag, Cat) { for(; first != last; ++first, ++result) *result = op(*first); return result; } -template +template OutIter segmented_transform_dispatch - (SegIter first, SegIter last, OutIter result, UnaryOp op, segmented_iterator_tag) + (SegIter first, SegIter last, OutIter result, UnaryOp op, segmented_iterator_tag, Cat) { typedef segmented_iterator_traits traits; typedef typename traits::local_iterator local_iterator; @@ -56,15 +92,15 @@ OutIter segmented_transform_dispatch segment_iterator const slast = traits::segment(last); if(sfirst == slast) { - return (segmented_transform_dispatch)(traits::local(first), traits::local(last), result, op, is_local_seg_t()); + return (segmented_transform_dispatch)(traits::local(first), traits::local(last), result, op, is_local_seg_t(), Cat()); } else { - result = (segmented_transform_dispatch)(traits::local(first), traits::end(sfirst), result, op, is_local_seg_t()); + result = (segmented_transform_dispatch)(traits::local(first), traits::end(sfirst), result, op, is_local_seg_t(), Cat()); for(++sfirst; sfirst != slast; ++sfirst) - result = (segmented_transform_dispatch)(traits::begin(sfirst), traits::end(sfirst), result, op, is_local_seg_t()); + result = (segmented_transform_dispatch)(traits::begin(sfirst), traits::end(sfirst), result, op, is_local_seg_t(), Cat()); - return (segmented_transform_dispatch)(traits::begin(sfirst), traits::local(last), result, op, is_local_seg_t()); + return (segmented_transform_dispatch)(traits::begin(sfirst), traits::local(last), result, op, is_local_seg_t(), Cat()); } } @@ -79,7 +115,7 @@ OutIter segmented_transform (InIter first, Sent last, OutIter result, UnaryOp op { typedef segmented_iterator_traits traits; return detail_algo::segmented_transform_dispatch - (first, last, result, op, typename traits::is_segmented_iterator()); + (first, last, result, op, typename traits::is_segmented_iterator(), typename iterator_traits::iterator_category()); } } // namespace container