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
68641365
Unverified
Commit
68641365
authored
Sep 05, 2019
by
Joseph Noir
Committed by
GitHub
Sep 05, 2019
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #899
Improve stringification_inspector implementation
parents
5dff9fbc
3f1a546f
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
296 additions
and
233 deletions
+296
-233
libcaf_core/caf/deep_to_string.hpp
libcaf_core/caf/deep_to_string.hpp
+17
-27
libcaf_core/caf/detail/parser/read_timespan.hpp
libcaf_core/caf/detail/parser/read_timespan.hpp
+2
-2
libcaf_core/caf/detail/stringification_inspector.hpp
libcaf_core/caf/detail/stringification_inspector.hpp
+84
-146
libcaf_core/src/actor_system_config.cpp
libcaf_core/src/actor_system_config.cpp
+1
-1
libcaf_core/src/stringification_inspector.cpp
libcaf_core/src/stringification_inspector.cpp
+134
-31
libcaf_core/test/deep_to_string.cpp
libcaf_core/test/deep_to_string.cpp
+29
-7
libcaf_core/test/message.cpp
libcaf_core/test/message.cpp
+3
-3
libcaf_core/test/serialization.cpp
libcaf_core/test/serialization.cpp
+25
-15
libcaf_core/test/serializer_impl.cpp
libcaf_core/test/serializer_impl.cpp
+1
-1
No files found.
libcaf_core/caf/deep_to_string.hpp
View file @
68641365
...
...
@@ -18,47 +18,37 @@
#pragma once
#include <array>
#include <tuple>
#include <string>
#include <utility>
#include <functional>
#include <type_traits>
#include <tuple>
#include "caf/atom.hpp"
#include "caf/detail/apply_args.hpp"
#include "caf/detail/type_traits.hpp"
#include "caf/detail/stringification_inspector.hpp"
namespace
caf
{
class
deep_to_string_t
{
public:
constexpr
deep_to_string_t
()
{
// nop
}
template
<
class
...
Ts
>
std
::
string
operator
()(
Ts
&&
...
xs
)
const
{
std
::
string
result
;
detail
::
stringification_inspector
f
{
result
};
f
(
std
::
forward
<
Ts
>
(
xs
)...);
return
result
;
}
};
/// Unrolls collections such as vectors/maps, decomposes
/// tuples/pairs/arrays, auto-escapes strings and calls
/// `to_string` for user-defined types via argument-dependent
/// loopkup (ADL). Any user-defined type that does not
/// provide a `to_string` is mapped to `<unprintable>`.
constexpr
deep_to_string_t
deep_to_string
=
deep_to_string_t
{};
template
<
class
...
Ts
>
std
::
string
deep_to_string
(
const
Ts
&
...
xs
)
{
std
::
string
result
;
detail
::
stringification_inspector
f
{
result
};
f
(
xs
...);
return
result
;
}
struct
deep_to_string_t
{
template
<
class
...
Ts
>
std
::
string
operator
()(
const
Ts
&
...
xs
)
const
{
return
deep_to_string
(
xs
...);
}
};
/// Convenience function for `deep_to_string(std::forward_as_tuple(xs...))`.
template
<
class
...
Ts
>
std
::
string
deep_to_string_as_tuple
(
Ts
&
&
...
xs
)
{
return
deep_to_string
(
std
::
forward_as_tuple
(
std
::
forward
<
Ts
>
(
xs
)
...));
std
::
string
deep_to_string_as_tuple
(
const
Ts
&
...
xs
)
{
return
deep_to_string
(
std
::
forward_as_tuple
(
xs
...));
}
}
// namespace caf
libcaf_core/caf/detail/parser/read_timespan.hpp
View file @
68641365
...
...
@@ -46,11 +46,11 @@ void read_timespan(state<Iterator, Sentinel>& ps, Consumer&& consumer,
struct
interim_consumer
{
using
value_type
=
int64_t
;
void
value
(
int64_t
y
)
{
void
value
(
value_type
y
)
{
x
=
y
;
}
int64_t
x
=
0
;
value_type
x
=
0
;
};
interim_consumer
ic
;
timespan
result
;
...
...
libcaf_core/caf/detail/stringification_inspector.hpp
View file @
68641365
...
...
@@ -19,16 +19,15 @@
#pragma once
#include <chrono>
#include <functional>
#include <string>
#include <type_traits>
#include <vector>
#include "caf/atom.hpp"
#include "caf/detail/append_hex.hpp"
#include "caf/detail/apply_args.hpp"
#include "caf/detail/int_list.hpp"
#include "caf/detail/type_traits.hpp"
#include "caf/
error
.hpp"
#include "caf/
fwd
.hpp"
#include "caf/meta/annotation.hpp"
#include "caf/meta/hex_formatted.hpp"
#include "caf/meta/omittable.hpp"
...
...
@@ -68,84 +67,82 @@ public:
/// Prints a separator to the result string.
void
sep
();
inline
void
traverse
()
noexcept
{
// end of recursion
}
void
consume
(
atom_value
&
x
);
void
consume
(
atom_value
x
);
void
consume
(
string_view
str
);
void
consume
(
timespan
&
x
);
void
consume
(
timespan
x
);
void
consume
(
timestamp
&
x
);
void
consume
(
timestamp
x
);
template
<
class
Clock
,
class
Duration
>
void
consume
(
std
::
chrono
::
time_point
<
Clock
,
Duration
>&
x
)
{
timestamp
tmp
{
std
::
chrono
::
duration_cast
<
timespan
>
(
x
.
time_since_epoch
())};
consume
(
tmp
);
}
void
consume
(
bool
x
);
template
<
class
Rep
,
class
Period
>
void
consume
(
std
::
chrono
::
duration
<
Rep
,
Period
>&
x
)
{
auto
tmp
=
std
::
chrono
::
duration_cast
<
timespan
>
(
x
);
consume
(
tmp
);
}
void
consume
(
const
void
*
ptr
);
void
consume
(
const
char
*
cstr
);
void
consume
(
const
std
::
vector
<
bool
>&
xs
);
inline
void
consume
(
bool
&
x
)
{
result_
+=
x
?
"true"
:
"false"
;
template
<
class
T
>
enable_if_t
<
std
::
is_floating_point
<
T
>::
value
>
consume
(
T
x
)
{
result_
+=
std
::
to_string
(
x
);
}
inline
void
consume
(
const
char
*
cstr
)
{
if
(
cstr
==
nullptr
)
{
result_
+=
"null"
;
}
else
{
string_view
tmp
{
cstr
,
strlen
(
cstr
)};
consume
(
tmp
);
template
<
class
T
>
enable_if_t
<
std
::
is_integral
<
T
>::
value
&&
std
::
is_signed
<
T
>::
value
>
consume
(
T
x
)
{
consume_int
(
static_cast
<
int64_t
>
(
x
));
}
template
<
class
T
>
enable_if_t
<
std
::
is_integral
<
T
>::
value
&&
std
::
is_unsigned
<
T
>::
value
>
consume
(
T
x
)
{
consume_int
(
static_cast
<
uint64_t
>
(
x
));
}
inline
void
consume
(
char
*
cstr
)
{
consume
(
const_cast
<
const
char
*>
(
cstr
));
template
<
class
Clock
,
class
Duration
>
void
consume
(
std
::
chrono
::
time_point
<
Clock
,
Duration
>
x
)
{
timestamp
tmp
{
std
::
chrono
::
duration_cast
<
timespan
>
(
x
.
time_since_epoch
())};
consume
(
tmp
);
}
template
<
class
T
>
enable_if_tt
<
std
::
is_arithmetic
<
T
>>
consume
(
T
&
x
)
{
result_
+=
std
::
to_string
(
x
);
template
<
class
Rep
,
class
Period
>
void
consume
(
std
::
chrono
::
duration
<
Rep
,
Period
>
x
)
{
auto
tmp
=
std
::
chrono
::
duration_cast
<
timespan
>
(
x
);
consume
(
tmp
);
}
//
unwrap std::ref
//
Unwrap std::ref.
template
<
class
T
>
void
consume
(
std
::
reference_wrapper
<
T
>
&
x
)
{
void
consume
(
std
::
reference_wrapper
<
T
>
x
)
{
return
consume
(
x
.
get
());
}
/// Picks up user-defined `to_string` functions.
template
<
class
T
>
enable_if_t
<!
std
::
is_pointer
<
T
>::
value
&&
has_to_string
<
T
>::
value
>
consume
(
T
&
x
)
{
consume
(
const
T
&
x
)
{
result_
+=
to_string
(
x
);
}
/// Delegates to `inspect(*this, x)` if available and `T`
///
does not provide a `to_string`
.
/// Delegates to `inspect(*this, x)` if available and `T`
does not provide
///
a `to_string` overload
.
template
<
class
T
>
enable_if_t
<
is_inspectable
<
stringification_inspector
,
T
>::
value
enable_if_t
<
is_inspectable
<
stringification_inspector
,
T
>::
value
&&
!
has_to_string
<
T
>::
value
>
consume
(
T
&
x
)
{
inspect
(
*
this
,
x
);
consume
(
const
T
&
x
)
{
inspect
(
*
this
,
const_cast
<
T
&>
(
x
)
);
}
template
<
class
F
,
class
S
>
void
consume
(
std
::
pair
<
F
,
S
>&
x
)
{
void
consume
(
const
std
::
pair
<
F
,
S
>&
x
)
{
result_
+=
'('
;
traverse
(
deconst
(
x
.
first
),
deconst
(
x
.
second
)
);
traverse
(
x
.
first
,
x
.
second
);
result_
+=
')'
;
}
template
<
class
...
Ts
>
void
consume
(
std
::
tuple
<
Ts
...
>&
x
)
{
void
consume
(
const
std
::
tuple
<
Ts
...
>&
x
)
{
result_
+=
'('
;
apply_args
(
*
this
,
get_indices
(
x
),
x
);
result_
+=
')'
;
...
...
@@ -154,33 +151,40 @@ public:
template
<
class
T
>
enable_if_t
<
is_map_like
<
T
>::
value
&&
!
is_inspectable
<
stringification_inspector
,
T
>::
value
&&
!
std
::
is_convertible
<
T
,
string_view
>::
value
&&
!
has_to_string
<
T
>::
value
>
consume
(
T
&
xs
)
{
consume
(
const
T
&
xs
)
{
result_
+=
'{'
;
for
(
const
auto
&
kvp
:
xs
)
{
sep
();
consume
(
deconst
(
kvp
.
first
)
);
consume
(
kvp
.
first
);
result_
+=
" = "
;
consume
(
deconst
(
kvp
.
second
)
);
consume
(
kvp
.
second
);
}
result_
+=
'}'
;
}
template
<
class
Iterator
>
void
consume_range
(
Iterator
first
,
Iterator
last
)
{
result_
+=
'['
;
while
(
first
!=
last
)
{
sep
();
consume
(
*
first
++
);
}
result_
+=
']'
;
}
template
<
class
T
>
enable_if_t
<
is_iterable
<
T
>::
value
&&
!
is_map_like
<
T
>::
value
&&
!
is_inspectable
<
stringification_inspector
,
T
>::
value
&&
!
std
::
is_convertible
<
T
,
string_view
>::
value
&&
!
is_inspectable
<
stringification_inspector
,
T
>::
value
&&
!
has_to_string
<
T
>::
value
>
consume
(
T
&
xs
)
{
result_
+=
'['
;
// use a hand-written for loop instead of for-each to avoid
// range-loop-analysis warnings when using this function with vector<bool>
for
(
auto
i
=
xs
.
begin
();
i
!=
xs
.
end
();
++
i
)
{
sep
();
consume
(
deconst
(
*
i
));
consume
(
const
T
&
xs
)
{
consume_range
(
xs
.
begin
(),
xs
.
end
());
}
result_
+=
']'
;
template
<
class
T
,
size_t
S
>
void
consume
(
const
T
(
&
xs
)[
S
])
{
return
consume_range
(
xs
,
xs
+
S
);
}
template
<
class
T
>
...
...
@@ -188,35 +192,17 @@ public:
&&
!
is_iterable
<
T
>::
value
// pick begin()/end() over peek_all
&&
!
is_inspectable
<
stringification_inspector
,
T
>::
value
&&
!
has_to_string
<
T
>::
value
>
consume
(
T
&
xs
)
{
consume
(
const
T
&
xs
)
{
result_
+=
'['
;
xs
.
peek_all
(
*
this
);
result_
+=
']'
;
}
template
<
class
T
>
void
consume
(
T
*
xs
,
size_t
n
)
{
result_
+=
'('
;
for
(
size_t
i
=
0
;
i
<
n
;
++
i
)
{
sep
();
consume
(
deconst
(
xs
[
i
]));
}
result_
+=
')'
;
}
template
<
class
T
,
size_t
S
>
void
consume
(
std
::
array
<
T
,
S
>&
xs
)
{
return
consume
(
xs
.
data
(),
S
);
}
template
<
class
T
,
size_t
S
>
void
consume
(
T
(
&
xs
)[
S
])
{
return
consume
(
xs
,
S
);
}
template
<
class
T
>
enable_if_t
<!
std
::
is_same
<
decay_t
<
T
>
,
void
>::
value
>
consume
(
T
*&
ptr
)
{
enable_if_t
<
std
::
is_pointer
<
T
>::
value
&&
!
std
::
is_same
<
void
,
typename
std
::
remove_pointer
<
T
>::
type
>::
value
>
consume
(
const
T
ptr
)
{
if
(
ptr
)
{
result_
+=
'*'
;
consume
(
*
ptr
);
...
...
@@ -225,68 +211,22 @@ public:
}
}
inline
void
consume
(
const
void
*
ptr
)
{
result_
+=
"0x"
;
auto
int_val
=
reinterpret_cast
<
intptr_t
>
(
ptr
);
consume
(
int_val
);
}
/// Print duration types with nanosecond resolution.
template
<
class
Rep
>
void
consume
(
std
::
chrono
::
duration
<
Rep
,
std
::
nano
>&
x
)
{
result_
+=
std
::
to_string
(
x
.
count
());
result_
+=
"ns"
;
}
/// Print duration types with microsecond resolution.
template
<
class
Rep
>
void
consume
(
std
::
chrono
::
duration
<
Rep
,
std
::
micro
>&
x
)
{
result_
+=
std
::
to_string
(
x
.
count
());
result_
+=
"us"
;
}
/// Print duration types with millisecond resolution.
template
<
class
Rep
>
void
consume
(
std
::
chrono
::
duration
<
Rep
,
std
::
milli
>&
x
)
{
result_
+=
std
::
to_string
(
x
.
count
());
result_
+=
"ms"
;
}
/// Print duration types with second resolution.
template
<
class
Rep
>
void
consume
(
std
::
chrono
::
duration
<
Rep
,
std
::
ratio
<
1
>>&
x
)
{
result_
+=
std
::
to_string
(
x
.
count
());
result_
+=
"s"
;
}
/// Print duration types with minute resolution.
template
<
class
Rep
>
void
consume
(
std
::
chrono
::
duration
<
Rep
,
std
::
ratio
<
60
>>&
x
)
{
result_
+=
std
::
to_string
(
x
.
count
());
result_
+=
"min"
;
}
/// Print duration types with hour resolution.
template
<
class
Rep
>
void
consume
(
std
::
chrono
::
duration
<
Rep
,
std
::
ratio
<
3600
>>&
x
)
{
result_
+=
std
::
to_string
(
x
.
count
());
result_
+=
"h"
;
}
/// Fallback printing `<unprintable>`.
template
<
class
T
>
enable_if_t
<
!
is_iterable
<
T
>::
value
&&
!
has_peek_all
<
T
>::
value
enable_if_t
<!
is_iterable
<
T
>::
value
&&
!
has_peek_all
<
T
>::
value
&&
!
std
::
is_pointer
<
T
>::
value
&&
!
is_inspectable
<
stringification_inspector
,
T
>::
value
&&
!
std
::
is_arithmetic
<
T
>::
value
&&
!
std
::
is_convertible
<
T
,
string_view
>::
value
&&
!
has_to_string
<
T
>::
value
>
consume
(
T
&
)
{
consume
(
const
T
&
)
{
result_
+=
"<unprintable>"
;
}
void
traverse
()
{
// end of recursion
}
template
<
class
T
,
class
...
Ts
>
void
traverse
(
const
meta
::
hex_formatted_t
&
,
const
T
&
x
,
const
Ts
&
...
xs
)
{
sep
();
...
...
@@ -336,7 +276,7 @@ public:
enable_if_t
<!
meta
::
is_annotation
<
T
>::
value
&&
!
is_callable
<
T
>::
value
>
traverse
(
const
T
&
x
,
const
Ts
&
...
xs
)
{
sep
();
consume
(
deconst
(
x
)
);
consume
(
x
);
traverse
(
xs
...);
}
...
...
@@ -349,14 +289,12 @@ public:
}
private:
template
<
class
T
>
T
&
deconst
(
const
T
&
x
)
{
return
const_cast
<
T
&>
(
x
);
}
void
consume_int
(
int64_t
x
);
void
consume_int
(
uint64_t
x
);
std
::
string
&
result_
;
};
}
// namespace detail
}
// namespace caf
libcaf_core/src/actor_system_config.cpp
View file @
68641365
...
...
@@ -336,7 +336,7 @@ void print(const config_value::dictionary& xs, indentation indent) {
cout
<<
indent
<<
kvp
.
first
<<
" = "
<<
to_string
(
kvp
.
second
)
<<
'\n'
;
}
}
}
;
}
}
// namespace <anonymous>
...
...
libcaf_core/src/stringification_inspector.cpp
View file @
68641365
...
...
@@ -18,8 +18,35 @@
#include "caf/detail/stringification_inspector.hpp"
#include <algorithm>
#include <ctime>
#include "caf/atom.hpp"
namespace
{
void
escape
(
std
::
string
&
result
,
char
c
)
{
switch
(
c
)
{
default:
result
+=
c
;
break
;
case
'\n'
:
result
+=
R"(\n)"
;
break
;
case
'\t'
:
result
+=
R"(\t)"
;
break
;
case
'\\'
:
result
+=
R"(\\)"
;
break
;
case
'"'
:
result
+=
R"(\")"
;
break
;
}
}
}
// namespace
namespace
caf
{
namespace
detail
{
...
...
@@ -36,7 +63,7 @@ void stringification_inspector::sep() {
}
}
void
stringification_inspector
::
consume
(
atom_value
&
x
)
{
void
stringification_inspector
::
consume
(
atom_value
x
)
{
result_
+=
'\''
;
result_
+=
to_string
(
x
);
result_
+=
'\''
;
...
...
@@ -54,42 +81,54 @@ void stringification_inspector::consume(string_view str) {
}
// Escape string.
result_
+=
'"'
;
for
(
char
c
:
str
)
{
switch
(
c
)
{
default:
result_
+=
c
;
break
;
case
'\\'
:
result_
+=
R"(\\)"
;
break
;
case
'"'
:
result_
+=
R"(\")"
;
break
;
}
}
for
(
char
c
:
str
)
escape
(
result_
,
c
);
result_
+=
'"'
;
}
void
stringification_inspector
::
consume
(
timespan
&
x
)
{
auto
count
=
x
.
count
();
auto
res
=
[
&
](
const
char
*
suffix
)
{
result_
+=
std
::
to_string
(
count
);
result_
+=
suffix
;
};
// Check whether it's nano-, micro-, or milliseconds.
for
(
auto
suffix
:
{
"ns"
,
"us"
,
"ms"
})
{
if
(
count
%
1000
!=
0
)
return
res
(
suffix
);
count
/=
1000
;
}
// After the loop we only need to differentiate between seconds and minutes.
if
(
count
%
60
!=
0
)
return
res
(
"s"
);
count
/=
60
;
return
res
(
"min"
);
void
stringification_inspector
::
consume
(
timespan
x
)
{
auto
ns
=
x
.
count
();
if
(
ns
%
1000
>
0
)
{
consume
(
ns
);
result_
+=
"ns"
;
return
;
}
auto
us
=
ns
/
1000
;
if
(
us
%
1000
>
0
)
{
consume
(
us
);
result_
+=
"us"
;
return
;
}
auto
ms
=
us
/
1000
;
if
(
ms
%
1000
>
0
)
{
consume
(
ms
);
result_
+=
"ms"
;
return
;
}
auto
s
=
ms
/
1000
;
if
(
s
%
60
>
0
)
{
consume
(
s
);
result_
+=
"s"
;
return
;
}
auto
min
=
s
/
60
;
if
(
min
%
60
>
0
)
{
consume
(
min
);
result_
+=
"min"
;
return
;
}
auto
h
=
min
/
60
;
if
(
min
%
24
>
0
)
{
consume
(
h
);
result_
+=
"h"
;
return
;
}
auto
d
=
h
/
24
;
consume
(
d
);
result_
+=
"d"
;
}
void
stringification_inspector
::
consume
(
timestamp
&
x
)
{
void
stringification_inspector
::
consume
(
timestamp
x
)
{
char
buf
[
64
];
auto
y
=
std
::
chrono
::
time_point_cast
<
timestamp
::
clock
::
duration
>
(
x
);
auto
z
=
timestamp
::
clock
::
to_time_t
(
y
);
...
...
@@ -104,5 +143,69 @@ void stringification_inspector::consume(timestamp& x) {
result_
+=
frac
;
}
void
stringification_inspector
::
consume
(
bool
x
)
{
result_
+=
x
?
"true"
:
"false"
;
}
void
stringification_inspector
::
consume
(
const
void
*
ptr
)
{
result_
+=
"0x"
;
consume
(
reinterpret_cast
<
intptr_t
>
(
ptr
));
}
void
stringification_inspector
::
consume
(
const
char
*
cstr
)
{
if
(
cstr
==
nullptr
)
{
result_
+=
"<null>"
;
return
;
}
if
(
cstr
[
0
]
==
'\0'
)
{
result_
+=
R"("")"
;
return
;
}
if
(
cstr
[
0
]
==
'"'
)
{
// Assume an already escaped string.
result_
+=
cstr
;
return
;
}
// Escape string.
result_
+=
'"'
;
for
(
char
c
=
*
cstr
++
;
c
!=
'\0'
;
c
=
*
cstr
++
)
escape
(
result_
,
c
);
result_
+=
'"'
;
}
void
stringification_inspector
::
consume
(
const
std
::
vector
<
bool
>&
xs
)
{
result_
+=
'['
;
for
(
bool
x
:
xs
)
{
sep
();
consume
(
x
);
}
result_
+=
']'
;
}
void
stringification_inspector
::
consume_int
(
int64_t
x
)
{
if
(
x
>=
0
)
return
consume_int
(
static_cast
<
uint64_t
>
(
x
));
result_
+=
'-'
;
auto
begin
=
result_
.
size
();
result_
+=
-
(
x
%
10
)
+
'0'
;
x
/=
10
;
while
(
x
!=
0
)
{
result_
+=
-
(
x
%
10
)
+
'0'
;
x
/=
10
;
}
std
::
reverse
(
result_
.
begin
()
+
begin
,
result_
.
end
());
}
void
stringification_inspector
::
consume_int
(
uint64_t
x
)
{
auto
begin
=
result_
.
size
();
result_
+=
(
x
%
10
)
+
'0'
;
x
/=
10
;
while
(
x
!=
0
)
{
result_
+=
(
x
%
10
)
+
'0'
;
x
/=
10
;
}
std
::
reverse
(
result_
.
begin
()
+
begin
,
result_
.
end
());
}
}
// namespace detail
}
// namespace caf
libcaf_core/test/deep_to_string.cpp
View file @
68641365
...
...
@@ -32,16 +32,38 @@ void foobar() {
}
// namespace <anonymous>
#define CHECK_DEEP_TO_STRING(val, str) CAF_CHECK_EQUAL(deep_to_string(val), str)
CAF_TEST
(
timespans
)
{
CAF_CHECK_EQUAL
(
deep_to_string
(
timespan
{
1
}),
"1ns"
);
CAF_CHECK_EQUAL
(
deep_to_string
(
timespan
{
1000
}),
"1us"
);
CAF_CHECK_EQUAL
(
deep_to_string
(
timespan
{
1000000
}),
"1ms"
);
CAF_CHECK_EQUAL
(
deep_to_string
(
timespan
{
1000000000
}),
"1s"
);
CAF_CHECK_EQUAL
(
deep_to_string
(
timespan
{
60000000000
}),
"1min"
);
CHECK_DEEP_TO_STRING
(
timespan
{
1
},
"1ns"
);
CHECK_DEEP_TO_STRING
(
timespan
{
1000
},
"1us"
);
CHECK_DEEP_TO_STRING
(
timespan
{
1000000
},
"1ms"
);
CHECK_DEEP_TO_STRING
(
timespan
{
1000000000
},
"1s"
);
CHECK_DEEP_TO_STRING
(
timespan
{
60000000000
},
"1min"
);
}
CAF_TEST
(
integer
lists
)
{
int
carray
[]
=
{
1
,
2
,
3
,
4
};
using
array_type
=
std
::
array
<
int
,
4
>
;
CHECK_DEEP_TO_STRING
(
std
::
list
<
int
>
({
1
,
2
,
3
,
4
}),
"[1, 2, 3, 4]"
);
CHECK_DEEP_TO_STRING
(
std
::
vector
<
int
>
({
1
,
2
,
3
,
4
}),
"[1, 2, 3, 4]"
);
CHECK_DEEP_TO_STRING
(
std
::
set
<
int
>
({
1
,
2
,
3
,
4
}),
"[1, 2, 3, 4]"
);
CHECK_DEEP_TO_STRING
(
array_type
({{
1
,
2
,
3
,
4
}}),
"[1, 2, 3, 4]"
);
CHECK_DEEP_TO_STRING
(
carray
,
"[1, 2, 3, 4]"
);
}
CAF_TEST
(
boolean
lists
)
{
bool
carray
[]
=
{
false
,
true
};
using
array_type
=
std
::
array
<
bool
,
2
>
;
CHECK_DEEP_TO_STRING
(
std
::
list
<
bool
>
({
false
,
true
}),
"[false, true]"
);
CHECK_DEEP_TO_STRING
(
std
::
vector
<
bool
>
({
false
,
true
}),
"[false, true]"
);
CHECK_DEEP_TO_STRING
(
std
::
set
<
bool
>
({
false
,
true
}),
"[false, true]"
);
CHECK_DEEP_TO_STRING
(
array_type
({{
false
,
true
}}),
"[false, true]"
);
CHECK_DEEP_TO_STRING
(
carray
,
"[false, true]"
);
}
CAF_TEST
(
pointers
)
{
auto
i
=
42
;
C
AF_CHECK_EQUAL
(
deep_to_string
(
&
i
)
,
"*42"
);
C
AF_CHECK_EQUAL
(
deep_to_string
(
foobar
)
,
"<fun>"
);
C
HECK_DEEP_TO_STRING
(
&
i
,
"*42"
);
C
HECK_DEEP_TO_STRING
(
foobar
,
"<fun>"
);
}
libcaf_core/test/message.cpp
View file @
68641365
...
...
@@ -272,10 +272,10 @@ CAF_TEST(tuples_to_string) {
}
CAF_TEST
(
arrays_to_string
)
{
CAF_CHECK_EQUAL
(
msg_as_string
(
s1
{}),
"(
(10, 20, 30)
)"
);
CAF_CHECK_EQUAL
(
msg_as_string
(
s1
{}),
"(
[10, 20, 30]
)"
);
auto
msg2
=
make_message
(
s2
{});
s2
tmp
;
tmp
.
value
[
0
][
1
]
=
100
;
CAF_CHECK_EQUAL
(
to_string
(
msg2
),
"(
((1, 10), (2, 20), (3, 30), (4, 40))
)"
);
CAF_CHECK_EQUAL
(
msg_as_string
(
s3
{}),
"(
(1, 2, 3, 4)
)"
);
CAF_CHECK_EQUAL
(
to_string
(
msg2
),
"(
[[1, 10], [2, 20], [3, 30], [4, 40]]
)"
);
CAF_CHECK_EQUAL
(
msg_as_string
(
s3
{}),
"(
[1, 2, 3, 4]
)"
);
}
libcaf_core/test/serialization.cpp
View file @
68641365
...
...
@@ -554,7 +554,7 @@ SERIALIZATION_TEST(bool_vector_size_0) {
SERIALIZATION_TEST
(
bool_vector_size_1
)
{
std
::
vector
<
bool
>
xs
{
true
};
CAF_CHECK_EQUAL
(
deep_to_string
(
xs
),
"[
1
]"
);
CAF_CHECK_EQUAL
(
deep_to_string
(
xs
),
"[
true
]"
);
CAF_CHECK_EQUAL
(
xs
,
roundtrip
(
xs
));
CAF_CHECK_EQUAL
(
xs
,
msg_roundtrip
(
xs
));
}
...
...
@@ -563,11 +563,14 @@ SERIALIZATION_TEST(bool_vector_size_63) {
std
::
vector
<
bool
>
xs
;
for
(
int
i
=
0
;
i
<
63
;
++
i
)
xs
.
push_back
(
i
%
3
==
0
);
CAF_CHECK_EQUAL
(
deep_to_string
(
xs
),
"[1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, "
"0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, "
"1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, "
"0, 1, 0, 0]"
);
CAF_CHECK_EQUAL
(
deep_to_string
(
xs
),
"[true, false, false, true, false, false, true, false, false, true, false, "
"false, true, false, false, true, false, false, true, false, false, true, "
"false, false, true, false, false, true, false, false, true, false, false, "
"true, false, false, true, false, false, true, false, false, true, false, "
"false, true, false, false, true, false, false, true, false, false, true, "
"false, false, true, false, false, true, false, false]"
);
CAF_CHECK_EQUAL
(
xs
,
roundtrip
(
xs
));
CAF_CHECK_EQUAL
(
xs
,
msg_roundtrip
(
xs
));
}
...
...
@@ -577,10 +580,14 @@ SERIALIZATION_TEST(bool_vector_size_64) {
for
(
int
i
=
0
;
i
<
64
;
++
i
)
xs
.
push_back
(
i
%
5
==
0
);
CAF_CHECK_EQUAL
(
deep_to_string
(
xs
),
"[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, "
"0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, "
"0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, "
"0, 1, 0, 0, 0]"
);
"[true, false, false, false, false, true, false, false, "
"false, false, true, false, false, false, false, true, "
"false, false, false, false, true, false, false, false, "
"false, true, false, false, false, false, true, false, "
"false, false, false, true, false, false, false, false, "
"true, false, false, false, false, true, false, false, "
"false, false, true, false, false, false, false, true, "
"false, false, false, false, true, false, false, false]"
);
CAF_CHECK_EQUAL
(
xs
,
roundtrip
(
xs
));
CAF_CHECK_EQUAL
(
xs
,
msg_roundtrip
(
xs
));
}
...
...
@@ -589,11 +596,14 @@ SERIALIZATION_TEST(bool_vector_size_65) {
std
::
vector
<
bool
>
xs
;
for
(
int
i
=
0
;
i
<
65
;
++
i
)
xs
.
push_back
(
!
(
i
%
7
==
0
));
CAF_CHECK_EQUAL
(
deep_to_string
(
xs
),
"[0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, "
"1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, "
"1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, "
"1, 1, 1, 1, 0, 1]"
);
CAF_CHECK_EQUAL
(
deep_to_string
(
xs
),
"[false, true, true, true, true, true, true, false, true, true, true, "
"true, true, true, false, true, true, true, true, true, true, false, true, "
"true, true, true, true, true, false, true, true, true, true, true, true, "
"false, true, true, true, true, true, true, false, true, true, true, true, "
"true, true, false, true, true, true, true, true, true, false, true, true, "
"true, true, true, true, false, true]"
);
CAF_CHECK_EQUAL
(
xs
,
roundtrip
(
xs
));
CAF_CHECK_EQUAL
(
xs
,
msg_roundtrip
(
xs
));
}
libcaf_core/test/serializer_impl.cpp
View file @
68641365
...
...
@@ -165,4 +165,4 @@ CAF_TEST(serialize and deserialize with std::vector<uint8_t>) {
CAF_CHECK_EQUAL
(
data_to_serialize
,
deserialized_data
);
}
CAF_TEST_FIXTURE_SCOPE_END
()
;
CAF_TEST_FIXTURE_SCOPE_END
()
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