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
eb1fb939
Commit
eb1fb939
authored
Oct 15, 2013
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fixed partial_function args in match_expr_concat
parent
c25d2453
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
213 additions
and
63 deletions
+213
-63
cppa/behavior.hpp
cppa/behavior.hpp
+0
-3
cppa/detail/behavior_impl.hpp
cppa/detail/behavior_impl.hpp
+6
-0
cppa/detail/typed_actor_util.hpp
cppa/detail/typed_actor_util.hpp
+1
-1
cppa/match_expr.hpp
cppa/match_expr.hpp
+53
-50
cppa/message_future.hpp
cppa/message_future.hpp
+38
-4
cppa/partial_function.hpp
cppa/partial_function.hpp
+3
-3
src/partial_function.cpp
src/partial_function.cpp
+16
-0
unit_testing/test_spawn.cpp
unit_testing/test_spawn.cpp
+76
-0
unit_testing/test_typed_spawn.cpp
unit_testing/test_typed_spawn.cpp
+20
-2
No files found.
cppa/behavior.hpp
View file @
eb1fb939
...
@@ -112,9 +112,6 @@ class behavior {
...
@@ -112,9 +112,6 @@ class behavior {
*/
*/
behavior
add_continuation
(
continuation_fun
fun
);
behavior
add_continuation
(
continuation_fun
fun
);
//template<typename F>
//inline behavior add_continuation(F fun);
private:
private:
impl_ptr
m_impl
;
impl_ptr
m_impl
;
...
...
cppa/detail/behavior_impl.hpp
View file @
eb1fb939
...
@@ -44,6 +44,7 @@
...
@@ -44,6 +44,7 @@
namespace
cppa
{
namespace
cppa
{
class
partial_function
;
typedef
optional
<
any_tuple
>
bhvr_invoke_result
;
typedef
optional
<
any_tuple
>
bhvr_invoke_result
;
}
// namespace cppa
}
// namespace cppa
...
@@ -224,6 +225,11 @@ default_behavior_impl<dummy_match_expr, F>* new_default_behavior(util::duration
...
@@ -224,6 +225,11 @@ default_behavior_impl<dummy_match_expr, F>* new_default_behavior(util::duration
typedef
intrusive_ptr
<
behavior_impl
>
behavior_impl_ptr
;
typedef
intrusive_ptr
<
behavior_impl
>
behavior_impl_ptr
;
// implemented in partial_function.cpp
behavior_impl_ptr
combine
(
behavior_impl_ptr
,
const
partial_function
&
);
behavior_impl_ptr
combine
(
const
partial_function
&
,
behavior_impl_ptr
);
behavior_impl_ptr
extract
(
const
partial_function
&
);
}
}
// namespace cppa::detail
}
}
// namespace cppa::detail
#endif // BEHAVIOR_IMPL_HPP
#endif // BEHAVIOR_IMPL_HPP
cppa/detail/typed_actor_util.hpp
View file @
eb1fb939
...
@@ -108,7 +108,7 @@ inline void assert_types() {
...
@@ -108,7 +108,7 @@ inline void assert_types() {
template
<
typename
T
>
template
<
typename
T
>
struct
lifted_result_type
{
struct
lifted_result_type
{
typedef
util
::
type_list
<
T
>
type
;
typedef
util
::
type_list
<
typename
detail
::
implicit_conversions
<
T
>::
type
>
type
;
};
};
template
<
typename
...
Ts
>
template
<
typename
...
Ts
>
...
...
cppa/match_expr.hpp
View file @
eb1fb939
...
@@ -520,8 +520,8 @@ Result unroll_expr(PPFPs& fs,
...
@@ -520,8 +520,8 @@ Result unroll_expr(PPFPs& fs,
}
}
// PPFP = projection_partial_function_pair
// PPFP = projection_partial_function_pair
template
<
class
PPFPs
,
class
T
uple
>
template
<
class
PPFPs
,
class
T
>
inline
bool
can_unroll_expr
(
PPFPs
&
,
minus1l
,
const
std
::
type_info
&
,
const
T
uple
&
)
{
inline
bool
can_unroll_expr
(
PPFPs
&
,
minus1l
,
const
std
::
type_info
&
,
const
T
&
)
{
return
false
;
return
false
;
}
}
...
@@ -906,21 +906,40 @@ match_expr_collect(const T& arg, const Ts&... args) {
...
@@ -906,21 +906,40 @@ match_expr_collect(const T& arg, const Ts&... args) {
namespace
detail
{
namespace
detail
{
typedef
std
::
true_type
with_timeout
;
//typedef std::true_type with_timeout;
typedef
std
::
false_type
without_timeout
;
//typedef std::false_type without_timeout;
// with timeout
// end of recursion
// end of recursion
template
<
class
Data
,
class
Token
>
behavior_impl_ptr
concat_rec
(
const
Data
&
data
,
Token
)
{
typedef
typename
match_expr_from_type_list
<
Token
>::
type
combined_type
;
auto
lvoid
=
[]
{
};
typedef
default_behavior_impl
<
combined_type
,
decltype
(
lvoid
)
>
impl_type
;
return
new
impl_type
(
data
,
util
::
duration
{},
lvoid
);
}
// end of recursion with nothing but a partial function
inline
behavior_impl_ptr
concat_rec
(
const
tdata
<>&
,
util
::
empty_type_list
,
const
partial_function
&
pfun
)
{
return
extract
(
pfun
);
}
// end of recursion with timeout
template
<
class
Data
,
class
Token
,
typename
F
>
template
<
class
Data
,
class
Token
,
typename
F
>
behavior_impl
*
concat_rec
(
const
Data
&
data
,
Token
,
const
timeout_definition
<
F
>&
arg
)
{
behavior_impl_ptr
concat_rec
(
const
Data
&
data
,
Token
,
const
timeout_definition
<
F
>&
arg
)
{
typedef
typename
match_expr_from_type_list
<
Token
>::
type
combined_type
;
typedef
typename
match_expr_from_type_list
<
Token
>::
type
combined_type
;
return
new
default_behavior_impl
<
combined_type
,
F
>
{
data
,
arg
};
return
new
default_behavior_impl
<
combined_type
,
F
>
{
data
,
arg
};
}
}
// recursive concatenation function
// recursive concatenation function
template
<
class
Data
,
class
Token
,
typename
T
,
typename
...
Ts
>
template
<
class
Data
,
class
Token
,
typename
T
,
typename
...
Ts
>
behavior_impl
*
concat_rec
(
const
Data
&
data
,
Token
,
const
T
&
arg
,
const
Ts
&
...
args
)
{
behavior_impl_ptr
concat_rec
(
const
Data
&
data
,
Token
,
const
T
&
arg
,
const
Ts
&
...
args
)
{
typedef
typename
util
::
tl_concat
<
typedef
typename
util
::
tl_concat
<
Token
,
Token
,
typename
T
::
cases_list
typename
T
::
cases_list
...
@@ -938,57 +957,41 @@ behavior_impl* concat_rec(const Data& data, Token, const T& arg, const Ts&... ar
...
@@ -938,57 +957,41 @@ behavior_impl* concat_rec(const Data& data, Token, const T& arg, const Ts&... ar
return
concat_rec
(
next_data
,
next_token
,
args
...);
return
concat_rec
(
next_data
,
next_token
,
args
...);
}
}
template
<
typename
F
>
// handle partial functions at end of recursion
behavior_impl
*
concat_expr
(
with_timeout
,
const
timeout_definition
<
F
>&
arg
)
{
template
<
class
Data
,
class
Token
>
typedef
default_behavior_impl
<
dummy_match_expr
,
F
>
impl_type
;
behavior_impl_ptr
concat_rec
(
const
Data
&
data
,
return
new
impl_type
(
dummy_match_expr
{},
arg
);
Token
token
,
const
partial_function
&
pfun
)
{
return
combine
(
concat_rec
(
data
,
token
),
pfun
);
}
}
template
<
typename
T
,
typename
...
Ts
>
// handle partial functions in between
behavior_impl
*
concat_expr
(
with_timeout
,
const
T
&
arg
,
const
Ts
&
...
args
)
{
template
<
class
Data
,
class
Token
,
typename
T
,
typename
...
Ts
>
typename
tdata_from_type_list
<
behavior_impl_ptr
concat_rec
(
const
Data
&
data
,
typename
util
::
tl_map
<
Token
token
,
typename
T
::
cases_list
,
const
partial_function
&
pfun
,
gref_wrapped
const
T
&
arg
,
>::
type
const
Ts
&
...
args
)
{
>::
type
auto
lhs
=
concat_rec
(
data
,
token
);
wrapper
;
detail
::
tdata
<>
dummy
;
detail
::
rebind_tdata
(
wrapper
,
arg
.
cases
()
);
auto
rhs
=
concat_rec
(
dummy
,
util
::
empty_type_list
{},
arg
,
args
...
);
return
co
ncat_rec
(
wrapper
,
typename
T
::
cases_list
{},
args
...
);
return
co
mbine
(
lhs
,
pfun
)
->
or_else
(
rhs
);
}
}
// without timeout
// handle partial functions at recursion start
template
<
typename
T
,
typename
...
Ts
>
template
<
typename
T
,
typename
...
Ts
>
behavior_impl
*
concat_expr
(
without_timeout
,
const
T
&
arg
,
const
Ts
&
...
args
)
{
behavior_impl_ptr
concat_rec
(
const
tdata
<>&
data
,
typename
tdata_from_type_list
<
util
::
empty_type_list
token
,
typename
util
::
tl_map
<
const
partial_function
&
pfun
,
typename
util
::
tl_concat
<
const
T
&
arg
,
typename
T
::
cases_list
,
const
Ts
&
...
args
)
{
typename
Ts
::
cases_list
...
return
combine
(
pfun
,
concat_rec
(
data
,
token
,
arg
,
args
...));
>::
type
,
gref_wrapped
>::
type
>::
type
all_cases
;
typedef
typename
match_expr_from_type_list
<
typename
util
::
tl_concat
<
typename
T
::
cases_list
,
typename
Ts
::
cases_list
...
>::
type
>::
type
combined_type
;
auto
lvoid
=
[]
{
};
typedef
default_behavior_impl
<
combined_type
,
decltype
(
lvoid
)
>
impl_type
;
rebind_tdata
(
all_cases
,
arg
.
cases
(),
args
.
cases
()...);
return
new
impl_type
(
all_cases
,
util
::
duration
{},
lvoid
);
}
}
template
<
typename
T
,
typename
...
Ts
>
template
<
typename
T
,
typename
...
Ts
>
behavior_impl_ptr
match_expr_concat
(
const
T
&
arg
,
const
Ts
&
...
args
)
{
behavior_impl_ptr
match_expr_concat
(
const
T
&
arg
,
const
Ts
&
...
args
)
{
std
::
integral_constant
<
bool
,
util
::
disjunction
<
T
::
may_have_timeout
,
Ts
::
may_have_timeout
...
>::
value
>
token
;
detail
::
tdata
<>
dummy
;
// use static call dispatch to select correct function
return
concat_rec
(
dummy
,
util
::
empty_type_list
{},
arg
,
args
...);
return
concat_expr
(
token
,
arg
,
args
...);
}
}
}
// namespace detail
}
// namespace detail
...
...
cppa/message_future.hpp
View file @
eb1fb939
...
@@ -62,13 +62,13 @@ class continue_helper {
...
@@ -62,13 +62,13 @@ class continue_helper {
inline
continue_helper
(
message_id
mid
)
:
m_mid
(
mid
)
{
}
inline
continue_helper
(
message_id
mid
)
:
m_mid
(
mid
)
{
}
template
<
typename
F
>
template
<
typename
F
>
void
continue_with
(
F
fun
)
{
continue_helper
&
continue_with
(
F
fun
)
{
continue_with
(
behavior
::
continuation_fun
{
partial_function
{
return
continue_with
(
behavior
::
continuation_fun
{
partial_function
{
on
(
any_vals
,
arg_match
)
>>
fun
on
(
any_vals
,
arg_match
)
>>
fun
}});
}});
}
}
inline
void
continue_with
(
behavior
::
continuation_fun
fun
)
{
inline
continue_helper
&
continue_with
(
behavior
::
continuation_fun
fun
)
{
auto
ref_opt
=
self
->
bhvr_stack
().
sync_handler
(
m_mid
);
auto
ref_opt
=
self
->
bhvr_stack
().
sync_handler
(
m_mid
);
if
(
ref_opt
)
{
if
(
ref_opt
)
{
auto
&
ref
=
*
ref_opt
;
auto
&
ref
=
*
ref_opt
;
...
@@ -77,6 +77,7 @@ class continue_helper {
...
@@ -77,6 +77,7 @@ class continue_helper {
ref
=
cpy
.
add_continuation
(
std
::
move
(
fun
));
ref
=
cpy
.
add_continuation
(
std
::
move
(
fun
));
}
}
else
CPPA_LOG_ERROR
(
".continue_with: failed to add continuation"
);
else
CPPA_LOG_ERROR
(
".continue_with: failed to add continuation"
);
return
*
this
;
}
}
inline
message_id
get_message_id
()
const
{
inline
message_id
get_message_id
()
const
{
...
@@ -196,9 +197,41 @@ class typed_continue_helper {
...
@@ -196,9 +197,41 @@ class typed_continue_helper {
typed_continue_helper
(
continue_helper
ch
)
:
m_ch
(
std
::
move
(
ch
))
{
}
typed_continue_helper
(
continue_helper
ch
)
:
m_ch
(
std
::
move
(
ch
))
{
}
template
<
typename
F
>
template
<
typename
F
>
void
continue_with
(
F
fun
)
{
typed_continue_helper
<
typename
util
::
get_callable_trait
<
F
>::
result_type
>
continue_with
(
F
fun
)
{
detail
::
assert_types
<
result_types
,
F
>
();
detail
::
assert_types
<
result_types
,
F
>
();
m_ch
.
continue_with
(
std
::
move
(
fun
));
m_ch
.
continue_with
(
std
::
move
(
fun
));
return
{
m_ch
};
}
inline
message_id
get_message_id
()
const
{
return
m_ch
.
get_message_id
();
}
private:
continue_helper
m_ch
;
};
/*
template<>
class typed_continue_helper<void> {
public:
typedef int message_id_wrapper_tag;
typedef util::type_list<void> result_types;
typed_continue_helper(continue_helper ch) : m_ch(std::move(ch)) { }
template<typename F>
void continue_with(F fun) {
using arg_types = typename util::get_callable_trait<F>::arg_types;
static_assert(std::is_same<util::empty_type_list, arg_types>::value,
"functor takes too much arguments");
m_ch.continue_with(std::move(fun));
}
}
inline message_id get_message_id() const {
inline message_id get_message_id() const {
...
@@ -210,6 +243,7 @@ class typed_continue_helper {
...
@@ -210,6 +243,7 @@ class typed_continue_helper {
continue_helper m_ch;
continue_helper m_ch;
};
};
*/
template
<
typename
OutputList
>
template
<
typename
OutputList
>
class
typed_message_future
{
class
typed_message_future
{
...
...
cppa/partial_function.hpp
View file @
eb1fb939
...
@@ -65,7 +65,7 @@ class partial_function {
...
@@ -65,7 +65,7 @@ class partial_function {
typedef
intrusive_ptr
<
detail
::
behavior_impl
>
impl_ptr
;
typedef
intrusive_ptr
<
detail
::
behavior_impl
>
impl_ptr
;
inline
auto
as_behavior_impl
()
const
->
const
impl_ptr
&
;
inline
auto
as_behavior_impl
()
const
->
impl_ptr
;
partial_function
(
impl_ptr
ptr
);
partial_function
(
impl_ptr
ptr
);
...
@@ -142,7 +142,7 @@ match_expr_convert(const T0& arg0, const T1& arg1, const Ts&... args) {
...
@@ -142,7 +142,7 @@ match_expr_convert(const T0& arg0, const T1& arg1, const Ts&... args) {
template
<
typename
...
Cases
>
template
<
typename
...
Cases
>
partial_function
operator
,(
const
match_expr
<
Cases
...
>&
mexpr
,
partial_function
operator
,(
const
match_expr
<
Cases
...
>&
mexpr
,
const
partial_function
&
pfun
)
{
const
partial_function
&
pfun
)
{
return
mexpr
.
as_behavior_impl
()
->
or_else
(
pfun
.
as_behavior_impl
);
return
mexpr
.
as_behavior_impl
()
->
or_else
(
pfun
.
as_behavior_impl
()
);
}
}
/******************************************************************************
/******************************************************************************
...
@@ -177,7 +177,7 @@ partial_function::or_else(Ts&&... args) const {
...
@@ -177,7 +177,7 @@ partial_function::or_else(Ts&&... args) const {
return
m_impl
->
or_else
(
tmp
.
as_behavior_impl
());
return
m_impl
->
or_else
(
tmp
.
as_behavior_impl
());
}
}
inline
auto
partial_function
::
as_behavior_impl
()
const
->
const
impl_ptr
&
{
inline
auto
partial_function
::
as_behavior_impl
()
const
->
impl_ptr
{
return
m_impl
;
return
m_impl
;
}
}
...
...
src/partial_function.cpp
View file @
eb1fb939
...
@@ -40,3 +40,19 @@ partial_function::partial_function(impl_ptr ptr) : m_impl(std::move(ptr)) { }
...
@@ -40,3 +40,19 @@ partial_function::partial_function(impl_ptr ptr) : m_impl(std::move(ptr)) { }
void
detail
::
behavior_impl
::
handle_timeout
()
{
}
void
detail
::
behavior_impl
::
handle_timeout
()
{
}
}
// namespace cppa
}
// namespace cppa
namespace
cppa
{
namespace
detail
{
behavior_impl_ptr
combine
(
behavior_impl_ptr
lhs
,
const
partial_function
&
rhs
)
{
return
lhs
->
or_else
(
rhs
.
as_behavior_impl
());
}
behavior_impl_ptr
combine
(
const
partial_function
&
lhs
,
behavior_impl_ptr
rhs
)
{
return
lhs
.
as_behavior_impl
()
->
or_else
(
rhs
);
}
behavior_impl_ptr
extract
(
const
partial_function
&
arg
)
{
return
arg
.
as_behavior_impl
();
}
}
}
// namespace cppa::detail
unit_testing/test_spawn.cpp
View file @
eb1fb939
...
@@ -390,10 +390,86 @@ void test_serial_reply() {
...
@@ -390,10 +390,86 @@ void test_serial_reply() {
}
}
void
test_or_else
()
{
partial_function
handle_a
{
on
(
"a"
)
>>
[]
{
return
1
;
}
};
partial_function
handle_b
{
on
(
"b"
)
>>
[]
{
return
2
;
}
};
partial_function
handle_c
{
on
(
"c"
)
>>
[]
{
return
3
;
}
};
auto
run_testee
([](
actor_ptr
testee
)
{
sync_send
(
testee
,
"a"
).
await
([](
int
i
)
{
CPPA_CHECK_EQUAL
(
i
,
1
);
});
sync_send
(
testee
,
"b"
).
await
([](
int
i
)
{
CPPA_CHECK_EQUAL
(
i
,
2
);
});
sync_send
(
testee
,
"c"
).
await
([](
int
i
)
{
CPPA_CHECK_EQUAL
(
i
,
3
);
});
send_exit
(
testee
,
exit_reason
::
user_shutdown
);
await_all_others_done
();
});
run_testee
(
spawn
([
=
]
{
become
(
handle_a
.
or_else
(
handle_b
).
or_else
(
handle_c
));
})
);
run_testee
(
spawn
([
=
]
{
become
(
handle_a
,
handle_b
,
handle_c
);
})
);
run_testee
(
spawn
([
=
]
{
become
(
handle_a
.
or_else
(
handle_b
),
on
(
"c"
)
>>
[]
{
return
3
;
}
);
})
);
run_testee
(
spawn
([
=
]
{
become
(
on
(
"a"
)
>>
[]
{
return
1
;
},
handle_b
.
or_else
(
handle_c
)
);
})
);
}
void
test_continuation
()
{
auto
mirror
=
spawn
<
simple_mirror
>
();
spawn
([
=
]
{
sync_send
(
mirror
,
42
).
then
(
on
(
42
)
>>
[]
{
return
"fourty-two"
;
}
).
continue_with
(
[
=
](
const
string
&
ref
)
{
CPPA_CHECK_EQUAL
(
ref
,
"fourty-two"
);
return
4.2
f
;
}
).
continue_with
(
[
=
](
float
f
)
{
CPPA_CHECK_EQUAL
(
f
,
4.2
f
);
send_exit
(
mirror
,
exit_reason
::
user_shutdown
);
self
->
quit
();
}
);
});
await_all_others_done
();
}
int
main
()
{
int
main
()
{
CPPA_TEST
(
test_spawn
);
CPPA_TEST
(
test_spawn
);
test_serial_reply
();
test_serial_reply
();
test_or_else
();
test_continuation
();
// check whether detached actors and scheduled actors interact w/o errors
// check whether detached actors and scheduled actors interact w/o errors
auto
m
=
spawn
<
master
,
detached
>
();
auto
m
=
spawn
<
master
,
detached
>
();
...
...
unit_testing/test_typed_spawn.cpp
View file @
eb1fb939
...
@@ -153,8 +153,26 @@ int main() {
...
@@ -153,8 +153,26 @@ int main() {
sync_send
(
ptr
,
1.2
f
).
await
(
sync_send
(
ptr
,
1.2
f
).
await
(
[]
{
CPPA_CHECKPOINT
();
}
[]
{
CPPA_CHECKPOINT
();
}
);
);
spawn
([
=
]
{
sync_send
(
ptr
,
2.3
f
).
then
(
[]
(
int
c
)
{
CPPA_CHECK_EQUAL
(
c
,
3
);
return
"hello continuation"
;
}
).
continue_with
(
[]
(
const
string
&
str
)
{
CPPA_CHECK_EQUAL
(
str
,
"hello continuation"
);
return
4.2
;
}
).
continue_with
(
[
=
]
(
double
d
)
{
CPPA_CHECK_EQUAL
(
d
,
4.2
);
send_exit
(
ptr0
,
exit_reason
::
user_shutdown
);
send_exit
(
ptr0
,
exit_reason
::
user_shutdown
);
send_exit
(
ptr
,
exit_reason
::
user_shutdown
);
send_exit
(
ptr
,
exit_reason
::
user_shutdown
);
self
->
quit
();
}
);
});
await_all_others_done
();
await_all_others_done
();
CPPA_CHECKPOINT
();
CPPA_CHECKPOINT
();
shutdown
();
shutdown
();
...
...
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