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
f2f60445
Commit
f2f60445
authored
May 26, 2015
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Simplify advanced match case a bit
parent
d90a8554
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
137 additions
and
240 deletions
+137
-240
libcaf_core/caf/detail/behavior_impl.hpp
libcaf_core/caf/detail/behavior_impl.hpp
+1
-1
libcaf_core/caf/detail/match_case_builder.hpp
libcaf_core/caf/detail/match_case_builder.hpp
+102
-145
libcaf_core/caf/match_case.hpp
libcaf_core/caf/match_case.hpp
+33
-93
libcaf_core/caf/on.hpp
libcaf_core/caf/on.hpp
+1
-1
No files found.
libcaf_core/caf/detail/behavior_impl.hpp
View file @
f2f60445
...
...
@@ -209,7 +209,7 @@ intrusive_ptr<R> make_behavior_ra(timeout_definition<F>& td,
}
template
<
class
R
,
class
...
Ts
>
intrusive_ptr
<
R
>
make_behavior_ra
(
tail_argument_token
&
,
Ts
...
xs
)
{
intrusive_ptr
<
R
>
make_behavior_ra
(
tail_argument_token
&
,
Ts
&
...
xs
)
{
return
make_behavior_eor
<
R
>
(
std
::
tuple_cat
(
to_match_case_tuple
(
xs
)...));
}
...
...
libcaf_core/caf/detail/m
essage
_case_builder.hpp
→
libcaf_core/caf/detail/m
atch
_case_builder.hpp
View file @
f2f60445
...
...
@@ -26,6 +26,8 @@
#include "caf/match_case.hpp"
#include "caf/timeout_definition.hpp"
#include "caf/detail/tail_argument_token.hpp"
namespace
caf
{
namespace
detail
{
...
...
@@ -105,79 +107,97 @@ struct tuple_maker {
struct
variadic_ctor
{};
template
<
class
Expr
,
class
Transformers
,
class
Pattern
>
struct
get_advanced_match_case
{
using
ctrait
=
typename
get_callable_trait
<
Expr
>::
type
;
template
<
class
F
,
class
Projections
,
class
Pattern
>
struct
advanced_match_case_factory
{
static
constexpr
bool
uses_arg_match
=
std
::
is_same
<
arg_match_t
,
typename
detail
::
tl_back
<
Pattern
>::
type
>::
value
;
using
fargs
=
typename
get_callable_trait
<
F
>::
arg_types
;
static
constexpr
size_t
fargs_size
=
detail
::
tl_size
<
fargs
>::
value
;
using
decayed_fargs
=
typename
tl_map
<
fargs
,
std
::
decay
>::
type
;
using
concatenated_pattern
=
typename
detail
::
tl_concat
<
typename
detail
::
tl_pop_back
<
Pattern
>::
type
,
decayed_fargs
>::
type
;
using
full_pattern
=
typename
std
::
conditional
<
uses_arg_match
,
concatenated_pattern
,
Pattern
>::
type
;
using
filtered_pattern
=
typename
tl_filter_not_type
<
P
attern
,
typename
detail
::
tl_filter_not_type
<
full_p
attern
,
anything
>::
type
;
using
padded_
transformer
s
=
typename
tl_pad_right
<
Transformer
s
,
tl_size
<
filtered_pattern
>::
value
using
padded_
projection
s
=
typename
detail
::
tl_pad_right
<
Projection
s
,
detail
::
tl_size
<
filtered_pattern
>::
value
>::
type
;
using
base_signature
=
typename
tl_map
<
filtered_pattern
,
std
::
add_const
,
std
::
add_lvalue_reference
using
projection_funs
=
typename
detail
::
tl_apply
<
padded_projections
,
std
::
tuple
>::
type
;
using
padded_expr_args
=
typename
tl_map_conditional
<
typename
tl_pad_left
<
typename
ctrait
::
arg_types
,
tl_size
<
filtered_pattern
>::
value
using
tuple_type
=
typename
detail
::
tl_apply
<
typename
detail
::
tl_zip_right
<
typename
detail
::
tl_map
<
padded_projections
,
projection_result
>::
type
,
fargs
,
detail
::
left_or_right
,
fargs_size
>::
type
,
std
::
is_lvalue_reference
,
false
,
std
::
add_const
,
std
::
add_lvalue_reference
std
::
tuple
>::
type
;
// override base signature with required argument types of Expr
// and result types of transformation
using
partial_fun_signature
=
typename
tl_zip
<
typename
tl_map
<
padded_transformers
,
map_to_result_type
,
rm_optional
,
std
::
add_lvalue_reference
>::
type
,
typename
tl_zip
<
padded_expr_args
,
base_signature
,
left_or_right
>::
type
,
left_or_right
using
padding
=
typename
detail
::
tl_apply
<
typename
detail
::
tl_replicate
<
fargs_size
,
unit_t
>::
type
,
std
::
tuple
>::
type
;
// 'inherit' mutable references from partial_fun_signature
// for arguments without transformation
using
projection_signature
=
typename
tl_zip
<
typename
tl_zip
<
padded_transformers
,
partial_fun_signature
,
if_not_left
>::
type
,
base_signature
,
deduce_ref_type
>::
type
;
static
projection_funs
pad
(
projection_funs
res
,
std
::
false_type
)
{
return
std
::
move
(
res
);
}
template
<
class
Guards
>
static
projection_funs
pad
(
Guards
gs
,
std
::
true_type
)
{
return
std
::
tuple_cat
(
std
::
move
(
gs
),
padding
{});
}
using
case_type
=
advanced_match_case_impl
<
F
,
tuple_type
,
full_pattern
,
projection_funs
>
;
using
type
=
advanced_match_case_impl
<
Expr
,
Pattern
,
padded_transformers
,
projection_signature
>
;
template
<
class
Guards
>
static
case_type
create
(
F
f
,
Guards
gs
)
{
std
::
integral_constant
<
bool
,
uses_arg_match
>
tk
;
return
{
tl_exists
<
full_pattern
,
is_anything
>::
value
,
make_type_token_from_list
<
full_pattern
>
(),
std
::
move
(
f
)
,
pad
(
std
::
move
(
gs
),
tk
)};
}
};
template
<
class
X
,
class
Y
>
...
...
@@ -190,40 +210,42 @@ struct pattern_projection_zipper<anything, Y> {
using
type
=
none_t
;
};
template
<
class
Projections
,
class
Pattern
,
bool
UsesArgMatch
=
std
::
is_same
<
arg_match_t
,
typename
tl_back
<
Pattern
>
::
type
>::
value
>
template
<
class
Projections
,
class
Pattern
>
class
advanced_match_case_builder
:
public
message_case_builder
{
public:
using
guards_tuple
=
typename
tl_
apply
<
// discard projection if at the same index in Pattern is a wildcard
typename
tl_filter_not_type
<
typename
tl_zip
<
Pattern
,
Projections
,
pattern_projection_zipper
>::
type
,
none_t
using
filtered_projections
=
typename
tl_
filter_not_type
<
typename
tl_zip
<
Pattern
,
Projections
,
pattern_projection_zipper
>::
type
,
std
::
tuple
none_t
>::
type
;
advanced_match_case_builder
()
=
default
;
using
guards_tuple
=
typename
detail
::
tl_apply
<
typename
std
::
conditional
<
std
::
is_same
<
arg_match_t
,
typename
tl_back
<
Pattern
>::
type
>::
value
,
typename
tl_pop_back
<
filtered_projections
>::
type
,
filtered_projections
>::
type
,
std
::
tuple
>::
type
;
template
<
class
...
Fs
>
advanced_match_case_builder
(
variadic_ctor
,
Fs
...
fs
)
:
m_guards
(
make_guards
(
Pattern
{},
fs
...))
{
// nop
}
advanced_match_case_builder
(
guards_tuple
arg1
)
:
m_guards
(
std
::
move
(
arg1
))
{
:
m_g
(
make_guards
(
Pattern
{},
fs
...))
{
// nop
}
template
<
class
F
>
typename
get_advanced_match_case
<
F
,
Projections
,
Pattern
>::
type
typename
advanced_match_case_factory
<
F
,
Projections
,
Pattern
>::
case_
type
operator
>>
(
F
f
)
const
{
return
{
f
,
m_guards
}
;
return
advanced_match_case_factory
<
F
,
Projections
,
Pattern
>::
create
(
f
,
m_g
)
;
}
private:
...
...
@@ -232,71 +254,6 @@ class advanced_match_case_builder : public message_case_builder {
return
std
::
make_tuple
(
std
::
move
(
fs
)...);
}
template
<
class
T
,
class
F
,
class
...
Fs
>
static
guards_tuple
make_guards
(
std
::
pair
<
wrapped
<
T
>
,
F
>
x
,
Fs
&&
...
fs
)
{
return
make_guards
(
std
::
forward
<
Fs
>
(
fs
)...,
x
.
second
);
}
template
<
class
F
,
class
...
Fs
>
static
guards_tuple
make_guards
(
std
::
pair
<
wrapped
<
anything
>
,
F
>
,
Fs
&&
...
fs
)
{
return
make_guards
(
std
::
forward
<
Fs
>
(
fs
)...);
}
template
<
class
...
Ts
,
class
...
Fs
>
static
guards_tuple
make_guards
(
type_list
<
Ts
...
>
,
Fs
&
...
fs
)
{
tail_argument_token
eoa
;
return
make_guards
(
std
::
make_pair
(
wrapped
<
Ts
>
(),
std
::
ref
(
fs
))...,
eoa
);
}
guards_tuple
m_guards
;
};
template
<
class
Projections
,
class
Pattern
>
struct
advanced_match_case_builder
<
Projections
,
Pattern
,
true
>
:
public
message_case_builder
{
public:
using
guards_tuple
=
typename
detail
::
tl_apply
<
typename
tl_pop_back
<
Projections
>::
type
,
std
::
tuple
>::
type
;
using
pattern
=
typename
tl_pop_back
<
Pattern
>::
type
;
advanced_match_case_builder
()
=
default
;
template
<
class
...
Fs
>
advanced_match_case_builder
(
variadic_ctor
,
Fs
...
fs
)
:
m_guards
(
make_guards
(
Pattern
{},
fs
...))
{
// nop
}
advanced_match_case_builder
(
guards_tuple
arg1
)
:
m_guards
(
std
::
move
(
arg1
))
{
// nop
}
template
<
class
F
>
typename
get_advanced_match_case
<
F
,
Projections
,
typename
tl_concat
<
pattern
,
typename
tl_map
<
typename
get_callable_trait
<
F
>::
arg_types
,
std
::
decay
>::
type
>::
type
>::
type
operator
>>
(
F
f
)
const
{
using
padding
=
typename
tl_apply
<
typename
tl_replicate
<
get_callable_trait
<
F
>::
num_args
,
unit_t
>::
type
,
std
::
tuple
>::
type
;
return
{
f
,
std
::
tuple_cat
(
m_guards
,
padding
{})};
}
private:
static
guards_tuple
make_guards
(
tail_argument_token
&
)
{
return
{};
}
...
...
@@ -323,7 +280,7 @@ struct advanced_match_case_builder<Projections, Pattern, true>
return
make_guards
(
std
::
make_pair
(
wrapped
<
Ts
>
(),
std
::
ref
(
fs
))...,
eoa
);
}
guards_tuple
m_g
uards
;
guards_tuple
m_g
;
};
template
<
class
Left
,
class
Right
>
...
...
libcaf_core/caf/match_case.hpp
View file @
f2f60445
...
...
@@ -317,28 +317,13 @@ struct projection_is_trivial {
>
::
value
==
0
;
};
/*
* A lifted functor consists of a set of projections, a plain-old
* functor and its signature. Note that the signature of the lifted
* functor might differ from the underlying functor, because
* of the projections.
/**
* @tparam F Function or function object denoting the callback.
* @tparam Tuple Type of the storage for intermediate results during matching.
* @tparam Pattern Input types for this match case.
*/
template
<
class
F
,
class
Pattern
,
class
Projections
,
class
Signature
>
class
advanced_match_case_impl
:
public
advanced_match_case
<
F
,
typename
detail
::
tl_apply
<
typename
detail
::
tl_zip_right
<
typename
detail
::
tl_map
<
Projections
,
projection_result
>::
type
,
typename
detail
::
get_callable_trait
<
F
>::
arg_types
,
detail
::
left_or_right
,
detail
::
get_callable_trait
<
F
>::
num_args
>::
type
,
std
::
tuple
>::
type
>
{
template
<
class
F
,
class
Tuple
,
class
Pattern
,
class
Projections
>
class
advanced_match_case_impl
:
public
advanced_match_case
<
F
,
Tuple
>
{
public:
using
plain_result_type
=
typename
detail
::
get_callable_trait
<
F
>::
result_type
;
...
...
@@ -349,22 +334,8 @@ class advanced_match_case_impl : public
typename
std
::
remove_const
<
plain_result_type
>::
type
>::
type
;
using
pattern
=
Pattern
;
using
filtered_pattern
=
typename
detail
::
tl_filter_not_type
<
Pattern
,
anything
>::
type
;
using
intermediate_tuple
=
typename
detail
::
tl_apply
<
filtered_pattern
,
detail
::
pseudo_tuple
>::
type
;
static
constexpr
uint32_t
static_type_token
=
detail
::
make_type_token_from_list
<
p
attern
>
();
detail
::
make_type_token_from_list
<
P
attern
>
();
// Let F be "R (Ts...)" then match_case<F...> returns optional<R>
// unless R is void in which case bool is returned
...
...
@@ -375,73 +346,42 @@ class advanced_match_case_impl : public
optional
<
result_type
>
>::
type
;
using
projections_list
=
Projections
;
// Needed for static type checking when assigning to a typed behavior.
using
arg_types
=
Pattern
;
using
projections
=
typename
detail
::
tl_apply
<
projections_list
,
std
::
tuple
>::
type
;
using
fargs
=
typename
detail
::
get_callable_trait
<
F
>::
arg_types
;
/*
* Needed for static type checking when assigning to a typed behavior.
*/
using
arg_types
=
Signature
;
static
constexpr
size_t
fargs_size
=
detail
::
tl_size
<
fargs
>::
value
;
using
fun_args
=
typename
detail
::
get_callable_trait
<
F
>::
arg_types
;
using
super
=
advanced_match_case
<
F
,
Tuple
>
;
static
constexpr
size_t
num_fun_args
=
detail
::
tl_size
<
fun_args
>::
value
;
static
constexpr
bool
is_manipulator
=
detail
::
tl_exists
<
fun_args
,
detail
::
is_mutable_ref
>::
value
;
using
tuple_type
=
typename
detail
::
tl_apply
<
typename
detail
::
tl_zip_right
<
typename
detail
::
tl_map
<
projections_list
,
projection_result
>::
type
,
fun_args
,
detail
::
left_or_right
,
num_fun_args
>::
type
,
std
::
tuple
>::
type
;
using
super
=
advanced_match_case
<
F
,
tuple_type
>
;
advanced_match_case_impl
()
=
default
;
advanced_match_case_impl
(
advanced_match_case_impl
&&
)
=
default
;
advanced_match_case_impl
(
const
advanced_match_case_impl
&
)
=
default
;
advanced_match_case_impl
&
operator
=
(
advanced_match_case_impl
&&
)
=
default
;
advanced_match_case_impl
&
operator
=
(
const
advanced_match_case_impl
&
)
=
default
;
advanced_match_case_impl
(
F
f
)
:
super
(
pattern_has_wildcard
<
Pattern
>::
value
,
static_type_token
,
std
::
move
(
f
))
{
// nop
}
advanced_match_case_impl
(
F
f
,
projections
ps
)
:
super
(
pattern_has_wildcard
<
Pattern
>::
value
,
static_type_token
,
std
::
move
(
f
)),
advanced_match_case_impl
(
bool
has_wcard
,
uint32_t
ttoken
,
F
f
,
Projections
ps
)
:
super
(
has_wcard
,
ttoken
,
std
::
move
(
f
)),
m_ps
(
std
::
move
(
ps
))
{
// nop
}
bool
prepare_invoke
(
message
&
msg
,
tuple_typ
e
*
out
)
{
bool
prepare_invoke
(
message
&
msg
,
Tupl
e
*
out
)
{
// detach msg before invoking m_fun if needed
if
(
is_manipulator
)
{
if
(
detail
::
tl_exists
<
fargs
,
detail
::
is_mutable_ref
>::
value
)
{
msg
.
force_detach
();
}
using
filtered_pattern
=
typename
detail
::
tl_filter_not_type
<
Pattern
,
anything
>::
type
;
using
intermediate_tuple
=
typename
detail
::
tl_apply
<
filtered_pattern
,
detail
::
pseudo_tuple
>::
type
;
intermediate_tuple
it
;
detail
::
meta_elements
<
p
attern
>
ms
;
detail
::
meta_elements
<
P
attern
>
ms
;
// check if try_match() reports success
if
(
!
detail
::
try_match
(
msg
,
ms
.
arr
.
data
(),
ms
.
arr
.
size
(),
it
.
data
))
{
return
false
;
...
...
@@ -449,8 +389,8 @@ class advanced_match_case_impl : public
match_case_zipper
zip
;
using
indices_type
=
typename
detail
::
il_indices
<
intermediate_tuple
>::
type
;
//indices_type indices;
typename
detail
::
il_take
<
indices_type
,
detail
::
tl_size
<
projections_list
>::
value
-
num_fun_args
>::
type
lefts
;
typename
detail
::
il_right
<
indices_type
,
num_fun_args
>::
type
rights
;
typename
detail
::
il_take
<
indices_type
,
std
::
tuple_size
<
Projections
>::
value
-
fargs_size
>::
type
lefts
;
typename
detail
::
il_right
<
indices_type
,
fargs_size
>::
type
rights
;
has_none
hn
;
// check if guards of discarded arguments are fulfilled
auto
lhs_tup
=
tuple_zip
(
zip
,
lefts
,
m_ps
,
it
);
...
...
@@ -458,18 +398,18 @@ class advanced_match_case_impl : public
return
false
;
}
// zip remaining arguments into output tuple
new
(
out
)
tuple_type
(
tuple_zip
(
zip
,
rights
,
m_ps
,
it
));
new
(
out
)
Tuple
(
tuple_zip
(
zip
,
rights
,
m_ps
,
it
));
//tuple_type rhs_tup = tuple_zip(zip, rights, m_ps, it);
// check if remaining guards are fulfilled
if
(
detail
::
apply_args
(
hn
,
detail
::
get_indices
(
*
out
),
*
out
))
{
out
->~
tuple_typ
e
();
out
->~
Tupl
e
();
return
false
;
}
return
true
;
}
private:
p
rojections
m_ps
;
P
rojections
m_ps
;
};
struct
match_case_info
{
...
...
libcaf_core/caf/on.hpp
View file @
f2f60445
...
...
@@ -39,9 +39,9 @@
#include "caf/detail/type_list.hpp"
#include "caf/detail/arg_match_t.hpp"
#include "caf/detail/type_traits.hpp"
#include "caf/detail/match_case_builder.hpp"
#include "caf/detail/tail_argument_token.hpp"
#include "caf/detail/implicit_conversions.hpp"
#include "caf/detail/message_case_builder.hpp"
namespace
caf
{
namespace
detail
{
...
...
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