Skip to content

Commit

Permalink
Merge pull request #1992 from STEllAR-GROUP/shared_executor_test
Browse files Browse the repository at this point in the history
Fixing shared_executor_test
  • Loading branch information
hkaiser committed Feb 20, 2016
2 parents fd3b7ea + 45f26dd commit b54cfd1
Show file tree
Hide file tree
Showing 11 changed files with 144 additions and 91 deletions.
4 changes: 4 additions & 0 deletions CMakeLists.txt
Expand Up @@ -854,6 +854,10 @@ hpx_check_for_cxx14_std_integer_sequence(
hpx_check_for_cxx14_std_result_of_sfinae(
DEFINITIONS HPX_HAVE_CXX14_STD_RESULT_OF_SFINAE)

# check for experimental facilities
hpx_check_for_cxx_experimental_std_optional(
DEFINITIONS HPX_HAVE_CXX1Y_EXPERIMENTAL_OPTIONAL)

################################################################################
# Check for misc system headers
################################################################################
Expand Down
7 changes: 7 additions & 0 deletions cmake/HPX_AddConfigTest.cmake
Expand Up @@ -391,3 +391,10 @@ macro(hpx_check_for_cxx14_std_result_of_sfinae)
SOURCE cmake/tests/cxx14_std_result_of_sfinae.cpp
FILE ${ARGN})
endmacro()

###############################################################################
macro(hpx_check_for_cxx_experimental_std_optional)
add_hpx_config_test(HPX_WITH_CXX1Y_EXPERIMENTAL_OPTIONAL
SOURCE cmake/tests/cxx1y_experimental_std_optional.cpp
FILE ${ARGN})
endmacro()
11 changes: 11 additions & 0 deletions cmake/tests/cxx1y_experimental_std_optional.cpp
@@ -0,0 +1,11 @@
// Copyright (c) 2016 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)

#include <experimental/optional>

int main()
{
std::experimental::optional<int> opt;
}
23 changes: 16 additions & 7 deletions hpx/parallel/executors/distribution_policy_executor.hpp
Expand Up @@ -29,15 +29,13 @@ namespace hpx { namespace parallel { HPX_INLINE_NAMESPACE(v3)
namespace detail
{
template <typename F, typename Enable = void>
struct async_execute_result
struct distribution_policy_execute_result
{
typedef typename hpx::util::result_of<
typename hpx::util::decay<F>::type()
>::type type;
typedef typename hpx::util::result_of<F()>::type type;
};

template <typename Action>
struct async_execute_result<Action,
struct distribution_policy_execute_result<Action,
typename std::enable_if<hpx::traits::is_action<Action>::value>::type>
{
typedef typename Action::local_result_type type;
Expand Down Expand Up @@ -91,7 +89,9 @@ namespace hpx { namespace parallel { HPX_INLINE_NAMESPACE(v3)
template <typename F>
typename std::enable_if<
!hpx::traits::is_action<F>::value,
hpx::future<typename detail::async_execute_result<F>::type>
hpx::future<
typename detail::distribution_policy_execute_result<F>::type
>
>::type
async_execute_impl(F && f) const
{
Expand Down Expand Up @@ -134,11 +134,20 @@ namespace hpx { namespace parallel { HPX_INLINE_NAMESPACE(v3)
}

template <typename F>
hpx::future<typename detail::async_execute_result<F>::type>
hpx::future<
typename detail::distribution_policy_execute_result<F>::type
>
async_execute(F && f) const
{
return async_execute_impl(std::forward<F>(f));
}

template <typename F>
typename detail::distribution_policy_execute_result<F>::type
execute(F && f)
{
return async_execute_impl(std::forward<F>(f)).get();
}
/// \endcond

private:
Expand Down
72 changes: 55 additions & 17 deletions hpx/parallel/executors/executor_traits.hpp
@@ -1,4 +1,4 @@
// Copyright (c) 2007-2015 Hartmut Kaiser
// Copyright (c) 2007-2016 Hartmut Kaiser
// Copyright (c) 2015 Daniel Bourgeois
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
Expand All @@ -14,11 +14,11 @@
#include <hpx/exception_list.hpp>
#include <hpx/async.hpp>
#include <hpx/traits/is_executor.hpp>
#include <hpx/util/decay.hpp>
#include <hpx/util/always_void.hpp>
#include <hpx/util/result_of.hpp>
#include <hpx/util/deferred_call.hpp>
#include <hpx/util/unwrapped.hpp>
#include <hpx/util/invoke.hpp>
#include <hpx/parallel/config/inline_namespace.hpp>

#include <type_traits>
Expand All @@ -29,6 +29,12 @@
#include <boost/range/irange.hpp>
#include <boost/throw_exception.hpp>

#if defined(HPX_HAVE_CXX1Y_EXPERIMENTAL_OPTIONAL)
#include <experimental/optional>
#else
#include <boost/optional.hpp>
#endif

#if defined(HPX_GCC_VERSION) && HPX_GCC_VERSION < 40700
#define HPX_ENABLE_WORKAROUND_FOR_GCC46
#endif
Expand Down Expand Up @@ -151,11 +157,36 @@ namespace hpx { namespace parallel { HPX_INLINE_NAMESPACE(v3)
struct execute_helper
{
template <typename Executor, typename F>
static auto call(hpx::traits::detail::wrap_int, Executor& exec, F && f)
-> decltype(exec.async_execute(std::forward<F>(f)).get())
static auto call_impl(Executor& exec, F && f, std::false_type)
-> decltype(hpx::util::invoke(std::forward<F>(f)))
{
try {
return exec.async_execute(std::forward<F>(f)).get();
typedef typename hpx::util::result_of<F()>::type result_type;

#if defined(HPX_HAVE_CXX1Y_EXPERIMENTAL_OPTIONAL)
std::experimental::optional<result_type> out;
auto && wrapper =
[&]()
{
out.emplace(hpx::util::invoke(std::forward<F>(f)));
};
#else
boost::optional<result_type> out;
auto && wrapper =
[&]()
{
#if BOOST_VERSION < 105600
out = boost::in_place(
hpx::util::invoke(std::forward<F>(f)));
#else
out.emplace(hpx::util::invoke(std::forward<F>(f)));
#endif
};
#endif

// use async execution, wait for result, propagate exceptions
exec.async_execute(std::ref(wrapper)).get();
return std::move(*out);
}
catch (std::bad_alloc const& ba) {
boost::throw_exception(ba);
Expand All @@ -167,6 +198,21 @@ namespace hpx { namespace parallel { HPX_INLINE_NAMESPACE(v3)
}
}

template <typename Executor, typename F>
static void call_impl(Executor& exec, F && f, std::true_type)
{
exec.async_execute(std::forward<F>(f)).get();
}

template <typename Executor, typename F>
static auto call(hpx::traits::detail::wrap_int, Executor& exec, F && f)
-> decltype(hpx::util::invoke(std::forward<F>(f)))
{
typedef std::is_void<typename hpx::util::result_of<F()>::type>
is_void;
return call_impl(exec, std::forward<F>(f), is_void());
}

template <typename Executor, typename F>
static auto call(int, Executor& exec, F && f)
-> decltype(exec.execute(std::forward<F>(f)))
Expand All @@ -178,9 +224,7 @@ namespace hpx { namespace parallel { HPX_INLINE_NAMESPACE(v3)
template <typename Executor, typename F>
auto call_execute(Executor& exec, F && f)
#if defined(HPX_ENABLE_WORKAROUND_FOR_GCC46)
-> typename hpx::util::result_of<
typename hpx::util::decay<F>::type()
>::type
-> typename hpx::util::result_of<F()>::type
#else
-> decltype(execute_helper::call(0, exec, std::forward<F>(f)))
#endif
Expand All @@ -198,9 +242,7 @@ namespace hpx { namespace parallel { HPX_INLINE_NAMESPACE(v3)
typedef typename
std::iterator_traits<iterator_type>::value_type
value_type;
typedef typename hpx::util::result_of<
typename hpx::util::decay<F>::type(value_type)
>::type type;
typedef typename hpx::util::result_of<F(value_type)>::type type;
};

///////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -435,9 +477,7 @@ namespace hpx { namespace parallel { HPX_INLINE_NAMESPACE(v3)
static auto async_execute(executor_type& exec, F && f)
#if defined(HPX_ENABLE_WORKAROUND_FOR_GCC46)
-> typename future<
typename hpx::util::result_of<
typename hpx::util::decay<F>::type()
>::type
typename hpx::util::result_of<F()>::type
>::type
#else
-> decltype(exec.async_execute(std::forward<F>(f)))
Expand Down Expand Up @@ -465,9 +505,7 @@ namespace hpx { namespace parallel { HPX_INLINE_NAMESPACE(v3)
template <typename F>
static auto execute(executor_type& exec, F && f)
#if defined(HPX_ENABLE_WORKAROUND_FOR_GCC46)
-> typename hpx::util::result_of<
typename hpx::util::decay<F>::type()
>::type
-> typename hpx::util::result_of<F()>::type
#else
-> decltype(detail::call_execute(exec, std::forward<F>(f)))
#endif
Expand Down
5 changes: 1 addition & 4 deletions hpx/parallel/executors/parallel_executor.hpp
Expand Up @@ -16,7 +16,6 @@
#include <hpx/parallel/executors/executor_traits.hpp>
#include <hpx/parallel/executors/auto_chunk_size.hpp>
#include <hpx/runtime/threads/thread_executor.hpp>
#include <hpx/util/decay.hpp>

#include <boost/detail/scoped_enum_emulation.hpp>

Expand Down Expand Up @@ -49,9 +48,7 @@ namespace hpx { namespace parallel { HPX_INLINE_NAMESPACE(v3)
}

template <typename F>
hpx::future<typename hpx::util::result_of<
typename hpx::util::decay<F>::type()
>::type>
hpx::future<typename hpx::util::result_of<F()>::type>
async_execute(F && f)
{
return hpx::async(l_, std::forward<F>(f));
Expand Down
12 changes: 4 additions & 8 deletions hpx/parallel/executors/sequential_executor.hpp
Expand Up @@ -14,7 +14,7 @@
#include <hpx/parallel/exception_list.hpp>
#include <hpx/parallel/executors/executor_traits.hpp>
#include <hpx/runtime/threads/thread_executor.hpp>
#include <hpx/util/decay.hpp>
#include <hpx/util/invoke.hpp>
#include <hpx/util/result_of.hpp>
#include <hpx/util/unwrapped.hpp>

Expand Down Expand Up @@ -50,13 +50,11 @@ namespace hpx { namespace parallel { HPX_INLINE_NAMESPACE(v3)
}

template <typename F>
static typename hpx::util::result_of<
typename hpx::util::decay<F>::type()
>::type
static typename hpx::util::result_of<F()>::type
execute(F && f)
{
try {
return f();
return hpx::util::invoke(f);
}
catch (std::bad_alloc const& ba) {
boost::throw_exception(ba);
Expand All @@ -69,9 +67,7 @@ namespace hpx { namespace parallel { HPX_INLINE_NAMESPACE(v3)
}

template <typename F>
static hpx::future<typename hpx::util::result_of<
typename hpx::util::decay<F>::type()
>::type>
static hpx::future<typename hpx::util::result_of<F()>::type>
async_execute(F && f)
{
return hpx::async(launch::deferred, std::forward<F>(f));
Expand Down
24 changes: 6 additions & 18 deletions hpx/parallel/executors/thread_timed_executor_traits.hpp
Expand Up @@ -120,15 +120,11 @@ namespace hpx { namespace parallel { HPX_INLINE_NAMESPACE(v3)
/// \returns f()'s result through a future
///
template <typename F>
static hpx::future<typename hpx::util::result_of<
typename hpx::util::decay<F>::type()
>::type>
static hpx::future<typename hpx::util::result_of<F()>::type>
async_execute_at(executor_type& sched,
hpx::util::steady_time_point const& abs_time, F && f)
{
typedef typename hpx::util::result_of<
typename hpx::util::decay<F>::type()
>::type result_type;
typedef typename hpx::util::result_of<F()>::type result_type;

lcos::local::packaged_task<result_type()> task(std::forward<F>(f));
hpx::future<result_type> result = task.get_future();
Expand All @@ -152,15 +148,11 @@ namespace hpx { namespace parallel { HPX_INLINE_NAMESPACE(v3)
/// \returns f()'s result through a future
///
template <typename F>
static hpx::future<typename hpx::util::result_of<
typename hpx::util::decay<F>::type()
>::type>
static hpx::future<typename hpx::util::result_of<F()>::type>
async_execute_after(executor_type& sched,
hpx::util::steady_duration const& rel_time, F && f)
{
typedef typename hpx::util::result_of<
typename hpx::util::decay<F>::type()
>::type result_type;
typedef typename hpx::util::result_of<F()>::type result_type;

lcos::local::packaged_task<result_type()> task(std::forward<F>(f));
hpx::future<result_type> result = task.get_future();
Expand All @@ -185,9 +177,7 @@ namespace hpx { namespace parallel { HPX_INLINE_NAMESPACE(v3)
/// \returns f()'s result
///
template <typename F>
static typename hpx::util::result_of<
typename hpx::util::decay<F>::type()
>::type
static typename hpx::util::result_of<F()>::type
execute_at(executor_type& sched,
hpx::util::steady_time_point const& abs_time, F && f)
{
Expand All @@ -211,9 +201,7 @@ namespace hpx { namespace parallel { HPX_INLINE_NAMESPACE(v3)
/// \returns f()'s result
///
template <typename F>
static typename hpx::util::result_of<
typename hpx::util::decay<F>::type()
>::type
static typename hpx::util::result_of<F()>::type
execute_after(executor_type& sched,
hpx::util::steady_duration const& rel_time, F && f)
{
Expand Down

0 comments on commit b54cfd1

Please sign in to comment.