mirror of
https://github.com/boostorg/container.git
synced 2026-07-05 16:30:46 +02:00
Algorithm fine-tuning
This commit is contained in:
@@ -21,7 +21,7 @@
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
#include <boost/container/detail/compare_functors.hpp>
|
||||
#include <boost/container/experimental/segmented_find_if.hpp>
|
||||
#include <boost/container/experimental/segmented_none_of.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
@@ -32,7 +32,7 @@ template <class InpIter, class Sent, class Pred>
|
||||
BOOST_CONTAINER_FORCEINLINE
|
||||
bool segmented_all_of(InpIter first, Sent last, Pred pred)
|
||||
{
|
||||
return (segmented_find_if)(first, last, not_pred<Pred>(pred)) == last;
|
||||
return (segmented_none_of)(first, last, not_pred<Pred>(pred));
|
||||
}
|
||||
|
||||
} // namespace container
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
#include <boost/container/experimental/segmented_find_if.hpp>
|
||||
#include <boost/container/experimental/segmented_none_of.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace container {
|
||||
@@ -31,7 +31,7 @@ template <class InpIter, class Sent, class Pred>
|
||||
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
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<local_iterator>::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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -147,7 +147,7 @@ struct is_sentinel<Iter, Iter>
|
||||
#include <boost/container/detail/config_end.hpp>
|
||||
|
||||
//#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"
|
||||
|
||||
@@ -74,9 +74,9 @@ OutIter merge_scan(SegIt first, SegIt last, InIter2& first2, Sent2 last2, OutIte
|
||||
typedef typename segmented_iterator_traits
|
||||
<local_iterator>::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());
|
||||
|
||||
@@ -131,8 +131,9 @@ 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(), 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<SegIter, InpIter2> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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<local_iterator>::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());
|
||||
|
||||
@@ -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<local_iterator>::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());
|
||||
|
||||
@@ -64,9 +64,9 @@ void set_symmetric_difference_scan(SegIt first, SegIt last, InIter2& first2, Sen
|
||||
typedef typename segmented_iterator_traits
|
||||
<local_iterator>::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());
|
||||
|
||||
@@ -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<local_iterator>::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());
|
||||
|
||||
@@ -96,9 +96,9 @@ OuterIter stable_partition_scan(SegIt first, SegIt last, OuterIter result,
|
||||
|
||||
typedef sp_chained_composer<Composer, traits> 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());
|
||||
|
||||
Reference in New Issue
Block a user