Skip to content

Commit 775733c

Browse files
committed
Attempting to improve compiler error messages
- this is an experiment of how to best improve generated error messages if no appropriate tag_invoke overloads are being available Signed-off-by: Hartmut Kaiser <hartmut.kaiser@gmail.com>
1 parent a0145e3 commit 775733c

7 files changed

Lines changed: 277 additions & 141 deletions

File tree

libs/core/algorithms/include/hpx/parallel/algorithms/partial_sort.hpp

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -346,15 +346,6 @@ namespace hpx::parallel {
346346
hpx::future<Iter> parallel_partial_sort(ExPolicy&& policy, Iter first,
347347
Iter middle, Iter last, std::uint32_t level, Comp&& comp = Comp());
348348

349-
HPX_CXX_EXPORT struct sort_thread_helper
350-
{
351-
template <typename... Ts>
352-
decltype(auto) operator()(Ts&&... ts) const
353-
{
354-
return sort_thread(HPX_FORWARD(Ts, ts)...);
355-
}
356-
};
357-
358349
HPX_CXX_EXPORT struct parallel_partial_sort_helper
359350
{
360351
template <typename... Ts>
@@ -399,15 +390,15 @@ namespace hpx::parallel {
399390
policy.parameters(), policy.executor(),
400391
hpx::chrono::null_duration, cores, nelem);
401392

402-
hpx::future<Iter> left = execution::async_execute(
403-
policy.executor(), sort_thread_helper(), policy, first,
404-
c_last, comp, chunk_size);
393+
hpx::future<Iter> left =
394+
execution::async_execute(policy.executor(), sort_thread{},
395+
policy, first, c_last, comp, chunk_size);
405396

406397
hpx::future<Iter> right;
407398
if (middle != c_last)
408399
{
409400
right = execution::async_execute(policy.executor(),
410-
parallel_partial_sort_helper(), policy, c_last + 1,
401+
parallel_partial_sort_helper{}, policy, c_last + 1,
411402
middle, last, level - 1, comp);
412403
}
413404
else

libs/core/algorithms/include/hpx/parallel/algorithms/sort.hpp

Lines changed: 70 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -187,51 +187,37 @@ namespace hpx::parallel {
187187

188188
// \brief this function is the work assigned to each thread in the
189189
// parallel process
190-
HPX_CXX_EXPORT template <typename ExPolicy, typename RandomIt,
191-
typename Comp>
192-
hpx::future<RandomIt> sort_thread(ExPolicy&& policy, RandomIt first,
193-
RandomIt last, Comp comp, std::size_t chunk_size)
190+
HPX_CXX_EXPORT struct sort_thread
194191
{
195-
std::ptrdiff_t const N = last - first;
196-
if (static_cast<std::size_t>(N) <= chunk_size)
192+
template <typename ExPolicy, typename RandomIt, typename Comp>
193+
hpx::future<RandomIt> operator()(ExPolicy&& policy, RandomIt first,
194+
RandomIt last, Comp comp, std::size_t chunk_size)
197195
{
198-
return execution::async_execute(policy.executor(),
199-
[first, last, comp = HPX_MOVE(comp)]() -> RandomIt {
200-
std::sort(first, last, comp);
201-
return last;
202-
});
203-
}
196+
std::ptrdiff_t const N = last - first;
197+
if (static_cast<std::size_t>(N) <= chunk_size)
198+
{
199+
return execution::async_execute(policy.executor(),
200+
[first, last, comp = HPX_MOVE(comp)]() -> RandomIt {
201+
std::sort(first, last, comp);
202+
return last;
203+
});
204+
}
204205

205-
// check if sorted
206-
if (detail::is_sorted_sequential(first, last, comp))
207-
{
208-
return hpx::make_ready_future(last);
209-
}
206+
// check if sorted
207+
if (detail::is_sorted_sequential(first, last, comp))
208+
{
209+
return hpx::make_ready_future(last);
210+
}
210211

211-
// pivot selections
212-
pivot9(first, last, comp);
212+
// pivot selections
213+
pivot9(first, last, comp);
213214

214-
using reference =
215-
typename std::iterator_traits<RandomIt>::reference;
215+
using reference =
216+
typename std::iterator_traits<RandomIt>::reference;
216217

217-
reference val = *first;
218-
RandomIt c_first = first + 1, c_last = last - 1;
218+
reference val = *first;
219+
RandomIt c_first = first + 1, c_last = last - 1;
219220

220-
while (comp(*c_first, val))
221-
{
222-
++c_first;
223-
}
224-
while (comp(val, *c_last))
225-
{
226-
--c_last;
227-
}
228-
while (c_first < c_last)
229-
{
230-
#if defined(HPX_HAVE_CXX20_STD_RANGES_ITER_SWAP)
231-
std::ranges::iter_swap(c_first++, c_last--);
232-
#else
233-
std::iter_swap(c_first++, c_last--);
234-
#endif
235221
while (comp(*c_first, val))
236222
{
237223
++c_first;
@@ -240,40 +226,56 @@ namespace hpx::parallel {
240226
{
241227
--c_last;
242228
}
243-
}
244-
229+
while (c_first < c_last)
230+
{
245231
#if defined(HPX_HAVE_CXX20_STD_RANGES_ITER_SWAP)
246-
std::ranges::iter_swap(first, c_last);
232+
std::ranges::iter_swap(c_first++, c_last--);
247233
#else
248-
std::iter_swap(first, c_last);
234+
std::iter_swap(c_first++, c_last--);
249235
#endif
250-
251-
// spawn tasks for each sub section
252-
hpx::future<RandomIt> left = execution::async_execute(
253-
policy.executor(), &sort_thread<ExPolicy, RandomIt, Comp>,
254-
policy, first, c_last, comp, chunk_size);
255-
256-
hpx::future<RandomIt> right = execution::async_execute(
257-
policy.executor(), &sort_thread<ExPolicy, RandomIt, Comp>,
258-
policy, c_first, last, comp, chunk_size);
259-
260-
return hpx::dataflow(
261-
[last](hpx::future<RandomIt>&& leftf,
262-
hpx::future<RandomIt>&& rightf) -> RandomIt {
263-
if (leftf.has_exception() || rightf.has_exception())
236+
while (comp(*c_first, val))
264237
{
265-
std::list<std::exception_ptr> errors;
266-
if (leftf.has_exception())
267-
errors.push_back(leftf.get_exception_ptr());
268-
if (rightf.has_exception())
269-
errors.push_back(rightf.get_exception_ptr());
270-
271-
throw exception_list(HPX_MOVE(errors));
238+
++c_first;
272239
}
273-
return last;
274-
},
275-
HPX_MOVE(left), HPX_MOVE(right));
276-
}
240+
while (comp(val, *c_last))
241+
{
242+
--c_last;
243+
}
244+
}
245+
246+
#if defined(HPX_HAVE_CXX20_STD_RANGES_ITER_SWAP)
247+
std::ranges::iter_swap(first, c_last);
248+
#else
249+
std::iter_swap(first, c_last);
250+
#endif
251+
252+
// spawn tasks for each subsection
253+
hpx::future<RandomIt> left =
254+
execution::async_execute(policy.executor(), *this, policy,
255+
first, c_last, comp, chunk_size);
256+
257+
hpx::future<RandomIt> right =
258+
execution::async_execute(policy.executor(), *this, policy,
259+
c_first, last, comp, chunk_size);
260+
261+
return hpx::dataflow(
262+
[last](hpx::future<RandomIt>&& leftf,
263+
hpx::future<RandomIt>&& rightf) -> RandomIt {
264+
if (leftf.has_exception() || rightf.has_exception())
265+
{
266+
std::list<std::exception_ptr> errors;
267+
if (leftf.has_exception())
268+
errors.push_back(leftf.get_exception_ptr());
269+
if (rightf.has_exception())
270+
errors.push_back(rightf.get_exception_ptr());
271+
272+
throw exception_list(HPX_MOVE(errors));
273+
}
274+
return last;
275+
},
276+
HPX_MOVE(left), HPX_MOVE(right));
277+
}
278+
};
277279

278280
// policy : execution policy
279281
// [in] first iterator to the first element to sort
@@ -324,8 +326,7 @@ namespace hpx::parallel {
324326
return hpx::make_ready_future(last);
325327
}
326328

327-
return execution::async_execute(policy.executor(),
328-
&sort_thread<std::decay_t<ExPolicy>, RandomIt, Comp>,
329+
return execution::async_execute(policy.executor(), sort_thread{},
329330
HPX_FORWARD(ExPolicy, policy), first, last,
330331
HPX_FORWARD(Comp, comp), chunk_size);
331332
}

0 commit comments

Comments
 (0)