| /* { dg-additional-options "-std=c++20" } */ |
| |
| /* Functional */ |
| |
| #include <functional> |
| #include <utility> |
| |
| #include "target-flex-common.h" |
| |
| template<typename T,typename Fn> |
| auto invoke_unary(T&& a, Fn&& fn) noexcept |
| { |
| return std::invoke(std::forward<Fn>(fn), |
| std::forward<T>(a)); |
| } |
| |
| template<typename T, typename U, typename Fn> |
| auto invoke_binary(T&& a, U&& b, Fn&& fn) noexcept |
| { |
| return std::invoke(std::forward<Fn>(fn), |
| std::forward<T>(a), |
| std::forward<U>(b)); |
| } |
| |
| bool test(unsigned arg) |
| { |
| bool ok; |
| #pragma omp target map(from: ok) map(to: arg) |
| { |
| bool inner_ok = true; |
| { |
| VERIFY (std::plus{}(arg, 2) == arg + 2); |
| auto bound_plus_arg = std::bind_front(std::plus{}, arg); |
| VERIFY (bound_plus_arg(10) == arg + 10); |
| VERIFY (bound_plus_arg(20) == arg + 20); |
| |
| VERIFY (std::not_fn(std::not_equal_to{})(arg, arg)); |
| VERIFY (invoke_binary(arg, arg, std::not_fn(std::not_equal_to{}))); |
| auto bound_equals_arg = std::bind_front(std::not_fn(std::not_equal_to{}), arg); |
| VERIFY (bound_equals_arg(arg)); |
| VERIFY (std::not_fn(bound_equals_arg)(arg + 1)); |
| VERIFY (invoke_unary(arg, bound_equals_arg)); |
| |
| VERIFY (std::not_fn(std::ranges::not_equal_to{})(arg, arg)); |
| VERIFY (invoke_binary(arg, arg, std::not_fn(std::ranges::not_equal_to{}))); |
| auto bound_ranges_equals_arg = std::bind_front(std::not_fn(std::ranges::not_equal_to{}), arg); |
| VERIFY (bound_ranges_equals_arg(arg)); |
| VERIFY (std::not_fn(bound_ranges_equals_arg)(arg + 1)); |
| VERIFY (invoke_unary(arg, bound_ranges_equals_arg)); |
| } |
| end: |
| ok = inner_ok; |
| } |
| return ok; |
| } |
| |
| int main() |
| { |
| volatile unsigned arg = 42u; |
| return test(arg) ? 0 : 1; |
| } |