Skip to content

Commit

Permalink
Fix parallel_for_each iterator tag dispatch for move iterators + fix …
Browse files Browse the repository at this point in the history
…stack overflow on Windows (#1276)
  • Loading branch information
kboyarinov committed Dec 13, 2023
1 parent f4db1c8 commit 3b9f9ba
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 6 deletions.
21 changes: 20 additions & 1 deletion include/oneapi/tbb/parallel_for_each.h
Original file line number Diff line number Diff line change
Expand Up @@ -409,12 +409,31 @@ using tag = typename std::iterator_traits<It>::iterator_category;

#if __TBB_CPP20_PRESENT
template <typename It>
using iterator_tag_dispatch =
struct move_iterator_dispatch_helper {
using type = It;
};

// Until C++23, std::move_iterator::iterator_concept always defines
// to std::input_iterator_tag and hence std::forward_iterator concept
// always evaluates to false, so std::move_iterator dispatch should be
// made according to the base iterator type.
template <typename It>
struct move_iterator_dispatch_helper<std::move_iterator<It>> {
using type = It;
};

template <typename It>
using iterator_tag_dispatch_impl =
std::conditional_t<std::random_access_iterator<It>,
std::random_access_iterator_tag,
std::conditional_t<std::forward_iterator<It>,
std::forward_iterator_tag,
std::input_iterator_tag>>;

template <typename It>
using iterator_tag_dispatch =
iterator_tag_dispatch_impl<typename move_iterator_dispatch_helper<It>::type>;

#else
template<typename It>
using iterator_tag_dispatch = typename
Expand Down
2 changes: 0 additions & 2 deletions test/conformance/conformance_parallel_for_each.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,8 @@ class ForEachInvokeItem {
void do_action_and_feed(oneapi::tbb::feeder<ForEachInvokeItem>& feeder) const {
CHECK_MESSAGE(change_vector.size() % 2 == 0, "incorrect test setup");
std::size_t shift = change_vector.size() / 2;
std::cout << "Process " << real_value << std::endl;
++change_vector[real_value];
if (real_value < shift) {
std::cout << "Add " << real_value + shift << std::endl;
feeder.add(ForEachInvokeItem(real_value + shift, change_vector));
}
}
Expand Down
6 changes: 3 additions & 3 deletions test/tbb/test_parallel_for_each.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -290,10 +290,10 @@ template <typename Category>
void test_with_cpp20_iterator() {
constexpr std::size_t n = 1'000'000;

no_copy_move elements[n];
std::vector<no_copy_move> elements(n);

cpp20_iterator<no_copy_move, Category> begin(elements);
cpp20_iterator<no_copy_move, Category> end(elements + n);
cpp20_iterator<no_copy_move, Category> begin(elements.data());
cpp20_iterator<no_copy_move, Category> end(elements.data() + n);

oneapi::tbb::parallel_for_each(begin, end, [](no_copy_move& element) {
element.item = 42;
Expand Down

0 comments on commit 3b9f9ba

Please sign in to comment.