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
db73ab96
Commit
db73ab96
authored
Nov 19, 2019
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix build on MSVC
parent
c1c603c1
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
116 additions
and
123 deletions
+116
-123
libcaf_core/caf/read_inspector.hpp
libcaf_core/caf/read_inspector.hpp
+55
-65
libcaf_core/caf/write_inspector.hpp
libcaf_core/caf/write_inspector.hpp
+61
-58
No files found.
libcaf_core/caf/read_inspector.hpp
View file @
db73ab96
...
@@ -30,16 +30,13 @@
...
@@ -30,16 +30,13 @@
#include "caf/unifyn.hpp"
#include "caf/unifyn.hpp"
#define CAF_READ_INSPECTOR_TRY(statement) \
#define CAF_READ_INSPECTOR_TRY(statement) \
using CAF_UNIFYN(statement_result) = decltype(statement); \
if constexpr (std::is_same<decltype(statement), void>::value) { \
if constexpr (std::is_same<CAF_UNIFYN(statement_result), void>::value) { \
statement; \
statement; \
} else
if constexpr (std::is_same<CAF_UNIFYN(statement_result),
\
} else
{
\
bool>::value) {
\
if (auto err = statement) {
\
if (!statement)
\
result = err;
\
return false; \
return false; \
} else if (auto err = statement) { \
} \
result = err; \
return false; \
}
}
namespace
caf
{
namespace
caf
{
...
@@ -54,59 +51,8 @@ public:
...
@@ -54,59 +51,8 @@ public:
template
<
class
...
Ts
>
template
<
class
...
Ts
>
[[
nodiscard
]]
auto
operator
()(
Ts
&&
...
xs
)
{
[[
nodiscard
]]
auto
operator
()(
Ts
&&
...
xs
)
{
auto
&
dref
=
*
static_cast
<
Subtype
*>
(
this
);
typename
Subtype
::
result_type
result
;
typename
Subtype
::
result_type
result
;
auto
f
=
[
&
result
,
&
dref
](
auto
&&
x
)
{
static_cast
<
void
>
((
try_apply
(
result
,
xs
)
&&
...));
using
type
=
std
::
remove_const_t
<
std
::
remove_reference_t
<
decltype
(
x
)
>>
;
if
constexpr
(
std
::
is_empty
<
type
>::
value
)
{
// nop
}
else
if
constexpr
(
meta
::
is_save_callback_v
<
type
>
)
{
CAF_READ_INSPECTOR_TRY
(
x
.
fun
())
}
else
if
constexpr
(
meta
::
is_annotation_v
<
type
>
//
||
is_allowed_unsafe_message_type_v
<
type
>
)
{
// skip element
}
else
if
constexpr
(
detail
::
can_apply_v
<
Subtype
,
decltype
(
x
)
>
)
{
using
apply_type
=
decltype
(
dref
.
apply
(
x
));
if
constexpr
(
std
::
is_same
<
apply_type
,
void
>::
value
)
{
dref
.
apply
(
x
);
}
else
if
constexpr
(
std
::
is_same
<
apply_type
,
bool
>::
value
)
{
if
(
!
dref
.
apply
(
x
))
{
result
=
sec
::
end_of_stream
;
return
false
;
}
}
else
{
CAF_READ_INSPECTOR_TRY
(
dref
.
apply
(
x
))
}
}
else
if
constexpr
(
std
::
is_integral
<
type
>::
value
)
{
using
squashed_type
=
detail
::
squashed_int_t
<
type
>
;
CAF_READ_INSPECTOR_TRY
(
dref
.
apply
(
static_cast
<
squashed_type
>
(
x
)))
}
else
if
constexpr
(
std
::
is_array
<
type
>::
value
)
{
CAF_READ_INSPECTOR_TRY
(
apply_array
(
dref
,
x
))
}
else
if
constexpr
(
detail
::
is_stl_tuple_type
<
type
>::
value
)
{
std
::
make_index_sequence
<
std
::
tuple_size
<
type
>::
value
>
seq
;
CAF_READ_INSPECTOR_TRY
(
apply_tuple
(
dref
,
x
,
seq
))
}
else
if
constexpr
(
detail
::
is_map_like
<
type
>::
value
)
{
CAF_READ_INSPECTOR_TRY
(
dref
.
begin_sequence
(
x
.
size
()))
for
(
const
auto
&
kvp
:
x
)
{
CAF_READ_INSPECTOR_TRY
(
dref
(
kvp
.
first
,
kvp
.
second
))
}
CAF_READ_INSPECTOR_TRY
(
dref
.
end_sequence
())
}
else
if
constexpr
(
detail
::
is_list_like
<
type
>::
value
)
{
CAF_READ_INSPECTOR_TRY
(
dref
.
begin_sequence
(
x
.
size
()))
for
(
const
auto
&
value
:
x
)
{
CAF_READ_INSPECTOR_TRY
(
dref
(
value
))
}
CAF_READ_INSPECTOR_TRY
(
dref
.
end_sequence
())
}
else
{
static_assert
(
detail
::
is_inspectable
<
Subtype
,
type
>::
value
);
using
caf
::
detail
::
inspect
;
// We require that the implementation for `inspect` does not modify its
// arguments when passing a reading inspector.
CAF_READ_INSPECTOR_TRY
(
inspect
(
dref
,
const_cast
<
type
&>
(
x
)));
}
return
true
;
};
static_cast
<
void
>
((
f
(
std
::
forward
<
Ts
>
(
xs
))
&&
...));
return
result
;
return
result
;
}
}
...
@@ -118,14 +64,58 @@ private:
...
@@ -118,14 +64,58 @@ private:
}
}
template
<
class
T
,
size_t
...
Is
>
template
<
class
T
,
size_t
...
Is
>
static
auto
apply_array
(
Subtype
&
dref
,
T
*
xs
,
std
::
index_sequence
<
Is
...
>
)
{
static
auto
apply_array
(
Subtype
&
dref
,
const
T
*
xs
,
std
::
index_sequence
<
Is
...
>
)
{
return
dref
(
xs
[
Is
]...);
return
dref
(
xs
[
Is
]...);
}
}
template
<
class
T
,
size_t
N
>
template
<
class
R
,
class
T
>
static
auto
apply_array
(
Subtype
&
dref
,
T
(
&
xs
)[
N
])
{
std
::
enable_if_t
<
meta
::
is_annotation_v
<
T
>
,
bool
>
try_apply
(
R
&
result
,
T
&
x
)
{
std
::
make_index_sequence
<
N
>
seq
;
if
constexpr
(
meta
::
is_save_callback_v
<
T
>
)
return
apply_array
(
dref
,
xs
,
seq
);
CAF_READ_INSPECTOR_TRY
(
x
.
fun
())
return
true
;
}
template
<
class
R
,
class
T
>
std
::
enable_if_t
<!
meta
::
is_annotation_v
<
T
>
,
bool
>
try_apply
(
R
&
result
,
const
T
&
x
)
{
Subtype
&
dref
=
*
static_cast
<
Subtype
*>
(
this
);
if
constexpr
(
std
::
is_empty
<
T
>::
value
||
is_allowed_unsafe_message_type_v
<
T
>
)
{
// skip element
}
else
if
constexpr
(
detail
::
can_apply_v
<
Subtype
,
decltype
(
x
)
>
)
{
CAF_READ_INSPECTOR_TRY
(
dref
.
apply
(
x
))
}
else
if
constexpr
(
std
::
is_integral
<
T
>::
value
)
{
using
squashed_type
=
detail
::
squashed_int_t
<
T
>
;
auto
squashed_x
=
static_cast
<
squashed_type
>
(
x
);
CAF_READ_INSPECTOR_TRY
(
dref
.
apply
(
squashed_x
))
}
else
if
constexpr
(
std
::
is_array
<
T
>::
value
)
{
std
::
make_index_sequence
<
std
::
extent
<
T
>::
value
>
seq
;
CAF_READ_INSPECTOR_TRY
(
apply_array
(
dref
,
x
,
seq
))
}
else
if
constexpr
(
detail
::
is_stl_tuple_type
<
T
>::
value
)
{
std
::
make_index_sequence
<
std
::
tuple_size
<
T
>::
value
>
seq
;
CAF_READ_INSPECTOR_TRY
(
apply_tuple
(
dref
,
x
,
seq
))
}
else
if
constexpr
(
detail
::
is_map_like
<
T
>::
value
)
{
CAF_READ_INSPECTOR_TRY
(
dref
.
begin_sequence
(
x
.
size
()))
for
(
const
auto
&
kvp
:
x
)
{
CAF_READ_INSPECTOR_TRY
(
dref
(
kvp
.
first
,
kvp
.
second
))
}
CAF_READ_INSPECTOR_TRY
(
dref
.
end_sequence
())
}
else
if
constexpr
(
detail
::
is_list_like
<
T
>::
value
)
{
CAF_READ_INSPECTOR_TRY
(
dref
.
begin_sequence
(
x
.
size
()))
for
(
const
auto
&
value
:
x
)
{
CAF_READ_INSPECTOR_TRY
(
dref
(
value
))
}
CAF_READ_INSPECTOR_TRY
(
dref
.
end_sequence
())
}
else
{
static_assert
(
detail
::
is_inspectable
<
Subtype
,
T
>::
value
);
using
caf
::
detail
::
inspect
;
// We require that the implementation for `inspect` does not modify its
// arguments when passing a reading inspector.
auto
&
mutable_x
=
const_cast
<
T
&>
(
x
);
CAF_READ_INSPECTOR_TRY
(
inspect
(
dref
,
mutable_x
));
}
return
true
;
}
}
};
};
...
...
libcaf_core/caf/write_inspector.hpp
View file @
db73ab96
...
@@ -34,9 +34,11 @@
...
@@ -34,9 +34,11 @@
#define CAF_WRITE_INSPECTOR_TRY(statement) \
#define CAF_WRITE_INSPECTOR_TRY(statement) \
if constexpr (std::is_same<decltype(statement), void>::value) { \
if constexpr (std::is_same<decltype(statement), void>::value) { \
statement; \
statement; \
} else if (auto err = statement) { \
} else { \
result = err; \
if (auto err = statement) { \
return false; \
result = err; \
return false; \
} \
}
}
namespace
caf
{
namespace
caf
{
...
@@ -56,58 +58,11 @@ public:
...
@@ -56,58 +58,11 @@ public:
template
<
class
...
Ts
>
template
<
class
...
Ts
>
[[
nodiscard
]]
auto
operator
()(
Ts
&&
...
xs
)
{
[[
nodiscard
]]
auto
operator
()(
Ts
&&
...
xs
)
{
auto
&
dref
=
*
static_cast
<
Subtype
*>
(
this
);
static_assert
(
((
std
::
is_lvalue_reference
<
Ts
>::
value
||
meta
::
is_annotation_v
<
Ts
>
)
//
&&
...));
typename
Subtype
::
result_type
result
;
typename
Subtype
::
result_type
result
;
auto
f
=
[
&
result
,
&
dref
](
auto
&&
x
)
{
static_cast
<
void
>
((
try_apply
(
result
,
xs
)
&&
...));
using
type
=
std
::
remove_reference_t
<
decltype
(
x
)
>
;
if
constexpr
(
std
::
is_empty
<
type
>::
value
)
{
// nop
}
else
if
constexpr
(
meta
::
is_load_callback_v
<
type
>
)
{
CAF_WRITE_INSPECTOR_TRY
(
x
.
fun
())
}
else
if
constexpr
(
meta
::
is_annotation_v
<
type
>
//
||
is_allowed_unsafe_message_type_v
<
type
>
)
{
// skip element
}
else
if
constexpr
(
detail
::
can_apply_v
<
Subtype
,
decltype
(
x
)
>
)
{
CAF_WRITE_INSPECTOR_TRY
(
dref
.
apply
(
x
))
}
else
if
constexpr
(
std
::
is_integral
<
type
>::
value
)
{
using
squashed_type
=
detail
::
squashed_int_t
<
type
>
;
CAF_WRITE_INSPECTOR_TRY
(
dref
.
apply
(
reinterpret_cast
<
squashed_type
&>
(
x
)))
}
else
if
constexpr
(
std
::
is_array
<
type
>::
value
)
{
CAF_WRITE_INSPECTOR_TRY
(
apply_array
(
dref
,
x
))
}
else
if
constexpr
(
detail
::
is_stl_tuple_type_v
<
type
>
)
{
std
::
make_index_sequence
<
std
::
tuple_size
<
type
>::
value
>
seq
;
CAF_WRITE_INSPECTOR_TRY
(
apply_tuple
(
dref
,
x
,
seq
))
}
else
if
constexpr
(
detail
::
is_map_like_v
<
type
>
)
{
x
.
clear
();
size_t
size
=
0
;
CAF_WRITE_INSPECTOR_TRY
(
dref
.
begin_sequence
(
size
))
for
(
size_t
i
=
0
;
i
<
size
;
++
i
)
{
auto
key
=
typename
type
::
key_type
{};
auto
val
=
typename
type
::
mapped_type
{};
CAF_WRITE_INSPECTOR_TRY
(
dref
(
key
,
val
))
x
.
emplace
(
std
::
move
(
key
),
std
::
move
(
val
));
}
CAF_WRITE_INSPECTOR_TRY
(
dref
.
end_sequence
())
}
else
if
constexpr
(
detail
::
is_list_like_v
<
type
>
)
{
x
.
clear
();
size_t
size
=
0
;
CAF_WRITE_INSPECTOR_TRY
(
dref
.
begin_sequence
(
size
))
for
(
size_t
i
=
0
;
i
<
size
;
++
i
)
{
auto
tmp
=
typename
type
::
value_type
{};
CAF_WRITE_INSPECTOR_TRY
(
dref
(
tmp
))
x
.
insert
(
x
.
end
(),
std
::
move
(
tmp
));
}
CAF_WRITE_INSPECTOR_TRY
(
dref
.
end_sequence
())
}
else
{
static_assert
(
std
::
is_lvalue_reference
<
decltype
(
x
)
>::
value
//
&&
!
std
::
is_const
<
decltype
(
x
)
>::
value
);
static_assert
(
detail
::
is_inspectable
<
Subtype
,
type
>::
value
);
using
caf
::
detail
::
inspect
;
CAF_WRITE_INSPECTOR_TRY
(
inspect
(
dref
,
x
));
}
return
true
;
};
static_cast
<
void
>
((
f
(
std
::
forward
<
Ts
>
(
xs
))
&&
...));
return
result
;
return
result
;
}
}
...
@@ -123,10 +78,58 @@ private:
...
@@ -123,10 +78,58 @@ private:
return
dref
(
xs
[
Is
]...);
return
dref
(
xs
[
Is
]...);
}
}
template
<
class
T
,
size_t
N
>
template
<
class
R
,
class
T
>
static
auto
apply_array
(
Subtype
&
dref
,
T
(
&
xs
)[
N
])
{
std
::
enable_if_t
<
meta
::
is_annotation_v
<
T
>
,
bool
>
try_apply
(
R
&
result
,
T
&
x
)
{
std
::
make_index_sequence
<
N
>
seq
;
if
constexpr
(
meta
::
is_load_callback_v
<
T
>
)
return
apply_array
(
dref
,
xs
,
seq
);
CAF_WRITE_INSPECTOR_TRY
(
x
.
fun
())
return
true
;
}
template
<
class
R
,
class
T
>
std
::
enable_if_t
<!
meta
::
is_annotation_v
<
T
>
,
bool
>
try_apply
(
R
&
result
,
T
&
x
)
{
Subtype
&
dref
=
*
static_cast
<
Subtype
*>
(
this
);
if
constexpr
(
std
::
is_empty
<
T
>::
value
||
is_allowed_unsafe_message_type_v
<
T
>
)
{
// skip element
}
else
if
constexpr
(
detail
::
can_apply_v
<
Subtype
,
decltype
(
x
)
>
)
{
CAF_WRITE_INSPECTOR_TRY
(
dref
.
apply
(
x
))
}
else
if
constexpr
(
std
::
is_integral
<
T
>::
value
)
{
using
squashed_type
=
detail
::
squashed_int_t
<
T
>
;
auto
&
squashed_x
=
reinterpret_cast
<
squashed_type
&>
(
x
);
CAF_WRITE_INSPECTOR_TRY
(
dref
.
apply
(
squashed_x
))
}
else
if
constexpr
(
std
::
is_array
<
T
>::
value
)
{
std
::
make_index_sequence
<
std
::
extent
<
T
>::
value
>
seq
;
CAF_WRITE_INSPECTOR_TRY
(
apply_array
(
dref
,
x
,
seq
))
}
else
if
constexpr
(
detail
::
is_stl_tuple_type_v
<
T
>
)
{
std
::
make_index_sequence
<
std
::
tuple_size
<
T
>::
value
>
seq
;
CAF_WRITE_INSPECTOR_TRY
(
apply_tuple
(
dref
,
x
,
seq
))
}
else
if
constexpr
(
detail
::
is_map_like_v
<
T
>
)
{
x
.
clear
();
size_t
size
=
0
;
CAF_WRITE_INSPECTOR_TRY
(
dref
.
begin_sequence
(
size
))
for
(
size_t
i
=
0
;
i
<
size
;
++
i
)
{
auto
key
=
typename
T
::
key_type
{};
auto
val
=
typename
T
::
mapped_type
{};
CAF_WRITE_INSPECTOR_TRY
(
dref
(
key
,
val
))
x
.
emplace
(
std
::
move
(
key
),
std
::
move
(
val
));
}
CAF_WRITE_INSPECTOR_TRY
(
dref
.
end_sequence
())
}
else
if
constexpr
(
detail
::
is_list_like_v
<
T
>
)
{
x
.
clear
();
size_t
size
=
0
;
CAF_WRITE_INSPECTOR_TRY
(
dref
.
begin_sequence
(
size
))
for
(
size_t
i
=
0
;
i
<
size
;
++
i
)
{
auto
tmp
=
typename
T
::
value_type
{};
CAF_WRITE_INSPECTOR_TRY
(
dref
(
tmp
))
x
.
insert
(
x
.
end
(),
std
::
move
(
tmp
));
}
CAF_WRITE_INSPECTOR_TRY
(
dref
.
end_sequence
())
}
else
{
static_assert
(
detail
::
is_inspectable
<
Subtype
,
T
>::
value
);
using
caf
::
detail
::
inspect
;
CAF_WRITE_INSPECTOR_TRY
(
inspect
(
dref
,
x
));
}
return
true
;
}
}
};
};
...
...
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