Refactor segmented_copy_if_dispatch to avoid too many intermediate functions

This commit is contained in:
Ion Gaztañaga
2026-03-16 16:12:56 +01:00
parent f5032dad86
commit d026a2431a
@@ -30,25 +30,6 @@ OutIter segmented_copy_if(InIter first, Sent last, OutIter result, Pred pred);
namespace detail_algo {
template <class SegIter, class OutIter, class Pred>
OutIter segmented_copy_if_dispatch
(SegIter first, SegIter last, OutIter result, Pred pred, segmented_iterator_tag)
{
typedef segmented_iterator_traits<SegIter> traits;
typename traits::segment_iterator sfirst = traits::segment(first);
typename traits::segment_iterator slast = traits::segment(last);
if(sfirst == slast) {
result = boost::container::segmented_copy_if(traits::local(first), traits::local(last), result, pred);
}
else {
result = boost::container::segmented_copy_if(traits::local(first), traits::end(sfirst), result, pred);
for(++sfirst; sfirst != slast; ++sfirst)
result = boost::container::segmented_copy_if(traits::begin(sfirst), traits::end(sfirst), result, pred);
result = boost::container::segmented_copy_if(traits::begin(sfirst), traits::local(last), result, pred);
}
return result;
}
template <class InIter, class Sent, class OutIter, class Pred, class Tag>
typename algo_enable_if_c<
!Tag::value || is_sentinel<Sent, InIter>::value, OutIter>::type
@@ -63,12 +44,36 @@ segmented_copy_if_dispatch
return result;
}
template <class SegIter, class OutIter, class Pred>
OutIter segmented_copy_if_dispatch
(SegIter first, SegIter last, OutIter result, Pred pred, segmented_iterator_tag)
{
typedef segmented_iterator_traits<SegIter> traits;
typedef typename traits::local_iterator local_iterator;
typedef typename traits::segment_iterator segment_iterator;
typedef typename segmented_iterator_traits<local_iterator>::is_segmented_iterator is_local_seg_t;
segment_iterator sfirst = traits::segment(first);
segment_iterator slast = traits::segment(last);
if(sfirst == slast) {
result = (segmented_copy_if_dispatch)(traits::local(first), traits::local(last), result, pred, is_local_seg_t());
}
else {
result = (segmented_copy_if_dispatch)(traits::local(first), traits::end(sfirst), result, pred, is_local_seg_t());
for(++sfirst; sfirst != slast; ++sfirst)
result = (segmented_copy_if_dispatch)(traits::begin(sfirst), traits::end(sfirst), result, pred, is_local_seg_t());
result = (segmented_copy_if_dispatch)(traits::begin(sfirst), traits::local(last), result, pred, is_local_seg_t());
}
return result;
}
} // namespace detail_algo
//! Copies elements satisfying \c pred from [first, last) to the range
//! beginning at \c result. Segmentation is exploited on the input range.
template <class InIter, class Sent, class OutIter, class Pred>
inline OutIter segmented_copy_if(InIter first, Sent last, OutIter result, Pred pred)
BOOST_CONTAINER_FORCEINLINE OutIter segmented_copy_if(InIter first, Sent last, OutIter result, Pred pred)
{
typedef segmented_iterator_traits<InIter> traits;
return detail_algo::segmented_copy_if_dispatch(first, last, result, pred,