Skip to content

Commit

Permalink
Adding container based versions for parallel::reverse[_copy]
Browse files Browse the repository at this point in the history
- fixing return types for parallel::reverse
- adding tests
  • Loading branch information
hkaiser committed Dec 22, 2015
1 parent f252325 commit 3970ff4
Show file tree
Hide file tree
Showing 8 changed files with 882 additions and 27 deletions.
2 changes: 2 additions & 0 deletions docs/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,9 @@ set(doxygen_dependencies
"${PROJECT_SOURCE_DIR}/hpx/parallel/algorithms/uninitialized_fill.hpp"
"${PROJECT_SOURCE_DIR}/hpx/parallel/container_algorithms/copy.hpp"
"${PROJECT_SOURCE_DIR}/hpx/parallel/container_algorithms/for_each.hpp"
"${PROJECT_SOURCE_DIR}/hpx/parallel/container_algorithms/remove_copy.hpp"
"${PROJECT_SOURCE_DIR}/hpx/parallel/container_algorithms/replace.hpp"
"${PROJECT_SOURCE_DIR}/hpx/parallel/container_algorithms/reverse.hpp"
"${PROJECT_SOURCE_DIR}/hpx/parallel/container_algorithms/sort.hpp"
"${PROJECT_SOURCE_DIR}/hpx/parallel/container_algorithms/transform.hpp"
"${PROJECT_SOURCE_DIR}/hpx/parallel/executors/auto_chunk_size.hpp"
Expand Down
3 changes: 2 additions & 1 deletion hpx/include/parallel_reverse.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2007-2014 Hartmut Kaiser
// Copyright (c) 2007-2015 Hartmut Kaiser
// Copyright (c) 2014 Grant Mercer
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
Expand All @@ -8,5 +8,6 @@
#define HPX_PARALLEL_REVERSE_COPY_JUL_29_2014_0348PM

#include <hpx/parallel/algorithms/reverse.hpp>
#include <hpx/parallel/container_algorithms/reverse.hpp>

#endif
60 changes: 34 additions & 26 deletions hpx/parallel/algorithms/reverse.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
#if !defined(HPX_PARALLEL_DETAIL_REVERSE_JUL_29_2014_0432PM)
#define HPX_PARALLEL_DETAIL_REVERSE_JUL_29_2014_0432PM

#include <hpx/hpx_fwd.hpp>
#include <hpx/util/unused.hpp>
#include <hpx/util/void_guard.hpp>
#include <hpx/config.hpp>
#include <hpx/traits/concepts.hpp>
#include <hpx/util/move.hpp>

#include <hpx/parallel/config/inline_namespace.hpp>
#include <hpx/parallel/execution_policy.hpp>
Expand All @@ -34,41 +34,47 @@ namespace hpx { namespace parallel { HPX_INLINE_NAMESPACE(v1)
namespace detail
{
/// \cond NOINTERNAL
struct reverse : public detail::algorithm<reverse>
template <typename Iter>
struct reverse : public detail::algorithm<reverse<Iter>, Iter>
{
reverse()
: reverse::algorithm("reverse")
{}

template <typename ExPolicy, typename BidirIter>
static hpx::util::unused_type
static BidirIter
sequential(ExPolicy, BidirIter first, BidirIter last)
{
std::reverse(first, last);
return hpx::util::unused;
return last;
}

template <typename ExPolicy, typename BidirIter>
static typename util::detail::algorithm_result<ExPolicy>::type
static typename util::detail::algorithm_result<
ExPolicy, BidirIter
>::type
parallel(ExPolicy policy, BidirIter first, BidirIter last)
{
typedef std::reverse_iterator<BidirIter> destination_iterator;
typedef hpx::util::zip_iterator<BidirIter, destination_iterator>
zip_iterator;
typedef typename zip_iterator::reference reference;
typedef typename util::detail::algorithm_result<ExPolicy>::type
result_type;

return hpx::util::void_guard<result_type>(),
return util::detail::convert_to_result(
for_each_n<zip_iterator>().call(
policy, boost::mpl::false_(),
hpx::util::make_zip_iterator(
first, destination_iterator(last)),
std::distance(first, last) / 2,
[](reference t) {
[](reference t)
{
using hpx::util::get;
std::swap(get<0>(t), get<1>(t));
});
}),
[last](zip_iterator const&) -> BidirIter
{
return last;
});
}
};
/// \endcond
Expand Down Expand Up @@ -105,17 +111,18 @@ namespace hpx { namespace parallel { HPX_INLINE_NAMESPACE(v1)
/// fashion in unspecified threads, and indeterminately sequenced
/// within each thread.
///
/// \returns The \a reverse algorithm returns a \a hpx::future<void>
/// \returns The \a reverse algorithm returns a \a hpx::future<BidirIter>
/// if the execution policy is of type
/// \a sequential_task_execution_policy or
/// \a parallel_task_execution_policy and
/// returns \a void otherwise.
/// returns \a BidirIter otherwise.
/// It returns \a last.
///
template <typename ExPolicy, typename BidirIter>
inline typename boost::enable_if<
is_execution_policy<ExPolicy>,
typename util::detail::algorithm_result<ExPolicy>::type
>::type
template <typename ExPolicy, typename BidirIter,
HPX_CONCEPT_REQUIRES_(
is_execution_policy<ExPolicy>::value &&
traits::detail::is_iterator<BidirIter>::value)>
typename util::detail::algorithm_result<ExPolicy, BidirIter>::type
reverse(ExPolicy && policy, BidirIter first, BidirIter last)
{
typedef typename std::iterator_traits<BidirIter>::iterator_category
Expand All @@ -128,7 +135,7 @@ namespace hpx { namespace parallel { HPX_INLINE_NAMESPACE(v1)

typedef typename is_sequential_execution_policy<ExPolicy>::type is_seq;

return detail::reverse().call(
return detail::reverse<BidirIter>().call(
std::forward<ExPolicy>(policy), is_seq(), first, last);
}

Expand Down Expand Up @@ -246,12 +253,13 @@ namespace hpx { namespace parallel { HPX_INLINE_NAMESPACE(v1)
/// element in the destination range, one past the last element
/// copied.
///
template <typename ExPolicy, typename BidirIter, typename OutIter>
inline typename boost::enable_if<
is_execution_policy<ExPolicy>,
typename util::detail::algorithm_result<
ExPolicy, std::pair<BidirIter, OutIter>
>::type
template <typename ExPolicy, typename BidirIter, typename OutIter,
HPX_CONCEPT_REQUIRES_(
is_execution_policy<ExPolicy>::value &&
traits::detail::is_iterator<BidirIter>::value &&
traits::detail::is_iterator<OutIter>::value)>
typename util::detail::algorithm_result<
ExPolicy, std::pair<BidirIter, OutIter>
>::type
reverse_copy(ExPolicy && policy, BidirIter first, BidirIter last,
OutIter dest_first)
Expand Down
2 changes: 2 additions & 0 deletions hpx/parallel/container_algorithms.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@

#include <hpx/parallel/container_algorithms/copy.hpp>
#include <hpx/parallel/container_algorithms/for_each.hpp>
#include <hpx/parallel/container_algorithms/remove_copy.hpp>
#include <hpx/parallel/container_algorithms/replace.hpp>
#include <hpx/parallel/container_algorithms/reverse.hpp>
#include <hpx/parallel/container_algorithms/sort.hpp>
#include <hpx/parallel/container_algorithms/transform.hpp>

Expand Down
148 changes: 148 additions & 0 deletions hpx/parallel/container_algorithms/reverse.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
// Copyright (c) 2007-2015 Hartmut Kaiser
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

/// \file parallel/container_algorithms/reverse.hpp

#if !defined(HPX_PARALLEL_CONTAINER_ALGORITHMS_REVERSE_DEC_21_2015_0245PM)
#define HPX_PARALLEL_CONTAINER_ALGORITHMS_REVERSE_DEC_21_2015_0245PM

#include <hpx/config.hpp>
#include <hpx/util/move.hpp>

#include <hpx/parallel/algorithms/reverse.hpp>
#include <hpx/parallel/traits/is_range.hpp>
#include <hpx/parallel/traits/projected_range.hpp>
#include <hpx/parallel/traits/range_traits.hpp>
#include <hpx/parallel/util/projection_identity.hpp>

#include <boost/range/functions.hpp>

#include <type_traits>

namespace hpx { namespace parallel { HPX_INLINE_NAMESPACE(v1)
{
/// Reverses the order of the elements in the range [first, last).
/// Behaves as if applying std::iter_swap to every pair of iterators
/// first+i, (last-i) - 1 for each non-negative i < (last-first)/2.
///
/// \note Complexity: Linear in the distance between \a first and \a last.
///
/// \tparam ExPolicy The type of the execution policy to use (deduced).
/// It describes the manner in which the execution
/// of the algorithm may be parallelized and the manner
/// in which it executes the assignments.
/// \tparam BidirIter The type of the source iterators used (deduced).
/// This iterator type must meet the requirements of an
/// bidirectional iterator.
///
/// \param policy The execution policy to use for the scheduling of
/// the iterations.
/// \param first Refers to the beginning of the sequence of elements
/// the algorithm will be applied to.
/// \param last Refers to the end of the sequence of elements the
/// algorithm will be applied to.
///
/// The assignments in the parallel \a reverse algorithm invoked
/// with an execution policy object of type \a sequential_execution_policy
/// execute in sequential order in the calling thread.
///
/// The assignments in the parallel \a reverse algorithm invoked with
/// an execution policy object of type \a parallel_execution_policy or
/// \a parallel_task_execution_policy are permitted to execute in an unordered
/// fashion in unspecified threads, and indeterminately sequenced
/// within each thread.
///
/// \returns The \a reverse algorithm returns a \a hpx::future<BidirIter>
/// if the execution policy is of type
/// \a sequential_task_execution_policy or
/// \a parallel_task_execution_policy and
/// returns \a BidirIter otherwise.
/// It returns \a last.
///
template <typename ExPolicy, typename Rng,
HPX_CONCEPT_REQUIRES_(
is_execution_policy<ExPolicy>::value &&
traits::is_range<Rng>::value)>
typename util::detail::algorithm_result<
ExPolicy, typename traits::range_iterator<Rng>::type
>::type
reverse(ExPolicy && policy, Rng rng)
{
return reverse(std::forward<ExPolicy>(policy),
boost::begin(rng), boost::end(rng));
}

///////////////////////////////////////////////////////////////////////////
/// Copies the elements from the range [first, last) to another range
/// beginning at dest_first in such a way that the elements in the new
/// range are in reverse order.
/// Behaves as if by executing the assignment
/// *(dest_first + (last - first) - 1 - i) = *(first + i) once for each
/// non-negative i < (last - first)
/// If the source and destination ranges (that is, [first, last) and
/// [dest_first, dest_first+(last-first)) respectively) overlap, the
/// behavior is undefined.
///
/// \note Complexity: Performs exactly \a last - \a first assignments.
///
/// \tparam ExPolicy The type of the execution policy to use (deduced).
/// It describes the manner in which the execution
/// of the algorithm may be parallelized and the manner
/// in which it executes the assignments.
/// \tparam BidirIter The type of the source iterators used (deduced).
/// This iterator type must meet the requirements of an
/// bidirectional iterator.
/// \tparam OutputIter The type of the iterator representing the
/// destination range (deduced).
/// This iterator type must meet the requirements of an
/// output iterator.
///
/// \param policy The execution policy to use for the scheduling of
/// the iterations.
/// \param first Refers to the beginning of the sequence of elements
/// the algorithm will be applied to.
/// \param last Refers to the end of the sequence of elements the
/// algorithm will be applied to.
/// \param dest_first Refers to the begin of the destination range.
///
/// The assignments in the parallel \a reverse_copy algorithm invoked
/// with an execution policy object of type \a sequential_execution_policy
/// execute in sequential order in the calling thread.
///
/// The assignments in the parallel \a reverse_copy algorithm invoked with
/// an execution policy object of type \a parallel_execution_policy or
/// \a parallel_task_execution_policy are permitted to execute in an unordered
/// fashion in unspecified threads, and indeterminately sequenced
/// within each thread.
///
/// \returns The \a reverse_copy algorithm returns a
/// \a hpx::future<std::pair<BidirIter, OutIter> >
/// if the execution policy is of type
/// \a sequential_task_execution_policy or
/// \a parallel_task_execution_policy and
/// returns \a std::pair<BidirIter, 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 Rng, typename OutIter,
HPX_CONCEPT_REQUIRES_(
is_execution_policy<ExPolicy>::value &&
traits::is_range<Rng>::value &&
traits::detail::is_iterator<OutIter>::value)>
typename util::detail::algorithm_result<
ExPolicy,
std::pair<typename traits::range_iterator<Rng>::type, OutIter>
>::type
reverse_copy(ExPolicy && policy, Rng rng, OutIter dest_first)
{
return reverse_copy(std::forward<ExPolicy>(policy),
boost::begin(rng), boost::end(rng), dest_first);
}
}}}

#endif
2 changes: 2 additions & 0 deletions tests/unit/parallel/container_algorithms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ set(tests
replace_copy_range
replace_copy_if_range
replace_if_range
reverse_range
reverse_copy_range
sort_range
transform_range
transform_range_binary
Expand Down
Loading

0 comments on commit 3970ff4

Please sign in to comment.