-
-
Notifications
You must be signed in to change notification settings - Fork 435
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Contains and contains_subrange parallel algorithm implementaion
- Loading branch information
1 parent
ba8f05f
commit 1f8897c
Showing
3 changed files
with
130 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
128 changes: 128 additions & 0 deletions
128
libs/core/algorithms/include/hpx/parallel/algorithms/contains.hpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
#pragma once | ||
|
||
#include <hpx/config.hpp> | ||
#include <hpx/execution/algorithms/detail/predicates.hpp> | ||
#include <hpx/executors/execution_policy.hpp> | ||
#include <hpx/iterator_support/traits/is_iterator.hpp> | ||
#include <hpx/parallel/algorithms/detail/dispatch.hpp> | ||
#include <hpx/parallel/algorithms/detail/distance.hpp> | ||
#include <hpx/parallel/util/detail/algorithm_result.hpp> | ||
#include <hpx/parallel/util/loop.hpp> | ||
#include <hpx/type_support/identity.hpp> | ||
|
||
#include <algorithm> | ||
#include <cstddef> | ||
#include <iterator> | ||
#include <type_traits> | ||
#include <utility> | ||
|
||
namespace hpx::parallel { | ||
namespace detail { | ||
struct contains : public algorithm<contains, bool> | ||
{ | ||
constexpr contains() noexcept | ||
: algorithm("contains") | ||
{ | ||
|
||
} | ||
|
||
template <typename ExPolicy, typename Iterator, typename Sentinel, | ||
typename T, typename Proj> | ||
static constexpr bool sequential(ExPolicy, Iterator first, | ||
Sentinel last, const T& val, Proj&& proj) | ||
{ | ||
auto const distance = detail::distance(first, last); | ||
if (distance <= 0) | ||
return false; | ||
|
||
const auto itr = util::loop_pred< | ||
std::decay_t<hpx::execution::sequenced_policy>>(first, last, | ||
[&val, &proj] (const auto& cur) | ||
{ return HPX_INVOKE(proj, *cur) == val; }); | ||
|
||
return itr != last; | ||
} | ||
|
||
template <typename ExPolicy, typename Iterator, typename Sentinel, | ||
typename T, typename Proj> | ||
static util::detail::algorithm_result_t<ExPolicy, bool> parallel( | ||
ExPolicy&& policy, Iterator first, Sentinel last, const T& val, | ||
Proj&& proj) | ||
{ | ||
const auto distance = detail::distance(first, last); | ||
if (distance <= 0) | ||
{ | ||
return util::detail::algorithm_result<ExPolicy, bool>::get( | ||
false); | ||
} | ||
|
||
const auto itr = util::loop_pred< | ||
std::decay_t<ExPolicy>>(first, last, [&val, &proj] | ||
(const auto& cur) { return HPX_INVOKE(proj, *cur) == val; }); | ||
|
||
if (itr == last) | ||
{ | ||
return util::detail::algorithm_result<ExPolicy, bool>::get( | ||
false); | ||
} | ||
|
||
return util::detail::algorithm_result<ExPolicy, bool>::get(true); | ||
} | ||
|
||
}; | ||
} | ||
} | ||
namespace hpx { | ||
|
||
inline constexpr struct contains_t final | ||
: hpx::functional::detail::tag_fallback<contains_t> | ||
{ | ||
private: | ||
template <typename Iterator, typename Sentinel, | ||
typename T, typename Proj = hpx::identity, | ||
HPX_CONCEPT_REQUIRES_( | ||
hpx::traits::is_iterator_v<Iterator> && | ||
hpx::traits::is_iterator_v<Iterator> && | ||
hpx::is_invocable_v<Proj, | ||
typename std::iterator_traits<Iterator>::value_type> | ||
)> | ||
|
||
friend bool tag_fallback_invoke(hpx::contains_t, Iterator first, | ||
Sentinel last, const T& val, Proj&& proj = Proj()) | ||
{ | ||
static_assert(hpx::traits::is_input_iterator_v<Iterator>, | ||
"Required at least input iterator."); | ||
|
||
static_assert(hpx::traits::is_input_iterator_v<Sentinel>, | ||
"Required at least input iterator."); | ||
|
||
return hpx::parallel::detail::contains().call(hpx::execution::seq, | ||
first, last, val, proj); | ||
} | ||
|
||
template <typename ExPolicy, typename Iterator, typename Sentinel, | ||
typename T, typename Proj = hpx::identity, HPX_CONCEPT_REQUIRES_( | ||
hpx::is_execution_policy_v<ExPolicy> && | ||
hpx::traits::is_iterator_v<Iterator> && | ||
hpx::traits::is_iterator_v<Iterator> && | ||
hpx::is_invocable_v<Proj, | ||
typename std::iterator_traits<Iterator>::value_type>)> | ||
|
||
friend typename parallel::util::detail::algorithm_result<ExPolicy, | ||
bool>::type | ||
tag_fallback_invoke(hpx::contains_t, ExPolicy&& policy, Iterator first, | ||
Sentinel last, T const& val, Proj&& proj = Proj()) | ||
{ | ||
static_assert(hpx::traits::is_iterator_v<Iterator>, | ||
"Required at least iterator."); | ||
|
||
static_assert(hpx::traits::is_iterator_v<Sentinel>, | ||
"Required at least iterator."); | ||
|
||
return hpx::parallel::detail::contains().call( | ||
HPX_FORWARD(ExPolicy, policy), first, last, val, | ||
HPX_FORWARD(Proj, proj)); | ||
} | ||
|
||
} contains{}; | ||
} |