Skip to content

Commit beb17e2

Browse files
committed
Optimize segmented_copy_if algorithm when the second range is segmented
1 parent f047a33 commit beb17e2

1 file changed

Lines changed: 45 additions & 0 deletions

File tree

include/boost/container/experimental/segmented_copy_if.hpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,51 @@ segmented_copy_if_dst_bounded
120120
return segduo<SrcIter, DstIter>(first, dst_first);
121121
}
122122

123+
template <class RASrcIter, class RADstIter, class Pred>
124+
typename iterator_enable_if_tag
125+
<RADstIter, std::random_access_iterator_tag, segduo<RASrcIter, RADstIter> >::type
126+
segmented_copy_if_dst_bounded
127+
(RASrcIter first, RASrcIter last, RADstIter dst_first, RADstIter dst_last, Pred pred,
128+
const non_segmented_iterator_tag &, const std::random_access_iterator_tag &src_tag)
129+
{
130+
typedef typename iterator_traits<RASrcIter>::difference_type difference_type;
131+
132+
difference_type src_n = last - first;
133+
difference_type dst_n = difference_type(dst_last - dst_first);
134+
135+
(void)src_tag;
136+
RASrcIter cur = first;
137+
RADstIter dst_cur = dst_first;
138+
if(src_n <= dst_n) {
139+
// Whole source fits the remaining destination capacity: lean pass,
140+
// no destination-full check (mirrors the original single-chunk kernel).
141+
BOOST_CONTAINER_SEGMENTED_UNROLL(4)
142+
while(src_n) {
143+
--src_n;
144+
if(pred(*cur)) {
145+
*dst_cur = *cur;
146+
++dst_cur;
147+
}
148+
++cur;
149+
}
150+
}
151+
else {
152+
// Source spans more than the destination segment: single bounded pass,
153+
// check the destination only on a hit -- avoids repeated chunk set-ups.
154+
BOOST_CONTAINER_SEGMENTED_UNROLL(4)
155+
while(cur != last) {
156+
if(pred(*cur)) {
157+
if(dst_cur == dst_last)
158+
break;
159+
*dst_cur = *cur;
160+
++dst_cur;
161+
}
162+
++cur;
163+
}
164+
}
165+
return segduo<RASrcIter, RADstIter>(cur, dst_cur);
166+
}
167+
123168
template <class SrcIter, class Sent, class SegDstIter, class Pred, class SrcCat>
124169
segduo<SrcIter, SegDstIter> segmented_copy_if_dst_bounded
125170
(SrcIter first, Sent last, SegDstIter dst_first, SegDstIter dst_last, Pred pred,

0 commit comments

Comments
 (0)