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
9aa81913
Commit
9aa81913
authored
Jun 22, 2016
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Simplify implementation of behaviors
parent
37b08840
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
161 additions
and
124 deletions
+161
-124
libcaf_core/caf/detail/behavior_impl.hpp
libcaf_core/caf/detail/behavior_impl.hpp
+104
-121
libcaf_core/caf/detail/int_list.hpp
libcaf_core/caf/detail/int_list.hpp
+8
-0
libcaf_core/caf/detail/type_list.hpp
libcaf_core/caf/detail/type_list.hpp
+17
-1
libcaf_core/caf/timeout_definition.hpp
libcaf_core/caf/timeout_definition.hpp
+25
-0
libcaf_core/caf/typed_behavior.hpp
libcaf_core/caf/typed_behavior.hpp
+7
-2
No files found.
libcaf_core/caf/detail/behavior_impl.hpp
View file @
9aa81913
...
...
@@ -54,12 +54,6 @@ class message_handler;
namespace
caf
{
namespace
detail
{
template
<
class
...
Ts
>
struct
has_skip
{
static
constexpr
bool
value
=
disjunction
<
std
::
is_same
<
Ts
,
skip_t
>::
value
...
>::
value
;
};
class
behavior_impl
:
public
ref_counted
{
public:
using
pointer
=
intrusive_ptr
<
behavior_impl
>
;
...
...
@@ -95,154 +89,143 @@ protected:
match_case_info
*
end_
;
};
template
<
size_t
Pos
,
size_t
Size
>
struct
defaut_bhvr_impl_init
{
template
<
class
Array
,
class
Tuple
>
static
void
init
(
Array
&
arr
,
Tuple
&
tup
)
{
auto
&
x
=
arr
[
Pos
];
x
.
ptr
=
&
std
::
get
<
Pos
>
(
tup
);
x
.
type_token
=
x
.
ptr
->
type_token
();
defaut_bhvr_impl_init
<
Pos
+
1
,
Size
>::
init
(
arr
,
tup
);
}
};
template
<
class
Tuple
>
void
call_timeout_handler
(
Tuple
&
tup
,
std
::
true_type
)
{
auto
&
f
=
std
::
get
<
std
::
tuple_size
<
Tuple
>::
value
-
1
>
(
tup
);
f
.
handler
();
}
template
<
size_t
Size
>
struct
defaut_bhvr_impl_init
<
Size
,
Size
>
{
template
<
class
Array
,
class
Tuple
>
static
void
init
(
Array
&
,
Tuple
&
)
{
template
<
class
Tuple
>
void
call_timeout_handler
(
Tuple
&
,
std
::
false_type
)
{
// nop
}
}
template
<
class
T
,
bool
IsTimeout
=
is_timeout_definition
<
T
>
::
value
>
struct
lift_behavior
{
using
type
=
trivial_match_case
<
T
>
;
};
template
<
class
T
>
struct
lift_behavior
<
T
,
true
>
{
using
type
=
T
;
};
template
<
bool
HasTimeout
,
class
Tuple
>
struct
with_generic_timeout
;
template
<
class
...
Ts
>
struct
with_generic_timeout
<
false
,
std
::
tuple
<
Ts
...
>>
{
using
type
=
std
::
tuple
<
Ts
...,
generic_timeout_definition
>
;
};
template
<
class
...
Ts
>
struct
with_generic_timeout
<
true
,
std
::
tuple
<
Ts
...
>>
{
using
type
=
typename
tl_apply
<
typename
tl_replace_back
<
type_list
<
Ts
...
>
,
generic_timeout_definition
>::
type
,
std
::
tuple
>::
type
;
};
template
<
class
Tuple
>
class
default_behavior_impl
:
public
behavior_impl
{
class
default_behavior_impl
;
template
<
class
...
Ts
>
class
default_behavior_impl
<
std
::
tuple
<
Ts
...
>>
:
public
behavior_impl
{
public:
static
constexpr
size_t
num_cases
=
std
::
tuple_size
<
Tuple
>::
value
;
using
tuple_type
=
std
::
tuple
<
Ts
...
>
;
template
<
class
T
>
default_behavior_impl
(
const
T
&
tup
)
:
cases_
(
std
::
move
(
tup
))
{
init
();
}
using
back_type
=
typename
tl_back
<
type_list
<
Ts
...
>>::
type
;
static
constexpr
bool
has_timeout
=
is_timeout_definition
<
back_type
>::
value
;
static
constexpr
size_t
num_cases
=
sizeof
...(
Ts
)
-
(
has_timeout
?
1
:
0
);
using
cases
=
typename
std
::
conditional
<
has_timeout
,
typename
tl_pop_back
<
type_list
<
Ts
...
>>::
type
,
type_list
<
Ts
...
>
>::
type
;
template
<
class
T
,
class
F
>
default_behavior_impl
(
const
T
&
tup
,
const
timeout_definition
<
F
>&
d
)
:
behavior_impl
(
d
.
timeout
),
cases_
(
tup
),
fun_
(
d
.
handler
)
{
default_behavior_impl
(
tuple_type
&&
tup
)
:
cases_
(
std
::
move
(
tup
))
{
init
();
}
t
ypename
behavior_impl
::
pointer
copy
(
const
generic_timeout_definition
&
tdef
)
const
override
{
return
make_counted
<
default_behavior_impl
<
Tuple
>>
(
cases_
,
tdef
);
t
emplate
<
class
...
Us
>
default_behavior_impl
(
Us
&&
...
xs
)
:
cases_
(
std
::
forward
<
Us
>
(
xs
)...)
{
init
(
);
}
void
handle_timeout
()
override
{
fun_
();
std
::
integral_constant
<
bool
,
has_timeout
>
token
;
call_timeout_handler
(
cases_
,
token
);
}
typename
behavior_impl
::
pointer
copy
(
const
generic_timeout_definition
&
td
)
const
override
;
private:
void
init
()
{
defaut_bhvr_impl_init
<
0
,
num_cases
>::
init
(
arr_
,
cases_
)
;
begin_
=
arr_
.
data
()
;
end_
=
begin_
+
arr_
.
size
(
);
std
::
integral_constant
<
size_t
,
0
>
first
;
std
::
integral_constant
<
size_t
,
num_cases
>
last
;
init
(
first
,
last
);
}
Tuple
cases_
;
std
::
array
<
match_case_info
,
num_cases
>
arr_
;
std
::
function
<
void
()
>
fun_
;
};
template
<
size_t
Last
>
void
init
(
std
::
integral_constant
<
size_t
,
Last
>
,
std
::
integral_constant
<
size_t
,
Last
>
)
{
this
->
begin_
=
arr_
.
data
();
this
->
end_
=
arr_
.
data
()
+
arr_
.
size
();
std
::
integral_constant
<
bool
,
has_timeout
>
token
;
set_timeout
(
token
);
}
// eor = end of recursion
// ra = reorganize arguments
template
<
size_t
First
,
size_t
Last
>
void
init
(
std
::
integral_constant
<
size_t
,
First
>
,
std
::
integral_constant
<
size_t
,
Last
>
last
)
{
auto
&
element
=
std
::
get
<
First
>
(
cases_
);
arr_
[
First
]
=
match_case_info
{
element
.
type_token
(),
&
element
};
init
(
std
::
integral_constant
<
size_t
,
First
+
1
>
{},
last
);
}
template
<
class
R
,
class
...
Ts
>
intrusive_ptr
<
R
>
make_behavior_eor
(
const
std
::
tuple
<
Ts
...
>&
match_cases
)
{
return
make_counted
<
R
>
(
match_cases
);
}
void
set_timeout
(
std
::
true_type
)
{
this
->
timeout_
=
std
::
get
<
num_cases
>
(
cases_
).
timeout
;
}
template
<
class
R
,
class
...
Ts
,
class
F
>
intrusive_ptr
<
R
>
make_behavior_eor
(
const
std
::
tuple
<
Ts
...
>&
match_cases
,
const
timeout_definition
<
F
>&
td
)
{
return
make_counted
<
R
>
(
match_cases
,
td
);
}
void
set_timeout
(
std
::
false_type
)
{
// nop
}
template
<
class
F
,
bool
IsMC
=
std
::
is_base_of
<
match_case
,
F
>
::
value
>
struct
lift_to_mctuple
{
using
type
=
std
::
tuple
<
trivial_match_case
<
F
>>
;
tuple_type
cases_
;
std
::
array
<
match_case_info
,
num_cases
>
arr_
;
};
template
<
class
T
>
struct
lift_to_mctuple
<
T
,
true
>
{
using
type
=
std
::
tuple
<
T
>
;
template
<
class
Tuple
>
struct
behavior_factory
{
template
<
class
...
Ts
>
typename
behavior_impl
::
pointer
operator
()(
Ts
&&
...
xs
)
const
{
return
make_counted
<
default_behavior_impl
<
Tuple
>>
(
std
::
forward
<
Ts
>
(
xs
)...);
}
};
template
<
class
...
Ts
>
struct
lift_to_mctuple
<
std
::
tuple
<
Ts
...
>
,
false
>
{
using
type
=
std
::
tuple
<
Ts
...
>
;
};
template
<
class
F
>
struct
lift_to_mctuple
<
timeout_definition
<
F
>
,
false
>
{
using
type
=
std
::
tuple
<>
;
};
template
<
class
T
,
class
...
Ts
>
struct
join_std_tuples
;
template
<
class
T
>
struct
join_std_tuples
<
T
>
{
using
type
=
T
;
};
template
<
class
...
Prefix
,
class
...
Infix
,
class
...
Suffix
>
struct
join_std_tuples
<
std
::
tuple
<
Prefix
...
>
,
std
::
tuple
<
Infix
...
>
,
Suffix
...
>
:
join_std_tuples
<
std
::
tuple
<
Prefix
...,
Infix
...
>
,
Suffix
...
>
{
// nop
};
// this function reorganizes its arguments to shift the timeout definition
// to the front (receives it at the tail)
template
<
class
R
,
class
F
,
class
...
Ts
>
intrusive_ptr
<
R
>
make_behavior_ra
(
const
timeout_definition
<
F
>&
td
,
const
tail_argument_token
&
,
const
Ts
&
...
xs
)
{
return
make_behavior_eor
<
R
>
(
std
::
tuple_cat
(
to_match_case_tuple
(
xs
)...),
td
);
}
template
<
class
R
,
class
...
Ts
>
intrusive_ptr
<
R
>
make_behavior_ra
(
const
tail_argument_token
&
,
const
Ts
&
...
xs
)
{
return
make_behavior_eor
<
R
>
(
std
::
tuple_cat
(
to_match_case_tuple
(
xs
)...));
}
// for some reason, this call is ambigious on GCC without enable_if
template
<
class
R
,
class
T
,
class
...
Ts
>
typename
std
::
enable_if
<
!
std
::
is_same
<
T
,
tail_argument_token
>::
value
,
intrusive_ptr
<
R
>
>::
type
make_behavior_ra
(
const
T
&
x
,
const
Ts
&
...
xs
)
{
return
make_behavior_ra
<
R
>
(
xs
...,
x
);
typename
behavior_impl
::
pointer
default_behavior_impl
<
std
::
tuple
<
Ts
...
>>::
copy
(
const
generic_timeout_definition
&
td
)
const
{
using
tuple_type
=
typename
with_generic_timeout
<
has_timeout
,
std
::
tuple
<
Ts
...
>>::
type
;
behavior_factory
<
tuple_type
>
factory
;
// = &make_counted<default_behavior_impl<tuple_type>>;
typename
il_range
<
0
,
num_cases
>::
type
indices
;
return
apply_args_suffxied
(
factory
,
indices
,
cases_
,
td
);
}
// this function reorganizes its arguments to shift the timeout definition
// to the front (receives it at the tail)
template
<
class
...
Ts
>
intrusive_ptr
<
default_behavior_impl
<
typename
join_std_tuples
<
typename
lift_to_mctuple
<
Ts
>::
type
...
>::
type
>>
make_behavior
(
const
Ts
&
...
xs
)
{
using
result_type
=
default_behavior_impl
<
typename
join_std_tuples
<
typename
lift_to_mctuple
<
Ts
>::
type
...
>::
type
>
;
tail_argument_token
eoa
;
return
make_behavior_ra
<
result_type
>
(
xs
...,
eoa
);
intrusive_ptr
<
default_behavior_impl
<
std
::
tuple
<
typename
lift_behavior
<
Ts
>::
type
...
>>>
make_behavior
(
Ts
...
xs
)
{
using
type
=
default_behavior_impl
<
std
::
tuple
<
typename
lift_behavior
<
Ts
>::
type
...
>>
;
return
make_counted
<
type
>
(
std
::
move
(
xs
)...);
}
using
behavior_impl_ptr
=
intrusive_ptr
<
behavior_impl
>
;
...
...
libcaf_core/caf/detail/int_list.hpp
View file @
9aa81913
...
...
@@ -111,6 +111,14 @@ get_right_indices(const T&) {
return
{};
}
template
<
long
First
,
long
Last
,
long
...
Is
>
struct
il_range
:
il_range
<
First
+
1
,
Last
,
Is
...,
First
>
{};
template
<
long
Last
,
long
...
Is
>
struct
il_range
<
Last
,
Last
,
Is
...
>
{
using
type
=
int_list
<
Is
...
>
;
};
}
// namespace detail
}
// namespace caf
...
...
libcaf_core/caf/detail/type_list.hpp
View file @
9aa81913
...
...
@@ -632,6 +632,22 @@ struct tl_pop_back<empty_type_list> {
using
type
=
empty_type_list
;
};
// list replace_back()
/// Creates a new list with all but the last element of `List`
/// and append `T` to the new list.
template
<
class
List
,
class
Back
,
class
Intermediate
=
type_list
<
>
>
struct
tl_replace_back
;
template
<
class
T0
,
class
T1
,
class
...
Ts
,
class
Back
,
class
...
Us
>
struct
tl_replace_back
<
type_list
<
T0
,
T1
,
Ts
...
>
,
Back
,
type_list
<
Us
...
>>
:
tl_replace_back
<
type_list
<
T1
,
Ts
...
>
,
Back
,
type_list
<
Us
...,
T0
>>
{};
template
<
class
T
,
class
Back
,
class
...
Us
>
struct
tl_replace_back
<
type_list
<
T
>
,
Back
,
type_list
<
Us
...
>>
{
using
type
=
type_list
<
Us
...,
Back
>
;
};
// type at(size_t)
template
<
size_t
N
,
class
...
E
>
...
...
libcaf_core/caf/timeout_definition.hpp
View file @
9aa81913
...
...
@@ -21,6 +21,7 @@
#define CAF_TIMEOUT_DEFINITION_HPP
#include <functional>
#include <type_traits>
#include "caf/duration.hpp"
...
...
@@ -37,13 +38,37 @@ behavior_impl* new_default_behavior(duration d, std::function<void()> fun);
template
<
class
F
>
struct
timeout_definition
{
static
constexpr
bool
may_have_timeout
=
true
;
duration
timeout
;
F
handler
;
detail
::
behavior_impl
*
as_behavior_impl
()
const
{
return
detail
::
new_default_behavior
(
timeout
,
handler
);
}
timeout_definition
()
=
default
;
timeout_definition
(
timeout_definition
&&
)
=
default
;
timeout_definition
(
const
timeout_definition
&
)
=
default
;
timeout_definition
(
duration
d
,
F
&&
f
)
:
timeout
(
d
),
handler
(
std
::
move
(
f
))
{
// nop
}
template
<
class
U
>
timeout_definition
(
const
timeout_definition
<
U
>&
other
)
:
timeout
(
other
.
timeout
),
handler
(
other
.
handler
)
{
// nop
}
};
template
<
class
T
>
struct
is_timeout_definition
:
std
::
false_type
{};
template
<
class
T
>
struct
is_timeout_definition
<
timeout_definition
<
T
>>
:
std
::
true_type
{};
using
generic_timeout_definition
=
timeout_definition
<
std
::
function
<
void
()
>>
;
}
// namespace caf
...
...
libcaf_core/caf/typed_behavior.hpp
View file @
9aa81913
...
...
@@ -164,7 +164,7 @@ public:
template
<
class
T
,
class
...
Ts
>
typed_behavior
(
T
x
,
Ts
...
xs
)
{
set
(
detail
::
make_behavior
(
x
,
xs
...));
set
(
detail
::
make_behavior
(
std
::
move
(
x
),
std
::
move
(
xs
)
...));
}
struct
unsafe_init
{
};
...
...
@@ -209,7 +209,12 @@ private:
template
<
class
...
Ts
>
void
set
(
intrusive_ptr
<
detail
::
default_behavior_impl
<
std
::
tuple
<
Ts
...
>>>
bp
)
{
using
mpi
=
detail
::
type_list
<
typename
detail
::
deduce_mpi
<
Ts
>::
type
...
>
;
using
impl
=
detail
::
default_behavior_impl
<
std
::
tuple
<
Ts
...
>>
;
using
mpi
=
typename
detail
::
tl_map
<
typename
impl
::
cases
,
detail
::
deduce_mpi
>::
type
;
static_assert
(
detail
::
tl_is_distinct
<
mpi
>::
value
,
"multiple handler defintions found"
);
detail
::
static_asserter
<
signatures
,
mpi
,
detail
::
ctm
>::
verify_match
();
...
...
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