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
715e1999
Commit
715e1999
authored
Feb 10, 2014
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
properly implemented skipping for typed actors
parent
81f824fb
Changes
23
Show whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
242 additions
and
174 deletions
+242
-174
CMakeLists.txt
CMakeLists.txt
+0
-1
cppa.files
cppa.files
+2
-2
cppa/behavior.hpp
cppa/behavior.hpp
+12
-7
cppa/blocking_actor.hpp
cppa/blocking_actor.hpp
+5
-5
cppa/continue_helper.hpp
cppa/continue_helper.hpp
+1
-0
cppa/detail/behavior_impl.hpp
cppa/detail/behavior_impl.hpp
+5
-8
cppa/detail/projection.hpp
cppa/detail/projection.hpp
+0
-19
cppa/detail/response_handle_util.hpp
cppa/detail/response_handle_util.hpp
+3
-3
cppa/match.hpp
cppa/match.hpp
+16
-13
cppa/match_expr.hpp
cppa/match_expr.hpp
+26
-4
cppa/may_have_timeout.hpp
cppa/may_have_timeout.hpp
+24
-4
cppa/on.hpp
cppa/on.hpp
+9
-12
cppa/optional_variant.hpp
cppa/optional_variant.hpp
+1
-3
cppa/partial_function.hpp
cppa/partial_function.hpp
+30
-8
cppa/skip_message.hpp
cppa/skip_message.hpp
+11
-7
cppa/typed_behavior.hpp
cppa/typed_behavior.hpp
+56
-41
cppa/typed_continue_helper.hpp
cppa/typed_continue_helper.hpp
+2
-0
cppa/util/type_traits.hpp
cppa/util/type_traits.hpp
+6
-4
src/behavior.cpp
src/behavior.cpp
+0
-1
src/string_serialization.cpp
src/string_serialization.cpp
+3
-4
unit_testing/test_match.cpp
unit_testing/test_match.cpp
+10
-12
unit_testing/test_sync_send.cpp
unit_testing/test_sync_send.cpp
+6
-6
unit_testing/test_typed_spawn.cpp
unit_testing/test_typed_spawn.cpp
+14
-10
No files found.
CMakeLists.txt
View file @
715e1999
...
...
@@ -186,7 +186,6 @@ set(LIBCPPA_SRC
src/node_id.cpp
src/object.cpp
src/object_array.cpp
src/on.cpp
src/opt.cpp
src/partial_function.cpp
src/primitive_variant.cpp
...
...
cppa.files
View file @
715e1999
...
...
@@ -113,7 +113,7 @@ cppa/mailbox_based.hpp
cppa/mailbox_element.hpp
cppa/match.hpp
cppa/match_expr.hpp
cppa/
match_hint
.hpp
cppa/
skip_message
.hpp
cppa/memory_cached.hpp
cppa/memory_managed.hpp
cppa/message_header.hpp
...
...
@@ -293,7 +293,6 @@ src/middleman_event_handler_poll.cpp
src/node_id.cpp
src/object.cpp
src/object_array.cpp
src/on.cpp
src/opencl/actor_facade.cpp
src/opencl/global.cpp
src/opencl/opencl_metainfo.cpp
...
...
@@ -349,3 +348,4 @@ unit_testing/test_typed_remote_actor.cpp
unit_testing/test_typed_spawn.cpp
unit_testing/test_uniform_type.cpp
unit_testing/test_yield_interface.cpp
cppa/may_have_timeout.hpp
cppa/behavior.hpp
View file @
715e1999
...
...
@@ -64,8 +64,6 @@ class behavior {
inline
behavior
(
impl_ptr
ptr
);
static
constexpr
bool
may_have_timeout
=
true
;
/** @endcond */
behavior
()
=
default
;
...
...
@@ -88,6 +86,14 @@ class behavior {
template
<
typename
...
Cs
,
typename
T
,
typename
...
Ts
>
behavior
(
const
match_expr
<
Cs
...
>&
arg0
,
const
T
&
arg1
,
const
Ts
&
...
args
);
template
<
typename
F
,
typename
Enable
=
typename
std
::
enable_if
<
util
::
is_callable
<
F
>
::
value
&&
!
std
::
is_same
<
F
,
behavior
>::
value
&&
!
std
::
is_same
<
F
,
partial_function
>::
value
>::
type
>
behavior
(
F
fun
);
/**
* @brief Invokes the timeout callback.
*/
...
...
@@ -137,6 +143,10 @@ inline behavior operator,(const match_expr<Cs...>& lhs,
* inline and template member function implementations *
******************************************************************************/
template
<
typename
F
,
typename
Enable
>
behavior
::
behavior
(
F
fun
)
:
m_impl
(
detail
::
match_expr_from_functor
(
std
::
move
(
fun
)).
as_behavior_impl
())
{
}
template
<
typename
F
>
behavior
::
behavior
(
const
timeout_definition
<
F
>&
arg
)
:
m_impl
(
detail
::
new_default_behavior
(
arg
.
timeout
,
arg
.
handler
))
{
}
...
...
@@ -173,11 +183,6 @@ inline auto behavior::as_behavior_impl() const -> const impl_ptr& {
return
m_impl
;
}
//template<typename F>
//inline behavior behavior::add_continuation(F fun) {
// return {new detail::continuation_decorator<F>(std::move(fun), m_impl)};
//}
}
// namespace cppa
#endif // CPPA_BEHAVIOR_HPP
cppa/blocking_actor.hpp
View file @
715e1999
...
...
@@ -70,7 +70,7 @@ class blocking_actor
void
operator
()(
Ts
&&
...
args
)
{
static_assert
(
sizeof
...(
Ts
)
>
0
,
"operator() requires at least one argument"
);
behavior
bhvr
=
match_expr
_convert
(
std
::
forward
<
Ts
>
(
args
)...);
behavior
bhvr
=
lift_and
_convert
(
std
::
forward
<
Ts
>
(
args
)...);
while
(
m_stmt
())
m_dq
(
bhvr
);
}
...
...
@@ -85,7 +85,7 @@ class blocking_actor
template
<
typename
...
Ts
>
void
operator
()(
Ts
&&
...
args
)
{
behavior
bhvr
=
match_expr
_convert
(
std
::
forward
<
Ts
>
(
args
)...);
behavior
bhvr
=
lift_and
_convert
(
std
::
forward
<
Ts
>
(
args
)...);
for
(
;
begin
!=
end
;
++
begin
)
m_dq
(
bhvr
);
}
...
...
@@ -111,7 +111,7 @@ class blocking_actor
template
<
typename
...
Ts
>
void
receive
(
Ts
&&
...
args
)
{
static_assert
(
sizeof
...(
Ts
),
"at least one argument required"
);
dequeue
(
match_expr
_convert
(
std
::
forward
<
Ts
>
(
args
)...));
dequeue
(
lift_and
_convert
(
std
::
forward
<
Ts
>
(
args
)...));
}
/**
...
...
@@ -120,7 +120,7 @@ class blocking_actor
*/
template
<
typename
...
Ts
>
void
receive_loop
(
Ts
&&
...
args
)
{
behavior
bhvr
=
match_expr
_convert
(
std
::
forward
<
Ts
>
(
args
)...);
behavior
bhvr
=
lift_and
_convert
(
std
::
forward
<
Ts
>
(
args
)...);
for
(;;)
dequeue
(
bhvr
);
}
...
...
@@ -192,7 +192,7 @@ class blocking_actor
template
<
typename
...
Ts
>
do_receive_helper
do_receive
(
Ts
&&
...
args
)
{
return
{
make_dequeue_callback
()
,
match_expr
_convert
(
std
::
forward
<
Ts
>
(
args
)...)};
,
lift_and
_convert
(
std
::
forward
<
Ts
>
(
args
)...)};
}
optional
<
behavior
&>
sync_handler
(
message_id
msg_id
)
override
{
...
...
cppa/continue_helper.hpp
View file @
715e1999
...
...
@@ -36,6 +36,7 @@
#include "cppa/on.hpp"
#include "cppa/behavior.hpp"
#include "cppa/message_id.hpp"
#include "cppa/partial_function.hpp"
namespace
cppa
{
...
...
cppa/detail/behavior_impl.hpp
View file @
715e1999
...
...
@@ -78,9 +78,9 @@ struct optional_any_tuple_visitor {
};
template
<
typename
...
Ts
>
struct
has_
match_hint
{
struct
has_
skip_message
{
static
constexpr
bool
value
=
util
::
disjunction
<
std
::
is_same
<
Ts
,
match_hin
t
>::
value
...
std
::
is_same
<
Ts
,
skip_message_
t
>::
value
...
>::
value
;
};
...
...
@@ -188,13 +188,10 @@ class default_behavior_impl : public behavior_impl {
private:
template
<
typename
...
Ts
>
typename
std
::
enable_if
<
has_
match_hint
<
Ts
...
>::
value
,
bhvr_invoke_result
>::
type
typename
std
::
enable_if
<
has_
skip_message
<
Ts
...
>::
value
,
bhvr_invoke_result
>::
type
eval_res
(
optional_variant
<
Ts
...
>&&
res
)
{
if
(
res
)
{
if
(
res
.
template
is
<
match_hint
>())
{
if
(
get
<
match_hint
>
(
res
)
==
match_hint
::
handle
)
{
return
any_tuple
{};
}
if
(
res
.
template
is
<
skip_message_t
>())
{
return
none
;
}
return
apply_visitor
(
optional_any_tuple_visitor
{},
res
);
...
...
@@ -203,7 +200,7 @@ class default_behavior_impl : public behavior_impl {
}
template
<
typename
...
Ts
>
typename
std
::
enable_if
<!
has_
match_hint
<
Ts
...
>::
value
,
bhvr_invoke_result
>::
type
typename
std
::
enable_if
<!
has_
skip_message
<
Ts
...
>::
value
,
bhvr_invoke_result
>::
type
eval_res
(
optional_variant
<
Ts
...
>&&
res
)
{
return
apply_visitor
(
optional_any_tuple_visitor
{},
res
);
}
...
...
cppa/detail/projection.hpp
View file @
715e1999
...
...
@@ -93,25 +93,6 @@ class projection {
projection
(
const
projection
&
)
=
default
;
/**
* @brief Invokes @p fun with a projection of <tt>args...</tt> and stores
* the result of @p fun in @p result.
*/
/*
template<class PartFun>
bool invoke(PartFun& fun, typename PartFun::result_type& result, Ts... args) const {
typename collected_args_tuple<ProjectionFuns, Ts...>::type pargs;
if (collect(pargs, m_funs, std::forward<Ts>(args)...)) {
auto indices = util::get_indices(pargs);
if (is_defined_at(fun, pargs, indices)) {
result = util::apply_args(fun, pargs, indices);
return true;
}
}
return false;
}
*/
/**
* @brief Invokes @p fun with a projection of <tt>args...</tt>.
*/
...
...
cppa/detail/response_handle_util.hpp
View file @
715e1999
...
...
@@ -32,7 +32,7 @@
#define CPPA_DETAIL_RESPONSE_FUTURE_UTIL_HPP
#include "cppa/on.hpp"
#include "cppa/
match_hint
.hpp"
#include "cppa/
skip_message
.hpp"
#include "cppa/system_messages.hpp"
#include "cppa/util/type_traits.hpp"
...
...
@@ -42,9 +42,9 @@ namespace detail {
template
<
typename
Actor
,
typename
...
Fs
>
behavior
fs2bhvr
(
Actor
*
self
,
Fs
...
fs
)
{
auto
handle_sync_timeout
=
[
self
]()
->
match_hin
t
{
auto
handle_sync_timeout
=
[
self
]()
->
skip_message_
t
{
self
->
handle_sync_timeout
();
return
match_hint
::
skip
;
return
{}
;
};
return
behavior
{
on
<
sync_timeout_msg
>
()
>>
handle_sync_timeout
,
...
...
cppa/match.hpp
View file @
715e1999
...
...
@@ -37,8 +37,8 @@
#include <type_traits>
#include "cppa/any_tuple.hpp"
#include "cppa/match_hint.hpp"
#include "cppa/match_expr.hpp"
#include "cppa/skip_message.hpp"
#include "cppa/partial_function.hpp"
#include "cppa/util/tbind.hpp"
...
...
@@ -170,14 +170,8 @@ static inline bool eval_res(const optional<T>& res, bool&) {
return
static_cast
<
bool
>
(
res
);
}
static
inline
bool
eval_res
(
const
optional
<
match_hint
>&
res
,
bool
&
skipped
)
{
if
(
res
)
{
if
(
*
res
==
match_hint
::
skip
)
{
skipped
=
true
;
return
false
;
}
return
true
;
}
static
inline
bool
eval_res
(
const
optional
<
skip_message_t
>&
res
,
bool
&
skipped
)
{
if
(
res
)
skipped
=
true
;
return
false
;
}
...
...
@@ -240,13 +234,22 @@ size_t run_case(std::vector<T>& vec,
InputIterator
&
pos
,
const
InputIterator
&
end
,
Case
&
target
)
{
// check that there's no empty match expression
// (would cause indefinite recursion)
static
constexpr
size_t
num_args
=
util
::
tl_size
<
typename
Case
::
pattern_type
>::
value
;
typedef
typename
Case
::
second_type
partial_fun_type
;
typedef
typename
partial_fun_type
::
arg_types
arg_types
;
typedef
typename
util
::
tl_map
<
arg_types
,
util
::
rm_const_and_ref
>::
type
plain_args
;
static_assert
(
num_args
>
0
,
"empty match expressions are not allowed in stream matching"
);
static_assert
(
util
::
tl_forall
<
plain_args
,
util
::
tbind
<
std
::
is_same
,
T
>::
template
type
>
::
value
,
typedef
typename
Case
::
first_type
projection_type
;
typedef
typename
projection_type
::
arg_types
arg_types
;
typedef
typename
util
::
tl_map
<
arg_types
,
util
::
rm_const_and_ref
>::
type
plain_args
;
static_assert
(
util
::
tl_forall
<
plain_args
,
util
::
tbind
<
std
::
is_same
,
T
>::
template
type
>
::
value
,
"match_stream<T>: at least one callback argument "
"is not of type T"
);
while
(
vec
.
size
()
<
num_args
)
{
...
...
cppa/match_expr.hpp
View file @
715e1999
...
...
@@ -359,7 +359,6 @@ struct invoke_util
typename
util
::
tl_filter_not_type
<
Pattern
,
anything
>::
type
>
{
};
template
<
class
Pattern
,
class
Projection
,
class
PartialFun
>
struct
projection_partial_function_pair
:
std
::
pair
<
Projection
,
PartialFun
>
{
template
<
typename
...
Ts
>
...
...
@@ -629,7 +628,8 @@ struct get_case_result {
namespace
cppa
{
/**
* @brief A match expression encapsulating cases <tt>Cs...</tt>.
* @brief A match expression encapsulating cases <tt>Cs...</tt>, whereas
* each case is a @p detail::projection_partial_function_pair.
*/
template
<
class
...
Cs
>
class
match_expr
{
...
...
@@ -638,8 +638,6 @@ class match_expr {
public:
static
constexpr
bool
may_have_timeout
=
false
;
typedef
util
::
type_list
<
Cs
...
>
cases_list
;
typedef
typename
optional_variant_from_type_list
<
...
...
@@ -995,6 +993,30 @@ behavior_impl_ptr match_expr_concat(const T& arg, const Ts&... args) {
return
concat_rec
(
dummy
,
util
::
empty_type_list
{},
arg
,
args
...);
}
template
<
typename
F
>
match_expr
<
typename
get_case
<
false
,
F
,
empty_value_guard
,
util
::
empty_type_list
,
util
::
empty_type_list
>::
type
>
match_expr_from_functor
(
F
fun
)
{
typedef
typename
get_case
<
false
,
F
,
empty_value_guard
,
util
::
empty_type_list
,
util
::
empty_type_list
>::
type
result_type
;
return
result_type
{
typename
result_type
::
first_type
{},
typename
result_type
::
second_type
{
std
::
move
(
fun
),
empty_value_guard
{}}};
}
}
// namespace detail
}
// namespace cppa
...
...
src/on.c
pp
→
cppa/may_have_timeout.h
pp
View file @
715e1999
...
...
@@ -27,12 +27,32 @@
* along with libcppa. If not, see <http://www.gnu.org/licenses/>. *
\******************************************************************************/
#include "cppa/on.hpp"
#ifndef MAY_HAVE_TIMEOUT_HPP
#define MAY_HAVE_TIMEOUT_HPP
namespace
cppa
{
match_hint
skip_message
()
{
return
match_hint
::
skip
;
}
template
<
typename
F
>
struct
timeout_definition
;
class
behavior
;
template
<
typename
T
>
struct
may_have_timeout
{
static
constexpr
bool
value
=
false
;
};
template
<
>
struct
may_have_timeout
<
behavior
>
{
static
constexpr
bool
value
=
true
;
};
template
<
typename
F
>
struct
may_have_timeout
<
timeout_definition
<
F
>>
{
static
constexpr
bool
value
=
true
;
};
}
// namespace cppa
#endif // MAY_HAVE_TIMEOUT_HPP
cppa/on.hpp
View file @
715e1999
...
...
@@ -38,12 +38,12 @@
#include "cppa/unit.hpp"
#include "cppa/atom.hpp"
#include "cppa/anything.hpp"
#include "cppa/behavior.hpp"
#include "cppa/any_tuple.hpp"
#include "cppa/guard_expr.hpp"
#include "cppa/match_hint.hpp"
#include "cppa/match_expr.hpp"
#include "cppa/partial_function.hpp"
#include "cppa/skip_message.hpp"
#include "cppa/may_have_timeout.hpp"
#include "cppa/timeout_definition.hpp"
#include "cppa/util/duration.hpp"
#include "cppa/util/type_list.hpp"
...
...
@@ -227,11 +227,6 @@ namespace cppa {
*/
constexpr
anything
any_vals
=
anything
{};
/**
* @brief Returns {@link match_hint skipped}.
*/
match_hint
skip_message
();
#ifdef CPPA_DOCUMENTATION
/**
...
...
@@ -418,14 +413,16 @@ constexpr detail::on_the_fly_rvalue_builder on_arg_match;
// and even more convenience
template
<
typename
F
,
class
E
=
typename
std
::
enable_if
<
util
::
is_callable
<
F
>
::
value
>::
type
>
template
<
typename
F
,
class
E
=
typename
std
::
enable_if
<
util
::
is_callable
<
F
>
::
value
>::
type
>
inline
auto
lift_to_match_expr
(
F
fun
)
->
decltype
(
on_arg_match
>>
fun
)
{
return
(
on_arg_match
>>
fun
);
}
template
<
typename
...
Cs
>
inline
match_expr
<
Cs
...
>
lift_to_match_expr
(
match_expr
<
Cs
...
>
expr
)
{
return
std
::
move
(
expr
);
template
<
typename
T
,
class
E
=
typename
std
::
enable_if
<!
util
::
is_callable
<
T
>
::
value
>::
type
>
inline
T
lift_to_match_expr
(
T
arg
)
{
return
arg
;
}
#endif // CPPA_DOCUMENTATION
...
...
cppa/optional_variant.hpp
View file @
715e1999
...
...
@@ -38,7 +38,7 @@
#include "cppa/none.hpp"
#include "cppa/unit.hpp"
#include "cppa/optional.hpp"
#include "cppa/
match_hint
.hpp"
#include "cppa/
skip_message
.hpp"
#include "cppa/util/type_list.hpp"
#include "cppa/util/type_traits.hpp"
...
...
@@ -116,8 +116,6 @@ class optional_variant {
static
constexpr
int
void_pos
=
util
::
tl_find
<
types
,
void
>::
value
;
static
constexpr
bool
has_match_hint
=
util
::
tl_find
<
types
,
match_hint
>::
value
!=
-
1
;
/**
* @brief Checks whether this objects holds a value of type @p T.
*/
...
...
cppa/partial_function.hpp
View file @
715e1999
...
...
@@ -37,10 +37,12 @@
#include <utility>
#include <type_traits>
#include "cppa/on.hpp"
#include "cppa/behavior.hpp"
#include "cppa/any_tuple.hpp"
#include "cppa/ref_counted.hpp"
#include "cppa/intrusive_ptr.hpp"
#include "cppa/may_have_timeout.hpp"
#include "cppa/timeout_definition.hpp"
#include "cppa/util/duration.hpp"
...
...
@@ -69,8 +71,6 @@ class partial_function {
partial_function
(
impl_ptr
ptr
);
static
constexpr
bool
may_have_timeout
=
false
;
/** @endcond */
partial_function
()
=
default
;
...
...
@@ -107,7 +107,9 @@ class partial_function {
*/
template
<
typename
...
Ts
>
typename
std
::
conditional
<
util
::
disjunction
<
util
::
rm_const_and_ref
<
Ts
>::
type
::
may_have_timeout
...
>::
value
,
util
::
disjunction
<
may_have_timeout
<
typename
util
::
rm_const_and_ref
<
Ts
>::
type
>::
value
...
>::
value
,
behavior
,
partial_function
>::
type
...
...
@@ -120,7 +122,11 @@ class partial_function {
};
template
<
typename
T
>
typename
std
::
conditional
<
T
::
may_have_timeout
,
behavior
,
partial_function
>::
type
typename
std
::
conditional
<
may_have_timeout
<
T
>::
value
,
behavior
,
partial_function
>::
type
match_expr_convert
(
const
T
&
arg
)
{
return
{
arg
};
}
...
...
@@ -128,9 +134,9 @@ match_expr_convert(const T& arg) {
template
<
typename
T0
,
typename
T1
,
typename
...
Ts
>
typename
std
::
conditional
<
util
::
disjunction
<
T0
::
may_have_timeout
,
T1
::
may_have_timeout
,
Ts
::
may_have_timeout
...
may_have_timeout
<
T0
>::
value
,
may_have_timeout
<
T1
>::
value
,
may_have_timeout
<
Ts
>::
value
...
>::
value
,
behavior
,
partial_function
...
...
@@ -139,6 +145,20 @@ match_expr_convert(const T0& arg0, const T1& arg1, const Ts&... args) {
return
detail
::
match_expr_concat
(
arg0
,
arg1
,
args
...);
}
// calls match_expr_convert(lift_to_match_expr(args)...)
template
<
typename
...
Ts
>
typename
std
::
conditional
<
util
::
disjunction
<
may_have_timeout
<
Ts
>::
value
...
>::
value
,
behavior
,
partial_function
>::
type
lift_and_convert
(
Ts
&&
...
args
)
{
static_assert
(
sizeof
...(
Ts
)
>
0
,
"at least one argument required"
);
return
match_expr_convert
(
lift_to_match_expr
(
std
::
forward
<
Ts
>
(
args
))...);
}
template
<
typename
...
Cases
>
partial_function
operator
,(
const
match_expr
<
Cases
...
>&
mexpr
,
const
partial_function
&
pfun
)
{
...
...
@@ -174,7 +194,9 @@ inline optional<any_tuple> partial_function::operator()(T&& arg) {
template
<
typename
...
Ts
>
typename
std
::
conditional
<
util
::
disjunction
<
util
::
rm_const_and_ref
<
Ts
>::
type
::
may_have_timeout
...
>::
value
,
util
::
disjunction
<
may_have_timeout
<
typename
util
::
rm_const_and_ref
<
Ts
>::
type
>::
value
...
>::
value
,
behavior
,
partial_function
>::
type
...
...
cppa/
match_hint
.hpp
→
cppa/
skip_message
.hpp
View file @
715e1999
...
...
@@ -31,8 +31,6 @@
#ifndef CPPA_MATCH_HINT_HPP
#define CPPA_MATCH_HINT_HPP
#include <iosfwd>
namespace
cppa
{
/**
...
...
@@ -40,13 +38,19 @@ namespace cppa {
* expressions. This type is evaluated by the runtime system of libcppa
* and can be used to intentionally skip messages.
*/
enum
class
match_hint
{
skip
,
handle
};
struct
skip_message_t
{
constexpr
skip_message_t
()
{
}
};
/**
* @brief Tells the runtime system to skip a message when used as message
* handler, i.e., causes the runtime to leave the message in
* the mailbox of an actor.
*/
constexpr
skip_message_t
skip_message
()
{
return
{};
}
// implemented in string_serialization.cpp
std
::
ostream
&
operator
<<
(
std
::
ostream
&
,
match_hin
t
);
std
::
ostream
&
operator
<<
(
std
::
ostream
&
,
skip_message_
t
);
}
// namespace cppa
...
...
cppa/typed_behavior.hpp
View file @
715e1999
...
...
@@ -33,6 +33,7 @@
#include "cppa/behavior.hpp"
#include "cppa/match_expr.hpp"
#include "cppa/typed_continue_helper.hpp"
#include "cppa/detail/typed_actor_util.hpp"
...
...
@@ -43,51 +44,69 @@ namespace detail {
template
<
typename
...
Rs
>
class
functor_based_typed_actor
;
template
<
typename
T
>
struct
match_hint_to_void
{
typedef
T
type
;
}
;
// converts a list of replies_to<...>::with<...> elements to a list of
// lists containing the replies_to<...> half only
template
<
typename
List
>
struct
input_only
;
template
<
>
struct
match_hint_to_void
<
match_hint
>
{
typedef
void
type
;
};
template
<
typename
T
>
struct
infer_result_from_continue_helper
{
typedef
T
type
;
template
<
typename
...
Ts
>
struct
input_only
<
util
::
type_list
<
Ts
...
>>
{
typedef
util
::
type_list
<
typename
Ts
::
input_types
...
>
type
;
};
template
<
typename
R
>
struct
infer_result_from_continue_helper
<
typed_continue_helper
<
R
>>
{
typedef
R
type
;
};
typedef
util
::
type_list
<
skip_message_t
>
skip_list
;
template
<
class
List
>
struct
collapse_infered_list
{
struct
unbox_typed_continue_helper
{
// do nothing if List is actually a list, i.e., not a typed_continue_helper
typedef
List
type
;
};
template
<
typename
...
Ts
>
struct
collapse_infered_list
<
util
::
type_list
<
util
::
type_list
<
Ts
...
>>>
{
typedef
util
::
type_list
<
Ts
...
>
type
;
template
<
class
List
>
struct
unbox_typed_continue_helper
<
util
::
type_list
<
typed_continue_helper
<
List
>>>
{
typedef
List
type
;
};
template
<
typename
T
>
struct
infer_response_types
{
typedef
typename
T
::
input_types
input_types
;
typedef
typename
util
::
tl_map
<
typename
T
::
output_types
,
match_hint_to_void
,
infer_result_from_continue_helper
template
<
typename
SList
>
struct
valid_input_predicate
{
typedef
typename
input_only
<
SList
>::
type
s_inputs
;
template
<
typename
Expr
>
struct
inner
{
typedef
typename
Expr
::
input_types
input_types
;
typedef
typename
unbox_typed_continue_helper
<
typename
Expr
::
output_types
>::
type
output_types
;
typedef
typename
replies_to_from_type_list
<
input_types
,
// continue_helper stores a type list,
// so we need to collapse the list here
typename
collapse_infered_list
<
output_types
>::
type
>::
type
type
;
static
constexpr
int
pos
=
util
::
tl_find
<
s_inputs
,
input_types
>::
value
;
static_assert
(
pos
!=
-
1
,
"cannot assign given match expression to "
"typed behavior, because the expression "
"contains at least one pattern that is "
"not defined in the actor's type"
);
typedef
typename
util
::
tl_at
<
SList
,
pos
>::
type
s_element
;
typedef
typename
s_element
::
output_types
s_out
;
static
constexpr
bool
value
=
std
::
is_same
<
output_types
,
s_out
>::
value
||
std
::
is_same
<
output_types
,
skip_list
>::
value
;
static_assert
(
value
,
"wtf"
);
};
};
// Tests whether the input list (IList) matches the
// signature list (SList) for a typed actor behavior
template
<
class
SList
,
class
IList
>
struct
valid_input
{
// check for each element in IList that there's an element in SList that
// (1) has an identical input type list
// (2) has an identical output type list
// OR the output of the element in IList is skip_message_t
static_assert
(
util
::
tl_is_distinct
<
IList
>::
value
,
"given pattern is not distinct"
);
static
constexpr
bool
value
=
util
::
tl_size
<
SList
>::
value
==
util
::
tl_size
<
IList
>::
value
&&
util
::
tl_forall
<
IList
,
valid_input_predicate
<
SList
>::
template
inner
>
::
value
;
};
// this function is called from typed_behavior<...>::set and its whole
...
...
@@ -95,12 +114,12 @@ struct infer_response_types {
// (this function only has the type informations needed to understand the error)
template
<
class
SignatureList
,
class
InputList
>
void
static_check_typed_behavior_input
()
{
constexpr
bool
is_
equal
=
util
::
tl_equal
<
SignatureList
,
InputList
>::
value
;
constexpr
bool
is_
valid
=
valid_input
<
SignatureList
,
InputList
>::
value
;
// note: it might be worth considering to allow a wildcard in the
// InputList if its return type is identical to all "missing"
// input types ... however, it might lead to unexpected results
// and would cause a lot of not-so-straightforward code here
static_assert
(
is_
equal
,
"given pattern cannot be used to initialize "
static_assert
(
is_
valid
,
"given pattern cannot be used to initialize "
"typed behavior (exact match needed)"
);
}
...
...
@@ -181,11 +200,7 @@ class typed_behavior {
typedef
typename
util
::
tl_map
<
util
::
type_list
<
typename
detail
::
deduce_signature
<
Cs
>::
type
...
>
,
// returning a match_hint from a message handler does
// not send anything back, so we can consider
// match_hint to be void
detail
::
infer_response_types
>
>::
type
input
;
// check types
...
...
cppa/typed_continue_helper.hpp
View file @
715e1999
...
...
@@ -35,6 +35,8 @@
#include "cppa/util/type_traits.hpp"
#include "cppa/detail/typed_actor_util.hpp"
namespace
cppa
{
template
<
typename
OutputList
>
...
...
cppa/util/type_traits.hpp
View file @
715e1999
...
...
@@ -40,7 +40,8 @@
#include "cppa/util/type_list.hpp"
#include "cppa/util/type_traits.hpp"
namespace
cppa
{
namespace
util
{
namespace
cppa
{
namespace
util
{
/**
* @addtogroup MetaProgramming
...
...
@@ -59,7 +60,7 @@ template<typename T> struct rm_const_and_ref<const T> { typedef T type; };
template
<
typename
T
>
struct
rm_const_and_ref
<
T
&>
{
typedef
T
type
;
};
template
<
>
struct
rm_const_and_ref
<
void
>
{
};
//
template<> struct rm_const_and_ref<void> { };
/**
* @brief Joins all bool constants using operator &&.
...
...
@@ -94,7 +95,6 @@ struct disjunction<V0, Vs...> {
template
<
>
struct
disjunction
<>
{
static
constexpr
bool
value
=
false
;
};
/**
* @brief Equal to std::is_same<T, anything>.
*/
...
...
@@ -496,6 +496,8 @@ struct type_at<0, T0, Ts...> {
/**
* @}
*/
}
}
// namespace cppa::util
}
// namespace util
}
// namespace cppa
#endif // CPPA_UTIL_TYPE_TRAITS_HPP
src/behavior.cpp
View file @
715e1999
...
...
@@ -86,5 +86,4 @@ behavior behavior::add_continuation(continuation_fun fun) {
return
{
new
continuation_decorator
(
std
::
move
(
fun
),
m_impl
)};
}
}
// namespace cppa
src/string_serialization.cpp
View file @
715e1999
...
...
@@ -38,11 +38,11 @@
#include "cppa/atom.hpp"
#include "cppa/object.hpp"
#include "cppa/to_string.hpp"
#include "cppa/match_hint.hpp"
#include "cppa/serializer.hpp"
#include "cppa/singletons.hpp"
#include "cppa/from_string.hpp"
#include "cppa/deserializer.hpp"
#include "cppa/skip_message.hpp"
#include "cppa/actor_namespace.hpp"
#include "cppa/primitive_variant.hpp"
#include "cppa/uniform_type_info.hpp"
...
...
@@ -526,9 +526,8 @@ string to_verbose_string(const exception& e) {
return
oss
.
str
();
}
std
::
ostream
&
operator
<<
(
std
::
ostream
&
out
,
match_hint
mh
)
{
return
out
<<
(
mh
==
match_hint
::
handle
?
"match_hint::handle"
:
"match_hint::skip"
);
std
::
ostream
&
operator
<<
(
std
::
ostream
&
out
,
skip_message_t
)
{
return
out
<<
"skip_message"
;
}
}
// namespace cppa
unit_testing/test_match.cpp
View file @
715e1999
...
...
@@ -268,17 +268,12 @@ void test_match_stream() {
CPPA_CHECK
(
name
==
"foo"
||
name
==
"bar"
);
return
name
==
"foo"
||
name
==
"bar"
;
},
on
(
"-p"
,
arg_match
)
>>
[
&
](
const
string
&
port
)
->
match_hint
{
auto
i
=
toint
(
port
);
if
(
i
)
{
CPPA_CHECK_EQUAL
(
*
i
,
2
);
return
match_hint
::
handle
;
}
else
return
match_hint
::
skip
;
on
(
"-p"
,
toint
)
>>
[
&
](
int
port
)
{
CPPA_CHECK_EQUAL
(
port
,
2
);
},
on_arg_match
>>
[](
const
string
&
arg
)
->
match_hin
t
{
on_arg_match
>>
[](
const
string
&
arg
)
->
skip_message_
t
{
CPPA_FAILURE
(
"unexpected string: "
<<
arg
);
return
match_hint
::
skip
;
return
{}
;
}
);
CPPA_CHECK_EQUAL
(
success
,
true
);
...
...
@@ -291,10 +286,13 @@ void test_behavior() {
CPPA_CHECK_EQUAL(static_cast<bool>(pf(tup)), expected_result); \
CPPA_CHECK_EQUAL(last_invoked_fun, str); \
}
auto
not_42
=
[](
int
i
)
->
optional
<
int
>
{
if
(
i
!=
42
)
return
i
;
return
none
;
};
behavior
bhvr1
{
on
<
int
>
()
>>
[
&
](
int
i
)
->
match_hint
{
on
(
not_42
)
>>
[
&
](
int
)
{
last_invoked_fun
=
"<int>@1"
;
return
(
i
==
42
)
?
match_hint
::
skip
:
match_hint
::
handle
;
},
on
<
float
>
()
>>
[
&
]
{
last_invoked_fun
=
"<float>@2"
;
...
...
@@ -306,7 +304,7 @@ void test_behavior() {
last_invoked_fun
=
"<*>@4"
;
}
};
bhvr_check
(
bhvr1
,
make_any_tuple
(
42
),
false
,
"<int>@1
"
);
bhvr_check
(
bhvr1
,
make_any_tuple
(
42
),
true
,
"<int>@3
"
);
bhvr_check
(
bhvr1
,
make_any_tuple
(
24
),
true
,
"<int>@1"
);
bhvr_check
(
bhvr1
,
make_any_tuple
(
2.
f
),
true
,
"<float>@2"
);
bhvr_check
(
bhvr1
,
make_any_tuple
(
""
),
true
,
"<*>@4"
);
...
...
unit_testing/test_sync_send.cpp
View file @
715e1999
...
...
@@ -217,16 +217,16 @@ void test_sync_send() {
self
->
send_exit
(
mirror
,
exit_reason
::
user_shutdown
);
self
->
await_all_other_actors_done
();
CPPA_CHECKPOINT
();
auto
non_normal_down_msg
=
[](
down_msg
dm
)
->
optional
<
down_msg
>
{
if
(
dm
.
reason
!=
exit_reason
::
normal
)
return
dm
;
return
none
;
};
auto
await_success_message
=
[
&
]
{
self
->
receive
(
on
(
atom
(
"success"
))
>>
CPPA_CHECKPOINT_CB
(),
on
(
atom
(
"failure"
))
>>
CPPA_FAILURE_CB
(
"A didn't receive sync response"
),
on_arg_match
>>
[
&
](
const
down_msg
&
dm
)
->
match_hint
{
if
(
dm
.
reason
!=
exit_reason
::
normal
)
{
on
(
non_normal_down_msg
)
>>
[
&
](
const
down_msg
&
dm
)
{
CPPA_FAILURE
(
"A exited for reason "
<<
dm
.
reason
);
return
match_hint
::
handle
;
}
return
match_hint
::
skip
;
}
);
};
...
...
unit_testing/test_typed_spawn.cpp
View file @
715e1999
...
...
@@ -137,7 +137,7 @@ typedef typed_actor<
replies_to
<
get_state_msg
>::
with
<
string
>
,
replies_to
<
string
>::
with
<
void
>
,
replies_to
<
float
>::
with
<
void
>
,
replies_to
<
int
>::
with
<
void
>
replies_to
<
int
>::
with
<
int
>
>
event_testee_type
;
...
...
@@ -162,12 +162,11 @@ class event_testee : public event_testee_type::base {
on
<
get_state_msg
>
()
>>
[]
{
return
"wait4int"
;
},
on
<
int
>
()
>>
[
=
]
{
on
<
int
>
()
>>
[
=
]
()
->
int
{
become
(
wait4float
());
return
42
;
},
(
on
<
float
>
()
||
on
<
string
>
())
>>
[]
{
return
match_hint
::
skip
;
}
(
on
<
float
>
()
||
on
<
string
>
())
>>
skip_message
};
}
...
...
@@ -179,9 +178,7 @@ class event_testee : public event_testee_type::base {
on
<
float
>
()
>>
[
=
]
{
become
(
wait4string
());
},
(
on
<
string
>
()
||
on
<
int
>
())
>>
[]
{
return
match_hint
::
skip
;
}
(
on
<
string
>
()
||
on
<
int
>
())
>>
skip_message
};
}
...
...
@@ -208,11 +205,18 @@ void test_event_testee() {
set
<
string
>
iface
{
"cppa::replies_to<get_state_msg>::with<@str>"
,
"cppa::replies_to<@str>::with<void>"
,
"cppa::replies_to<float>::with<void>"
,
"cppa::replies_to<@i32>::with<
void
>"
};
"cppa::replies_to<@i32>::with<
@i32
>"
};
CPPA_CHECK
(
sub_et
->
interface
()
==
iface
);
self
->
send
(
sub_et
,
get_state_msg
{});
// we expect three 42s
int
i
=
0
;
self
->
receive_for
(
i
,
3
)
(
[](
int
value
)
{
CPPA_CHECK_EQUAL
(
value
,
42
);
}
);
self
->
receive
(
on_arg_match
>>
[
&
](
const
string
&
str
)
{
[
&
](
const
string
&
str
)
{
result
=
str
;
},
after
(
chrono
::
minutes
(
1
))
>>
[
&
]()
{
...
...
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