/* { dg-additional-options "-std=c++20" } */ /* c++20 */ /* std::common_iterator uses std::variant. */ #include #include #include //TODO PR120454 "C++ constexpr vs. OpenMP implicit mapping" #pragma omp declare target(std::ranges::distance, std::ranges::next) #include "target-flex-common.h" namespace stdr = std::ranges; template bool simple_equal(const It0 begin0, const It0 end0, const It1 begin1, const It1 end1) BL_NOEXCEPT { It0 it0 = begin0; It1 it1 = begin1; for (; it0 != end0; ++it0, ++it1) if (it1 == end1 || *it0 != *it1) return false; return true; } template void simple_copy(const It begin, const It end, OutIt out) BL_NOEXCEPT { for (It it = begin; it != end; ++it, ++out) *out = *it; } template bool test(const T (&arr)[Size]) { bool ok; T out_rev_arr[Size]; T out_fwd_arr[Size]; T out_first_half_arr[Size / 2]; #pragma omp target defaultmap(none) \ map(from: ok, out_rev_arr[:Size], out_fwd_arr[:Size], \ out_first_half_arr[:Size / 2]) \ map(to: arr[:Size]) { bool inner_ok = true; { std::span span = {arr, Size}; std::vector rev_vec(std::reverse_iterator{span.end()}, std::reverse_iterator{span.begin()}); VERIFY (std::distance(span.begin(), span.end()) == std::distance(rev_vec.begin(), rev_vec.end())); VERIFY (stdr::distance(span.begin(), span.end()) == stdr::distance(rev_vec.begin(), rev_vec.end())); VERIFY (stdr::distance(span) == stdr::distance(rev_vec)); VERIFY (simple_equal(span.begin(), span.end(), std::reverse_iterator{rev_vec.end()}, std::reverse_iterator{rev_vec.begin()})); simple_copy(rev_vec.begin(), rev_vec.end(), out_rev_arr); simple_copy(std::reverse_iterator{rev_vec.end()}, std::reverse_iterator{rev_vec.begin()}, out_fwd_arr); using counted_iter = std::counted_iterator; using common_iter = std::common_iterator; std::vector front_half; simple_copy(common_iter{counted_iter{span.begin(), Size / 2}}, common_iter{std::default_sentinel}, std::back_insert_iterator{front_half}); VERIFY (simple_equal(span.begin(), stdr::next(span.begin(), Size / 2), front_half.begin(), front_half.end())); simple_copy(front_half.begin(), front_half.end(), out_first_half_arr); } end: ok = inner_ok; } VERIFY_NON_TARGET (simple_equal(std::reverse_iterator{arr + Size}, std::reverse_iterator{arr}, out_rev_arr, out_rev_arr + Size)); VERIFY_NON_TARGET (simple_equal(arr, arr + Size, out_fwd_arr, out_fwd_arr + Size)); VERIFY_NON_TARGET (simple_equal(arr, arr + Size / 2, out_first_half_arr, out_first_half_arr + Size / 2)); return ok; } int main() { int arr[] = {0, 1, 2, 3, 4, 5, 6, 7}; return test(arr) ? 0 : 1; }