New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allowing for non-default-constructible component types #2851
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,6 +15,7 @@ | |
#include <hpx/runtime/components/unique_component_name.hpp> | ||
#include <hpx/runtime/naming/resolver_client.hpp> | ||
#include <hpx/throw_exception.hpp> | ||
#include <hpx/util/assert.hpp> | ||
#include <hpx/util/atomic_count.hpp> | ||
#include <hpx/util/detail/pp/cat.hpp> | ||
#include <hpx/util/detail/pp/expand.hpp> | ||
|
@@ -24,6 +25,7 @@ | |
|
||
#include <cstddef> | ||
#include <string> | ||
#include <type_traits> | ||
|
||
/////////////////////////////////////////////////////////////////////////////// | ||
namespace hpx { namespace components | ||
|
@@ -152,6 +154,22 @@ namespace hpx { namespace components | |
/// created (\a count > 1) the GID's of all new instances are | ||
/// sequential in a row. | ||
naming::gid_type create(std::size_t count = 1) | ||
{ | ||
return create<Component>(count, | ||
std::is_default_constructible< | ||
typename Component::type_holder>()); | ||
} | ||
|
||
template <typename Component_> | ||
naming::gid_type create(std::size_t count, std::false_type) | ||
{ | ||
// shouldn't ever be called for non-default-constructible types | ||
HPX_ASSERT(false); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same as above |
||
return naming::invalid_gid; | ||
} | ||
|
||
template <typename Component_> | ||
naming::gid_type create(std::size_t count, std::true_type) | ||
{ | ||
if (isenabled_) | ||
{ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
// Copyright (c) 2015-2017 Hartmut Kaiser | ||
// Copyright (c) 2017 Igor Krivenko | ||
// | ||
// 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 <hpx/hpx_main.hpp> | ||
#include <hpx/include/components.hpp> | ||
#include <hpx/include/actions.hpp> | ||
#include <hpx/util/lightweight_test.hpp> | ||
|
||
#include <cstddef> | ||
#include <utility> | ||
#include <vector> | ||
|
||
/////////////////////////////////////////////////////////////////////////////// | ||
struct test_server : hpx::components::simple_component_base<test_server> | ||
{ | ||
test_server() = delete; | ||
test_server(int i) : i_(i) {} | ||
|
||
hpx::id_type call() const { return hpx::find_here(); } | ||
|
||
HPX_DEFINE_COMPONENT_ACTION(test_server, call); | ||
|
||
int i_; | ||
}; | ||
|
||
typedef hpx::components::simple_component<test_server> server_type; | ||
HPX_REGISTER_COMPONENT(server_type, test_server); | ||
|
||
typedef test_server::call_action call_action; | ||
HPX_REGISTER_ACTION(call_action); | ||
|
||
struct test_client : hpx::components::client_base<test_client, test_server> | ||
{ | ||
typedef hpx::components::client_base<test_client, test_server> base_type; | ||
|
||
test_client(hpx::id_type const& id) | ||
: base_type(id) | ||
{} | ||
test_client(hpx::future<hpx::id_type> && id) | ||
: base_type(std::move(id)) | ||
{} | ||
|
||
hpx::id_type call() const | ||
{ | ||
return hpx::async<call_action>(this->get_id()).get(); | ||
} | ||
}; | ||
|
||
/////////////////////////////////////////////////////////////////////////////// | ||
void test_create_single_instance() | ||
{ | ||
// make sure created objects live on locality they are supposed to be | ||
for (hpx::id_type const& loc: hpx::find_all_localities()) | ||
{ | ||
hpx::id_type id = hpx::new_<test_server>(loc, 42).get(); | ||
HPX_TEST(hpx::async<call_action>(id).get() == loc); | ||
} | ||
|
||
for (hpx::id_type const& loc: hpx::find_all_localities()) | ||
{ | ||
test_client t1 = hpx::new_<test_client>(loc, 42); | ||
HPX_TEST(t1.call() == loc); | ||
} | ||
|
||
// make sure distribution policy is properly used | ||
hpx::id_type id = hpx::new_<test_server>(hpx::default_layout, 42).get(); | ||
HPX_TEST(hpx::async<call_action>(id).get() == hpx::find_here()); | ||
|
||
test_client t2 = hpx::new_<test_client>(hpx::default_layout, 42); | ||
HPX_TEST(t2.call() == hpx::find_here()); | ||
|
||
for (hpx::id_type const& loc: hpx::find_all_localities()) | ||
{ | ||
hpx::id_type id = | ||
hpx::new_<test_server>(hpx::default_layout(loc), 42).get(); | ||
HPX_TEST(hpx::async<call_action>(id).get() == loc); | ||
} | ||
|
||
for (hpx::id_type const& loc: hpx::find_all_localities()) | ||
{ | ||
test_client t3 = hpx::new_<test_client>(hpx::default_layout(loc), 42); | ||
HPX_TEST(t3.call() == loc); | ||
} | ||
} | ||
|
||
/////////////////////////////////////////////////////////////////////////////// | ||
void test_create_multiple_instances() | ||
{ | ||
// make sure created objects live on locality they are supposed to be | ||
for (hpx::id_type const& loc: hpx::find_all_localities()) | ||
{ | ||
std::vector<hpx::id_type> ids = | ||
hpx::new_<test_server[]>(loc, 10, 42).get(); | ||
HPX_TEST_EQ(ids.size(), std::size_t(10)); | ||
|
||
for (hpx::id_type const& id: ids) | ||
{ | ||
HPX_TEST(hpx::async<call_action>(id).get() == loc); | ||
} | ||
} | ||
|
||
for (hpx::id_type const& loc: hpx::find_all_localities()) | ||
{ | ||
std::vector<test_client> ids = | ||
hpx::new_<test_client[]>(loc, 10, 42).get(); | ||
HPX_TEST_EQ(ids.size(), std::size_t(10)); | ||
|
||
for (test_client const& c: ids) | ||
{ | ||
HPX_TEST(c.call() == loc); | ||
} | ||
} | ||
|
||
// make sure distribution policy is properly used | ||
std::vector<hpx::id_type> ids = | ||
hpx::new_<test_server[]>(hpx::default_layout, 10, 42).get(); | ||
HPX_TEST_EQ(ids.size(), std::size_t(10)); | ||
for (hpx::id_type const& id: ids) | ||
{ | ||
HPX_TEST(hpx::async<call_action>(id).get() == hpx::find_here()); | ||
} | ||
|
||
std::vector<test_client> clients = | ||
hpx::new_<test_client[]>(hpx::default_layout, 10, 42).get(); | ||
HPX_TEST_EQ(clients.size(), std::size_t(10)); | ||
for (test_client const& c: clients) | ||
{ | ||
HPX_TEST(c.call() == hpx::find_here()); | ||
} | ||
|
||
for (hpx::id_type const& loc: hpx::find_all_localities()) | ||
{ | ||
std::vector<hpx::id_type> ids = | ||
hpx::new_<test_server[]>(hpx::default_layout(loc), 10, 42).get(); | ||
HPX_TEST_EQ(ids.size(), std::size_t(10)); | ||
|
||
for (hpx::id_type const& id: ids) | ||
{ | ||
HPX_TEST(hpx::async<call_action>(id).get() == loc); | ||
} | ||
} | ||
|
||
for (hpx::id_type const& loc: hpx::find_all_localities()) | ||
{ | ||
std::vector<test_client> ids = | ||
hpx::new_<test_client[]>(hpx::default_layout(loc), 10, 42).get(); | ||
HPX_TEST_EQ(ids.size(), std::size_t(10)); | ||
|
||
for (test_client const& c: ids) | ||
{ | ||
HPX_TEST(c.call() == loc); | ||
} | ||
} | ||
} | ||
|
||
/////////////////////////////////////////////////////////////////////////////// | ||
int main() | ||
{ | ||
test_create_single_instance(); | ||
test_create_multiple_instances(); | ||
|
||
return 0; | ||
} | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we have to resort to a runtime error here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you suggest? A static assert would trigger for any non-default constructible type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only if we call new_ without arguments, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, always - this function is called by
create(size_t)
which is a virtual function.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah, right, too bad :/