2121#include < boost/container/detail/config_begin.hpp>
2222#include < boost/container/detail/workaround.hpp>
2323#include < boost/container/experimental/segmented_iterator_traits.hpp>
24+ #include < boost/container/detail/iterators.hpp>
2425
2526namespace boost {
2627namespace container {
@@ -30,21 +31,71 @@ FwdIt segmented_partition_point(FwdIt first, Sent last, Predicate pred);
3031
3132namespace detail_algo {
3233
33- template <class FwdIt , class Sent , class Predicate , class Tag >
34+ #if defined(BOOST_CONTAINER_SEGMENTED_LOOP_UNROLLING)
35+
36+ template <class RAIter , class Predicate >
37+ RAIter segmented_partition_point_dispatch
38+ (RAIter first, RAIter last, Predicate pred, const non_segmented_iterator_tag &, const std::random_access_iterator_tag &)
39+ {
40+ typedef typename iterator_traits<RAIter>::difference_type difference_type;
41+
42+ difference_type n = last - first;
43+ while (n >= difference_type (4 )) {
44+ if (!pred (*first))
45+ goto final_result;
46+ ++first;
47+ if (!pred (*first))
48+ goto final_result;
49+ ++first;
50+ if (!pred (*first))
51+ goto final_result;
52+ ++first;
53+ if (!pred (*first))
54+ goto final_result;
55+ ++first;
56+ n -= 4 ;
57+ }
58+
59+ switch (n % 4 ) {
60+ case 3 :
61+ if (!pred (*first))
62+ break ;
63+ ++first;
64+ BOOST_FALLTHROUGH;
65+ case 2 :
66+ if (!pred (*first))
67+ break ;
68+ ++first;
69+ BOOST_FALLTHROUGH;
70+ case 1 :
71+ if (!pred (*first))
72+ break ;
73+ ++first;
74+ BOOST_FALLTHROUGH;
75+ default :
76+ break ;
77+ }
78+ final_result:
79+ return first;
80+ }
81+
82+ #endif // BOOST_CONTAINER_SEGMENTED_LOOP_UNROLLING
83+
84+ template <class FwdIt , class Sent , class Predicate , class Tag , class Cat >
3485typename algo_enable_if_c<
3586 !Tag::value || is_sentinel<Sent, FwdIt>::value, FwdIt>::type
3687segmented_partition_point_dispatch
37- (FwdIt first, Sent last, Predicate pred, Tag)
88+ (FwdIt first, Sent last, Predicate pred, Tag, Cat )
3889{
3990 for (; first != last; ++first)
4091 if (!pred (*first))
4192 return first;
4293 return last;
4394}
4495
45- template <class SegIter , class Predicate >
96+ template <class SegIter , class Predicate , class Cat >
4697SegIter segmented_partition_point_dispatch
47- (SegIter first, SegIter last, Predicate pred, segmented_iterator_tag)
98+ (SegIter first, SegIter last, Predicate pred, segmented_iterator_tag, Cat )
4899{
49100 typedef segmented_iterator_traits<SegIter> traits;
50101 typedef typename traits::local_iterator local_iterator;
@@ -57,24 +108,24 @@ SegIter segmented_partition_point_dispatch
57108
58109 if (scur == slast) {
59110 return traits::compose (scur,
60- (segmented_partition_point_dispatch)(traits::local (first), traits::local (last), pred, is_local_seg_t ()));
111+ (segmented_partition_point_dispatch)(traits::local (first), traits::local (last), pred, is_local_seg_t (), Cat () ));
61112 }
62113 else {
63114 {
64115 local_iterator lcur =
65- (segmented_partition_point_dispatch)(traits::local (first), traits::end (scur), pred, is_local_seg_t ());
116+ (segmented_partition_point_dispatch)(traits::local (first), traits::end (scur), pred, is_local_seg_t (), Cat () );
66117 if (lcur != traits::end (scur))
67118 return traits::compose (scur, lcur);
68119 }
69120
70121 for (++scur; scur != slast; ++scur) {
71122 local_iterator lcur =
72- (segmented_partition_point_dispatch)(traits::begin (scur), traits::end (scur), pred, is_local_seg_t ());
123+ (segmented_partition_point_dispatch)(traits::begin (scur), traits::end (scur), pred, is_local_seg_t (), Cat () );
73124 if (lcur != traits::end (scur))
74125 return traits::compose (scur, lcur);
75126 }
76127 return traits::compose (slast,
77- (segmented_partition_point_dispatch)(traits::begin (scur), traits::local (last), pred, is_local_seg_t ()));
128+ (segmented_partition_point_dispatch)(traits::begin (scur), traits::local (last), pred, is_local_seg_t (), Cat () ));
78129 }
79130 return last;
80131}
@@ -92,7 +143,7 @@ FwdIt segmented_partition_point(FwdIt first, Sent last, Predicate pred)
92143{
93144 typedef segmented_iterator_traits<FwdIt> traits;
94145 return detail_algo::segmented_partition_point_dispatch
95- (first, last, pred, typename traits::is_segmented_iterator ());
146+ (first, last, pred, typename traits::is_segmented_iterator (), typename iterator_traits<FwdIt>:: iterator_category () );
96147}
97148
98149} // namespace container
0 commit comments