Commit 920deb05 authored by ufownl's avatar ufownl

spawn_in_group variant that allows for multiple groups

relates #306
parent 36ef46e5
...@@ -92,22 +92,53 @@ class local_actor : public abstract_actor, public resumable { ...@@ -92,22 +92,53 @@ class local_actor : public abstract_actor, public resumable {
return eval_opts(Os, std::move(res)); return eval_opts(Os, std::move(res));
} }
template <class T, spawn_options Os, class... Ts> template <class T, spawn_options Os = no_spawn_options, class Groups,
actor spawn_in_group(const group& grp, Ts&&... xs) { class... Ts>
actor spawn_in_groups(const Groups& grps, Ts&&... xs) {
constexpr auto os = make_unbound(Os); constexpr auto os = make_unbound(Os);
auto res = spawn_class<T, os>(host(), group_subscriber{grp}, auto res = spawn_class<T, os>(host(),
groups_subscriber<
decltype(std::begin(grps))
>{std::begin(grps), std::end(grps)},
std::forward<Ts>(xs)...); std::forward<Ts>(xs)...);
return eval_opts(Os, std::move(res)); return eval_opts(Os, std::move(res));
} }
template <spawn_options Os = no_spawn_options, class... Ts> template <class T, spawn_options Os = no_spawn_options, class... Ts>
actor spawn_in_groups(std::initializer_list<group> grps, Ts&&... xs) {
return spawn_in_groups<
T, Os, std::initializer_list<group>
>(grps, std::forward<Ts>(xs)...);
}
template <class T, spawn_options Os = no_spawn_options, class... Ts>
actor spawn_in_group(const group& grp, Ts&&... xs) { actor spawn_in_group(const group& grp, Ts&&... xs) {
return spawn_in_groups<T, Os>({grp}, std::forward<Ts>(xs)...);
}
template <spawn_options Os = no_spawn_options, class Groups, class... Ts>
actor spawn_in_groups(const Groups& grps, Ts&&... xs) {
constexpr auto os = make_unbound(Os); constexpr auto os = make_unbound(Os);
auto res = spawn_functor<os>(host(), group_subscriber{grp}, auto res = spawn_functor<os>(host(),
groups_subscriber<
decltype(std::begin(grps))
>{std::begin(grps), std::end(grps)},
std::forward<Ts>(xs)...); std::forward<Ts>(xs)...);
return eval_opts(Os, std::move(res)); return eval_opts(Os, std::move(res));
} }
template <spawn_options Os = no_spawn_options, class... Ts>
actor spawn_in_groups(std::initializer_list<group> grps, Ts&&... xs) {
return spawn_in_groups<
Os, std::initializer_list<group>
>(grps, std::forward<Ts>(xs)...);
}
template <spawn_options Os = no_spawn_options, class... Ts>
actor spawn_in_group(const group& grp, Ts&&... xs) {
return spawn_in_groups<Os>({grp}, std::forward<Ts>(xs)...);
}
/**************************************************************************** /****************************************************************************
* spawn typed actors * * spawn typed actors *
****************************************************************************/ ****************************************************************************/
......
...@@ -170,14 +170,56 @@ actor spawn(Ts&&... xs) { ...@@ -170,14 +170,56 @@ actor spawn(Ts&&... xs) {
std::forward<Ts>(xs)...); std::forward<Ts>(xs)...);
} }
/**
* Returns a new actor that immediately, i.e., before this function
* returns, joins `grps` of type `C` using `xs` as constructor arguments
*/
template <class C, spawn_options Os = no_spawn_options, class Groups,
class... Ts>
actor spawn_in_groups(const Groups& grps, Ts&&... xs) {
return spawn_class<C, Os>(nullptr,
groups_subscriber<
decltype(std::begin(grps))
>{std::begin(grps), std::end(grps)},
std::forward<Ts>(xs)...);
}
template <class C, spawn_options Os = no_spawn_options, class... Ts>
actor spawn_in_groups(std::initializer_list<group> grps, Ts&&... xs) {
return spawn_in_groups<
C, Os, std::initializer_list<group>
>(grps, std::forward<Ts>(xs)...);
}
/** /**
* Returns a new actor that immediately, i.e., before this function * Returns a new actor that immediately, i.e., before this function
* returns, joins `grp` of type `C` using `xs` as constructor arguments * returns, joins `grp` of type `C` using `xs` as constructor arguments
*/ */
template <class C, spawn_options Os = no_spawn_options, class... Ts> template <class C, spawn_options Os = no_spawn_options, class... Ts>
actor spawn_in_group(const group& grp, Ts&&... xs) { actor spawn_in_group(const group& grp, Ts&&... xs) {
return spawn_class<C, Os>(nullptr, group_subscriber{grp}, return spawn_in_groups<C, Os>({grp}, std::forward<Ts>(xs)...);
std::forward<Ts>(xs)...); }
/**
* Returns a new actor that immediately, i.e., before this function
* returns, joins `grps`. The first element of `xs` must
* be the functor, the remaining arguments its arguments.
*/
template <spawn_options Os = no_spawn_options, class Groups, class... Ts>
actor spawn_in_groups(const Groups& grps, Ts&&... xs) {
static_assert(sizeof...(Ts) > 0, "too few arguments provided");
return spawn_functor<Os>(nullptr,
groups_subscriber<
decltype(std::begin(grps))
>{std::begin(grps), std::end(grps)},
std::forward<Ts>(xs)...);
}
template <spawn_options Os = no_spawn_options, class... Ts>
actor spawn_in_groups(std::initializer_list<group> grps, Ts&&... xs) {
return spawn_in_groups<
Os, std::initializer_list<group>
>(grps, std::forward<Ts>(xs)...);
} }
/** /**
...@@ -187,9 +229,7 @@ actor spawn_in_group(const group& grp, Ts&&... xs) { ...@@ -187,9 +229,7 @@ actor spawn_in_group(const group& grp, Ts&&... xs) {
*/ */
template <spawn_options Os = no_spawn_options, class... Ts> template <spawn_options Os = no_spawn_options, class... Ts>
actor spawn_in_group(const group& grp, Ts&&... xs) { actor spawn_in_group(const group& grp, Ts&&... xs) {
static_assert(sizeof...(Ts) > 0, "too few arguments provided"); return spawn_in_groups<Os>({grp}, std::forward<Ts>(xs)...);
return spawn_functor<Os>(nullptr, group_subscriber{grp},
std::forward<Ts>(xs)...);
} }
/** /**
......
...@@ -48,19 +48,25 @@ actor spawn_functor(execution_unit* host, ...@@ -48,19 +48,25 @@ actor spawn_functor(execution_unit* host,
F fun, F fun,
Ts&&... xs); Ts&&... xs);
class group_subscriber { template <class InputIt>
class groups_subscriber {
public: public:
inline group_subscriber(const group& grp) : m_grp(grp) { inline groups_subscriber(InputIt first, InputIt last)
: m_first(first),
m_last(last) {
// nop // nop
} }
template <class T> template <class T>
inline void operator()(T* ptr) const { inline void operator()(T* ptr) const {
ptr->join(m_grp); for (auto i = m_first; i != m_last; ++i) {
ptr->join(*i);
}
} }
private: private:
group m_grp; InputIt m_first;
InputIt m_last;
}; };
struct empty_before_launch_callback { struct empty_before_launch_callback {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment