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
5c0525b7
Commit
5c0525b7
authored
Aug 06, 2014
by
Joseph Noir
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'topic/announce_optionals' into develop
parents
0a86b71c
2b4734b9
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
98 additions
and
87 deletions
+98
-87
libcaf_core/caf/detail/default_uniform_type_info.hpp
libcaf_core/caf/detail/default_uniform_type_info.hpp
+82
-76
libcaf_core/caf/detail/type_traits.hpp
libcaf_core/caf/detail/type_traits.hpp
+10
-0
libcaf_core/caf/on.hpp
libcaf_core/caf/on.hpp
+6
-11
No files found.
libcaf_core/caf/detail/default_uniform_type_info.hpp
View file @
5c0525b7
...
...
@@ -30,9 +30,9 @@
#include "caf/deserializer.hpp"
#include "caf/detail/type_traits.hpp"
#include "caf/detail/types_array.hpp"
#include "caf/detail/abstract_uniform_type_info.hpp"
#include "caf/detail/types_array.hpp"
namespace
caf
{
namespace
detail
{
...
...
@@ -42,62 +42,66 @@ using uniform_type_info_ptr = uniform_type_info_ptr;
// check if there's a 'push_back' that takes a C::value_type
template
<
class
T
>
char
sfinae_has_push_back
(
T
*
ptr
,
typename
T
::
value_type
*
val
=
nullptr
,
decltype
(
ptr
->
push_back
(
*
val
))
*
=
nullptr
);
decltype
(
ptr
->
push_back
(
*
val
))
*
=
nullptr
);
long
sfinae_has_push_back
(
void
*
);
// SFNINAE default
template
<
class
T
>
struct
is_stl_compliant_list
{
static
constexpr
bool
value
=
detail
::
is_iterable
<
T
>::
value
&&
sizeof
(
sfinae_has_push_back
(
static_cast
<
T
*>
(
nullptr
)))
==
sizeof
(
char
);
detail
::
is_iterable
<
T
>::
value
&&
sizeof
(
sfinae_has_push_back
(
static_cast
<
T
*>
(
nullptr
)))
==
sizeof
(
char
);
};
// check if there's an 'insert' that takes a C::value_type
template
<
class
T
>
char
sfinae_has_insert
(
T
*
ptr
,
typename
T
::
value_type
*
val
=
nullptr
,
decltype
(
ptr
->
insert
(
*
val
))
*
=
nullptr
);
decltype
(
ptr
->
insert
(
*
val
))
*
=
nullptr
);
long
sfinae_has_insert
(
void
*
);
// SFNINAE default
template
<
class
T
>
struct
is_stl_compliant_map
{
static
constexpr
bool
value
=
detail
::
is_iterable
<
T
>::
value
&&
sizeof
(
sfinae_has_insert
(
static_cast
<
T
*>
(
nullptr
)))
==
sizeof
(
char
);
detail
::
is_iterable
<
T
>::
value
&&
sizeof
(
sfinae_has_insert
(
static_cast
<
T
*>
(
nullptr
)))
==
sizeof
(
char
);
};
template
<
class
T
>
struct
is_stl_pair
:
std
::
false_type
{};
struct
is_stl_pair
:
std
::
false_type
{
// no members
};
template
<
class
F
,
typename
S
>
struct
is_stl_pair
<
std
::
pair
<
F
,
S
>>
:
std
::
true_type
{};
struct
is_stl_pair
<
std
::
pair
<
F
,
S
>>
:
std
::
true_type
{
// no members
};
using
primitive_impl
=
std
::
integral_constant
<
int
,
0
>
;
using
list_impl
=
std
::
integral_constant
<
int
,
1
>
;
using
map_impl
=
std
::
integral_constant
<
int
,
2
>
;
using
pair_impl
=
std
::
integral_constant
<
int
,
3
>
;
using
opt_impl
=
std
::
integral_constant
<
int
,
4
>
;
using
recursive_impl
=
std
::
integral_constant
<
int
,
9
>
;
template
<
class
T
>
constexpr
int
impl_id
()
{
return
detail
::
is_primitive
<
T
>::
value
?
0
:
(
is_stl_compliant_list
<
T
>::
value
?
1
:
(
is_stl_compliant_map
<
T
>::
value
?
2
:
(
is_stl_pair
<
T
>::
value
?
3
:
9
)));
return
detail
::
is_primitive
<
T
>::
value
?
0
:
(
is_stl_compliant_list
<
T
>::
value
?
1
:
(
is_stl_compliant_map
<
T
>::
value
?
2
:
(
is_stl_pair
<
T
>::
value
?
3
:
(
detail
::
is_optional
<
T
>::
value
?
4
:
9
))));
}
template
<
class
T
>
struct
deconst_pair
{
using
type
=
T
;
};
template
<
class
K
,
typename
V
>
...
...
@@ -105,13 +109,10 @@ struct deconst_pair<std::pair<K, V>> {
using
first_type
=
typename
std
::
remove_const
<
K
>::
type
;
using
second_type
=
typename
std
::
remove_const
<
V
>::
type
;
using
type
=
std
::
pair
<
first_type
,
second_type
>
;
};
class
default_serialize_policy
{
public:
template
<
class
T
>
void
operator
()(
const
T
&
val
,
serializer
*
s
)
const
{
std
::
integral_constant
<
int
,
impl_id
<
T
>
()
>
token
;
...
...
@@ -122,11 +123,9 @@ class default_serialize_policy {
void
operator
()(
T
&
val
,
deserializer
*
d
)
const
{
std
::
integral_constant
<
int
,
impl_id
<
T
>
()
>
token
;
dimpl
(
val
,
d
,
token
);
// static_types_array<T>::arr[0]->deserialize(&val, d);
}
private:
template
<
class
T
>
void
simpl
(
const
T
&
val
,
serializer
*
s
,
primitive_impl
)
const
{
s
->
write_value
(
val
);
...
...
@@ -154,6 +153,15 @@ class default_serialize_policy {
(
*
this
)(
val
.
second
,
s
);
}
template
<
class
T
>
void
simpl
(
const
optional
<
T
>&
val
,
serializer
*
s
,
opt_impl
)
const
{
uint8_t
flag
=
val
?
1
:
0
;
s
->
write_value
(
flag
);
if
(
val
)
{
(
*
this
)(
*
val
,
s
);
}
}
template
<
class
T
>
void
simpl
(
const
T
&
val
,
serializer
*
s
,
recursive_impl
)
const
{
static_types_array
<
T
>::
arr
[
0
]
->
serialize
(
&
val
,
s
);
...
...
@@ -195,19 +203,30 @@ class default_serialize_policy {
(
*
this
)(
storage
.
second
,
d
);
}
template
<
class
T
>
void
dimpl
(
optional
<
T
>&
val
,
deserializer
*
d
,
opt_impl
)
const
{
auto
flag
=
d
->
read
<
uint8_t
>
();
if
(
flag
!=
0
)
{
T
tmp
;
(
*
this
)(
tmp
,
d
);
val
=
std
::
move
(
tmp
);
}
else
{
val
=
none
;
}
}
template
<
class
T
>
void
dimpl
(
T
&
storage
,
deserializer
*
d
,
recursive_impl
)
const
{
static_types_array
<
T
>::
arr
[
0
]
->
deserialize
(
&
storage
,
d
);
}
};
class
forwarding_serialize_policy
{
public:
inline
forwarding_serialize_policy
(
uniform_type_info_ptr
uti
)
:
m_uti
(
std
::
move
(
uti
))
{}
:
m_uti
(
std
::
move
(
uti
))
{
// nop
}
template
<
class
T
>
void
operator
()(
const
T
&
val
,
serializer
*
s
)
const
{
...
...
@@ -220,25 +239,25 @@ class forwarding_serialize_policy {
}
private:
uniform_type_info_ptr
m_uti
;
};
template
<
class
T
,
class
AccessPolicy
,
class
SerializePolicy
=
default_serialize_policy
,
bool
IsEnum
=
std
::
is_enum
<
T
>
::
value
,
bool
IsEmptyType
=
std
::
is_class
<
T
>::
value
&&
std
::
is_empty
<
T
>::
value
>
class
SerializePolicy
=
default_serialize_policy
,
bool
IsEnum
=
std
::
is_enum
<
T
>
::
value
,
bool
IsEmptyType
=
std
::
is_class
<
T
>::
value
&&
std
::
is_empty
<
T
>::
value
>
class
member_tinfo
:
public
detail
::
abstract_uniform_type_info
<
T
>
{
public:
member_tinfo
(
AccessPolicy
apol
,
SerializePolicy
spol
)
:
m_apol
(
std
::
move
(
apol
)),
m_spol
(
std
::
move
(
spol
))
{}
:
m_apol
(
std
::
move
(
apol
)),
m_spol
(
std
::
move
(
spol
))
{
// nop
}
member_tinfo
(
AccessPolicy
apol
)
:
m_apol
(
std
::
move
(
apol
))
{}
member_tinfo
(
AccessPolicy
apol
)
:
m_apol
(
std
::
move
(
apol
))
{
// nop
}
member_tinfo
()
{}
member_tinfo
()
=
default
;
void
serialize
(
const
void
*
vptr
,
serializer
*
s
)
const
override
{
m_spol
(
m_apol
(
vptr
),
s
);
...
...
@@ -278,9 +297,7 @@ class member_tinfo<T, A, S, false, true>
// nop
}
member_tinfo
()
{
// nop
}
member_tinfo
()
=
default
;
void
serialize
(
const
void
*
,
serializer
*
)
const
override
{
// nop
...
...
@@ -294,16 +311,15 @@ class member_tinfo<T, A, S, false, true>
template
<
class
T
,
class
AccessPolicy
,
class
SerializePolicy
>
class
member_tinfo
<
T
,
AccessPolicy
,
SerializePolicy
,
true
,
false
>
:
public
detail
::
abstract_uniform_type_info
<
T
>
{
public:
using
value_type
=
typename
std
::
underlying_type
<
T
>::
type
;
public:
member_tinfo
(
AccessPolicy
apol
,
SerializePolicy
spol
)
:
m_apol
(
std
::
move
(
apol
)),
m_spol
(
std
::
move
(
spol
))
{}
member_tinfo
(
AccessPolicy
apol
)
:
m_apol
(
std
::
move
(
apol
))
{}
member_tinfo
()
{}
member_tinfo
()
=
default
;
void
serialize
(
const
void
*
p
,
serializer
*
s
)
const
override
{
auto
val
=
m_apol
(
p
);
...
...
@@ -319,18 +335,17 @@ class member_tinfo<T, AccessPolicy, SerializePolicy, true, false>
private:
AccessPolicy
m_apol
;
SerializePolicy
m_spol
;
};
template
<
class
T
,
class
C
>
class
memptr_access_policy
{
public:
inline
memptr_access_policy
(
T
C
::*
memptr
)
:
m_memptr
(
memptr
)
{
// nop
}
memptr_access_policy
(
const
memptr_access_policy
&
)
=
default
;
memptr_access_policy
&
operator
=
(
const
memptr_access_policy
&
)
=
default
;
inline
memptr_access_policy
(
T
C
::*
memptr
)
:
m_memptr
(
memptr
)
{}
inline
T
&
operator
()(
void
*
vptr
)
const
{
auto
ptr
=
reinterpret_cast
<
C
*>
(
vptr
);
return
*
ptr
.
*
m_memptr
;
...
...
@@ -355,7 +370,6 @@ class memptr_access_policy {
template
<
class
C
,
typename
GRes
,
typename
SRes
,
typename
SArg
>
class
getter_setter_access_policy
{
public:
using
getter
=
GRes
(
C
::*
)()
const
;
...
...
@@ -377,15 +391,12 @@ class getter_setter_access_policy {
static
constexpr
bool
grants_mutable_access
=
false
;
private:
getter
m_get
;
setter
m_set
;
};
template
<
class
T
>
struct
fake_access_policy
{
inline
T
&
operator
()(
void
*
vptr
)
const
{
return
*
reinterpret_cast
<
T
*>
(
vptr
);
}
...
...
@@ -400,7 +411,6 @@ struct fake_access_policy {
}
static
constexpr
bool
grants_mutable_access
=
true
;
};
template
<
class
T
,
class
C
>
...
...
@@ -436,15 +446,13 @@ uniform_type_info_ptr new_member_tinfo(GRes (C::*getter)() const,
using
value_type
=
typename
detail
::
rm_const_and_ref
<
GRes
>::
type
;
using
tinfo
=
member_tinfo
<
value_type
,
access_policy
,
forwarding_serialize_policy
>
;
return
uniform_type_info_ptr
(
new
tinfo
(
access_policy
(
getter
,
setter
),
std
::
move
(
meminf
)));
return
uniform_type_info_ptr
(
new
tinfo
(
access_policy
(
getter
,
setter
),
std
::
move
(
meminf
)));
}
template
<
class
T
>
class
default_uniform_type_info
:
public
detail
::
abstract_uniform_type_info
<
T
>
{
public:
template
<
class
...
Ts
>
default_uniform_type_info
(
Ts
&&
...
args
)
{
push_back
(
std
::
forward
<
Ts
>
(
args
)...);
...
...
@@ -457,22 +465,24 @@ class default_uniform_type_info : public detail::abstract_uniform_type_info<T> {
void
serialize
(
const
void
*
obj
,
serializer
*
s
)
const
override
{
// serialize each member
for
(
auto
&
m
:
m_members
)
m
->
serialize
(
obj
,
s
);
for
(
auto
&
m
:
m_members
)
{
m
->
serialize
(
obj
,
s
);
}
}
void
deserialize
(
void
*
obj
,
deserializer
*
d
)
const
override
{
// deserialize each member
for
(
auto
&
m
:
m_members
)
m
->
deserialize
(
obj
,
d
);
for
(
auto
&
m
:
m_members
)
{
m
->
deserialize
(
obj
,
d
);
}
}
protected:
bool
pod_mems_equals
(
const
T
&
lhs
,
const
T
&
rhs
)
const
override
{
return
pod_eq
(
lhs
,
rhs
);
}
private:
template
<
class
C
>
typename
std
::
enable_if
<
std
::
is_pod
<
C
>::
value
,
bool
>::
type
pod_eq
(
const
C
&
lhs
,
const
C
&
rhs
)
const
{
...
...
@@ -488,8 +498,9 @@ class default_uniform_type_info : public detail::abstract_uniform_type_info<T> {
return
false
;
}
// terminates recursion
inline
void
push_back
()
{}
inline
void
push_back
()
{
// terminate recursion
}
template
<
class
R
,
class
C
,
class
...
Ts
>
void
push_back
(
R
C
::*
memptr
,
Ts
&&
...
args
)
{
...
...
@@ -535,18 +546,17 @@ class default_uniform_type_info : public detail::abstract_uniform_type_info<T> {
}
std
::
vector
<
uniform_type_info_ptr
>
m_members
;
};
template
<
class
...
Rs
>
class
default_uniform_type_info
<
typed_actor
<
Rs
...
>>
:
public
detail
::
abstract_uniform_type_info
<
typed_actor
<
Rs
...
>>
{
class
default_uniform_type_info
<
typed_actor
<
Rs
...
>>
:
public
detail
::
abstract_uniform_type_info
<
typed_actor
<
Rs
...
>>
{
public:
using
handle_type
=
typed_actor
<
Rs
...
>
;
default_uniform_type_info
()
{
sub_uti
=
uniform_typeid
<
actor
>
();
}
default_uniform_type_info
()
{
sub_uti
=
uniform_typeid
<
actor
>
();
}
void
serialize
(
const
void
*
obj
,
serializer
*
s
)
const
override
{
auto
tmp
=
actor_cast
<
actor
>
(
deref
(
obj
).
address
());
...
...
@@ -560,17 +570,13 @@ class default_uniform_type_info<typed_actor<
}
private:
const
uniform_type_info
*
sub_uti
;
static
handle_type
&
deref
(
void
*
ptr
)
{
return
*
reinterpret_cast
<
handle_type
*>
(
ptr
);
}
static
const
handle_type
&
deref
(
const
void
*
ptr
)
{
return
*
reinterpret_cast
<
const
handle_type
*>
(
ptr
);
}
const
uniform_type_info
*
sub_uti
;
};
}
// namespace detail
...
...
libcaf_core/caf/detail/type_traits.hpp
View file @
5c0525b7
...
...
@@ -479,6 +479,16 @@ struct type_at<0, T0, Ts...> {
using
type
=
T0
;
};
template
<
class
T
>
struct
is_optional
:
std
::
false_type
{
// no members
};
template
<
class
T
>
struct
is_optional
<
optional
<
T
>>
:
std
::
true_type
{
// no members
};
}
// namespace detail
}
// namespace caf
...
...
libcaf_core/caf/on.hpp
View file @
5c0525b7
...
...
@@ -335,28 +335,23 @@ struct to_guard<anything, false> {
template
<
class
T
>
struct
to_guard
<
detail
::
wrapped
<
T
>
,
false
>
:
to_guard
<
anything
>
{};
template
<
class
T
>
struct
is_optional
:
std
::
false_type
{};
template
<
class
T
>
struct
is_optional
<
optional
<
T
>>
:
std
::
true_type
{};
template
<
class
T
>
struct
to_guard
<
T
,
true
>
{
using
ct
=
typename
detail
::
get_callable_trait
<
T
>::
type
;
using
arg_types
=
typename
ct
::
arg_types
;
static_assert
(
detail
::
tl_size
<
arg_types
>::
value
==
1
,
"projection/guard must take exactly one argument"
);
static_assert
(
is_optional
<
typename
ct
::
result_type
>::
value
,
"projection/guard must return an optional value"
);
"projection/guard must take exactly one argument"
);
static_assert
(
detail
::
is_optional
<
typename
ct
::
result_type
>::
value
,
"projection/guard must return an optional value"
);
using
value_type
=
typename
std
::
conditional
<
std
::
is_function
<
T
>::
value
,
T
*
,
T
>::
type
;
static
value_type
_
(
value_type
val
)
{
return
val
;
}
static
value_type
_
(
value_type
val
)
{
return
val
;
}
};
template
<
class
T
>
...
...
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