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
8c8fb8be
Commit
8c8fb8be
authored
Dec 03, 2020
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Simplify and streamline the type inspection API
parent
b57ead03
Changes
79
Show whitespace changes
Inline
Side-by-side
Showing
79 changed files
with
1782 additions
and
921 deletions
+1782
-921
cmake/caf-generate-enum-strings.cpp
cmake/caf-generate-enum-strings.cpp
+55
-24
examples/custom_type/custom_types_1.cpp
examples/custom_type/custom_types_1.cpp
+2
-2
libcaf_core/caf/binary_deserializer.hpp
libcaf_core/caf/binary_deserializer.hpp
+25
-8
libcaf_core/caf/binary_serializer.hpp
libcaf_core/caf/binary_serializer.hpp
+18
-9
libcaf_core/caf/config_value.hpp
libcaf_core/caf/config_value.hpp
+2
-2
libcaf_core/caf/config_value_reader.hpp
libcaf_core/caf/config_value_reader.hpp
+2
-0
libcaf_core/caf/config_value_writer.hpp
libcaf_core/caf/config_value_writer.hpp
+2
-0
libcaf_core/caf/cow_tuple.hpp
libcaf_core/caf/cow_tuple.hpp
+3
-11
libcaf_core/caf/deep_to_string.hpp
libcaf_core/caf/deep_to_string.hpp
+1
-1
libcaf_core/caf/default_enum_inspect.hpp
libcaf_core/caf/default_enum_inspect.hpp
+54
-0
libcaf_core/caf/deserializer.hpp
libcaf_core/caf/deserializer.hpp
+25
-4
libcaf_core/caf/detail/make_meta_object.hpp
libcaf_core/caf/detail/make_meta_object.hpp
+5
-5
libcaf_core/caf/detail/serialized_size.hpp
libcaf_core/caf/detail/serialized_size.hpp
+7
-3
libcaf_core/caf/detail/size_based_credit_controller.hpp
libcaf_core/caf/detail/size_based_credit_controller.hpp
+1
-1
libcaf_core/caf/detail/stringification_inspector.hpp
libcaf_core/caf/detail/stringification_inspector.hpp
+15
-9
libcaf_core/caf/detail/type_traits.hpp
libcaf_core/caf/detail/type_traits.hpp
+42
-17
libcaf_core/caf/exit_reason.hpp
libcaf_core/caf/exit_reason.hpp
+15
-0
libcaf_core/caf/fwd.hpp
libcaf_core/caf/fwd.hpp
+1
-1
libcaf_core/caf/hash/fnv.hpp
libcaf_core/caf/hash/fnv.hpp
+3
-1
libcaf_core/caf/hash/sha1.hpp
libcaf_core/caf/hash/sha1.hpp
+4
-1
libcaf_core/caf/inspector_access.hpp
libcaf_core/caf/inspector_access.hpp
+68
-314
libcaf_core/caf/inspector_access_base.hpp
libcaf_core/caf/inspector_access_base.hpp
+4
-4
libcaf_core/caf/inspector_access_type.hpp
libcaf_core/caf/inspector_access_type.hpp
+10
-100
libcaf_core/caf/load_inspector.hpp
libcaf_core/caf/load_inspector.hpp
+1
-8
libcaf_core/caf/load_inspector_base.hpp
libcaf_core/caf/load_inspector_base.hpp
+118
-18
libcaf_core/caf/message_id.hpp
libcaf_core/caf/message_id.hpp
+9
-22
libcaf_core/caf/pec.hpp
libcaf_core/caf/pec.hpp
+15
-0
libcaf_core/caf/save_inspector.hpp
libcaf_core/caf/save_inspector.hpp
+1
-8
libcaf_core/caf/save_inspector_base.hpp
libcaf_core/caf/save_inspector_base.hpp
+79
-16
libcaf_core/caf/sec.hpp
libcaf_core/caf/sec.hpp
+14
-0
libcaf_core/caf/serializer.hpp
libcaf_core/caf/serializer.hpp
+21
-4
libcaf_core/caf/stream_priority.hpp
libcaf_core/caf/stream_priority.hpp
+19
-4
libcaf_core/caf/uri.hpp
libcaf_core/caf/uri.hpp
+3
-24
libcaf_core/src/binary_serializer.cpp
libcaf_core/src/binary_serializer.cpp
+2
-2
libcaf_core/src/config_value_reader.cpp
libcaf_core/src/config_value_reader.cpp
+11
-0
libcaf_core/src/config_value_writer.cpp
libcaf_core/src/config_value_writer.cpp
+4
-0
libcaf_core/src/deserializer.cpp
libcaf_core/src/deserializer.cpp
+1
-1
libcaf_core/src/detail/serialized_size.cpp
libcaf_core/src/detail/serialized_size.cpp
+6
-1
libcaf_core/src/detail/stringification_inspector.cpp
libcaf_core/src/detail/stringification_inspector.cpp
+20
-10
libcaf_core/src/exit_reason_strings.cpp
libcaf_core/src/exit_reason_strings.cpp
+50
-0
libcaf_core/src/intrusive/inbox_result_strings.cpp
libcaf_core/src/intrusive/inbox_result_strings.cpp
+30
-0
libcaf_core/src/intrusive/task_result_strings.cpp
libcaf_core/src/intrusive/task_result_strings.cpp
+34
-0
libcaf_core/src/invoke_message_result_strings.cpp
libcaf_core/src/invoke_message_result_strings.cpp
+30
-0
libcaf_core/src/logger.cpp
libcaf_core/src/logger.cpp
+1
-1
libcaf_core/src/message_priority_strings.cpp
libcaf_core/src/message_priority_strings.cpp
+26
-0
libcaf_core/src/pec_strings.cpp
libcaf_core/src/pec_strings.cpp
+110
-0
libcaf_core/src/sec_strings.cpp
libcaf_core/src/sec_strings.cpp
+270
-0
libcaf_core/src/serializer.cpp
libcaf_core/src/serializer.cpp
+1
-1
libcaf_core/src/stream_priority_strings.cpp
libcaf_core/src/stream_priority_strings.cpp
+38
-0
libcaf_core/test/actor_profiler.cpp
libcaf_core/test/actor_profiler.cpp
+6
-6
libcaf_core/test/actor_registry.cpp
libcaf_core/test/actor_registry.cpp
+2
-2
libcaf_core/test/binary_deserializer.cpp
libcaf_core/test/binary_deserializer.cpp
+1
-1
libcaf_core/test/binary_serializer.cpp
libcaf_core/test/binary_serializer.cpp
+2
-2
libcaf_core/test/config_value_reader.cpp
libcaf_core/test/config_value_reader.cpp
+13
-7
libcaf_core/test/config_value_writer.cpp
libcaf_core/test/config_value_writer.cpp
+13
-9
libcaf_core/test/core-test.hpp
libcaf_core/test/core-test.hpp
+58
-0
libcaf_core/test/detail/serialized_size.cpp
libcaf_core/test/detail/serialized_size.cpp
+1
-1
libcaf_core/test/ipv4_endpoint.cpp
libcaf_core/test/ipv4_endpoint.cpp
+2
-2
libcaf_core/test/ipv6_endpoint.cpp
libcaf_core/test/ipv6_endpoint.cpp
+2
-2
libcaf_core/test/load_inspector.cpp
libcaf_core/test/load_inspector.cpp
+27
-20
libcaf_core/test/message.cpp
libcaf_core/test/message.cpp
+7
-10
libcaf_core/test/message_builder.cpp
libcaf_core/test/message_builder.cpp
+3
-5
libcaf_core/test/nasty.hpp
libcaf_core/test/nasty.hpp
+11
-15
libcaf_core/test/node_id.cpp
libcaf_core/test/node_id.cpp
+2
-2
libcaf_core/test/save_inspector.cpp
libcaf_core/test/save_inspector.cpp
+46
-64
libcaf_core/test/serialization.cpp
libcaf_core/test/serialization.cpp
+52
-2
libcaf_core/test/tracing_data.cpp
libcaf_core/test/tracing_data.cpp
+5
-5
libcaf_core/test/uri.cpp
libcaf_core/test/uri.cpp
+2
-2
libcaf_io/caf/io/basp/message_type.hpp
libcaf_io/caf/io/basp/message_type.hpp
+12
-0
libcaf_io/caf/io/basp/remote_message_handler.hpp
libcaf_io/caf/io/basp/remote_message_handler.hpp
+4
-4
libcaf_io/caf/io/network/protocol.hpp
libcaf_io/caf/io/network/protocol.hpp
+22
-0
libcaf_io/src/io/basp/instance.cpp
libcaf_io/src/io/basp/instance.cpp
+26
-15
libcaf_io/src/io/basp/message_type_strings.cpp
libcaf_io/src/io/basp/message_type_strings.cpp
+46
-0
libcaf_io/src/io/network/operation_strings.cpp
libcaf_io/src/io/network/operation_strings.cpp
+30
-0
libcaf_io/test/io/basp_broker.cpp
libcaf_io/test/io/basp_broker.cpp
+12
-9
libcaf_io/test/io/network/ip_endpoint.cpp
libcaf_io/test/io/network/ip_endpoint.cpp
+6
-6
libcaf_io/test/io/worker.cpp
libcaf_io/test/io/worker.cpp
+1
-1
libcaf_test/caf/test/dsl.hpp
libcaf_test/caf/test/dsl.hpp
+2
-2
manual/TypeInspection.rst
manual/TypeInspection.rst
+88
-90
No files found.
cmake/caf-generate-enum-strings.cpp
View file @
8c8fb8be
...
@@ -94,6 +94,27 @@ int main(int argc, char** argv) {
...
@@ -94,6 +94,27 @@ int main(int argc, char** argv) {
cerr
<<
"empty enum name found
\n
"
;
cerr
<<
"empty enum name found
\n
"
;
return
EXIT_FAILURE
;
return
EXIT_FAILURE
;
}
}
std
::
string
case_label_prefix
;
if
(
is_enum_class
)
case_label_prefix
=
enum_name
+
"::"
;
// Read until hitting the closing '}'.
std
::
vector
<
std
::
string
>
enum_values
;
for
(;;)
{
if
(
!
getline
(
in
,
line
))
{
cerr
<<
"unable to read enum values
\n
"
;
return
EXIT_FAILURE
;
}
trim
(
line
);
if
(
line
.
empty
())
continue
;
if
(
line
[
0
]
==
'}'
)
break
;
if
(
line
[
0
]
!=
'/'
)
{
keep_alnum
(
line
);
enum_values
.
emplace_back
(
line
);
}
}
// Generate output file.
std
::
ofstream
out
{
argv
[
2
]};
std
::
ofstream
out
{
argv
[
2
]};
if
(
!
out
)
{
if
(
!
out
)
{
cerr
<<
"unable to open output file: "
<<
argv
[
2
]
<<
'\n'
;
cerr
<<
"unable to open output file: "
<<
argv
[
2
]
<<
'\n'
;
...
@@ -104,7 +125,8 @@ int main(int argc, char** argv) {
...
@@ -104,7 +125,8 @@ int main(int argc, char** argv) {
<<
"// DO NOT EDIT: "
<<
"// DO NOT EDIT: "
"this file is auto-generated by caf-generate-enum-strings.
\n
"
"this file is auto-generated by caf-generate-enum-strings.
\n
"
"// Run the target update-enum-strings if this file is out of sync.
\n
"
"// Run the target update-enum-strings if this file is out of sync.
\n
"
"#include
\"
caf/config.hpp
\"\n\n
"
"#include
\"
caf/config.hpp
\"\n
"
"#include
\"
caf/string_view.hpp
\"\n\n
"
"CAF_PUSH_DEPRECATED_WARNING
\n\n
"
"CAF_PUSH_DEPRECATED_WARNING
\n\n
"
<<
"#include
\"
"
<<
namespaces
[
0
];
<<
"#include
\"
"
<<
namespaces
[
0
];
for
(
size_t
i
=
1
;
i
<
namespaces
.
size
();
++
i
)
for
(
size_t
i
=
1
;
i
<
namespaces
.
size
();
++
i
)
...
@@ -114,35 +136,44 @@ int main(int argc, char** argv) {
...
@@ -114,35 +136,44 @@ int main(int argc, char** argv) {
<<
"namespace "
<<
namespaces
[
0
]
<<
" {
\n
"
;
<<
"namespace "
<<
namespaces
[
0
]
<<
" {
\n
"
;
for
(
size_t
i
=
1
;
i
<
namespaces
.
size
();
++
i
)
for
(
size_t
i
=
1
;
i
<
namespaces
.
size
();
++
i
)
out
<<
"namespace "
<<
namespaces
[
i
]
<<
" {
\n
"
;
out
<<
"namespace "
<<
namespaces
[
i
]
<<
" {
\n
"
;
out
<<
"
\n
std::string to_string("
<<
enum_name
<<
" x) {
\n
"
out
<<
'\n'
;
// Generate to_string implementation.
out
<<
"std::string to_string("
<<
enum_name
<<
" x) {
\n
"
<<
" switch(x) {
\n
"
<<
" switch(x) {
\n
"
<<
" default:
\n
"
<<
" default:
\n
"
<<
" return
\"
???
\"
;
\n
"
;
<<
" return
\"
???
\"
;
\n
"
;
for
(
auto
&
val
:
enum_values
)
// Read until hitting the closing '}'.
out
<<
" case "
<<
case_label_prefix
<<
val
<<
":
\n
"
std
::
string
case_label_prefix
;
<<
" return
\"
"
<<
val
<<
"
\"
;
\n
"
;
if
(
is_enum_class
)
case_label_prefix
=
enum_name
+
"::"
;
for
(;;)
{
if
(
!
getline
(
in
,
line
))
{
cerr
<<
"unable to read enum values
\n
"
;
return
EXIT_FAILURE
;
}
trim
(
line
);
if
(
line
.
empty
())
continue
;
if
(
line
[
0
]
==
'}'
)
break
;
if
(
line
[
0
]
!=
'/'
)
{
keep_alnum
(
line
);
out
<<
" case "
<<
case_label_prefix
<<
line
<<
":
\n
"
<<
" return
\"
"
<<
line
<<
"
\"
;
\n
"
;
}
}
// Done. Print file footer and exit.
out
<<
" };
\n
"
out
<<
" };
\n
"
<<
"}
\n\n
"
;
<<
"}
\n\n
"
;
// Generate from_string implementation.
out
<<
"bool from_string(string_view in, "
<<
enum_name
<<
"& out) {
\n
"
;
for
(
auto
&
val
:
enum_values
)
out
<<
"if (in ==
\"
"
<<
val
<<
"
\"
) {
\n
"
<<
" out = "
<<
case_label_prefix
<<
val
<<
";
\n
"
<<
" return true;
\n
"
<<
" } else "
;
out
<<
"{
\n
"
<<
" return false;
\n
"
<<
" }
\n
"
<<
"}
\n\n
"
;
// Generate from_integer implementation.
out
<<
"bool from_integer(std::underlying_type_t<"
<<
enum_name
<<
"> in,
\n
"
<<
" "
<<
enum_name
<<
"& out) {
\n
"
<<
" auto result = static_cast<"
<<
enum_name
<<
">(in);
\n
"
<<
" switch(result) {
\n
"
<<
" default:
\n
"
<<
" return false;
\n
"
;
for
(
auto
&
val
:
enum_values
)
out
<<
" case "
<<
case_label_prefix
<<
val
<<
":
\n
"
;
out
<<
" out = result;
\n
"
<<
" return true;
\n
"
<<
" };
\n
"
<<
"}
\n\n
"
;
// Done. Print file footer and exit.
for
(
auto
i
=
namespaces
.
rbegin
();
i
!=
namespaces
.
rend
();
++
i
)
for
(
auto
i
=
namespaces
.
rbegin
();
i
!=
namespaces
.
rend
();
++
i
)
out
<<
"} // namespace "
<<
*
i
<<
'\n'
;
out
<<
"} // namespace "
<<
*
i
<<
'\n'
;
out
<<
"
\n
CAF_POP_WARNINGS
\n
"
;
out
<<
"
\n
CAF_POP_WARNINGS
\n
"
;
return
EXIT_SUCCESS
;
}
}
examples/custom_type/custom_types_1.cpp
View file @
8c8fb8be
...
@@ -94,14 +94,14 @@ void caf_main(actor_system& sys) {
...
@@ -94,14 +94,14 @@ void caf_main(actor_system& sys) {
binary_serializer
::
container_type
buf
;
binary_serializer
::
container_type
buf
;
// write f1 to buffer
// write f1 to buffer
binary_serializer
sink
{
sys
,
buf
};
binary_serializer
sink
{
sys
,
buf
};
if
(
!
sink
.
apply
_object
(
f1
))
{
if
(
!
sink
.
apply
(
f1
))
{
std
::
cerr
<<
"*** failed to serialize foo2: "
<<
to_string
(
sink
.
get_error
())
std
::
cerr
<<
"*** failed to serialize foo2: "
<<
to_string
(
sink
.
get_error
())
<<
'\n'
;
<<
'\n'
;
return
;
return
;
}
}
// read f2 back from buffer
// read f2 back from buffer
binary_deserializer
source
{
sys
,
buf
};
binary_deserializer
source
{
sys
,
buf
};
if
(
!
source
.
apply
_object
(
f2
))
{
if
(
!
source
.
apply
(
f2
))
{
std
::
cerr
<<
"*** failed to deserialize foo2: "
std
::
cerr
<<
"*** failed to deserialize foo2: "
<<
to_string
(
source
.
get_error
())
<<
'\n'
;
<<
to_string
(
source
.
get_error
())
<<
'\n'
;
return
;
return
;
...
...
libcaf_core/caf/binary_deserializer.hpp
View file @
8c8fb8be
...
@@ -21,9 +21,11 @@
...
@@ -21,9 +21,11 @@
#include <cstddef>
#include <cstddef>
#include <string>
#include <string>
#include <tuple>
#include <tuple>
#include <type_traits>
#include <utility>
#include <utility>
#include "caf/detail/core_export.hpp"
#include "caf/detail/core_export.hpp"
#include "caf/detail/squashed_int.hpp"
#include "caf/error_code.hpp"
#include "caf/error_code.hpp"
#include "caf/fwd.hpp"
#include "caf/fwd.hpp"
#include "caf/load_inspector_base.hpp"
#include "caf/load_inspector_base.hpp"
...
@@ -37,6 +39,10 @@ namespace caf {
...
@@ -37,6 +39,10 @@ namespace caf {
class
CAF_CORE_EXPORT
binary_deserializer
class
CAF_CORE_EXPORT
binary_deserializer
:
public
load_inspector_base
<
binary_deserializer
>
{
:
public
load_inspector_base
<
binary_deserializer
>
{
public:
public:
// -- member types -----------------------------------------------------------
using
super
=
load_inspector_base
<
binary_deserializer
>
;
// -- constructors, destructors, and assignment operators --------------------
// -- constructors, destructors, and assignment operators --------------------
template
<
class
Container
>
template
<
class
Container
>
...
@@ -107,11 +113,11 @@ public:
...
@@ -107,11 +113,11 @@ public:
bool
fetch_next_object_type
(
type_id_t
&
type
)
noexcept
;
bool
fetch_next_object_type
(
type_id_t
&
type
)
noexcept
;
constexpr
bool
begin_object
(
string_view
)
noexcept
{
constexpr
bool
begin_object
(
string_view
)
noexcept
{
return
ok
;
return
true
;
}
}
constexpr
bool
end_object
()
noexcept
{
constexpr
bool
end_object
()
noexcept
{
return
ok
;
return
true
;
}
}
constexpr
bool
begin_field
(
string_view
)
noexcept
{
constexpr
bool
begin_field
(
string_view
)
noexcept
{
...
@@ -127,29 +133,29 @@ public:
...
@@ -127,29 +133,29 @@ public:
span
<
const
type_id_t
>
types
,
size_t
&
index
)
noexcept
;
span
<
const
type_id_t
>
types
,
size_t
&
index
)
noexcept
;
constexpr
bool
end_field
()
{
constexpr
bool
end_field
()
{
return
ok
;
return
true
;
}
}
constexpr
bool
begin_tuple
(
size_t
)
noexcept
{
constexpr
bool
begin_tuple
(
size_t
)
noexcept
{
return
ok
;
return
true
;
}
}
constexpr
bool
end_tuple
()
noexcept
{
constexpr
bool
end_tuple
()
noexcept
{
return
ok
;
return
true
;
}
}
constexpr
bool
begin_key_value_pair
()
noexcept
{
constexpr
bool
begin_key_value_pair
()
noexcept
{
return
ok
;
return
true
;
}
}
constexpr
bool
end_key_value_pair
()
noexcept
{
constexpr
bool
end_key_value_pair
()
noexcept
{
return
ok
;
return
true
;
}
}
bool
begin_sequence
(
size_t
&
list_size
)
noexcept
;
bool
begin_sequence
(
size_t
&
list_size
)
noexcept
;
constexpr
bool
end_sequence
()
noexcept
{
constexpr
bool
end_sequence
()
noexcept
{
return
ok
;
return
true
;
}
}
bool
begin_associative_array
(
size_t
&
size
)
noexcept
{
bool
begin_associative_array
(
size_t
&
size
)
noexcept
{
...
@@ -180,6 +186,17 @@ public:
...
@@ -180,6 +186,17 @@ public:
bool
value
(
uint64_t
&
x
)
noexcept
;
bool
value
(
uint64_t
&
x
)
noexcept
;
template
<
class
T
>
std
::
enable_if_t
<
std
::
is_integral
<
T
>::
value
,
bool
>
value
(
T
&
x
)
noexcept
{
auto
tmp
=
detail
::
squashed_int_t
<
T
>
{
0
};
if
(
value
(
tmp
))
{
x
=
static_cast
<
T
>
(
tmp
);
return
true
;
}
else
{
return
false
;
}
}
bool
value
(
float
&
x
)
noexcept
;
bool
value
(
float
&
x
)
noexcept
;
bool
value
(
double
&
x
)
noexcept
;
bool
value
(
double
&
x
)
noexcept
;
...
...
libcaf_core/caf/binary_serializer.hpp
View file @
8c8fb8be
...
@@ -20,11 +20,13 @@
...
@@ -20,11 +20,13 @@
#include <cstddef>
#include <cstddef>
#include <string>
#include <string>
#include <type_traits>
#include <vector>
#include <vector>
#include "caf/byte.hpp"
#include "caf/byte.hpp"
#include "caf/byte_buffer.hpp"
#include "caf/byte_buffer.hpp"
#include "caf/detail/core_export.hpp"
#include "caf/detail/core_export.hpp"
#include "caf/detail/squashed_int.hpp"
#include "caf/fwd.hpp"
#include "caf/fwd.hpp"
#include "caf/save_inspector_base.hpp"
#include "caf/save_inspector_base.hpp"
#include "caf/span.hpp"
#include "caf/span.hpp"
...
@@ -37,6 +39,8 @@ class CAF_CORE_EXPORT binary_serializer
...
@@ -37,6 +39,8 @@ class CAF_CORE_EXPORT binary_serializer
public:
public:
// -- member types -----------------------------------------------------------
// -- member types -----------------------------------------------------------
using
super
=
save_inspector_base
<
binary_serializer
>
;
using
container_type
=
byte_buffer
;
using
container_type
=
byte_buffer
;
using
value_type
=
byte
;
using
value_type
=
byte
;
...
@@ -94,15 +98,15 @@ public:
...
@@ -94,15 +98,15 @@ public:
bool
inject_next_object_type
(
type_id_t
type
);
bool
inject_next_object_type
(
type_id_t
type
);
constexpr
bool
begin_object
(
string_view
)
{
constexpr
bool
begin_object
(
string_view
)
{
return
ok
;
return
true
;
}
}
constexpr
bool
end_object
()
{
constexpr
bool
end_object
()
{
return
ok
;
return
true
;
}
}
constexpr
bool
begin_field
(
string_view
)
noexcept
{
constexpr
bool
begin_field
(
string_view
)
noexcept
{
return
ok
;
return
true
;
}
}
bool
begin_field
(
string_view
,
bool
is_present
);
bool
begin_field
(
string_view
,
bool
is_present
);
...
@@ -113,29 +117,29 @@ public:
...
@@ -113,29 +117,29 @@ public:
size_t
index
);
size_t
index
);
constexpr
bool
end_field
()
{
constexpr
bool
end_field
()
{
return
ok
;
return
true
;
}
}
constexpr
bool
begin_tuple
(
size_t
)
{
constexpr
bool
begin_tuple
(
size_t
)
{
return
ok
;
return
true
;
}
}
constexpr
bool
end_tuple
()
{
constexpr
bool
end_tuple
()
{
return
ok
;
return
true
;
}
}
constexpr
bool
begin_key_value_pair
()
{
constexpr
bool
begin_key_value_pair
()
{
return
ok
;
return
true
;
}
}
constexpr
bool
end_key_value_pair
()
{
constexpr
bool
end_key_value_pair
()
{
return
ok
;
return
true
;
}
}
bool
begin_sequence
(
size_t
list_size
);
bool
begin_sequence
(
size_t
list_size
);
constexpr
bool
end_sequence
()
{
constexpr
bool
end_sequence
()
{
return
ok
;
return
true
;
}
}
bool
begin_associative_array
(
size_t
size
)
{
bool
begin_associative_array
(
size_t
size
)
{
...
@@ -166,6 +170,11 @@ public:
...
@@ -166,6 +170,11 @@ public:
bool
value
(
uint64_t
x
);
bool
value
(
uint64_t
x
);
template
<
class
T
>
std
::
enable_if_t
<
std
::
is_integral
<
T
>::
value
,
bool
>
value
(
T
x
)
{
return
value
(
static_cast
<
detail
::
squashed_int_t
<
T
>>
(
x
));
}
bool
value
(
float
x
);
bool
value
(
float
x
);
bool
value
(
double
x
);
bool
value
(
double
x
);
...
...
libcaf_core/caf/config_value.hpp
View file @
8c8fb8be
...
@@ -942,7 +942,7 @@ struct inspect_config_value_access {
...
@@ -942,7 +942,7 @@ struct inspect_config_value_access {
static
optional
<
T
>
get_if
(
const
config_value
*
x
)
{
static
optional
<
T
>
get_if
(
const
config_value
*
x
)
{
config_value_reader
reader
{
x
};
config_value_reader
reader
{
x
};
auto
tmp
=
T
{};
auto
tmp
=
T
{};
if
(
detail
::
load
_value
(
reader
,
tmp
))
if
(
detail
::
load
(
reader
,
tmp
))
return
optional
<
T
>
{
std
::
move
(
tmp
)};
return
optional
<
T
>
{
std
::
move
(
tmp
)};
return
none
;
return
none
;
}
}
...
@@ -985,7 +985,7 @@ struct inspect_config_value_access {
...
@@ -985,7 +985,7 @@ struct inspect_config_value_access {
static
config_value
convert
(
const
T
&
x
)
{
static
config_value
convert
(
const
T
&
x
)
{
config_value
result
;
config_value
result
;
config_value_writer
writer
{
&
result
};
config_value_writer
writer
{
&
result
};
if
(
!
detail
::
save
_value
(
writer
,
x
))
if
(
!
detail
::
save
(
writer
,
x
))
CAF_RAISE_ERROR
(
"unable to convert type to a config_value"
);
CAF_RAISE_ERROR
(
"unable to convert type to a config_value"
);
return
result
;
return
result
;
}
}
...
...
libcaf_core/caf/config_value_reader.hpp
View file @
8c8fb8be
...
@@ -131,6 +131,8 @@ public:
...
@@ -131,6 +131,8 @@ public:
bool
end_associative_array
()
override
;
bool
end_associative_array
()
override
;
bool
value
(
byte
&
x
)
override
;
bool
value
(
bool
&
x
)
override
;
bool
value
(
bool
&
x
)
override
;
bool
value
(
int8_t
&
x
)
override
;
bool
value
(
int8_t
&
x
)
override
;
...
...
libcaf_core/caf/config_value_writer.hpp
View file @
8c8fb8be
...
@@ -102,6 +102,8 @@ public:
...
@@ -102,6 +102,8 @@ public:
bool
end_associative_array
()
override
;
bool
end_associative_array
()
override
;
bool
value
(
byte
x
)
override
;
bool
value
(
bool
x
)
override
;
bool
value
(
bool
x
)
override
;
bool
value
(
int8_t
x
)
override
;
bool
value
(
int8_t
x
)
override
;
...
...
libcaf_core/caf/cow_tuple.hpp
View file @
8c8fb8be
...
@@ -136,19 +136,11 @@ struct inspector_access<cow_tuple<Ts...>> {
...
@@ -136,19 +136,11 @@ struct inspector_access<cow_tuple<Ts...>> {
using
value_type
=
cow_tuple
<
Ts
...
>
;
using
value_type
=
cow_tuple
<
Ts
...
>
;
template
<
class
Inspector
>
template
<
class
Inspector
>
static
bool
apply
_object
(
Inspector
&
f
,
value_type
&
x
)
{
static
bool
apply
(
Inspector
&
f
,
value_type
&
x
)
{
if
constexpr
(
Inspector
::
is_loading
)
if
constexpr
(
Inspector
::
is_loading
)
return
detail
::
load_object
(
f
,
x
.
unshared
());
return
f
.
tuple
(
x
.
unshared
());
else
else
return
detail
::
save_object
(
f
,
detail
::
as_mutable_ref
(
x
.
data
()));
return
f
.
tuple
(
x
.
data
());
}
template
<
class
Inspector
>
static
bool
apply_value
(
Inspector
&
f
,
value_type
&
x
)
{
if
constexpr
(
Inspector
::
is_loading
)
return
detail
::
load_value
(
f
,
x
.
unshared
());
else
return
detail
::
save_value
(
f
,
detail
::
as_mutable_ref
(
x
.
data
()));
}
}
template
<
class
Inspector
>
template
<
class
Inspector
>
...
...
libcaf_core/caf/deep_to_string.hpp
View file @
8c8fb8be
...
@@ -35,7 +35,7 @@ std::string deep_to_string(const T& x) {
...
@@ -35,7 +35,7 @@ std::string deep_to_string(const T& x) {
using
inspector_type
=
detail
::
stringification_inspector
;
using
inspector_type
=
detail
::
stringification_inspector
;
std
::
string
result
;
std
::
string
result
;
inspector_type
f
{
result
};
inspector_type
f
{
result
};
detail
::
save
_value
(
f
,
detail
::
as_mutable_ref
(
x
));
detail
::
save
(
f
,
detail
::
as_mutable_ref
(
x
));
return
result
;
return
result
;
}
}
...
...
libcaf_core/caf/default_enum_inspect.hpp
0 → 100644
View file @
8c8fb8be
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2020 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#pragma once
#include <string>
#include <type_traits>
#include "caf/string_view.hpp"
namespace
caf
{
/// Convenience function for providing a default inspection scaffold for custom
/// enumeration types.
///
/// The enumeration type must provide the following interface based on free
/// functions:
///
/// ~~~(cpp)
/// enum class Enumeration : ... { ... };
/// std::string to_string(Enumeration);
/// bool from_string(string_view, Enumeration&);
/// bool from_integer(std::underlying_type_t<Enumeration>, Enumeration&);
/// ~~~
template
<
class
Inspector
,
class
Enumeration
>
bool
default_enum_inspect
(
Inspector
&
f
,
Enumeration
&
x
)
{
using
integer_type
=
std
::
underlying_type_t
<
Enumeration
>
;
if
(
f
.
has_human_readable_format
())
{
auto
get
=
[
&
x
]
{
return
to_string
(
x
);
};
auto
set
=
[
&
x
](
string_view
str
)
{
return
from_string
(
str
,
x
);
};
return
f
.
apply
(
get
,
set
);
}
else
{
auto
get
=
[
&
x
]
{
return
static_cast
<
integer_type
>
(
x
);
};
auto
set
=
[
&
x
](
integer_type
val
)
{
return
from_integer
(
val
,
x
);
};
return
f
.
apply
(
get
,
set
);
}
}
}
// namespace caf
libcaf_core/caf/deserializer.hpp
View file @
8c8fb8be
...
@@ -26,6 +26,7 @@
...
@@ -26,6 +26,7 @@
#include "caf/byte.hpp"
#include "caf/byte.hpp"
#include "caf/detail/core_export.hpp"
#include "caf/detail/core_export.hpp"
#include "caf/detail/squashed_int.hpp"
#include "caf/fwd.hpp"
#include "caf/fwd.hpp"
#include "caf/load_inspector_base.hpp"
#include "caf/load_inspector_base.hpp"
#include "caf/span.hpp"
#include "caf/span.hpp"
...
@@ -37,6 +38,10 @@ namespace caf {
...
@@ -37,6 +38,10 @@ namespace caf {
/// Technology-independent deserialization interface.
/// Technology-independent deserialization interface.
class
CAF_CORE_EXPORT
deserializer
:
public
load_inspector_base
<
deserializer
>
{
class
CAF_CORE_EXPORT
deserializer
:
public
load_inspector_base
<
deserializer
>
{
public:
public:
// -- member types -----------------------------------------------------------
using
super
=
load_inspector_base
<
deserializer
>
;
// -- constructors, destructors, and assignment operators --------------------
// -- constructors, destructors, and assignment operators --------------------
explicit
deserializer
(
actor_system
&
sys
)
noexcept
;
explicit
deserializer
(
actor_system
&
sys
)
noexcept
;
...
@@ -111,9 +116,12 @@ public:
...
@@ -111,9 +116,12 @@ public:
/// @note the default implementation calls `end_sequence()`.
/// @note the default implementation calls `end_sequence()`.
virtual
bool
end_associative_array
();
virtual
bool
end_associative_array
();
/// Reads primitive value from the input.
/// Reads `x` from the input.
/// @param x The primitive value.
/// @param x A reference to a builtin type.
/// @returns A non-zero error code on failure, `sec::success` otherwise.
/// @returns `true` on success, `false` otherwise.
virtual
bool
value
(
byte
&
x
)
=
0
;
/// @copydoc value
virtual
bool
value
(
bool
&
x
)
=
0
;
virtual
bool
value
(
bool
&
x
)
=
0
;
/// @copydoc value
/// @copydoc value
...
@@ -140,6 +148,17 @@ public:
...
@@ -140,6 +148,17 @@ public:
/// @copydoc value
/// @copydoc value
virtual
bool
value
(
uint64_t
&
)
=
0
;
virtual
bool
value
(
uint64_t
&
)
=
0
;
/// @copydoc value
template
<
class
T
>
std
::
enable_if_t
<
std
::
is_integral
<
T
>::
value
,
bool
>
value
(
T
&
x
)
noexcept
{
auto
tmp
=
detail
::
squashed_int_t
<
T
>
{
0
};
if
(
value
(
tmp
))
{
x
=
static_cast
<
T
>
(
tmp
);
return
true
;
}
else
{
return
false
;
}
}
/// @copydoc value
/// @copydoc value
virtual
bool
value
(
float
&
)
=
0
;
virtual
bool
value
(
float
&
)
=
0
;
...
@@ -163,10 +182,12 @@ public:
...
@@ -163,10 +182,12 @@ public:
/// @returns A non-zero error code on failure, `sec::success` otherwise.
/// @returns A non-zero error code on failure, `sec::success` otherwise.
virtual
bool
value
(
span
<
byte
>
x
)
=
0
;
virtual
bool
value
(
span
<
byte
>
x
)
=
0
;
using
super
::
list
;
/// Adds each boolean in `xs` to the output. Derived classes can override this
/// Adds each boolean in `xs` to the output. Derived classes can override this
/// member function to pack the booleans, for example to avoid using one byte
/// member function to pack the booleans, for example to avoid using one byte
/// for each value in a binary output format.
/// for each value in a binary output format.
virtual
bool
value
(
std
::
vector
<
bool
>&
xs
);
virtual
bool
list
(
std
::
vector
<
bool
>&
xs
);
protected:
protected:
/// Provides access to the ::proxy_registry and to the ::actor_system.
/// Provides access to the ::proxy_registry and to the ::actor_system.
...
...
libcaf_core/caf/detail/make_meta_object.hpp
View file @
8c8fb8be
...
@@ -50,28 +50,28 @@ void copy_construct(void* ptr, const void* src) {
...
@@ -50,28 +50,28 @@ void copy_construct(void* ptr, const void* src) {
template
<
class
T
>
template
<
class
T
>
bool
save_binary
(
binary_serializer
&
sink
,
const
void
*
ptr
)
{
bool
save_binary
(
binary_serializer
&
sink
,
const
void
*
ptr
)
{
return
sink
.
apply
_object
(
*
static_cast
<
const
T
*>
(
ptr
));
return
sink
.
apply
(
*
static_cast
<
const
T
*>
(
ptr
));
}
}
template
<
class
T
>
template
<
class
T
>
bool
load_binary
(
binary_deserializer
&
source
,
void
*
ptr
)
{
bool
load_binary
(
binary_deserializer
&
source
,
void
*
ptr
)
{
return
source
.
apply
_object
(
*
static_cast
<
T
*>
(
ptr
));
return
source
.
apply
(
*
static_cast
<
T
*>
(
ptr
));
}
}
template
<
class
T
>
template
<
class
T
>
bool
save
(
serializer
&
sink
,
const
void
*
ptr
)
{
bool
save
(
serializer
&
sink
,
const
void
*
ptr
)
{
return
sink
.
apply
_object
(
*
static_cast
<
const
T
*>
(
ptr
));
return
sink
.
apply
(
*
static_cast
<
const
T
*>
(
ptr
));
}
}
template
<
class
T
>
template
<
class
T
>
bool
load
(
deserializer
&
source
,
void
*
ptr
)
{
bool
load
(
deserializer
&
source
,
void
*
ptr
)
{
return
source
.
apply
_object
(
*
static_cast
<
T
*>
(
ptr
));
return
source
.
apply
(
*
static_cast
<
T
*>
(
ptr
));
}
}
template
<
class
T
>
template
<
class
T
>
void
stringify
(
std
::
string
&
buf
,
const
void
*
ptr
)
{
void
stringify
(
std
::
string
&
buf
,
const
void
*
ptr
)
{
stringification_inspector
f
{
buf
};
stringification_inspector
f
{
buf
};
auto
unused
=
f
.
apply
_object
(
*
static_cast
<
const
T
*>
(
ptr
));
auto
unused
=
f
.
apply
(
*
static_cast
<
const
T
*>
(
ptr
));
static_cast
<
void
>
(
unused
);
static_cast
<
void
>
(
unused
);
}
}
...
...
libcaf_core/caf/detail/serialized_size.hpp
View file @
8c8fb8be
...
@@ -58,6 +58,8 @@ public:
...
@@ -58,6 +58,8 @@ public:
bool
end_sequence
()
override
;
bool
end_sequence
()
override
;
bool
value
(
byte
x
)
override
;
bool
value
(
bool
x
)
override
;
bool
value
(
bool
x
)
override
;
bool
value
(
int8_t
x
)
override
;
bool
value
(
int8_t
x
)
override
;
...
@@ -90,13 +92,15 @@ public:
...
@@ -90,13 +92,15 @@ public:
bool
value
(
span
<
const
byte
>
x
)
override
;
bool
value
(
span
<
const
byte
>
x
)
override
;
bool
value
(
const
std
::
vector
<
bool
>&
xs
)
override
;
using
super
::
list
;
bool
list
(
const
std
::
vector
<
bool
>&
xs
)
override
;
};
};
template
<
class
T
>
template
<
class
T
>
size_t
serialized_size
(
const
T
&
x
)
{
size_t
serialized_size
(
const
T
&
x
)
{
serialized_size_inspector
f
;
serialized_size_inspector
f
;
auto
unused
=
f
.
apply
_object
(
x
);
auto
unused
=
f
.
apply
(
x
);
static_cast
<
void
>
(
unused
);
// Always true.
static_cast
<
void
>
(
unused
);
// Always true.
return
f
.
result
;
return
f
.
result
;
}
}
...
@@ -104,7 +108,7 @@ size_t serialized_size(const T& x) {
...
@@ -104,7 +108,7 @@ size_t serialized_size(const T& x) {
template
<
class
T
>
template
<
class
T
>
size_t
serialized_size
(
actor_system
&
sys
,
const
T
&
x
)
{
size_t
serialized_size
(
actor_system
&
sys
,
const
T
&
x
)
{
serialized_size_inspector
f
{
sys
};
serialized_size_inspector
f
{
sys
};
auto
unused
=
f
.
apply
_object
(
x
);
auto
unused
=
f
.
apply
(
x
);
static_cast
<
void
>
(
unused
);
// Always true.
static_cast
<
void
>
(
unused
);
// Always true.
return
f
.
result
;
return
f
.
result
;
}
}
...
...
libcaf_core/caf/detail/size_based_credit_controller.hpp
View file @
8c8fb8be
...
@@ -66,7 +66,7 @@ public:
...
@@ -66,7 +66,7 @@ public:
this
->
inspector_
.
result
=
0
;
this
->
inspector_
.
result
=
0
;
this
->
sampled_elements_
+=
x
.
xs_size
;
this
->
sampled_elements_
+=
x
.
xs_size
;
for
(
auto
&
element
:
x
.
xs
.
get_as
<
std
::
vector
<
T
>>
(
0
))
for
(
auto
&
element
:
x
.
xs
.
get_as
<
std
::
vector
<
T
>>
(
0
))
detail
::
save
_value
(
this
->
inspector_
,
element
);
detail
::
save
(
this
->
inspector_
,
element
);
this
->
sampled_total_size_
this
->
sampled_total_size_
+=
static_cast
<
int64_t
>
(
this
->
inspector_
.
result
);
+=
static_cast
<
int64_t
>
(
this
->
inspector_
.
result
);
}
}
...
...
libcaf_core/caf/detail/stringification_inspector.hpp
View file @
8c8fb8be
...
@@ -40,7 +40,7 @@ class CAF_CORE_EXPORT stringification_inspector
...
@@ -40,7 +40,7 @@ class CAF_CORE_EXPORT stringification_inspector
public:
public:
// -- member types -----------------------------------------------------------
// -- member types -----------------------------------------------------------
using
super
=
save_inspector
;
using
super
=
save_inspector
_base
<
stringification_inspector
>
;
// -- constructors, destructors, and assignment operators --------------------
// -- constructors, destructors, and assignment operators --------------------
...
@@ -100,6 +100,8 @@ public:
...
@@ -100,6 +100,8 @@ public:
return
end_sequence
();
return
end_sequence
();
}
}
bool
value
(
byte
x
);
bool
value
(
bool
x
);
bool
value
(
bool
x
);
template
<
class
Integral
>
template
<
class
Integral
>
...
@@ -126,7 +128,11 @@ public:
...
@@ -126,7 +128,11 @@ public:
bool
value
(
const
std
::
u32string
&
x
);
bool
value
(
const
std
::
u32string
&
x
);
bool
value
(
const
std
::
vector
<
bool
>&
xs
);
bool
value
(
span
<
const
byte
>
x
);
using
super
::
list
;
bool
list
(
const
std
::
vector
<
bool
>&
xs
);
// -- builtin inspection to pick up to_string or provide nicer formatting ----
// -- builtin inspection to pick up to_string or provide nicer formatting ----
...
@@ -146,14 +152,14 @@ public:
...
@@ -146,14 +152,14 @@ public:
return
true
;
return
true
;
}
}
result_
+=
'{'
;
result_
+=
'{'
;
save
_value
(
*
this
,
i
->
first
);
save
(
*
this
,
i
->
first
);
result_
+=
" = "
;
result_
+=
" = "
;
save
_value
(
*
this
,
i
->
second
);
save
(
*
this
,
i
->
second
);
while
(
++
i
!=
last
)
{
while
(
++
i
!=
last
)
{
sep
();
sep
();
save
_value
(
*
this
,
i
->
first
);
save
(
*
this
,
i
->
first
);
result_
+=
" = "
;
result_
+=
" = "
;
save
_value
(
*
this
,
i
->
second
);
save
(
*
this
,
i
->
second
);
}
}
result_
+=
'}'
;
result_
+=
'}'
;
return
true
;
return
true
;
...
@@ -186,7 +192,7 @@ public:
...
@@ -186,7 +192,7 @@ public:
}
else
{
}
else
{
sep
();
sep
();
result_
+=
'*'
;
result_
+=
'*'
;
save
_value
(
*
this
,
detail
::
as_mutable_ref
(
*
x
));
save
(
*
this
,
detail
::
as_mutable_ref
(
*
x
));
return
true
;
return
true
;
}
}
}
}
...
@@ -198,7 +204,7 @@ public:
...
@@ -198,7 +204,7 @@ public:
result_
+=
"null"
;
result_
+=
"null"
;
}
else
{
}
else
{
result_
+=
'*'
;
result_
+=
'*'
;
save
_value
(
*
this
,
detail
::
as_mutable_ref
(
*
x
));
save
(
*
this
,
detail
::
as_mutable_ref
(
*
x
));
}
}
return
true
;
return
true
;
}
}
...
@@ -228,7 +234,7 @@ private:
...
@@ -228,7 +234,7 @@ private:
sep
();
sep
();
result_
+=
'['
;
result_
+=
'['
;
while
(
first
!=
sentinel
)
while
(
first
!=
sentinel
)
save
_value
(
*
this
,
*
first
++
);
save
(
*
this
,
*
first
++
);
result_
+=
']'
;
result_
+=
']'
;
}
}
...
...
libcaf_core/caf/detail/type_traits.hpp
View file @
8c8fb8be
...
@@ -878,23 +878,6 @@ public:
...
@@ -878,23 +878,6 @@ public:
static
constexpr
bool
value
=
result_type
::
value
;
static
constexpr
bool
value
=
result_type
::
value
;
};
};
/// Checks whether `T` provides an `inspect_value` overload for `Inspector`.
template
<
class
Inspector
,
class
T
>
class
has_inspect_value_overload
{
private:
template
<
class
U
>
static
auto
sfinae
(
Inspector
&
x
,
U
&
y
)
->
decltype
(
inspect_value
(
x
,
y
),
std
::
true_type
{});
static
std
::
false_type
sfinae
(
Inspector
&
,
...);
using
result_type
=
decltype
(
sfinae
(
std
::
declval
<
Inspector
&>
(),
std
::
declval
<
T
&>
()));
public:
static
constexpr
bool
value
=
result_type
::
value
;
};
/// Checks whether the inspector has a `builtin_inspect` overload for `T`.
/// Checks whether the inspector has a `builtin_inspect` overload for `T`.
template
<
class
Inspector
,
class
T
>
template
<
class
Inspector
,
class
T
>
class
has_builtin_inspect
{
class
has_builtin_inspect
{
...
@@ -980,6 +963,48 @@ public:
...
@@ -980,6 +963,48 @@ public:
static
constexpr
bool
value
=
sfinae_result
::
value
;
static
constexpr
bool
value
=
sfinae_result
::
value
;
};
};
/// Checks whether `T` is primitive, i.e., either an arithmetic type or
/// convertible to one of STL's string types.
template
<
class
T
,
bool
IsLoading
>
struct
is_builtin_inspector_type
{
static
constexpr
bool
value
=
std
::
is_arithmetic
<
T
>::
value
;
};
template
<
bool
IsLoading
>
struct
is_builtin_inspector_type
<
byte
,
IsLoading
>
{
static
constexpr
bool
value
=
true
;
};
template
<
bool
IsLoading
>
struct
is_builtin_inspector_type
<
span
<
byte
>
,
IsLoading
>
{
static
constexpr
bool
value
=
true
;
};
template
<
bool
IsLoading
>
struct
is_builtin_inspector_type
<
std
::
string
,
IsLoading
>
{
static
constexpr
bool
value
=
true
;
};
template
<
bool
IsLoading
>
struct
is_builtin_inspector_type
<
std
::
u16string
,
IsLoading
>
{
static
constexpr
bool
value
=
true
;
};
template
<
bool
IsLoading
>
struct
is_builtin_inspector_type
<
std
::
u32string
,
IsLoading
>
{
static
constexpr
bool
value
=
true
;
};
template
<
>
struct
is_builtin_inspector_type
<
string_view
,
false
>
{
static
constexpr
bool
value
=
true
;
};
template
<
>
struct
is_builtin_inspector_type
<
span
<
const
byte
>
,
false
>
{
static
constexpr
bool
value
=
true
;
};
}
// namespace caf::detail
}
// namespace caf::detail
#undef CAF_HAS_MEMBER_TRAIT
#undef CAF_HAS_MEMBER_TRAIT
...
...
libcaf_core/caf/exit_reason.hpp
View file @
8c8fb8be
...
@@ -24,8 +24,11 @@
...
@@ -24,8 +24,11 @@
#include <cstdint>
#include <cstdint>
#include <string>
#include <string>
#include <type_traits>
#include "caf/default_enum_inspect.hpp"
#include "caf/detail/core_export.hpp"
#include "caf/detail/core_export.hpp"
#include "caf/fwd.hpp"
#include "caf/is_error_code_enum.hpp"
#include "caf/is_error_code_enum.hpp"
namespace
caf
{
namespace
caf
{
...
@@ -55,6 +58,18 @@ enum class exit_reason : uint8_t {
...
@@ -55,6 +58,18 @@ enum class exit_reason : uint8_t {
/// @relates exit_reason
/// @relates exit_reason
CAF_CORE_EXPORT
std
::
string
to_string
(
exit_reason
);
CAF_CORE_EXPORT
std
::
string
to_string
(
exit_reason
);
/// @relates exit_reason
CAF_CORE_EXPORT
bool
from_string
(
string_view
,
exit_reason
&
);
/// @relates exit_reason
CAF_CORE_EXPORT
bool
from_integer
(
std
::
underlying_type_t
<
exit_reason
>
,
exit_reason
&
);
template
<
class
Inspector
>
bool
inspect
(
Inspector
&
f
,
exit_reason
&
x
)
{
return
default_enum_inspect
(
f
,
x
);
}
}
// namespace caf
}
// namespace caf
CAF_ERROR_CODE_ENUM
(
exit_reason
)
CAF_ERROR_CODE_ENUM
(
exit_reason
)
libcaf_core/caf/fwd.hpp
View file @
8c8fb8be
...
@@ -196,7 +196,7 @@ enum class exit_reason : uint8_t;
...
@@ -196,7 +196,7 @@ enum class exit_reason : uint8_t;
enum
class
invoke_message_result
;
enum
class
invoke_message_result
;
enum
class
pec
:
uint8_t
;
enum
class
pec
:
uint8_t
;
enum
class
sec
:
uint8_t
;
enum
class
sec
:
uint8_t
;
enum
class
stream_priority
;
enum
class
stream_priority
:
uint8_t
;
// -- aliases ------------------------------------------------------------------
// -- aliases ------------------------------------------------------------------
...
...
libcaf_core/caf/hash/fnv.hpp
View file @
8c8fb8be
...
@@ -43,6 +43,8 @@ class fnv : public save_inspector_base<fnv<T>> {
...
@@ -43,6 +43,8 @@ class fnv : public save_inspector_base<fnv<T>> {
public:
public:
static_assert
(
sizeof
(
T
)
==
4
||
sizeof
(
T
)
==
8
);
static_assert
(
sizeof
(
T
)
==
4
||
sizeof
(
T
)
==
8
);
using
super
=
save_inspector_base
<
fnv
<
T
>>
;
constexpr
fnv
()
noexcept
:
result
(
init
())
{
constexpr
fnv
()
noexcept
:
result
(
init
())
{
// nop
// nop
}
}
...
@@ -154,7 +156,7 @@ public:
...
@@ -154,7 +156,7 @@ public:
static
T
compute
(
Ts
&&
...
xs
)
noexcept
{
static
T
compute
(
Ts
&&
...
xs
)
noexcept
{
using
detail
::
as_mutable_ref
;
using
detail
::
as_mutable_ref
;
fnv
f
;
fnv
f
;
auto
unused
=
f
.
apply_objects
(
xs
...);
auto
unused
=
(
f
.
apply
(
xs
)
&&
...);
static_cast
<
void
>
(
unused
);
// Always true.
static_cast
<
void
>
(
unused
);
// Always true.
return
f
.
result
;
return
f
.
result
;
}
}
...
...
libcaf_core/caf/hash/sha1.hpp
View file @
8c8fb8be
...
@@ -37,6 +37,9 @@ public:
...
@@ -37,6 +37,9 @@ public:
/// Hash size in bytes.
/// Hash size in bytes.
static
constexpr
size_t
hash_size
=
20
;
static
constexpr
size_t
hash_size
=
20
;
/// Alias to the super types.
using
super
=
save_inspector_base
<
sha1
>
;
/// Array type for storing a 160-bit hash.
/// Array type for storing a 160-bit hash.
using
result_type
=
std
::
array
<
byte
,
hash_size
>
;
using
result_type
=
std
::
array
<
byte
,
hash_size
>
;
...
@@ -152,7 +155,7 @@ public:
...
@@ -152,7 +155,7 @@ public:
static
result_type
compute
(
Ts
&&
...
xs
)
noexcept
{
static
result_type
compute
(
Ts
&&
...
xs
)
noexcept
{
using
detail
::
as_mutable_ref
;
using
detail
::
as_mutable_ref
;
sha1
f
;
sha1
f
;
auto
unused
=
f
.
apply
_objects
(
xs
...);
auto
unused
=
f
.
apply
(
xs
...);
static_cast
<
void
>
(
unused
);
// Always true.
static_cast
<
void
>
(
unused
);
// Always true.
return
f
.
result
();
return
f
.
result
();
}
}
...
...
libcaf_core/caf/inspector_access.hpp
View file @
8c8fb8be
...
@@ -73,137 +73,65 @@ constexpr bool assertion_failed_v = false;
...
@@ -73,137 +73,65 @@ constexpr bool assertion_failed_v = false;
// -- loading ------------------------------------------------------------------
// -- loading ------------------------------------------------------------------
template
<
class
Inspector
,
class
T
>
template
<
class
Inspector
,
class
T
>
bool
load_value
(
Inspector
&
f
,
T
&
x
);
bool
load
(
Inspector
&
f
,
T
&
x
,
inspector_access_type
::
specialization
)
{
return
inspector_access
<
T
>::
apply
(
f
,
x
);
template
<
class
Inspector
,
class
T
>
bool
load_value
(
Inspector
&
f
,
T
&
x
,
inspector_access_type
::
specialization
)
{
return
inspector_access
<
T
>::
apply_value
(
f
,
x
);
}
template
<
class
Inspector
,
class
T
>
bool
load_value
(
Inspector
&
f
,
T
&
x
,
inspector_access_type
::
inspect_value
)
{
return
inspect_value
(
f
,
x
);
}
}
template
<
class
Inspector
,
class
T
>
template
<
class
Inspector
,
class
T
>
bool
load
_value
(
Inspector
&
f
,
T
&
x
,
inspector_access_type
::
inspect
)
{
bool
load
(
Inspector
&
f
,
T
&
x
,
inspector_access_type
::
inspect
)
{
return
inspect
(
f
,
x
);
return
inspect
(
f
,
x
);
}
}
template
<
class
Inspector
,
class
T
>
template
<
class
Inspector
,
class
T
>
bool
load_value
(
Inspector
&
f
,
T
&
x
,
inspector_access_type
::
integral
)
{
bool
load
(
Inspector
&
f
,
T
&
x
,
inspector_access_type
::
builtin
)
{
auto
tmp
=
detail
::
squashed_int_t
<
T
>
{
0
};
if
(
f
.
value
(
tmp
))
{
x
=
static_cast
<
T
>
(
tmp
);
return
true
;
}
return
false
;
}
template
<
class
Inspector
,
class
T
>
bool
load_value
(
Inspector
&
f
,
T
&
x
,
inspector_access_type
::
builtin
)
{
return
f
.
builtin_inspect
(
x
);
}
template
<
class
Inspector
,
class
T
>
bool
load_value
(
Inspector
&
f
,
T
&
x
,
inspector_access_type
::
trivial
)
{
return
f
.
value
(
x
);
return
f
.
value
(
x
);
}
}
template
<
class
Inspector
,
class
T
>
template
<
class
Inspector
,
class
T
>
bool
load_value
(
Inspector
&
f
,
T
&
x
,
inspector_access_type
::
enumeration
)
{
bool
load
(
Inspector
&
f
,
T
&
x
,
inspector_access_type
::
builtin_inspect
)
{
auto
tmp
=
detail
::
squashed_int_t
<
std
::
underlying_type_t
<
T
>>
{
0
};
return
f
.
builtin_inspect
(
x
);
if
(
f
.
value
(
tmp
))
{
x
=
static_cast
<
T
>
(
tmp
);
return
true
;
}
return
false
;
}
}
template
<
class
Inspector
,
class
T
>
template
<
class
Inspector
,
class
T
>
bool
load
_value
(
Inspector
&
f
,
T
&
x
,
inspector_access_type
::
empty
)
{
bool
load
(
Inspector
&
f
,
T
&
x
,
inspector_access_type
::
empty
)
{
return
f
.
object
(
x
).
fields
();
return
f
.
object
(
x
).
fields
();
}
}
template
<
class
Inspector
,
class
T
>
template
<
class
Inspector
,
class
T
>
bool
load
_value
(
Inspector
&
f
,
T
&
,
inspector_access_type
::
unsafe
)
{
bool
load
(
Inspector
&
f
,
T
&
,
inspector_access_type
::
unsafe
)
{
f
.
emplace_error
(
sec
::
unsafe_type
);
f
.
emplace_error
(
sec
::
unsafe_type
);
return
false
;
return
false
;
}
}
template
<
class
Inspector
,
class
T
,
size_t
N
>
template
<
class
Inspector
,
class
T
,
size_t
N
>
bool
load_value
(
Inspector
&
f
,
T
(
&
xs
)[
N
],
inspector_access_type
::
array
)
{
bool
load
(
Inspector
&
f
,
T
(
&
xs
)[
N
],
inspector_access_type
::
tuple
)
{
if
(
!
f
.
begin_tuple
(
N
))
return
f
.
tuple
(
xs
);
return
false
;
for
(
size_t
index
=
0
;
index
<
N
;
++
index
)
if
(
!
load_value
(
f
,
xs
[
index
]))
return
false
;
return
f
.
end_tuple
();
}
template
<
class
Inspector
,
class
T
,
size_t
...
Ns
>
bool
load_tuple
(
Inspector
&
f
,
T
&
xs
,
std
::
index_sequence
<
Ns
...
>
)
{
return
f
.
begin_tuple
(
sizeof
...(
Ns
))
//
&&
(
load_value
(
f
,
get
<
Ns
>
(
xs
))
&&
...)
//
&&
f
.
end_tuple
();
}
}
template
<
class
Inspector
,
class
T
>
template
<
class
Inspector
,
class
T
>
bool
load_value
(
Inspector
&
f
,
T
&
x
,
inspector_access_type
::
tuple
)
{
bool
load
(
Inspector
&
f
,
T
&
xs
,
inspector_access_type
::
tuple
)
{
return
load_tuple
(
f
,
x
,
return
f
.
tuple
(
xs
);
std
::
make_index_sequence
<
std
::
tuple_size
<
T
>::
value
>
{});
}
}
template
<
class
Inspector
,
class
T
>
template
<
class
Inspector
,
class
T
>
bool
load_value
(
Inspector
&
f
,
T
&
x
,
inspector_access_type
::
map
)
{
bool
load
(
Inspector
&
f
,
T
&
x
,
inspector_access_type
::
map
)
{
x
.
clear
();
return
f
.
map
(
x
);
size_t
size
=
0
;
if
(
!
f
.
begin_associative_array
(
size
))
return
false
;
for
(
size_t
i
=
0
;
i
<
size
;
++
i
)
{
auto
key
=
typename
T
::
key_type
{};
auto
val
=
typename
T
::
mapped_type
{};
if
(
!
(
f
.
begin_key_value_pair
()
//
&&
load_value
(
f
,
key
)
//
&&
load_value
(
f
,
val
)
//
&&
f
.
end_key_value_pair
()))
return
false
;
// A multimap returns an iterator, a regular map returns a pair.
auto
emplace_result
=
x
.
emplace
(
std
::
move
(
key
),
std
::
move
(
val
));
if
constexpr
(
is_pair
<
decltype
(
emplace_result
)
>::
value
)
{
if
(
!
emplace_result
.
second
)
{
f
.
emplace_error
(
sec
::
runtime_error
,
"multiple key definitions"
);
return
false
;
}
}
}
return
f
.
end_associative_array
();
}
}
template
<
class
Inspector
,
class
T
>
template
<
class
Inspector
,
class
T
>
bool
load_value
(
Inspector
&
f
,
T
&
x
,
inspector_access_type
::
list
)
{
bool
load
(
Inspector
&
f
,
T
&
x
,
inspector_access_type
::
list
)
{
x
.
clear
();
return
f
.
list
(
x
);
size_t
size
=
0
;
if
(
!
f
.
begin_sequence
(
size
))
return
false
;
for
(
size_t
i
=
0
;
i
<
size
;
++
i
)
{
auto
val
=
typename
T
::
value_type
{};
if
(
!
detail
::
load_value
(
f
,
val
))
return
false
;
x
.
insert
(
x
.
end
(),
std
::
move
(
val
));
}
return
f
.
end_sequence
();
}
}
template
<
class
Inspector
,
class
T
>
template
<
class
Inspector
,
class
T
>
std
::
enable_if_t
<
accepts_opaque_value
<
Inspector
,
T
>::
value
,
bool
>
std
::
enable_if_t
<
accepts_opaque_value
<
Inspector
,
T
>::
value
,
bool
>
load
_value
(
Inspector
&
f
,
T
&
x
,
inspector_access_type
::
none
)
{
load
(
Inspector
&
f
,
T
&
x
,
inspector_access_type
::
none
)
{
return
f
.
opaque_value
(
x
);
return
f
.
opaque_value
(
x
);
}
}
template
<
class
Inspector
,
class
T
>
template
<
class
Inspector
,
class
T
>
std
::
enable_if_t
<!
accepts_opaque_value
<
Inspector
,
T
>::
value
,
bool
>
std
::
enable_if_t
<!
accepts_opaque_value
<
Inspector
,
T
>::
value
,
bool
>
load
_value
(
Inspector
&
,
T
&
,
inspector_access_type
::
none
)
{
load
(
Inspector
&
,
T
&
,
inspector_access_type
::
none
)
{
static_assert
(
static_assert
(
detail
::
assertion_failed_v
<
T
>
,
detail
::
assertion_failed_v
<
T
>
,
"please provide an inspect overload for T or specialize inspector_access"
);
"please provide an inspect overload for T or specialize inspector_access"
);
...
@@ -211,28 +139,8 @@ load_value(Inspector&, T&, inspector_access_type::none) {
...
@@ -211,28 +139,8 @@ load_value(Inspector&, T&, inspector_access_type::none) {
}
}
template
<
class
Inspector
,
class
T
>
template
<
class
Inspector
,
class
T
>
bool
load_value
(
Inspector
&
f
,
T
&
x
)
{
bool
load
(
Inspector
&
f
,
T
&
x
)
{
return
load_value
(
f
,
x
,
inspect_value_access_type
<
Inspector
,
T
>
());
return
load
(
f
,
x
,
inspect_access_type
<
Inspector
,
T
>
());
}
template
<
class
Inspector
,
class
T
>
bool
load_object
(
Inspector
&
f
,
T
&
x
,
inspector_access_type
::
specialization
)
{
return
inspector_access
<
T
>::
apply_object
(
f
,
x
);
}
template
<
class
Inspector
,
class
T
>
bool
load_object
(
Inspector
&
f
,
T
&
x
,
inspector_access_type
::
inspect
)
{
return
inspect
(
f
,
x
);
}
template
<
class
Inspector
,
class
T
,
class
Token
>
bool
load_object
(
Inspector
&
f
,
T
&
x
,
Token
)
{
return
f
.
object
(
x
).
fields
(
f
.
field
(
"value"
,
x
));
}
template
<
class
Inspector
,
class
T
>
bool
load_object
(
Inspector
&
f
,
T
&
x
)
{
return
load_object
(
f
,
x
,
inspect_object_access_type
<
Inspector
,
T
>
());
}
}
template
<
class
Inspector
,
class
T
,
class
IsValid
,
class
SyncValue
>
template
<
class
Inspector
,
class
T
,
class
IsValid
,
class
SyncValue
>
...
@@ -257,116 +165,65 @@ bool load_field(Inspector& f, string_view field_name, T& x, IsValid& is_valid,
...
@@ -257,116 +165,65 @@ bool load_field(Inspector& f, string_view field_name, T& x, IsValid& is_valid,
// -- saving -------------------------------------------------------------------
// -- saving -------------------------------------------------------------------
template
<
class
Inspector
,
class
T
>
template
<
class
Inspector
,
class
T
>
bool
save_value
(
Inspector
&
f
,
T
&
x
);
bool
save
(
Inspector
&
f
,
T
&
x
,
inspector_access_type
::
specialization
)
{
return
inspector_access
<
T
>::
apply
(
f
,
x
);
template
<
class
Inspector
,
class
T
>
bool
save_value
(
Inspector
&
f
,
const
T
&
x
);
template
<
class
Inspector
,
class
T
>
bool
save_value
(
Inspector
&
f
,
T
&
x
,
inspector_access_type
::
specialization
)
{
return
inspector_access
<
T
>::
apply_value
(
f
,
x
);
}
}
template
<
class
Inspector
,
class
T
>
template
<
class
Inspector
,
class
T
>
bool
save_value
(
Inspector
&
f
,
T
&
x
,
inspector_access_type
::
inspect_value
)
{
bool
save
(
Inspector
&
f
,
T
&
x
,
inspector_access_type
::
inspect
)
{
return
inspect_value
(
f
,
x
);
}
template
<
class
Inspector
,
class
T
>
bool
save_value
(
Inspector
&
f
,
T
&
x
,
inspector_access_type
::
inspect
)
{
return
inspect
(
f
,
x
);
return
inspect
(
f
,
x
);
}
}
template
<
class
Inspector
,
class
T
>
template
<
class
Inspector
,
class
T
>
bool
save_value
(
Inspector
&
f
,
T
&
x
,
inspector_access_type
::
integral
)
{
bool
save
(
Inspector
&
f
,
T
&
x
,
inspector_access_type
::
builtin
)
{
auto
tmp
=
static_cast
<
detail
::
squashed_int_t
<
T
>>
(
x
);
return
f
.
value
(
tmp
);
}
template
<
class
Inspector
,
class
T
>
bool
save_value
(
Inspector
&
f
,
T
&
x
,
inspector_access_type
::
builtin
)
{
return
f
.
builtin_inspect
(
x
);
}
template
<
class
Inspector
,
class
T
>
bool
save_value
(
Inspector
&
f
,
T
&
x
,
inspector_access_type
::
trivial
)
{
return
f
.
value
(
x
);
return
f
.
value
(
x
);
}
}
template
<
class
Inspector
,
class
T
>
template
<
class
Inspector
,
class
T
>
bool
save_value
(
Inspector
&
f
,
T
&
x
,
inspector_access_type
::
enumeration
)
{
bool
save
(
Inspector
&
f
,
T
&
x
,
inspector_access_type
::
builtin_inspect
)
{
auto
tmp
=
static_cast
<
detail
::
squashed_int_t
<
std
::
underlying_type_t
<
T
>>>
(
x
);
return
f
.
builtin_inspect
(
x
);
return
f
.
value
(
tmp
);
}
}
template
<
class
Inspector
,
class
T
>
template
<
class
Inspector
,
class
T
>
bool
save
_value
(
Inspector
&
f
,
T
&
x
,
inspector_access_type
::
empty
)
{
bool
save
(
Inspector
&
f
,
T
&
x
,
inspector_access_type
::
empty
)
{
return
f
.
object
(
x
).
fields
();
return
f
.
object
(
x
).
fields
();
}
}
template
<
class
Inspector
,
class
T
>
template
<
class
Inspector
,
class
T
>
bool
save
_value
(
Inspector
&
f
,
T
&
,
inspector_access_type
::
unsafe
)
{
bool
save
(
Inspector
&
f
,
T
&
,
inspector_access_type
::
unsafe
)
{
f
.
emplace_error
(
sec
::
unsafe_type
);
f
.
emplace_error
(
sec
::
unsafe_type
);
return
false
;
return
false
;
}
}
template
<
class
Inspector
,
class
T
,
size_t
N
>
template
<
class
Inspector
,
class
T
,
size_t
N
>
bool
save_value
(
Inspector
&
f
,
T
(
&
xs
)[
N
],
inspector_access_type
::
array
)
{
bool
save
(
Inspector
&
f
,
T
(
&
xs
)[
N
],
inspector_access_type
::
tuple
)
{
if
(
!
f
.
begin_tuple
(
N
))
return
f
.
tuple
(
xs
);
return
false
;
for
(
size_t
index
=
0
;
index
<
N
;
++
index
)
if
(
!
save_value
(
f
,
xs
[
index
]))
return
false
;
return
f
.
end_tuple
();
}
template
<
class
Inspector
,
class
T
,
size_t
...
Ns
>
bool
save_tuple
(
Inspector
&
f
,
T
&
xs
,
std
::
index_sequence
<
Ns
...
>
)
{
return
f
.
begin_tuple
(
sizeof
...(
Ns
))
//
&&
(
save_value
(
f
,
get
<
Ns
>
(
xs
))
&&
...)
//
&&
f
.
end_tuple
();
}
}
template
<
class
Inspector
,
class
T
>
template
<
class
Inspector
,
class
T
>
bool
save_value
(
Inspector
&
f
,
T
&
x
,
inspector_access_type
::
tuple
)
{
bool
save
(
Inspector
&
f
,
const
T
&
xs
,
inspector_access_type
::
tuple
)
{
return
save_tuple
(
f
,
x
,
return
f
.
tuple
(
xs
);
std
::
make_index_sequence
<
std
::
tuple_size
<
T
>::
value
>
{});
}
}
template
<
class
Inspector
,
class
T
>
template
<
class
Inspector
,
class
T
>
bool
save_value
(
Inspector
&
f
,
T
&
x
,
inspector_access_type
::
map
)
{
bool
save
(
Inspector
&
f
,
T
&
x
,
inspector_access_type
::
map
)
{
if
(
!
f
.
begin_associative_array
(
x
.
size
()))
return
f
.
map
(
x
);
return
false
;
for
(
auto
&&
kvp
:
x
)
{
if
(
!
(
f
.
begin_key_value_pair
()
//
&&
save_value
(
f
,
kvp
.
first
)
//
&&
save_value
(
f
,
kvp
.
second
)
//
&&
f
.
end_key_value_pair
()))
return
false
;
}
return
f
.
end_associative_array
();
}
}
template
<
class
Inspector
,
class
T
>
template
<
class
Inspector
,
class
T
>
bool
save_value
(
Inspector
&
f
,
T
&
x
,
inspector_access_type
::
list
)
{
bool
save
(
Inspector
&
f
,
T
&
x
,
inspector_access_type
::
list
)
{
auto
size
=
x
.
size
();
return
f
.
list
(
x
);
if
(
!
f
.
begin_sequence
(
size
))
return
false
;
for
(
auto
&&
val
:
x
)
if
(
!
save_value
(
f
,
val
))
return
false
;
return
f
.
end_sequence
();
}
}
template
<
class
Inspector
,
class
T
>
template
<
class
Inspector
,
class
T
>
std
::
enable_if_t
<
accepts_opaque_value
<
Inspector
,
T
>::
value
,
bool
>
std
::
enable_if_t
<
accepts_opaque_value
<
Inspector
,
T
>::
value
,
bool
>
save
_value
(
Inspector
&
f
,
T
&
x
,
inspector_access_type
::
none
)
{
save
(
Inspector
&
f
,
T
&
x
,
inspector_access_type
::
none
)
{
return
f
.
opaque_value
(
x
);
return
f
.
opaque_value
(
x
);
}
}
template
<
class
Inspector
,
class
T
>
template
<
class
Inspector
,
class
T
>
std
::
enable_if_t
<!
accepts_opaque_value
<
Inspector
,
T
>::
value
,
bool
>
std
::
enable_if_t
<!
accepts_opaque_value
<
Inspector
,
T
>::
value
,
bool
>
save
_value
(
Inspector
&
,
T
&
,
inspector_access_type
::
none
)
{
save
(
Inspector
&
,
T
&
,
inspector_access_type
::
none
)
{
static_assert
(
static_assert
(
detail
::
assertion_failed_v
<
T
>
,
detail
::
assertion_failed_v
<
T
>
,
"please provide an inspect overload for T or specialize inspector_access"
);
"please provide an inspect overload for T or specialize inspector_access"
);
...
@@ -374,34 +231,13 @@ save_value(Inspector&, T&, inspector_access_type::none) {
...
@@ -374,34 +231,13 @@ save_value(Inspector&, T&, inspector_access_type::none) {
}
}
template
<
class
Inspector
,
class
T
>
template
<
class
Inspector
,
class
T
>
bool
save
_value
(
Inspector
&
f
,
T
&
x
)
{
bool
save
(
Inspector
&
f
,
T
&
x
)
{
return
save
_value
(
f
,
x
,
inspect_value
_access_type
<
Inspector
,
T
>
());
return
save
(
f
,
x
,
inspect
_access_type
<
Inspector
,
T
>
());
}
}
template
<
class
Inspector
,
class
T
>
template
<
class
Inspector
,
class
T
>
bool
save_value
(
Inspector
&
f
,
const
T
&
x
)
{
bool
save
(
Inspector
&
f
,
const
T
&
x
)
{
return
save_value
(
f
,
as_mutable_ref
(
x
),
return
save
(
f
,
as_mutable_ref
(
x
),
inspect_access_type
<
Inspector
,
T
>
());
inspect_value_access_type
<
Inspector
,
T
>
());
}
template
<
class
Inspector
,
class
T
>
bool
save_object
(
Inspector
&
f
,
T
&
x
,
inspector_access_type
::
specialization
)
{
return
inspector_access
<
T
>::
apply_object
(
f
,
x
);
}
template
<
class
Inspector
,
class
T
>
bool
save_object
(
Inspector
&
f
,
T
&
x
,
inspector_access_type
::
inspect
)
{
return
inspect
(
f
,
x
);
}
template
<
class
Inspector
,
class
T
,
class
Token
>
bool
save_object
(
Inspector
&
f
,
T
&
x
,
Token
)
{
return
f
.
object
(
x
).
fields
(
f
.
field
(
"value"
,
x
));
}
template
<
class
Inspector
,
class
T
>
bool
save_object
(
Inspector
&
f
,
T
&
x
)
{
return
save_object
(
f
,
x
,
inspect_object_access_type
<
Inspector
,
T
>
());
}
}
template
<
class
Inspector
,
class
T
>
template
<
class
Inspector
,
class
T
>
...
@@ -422,77 +258,13 @@ bool save_field(Inspector& f, string_view field_name, IsPresent& is_present,
...
@@ -422,77 +258,13 @@ bool save_field(Inspector& f, string_view field_name, IsPresent& is_present,
return
impl
::
save_field
(
f
,
field_name
,
is_present
,
get
);
return
impl
::
save_field
(
f
,
field_name
,
is_present
,
get
);
}
}
// -- dispatching to save or load using getter/setter API ----------------------
template
<
class
Inspector
,
class
T
>
bool
split_save_load
(
Inspector
&
f
,
T
&
x
)
{
if
constexpr
(
Inspector
::
is_loading
)
return
load_value
(
f
,
x
);
else
return
save_value
(
f
,
x
);
}
template
<
class
Inspector
,
class
Get
,
class
Set
>
bool
split_save_load
(
Inspector
&
f
,
Get
&&
get
,
Set
&&
set
)
{
using
value_type
=
std
::
decay_t
<
decltype
(
get
())
>
;
if
constexpr
(
Inspector
::
is_loading
)
{
auto
tmp
=
value_type
{};
if
(
load_value
(
f
,
tmp
))
return
set
(
std
::
move
(
tmp
));
return
false
;
}
else
{
auto
&&
x
=
get
();
return
save_value
(
f
,
x
);
}
}
}
// namespace caf::detail
}
// namespace caf::detail
namespace
caf
{
namespace
caf
{
/// Default implementation for @ref inspector_access.
// -- customization points -----------------------------------------------------
template
<
class
T
>
struct
default_inspector_access
:
inspector_access_base
<
T
>
{
// -- interface functions ----------------------------------------------------
/// Applies `x` as an object to `f`.
/// Customization point for adding support for a custom type.
template
<
class
Inspector
>
[[
nodiscard
]]
static
bool
apply_object
(
Inspector
&
f
,
T
&
x
)
{
// Dispatch to user-provided `inspect` overload or assume a trivial type.
if
constexpr
(
std
::
is_empty
<
T
>::
value
)
{
return
f
.
object
(
x
).
fields
();
}
else
{
return
f
.
object
(
x
).
fields
(
f
.
field
(
"value"
,
x
));
}
}
/// Applies `x` as a single value to `f`.
template
<
class
Inspector
>
[[
nodiscard
]]
static
bool
apply_value
(
Inspector
&
f
,
T
&
x
)
{
constexpr
auto
token
=
nested_inspect_value_access_type
<
Inspector
,
T
>
();
if
constexpr
(
Inspector
::
is_loading
)
return
detail
::
load_value
(
f
,
x
,
token
);
else
return
detail
::
save_value
(
f
,
x
,
token
);
}
// -- deprecated API ---------------------------------------------------------
template
<
class
Inspector
>
[[
deprecated
(
"inspect() overloads should return bool"
)]]
//
[[
nodiscard
]]
static
bool
apply_deprecated
(
Inspector
&
f
,
T
&
x
)
{
if
(
auto
err
=
inspect
(
f
,
x
))
{
f
.
emplace_error
(
std
::
move
(
err
));
return
false
;
}
return
true
;
}
};
/// Customization point for adding support for a custom type. The default
/// implementation requires an `inspect` overload for `T` that is available via
/// ADL.
template
<
class
T
>
template
<
class
T
>
struct
inspector_access
;
struct
inspector_access
;
...
@@ -559,15 +331,10 @@ struct optional_inspector_access {
...
@@ -559,15 +331,10 @@ struct optional_inspector_access {
using
value_type
=
typename
traits
::
value_type
;
using
value_type
=
typename
traits
::
value_type
;
template
<
class
Inspector
>
template
<
class
Inspector
>
[[
nodiscard
]]
static
bool
apply
_object
(
Inspector
&
f
,
container_type
&
x
)
{
[[
nodiscard
]]
static
bool
apply
(
Inspector
&
f
,
container_type
&
x
)
{
return
f
.
object
(
x
).
fields
(
f
.
field
(
"value"
,
x
));
return
f
.
object
(
x
).
fields
(
f
.
field
(
"value"
,
x
));
}
}
template
<
class
Inspector
>
[[
nodiscard
]]
static
bool
apply_value
(
Inspector
&
f
,
container_type
&
x
)
{
return
apply_object
(
f
,
x
);
}
template
<
class
Inspector
>
template
<
class
Inspector
>
static
bool
static
bool
save_field
(
Inspector
&
f
,
string_view
field_name
,
container_type
&
x
)
{
save_field
(
Inspector
&
f
,
string_view
field_name
,
container_type
&
x
)
{
...
@@ -696,18 +463,13 @@ struct variant_inspector_access {
...
@@ -696,18 +463,13 @@ struct variant_inspector_access {
using
traits
=
variant_inspector_traits
<
T
>
;
using
traits
=
variant_inspector_traits
<
T
>
;
template
<
class
Inspector
>
template
<
class
Inspector
>
[[
nodiscard
]]
static
bool
apply
_object
(
Inspector
&
f
,
value_type
&
x
)
{
[[
nodiscard
]]
static
bool
apply
(
Inspector
&
f
,
value_type
&
x
)
{
return
f
.
object
(
x
).
fields
(
f
.
field
(
"value"
,
x
));
return
f
.
object
(
x
).
fields
(
f
.
field
(
"value"
,
x
));
}
}
template
<
class
Inspector
>
[[
nodiscard
]]
static
bool
apply_value
(
Inspector
&
f
,
value_type
&
x
)
{
return
apply_object
(
f
,
x
);
}
template
<
class
Inspector
>
template
<
class
Inspector
>
static
bool
save_field
(
Inspector
&
f
,
string_view
field_name
,
value_type
&
x
)
{
static
bool
save_field
(
Inspector
&
f
,
string_view
field_name
,
value_type
&
x
)
{
auto
g
=
[
&
f
](
auto
&
y
)
{
return
detail
::
save
_value
(
f
,
y
);
};
auto
g
=
[
&
f
](
auto
&
y
)
{
return
detail
::
save
(
f
,
y
);
};
return
f
.
begin_field
(
field_name
,
make_span
(
traits
::
allowed_types
),
return
f
.
begin_field
(
field_name
,
make_span
(
traits
::
allowed_types
),
traits
::
type_index
(
x
))
//
traits
::
type_index
(
x
))
//
&&
traits
::
visit
(
g
,
x
)
//
&&
traits
::
visit
(
g
,
x
)
//
...
@@ -720,7 +482,7 @@ struct variant_inspector_access {
...
@@ -720,7 +482,7 @@ struct variant_inspector_access {
auto
allowed_types
=
make_span
(
traits
::
allowed_types
);
auto
allowed_types
=
make_span
(
traits
::
allowed_types
);
if
(
is_present
())
{
if
(
is_present
())
{
auto
&&
x
=
get
();
auto
&&
x
=
get
();
auto
g
=
[
&
f
](
auto
&
y
)
{
return
detail
::
save
_value
(
f
,
y
);
};
auto
g
=
[
&
f
](
auto
&
y
)
{
return
detail
::
save
(
f
,
y
);
};
return
f
.
begin_field
(
field_name
,
true
,
allowed_types
,
return
f
.
begin_field
(
field_name
,
true
,
allowed_types
,
traits
::
type_index
(
x
))
//
traits
::
type_index
(
x
))
//
&&
traits
::
visit
(
g
,
x
)
//
&&
traits
::
visit
(
g
,
x
)
//
...
@@ -735,7 +497,7 @@ struct variant_inspector_access {
...
@@ -735,7 +497,7 @@ struct variant_inspector_access {
value_type
&
x
,
type_id_t
runtime_type
)
{
value_type
&
x
,
type_id_t
runtime_type
)
{
auto
res
=
false
;
auto
res
=
false
;
auto
type_found
=
traits
::
load
(
runtime_type
,
[
&
](
auto
&
tmp
)
{
auto
type_found
=
traits
::
load
(
runtime_type
,
[
&
](
auto
&
tmp
)
{
if
(
!
detail
::
load
_value
(
f
,
tmp
))
if
(
!
detail
::
load
(
f
,
tmp
))
return
;
return
;
traits
::
assign
(
x
,
std
::
move
(
tmp
));
traits
::
assign
(
x
,
std
::
move
(
tmp
));
res
=
true
;
res
=
true
;
...
@@ -876,12 +638,7 @@ struct inspector_access<std::chrono::duration<Rep, Period>>
...
@@ -876,12 +638,7 @@ struct inspector_access<std::chrono::duration<Rep, Period>>
using
value_type
=
std
::
chrono
::
duration
<
Rep
,
Period
>
;
using
value_type
=
std
::
chrono
::
duration
<
Rep
,
Period
>
;
template
<
class
Inspector
>
template
<
class
Inspector
>
static
bool
apply_object
(
Inspector
&
f
,
value_type
&
x
)
{
static
bool
apply
(
Inspector
&
f
,
value_type
&
x
)
{
return
f
.
object
(
x
).
fields
(
f
.
field
(
"value"
,
x
));
}
template
<
class
Inspector
>
static
bool
apply_value
(
Inspector
&
f
,
value_type
&
x
)
{
if
(
f
.
has_human_readable_format
())
{
if
(
f
.
has_human_readable_format
())
{
auto
get
=
[
&
x
]
{
auto
get
=
[
&
x
]
{
std
::
string
str
;
std
::
string
str
;
...
@@ -892,14 +649,15 @@ struct inspector_access<std::chrono::duration<Rep, Period>>
...
@@ -892,14 +649,15 @@ struct inspector_access<std::chrono::duration<Rep, Period>>
auto
err
=
detail
::
parse
(
str
,
x
);
auto
err
=
detail
::
parse
(
str
,
x
);
return
!
err
;
return
!
err
;
};
};
return
detail
::
split_save_load
(
f
,
get
,
set
);
return
f
.
apply
(
get
,
set
);
}
}
else
{
auto
get
=
[
&
x
]
{
return
x
.
count
();
};
auto
get
=
[
&
x
]
{
return
x
.
count
();
};
auto
set
=
[
&
x
](
Rep
value
)
{
auto
set
=
[
&
x
](
Rep
value
)
{
x
=
std
::
chrono
::
duration
<
Rep
,
Period
>
{
value
};
x
=
std
::
chrono
::
duration
<
Rep
,
Period
>
{
value
};
return
true
;
return
true
;
};
};
return
detail
::
split_save_load
(
f
,
get
,
set
);
return
f
.
apply
(
get
,
set
);
}
}
}
};
};
...
@@ -912,12 +670,7 @@ struct inspector_access<
...
@@ -912,12 +670,7 @@ struct inspector_access<
=
std
::
chrono
::
time_point
<
std
::
chrono
::
system_clock
,
Duration
>
;
=
std
::
chrono
::
time_point
<
std
::
chrono
::
system_clock
,
Duration
>
;
template
<
class
Inspector
>
template
<
class
Inspector
>
static
bool
apply_object
(
Inspector
&
f
,
value_type
&
x
)
{
static
bool
apply
(
Inspector
&
f
,
value_type
&
x
)
{
return
f
.
object
(
x
).
fields
(
f
.
field
(
"value"
,
x
));
}
template
<
class
Inspector
>
static
bool
apply_value
(
Inspector
&
f
,
value_type
&
x
)
{
if
(
f
.
has_human_readable_format
())
{
if
(
f
.
has_human_readable_format
())
{
auto
get
=
[
&
x
]
{
auto
get
=
[
&
x
]
{
std
::
string
str
;
std
::
string
str
;
...
@@ -928,15 +681,16 @@ struct inspector_access<
...
@@ -928,15 +681,16 @@ struct inspector_access<
auto
err
=
detail
::
parse
(
str
,
x
);
auto
err
=
detail
::
parse
(
str
,
x
);
return
!
err
;
return
!
err
;
};
};
return
detail
::
split_save_load
(
f
,
get
,
set
);
return
f
.
apply
(
get
,
set
);
}
}
else
{
using
rep_type
=
typename
Duration
::
rep
;
using
rep_type
=
typename
Duration
::
rep
;
auto
get
=
[
&
x
]
{
return
x
.
time_since_epoch
().
count
();
};
auto
get
=
[
&
x
]
{
return
x
.
time_since_epoch
().
count
();
};
auto
set
=
[
&
x
](
rep_type
value
)
{
auto
set
=
[
&
x
](
rep_type
value
)
{
x
=
value_type
{
Duration
{
value
}};
x
=
value_type
{
Duration
{
value
}};
return
true
;
return
true
;
};
};
return
detail
::
split_save_load
(
f
,
get
,
set
);
return
f
.
apply
(
get
,
set
);
}
}
}
};
};
...
...
libcaf_core/caf/inspector_access_base.hpp
View file @
8c8fb8be
...
@@ -32,7 +32,7 @@ struct inspector_access_base {
...
@@ -32,7 +32,7 @@ struct inspector_access_base {
template
<
class
Inspector
,
class
IsValid
,
class
SyncValue
>
template
<
class
Inspector
,
class
IsValid
,
class
SyncValue
>
static
bool
load_field
(
Inspector
&
f
,
string_view
field_name
,
T
&
x
,
static
bool
load_field
(
Inspector
&
f
,
string_view
field_name
,
T
&
x
,
IsValid
&
is_valid
,
SyncValue
&
sync_value
)
{
IsValid
&
is_valid
,
SyncValue
&
sync_value
)
{
if
(
f
.
begin_field
(
field_name
)
&&
f
.
apply
_value
(
x
))
{
if
(
f
.
begin_field
(
field_name
)
&&
f
.
apply
(
x
))
{
if
(
!
is_valid
(
x
))
{
if
(
!
is_valid
(
x
))
{
f
.
emplace_error
(
sec
::
field_invariant_check_failed
,
f
.
emplace_error
(
sec
::
field_invariant_check_failed
,
to_string
(
field_name
));
to_string
(
field_name
));
...
@@ -58,7 +58,7 @@ struct inspector_access_base {
...
@@ -58,7 +58,7 @@ struct inspector_access_base {
if
(
!
f
.
begin_field
(
field_name
,
is_present
))
if
(
!
f
.
begin_field
(
field_name
,
is_present
))
return
false
;
return
false
;
if
(
is_present
)
{
if
(
is_present
)
{
if
(
!
f
.
apply
_value
(
x
))
if
(
!
f
.
apply
(
x
))
return
false
;
return
false
;
if
(
!
is_valid
(
x
))
{
if
(
!
is_valid
(
x
))
{
f
.
emplace_error
(
sec
::
field_invariant_check_failed
,
f
.
emplace_error
(
sec
::
field_invariant_check_failed
,
...
@@ -80,7 +80,7 @@ struct inspector_access_base {
...
@@ -80,7 +80,7 @@ struct inspector_access_base {
template
<
class
Inspector
>
template
<
class
Inspector
>
static
bool
save_field
(
Inspector
&
f
,
string_view
field_name
,
T
&
x
)
{
static
bool
save_field
(
Inspector
&
f
,
string_view
field_name
,
T
&
x
)
{
return
f
.
begin_field
(
field_name
)
//
return
f
.
begin_field
(
field_name
)
//
&&
f
.
apply
_value
(
x
)
//
&&
f
.
apply
(
x
)
//
&&
f
.
end_field
();
&&
f
.
end_field
();
}
}
...
@@ -91,7 +91,7 @@ struct inspector_access_base {
...
@@ -91,7 +91,7 @@ struct inspector_access_base {
if
(
is_present
())
{
if
(
is_present
())
{
auto
&&
x
=
get
();
auto
&&
x
=
get
();
return
f
.
begin_field
(
field_name
,
true
)
//
return
f
.
begin_field
(
field_name
,
true
)
//
&&
f
.
apply
_value
(
x
)
//
&&
f
.
apply
(
x
)
//
&&
f
.
end_field
();
&&
f
.
end_field
();
}
}
return
f
.
begin_field
(
field_name
,
false
)
&&
f
.
end_field
();
return
f
.
begin_field
(
field_name
,
false
)
&&
f
.
end_field
();
...
...
libcaf_core/caf/inspector_access_type.hpp
View file @
8c8fb8be
...
@@ -35,23 +35,14 @@ struct inspector_access_type {
...
@@ -35,23 +35,14 @@ struct inspector_access_type {
/// Flags types that provide an `inspector_access` specialization.
/// Flags types that provide an `inspector_access` specialization.
struct
specialization
{};
struct
specialization
{};
/// Flags types that provide an `inspect_value()` overload.
struct
inspect_value
{};
/// Flags types that provide an `inspect()` overload.
/// Flags types that provide an `inspect()` overload.
struct
inspect
{};
struct
inspect
{};
/// Flags builtin integral types.
/// Flags types with builtin support of the inspection API.
struct
integral
{};
/// Flags types with builtin support via `Inspector::builtin_inspect`.
struct
builtin
{};
struct
builtin
{};
/// Flags types with builtin support via `Inspector::value`.
/// Flags types with builtin support via `Inspector::builtin_inspect`.
struct
trivial
{};
struct
builtin_inspect
{};
/// Flags `enum` types.
struct
enumeration
{};
/// Flags stateless message types.
/// Flags stateless message types.
struct
empty
{};
struct
empty
{};
...
@@ -59,15 +50,9 @@ struct inspector_access_type {
...
@@ -59,15 +50,9 @@ struct inspector_access_type {
/// Flags allowed unsafe message types.
/// Flags allowed unsafe message types.
struct
unsafe
{};
struct
unsafe
{};
/// Flags native C array types.
struct
array
{};
/// Flags types with `std::tuple`-like API.
/// Flags types with `std::tuple`-like API.
struct
tuple
{};
struct
tuple
{};
/// Flags type that specialize `inspector_access_boxed_value_traits`.
struct
boxed_value
{};
/// Flags types with `std::map`-like API.
/// Flags types with `std::map`-like API.
struct
map
{};
struct
map
{};
...
@@ -80,98 +65,23 @@ struct inspector_access_type {
...
@@ -80,98 +65,23 @@ struct inspector_access_type {
/// @relates inspector_access_type
/// @relates inspector_access_type
template
<
class
Inspector
,
class
T
>
template
<
class
Inspector
,
class
T
>
constexpr
auto
inspect_
object_
access_type
()
{
constexpr
auto
inspect_access_type
()
{
using
namespace
detail
;
using
namespace
detail
;
// Order: unsafe (error) > C Array > builtin
_inspect > inspector_access >
// Order: unsafe (error) > C Array > builtin
> builtin_inspect
// inspect > trivial > defaults.
//
> inspector_access >
inspect > trivial > defaults.
if
constexpr
(
is_allowed_unsafe_message_type_v
<
T
>
)
if
constexpr
(
is_allowed_unsafe_message_type_v
<
T
>
)
return
inspector_access_type
::
unsafe
{};
return
inspector_access_type
::
unsafe
{};
else
if
constexpr
(
std
::
is_array
<
T
>::
value
)
else
if
constexpr
(
std
::
is_array
<
T
>::
value
)
return
inspector_access_type
::
array
{};
else
if
constexpr
(
has_builtin_inspect
<
Inspector
,
T
>::
value
)
return
inspector_access_type
::
builtin
{};
else
if
constexpr
(
detail
::
is_complete
<
inspector_access
<
T
>>
)
return
inspector_access_type
::
specialization
{};
else
if
constexpr
(
has_inspect_overload
<
Inspector
,
T
>::
value
)
return
inspector_access_type
::
inspect
{};
else
if
constexpr
(
is_trivial_inspector_value_v
<
Inspector
::
is_loading
,
T
>
)
return
inspector_access_type
::
trivial
{};
else
if
constexpr
(
std
::
is_integral
<
T
>::
value
)
return
inspector_access_type
::
integral
{};
else
if
constexpr
(
std
::
is_enum
<
T
>::
value
)
return
inspector_access_type
::
enumeration
{};
else
if
constexpr
(
std
::
is_empty
<
T
>::
value
)
return
inspector_access_type
::
empty
{};
else
if
constexpr
(
is_stl_tuple_type_v
<
T
>
)
return
inspector_access_type
::
tuple
{};
return
inspector_access_type
::
tuple
{};
else
if
constexpr
(
is_map_like_v
<
T
>
)
else
if
constexpr
(
detail
::
is_builtin_inspector_type
<
return
inspector_access_type
::
map
{};
T
,
Inspector
::
is_loading
>::
value
)
else
if
constexpr
(
is_list_like_v
<
T
>
)
return
inspector_access_type
::
list
{};
else
return
inspector_access_type
::
none
{};
}
/// @relates inspector_access_type
template
<
class
Inspector
,
class
T
>
constexpr
auto
inspect_value_access_type
()
{
// Order: unsafe (error) > C Array > builtin_inspect > inspector_access >
// inspect_value > inspect > defaults.
// This is the same as in inspect_object_access_type, except that we pick up
// inspect_value overloads.
using
namespace
detail
;
if
constexpr
(
is_allowed_unsafe_message_type_v
<
T
>
)
return
inspector_access_type
::
unsafe
{};
else
if
constexpr
(
std
::
is_array
<
T
>::
value
)
return
inspector_access_type
::
array
{};
else
if
constexpr
(
has_builtin_inspect
<
Inspector
,
T
>::
value
)
return
inspector_access_type
::
builtin
{};
return
inspector_access_type
::
builtin
{};
else
if
constexpr
(
has_builtin_inspect
<
Inspector
,
T
>::
value
)
return
inspector_access_type
::
builtin_inspect
{};
else
if
constexpr
(
detail
::
is_complete
<
inspector_access
<
T
>>
)
else
if
constexpr
(
detail
::
is_complete
<
inspector_access
<
T
>>
)
return
inspector_access_type
::
specialization
{};
return
inspector_access_type
::
specialization
{};
else
if
constexpr
(
has_inspect_value_overload
<
Inspector
,
T
>::
value
)
return
inspector_access_type
::
inspect_value
{};
else
if
constexpr
(
has_inspect_overload
<
Inspector
,
T
>::
value
)
else
if
constexpr
(
has_inspect_overload
<
Inspector
,
T
>::
value
)
return
inspector_access_type
::
inspect
{};
return
inspector_access_type
::
inspect
{};
else
if
constexpr
(
is_trivial_inspector_value_v
<
Inspector
::
is_loading
,
T
>
)
return
inspector_access_type
::
trivial
{};
else
if
constexpr
(
std
::
is_integral
<
T
>::
value
)
return
inspector_access_type
::
integral
{};
else
if
constexpr
(
std
::
is_enum
<
T
>::
value
)
return
inspector_access_type
::
enumeration
{};
else
if
constexpr
(
std
::
is_empty
<
T
>::
value
)
return
inspector_access_type
::
empty
{};
else
if
constexpr
(
is_stl_tuple_type_v
<
T
>
)
return
inspector_access_type
::
tuple
{};
else
if
constexpr
(
is_map_like_v
<
T
>
)
return
inspector_access_type
::
map
{};
else
if
constexpr
(
is_list_like_v
<
T
>
)
return
inspector_access_type
::
list
{};
else
return
inspector_access_type
::
none
{};
}
/// Same as `inspect_value_access_type`, but ignores specialization of
/// `inspector_access` as well as `inspect` and `inspect_value` overloads.
/// @relates inspector_access_type
template
<
class
Inspector
,
class
T
>
constexpr
auto
nested_inspect_value_access_type
()
{
// Order: unsafe (error) > C Array > builtin_inspect > inspector_access >
// inspect_value > inspect > defaults.
// This is the same as in inspect_object_access_type, except that we pick up
// inspect_value overloads.
using
namespace
detail
;
if
constexpr
(
is_allowed_unsafe_message_type_v
<
T
>
)
return
inspector_access_type
::
unsafe
{};
else
if
constexpr
(
std
::
is_array
<
T
>::
value
)
return
inspector_access_type
::
array
{};
else
if
constexpr
(
has_builtin_inspect
<
Inspector
,
T
>::
value
)
return
inspector_access_type
::
builtin
{};
else
if
constexpr
(
is_trivial_inspector_value_v
<
Inspector
::
is_loading
,
T
>
)
return
inspector_access_type
::
trivial
{};
else
if
constexpr
(
std
::
is_integral
<
T
>::
value
)
return
inspector_access_type
::
integral
{};
else
if
constexpr
(
std
::
is_enum
<
T
>::
value
)
return
inspector_access_type
::
enumeration
{};
else
if
constexpr
(
std
::
is_empty
<
T
>::
value
)
else
if
constexpr
(
std
::
is_empty
<
T
>::
value
)
return
inspector_access_type
::
empty
{};
return
inspector_access_type
::
empty
{};
else
if
constexpr
(
is_stl_tuple_type_v
<
T
>
)
else
if
constexpr
(
is_stl_tuple_type_v
<
T
>
)
...
...
libcaf_core/caf/load_inspector.hpp
View file @
8c8fb8be
...
@@ -37,17 +37,10 @@ class CAF_CORE_EXPORT load_inspector {
...
@@ -37,17 +37,10 @@ class CAF_CORE_EXPORT load_inspector {
public:
public:
// -- member types -----------------------------------------------------------
// -- member types -----------------------------------------------------------
using
result_type
=
bool
;
using
result_type
[[
deprecated
(
"inspectors always return bool"
)]]
=
bool
;
// -- constants --------------------------------------------------------------
// -- constants --------------------------------------------------------------
/// Convenience constant to indicate success of a processing step.
static
constexpr
bool
ok
=
true
;
/// Convenience constant to indicate that a processing step failed and no
/// further processing steps should take place.
static
constexpr
bool
stop
=
false
;
/// Enables dispatching on the inspector type.
/// Enables dispatching on the inspector type.
static
constexpr
bool
is_loading
=
true
;
static
constexpr
bool
is_loading
=
true
;
...
...
libcaf_core/caf/load_inspector_base.hpp
View file @
8c8fb8be
...
@@ -18,6 +18,10 @@
...
@@ -18,6 +18,10 @@
#pragma once
#pragma once
#include <array>
#include <tuple>
#include <utility>
#include "caf/inspector_access.hpp"
#include "caf/inspector_access.hpp"
#include "caf/load_inspector.hpp"
#include "caf/load_inspector.hpp"
...
@@ -37,36 +41,132 @@ public:
...
@@ -37,36 +41,132 @@ public:
return
super
::
object_t
<
Subtype
>
{
type_name_or_anonymous
<
T
>
(),
dptr
()};
return
super
::
object_t
<
Subtype
>
{
type_name_or_anonymous
<
T
>
(),
dptr
()};
}
}
// -- dispatching to load/load functions -------------------------------------
template
<
class
T
>
bool
list
(
T
&
xs
)
{
xs
.
clear
();
auto
size
=
size_t
{
0
};
if
(
!
dref
().
begin_sequence
(
size
))
return
false
;
for
(
size_t
i
=
0
;
i
<
size
;
++
i
)
{
auto
val
=
typename
T
::
value_type
{};
if
(
!
detail
::
load
(
dref
(),
val
))
return
false
;
xs
.
insert
(
xs
.
end
(),
std
::
move
(
val
));
}
return
dref
().
end_sequence
();
}
template
<
class
T
>
template
<
class
T
>
[[
nodiscard
]]
bool
apply_object
(
T
&
x
)
{
bool
map
(
T
&
xs
)
{
static_assert
(
!
std
::
is_const
<
T
>::
value
);
xs
.
clear
();
constexpr
auto
token
=
inspect_object_access_type
<
Subtype
,
T
>
();
auto
size
=
size_t
{
0
};
return
detail
::
load_object
(
dref
(),
x
,
token
);
if
(
!
dref
().
begin_associative_array
(
size
))
return
false
;
for
(
size_t
i
=
0
;
i
<
size
;
++
i
)
{
auto
key
=
typename
T
::
key_type
{};
auto
val
=
typename
T
::
mapped_type
{};
if
(
!
(
dref
().
begin_key_value_pair
()
//
&&
detail
::
load
(
dref
(),
key
)
//
&&
detail
::
load
(
dref
(),
val
)
//
&&
dref
().
end_key_value_pair
()))
return
false
;
// A multimap returns an iterator, a regular map returns a pair.
auto
emplace_result
=
xs
.
emplace
(
std
::
move
(
key
),
std
::
move
(
val
));
if
constexpr
(
detail
::
is_pair
<
decltype
(
emplace_result
)
>::
value
)
{
if
(
!
emplace_result
.
second
)
{
dref
().
emplace_error
(
sec
::
runtime_error
,
"multiple key definitions"
);
return
false
;
}
}
}
return
dref
().
end_associative_array
();
}
}
template
<
class
...
Ts
>
template
<
class
T
,
size_t
...
Is
>
[[
nodiscard
]]
bool
apply_objects
(
Ts
&
...
xs
)
{
bool
tuple
(
T
&
xs
,
std
::
index_sequence
<
Is
...
>
)
{
return
(
apply_object
(
xs
)
&&
...);
return
dref
().
begin_tuple
(
sizeof
...(
Is
))
&&
(
detail
::
load
(
dref
(),
get
<
Is
>
(
xs
))
&&
...)
//
&&
dref
().
end_tuple
();
}
}
template
<
class
T
>
template
<
class
T
>
bool
apply_value
(
T
&
x
)
{
bool
tuple
(
T
&
xs
)
{
return
detail
::
load_value
(
dref
(),
x
);
return
tuple
(
xs
,
std
::
make_index_sequence
<
std
::
tuple_size
<
T
>::
value
>
{}
);
}
}
template
<
class
T
,
size_t
N
>
bool
tuple
(
T
(
&
xs
)[
N
])
{
if
(
!
dref
().
begin_tuple
(
N
))
return
false
;
for
(
size_t
index
=
0
;
index
<
N
;
++
index
)
if
(
!
detail
::
load
(
dref
(),
xs
[
index
]))
return
false
;
return
dref
().
end_tuple
();
}
// -- dispatching to load/load functions -------------------------------------
template
<
class
T
>
[[
nodiscard
]]
bool
apply
(
T
&
x
)
{
static_assert
(
!
std
::
is_const
<
T
>::
value
);
return
detail
::
load
(
dref
(),
x
);
}
/// Deerializes a primitive value with getter / setter access.
template
<
class
Get
,
class
Set
>
template
<
class
Get
,
class
Set
>
bool
apply_value
(
Get
&&
get
,
Set
&&
set
)
{
[[
nodiscard
]]
bool
apply
(
Get
&&
get
,
Set
&&
set
)
{
using
field_type
=
std
::
decay_t
<
decltype
(
get
())
>
;
using
value_type
=
std
::
decay_t
<
decltype
(
get
())
>
;
auto
tmp
=
field_type
{};
auto
tmp
=
value_type
{};
if
(
apply_value
(
tmp
))
{
using
setter_result
=
decltype
(
set
(
std
::
move
(
tmp
)));
if
(
set
(
std
::
move
(
tmp
)))
if
constexpr
(
std
::
is_same
<
setter_result
,
bool
>::
value
)
{
if
(
dref
().
value
(
tmp
))
return
set
(
std
::
move
(
tmp
));
else
return
false
;
}
else
{
static_assert
(
std
::
is_convertible
<
setter_result
,
error
>::
value
);
if
(
dref
().
value
(
tmp
))
{
if
(
auto
err
=
set
(
std
::
move
(
tmp
));
!
err
)
{
return
true
;
return
true
;
this
->
set_error
(
sec
::
load_callback_failed
);
}
else
{
this
->
emplace_error
(
std
::
move
(
err
));
return
false
;
}
}
else
{
return
false
;
}
}
}
}
// -- deprecated API: remove with CAF 0.19 -----------------------------------
template
<
class
T
>
[[
deprecated
(
"auto-conversion to underlying type is unsafe, add inspect"
)]]
//
std
::
enable_if_t
<
std
::
is_enum
<
T
>::
value
,
bool
>
opaque_value
(
T
&
val
)
{
auto
tmp
=
std
::
underlying_type_t
<
T
>
{
0
};
if
(
dref
().
value
(
tmp
))
{
val
=
static_cast
<
T
>
(
tmp
);
return
true
;
}
else
{
return
false
;
return
false
;
}
}
}
template
<
class
T
>
[[
deprecated
(
"use apply instead"
)]]
bool
apply_object
(
T
&
x
)
{
return
detail
::
save
(
dref
(),
x
);
}
template
<
class
...
Ts
>
[[
deprecated
(
"use apply instead"
)]]
bool
apply_objects
(
Ts
&
...
xs
)
{
return
(
apply
(
xs
)
&&
...);
}
template
<
class
T
>
[[
deprecated
(
"use apply instead"
)]]
bool
apply_value
(
T
&
x
)
{
return
detail
::
save
(
dref
(),
x
);
}
private:
private:
Subtype
*
dptr
()
{
Subtype
*
dptr
()
{
...
...
libcaf_core/caf/message_id.hpp
View file @
8c8fb8be
...
@@ -229,28 +229,15 @@ constexpr message_id make_message_id(message_priority p) {
...
@@ -229,28 +229,15 @@ constexpr message_id make_message_id(message_priority p) {
// -- inspection support -------------------------------------------------------
// -- inspection support -------------------------------------------------------
template
<
>
template
<
class
Inspector
>
struct
inspector_access
<
message_id
>
:
inspector_access_base
<
message_id
>
{
bool
inspect
(
Inspector
&
f
,
message_id
&
x
)
{
template
<
class
Inspector
>
static
bool
apply_object
(
Inspector
&
f
,
message_id
&
x
)
{
auto
get
=
[
&
x
]
{
return
x
.
integer_value
();
};
auto
get
=
[
&
x
]
{
return
x
.
integer_value
();
};
auto
set
=
[
&
x
](
uint64_t
val
)
{
auto
set
=
[
&
x
](
uint64_t
val
)
{
x
=
message_id
{
val
};
x
=
message_id
{
val
};
return
true
;
return
true
;
};
};
return
f
.
object
(
x
).
fields
(
f
.
field
(
"value"
,
get
,
set
));
return
f
.
apply
(
get
,
set
);
}
}
template
<
class
Inspector
>
static
bool
apply_value
(
Inspector
&
f
,
message_id
&
x
)
{
auto
get
=
[
&
x
]
{
return
x
.
integer_value
();
};
auto
set
=
[
&
x
](
uint64_t
val
)
{
x
=
message_id
{
val
};
return
true
;
};
return
detail
::
split_save_load
(
f
,
get
,
set
);
}
};
}
// namespace caf
}
// namespace caf
...
...
libcaf_core/caf/pec.hpp
View file @
8c8fb8be
...
@@ -20,7 +20,9 @@
...
@@ -20,7 +20,9 @@
#include <cstdint>
#include <cstdint>
#include <string>
#include <string>
#include <type_traits>
#include "caf/default_enum_inspect.hpp"
#include "caf/detail/core_export.hpp"
#include "caf/detail/core_export.hpp"
#include "caf/fwd.hpp"
#include "caf/fwd.hpp"
#include "caf/is_error_code_enum.hpp"
#include "caf/is_error_code_enum.hpp"
...
@@ -80,8 +82,21 @@ enum class pec : uint8_t {
...
@@ -80,8 +82,21 @@ enum class pec : uint8_t {
invalid_state
,
invalid_state
,
};
};
/// @relates pec
CAF_CORE_EXPORT
std
::
string
to_string
(
pec
);
CAF_CORE_EXPORT
std
::
string
to_string
(
pec
);
/// @relates pec
CAF_CORE_EXPORT
bool
from_string
(
string_view
,
pec
&
);
/// @relates pec
CAF_CORE_EXPORT
bool
from_integer
(
std
::
underlying_type_t
<
pec
>
,
pec
&
);
/// @relates pec
template
<
class
Inspector
>
bool
inspect
(
Inspector
&
f
,
pec
&
x
)
{
return
default_enum_inspect
(
f
,
x
);
}
}
// namespace caf
}
// namespace caf
CAF_ERROR_CODE_ENUM
(
pec
)
CAF_ERROR_CODE_ENUM
(
pec
)
libcaf_core/caf/save_inspector.hpp
View file @
8c8fb8be
...
@@ -37,17 +37,10 @@ class CAF_CORE_EXPORT save_inspector {
...
@@ -37,17 +37,10 @@ class CAF_CORE_EXPORT save_inspector {
public:
public:
// -- member types -----------------------------------------------------------
// -- member types -----------------------------------------------------------
using
result_type
=
bool
;
using
result_type
[[
deprecated
(
"inspectors always return bool"
)]]
=
bool
;
// -- constants --------------------------------------------------------------
// -- constants --------------------------------------------------------------
/// Convenience constant to indicate success of a processing step.
static
constexpr
bool
ok
=
true
;
/// Convenience constant to indicate that a processing step failed and no
/// further processing steps should take place.
static
constexpr
bool
stop
=
false
;
/// Enables dispatching on the inspector type.
/// Enables dispatching on the inspector type.
static
constexpr
bool
is_loading
=
false
;
static
constexpr
bool
is_loading
=
false
;
...
...
libcaf_core/caf/save_inspector_base.hpp
View file @
8c8fb8be
...
@@ -30,41 +30,104 @@ public:
...
@@ -30,41 +30,104 @@ public:
using
super
=
save_inspector
;
using
super
=
save_inspector
;
// -- DSL entry point
-
-------------------------------------------------------
// -- DSL entry point
s
-------------------------------------------------------
template
<
class
T
>
template
<
class
T
>
constexpr
auto
object
(
T
&
)
noexcept
{
constexpr
auto
object
(
T
&
)
noexcept
{
return
super
::
object_t
<
Subtype
>
{
type_name_or_anonymous
<
T
>
(),
dptr
()};
return
super
::
object_t
<
Subtype
>
{
type_name_or_anonymous
<
T
>
(),
dptr
()};
}
}
// -- dispatching to load/save functions -------------------------------------
template
<
class
T
>
bool
list
(
const
T
&
xs
)
{
using
value_type
=
typename
T
::
value_type
;
auto
size
=
xs
.
size
();
if
(
!
dref
().
begin_sequence
(
size
))
return
false
;
for
(
auto
&&
val
:
xs
)
{
using
found_type
=
std
::
decay_t
<
decltype
(
val
)
>
;
if
constexpr
(
std
::
is_same
<
found_type
,
value_type
>::
value
)
{
if
(
!
detail
::
save
(
dref
(),
val
))
return
false
;
}
else
{
// Deals with atrocities like std::vector<bool>.
auto
tmp
=
static_cast
<
value_type
>
(
val
);
if
(
!
detail
::
save
(
dref
(),
tmp
))
return
false
;
}
}
return
dref
().
end_sequence
();
}
template
<
class
T
>
template
<
class
T
>
[[
nodiscard
]]
bool
apply_object
(
T
&
x
)
{
bool
map
(
const
T
&
xs
)
{
constexpr
auto
token
=
inspect_object_access_type
<
Subtype
,
T
>
();
if
(
!
dref
().
begin_associative_array
(
xs
.
size
()))
return
detail
::
save_object
(
dref
(),
x
,
token
);
return
false
;
for
(
auto
&&
kvp
:
xs
)
{
if
(
!
(
dref
().
begin_key_value_pair
()
//
&&
detail
::
save
(
dref
(),
kvp
.
first
)
//
&&
detail
::
save
(
dref
(),
kvp
.
second
)
//
&&
dref
().
end_key_value_pair
()))
return
false
;
}
return
dref
().
end_associative_array
();
}
template
<
class
T
,
size_t
...
Is
>
bool
tuple
(
const
T
&
xs
,
std
::
index_sequence
<
Is
...
>
)
{
return
dref
().
begin_tuple
(
sizeof
...(
Is
))
//
&&
(
detail
::
save
(
dref
(),
get
<
Is
>
(
xs
))
&&
...)
//
&&
dref
().
end_tuple
();
}
}
template
<
class
T
>
template
<
class
T
>
[[
nodiscard
]]
bool
apply_object
(
const
T
&
x
)
{
bool
tuple
(
const
T
&
xs
)
{
constexpr
auto
token
=
inspect_object_access_type
<
Subtype
,
T
>
();
return
tuple
(
xs
,
std
::
make_index_sequence
<
std
::
tuple_size
<
T
>::
value
>
{});
return
detail
::
save_object
(
dref
(),
detail
::
as_mutable_ref
(
x
),
token
);
}
}
template
<
class
...
Ts
>
template
<
class
T
,
size_t
N
>
[[
nodiscard
]]
bool
apply_objects
(
Ts
&&
...
xs
)
{
bool
tuple
(
T
(
&
xs
)[
N
])
{
return
(
apply_object
(
xs
)
&&
...);
if
(
!
dref
().
begin_tuple
(
N
))
return
false
;
for
(
size_t
index
=
0
;
index
<
N
;
++
index
)
if
(
!
detail
::
save
(
dref
(),
xs
[
index
]))
return
false
;
return
dref
().
end_tuple
();
}
}
// -- dispatching to load/save functions -------------------------------------
template
<
class
T
>
template
<
class
T
>
[[
nodiscard
]]
bool
apply
_value
(
T
&
x
)
{
[[
nodiscard
]]
bool
apply
(
const
T
&
x
)
{
return
detail
::
save
_value
(
dref
(),
x
);
return
detail
::
save
(
dref
(),
x
);
}
}
template
<
class
Get
,
class
Set
>
template
<
class
Get
,
class
Set
>
[[
nodiscard
]]
bool
apply_value
(
Get
&&
get
,
Set
&&
)
{
[[
nodiscard
]]
bool
apply
(
Get
&&
get
,
Set
&&
)
{
auto
&&
x
=
get
();
return
detail
::
save
(
dref
(),
get
());
return
detail
::
save_value
(
dref
(),
x
);
}
// -- deprecated API: remove with CAF 0.19 -----------------------------------
template
<
class
T
>
[[
deprecated
(
"auto-conversion to underlying type is unsafe, add inspect"
)]]
//
std
::
enable_if_t
<
std
::
is_enum
<
T
>::
value
,
bool
>
opaque_value
(
T
val
)
{
return
dref
().
value
(
static_cast
<
std
::
underlying_type_t
<
T
>>
(
val
));
}
template
<
class
T
>
[[
deprecated
(
"use apply instead"
)]]
bool
apply_object
(
const
T
&
x
)
{
return
apply
(
x
);
}
template
<
class
...
Ts
>
[[
deprecated
(
"use apply instead"
)]]
bool
apply_objects
(
const
Ts
&
...
xs
)
{
return
(
apply
(
xs
)
&&
...);
}
template
<
class
T
>
[[
deprecated
(
"use apply instead"
)]]
bool
apply_value
(
const
T
&
x
)
{
return
apply
(
x
);
}
}
private:
private:
...
...
libcaf_core/caf/sec.hpp
View file @
8c8fb8be
...
@@ -24,7 +24,9 @@
...
@@ -24,7 +24,9 @@
#include <cstdint>
#include <cstdint>
#include <string>
#include <string>
#include <type_traits>
#include "caf/default_enum_inspect.hpp"
#include "caf/detail/core_export.hpp"
#include "caf/detail/core_export.hpp"
#include "caf/fwd.hpp"
#include "caf/fwd.hpp"
#include "caf/is_error_code_enum.hpp"
#include "caf/is_error_code_enum.hpp"
...
@@ -167,6 +169,18 @@ enum class sec : uint8_t {
...
@@ -167,6 +169,18 @@ enum class sec : uint8_t {
/// @relates sec
/// @relates sec
CAF_CORE_EXPORT
std
::
string
to_string
(
sec
);
CAF_CORE_EXPORT
std
::
string
to_string
(
sec
);
/// @relates sec
CAF_CORE_EXPORT
bool
from_string
(
string_view
,
sec
&
);
/// @relates sec
CAF_CORE_EXPORT
bool
from_integer
(
std
::
underlying_type_t
<
sec
>
,
sec
&
);
/// @relates sec
template
<
class
Inssector
>
bool
inspect
(
Inssector
&
f
,
sec
&
x
)
{
return
default_enum_inspect
(
f
,
x
);
}
}
// namespace caf
}
// namespace caf
CAF_ERROR_CODE_ENUM
(
sec
)
CAF_ERROR_CODE_ENUM
(
sec
)
libcaf_core/caf/serializer.hpp
View file @
8c8fb8be
...
@@ -22,10 +22,12 @@
...
@@ -22,10 +22,12 @@
#include <cstdint>
#include <cstdint>
#include <string>
#include <string>
#include <tuple>
#include <tuple>
#include <type_traits>
#include <utility>
#include <utility>
#include "caf/byte.hpp"
#include "caf/byte.hpp"
#include "caf/detail/core_export.hpp"
#include "caf/detail/core_export.hpp"
#include "caf/detail/squashed_int.hpp"
#include "caf/fwd.hpp"
#include "caf/fwd.hpp"
#include "caf/meta/annotation.hpp"
#include "caf/meta/annotation.hpp"
#include "caf/meta/save_callback.hpp"
#include "caf/meta/save_callback.hpp"
...
@@ -40,6 +42,10 @@ namespace caf {
...
@@ -40,6 +42,10 @@ namespace caf {
/// Technology-independent serialization interface.
/// Technology-independent serialization interface.
class
CAF_CORE_EXPORT
serializer
:
public
save_inspector_base
<
serializer
>
{
class
CAF_CORE_EXPORT
serializer
:
public
save_inspector_base
<
serializer
>
{
public:
public:
// -- member types -----------------------------------------------------------
using
super
=
save_inspector_base
<
serializer
>
;
// -- constructors, destructors, and assignment operators --------------------
// -- constructors, destructors, and assignment operators --------------------
explicit
serializer
(
actor_system
&
sys
)
noexcept
;
explicit
serializer
(
actor_system
&
sys
)
noexcept
;
...
@@ -116,9 +122,12 @@ public:
...
@@ -116,9 +122,12 @@ public:
/// @note the default implementation calls `end_sequence()`.
/// @note the default implementation calls `end_sequence()`.
virtual
bool
end_associative_array
();
virtual
bool
end_associative_array
();
/// Adds the primitive type `x` to the output.
/// Adds `x` to the output.
/// @param x The primitive value.
/// @param x A value for a builtin type.
/// @returns A non-zero error code on failure, `sec::success` otherwise.
/// @returns `true` on success, `false` otherwise.
virtual
bool
value
(
byte
x
)
=
0
;
/// @copydoc value
virtual
bool
value
(
bool
x
)
=
0
;
virtual
bool
value
(
bool
x
)
=
0
;
/// @copydoc value
/// @copydoc value
...
@@ -145,6 +154,12 @@ public:
...
@@ -145,6 +154,12 @@ public:
/// @copydoc value
/// @copydoc value
virtual
bool
value
(
uint64_t
x
)
=
0
;
virtual
bool
value
(
uint64_t
x
)
=
0
;
/// @copydoc value
template
<
class
T
>
std
::
enable_if_t
<
std
::
is_integral
<
T
>::
value
,
bool
>
value
(
T
x
)
{
return
value
(
static_cast
<
detail
::
squashed_int_t
<
T
>>
(
x
));
}
/// @copydoc value
/// @copydoc value
virtual
bool
value
(
float
x
)
=
0
;
virtual
bool
value
(
float
x
)
=
0
;
...
@@ -168,10 +183,12 @@ public:
...
@@ -168,10 +183,12 @@ public:
/// @returns A non-zero error code on failure, `sec::success` otherwise.
/// @returns A non-zero error code on failure, `sec::success` otherwise.
virtual
bool
value
(
span
<
const
byte
>
x
)
=
0
;
virtual
bool
value
(
span
<
const
byte
>
x
)
=
0
;
using
super
::
list
;
/// Adds each boolean in `xs` to the output. Derived classes can override this
/// Adds each boolean in `xs` to the output. Derived classes can override this
/// member function to pack the booleans, for example to avoid using one byte
/// member function to pack the booleans, for example to avoid using one byte
/// for each value in a binary output format.
/// for each value in a binary output format.
virtual
bool
value
(
const
std
::
vector
<
bool
>&
xs
);
virtual
bool
list
(
const
std
::
vector
<
bool
>&
xs
);
protected:
protected:
/// Provides access to the ::proxy_registry and to the ::actor_system.
/// Provides access to the ::proxy_registry and to the ::actor_system.
...
...
libcaf_core/caf/stream_priority.hpp
View file @
8c8fb8be
...
@@ -18,14 +18,18 @@
...
@@ -18,14 +18,18 @@
#pragma once
#pragma once
#include <cstdint>
#include <string>
#include <string>
#include <type_traits>
#include "caf/default_enum_inspect.hpp"
#include "caf/detail/core_export.hpp"
#include "caf/detail/core_export.hpp"
#include "caf/fwd.hpp"
namespace
caf
{
namespace
caf
{
/// Categorizes individual streams.
/// Categorizes individual streams.
enum
class
stream_priority
{
enum
class
stream_priority
:
uint8_t
{
/// Denotes soft-realtime traffic.
/// Denotes soft-realtime traffic.
very_high
,
very_high
,
/// Denotes time-sensitive traffic.
/// Denotes time-sensitive traffic.
...
@@ -38,9 +42,20 @@ enum class stream_priority {
...
@@ -38,9 +42,20 @@ enum class stream_priority {
very_low
very_low
};
};
/// Stores the number of `stream_priority` classes.
/// @relates stream_priority
static
constexpr
size_t
stream_priorities
=
5
;
CAF_CORE_EXPORT
std
::
string
to_string
(
stream_priority
x
);
CAF_CORE_EXPORT
std
::
string
to_string
(
stream_priority
x
);
/// @relates stream_priority
CAF_CORE_EXPORT
bool
from_string
(
string_view
,
stream_priority
&
);
/// @relates stream_priority
CAF_CORE_EXPORT
bool
from_integer
(
std
::
underlying_type_t
<
stream_priority
>
,
stream_priority
&
);
/// @relates stream_priority
template
<
class
Inspector
>
bool
inspect
(
Inspector
&
f
,
stream_priority
&
x
)
{
return
default_enum_inspect
(
f
,
x
);
}
}
// namespace caf
}
// namespace caf
libcaf_core/caf/uri.hpp
View file @
8c8fb8be
...
@@ -260,35 +260,14 @@ CAF_CORE_EXPORT expected<uri> make_uri(string_view str);
...
@@ -260,35 +260,14 @@ CAF_CORE_EXPORT expected<uri> make_uri(string_view str);
template
<
>
template
<
>
struct
inspector_access
<
uri
>
:
inspector_access_base
<
uri
>
{
struct
inspector_access
<
uri
>
:
inspector_access_base
<
uri
>
{
template
<
class
Inspector
>
template
<
class
Inspector
>
static
bool
apply
_object
(
Inspector
&
f
,
uri
&
x
)
{
static
bool
apply
(
Inspector
&
f
,
uri
&
x
)
{
if
(
f
.
has_human_readable_format
())
{
if
(
f
.
has_human_readable_format
())
{
// TODO: extend the inspector DSL to promote string_view to std::string
// automatically to avoid unnecessary to_string conversions.
auto
get
=
[
&
x
]
{
return
to_string
(
x
);
};
auto
get
=
[
&
x
]
{
return
to_string
(
x
);
};
// TODO: setters should be able to return the error directly to avoid loss
// of information.
auto
set
=
[
&
x
](
std
::
string
str
)
{
auto
set
=
[
&
x
](
std
::
string
str
)
{
auto
err
=
parse
(
str
,
x
);
auto
err
=
parse
(
str
,
x
);
return
err
.
empty
()
;
return
!
err
;
};
};
return
f
.
object
(
x
).
fields
(
f
.
field
(
"value"
,
get
,
set
));
return
f
.
apply
(
get
,
set
);
}
else
{
if
constexpr
(
Inspector
::
is_loading
)
if
(
!
x
.
impl_
->
unique
())
x
.
impl_
.
reset
(
new
uri
::
impl_type
,
false
);
return
inspect
(
f
,
*
x
.
impl_
);
}
}
template
<
class
Inspector
>
static
bool
apply_value
(
Inspector
&
f
,
uri
&
x
)
{
if
(
f
.
has_human_readable_format
())
{
auto
get
=
[
&
x
]
{
return
to_string
(
x
);
};
auto
set
=
[
&
x
](
std
::
string
str
)
{
auto
err
=
parse
(
str
,
x
);
return
err
.
empty
();
};
return
detail
::
split_save_load
(
f
,
get
,
set
);
}
else
{
}
else
{
if
constexpr
(
Inspector
::
is_loading
)
if
constexpr
(
Inspector
::
is_loading
)
if
(
!
x
.
impl_
->
unique
())
if
(
!
x
.
impl_
->
unique
())
...
...
libcaf_core/src/binary_serializer.cpp
View file @
8c8fb8be
...
@@ -139,7 +139,7 @@ bool binary_serializer::value(span<const byte> x) {
...
@@ -139,7 +139,7 @@ bool binary_serializer::value(span<const byte> x) {
}
}
write_pos_
+=
x
.
size
();
write_pos_
+=
x
.
size
();
CAF_ASSERT
(
write_pos_
<=
buf_
.
size
());
CAF_ASSERT
(
write_pos_
<=
buf_
.
size
());
return
ok
;
return
true
;
}
}
bool
binary_serializer
::
value
(
byte
x
)
{
bool
binary_serializer
::
value
(
byte
x
)
{
...
@@ -148,7 +148,7 @@ bool binary_serializer::value(byte x) {
...
@@ -148,7 +148,7 @@ bool binary_serializer::value(byte x) {
else
else
buf_
[
write_pos_
]
=
x
;
buf_
[
write_pos_
]
=
x
;
++
write_pos_
;
++
write_pos_
;
return
ok
;
return
true
;
}
}
bool
binary_serializer
::
value
(
bool
x
)
{
bool
binary_serializer
::
value
(
bool
x
)
{
...
...
libcaf_core/src/config_value_reader.cpp
View file @
8c8fb8be
...
@@ -448,6 +448,17 @@ bool pull(config_value_reader& reader, T& x) {
...
@@ -448,6 +448,17 @@ bool pull(config_value_reader& reader, T& x) {
}
// namespace
}
// namespace
bool
config_value_reader
::
value
(
byte
&
x
)
{
CHECK_NOT_EMPTY
();
auto
tmp
=
uint8_t
{
0
};
if
(
pull
(
*
this
,
tmp
))
{
x
=
static_cast
<
byte
>
(
tmp
);
return
true
;
}
else
{
return
false
;
}
}
bool
config_value_reader
::
value
(
bool
&
x
)
{
bool
config_value_reader
::
value
(
bool
&
x
)
{
CHECK_NOT_EMPTY
();
CHECK_NOT_EMPTY
();
return
pull
(
*
this
,
x
);
return
pull
(
*
this
,
x
);
...
...
libcaf_core/src/config_value_writer.cpp
View file @
8c8fb8be
...
@@ -339,6 +339,10 @@ bool config_value_writer::end_associative_array() {
...
@@ -339,6 +339,10 @@ bool config_value_writer::end_associative_array() {
return
true
;
return
true
;
}
}
bool
config_value_writer
::
value
(
byte
x
)
{
return
push
(
config_value
{
static_cast
<
config_value
::
integer
>
(
x
)});
}
bool
config_value_writer
::
value
(
bool
x
)
{
bool
config_value_writer
::
value
(
bool
x
)
{
return
push
(
config_value
{
x
});
return
push
(
config_value
{
x
});
}
}
...
...
libcaf_core/src/deserializer.cpp
View file @
8c8fb8be
...
@@ -51,7 +51,7 @@ bool deserializer::end_associative_array() {
...
@@ -51,7 +51,7 @@ bool deserializer::end_associative_array() {
return
end_sequence
();
return
end_sequence
();
}
}
bool
deserializer
::
value
(
std
::
vector
<
bool
>&
x
)
{
bool
deserializer
::
list
(
std
::
vector
<
bool
>&
x
)
{
x
.
clear
();
x
.
clear
();
size_t
size
=
0
;
size_t
size
=
0
;
if
(
!
begin_sequence
(
size
))
if
(
!
begin_sequence
(
size
))
...
...
libcaf_core/src/detail/serialized_size.cpp
View file @
8c8fb8be
...
@@ -107,6 +107,11 @@ bool serialized_size_inspector::end_sequence() {
...
@@ -107,6 +107,11 @@ bool serialized_size_inspector::end_sequence() {
return
true
;
return
true
;
}
}
bool
serialized_size_inspector
::
value
(
byte
x
)
{
result
+=
sizeof
(
x
);
return
true
;
}
bool
serialized_size_inspector
::
value
(
bool
)
{
bool
serialized_size_inspector
::
value
(
bool
)
{
result
+=
sizeof
(
uint8_t
);
result
+=
sizeof
(
uint8_t
);
return
true
;
return
true
;
...
@@ -194,7 +199,7 @@ bool serialized_size_inspector::value(span<const byte> x) {
...
@@ -194,7 +199,7 @@ bool serialized_size_inspector::value(span<const byte> x) {
return
true
;
return
true
;
}
}
bool
serialized_size_inspector
::
value
(
const
std
::
vector
<
bool
>&
xs
)
{
bool
serialized_size_inspector
::
list
(
const
std
::
vector
<
bool
>&
xs
)
{
CAF_IGNORE_UNUSED
(
begin_sequence
(
xs
.
size
()));
CAF_IGNORE_UNUSED
(
begin_sequence
(
xs
.
size
()));
result
+=
(
xs
.
size
()
+
static_cast
<
size_t
>
(
xs
.
size
()
%
8
!=
0
))
/
8
;
result
+=
(
xs
.
size
()
+
static_cast
<
size_t
>
(
xs
.
size
()
%
8
!=
0
))
/
8
;
return
end_sequence
();
return
end_sequence
();
...
...
libcaf_core/src/detail/stringification_inspector.cpp
View file @
8c8fb8be
...
@@ -57,7 +57,7 @@ bool stringification_inspector::begin_object(string_view name) {
...
@@ -57,7 +57,7 @@ bool stringification_inspector::begin_object(string_view name) {
}
else
{
}
else
{
in_string_object_
=
true
;
in_string_object_
=
true
;
}
}
return
ok
;
return
true
;
}
}
bool
stringification_inspector
::
end_object
()
{
bool
stringification_inspector
::
end_object
()
{
...
@@ -65,11 +65,11 @@ bool stringification_inspector::end_object() {
...
@@ -65,11 +65,11 @@ bool stringification_inspector::end_object() {
result_
+=
')'
;
result_
+=
')'
;
else
else
in_string_object_
=
false
;
in_string_object_
=
false
;
return
ok
;
return
true
;
}
}
bool
stringification_inspector
::
begin_field
(
string_view
)
{
bool
stringification_inspector
::
begin_field
(
string_view
)
{
return
ok
;
return
true
;
}
}
bool
stringification_inspector
::
begin_field
(
string_view
,
bool
is_present
)
{
bool
stringification_inspector
::
begin_field
(
string_view
,
bool
is_present
)
{
...
@@ -78,12 +78,12 @@ bool stringification_inspector::begin_field(string_view, bool is_present) {
...
@@ -78,12 +78,12 @@ bool stringification_inspector::begin_field(string_view, bool is_present) {
result_
+=
"null"
;
result_
+=
"null"
;
else
else
result_
+=
'*'
;
result_
+=
'*'
;
return
ok
;
return
true
;
}
}
bool
stringification_inspector
::
begin_field
(
string_view
,
span
<
const
type_id_t
>
,
bool
stringification_inspector
::
begin_field
(
string_view
,
span
<
const
type_id_t
>
,
size_t
)
{
size_t
)
{
return
ok
;
return
true
;
}
}
bool
stringification_inspector
::
begin_field
(
string_view
,
bool
is_present
,
bool
stringification_inspector
::
begin_field
(
string_view
,
bool
is_present
,
...
@@ -93,22 +93,26 @@ bool stringification_inspector::begin_field(string_view, bool is_present,
...
@@ -93,22 +93,26 @@ bool stringification_inspector::begin_field(string_view, bool is_present,
result_
+=
"null"
;
result_
+=
"null"
;
else
else
result_
+=
'*'
;
result_
+=
'*'
;
return
ok
;
return
true
;
}
}
bool
stringification_inspector
::
end_field
()
{
bool
stringification_inspector
::
end_field
()
{
return
ok
;
return
true
;
}
}
bool
stringification_inspector
::
begin_sequence
(
size_t
)
{
bool
stringification_inspector
::
begin_sequence
(
size_t
)
{
sep
();
sep
();
result_
+=
'['
;
result_
+=
'['
;
return
ok
;
return
true
;
}
}
bool
stringification_inspector
::
end_sequence
()
{
bool
stringification_inspector
::
end_sequence
()
{
result_
+=
']'
;
result_
+=
']'
;
return
ok
;
return
true
;
}
bool
stringification_inspector
::
value
(
byte
x
)
{
return
value
(
span
<
const
byte
>
(
&
x
,
1
));
}
}
bool
stringification_inspector
::
value
(
bool
x
)
{
bool
stringification_inspector
::
value
(
bool
x
)
{
...
@@ -228,7 +232,13 @@ bool stringification_inspector::int_value(uint64_t x) {
...
@@ -228,7 +232,13 @@ bool stringification_inspector::int_value(uint64_t x) {
return
true
;
return
true
;
}
}
bool
stringification_inspector
::
value
(
const
std
::
vector
<
bool
>&
xs
)
{
bool
stringification_inspector
::
value
(
span
<
const
byte
>
x
)
{
sep
();
detail
::
append_hex
(
result_
,
x
.
data
(),
x
.
size
());
return
true
;
}
bool
stringification_inspector
::
list
(
const
std
::
vector
<
bool
>&
xs
)
{
begin_sequence
(
xs
.
size
());
begin_sequence
(
xs
.
size
());
for
(
bool
x
:
xs
)
for
(
bool
x
:
xs
)
value
(
x
);
value
(
x
);
...
...
libcaf_core/src/exit_reason_strings.cpp
View file @
8c8fb8be
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
// DO NOT EDIT: this file is auto-generated by caf-generate-enum-strings.
// DO NOT EDIT: this file is auto-generated by caf-generate-enum-strings.
// Run the target update-enum-strings if this file is out of sync.
// Run the target update-enum-strings if this file is out of sync.
#include "caf/config.hpp"
#include "caf/config.hpp"
#include "caf/string_view.hpp"
CAF_PUSH_DEPRECATED_WARNING
CAF_PUSH_DEPRECATED_WARNING
...
@@ -34,6 +35,55 @@ std::string to_string(exit_reason x) {
...
@@ -34,6 +35,55 @@ std::string to_string(exit_reason x) {
};
};
}
}
bool
from_string
(
string_view
in
,
exit_reason
&
out
)
{
if
(
in
==
"normal"
)
{
out
=
exit_reason
::
normal
;
return
true
;
}
else
if
(
in
==
"unhandled_exception"
)
{
out
=
exit_reason
::
unhandled_exception
;
return
true
;
}
else
if
(
in
==
"unknown"
)
{
out
=
exit_reason
::
unknown
;
return
true
;
}
else
if
(
in
==
"out_of_workers"
)
{
out
=
exit_reason
::
out_of_workers
;
return
true
;
}
else
if
(
in
==
"user_shutdown"
)
{
out
=
exit_reason
::
user_shutdown
;
return
true
;
}
else
if
(
in
==
"kill"
)
{
out
=
exit_reason
::
kill
;
return
true
;
}
else
if
(
in
==
"remote_link_unreachable"
)
{
out
=
exit_reason
::
remote_link_unreachable
;
return
true
;
}
else
if
(
in
==
"unreachable"
)
{
out
=
exit_reason
::
unreachable
;
return
true
;
}
else
{
return
false
;
}
}
bool
from_integer
(
std
::
underlying_type_t
<
exit_reason
>
in
,
exit_reason
&
out
)
{
auto
result
=
static_cast
<
exit_reason
>
(
in
);
switch
(
result
)
{
default:
return
false
;
case
exit_reason
:
:
normal
:
case
exit_reason
:
:
unhandled_exception
:
case
exit_reason
:
:
unknown
:
case
exit_reason
:
:
out_of_workers
:
case
exit_reason
:
:
user_shutdown
:
case
exit_reason
:
:
kill
:
case
exit_reason
:
:
remote_link_unreachable
:
case
exit_reason
:
:
unreachable
:
out
=
result
;
return
true
;
};
}
}
// namespace caf
}
// namespace caf
CAF_POP_WARNINGS
CAF_POP_WARNINGS
libcaf_core/src/intrusive/inbox_result_strings.cpp
View file @
8c8fb8be
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
// DO NOT EDIT: this file is auto-generated by caf-generate-enum-strings.
// DO NOT EDIT: this file is auto-generated by caf-generate-enum-strings.
// Run the target update-enum-strings if this file is out of sync.
// Run the target update-enum-strings if this file is out of sync.
#include "caf/config.hpp"
#include "caf/config.hpp"
#include "caf/string_view.hpp"
CAF_PUSH_DEPRECATED_WARNING
CAF_PUSH_DEPRECATED_WARNING
...
@@ -25,6 +26,35 @@ std::string to_string(inbox_result x) {
...
@@ -25,6 +26,35 @@ std::string to_string(inbox_result x) {
};
};
}
}
bool
from_string
(
string_view
in
,
inbox_result
&
out
)
{
if
(
in
==
"success"
)
{
out
=
inbox_result
::
success
;
return
true
;
}
else
if
(
in
==
"unblocked_reader"
)
{
out
=
inbox_result
::
unblocked_reader
;
return
true
;
}
else
if
(
in
==
"queue_closed"
)
{
out
=
inbox_result
::
queue_closed
;
return
true
;
}
else
{
return
false
;
}
}
bool
from_integer
(
std
::
underlying_type_t
<
inbox_result
>
in
,
inbox_result
&
out
)
{
auto
result
=
static_cast
<
inbox_result
>
(
in
);
switch
(
result
)
{
default:
return
false
;
case
inbox_result
:
:
success
:
case
inbox_result
:
:
unblocked_reader
:
case
inbox_result
:
:
queue_closed
:
out
=
result
;
return
true
;
};
}
}
// namespace intrusive
}
// namespace intrusive
}
// namespace caf
}
// namespace caf
...
...
libcaf_core/src/intrusive/task_result_strings.cpp
View file @
8c8fb8be
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
// DO NOT EDIT: this file is auto-generated by caf-generate-enum-strings.
// DO NOT EDIT: this file is auto-generated by caf-generate-enum-strings.
// Run the target update-enum-strings if this file is out of sync.
// Run the target update-enum-strings if this file is out of sync.
#include "caf/config.hpp"
#include "caf/config.hpp"
#include "caf/string_view.hpp"
CAF_PUSH_DEPRECATED_WARNING
CAF_PUSH_DEPRECATED_WARNING
...
@@ -27,6 +28,39 @@ std::string to_string(task_result x) {
...
@@ -27,6 +28,39 @@ std::string to_string(task_result x) {
};
};
}
}
bool
from_string
(
string_view
in
,
task_result
&
out
)
{
if
(
in
==
"resume"
)
{
out
=
task_result
::
resume
;
return
true
;
}
else
if
(
in
==
"skip"
)
{
out
=
task_result
::
skip
;
return
true
;
}
else
if
(
in
==
"stop"
)
{
out
=
task_result
::
stop
;
return
true
;
}
else
if
(
in
==
"stop_all"
)
{
out
=
task_result
::
stop_all
;
return
true
;
}
else
{
return
false
;
}
}
bool
from_integer
(
std
::
underlying_type_t
<
task_result
>
in
,
task_result
&
out
)
{
auto
result
=
static_cast
<
task_result
>
(
in
);
switch
(
result
)
{
default:
return
false
;
case
task_result
:
:
resume
:
case
task_result
:
:
skip
:
case
task_result
:
:
stop
:
case
task_result
:
:
stop_all
:
out
=
result
;
return
true
;
};
}
}
// namespace intrusive
}
// namespace intrusive
}
// namespace caf
}
// namespace caf
...
...
libcaf_core/src/invoke_message_result_strings.cpp
View file @
8c8fb8be
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
// DO NOT EDIT: this file is auto-generated by caf-generate-enum-strings.
// DO NOT EDIT: this file is auto-generated by caf-generate-enum-strings.
// Run the target update-enum-strings if this file is out of sync.
// Run the target update-enum-strings if this file is out of sync.
#include "caf/config.hpp"
#include "caf/config.hpp"
#include "caf/string_view.hpp"
CAF_PUSH_DEPRECATED_WARNING
CAF_PUSH_DEPRECATED_WARNING
...
@@ -24,6 +25,35 @@ std::string to_string(invoke_message_result x) {
...
@@ -24,6 +25,35 @@ std::string to_string(invoke_message_result x) {
};
};
}
}
bool
from_string
(
string_view
in
,
invoke_message_result
&
out
)
{
if
(
in
==
"consumed"
)
{
out
=
invoke_message_result
::
consumed
;
return
true
;
}
else
if
(
in
==
"skipped"
)
{
out
=
invoke_message_result
::
skipped
;
return
true
;
}
else
if
(
in
==
"dropped"
)
{
out
=
invoke_message_result
::
dropped
;
return
true
;
}
else
{
return
false
;
}
}
bool
from_integer
(
std
::
underlying_type_t
<
invoke_message_result
>
in
,
invoke_message_result
&
out
)
{
auto
result
=
static_cast
<
invoke_message_result
>
(
in
);
switch
(
result
)
{
default:
return
false
;
case
invoke_message_result
:
:
consumed
:
case
invoke_message_result
:
:
skipped
:
case
invoke_message_result
:
:
dropped
:
out
=
result
;
return
true
;
};
}
}
// namespace caf
}
// namespace caf
CAF_POP_WARNINGS
CAF_POP_WARNINGS
libcaf_core/src/logger.cpp
View file @
8c8fb8be
...
@@ -602,7 +602,7 @@ void logger::log_first_line() {
...
@@ -602,7 +602,7 @@ void logger::log_first_line() {
msg
+=
to_string
(
system_
.
node
());
msg
+=
to_string
(
system_
.
node
());
msg
+=
", excluded-components = "
;
msg
+=
", excluded-components = "
;
detail
::
stringification_inspector
f
{
msg
};
detail
::
stringification_inspector
f
{
msg
};
detail
::
save
_value
(
f
,
filter
);
detail
::
save
(
f
,
filter
);
return
msg
;
return
msg
;
};
};
namespace
lg
=
defaults
::
logger
;
namespace
lg
=
defaults
::
logger
;
...
...
libcaf_core/src/message_priority_strings.cpp
View file @
8c8fb8be
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
// DO NOT EDIT: this file is auto-generated by caf-generate-enum-strings.
// DO NOT EDIT: this file is auto-generated by caf-generate-enum-strings.
// Run the target update-enum-strings if this file is out of sync.
// Run the target update-enum-strings if this file is out of sync.
#include "caf/config.hpp"
#include "caf/config.hpp"
#include "caf/string_view.hpp"
CAF_PUSH_DEPRECATED_WARNING
CAF_PUSH_DEPRECATED_WARNING
...
@@ -22,6 +23,31 @@ std::string to_string(message_priority x) {
...
@@ -22,6 +23,31 @@ std::string to_string(message_priority x) {
};
};
}
}
bool
from_string
(
string_view
in
,
message_priority
&
out
)
{
if
(
in
==
"high"
)
{
out
=
message_priority
::
high
;
return
true
;
}
else
if
(
in
==
"normal"
)
{
out
=
message_priority
::
normal
;
return
true
;
}
else
{
return
false
;
}
}
bool
from_integer
(
std
::
underlying_type_t
<
message_priority
>
in
,
message_priority
&
out
)
{
auto
result
=
static_cast
<
message_priority
>
(
in
);
switch
(
result
)
{
default:
return
false
;
case
message_priority
:
:
high
:
case
message_priority
:
:
normal
:
out
=
result
;
return
true
;
};
}
}
// namespace caf
}
// namespace caf
CAF_POP_WARNINGS
CAF_POP_WARNINGS
libcaf_core/src/pec_strings.cpp
View file @
8c8fb8be
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
// DO NOT EDIT: this file is auto-generated by caf-generate-enum-strings.
// DO NOT EDIT: this file is auto-generated by caf-generate-enum-strings.
// Run the target update-enum-strings if this file is out of sync.
// Run the target update-enum-strings if this file is out of sync.
#include "caf/config.hpp"
#include "caf/config.hpp"
#include "caf/string_view.hpp"
CAF_PUSH_DEPRECATED_WARNING
CAF_PUSH_DEPRECATED_WARNING
...
@@ -64,6 +65,115 @@ std::string to_string(pec x) {
...
@@ -64,6 +65,115 @@ std::string to_string(pec x) {
};
};
}
}
bool
from_string
(
string_view
in
,
pec
&
out
)
{
if
(
in
==
"success"
)
{
out
=
pec
::
success
;
return
true
;
}
else
if
(
in
==
"trailing_character"
)
{
out
=
pec
::
trailing_character
;
return
true
;
}
else
if
(
in
==
"unexpected_eof"
)
{
out
=
pec
::
unexpected_eof
;
return
true
;
}
else
if
(
in
==
"unexpected_character"
)
{
out
=
pec
::
unexpected_character
;
return
true
;
}
else
if
(
in
==
"timespan_overflow"
)
{
out
=
pec
::
timespan_overflow
;
return
true
;
}
else
if
(
in
==
"fractional_timespan"
)
{
out
=
pec
::
fractional_timespan
;
return
true
;
}
else
if
(
in
==
"too_many_characters"
)
{
out
=
pec
::
too_many_characters
;
return
true
;
}
else
if
(
in
==
"invalid_escape_sequence"
)
{
out
=
pec
::
invalid_escape_sequence
;
return
true
;
}
else
if
(
in
==
"unexpected_newline"
)
{
out
=
pec
::
unexpected_newline
;
return
true
;
}
else
if
(
in
==
"integer_overflow"
)
{
out
=
pec
::
integer_overflow
;
return
true
;
}
else
if
(
in
==
"integer_underflow"
)
{
out
=
pec
::
integer_underflow
;
return
true
;
}
else
if
(
in
==
"exponent_underflow"
)
{
out
=
pec
::
exponent_underflow
;
return
true
;
}
else
if
(
in
==
"exponent_overflow"
)
{
out
=
pec
::
exponent_overflow
;
return
true
;
}
else
if
(
in
==
"type_mismatch"
)
{
out
=
pec
::
type_mismatch
;
return
true
;
}
else
if
(
in
==
"not_an_option"
)
{
out
=
pec
::
not_an_option
;
return
true
;
}
else
if
(
in
==
"invalid_argument"
)
{
out
=
pec
::
invalid_argument
;
return
true
;
}
else
if
(
in
==
"missing_argument"
)
{
out
=
pec
::
missing_argument
;
return
true
;
}
else
if
(
in
==
"invalid_category"
)
{
out
=
pec
::
invalid_category
;
return
true
;
}
else
if
(
in
==
"invalid_field_name"
)
{
out
=
pec
::
invalid_field_name
;
return
true
;
}
else
if
(
in
==
"repeated_field_name"
)
{
out
=
pec
::
repeated_field_name
;
return
true
;
}
else
if
(
in
==
"missing_field"
)
{
out
=
pec
::
missing_field
;
return
true
;
}
else
if
(
in
==
"invalid_range_expression"
)
{
out
=
pec
::
invalid_range_expression
;
return
true
;
}
else
if
(
in
==
"invalid_state"
)
{
out
=
pec
::
invalid_state
;
return
true
;
}
else
{
return
false
;
}
}
bool
from_integer
(
std
::
underlying_type_t
<
pec
>
in
,
pec
&
out
)
{
auto
result
=
static_cast
<
pec
>
(
in
);
switch
(
result
)
{
default:
return
false
;
case
pec
:
:
success
:
case
pec
:
:
trailing_character
:
case
pec
:
:
unexpected_eof
:
case
pec
:
:
unexpected_character
:
case
pec
:
:
timespan_overflow
:
case
pec
:
:
fractional_timespan
:
case
pec
:
:
too_many_characters
:
case
pec
:
:
invalid_escape_sequence
:
case
pec
:
:
unexpected_newline
:
case
pec
:
:
integer_overflow
:
case
pec
:
:
integer_underflow
:
case
pec
:
:
exponent_underflow
:
case
pec
:
:
exponent_overflow
:
case
pec
:
:
type_mismatch
:
case
pec
:
:
not_an_option
:
case
pec
:
:
invalid_argument
:
case
pec
:
:
missing_argument
:
case
pec
:
:
invalid_category
:
case
pec
:
:
invalid_field_name
:
case
pec
:
:
repeated_field_name
:
case
pec
:
:
missing_field
:
case
pec
:
:
invalid_range_expression
:
case
pec
:
:
invalid_state
:
out
=
result
;
return
true
;
};
}
}
// namespace caf
}
// namespace caf
CAF_POP_WARNINGS
CAF_POP_WARNINGS
libcaf_core/src/sec_strings.cpp
View file @
8c8fb8be
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
// DO NOT EDIT: this file is auto-generated by caf-generate-enum-strings.
// DO NOT EDIT: this file is auto-generated by caf-generate-enum-strings.
// Run the target update-enum-strings if this file is out of sync.
// Run the target update-enum-strings if this file is out of sync.
#include "caf/config.hpp"
#include "caf/config.hpp"
#include "caf/string_view.hpp"
CAF_PUSH_DEPRECATED_WARNING
CAF_PUSH_DEPRECATED_WARNING
...
@@ -144,6 +145,275 @@ std::string to_string(sec x) {
...
@@ -144,6 +145,275 @@ std::string to_string(sec x) {
};
};
}
}
bool
from_string
(
string_view
in
,
sec
&
out
)
{
if
(
in
==
"none"
)
{
out
=
sec
::
none
;
return
true
;
}
else
if
(
in
==
"unexpected_message"
)
{
out
=
sec
::
unexpected_message
;
return
true
;
}
else
if
(
in
==
"unexpected_response"
)
{
out
=
sec
::
unexpected_response
;
return
true
;
}
else
if
(
in
==
"request_receiver_down"
)
{
out
=
sec
::
request_receiver_down
;
return
true
;
}
else
if
(
in
==
"request_timeout"
)
{
out
=
sec
::
request_timeout
;
return
true
;
}
else
if
(
in
==
"no_such_group_module"
)
{
out
=
sec
::
no_such_group_module
;
return
true
;
}
else
if
(
in
==
"no_actor_published_at_port"
)
{
out
=
sec
::
no_actor_published_at_port
;
return
true
;
}
else
if
(
in
==
"unexpected_actor_messaging_interface"
)
{
out
=
sec
::
unexpected_actor_messaging_interface
;
return
true
;
}
else
if
(
in
==
"state_not_serializable"
)
{
out
=
sec
::
state_not_serializable
;
return
true
;
}
else
if
(
in
==
"unsupported_sys_key"
)
{
out
=
sec
::
unsupported_sys_key
;
return
true
;
}
else
if
(
in
==
"unsupported_sys_message"
)
{
out
=
sec
::
unsupported_sys_message
;
return
true
;
}
else
if
(
in
==
"disconnect_during_handshake"
)
{
out
=
sec
::
disconnect_during_handshake
;
return
true
;
}
else
if
(
in
==
"cannot_forward_to_invalid_actor"
)
{
out
=
sec
::
cannot_forward_to_invalid_actor
;
return
true
;
}
else
if
(
in
==
"no_route_to_receiving_node"
)
{
out
=
sec
::
no_route_to_receiving_node
;
return
true
;
}
else
if
(
in
==
"failed_to_assign_scribe_from_handle"
)
{
out
=
sec
::
failed_to_assign_scribe_from_handle
;
return
true
;
}
else
if
(
in
==
"failed_to_assign_doorman_from_handle"
)
{
out
=
sec
::
failed_to_assign_doorman_from_handle
;
return
true
;
}
else
if
(
in
==
"cannot_close_invalid_port"
)
{
out
=
sec
::
cannot_close_invalid_port
;
return
true
;
}
else
if
(
in
==
"cannot_connect_to_node"
)
{
out
=
sec
::
cannot_connect_to_node
;
return
true
;
}
else
if
(
in
==
"cannot_open_port"
)
{
out
=
sec
::
cannot_open_port
;
return
true
;
}
else
if
(
in
==
"network_syscall_failed"
)
{
out
=
sec
::
network_syscall_failed
;
return
true
;
}
else
if
(
in
==
"invalid_argument"
)
{
out
=
sec
::
invalid_argument
;
return
true
;
}
else
if
(
in
==
"invalid_protocol_family"
)
{
out
=
sec
::
invalid_protocol_family
;
return
true
;
}
else
if
(
in
==
"cannot_publish_invalid_actor"
)
{
out
=
sec
::
cannot_publish_invalid_actor
;
return
true
;
}
else
if
(
in
==
"cannot_spawn_actor_from_arguments"
)
{
out
=
sec
::
cannot_spawn_actor_from_arguments
;
return
true
;
}
else
if
(
in
==
"end_of_stream"
)
{
out
=
sec
::
end_of_stream
;
return
true
;
}
else
if
(
in
==
"no_context"
)
{
out
=
sec
::
no_context
;
return
true
;
}
else
if
(
in
==
"unknown_type"
)
{
out
=
sec
::
unknown_type
;
return
true
;
}
else
if
(
in
==
"no_proxy_registry"
)
{
out
=
sec
::
no_proxy_registry
;
return
true
;
}
else
if
(
in
==
"runtime_error"
)
{
out
=
sec
::
runtime_error
;
return
true
;
}
else
if
(
in
==
"remote_linking_failed"
)
{
out
=
sec
::
remote_linking_failed
;
return
true
;
}
else
if
(
in
==
"cannot_add_upstream"
)
{
out
=
sec
::
cannot_add_upstream
;
return
true
;
}
else
if
(
in
==
"upstream_already_exists"
)
{
out
=
sec
::
upstream_already_exists
;
return
true
;
}
else
if
(
in
==
"invalid_upstream"
)
{
out
=
sec
::
invalid_upstream
;
return
true
;
}
else
if
(
in
==
"cannot_add_downstream"
)
{
out
=
sec
::
cannot_add_downstream
;
return
true
;
}
else
if
(
in
==
"downstream_already_exists"
)
{
out
=
sec
::
downstream_already_exists
;
return
true
;
}
else
if
(
in
==
"invalid_downstream"
)
{
out
=
sec
::
invalid_downstream
;
return
true
;
}
else
if
(
in
==
"no_downstream_stages_defined"
)
{
out
=
sec
::
no_downstream_stages_defined
;
return
true
;
}
else
if
(
in
==
"stream_init_failed"
)
{
out
=
sec
::
stream_init_failed
;
return
true
;
}
else
if
(
in
==
"invalid_stream_state"
)
{
out
=
sec
::
invalid_stream_state
;
return
true
;
}
else
if
(
in
==
"unhandled_stream_error"
)
{
out
=
sec
::
unhandled_stream_error
;
return
true
;
}
else
if
(
in
==
"bad_function_call"
)
{
out
=
sec
::
bad_function_call
;
return
true
;
}
else
if
(
in
==
"feature_disabled"
)
{
out
=
sec
::
feature_disabled
;
return
true
;
}
else
if
(
in
==
"cannot_open_file"
)
{
out
=
sec
::
cannot_open_file
;
return
true
;
}
else
if
(
in
==
"socket_invalid"
)
{
out
=
sec
::
socket_invalid
;
return
true
;
}
else
if
(
in
==
"socket_disconnected"
)
{
out
=
sec
::
socket_disconnected
;
return
true
;
}
else
if
(
in
==
"socket_operation_failed"
)
{
out
=
sec
::
socket_operation_failed
;
return
true
;
}
else
if
(
in
==
"unavailable_or_would_block"
)
{
out
=
sec
::
unavailable_or_would_block
;
return
true
;
}
else
if
(
in
==
"incompatible_versions"
)
{
out
=
sec
::
incompatible_versions
;
return
true
;
}
else
if
(
in
==
"incompatible_application_ids"
)
{
out
=
sec
::
incompatible_application_ids
;
return
true
;
}
else
if
(
in
==
"malformed_basp_message"
)
{
out
=
sec
::
malformed_basp_message
;
return
true
;
}
else
if
(
in
==
"serializing_basp_payload_failed"
)
{
out
=
sec
::
serializing_basp_payload_failed
;
return
true
;
}
else
if
(
in
==
"redundant_connection"
)
{
out
=
sec
::
redundant_connection
;
return
true
;
}
else
if
(
in
==
"remote_lookup_failed"
)
{
out
=
sec
::
remote_lookup_failed
;
return
true
;
}
else
if
(
in
==
"no_tracing_context"
)
{
out
=
sec
::
no_tracing_context
;
return
true
;
}
else
if
(
in
==
"all_requests_failed"
)
{
out
=
sec
::
all_requests_failed
;
return
true
;
}
else
if
(
in
==
"field_invariant_check_failed"
)
{
out
=
sec
::
field_invariant_check_failed
;
return
true
;
}
else
if
(
in
==
"field_value_synchronization_failed"
)
{
out
=
sec
::
field_value_synchronization_failed
;
return
true
;
}
else
if
(
in
==
"invalid_field_type"
)
{
out
=
sec
::
invalid_field_type
;
return
true
;
}
else
if
(
in
==
"unsafe_type"
)
{
out
=
sec
::
unsafe_type
;
return
true
;
}
else
if
(
in
==
"save_callback_failed"
)
{
out
=
sec
::
save_callback_failed
;
return
true
;
}
else
if
(
in
==
"load_callback_failed"
)
{
out
=
sec
::
load_callback_failed
;
return
true
;
}
else
if
(
in
==
"conversion_failed"
)
{
out
=
sec
::
conversion_failed
;
return
true
;
}
else
if
(
in
==
"connection_closed"
)
{
out
=
sec
::
connection_closed
;
return
true
;
}
else
{
return
false
;
}
}
bool
from_integer
(
std
::
underlying_type_t
<
sec
>
in
,
sec
&
out
)
{
auto
result
=
static_cast
<
sec
>
(
in
);
switch
(
result
)
{
default:
return
false
;
case
sec
:
:
none
:
case
sec
:
:
unexpected_message
:
case
sec
:
:
unexpected_response
:
case
sec
:
:
request_receiver_down
:
case
sec
:
:
request_timeout
:
case
sec
:
:
no_such_group_module
:
case
sec
:
:
no_actor_published_at_port
:
case
sec
:
:
unexpected_actor_messaging_interface
:
case
sec
:
:
state_not_serializable
:
case
sec
:
:
unsupported_sys_key
:
case
sec
:
:
unsupported_sys_message
:
case
sec
:
:
disconnect_during_handshake
:
case
sec
:
:
cannot_forward_to_invalid_actor
:
case
sec
:
:
no_route_to_receiving_node
:
case
sec
:
:
failed_to_assign_scribe_from_handle
:
case
sec
:
:
failed_to_assign_doorman_from_handle
:
case
sec
:
:
cannot_close_invalid_port
:
case
sec
:
:
cannot_connect_to_node
:
case
sec
:
:
cannot_open_port
:
case
sec
:
:
network_syscall_failed
:
case
sec
:
:
invalid_argument
:
case
sec
:
:
invalid_protocol_family
:
case
sec
:
:
cannot_publish_invalid_actor
:
case
sec
:
:
cannot_spawn_actor_from_arguments
:
case
sec
:
:
end_of_stream
:
case
sec
:
:
no_context
:
case
sec
:
:
unknown_type
:
case
sec
:
:
no_proxy_registry
:
case
sec
:
:
runtime_error
:
case
sec
:
:
remote_linking_failed
:
case
sec
:
:
cannot_add_upstream
:
case
sec
:
:
upstream_already_exists
:
case
sec
:
:
invalid_upstream
:
case
sec
:
:
cannot_add_downstream
:
case
sec
:
:
downstream_already_exists
:
case
sec
:
:
invalid_downstream
:
case
sec
:
:
no_downstream_stages_defined
:
case
sec
:
:
stream_init_failed
:
case
sec
:
:
invalid_stream_state
:
case
sec
:
:
unhandled_stream_error
:
case
sec
:
:
bad_function_call
:
case
sec
:
:
feature_disabled
:
case
sec
:
:
cannot_open_file
:
case
sec
:
:
socket_invalid
:
case
sec
:
:
socket_disconnected
:
case
sec
:
:
socket_operation_failed
:
case
sec
:
:
unavailable_or_would_block
:
case
sec
:
:
incompatible_versions
:
case
sec
:
:
incompatible_application_ids
:
case
sec
:
:
malformed_basp_message
:
case
sec
:
:
serializing_basp_payload_failed
:
case
sec
:
:
redundant_connection
:
case
sec
:
:
remote_lookup_failed
:
case
sec
:
:
no_tracing_context
:
case
sec
:
:
all_requests_failed
:
case
sec
:
:
field_invariant_check_failed
:
case
sec
:
:
field_value_synchronization_failed
:
case
sec
:
:
invalid_field_type
:
case
sec
:
:
unsafe_type
:
case
sec
:
:
save_callback_failed
:
case
sec
:
:
load_callback_failed
:
case
sec
:
:
conversion_failed
:
case
sec
:
:
connection_closed
:
out
=
result
;
return
true
;
};
}
}
// namespace caf
}
// namespace caf
CAF_POP_WARNINGS
CAF_POP_WARNINGS
libcaf_core/src/serializer.cpp
View file @
8c8fb8be
...
@@ -51,7 +51,7 @@ bool serializer::end_associative_array() {
...
@@ -51,7 +51,7 @@ bool serializer::end_associative_array() {
return
end_sequence
();
return
end_sequence
();
}
}
bool
serializer
::
value
(
const
std
::
vector
<
bool
>&
xs
)
{
bool
serializer
::
list
(
const
std
::
vector
<
bool
>&
xs
)
{
if
(
!
begin_sequence
(
xs
.
size
()))
if
(
!
begin_sequence
(
xs
.
size
()))
return
false
;
return
false
;
for
(
bool
x
:
xs
)
for
(
bool
x
:
xs
)
...
...
libcaf_core/src/stream_priority_strings.cpp
View file @
8c8fb8be
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
// DO NOT EDIT: this file is auto-generated by caf-generate-enum-strings.
// DO NOT EDIT: this file is auto-generated by caf-generate-enum-strings.
// Run the target update-enum-strings if this file is out of sync.
// Run the target update-enum-strings if this file is out of sync.
#include "caf/config.hpp"
#include "caf/config.hpp"
#include "caf/string_view.hpp"
CAF_PUSH_DEPRECATED_WARNING
CAF_PUSH_DEPRECATED_WARNING
...
@@ -28,6 +29,43 @@ std::string to_string(stream_priority x) {
...
@@ -28,6 +29,43 @@ std::string to_string(stream_priority x) {
};
};
}
}
bool
from_string
(
string_view
in
,
stream_priority
&
out
)
{
if
(
in
==
"very_high"
)
{
out
=
stream_priority
::
very_high
;
return
true
;
}
else
if
(
in
==
"high"
)
{
out
=
stream_priority
::
high
;
return
true
;
}
else
if
(
in
==
"normal"
)
{
out
=
stream_priority
::
normal
;
return
true
;
}
else
if
(
in
==
"low"
)
{
out
=
stream_priority
::
low
;
return
true
;
}
else
if
(
in
==
"very_low"
)
{
out
=
stream_priority
::
very_low
;
return
true
;
}
else
{
return
false
;
}
}
bool
from_integer
(
std
::
underlying_type_t
<
stream_priority
>
in
,
stream_priority
&
out
)
{
auto
result
=
static_cast
<
stream_priority
>
(
in
);
switch
(
result
)
{
default:
return
false
;
case
stream_priority
:
:
very_high
:
case
stream_priority
:
:
high
:
case
stream_priority
:
:
normal
:
case
stream_priority
:
:
low
:
case
stream_priority
:
:
very_low
:
out
=
result
;
return
true
;
};
}
}
// namespace caf
}
// namespace caf
CAF_POP_WARNINGS
CAF_POP_WARNINGS
libcaf_core/test/actor_profiler.cpp
View file @
8c8fb8be
...
@@ -210,15 +210,15 @@ CAF_TEST(profilers record request / response messaging) {
...
@@ -210,15 +210,15 @@ CAF_TEST(profilers record request / response messaging) {
"new: worker"
,
"new: worker"
,
"new: server"
,
"new: server"
,
"new: client"
,
"new: client"
,
"client sends: message(
int32_t(19), int32_t(23)
)"
,
"client sends: message(
19, 23
)"
,
"server got: message(
int32_t(19), int32_t(23)
)"
,
"server got: message(
19, 23
)"
,
"server sends: message(
int32_t(19), int32_t(23)
)"
,
"server sends: message(
19, 23
)"
,
"server consumed the message"
,
"server consumed the message"
,
"delete: server"
,
"delete: server"
,
"worker got: message(
int32_t(19), int32_t(23)
)"
,
"worker got: message(
19, 23
)"
,
"worker sends: message(
int32_t(42)
)"
,
"worker sends: message(
42
)"
,
"worker consumed the message"
,
"worker consumed the message"
,
"client got: message(
int32_t(42)
)"
,
"client got: message(
42
)"
,
"client consumed the message"
,
"client consumed the message"
,
"delete: worker"
,
"delete: worker"
,
"delete: client"
,
"delete: client"
,
...
...
libcaf_core/test/actor_registry.cpp
View file @
8c8fb8be
...
@@ -54,12 +54,12 @@ CAF_TEST(serialization roundtrips go through the registry) {
...
@@ -54,12 +54,12 @@ CAF_TEST(serialization roundtrips go through the registry) {
CAF_MESSAGE
(
"hdl.id: "
<<
hdl
->
id
());
CAF_MESSAGE
(
"hdl.id: "
<<
hdl
->
id
());
byte_buffer
buf
;
byte_buffer
buf
;
binary_serializer
sink
{
sys
,
buf
};
binary_serializer
sink
{
sys
,
buf
};
if
(
!
sink
.
apply
_object
(
hdl
))
if
(
!
sink
.
apply
(
hdl
))
CAF_FAIL
(
"serialization failed: "
<<
sink
.
get_error
());
CAF_FAIL
(
"serialization failed: "
<<
sink
.
get_error
());
CAF_MESSAGE
(
"buf: "
<<
buf
);
CAF_MESSAGE
(
"buf: "
<<
buf
);
actor
hdl2
;
actor
hdl2
;
binary_deserializer
source
{
sys
,
buf
};
binary_deserializer
source
{
sys
,
buf
};
if
(
!
source
.
apply
_object
(
hdl2
))
if
(
!
source
.
apply
(
hdl2
))
CAF_FAIL
(
"deserialization failed: "
<<
source
.
get_error
());
CAF_FAIL
(
"deserialization failed: "
<<
source
.
get_error
());
CAF_CHECK_EQUAL
(
hdl
,
hdl2
);
CAF_CHECK_EQUAL
(
hdl
,
hdl2
);
anon_send_exit
(
hdl
,
exit_reason
::
user_shutdown
);
anon_send_exit
(
hdl
,
exit_reason
::
user_shutdown
);
...
...
libcaf_core/test/binary_deserializer.cpp
View file @
8c8fb8be
...
@@ -60,7 +60,7 @@ struct fixture {
...
@@ -60,7 +60,7 @@ struct fixture {
template
<
class
...
Ts
>
template
<
class
...
Ts
>
void
load
(
const
std
::
vector
<
byte
>&
buf
,
Ts
&
...
xs
)
{
void
load
(
const
std
::
vector
<
byte
>&
buf
,
Ts
&
...
xs
)
{
binary_deserializer
source
{
nullptr
,
buf
};
binary_deserializer
source
{
nullptr
,
buf
};
if
(
!
source
.
apply_objects
(
xs
...))
if
(
!
(
source
.
apply
(
xs
)
&&
...))
CAF_FAIL
(
"binary_deserializer failed to load: "
<<
source
.
get_error
());
CAF_FAIL
(
"binary_deserializer failed to load: "
<<
source
.
get_error
());
}
}
...
...
libcaf_core/test/binary_serializer.cpp
View file @
8c8fb8be
...
@@ -58,7 +58,7 @@ struct fixture {
...
@@ -58,7 +58,7 @@ struct fixture {
auto
save
(
const
Ts
&
...
xs
)
{
auto
save
(
const
Ts
&
...
xs
)
{
byte_buffer
result
;
byte_buffer
result
;
binary_serializer
sink
{
nullptr
,
result
};
binary_serializer
sink
{
nullptr
,
result
};
if
(
!
sink
.
apply_objects
(
xs
...))
if
(
!
(
sink
.
apply
(
xs
)
&&
...))
CAF_FAIL
(
"binary_serializer failed to save: "
<<
sink
.
get_error
());
CAF_FAIL
(
"binary_serializer failed to save: "
<<
sink
.
get_error
());
return
result
;
return
result
;
}
}
...
@@ -66,7 +66,7 @@ struct fixture {
...
@@ -66,7 +66,7 @@ struct fixture {
template
<
class
...
Ts
>
template
<
class
...
Ts
>
void
save_to_buf
(
byte_buffer
&
data
,
const
Ts
&
...
xs
)
{
void
save_to_buf
(
byte_buffer
&
data
,
const
Ts
&
...
xs
)
{
binary_serializer
sink
{
nullptr
,
data
};
binary_serializer
sink
{
nullptr
,
data
};
if
(
!
sink
.
apply_objects
(
xs
...))
if
(
!
(
sink
.
apply
(
xs
)
&&
...))
CAF_FAIL
(
"binary_serializer failed to save: "
<<
sink
.
get_error
());
CAF_FAIL
(
"binary_serializer failed to save: "
<<
sink
.
get_error
());
}
}
};
};
...
...
libcaf_core/test/config_value_reader.cpp
View file @
8c8fb8be
...
@@ -43,13 +43,13 @@ constexpr i64 operator""_i64(unsigned long long int x) {
...
@@ -43,13 +43,13 @@ constexpr i64 operator""_i64(unsigned long long int x) {
using
i64_list
=
std
::
vector
<
i64
>
;
using
i64_list
=
std
::
vector
<
i64
>
;
struct
fixture
{
struct
fixture
{
settings
xs
;
config_value
x
;
template
<
class
T
>
template
<
class
T
>
void
deserialize
(
const
config_value
&
src
,
T
&
value
)
{
void
deserialize
(
const
config_value
&
src
,
T
&
value
)
{
config_value_reader
reader
{
&
src
};
config_value_reader
reader
{
&
src
};
if
(
!
detail
::
load
_value
(
reader
,
value
))
if
(
!
detail
::
load
(
reader
,
value
))
CAF_FAIL
(
"
failed to deserialize from settings
: "
<<
reader
.
get_error
());
CAF_FAIL
(
"
deserialization failed
: "
<<
reader
.
get_error
());
}
}
template
<
class
T
>
template
<
class
T
>
...
@@ -59,7 +59,7 @@ struct fixture {
...
@@ -59,7 +59,7 @@ struct fixture {
template
<
class
T
>
template
<
class
T
>
void
deserialize
(
T
&
value
)
{
void
deserialize
(
T
&
value
)
{
return
deserialize
(
x
s
,
value
);
return
deserialize
(
x
,
value
);
}
}
template
<
class
T
>
template
<
class
T
>
...
@@ -71,7 +71,10 @@ struct fixture {
...
@@ -71,7 +71,10 @@ struct fixture {
template
<
class
T
>
template
<
class
T
>
optional
<
T
>
get
(
string_view
key
)
{
optional
<
T
>
get
(
string_view
key
)
{
return
get
<
T
>
(
xs
,
key
);
if
(
auto
*
xs
=
get_if
<
settings
>
(
&
x
))
return
get
<
T
>
(
*
xs
,
key
);
else
CAF_FAIL
(
"fixture does not contain a dictionary"
);
}
}
};
};
...
@@ -81,12 +84,14 @@ CAF_TEST_FIXTURE_SCOPE(config_value_reader_tests, fixture)
...
@@ -81,12 +84,14 @@ CAF_TEST_FIXTURE_SCOPE(config_value_reader_tests, fixture)
CAF_TEST
(
readers
deserialize
builtin
types
from
config
values
)
{
CAF_TEST
(
readers
deserialize
builtin
types
from
config
values
)
{
std
::
string
value
;
std
::
string
value
;
auto
&
xs
=
x
.
as_dictionary
();
put
(
xs
,
"foo"
,
"bar"
);
put
(
xs
,
"foo"
,
"bar"
);
deserialize
(
xs
[
"foo"
],
value
);
deserialize
(
xs
[
"foo"
],
value
);
CAF_CHECK_EQUAL
(
value
,
"bar"
);
CAF_CHECK_EQUAL
(
value
,
"bar"
);
}
}
CAF_TEST
(
readers
deserialize
simple
objects
from
configs
)
{
CAF_TEST
(
readers
deserialize
simple
objects
from
configs
)
{
auto
&
xs
=
x
.
as_dictionary
();
put
(
xs
,
"foo"
,
"hello"
);
put
(
xs
,
"foo"
,
"hello"
);
put
(
xs
,
"bar"
,
"world"
);
put
(
xs
,
"bar"
,
"world"
);
foobar
fb
;
foobar
fb
;
...
@@ -97,6 +102,7 @@ CAF_TEST(readers deserialize simple objects from configs) {
...
@@ -97,6 +102,7 @@ CAF_TEST(readers deserialize simple objects from configs) {
CAF_TEST
(
readers
deserialize
complex
objects
from
configs
)
{
CAF_TEST
(
readers
deserialize
complex
objects
from
configs
)
{
CAF_MESSAGE
(
"fill a dictionary with data for a 'basics' object"
);
CAF_MESSAGE
(
"fill a dictionary with data for a 'basics' object"
);
auto
&
xs
=
x
.
as_dictionary
();
put
(
xs
,
"v1"
,
settings
{});
put
(
xs
,
"v1"
,
settings
{});
put
(
xs
,
"v2"
,
42
_i64
);
put
(
xs
,
"v2"
,
42
_i64
);
put
(
xs
,
"v3"
,
i64_list
({
1
,
2
,
3
,
4
}));
put
(
xs
,
"v3"
,
i64_list
({
1
,
2
,
3
,
4
}));
...
@@ -140,11 +146,11 @@ CAF_TEST(readers deserialize objects from the output of writers) {
...
@@ -140,11 +146,11 @@ CAF_TEST(readers deserialize objects from the output of writers) {
line
l
{{
10
,
20
,
30
},
{
70
,
60
,
50
}};
line
l
{{
10
,
20
,
30
},
{
70
,
60
,
50
}};
config_value
tmp
;
config_value
tmp
;
config_value_writer
writer
{
&
tmp
};
config_value_writer
writer
{
&
tmp
};
if
(
!
detail
::
save
_value
(
writer
,
l
))
if
(
!
detail
::
save
(
writer
,
l
))
CAF_FAIL
(
"failed two write to settings: "
<<
writer
.
get_error
());
CAF_FAIL
(
"failed two write to settings: "
<<
writer
.
get_error
());
if
(
!
holds_alternative
<
settings
>
(
tmp
))
if
(
!
holds_alternative
<
settings
>
(
tmp
))
CAF_FAIL
(
"writer failed to produce a dictionary"
);
CAF_FAIL
(
"writer failed to produce a dictionary"
);
x
s
=
std
::
move
(
caf
::
get
<
settings
>
(
tmp
));
x
.
as_dictionary
()
=
std
::
move
(
caf
::
get
<
settings
>
(
tmp
));
}
}
CAF_MESSAGE
(
"serialize and verify the 'line' object"
);
CAF_MESSAGE
(
"serialize and verify the 'line' object"
);
{
{
...
...
libcaf_core/test/config_value_writer.cpp
View file @
8c8fb8be
...
@@ -41,17 +41,13 @@ constexpr i64 operator""_i64(unsigned long long int x) {
...
@@ -41,17 +41,13 @@ constexpr i64 operator""_i64(unsigned long long int x) {
using
i64_list
=
std
::
vector
<
i64
>
;
using
i64_list
=
std
::
vector
<
i64
>
;
struct
fixture
{
struct
fixture
{
settings
xs
;
config_value
x
;
template
<
class
T
>
template
<
class
T
>
void
set
(
const
T
&
value
)
{
void
set
(
const
T
&
value
)
{
config_value
val
;
config_value_writer
writer
{
&
x
};
config_value_writer
writer
{
&
val
};
if
(
!
detail
::
save
(
writer
,
value
))
if
(
!
detail
::
save_value
(
writer
,
value
))
CAF_FAIL
(
"failed two write to settings: "
<<
writer
.
get_error
());
CAF_FAIL
(
"failed two write to settings: "
<<
writer
.
get_error
());
if
(
!
holds_alternative
<
settings
>
(
val
))
CAF_FAIL
(
"serializing T did not result in a dictionary"
);
xs
=
std
::
move
(
caf
::
get
<
settings
>
(
val
));
}
}
template
<
class
T
>
template
<
class
T
>
...
@@ -63,7 +59,10 @@ struct fixture {
...
@@ -63,7 +59,10 @@ struct fixture {
template
<
class
T
>
template
<
class
T
>
optional
<
T
>
get
(
string_view
key
)
{
optional
<
T
>
get
(
string_view
key
)
{
return
get
<
T
>
(
xs
,
key
);
if
(
auto
*
xs
=
get_if
<
settings
>
(
&
x
))
return
get
<
T
>
(
*
xs
,
key
);
else
CAF_FAIL
(
"fixture does not contain a dictionary"
);
}
}
};
};
...
@@ -101,7 +100,6 @@ CAF_TEST(empty types and maps become dictionaries) {
...
@@ -101,7 +100,6 @@ CAF_TEST(empty types and maps become dictionaries) {
tst
.
v7
[
"two"
]
=
2
;
tst
.
v7
[
"two"
]
=
2
;
tst
.
v7
[
"three"
]
=
3
;
tst
.
v7
[
"three"
]
=
3
;
set
(
tst
);
set
(
tst
);
CAF_MESSAGE
(
xs
);
CAF_CHECK_EQUAL
(
get
<
settings
>
(
"v1"
),
settings
{});
CAF_CHECK_EQUAL
(
get
<
settings
>
(
"v1"
),
settings
{});
CAF_CHECK_EQUAL
(
get
<
i64
>
(
"v2"
),
42
_i64
);
CAF_CHECK_EQUAL
(
get
<
i64
>
(
"v2"
),
42
_i64
);
CAF_CHECK_EQUAL
(
get
<
i64_list
>
(
"v3"
),
i64_list
({
-
1
,
-
2
,
-
3
,
-
4
}));
CAF_CHECK_EQUAL
(
get
<
i64_list
>
(
"v3"
),
i64_list
({
-
1
,
-
2
,
-
3
,
-
4
}));
...
@@ -128,4 +126,10 @@ CAF_TEST(empty types and maps become dictionaries) {
...
@@ -128,4 +126,10 @@ CAF_TEST(empty types and maps become dictionaries) {
CAF_CHECK_EQUAL
(
get
<
config_value
::
list
>
(
"v8"
),
config_value
::
list
());
CAF_CHECK_EQUAL
(
get
<
config_value
::
list
>
(
"v8"
),
config_value
::
list
());
}
}
CAF_TEST
(
custom
inspect
overloads
may
produce
single
values
)
{
auto
tue
=
weekday
::
tuesday
;
set
(
tue
);
CAF_CHECK_EQUAL
(
x
,
"tuesday"
s
);
}
CAF_TEST_FIXTURE_SCOPE_END
()
CAF_TEST_FIXTURE_SCOPE_END
()
libcaf_core/test/core-test.hpp
View file @
8c8fb8be
...
@@ -200,6 +200,20 @@ enum class test_enum : int32_t {
...
@@ -200,6 +200,20 @@ enum class test_enum : int32_t {
// Implemented in serialization.cpp
// Implemented in serialization.cpp
std
::
string
to_string
(
test_enum
x
);
std
::
string
to_string
(
test_enum
x
);
template
<
class
Inspector
>
bool
inspect
(
Inspector
&
f
,
test_enum
&
x
)
{
auto
get
=
[
&
x
]
{
return
static_cast
<
int32_t
>
(
x
);
};
auto
set
=
[
&
x
](
int32_t
val
)
{
if
(
val
>=
0
&&
val
<=
2
)
{
x
=
static_cast
<
test_enum
>
(
val
);
return
true
;
}
else
{
return
false
;
}
};
return
f
.
apply
(
get
,
set
);
}
// Used in serializer.cpp and deserializer.cpp
// Used in serializer.cpp and deserializer.cpp
struct
test_data
{
struct
test_data
{
int32_t
i32
;
int32_t
i32
;
...
@@ -231,10 +245,54 @@ enum class dummy_enum_class : short { foo, bar };
...
@@ -231,10 +245,54 @@ enum class dummy_enum_class : short { foo, bar };
return
x
==
dummy_enum_class
::
foo
?
"foo"
:
"bar"
;
return
x
==
dummy_enum_class
::
foo
?
"foo"
:
"bar"
;
}
}
template
<
class
Inspector
>
bool
inspect
(
Inspector
&
f
,
dummy_enum_class
&
x
)
{
auto
get
=
[
&
x
]
{
return
static_cast
<
short
>
(
x
);
};
auto
set
=
[
&
x
](
short
val
)
{
if
(
val
>=
0
&&
val
<=
1
)
{
x
=
static_cast
<
dummy_enum_class
>
(
val
);
return
true
;
}
else
{
return
false
;
}
};
return
f
.
apply
(
get
,
set
);
}
enum
class
level
{
all
,
trace
,
debug
,
warning
,
error
};
enum
class
level
{
all
,
trace
,
debug
,
warning
,
error
};
template
<
class
Inspector
>
bool
inspect
(
Inspector
&
f
,
level
&
x
)
{
using
integer_type
=
std
::
underlying_type_t
<
level
>
;
auto
get
=
[
&
x
]
{
return
static_cast
<
integer_type
>
(
x
);
};
auto
set
=
[
&
x
](
integer_type
val
)
{
if
(
val
>=
0
&&
val
<=
4
)
{
x
=
static_cast
<
level
>
(
val
);
return
true
;
}
else
{
return
false
;
}
};
return
f
.
apply
(
get
,
set
);
}
enum
dummy_enum
{
de_foo
,
de_bar
};
enum
dummy_enum
{
de_foo
,
de_bar
};
template
<
class
Inspector
>
bool
inspect
(
Inspector
&
f
,
dummy_enum
&
x
)
{
using
integer_type
=
std
::
underlying_type_t
<
dummy_enum
>
;
auto
get
=
[
&
x
]
{
return
static_cast
<
integer_type
>
(
x
);
};
auto
set
=
[
&
x
](
integer_type
val
)
{
if
(
val
>=
0
&&
val
<=
1
)
{
x
=
static_cast
<
dummy_enum
>
(
val
);
return
true
;
}
else
{
return
false
;
}
};
return
f
.
apply
(
get
,
set
);
}
// -- type IDs for for all unit test suites ------------------------------------
// -- type IDs for for all unit test suites ------------------------------------
#define ADD_TYPE_ID(type) CAF_ADD_TYPE_ID(core_test, type)
#define ADD_TYPE_ID(type) CAF_ADD_TYPE_ID(core_test, type)
...
...
libcaf_core/test/detail/serialized_size.cpp
View file @
8c8fb8be
...
@@ -39,7 +39,7 @@ struct fixture : test_coordinator_fixture<> {
...
@@ -39,7 +39,7 @@ struct fixture : test_coordinator_fixture<> {
size_t
actual_size
(
const
Ts
&
...
xs
)
{
size_t
actual_size
(
const
Ts
&
...
xs
)
{
byte_buffer
buf
;
byte_buffer
buf
;
binary_serializer
sink
{
sys
,
buf
};
binary_serializer
sink
{
sys
,
buf
};
if
(
!
sink
.
apply_objects
(
xs
...))
if
(
!
(
sink
.
apply
(
xs
)
&&
...))
CAF_FAIL
(
"failed to serialize data: "
<<
sink
.
get_error
());
CAF_FAIL
(
"failed to serialize data: "
<<
sink
.
get_error
());
return
buf
.
size
();
return
buf
.
size
();
}
}
...
...
libcaf_core/test/ipv4_endpoint.cpp
View file @
8c8fb8be
...
@@ -54,11 +54,11 @@ struct fixture {
...
@@ -54,11 +54,11 @@ struct fixture {
T
roundtrip
(
T
x
)
{
T
roundtrip
(
T
x
)
{
byte_buffer
buf
;
byte_buffer
buf
;
binary_serializer
sink
(
sys
,
buf
);
binary_serializer
sink
(
sys
,
buf
);
if
(
!
sink
.
apply
_object
(
x
))
if
(
!
sink
.
apply
(
x
))
CAF_FAIL
(
"serialization failed: "
<<
sink
.
get_error
());
CAF_FAIL
(
"serialization failed: "
<<
sink
.
get_error
());
binary_deserializer
source
(
sys
,
make_span
(
buf
));
binary_deserializer
source
(
sys
,
make_span
(
buf
));
T
y
;
T
y
;
if
(
!
source
.
apply
_object
(
y
))
if
(
!
source
.
apply
(
y
))
CAF_FAIL
(
"deserialization failed: "
<<
source
.
get_error
());
CAF_FAIL
(
"deserialization failed: "
<<
source
.
get_error
());
return
y
;
return
y
;
}
}
...
...
libcaf_core/test/ipv6_endpoint.cpp
View file @
8c8fb8be
...
@@ -54,11 +54,11 @@ struct fixture {
...
@@ -54,11 +54,11 @@ struct fixture {
T
roundtrip
(
T
x
)
{
T
roundtrip
(
T
x
)
{
byte_buffer
buf
;
byte_buffer
buf
;
binary_serializer
sink
(
sys
,
buf
);
binary_serializer
sink
(
sys
,
buf
);
if
(
!
sink
.
apply
_object
(
x
))
if
(
!
sink
.
apply
(
x
))
CAF_FAIL
(
"serialization failed: "
<<
sink
.
get_error
());
CAF_FAIL
(
"serialization failed: "
<<
sink
.
get_error
());
binary_deserializer
source
(
sys
,
make_span
(
buf
));
binary_deserializer
source
(
sys
,
make_span
(
buf
));
T
y
;
T
y
;
if
(
!
source
.
apply
_object
(
y
))
if
(
!
source
.
apply
(
y
))
CAF_FAIL
(
"serialization failed: "
<<
source
.
get_error
());
CAF_FAIL
(
"serialization failed: "
<<
source
.
get_error
());
return
y
;
return
y
;
}
}
...
...
libcaf_core/test/load_inspector.cpp
View file @
8c8fb8be
...
@@ -44,7 +44,7 @@ struct testee : deserializer {
...
@@ -44,7 +44,7 @@ struct testee : deserializer {
bool
load_field_failed
(
string_view
,
sec
code
)
{
bool
load_field_failed
(
string_view
,
sec
code
)
{
set_error
(
make_error
(
code
));
set_error
(
make_error
(
code
));
return
stop
;
return
false
;
}
}
size_t
indent
=
0
;
size_t
indent
=
0
;
...
@@ -63,14 +63,14 @@ struct testee : deserializer {
...
@@ -63,14 +63,14 @@ struct testee : deserializer {
indent
+=
2
;
indent
+=
2
;
log
+=
"begin object "
;
log
+=
"begin object "
;
log
.
insert
(
log
.
end
(),
object_name
.
begin
(),
object_name
.
end
());
log
.
insert
(
log
.
end
(),
object_name
.
begin
(),
object_name
.
end
());
return
ok
;
return
true
;
}
}
bool
end_object
()
override
{
bool
end_object
()
override
{
indent
-=
2
;
indent
-=
2
;
new_line
();
new_line
();
log
+=
"end object"
;
log
+=
"end object"
;
return
ok
;
return
true
;
}
}
bool
begin_field
(
string_view
name
)
override
{
bool
begin_field
(
string_view
name
)
override
{
...
@@ -78,7 +78,7 @@ struct testee : deserializer {
...
@@ -78,7 +78,7 @@ struct testee : deserializer {
indent
+=
2
;
indent
+=
2
;
log
+=
"begin field "
;
log
+=
"begin field "
;
log
.
insert
(
log
.
end
(),
name
.
begin
(),
name
.
end
());
log
.
insert
(
log
.
end
(),
name
.
begin
(),
name
.
end
());
return
ok
;
return
true
;
}
}
bool
begin_field
(
string_view
name
,
bool
&
is_present
)
override
{
bool
begin_field
(
string_view
name
,
bool
&
is_present
)
override
{
...
@@ -87,7 +87,7 @@ struct testee : deserializer {
...
@@ -87,7 +87,7 @@ struct testee : deserializer {
log
+=
"begin optional field "
;
log
+=
"begin optional field "
;
log
.
insert
(
log
.
end
(),
name
.
begin
(),
name
.
end
());
log
.
insert
(
log
.
end
(),
name
.
begin
(),
name
.
end
());
is_present
=
false
;
is_present
=
false
;
return
ok
;
return
true
;
}
}
bool
begin_field
(
string_view
name
,
span
<
const
type_id_t
>
,
bool
begin_field
(
string_view
name
,
span
<
const
type_id_t
>
,
...
@@ -97,7 +97,7 @@ struct testee : deserializer {
...
@@ -97,7 +97,7 @@ struct testee : deserializer {
log
+=
"begin variant field "
;
log
+=
"begin variant field "
;
log
.
insert
(
log
.
end
(),
name
.
begin
(),
name
.
end
());
log
.
insert
(
log
.
end
(),
name
.
begin
(),
name
.
end
());
type_index
=
0
;
type_index
=
0
;
return
ok
;
return
true
;
}
}
bool
begin_field
(
string_view
name
,
bool
&
is_present
,
span
<
const
type_id_t
>
,
bool
begin_field
(
string_view
name
,
bool
&
is_present
,
span
<
const
type_id_t
>
,
...
@@ -107,14 +107,14 @@ struct testee : deserializer {
...
@@ -107,14 +107,14 @@ struct testee : deserializer {
log
+=
"begin optional variant field "
;
log
+=
"begin optional variant field "
;
log
.
insert
(
log
.
end
(),
name
.
begin
(),
name
.
end
());
log
.
insert
(
log
.
end
(),
name
.
begin
(),
name
.
end
());
is_present
=
false
;
is_present
=
false
;
return
ok
;
return
true
;
}
}
bool
end_field
()
override
{
bool
end_field
()
override
{
indent
-=
2
;
indent
-=
2
;
new_line
();
new_line
();
log
+=
"end field"
;
log
+=
"end field"
;
return
ok
;
return
true
;
}
}
bool
begin_tuple
(
size_t
size
)
override
{
bool
begin_tuple
(
size_t
size
)
override
{
...
@@ -122,28 +122,28 @@ struct testee : deserializer {
...
@@ -122,28 +122,28 @@ struct testee : deserializer {
indent
+=
2
;
indent
+=
2
;
log
+=
"begin tuple of size "
;
log
+=
"begin tuple of size "
;
log
+=
std
::
to_string
(
size
);
log
+=
std
::
to_string
(
size
);
return
ok
;
return
true
;
}
}
bool
end_tuple
()
override
{
bool
end_tuple
()
override
{
indent
-=
2
;
indent
-=
2
;
new_line
();
new_line
();
log
+=
"end tuple"
;
log
+=
"end tuple"
;
return
ok
;
return
true
;
}
}
bool
begin_key_value_pair
()
override
{
bool
begin_key_value_pair
()
override
{
new_line
();
new_line
();
indent
+=
2
;
indent
+=
2
;
log
+=
"begin key-value pair"
;
log
+=
"begin key-value pair"
;
return
ok
;
return
true
;
}
}
bool
end_key_value_pair
()
override
{
bool
end_key_value_pair
()
override
{
indent
-=
2
;
indent
-=
2
;
new_line
();
new_line
();
log
+=
"end key-value pair"
;
log
+=
"end key-value pair"
;
return
ok
;
return
true
;
}
}
bool
begin_sequence
(
size_t
&
size
)
override
{
bool
begin_sequence
(
size_t
&
size
)
override
{
...
@@ -152,14 +152,14 @@ struct testee : deserializer {
...
@@ -152,14 +152,14 @@ struct testee : deserializer {
indent
+=
2
;
indent
+=
2
;
log
+=
"begin sequence of size "
;
log
+=
"begin sequence of size "
;
log
+=
std
::
to_string
(
size
);
log
+=
std
::
to_string
(
size
);
return
ok
;
return
true
;
}
}
bool
end_sequence
()
override
{
bool
end_sequence
()
override
{
indent
-=
2
;
indent
-=
2
;
new_line
();
new_line
();
log
+=
"end sequence"
;
log
+=
"end sequence"
;
return
ok
;
return
true
;
}
}
bool
begin_associative_array
(
size_t
&
size
)
override
{
bool
begin_associative_array
(
size_t
&
size
)
override
{
...
@@ -168,21 +168,21 @@ struct testee : deserializer {
...
@@ -168,21 +168,21 @@ struct testee : deserializer {
indent
+=
2
;
indent
+=
2
;
log
+=
"begin associative array of size "
;
log
+=
"begin associative array of size "
;
log
+=
std
::
to_string
(
size
);
log
+=
std
::
to_string
(
size
);
return
ok
;
return
true
;
}
}
bool
end_associative_array
()
override
{
bool
end_associative_array
()
override
{
indent
-=
2
;
indent
-=
2
;
new_line
();
new_line
();
log
+=
"end associative array"
;
log
+=
"end associative array"
;
return
ok
;
return
true
;
}
}
bool
value
(
bool
&
x
)
override
{
bool
value
(
bool
&
x
)
override
{
new_line
();
new_line
();
log
+=
"bool value"
;
log
+=
"bool value"
;
x
=
false
;
x
=
false
;
return
ok
;
return
true
;
}
}
template
<
class
T
>
template
<
class
T
>
...
@@ -192,7 +192,14 @@ struct testee : deserializer {
...
@@ -192,7 +192,14 @@ struct testee : deserializer {
log
.
insert
(
log
.
end
(),
tn
.
begin
(),
tn
.
end
());
log
.
insert
(
log
.
end
(),
tn
.
begin
(),
tn
.
end
());
log
+=
" value"
;
log
+=
" value"
;
x
=
T
{};
x
=
T
{};
return
ok
;
return
true
;
}
bool
value
(
byte
&
x
)
override
{
new_line
();
log
+=
"byte value"
;
x
=
byte
{};
return
true
;
}
}
bool
value
(
int8_t
&
x
)
override
{
bool
value
(
int8_t
&
x
)
override
{
...
@@ -256,7 +263,7 @@ struct testee : deserializer {
...
@@ -256,7 +263,7 @@ struct testee : deserializer {
log
+=
"caf::span<caf::byte> value"
;
log
+=
"caf::span<caf::byte> value"
;
for
(
auto
&
x
:
xs
)
for
(
auto
&
x
:
xs
)
x
=
byte
{
0
};
x
=
byte
{
0
};
return
ok
;
return
true
;
}
}
};
};
...
@@ -330,7 +337,7 @@ end object)_");
...
@@ -330,7 +337,7 @@ end object)_");
CAF_TEST
(
load
inspectors
support
optional
)
{
CAF_TEST
(
load
inspectors
support
optional
)
{
optional
<
int32_t
>
x
;
optional
<
int32_t
>
x
;
CAF_CHECK_EQUAL
(
f
.
apply
_object
(
x
),
true
);
CAF_CHECK_EQUAL
(
f
.
apply
(
x
),
true
);
CAF_CHECK_EQUAL
(
f
.
log
,
R"_(
CAF_CHECK_EQUAL
(
f
.
log
,
R"_(
begin object anonymous
begin object anonymous
begin optional field value
begin optional field value
...
...
libcaf_core/test/message.cpp
View file @
8c8fb8be
...
@@ -110,19 +110,16 @@ CAF_TEST(to_string converts messages to strings) {
...
@@ -110,19 +110,16 @@ CAF_TEST(to_string converts messages to strings) {
CAF_CHECK_EQUAL
(
msg_as_string
(),
"message()"
);
CAF_CHECK_EQUAL
(
msg_as_string
(),
"message()"
);
CAF_CHECK_EQUAL
(
msg_as_string
(
"hello"
,
"world"
),
CAF_CHECK_EQUAL
(
msg_as_string
(
"hello"
,
"world"
),
R"__(message("hello", "world"))__"
);
R"__(message("hello", "world"))__"
);
CAF_CHECK_EQUAL
(
CAF_CHECK_EQUAL
(
msg_as_string
(
svec
{
"one"
,
"two"
,
"three"
}),
msg_as_string
(
svec
{
"one"
,
"two"
,
"three"
}),
R"__(message(["one", "two", "three"]))__"
);
R"__(message(std::vector<std::string>(["one", "two", "three"])))__"
);
CAF_CHECK_EQUAL
(
msg_as_string
(
svec
{
"one"
,
"two"
},
"three"
,
"four"
,
CAF_CHECK_EQUAL
(
msg_as_string
(
svec
{
"one"
,
"two"
},
"three"
,
"four"
,
svec
{
"five"
,
"six"
,
"seven"
}),
svec
{
"five"
,
"six"
,
"seven"
}),
R"__(message(std::vector<std::string>(["one", "two"])
, "three", "four", )__"
R"__(message(["one", "two"]
, "three", "four", )__"
R"__(std::vector<std::string>(["five", "six", "seven"])
))__"
);
R"__(["five", "six", "seven"]
))__"
);
auto
teststr
=
R"__(message("this is a \"test\""))__"
;
// fails inline on MSVC
auto
teststr
=
R"__(message("this is a \"test\""))__"
;
// fails inline on MSVC
CAF_CHECK_EQUAL
(
msg_as_string
(
R"__(this is a "test")__"
),
teststr
);
CAF_CHECK_EQUAL
(
msg_as_string
(
R"__(this is a "test")__"
),
teststr
);
CAF_CHECK_EQUAL
(
msg_as_string
(
make_tuple
(
1
,
2
,
3
),
4
,
5
),
CAF_CHECK_EQUAL
(
msg_as_string
(
make_tuple
(
1
,
2
,
3
),
4
,
5
),
"message(std::tuple<int32_t, int32_t, int32_t>([1, 2, 3]), "
"message([1, 2, 3], 4, 5)"
);
"int32_t(4), int32_t(5))"
);
CAF_CHECK_EQUAL
(
msg_as_string
(
s1
{}),
"message(s1([10, 20, 30]))"
);
CAF_CHECK_EQUAL
(
msg_as_string
(
s1
{}),
"message(s1([10, 20, 30]))"
);
s2
tmp
;
s2
tmp
;
tmp
.
value
[
0
][
1
]
=
100
;
tmp
.
value
[
0
][
1
]
=
100
;
...
...
libcaf_core/test/message_builder.cpp
View file @
8c8fb8be
...
@@ -47,7 +47,7 @@ CAF_TEST(message builder can build messages incrermenetally) {
...
@@ -47,7 +47,7 @@ CAF_TEST(message builder can build messages incrermenetally) {
CAF_CHECK_EQUAL
(
builder
.
size
(),
1u
);
CAF_CHECK_EQUAL
(
builder
.
size
(),
1u
);
CAF_CHECK_EQUAL
(
msg
.
types
(),
make_type_id_list
<
int32_t
>
());
CAF_CHECK_EQUAL
(
msg
.
types
(),
make_type_id_list
<
int32_t
>
());
CAF_CHECK_EQUAL
(
to_string
(
msg
.
types
()),
"[int32_t]"
);
CAF_CHECK_EQUAL
(
to_string
(
msg
.
types
()),
"[int32_t]"
);
CAF_CHECK_EQUAL
(
to_string
(
msg
),
"message(
int32_t(1)
)"
);
CAF_CHECK_EQUAL
(
to_string
(
msg
),
"message(
1
)"
);
}
}
STEP
(
"after adding [2, 3], the message is (1, 2, 3)"
)
{
STEP
(
"after adding [2, 3], the message is (1, 2, 3)"
)
{
std
::
vector
<
int32_t
>
xs
{
2
,
3
};
std
::
vector
<
int32_t
>
xs
{
2
,
3
};
...
@@ -57,15 +57,13 @@ CAF_TEST(message builder can build messages incrermenetally) {
...
@@ -57,15 +57,13 @@ CAF_TEST(message builder can build messages incrermenetally) {
CAF_CHECK_EQUAL
(
msg
.
types
(),
CAF_CHECK_EQUAL
(
msg
.
types
(),
(
make_type_id_list
<
int32_t
,
int32_t
,
int32_t
>
()));
(
make_type_id_list
<
int32_t
,
int32_t
,
int32_t
>
()));
CAF_CHECK_EQUAL
(
to_string
(
msg
.
types
()),
"[int32_t, int32_t, int32_t]"
);
CAF_CHECK_EQUAL
(
to_string
(
msg
.
types
()),
"[int32_t, int32_t, int32_t]"
);
CAF_CHECK_EQUAL
(
to_string
(
msg
),
CAF_CHECK_EQUAL
(
to_string
(
msg
),
"message(1, 2, 3)"
);
"message(int32_t(1), int32_t(2), int32_t(3))"
);
}
}
STEP
(
"moving the content to a message produces the same message again"
)
{
STEP
(
"moving the content to a message produces the same message again"
)
{
auto
msg
=
builder
.
move_to_message
();
auto
msg
=
builder
.
move_to_message
();
CAF_CHECK_EQUAL
(
msg
.
types
(),
CAF_CHECK_EQUAL
(
msg
.
types
(),
(
make_type_id_list
<
int32_t
,
int32_t
,
int32_t
>
()));
(
make_type_id_list
<
int32_t
,
int32_t
,
int32_t
>
()));
CAF_CHECK_EQUAL
(
to_string
(
msg
.
types
()),
"[int32_t, int32_t, int32_t]"
);
CAF_CHECK_EQUAL
(
to_string
(
msg
.
types
()),
"[int32_t, int32_t, int32_t]"
);
CAF_CHECK_EQUAL
(
to_string
(
msg
),
CAF_CHECK_EQUAL
(
to_string
(
msg
),
"message(1, 2, 3)"
);
"message(int32_t(1), int32_t(2), int32_t(3))"
);
}
}
}
}
libcaf_core/test/nasty.hpp
View file @
8c8fb8be
...
@@ -28,22 +28,18 @@ bool inspect(Inspector& f, weekday& x) {
...
@@ -28,22 +28,18 @@ bool inspect(Inspector& f, weekday& x) {
if
(
f
.
has_human_readable_format
())
{
if
(
f
.
has_human_readable_format
())
{
auto
get
=
[
&
x
]
{
return
to_string
(
x
);
};
auto
get
=
[
&
x
]
{
return
to_string
(
x
);
};
auto
set
=
[
&
x
](
std
::
string
str
)
{
return
parse
(
str
,
x
);
};
auto
set
=
[
&
x
](
std
::
string
str
)
{
return
parse
(
str
,
x
);
};
return
f
.
object
(
x
).
fields
(
f
.
field
(
"value"
,
get
,
set
)
);
return
f
.
apply
(
get
,
set
);
}
else
{
}
else
{
using
default_impl
=
caf
::
default_inspector_access
<
weekday
>
;
auto
get
=
[
&
x
]
{
return
static_cast
<
uint8_t
>
(
x
);
};
return
default_impl
::
apply_object
(
f
,
x
);
auto
set
=
[
&
x
](
uint8_t
val
)
{
}
if
(
val
<
7
)
{
}
x
=
static_cast
<
weekday
>
(
val
);
return
true
;
template
<
class
Inspector
>
bool
inspect_value
(
Inspector
&
f
,
weekday
&
x
)
{
if
(
f
.
has_human_readable_format
())
{
auto
get
=
[
&
x
]
{
return
to_string
(
x
);
};
auto
set
=
[
&
x
](
std
::
string
str
)
{
return
parse
(
str
,
x
);
};
return
f
.
apply_value
(
get
,
set
);
}
else
{
}
else
{
using
default_impl
=
caf
::
default_inspector_access
<
weekday
>
;
return
false
;
return
default_impl
::
apply_value
(
f
,
x
);
}
};
return
f
.
apply
(
get
,
set
);
}
}
}
}
...
...
libcaf_core/test/node_id.cpp
View file @
8c8fb8be
...
@@ -33,7 +33,7 @@ node_id roundtrip(node_id nid) {
...
@@ -33,7 +33,7 @@ node_id roundtrip(node_id nid) {
byte_buffer
buf
;
byte_buffer
buf
;
{
{
binary_serializer
sink
{
nullptr
,
buf
};
binary_serializer
sink
{
nullptr
,
buf
};
if
(
!
sink
.
apply
_object
(
nid
))
if
(
!
sink
.
apply
(
nid
))
CAF_FAIL
(
"serialization failed: "
<<
sink
.
get_error
());
CAF_FAIL
(
"serialization failed: "
<<
sink
.
get_error
());
}
}
if
(
buf
.
empty
())
if
(
buf
.
empty
())
...
@@ -41,7 +41,7 @@ node_id roundtrip(node_id nid) {
...
@@ -41,7 +41,7 @@ node_id roundtrip(node_id nid) {
node_id
result
;
node_id
result
;
{
{
binary_deserializer
source
{
nullptr
,
buf
};
binary_deserializer
source
{
nullptr
,
buf
};
if
(
!
source
.
apply
_object
(
result
))
if
(
!
source
.
apply
(
result
))
CAF_FAIL
(
"deserialization failed: "
<<
source
.
get_error
());
CAF_FAIL
(
"deserialization failed: "
<<
source
.
get_error
());
if
(
source
.
remaining
()
>
0
)
if
(
source
.
remaining
()
>
0
)
CAF_FAIL
(
"binary_serializer ignored part of its input"
);
CAF_FAIL
(
"binary_serializer ignored part of its input"
);
...
...
libcaf_core/test/save_inspector.cpp
View file @
8c8fb8be
...
@@ -54,7 +54,7 @@ struct testee : serializer {
...
@@ -54,7 +54,7 @@ struct testee : serializer {
log
+=
"next object type: "
;
log
+=
"next object type: "
;
auto
tn
=
detail
::
global_meta_object
(
type
)
->
type_name
;
auto
tn
=
detail
::
global_meta_object
(
type
)
->
type_name
;
log
.
insert
(
log
.
end
(),
tn
.
begin
(),
tn
.
end
());
log
.
insert
(
log
.
end
(),
tn
.
begin
(),
tn
.
end
());
return
ok
;
return
true
;
}
}
bool
begin_object
(
string_view
object_name
)
override
{
bool
begin_object
(
string_view
object_name
)
override
{
...
@@ -62,7 +62,7 @@ struct testee : serializer {
...
@@ -62,7 +62,7 @@ struct testee : serializer {
indent
+=
2
;
indent
+=
2
;
log
+=
"begin object "
;
log
+=
"begin object "
;
log
.
insert
(
log
.
end
(),
object_name
.
begin
(),
object_name
.
end
());
log
.
insert
(
log
.
end
(),
object_name
.
begin
(),
object_name
.
end
());
return
ok
;
return
true
;
}
}
bool
end_object
()
override
{
bool
end_object
()
override
{
...
@@ -71,7 +71,7 @@ struct testee : serializer {
...
@@ -71,7 +71,7 @@ struct testee : serializer {
indent
-=
2
;
indent
-=
2
;
new_line
();
new_line
();
log
+=
"end object"
;
log
+=
"end object"
;
return
ok
;
return
true
;
}
}
bool
begin_field
(
string_view
name
)
override
{
bool
begin_field
(
string_view
name
)
override
{
...
@@ -79,7 +79,7 @@ struct testee : serializer {
...
@@ -79,7 +79,7 @@ struct testee : serializer {
indent
+=
2
;
indent
+=
2
;
log
+=
"begin field "
;
log
+=
"begin field "
;
log
.
insert
(
log
.
end
(),
name
.
begin
(),
name
.
end
());
log
.
insert
(
log
.
end
(),
name
.
begin
(),
name
.
end
());
return
ok
;
return
true
;
}
}
bool
begin_field
(
string_view
name
,
bool
)
override
{
bool
begin_field
(
string_view
name
,
bool
)
override
{
...
@@ -87,7 +87,7 @@ struct testee : serializer {
...
@@ -87,7 +87,7 @@ struct testee : serializer {
indent
+=
2
;
indent
+=
2
;
log
+=
"begin optional field "
;
log
+=
"begin optional field "
;
log
.
insert
(
log
.
end
(),
name
.
begin
(),
name
.
end
());
log
.
insert
(
log
.
end
(),
name
.
begin
(),
name
.
end
());
return
ok
;
return
true
;
}
}
bool
begin_field
(
string_view
name
,
span
<
const
type_id_t
>
,
size_t
)
override
{
bool
begin_field
(
string_view
name
,
span
<
const
type_id_t
>
,
size_t
)
override
{
...
@@ -95,7 +95,7 @@ struct testee : serializer {
...
@@ -95,7 +95,7 @@ struct testee : serializer {
indent
+=
2
;
indent
+=
2
;
log
+=
"begin variant field "
;
log
+=
"begin variant field "
;
log
.
insert
(
log
.
end
(),
name
.
begin
(),
name
.
end
());
log
.
insert
(
log
.
end
(),
name
.
begin
(),
name
.
end
());
return
ok
;
return
true
;
}
}
bool
begin_field
(
string_view
name
,
bool
,
span
<
const
type_id_t
>
,
bool
begin_field
(
string_view
name
,
bool
,
span
<
const
type_id_t
>
,
...
@@ -104,7 +104,7 @@ struct testee : serializer {
...
@@ -104,7 +104,7 @@ struct testee : serializer {
indent
+=
2
;
indent
+=
2
;
log
+=
"begin optional variant field "
;
log
+=
"begin optional variant field "
;
log
.
insert
(
log
.
end
(),
name
.
begin
(),
name
.
end
());
log
.
insert
(
log
.
end
(),
name
.
begin
(),
name
.
end
());
return
ok
;
return
true
;
}
}
bool
end_field
()
override
{
bool
end_field
()
override
{
...
@@ -113,7 +113,7 @@ struct testee : serializer {
...
@@ -113,7 +113,7 @@ struct testee : serializer {
indent
-=
2
;
indent
-=
2
;
new_line
();
new_line
();
log
+=
"end field"
;
log
+=
"end field"
;
return
ok
;
return
true
;
}
}
bool
begin_tuple
(
size_t
size
)
override
{
bool
begin_tuple
(
size_t
size
)
override
{
...
@@ -121,7 +121,7 @@ struct testee : serializer {
...
@@ -121,7 +121,7 @@ struct testee : serializer {
indent
+=
2
;
indent
+=
2
;
log
+=
"begin tuple of size "
;
log
+=
"begin tuple of size "
;
log
+=
std
::
to_string
(
size
);
log
+=
std
::
to_string
(
size
);
return
ok
;
return
true
;
}
}
bool
end_tuple
()
override
{
bool
end_tuple
()
override
{
...
@@ -130,14 +130,14 @@ struct testee : serializer {
...
@@ -130,14 +130,14 @@ struct testee : serializer {
indent
-=
2
;
indent
-=
2
;
new_line
();
new_line
();
log
+=
"end tuple"
;
log
+=
"end tuple"
;
return
ok
;
return
true
;
}
}
bool
begin_key_value_pair
()
override
{
bool
begin_key_value_pair
()
override
{
new_line
();
new_line
();
indent
+=
2
;
indent
+=
2
;
log
+=
"begin key-value pair"
;
log
+=
"begin key-value pair"
;
return
ok
;
return
true
;
}
}
bool
end_key_value_pair
()
override
{
bool
end_key_value_pair
()
override
{
...
@@ -146,7 +146,7 @@ struct testee : serializer {
...
@@ -146,7 +146,7 @@ struct testee : serializer {
indent
-=
2
;
indent
-=
2
;
new_line
();
new_line
();
log
+=
"end key-value pair"
;
log
+=
"end key-value pair"
;
return
ok
;
return
true
;
}
}
bool
begin_sequence
(
size_t
size
)
override
{
bool
begin_sequence
(
size_t
size
)
override
{
...
@@ -154,7 +154,7 @@ struct testee : serializer {
...
@@ -154,7 +154,7 @@ struct testee : serializer {
indent
+=
2
;
indent
+=
2
;
log
+=
"begin sequence of size "
;
log
+=
"begin sequence of size "
;
log
+=
std
::
to_string
(
size
);
log
+=
std
::
to_string
(
size
);
return
ok
;
return
true
;
}
}
bool
end_sequence
()
override
{
bool
end_sequence
()
override
{
...
@@ -163,7 +163,7 @@ struct testee : serializer {
...
@@ -163,7 +163,7 @@ struct testee : serializer {
indent
-=
2
;
indent
-=
2
;
new_line
();
new_line
();
log
+=
"end sequence"
;
log
+=
"end sequence"
;
return
ok
;
return
true
;
}
}
bool
begin_associative_array
(
size_t
size
)
override
{
bool
begin_associative_array
(
size_t
size
)
override
{
...
@@ -171,7 +171,7 @@ struct testee : serializer {
...
@@ -171,7 +171,7 @@ struct testee : serializer {
indent
+=
2
;
indent
+=
2
;
log
+=
"begin associative array of size "
;
log
+=
"begin associative array of size "
;
log
+=
std
::
to_string
(
size
);
log
+=
std
::
to_string
(
size
);
return
ok
;
return
true
;
}
}
bool
end_associative_array
()
override
{
bool
end_associative_array
()
override
{
...
@@ -180,103 +180,109 @@ struct testee : serializer {
...
@@ -180,103 +180,109 @@ struct testee : serializer {
indent
-=
2
;
indent
-=
2
;
new_line
();
new_line
();
log
+=
"end associative array"
;
log
+=
"end associative array"
;
return
ok
;
return
true
;
}
bool
value
(
byte
)
override
{
new_line
();
log
+=
"byte value"
;
return
true
;
}
}
bool
value
(
bool
)
override
{
bool
value
(
bool
)
override
{
new_line
();
new_line
();
log
+=
"bool value"
;
log
+=
"bool value"
;
return
ok
;
return
true
;
}
}
bool
value
(
int8_t
)
override
{
bool
value
(
int8_t
)
override
{
new_line
();
new_line
();
log
+=
"int8_t value"
;
log
+=
"int8_t value"
;
return
ok
;
return
true
;
}
}
bool
value
(
uint8_t
)
override
{
bool
value
(
uint8_t
)
override
{
new_line
();
new_line
();
log
+=
"uint8_t value"
;
log
+=
"uint8_t value"
;
return
ok
;
return
true
;
}
}
bool
value
(
int16_t
)
override
{
bool
value
(
int16_t
)
override
{
new_line
();
new_line
();
log
+=
"int16_t value"
;
log
+=
"int16_t value"
;
return
ok
;
return
true
;
}
}
bool
value
(
uint16_t
)
override
{
bool
value
(
uint16_t
)
override
{
new_line
();
new_line
();
log
+=
"uint16_t value"
;
log
+=
"uint16_t value"
;
return
ok
;
return
true
;
}
}
bool
value
(
int32_t
)
override
{
bool
value
(
int32_t
)
override
{
new_line
();
new_line
();
log
+=
"int32_t value"
;
log
+=
"int32_t value"
;
return
ok
;
return
true
;
}
}
bool
value
(
uint32_t
)
override
{
bool
value
(
uint32_t
)
override
{
new_line
();
new_line
();
log
+=
"uint32_t value"
;
log
+=
"uint32_t value"
;
return
ok
;
return
true
;
}
}
bool
value
(
int64_t
)
override
{
bool
value
(
int64_t
)
override
{
new_line
();
new_line
();
log
+=
"int64_t value"
;
log
+=
"int64_t value"
;
return
ok
;
return
true
;
}
}
bool
value
(
uint64_t
)
override
{
bool
value
(
uint64_t
)
override
{
new_line
();
new_line
();
log
+=
"uint64_t value"
;
log
+=
"uint64_t value"
;
return
ok
;
return
true
;
}
}
bool
value
(
float
)
override
{
bool
value
(
float
)
override
{
new_line
();
new_line
();
log
+=
"float value"
;
log
+=
"float value"
;
return
ok
;
return
true
;
}
}
bool
value
(
double
)
override
{
bool
value
(
double
)
override
{
new_line
();
new_line
();
log
+=
"double value"
;
log
+=
"double value"
;
return
ok
;
return
true
;
}
}
bool
value
(
long
double
)
override
{
bool
value
(
long
double
)
override
{
new_line
();
new_line
();
log
+=
"long double value"
;
log
+=
"long double value"
;
return
ok
;
return
true
;
}
}
bool
value
(
string_view
)
override
{
bool
value
(
string_view
)
override
{
new_line
();
new_line
();
log
+=
"std::string value"
;
log
+=
"std::string value"
;
return
ok
;
return
true
;
}
}
bool
value
(
const
std
::
u16string
&
)
override
{
bool
value
(
const
std
::
u16string
&
)
override
{
new_line
();
new_line
();
log
+=
"std::u16string value"
;
log
+=
"std::u16string value"
;
return
ok
;
return
true
;
}
}
bool
value
(
const
std
::
u32string
&
)
override
{
bool
value
(
const
std
::
u32string
&
)
override
{
new_line
();
new_line
();
log
+=
"std::u32string value"
;
log
+=
"std::u32string value"
;
return
ok
;
return
true
;
}
}
bool
value
(
span
<
const
byte
>
)
override
{
bool
value
(
span
<
const
byte
>
)
override
{
new_line
();
new_line
();
log
+=
"byte_span value"
;
log
+=
"byte_span value"
;
return
ok
;
return
true
;
}
}
};
};
...
@@ -290,7 +296,7 @@ CAF_TEST_FIXTURE_SCOPE(load_inspector_tests, fixture)
...
@@ -290,7 +296,7 @@ CAF_TEST_FIXTURE_SCOPE(load_inspector_tests, fixture)
CAF_TEST
(
save
inspectors
can
visit
C
arrays
)
{
CAF_TEST
(
save
inspectors
can
visit
C
arrays
)
{
int32_t
xs
[]
=
{
1
,
2
,
3
};
int32_t
xs
[]
=
{
1
,
2
,
3
};
CAF_CHECK_EQUAL
(
detail
::
save
_value
(
f
,
xs
),
true
);
CAF_CHECK_EQUAL
(
detail
::
save
(
f
,
xs
),
true
);
CAF_CHECK_EQUAL
(
f
.
log
,
R"_(
CAF_CHECK_EQUAL
(
f
.
log
,
R"_(
begin tuple of size 3
begin tuple of size 3
int32_t value
int32_t value
...
@@ -436,7 +442,7 @@ end object)_");
...
@@ -436,7 +442,7 @@ end object)_");
CAF_TEST
(
save
inspectors
support
optional
)
{
CAF_TEST
(
save
inspectors
support
optional
)
{
optional
<
int32_t
>
x
;
optional
<
int32_t
>
x
;
CAF_CHECK_EQUAL
(
f
.
apply
_object
(
x
),
true
);
CAF_CHECK_EQUAL
(
f
.
apply
(
x
),
true
);
CAF_CHECK_EQUAL
(
f
.
log
,
R"_(
CAF_CHECK_EQUAL
(
f
.
log
,
R"_(
begin object anonymous
begin object anonymous
begin optional field value
begin optional field value
...
@@ -717,21 +723,9 @@ begin object message
...
@@ -717,21 +723,9 @@ begin object message
end field
end field
begin field values
begin field values
begin tuple of size 3
begin tuple of size 3
begin object int32_t
begin field value
int32_t value
int32_t value
end field
end object
begin object std::string
begin field value
std::string value
std::string value
end field
end object
begin object double
begin field value
double value
double value
end field
end object
end tuple
end tuple
end field
end field
end object)_"
);
end object)_"
);
...
@@ -744,23 +738,11 @@ begin object message
...
@@ -744,23 +738,11 @@ begin object message
begin field values
begin field values
begin sequence of size 3
begin sequence of size 3
next object type: int32_t
next object type: int32_t
begin object int32_t
begin field value
int32_t value
int32_t value
end field
end object
next object type: std::string
next object type: std::string
begin object std::string
begin field value
std::string value
std::string value
end field
end object
next object type: double
next object type: double
begin object double
begin field value
double value
double value
end field
end object
end sequence
end sequence
end field
end field
end object)_"
);
end object)_"
);
...
...
libcaf_core/test/serialization.cpp
View file @
8c8fb8be
...
@@ -30,6 +30,7 @@
...
@@ -30,6 +30,7 @@
#include <limits>
#include <limits>
#include <list>
#include <list>
#include <locale>
#include <locale>
#include <map>
#include <memory>
#include <memory>
#include <new>
#include <new>
#include <set>
#include <set>
...
@@ -52,17 +53,66 @@
...
@@ -52,17 +53,66 @@
#include "caf/detail/ieee_754.hpp"
#include "caf/detail/ieee_754.hpp"
#include "caf/detail/int_list.hpp"
#include "caf/detail/int_list.hpp"
#include "caf/detail/safe_equal.hpp"
#include "caf/detail/safe_equal.hpp"
#include "caf/detail/stringification_inspector.hpp"
#include "caf/detail/type_traits.hpp"
#include "caf/detail/type_traits.hpp"
#include "caf/event_based_actor.hpp"
#include "caf/event_based_actor.hpp"
#include "caf/message.hpp"
#include "caf/message.hpp"
#include "caf/message_handler.hpp"
#include "caf/message_handler.hpp"
#include "caf/proxy_registry.hpp"
#include "caf/proxy_registry.hpp"
#include "caf/ref_counted.hpp"
#include "caf/ref_counted.hpp"
#include "caf/sec.hpp"
#include "caf/serializer.hpp"
#include "caf/serializer.hpp"
#include "caf/variant.hpp"
#include "caf/variant.hpp"
struct
opaque
{
int
secret
;
};
CAF_ALLOW_UNSAFE_MESSAGE_TYPE
(
opaque
)
struct
the_great_unknown
{
int
secret
;
};
using
namespace
caf
;
using
namespace
caf
;
using
bs
=
binary_serializer
;
using
si
=
detail
::
stringification_inspector
;
using
iat
=
inspector_access_type
;
template
<
class
Inspector
,
class
T
>
struct
access_of
{
template
<
class
What
>
static
constexpr
bool
is
=
std
::
is_same
<
decltype
(
inspect_access_type
<
Inspector
,
T
>
()),
What
>::
value
;
};
static_assert
(
access_of
<
bs
,
variant
<
int
,
double
>>::
is
<
iat
::
specialization
>
);
static_assert
(
access_of
<
bs
,
sec
>::
is
<
iat
::
inspect
>
);
static_assert
(
access_of
<
bs
,
int
>::
is
<
iat
::
builtin
>
);
static_assert
(
access_of
<
bs
,
dummy_tag_type
>::
is
<
iat
::
empty
>
);
static_assert
(
access_of
<
bs
,
opaque
>::
is
<
iat
::
unsafe
>
);
static_assert
(
access_of
<
bs
,
std
::
tuple
<
int
,
double
>>::
is
<
iat
::
tuple
>
);
static_assert
(
access_of
<
bs
,
std
::
map
<
int
,
int
>>::
is
<
iat
::
map
>
);
static_assert
(
access_of
<
bs
,
std
::
vector
<
bool
>>::
is
<
iat
::
list
>
);
static_assert
(
access_of
<
bs
,
the_great_unknown
>::
is
<
iat
::
none
>
);
// The stringification inspector picks up to_string via builtin_inspect.
static_assert
(
access_of
<
si
,
sec
>::
is
<
iat
::
builtin_inspect
>
);
static_assert
(
access_of
<
si
,
timespan
>::
is
<
iat
::
builtin_inspect
>
);
const
char
*
test_enum_strings
[]
=
{
const
char
*
test_enum_strings
[]
=
{
"a"
,
"a"
,
"b"
,
"b"
,
...
@@ -111,7 +161,7 @@ struct fixture : test_coordinator_fixture<> {
...
@@ -111,7 +161,7 @@ struct fixture : test_coordinator_fixture<> {
byte_buffer
serialize
(
const
Ts
&
...
xs
)
{
byte_buffer
serialize
(
const
Ts
&
...
xs
)
{
byte_buffer
buf
;
byte_buffer
buf
;
binary_serializer
sink
{
sys
,
buf
};
binary_serializer
sink
{
sys
,
buf
};
if
(
!
sink
.
apply_objects
(
xs
...))
if
(
!
(
sink
.
apply
(
xs
)
&&
...))
CAF_FAIL
(
"serialization failed: "
CAF_FAIL
(
"serialization failed: "
<<
sink
.
get_error
()
<<
sink
.
get_error
()
<<
", data: "
<<
deep_to_string
(
std
::
forward_as_tuple
(
xs
...)));
<<
", data: "
<<
deep_to_string
(
std
::
forward_as_tuple
(
xs
...)));
...
@@ -121,7 +171,7 @@ struct fixture : test_coordinator_fixture<> {
...
@@ -121,7 +171,7 @@ struct fixture : test_coordinator_fixture<> {
template
<
class
...
Ts
>
template
<
class
...
Ts
>
void
deserialize
(
const
byte_buffer
&
buf
,
Ts
&
...
xs
)
{
void
deserialize
(
const
byte_buffer
&
buf
,
Ts
&
...
xs
)
{
binary_deserializer
source
{
sys
,
buf
};
binary_deserializer
source
{
sys
,
buf
};
if
(
!
source
.
apply_objects
(
xs
...))
if
(
!
(
source
.
apply
(
xs
)
&&
...))
CAF_FAIL
(
"deserialization failed: "
<<
source
.
get_error
());
CAF_FAIL
(
"deserialization failed: "
<<
source
.
get_error
());
}
}
...
...
libcaf_core/test/tracing_data.cpp
View file @
8c8fb8be
...
@@ -47,11 +47,11 @@ public:
...
@@ -47,11 +47,11 @@ public:
}
}
bool
serialize
(
serializer
&
sink
)
const
override
{
bool
serialize
(
serializer
&
sink
)
const
override
{
return
sink
.
apply
_object
(
value
);
return
sink
.
apply
(
value
);
}
}
bool
serialize
(
binary_serializer
&
sink
)
const
override
{
bool
serialize
(
binary_serializer
&
sink
)
const
override
{
return
sink
.
apply
_object
(
value
);
return
sink
.
apply
(
value
);
}
}
};
};
...
@@ -72,7 +72,7 @@ private:
...
@@ -72,7 +72,7 @@ private:
bool
deserialize_impl
(
Deserializer
&
source
,
bool
deserialize_impl
(
Deserializer
&
source
,
std
::
unique_ptr
<
tracing_data
>&
dst
)
const
{
std
::
unique_ptr
<
tracing_data
>&
dst
)
const
{
string
value
;
string
value
;
if
(
!
source
.
apply
_object
(
value
))
if
(
!
source
.
apply
(
value
))
return
false
;
return
false
;
dst
.
reset
(
new
dummy_tracing_data
(
std
::
move
(
value
)));
dst
.
reset
(
new
dummy_tracing_data
(
std
::
move
(
value
)));
return
true
;
return
true
;
...
@@ -193,10 +193,10 @@ CAF_TEST(tracing data is serializable) {
...
@@ -193,10 +193,10 @@ CAF_TEST(tracing data is serializable) {
byte_buffer
buf
;
byte_buffer
buf
;
binary_serializer
sink
{
sys
,
buf
};
binary_serializer
sink
{
sys
,
buf
};
tracing_data_ptr
data
{
new
dummy_tracing_data
(
"iTrace"
)};
tracing_data_ptr
data
{
new
dummy_tracing_data
(
"iTrace"
)};
CAF_CHECK
(
sink
.
apply
_object
(
data
));
CAF_CHECK
(
sink
.
apply
(
data
));
binary_deserializer
source
{
sys
,
buf
};
binary_deserializer
source
{
sys
,
buf
};
tracing_data_ptr
copy
;
tracing_data_ptr
copy
;
CAF_CHECK
(
source
.
apply
_object
(
copy
));
CAF_CHECK
(
source
.
apply
(
copy
));
CAF_REQUIRE_NOT_EQUAL
(
copy
.
get
(),
nullptr
);
CAF_REQUIRE_NOT_EQUAL
(
copy
.
get
(),
nullptr
);
CAF_CHECK_EQUAL
(
dynamic_cast
<
dummy_tracing_data
&>
(
*
copy
).
value
,
"iTrace"
);
CAF_CHECK_EQUAL
(
dynamic_cast
<
dummy_tracing_data
&>
(
*
copy
).
value
,
"iTrace"
);
}
}
...
...
libcaf_core/test/uri.cpp
View file @
8c8fb8be
...
@@ -133,7 +133,7 @@ struct fixture {
...
@@ -133,7 +133,7 @@ struct fixture {
byte_buffer
serialize
(
uri
x
)
{
byte_buffer
serialize
(
uri
x
)
{
byte_buffer
buf
;
byte_buffer
buf
;
binary_serializer
sink
{
nullptr
,
buf
};
binary_serializer
sink
{
nullptr
,
buf
};
if
(
!
sink
.
apply
_objects
(
x
))
if
(
!
sink
.
apply
(
x
))
CAF_FAIL
(
"unable to serialize "
<<
x
<<
": "
<<
sink
.
get_error
());
CAF_FAIL
(
"unable to serialize "
<<
x
<<
": "
<<
sink
.
get_error
());
return
buf
;
return
buf
;
}
}
...
@@ -141,7 +141,7 @@ struct fixture {
...
@@ -141,7 +141,7 @@ struct fixture {
uri
deserialize
(
byte_buffer
buf
)
{
uri
deserialize
(
byte_buffer
buf
)
{
uri
result
;
uri
result
;
binary_deserializer
source
{
nullptr
,
buf
};
binary_deserializer
source
{
nullptr
,
buf
};
if
(
!
source
.
apply
_objects
(
result
))
if
(
!
source
.
apply
(
result
))
CAF_FAIL
(
"unable to deserialize from buffer: "
<<
source
.
get_error
());
CAF_FAIL
(
"unable to deserialize from buffer: "
<<
source
.
get_error
());
return
result
;
return
result
;
}
}
...
...
libcaf_io/caf/io/basp/message_type.hpp
View file @
8c8fb8be
...
@@ -20,7 +20,9 @@
...
@@ -20,7 +20,9 @@
#include <cstdint>
#include <cstdint>
#include <string>
#include <string>
#include <type_traits>
#include "caf/default_enum_inspect.hpp"
#include "caf/detail/io_export.hpp"
#include "caf/detail/io_export.hpp"
namespace
caf
::
io
::
basp
{
namespace
caf
::
io
::
basp
{
...
@@ -76,6 +78,16 @@ enum class message_type : uint8_t {
...
@@ -76,6 +78,16 @@ enum class message_type : uint8_t {
CAF_IO_EXPORT
std
::
string
to_string
(
message_type
);
CAF_IO_EXPORT
std
::
string
to_string
(
message_type
);
CAF_IO_EXPORT
bool
from_string
(
string_view
,
message_type
&
);
CAF_IO_EXPORT
bool
from_integer
(
std
::
underlying_type_t
<
message_type
>
,
message_type
&
);
template
<
class
Inssector
>
bool
inspect
(
Inssector
&
f
,
message_type
&
x
)
{
return
default_enum_inspect
(
f
,
x
);
}
/// @}
/// @}
}
// namespace caf::io::basp
}
// namespace caf::io::basp
libcaf_io/caf/io/basp/remote_message_handler.hpp
View file @
8c8fb8be
...
@@ -79,12 +79,12 @@ public:
...
@@ -79,12 +79,12 @@ public:
if
(
dref
.
hdr_
.
operation
==
basp
::
message_type
::
routed_message
)
{
if
(
dref
.
hdr_
.
operation
==
basp
::
message_type
::
routed_message
)
{
node_id
src_node
;
node_id
src_node
;
node_id
dst_node
;
node_id
dst_node
;
if
(
!
source
.
apply
_object
(
src_node
))
{
if
(
!
source
.
apply
(
src_node
))
{
CAF_LOG_ERROR
(
CAF_LOG_ERROR
(
"failed to read source of routed message:"
<<
source
.
get_error
());
"failed to read source of routed message:"
<<
source
.
get_error
());
return
;
return
;
}
}
if
(
!
source
.
apply
_object
(
dst_node
))
{
if
(
!
source
.
apply
(
dst_node
))
{
CAF_LOG_ERROR
(
"failed to read destination of routed message:"
CAF_LOG_ERROR
(
"failed to read destination of routed message:"
<<
source
.
get_error
());
<<
source
.
get_error
());
return
;
return
;
...
@@ -108,13 +108,13 @@ public:
...
@@ -108,13 +108,13 @@ public:
return
;
return
;
}
}
// Get the remainder of the message.
// Get the remainder of the message.
if
(
!
source
.
apply
_object
(
stages
))
{
if
(
!
source
.
apply
(
stages
))
{
CAF_LOG_ERROR
(
"failed to read stages:"
<<
source
.
get_error
());
CAF_LOG_ERROR
(
"failed to read stages:"
<<
source
.
get_error
());
return
;
return
;
}
}
auto
&
mm_metrics
=
ctx
->
system
().
middleman
().
metric_singletons
;
auto
&
mm_metrics
=
ctx
->
system
().
middleman
().
metric_singletons
;
auto
t0
=
telemetry
::
timer
::
clock_type
::
now
();
auto
t0
=
telemetry
::
timer
::
clock_type
::
now
();
if
(
!
source
.
apply
_objects
(
msg
))
{
if
(
!
source
.
apply
(
msg
))
{
CAF_LOG_ERROR
(
"failed to read message content:"
<<
source
.
get_error
());
CAF_LOG_ERROR
(
"failed to read message content:"
<<
source
.
get_error
());
return
;
return
;
}
}
...
...
libcaf_io/caf/io/network/protocol.hpp
View file @
8c8fb8be
...
@@ -40,10 +40,32 @@ inline std::string to_string(protocol::transport x) {
...
@@ -40,10 +40,32 @@ inline std::string to_string(protocol::transport x) {
return
x
==
protocol
::
tcp
?
"TCP"
:
"UDP"
;
return
x
==
protocol
::
tcp
?
"TCP"
:
"UDP"
;
}
}
template
<
class
Inspector
>
bool
inspect
(
Inspector
&
f
,
protocol
::
transport
&
x
)
{
using
integer_type
=
std
::
underlying_type_t
<
protocol
::
transport
>
;
auto
get
=
[
&
x
]
{
return
static_cast
<
integer_type
>
(
x
);
};
auto
set
=
[
&
x
](
integer_type
val
)
{
x
=
static_cast
<
protocol
::
transport
>
(
val
);
return
true
;
};
return
f
.
apply
(
get
,
set
);
}
inline
std
::
string
to_string
(
protocol
::
network
x
)
{
inline
std
::
string
to_string
(
protocol
::
network
x
)
{
return
x
==
protocol
::
ipv4
?
"IPv4"
:
"IPv6"
;
return
x
==
protocol
::
ipv4
?
"IPv4"
:
"IPv6"
;
}
}
template
<
class
Inspector
>
bool
inspect
(
Inspector
&
f
,
protocol
::
network
&
x
)
{
using
integer_type
=
std
::
underlying_type_t
<
protocol
::
network
>
;
auto
get
=
[
&
x
]
{
return
static_cast
<
integer_type
>
(
x
);
};
auto
set
=
[
&
x
](
integer_type
val
)
{
x
=
static_cast
<
protocol
::
network
>
(
val
);
return
true
;
};
return
f
.
apply
(
get
,
set
);
}
template
<
class
Inspector
>
template
<
class
Inspector
>
bool
inspect
(
Inspector
&
f
,
protocol
&
x
)
{
bool
inspect
(
Inspector
&
f
,
protocol
&
x
)
{
return
f
.
object
(
x
).
fields
(
f
.
field
(
"trans"
,
x
.
trans
),
f
.
field
(
"net"
,
x
.
net
));
return
f
.
object
(
x
).
fields
(
f
.
field
(
"trans"
,
x
.
trans
),
f
.
field
(
"net"
,
x
.
net
));
...
...
libcaf_io/src/io/basp/instance.cpp
View file @
8c8fb8be
...
@@ -73,7 +73,7 @@ connection_state instance::handle(execution_unit* ctx, new_data_msg& dm,
...
@@ -73,7 +73,7 @@ connection_state instance::handle(execution_unit* ctx, new_data_msg& dm,
}
}
}
else
{
}
else
{
binary_deserializer
source
{
ctx
,
dm
.
buf
};
binary_deserializer
source
{
ctx
,
dm
.
buf
};
if
(
!
source
.
apply
_object
(
hdr
))
{
if
(
!
source
.
apply
(
hdr
))
{
CAF_LOG_WARNING
(
"failed to receive header:"
<<
source
.
get_error
());
CAF_LOG_WARNING
(
"failed to receive header:"
<<
source
.
get_error
());
return
err
(
malformed_basp_message
);
return
err
(
malformed_basp_message
);
}
}
...
@@ -185,7 +185,7 @@ bool instance::dispatch(execution_unit* ctx, const strong_actor_ptr& sender,
...
@@ -185,7 +185,7 @@ bool instance::dispatch(execution_unit* ctx, const strong_actor_ptr& sender,
sender
?
sender
->
id
()
:
invalid_actor_id
,
sender
?
sender
->
id
()
:
invalid_actor_id
,
dest_actor
};
dest_actor
};
auto
writer
=
make_callback
([
&
](
binary_serializer
&
sink
)
{
//
auto
writer
=
make_callback
([
&
](
binary_serializer
&
sink
)
{
//
return
sink
.
apply
_objects
(
forwarding_stack
,
msg
);
return
sink
.
apply
(
forwarding_stack
)
&&
sink
.
apply
(
msg
);
});
});
write
(
ctx
,
callee_
.
get_buffer
(
path
->
hdl
),
hdr
,
&
writer
);
write
(
ctx
,
callee_
.
get_buffer
(
path
->
hdl
),
hdr
,
&
writer
);
}
else
{
}
else
{
...
@@ -199,7 +199,10 @@ bool instance::dispatch(execution_unit* ctx, const strong_actor_ptr& sender,
...
@@ -199,7 +199,10 @@ bool instance::dispatch(execution_unit* ctx, const strong_actor_ptr& sender,
CAF_LOG_DEBUG
(
"send routed message: "
CAF_LOG_DEBUG
(
"send routed message: "
<<
CAF_ARG
(
source_node
)
<<
CAF_ARG
(
dest_node
)
<<
CAF_ARG
(
source_node
)
<<
CAF_ARG
(
dest_node
)
<<
CAF_ARG
(
forwarding_stack
)
<<
CAF_ARG
(
msg
));
<<
CAF_ARG
(
forwarding_stack
)
<<
CAF_ARG
(
msg
));
return
sink
.
apply_objects
(
source_node
,
dest_node
,
forwarding_stack
,
msg
);
return
sink
.
apply
(
source_node
)
//
&&
sink
.
apply
(
dest_node
)
//
&&
sink
.
apply
(
forwarding_stack
)
//
&&
sink
.
apply
(
msg
);
});
});
write
(
ctx
,
callee_
.
get_buffer
(
path
->
hdl
),
hdr
,
&
writer
);
write
(
ctx
,
callee_
.
get_buffer
(
path
->
hdl
),
hdr
,
&
writer
);
}
}
...
@@ -229,7 +232,7 @@ void instance::write(execution_unit* ctx, byte_buffer& buf, header& hdr,
...
@@ -229,7 +232,7 @@ void instance::write(execution_unit* ctx, byte_buffer& buf, header& hdr,
mm_metrics
.
outbound_messages_size
->
observe
(
signed_payload_len
);
mm_metrics
.
outbound_messages_size
->
observe
(
signed_payload_len
);
hdr
.
payload_len
=
static_cast
<
uint32_t
>
(
payload_len
);
hdr
.
payload_len
=
static_cast
<
uint32_t
>
(
payload_len
);
}
}
if
(
!
sink
.
apply
_objects
(
hdr
))
if
(
!
sink
.
apply
(
hdr
))
CAF_LOG_ERROR
(
sink
.
get_error
());
CAF_LOG_ERROR
(
sink
.
get_error
());
}
}
...
@@ -258,7 +261,10 @@ void instance::write_server_handshake(execution_unit* ctx, byte_buffer& out_buf,
...
@@ -258,7 +261,10 @@ void instance::write_server_handshake(execution_unit* ctx, byte_buffer& out_buf,
aid
=
pa
->
first
->
id
();
aid
=
pa
->
first
->
id
();
iface
=
pa
->
second
;
iface
=
pa
->
second
;
}
}
return
sink
.
apply_objects
(
this_node_
,
app_ids
,
aid
,
iface
);
return
sink
.
apply
(
this_node_
)
//
&&
sink
.
apply
(
app_ids
)
//
&&
sink
.
apply
(
aid
)
//
&&
sink
.
apply
(
iface
);
});
});
header
hdr
{
message_type
::
server_handshake
,
header
hdr
{
message_type
::
server_handshake
,
0
,
0
,
...
@@ -271,7 +277,7 @@ void instance::write_server_handshake(execution_unit* ctx, byte_buffer& out_buf,
...
@@ -271,7 +277,7 @@ void instance::write_server_handshake(execution_unit* ctx, byte_buffer& out_buf,
void
instance
::
write_client_handshake
(
execution_unit
*
ctx
,
byte_buffer
&
buf
)
{
void
instance
::
write_client_handshake
(
execution_unit
*
ctx
,
byte_buffer
&
buf
)
{
auto
writer
=
make_callback
([
&
](
binary_serializer
&
sink
)
{
//
auto
writer
=
make_callback
([
&
](
binary_serializer
&
sink
)
{
//
return
sink
.
apply
_objects
(
this_node_
);
return
sink
.
apply
(
this_node_
);
});
});
header
hdr
{
message_type
::
client_handshake
,
header
hdr
{
message_type
::
client_handshake
,
0
,
0
,
...
@@ -286,7 +292,7 @@ void instance::write_monitor_message(execution_unit* ctx, byte_buffer& buf,
...
@@ -286,7 +292,7 @@ void instance::write_monitor_message(execution_unit* ctx, byte_buffer& buf,
const
node_id
&
dest_node
,
actor_id
aid
)
{
const
node_id
&
dest_node
,
actor_id
aid
)
{
CAF_LOG_TRACE
(
CAF_ARG
(
dest_node
)
<<
CAF_ARG
(
aid
));
CAF_LOG_TRACE
(
CAF_ARG
(
dest_node
)
<<
CAF_ARG
(
aid
));
auto
writer
=
make_callback
([
&
](
binary_serializer
&
sink
)
{
//
auto
writer
=
make_callback
([
&
](
binary_serializer
&
sink
)
{
//
return
sink
.
apply
_objects
(
this_node_
,
dest_node
);
return
sink
.
apply
(
this_node_
)
&&
sink
.
apply
(
dest_node
);
});
});
header
hdr
{
message_type
::
monitor_message
,
0
,
0
,
0
,
invalid_actor_id
,
aid
};
header
hdr
{
message_type
::
monitor_message
,
0
,
0
,
0
,
invalid_actor_id
,
aid
};
write
(
ctx
,
buf
,
hdr
,
&
writer
);
write
(
ctx
,
buf
,
hdr
,
&
writer
);
...
@@ -296,8 +302,8 @@ void instance::write_down_message(execution_unit* ctx, byte_buffer& buf,
...
@@ -296,8 +302,8 @@ void instance::write_down_message(execution_unit* ctx, byte_buffer& buf,
const
node_id
&
dest_node
,
actor_id
aid
,
const
node_id
&
dest_node
,
actor_id
aid
,
const
error
&
rsn
)
{
const
error
&
rsn
)
{
CAF_LOG_TRACE
(
CAF_ARG
(
dest_node
)
<<
CAF_ARG
(
aid
)
<<
CAF_ARG
(
rsn
));
CAF_LOG_TRACE
(
CAF_ARG
(
dest_node
)
<<
CAF_ARG
(
aid
)
<<
CAF_ARG
(
rsn
));
auto
writer
=
make_callback
([
&
](
binary_serializer
&
sink
)
{
//
auto
writer
=
make_callback
([
&
](
binary_serializer
&
sink
)
{
return
sink
.
apply
_objects
(
this_node_
,
dest_node
,
rsn
);
return
sink
.
apply
(
this_node_
)
&&
sink
.
apply
(
dest_node
)
&&
sink
.
apply
(
rsn
);
});
});
header
hdr
{
message_type
::
down_message
,
0
,
0
,
0
,
aid
,
invalid_actor_id
};
header
hdr
{
message_type
::
down_message
,
0
,
0
,
0
,
aid
,
invalid_actor_id
};
write
(
ctx
,
buf
,
hdr
,
&
writer
);
write
(
ctx
,
buf
,
hdr
,
&
writer
);
...
@@ -333,7 +339,10 @@ connection_state instance::handle(execution_unit* ctx, connection_handle hdl,
...
@@ -333,7 +339,10 @@ connection_state instance::handle(execution_unit* ctx, connection_handle hdl,
string_list
app_ids
;
string_list
app_ids
;
actor_id
aid
=
invalid_actor_id
;
actor_id
aid
=
invalid_actor_id
;
std
::
set
<
std
::
string
>
sigs
;
std
::
set
<
std
::
string
>
sigs
;
if
(
!
source
.
apply_objects
(
source_node
,
app_ids
,
aid
,
sigs
))
{
if
(
!
source
.
apply
(
source_node
)
//
||
!
source
.
apply
(
app_ids
)
//
||
!
source
.
apply
(
aid
)
//
||
!
source
.
apply
(
sigs
))
{
CAF_LOG_WARNING
(
"unable to deserialize payload of server handshake:"
CAF_LOG_WARNING
(
"unable to deserialize payload of server handshake:"
<<
source
.
get_error
());
<<
source
.
get_error
());
return
serializing_basp_payload_failed
;
return
serializing_basp_payload_failed
;
...
@@ -383,7 +392,7 @@ connection_state instance::handle(execution_unit* ctx, connection_handle hdl,
...
@@ -383,7 +392,7 @@ connection_state instance::handle(execution_unit* ctx, connection_handle hdl,
// Deserialize payload.
// Deserialize payload.
binary_deserializer
source
{
ctx
,
*
payload
};
binary_deserializer
source
{
ctx
,
*
payload
};
node_id
source_node
;
node_id
source_node
;
if
(
!
source
.
apply
_objects
(
source_node
))
{
if
(
!
source
.
apply
(
source_node
))
{
CAF_LOG_WARNING
(
"unable to deserialize payload of client handshake:"
CAF_LOG_WARNING
(
"unable to deserialize payload of client handshake:"
<<
source
.
get_error
());
<<
source
.
get_error
());
return
serializing_basp_payload_failed
;
return
serializing_basp_payload_failed
;
...
@@ -406,7 +415,7 @@ connection_state instance::handle(execution_unit* ctx, connection_handle hdl,
...
@@ -406,7 +415,7 @@ connection_state instance::handle(execution_unit* ctx, connection_handle hdl,
binary_deserializer
source
{
ctx
,
*
payload
};
binary_deserializer
source
{
ctx
,
*
payload
};
node_id
source_node
;
node_id
source_node
;
node_id
dest_node
;
node_id
dest_node
;
if
(
!
source
.
apply
_objects
(
source_node
,
dest_node
))
{
if
(
!
source
.
apply
(
source_node
)
||
!
source
.
apply
(
dest_node
))
{
CAF_LOG_WARNING
(
CAF_LOG_WARNING
(
"unable to deserialize source and destination for routed message:"
"unable to deserialize source and destination for routed message:"
<<
source
.
get_error
());
<<
source
.
get_error
());
...
@@ -465,7 +474,7 @@ connection_state instance::handle(execution_unit* ctx, connection_handle hdl,
...
@@ -465,7 +474,7 @@ connection_state instance::handle(execution_unit* ctx, connection_handle hdl,
binary_deserializer
source
{
ctx
,
*
payload
};
binary_deserializer
source
{
ctx
,
*
payload
};
node_id
source_node
;
node_id
source_node
;
node_id
dest_node
;
node_id
dest_node
;
if
(
!
source
.
apply
_objects
(
source_node
,
dest_node
))
{
if
(
!
source
.
apply
(
source_node
)
||
!
source
.
apply
(
dest_node
))
{
CAF_LOG_WARNING
(
"unable to deserialize payload of monitor message:"
CAF_LOG_WARNING
(
"unable to deserialize payload of monitor message:"
<<
source
.
get_error
());
<<
source
.
get_error
());
return
serializing_basp_payload_failed
;
return
serializing_basp_payload_failed
;
...
@@ -482,7 +491,9 @@ connection_state instance::handle(execution_unit* ctx, connection_handle hdl,
...
@@ -482,7 +491,9 @@ connection_state instance::handle(execution_unit* ctx, connection_handle hdl,
node_id
source_node
;
node_id
source_node
;
node_id
dest_node
;
node_id
dest_node
;
error
fail_state
;
error
fail_state
;
if
(
!
source
.
apply_objects
(
source_node
,
dest_node
,
fail_state
))
{
if
(
!
source
.
apply
(
source_node
)
//
||
!
source
.
apply
(
dest_node
)
//
||
!
source
.
apply
(
fail_state
))
{
CAF_LOG_WARNING
(
"unable to deserialize payload of down message:"
CAF_LOG_WARNING
(
"unable to deserialize payload of down message:"
<<
source
.
get_error
());
<<
source
.
get_error
());
return
serializing_basp_payload_failed
;
return
serializing_basp_payload_failed
;
...
@@ -520,7 +531,7 @@ void instance::forward(execution_unit* ctx, const node_id& dest_node,
...
@@ -520,7 +531,7 @@ void instance::forward(execution_unit* ctx, const node_id& dest_node,
auto
path
=
lookup
(
dest_node
);
auto
path
=
lookup
(
dest_node
);
if
(
path
)
{
if
(
path
)
{
binary_serializer
sink
{
ctx
,
callee_
.
get_buffer
(
path
->
hdl
)};
binary_serializer
sink
{
ctx
,
callee_
.
get_buffer
(
path
->
hdl
)};
if
(
!
sink
.
apply
_object
(
hdr
))
{
if
(
!
sink
.
apply
(
hdr
))
{
CAF_LOG_ERROR
(
"unable to serialize BASP header:"
<<
sink
.
get_error
());
CAF_LOG_ERROR
(
"unable to serialize BASP header:"
<<
sink
.
get_error
());
return
;
return
;
}
}
...
...
libcaf_io/src/io/basp/message_type_strings.cpp
View file @
8c8fb8be
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
// DO NOT EDIT: this file is auto-generated by caf-generate-enum-strings.
// DO NOT EDIT: this file is auto-generated by caf-generate-enum-strings.
// Run the target update-enum-strings if this file is out of sync.
// Run the target update-enum-strings if this file is out of sync.
#include "caf/config.hpp"
#include "caf/config.hpp"
#include "caf/string_view.hpp"
CAF_PUSH_DEPRECATED_WARNING
CAF_PUSH_DEPRECATED_WARNING
...
@@ -34,6 +35,51 @@ std::string to_string(message_type x) {
...
@@ -34,6 +35,51 @@ std::string to_string(message_type x) {
};
};
}
}
bool
from_string
(
string_view
in
,
message_type
&
out
)
{
if
(
in
==
"server_handshake"
)
{
out
=
message_type
::
server_handshake
;
return
true
;
}
else
if
(
in
==
"client_handshake"
)
{
out
=
message_type
::
client_handshake
;
return
true
;
}
else
if
(
in
==
"direct_message"
)
{
out
=
message_type
::
direct_message
;
return
true
;
}
else
if
(
in
==
"routed_message"
)
{
out
=
message_type
::
routed_message
;
return
true
;
}
else
if
(
in
==
"monitor_message"
)
{
out
=
message_type
::
monitor_message
;
return
true
;
}
else
if
(
in
==
"down_message"
)
{
out
=
message_type
::
down_message
;
return
true
;
}
else
if
(
in
==
"heartbeat"
)
{
out
=
message_type
::
heartbeat
;
return
true
;
}
else
{
return
false
;
}
}
bool
from_integer
(
std
::
underlying_type_t
<
message_type
>
in
,
message_type
&
out
)
{
auto
result
=
static_cast
<
message_type
>
(
in
);
switch
(
result
)
{
default:
return
false
;
case
message_type
:
:
server_handshake
:
case
message_type
:
:
client_handshake
:
case
message_type
:
:
direct_message
:
case
message_type
:
:
routed_message
:
case
message_type
:
:
monitor_message
:
case
message_type
:
:
down_message
:
case
message_type
:
:
heartbeat
:
out
=
result
;
return
true
;
};
}
}
// namespace basp
}
// namespace basp
}
// namespace io
}
// namespace io
}
// namespace caf
}
// namespace caf
...
...
libcaf_io/src/io/network/operation_strings.cpp
View file @
8c8fb8be
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
// DO NOT EDIT: this file is auto-generated by caf-generate-enum-strings.
// DO NOT EDIT: this file is auto-generated by caf-generate-enum-strings.
// Run the target update-enum-strings if this file is out of sync.
// Run the target update-enum-strings if this file is out of sync.
#include "caf/config.hpp"
#include "caf/config.hpp"
#include "caf/string_view.hpp"
CAF_PUSH_DEPRECATED_WARNING
CAF_PUSH_DEPRECATED_WARNING
...
@@ -26,6 +27,35 @@ std::string to_string(operation x) {
...
@@ -26,6 +27,35 @@ std::string to_string(operation x) {
};
};
}
}
bool
from_string
(
string_view
in
,
operation
&
out
)
{
if
(
in
==
"read"
)
{
out
=
operation
::
read
;
return
true
;
}
else
if
(
in
==
"write"
)
{
out
=
operation
::
write
;
return
true
;
}
else
if
(
in
==
"propagate_error"
)
{
out
=
operation
::
propagate_error
;
return
true
;
}
else
{
return
false
;
}
}
bool
from_integer
(
std
::
underlying_type_t
<
operation
>
in
,
operation
&
out
)
{
auto
result
=
static_cast
<
operation
>
(
in
);
switch
(
result
)
{
default:
return
false
;
case
operation
:
:
read
:
case
operation
:
:
write
:
case
operation
:
:
propagate_error
:
out
=
result
;
return
true
;
};
}
}
// namespace network
}
// namespace network
}
// namespace io
}
// namespace io
}
// namespace caf
}
// namespace caf
...
...
libcaf_io/test/io/basp_broker.cpp
View file @
8c8fb8be
...
@@ -163,7 +163,7 @@ public:
...
@@ -163,7 +163,7 @@ public:
uint32_t
serialized_size
(
const
message
&
msg
)
{
uint32_t
serialized_size
(
const
message
&
msg
)
{
byte_buffer
buf
;
byte_buffer
buf
;
binary_serializer
sink
{
mpx_
,
buf
};
binary_serializer
sink
{
mpx_
,
buf
};
if
(
!
sink
.
apply
_object
(
msg
))
if
(
!
sink
.
apply
(
msg
))
CAF_FAIL
(
"failed to serialize message: "
<<
sink
.
get_error
());
CAF_FAIL
(
"failed to serialize message: "
<<
sink
.
get_error
());
return
static_cast
<
uint32_t
>
(
buf
.
size
());
return
static_cast
<
uint32_t
>
(
buf
.
size
());
}
}
...
@@ -221,7 +221,7 @@ public:
...
@@ -221,7 +221,7 @@ public:
template
<
class
...
Ts
>
template
<
class
...
Ts
>
void
to_payload
(
byte_buffer
&
buf
,
const
Ts
&
...
xs
)
{
void
to_payload
(
byte_buffer
&
buf
,
const
Ts
&
...
xs
)
{
binary_serializer
sink
{
mpx_
,
buf
};
binary_serializer
sink
{
mpx_
,
buf
};
if
(
!
sink
.
apply_objects
(
xs
...))
if
(
!
(
sink
.
apply
(
xs
)
&&
...))
CAF_FAIL
(
"failed to serialize payload: "
<<
sink
.
get_error
());
CAF_FAIL
(
"failed to serialize payload: "
<<
sink
.
get_error
());
}
}
...
@@ -229,13 +229,13 @@ public:
...
@@ -229,13 +229,13 @@ public:
instance
().
write
(
mpx_
,
buf
,
hdr
,
writer
);
instance
().
write
(
mpx_
,
buf
,
hdr
,
writer
);
}
}
template
<
class
T
,
class
...
Ts
>
template
<
class
...
Ts
>
void
to_buf
(
byte_buffer
&
buf
,
basp
::
header
&
hdr
,
payload_writer
*
writer
,
void
to_buf
(
byte_buffer
&
buf
,
basp
::
header
&
hdr
,
payload_writer
*
writer
,
const
T
&
x
,
const
T
s
&
...
xs
)
{
const
Ts
&
...
xs
)
{
auto
pw
=
make_callback
([
&
](
binary_serializer
&
sink
)
{
auto
pw
=
make_callback
([
&
](
binary_serializer
&
sink
)
{
if
(
writer
!=
nullptr
&&
!
(
*
writer
)(
sink
))
if
(
writer
!=
nullptr
&&
!
(
*
writer
)(
sink
))
return
false
;
return
false
;
return
sink
.
apply_objects
(
x
,
xs
...);
return
(
sink
.
apply
(
xs
)
&&
...);
});
});
to_buf
(
buf
,
hdr
,
&
pw
);
to_buf
(
buf
,
hdr
,
&
pw
);
}
}
...
@@ -243,7 +243,7 @@ public:
...
@@ -243,7 +243,7 @@ public:
std
::
pair
<
basp
::
header
,
byte_buffer
>
from_buf
(
const
byte_buffer
&
buf
)
{
std
::
pair
<
basp
::
header
,
byte_buffer
>
from_buf
(
const
byte_buffer
&
buf
)
{
basp
::
header
hdr
;
basp
::
header
hdr
;
binary_deserializer
source
{
mpx_
,
buf
};
binary_deserializer
source
{
mpx_
,
buf
};
if
(
!
source
.
apply
_object
(
hdr
))
if
(
!
source
.
apply
(
hdr
))
CAF_FAIL
(
"failed to deserialize header: "
<<
source
.
get_error
());
CAF_FAIL
(
"failed to deserialize header: "
<<
source
.
get_error
());
byte_buffer
payload
;
byte_buffer
payload
;
if
(
hdr
.
payload_len
>
0
)
{
if
(
hdr
.
payload_len
>
0
)
{
...
@@ -307,7 +307,7 @@ public:
...
@@ -307,7 +307,7 @@ public:
binary_deserializer
source
{
mpx_
,
buf
};
binary_deserializer
source
{
mpx_
,
buf
};
std
::
vector
<
strong_actor_ptr
>
stages
;
std
::
vector
<
strong_actor_ptr
>
stages
;
message
msg
;
message
msg
;
if
(
!
source
.
apply
_objects
(
stages
,
msg
))
if
(
!
source
.
apply
(
stages
)
||
!
source
.
apply
(
msg
))
CAF_FAIL
(
"deserialization failed: "
<<
source
.
get_error
());
CAF_FAIL
(
"deserialization failed: "
<<
source
.
get_error
());
auto
src
=
actor_cast
<
strong_actor_ptr
>
(
registry_
->
get
(
hdr
.
source_actor
));
auto
src
=
actor_cast
<
strong_actor_ptr
>
(
registry_
->
get
(
hdr
.
source_actor
));
auto
dest
=
registry_
->
get
(
hdr
.
dest_actor
);
auto
dest
=
registry_
->
get
(
hdr
.
dest_actor
);
...
@@ -348,7 +348,7 @@ public:
...
@@ -348,7 +348,7 @@ public:
basp
::
header
hdr
;
basp
::
header
hdr
;
{
// lifetime scope of source
{
// lifetime scope of source
binary_deserializer
source
{
this_
->
mpx
(),
ob
};
binary_deserializer
source
{
this_
->
mpx
(),
ob
};
if
(
!
source
.
apply
_objects
(
hdr
))
if
(
!
source
.
apply
(
hdr
))
CAF_FAIL
(
"failed to deserialize header: "
<<
source
.
get_error
());
CAF_FAIL
(
"failed to deserialize header: "
<<
source
.
get_error
());
}
}
byte_buffer
payload
;
byte_buffer
payload
;
...
@@ -486,7 +486,10 @@ CAF_TEST(non_empty_server_handshake) {
...
@@ -486,7 +486,10 @@ CAF_TEST(non_empty_server_handshake) {
std
::
set
<
std
::
string
>
ifs
{
"caf::replies_to<@u16>::with<@u16>"
};
std
::
set
<
std
::
string
>
ifs
{
"caf::replies_to<@u16>::with<@u16>"
};
binary_serializer
sink
{
nullptr
,
expected_payload
};
binary_serializer
sink
{
nullptr
,
expected_payload
};
auto
id
=
self
()
->
id
();
auto
id
=
self
()
->
id
();
if
(
!
sink
.
apply_objects
(
instance
().
this_node
(),
app_ids
,
id
,
ifs
))
if
(
!
sink
.
apply
(
instance
().
this_node
())
//
||
!
sink
.
apply
(
app_ids
)
//
||
!
sink
.
apply
(
id
)
//
||
!
sink
.
apply
(
ifs
))
CAF_FAIL
(
"serializing handshake failed: "
<<
sink
.
get_error
());
CAF_FAIL
(
"serializing handshake failed: "
<<
sink
.
get_error
());
CAF_CHECK_EQUAL
(
hexstr
(
payload
),
hexstr
(
expected_payload
));
CAF_CHECK_EQUAL
(
hexstr
(
payload
),
hexstr
(
expected_payload
));
}
}
...
...
libcaf_io/test/io/network/ip_endpoint.cpp
View file @
8c8fb8be
...
@@ -45,19 +45,19 @@ public:
...
@@ -45,19 +45,19 @@ public:
};
};
struct
fixture
:
test_coordinator_fixture
<>
{
struct
fixture
:
test_coordinator_fixture
<>
{
template
<
class
T
,
class
...
Ts
>
template
<
class
...
Ts
>
auto
serialize
(
T
&
x
,
T
s
&
...
xs
)
{
auto
serialize
(
Ts
&
...
xs
)
{
byte_buffer
buf
;
byte_buffer
buf
;
binary_serializer
sink
{
sys
,
buf
};
binary_serializer
sink
{
sys
,
buf
};
if
(
!
sink
.
apply_objects
(
x
,
xs
...))
if
(
!
(
sink
.
apply
(
xs
)
&&
...))
CAF_FAIL
(
"serialization failed: "
<<
sink
.
get_error
());
CAF_FAIL
(
"serialization failed: "
<<
sink
.
get_error
());
return
buf
;
return
buf
;
}
}
template
<
class
Buffer
,
class
T
,
class
...
Ts
>
template
<
class
Buffer
,
class
...
Ts
>
void
deserialize
(
const
Buffer
&
buf
,
T
&
x
,
T
s
&
...
xs
)
{
void
deserialize
(
const
Buffer
&
buf
,
Ts
&
...
xs
)
{
binary_deserializer
source
{
sys
,
buf
};
binary_deserializer
source
{
sys
,
buf
};
if
(
!
source
.
apply_objects
(
x
,
xs
...))
if
(
!
(
source
.
apply
(
xs
)
&&
...))
CAF_FAIL
(
"serialization failed: "
<<
source
.
get_error
());
CAF_FAIL
(
"serialization failed: "
<<
source
.
get_error
());
}
}
};
};
...
...
libcaf_io/test/io/worker.cpp
View file @
8c8fb8be
...
@@ -120,7 +120,7 @@ CAF_TEST(deliver serialized message) {
...
@@ -120,7 +120,7 @@ CAF_TEST(deliver serialized message) {
std
::
vector
<
strong_actor_ptr
>
stages
;
std
::
vector
<
strong_actor_ptr
>
stages
;
binary_serializer
sink
{
sys
,
payload
};
binary_serializer
sink
{
sys
,
payload
};
auto
msg
=
make_message
(
ok_atom_v
);
auto
msg
=
make_message
(
ok_atom_v
);
if
(
!
sink
.
apply
_objects
(
stages
,
msg
))
if
(
!
sink
.
apply
(
stages
)
||
!
sink
.
apply
(
msg
))
CAF_FAIL
(
"unable to serialize message: "
<<
sink
.
get_error
());
CAF_FAIL
(
"unable to serialize message: "
<<
sink
.
get_error
());
io
::
basp
::
header
hdr
{
io
::
basp
::
message_type
::
direct_message
,
io
::
basp
::
header
hdr
{
io
::
basp
::
message_type
::
direct_message
,
0
,
0
,
...
...
libcaf_test/caf/test/dsl.hpp
View file @
8c8fb8be
...
@@ -843,7 +843,7 @@ public:
...
@@ -843,7 +843,7 @@ public:
caf
::
byte_buffer
serialize
(
const
Ts
&
...
xs
)
{
caf
::
byte_buffer
serialize
(
const
Ts
&
...
xs
)
{
caf
::
byte_buffer
buf
;
caf
::
byte_buffer
buf
;
caf
::
binary_serializer
sink
{
sys
,
buf
};
caf
::
binary_serializer
sink
{
sys
,
buf
};
if
(
!
sink
.
apply
_objects
(
xs
...))
if
(
!
sink
.
apply
(
xs
...))
CAF_FAIL
(
"serialization failed: "
<<
sink
.
get_error
());
CAF_FAIL
(
"serialization failed: "
<<
sink
.
get_error
());
return
buf
;
return
buf
;
}
}
...
@@ -851,7 +851,7 @@ public:
...
@@ -851,7 +851,7 @@ public:
template
<
class
...
Ts
>
template
<
class
...
Ts
>
void
deserialize
(
const
caf
::
byte_buffer
&
buf
,
Ts
&
...
xs
)
{
void
deserialize
(
const
caf
::
byte_buffer
&
buf
,
Ts
&
...
xs
)
{
caf
::
binary_deserializer
source
{
sys
,
buf
};
caf
::
binary_deserializer
source
{
sys
,
buf
};
if
(
!
source
.
apply
_objects
(
xs
...))
if
(
!
source
.
apply
(
xs
...))
CAF_FAIL
(
"deserialization failed: "
<<
source
.
get_error
());
CAF_FAIL
(
"deserialization failed: "
<<
source
.
get_error
());
}
}
...
...
manual/TypeInspection.rst
View file @
8c8fb8be
...
@@ -6,20 +6,36 @@ Type Inspection
...
@@ -6,20 +6,36 @@ Type Inspection
We designed CAF with distributed systems in mind. Hence, all message types must
We designed CAF with distributed systems in mind. Hence, all message types must
be serializable. Using a message type that is not serializable causes a compiler
be serializable. Using a message type that is not serializable causes a compiler
error unless explicitly listed as unsafe message type by the user (see
error unless explicitly listed as unsafe message type by the user (see
:ref:`unsafe-message-type`).
:ref:`unsafe-message-type`). Any unsafe message type may used only for messages
that remain local, i.e., never cross the wire.
.. _type-inspection-data-model:
.. _type-inspection-data-model:
Data Model
Data Model
----------
----------
Type inspection in CAF uses a hierarchical, object-oriented data model. The main
Type inspection in CAF uses a hierarchical data model with the following
abstraction is the *object*. An object has one or more *fields*. Fields have a
building blocks:
*name* and may be *optional*. Further, fields can take on several different (but
fixed) *types*.
Depending on its type, a field contains: a single *value*, a variable-length
built-in types
*sequence*, or a fixed-size *tuple*.
- Signed and unsigned integer types for 8, 16, 32 and 64 bit
- The floating point types ``float``, ``double`` and ``long double``
- Bytes, booleans, and strings
lists
Dynamically-sized container types such as ``std::vector``.
tuples
Fixed-sized container types such as ``std::tuple`` or ``std::array`` as well
as builtin C array types.
maps
Dynamically-sized container types with key/value pairs such as ``std::map``.
objects
User-defined types. An object has one or more *fields*. Fields have a *name*
and may be *optional*. Further, fields may take on a fixed number of different
types.
To see how this maps to C++ types, consider the following type definition:
To see how this maps to C++ types, consider the following type definition:
...
@@ -32,25 +48,25 @@ To see how this maps to C++ types, consider the following type definition:
...
@@ -32,25 +48,25 @@ To see how this maps to C++ types, consider the following type definition:
};
};
Here, field ``x1`` is either a ``string`` or a ``double`` at runtime. The field
Here, field ``x1`` is either a ``string`` or a ``double`` at runtime. The field
``x2`` is optional and may contain a fixed-size tuple with two elements. Lastly,
``x2`` is optional and may contain a fixed-size tuple with two elements
field ``x3`` contains any number of string values at runtime.
(built-in types). Lastly, field ``x3`` contains any number of string values at
runtime.
Numbers and strings are primitive types in the inspector API.
Inspecting Objects
Inspecting Objects
------------------
------------------
The inspection API allows CAF to deconstruct C++ objects
into fields and values.
The inspection API allows CAF to deconstruct C++ objects
. Users can either
Users can either provide free functions named ``inspect`` that CAF picks up via
provide free functions named ``inspect`` that CAF picks up via `ADL
`ADL <https://en.wikipedia.org/wiki/Argument-dependent_name_lookup>`_ or
<https://en.wikipedia.org/wiki/Argument-dependent_name_lookup>`_ or specialize
specialize
``caf::inspector_access``.
``caf::inspector_access``.
In both cases, users call members and member functions on an ``Inspector`` that
In both cases, users call members and member functions on an ``Inspector`` that
provides a domain-specific language (DSL) for describing the structure of a C++
provides a domain-specific language (DSL) for describing the structure of a C++
object.
object.
After listing a custom type ``T`` in a type ID block and either providing a free
After listing a custom type ``T`` in a type ID block and either providing a free
``inspect`` overload or specializing ``inspector_access``, CAF is able to:
``inspect`` function overload or specializing ``inspector_access``, CAF is able
to:
- Serialize and deserialize objects of type ``T`` to/from Byte sequences.
- Serialize and deserialize objects of type ``T`` to/from Byte sequences.
- Render objects of type ``T`` as a human-readable string via
- Render objects of type ``T`` as a human-readable string via
...
@@ -65,11 +81,18 @@ the inspection API.
...
@@ -65,11 +81,18 @@ the inspection API.
.. code-block:: C++
.. code-block:: C++
struct point_3d {
struct point_3d {
int x;
int
32_t
x;
int y;
int
32_t
y;
int z;
int
32_t
z;
};
};
.. note::
We strongly recommend using the fixed-width integer types in all user-defined
messaging types. Consistently using these types over ``short``, ``int``,
``long``, etc. avoids bugs in heterogeneous environemnts that are hard to
debug.
.. _writing-inspect-overloads:
.. _writing-inspect-overloads:
Writing ``inspect`` Overloads
Writing ``inspect`` Overloads
...
@@ -92,15 +115,13 @@ the inspector:
...
@@ -92,15 +115,13 @@ the inspector:
f.field("z", x.z));
f.field("z", x.z));
}
}
Writing ``inspect_value`` Overloads
As mentioned in the section on the :ref:`data model
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<type-inspection-data-model>`, objects are containers for fields that in turn
contain values. When providing an ``inspect`` overload, CAF recursively
The free function ``inspect`` models the object-level type inspection. As
traverses all fields.
mentioned in the section on the :ref:`data model <type-inspection-data-model>`,
objects are containers for fields that in turn contain a value. When providing
an ``inspect`` overload, CAF recursively visits a value as an object.
For example, consider the following ID type that simply wraps a string:
Not every type needs to expose itself as ``object``, though. For example,
consider the following ID type that simply wraps a string:
.. code-block:: C++
.. code-block:: C++
...
@@ -111,14 +132,16 @@ For example, consider the following ID type that simply wraps a string:
...
@@ -111,14 +132,16 @@ For example, consider the following ID type that simply wraps a string:
return f.object(x).fields(f.field("value", x.value));
return f.object(x).fields(f.field("value", x.value));
}
}
The type ``id`` is basically a *strong typedef* to improve type safety
. To a
The type ``id`` is basically a *strong typedef* to improve type safety
when
type inspector, ID objects look as follows:
writing code. To a
type inspector, ID objects look as follows:
.. code-block:: none
.. code-block:: none
object(type: "id") {
object(type: "id") {
field(name: "value") {
field(name: "value") {
value(type: "string")
value(type: "string") {
...
}
}
}
}
}
...
@@ -138,7 +161,7 @@ By providing the ``inspect`` overload for ID, inspectors can recursively visit
...
@@ -138,7 +161,7 @@ By providing the ``inspect`` overload for ID, inspectors can recursively visit
an ``id`` as an object. Hence, the above implementations work as expected. When
an ``id`` as an object. Hence, the above implementations work as expected. When
using ``person`` in human-readable data formats such as CAF configurations,
using ``person`` in human-readable data formats such as CAF configurations,
however, allowing CAF to look "inside" a strong typedef can simplify working
however, allowing CAF to look "inside" a strong typedef can simplify working
with types.
with
such
types.
With the current implementation, we could read the key ``manager.ceo`` from a
With the current implementation, we could read the key ``manager.ceo`` from a
configuration file with this content:
configuration file with this content:
...
@@ -154,20 +177,23 @@ configuration file with this content:
...
@@ -154,20 +177,23 @@ configuration file with this content:
}
}
}
}
This clearly is more verbose than it needs to be. By also providing an overload
This clearly appears more verbose than it needs to be. Users generally need not
for ``inspect_value``, we can teach CAF how to inspect an ID directly as a
care about such internal types like ``id`` that only exist as a safeguard during
*value* without having to recursively visit it as an object:
programming.
Hence, we generally recommend making such types transparent to CAF inspectors.
For our ``id`` type, the ``inspect`` overload may instead look as follows:
.. code-block:: C++
.. code-block:: C++
template <class Inspector>
template <class Inspector>
bool inspect
_value
(Inspector& f, id& x) {
bool inspect(Inspector& f, id& x) {
return f.apply
_value
(x.value);
return f.apply(x.value);
}
}
With this
overload in place, inspectors can now remove one level of indirection
With this
implementation instead of the previous one, inspectors simply read or
and read or write strings whenever they encounter an ``id`` as value. This
write strings whenever they encounter an ``id`` as value. This simplifies our
allows us to simply our config file from before
:
config file from before and thus gives a much cleaner interface to users
:
.. code-block:: none
.. code-block:: none
...
@@ -184,7 +210,7 @@ Specializing ``inspector_access``
...
@@ -184,7 +210,7 @@ Specializing ``inspector_access``
Working with 3rd party libraries usually rules out adding free functions for
Working with 3rd party libraries usually rules out adding free functions for
existing classes, because the namespace belongs to a another project. Hence, CAF
existing classes, because the namespace belongs to a another project. Hence, CAF
also allows specializing ``inspector_access`` instead. This requires writing
also allows specializing ``inspector_access`` instead. This requires writing
more boilerplate code
and
allows customizing every step of the inspection
more boilerplate code
but
allows customizing every step of the inspection
process.
process.
The full interface of ``inspector_access`` looks as follows:
The full interface of ``inspector_access`` looks as follows:
...
@@ -194,10 +220,7 @@ The full interface of ``inspector_access`` looks as follows:
...
@@ -194,10 +220,7 @@ The full interface of ``inspector_access`` looks as follows:
template <class T>
template <class T>
struct inspector_access {
struct inspector_access {
template <class Inspector>
template <class Inspector>
static bool apply_object(Inspector& f, T& x);
static bool apply(Inspector& f, T& x);
template <class Inspector>
static bool apply_value(Inspector& f, T& x);
template <class Inspector>
template <class Inspector>
static bool save_field(Inspector& f, string_view field_name, T& x);
static bool save_field(Inspector& f, string_view field_name, T& x);
...
@@ -216,11 +239,8 @@ The full interface of ``inspector_access`` looks as follows:
...
@@ -216,11 +239,8 @@ The full interface of ``inspector_access`` looks as follows:
SetFallback& set_fallback);
SetFallback& set_fallback);
};
};
The static member function ``apply_object`` has the same role as the free
The static member function ``apply`` has the same role as the free ``inspect``
``inspect`` function. Likewise, ``apply_value`` corresponds to the free
function. For most types, we can implement only ``apply`` and use a default
``inspect_value`` function.
For most types, we can implement only ``apply_object`` and use default
implementation for the other member functions. For example, specializing
implementation for the other member functions. For example, specializing
``inspector_access`` for our ``point_3d`` would look as follows:
``inspector_access`` for our ``point_3d`` would look as follows:
...
@@ -231,16 +251,11 @@ implementation for the other member functions. For example, specializing
...
@@ -231,16 +251,11 @@ implementation for the other member functions. For example, specializing
template <>
template <>
struct inspector_access<point_3d> : inspector_access_base<point_3d> {
struct inspector_access<point_3d> : inspector_access_base<point_3d> {
template <class Inspector>
template <class Inspector>
static bool apply
_object
(Inspector& f, point_3d& x) {
static bool apply(Inspector& f, point_3d& x) {
return f.object(x).fields(f.field("x", x.x),
return f.object(x).fields(f.field("x", x.x),
f.field("y", x.y),
f.field("y", x.y),
f.field("z", x.z));
f.field("z", x.z));
}
}
template <class Inspector>
static bool apply_value(Inspector& f, point_3d& x) {
return apply_object(f, x);
}
};
};
} // namespace caf
} // namespace caf
...
@@ -255,13 +270,6 @@ becomes necessary when integration custom types that have semantics similar to
...
@@ -255,13 +270,6 @@ becomes necessary when integration custom types that have semantics similar to
Please refer to the Doxygen documentation for more details on ``save_field``
Please refer to the Doxygen documentation for more details on ``save_field``
and ``load_field``.
and ``load_field``.
In :ref:`our previous example <writing-inspect-overloads>`, we provided an
``inspect`` overload that was similar to our implementation of ``apply_object``.
Most of the time, we only need to implement ``apply_object`` and can call it
from ``apply_value``. The latter customizes how CAF inspects a value inside a
field. By calling ``apply_object``, we simply recursively visit ``x`` as an
object again.
Types with Getter and Setter Access
Types with Getter and Setter Access
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
...
@@ -433,13 +441,13 @@ machine-to-machine communication, using the underlying integer representation
...
@@ -433,13 +441,13 @@ machine-to-machine communication, using the underlying integer representation
gives the best performance. However, using the constant names results in a much
gives the best performance. However, using the constant names results in a much
better user experience in all other cases.
better user experience in all other cases.
The following code illustrates how to
use a string representation for inspectors
The following code illustrates how to
provide a string representation for
that operate on human-readable data representation and the underlying type for
inspectors that operate on human-readable data representation and the underlying
an ``enum class`` otherwise.
type for
an ``enum class`` otherwise.
.. code-block:: C++
.. code-block:: C++
enum class weekday {
enum class weekday
: uint8_t
{
monday,
monday,
tuesday,
tuesday,
wednesday,
wednesday,
...
@@ -458,34 +466,24 @@ an ``enum class`` otherwise.
...
@@ -458,34 +466,24 @@ an ``enum class`` otherwise.
if (f.has_human_readable_format()) {
if (f.has_human_readable_format()) {
auto get = [&x] { return to_string(x); };
auto get = [&x] { return to_string(x); };
auto set = [&x](std::string str) { return parse(str, x); };
auto set = [&x](std::string str) { return parse(str, x); };
return f.
object(x).fields(f.field("value", get, set)
);
return f.
apply(get, set
);
} else {
} else {
using default_impl = caf::default_inspector_access<weekday>;
auto get = [&x] { return static_cast<uint8_t>(x); };
return default_impl::apply_object(f, x);
auto set = [&x](uint8_t val) {
}
if (val < 7) {
}
x = static_cast<weekday>(val);
return true;
template <class Inspector>
bool inspect_value(Inspector& f, weekday& x) {
if (f.has_human_readable_format()) {
auto get = [&x] { return to_string(x); };
auto set = [&x](std::string str) { return parse(str, x); };
return f.apply_value(get, set);
} else {
} else {
using default_impl = caf::default_inspector_access<weekday>;
return false;
return default_impl::apply_value(f, x);
}
};
return f.apply(get, set);
}
}
}
}
When inspecting an object of type ``weekday``, we treat it as if we were
When inspecting an object of type ``weekday``, we treat is as if it were a
inspecting an object with a single field named ``value``. However, usually we
string for inspectors with human-readable data formats. Otherwise, we treat the
are going to inspect other objects that contain values of type ``weekday``. In
weekday as if it were an integer between 0 and 6.
both cases, we provide getter and setter functions that convert between strings
and enumeration values.
For inspectors that operate on machine-to-machine data formats, we simply fall
back to the default implementation that is going to use the underlying integer
values.
.. _unsafe-message-type:
.. _unsafe-message-type:
...
...
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