Skip to content

Commit

Permalink
Fixed remove*, replace, reverse, search, and transform algorithms
Browse files Browse the repository at this point in the history
  • Loading branch information
hkaiser committed Jun 30, 2017
1 parent 6f4c238 commit dce77a9
Show file tree
Hide file tree
Showing 18 changed files with 336 additions and 184 deletions.
110 changes: 66 additions & 44 deletions hpx/parallel/algorithms/remove_copy.hpp
Expand Up @@ -36,9 +36,9 @@ namespace hpx { namespace parallel { inline namespace v1
/// \cond NOINTERNAL

// sequential remove_copy
template <typename InIter, typename OutIter, typename T, typename Proj>
inline std::pair<InIter, OutIter>
sequential_remove_copy(InIter first, InIter last, OutIter dest,
template <typename FwdIter, typename OutIter, typename T, typename Proj>
inline std::pair<FwdIter, OutIter>
sequential_remove_copy(FwdIter first, FwdIter last, OutIter dest,
T const& value, Proj && proj)
{
for (/* */; first != last; ++first)
Expand All @@ -59,10 +59,10 @@ namespace hpx { namespace parallel { inline namespace v1
: remove_copy::algorithm("remove_copy")
{}

template <typename ExPolicy, typename InIter, typename OutIter,
template <typename ExPolicy, typename FwdIter, typename OutIter,
typename T, typename Proj>
static std::pair<InIter, OutIter>
sequential(ExPolicy, InIter first, InIter last,
static std::pair<FwdIter, OutIter>
sequential(ExPolicy, FwdIter first, FwdIter last,
OutIter dest, const T& val, Proj && proj)
{
return sequential_remove_copy(first, last, dest, val,
Expand All @@ -80,7 +80,7 @@ namespace hpx { namespace parallel { inline namespace v1
return copy_if<IterPair>().call(
std::forward<ExPolicy>(policy), std::false_type(),
first, last, dest,
[val, proj](T const& a)
[val, proj](T const& a) -> bool
{
HPX_UNUSED(proj);
return !(a == val);
Expand Down Expand Up @@ -108,14 +108,14 @@ namespace hpx { namespace parallel { inline namespace v1
/// It describes the manner in which the execution
/// of the algorithm may be parallelized and the manner
/// in which it executes the assignments.
/// \tparam InIter The type of the source iterators used (deduced).
/// \tparam FwdIter The type of the source iterators used (deduced).
/// This iterator type must meet the requirements of an
/// input iterator.
/// forward iterator.
/// \tparam OutIter The type of the iterator representing the
/// destination range (deduced).
/// This iterator type must meet the requirements of an
/// output iterator.
/// \tparam T The type that the result of dereferencing InIter is
/// forward iterator.
/// \tparam T The type that the result of dereferencing FwdIter is
/// compared to.
/// \tparam Proj The type of an optional projection function. This
/// defaults to \a util::projection_identity
Expand Down Expand Up @@ -144,38 +144,39 @@ namespace hpx { namespace parallel { inline namespace v1
/// within each thread.
///
/// \returns The \a remove_copy algorithm returns a
/// \a hpx::future<tagged_pair<tag::in(InIter), tag::out(OutIter)> >
/// \a hpx::future<tagged_pair<tag::in(FwdIter), tag::out(OutIter)> >
/// if the execution policy is of type
/// \a sequenced_task_policy or
/// \a parallel_task_policy and
/// returns \a tagged_pair<tag::in(InIter), tag::out(OutIter)>
/// returns \a tagged_pair<tag::in(FwdIter), tag::out(OutIter)>
/// otherwise.
/// The \a copy algorithm returns the pair of the input iterator
/// forwarded to the first element after the last in the input
/// sequence and the output iterator to the
/// element in the destination range, one past the last element
/// copied.
///
template <typename ExPolicy, typename InIter, typename OutIter, typename T,
template <typename ExPolicy, typename FwdIter, typename OutIter, typename T,
typename Proj = util::projection_identity,
HPX_CONCEPT_REQUIRES_(
execution::is_execution_policy<ExPolicy>::value &&
hpx::traits::is_iterator<InIter>::value &&
hpx::traits::is_iterator<FwdIter>::value &&
hpx::traits::is_iterator<OutIter>::value &&
traits::is_projected<Proj, InIter>::value &&
traits::is_projected<Proj, FwdIter>::value &&
traits::is_indirect_callable<
ExPolicy, std::equal_to<T>,
traits::projected<Proj, InIter>,
traits::projected<Proj, FwdIter>,
traits::projected<Proj, T const*>
>::value)>
typename util::detail::algorithm_result<
ExPolicy, hpx::util::tagged_pair<tag::in(InIter), tag::out(OutIter)>
ExPolicy, hpx::util::tagged_pair<tag::in(FwdIter), tag::out(OutIter)>
>::type
remove_copy(ExPolicy && policy, InIter first, InIter last, OutIter dest,
remove_copy(ExPolicy && policy, FwdIter first, FwdIter last, OutIter dest,
T const& val, Proj && proj = Proj())
{
#if defined(HPX_HAVE_ALGORITHM_INPUT_ITERATOR_SUPPORT)
static_assert(
(hpx::traits::is_input_iterator<InIter>::value),
(hpx::traits::is_input_iterator<FwdIter>::value),
"Requires at least input iterator.");
static_assert(
(hpx::traits::is_output_iterator<OutIter>::value ||
Expand All @@ -184,12 +185,22 @@ namespace hpx { namespace parallel { inline namespace v1

typedef std::integral_constant<bool,
execution::is_sequenced_execution_policy<ExPolicy>::value ||
!hpx::traits::is_forward_iterator<InIter>::value ||
!hpx::traits::is_forward_iterator<FwdIter>::value ||
!hpx::traits::is_forward_iterator<OutIter>::value
> is_seq;
#else
static_assert(
(hpx::traits::is_forward_iterator<FwdIter>::value),
"Requires at least forward iterator.");
static_assert(
(hpx::traits::is_forward_iterator<OutIter>::value),
"Requires at least forward iterator.");

typedef execution::is_sequenced_execution_policy<ExPolicy> is_seq;
#endif

return hpx::util::make_tagged_pair<tag::in, tag::out>(
detail::remove_copy<std::pair<InIter, OutIter> >().call(
detail::remove_copy<std::pair<FwdIter, OutIter> >().call(
std::forward<ExPolicy>(policy), is_seq(),
first, last, dest, val, std::forward<Proj>(proj)));
}
Expand All @@ -201,9 +212,9 @@ namespace hpx { namespace parallel { inline namespace v1
/// \cond NOINTERNAL

// sequential remove_copy_if
template <typename InIter, typename OutIter, typename F, typename Proj>
inline std::pair<InIter, OutIter>
sequential_remove_copy_if(InIter first, InIter last, OutIter dest, F p,
template <typename FwdIter, typename OutIter, typename F, typename Proj>
inline std::pair<FwdIter, OutIter>
sequential_remove_copy_if(FwdIter first, FwdIter last, OutIter dest, F p,
Proj && proj)
{
for (/* */; first != last; ++first)
Expand All @@ -225,10 +236,10 @@ namespace hpx { namespace parallel { inline namespace v1
: remove_copy_if::algorithm("remove_copy_if")
{}

template <typename ExPolicy, typename InIter, typename OutIter,
template <typename ExPolicy, typename FwdIter, typename OutIter,
typename F, typename Proj>
static std::pair<InIter, OutIter>
sequential(ExPolicy, InIter first, InIter last,
static std::pair<FwdIter, OutIter>
sequential(ExPolicy, FwdIter first, FwdIter last,
OutIter dest, F && f, Proj && proj)
{
return sequential_remove_copy_if(first, last, dest,
Expand All @@ -249,7 +260,7 @@ namespace hpx { namespace parallel { inline namespace v1
return copy_if<IterPair>().call(
std::forward<ExPolicy>(policy), std::false_type(),
first, last, dest,
[f](value_type const& a)
[f](value_type const& a) -> bool
{
return !hpx::util::invoke(f, a);
},
Expand Down Expand Up @@ -277,13 +288,13 @@ namespace hpx { namespace parallel { inline namespace v1
/// It describes the manner in which the execution
/// of the algorithm may be parallelized and the manner
/// in which it executes the assignments.
/// \tparam InIter The type of the source iterators used (deduced).
/// \tparam FwdIter The type of the source iterators used (deduced).
/// This iterator type must meet the requirements of an
/// input iterator.
/// forward iterator.
/// \tparam OutIter The type of the iterator representing the
/// destination range (deduced).
/// This iterator type must meet the requirements of an
/// output iterator.
/// forward iterator.
/// \tparam F The type of the function/function object to use
/// (deduced). Unlike its sequential form, the parallel
/// overload of \a copy_if requires \a F to meet the
Expand All @@ -310,7 +321,7 @@ namespace hpx { namespace parallel { inline namespace v1
/// The signature does not need to have const&, but
/// the function must not modify the objects passed to
/// it. The type \a Type must be such that an object of
/// type \a InIter can be dereferenced and then
/// type \a FwdIter can be dereferenced and then
/// implicitly converted to Type.
/// \param proj Specifies the function (or function object) which
/// will be invoked for each of the elements as a
Expand All @@ -328,36 +339,37 @@ namespace hpx { namespace parallel { inline namespace v1
/// within each thread.
///
/// \returns The \a remove_copy_if algorithm returns a
/// \a hpx::future<tagged_pair<tag::in(InIter), tag::out(OutIter)> >
/// \a hpx::future<tagged_pair<tag::in(FwdIter), tag::out(OutIter)> >
/// if the execution policy is of type
/// \a sequenced_task_policy or
/// \a parallel_task_policy and
/// returns \a tagged_pair<tag::in(InIter), tag::out(OutIter)>
/// returns \a tagged_pair<tag::in(FwdIter), tag::out(OutIter)>
/// otherwise.
/// The \a copy algorithm returns the pair of the input iterator
/// forwarded to the first element after the last in the input
/// sequence and the output iterator to the
/// element in the destination range, one past the last element
/// copied.
///
template <typename ExPolicy, typename InIter, typename OutIter, typename F,
template <typename ExPolicy, typename FwdIter, typename OutIter, typename F,
typename Proj = util::projection_identity,
HPX_CONCEPT_REQUIRES_(
execution::is_execution_policy<ExPolicy>::value &&
hpx::traits::is_iterator<InIter>::value &&
traits::is_projected<Proj, InIter>::value &&
hpx::traits::is_iterator<FwdIter>::value &&
traits::is_projected<Proj, FwdIter>::value &&
traits::is_indirect_callable<
ExPolicy, F, traits::projected<Proj, InIter>
ExPolicy, F, traits::projected<Proj, FwdIter>
>::value &&
hpx::traits::is_iterator<OutIter>::value)>
typename util::detail::algorithm_result<
ExPolicy, hpx::util::tagged_pair<tag::in(InIter), tag::out(OutIter)>
ExPolicy, hpx::util::tagged_pair<tag::in(FwdIter), tag::out(OutIter)>
>::type
remove_copy_if(ExPolicy && policy, InIter first, InIter last, OutIter dest,
remove_copy_if(ExPolicy && policy, FwdIter first, FwdIter last, OutIter dest,
F && f, Proj && proj = Proj())
{
#if defined(HPX_HAVE_ALGORITHM_INPUT_ITERATOR_SUPPORT)
static_assert(
(hpx::traits::is_input_iterator<InIter>::value),
(hpx::traits::is_input_iterator<FwdIter>::value),
"Requires at least input iterator.");
static_assert(
(hpx::traits::is_output_iterator<OutIter>::value ||
Expand All @@ -366,12 +378,22 @@ namespace hpx { namespace parallel { inline namespace v1

typedef std::integral_constant<bool,
execution::is_sequenced_execution_policy<ExPolicy>::value ||
!hpx::traits::is_forward_iterator<InIter>::value ||
!hpx::traits::is_forward_iterator<FwdIter>::value ||
!hpx::traits::is_forward_iterator<OutIter>::value
> is_seq;
#else
static_assert(
(hpx::traits::is_forward_iterator<FwdIter>::value),
"Requires at least forward iterator.");
static_assert(
(hpx::traits::is_forward_iterator<OutIter>::value),
"Requires at least forward iterator.");

typedef execution::is_sequenced_execution_policy<ExPolicy> is_seq;
#endif

return hpx::util::make_tagged_pair<tag::in, tag::out>(
detail::remove_copy_if<std::pair<InIter, OutIter> >().call(
detail::remove_copy_if<std::pair<FwdIter, OutIter> >().call(
std::forward<ExPolicy>(policy), is_seq(),
first, last, dest, std::forward<F>(f),
std::forward<Proj>(proj)));
Expand Down

0 comments on commit dce77a9

Please sign in to comment.