Skip to content

Commit

Permalink
Merge pull request #1619 from STEllAR-GROUP/fixing_1615
Browse files Browse the repository at this point in the history
Fix result type calculation for hpx::make_continuation
  • Loading branch information
hkaiser committed Jun 27, 2015
2 parents 2d81fcf + 3bfb9f1 commit d258fd4
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 10 deletions.
32 changes: 22 additions & 10 deletions hpx/runtime/actions/continuation.hpp
Expand Up @@ -17,6 +17,7 @@
#include <hpx/util/invoke.hpp>
#include <hpx/util/logging.hpp>
#include <hpx/util/demangle_helper.hpp>
#include <hpx/util/result_of.hpp>
#include <hpx/traits/is_action.hpp>
#include <hpx/traits/is_callable.hpp>
#include <hpx/traits/is_executor.hpp>
Expand Down Expand Up @@ -229,7 +230,7 @@ namespace hpx { namespace actions
template <typename F, typename T1, typename T2>
struct result<F(T1, T2)>
{
typedef T2 type;
typedef typename util::result_of<cont_type(T1, T2)>::type type;
};

continuation_impl() {}
Expand All @@ -242,13 +243,16 @@ namespace hpx { namespace actions
virtual ~continuation_impl() {}

template <typename T>
T operator()(hpx::id_type const& lco, T && t) const
typename result<continuation_impl(hpx::id_type, T)>::type
operator()(hpx::id_type const& lco, T && t) const
{
hpx::apply_c(cont_, lco, target_, std::forward<T>(t));

// Yep, 't' is a zombie, however we don't use the returned value
// anyways. We need it for result type calculation, though.
return std::move(t);
// Unfortunately we need to default construct the return value,
// this possibly imposes an additional restriction of return types.
typedef typename result<continuation_impl(hpx::id_type, T)>::type
result_type;
return result_type();
}

virtual bool has_to_wait_for_futures()
Expand Down Expand Up @@ -290,7 +294,12 @@ namespace hpx { namespace actions
template <typename This, typename T1, typename T2>
struct result<This(T1, T2)>
{
typedef T2 type;
typedef typename util::result_of<
cont_type(T1, T2)
>::type result_type;
typedef typename util::result_of<
function_type(hpx::id_type, result_type)
>::type type;
};

continuation2_impl() {}
Expand All @@ -306,15 +315,18 @@ namespace hpx { namespace actions
virtual ~continuation2_impl() {}

template <typename T>
T operator()(hpx::id_type const& lco, T && t) const
typename result<continuation2_impl(hpx::id_type, T)>::type
operator()(hpx::id_type const& lco, T && t) const
{
using hpx::util::placeholders::_2;
hpx::apply_continue(cont_, hpx::util::bind(f_, lco, _2),
target_, std::forward<T>(t));

// Yep, 't' is a zombie, however we don't use the returned value
// anyways. We need it for result type calculation, though.
return std::move(t);
// Unfortunately we need to default construct the return value,
// this possibly imposes an additional restriction of return types.
typedef typename result<continuation2_impl(hpx::id_type, T)>::type
result_type;
return result_type();
}

virtual bool has_to_wait_for_futures()
Expand Down
1 change: 1 addition & 0 deletions tests/regressions/actions/CMakeLists.txt
Expand Up @@ -6,6 +6,7 @@
add_subdirectory(components)

set(tests
make_continuation_1615
plain_action_1330
plain_action_1550
plain_action_move_semantics
Expand Down
43 changes: 43 additions & 0 deletions tests/regressions/actions/make_continuation_1615.cpp
@@ -0,0 +1,43 @@
// Copyright (c) 2015 Matthias Vill
//
// 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)

// Verify that #1615 was properly fixed (hpx::make_continuation requires input
// and output to be the same)

#include <hpx/hpx_init.hpp>
#include <hpx/include/actions.hpp>
#include <hpx/include/async.hpp>
#include <hpx/util/lightweight_test.hpp>

#include <boost/lexical_cast.hpp>

boost::int32_t times2(boost::int32_t i)
{
return i * 2;
}
HPX_PLAIN_ACTION(times2); // defines times2_action

std::string my_to_string(boost::int32_t i)
{
return boost::lexical_cast<std::string>(i);
}
HPX_PLAIN_ACTION(my_to_string); // defines to_string_action

int hpx_main(int argc, char* argv[])
{
std::string result = hpx::async_continue(
times2_action(), hpx::make_continuation(my_to_string_action()),
hpx::find_here(), 42).get();

HPX_TEST_EQ(result, std::string("84"));

return hpx::finalize();
}

int main(int argc, char* argv[])
{
HPX_TEST_EQ(hpx::init(argc, argv), 0);
return hpx::util::report_errors();
}

0 comments on commit d258fd4

Please sign in to comment.