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
Show 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:
for
(
auto
&
x
:
xs
)
{
using
value_type
=
typename
std
::
remove_reference
<
decltype
(
x
)
>::
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
none
;
...
...
@@ -252,7 +252,7 @@ public:
template
<
class
U
,
class
T
>
error
consume_range_c
(
T
&
xs
)
{
for
(
U
x
:
xs
)
{
if
(
auto
err
=
apply_derived
(
x
))
if
(
auto
err
=
dref
().
apply
(
x
))
return
err
;
}
return
none
;
...
...
@@ -264,7 +264,7 @@ public:
auto
insert_iter
=
std
::
inserter
(
xs
,
xs
.
end
());
for
(
size_t
i
=
0
;
i
<
num_elements
;
++
i
)
{
typename
std
::
remove_const
<
typename
T
::
value_type
>::
type
x
;
if
(
auto
err
=
apply_derived
(
x
))
if
(
auto
err
=
dref
().
apply
(
x
))
return
err
;
*
insert_iter
++
=
std
::
move
(
x
);
}
...
...
@@ -278,7 +278,7 @@ public:
auto
insert_iter
=
std
::
inserter
(
xs
,
xs
.
end
());
for
(
size_t
i
=
0
;
i
<
num_elements
;
++
i
)
{
U
x
;
if
(
auto
err
=
apply_derived
(
x
))
if
(
auto
err
=
dref
().
apply
(
x
))
return
err
;
*
insert_iter
++
=
std
::
move
(
x
);
}
...
...
@@ -375,8 +375,9 @@ public:
using
t0
=
typename
std
::
remove_const
<
F
>::
type
;
// This cast allows the data processor to cope with
// `pair<const K, V>` value types used by `std::map`.
return
error
::
eval
([
&
]
{
return
apply_derived
(
const_cast
<
t0
&>
(
xs
.
first
));
},
[
&
]
{
return
apply_derived
(
xs
.
second
);
});
if
(
auto
err
=
dref
().
apply
(
const_cast
<
t0
&>
(
xs
.
first
)))
return
err
;
return
dref
().
apply
(
xs
.
second
);
}
template
<
class
...
Ts
>
...
...
@@ -470,29 +471,31 @@ public:
// -- operator() -------------------------------------------------------------
inline
error
operator
()()
{
error
operator
()()
{
return
none
;
}
template
<
class
F
,
class
...
Ts
>
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
)
e
=
x
.
fun
();
return
e
?
e
:
(
*
this
)(
std
::
forward
<
Ts
>
(
xs
)...);
if
(
auto
err
=
x
.
fun
())
return
err
;
return
dref
()(
std
::
forward
<
Ts
>
(
xs
)...);
}
template
<
class
F
,
class
...
Ts
>
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
)
e
=
x
.
fun
();
return
e
?
e
:
(
*
this
)(
std
::
forward
<
Ts
>
(
xs
)...);
if
(
auto
err
=
x
.
fun
())
return
err
;
return
dref
()(
std
::
forward
<
Ts
>
(
xs
)...);
}
template
<
class
...
Ts
>
error
operator
()(
const
meta
::
annotation
&
,
Ts
&&
...
xs
)
{
return
(
*
this
)(
std
::
forward
<
Ts
>
(
xs
)...);
return
dref
(
)(
std
::
forward
<
Ts
>
(
xs
)...);
}
template
<
class
T
,
class
...
Ts
>
...
...
@@ -501,7 +504,7 @@ public:
error
>::
type
operator
()(
const
T
&
,
Ts
&&
...
xs
)
{
return
(
*
this
)(
std
::
forward
<
Ts
>
(
xs
)...);
return
dref
(
)(
std
::
forward
<
Ts
>
(
xs
)...);
}
template
<
class
T
,
class
...
Ts
>
...
...
@@ -519,7 +522,7 @@ public:
"a loading inspector requires mutable lvalue references"
);
if
(
auto
err
=
apply
(
deconst
(
x
)))
return
err
;
return
apply_derived
(
std
::
forward
<
Ts
>
(
xs
)...);
return
dref
()
(
std
::
forward
<
Ts
>
(
xs
)...);
}
protected
:
...
...
@@ -578,12 +581,6 @@ private:
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_
;
}
;
...
...
libcaf_core/caf/deep_to_string.hpp
View file @
0a03d7d6
...
...
@@ -38,9 +38,16 @@ std::string deep_to_string(const Ts&... xs) {
return
result
;
}
/// Wrapper to `deep_to_string` for using the function as an inspector.
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
>
std
::
string
operator
()(
const
Ts
&
...
xs
)
const
{
result_type
operator
()(
const
Ts
&
...
xs
)
const
{
return
deep_to_string
(
xs
...);
}
};
...
...
libcaf_core/caf/error.hpp
View file @
0a03d7d6
...
...
@@ -19,18 +19,15 @@
#pragma once
#include <cstdint>
#include <utility>
#include <functional>
#include "caf/fwd.hpp"
#include "caf/atom.hpp"
#include "caf/none.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/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
{
...
...
@@ -56,8 +53,8 @@ public:
/// Convenience alias for `std::enable_if<has_make_error<T>::value, U>::type`.
template
<
class
T
,
class
U
=
void
>
using
enable_if_has_make_error_t
=
typename
std
::
enable_if
<
has_make_error
<
T
>::
value
,
U
>::
type
;
using
enable_if_has_make_error_t
=
typename
std
::
enable_if
<
has_make_error
<
T
>::
value
,
U
>::
type
;
/// A serializable type for storing error codes with category and optional,
/// human-readable context information. Unlike error handling classes from
...
...
@@ -91,13 +88,6 @@ using enable_if_has_make_error_t
/// rendering error messages via `actor_system::render(const error&)`.
class
error
:
detail
::
comparable
<
error
>
{
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 --------------------
error
()
noexcept
;
...
...
@@ -141,12 +131,12 @@ public:
const
message
&
context
()
const
noexcept
;
/// Returns `*this != none`.
inline
explicit
operator
bool
()
const
noexcept
{
explicit
operator
bool
()
const
noexcept
{
return
data_
!=
nullptr
;
}
/// Returns `*this == none`.
inline
bool
operator
!
()
const
noexcept
{
bool
operator
!
()
const
noexcept
{
return
data_
==
nullptr
;
}
...
...
@@ -156,6 +146,14 @@ public:
// -- 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.
/// @pre `*this != none`
message
&
context
()
noexcept
;
...
...
@@ -163,46 +161,74 @@ public:
/// Sets the error code to 0.
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 -------------------------------------------
/// @cond PRIVATE
static
inline
error
eval
()
{
static
error
eval
()
{
return
none
;
}
template
<
class
F
,
class
...
Fs
>
static
error
eval
(
F
&&
f
,
Fs
&&
...
fs
)
{
auto
x
=
f
();
return
x
?
x
:
eval
(
std
::
forward
<
Fs
>
(
fs
)...);
if
(
auto
err
=
f
())
return
err
;
return
eval
(
std
::
forward
<
Fs
>
(
fs
)...);
}
/// @endcond
// --
friend functions
-------------------------------------------------------
// --
nested classes --
-------------------------------------------------------
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
)
;
struct
data
;
struct
inspect_helper
{
uint8_t
code
;
error
&
err
;
};
return
x
.
apply
(
fun
);
}
private:
// --
inspection support
-----------------------------------------------------
// --
member variables --
-----------------------------------------------------
error
apply
(
const
inspect_fun
&
f
);
data
*
data_
;
};
// -- nested classes ------------
---------------------------------------------
// -- operators and free functions
---------------------------------------------
struct
data
;
/// @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
});
}
// -- member variables -------------------------------------------------------
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
());
}
data
*
data_
;
};
/// @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
std
::
string
to_string
(
const
error
&
x
);
...
...
@@ -252,4 +278,3 @@ bool operator!=(E x, const error& y) {
}
}
// namespace caf
libcaf_core/src/error.cpp
View file @
0a03d7d6
...
...
@@ -18,11 +18,11 @@
#include "caf/error.hpp"
#include "caf/config.hpp"
#include "caf/message.hpp"
#include "caf/serializer.hpp"
#include "caf/deserializer.hpp"
#include <utility>
#include "caf/deep_to_string.hpp"
#include "caf/make_message.hpp"
#include "caf/message.hpp"
namespace
caf
{
...
...
@@ -55,8 +55,11 @@ error& error::operator=(error&& x) noexcept {
return
*
this
;
}
error
::
error
(
const
error
&
x
)
:
data_
(
x
?
new
data
(
*
x
.
data_
)
:
nullptr
)
{
// nop
error
::
error
(
const
error
&
x
)
{
if
(
x
)
data_
=
new
data
(
*
x
.
data_
);
else
data_
=
nullptr
;
}
error
&
error
::
operator
=
(
const
error
&
x
)
{
...
...
@@ -73,8 +76,7 @@ error& error::operator=(const error& x) {
return
*
this
;
}
error
::
error
(
uint8_t
x
,
atom_value
y
)
:
data_
(
x
!=
0
?
new
data
{
x
,
y
,
none
}
:
nullptr
)
{
error
::
error
(
uint8_t
x
,
atom_value
y
)
:
error
(
x
,
y
,
make_message
())
{
// nop
}
...
...
@@ -139,6 +141,16 @@ int error::compare(uint8_t x, atom_value y) const noexcept {
// -- 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
{
CAF_ASSERT
(
data_
!=
nullptr
);
return
data_
->
context
;
...
...
@@ -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
)
{
data
tmp
{
0
,
atom
(
""
),
message
{}};
data
&
ref
=
data_
!=
nullptr
?
*
data_
:
tmp
;
auto
result
=
f
(
meta
::
type_name
(
"error"
),
ref
.
code
,
ref
.
category
,
meta
::
omittable_if_empty
(),
ref
.
context
);
if
(
ref
.
code
==
0
)
clear
();
else
if
(
&
tmp
==
&
ref
)
data_
=
new
data
(
std
::
move
(
tmp
));
return
result
;
void
error
::
assign
(
uint8_t
code
,
atom_value
category
,
message
context
)
{
if
(
data_
==
nullptr
)
{
data_
=
new
data
{
code
,
category
,
std
::
move
(
context
)};
}
else
{
data_
->
code
=
code
;
data_
->
category
=
category
;
data_
->
context
=
std
::
move
(
context
);
}
}
// -- operators and free functions ---------------------------------------------
std
::
string
to_string
(
const
error
&
x
)
{
if
(
!
x
)
return
"none"
;
return
deep_to_string
(
meta
::
type_name
(
"error"
),
x
.
code
(),
x
.
category
(),
meta
::
omittable_if_empty
(),
x
.
context
()
);
deep_to_string_t
f
;
return
inspect
(
f
,
x
);
}
}
// 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