diff --git a/include/boost/container/experimental/segmented_all_of.hpp b/include/boost/container/experimental/segmented_all_of.hpp index dd774cf..6803d58 100644 --- a/include/boost/container/experimental/segmented_all_of.hpp +++ b/include/boost/container/experimental/segmented_all_of.hpp @@ -21,7 +21,7 @@ #include #include #include -#include +#include namespace boost { namespace container { @@ -32,7 +32,7 @@ template BOOST_CONTAINER_FORCEINLINE bool segmented_all_of(InpIter first, Sent last, Pred pred) { - return (segmented_find_if)(first, last, not_pred(pred)) == last; + return (segmented_none_of)(first, last, not_pred(pred)); } } // namespace container diff --git a/include/boost/container/experimental/segmented_any_of.hpp b/include/boost/container/experimental/segmented_any_of.hpp index 3ffcc33..1591eef 100644 --- a/include/boost/container/experimental/segmented_any_of.hpp +++ b/include/boost/container/experimental/segmented_any_of.hpp @@ -20,7 +20,7 @@ #include #include -#include +#include namespace boost { namespace container { @@ -31,7 +31,7 @@ template BOOST_CONTAINER_FORCEINLINE bool segmented_any_of(InpIter first, Sent last, Pred pred) { - return !((segmented_find_if)(first, last, pred) == last); + return !(segmented_none_of)(first, last, pred); } } // namespace container diff --git a/include/boost/container/experimental/segmented_copy_n.hpp b/include/boost/container/experimental/segmented_copy_n.hpp index afebfe3..c748343 100644 --- a/include/boost/container/experimental/segmented_copy_n.hpp +++ b/include/boost/container/experimental/segmented_copy_n.hpp @@ -82,10 +82,16 @@ OutIter copy_n_scan(SegIt first, SegIt last, Size& count, OutIter result, segmen else { result = copy_n_scan(lcur, traits::end(scur), count, result, is_local_seg_t()); - for(++scur; scur != slast && count > 0; ++scur) - result = copy_n_scan(traits::begin(scur), traits::end(scur), count, result, is_local_seg_t()); + if (!count) + return result; - return count ? copy_n_scan(traits::begin(scur), traits::local(last), count, result, is_local_seg_t()) : result; + for (++scur; scur != slast; ++scur) { + result = copy_n_scan(traits::begin(scur), traits::end(scur), count, result, is_local_seg_t()); + if (!count) + return result; + } + + return copy_n_scan(traits::begin(scur), traits::local(last), count, result, is_local_seg_t()); } } diff --git a/include/boost/container/experimental/segmented_find_if.hpp b/include/boost/container/experimental/segmented_find_if.hpp index f8276c7..ea75b86 100644 --- a/include/boost/container/experimental/segmented_find_if.hpp +++ b/include/boost/container/experimental/segmented_find_if.hpp @@ -115,7 +115,10 @@ SegIter segmented_find_if_dispatch 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(), local_cat_t())); + const local_iterator ll = traits::local(last); + const local_iterator r = (segmented_find_if_dispatch)(traits::local(first), ll, pred, is_local_seg_t(), local_cat_t()); + if (r != ll) + return traits::compose(sfirst, r); } else { //First segment @@ -133,8 +136,14 @@ SegIter segmented_find_if_dispatch 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(), local_cat_t())); + { + const local_iterator ll = traits::local(last); + const local_iterator r = (segmented_find_if_dispatch)(traits::begin(slast), traits::local(last), pred, is_local_seg_t(), local_cat_t()); + if (r != ll) + return traits::compose(sfirst, r); + } } + return last; } } // namespace detail_algo diff --git a/include/boost/container/experimental/segmented_generate_n.hpp b/include/boost/container/experimental/segmented_generate_n.hpp index bdc1192..50eafc4 100644 --- a/include/boost/container/experimental/segmented_generate_n.hpp +++ b/include/boost/container/experimental/segmented_generate_n.hpp @@ -101,24 +101,27 @@ SegIt generate_n_scan(SegIt first, SegIt last, Size& count, Generator& gen, segm typedef typename traits::segment_iterator segment_iterator; typedef typename segmented_iterator_traits::is_segmented_iterator is_local_seg_t; - segment_iterator scur = traits::segment(first); - segment_iterator slast = traits::segment(last); + segment_iterator scur = traits::segment(first); + segment_iterator const slast = traits::segment(last); if(scur == slast) { - return traits::compose(scur, generate_n_scan(traits::local(first), traits::local(last), count, gen, is_local_seg_t())); + const local_iterator ll = traits::local(last); + const local_iterator r = (generate_n_scan)(traits::local(first), ll, count, gen, is_local_seg_t()); + return (r != ll) ? traits::compose(scur, r) : last; } else { - local_iterator lcur = generate_n_scan(traits::local(first), traits::end(scur), count, gen, is_local_seg_t()); - if(count > 0) { - for(++scur; scur != slast; ++scur) { - lcur = generate_n_scan(traits::begin(scur), traits::end(scur), count, gen, is_local_seg_t()); - if(!count) - break; - } - if(count > 0 && scur == slast) - lcur = generate_n_scan(traits::begin(slast), traits::local(last), count, gen, is_local_seg_t()); + local_iterator r = generate_n_scan(traits::local(first), traits::end(scur), count, gen, is_local_seg_t()); + if (!count) + return traits::compose(scur, r); + + for (++scur; scur != slast; ++scur) { + r = generate_n_scan(traits::begin(scur), traits::end(scur), count, gen, is_local_seg_t()); + if (!count) + return traits::compose(scur, r); } - return traits::compose(scur, lcur); + const local_iterator ll = traits::local(last); + r = generate_n_scan(traits::begin(slast), ll, count, gen, is_local_seg_t()); + return (r != ll) ? traits::compose(scur, r) : last; } } diff --git a/include/boost/container/experimental/segmented_iterator_traits.hpp b/include/boost/container/experimental/segmented_iterator_traits.hpp index d79e1b5..ec2e7ca 100644 --- a/include/boost/container/experimental/segmented_iterator_traits.hpp +++ b/include/boost/container/experimental/segmented_iterator_traits.hpp @@ -147,7 +147,7 @@ struct is_sentinel #include //#define BOOST_CONTAINER_ENABLE_SEGMENTED_LOOP_UNROLLING -//#define BOOST_CONTAINER_DISABLE_SEGMENTED_LOOP_UNROLLING +#define BOOST_CONTAINER_DISABLE_SEGMENTED_LOOP_UNROLLING #if defined(BOOST_CONTAINER_ENABLE_SEGMENTED_LOOP_UNROLLING) && defined(BOOST_CONTAINER_DISABLE_SEGMENTED_LOOP_UNROLLING) #error "Cannot define both BOOST_CONTAINER_ENABLE_SEGMENTED_LOOP_UNROLLING and BOOST_CONTAINER_DISABLE_SEGMENTED_LOOP_UNROLLING" diff --git a/include/boost/container/experimental/segmented_merge.hpp b/include/boost/container/experimental/segmented_merge.hpp index aa6d46b..6795fb4 100644 --- a/include/boost/container/experimental/segmented_merge.hpp +++ b/include/boost/container/experimental/segmented_merge.hpp @@ -74,9 +74,9 @@ OutIter merge_scan(SegIt first, SegIt last, InIter2& first2, Sent2 last2, OutIte typedef typename segmented_iterator_traits ::is_segmented_iterator is_local_seg_t; - segment_iterator scur = traits::segment(first); - segment_iterator slast = traits::segment(last); - local_iterator lcur = traits::local(first); + segment_iterator scur = traits::segment(first); + segment_iterator const slast = traits::segment(last); + local_iterator lcur = traits::local(first); if(scur == slast) { return merge_scan(lcur, traits::local(last), first2, last2, result, comp, is_local_seg_t()); diff --git a/include/boost/container/experimental/segmented_mismatch.hpp b/include/boost/container/experimental/segmented_mismatch.hpp index 066ffb8..7b404d2 100644 --- a/include/boost/container/experimental/segmented_mismatch.hpp +++ b/include/boost/container/experimental/segmented_mismatch.hpp @@ -131,8 +131,9 @@ std::pair 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(), local_cat_t()); - return return_t(traits::compose(sfirst, r.first), r.second); + const local_iterator ll = traits::local(last1); + const local_return_t r = (segmented_mismatch_dispatch)(traits::local(first1), ll, first2, pred, is_local_seg_t(), local_cat_t()); + return return_t((r.first != ll) ? traits::compose(sfirst, r.first) : last1, r.second); } else { // First segment @@ -150,8 +151,9 @@ std::pair segmented_mismatch_dispatch } // Last segment - 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); + le = traits::local(last1); + r = (segmented_mismatch_dispatch)(traits::begin(slast), le, r.second, pred, is_local_seg_t(), local_cat_t()); + return return_t((r.first != le) ? traits::compose(sfirst, r.first) : last1, r.second); } } diff --git a/include/boost/container/experimental/segmented_partition_point.hpp b/include/boost/container/experimental/segmented_partition_point.hpp index abf309a..73c45f5 100644 --- a/include/boost/container/experimental/segmented_partition_point.hpp +++ b/include/boost/container/experimental/segmented_partition_point.hpp @@ -117,25 +117,35 @@ SegIter segmented_partition_point_dispatch 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(), local_cat_t())); + const local_iterator ll = traits::local(last); + const local_iterator r = (segmented_partition_point_dispatch) + (traits::local(first), ll, pred, is_local_seg_t(), local_cat_t()); + if (r != ll) + return traits::compose(scur, r); } else { - { - local_iterator lcur = - (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); + { //first segment + const local_iterator le = traits::end(scur); + const local_iterator r = (segmented_partition_point_dispatch) + (traits::local(first), le, pred, is_local_seg_t(), local_cat_t()); + if (r != le) + return traits::compose(scur, r); } - + //middle segments for(++scur; scur != slast; ++scur) { - local_iterator lcur = - (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); + const local_iterator le = traits::end(scur); + const local_iterator r = (segmented_partition_point_dispatch) + (traits::begin(scur), le, pred, is_local_seg_t(), local_cat_t()); + if (r != le) + return traits::compose(scur, r); + } + { //last segment + const local_iterator ll = traits::local(last); + const local_iterator r = (segmented_partition_point_dispatch) + (traits::begin(scur), ll, pred, is_local_seg_t(), local_cat_t()); + if (r != ll) + return traits::compose(scur, r); } - return traits::compose(slast, - (segmented_partition_point_dispatch)(traits::begin(scur), traits::local(last), pred, is_local_seg_t(), local_cat_t())); } return last; } diff --git a/include/boost/container/experimental/segmented_remove_if.hpp b/include/boost/container/experimental/segmented_remove_if.hpp index 621d692..6595241 100644 --- a/include/boost/container/experimental/segmented_remove_if.hpp +++ b/include/boost/container/experimental/segmented_remove_if.hpp @@ -42,6 +42,9 @@ FwdIt segmented_remove_if(FwdIt first, Sent last, Predicate pred) FwdIt next = first; ++next; + //TODO: This is not the most efficient way to implement segmented_remove_if + //because it does not take advantage that both ranges are segmented, + //but it is the simplest way to implement it return segmented_remove_copy_if(next, last, first, pred); } diff --git a/include/boost/container/experimental/segmented_set_difference.hpp b/include/boost/container/experimental/segmented_set_difference.hpp index 1d8ebf8..a533e02 100644 --- a/include/boost/container/experimental/segmented_set_difference.hpp +++ b/include/boost/container/experimental/segmented_set_difference.hpp @@ -67,9 +67,9 @@ OutIter set_difference_scan(SegIt first, SegIt last, InIter2& first2, Sent2 last typedef typename traits::local_iterator local_iterator; typedef typename segmented_iterator_traits::is_segmented_iterator is_local_seg_t; - segment_iterator scur = traits::segment(first); - segment_iterator slast = traits::segment(last); - local_iterator lcur = traits::local(first); + segment_iterator scur = traits::segment(first); + segment_iterator const slast = traits::segment(last); + local_iterator lcur = traits::local(first); if(scur == slast) { return set_difference_scan(lcur, traits::local(last), first2, last2, result, comp, is_local_seg_t()); diff --git a/include/boost/container/experimental/segmented_set_intersection.hpp b/include/boost/container/experimental/segmented_set_intersection.hpp index 9094181..7fcc35b 100644 --- a/include/boost/container/experimental/segmented_set_intersection.hpp +++ b/include/boost/container/experimental/segmented_set_intersection.hpp @@ -64,9 +64,9 @@ OutIter set_intersection_scan(SegIt first, SegIt last, InIter2& first2, Sent2 la typedef typename traits::local_iterator local_iterator; typedef typename segmented_iterator_traits::is_segmented_iterator is_local_seg_t; - segment_iterator scur = traits::segment(first); - segment_iterator slast = traits::segment(last); - local_iterator lcur = traits::local(first); + segment_iterator scur = traits::segment(first); + segment_iterator const slast = traits::segment(last); + local_iterator lcur = traits::local(first); if(scur == slast) { return (set_intersection_scan)(lcur, traits::local(last), first2, last2, result, comp, is_local_seg_t()); diff --git a/include/boost/container/experimental/segmented_set_symmetric_difference.hpp b/include/boost/container/experimental/segmented_set_symmetric_difference.hpp index 5440829..25cfb5c 100644 --- a/include/boost/container/experimental/segmented_set_symmetric_difference.hpp +++ b/include/boost/container/experimental/segmented_set_symmetric_difference.hpp @@ -64,9 +64,9 @@ void set_symmetric_difference_scan(SegIt first, SegIt last, InIter2& first2, Sen typedef typename segmented_iterator_traits ::is_segmented_iterator is_local_seg_t; - segment_iterator scur = traits::segment(first); - segment_iterator slast = traits::segment(last); - local_iterator lcur = traits::local(first); + segment_iterator scur = traits::segment(first); + segment_iterator const slast = traits::segment(last); + local_iterator lcur = traits::local(first); if(scur == slast) { set_symmetric_difference_scan(lcur, traits::local(last), first2, last2, result, comp, is_local_seg_t()); diff --git a/include/boost/container/experimental/segmented_set_union.hpp b/include/boost/container/experimental/segmented_set_union.hpp index 04ad447..70fd34f 100644 --- a/include/boost/container/experimental/segmented_set_union.hpp +++ b/include/boost/container/experimental/segmented_set_union.hpp @@ -67,9 +67,9 @@ InIter2 set_union_scan(SegIt first, SegIt last, InIter2 first2, Sent2 last2, Out typedef typename traits::segment_iterator segment_iterator; typedef typename segmented_iterator_traits::is_segmented_iterator is_local_seg_t; - segment_iterator scur = traits::segment(first); - segment_iterator slast = traits::segment(last); - local_iterator lcur = traits::local(first); + segment_iterator scur = traits::segment(first); + segment_iterator const slast = traits::segment(last); + local_iterator lcur = traits::local(first); if(scur == slast) { first2 = set_union_scan(lcur, traits::local(last), first2, last2, result, comp, is_local_seg_t()); diff --git a/include/boost/container/experimental/segmented_stable_partition.hpp b/include/boost/container/experimental/segmented_stable_partition.hpp index b5f71b4..2095c92 100644 --- a/include/boost/container/experimental/segmented_stable_partition.hpp +++ b/include/boost/container/experimental/segmented_stable_partition.hpp @@ -96,9 +96,9 @@ OuterIter stable_partition_scan(SegIt first, SegIt last, OuterIter result, typedef sp_chained_composer composer_t; - segment_iterator scur = traits::segment(first); + segment_iterator scur = traits::segment(first); segment_iterator const slast = traits::segment(last); - local_iterator lcur = traits::local(first); + local_iterator lcur = traits::local(first); if(scur == slast) { result = stable_partition_scan(lcur, traits::local(last), result, composer_t(composer, scur), pred, is_local_seg_t());