Skip to content

Commit

Permalink
Adding action specializations for noexcept functions
Browse files Browse the repository at this point in the history
  • Loading branch information
hkaiser committed Dec 3, 2019
1 parent 8558bc9 commit f3e7aab
Show file tree
Hide file tree
Showing 6 changed files with 165 additions and 1 deletion.
8 changes: 8 additions & 0 deletions cmake/HPX_AddConfigTest.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -759,6 +759,14 @@ function(hpx_check_for_cxx17_if_constexpr)
FILE ${ARGN})
endfunction()

###############################################################################
function(hpx_check_for_cxx17_noexcept_functions_as_nontype_template_arguments)
add_hpx_config_test(
HPX_WITH_CXX17_NOEXCEPT_FUNCTIONS_AS_NONTYPE_TEMPLATE_ARGUMENTS
SOURCE cmake/tests/cxx17_noexcept_function.cpp
FILE ${ARGN})
endfunction()

###############################################################################
function(hpx_check_for_mm_prefetch)
add_hpx_config_test(HPX_WITH_MM_PREFETCH
Expand Down
4 changes: 4 additions & 0 deletions cmake/HPX_PerformCxxFeatureTests.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -227,5 +227,9 @@ function(hpx_perform_cxx_feature_tests)

hpx_check_for_cxx17_std_in_place_type_t(
DEFINITIONS HPX_HAVE_CXX17_STD_IN_PLACE_TYPE_T)

hpx_check_for_cxx17_noexcept_functions_as_nontype_template_arguments(
DEFINITIONS HPX_HAVE_CXX17_NOEXCEPT_FUNCTIONS_AS_NONTYPE_TEMPLATE_ARGUMENTS)

endif()
endfunction()
29 changes: 29 additions & 0 deletions cmake/tests/cxx17_noexcept_function.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) 2019 Hartmut Kaiser
//
// SPDX-License-Identifier: BSL-1.0
// 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)

// This tests whether noexcept function used a non-type template arguments are
// properly supported by the compiler.

template <typename F, F f>
struct action;

template <typename R, typename... Args, R (*F)(Args...)>
struct action<R (*)(Args...), F>
{
};

template <typename R, typename... Args, R (*F)(Args...) noexcept>
struct action<R (*)(Args...) noexcept, F>
{
};

void foo() noexcept {}

int main()
{
action<decltype(&foo), &foo> t;
return 0;
}
88 changes: 88 additions & 0 deletions hpx/runtime/actions/component_action.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,94 @@ namespace hpx { namespace actions
}
};

#if defined(HPX_HAVE_CXX17_NOEXCEPT_FUNCTIONS_AS_NONTYPE_TEMPLATE_ARGUMENTS)
///////////////////////////////////////////////////////////////////////////
// Specialized generic non-const noexcept component action types allowing
// to hold a different number of arguments
///////////////////////////////////////////////////////////////////////////
template <
typename Component, typename R, typename ...Ps,
R (Component::*F)(Ps...) noexcept, typename Derived>
struct action<R (Component::*)(Ps...) noexcept, F, Derived>
: public basic_action<Component, R(Ps...),
typename detail::action_type<
action<R (Component::*)(Ps...) noexcept, F, Derived>,
Derived
>::type
>
{
public:
typedef typename detail::action_type<
action, Derived
>::type derived_type;

static std::string get_action_name(naming::address::address_type lva)
{
return detail::make_component_action_name(
detail::get_action_name<derived_type>(),
get_lva<Component>::call(lva));
}

template <typename ...Ts>
static R invoke(
naming::address::address_type lva,
naming::address::component_type comptype, Ts&&... vs)
{
basic_action<Component, R(Ps...), derived_type>::
increment_invocation_count();

using is_future = typename traits::is_future<R>::type;
return detail::component_invoke<Component, R>(is_future{},
lva, comptype, F, std::forward<Ts>(vs)...);
}
};

///////////////////////////////////////////////////////////////////////////
// Specialized generic const noexcept component action types allowing to
// hold a different number of arguments
///////////////////////////////////////////////////////////////////////////
template <
typename Component, typename R, typename ...Ps,
R (Component::*F)(Ps...) const noexcept, typename Derived>
struct action<R (Component::*)(Ps...) const noexcept, F, Derived>
: public basic_action<Component const, R(Ps...),
typename detail::action_type<
action<R (Component::*)(Ps...) const noexcept, F, Derived>,
Derived
>::type
>
{
public:
typedef typename detail::action_type<
action, Derived
>::type derived_type;

static std::string get_action_name(naming::address::address_type lva)
{
return detail::make_component_action_name(
detail::get_action_name<derived_type>(),
get_lva<Component>::call(lva));
}

template <typename ...Ts>
static R invoke(
naming::address::address_type lva,
naming::address::component_type comptype, Ts&&... vs)
{
basic_action<Component const, R(Ps...), derived_type>::
increment_invocation_count();

using is_future_or_client = typename std::integral_constant<bool,
traits::is_future<R>::value ||
traits::is_client<R>::value>::type;

return detail::component_invoke<Component const, R>(
is_future_or_client{}, lva, comptype, F,
std::forward<Ts>(vs)...);
}
};
#endif

/// \endcond
}}

Expand Down
35 changes: 35 additions & 0 deletions hpx/runtime/actions/plain_action.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,41 @@ namespace hpx { namespace actions
}
};

#if defined(HPX_HAVE_CXX17_NOEXCEPT_FUNCTIONS_AS_NONTYPE_TEMPLATE_ARGUMENTS)
template <
typename R, typename ...Ps,
R (*F)(Ps...) noexcept, typename Derived>
struct action<R (*)(Ps...) noexcept, F, Derived>
: public basic_action<detail::plain_function, R(Ps...),
typename detail::action_type<
action<R (*)(Ps...) noexcept, F, Derived>,
Derived
>::type
>
{
public:
typedef typename detail::action_type<
action, Derived
>::type derived_type;

static std::string get_action_name(naming::address::address_type /*lva*/)
{
return detail::make_plain_action_name(
detail::get_action_name<derived_type>());
}

template <typename ...Ts>
static R invoke(
naming::address::address_type /*lva*/,
naming::address::component_type comptype, Ts&&... vs)
{
basic_action<detail::plain_function, R(Ps...),
derived_type>::increment_invocation_count();
return F(std::forward<Ts>(vs)...);
}
};
#endif

/// \endcond
}}

Expand Down
2 changes: 1 addition & 1 deletion tests/performance/local/future_overhead.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ double global_scratch = 0;
std::uint64_t num_iterations = 0;

///////////////////////////////////////////////////////////////////////////////
double null_function()
double null_function() noexcept
{
if (num_iterations > 0)
{
Expand Down

0 comments on commit f3e7aab

Please sign in to comment.