@@ -201,105 +201,127 @@ namespace hpx::parallel::detail {
201201 {
202202 }
203203
204- template <typename ExPolicy, typename FwdIter2, typename Pred,
205- typename Proj1, typename Proj2>
206- static FwdIter sequential (ExPolicy, FwdIter first, std::size_t count,
207- FwdIter2 s_first, FwdIter2 s_last, Pred&& op, Proj1&& proj1,
208- Proj2&& proj2)
204+ template <typename ExPolicy, typename Size, typename T, typename Pred,
205+ typename Proj>
206+ static FwdIter sequential (ExPolicy, FwdIter first, Sent last,
207+ Size count, T const & value, Pred&& pred, Proj&& proj)
209208 {
210- return std::search (first, std::next (first, count), s_first, s_last,
211- util::compare_projected<Pred&, Proj1&, Proj2&>(
212- op, proj1, proj2));
213- }
209+ using difference_type =
210+ typename std::iterator_traits<FwdIter>::difference_type;
211+
212+ if (count <= 0 )
213+ return first;
214+ if (first == last)
215+ return last;
216+ difference_type n = std::distance (first, last);
217+ if (static_cast <difference_type>(count) > n)
218+ return last;
219+
220+ auto value_proj = proj (value);
221+
222+ FwdIter it = first;
223+ FwdIter end = first;
224+ std::advance (end, n - static_cast <difference_type>(count) + 1 );
225+
226+ for (; it != end; ++it)
227+ {
228+ FwdIter curr = it;
229+ Size matched = 0 ;
230+
231+ while (matched < count && pred (proj (*curr), value_proj))
232+ {
233+ ++curr;
234+ ++matched;
235+ }
236+
237+ if (matched == count)
238+ return it;
239+ }
214240
215- template <typename ExPolicy, typename FwdIter2, typename Pred,
216- typename Proj1, typename Proj2>
241+ return last;
242+ }
243+ template <typename ExPolicy, typename Size, typename T, typename Pred,
244+ typename Proj>
217245 static util::detail::algorithm_result_t <ExPolicy, FwdIter> parallel (
218- ExPolicy&& orgpolicy, FwdIter first, std::size_t count,
219- FwdIter2 s_first, FwdIter2 s_last, Pred&& op, Proj1&& proj1,
220- Proj2&& proj2)
246+ ExPolicy&& orgpolicy, FwdIter first, Sent last, Size count,
247+ T const & value, Pred&& pred, Proj&& proj)
221248 {
222- typedef typename std::iterator_traits<FwdIter>::reference reference;
223- typedef typename std::iterator_traits<FwdIter>::difference_type
224- difference_type;
225- typedef typename std::iterator_traits<FwdIter2>::difference_type
226- s_difference_type;
227- typedef util::detail::algorithm_result<ExPolicy, FwdIter> result;
249+ using result_type =
250+ util::detail::algorithm_result<ExPolicy, FwdIter>;
251+ using difference_type =
252+ typename std::iterator_traits<FwdIter>::difference_type;
253+
254+ if (count <= 0 )
255+ return result_type::get (HPX_MOVE (first));
228256
229- s_difference_type diff = std::distance (s_first, s_last);
230- if (diff <= 0 )
231- return result::get (HPX_MOVE (first));
257+ if (first == last)
258+ return result_type::get (HPX_MOVE (last));
232259
233- if (diff > s_difference_type (count))
234- return result::get (HPX_MOVE (first));
260+ difference_type n = std::distance (first, last);
261+ if (static_cast <difference_type>(count) > n)
262+ return result_type::get (HPX_MOVE (last));
263+
264+ // Number of valid starting positions
265+ difference_type max_start =
266+ n - static_cast <difference_type>(count) + 1 ;
267+
268+ auto value_proj = proj (value);
235269
236270 decltype (auto ) policy =
237271 hpx::execution::experimental::adapt_placement_mode (
238272 HPX_FORWARD (ExPolicy, orgpolicy),
239273 hpx::threads::thread_placement_hint::breadth_first);
240274
241275 using policy_type = std::decay_t <decltype (policy)>;
276+ using partitioner = util::partitioner<policy_type, FwdIter, void >;
242277
243- using partitioner =
244- util::partitioner< decltype (policy), FwdIter, void > ;
278+ hpx::parallel::util::cancellation_token<difference_type> tok (
279+ max_start) ;
245280
246- hpx::parallel::util::cancellation_token<difference_type> tok (count);
247-
248- auto f1 = [count, diff, tok, s_first, op = HPX_FORWARD (Pred, op),
249- proj1 = HPX_FORWARD (Proj1, proj1),
250- proj2 = HPX_FORWARD (Proj2, proj2)](FwdIter it,
251- std::size_t part_size,
281+ auto f1 = [first, max_start, count, value_proj,
282+ pred = HPX_FORWARD (Pred, pred),
283+ proj = HPX_FORWARD (Proj, proj),
284+ tok](FwdIter it, std::size_t part_size,
252285 std::size_t base_idx) mutable -> void {
253- FwdIter curr = it;
254-
255286 util::loop_idx_n<policy_type>(base_idx, it, part_size, tok,
256- [count, diff, s_first, &tok, &curr,
257- op = HPX_FORWARD (Pred, op),
258- proj1 = HPX_FORWARD (Proj1, proj1),
259- proj2 = HPX_FORWARD (Proj2, proj2)](
260- reference v, std::size_t i) -> void {
261- ++curr;
262- if (HPX_INVOKE (op, HPX_INVOKE (proj1, v),
263- HPX_INVOKE (proj2, *s_first)))
264- {
265- difference_type local_count = 1 ;
266- FwdIter2 needle = s_first;
267- FwdIter mid = curr;
287+ [=, &tok](auto &&, std::size_t idx) mutable -> void {
288+ difference_type start_idx =
289+ static_cast <difference_type>(idx);
290+ if (start_idx >= max_start)
291+ return ;
268292
269- // clang-format off
270- for (difference_type len = 0 ; local_count != diff &&
271- len != difference_type (count);
272- ++local_count, ++len, ++mid)
273- // clang-format on
274- {
275- if (!HPX_INVOKE (op, HPX_INVOKE (proj1, *mid),
276- HPX_INVOKE (proj2, *++needle)))
277- break ;
278- }
293+ FwdIter start = first;
294+ std::advance (start, start_idx);
279295
280- if (local_count == diff)
281- tok.cancel (i);
296+ FwdIter curr = start;
297+ Size matched = 0 ;
298+
299+ while (matched < count && pred (proj (*curr), value_proj))
300+ {
301+ ++curr;
302+ ++matched;
282303 }
304+
305+ if (matched == count)
306+ tok.cancel (start_idx);
283307 });
284308 };
285309
286- auto f2 = [=](auto &&... data) mutable -> FwdIter {
287- static_assert (sizeof ...(data) < 2 );
288-
289- // make sure iterators embedded in function object that is
290- // attached to futures are invalidated
310+ auto f2 = [first, last, max_start, tok](
311+ auto &&... data) mutable -> FwdIter {
291312 util::detail::clear_container (data...);
292313
293- difference_type search_res = tok.get_data ();
294- if (search_res != s_difference_type (count) )
295- std::advance (first, search_res );
314+ difference_type idx = tok.get_data ();
315+ if (idx == max_start )
316+ return HPX_MOVE (last );
296317
318+ std::advance (first, idx);
297319 return HPX_MOVE (first);
298320 };
299321
300322 return partitioner::call_with_index (
301- HPX_FORWARD (decltype (policy), policy), first,
302- count - (diff - 1 ), 1 , HPX_MOVE (f1), HPX_MOVE (f2));
323+ HPX_FORWARD (decltype (policy), policy), first, max_start, 1 ,
324+ HPX_MOVE (f1), HPX_MOVE (f2));
303325 }
304326 };
305327 // / \endcond
0 commit comments