Skip to content

Commit

Permalink
Introduce dispatching traits for async, apply and dataflow
Browse files Browse the repository at this point in the history
  • Loading branch information
hkaiser committed Jun 9, 2015
1 parent 4ecb22b commit e8a0ed1
Show file tree
Hide file tree
Showing 20 changed files with 476 additions and 393 deletions.
138 changes: 85 additions & 53 deletions hpx/apply.hpp
@@ -1,4 +1,4 @@
// Copyright (c) 2007-2014 Hartmut Kaiser
// 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)
Expand All @@ -15,75 +15,107 @@
#include <hpx/util/bind_action.hpp>
#include <hpx/util/decay.hpp>
#include <hpx/util/deferred_call.hpp>
#include <hpx/util/move.hpp>
#include <hpx/traits/is_action.hpp>
#include <hpx/traits/is_callable.hpp>
#include <hpx/traits/is_executor.hpp>
#include <hpx/traits/is_launch_policy.hpp>

#include <boost/utility/enable_if.hpp>

#include <type_traits>

///////////////////////////////////////////////////////////////////////////////
namespace hpx
namespace hpx { namespace detail
{
///////////////////////////////////////////////////////////////////////////
// Define apply() overloads for plain local functions and function objects.
// dispatching trait for hpx::apply

// Simply launch the given function or function object asynchronously
template <typename F, typename ...Ts>
typename boost::enable_if_c<
traits::detail::is_deferred_callable<F(Ts...)>::value
, bool
>::type
apply(threads::executor& sched, F&& f, Ts&&... vs)
// launch a plain function/function object
template <typename Func, typename Enable>
struct apply_dispatch
{
sched.add(
util::deferred_call(std::forward<F>(f), std::forward<Ts>(vs)...),
"hpx::apply");
return false;
}
template <typename F, typename ...Ts>
BOOST_FORCEINLINE static
typename boost::enable_if_c<
traits::detail::is_deferred_callable<F(Ts...)>::value,
bool
>::type
call(F&& f, Ts&&... ts)
{
threads::register_thread_nullary(
util::deferred_call(std::forward<F>(f), std::forward<Ts>(ts)...),
"hpx::apply");
return false;
}
};

template <typename Executor, typename F, typename ...Ts>
typename boost::enable_if_c<
boost::enable_if_c<
traits::is_executor<typename util::decay<Executor>::type>::value
, traits::detail::is_deferred_callable<F(Ts...)>
>::type::value
, bool
>::type
apply(Executor& exec, F&& f, Ts&&... vs)
// threads::executor
template <typename Executor>
struct apply_dispatch<Executor,
typename boost::enable_if_c<
traits::is_threads_executor<Executor>::value
>::type>
{
parallel::executor_traits<Executor>::apply_execute(exec,
util::deferred_call(std::forward<F>(f), std::forward<Ts>(vs)...));
return false;
}
template <typename F, typename ...Ts>
BOOST_FORCEINLINE static
typename boost::enable_if_c<
traits::detail::is_deferred_callable<F(Ts...)>::value,
bool
>::type
call(Executor& sched, F&& f, Ts&&... ts)
{
sched.add(
util::deferred_call(std::forward<F>(f), std::forward<Ts>(ts)...),
"hpx::apply");
return false;
}
};

template <typename F, typename ...Ts>
typename boost::enable_if_c<
boost::enable_if_c<
!traits::is_executor<typename util::decay<F>::type>::value
&& !traits::is_action<typename util::decay<F>::type>::value
&& !traits::is_bound_action<typename util::decay<F>::type>::value
, traits::detail::is_deferred_callable<F(Ts...)>
>::type::value
, bool
>::type
apply(F&& f, Ts&&... vs)
// parallel::executor
template <typename Executor>
struct apply_dispatch<Executor,
typename boost::enable_if_c<
traits::is_executor<Executor>::value
>::type>
{
threads::register_thread_nullary(
util::deferred_call(std::forward<F>(f), std::forward<Ts>(vs)...),
"hpx::apply");
return false;
}
template <typename F, typename ...Ts>
BOOST_FORCEINLINE static
typename boost::enable_if_c<
traits::detail::is_deferred_callable<F(Ts...)>::value,
bool
>::type
call(Executor& exec, F&& f, Ts&&... ts)
{
parallel::executor_traits<Executor>::apply_execute(exec,
util::deferred_call(std::forward<F>(f), std::forward<Ts>(ts)...));
return false;
}
};

///////////////////////////////////////////////////////////////////////////
// Define apply() overloads for bound actions
template <typename Action, typename BoundArgs, typename ...Ts>
bool apply(
hpx::util::detail::bound_action<Action, BoundArgs> const& bound
, Ts&&... vs
)
// bound action
template <typename Bound>
struct apply_dispatch<Bound,
typename boost::enable_if_c<
traits::is_bound_action<Bound>::value
>::type>
{
template <typename Action, typename BoundArgs, typename ...Ts>
BOOST_FORCEINLINE static bool
call(hpx::util::detail::bound_action<Action, BoundArgs> const& bound,
Ts&&... ts)
{
return bound.apply(std::forward<Ts>(ts)...);
}
};
}}

namespace hpx
{
template <typename F, typename ...Ts>
BOOST_FORCEINLINE bool apply(F&& f, Ts&&... ts)
{
return bound.apply(std::forward<Ts>(vs)...);
return detail::apply_dispatch<typename util::decay<F>::type>::call(
std::forward<F>(f), std::forward<Ts>(ts)...);
}
}

Expand Down

0 comments on commit e8a0ed1

Please sign in to comment.