From c64e4235db8f3e16e23bcf0bf34f225616f943b4 Mon Sep 17 00:00:00 2001 From: Hartmut Kaiser Date: Wed, 10 Nov 2021 12:25:41 -0600 Subject: [PATCH] Adapting adjacent_difference to work with proxy iterators - fixing assignment operator for proxy objects returned from segmented iterators - adding proxy_value traits allowing to extract type returned by a proxy - flyby: modernize adjacent_difference algorithm, adding missing concept checks --- .../partitioned_vector_segmented_iterator.hpp | 23 ++- .../hpx/algorithms/traits/is_value_proxy.hpp | 14 ++ .../algorithms/adjacent_difference.hpp | 76 ++++++---- .../adjacent_difference.hpp | 136 ++++++++++-------- .../regressions/for_each_value_proxy.cpp | 6 + .../include/hpx/compute/cuda/value_proxy.hpp | 6 + .../adjacent_difference.hpp | 123 ++++++++-------- 7 files changed, 232 insertions(+), 152 deletions(-) diff --git a/components/containers/partitioned_vector/include/hpx/components/containers/partitioned_vector/partitioned_vector_segmented_iterator.hpp b/components/containers/partitioned_vector/include/hpx/components/containers/partitioned_vector/partitioned_vector_segmented_iterator.hpp index 63764a522d14..7cef2e12f2dd 100644 --- a/components/containers/partitioned_vector/include/hpx/components/containers/partitioned_vector/partitioned_vector_segmented_iterator.hpp +++ b/components/containers/partitioned_vector/include/hpx/components/containers/partitioned_vector/partitioned_vector_segmented_iterator.hpp @@ -157,7 +157,9 @@ namespace hpx { namespace segmented { return *(it_.get_data()->begin() + it_.get_local_index()); } - template + template , local_vector_value_proxy>>> local_vector_value_proxy& operator=(T_&& value) { if (!it_.get_data()) @@ -214,7 +216,9 @@ namespace hpx { namespace segmented { return v_.get_value(launch::sync, index_); } - template + template , vector_value_proxy>>> vector_value_proxy& operator=(T_&& value) { v_.set_value(launch::sync, index_, std::forward(value)); @@ -1230,8 +1234,21 @@ namespace hpx { namespace traits { }; template - struct is_value_proxy> + struct proxy_value< + hpx::segmented::detail::local_vector_value_proxy> : std::true_type { }; + + template + struct is_value_proxy> + { + using type = T; + }; + + template + struct proxy_value> + { + using type = T; + }; }} // namespace hpx::traits diff --git a/libs/core/algorithms/include/hpx/algorithms/traits/is_value_proxy.hpp b/libs/core/algorithms/include/hpx/algorithms/traits/is_value_proxy.hpp index c27acd661867..8673009f2046 100644 --- a/libs/core/algorithms/include/hpx/algorithms/traits/is_value_proxy.hpp +++ b/libs/core/algorithms/include/hpx/algorithms/traits/is_value_proxy.hpp @@ -11,8 +11,22 @@ #include namespace hpx { namespace traits { + template struct is_value_proxy : std::false_type { }; + + template + HPX_INLINE_CONSTEXPR_VARIABLE bool is_value_proxy_v = + is_value_proxy::value; + + template + struct proxy_value + { + using type = T; + }; + + template + using proxy_value_t = typename proxy_value::type; }} // namespace hpx::traits diff --git a/libs/core/algorithms/include/hpx/parallel/algorithms/adjacent_difference.hpp b/libs/core/algorithms/include/hpx/parallel/algorithms/adjacent_difference.hpp index a210c090af6d..1dbbca1010c8 100644 --- a/libs/core/algorithms/include/hpx/parallel/algorithms/adjacent_difference.hpp +++ b/libs/core/algorithms/include/hpx/parallel/algorithms/adjacent_difference.hpp @@ -152,6 +152,7 @@ namespace hpx { #include #include +#include #include #include #include @@ -199,20 +200,25 @@ namespace hpx { namespace parallel { inline namespace v1 { parallel(ExPolicy&& policy, FwdIter1 first, Sent last, FwdIter2 dest, Op&& op) { - typedef hpx::util::zip_iterator - zip_iterator; - typedef util::detail::algorithm_result - result; - typedef typename std::iterator_traits::difference_type - difference_type; + using zip_iterator = + hpx::util::zip_iterator; + using result = + util::detail::algorithm_result; + using difference_type = + typename std::iterator_traits::difference_type; if (first == last) + { return result::get(std::move(dest)); + } difference_type count = detail::distance(first, last) - 1; FwdIter1 prev = first; - *dest++ = *first++; + hpx::traits::proxy_value_t< + typename std::iterator_traits::value_type> + tmp = *first++; + *dest++ = std::move(tmp); if (count == 0) { @@ -255,10 +261,10 @@ namespace hpx { namespace parallel { inline namespace v1 { HPX_DEPRECATED_V(1, 8, "hpx::parallel::adjacent_difference is deprecated, use " "hpx::adjacent_difference instead") - inline typename std::enable_if::value, - typename util::detail::algorithm_result::type>::type - adjacent_difference( - ExPolicy&& policy, FwdIter1 first, FwdIter1 last, FwdIter2 dest) + inline std::enable_if_t, + util::detail::algorithm_result_t> adjacent_difference(ExPolicy&& policy, FwdIter1 first, + FwdIter1 last, FwdIter2 dest) { #if defined(HPX_GCC_VERSION) && HPX_GCC_VERSION >= 100000 #pragma GCC diagnostic push @@ -276,10 +282,10 @@ namespace hpx { namespace parallel { inline namespace v1 { HPX_DEPRECATED_V(1, 8, "hpx::parallel::adjacent_difference is deprecated, use " "hpx::adjacent_difference instead") - inline typename std::enable_if::value, - typename util::detail::algorithm_result::type>::type - adjacent_difference(ExPolicy&& policy, FwdIter1 first, FwdIter1 last, - FwdIter2 dest, Op&& op) + inline std::enable_if_t, + util::detail::algorithm_result_t> adjacent_difference(ExPolicy&& policy, FwdIter1 first, + FwdIter1 last, FwdIter2 dest, Op&& op) { return detail::adjacent_difference().call( std::forward(policy), first, last, dest, @@ -297,13 +303,16 @@ namespace hpx { private: template ::value + hpx::traits::is_iterator_v && + hpx::traits::is_iterator_v )> // clang-format on friend FwdIter2 tag_fallback_invoke(hpx::adjacent_difference_t, FwdIter1 first, FwdIter1 last, FwdIter2 dest) { - static_assert((hpx::traits::is_forward_iterator::value), + static_assert(hpx::traits::is_forward_iterator_v, + "Required at least forward iterator."); + static_assert(hpx::traits::is_forward_iterator_v, "Required at least forward iterator."); return hpx::parallel::v1::detail::adjacent_difference() @@ -314,16 +323,19 @@ namespace hpx { // clang-format off template ::value && - hpx::traits::is_iterator::value + hpx::is_execution_policy_v && + hpx::traits::is_iterator_v && + hpx::traits::is_iterator_v )> // clang-format on - friend typename parallel::util::detail::algorithm_result::type + friend hpx::parallel::util::detail::algorithm_result_t tag_fallback_invoke(hpx::adjacent_difference_t, ExPolicy&& policy, FwdIter1 first, FwdIter1 last, FwdIter2 dest) { - static_assert((hpx::traits::is_forward_iterator::value), + static_assert(hpx::traits::is_forward_iterator_v, + "Required at least forward iterator."); + static_assert(hpx::traits::is_forward_iterator_v, "Required at least forward iterator."); return hpx::parallel::v1::detail::adjacent_difference() @@ -334,13 +346,16 @@ namespace hpx { // clang-format off template ::value + hpx::traits::is_iterator_v && + hpx::traits::is_iterator_v )> // clang-format on friend FwdIter2 tag_fallback_invoke(hpx::adjacent_difference_t, FwdIter1 first, FwdIter1 last, FwdIter2 dest, Op&& op) { - static_assert((hpx::traits::is_forward_iterator::value), + static_assert(hpx::traits::is_forward_iterator_v, + "Required at least forward iterator."); + static_assert(hpx::traits::is_forward_iterator_v, "Required at least forward iterator."); return hpx::parallel::v1::detail::adjacent_difference() @@ -351,16 +366,19 @@ namespace hpx { // clang-format off template ::value && - hpx::traits::is_iterator::value + hpx::is_execution_policy_v && + hpx::traits::is_iterator_v && + hpx::traits::is_iterator_v )> // clang-format on - friend typename parallel::util::detail::algorithm_result::type + friend hpx::parallel::util::detail::algorithm_result_t tag_fallback_invoke(hpx::adjacent_difference_t, ExPolicy&& policy, FwdIter1 first, FwdIter1 last, FwdIter2 dest, Op&& op) { - static_assert((hpx::traits::is_forward_iterator::value), + static_assert(hpx::traits::is_forward_iterator_v, + "Required at least forward iterator."); + static_assert(hpx::traits::is_forward_iterator_v, "Required at least forward iterator."); return hpx::parallel::v1::detail::adjacent_difference() diff --git a/libs/core/algorithms/include/hpx/parallel/container_algorithms/adjacent_difference.hpp b/libs/core/algorithms/include/hpx/parallel/container_algorithms/adjacent_difference.hpp index 1bd032c4e29a..1432753d91d4 100644 --- a/libs/core/algorithms/include/hpx/parallel/container_algorithms/adjacent_difference.hpp +++ b/libs/core/algorithms/include/hpx/parallel/container_algorithms/adjacent_difference.hpp @@ -269,6 +269,7 @@ namespace hpx { namespace ranges { #include namespace hpx { namespace ranges { + HPX_INLINE_CONSTEXPR_VARIABLE struct adjacent_difference_t final : hpx::detail::tag_parallel_algorithm { @@ -276,106 +277,108 @@ namespace hpx { namespace ranges { // clang-format off template ::value && - hpx::traits::is_sentinel_for::value + hpx::traits::is_iterator_v && + hpx::traits::is_iterator_v && + hpx::traits::is_sentinel_for_v )> - // clang-format on friend FwdIter2 tag_fallback_invoke(hpx::ranges::adjacent_difference_t, FwdIter1 first, Sent last, FwdIter2 dest) { - static_assert((hpx::traits::is_forward_iterator::value), + static_assert(hpx::traits::is_forward_iterator_v, + "Required at least forward iterator."); + static_assert(hpx::traits::is_forward_iterator_v, "Required at least forward iterator."); - typedef - typename std::iterator_traits::value_type value_type; return hpx::parallel::v1::detail::adjacent_difference() - .call(hpx::execution::seq, first, last, dest, - std::minus()); + .call(hpx::execution::seq, first, last, dest, std::minus<>()); } // clang-format off template ::value && - hpx::traits::is_iterator::value + hpx::traits::is_range_v && + hpx::traits::is_iterator_v )> - // clang-format on friend FwdIter2 tag_fallback_invoke( hpx::ranges::adjacent_difference_t, Rng&& rng, FwdIter2 dest) { - static_assert((hpx::traits::is_forward_iterator< - hpx::traits::range_iterator_t>::value), + static_assert(hpx::traits::is_forward_iterator_v< + hpx::traits::range_iterator_t>, + "Required at least forward iterator."); + static_assert(hpx::traits::is_forward_iterator_v, "Required at least forward iterator."); - typedef typename std::iterator_traits< - hpx::traits::range_iterator_t>::value_type value_type; return hpx::parallel::v1::detail::adjacent_difference() .call(hpx::execution::seq, hpx::util::begin(rng), - hpx::util::end(rng), dest, std::minus()); + hpx::util::end(rng), dest, std::minus<>()); } // clang-format off - template ::value && - hpx::traits::is_iterator::value && - hpx::traits::is_sentinel_for::value + hpx::is_execution_policy_v && + hpx::traits::is_iterator_v && + hpx::traits::is_iterator_v && + hpx::traits::is_sentinel_for_v )> // clang-format on - friend typename parallel::util::detail::algorithm_result::type + friend hpx::parallel::util::detail::algorithm_result_t tag_fallback_invoke(hpx::ranges::adjacent_difference_t, ExPolicy&& policy, FwdIter1 first, Sent last, FwdIter2 dest) { - static_assert((hpx::traits::is_forward_iterator::value), + static_assert(hpx::traits::is_forward_iterator_v, + "Required at least forward iterator."); + static_assert(hpx::traits::is_forward_iterator_v, "Required at least forward iterator."); - typedef - typename std::iterator_traits::value_type value_type; - - // typedef hpx::is_sequenced_execution_policy is_seq; return hpx::parallel::v1::detail::adjacent_difference() .call(std::forward(policy), first, last, dest, - std::minus()); + std::minus<>()); } // clang-format off template ::value && - hpx::traits::is_range::value && - hpx::traits::is_iterator::value + hpx::is_execution_policy_v && + hpx::traits::is_range_v && + hpx::traits::is_iterator_v )> // clang-format on - friend typename parallel::util::detail::algorithm_result::type + friend hpx::parallel::util::detail::algorithm_result_t tag_fallback_invoke(hpx::ranges::adjacent_difference_t, ExPolicy&& policy, Rng&& rng, FwdIter2 dest) { - static_assert((hpx::traits::is_forward_iterator< - hpx::traits::range_iterator_t>::value), + static_assert(hpx::traits::is_forward_iterator_v< + hpx::traits::range_iterator_t>, + "Required at least forward iterator."); + static_assert(hpx::traits::is_forward_iterator_v, "Required at least forward iterator."); - typedef typename std::iterator_traits< - hpx::traits::range_iterator_t>::value_type value_type; return hpx::parallel::v1::detail::adjacent_difference() .call(std::forward(policy), hpx::util::begin(rng), - hpx::util::end(rng), dest, std::minus()); + hpx::util::end(rng), dest, std::minus<>()); } // clang-format off - template ::value && - hpx::traits::is_sentinel_for::value + hpx::traits::is_iterator_v && + hpx::traits::is_iterator_v && + hpx::traits::is_sentinel_for_v )> // clang-format on friend FwdIter2 tag_fallback_invoke(hpx::ranges::adjacent_difference_t, FwdIter1 first, Sent last, FwdIter2 dest, Op&& op) { - static_assert((hpx::traits::is_forward_iterator::value), + static_assert(hpx::traits::is_forward_iterator_v, + "Required at least forward iterator."); + static_assert(hpx::traits::is_forward_iterator_v, "Required at least forward iterator."); return hpx::parallel::v1::detail::adjacent_difference() @@ -386,14 +389,17 @@ namespace hpx { namespace ranges { // clang-format off template ::value + hpx::traits::is_range_v && + hpx::traits::is_iterator_v )> // clang-format on friend FwdIter2 tag_fallback_invoke(hpx::ranges::adjacent_difference_t, Rng&& rng, FwdIter2 dest, Op&& op) { - static_assert((hpx::traits::is_forward_iterator< - hpx::traits::range_iterator_t>::value), + static_assert(hpx::traits::is_forward_iterator_v< + hpx::traits::range_iterator_t>, + "Required at least forward iterator."); + static_assert(hpx::traits::is_forward_iterator_v, "Required at least forward iterator."); return hpx::parallel::v1::detail::adjacent_difference() @@ -402,22 +408,24 @@ namespace hpx { namespace ranges { } // clang-format off - template ::value && - hpx::traits::is_iterator::value && - hpx::traits::is_iterator::value + hpx::is_execution_policy_v && + hpx::traits::is_iterator_v && + hpx::traits::is_iterator_v && + hpx::traits::is_sentinel_for_v )> - // clang-format on - friend typename parallel::util::detail::algorithm_result::type + friend hpx::parallel::util::detail::algorithm_result_t tag_fallback_invoke(hpx::ranges::adjacent_difference_t, ExPolicy&& policy, FwdIter1 first, Sent last, FwdIter2 dest, Op&& op) { - static_assert((hpx::traits::is_forward_iterator::value), + static_assert(hpx::traits::is_forward_iterator_v, + "Required at least forward iterator."); + static_assert(hpx::traits::is_forward_iterator_v, "Required at least forward iterator."); return hpx::parallel::v1::detail::adjacent_difference() @@ -426,27 +434,29 @@ namespace hpx { namespace ranges { } // clang-format off - template ::value && - hpx::traits::is_iterator::value + hpx::is_execution_policy_v && + hpx::traits::is_range_v && + hpx::traits::is_iterator_v )> - // clang-format on - friend typename parallel::util::detail::algorithm_result::type + friend hpx::parallel::util::detail::algorithm_result_t tag_fallback_invoke(hpx::ranges::adjacent_difference_t, ExPolicy&& policy, Rng&& rng, FwdIter2 dest, Op&& op) { - static_assert((hpx::traits::is_forward_iterator< - hpx::traits::range_iterator_t>::value), + static_assert(hpx::traits::is_forward_iterator_v< + hpx::traits::range_iterator_t>, + "Required at least forward iterator."); + static_assert(hpx::traits::is_forward_iterator_v, "Required at least forward iterator."); return hpx::parallel::v1::detail::adjacent_difference() .call(std::forward(policy), hpx::util::begin(rng), hpx::util::end(rng), dest, std::forward(op)); } - } adjacent_difference{}; }} // namespace hpx::ranges diff --git a/libs/full/compute/tests/regressions/for_each_value_proxy.cpp b/libs/full/compute/tests/regressions/for_each_value_proxy.cpp index 500acb7f9c43..be7097e84842 100644 --- a/libs/full/compute/tests/regressions/for_each_value_proxy.cpp +++ b/libs/full/compute/tests/regressions/for_each_value_proxy.cpp @@ -60,6 +60,12 @@ namespace hpx { namespace traits { struct is_value_proxy> : std::true_type { }; + + template + struct proxy_value> + { + using type = T; + }; }} // namespace hpx::traits template diff --git a/libs/full/compute_cuda/include/hpx/compute/cuda/value_proxy.hpp b/libs/full/compute_cuda/include/hpx/compute/cuda/value_proxy.hpp index e1e198f92eaa..55f8204f47b1 100644 --- a/libs/full/compute_cuda/include/hpx/compute/cuda/value_proxy.hpp +++ b/libs/full/compute_cuda/include/hpx/compute/cuda/value_proxy.hpp @@ -134,6 +134,12 @@ namespace hpx { namespace traits { : std::true_type { }; + + template + struct proxy_value> + { + using type = T; + }; }} // namespace hpx::traits #endif diff --git a/libs/full/segmented_algorithms/include/hpx/parallel/segmented_algorithms/adjacent_difference.hpp b/libs/full/segmented_algorithms/include/hpx/parallel/segmented_algorithms/adjacent_difference.hpp index 10f67bc2adbe..f2a531699a3e 100644 --- a/libs/full/segmented_algorithms/include/hpx/parallel/segmented_algorithms/adjacent_difference.hpp +++ b/libs/full/segmented_algorithms/include/hpx/parallel/segmented_algorithms/adjacent_difference.hpp @@ -29,6 +29,7 @@ #include namespace hpx { namespace parallel { inline namespace v1 { + /////////////////////////////////////////////////////////////////////////// // segmented_adjacent_difference namespace detail { @@ -38,21 +39,23 @@ namespace hpx { namespace parallel { inline namespace v1 { // sequential remote implementation template - static typename util::detail::algorithm_result::type + hpx::parallel::util::detail::algorithm_result_t segmented_adjacent_difference(Algo&& algo, ExPolicy const& policy, FwdIter1 first, FwdIter1 last, FwdIter2 dest, Op&& op, std::true_type) { - typedef hpx::traits::segmented_iterator_traits traits1; - typedef hpx::traits::segmented_iterator_traits traits2; - typedef typename traits1::segment_iterator segment_iterator1; - typedef typename traits1::local_iterator local_iterator_type1; - typedef typename traits2::segment_iterator segment_iterator2; - typedef typename traits2::local_iterator local_iterator_type2; + using traits1 = hpx::traits::segmented_iterator_traits; + using traits2 = hpx::traits::segmented_iterator_traits; + using segment_iterator1 = typename traits1::segment_iterator; + using local_iterator_type1 = typename traits1::local_iterator; + using segment_iterator2 = typename traits2::segment_iterator; + using local_iterator_type2 = typename traits2::local_iterator; - typedef util::detail::algorithm_result result; + using result = + hpx::parallel::util::detail::algorithm_result; - FwdIter1 ending, beginning; FwdIter2 end_dest = dest, curr; std::advance(end_dest, std::distance(first, last)); @@ -97,12 +100,14 @@ namespace hpx { namespace parallel { inline namespace v1 { out = dispatch(traits2::get_id(sdest), algo, policy, std::true_type(), beg, end, ldest, op); - beginning = traits1::compose(sit, beg); + FwdIter1 beginning = traits1::compose(sit, beg); if (beginning != last) { if (curr != end_dest) - *curr = hpx::util::invoke( + { + *curr = HPX_INVOKE( op, *beginning, *std::prev(beginning)); + } } } } @@ -116,12 +121,15 @@ namespace hpx { namespace parallel { inline namespace v1 { { out = dispatch(traits2::get_id(sdest), algo, policy, std::true_type(), beg, end, ldest, op); - beginning = traits1::compose(sit, beg); + + FwdIter1 beginning = traits1::compose(sit, beg); if (beginning != last) { if (curr != end_dest) - *curr = hpx::util::invoke( + { + *curr = HPX_INVOKE( op, *beginning, *std::prev(beginning)); + } } } dest = traits2::compose(sdest, out); @@ -132,34 +140,38 @@ namespace hpx { namespace parallel { inline namespace v1 { // parallel remote implementation template - static typename util::detail::algorithm_result::type + hpx::parallel::util::detail::algorithm_result_t segmented_adjacent_difference(Algo&& algo, ExPolicy const& policy, FwdIter1 first, FwdIter1 last, FwdIter2 dest, Op&& op, std::false_type) { - typedef hpx::traits::segmented_iterator_traits traits1; - typedef hpx::traits::segmented_iterator_traits traits2; - typedef typename traits1::segment_iterator segment_iterator1; - typedef typename traits1::local_iterator local_iterator_type1; - typedef typename traits2::segment_iterator segment_iterator2; - typedef typename traits2::local_iterator local_iterator_type2; + using traits1 = hpx::traits::segmented_iterator_traits; + using traits2 = hpx::traits::segmented_iterator_traits; + using segment_iterator1 = typename traits1::segment_iterator; + using local_iterator_type1 = typename traits1::local_iterator; + using segment_iterator2 = typename traits2::segment_iterator; + using local_iterator_type2 = typename traits2::local_iterator; - typedef util::detail::algorithm_result result; + using result = + hpx::parallel::util::detail::algorithm_result; - typedef std::integral_constant::value> - forced_seq; + using forced_seq = std::integral_constant>; segment_iterator1 sit = traits1::segment(first); segment_iterator1 send = traits1::segment(last); segment_iterator2 sdest = traits2::segment(dest); - typedef std::vector> segment_type; + using segment_type = std::vector>; segment_type segments; - segments.reserve(std::distance(sit, send)); + + auto size = std::distance(sit, send); + segments.reserve(size); std::vector between_segments; - between_segments.reserve(std::distance(sit, send)); + between_segments.reserve(size); if (sit == send) { @@ -218,6 +230,7 @@ namespace hpx { namespace parallel { inline namespace v1 { std::list errors; parallel::util::detail::handle_remote_exceptions< ExPolicy>::call(r, errors); + auto ft = r.back().get(); auto odest = traits2::compose(sdest, ft); auto start = between_segments.begin(); @@ -225,8 +238,7 @@ namespace hpx { namespace parallel { inline namespace v1 { { FwdIter2 curr = dest; std::advance(curr, std::distance(first, *start)); - *curr = hpx::util::invoke( - op, *(*start), *std::prev(*start)); + *curr = HPX_INVOKE(op, *(*start), *std::prev(*start)); start = std::next(start); } return odest; @@ -244,58 +256,55 @@ namespace hpx { namespace segmented { template ::value && - hpx::traits::is_iterator::value && - hpx::traits::is_segmented_iterator::value && - hpx::traits::is_iterator::value && - hpx::traits::is_segmented_iterator::value)> + hpx::is_execution_policy_v && + hpx::traits::is_iterator_v && + hpx::traits::is_segmented_iterator_v && + hpx::traits::is_iterator_v && + hpx::traits::is_segmented_iterator_v + )> // clang-format on - typename parallel::util::detail::algorithm_result::type + hpx::parallel::util::detail::algorithm_result_t tag_invoke(hpx::adjacent_difference_t, ExPolicy&& policy, FwdIter1 first, FwdIter1 last, FwdIter2 dest, Op&& op) { - static_assert(hpx::traits::is_input_iterator::value, - "Requires at least forwrad iterator."); - - static_assert(hpx::traits::is_input_iterator::value, + static_assert(hpx::traits::is_forward_iterator_v, + "Requires at least forward iterator."); + static_assert(hpx::traits::is_forward_iterator_v, "Requires at least forward iterator."); - - typedef hpx::is_sequenced_execution_policy is_seq; - typedef parallel::util::detail::algorithm_result - result; if (first == last) { + using result = + hpx::parallel::util::detail::algorithm_result; return result::get(std::move(dest)); } - typedef hpx::traits::segmented_iterator_traits - iterator_traits; + using is_seq = hpx::is_sequenced_execution_policy; + using traits = hpx::traits::segmented_iterator_traits; return hpx::parallel::v1::detail::segmented_adjacent_difference( hpx::parallel::v1::detail::adjacent_difference< - typename iterator_traits::local_iterator>(), + typename traits::local_iterator>(), std::forward(policy), first, last, dest, std::forward(op), is_seq()); } // clang-format off - template ::value && - hpx::traits::is_segmented_iterator::value && - hpx::traits::is_iterator::value && - hpx::traits::is_segmented_iterator::value + hpx::traits::is_iterator_v && + hpx::traits::is_segmented_iterator_v && + hpx::traits::is_iterator_v && + hpx::traits::is_segmented_iterator_v )> // clang-format on InIter2 tag_invoke(hpx::adjacent_difference_t, InIter1 first, InIter1 last, InIter2 dest, Op&& op) { - static_assert(hpx::traits::is_input_iterator::value, + static_assert(hpx::traits::is_input_iterator_v, "Requires at least input iterator."); - - static_assert(hpx::traits::is_input_iterator::value, + static_assert(hpx::traits::is_input_iterator_v, "Requires at least input iterator."); if (first == last) @@ -303,11 +312,11 @@ namespace hpx { namespace segmented { return dest; } - typedef hpx::traits::segmented_iterator_traits iterator_traits; + using traits = hpx::traits::segmented_iterator_traits; return hpx::parallel::v1::detail::segmented_adjacent_difference( hpx::parallel::v1::detail::adjacent_difference< - typename iterator_traits::local_iterator>(), + typename traits::local_iterator>(), hpx::execution::seq, first, last, dest, std::forward(op), std::true_type{}); }