Fix bug: iterator category was not properly passed in the recursive segmented calls.

This commit is contained in:
Ion Gaztañaga
2026-03-29 23:23:25 +02:00
parent 530b41dad9
commit 40174dec40
12 changed files with 64 additions and 51 deletions
@@ -95,21 +95,22 @@ typename boost::container::iterator_traits<SegIter>::difference_type
typedef typename traits::segment_iterator segment_iterator;
typedef typename traits::local_iterator local_iterator;
typedef typename segmented_iterator_traits<local_iterator>::is_segmented_iterator is_local_seg_t;
typedef typename iterator_traits<local_iterator>::iterator_category local_cat_t;
segment_iterator sfirst = traits::segment(first);
segment_iterator slast = traits::segment(last);
if(sfirst == slast) {
return (segmented_count_if_dispatch)(traits::local(first), traits::local(last), pred, is_local_seg_t(), Cat());
return (segmented_count_if_dispatch)(traits::local(first), traits::local(last), pred, is_local_seg_t(), local_cat_t());
}
else {
typename boost::container::iterator_traits<SegIter>::difference_type result = 0;
result += (segmented_count_if_dispatch)(traits::local(first), traits::end(sfirst), pred, is_local_seg_t(), Cat());
result += (segmented_count_if_dispatch)(traits::local(first), traits::end(sfirst), pred, is_local_seg_t(), local_cat_t());
for(++sfirst; sfirst != slast; ++sfirst)
result += (segmented_count_if_dispatch)(traits::begin(sfirst), traits::end(sfirst), pred, is_local_seg_t(), Cat());
result += (segmented_count_if_dispatch)(traits::begin(sfirst), traits::end(sfirst), pred, is_local_seg_t(), local_cat_t());
return result += (segmented_count_if_dispatch)(traits::begin(sfirst), traits::local(last), pred, is_local_seg_t(), Cat());
return result += (segmented_count_if_dispatch)(traits::begin(sfirst), traits::local(last), pred, is_local_seg_t(), local_cat_t());
}
}
@@ -109,30 +109,31 @@ SegIter segmented_find_if_dispatch
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;
typedef typename iterator_traits<local_iterator>::iterator_category local_cat_t;
segment_iterator sfirst = traits::segment(first);
const segment_iterator slast = traits::segment(last);
if(sfirst == slast) {
return traits::compose(sfirst, (segmented_find_if_dispatch)(traits::local(first), traits::local(last), pred, is_local_seg_t(), Cat()));
return traits::compose(sfirst, (segmented_find_if_dispatch)(traits::local(first), traits::local(last), pred, is_local_seg_t(), local_cat_t()));
}
else {
//First segment
{
const local_iterator le = traits::end(sfirst);
const local_iterator r = (segmented_find_if_dispatch)(traits::local(first), le, pred, is_local_seg_t(), Cat());
const local_iterator r = (segmented_find_if_dispatch)(traits::local(first), le, pred, is_local_seg_t(), local_cat_t());
if (r != le)
return traits::compose(sfirst, r);
}
//Middle segments
for (++sfirst; sfirst != slast; ++sfirst) {
const local_iterator le = traits::end(sfirst);
const local_iterator r = (segmented_find_if_dispatch)(traits::begin(sfirst), le, pred, is_local_seg_t(), Cat());
const local_iterator r = (segmented_find_if_dispatch)(traits::begin(sfirst), le, pred, is_local_seg_t(), local_cat_t());
if (r != le)
return traits::compose(sfirst, r);
}
//Last segment
return traits::compose(slast, (segmented_find_if_dispatch)(traits::begin(slast), traits::local(last), pred, is_local_seg_t(), Cat()));
return traits::compose(slast, (segmented_find_if_dispatch)(traits::begin(slast), traits::local(last), pred, is_local_seg_t(), local_cat_t()));
}
}
@@ -89,18 +89,19 @@ F segmented_for_each_dispatch
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;
typedef typename iterator_traits<local_iterator>::iterator_category local_cat_t;
segment_iterator sfirst = traits::segment(first);
segment_iterator slast = traits::segment(last);
if(sfirst == slast) {
return (segmented_for_each_dispatch)(traits::local(first), traits::local(last), boost::move(f), is_local_seg_t(), Cat());
return (segmented_for_each_dispatch)(traits::local(first), traits::local(last), boost::move(f), is_local_seg_t(), local_cat_t());
}
else {
f = (segmented_for_each_dispatch)(traits::local(first), traits::end(sfirst), boost::move(f), is_local_seg_t(), Cat());
f = (segmented_for_each_dispatch)(traits::local(first), traits::end(sfirst), boost::move(f), is_local_seg_t(), local_cat_t());
for(++sfirst; sfirst != slast; ++sfirst)
f = (segmented_for_each_dispatch)(traits::begin(sfirst), traits::end(sfirst), boost::move(f), is_local_seg_t(), Cat());
return (segmented_for_each_dispatch)(traits::begin(sfirst), traits::local(last), boost::move(f), is_local_seg_t(), Cat());
f = (segmented_for_each_dispatch)(traits::begin(sfirst), traits::end(sfirst), boost::move(f), is_local_seg_t(), local_cat_t());
return (segmented_for_each_dispatch)(traits::begin(sfirst), traits::local(last), boost::move(f), is_local_seg_t(), local_cat_t());
}
}
@@ -85,20 +85,21 @@ void segmented_generate_dispatch
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;
typedef typename iterator_traits<local_iterator>::iterator_category local_cat_t;
segment_iterator sfirst = traits::segment(first);
segment_iterator slast = traits::segment(last);
if(sfirst == slast) {
(segmented_generate_dispatch)(traits::local(first), traits::local(last), gen, is_local_seg_t(), Cat());
(segmented_generate_dispatch)(traits::local(first), traits::local(last), gen, is_local_seg_t(), local_cat_t());
}
else {
(segmented_generate_dispatch)(traits::local(first), traits::end(sfirst), gen, is_local_seg_t(), Cat());
(segmented_generate_dispatch)(traits::local(first), traits::end(sfirst), gen, is_local_seg_t(), local_cat_t());
for(++sfirst; sfirst != slast; ++sfirst)
(segmented_generate_dispatch)(traits::begin(sfirst), traits::end(sfirst), gen, is_local_seg_t(), Cat());
(segmented_generate_dispatch)(traits::begin(sfirst), traits::end(sfirst), gen, is_local_seg_t(), local_cat_t());
(segmented_generate_dispatch)(traits::begin(sfirst), traits::local(last), gen, is_local_seg_t(), Cat());
(segmented_generate_dispatch)(traits::begin(sfirst), traits::local(last), gen, is_local_seg_t(), local_cat_t());
}
}
@@ -122,6 +122,7 @@ std::pair<SegIter, InpIter2> segmented_mismatch_dispatch
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;
typedef typename iterator_traits<local_iterator>::iterator_category local_cat_t;
typedef std::pair<SegIter, InpIter2> return_t;
typedef std::pair<local_iterator, InpIter2> local_return_t;
@@ -130,26 +131,26 @@ std::pair<SegIter, InpIter2> segmented_mismatch_dispatch
segment_iterator const slast = traits::segment(last1);
if(sfirst == slast) {
const local_return_t r = (segmented_mismatch_dispatch)(traits::local(first1), traits::local(last1), first2, pred, is_local_seg_t(), Cat());
const local_return_t r = (segmented_mismatch_dispatch)(traits::local(first1), traits::local(last1), first2, pred, is_local_seg_t(), local_cat_t());
return return_t(traits::compose(sfirst, r.first), r.second);
}
else {
// First segment
local_iterator le = traits::end(sfirst);
local_return_t r = (segmented_mismatch_dispatch)(traits::local(first1), le, first2, pred, is_local_seg_t(), Cat());
local_return_t r = (segmented_mismatch_dispatch)(traits::local(first1), le, first2, pred, is_local_seg_t(), local_cat_t());
if (r.first != le)
return return_t(traits::compose(sfirst, r.first), r.second);
// Middle segments
for (++sfirst; sfirst != slast; ++sfirst) {
le = traits::end(sfirst);
r = (segmented_mismatch_dispatch)(traits::begin(sfirst), le, r.second, pred, is_local_seg_t(), Cat());
r = (segmented_mismatch_dispatch)(traits::begin(sfirst), le, r.second, pred, is_local_seg_t(), local_cat_t());
if (r.first != le)
return return_t(traits::compose(sfirst, r.first), r.second);
}
// Last segment
r = (segmented_mismatch_dispatch)(traits::begin(slast), traits::local(last1), r.second, pred, is_local_seg_t(), Cat());
r = (segmented_mismatch_dispatch)(traits::begin(slast), traits::local(last1), r.second, pred, is_local_seg_t(), local_cat_t());
return return_t(traits::compose(sfirst, r.first), r.second);
}
}
@@ -191,37 +191,39 @@ RAIter partition_scan(RAIter first, RAIter last, Pred pred, non_segmented_iterat
#endif //BOOST_CONTAINER_SEGMENTED_LOOP_UNROLLING
template <class SegIt, class OutIter, class Pred, class Cat>
OutIter partition_scan(SegIt first, SegIt last, OutIter result, Pred pred, segmented_iterator_tag, const Cat & cat)
OutIter partition_scan(SegIt first, SegIt last, OutIter result, Pred pred, segmented_iterator_tag, const Cat &)
{
typedef segmented_iterator_traits<SegIt> 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;
typedef typename iterator_traits<local_iterator>::iterator_category local_cat_t;
segment_iterator scur = traits::segment(first);
segment_iterator slast = traits::segment(last);
local_iterator lcur = traits::local(first);
if(scur == slast) {
return partition_scan(lcur, traits::local(last), result, pred, is_local_seg_t(), cat);
return partition_scan(lcur, traits::local(last), result, pred, is_local_seg_t(), local_cat_t());
}
else {
result = partition_scan(lcur, traits::end(scur), result, pred, is_local_seg_t(), cat);
result = partition_scan(lcur, traits::end(scur), result, pred, is_local_seg_t(), local_cat_t());
for(++scur; scur != slast; ++scur)
result = partition_scan(traits::begin(scur), traits::end(scur), result, pred, is_local_seg_t(), cat);
result = partition_scan(traits::begin(scur), traits::end(scur), result, pred, is_local_seg_t(), local_cat_t());
return partition_scan(traits::begin(scur), traits::local(last), result, pred, is_local_seg_t(), cat);
return partition_scan(traits::begin(scur), traits::local(last), result, pred, is_local_seg_t(), local_cat_t());
}
}
template <class SegIt, class Pred>
SegIt partition_scan(SegIt first, SegIt last, Pred pred, segmented_iterator_tag, const std::bidirectional_iterator_tag& cat)
SegIt partition_scan(SegIt first, SegIt last, Pred pred, segmented_iterator_tag, const std::bidirectional_iterator_tag&)
{
typedef segmented_iterator_traits<SegIt> 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;
typedef typename iterator_traits<local_iterator>::iterator_category local_cat_t;
segment_iterator sf = traits::segment(first);
segment_iterator sl = traits::segment(last);
@@ -273,7 +275,7 @@ SegIt partition_scan(SegIt first, SegIt last, Pred pred, segmented_iterator_tag,
}
same_segment_partition_step:
return traits::compose(sf, partition_scan(f_loc, l_loc, pred, is_local_seg_t(), cat));
return traits::compose(sf, partition_scan(f_loc, l_loc, pred, is_local_seg_t(), local_cat_t()));
}
//////////////////////////////////////////////
@@ -117,22 +117,23 @@ segmented_partition_copy_dispatch
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;
typedef typename iterator_traits<local_iterator>::iterator_category local_cat_t;
typedef std::pair<OutIter1, OutIter2> pair_t;
segment_iterator sfirst = traits::segment(first);
segment_iterator slast = traits::segment(last);
if(sfirst == slast) {
return (segmented_partition_copy_dispatch)(traits::local(first), traits::local(last), out_true, out_false, pred, is_local_seg_t(), Cat());
return (segmented_partition_copy_dispatch)(traits::local(first), traits::local(last), out_true, out_false, pred, is_local_seg_t(), local_cat_t());
}
else {
pair_t p = (segmented_partition_copy_dispatch)(traits::local(first), traits::end(sfirst), out_true, out_false, pred, is_local_seg_t(), Cat());
pair_t p = (segmented_partition_copy_dispatch)(traits::local(first), traits::end(sfirst), out_true, out_false, pred, is_local_seg_t(), local_cat_t());
for(++sfirst; sfirst != slast; ++sfirst) {
p = (segmented_partition_copy_dispatch)(traits::begin(sfirst), traits::end(sfirst), p.first, p.second, pred, is_local_seg_t(), Cat());
p = (segmented_partition_copy_dispatch)(traits::begin(sfirst), traits::end(sfirst), p.first, p.second, pred, is_local_seg_t(), local_cat_t());
}
return (segmented_partition_copy_dispatch)(traits::begin(sfirst), traits::local(last), p.first, p.second, pred, is_local_seg_t(), Cat());
return (segmented_partition_copy_dispatch)(traits::begin(sfirst), traits::local(last), p.first, p.second, pred, is_local_seg_t(), local_cat_t());
}
}
@@ -111,30 +111,31 @@ SegIter segmented_partition_point_dispatch
typedef typename traits::segment_iterator segment_iterator;
typedef typename segmented_iterator_traits
<local_iterator>::is_segmented_iterator is_local_seg_t;
typedef typename iterator_traits<local_iterator>::iterator_category local_cat_t;
segment_iterator scur = traits::segment(first);
segment_iterator const slast = traits::segment(last);
if(scur == slast) {
return traits::compose(scur,
(segmented_partition_point_dispatch)(traits::local(first), traits::local(last), pred, is_local_seg_t(), Cat()));
(segmented_partition_point_dispatch)(traits::local(first), traits::local(last), pred, is_local_seg_t(), local_cat_t()));
}
else {
{
local_iterator lcur =
(segmented_partition_point_dispatch)(traits::local(first), traits::end(scur), pred, is_local_seg_t(), Cat());
(segmented_partition_point_dispatch)(traits::local(first), traits::end(scur), pred, is_local_seg_t(), local_cat_t());
if (lcur != traits::end(scur))
return traits::compose(scur, lcur);
}
for(++scur; scur != slast; ++scur) {
local_iterator lcur =
(segmented_partition_point_dispatch)(traits::begin(scur), traits::end(scur), pred, is_local_seg_t(), Cat());
(segmented_partition_point_dispatch)(traits::begin(scur), traits::end(scur), pred, is_local_seg_t(), local_cat_t());
if(lcur != traits::end(scur))
return traits::compose(scur, lcur);
}
return traits::compose(slast,
(segmented_partition_point_dispatch)(traits::begin(scur), traits::local(last), pred, is_local_seg_t(), Cat()));
(segmented_partition_point_dispatch)(traits::begin(scur), traits::local(last), pred, is_local_seg_t(), local_cat_t()));
}
return last;
}
@@ -92,20 +92,21 @@ OutIter segmented_remove_copy_if_dispatch
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;
typedef typename iterator_traits<local_iterator>::iterator_category local_cat_t;
segment_iterator sfirst = traits::segment(first);
segment_iterator slast = traits::segment(last);
if(sfirst == slast) {
return (segmented_remove_copy_if_dispatch)(traits::local(first), traits::local(last), result, pred, is_local_seg_t(), Cat());
return (segmented_remove_copy_if_dispatch)(traits::local(first), traits::local(last), result, pred, is_local_seg_t(), local_cat_t());
}
else {
result = (segmented_remove_copy_if_dispatch)(traits::local(first), traits::end(sfirst), result, pred, is_local_seg_t(), Cat());
result = (segmented_remove_copy_if_dispatch)(traits::local(first), traits::end(sfirst), result, pred, is_local_seg_t(), local_cat_t());
for(++sfirst; sfirst != slast; ++sfirst)
result = (segmented_remove_copy_if_dispatch)(traits::begin(sfirst), traits::end(sfirst), result, pred, is_local_seg_t(), Cat());
result = (segmented_remove_copy_if_dispatch)(traits::begin(sfirst), traits::end(sfirst), result, pred, is_local_seg_t(), local_cat_t());
return (segmented_remove_copy_if_dispatch)(traits::begin(sfirst), traits::local(last), result, pred, is_local_seg_t(), Cat());
return (segmented_remove_copy_if_dispatch)(traits::begin(sfirst), traits::local(last), result, pred, is_local_seg_t(), local_cat_t());
}
}
@@ -88,20 +88,21 @@ void segmented_replace_if_dispatch
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;
typedef typename iterator_traits<local_iterator>::iterator_category local_cat_t;
segment_iterator sfirst = traits::segment(first);
segment_iterator slast = traits::segment(last);
if(sfirst == slast) {
(segmented_replace_if_dispatch)(traits::local(first), traits::local(last), pred, new_val, is_local_seg_t(), Cat());
(segmented_replace_if_dispatch)(traits::local(first), traits::local(last), pred, new_val, is_local_seg_t(), local_cat_t());
}
else {
(segmented_replace_if_dispatch)(traits::local(first), traits::end(sfirst), pred, new_val, is_local_seg_t(), Cat());
(segmented_replace_if_dispatch)(traits::local(first), traits::end(sfirst), pred, new_val, is_local_seg_t(), local_cat_t());
for(++sfirst; sfirst != slast; ++sfirst)
(segmented_replace_if_dispatch)(traits::begin(sfirst), traits::end(sfirst), pred, new_val, is_local_seg_t(), Cat());
(segmented_replace_if_dispatch)(traits::begin(sfirst), traits::end(sfirst), pred, new_val, is_local_seg_t(), local_cat_t());
(segmented_replace_if_dispatch)(traits::begin(sfirst), traits::local(last), pred, new_val, is_local_seg_t(), Cat());
(segmented_replace_if_dispatch)(traits::begin(sfirst), traits::local(last), pred, new_val, is_local_seg_t(), local_cat_t());
}
}
@@ -90,20 +90,21 @@ OutIter segmented_reverse_copy_dispatch
typedef typename traits::segment_iterator segment_iterator;
typedef typename segmented_iterator_traits
<local_iterator>::is_segmented_iterator is_local_seg_t;
typedef typename iterator_traits<local_iterator>::iterator_category local_cat_t;
segment_iterator const sfirst = traits::segment(first);
segment_iterator slast = traits::segment(last);
if(sfirst == slast) {
return (segmented_reverse_copy_dispatch)(traits::local(first), traits::local(last), result, is_local_seg_t(), Cat());
return (segmented_reverse_copy_dispatch)(traits::local(first), traits::local(last), result, is_local_seg_t(), local_cat_t());
}
else {
result = (segmented_reverse_copy_dispatch)(traits::begin(slast), traits::local(last), result, is_local_seg_t(), Cat());
result = (segmented_reverse_copy_dispatch)(traits::begin(slast), traits::local(last), result, is_local_seg_t(), local_cat_t());
for (--slast; slast != sfirst; --slast)
result = (segmented_reverse_copy_dispatch)(traits::begin(slast), traits::end(slast), result, is_local_seg_t(), Cat());
result = (segmented_reverse_copy_dispatch)(traits::begin(slast), traits::end(slast), result, is_local_seg_t(), local_cat_t());
return (segmented_reverse_copy_dispatch)(traits::local(first), traits::end(sfirst), result, is_local_seg_t(), Cat());
return (segmented_reverse_copy_dispatch)(traits::local(first), traits::end(sfirst), result, is_local_seg_t(), local_cat_t());
}
}
@@ -90,20 +90,21 @@ OutIter segmented_transform_dispatch
typedef typename traits::segment_iterator segment_iterator;
typedef typename segmented_iterator_traits
<local_iterator>::is_segmented_iterator is_local_seg_t;
typedef typename iterator_traits<local_iterator>::iterator_category local_cat_t;
segment_iterator sfirst = traits::segment(first);
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(), Cat());
return (segmented_transform_dispatch)(traits::local(first), traits::local(last), result, op, is_local_seg_t(), local_cat_t());
}
else {
result = (segmented_transform_dispatch)(traits::local(first), traits::end(sfirst), result, op, is_local_seg_t(), Cat());
result = (segmented_transform_dispatch)(traits::local(first), traits::end(sfirst), result, op, is_local_seg_t(), local_cat_t());
for(++sfirst; sfirst != slast; ++sfirst)
result = (segmented_transform_dispatch)(traits::begin(sfirst), traits::end(sfirst), result, op, is_local_seg_t(), Cat());
result = (segmented_transform_dispatch)(traits::begin(sfirst), traits::end(sfirst), result, op, is_local_seg_t(), local_cat_t());
return (segmented_transform_dispatch)(traits::begin(sfirst), traits::local(last), result, op, is_local_seg_t(), Cat());
return (segmented_transform_dispatch)(traits::begin(sfirst), traits::local(last), result, op, is_local_seg_t(), local_cat_t());
}
}