Skip to content

Commit

Permalink
Pre-decay template arguments early
Browse files Browse the repository at this point in the history
..to reduce the number of redudant instantiations
  • Loading branch information
K-ballo committed Dec 17, 2017
1 parent a7717bf commit d3c0163
Show file tree
Hide file tree
Showing 8 changed files with 135 additions and 100 deletions.
7 changes: 3 additions & 4 deletions hpx/lcos/detail/async_colocated.hpp
Expand Up @@ -37,10 +37,9 @@ namespace hpx { namespace detail
typedef
util::tuple<
hpx::util::detail::bound<
hpx::util::functional::extract_locality(
hpx::util::detail::placeholder<2ul> const&
, hpx::id_type&&
)
hpx::util::functional::extract_locality
, hpx::util::detail::placeholder<2ul>
, hpx::id_type
>
, Ts...
>
Expand Down
4 changes: 3 additions & 1 deletion hpx/runtime/actions/basic_action.hpp
Expand Up @@ -112,7 +112,9 @@ namespace hpx { namespace actions
naming::id_type target_;
continuation_type cont_;
naming::address::address_type lva_;
util::detail::deferred<F(Ts&&...)> f_;
util::detail::deferred<
typename std::decay<F>::type,
typename std::decay<Ts>::type...> f_;
};

///////////////////////////////////////////////////////////////////////
Expand Down
7 changes: 3 additions & 4 deletions hpx/runtime/applier/register_apply_colocated.hpp
Expand Up @@ -25,10 +25,9 @@ namespace hpx { namespace detail
typedef
util::tuple<
hpx::util::detail::bound<
hpx::util::functional::extract_locality(
hpx::util::detail::placeholder<2ul> const&
, hpx::id_type&&
)
hpx::util::functional::extract_locality
, hpx::util::detail::placeholder<2ul>
, hpx::id_type
>
, Ts...
>
Expand Down
12 changes: 8 additions & 4 deletions hpx/util/annotated_function.hpp
Expand Up @@ -14,7 +14,6 @@
#include <hpx/traits/get_function_address.hpp>
#include <hpx/traits/get_function_annotation.hpp>
#include <hpx/util/decay.hpp>
#include <hpx/util/deferred_call.hpp>
#include <hpx/util/invoke.hpp>
#include <hpx/util/thread_description.hpp>

Expand Down Expand Up @@ -138,7 +137,8 @@ namespace hpx { namespace util

public:
template <typename ... Ts>
typename invoke_deferred_result<F, Ts...>::type
typename invoke_result<
typename util::decay_unwrap<F>::type, Ts...>::type
operator()(Ts && ... ts)
{
annotate_function func(name_);
Expand Down Expand Up @@ -170,10 +170,14 @@ namespace hpx { namespace util
}

template <typename F>
detail::annotated_function<F>
detail::annotated_function<typename std::decay<F>::type>
annotated_function(F && f, char const* name = nullptr)
{
return detail::annotated_function<F>(std::forward<F>(f), name);
typedef detail::annotated_function<
typename std::decay<F>::type
> result_type;

return result_type(std::forward<F>(f), name);
}

#else
Expand Down
55 changes: 31 additions & 24 deletions hpx/util/bind.hpp
Expand Up @@ -254,18 +254,19 @@ namespace hpx { namespace util
return util::invoke(std::move(f), std::move(util::get<Is>(bound))...);
}

template <typename T>
class bound;

template <typename F, typename ...Ts>
class bound<F(Ts...)>
class bound
{
public:
bound() {} // needed for serialization

explicit bound(F&& f, Ts&&... vs)
: _f(std::forward<F>(f))
, _args(std::forward<Ts>(vs)...)
template <typename F_, typename ...Ts_, typename =
typename std::enable_if<
!std::is_same<typename std::decay<F_>::type, bound>::value
>::type>
explicit bound(F_&& f, Ts_&&... vs)
: _f(std::forward<F_>(f))
, _args(std::forward<Ts_>(vs)...)
{}

#if !defined(__NVCC__) && !defined(__CUDACC__)
Expand Down Expand Up @@ -358,14 +359,20 @@ namespace hpx { namespace util

///////////////////////////////////////////////////////////////////////////
template <typename F, typename ...Ts>
inline typename std::enable_if<
typename std::enable_if<
!traits::is_action<typename util::decay<F>::type>::value
, detail::bound<F(Ts&&...)>
, detail::bound<
typename std::decay<F>::type,
typename std::decay<Ts>::type...>
>::type
bind(F&& f, Ts&&... vs)
{
return detail::bound<F(Ts&&...)>(
std::forward<F>(f), std::forward<Ts>(vs)...);
typedef detail::bound<
typename std::decay<F>::type,
typename std::decay<Ts>::type...
> result_type;

return result_type(std::forward<F>(f), std::forward<Ts>(vs)...);
}

///////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -488,8 +495,8 @@ namespace hpx { namespace util
namespace hpx { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename T>
struct is_bind_expression<util::detail::bound<T> >
template <typename F, typename ...Ts>
struct is_bind_expression<util::detail::bound<F, Ts...> >
: std::true_type
{};

Expand All @@ -501,11 +508,11 @@ namespace hpx { namespace traits

///////////////////////////////////////////////////////////////////////////
#if defined(HPX_HAVE_THREAD_DESCRIPTION)
template <typename Sig>
struct get_function_address<util::detail::bound<Sig> >
template <typename F, typename ...Ts>
struct get_function_address<util::detail::bound<F, Ts...> >
{
static std::size_t
call(util::detail::bound<Sig> const& f) noexcept
call(util::detail::bound<F, Ts...> const& f) noexcept
{
return f.get_function_address();
}
Expand All @@ -522,11 +529,11 @@ namespace hpx { namespace traits
};

///////////////////////////////////////////////////////////////////////////
template <typename Sig>
struct get_function_annotation<util::detail::bound<Sig> >
template <typename F, typename ...Ts>
struct get_function_annotation<util::detail::bound<F, Ts...> >
{
static char const*
call(util::detail::bound<Sig> const& f) noexcept
call(util::detail::bound<F, Ts...> const& f) noexcept
{
return f.get_function_annotation();
}
Expand All @@ -543,11 +550,11 @@ namespace hpx { namespace traits
};

#if HPX_HAVE_ITTNOTIFY != 0 && !defined(HPX_HAVE_APEX)
template <typename Sig>
struct get_function_annotation_itt<util::detail::bound<Sig> >
template <typename F, typename ...Ts>
struct get_function_annotation_itt<util::detail::bound<F, Ts...> >
{
static util::itt::string_handle
call(util::detail::bound<Sig> const& f) noexcept
call(util::detail::bound<F, Ts...> const& f) noexcept
{
return f.get_function_annotation_itt();
}
Expand All @@ -570,10 +577,10 @@ namespace hpx { namespace traits
namespace hpx { namespace serialization
{
// serialization of the bound object
template <typename Archive, typename T>
template <typename Archive, typename F, typename ...Ts>
void serialize(
Archive& ar
, ::hpx::util::detail::bound<T>& bound
, ::hpx::util::detail::bound<F, Ts...>& bound
, unsigned int const version = 0)
{
bound.serialize(ar, version);
Expand Down
49 changes: 28 additions & 21 deletions hpx/util/bind_back.hpp
Expand Up @@ -74,18 +74,19 @@ namespace hpx { namespace util
}

///////////////////////////////////////////////////////////////////////
template <typename T>
struct bound_back;

template <typename F, typename ...Ts>
struct bound_back<F(Ts...)>
struct bound_back
{
public:
bound_back() {} // needed for serialization

explicit bound_back(F&& f, Ts&&... vs)
: _f(std::forward<F>(f))
, _args(std::forward<Ts>(vs)...)
template <typename F_, typename ...Ts_, typename =
typename std::enable_if<
!std::is_same<typename std::decay<F_>::type, bound_back>::value
>::type>
explicit bound_back(F_&& f, Ts_&&... vs)
: _f(std::forward<F_>(f))
, _args(std::forward<Ts_>(vs)...)
{}

#if !defined(__NVCC__) && !defined(__CUDACC__)
Expand Down Expand Up @@ -203,10 +204,16 @@ namespace hpx { namespace util
}

template <typename F, typename ...Ts>
detail::bound_back<F(Ts&&...)>
detail::bound_back<
typename std::decay<F>::type,
typename std::decay<Ts>::type...>
bind_back(F&& f, Ts&&... vs) {
return detail::bound_back<F(Ts&&...)>(
std::forward<F>(f), std::forward<Ts>(vs)...);
typedef detail::bound_back<
typename std::decay<F>::type,
typename std::decay<Ts>::type...
> result_type;

return result_type(std::forward<F>(f), std::forward<Ts>(vs)...);
}
}}

Expand All @@ -215,33 +222,33 @@ namespace hpx { namespace traits
{
///////////////////////////////////////////////////////////////////////////
#if defined(HPX_HAVE_THREAD_DESCRIPTION)
template <typename Sig>
struct get_function_address<util::detail::bound_back<Sig> >
template <typename F, typename ...Ts>
struct get_function_address<util::detail::bound_back<F, Ts...> >
{
static std::size_t
call(util::detail::bound_back<Sig> const& f) noexcept
call(util::detail::bound_back<F, Ts...> const& f) noexcept
{
return f.get_function_address();
}
};

///////////////////////////////////////////////////////////////////////////
template <typename Sig>
struct get_function_annotation<util::detail::bound_back<Sig> >
template <typename F, typename ...Ts>
struct get_function_annotation<util::detail::bound_back<F, Ts...> >
{
static char const*
call(util::detail::bound_back<Sig> const& f) noexcept
call(util::detail::bound_back<F, Ts...> const& f) noexcept
{
return f.get_function_annotation();
}
};

#if HPX_HAVE_ITTNOTIFY != 0 && !defined(HPX_HAVE_APEX)
template <typename Sig>
struct get_function_annotation_itt<util::detail::bound_back<Sig> >
template <typename F, typename ...Ts>
struct get_function_annotation_itt<util::detail::bound_back<F, Ts...> >
{
static util::itt::string_handle
call(util::detail::bound_back<Sig> const& f) noexcept
call(util::detail::bound_back<F, Ts...> const& f) noexcept
{
return f.get_function_annotation_itt();
}
Expand All @@ -254,10 +261,10 @@ namespace hpx { namespace traits
namespace hpx { namespace serialization
{
// serialization of the bound_back object
template <typename Archive, typename T>
template <typename Archive, typename F, typename ...Ts>
void serialize(
Archive& ar
, ::hpx::util::detail::bound_back<T>& bound
, ::hpx::util::detail::bound_back<F, Ts...>& bound
, unsigned int const version = 0)
{
bound.serialize(ar, version);
Expand Down

0 comments on commit d3c0163

Please sign in to comment.