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
0a03d7d6
Unverified
Commit
0a03d7d6
authored
Sep 11, 2019
by
Dominik Charousset
Committed by
GitHub
Sep 11, 2019
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #913
Reduce stack usage and indirections in serializers
parents
58f1d373
ae331cb6
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
128 additions
and
85 deletions
+128
-85
libcaf_core/caf/data_processor.hpp
libcaf_core/caf/data_processor.hpp
+19
-22
libcaf_core/caf/deep_to_string.hpp
libcaf_core/caf/deep_to_string.hpp
+8
-1
libcaf_core/caf/error.hpp
libcaf_core/caf/error.hpp
+65
-40
libcaf_core/src/error.cpp
libcaf_core/src/error.cpp
+36
-22
No files found.
libcaf_core/caf/data_processor.hpp
View file @
0a03d7d6
...
@@ -242,7 +242,7 @@ public:
...
@@ -242,7 +242,7 @@ public:
for
(
auto
&
x
:
xs
)
{
for
(
auto
&
x
:
xs
)
{
using
value_type
=
typename
std
::
remove_reference
<
decltype
(
x
)
>::
type
;
using
value_type
=
typename
std
::
remove_reference
<
decltype
(
x
)
>::
type
;
using
mutable_type
=
typename
std
::
remove_const
<
value_type
>::
type
;
using
mutable_type
=
typename
std
::
remove_const
<
value_type
>::
type
;
if
(
auto
err
=
apply_derived
(
const_cast
<
mutable_type
&>
(
x
)))
if
(
auto
err
=
dref
().
apply
(
const_cast
<
mutable_type
&>
(
x
)))
return
err
;
return
err
;
}
}
return
none
;
return
none
;
...
@@ -252,7 +252,7 @@ public:
...
@@ -252,7 +252,7 @@ public:
template
<
class
U
,
class
T
>
template
<
class
U
,
class
T
>
error
consume_range_c
(
T
&
xs
)
{
error
consume_range_c
(
T
&
xs
)
{
for
(
U
x
:
xs
)
{
for
(
U
x
:
xs
)
{
if
(
auto
err
=
apply_derived
(
x
))
if
(
auto
err
=
dref
().
apply
(
x
))
return
err
;
return
err
;
}
}
return
none
;
return
none
;
...
@@ -264,7 +264,7 @@ public:
...
@@ -264,7 +264,7 @@ public:
auto
insert_iter
=
std
::
inserter
(
xs
,
xs
.
end
());
auto
insert_iter
=
std
::
inserter
(
xs
,
xs
.
end
());
for
(
size_t
i
=
0
;
i
<
num_elements
;
++
i
)
{
for
(
size_t
i
=
0
;
i
<
num_elements
;
++
i
)
{
typename
std
::
remove_const
<
typename
T
::
value_type
>::
type
x
;
typename
std
::
remove_const
<
typename
T
::
value_type
>::
type
x
;
if
(
auto
err
=
apply_derived
(
x
))
if
(
auto
err
=
dref
().
apply
(
x
))
return
err
;
return
err
;
*
insert_iter
++
=
std
::
move
(
x
);
*
insert_iter
++
=
std
::
move
(
x
);
}
}
...
@@ -278,7 +278,7 @@ public:
...
@@ -278,7 +278,7 @@ public:
auto
insert_iter
=
std
::
inserter
(
xs
,
xs
.
end
());
auto
insert_iter
=
std
::
inserter
(
xs
,
xs
.
end
());
for
(
size_t
i
=
0
;
i
<
num_elements
;
++
i
)
{
for
(
size_t
i
=
0
;
i
<
num_elements
;
++
i
)
{
U
x
;
U
x
;
if
(
auto
err
=
apply_derived
(
x
))
if
(
auto
err
=
dref
().
apply
(
x
))
return
err
;
return
err
;
*
insert_iter
++
=
std
::
move
(
x
);
*
insert_iter
++
=
std
::
move
(
x
);
}
}
...
@@ -375,8 +375,9 @@ public:
...
@@ -375,8 +375,9 @@ public:
using
t0
=
typename
std
::
remove_const
<
F
>::
type
;
using
t0
=
typename
std
::
remove_const
<
F
>::
type
;
// This cast allows the data processor to cope with
// This cast allows the data processor to cope with
// `pair<const K, V>` value types used by `std::map`.
// `pair<const K, V>` value types used by `std::map`.
return
error
::
eval
([
&
]
{
return
apply_derived
(
const_cast
<
t0
&>
(
xs
.
first
));
},
if
(
auto
err
=
dref
().
apply
(
const_cast
<
t0
&>
(
xs
.
first
)))
[
&
]
{
return
apply_derived
(
xs
.
second
);
});
return
err
;
return
dref
().
apply
(
xs
.
second
);
}
}
template
<
class
...
Ts
>
template
<
class
...
Ts
>
...
@@ -470,29 +471,31 @@ public:
...
@@ -470,29 +471,31 @@ public:
// -- operator() -------------------------------------------------------------
// -- operator() -------------------------------------------------------------
inline
error
operator
()()
{
error
operator
()()
{
return
none
;
return
none
;
}
}
template
<
class
F
,
class
...
Ts
>
template
<
class
F
,
class
...
Ts
>
error
operator
()(
meta
::
save_callback_t
<
F
>
x
,
Ts
&&
...
xs
)
{
error
operator
()(
meta
::
save_callback_t
<
F
>
x
,
Ts
&&
...
xs
)
{
error
e
;
// TODO: use `if constexpr` when switching to C++17.
if
(
Derived
::
reads_state
)
if
(
Derived
::
reads_state
)
e
=
x
.
fun
();
if
(
auto
err
=
x
.
fun
())
return
e
?
e
:
(
*
this
)(
std
::
forward
<
Ts
>
(
xs
)...);
return
err
;
return
dref
()(
std
::
forward
<
Ts
>
(
xs
)...);
}
}
template
<
class
F
,
class
...
Ts
>
template
<
class
F
,
class
...
Ts
>
error
operator
()(
meta
::
load_callback_t
<
F
>
x
,
Ts
&&
...
xs
)
{
error
operator
()(
meta
::
load_callback_t
<
F
>
x
,
Ts
&&
...
xs
)
{
error
e
;
// TODO: use `if constexpr` when switching to C++17.
if
(
Derived
::
writes_state
)
if
(
Derived
::
writes_state
)
e
=
x
.
fun
();
if
(
auto
err
=
x
.
fun
())
return
e
?
e
:
(
*
this
)(
std
::
forward
<
Ts
>
(
xs
)...);
return
err
;
return
dref
()(
std
::
forward
<
Ts
>
(
xs
)...);
}
}
template
<
class
...
Ts
>
template
<
class
...
Ts
>
error
operator
()(
const
meta
::
annotation
&
,
Ts
&&
...
xs
)
{
error
operator
()(
const
meta
::
annotation
&
,
Ts
&&
...
xs
)
{
return
(
*
this
)(
std
::
forward
<
Ts
>
(
xs
)...);
return
dref
(
)(
std
::
forward
<
Ts
>
(
xs
)...);
}
}
template
<
class
T
,
class
...
Ts
>
template
<
class
T
,
class
...
Ts
>
...
@@ -501,7 +504,7 @@ public:
...
@@ -501,7 +504,7 @@ public:
error
error
>::
type
>::
type
operator
()(
const
T
&
,
Ts
&&
...
xs
)
{
operator
()(
const
T
&
,
Ts
&&
...
xs
)
{
return
(
*
this
)(
std
::
forward
<
Ts
>
(
xs
)...);
return
dref
(
)(
std
::
forward
<
Ts
>
(
xs
)...);
}
}
template
<
class
T
,
class
...
Ts
>
template
<
class
T
,
class
...
Ts
>
...
@@ -519,7 +522,7 @@ public:
...
@@ -519,7 +522,7 @@ public:
"a loading inspector requires mutable lvalue references"
);
"a loading inspector requires mutable lvalue references"
);
if
(
auto
err
=
apply
(
deconst
(
x
)))
if
(
auto
err
=
apply
(
deconst
(
x
)))
return
err
;
return
err
;
return
apply_derived
(
std
::
forward
<
Ts
>
(
xs
)...);
return
dref
()
(
std
::
forward
<
Ts
>
(
xs
)...);
}
}
protected
:
protected
:
...
@@ -578,12 +581,6 @@ private:
...
@@ -578,12 +581,6 @@ private:
return
*
static_cast
<
Derived
*>
(
this
);
return
*
static_cast
<
Derived
*>
(
this
);
}
}
// Applies `xs...` to `dref()`.
template
<
class
...
Ts
>
error
apply_derived
(
Ts
&&
...
xs
)
{
return
dref
()(
std
::
forward
<
Ts
>
(
xs
)...);
}
execution_unit
*
context_
;
execution_unit
*
context_
;
}
;
}
;
...
...
libcaf_core/caf/deep_to_string.hpp
View file @
0a03d7d6
...
@@ -38,9 +38,16 @@ std::string deep_to_string(const Ts&... xs) {
...
@@ -38,9 +38,16 @@ std::string deep_to_string(const Ts&... xs) {
return
result
;
return
result
;
}
}
/// Wrapper to `deep_to_string` for using the function as an inspector.
struct
deep_to_string_t
{
struct
deep_to_string_t
{
using
result_type
=
std
::
string
;
static
constexpr
bool
reads_state
=
true
;
static
constexpr
bool
writes_state
=
false
;
template
<
class
...
Ts
>
template
<
class
...
Ts
>
std
::
string
operator
()(
const
Ts
&
...
xs
)
const
{
result_type
operator
()(
const
Ts
&
...
xs
)
const
{
return
deep_to_string
(
xs
...);
return
deep_to_string
(
xs
...);
}
}
};
};
...
...
libcaf_core/caf/error.hpp
View file @
0a03d7d6
...
@@ -19,18 +19,15 @@
...
@@ -19,18 +19,15 @@
#pragma once
#pragma once
#include <cstdint>
#include <cstdint>
#include <utility>
#include <functional>
#include "caf/fwd.hpp"
#include "caf/atom.hpp"
#include "caf/none.hpp"
#include "caf/atom.hpp"
#include "caf/atom.hpp"
#include "caf/meta/type_name.hpp"
#include "caf/meta/omittable_if_empty.hpp"
#include "caf/detail/comparable.hpp"
#include "caf/detail/comparable.hpp"
#include "caf/detail/type_traits.hpp"
#include "caf/fwd.hpp"
#include "caf/meta/load_callback.hpp"
#include "caf/meta/omittable_if_empty.hpp"
#include "caf/meta/type_name.hpp"
#include "caf/none.hpp"
namespace
caf
{
namespace
caf
{
...
@@ -56,8 +53,8 @@ public:
...
@@ -56,8 +53,8 @@ public:
/// Convenience alias for `std::enable_if<has_make_error<T>::value, U>::type`.
/// Convenience alias for `std::enable_if<has_make_error<T>::value, U>::type`.
template
<
class
T
,
class
U
=
void
>
template
<
class
T
,
class
U
=
void
>
using
enable_if_has_make_error_t
using
enable_if_has_make_error_t
=
typename
std
::
enable_if
<
=
typename
std
::
enable_if
<
has_make_error
<
T
>::
value
,
U
>::
type
;
has_make_error
<
T
>::
value
,
U
>::
type
;
/// A serializable type for storing error codes with category and optional,
/// A serializable type for storing error codes with category and optional,
/// human-readable context information. Unlike error handling classes from
/// human-readable context information. Unlike error handling classes from
...
@@ -91,13 +88,6 @@ using enable_if_has_make_error_t
...
@@ -91,13 +88,6 @@ using enable_if_has_make_error_t
/// rendering error messages via `actor_system::render(const error&)`.
/// rendering error messages via `actor_system::render(const error&)`.
class
error
:
detail
::
comparable
<
error
>
{
class
error
:
detail
::
comparable
<
error
>
{
public:
public:
// -- member types -----------------------------------------------------------
using
inspect_fun
=
std
::
function
<
error
(
meta
::
type_name_t
,
uint8_t
&
,
atom_value
&
,
meta
::
omittable_if_empty_t
,
message
&
)
>
;
// -- constructors, destructors, and assignment operators --------------------
// -- constructors, destructors, and assignment operators --------------------
error
()
noexcept
;
error
()
noexcept
;
...
@@ -141,12 +131,12 @@ public:
...
@@ -141,12 +131,12 @@ public:
const
message
&
context
()
const
noexcept
;
const
message
&
context
()
const
noexcept
;
/// Returns `*this != none`.
/// Returns `*this != none`.
inline
explicit
operator
bool
()
const
noexcept
{
explicit
operator
bool
()
const
noexcept
{
return
data_
!=
nullptr
;
return
data_
!=
nullptr
;
}
}
/// Returns `*this == none`.
/// Returns `*this == none`.
inline
bool
operator
!
()
const
noexcept
{
bool
operator
!
()
const
noexcept
{
return
data_
==
nullptr
;
return
data_
==
nullptr
;
}
}
...
@@ -156,6 +146,14 @@ public:
...
@@ -156,6 +146,14 @@ public:
// -- modifiers --------------------------------------------------------------
// -- modifiers --------------------------------------------------------------
/// Returns the category-specific error code, whereas `0` means "no error".
/// @pre `*this != none`
uint8_t
&
code
()
noexcept
;
/// Returns the category of this error.
/// @pre `*this != none`
atom_value
&
category
()
noexcept
;
/// Returns context information to this error.
/// Returns context information to this error.
/// @pre `*this != none`
/// @pre `*this != none`
message
&
context
()
noexcept
;
message
&
context
()
noexcept
;
...
@@ -163,47 +161,75 @@ public:
...
@@ -163,47 +161,75 @@ public:
/// Sets the error code to 0.
/// Sets the error code to 0.
void
clear
()
noexcept
;
void
clear
()
noexcept
;
/// Assigns new code and category to this error.
void
assign
(
uint8_t
code
,
atom_value
category
);
/// Assigns new code, category and context to this error.
void
assign
(
uint8_t
code
,
atom_value
category
,
message
context
);
// -- static convenience functions -------------------------------------------
// -- static convenience functions -------------------------------------------
/// @cond PRIVATE
/// @cond PRIVATE
static
inline
error
eval
()
{
static
error
eval
()
{
return
none
;
return
none
;
}
}
template
<
class
F
,
class
...
Fs
>
template
<
class
F
,
class
...
Fs
>
static
error
eval
(
F
&&
f
,
Fs
&&
...
fs
)
{
static
error
eval
(
F
&&
f
,
Fs
&&
...
fs
)
{
auto
x
=
f
();
if
(
auto
err
=
f
())
return
x
?
x
:
eval
(
std
::
forward
<
Fs
>
(
fs
)...);
return
err
;
return
eval
(
std
::
forward
<
Fs
>
(
fs
)...);
}
}
/// @endcond
/// @endcond
// -- friend functions -------------------------------------------------------
template
<
class
Inspector
>
friend
typename
Inspector
::
result_type
inspect
(
Inspector
&
f
,
error
&
x
)
{
auto
fun
=
[
&
](
meta
::
type_name_t
x0
,
uint8_t
&
x1
,
atom_value
&
x2
,
meta
::
omittable_if_empty_t
x3
,
message
&
x4
)
->
error
{
return
f
(
x0
,
x1
,
x2
,
x3
,
x4
);
};
return
x
.
apply
(
fun
);
}
private:
// -- inspection support -----------------------------------------------------
error
apply
(
const
inspect_fun
&
f
);
// -- nested classes ---------------------------------------------------------
// -- nested classes ---------------------------------------------------------
struct
data
;
struct
data
;
struct
inspect_helper
{
uint8_t
code
;
error
&
err
;
};
private:
// -- member variables -------------------------------------------------------
// -- member variables -------------------------------------------------------
data
*
data_
;
data
*
data_
;
};
};
// -- operators and free functions ---------------------------------------------
/// @relates error
template
<
class
Inspector
>
detail
::
enable_if_t
<
Inspector
::
reads_state
,
typename
Inspector
::
result_type
>
inspect
(
Inspector
&
f
,
const
error
&
x
)
{
if
(
x
)
return
f
(
meta
::
type_name
(
"error"
),
x
.
code
(),
x
.
category
(),
meta
::
omittable_if_empty
(),
x
.
context
());
return
f
(
meta
::
type_name
(
"error"
),
uint8_t
{
0
});
}
template
<
class
Inspector
>
detail
::
enable_if_t
<
Inspector
::
writes_state
,
typename
Inspector
::
result_type
>
inspect
(
Inspector
&
f
,
error
::
inspect_helper
&
x
)
{
if
(
x
.
code
==
0
)
{
x
.
err
.
clear
();
return
f
();
}
x
.
err
.
assign
(
x
.
code
,
atom
(
""
));
return
f
(
x
.
err
.
category
(),
x
.
err
.
context
());
}
/// @relates error
template
<
class
Inspector
>
detail
::
enable_if_t
<
Inspector
::
writes_state
,
typename
Inspector
::
result_type
>
inspect
(
Inspector
&
f
,
error
&
x
)
{
error
::
inspect_helper
helper
{
0
,
x
};
return
f
(
helper
.
code
,
helper
);
}
/// @relates error
/// @relates error
std
::
string
to_string
(
const
error
&
x
);
std
::
string
to_string
(
const
error
&
x
);
...
@@ -252,4 +278,3 @@ bool operator!=(E x, const error& y) {
...
@@ -252,4 +278,3 @@ bool operator!=(E x, const error& y) {
}
}
}
// namespace caf
}
// namespace caf
libcaf_core/src/error.cpp
View file @
0a03d7d6
...
@@ -18,11 +18,11 @@
...
@@ -18,11 +18,11 @@
#include "caf/error.hpp"
#include "caf/error.hpp"
#include "caf/config.hpp"
#include <utility>
#include "caf/message.hpp"
#include "caf/serializer.hpp"
#include "caf/deserializer.hpp"
#include "caf/deep_to_string.hpp"
#include "caf/deep_to_string.hpp"
#include "caf/make_message.hpp"
#include "caf/message.hpp"
namespace
caf
{
namespace
caf
{
...
@@ -55,8 +55,11 @@ error& error::operator=(error&& x) noexcept {
...
@@ -55,8 +55,11 @@ error& error::operator=(error&& x) noexcept {
return
*
this
;
return
*
this
;
}
}
error
::
error
(
const
error
&
x
)
:
data_
(
x
?
new
data
(
*
x
.
data_
)
:
nullptr
)
{
error
::
error
(
const
error
&
x
)
{
// nop
if
(
x
)
data_
=
new
data
(
*
x
.
data_
);
else
data_
=
nullptr
;
}
}
error
&
error
::
operator
=
(
const
error
&
x
)
{
error
&
error
::
operator
=
(
const
error
&
x
)
{
...
@@ -73,13 +76,12 @@ error& error::operator=(const error& x) {
...
@@ -73,13 +76,12 @@ error& error::operator=(const error& x) {
return
*
this
;
return
*
this
;
}
}
error
::
error
(
uint8_t
x
,
atom_value
y
)
error
::
error
(
uint8_t
x
,
atom_value
y
)
:
error
(
x
,
y
,
make_message
())
{
:
data_
(
x
!=
0
?
new
data
{
x
,
y
,
none
}
:
nullptr
)
{
// nop
// nop
}
}
error
::
error
(
uint8_t
x
,
atom_value
y
,
message
z
)
error
::
error
(
uint8_t
x
,
atom_value
y
,
message
z
)
:
data_
(
x
!=
0
?
new
data
{
x
,
y
,
std
::
move
(
z
)}
:
nullptr
)
{
:
data_
(
x
!=
0
?
new
data
{
x
,
y
,
std
::
move
(
z
)}
:
nullptr
)
{
// nop
// nop
}
}
...
@@ -139,6 +141,16 @@ int error::compare(uint8_t x, atom_value y) const noexcept {
...
@@ -139,6 +141,16 @@ int error::compare(uint8_t x, atom_value y) const noexcept {
// -- modifiers --------------------------------------------------------------
// -- modifiers --------------------------------------------------------------
uint8_t
&
error
::
code
()
noexcept
{
CAF_ASSERT
(
data_
!=
nullptr
);
return
data_
->
code
;
}
atom_value
&
error
::
category
()
noexcept
{
CAF_ASSERT
(
data_
!=
nullptr
);
return
data_
->
category
;
}
message
&
error
::
context
()
noexcept
{
message
&
error
::
context
()
noexcept
{
CAF_ASSERT
(
data_
!=
nullptr
);
CAF_ASSERT
(
data_
!=
nullptr
);
return
data_
->
context
;
return
data_
->
context
;
...
@@ -151,25 +163,27 @@ void error::clear() noexcept {
...
@@ -151,25 +163,27 @@ void error::clear() noexcept {
}
}
}
}
// -- inspection support -----------------------------------------------------
void
error
::
assign
(
uint8_t
code
,
atom_value
category
)
{
return
assign
(
code
,
category
,
make_message
());
}
error
error
::
apply
(
const
inspect_fun
&
f
)
{
void
error
::
assign
(
uint8_t
code
,
atom_value
category
,
message
context
)
{
data
tmp
{
0
,
atom
(
""
),
message
{}};
if
(
data_
==
nullptr
)
{
data
&
ref
=
data_
!=
nullptr
?
*
data_
:
tmp
;
data_
=
new
data
{
code
,
category
,
std
::
move
(
context
)};
auto
result
=
f
(
meta
::
type_name
(
"error"
),
ref
.
code
,
ref
.
category
,
}
else
{
meta
::
omittable_if_empty
(),
ref
.
context
);
data_
->
code
=
code
;
if
(
ref
.
code
==
0
)
data_
->
category
=
category
;
clear
();
data_
->
context
=
std
::
move
(
context
);
else
if
(
&
tmp
==
&
ref
)
}
data_
=
new
data
(
std
::
move
(
tmp
));
return
result
;
}
}
// -- operators and free functions ---------------------------------------------
std
::
string
to_string
(
const
error
&
x
)
{
std
::
string
to_string
(
const
error
&
x
)
{
if
(
!
x
)
if
(
!
x
)
return
"none"
;
return
"none"
;
return
deep_to_string
(
meta
::
type_name
(
"error"
),
x
.
code
(),
x
.
category
(),
deep_to_string_t
f
;
meta
::
omittable_if_empty
(),
x
.
context
()
);
return
inspect
(
f
,
x
);
}
}
}
// namespace caf
}
// namespace caf
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