From 6d935f243e884ff3ecf143a648b154c33b4e0cbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Sun, 29 Mar 2026 15:41:18 +0200 Subject: [PATCH] Unroll segmented_generate --- .../experimental/segmented_generate.hpp | 54 +++++++++++++++---- 1 file changed, 45 insertions(+), 9 deletions(-) diff --git a/include/boost/container/experimental/segmented_generate.hpp b/include/boost/container/experimental/segmented_generate.hpp index da05b9a..710640c 100644 --- a/include/boost/container/experimental/segmented_generate.hpp +++ b/include/boost/container/experimental/segmented_generate.hpp @@ -21,6 +21,7 @@ #include #include #include +#include namespace boost { namespace container { @@ -30,18 +31,52 @@ void segmented_generate(FwdIt first, Sent last, Generator gen); namespace detail_algo { -template +#if defined(BOOST_CONTAINER_SEGMENTED_LOOP_UNROLLING) + +template +void segmented_generate_dispatch + (RAIter first, RAIter last, Generator &gen, 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)) { + *first = gen(); ++first; + *first = gen(); ++first; + *first = gen(); ++first; + *first = gen(); ++first; + n -= 4; + } + + switch (n % 4) { + case 3: + *first = gen(); ++first; + BOOST_FALLTHROUGH; + case 2: + *first = gen(); ++first; + BOOST_FALLTHROUGH; + case 1: + *first = gen(); ++first; + BOOST_FALLTHROUGH; + default: + break; + } +} + +#endif //BOOST_CONTAINER_SEGMENTED_LOOP_UNROLLING + +template BOOST_CONTAINER_FORCEINLINE typename algo_enable_if_c< !Tag::value || is_sentinel::value>::type -segmented_generate_dispatch(FwdIt first, Sent last, Generator &gen, Tag) +segmented_generate_dispatch(FwdIt first, Sent last, Generator &gen, Tag, Cat) { for(; first != last; ++first) *first = gen(); } -template +template void segmented_generate_dispatch - (SegIter first, SegIter last, Generator &gen, segmented_iterator_tag) + (SegIter first, SegIter last, Generator &gen, segmented_iterator_tag, Cat) { typedef segmented_iterator_traits traits; typedef typename traits::local_iterator local_iterator; @@ -52,15 +87,15 @@ void segmented_generate_dispatch segment_iterator slast = traits::segment(last); if(sfirst == slast) { - (segmented_generate_dispatch)(traits::local(first), traits::local(last), gen, is_local_seg_t()); + (segmented_generate_dispatch)(traits::local(first), traits::local(last), gen, is_local_seg_t(), Cat()); } else { - (segmented_generate_dispatch)(traits::local(first), traits::end(sfirst), gen, is_local_seg_t()); + (segmented_generate_dispatch)(traits::local(first), traits::end(sfirst), gen, is_local_seg_t(), Cat()); for(++sfirst; sfirst != slast; ++sfirst) - (segmented_generate_dispatch)(traits::begin(sfirst), traits::end(sfirst), gen, is_local_seg_t()); + (segmented_generate_dispatch)(traits::begin(sfirst), traits::end(sfirst), gen, is_local_seg_t(), Cat()); - (segmented_generate_dispatch)(traits::begin(sfirst), traits::local(last), gen, is_local_seg_t()); + (segmented_generate_dispatch)(traits::begin(sfirst), traits::local(last), gen, is_local_seg_t(), Cat()); } } @@ -74,7 +109,8 @@ BOOST_CONTAINER_FORCEINLINE void segmented_generate(FwdIt first, Sent last, Generator gen) { typedef segmented_iterator_traits traits; - detail_algo::segmented_generate_dispatch(first, last, gen, typename traits::is_segmented_iterator()); + detail_algo::segmented_generate_dispatch + (first, last, gen, typename traits::is_segmented_iterator(), typename iterator_traits::iterator_category()); } } // namespace container