mirror of
https://github.com/boostorg/container.git
synced 2026-07-06 11:40:45 +02:00
Apply dual random access optimization to several algorithms
This commit is contained in:
@@ -109,6 +109,26 @@ segmented_copy_dst_bounded
|
||||
return segduo<SrcIter, DstIter>(first, dst_first);
|
||||
}
|
||||
|
||||
#if defined(BOOST_CONTAINER_SEGMENTED_ENABLE_DUAL_RA_OPTIMIZATION)
|
||||
|
||||
template <class RASrcIter, class RADstIter>
|
||||
BOOST_CONTAINER_FORCEINLINE
|
||||
typename iterator_enable_if_tag
|
||||
<RADstIter, std::random_access_iterator_tag, segduo<RASrcIter, RADstIter> >::type
|
||||
segmented_copy_dst_bounded
|
||||
(RASrcIter first, RASrcIter last, RADstIter dst_first, RADstIter dst_last,
|
||||
const non_segmented_iterator_tag &, const std::random_access_iterator_tag &src_tag)
|
||||
{
|
||||
typedef typename iterator_traits<RASrcIter>::difference_type difference_type;
|
||||
const difference_type src_n = last - first;
|
||||
const difference_type dst_n = difference_type(dst_last - dst_first);
|
||||
const difference_type n = src_n < dst_n ? src_n : dst_n;
|
||||
return (segmented_copy_dst_bounded)(first, first + n, dst_first, unreachable_sentinel_t(),
|
||||
non_segmented_iterator_tag(), src_tag);
|
||||
}
|
||||
|
||||
#endif //BOOST_CONTAINER_SEGMENTED_ENABLE_DUAL_RA_OPTIMIZATION
|
||||
|
||||
template <class SrcIter, class Sent, class SegDstIter, class SrcCat>
|
||||
segduo<SrcIter, SegDstIter> segmented_copy_dst_bounded
|
||||
(SrcIter first, Sent last, SegDstIter dst_first, SegDstIter dst_last,
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
#include <boost/container/experimental/segmented_iterator_traits.hpp>
|
||||
#include <boost/container/experimental/wrapped_iterator.hpp>
|
||||
#include <boost/container/detail/iterator.hpp>
|
||||
|
||||
namespace boost {
|
||||
@@ -97,6 +98,36 @@ segmented_copy_if_dst_bounded
|
||||
return segduo<SrcIter, DstIter>(first, dst_first);
|
||||
}
|
||||
|
||||
#if defined(BOOST_CONTAINER_SEGMENTED_ENABLE_DUAL_RA_OPTIMIZATION)
|
||||
|
||||
template <class RASrcIter, class RADstIter, class Pred>
|
||||
BOOST_CONTAINER_FORCEINLINE
|
||||
typename iterator_enable_if_tag
|
||||
<RADstIter, std::random_access_iterator_tag, segduo<RASrcIter, RADstIter> >::type
|
||||
segmented_copy_if_dst_bounded
|
||||
(RASrcIter first, RASrcIter last, RADstIter dst_first, RADstIter dst_last, Pred pred,
|
||||
const non_segmented_iterator_tag &, const std::random_access_iterator_tag &src_tag)
|
||||
{
|
||||
typedef typename iterator_traits<RASrcIter>::difference_type difference_type;
|
||||
const difference_type src_n = last - first;
|
||||
const difference_type dst_n = difference_type(dst_last - dst_first);
|
||||
if (dst_n >= src_n) {
|
||||
return (segmented_copy_if_dst_bounded)(first, last, dst_first, unreachable_sentinel_t(),
|
||||
pred, non_segmented_iterator_tag(), src_tag);
|
||||
}
|
||||
else {
|
||||
//Dispatch to normal loop declaring the destination as bidirectional
|
||||
//to avoid recursion and stack overflow
|
||||
return (segmented_copy_if_dst_bounded)
|
||||
( first, last
|
||||
, make_wrapped_iterator<std::bidirectional_iterator_tag>(dst_first)
|
||||
, make_wrapped_iterator<std::bidirectional_iterator_tag>(dst_last)
|
||||
, pred, non_segmented_iterator_tag(), src_tag);
|
||||
}
|
||||
}
|
||||
|
||||
#endif //BOOST_CONTAINER_SEGMENTED_ENABLE_DUAL_RA_OPTIMIZATION
|
||||
|
||||
template <class SrcIter, class Sent, class SegDstIter, class Pred, class SrcCat>
|
||||
segduo<SrcIter, SegDstIter> segmented_copy_if_dst_bounded
|
||||
(SrcIter first, Sent last, SegDstIter dst_first, SegDstIter dst_last, Pred pred,
|
||||
|
||||
@@ -99,6 +99,26 @@ segmented_copy_n_dst_bounded
|
||||
return segduo<SrcIter, DstIter>(first, dst_first);
|
||||
}
|
||||
|
||||
#if defined(BOOST_CONTAINER_SEGMENTED_ENABLE_DUAL_RA_OPTIMIZATION)
|
||||
|
||||
template <class RASrcIter, class Size, class RADstIter>
|
||||
BOOST_CONTAINER_FORCEINLINE
|
||||
typename iterator_enable_if_tag
|
||||
<RADstIter, std::random_access_iterator_tag, segduo<RASrcIter, RADstIter> >::type
|
||||
segmented_copy_n_dst_bounded
|
||||
(RASrcIter first, Size& count, RADstIter dst_first, RADstIter dst_last,
|
||||
const non_segmented_iterator_tag &, const std::random_access_iterator_tag &src_tag)
|
||||
{
|
||||
typedef typename iterator_traits<RADstIter>::difference_type difference_type;
|
||||
const difference_type dst_n = dst_last - dst_first;
|
||||
Size n = count < Size(dst_n) ? count : Size(dst_n);
|
||||
count -= n; //Decrement before n is modified
|
||||
return (segmented_copy_n_dst_bounded)(first, n, dst_first, unreachable_sentinel_t(),
|
||||
non_segmented_iterator_tag(), src_tag);
|
||||
}
|
||||
|
||||
#endif //BOOST_CONTAINER_SEGMENTED_ENABLE_DUAL_RA_OPTIMIZATION
|
||||
|
||||
template <class SrcIter, class Size, class SegDstIter, class SrcCat>
|
||||
segduo<SrcIter, SegDstIter> segmented_copy_n_dst_bounded
|
||||
(SrcIter first, Size& count, SegDstIter dst_first, SegDstIter dst_last,
|
||||
@@ -289,10 +309,10 @@ BOOST_CONTAINER_FORCEINLINE OutIter segmented_copy_n_dispatch
|
||||
#if !defined(BOOST_CONTAINER_DISABLE_MULTI_SEGMENTED_ALGO)
|
||||
typedef segmented_iterator_traits<OutIter> dst_traits;
|
||||
return (segmented_copy_n_dst_dispatch)
|
||||
(first, count, result, typename dst_traits::is_segmented_iterator(), std::random_access_iterator_tag());
|
||||
(first, count, result, typename dst_traits::is_segmented_iterator(), src_tag);
|
||||
#else
|
||||
return (segmented_copy_n_dst_dispatch)
|
||||
(first, count, result, non_segmented_iterator_tag(), std::random_access_iterator_tag());
|
||||
(first, count, result, non_segmented_iterator_tag(), src_tag);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -54,6 +54,7 @@ struct equal_pred
|
||||
#if defined(BOOST_CONTAINER_SEGMENTED_LOOP_UNROLLING)
|
||||
|
||||
template <class RASrcIter, class Iter2, class Iter2Sent, class BinaryPred>
|
||||
BOOST_CONTAINER_FORCEINLINE
|
||||
segduo<RASrcIter, Iter2> segmented_equal_iter2_bounded
|
||||
(RASrcIter first1, RASrcIter last1, Iter2 first2, Iter2Sent iter2_last, BinaryPred pred,
|
||||
const non_segmented_iterator_tag &, const std::random_access_iterator_tag &)
|
||||
@@ -104,6 +105,7 @@ segduo<RASrcIter, Iter2> segmented_equal_iter2_bounded
|
||||
#endif //BOOST_CONTAINER_SEGMENTED_LOOP_UNROLLING
|
||||
|
||||
template <class SrcIter, class Sent, class Iter2, class Iter2Sent, class BinaryPred, class Iter2Tag, class SrcCat>
|
||||
BOOST_CONTAINER_FORCEINLINE
|
||||
typename algo_enable_if_c<!Iter2Tag::value, segduo<SrcIter, Iter2> >::type
|
||||
segmented_equal_iter2_bounded
|
||||
(SrcIter first1, Sent last1, Iter2 first2, Iter2Sent iter2_last, BinaryPred pred, Iter2Tag, SrcCat)
|
||||
@@ -119,6 +121,26 @@ segmented_equal_iter2_bounded
|
||||
return segduo<SrcIter, Iter2>(first1, first2);
|
||||
}
|
||||
|
||||
#if defined(BOOST_CONTAINER_SEGMENTED_ENABLE_DUAL_RA_OPTIMIZATION)
|
||||
|
||||
template <class RASrcIter, class RAIter2, class BinaryPred>
|
||||
BOOST_CONTAINER_FORCEINLINE
|
||||
typename iterator_enable_if_tag
|
||||
<RAIter2, std::random_access_iterator_tag, segduo<RASrcIter, RAIter2> >::type
|
||||
segmented_equal_iter2_bounded
|
||||
(RASrcIter first1, RASrcIter last1, RAIter2 first2, RAIter2 iter2_last, BinaryPred pred,
|
||||
const non_segmented_iterator_tag &, const std::random_access_iterator_tag &src_tag)
|
||||
{
|
||||
typedef typename iterator_traits<RASrcIter>::difference_type difference_type;
|
||||
const difference_type src_n = last1 - first1;
|
||||
const difference_type iter2_n = difference_type(iter2_last - first2);
|
||||
const difference_type n = src_n < iter2_n ? src_n : iter2_n;
|
||||
return (segmented_equal_iter2_bounded)(first1, first1 + n, first2, unreachable_sentinel_t(),
|
||||
pred, non_segmented_iterator_tag(), src_tag);
|
||||
}
|
||||
|
||||
#endif //BOOST_CONTAINER_SEGMENTED_ENABLE_DUAL_RA_OPTIMIZATION
|
||||
|
||||
template <class SrcIter, class Sent, class SegIter2, class BinaryPred, class SrcCat>
|
||||
segduo<SrcIter, SegIter2> segmented_equal_iter2_bounded
|
||||
(SrcIter first1, Sent last1, SegIter2 iter2_first, SegIter2 iter2_last, BinaryPred pred,
|
||||
|
||||
@@ -64,6 +64,7 @@ struct mismatch_equal
|
||||
#if defined(BOOST_CONTAINER_SEGMENTED_LOOP_UNROLLING)
|
||||
|
||||
template <class RASrcIter, class Iter2, class Iter2Sent, class BinaryPred>
|
||||
BOOST_CONTAINER_FORCEINLINE
|
||||
segduo<RASrcIter, Iter2> segmented_mismatch_iter2_bounded
|
||||
(RASrcIter first1, RASrcIter last1, Iter2 first2, Iter2Sent iter2_last, BinaryPred pred,
|
||||
const non_segmented_iterator_tag &, const std::random_access_iterator_tag &)
|
||||
@@ -114,6 +115,7 @@ segduo<RASrcIter, Iter2> segmented_mismatch_iter2_bounded
|
||||
#endif //BOOST_CONTAINER_SEGMENTED_LOOP_UNROLLING
|
||||
|
||||
template <class SrcIter, class Sent, class Iter2, class Iter2Sent, class BinaryPred, class Iter2Tag, class SrcCat>
|
||||
BOOST_CONTAINER_FORCEINLINE
|
||||
typename algo_enable_if_c<!Iter2Tag::value, segduo<SrcIter, Iter2> >::type
|
||||
segmented_mismatch_iter2_bounded
|
||||
(SrcIter first1, Sent last1, Iter2 first2, Iter2Sent iter2_last, BinaryPred pred, Iter2Tag, SrcCat)
|
||||
@@ -129,6 +131,26 @@ segmented_mismatch_iter2_bounded
|
||||
return segduo<SrcIter, Iter2>(first1, first2);
|
||||
}
|
||||
|
||||
#if defined(BOOST_CONTAINER_SEGMENTED_ENABLE_DUAL_RA_OPTIMIZATION)
|
||||
|
||||
template <class RASrcIter, class RAIter2, class BinaryPred>
|
||||
BOOST_CONTAINER_FORCEINLINE
|
||||
typename iterator_enable_if_tag
|
||||
<RAIter2, std::random_access_iterator_tag, segduo<RASrcIter, RAIter2> >::type
|
||||
segmented_mismatch_iter2_bounded
|
||||
(RASrcIter first1, RASrcIter last1, RAIter2 first2, RAIter2 iter2_last, BinaryPred pred,
|
||||
const non_segmented_iterator_tag &, const std::random_access_iterator_tag &src_tag)
|
||||
{
|
||||
typedef typename iterator_traits<RASrcIter>::difference_type difference_type;
|
||||
const difference_type src_n = last1 - first1;
|
||||
const difference_type iter2_n = difference_type(iter2_last - first2);
|
||||
const difference_type n = src_n < iter2_n ? src_n : iter2_n;
|
||||
return (segmented_mismatch_iter2_bounded)(first1, first1 + n, first2, unreachable_sentinel_t(),
|
||||
pred, non_segmented_iterator_tag(), src_tag);
|
||||
}
|
||||
|
||||
#endif //BOOST_CONTAINER_SEGMENTED_ENABLE_DUAL_RA_OPTIMIZATION
|
||||
|
||||
template <class SrcIter, class Sent, class SegIter2, class BinaryPred, class SrcCat>
|
||||
segduo<SrcIter, SegIter2> segmented_mismatch_iter2_bounded
|
||||
(SrcIter first1, Sent last1, SegIter2 iter2_first, SegIter2 iter2_last, BinaryPred pred,
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <boost/container/detail/config_begin.hpp>
|
||||
#include <boost/container/detail/workaround.hpp>
|
||||
#include <boost/container/experimental/segmented_iterator_traits.hpp>
|
||||
#include <boost/container/experimental/wrapped_iterator.hpp>
|
||||
#include <boost/container/detail/iterator.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
|
||||
@@ -48,7 +49,8 @@ namespace detail_algo {
|
||||
#if defined(BOOST_CONTAINER_SEGMENTED_LOOP_UNROLLING)
|
||||
|
||||
template <bool Move, class RASrcIter, class DstIter, class DstSent, class Pred>
|
||||
BOOST_CONTAINER_FORCEINLINE segduo<RASrcIter, DstIter> segmented_remove_copy_if_dst_bounded
|
||||
BOOST_CONTAINER_FORCEINLINE
|
||||
segduo<RASrcIter, DstIter> segmented_remove_copy_if_dst_bounded
|
||||
(RASrcIter first, RASrcIter last, DstIter dst_first, DstSent dst_last, Pred pred,
|
||||
const non_segmented_iterator_tag &, const std::random_access_iterator_tag &)
|
||||
{
|
||||
@@ -100,6 +102,36 @@ segmented_remove_copy_if_dst_bounded
|
||||
return segduo<SrcIter, DstIter>(first, dst_first);
|
||||
}
|
||||
|
||||
#if defined(BOOST_CONTAINER_SEGMENTED_ENABLE_DUAL_RA_OPTIMIZATION)
|
||||
|
||||
template <bool Move, class RASrcIter, class RADstIter, class Pred>
|
||||
BOOST_CONTAINER_FORCEINLINE
|
||||
typename iterator_enable_if_tag
|
||||
<RADstIter, std::random_access_iterator_tag, segduo<RASrcIter, RADstIter> >::type
|
||||
segmented_remove_copy_if_dst_bounded
|
||||
(RASrcIter first, RASrcIter last, RADstIter dst_first, RADstIter dst_last, Pred pred,
|
||||
const non_segmented_iterator_tag &, const std::random_access_iterator_tag &src_tag)
|
||||
{
|
||||
typedef typename iterator_traits<RASrcIter>::difference_type difference_type;
|
||||
const difference_type src_n = last - first;
|
||||
const difference_type dst_n = difference_type(dst_last - dst_first);
|
||||
if (dst_n >= src_n) {
|
||||
return (segmented_remove_copy_if_dst_bounded<Move>)(first, last, dst_first, unreachable_sentinel_t(),
|
||||
pred, non_segmented_iterator_tag(), src_tag);
|
||||
}
|
||||
else {
|
||||
//Dispatch to normal loop declaring the destination as bidirectional
|
||||
//to avoid recursion and stack overflow
|
||||
return (segmented_remove_copy_if_dst_bounded<Move>)
|
||||
( first, last
|
||||
, make_wrapped_iterator<std::bidirectional_iterator_tag>(dst_first)
|
||||
, make_wrapped_iterator<std::bidirectional_iterator_tag>(dst_last)
|
||||
, pred, non_segmented_iterator_tag(), src_tag);
|
||||
}
|
||||
}
|
||||
|
||||
#endif //BOOST_CONTAINER_SEGMENTED_ENABLE_DUAL_RA_OPTIMIZATION
|
||||
|
||||
template <bool Move, class SrcIter, class Sent, class SegDstIter, class Pred, class SrcCat>
|
||||
segduo<SrcIter, SegDstIter> segmented_remove_copy_if_dst_bounded
|
||||
(SrcIter first, Sent last, SegDstIter dst_first, SegDstIter dst_last, Pred pred,
|
||||
|
||||
@@ -109,6 +109,26 @@ segmented_reverse_copy_dst_bounded
|
||||
return segduo<BidirIter, DstIter>(last, dst_first);
|
||||
}
|
||||
|
||||
#if defined(BOOST_CONTAINER_SEGMENTED_ENABLE_DUAL_RA_OPTIMIZATION)
|
||||
|
||||
template <class RASrcIter, class RADstIter>
|
||||
BOOST_CONTAINER_FORCEINLINE
|
||||
typename iterator_enable_if_tag
|
||||
<RADstIter, std::random_access_iterator_tag, segduo<RASrcIter, RADstIter> >::type
|
||||
segmented_reverse_copy_dst_bounded
|
||||
(RASrcIter first, RASrcIter last, RADstIter dst_first, RADstIter dst_last,
|
||||
const non_segmented_iterator_tag &, const std::random_access_iterator_tag &src_tag)
|
||||
{
|
||||
typedef typename iterator_traits<RASrcIter>::difference_type difference_type;
|
||||
const difference_type src_n = last - first;
|
||||
const difference_type dst_n = difference_type(dst_last - dst_first);
|
||||
const difference_type n = src_n < dst_n ? src_n : dst_n;
|
||||
return (segmented_reverse_copy_dst_bounded)(last - n, last, dst_first, unreachable_sentinel_t(),
|
||||
non_segmented_iterator_tag(), src_tag);
|
||||
}
|
||||
|
||||
#endif //BOOST_CONTAINER_SEGMENTED_ENABLE_DUAL_RA_OPTIMIZATION
|
||||
|
||||
template <class BidirIter, class SegDstIter, class SrcCat>
|
||||
segduo<BidirIter, SegDstIter> segmented_reverse_copy_dst_bounded
|
||||
(BidirIter first, BidirIter last, SegDstIter dst_first, SegDstIter dst_last,
|
||||
|
||||
Reference in New Issue
Block a user