Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
Actor Framework
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
cpp-libs
Actor Framework
Commits
702041e6
Commit
702041e6
authored
Oct 13, 2015
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Support move-only types in spawn, close #348
parent
a9878bbc
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
90 additions
and
49 deletions
+90
-49
benchmarks
benchmarks
+1
-1
libcaf_core/caf/detail/apply_args.hpp
libcaf_core/caf/detail/apply_args.hpp
+12
-0
libcaf_core/caf/detail/init_fun_factory.hpp
libcaf_core/caf/detail/init_fun_factory.hpp
+56
-48
libcaf_core/test/dynamic_spawn.cpp
libcaf_core/test/dynamic_spawn.cpp
+21
-0
No files found.
benchmarks
@
2c45d8c1
Subproject commit 2
8a6b04ea653a80724517c570c9ae8325b90cf52
Subproject commit 2
c45d8c1c2b934e062baf378809201ac66d169a7
libcaf_core/caf/detail/apply_args.hpp
View file @
702041e6
...
...
@@ -52,6 +52,18 @@ auto apply_args_prefixed(F& f, detail::int_list<Is...>, Tuple& tup, Ts&&... xs)
return
f
(
std
::
forward
<
Ts
>
(
xs
)...,
get
<
Is
>
(
tup
)...);
}
template
<
class
F
,
class
Tuple
,
class
...
Ts
>
auto
apply_moved_args_prefixed
(
F
&
f
,
detail
::
int_list
<>
,
Tuple
&
,
Ts
&&
...
xs
)
->
decltype
(
f
(
std
::
forward
<
Ts
>
(
xs
)...))
{
return
f
(
std
::
forward
<
Ts
>
(
xs
)...);
}
template
<
class
F
,
long
...
Is
,
class
Tuple
,
class
...
Ts
>
auto
apply_moved_args_prefixed
(
F
&
f
,
detail
::
int_list
<
Is
...
>
,
Tuple
&
tup
,
Ts
&&
...
xs
)
->
decltype
(
f
(
std
::
forward
<
Ts
>
(
xs
)...,
std
::
move
(
get
<
Is
>
(
tup
))...))
{
return
f
(
std
::
forward
<
Ts
>
(
xs
)...,
std
::
move
(
get
<
Is
>
(
tup
))...);
}
template
<
class
F
,
long
...
Is
,
class
Tuple
,
class
...
Ts
>
auto
apply_args_suffxied
(
F
&
f
,
detail
::
int_list
<
Is
...
>
,
Tuple
&
tup
,
Ts
&&
...
xs
)
->
decltype
(
f
(
get
<
Is
>
(
tup
)...,
std
::
forward
<
Ts
>
(
xs
)...))
{
...
...
libcaf_core/caf/detail/init_fun_factory.hpp
View file @
702041e6
...
...
@@ -20,81 +20,89 @@
#ifndef CAF_DETAIL_INIT_FUN_FACTORY_HPP
#define CAF_DETAIL_INIT_FUN_FACTORY_HPP
#include <tuple>
#include <functional>
#include "caf/fwd.hpp"
#include "caf/detail/apply_args.hpp"
#include "caf/detail/type_traits.hpp"
namespace
caf
{
namespace
detail
{
template
<
class
Base
,
class
F
>
class
init_fun_factory
{
template
<
class
Base
,
class
F
,
class
ArgsPtr
,
bool
ReturnsBehavior
,
bool
HasSelfPtr
>
class
init_fun_factory_helper
{
public:
using
fun
=
std
::
function
<
behavior
(
local_actor
*
)
>
;
init_fun_factory_helper
(
init_fun_factory_helper
&&
)
=
default
;
init_fun_factory_helper
(
const
init_fun_factory_helper
&
)
=
default
;
template
<
class
...
Ts
>
fun
operator
()(
F
f
,
Ts
&&
...
xs
)
{
static_assert
(
std
::
is_base_of
<
local_actor
,
Base
>::
value
,
"Given Base does not extend local_actor"
);
using
trait
=
typename
detail
::
get_callable_trait
<
F
>::
type
;
using
arg_types
=
typename
trait
::
arg_types
;
using
result_type
=
typename
trait
::
result_type
;
using
first_arg
=
typename
detail
::
tl_head
<
arg_types
>::
type
;
bool_token
<
std
::
is_convertible
<
result_type
,
behavior
>::
value
>
token1
;
bool_token
<
std
::
is_pointer
<
first_arg
>::
value
>
token2
;
return
make
(
token1
,
token2
,
std
::
move
(
f
),
std
::
forward
<
Ts
>
(
xs
)...);
init_fun_factory_helper
(
F
fun
,
ArgsPtr
args
)
:
fun_
(
std
::
move
(
fun
)),
args_
(
std
::
move
(
args
))
{
// nop
}
behavior
operator
()(
local_actor
*
self
)
{
bool_token
<
ReturnsBehavior
>
returns_behavior_token
;
bool_token
<
HasSelfPtr
>
captures_self_token
;
return
apply
(
returns_behavior_token
,
captures_self_token
,
self
);
}
private:
// behavior (pointer)
template
<
class
Fun
>
static
fun
make
(
std
::
true_type
,
std
::
true_type
,
Fun
fun
)
{
return
[
fun
](
local_actor
*
ptr
)
->
behavior
{
auto
res
=
fun
(
static_cast
<
Base
*>
(
ptr
));
return
std
::
move
(
res
.
unbox
());
};
behavior
apply
(
std
::
true_type
,
std
::
true_type
,
local_actor
*
ptr
)
{
auto
res
=
apply_moved_args_prefixed
(
fun_
,
get_indices
(
*
args_
),
*
args_
,
static_cast
<
Base
*>
(
ptr
));
return
std
::
move
(
res
.
unbox
());
}
// void (pointer)
template
<
class
Fun
>
static
fun
make
(
std
::
false_type
,
std
::
true_type
,
Fun
fun
)
{
return
[
fun
](
local_actor
*
ptr
)
->
behavior
{
fun
(
static_cast
<
Base
*>
(
ptr
));
return
behavior
{};
};
behavior
apply
(
std
::
false_type
,
std
::
true_type
,
local_actor
*
ptr
)
{
apply_moved_args_prefixed
(
fun_
,
get_indices
(
*
args_
),
*
args_
,
static_cast
<
Base
*>
(
ptr
));
return
behavior
{};
}
// behavior ()
template
<
class
Fun
>
static
fun
make
(
std
::
true_type
,
std
::
false_type
,
Fun
fun
)
{
return
[
fun
](
local_actor
*
)
->
behavior
{
auto
res
=
fun
();
return
std
::
move
(
res
.
unbox
());
};
behavior
apply
(
std
::
true_type
,
std
::
false_type
,
local_actor
*
)
{
auto
res
=
apply_args
(
fun_
,
get_indices
(
*
args_
),
*
args_
);
return
std
::
move
(
res
.
unbox
());
}
// void ()
template
<
class
Fun
>
static
fun
make
(
std
::
false_type
,
std
::
false_type
,
Fun
fun
)
{
return
[
fun
](
local_actor
*
)
->
behavior
{
fun
();
return
behavior
{};
};
behavior
apply
(
std
::
false_type
,
std
::
false_type
,
local_actor
*
)
{
apply_args
(
fun_
,
get_indices
(
*
args_
),
*
args_
);
return
behavior
{};
}
template
<
class
Token
,
typename
T0
,
class
...
Ts
>
static
fun
make
(
Token
t1
,
std
::
true_type
t2
,
F
fun
,
T0
&&
x
,
Ts
&&
...
xs
)
{
return
make
(
t1
,
t2
,
std
::
bind
(
fun
,
std
::
placeholders
::
_1
,
detail
::
spawn_fwd
<
T0
>
(
x
),
detail
::
spawn_fwd
<
Ts
>
(
xs
)...));
}
F
fun_
;
ArgsPtr
args_
;
};
template
<
class
Token
,
typename
T0
,
class
...
Ts
>
static
fun
make
(
Token
t1
,
std
::
false_type
t2
,
F
fun
,
T0
&&
x
,
Ts
&&
...
xs
)
{
return
make
(
t1
,
t2
,
std
::
bind
(
fun
,
detail
::
spawn_fwd
<
T0
>
(
x
),
detail
::
spawn_fwd
<
Ts
>
(
xs
)...));
template
<
class
Base
,
class
F
>
class
init_fun_factory
{
public:
using
fun
=
std
::
function
<
behavior
(
local_actor
*
)
>
;
template
<
class
...
Ts
>
fun
operator
()(
F
f
,
Ts
&&
...
xs
)
{
static_assert
(
std
::
is_base_of
<
local_actor
,
Base
>::
value
,
"Given Base does not extend local_actor"
);
using
trait
=
typename
detail
::
get_callable_trait
<
F
>::
type
;
using
arg_types
=
typename
trait
::
arg_types
;
using
res_type
=
typename
trait
::
result_type
;
using
first_arg
=
typename
detail
::
tl_head
<
arg_types
>::
type
;
constexpr
bool
selfptr
=
std
::
is_pointer
<
first_arg
>::
value
;
constexpr
bool
rets
=
std
::
is_convertible
<
res_type
,
behavior
>::
value
;
using
tuple_type
=
decltype
(
std
::
make_tuple
(
detail
::
spawn_fwd
<
Ts
>
(
xs
)...));
using
tuple_ptr
=
std
::
shared_ptr
<
tuple_type
>
;
using
helper
=
init_fun_factory_helper
<
Base
,
F
,
tuple_ptr
,
rets
,
selfptr
>
;
return
helper
{
std
::
move
(
f
),
sizeof
...(
Ts
)
>
0
?
std
::
make_shared
<
tuple_type
>
(
detail
::
spawn_fwd
<
Ts
>
(
xs
)...)
:
nullptr
};
}
};
...
...
libcaf_core/test/dynamic_spawn.cpp
View file @
702041e6
...
...
@@ -857,4 +857,25 @@ CAF_TEST(exit_reason_in_scoped_actor) {
self
->
planned_exit_reason
(
exit_reason
::
user_defined
);
}
CAF_TEST
(
move_only_argument
)
{
using
unique_int
=
std
::
unique_ptr
<
int
>
;
unique_int
ptr
{
new
int
(
42
)};
auto
f
=
[](
event_based_actor
*
self
,
unique_int
ptr
)
->
behavior
{
auto
i
=
*
ptr
;
return
{
others
>>
[
=
]
{
self
->
quit
();
return
i
;
}
};
};
auto
testee
=
spawn
(
f
,
std
::
move
(
ptr
));
scoped_actor
self
;
self
->
sync_send
(
testee
,
1.
f
).
await
(
[](
int
i
)
{
CAF_CHECK
(
i
==
42
);
}
);
}
CAF_TEST_FIXTURE_SCOPE_END
()
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment