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
7bc60af3
Commit
7bc60af3
authored
Nov 23, 2019
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix undefined behavior in init_fun_factory
parent
3e3c9479
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
51 additions
and
38 deletions
+51
-38
libcaf_core/caf/detail/init_fun_factory.hpp
libcaf_core/caf/detail/init_fun_factory.hpp
+51
-38
No files found.
libcaf_core/caf/detail/init_fun_factory.hpp
View file @
7bc60af3
...
@@ -55,13 +55,16 @@ protected:
...
@@ -55,13 +55,16 @@ protected:
};
};
/// Wraps a user-defined function and gives it a uniform signature.
/// Wraps a user-defined function and gives it a uniform signature.
template
<
class
Base
,
class
F
,
class
ArgsPtr
,
bool
ReturnsBehavior
,
template
<
class
Base
,
class
F
,
class
Tuple
,
bool
ReturnsBehavior
,
bool
HasSelfPtr
>
bool
HasSelfPtr
>
class
init_fun_factory_helper
final
:
public
init_fun_factory_helper_base
{
class
init_fun_factory_helper
final
:
public
init_fun_factory_helper_base
{
public:
public:
init_fun_factory_helper
(
F
fun
,
ArgsPtr
args
)
using
args_pointer
=
std
::
shared_ptr
<
Tuple
>
;
:
fun_
(
std
::
move
(
fun
)),
args_
(
std
::
move
(
args
))
{
static
constexpr
bool
args_empty
=
std
::
tuple_size
<
Tuple
>::
value
==
0
;
init_fun_factory_helper
(
F
fun
,
args_pointer
args
)
:
fun_
(
std
::
move
(
fun
)),
args_
(
std
::
move
(
args
))
{
// nop
// nop
}
}
...
@@ -72,41 +75,52 @@ public:
...
@@ -72,41 +75,52 @@ public:
behavior
operator
()(
local_actor
*
self
)
final
{
behavior
operator
()(
local_actor
*
self
)
final
{
if
(
hook_
!=
nullptr
)
if
(
hook_
!=
nullptr
)
hook_
(
self
);
hook_
(
self
);
bool_token
<
ReturnsBehavior
>
returns_behavior_token
;
auto
dptr
=
static_cast
<
Base
*>
(
self
);
bool_token
<
HasSelfPtr
>
captures_self_token
;
if
constexpr
(
ReturnsBehavior
)
{
return
apply
(
returns_behavior_token
,
captures_self_token
,
self
);
auto
unbox
=
[](
auto
x
)
->
behavior
{
return
std
::
move
(
x
.
unbox
());
};
}
if
constexpr
(
args_empty
)
{
if
constexpr
(
HasSelfPtr
)
{
// behavior (pointer)
private:
return
unbox
(
fun_
(
dptr
));
// behavior (pointer)
}
else
{
behavior
apply
(
std
::
true_type
,
std
::
true_type
,
local_actor
*
ptr
)
{
// behavior ()
auto
res
=
apply_moved_args_prefixed
(
fun_
,
get_indices
(
*
args_
),
*
args_
,
return
unbox
(
fun_
());
static_cast
<
Base
*>
(
ptr
));
}
return
std
::
move
(
res
.
unbox
());
}
else
{
}
if
constexpr
(
HasSelfPtr
)
{
// behavior (pointer, args...)
// void (pointer)
auto
res
=
apply_moved_args_prefixed
(
fun_
,
get_indices
(
*
args_
),
behavior
apply
(
std
::
false_type
,
std
::
true_type
,
local_actor
*
ptr
)
{
*
args_
,
dptr
);
apply_moved_args_prefixed
(
fun_
,
get_indices
(
*
args_
),
return
unbox
(
std
::
move
(
res
));
*
args_
,
static_cast
<
Base
*>
(
ptr
));
}
else
{
return
behavior
{};
// behavior (args...)
}
return
unbox
(
apply_args
(
fun_
,
get_indices
(
*
args_
),
*
args_
));
}
// behavior ()
}
behavior
apply
(
std
::
true_type
,
std
::
false_type
,
local_actor
*
)
{
}
else
{
auto
res
=
apply_args
(
fun_
,
get_indices
(
*
args_
),
*
args_
);
if
constexpr
(
args_empty
)
{
return
std
::
move
(
res
.
unbox
());
if
constexpr
(
HasSelfPtr
)
{
}
// void (pointer)
fun_
(
dptr
);
// void ()
}
else
{
behavior
apply
(
std
::
false_type
,
std
::
false_type
,
local_actor
*
)
{
// void ()
apply_args
(
fun_
,
get_indices
(
*
args_
),
*
args_
);
fun_
();
return
behavior
{};
}
}
else
{
if
constexpr
(
HasSelfPtr
)
{
// void (pointer, args...)
apply_moved_args_prefixed
(
fun_
,
get_indices
(
*
args_
),
*
args_
,
dptr
);
}
else
{
// void (args...)
apply_args
(
fun_
,
get_indices
(
*
args_
),
*
args_
);
}
}
return
{};
}
}
}
F
fun_
;
F
fun_
;
ArgsPt
r
args_
;
args_pointe
r
args_
;
};
};
template
<
class
Base
,
class
F
>
template
<
class
Base
,
class
F
>
...
@@ -127,8 +141,7 @@ public:
...
@@ -127,8 +141,7 @@ public:
constexpr
bool
selfptr
=
std
::
is_pointer
<
first_arg
>::
value
;
constexpr
bool
selfptr
=
std
::
is_pointer
<
first_arg
>::
value
;
constexpr
bool
rets
=
std
::
is_convertible
<
res_type
,
behavior
>::
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_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_type
,
rets
,
selfptr
>
;
using
helper
=
init_fun_factory_helper
<
Base
,
F
,
tuple_ptr
,
rets
,
selfptr
>
;
return
ptr_type
{
new
helper
{
std
::
move
(
f
),
sizeof
...(
Ts
)
>
0
return
ptr_type
{
new
helper
{
std
::
move
(
f
),
sizeof
...(
Ts
)
>
0
?
std
::
make_shared
<
tuple_type
>
(
?
std
::
make_shared
<
tuple_type
>
(
detail
::
spawn_fwd
<
Ts
>
(
xs
)...)
detail
::
spawn_fwd
<
Ts
>
(
xs
)...)
...
...
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