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
dbdf9b26
Unverified
Commit
dbdf9b26
authored
Jan 05, 2021
by
Noir
Committed by
GitHub
Jan 05, 2021
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1194
Re-implement config_option using get_as
parents
3f59e8d4
f4c56936
Changes
54
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
54 changed files
with
1208 additions
and
1903 deletions
+1208
-1903
CHANGELOG.md
CHANGELOG.md
+21
-3
libcaf_core/caf/actor_system_config.hpp
libcaf_core/caf/actor_system_config.hpp
+16
-18
libcaf_core/caf/config_option.hpp
libcaf_core/caf/config_option.hpp
+19
-19
libcaf_core/caf/config_option_adder.hpp
libcaf_core/caf/config_option_adder.hpp
+2
-6
libcaf_core/caf/config_value.hpp
libcaf_core/caf/config_value.hpp
+153
-795
libcaf_core/caf/detail/config_consumer.hpp
libcaf_core/caf/detail/config_consumer.hpp
+7
-3
libcaf_core/caf/detail/dispatch_parse_cli.hpp
libcaf_core/caf/detail/dispatch_parse_cli.hpp
+0
-61
libcaf_core/caf/detail/parse.hpp
libcaf_core/caf/detail/parse.hpp
+12
-104
libcaf_core/caf/detail/parser/read_config.hpp
libcaf_core/caf/detail/parser/read_config.hpp
+26
-0
libcaf_core/caf/detail/stringification_inspector.hpp
libcaf_core/caf/detail/stringification_inspector.hpp
+7
-0
libcaf_core/caf/detail/type_traits.hpp
libcaf_core/caf/detail/type_traits.hpp
+38
-0
libcaf_core/caf/make_config_option.hpp
libcaf_core/caf/make_config_option.hpp
+24
-46
libcaf_core/caf/parser_state.hpp
libcaf_core/caf/parser_state.hpp
+4
-0
libcaf_core/caf/sec.hpp
libcaf_core/caf/sec.hpp
+2
-0
libcaf_core/caf/settings.hpp
libcaf_core/caf/settings.hpp
+36
-22
libcaf_core/caf/telemetry/histogram.hpp
libcaf_core/caf/telemetry/histogram.hpp
+1
-1
libcaf_core/caf/telemetry/metric_registry.hpp
libcaf_core/caf/telemetry/metric_registry.hpp
+1
-1
libcaf_core/src/actor_system.cpp
libcaf_core/src/actor_system.cpp
+2
-2
libcaf_core/src/actor_system_config.cpp
libcaf_core/src/actor_system_config.cpp
+8
-8
libcaf_core/src/config_option.cpp
libcaf_core/src/config_option.cpp
+11
-10
libcaf_core/src/config_option_adder.cpp
libcaf_core/src/config_option_adder.cpp
+5
-0
libcaf_core/src/config_option_set.cpp
libcaf_core/src/config_option_set.cpp
+26
-16
libcaf_core/src/config_value.cpp
libcaf_core/src/config_value.cpp
+83
-14
libcaf_core/src/config_value_reader.cpp
libcaf_core/src/config_value_reader.cpp
+2
-2
libcaf_core/src/config_value_writer.cpp
libcaf_core/src/config_value_writer.cpp
+2
-1
libcaf_core/src/detail/config_consumer.cpp
libcaf_core/src/detail/config_consumer.cpp
+15
-26
libcaf_core/src/detail/parse.cpp
libcaf_core/src/detail/parse.cpp
+54
-9
libcaf_core/src/logger.cpp
libcaf_core/src/logger.cpp
+1
-1
libcaf_core/src/make_config_option.cpp
libcaf_core/src/make_config_option.cpp
+23
-57
libcaf_core/src/scheduler/abstract_coordinator.cpp
libcaf_core/src/scheduler/abstract_coordinator.cpp
+2
-4
libcaf_core/src/sec_strings.cpp
libcaf_core/src/sec_strings.cpp
+6
-0
libcaf_core/src/settings.cpp
libcaf_core/src/settings.cpp
+6
-6
libcaf_core/test/actor_system_config.cpp
libcaf_core/test/actor_system_config.cpp
+10
-2
libcaf_core/test/config_option.cpp
libcaf_core/test/config_option.cpp
+162
-12
libcaf_core/test/config_option_set.cpp
libcaf_core/test/config_option_set.cpp
+21
-33
libcaf_core/test/config_value.cpp
libcaf_core/test/config_value.cpp
+89
-378
libcaf_core/test/config_value_writer.cpp
libcaf_core/test/config_value_writer.cpp
+25
-32
libcaf_core/test/core-test.cpp
libcaf_core/test/core-test.cpp
+45
-0
libcaf_core/test/core-test.hpp
libcaf_core/test/core-test.hpp
+11
-15
libcaf_core/test/detail/config_consumer.cpp
libcaf_core/test/detail/config_consumer.cpp
+5
-6
libcaf_core/test/detail/parse.cpp
libcaf_core/test/detail/parse.cpp
+5
-32
libcaf_core/test/detail/parser/read_bool.cpp
libcaf_core/test/detail/parser/read_bool.cpp
+16
-15
libcaf_core/test/load_inspector.cpp
libcaf_core/test/load_inspector.cpp
+2
-1
libcaf_core/test/message.cpp
libcaf_core/test/message.cpp
+3
-3
libcaf_core/test/message_lifetime.cpp
libcaf_core/test/message_lifetime.cpp
+2
-1
libcaf_core/test/mixin/requester.cpp
libcaf_core/test/mixin/requester.cpp
+7
-7
libcaf_core/test/settings.cpp
libcaf_core/test/settings.cpp
+36
-70
libcaf_core/test/span.cpp
libcaf_core/test/span.cpp
+8
-8
libcaf_core/test/variant.cpp
libcaf_core/test/variant.cpp
+6
-12
libcaf_io/src/io/basp/instance.cpp
libcaf_io/src/io/basp/instance.cpp
+3
-3
libcaf_io/src/io/middleman.cpp
libcaf_io/src/io/middleman.cpp
+1
-1
libcaf_test/caf/test/bdd_dsl.hpp
libcaf_test/caf/test/bdd_dsl.hpp
+5
-0
libcaf_test/caf/test/unit_test.hpp
libcaf_test/caf/test/unit_test.hpp
+86
-37
libcaf_test/caf/test/unit_test_impl.hpp
libcaf_test/caf/test/unit_test_impl.hpp
+45
-0
No files found.
CHANGELOG.md
View file @
dbdf9b26
...
@@ -16,6 +16,18 @@ is based on [Keep a Changelog](https://keepachangelog.com).
...
@@ -16,6 +16,18 @@ is based on [Keep a Changelog](https://keepachangelog.com).
and
`caf.middleman.serialization-time`
.
and
`caf.middleman.serialization-time`
.
-
The macro
`CAF_ADD_TYPE_ID`
now accepts an optional third parameter for
-
The macro
`CAF_ADD_TYPE_ID`
now accepts an optional third parameter for
allowing users to override the default type name.
allowing users to override the default type name.
-
The new function pair
`get_as`
and
`get_or`
model type conversions on a
`config_value`
. For example,
`get_as<int>(x)`
would convert the content of
`x`
to an
`int`
by either casting numeric values to
`int`
(with bound checks) or
trying to parse the input of
`x`
if it contains a string. The function
`get_or`
already existed for
`settings`
, but we have added new overloads for
generalizing the function to
`config_value`
as well.
### Deprecated
-
The new
`get_as`
and
`get_or`
function pair makes type conversions on a
`config_value`
via
`get`
,
`get_if`
, etc. obsolete. We will retain the
STL-style interface for treating a
`config_value`
as a
`variant`
-like type.
### Changed
### Changed
...
@@ -23,9 +35,15 @@ is based on [Keep a Changelog](https://keepachangelog.com).
...
@@ -23,9 +35,15 @@ is based on [Keep a Changelog](https://keepachangelog.com).
i.e.,
`caf-application.conf`
.
i.e.,
`caf-application.conf`
.
-
Simplify the type inspection API by removing the distinction between
-
Simplify the type inspection API by removing the distinction between
`apply_object`
and
`apply_value`
. Instead, inspectors only offer
`apply`
and
`apply_object`
and
`apply_value`
. Instead, inspectors only offer
`apply`
and
users may now also call
`map`
,
`list`
,
`tuple`
and
`value`
for unboxing simple
users may now also call
`map`
,
`list`
, and
`tuple`
for unboxing simple wrapper
wrapper types. Furthermore, CAF no longer automatically serializes enumeration
types. Furthermore, CAF no longer automatically serializes enumeration types
types using their underlying value because this is fundamentally unsafe.
using their underlying value because this is fundamentally unsafe.
-
CAF no longer parses the input to string options on the command line. For
example,
`my_app '--msg="hello"'`
results in CAF storing
`"hello"`
(including
the quotes) for the config option
`msg`
. Previously, CAF tried to parse any
string input on the command-line that starts with quotes in the same way it
would parse strings from a config file, leading to very unintuitive results in
some cases (#1113).
### Fixed
### Fixed
...
...
libcaf_core/caf/actor_system_config.hpp
View file @
dbdf9b26
...
@@ -325,6 +325,13 @@ private:
...
@@ -325,6 +325,13 @@ private:
/// Returns all user-provided configuration parameters.
/// Returns all user-provided configuration parameters.
CAF_CORE_EXPORT
const
settings
&
content
(
const
actor_system_config
&
cfg
);
CAF_CORE_EXPORT
const
settings
&
content
(
const
actor_system_config
&
cfg
);
/// Returns whether `xs` associates a value of type `T` to `name`.
/// @relates actor_system_config
template
<
class
T
>
bool
holds_alternative
(
const
actor_system_config
&
cfg
,
string_view
name
)
{
return
holds_alternative
<
T
>
(
content
(
cfg
),
name
);
}
/// Tries to retrieve the value associated to `name` from `cfg`.
/// Tries to retrieve the value associated to `name` from `cfg`.
/// @relates actor_system_config
/// @relates actor_system_config
template
<
class
T
>
template
<
class
T
>
...
@@ -339,29 +346,20 @@ T get(const actor_system_config& cfg, string_view name) {
...
@@ -339,29 +346,20 @@ T get(const actor_system_config& cfg, string_view name) {
return
get
<
T
>
(
content
(
cfg
),
name
);
return
get
<
T
>
(
content
(
cfg
),
name
);
}
}
/// Retrieves the value associated to `name` from `cfg` or returns
/// Retrieves the value associated to `name` from `cfg` or returns `fallback`.
/// `default_value`.
/// @relates actor_system_config
/// @relates actor_system_config
template
<
class
T
,
class
=
typename
std
::
enable_if
<
template
<
class
To
=
get_or_auto_deduce
,
class
Fallback
>
!
std
::
is_pointer
<
T
>
::
value
auto
get_or
(
const
actor_system_config
&
cfg
,
string_view
name
,
&&
!
std
::
is_convertible
<
T
,
string_view
>::
value
>::
type
>
Fallback
&&
fallback
)
{
T
get_or
(
const
actor_system_config
&
cfg
,
string_view
name
,
T
default_value
)
{
return
get_or
<
To
>
(
content
(
cfg
),
name
,
std
::
forward
<
Fallback
>
(
fallback
));
return
get_or
(
content
(
cfg
),
name
,
std
::
move
(
default_value
));
}
}
/// Retrieves the value associated to `name` from `cfg` or returns
/// Tries to retrieve the value associated to `name` from `cfg` as an instance
/// `default_value`.
/// of type `T`.
/// @relates actor_system_config
inline
std
::
string
get_or
(
const
actor_system_config
&
cfg
,
string_view
name
,
string_view
default_value
)
{
return
get_or
(
content
(
cfg
),
name
,
default_value
);
}
/// Returns whether `xs` associates a value of type `T` to `name`.
/// @relates actor_system_config
/// @relates actor_system_config
template
<
class
T
>
template
<
class
T
>
bool
holds_alternative
(
const
actor_system_config
&
cfg
,
string_view
name
)
{
expected
<
T
>
get_as
(
const
actor_system_config
&
cfg
,
string_view
name
)
{
return
holds_alternative
<
T
>
(
content
(
cfg
),
name
);
return
get_as
<
T
>
(
content
(
cfg
),
name
);
}
}
}
// namespace caf
}
// namespace caf
libcaf_core/caf/config_option.hpp
View file @
dbdf9b26
...
@@ -36,22 +36,19 @@ public:
...
@@ -36,22 +36,19 @@ public:
/// Custom vtable-like struct for delegating to type-specific functions and
/// Custom vtable-like struct for delegating to type-specific functions and
/// storing type-specific information shared by several config options.
/// storing type-specific information shared by several config options.
struct
meta_state
{
struct
meta_state
{
/// Checks whether a value matches the option's type.
/// Tries to perform this sequence of steps:
error
(
*
check
)(
const
config_value
&
);
/// - Convert the config value to the type of the config option.
/// - Assign the converted value back to the config value to synchronize
/// Stores a value in the given location.
/// conversions back to the caller.
void
(
*
store
)(
void
*
,
const
config_value
&
);
/// - Store the converted value in the pointer unless it is `nullptr`.
error
(
*
sync
)(
void
*
,
config_value
&
);
/// Tries to extract a value from the given location. Exists for backward
/// Tries to extract a value from the given location. Exists for backward
/// compatibility only and will get removed with CAF 0.17.
/// compatibility only and will get removed with CAF 0.17.
config_value
(
*
get
)(
const
void
*
);
config_value
(
*
get
)(
const
void
*
);
/// Tries to parse an input string. Stores and returns the parsed value on
/// success, returns an error otherwise.
expected
<
config_value
>
(
*
parse
)(
void
*
,
string_view
);
/// Human-readable name of the option's type.
/// Human-readable name of the option's type.
st
d
::
string
type_name
;
st
ring_view
type_name
;
};
};
// -- constructors, destructors, and assignment operators --------------------
// -- constructors, destructors, and assignment operators --------------------
...
@@ -89,12 +86,19 @@ public:
...
@@ -89,12 +86,19 @@ public:
/// Returns the full name for this config option as "<category>.<long name>".
/// Returns the full name for this config option as "<category>.<long name>".
string_view
full_name
()
const
noexcept
;
string_view
full_name
()
const
noexcept
;
/// Checks whether `x` holds a legal value for this option.
/// Synchronizes the value of this config option with `x` and vice versa.
error
check
(
const
config_value
&
x
)
const
;
///
/// Tries to perform this sequence of steps:
/// - Convert the config value to the type of the config option.
/// - Assign the converted value back to the config value to synchronize
/// conversions back to the caller.
/// - Store the converted value unless this option is stateless.
error
sync
(
config_value
&
x
)
const
;
/// Stores `x` in this option unless it is stateless.
[[
deprecated
(
"use sync instead"
)]]
error
store
(
const
config_value
&
x
)
const
;
/// @pre `check(x) == none`.
void
store
(
const
config_value
&
x
)
const
;
[[
deprecated
(
"use sync instead"
)]]
expected
<
config_value
>
parse
(
string_view
input
)
const
;
/// Returns a human-readable representation of this option's expected type.
/// Returns a human-readable representation of this option's expected type.
string_view
type_name
()
const
noexcept
;
string_view
type_name
()
const
noexcept
;
...
@@ -105,10 +109,6 @@ public:
...
@@ -105,10 +109,6 @@ public:
/// Returns whether the category is optional for CLI options.
/// Returns whether the category is optional for CLI options.
bool
has_flat_cli_name
()
const
noexcept
;
bool
has_flat_cli_name
()
const
noexcept
;
/// Tries to parse an input string. Stores and returns the parsed value on
/// success, returns an error otherwise.
expected
<
config_value
>
parse
(
string_view
input
)
const
;
/// @private
/// @private
// TODO: remove with CAF 0.17
// TODO: remove with CAF 0.17
optional
<
config_value
>
get
()
const
;
optional
<
config_value
>
get
()
const
;
...
...
libcaf_core/caf/config_option_adder.hpp
View file @
dbdf9b26
...
@@ -52,14 +52,10 @@ public:
...
@@ -52,14 +52,10 @@ public:
config_option_adder
&
config_option_adder
&
add_neg
(
bool
&
ref
,
string_view
name
,
string_view
description
);
add_neg
(
bool
&
ref
,
string_view
name
,
string_view
description
);
/// For backward compatibility only. Do not use for new code!
[[
deprecated
(
"use timespan options instead"
)]]
config_option_adder
&
/// @private
config_option_adder
&
add_us
(
size_t
&
ref
,
string_view
name
,
string_view
description
);
add_us
(
size_t
&
ref
,
string_view
name
,
string_view
description
);
/// For backward compatibility only. Do not use for new code!
[[
deprecated
(
"use timespan options instead"
)]]
config_option_adder
&
/// @private
config_option_adder
&
add_ms
(
size_t
&
ref
,
string_view
name
,
string_view
description
);
add_ms
(
size_t
&
ref
,
string_view
name
,
string_view
description
);
private:
private:
...
...
libcaf_core/caf/config_value.hpp
View file @
dbdf9b26
This diff is collapsed.
Click to expand it.
libcaf_core/caf/detail/config_consumer.hpp
View file @
dbdf9b26
...
@@ -36,6 +36,8 @@ class CAF_CORE_EXPORT config_list_consumer {
...
@@ -36,6 +36,8 @@ class CAF_CORE_EXPORT config_list_consumer {
public:
public:
// -- constructors, destructors, and assignment operators --------------------
// -- constructors, destructors, and assignment operators --------------------
config_list_consumer
()
=
default
;
config_list_consumer
(
const
config_option_set
*
options
,
config_list_consumer
(
const
config_option_set
*
options
,
config_consumer
*
parent
);
config_consumer
*
parent
);
...
@@ -60,18 +62,20 @@ public:
...
@@ -60,18 +62,20 @@ public:
template
<
class
T
>
template
<
class
T
>
void
value
(
T
&&
x
)
{
void
value
(
T
&&
x
)
{
xs_
.
emplace_back
(
std
::
forward
<
T
>
(
x
));
result
.
emplace_back
(
std
::
forward
<
T
>
(
x
));
}
}
config_value
::
list
result
;
std
::
string
qualified_key
();
std
::
string
qualified_key
();
private:
private:
// -- member variables -------------------------------------------------------
// -- member variables -------------------------------------------------------
const
config_option_set
*
options_
=
nullptr
;
const
config_option_set
*
options_
=
nullptr
;
variant
<
config_consumer
*
,
config_list_consumer
*
,
config_value_consumer
*>
variant
<
none_t
,
config_consumer
*
,
config_list_consumer
*
,
config_value_consumer
*>
parent_
;
parent_
;
config_value
::
list
xs_
;
};
};
/// Consumes a series of key-value pairs from an application configuration.
/// Consumes a series of key-value pairs from an application configuration.
...
...
libcaf_core/caf/detail/dispatch_parse_cli.hpp
deleted
100644 → 0
View file @
3f59e8d4
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2019 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 <type_traits>
#include "caf/config_value.hpp"
#include "caf/detail/type_traits.hpp"
namespace
caf
::
detail
{
template
<
class
Trait
>
struct
dispatch_parse_cli_helper
{
template
<
class
...
Ts
>
auto
operator
()(
Ts
&&
...
xs
)
->
decltype
(
Trait
::
parse_cli
(
std
::
forward
<
Ts
>
(
xs
)...))
{
return
Trait
::
parse_cli
(
std
::
forward
<
Ts
>
(
xs
)...);
}
};
template
<
class
Access
,
class
T
>
void
dispatch_parse_cli
(
std
::
true_type
,
string_parser_state
&
ps
,
T
&
x
,
const
char
*
char_blacklist
)
{
Access
::
parse_cli
(
ps
,
x
,
char_blacklist
);
}
template
<
class
Access
,
class
T
>
void
dispatch_parse_cli
(
std
::
false_type
,
string_parser_state
&
ps
,
T
&
x
,
const
char
*
)
{
Access
::
parse_cli
(
ps
,
x
);
}
template
<
class
T
>
void
dispatch_parse_cli
(
string_parser_state
&
ps
,
T
&
x
,
const
char
*
char_blacklist
)
{
using
access
=
caf
::
select_config_value_access_t
<
T
>
;
using
helper_fun
=
dispatch_parse_cli_helper
<
access
>
;
using
token_type
=
bool_token
<
detail
::
is_callable_with
<
helper_fun
,
string_parser_state
&
,
T
&
,
const
char
*>::
value
>
;
token_type
token
;
dispatch_parse_cli
<
access
>
(
token
,
ps
,
x
,
char_blacklist
);
}
}
// namespace caf::detail
libcaf_core/caf/detail/parse.hpp
View file @
dbdf9b26
...
@@ -101,21 +101,25 @@ CAF_CORE_EXPORT void parse(string_parser_state& ps, long double& x);
...
@@ -101,21 +101,25 @@ CAF_CORE_EXPORT void parse(string_parser_state& ps, long double& x);
// -- CAF types ----------------------------------------------------------------
// -- CAF types ----------------------------------------------------------------
CAF_CORE_EXPORT
void
parse
(
string_parser_state
&
ps
,
ipv4_address
&
x
);
CAF_CORE_EXPORT
void
parse
(
string_parser_state
&
,
ipv4_address
&
);
CAF_CORE_EXPORT
void
parse
(
string_parser_state
&
ps
,
ipv4_subnet
&
x
);
CAF_CORE_EXPORT
void
parse
(
string_parser_state
&
,
ipv4_subnet
&
);
CAF_CORE_EXPORT
void
parse
(
string_parser_state
&
ps
,
ipv4_endpoint
&
x
);
CAF_CORE_EXPORT
void
parse
(
string_parser_state
&
,
ipv4_endpoint
&
);
CAF_CORE_EXPORT
void
parse
(
string_parser_state
&
ps
,
ipv6_address
&
x
);
CAF_CORE_EXPORT
void
parse
(
string_parser_state
&
,
ipv6_address
&
);
CAF_CORE_EXPORT
void
parse
(
string_parser_state
&
ps
,
ipv6_subnet
&
x
);
CAF_CORE_EXPORT
void
parse
(
string_parser_state
&
,
ipv6_subnet
&
);
CAF_CORE_EXPORT
void
parse
(
string_parser_state
&
ps
,
ipv6_endpoint
&
x
);
CAF_CORE_EXPORT
void
parse
(
string_parser_state
&
,
ipv6_endpoint
&
);
CAF_CORE_EXPORT
void
parse
(
string_parser_state
&
ps
,
uri
&
x
);
CAF_CORE_EXPORT
void
parse
(
string_parser_state
&
,
uri
&
);
CAF_CORE_EXPORT
void
parse
(
string_parser_state
&
ps
,
config_value
&
x
);
CAF_CORE_EXPORT
void
parse
(
string_parser_state
&
,
config_value
&
);
CAF_CORE_EXPORT
void
parse
(
string_parser_state
&
,
std
::
vector
<
config_value
>&
);
CAF_CORE_EXPORT
void
parse
(
string_parser_state
&
,
dictionary
<
config_value
>&
);
// -- variadic utility ---------------------------------------------------------
// -- variadic utility ---------------------------------------------------------
...
@@ -209,102 +213,6 @@ void parse(string_parser_state& ps,
...
@@ -209,102 +213,6 @@ void parse(string_parser_state& ps,
x
=
value_type
{
since_epoch
};
x
=
value_type
{
since_epoch
};
}
}
// -- container types ----------------------------------------------------------
CAF_CORE_EXPORT
void
parse_element
(
string_parser_state
&
ps
,
std
::
string
&
x
,
const
char
*
char_blacklist
);
template
<
class
T
>
enable_if_t
<!
is_pair
<
T
>::
value
>
parse_element
(
string_parser_state
&
ps
,
T
&
x
,
const
char
*
);
template
<
class
First
,
class
Second
,
size_t
N
>
void
parse_element
(
string_parser_state
&
ps
,
std
::
pair
<
First
,
Second
>&
kvp
,
const
char
(
&
char_blacklist
)[
N
]);
struct
require_opening_char_t
{};
constexpr
auto
require_opening_char
=
require_opening_char_t
{};
struct
allow_omitting_opening_char_t
{};
constexpr
auto
allow_omitting_opening_char
=
allow_omitting_opening_char_t
{};
template
<
class
T
,
class
Policy
=
allow_omitting_opening_char_t
>
enable_if_tt
<
is_iterable
<
T
>>
parse
(
string_parser_state
&
ps
,
T
&
xs
,
Policy
=
{})
{
using
value_type
=
deconst_kvp_t
<
typename
T
::
value_type
>
;
static
constexpr
auto
is_map_type
=
is_pair
<
value_type
>::
value
;
static
constexpr
auto
opening_char
=
is_map_type
?
'{'
:
'['
;
static
constexpr
auto
closing_char
=
is_map_type
?
'}'
:
']'
;
auto
out
=
std
::
inserter
(
xs
,
xs
.
end
());
// List/map using [] or {} notation.
if
(
ps
.
consume
(
opening_char
))
{
char
char_blacklist
[]
=
{
closing_char
,
','
,
'\0'
};
do
{
if
(
ps
.
consume
(
closing_char
))
{
ps
.
skip_whitespaces
();
ps
.
code
=
ps
.
at_end
()
?
pec
::
success
:
pec
::
trailing_character
;
return
;
}
value_type
tmp
;
parse_element
(
ps
,
tmp
,
char_blacklist
);
if
(
ps
.
code
>
pec
::
trailing_character
)
return
;
*
out
++
=
std
::
move
(
tmp
);
}
while
(
ps
.
consume
(
','
));
if
(
ps
.
consume
(
closing_char
))
{
ps
.
skip_whitespaces
();
ps
.
code
=
ps
.
at_end
()
?
pec
::
success
:
pec
::
trailing_character
;
}
else
{
ps
.
code
=
pec
::
unexpected_character
;
}
return
;
}
if
constexpr
(
std
::
is_same
<
Policy
,
require_opening_char_t
>::
value
)
{
ps
.
code
=
pec
::
unexpected_character
;
}
else
{
// An empty string simply results in an empty list/map.
if
(
ps
.
at_end
())
return
;
// List/map without [] or {}.
do
{
char
char_blacklist
[]
=
{
','
,
'\0'
};
value_type
tmp
;
parse_element
(
ps
,
tmp
,
char_blacklist
);
if
(
ps
.
code
>
pec
::
trailing_character
)
return
;
*
out
++
=
std
::
move
(
tmp
);
}
while
(
ps
.
consume
(
','
));
ps
.
code
=
ps
.
at_end
()
?
pec
::
success
:
pec
::
trailing_character
;
}
}
template
<
class
T
>
enable_if_t
<!
is_pair
<
T
>::
value
>
parse_element
(
string_parser_state
&
ps
,
T
&
x
,
const
char
*
)
{
parse
(
ps
,
x
);
}
template
<
class
First
,
class
Second
,
size_t
N
>
void
parse_element
(
string_parser_state
&
ps
,
std
::
pair
<
First
,
Second
>&
kvp
,
const
char
(
&
char_blacklist
)[
N
])
{
static_assert
(
N
>
0
,
"empty array"
);
// TODO: consider to guard the blacklist computation with
// `if constexpr (is_same_v<First, string>)` when switching to C++17.
char
key_blacklist
[
N
+
1
];
if
(
N
>
1
)
memcpy
(
key_blacklist
,
char_blacklist
,
N
-
1
);
key_blacklist
[
N
-
1
]
=
'='
;
key_blacklist
[
N
]
=
'\0'
;
parse_element
(
ps
,
kvp
.
first
,
key_blacklist
);
if
(
ps
.
code
>
pec
::
trailing_character
)
return
;
if
(
!
ps
.
consume
(
'='
))
{
ps
.
code
=
pec
::
unexpected_character
;
return
;
}
parse_element
(
ps
,
kvp
.
second
,
char_blacklist
);
}
// -- convenience functions ----------------------------------------------------
// -- convenience functions ----------------------------------------------------
CAF_CORE_EXPORT
CAF_CORE_EXPORT
...
...
libcaf_core/caf/detail/parser/read_config.hpp
View file @
dbdf9b26
...
@@ -102,6 +102,28 @@ void read_config_list(State& ps, Consumer&& consumer) {
...
@@ -102,6 +102,28 @@ void read_config_list(State& ps, Consumer&& consumer) {
// clang-format on
// clang-format on
}
}
// Like read_config_list, but without surrounding '[]'.
template
<
class
State
,
class
Consumer
>
void
lift_config_list
(
State
&
ps
,
Consumer
&&
consumer
)
{
// clang-format off
start
();
state
(
init
)
{
epsilon
(
before_value
)
}
term_state
(
before_value
)
{
transition
(
before_value
,
"
\t\n
"
)
fsm_epsilon
(
read_config_comment
(
ps
,
consumer
),
before_value
,
'#'
)
fsm_epsilon
(
read_config_value
(
ps
,
consumer
,
std
::
true_type
{}),
after_value
)
}
term_state
(
after_value
)
{
transition
(
after_value
,
"
\t\n
"
)
transition
(
before_value
,
','
)
fsm_epsilon
(
read_config_comment
(
ps
,
consumer
),
after_value
,
'#'
)
}
fin
();
// clang-format on
}
template
<
bool
Nested
=
true
,
class
State
,
class
Consumer
>
template
<
bool
Nested
=
true
,
class
State
,
class
Consumer
>
void
read_config_map
(
State
&
ps
,
Consumer
&&
consumer
)
{
void
read_config_map
(
State
&
ps
,
Consumer
&&
consumer
)
{
std
::
string
key
;
std
::
string
key
;
...
@@ -140,6 +162,7 @@ void read_config_map(State& ps, Consumer&& consumer) {
...
@@ -140,6 +162,7 @@ void read_config_map(State& ps, Consumer&& consumer) {
unstable_state
(
after_value
)
{
unstable_state
(
after_value
)
{
transition
(
after_value
,
"
\t
"
)
transition
(
after_value
,
"
\t
"
)
transition
(
had_newline
,
"
\n
"
)
transition
(
had_newline
,
"
\n
"
)
transition_if
(
!
Nested
,
after_comma
,
','
)
transition
(
await_key_name
,
','
)
transition
(
await_key_name
,
','
)
transition_if
(
Nested
,
done
,
'}'
,
consumer
.
end_map
())
transition_if
(
Nested
,
done
,
'}'
,
consumer
.
end_map
())
fsm_epsilon
(
read_config_comment
(
ps
,
consumer
),
had_newline
,
'#'
)
fsm_epsilon
(
read_config_comment
(
ps
,
consumer
),
had_newline
,
'#'
)
...
@@ -157,6 +180,9 @@ void read_config_map(State& ps, Consumer&& consumer) {
...
@@ -157,6 +180,9 @@ void read_config_map(State& ps, Consumer&& consumer) {
epsilon_if
(
!
Nested
,
done
)
epsilon_if
(
!
Nested
,
done
)
epsilon
(
unexpected_end_of_input
)
epsilon
(
unexpected_end_of_input
)
}
}
term_state
(
after_comma
)
{
epsilon
(
await_key_name
)
}
state
(
unexpected_end_of_input
)
{
state
(
unexpected_end_of_input
)
{
// no transitions, only needed for the unstable states
// no transitions, only needed for the unstable states
}
}
...
...
libcaf_core/caf/detail/stringification_inspector.hpp
View file @
dbdf9b26
...
@@ -189,6 +189,13 @@ public:
...
@@ -189,6 +189,13 @@ public:
return
true
;
return
true
;
}
else
if
constexpr
(
std
::
is_same
<
T
,
char
>::
value
)
{
}
else
if
constexpr
(
std
::
is_same
<
T
,
char
>::
value
)
{
return
value
(
string_view
{
x
,
strlen
(
x
)});
return
value
(
string_view
{
x
,
strlen
(
x
)});
}
else
if
constexpr
(
std
::
is_same
<
T
,
void
>::
value
)
{
sep
();
result_
+=
"*<"
;
auto
addr
=
reinterpret_cast
<
intptr_t
>
(
x
);
result_
+=
std
::
to_string
(
addr
);
result_
+=
'>'
;
return
true
;
}
else
{
}
else
{
sep
();
sep
();
result_
+=
'*'
;
result_
+=
'*'
;
...
...
libcaf_core/caf/detail/type_traits.hpp
View file @
dbdf9b26
...
@@ -685,6 +685,44 @@ public:
...
@@ -685,6 +685,44 @@ public:
static
constexpr
bool
value
=
sfinae_type
::
value
;
static
constexpr
bool
value
=
sfinae_type
::
value
;
};
};
template
<
class
T
>
struct
has_reserve
{
private:
template
<
class
List
>
static
auto
sfinae
(
List
*
l
)
->
decltype
(
l
->
reserve
(
10
),
std
::
true_type
());
template
<
class
U
>
static
auto
sfinae
(...)
->
std
::
false_type
;
using
sfinae_type
=
decltype
(
sfinae
<
T
>
(
nullptr
));
public:
static
constexpr
bool
value
=
sfinae_type
::
value
;
};
template
<
class
T
>
constexpr
bool
has_reserve_v
=
has_reserve
<
T
>::
value
;
template
<
class
T
>
struct
has_emplace_back
{
private:
template
<
class
List
>
static
auto
sfinae
(
List
*
l
)
->
decltype
(
l
->
emplace_back
(
std
::
declval
<
typename
List
::
value_type
>
()),
std
::
true_type
());
template
<
class
U
>
static
auto
sfinae
(...)
->
std
::
false_type
;
using
sfinae_type
=
decltype
(
sfinae
<
T
>
(
nullptr
));
public:
static
constexpr
bool
value
=
sfinae_type
::
value
;
};
template
<
class
T
>
constexpr
bool
has_emplace_back_v
=
has_emplace_back
<
T
>::
value
;
template
<
class
T
>
template
<
class
T
>
class
has_call_error_handler
{
class
has_call_error_handler
{
private:
private:
...
...
libcaf_core/caf/make_config_option.hpp
View file @
dbdf9b26
...
@@ -22,7 +22,6 @@
...
@@ -22,7 +22,6 @@
#include "caf/config_option.hpp"
#include "caf/config_option.hpp"
#include "caf/config_value.hpp"
#include "caf/config_value.hpp"
#include "caf/detail/parse.hpp"
#include "caf/detail/type_traits.hpp"
#include "caf/detail/type_traits.hpp"
#include "caf/error.hpp"
#include "caf/error.hpp"
#include "caf/expected.hpp"
#include "caf/expected.hpp"
...
@@ -30,62 +29,41 @@
...
@@ -30,62 +29,41 @@
#include "caf/pec.hpp"
#include "caf/pec.hpp"
#include "caf/string_view.hpp"
#include "caf/string_view.hpp"
namespace
caf
{
namespace
caf
::
detail
{
namespace
detail
{
template
<
class
T
>
error
check_impl
(
const
config_value
&
x
)
{
if
(
holds_alternative
<
T
>
(
x
))
return
none
;
return
make_error
(
pec
::
type_mismatch
);
}
template
<
class
T
>
void
store_impl
(
void
*
ptr
,
const
config_value
&
x
)
{
*
static_cast
<
T
*>
(
ptr
)
=
get
<
T
>
(
x
);
}
template
<
class
T
>
config_value
get_impl
(
const
void
*
ptr
)
{
using
trait
=
detail
::
config_value_access_t
<
T
>
;
return
config_value
{
trait
::
convert
(
*
reinterpret_cast
<
const
T
*>
(
ptr
))};
}
template
<
class
T
>
template
<
class
T
>
expected
<
config_value
>
parse_impl
(
T
*
ptr
,
string_view
str
)
{
error
sync_impl
(
void
*
ptr
,
config_value
&
x
)
{
if
(
!
ptr
)
{
if
(
auto
val
=
get_as
<
T
>
(
x
))
{
T
tmp
;
if
(
auto
err
=
x
.
assign
(
*
val
);
!
err
)
{
return
parse_impl
(
&
tmp
,
str
);
if
(
ptr
)
*
static_cast
<
T
*>
(
ptr
)
=
std
::
move
(
*
val
);
return
none
;
}
else
{
return
err
;
}
}
else
{
return
std
::
move
(
val
.
error
());
}
}
if
constexpr
(
detail
::
has_clear_member
<
T
>::
value
)
ptr
->
clear
();
using
trait
=
detail
::
config_value_access_t
<
T
>
;
string_parser_state
ps
{
str
.
begin
(),
str
.
end
()};
trait
::
parse_cli
(
ps
,
*
ptr
,
top_level_cli_parsing
);
if
(
ps
.
code
!=
pec
::
success
)
return
make_error
(
ps
);
return
config_value
{
trait
::
convert
(
*
ptr
)};
}
}
CAF_CORE_EXPORT
expected
<
config_value
>
parse_impl
(
std
::
string
*
ptr
,
string_view
str
);
template
<
class
T
>
template
<
class
T
>
expected
<
config_value
>
parse_impl_delegate
(
void
*
ptr
,
string_view
str
)
{
config_value
get_impl
(
const
void
*
ptr
)
{
return
parse_impl
(
reinterpret_cast
<
T
*>
(
ptr
),
str
);
config_value
result
;
auto
err
=
result
.
assign
(
*
static_cast
<
const
T
*>
(
ptr
));
static_cast
<
void
>
(
err
);
// Safe to discard because sync() fails otherwise.
return
result
;
}
}
template
<
class
T
>
template
<
class
T
>
config_option
::
meta_state
*
option_meta_state_instance
()
{
config_option
::
meta_state
*
option_meta_state_instance
()
{
using
trait
=
detail
::
config_value_access_t
<
T
>
;
static
config_option
::
meta_state
obj
{
sync_impl
<
T
>
,
get_impl
<
T
>
,
static
config_option
::
meta_state
obj
{
check_impl
<
T
>
,
store_impl
<
T
>
,
config_value
::
mapped_type_name
<
T
>
()};
get_impl
<
T
>
,
parse_impl_delegate
<
T
>
,
trait
::
type_name
()};
return
&
obj
;
return
&
obj
;
}
}
}
// namespace detail
}
// namespace caf::detail
namespace
caf
{
/// Creates a config option that synchronizes with `storage`.
/// Creates a config option that synchronizes with `storage`.
template
<
class
T
>
template
<
class
T
>
...
@@ -110,12 +88,12 @@ make_negated_config_option(bool& storage, string_view category,
...
@@ -110,12 +88,12 @@ make_negated_config_option(bool& storage, string_view category,
string_view
name
,
string_view
description
);
string_view
name
,
string_view
description
);
// Reads timespans, but stores an integer representing microsecond resolution.
// Reads timespans, but stores an integer representing microsecond resolution.
CAF_CORE_EXPORT
config_option
[[
deprecated
(
"use timespan options instead"
)]]
CAF_CORE_EXPORT
config_option
make_us_resolution_config_option
(
size_t
&
storage
,
string_view
category
,
make_us_resolution_config_option
(
size_t
&
storage
,
string_view
category
,
string_view
name
,
string_view
description
);
string_view
name
,
string_view
description
);
// Reads timespans, but stores an integer representing millisecond resolution.
// Reads timespans, but stores an integer representing millisecond resolution.
CAF_CORE_EXPORT
config_option
[[
deprecated
(
"use timespan options instead"
)]]
CAF_CORE_EXPORT
config_option
make_ms_resolution_config_option
(
size_t
&
storage
,
string_view
category
,
make_ms_resolution_config_option
(
size_t
&
storage
,
string_view
category
,
string_view
name
,
string_view
description
);
string_view
name
,
string_view
description
);
...
...
libcaf_core/caf/parser_state.hpp
View file @
dbdf9b26
...
@@ -58,6 +58,10 @@ struct parser_state {
...
@@ -58,6 +58,10 @@ struct parser_state {
e
=
last
;
e
=
last
;
}
}
parser_state
(
const
parser_state
&
)
noexcept
=
default
;
parser_state
&
operator
=
(
const
parser_state
&
)
noexcept
=
default
;
/// Returns the null terminator when reaching the end of the string,
/// Returns the null terminator when reaching the end of the string,
/// otherwise the next character.
/// otherwise the next character.
char
next
()
noexcept
{
char
next
()
noexcept
{
...
...
libcaf_core/caf/sec.hpp
View file @
dbdf9b26
...
@@ -170,6 +170,8 @@ enum class sec : uint8_t {
...
@@ -170,6 +170,8 @@ enum class sec : uint8_t {
/// An operation failed because the callee does not implement this
/// An operation failed because the callee does not implement this
/// functionality.
/// functionality.
unsupported_operation
,
unsupported_operation
,
/// A key lookup failed.
no_such_key
=
65
,
};
};
/// @relates sec
/// @relates sec
...
...
libcaf_core/caf/settings.hpp
View file @
dbdf9b26
...
@@ -38,8 +38,8 @@ CAF_CORE_EXPORT std::string to_string(const settings& xs);
...
@@ -38,8 +38,8 @@ CAF_CORE_EXPORT std::string to_string(const settings& xs);
/// Tries to retrieve the value associated to `name` from `xs`.
/// Tries to retrieve the value associated to `name` from `xs`.
/// @relates config_value
/// @relates config_value
CAF_CORE_EXPORT
const
config_value
*
CAF_CORE_EXPORT
const
config_value
*
get_if
(
const
settings
*
xs
,
get_if
(
const
settings
*
xs
,
string_view
name
);
string_view
name
);
/// Tries to retrieve the value associated to `name` from `xs`.
/// Tries to retrieve the value associated to `name` from `xs`.
/// @relates config_value
/// @relates config_value
...
@@ -54,12 +54,14 @@ auto get_if(const settings* xs, string_view name) {
...
@@ -54,12 +54,14 @@ auto get_if(const settings* xs, string_view name) {
/// @relates config_value
/// @relates config_value
template
<
class
T
>
template
<
class
T
>
bool
holds_alternative
(
const
settings
&
xs
,
string_view
name
)
{
bool
holds_alternative
(
const
settings
&
xs
,
string_view
name
)
{
using
access
=
detail
::
config_value_access_t
<
T
>
;
if
(
auto
value
=
get_if
(
&
xs
,
name
))
if
(
auto
value
=
get_if
(
&
xs
,
name
))
return
access
::
is
(
*
value
);
return
holds_alternative
<
T
>
(
*
value
);
return
false
;
else
return
false
;
}
}
/// Retrieves the value associated to `name` from `xs`.
/// @relates actor_system_config
template
<
class
T
>
template
<
class
T
>
T
get
(
const
settings
&
xs
,
string_view
name
)
{
T
get
(
const
settings
&
xs
,
string_view
name
)
{
auto
result
=
get_if
<
T
>
(
&
xs
,
name
);
auto
result
=
get_if
<
T
>
(
&
xs
,
name
);
...
@@ -67,27 +69,39 @@ T get(const settings& xs, string_view name) {
...
@@ -67,27 +69,39 @@ T get(const settings& xs, string_view name) {
return
detail
::
move_if_not_ptr
(
result
);
return
detail
::
move_if_not_ptr
(
result
);
}
}
template
<
class
T
,
class
=
typename
std
::
enable_if
<
/// Retrieves the value associated to `name` from `xs` or returns `fallback`.
!
std
::
is_pointer
<
T
>
::
value
/// @relates actor_system_config
&&
!
std
::
is_convertible
<
T
,
string_view
>::
value
>::
type
>
template
<
class
To
=
get_or_auto_deduce
,
class
Fallback
>
T
get_or
(
const
settings
&
xs
,
string_view
name
,
T
default_value
)
{
auto
get_or
(
const
settings
&
xs
,
string_view
name
,
Fallback
&&
fallback
)
{
auto
result
=
get_if
<
T
>
(
&
xs
,
name
);
if
(
auto
ptr
=
get_if
(
&
xs
,
name
))
{
if
(
result
)
return
get_or
<
To
>
(
*
ptr
,
std
::
forward
<
Fallback
>
(
fallback
));
return
std
::
move
(
*
result
);
}
else
if
constexpr
(
std
::
is_same
<
To
,
get_or_auto_deduce
>::
value
)
{
return
default_value
;
using
guide
=
get_or_deduction_guide
<
std
::
decay_t
<
Fallback
>>
;
return
guide
::
convert
(
std
::
forward
<
Fallback
>
(
fallback
));
}
else
{
return
To
{
std
::
forward
<
Fallback
>
(
fallback
)};
}
}
}
CAF_CORE_EXPORT
std
::
string
/// Tries to retrieve the value associated to `name` from `xs` as an instance of
get_or
(
const
settings
&
xs
,
string_view
name
,
string_view
default_value
);
/// type `T`.
/// @relates actor_system_config
template
<
class
T
>
expected
<
T
>
get_as
(
const
settings
&
xs
,
string_view
name
)
{
if
(
auto
ptr
=
get_if
(
&
xs
,
name
))
return
get_as
<
T
>
(
*
ptr
);
else
return
{
sec
::
no_such_key
};
}
/// @private
/// @private
CAF_CORE_EXPORT
config_value
&
CAF_CORE_EXPORT
config_value
&
put_impl
(
settings
&
dict
,
put_impl
(
settings
&
dict
,
const
std
::
vector
<
string_view
>&
path
,
const
std
::
vector
<
string_view
>&
path
,
config_value
&
value
);
config_value
&
value
);
/// @private
/// @private
CAF_CORE_EXPORT
config_value
&
CAF_CORE_EXPORT
config_value
&
put_impl
(
settings
&
dict
,
string_view
key
,
put_impl
(
settings
&
dict
,
string_view
key
,
config_value
&
value
);
config_value
&
value
);
/// Converts `value` to a `config_value` and assigns it to `key`.
/// Converts `value` to a `config_value` and assigns it to `key`.
/// @param dict Dictionary of key-value pairs.
/// @param dict Dictionary of key-value pairs.
...
@@ -118,7 +132,7 @@ CAF_CORE_EXPORT config_value::list& put_list(settings& xs, std::string name);
...
@@ -118,7 +132,7 @@ CAF_CORE_EXPORT config_value::list& put_list(settings& xs, std::string name);
/// Inserts a new list named `name` into the dictionary `xs` and returns
/// Inserts a new list named `name` into the dictionary `xs` and returns
/// a reference to it. Overrides existing entries with the same name.
/// a reference to it. Overrides existing entries with the same name.
CAF_CORE_EXPORT
config_value
::
dictionary
&
CAF_CORE_EXPORT
config_value
::
dictionary
&
put_dictionary
(
settings
&
xs
,
put_dictionary
(
settings
&
xs
,
std
::
string
name
);
std
::
string
name
);
}
// namespace caf
}
// namespace caf
libcaf_core/caf/telemetry/histogram.hpp
View file @
dbdf9b26
...
@@ -128,7 +128,7 @@ private:
...
@@ -128,7 +128,7 @@ private:
return
false
;
return
false
;
for
(
const
auto
&
lbl
:
labels
)
{
for
(
const
auto
&
lbl
:
labels
)
{
if
(
auto
ptr
=
get_if
<
settings
>
(
cfg
,
lbl
.
str
()))
{
if
(
auto
ptr
=
get_if
<
settings
>
(
cfg
,
lbl
.
str
()))
{
if
(
auto
bounds
=
get_
if
<
std
::
vector
<
value_type
>>
(
ptr
,
"buckets"
))
{
if
(
auto
bounds
=
get_
as
<
std
::
vector
<
value_type
>>
(
*
ptr
,
"buckets"
))
{
std
::
sort
(
bounds
->
begin
(),
bounds
->
end
());
std
::
sort
(
bounds
->
begin
(),
bounds
->
end
());
bounds
->
erase
(
std
::
unique
(
bounds
->
begin
(),
bounds
->
end
()),
bounds
->
erase
(
std
::
unique
(
bounds
->
begin
(),
bounds
->
end
()),
bounds
->
end
());
bounds
->
end
());
...
...
libcaf_core/caf/telemetry/metric_registry.hpp
View file @
dbdf9b26
...
@@ -367,7 +367,7 @@ public:
...
@@ -367,7 +367,7 @@ public:
if
(
auto
grp
=
get_if
<
settings
>
(
config_
,
prefix
))
{
if
(
auto
grp
=
get_if
<
settings
>
(
config_
,
prefix
))
{
if
(
sub_settings
=
get_if
<
settings
>
(
grp
,
name
);
if
(
sub_settings
=
get_if
<
settings
>
(
grp
,
name
);
sub_settings
!=
nullptr
)
{
sub_settings
!=
nullptr
)
{
if
(
auto
lst
=
get_
if
<
upper_bounds_list
>
(
sub_settings
,
"buckets"
))
{
if
(
auto
lst
=
get_
as
<
upper_bounds_list
>
(
*
sub_settings
,
"buckets"
))
{
std
::
sort
(
lst
->
begin
(),
lst
->
end
());
std
::
sort
(
lst
->
begin
(),
lst
->
end
());
lst
->
erase
(
std
::
unique
(
lst
->
begin
(),
lst
->
end
()),
lst
->
end
());
lst
->
erase
(
std
::
unique
(
lst
->
begin
(),
lst
->
end
()),
lst
->
end
());
if
(
!
lst
->
empty
())
if
(
!
lst
->
empty
())
...
...
libcaf_core/src/actor_system.cpp
View file @
dbdf9b26
...
@@ -295,10 +295,10 @@ actor_system::actor_system(actor_system_config& cfg)
...
@@ -295,10 +295,10 @@ actor_system::actor_system(actor_system_config& cfg)
hook
->
init
(
*
this
);
hook
->
init
(
*
this
);
// Cache some configuration parameters for faster lookups at runtime.
// Cache some configuration parameters for faster lookups at runtime.
using
string_list
=
std
::
vector
<
std
::
string
>
;
using
string_list
=
std
::
vector
<
std
::
string
>
;
if
(
auto
lst
=
get_
if
<
string_list
>
(
&
cfg
,
if
(
auto
lst
=
get_
as
<
string_list
>
(
cfg
,
"caf.metrics-filters.actors.includes"
))
"caf.metrics-filters.actors.includes"
))
metrics_actors_includes_
=
std
::
move
(
*
lst
);
metrics_actors_includes_
=
std
::
move
(
*
lst
);
if
(
auto
lst
=
get_
if
<
string_list
>
(
&
cfg
,
if
(
auto
lst
=
get_
as
<
string_list
>
(
cfg
,
"caf.metrics-filters.actors.excludes"
))
"caf.metrics-filters.actors.excludes"
))
metrics_actors_excludes_
=
std
::
move
(
*
lst
);
metrics_actors_excludes_
=
std
::
move
(
*
lst
);
if
(
!
metrics_actors_includes_
.
empty
())
if
(
!
metrics_actors_includes_
.
empty
())
...
...
libcaf_core/src/actor_system_config.cpp
View file @
dbdf9b26
...
@@ -340,11 +340,10 @@ actor_system_config& actor_system_config::set_impl(string_view name,
...
@@ -340,11 +340,10 @@ actor_system_config& actor_system_config::set_impl(string_view name,
if
(
opt
==
nullptr
)
{
if
(
opt
==
nullptr
)
{
std
::
cerr
<<
"*** failed to set config parameter "
<<
name
std
::
cerr
<<
"*** failed to set config parameter "
<<
name
<<
": invalid name"
<<
std
::
endl
;
<<
": invalid name"
<<
std
::
endl
;
}
else
if
(
auto
err
=
opt
->
check
(
value
))
{
}
else
if
(
auto
err
=
opt
->
sync
(
value
))
{
std
::
cerr
<<
"*** failed to set config parameter "
<<
name
<<
": "
std
::
cerr
<<
"*** failed to set config parameter "
<<
name
<<
": "
<<
to_string
(
err
)
<<
std
::
endl
;
<<
to_string
(
err
)
<<
std
::
endl
;
}
else
{
}
else
{
opt
->
store
(
value
);
auto
category
=
opt
->
category
();
auto
category
=
opt
->
category
();
if
(
category
==
"global"
)
if
(
category
==
"global"
)
content
[
opt
->
long_name
()]
=
std
::
move
(
value
);
content
[
opt
->
long_name
()]
=
std
::
move
(
value
);
...
@@ -413,12 +412,13 @@ error actor_system_config::extract_config_file_path(string_list& args) {
...
@@ -413,12 +412,13 @@ error actor_system_config::extract_config_file_path(string_list& args) {
args
.
erase
(
i
);
args
.
erase
(
i
);
return
make_error
(
pec
::
missing_argument
,
std
::
move
(
str
));
return
make_error
(
pec
::
missing_argument
,
std
::
move
(
str
));
}
}
auto
evalue
=
ptr
->
parse
(
path
);
config_value
val
{
path
};
if
(
!
evalue
)
if
(
auto
err
=
ptr
->
sync
(
val
);
!
err
)
{
return
std
::
move
(
evalue
.
error
());
put
(
content
,
"config-file"
,
std
::
move
(
val
));
put
(
content
,
"config-file"
,
*
evalue
);
return
none
;
ptr
->
store
(
*
evalue
);
}
else
{
return
none
;
return
err
;
}
}
}
const
settings
&
content
(
const
actor_system_config
&
cfg
)
{
const
settings
&
content
(
const
actor_system_config
&
cfg
)
{
...
...
libcaf_core/src/config_option.cpp
View file @
dbdf9b26
...
@@ -128,16 +128,13 @@ string_view config_option::full_name() const noexcept {
...
@@ -128,16 +128,13 @@ string_view config_option::full_name() const noexcept {
return
buf_slice
(
buf_
[
0
]
==
'?'
?
1
:
0
,
long_name_separator_
);
return
buf_slice
(
buf_
[
0
]
==
'?'
?
1
:
0
,
long_name_separator_
);
}
}
error
config_option
::
check
(
const
config_value
&
x
)
const
{
error
config_option
::
sync
(
config_value
&
x
)
const
{
CAF_ASSERT
(
meta_
->
check
!=
nullptr
);
return
meta_
->
sync
(
value_
,
x
);
return
meta_
->
check
(
x
);
}
}
void
config_option
::
store
(
const
config_value
&
x
)
const
{
error
config_option
::
store
(
const
config_value
&
x
)
const
{
if
(
value_
!=
nullptr
)
{
auto
cpy
=
x
;
CAF_ASSERT
(
meta_
->
store
!=
nullptr
);
return
sync
(
cpy
);
meta_
->
store
(
value_
,
x
);
}
}
}
string_view
config_option
::
type_name
()
const
noexcept
{
string_view
config_option
::
type_name
()
const
noexcept
{
...
@@ -145,7 +142,7 @@ string_view config_option::type_name() const noexcept {
...
@@ -145,7 +142,7 @@ string_view config_option::type_name() const noexcept {
}
}
bool
config_option
::
is_flag
()
const
noexcept
{
bool
config_option
::
is_flag
()
const
noexcept
{
return
type_name
()
==
"bool
ean
"
;
return
type_name
()
==
"bool"
;
}
}
bool
config_option
::
has_flat_cli_name
()
const
noexcept
{
bool
config_option
::
has_flat_cli_name
()
const
noexcept
{
...
@@ -153,7 +150,11 @@ bool config_option::has_flat_cli_name() const noexcept {
...
@@ -153,7 +150,11 @@ bool config_option::has_flat_cli_name() const noexcept {
}
}
expected
<
config_value
>
config_option
::
parse
(
string_view
input
)
const
{
expected
<
config_value
>
config_option
::
parse
(
string_view
input
)
const
{
return
meta_
->
parse
(
value_
,
input
);
config_value
val
{
input
};
if
(
auto
err
=
sync
(
val
))
return
{
std
::
move
(
err
)};
else
return
{
std
::
move
(
val
)};
}
}
optional
<
config_value
>
config_option
::
get
()
const
{
optional
<
config_value
>
config_option
::
get
()
const
{
...
...
libcaf_core/src/config_option_adder.cpp
View file @
dbdf9b26
...
@@ -18,8 +18,11 @@
...
@@ -18,8 +18,11 @@
#include "caf/config_option_adder.hpp"
#include "caf/config_option_adder.hpp"
#include "caf/config.hpp"
#include "caf/config_option_set.hpp"
#include "caf/config_option_set.hpp"
CAF_PUSH_DEPRECATED_WARNING
namespace
caf
{
namespace
caf
{
config_option_adder
::
config_option_adder
(
config_option_set
&
target
,
config_option_adder
::
config_option_adder
(
config_option_set
&
target
,
...
@@ -53,3 +56,5 @@ config_option_adder& config_option_adder::add_impl(config_option&& opt) {
...
@@ -53,3 +56,5 @@ config_option_adder& config_option_adder::add_impl(config_option&& opt) {
}
}
}
// namespace caf
}
// namespace caf
CAF_POP_WARNINGS
libcaf_core/src/config_option_set.cpp
View file @
dbdf9b26
...
@@ -137,6 +137,12 @@ auto config_option_set::parse(settings& config, argument_iterator first,
...
@@ -137,6 +137,12 @@ auto config_option_set::parse(settings& config, argument_iterator first,
// Parses an argument.
// Parses an argument.
using
iter
=
string
::
const_iterator
;
using
iter
=
string
::
const_iterator
;
auto
consume
=
[
&
](
const
config_option
&
opt
,
iter
arg_begin
,
iter
arg_end
)
{
auto
consume
=
[
&
](
const
config_option
&
opt
,
iter
arg_begin
,
iter
arg_end
)
{
auto
to_pec_code
=
[](
const
error
&
err
)
{
if
(
err
.
category
()
==
type_id_v
<
pec
>
)
return
static_cast
<
pec
>
(
err
.
code
());
else
return
pec
::
invalid_argument
;
};
// Extract option name and category.
// Extract option name and category.
auto
opt_name
=
opt
.
long_name
();
auto
opt_name
=
opt
.
long_name
();
auto
opt_ctg
=
opt
.
category
();
auto
opt_ctg
=
opt
.
category
();
...
@@ -144,27 +150,31 @@ auto config_option_set::parse(settings& config, argument_iterator first,
...
@@ -144,27 +150,31 @@ auto config_option_set::parse(settings& config, argument_iterator first,
auto
&
entry
=
opt_ctg
==
"global"
?
config
:
select_entry
(
config
,
opt_ctg
);
auto
&
entry
=
opt_ctg
==
"global"
?
config
:
select_entry
(
config
,
opt_ctg
);
// Flags only consume the current element.
// Flags only consume the current element.
if
(
opt
.
is_flag
())
{
if
(
opt
.
is_flag
())
{
if
(
arg_begin
!=
arg_end
)
if
(
arg_begin
==
arg_end
)
{
config_value
cfg_true
{
true
};
if
(
auto
err
=
opt
.
sync
(
cfg_true
);
!
err
)
{
entry
[
opt_name
]
=
cfg_true
;
return
pec
::
success
;
}
else
{
return
to_pec_code
(
err
);
}
}
else
{
return
pec
::
invalid_argument
;
return
pec
::
invalid_argument
;
config_value
cfg_true
{
true
};
}
opt
.
store
(
cfg_true
);
entry
[
opt_name
]
=
cfg_true
;
}
else
{
}
else
{
if
(
arg_begin
==
arg_end
)
if
(
arg_begin
!=
arg_end
)
{
auto
arg_size
=
static_cast
<
size_t
>
(
std
::
distance
(
arg_begin
,
arg_end
));
config_value
val
{
string_view
{
std
::
addressof
(
*
arg_begin
),
arg_size
}};
if
(
auto
err
=
opt
.
sync
(
val
);
!
err
)
{
entry
[
opt_name
]
=
std
::
move
(
val
);
return
pec
::
success
;
}
else
{
return
to_pec_code
(
err
);
}
}
else
{
return
pec
::
missing_argument
;
return
pec
::
missing_argument
;
auto
slice_size
=
static_cast
<
size_t
>
(
std
::
distance
(
arg_begin
,
arg_end
));
string_view
slice
{
&*
arg_begin
,
slice_size
};
auto
val
=
opt
.
parse
(
slice
);
if
(
!
val
)
{
auto
&
err
=
val
.
error
();
if
(
err
.
category
()
==
type_id_v
<
pec
>
)
return
static_cast
<
pec
>
(
err
.
code
());
return
pec
::
invalid_argument
;
}
}
opt
.
store
(
*
val
);
entry
[
opt_name
]
=
std
::
move
(
*
val
);
}
}
return
pec
::
success
;
};
};
// We loop over the first N-1 values, because we always consider two
// We loop over the first N-1 values, because we always consider two
// arguments at once.
// arguments at once.
...
...
libcaf_core/src/config_value.cpp
View file @
dbdf9b26
...
@@ -62,6 +62,11 @@ auto no_conversions() {
...
@@ -62,6 +62,11 @@ auto no_conversions() {
return
detail
::
make_overload
(
no_conversion
<
To
,
From
>
()...);
return
detail
::
make_overload
(
no_conversion
<
To
,
From
>
()...);
}
}
template
<
class
T
>
constexpr
ptrdiff_t
signed_index_of
()
{
return
detail
::
tl_index_of
<
typename
config_value
::
types
,
T
>::
value
;
}
}
// namespace
}
// namespace
// -- constructors, destructors, and assignment operators ----------------------
// -- constructors, destructors, and assignment operators ----------------------
...
@@ -153,6 +158,10 @@ const char* config_value::type_name_at_index(size_t index) noexcept {
...
@@ -153,6 +158,10 @@ const char* config_value::type_name_at_index(size_t index) noexcept {
return
type_names
[
index
];
return
type_names
[
index
];
}
}
ptrdiff_t
config_value
::
signed_index
()
const
noexcept
{
return
static_cast
<
ptrdiff_t
>
(
data_
.
index
());
}
// -- utility ------------------------------------------------------------------
// -- utility ------------------------------------------------------------------
type_id_t
config_value
::
type_id
()
const
noexcept
{
type_id_t
config_value
::
type_id
()
const
noexcept
{
...
@@ -321,6 +330,16 @@ expected<timespan> config_value::to_timespan() const {
...
@@ -321,6 +330,16 @@ expected<timespan> config_value::to_timespan() const {
return
visit
(
f
,
data_
);
return
visit
(
f
,
data_
);
}
}
expected
<
uri
>
config_value
::
to_uri
()
const
{
using
result_type
=
expected
<
uri
>
;
auto
f
=
detail
::
make_overload
(
no_conversions
<
uri
,
none_t
,
bool
,
integer
,
real
,
timespan
,
config_value
::
list
,
config_value
::
dictionary
>
(),
[](
const
uri
&
x
)
{
return
result_type
{
x
};
},
[](
const
std
::
string
&
x
)
{
return
make_uri
(
x
);
});
return
visit
(
f
,
data_
);
}
expected
<
config_value
::
list
>
config_value
::
to_list
()
const
{
expected
<
config_value
::
list
>
config_value
::
to_list
()
const
{
using
result_type
=
expected
<
list
>
;
using
result_type
=
expected
<
list
>
;
auto
dict_to_list
=
[](
const
dictionary
&
dict
,
list
&
result
)
{
auto
dict_to_list
=
[](
const
dictionary
&
dict
,
list
&
result
)
{
...
@@ -335,18 +354,17 @@ expected<config_value::list> config_value::to_list() const {
...
@@ -335,18 +354,17 @@ expected<config_value::list> config_value::to_list() const {
auto
f
=
detail
::
make_overload
(
auto
f
=
detail
::
make_overload
(
no_conversions
<
list
,
none_t
,
bool
,
integer
,
real
,
timespan
,
uri
>
(),
no_conversions
<
list
,
none_t
,
bool
,
integer
,
real
,
timespan
,
uri
>
(),
[
dict_to_list
](
const
std
::
string
&
x
)
{
[
dict_to_list
](
const
std
::
string
&
x
)
{
// Check whether we can parse the string as a list. If that fails, try
// Check whether we can parse the string as a list. However, we also
// whether we can parse it as a dictionary instead (and then convert that
// accept dictionaries that we convert to lists of key-value pairs. We
// to a list).
// need to try converting to dictionary *first*, because detail::parse for
config_value
::
list
tmp
;
// the list otherwise produces a list with one dictionary.
if
(
detail
::
parse
(
x
,
tmp
,
detail
::
require_opening_char
)
==
none
)
if
(
config_value
::
dictionary
dict
;
detail
::
parse
(
x
,
dict
)
==
none
)
{
return
result_type
{
std
::
move
(
tmp
)};
config_value
::
list
tmp
;
config_value
::
dictionary
dict
;
if
(
detail
::
parse
(
x
,
dict
,
detail
::
require_opening_char
)
==
none
)
{
tmp
.
clear
();
dict_to_list
(
dict
,
tmp
);
dict_to_list
(
dict
,
tmp
);
return
result_type
{
std
::
move
(
tmp
)};
return
result_type
{
std
::
move
(
tmp
)};
}
}
if
(
config_value
::
list
tmp
;
detail
::
parse
(
x
,
tmp
)
==
none
)
return
result_type
{
std
::
move
(
tmp
)};
std
::
string
msg
=
"cannot convert "
;
std
::
string
msg
=
"cannot convert "
;
detail
::
print_escaped
(
msg
,
x
);
detail
::
print_escaped
(
msg
,
x
);
msg
+=
" to a list"
;
msg
+=
" to a list"
;
...
@@ -383,12 +401,11 @@ expected<config_value::dictionary> config_value::to_dictionary() const {
...
@@ -383,12 +401,11 @@ expected<config_value::dictionary> config_value::to_dictionary() const {
return
result_type
{
std
::
move
(
err
)};
return
result_type
{
std
::
move
(
err
)};
}
}
},
},
[](
const
std
::
string
&
x
)
{
[
this
](
const
std
::
string
&
x
)
{
if
(
dictionary
tmp
;
detail
::
parse
(
x
,
tmp
)
==
none
)
{
if
(
dictionary
tmp
;
detail
::
parse
(
x
,
tmp
)
==
none
)
return
result_type
{
std
::
move
(
tmp
)};
return
result_type
{
std
::
move
(
tmp
)};
}
if
(
auto
lst
=
to_list
())
{
if
(
list
tmp
;
detail
::
parse
(
x
,
tmp
)
==
none
)
{
config_value
ls
{
std
::
move
(
*
lst
)};
config_value
ls
{
std
::
move
(
tmp
)};
if
(
auto
res
=
ls
.
to_dictionary
())
if
(
auto
res
=
ls
.
to_dictionary
())
return
res
;
return
res
;
}
}
...
@@ -453,14 +470,66 @@ config_value::parse_msg_impl(string_view str,
...
@@ -453,14 +470,66 @@ config_value::parse_msg_impl(string_view str,
// -- related free functions ---------------------------------------------------
// -- related free functions ---------------------------------------------------
bool
operator
<
(
double
x
,
const
config_value
&
y
)
{
return
config_value
{
x
}
<
y
;
}
bool
operator
<=
(
double
x
,
const
config_value
&
y
)
{
return
config_value
{
x
}
<=
y
;
}
bool
operator
==
(
double
x
,
const
config_value
&
y
)
{
return
config_value
{
x
}
==
y
;
}
bool
operator
>
(
double
x
,
const
config_value
&
y
)
{
return
config_value
{
x
}
>
y
;
}
bool
operator
>=
(
double
x
,
const
config_value
&
y
)
{
return
config_value
{
x
}
>=
y
;
}
bool
operator
<
(
const
config_value
&
x
,
double
y
)
{
return
x
<
config_value
{
y
};
}
bool
operator
<=
(
const
config_value
&
x
,
double
y
)
{
return
x
<=
config_value
{
y
};
}
bool
operator
==
(
const
config_value
&
x
,
double
y
)
{
return
x
==
config_value
{
y
};
}
bool
operator
>
(
const
config_value
&
x
,
double
y
)
{
return
x
>
config_value
{
y
};
}
bool
operator
>=
(
const
config_value
&
x
,
double
y
)
{
return
x
>=
config_value
{
y
};
}
bool
operator
<
(
const
config_value
&
x
,
const
config_value
&
y
)
{
bool
operator
<
(
const
config_value
&
x
,
const
config_value
&
y
)
{
return
x
.
get_data
()
<
y
.
get_data
();
return
x
.
get_data
()
<
y
.
get_data
();
}
}
bool
operator
<=
(
const
config_value
&
x
,
const
config_value
&
y
)
{
return
x
.
get_data
()
<=
y
.
get_data
();
}
bool
operator
==
(
const
config_value
&
x
,
const
config_value
&
y
)
{
bool
operator
==
(
const
config_value
&
x
,
const
config_value
&
y
)
{
return
x
.
get_data
()
==
y
.
get_data
();
return
x
.
get_data
()
==
y
.
get_data
();
}
}
bool
operator
>
(
const
config_value
&
x
,
const
config_value
&
y
)
{
return
x
.
get_data
()
>
y
.
get_data
();
}
bool
operator
>=
(
const
config_value
&
x
,
const
config_value
&
y
)
{
return
x
.
get_data
()
>=
y
.
get_data
();
}
namespace
{
namespace
{
void
to_string_impl
(
std
::
string
&
str
,
const
config_value
&
x
);
void
to_string_impl
(
std
::
string
&
str
,
const
config_value
&
x
);
...
...
libcaf_core/src/config_value_reader.cpp
View file @
dbdf9b26
...
@@ -428,7 +428,7 @@ bool pull(config_value_reader& reader, T& x) {
...
@@ -428,7 +428,7 @@ bool pull(config_value_reader& reader, T& x) {
auto
&
top
=
reader
.
top
();
auto
&
top
=
reader
.
top
();
if
(
holds_alternative
<
const
config_value
*>
(
top
))
{
if
(
holds_alternative
<
const
config_value
*>
(
top
))
{
auto
ptr
=
get
<
const
config_value
*>
(
top
);
auto
ptr
=
get
<
const
config_value
*>
(
top
);
if
(
auto
val
=
get_
if
<
internal_type
>
(
ptr
))
{
if
(
auto
val
=
get_
as
<
internal_type
>
(
*
ptr
))
{
assign
(
*
val
);
assign
(
*
val
);
reader
.
pop
();
reader
.
pop
();
return
true
;
return
true
;
...
@@ -446,7 +446,7 @@ bool pull(config_value_reader& reader, T& x) {
...
@@ -446,7 +446,7 @@ bool pull(config_value_reader& reader, T& x) {
return
false
;
return
false
;
}
}
auto
ptr
=
std
::
addressof
(
seq
.
current
());
auto
ptr
=
std
::
addressof
(
seq
.
current
());
if
(
auto
val
=
get_
if
<
internal_type
>
(
ptr
))
{
if
(
auto
val
=
get_
as
<
internal_type
>
(
*
ptr
))
{
assign
(
*
val
);
assign
(
*
val
);
seq
.
advance
();
seq
.
advance
();
return
true
;
return
true
;
...
...
libcaf_core/src/config_value_writer.cpp
View file @
dbdf9b26
...
@@ -268,11 +268,12 @@ bool config_value_writer::begin_associative_array(size_t) {
...
@@ -268,11 +268,12 @@ bool config_value_writer::begin_associative_array(size_t) {
CHECK_NOT_EMPTY
();
CHECK_NOT_EMPTY
();
settings
*
inner
=
nullptr
;
settings
*
inner
=
nullptr
;
auto
f
=
detail
::
make_overload
(
auto
f
=
detail
::
make_overload
(
[
this
](
config_value
*
val
)
{
[
this
,
&
inner
](
config_value
*
val
)
{
// Morph the top element into a dictionary.
// Morph the top element into a dictionary.
auto
&
dict
=
val
->
as_dictionary
();
auto
&
dict
=
val
->
as_dictionary
();
dict
.
clear
();
dict
.
clear
();
st_
.
top
()
=
&
dict
;
st_
.
top
()
=
&
dict
;
inner
=
&
dict
;
return
true
;
return
true
;
},
},
[
this
](
settings
*
)
{
[
this
](
settings
*
)
{
...
...
libcaf_core/src/detail/config_consumer.cpp
View file @
dbdf9b26
...
@@ -43,14 +43,14 @@ config_list_consumer::config_list_consumer(config_value_consumer* parent)
...
@@ -43,14 +43,14 @@ config_list_consumer::config_list_consumer(config_value_consumer* parent)
}
}
pec
config_list_consumer
::
end_list
()
{
pec
config_list_consumer
::
end_list
()
{
auto
f
=
make_overload
(
auto
f
=
make_overload
(
[](
none_t
)
{
return
pec
::
success
;
},
[
this
](
config_consumer
*
ptr
)
{
[
this
](
config_consumer
*
ptr
)
{
return
ptr
->
value
(
config_value
{
std
::
move
(
xs_
)});
return
ptr
->
value
(
config_value
{
std
::
move
(
result
)});
},
},
[
this
](
auto
*
ptr
)
{
[
this
](
auto
*
ptr
)
{
ptr
->
value
(
config_value
{
std
::
move
(
xs_
)});
ptr
->
value
(
config_value
{
std
::
move
(
result
)});
return
pec
::
success
;
return
pec
::
success
;
});
});
return
visit
(
f
,
parent_
);
return
visit
(
f
,
parent_
);
}
}
...
@@ -59,7 +59,8 @@ config_consumer config_list_consumer::begin_map() {
...
@@ -59,7 +59,8 @@ config_consumer config_list_consumer::begin_map() {
}
}
std
::
string
config_list_consumer
::
qualified_key
()
{
std
::
string
config_list_consumer
::
qualified_key
()
{
auto
f
=
make_overload
([](
config_value_consumer
*
)
{
return
std
::
string
{};
},
auto
f
=
make_overload
([](
none_t
)
{
return
std
::
string
{};
},
[](
config_value_consumer
*
)
{
return
std
::
string
{};
},
[](
auto
*
ptr
)
{
return
ptr
->
qualified_key
();
});
[](
auto
*
ptr
)
{
return
ptr
->
qualified_key
();
});
return
visit
(
f
,
parent_
);
return
visit
(
f
,
parent_
);
}
}
...
@@ -156,16 +157,11 @@ void merge_into_place(settings& src, settings& dst) {
...
@@ -156,16 +157,11 @@ void merge_into_place(settings& src, settings& dst) {
}
// namespace
}
// namespace
pec
config_consumer
::
value_impl
(
config_value
&&
x
)
{
pec
config_consumer
::
value_impl
(
config_value
&&
x
)
{
// See whether there's a config_option associated to this key and perform a
// Sync with config option object if available.
// type check if necessary.
if
(
options_
!=
nullptr
)
const
config_option
*
opt
;
if
(
auto
opt
=
options_
->
qualified_name_lookup
(
category_
,
current_key_
))
if
(
options_
==
nullptr
)
{
if
(
auto
err
=
opt
->
sync
(
x
))
opt
=
nullptr
;
return
pec
::
type_mismatch
;
}
else
{
opt
=
options_
->
qualified_name_lookup
(
category_
,
current_key_
);
if
(
opt
&&
opt
->
check
(
x
)
!=
none
)
return
pec
::
type_mismatch
;
}
// Insert / replace value in the map.
// Insert / replace value in the map.
if
(
auto
dict
=
get_if
<
settings
>
(
&
x
))
{
if
(
auto
dict
=
get_if
<
settings
>
(
&
x
))
{
// Merge values into the destination, because it can already contain any
// Merge values into the destination, because it can already contain any
...
@@ -178,13 +174,6 @@ pec config_consumer::value_impl(config_value&& x) {
...
@@ -178,13 +174,6 @@ pec config_consumer::value_impl(config_value&& x) {
}
else
{
}
else
{
cfg_
->
insert_or_assign
(
current_key_
,
std
::
move
(
x
));
cfg_
->
insert_or_assign
(
current_key_
,
std
::
move
(
x
));
}
}
// Sync with config option if needed.
if
(
opt
)
{
if
(
auto
i
=
cfg_
->
find
(
current_key_
);
i
!=
cfg_
->
end
())
opt
->
store
(
i
->
second
);
else
return
pec
::
invalid_state
;
}
return
pec
::
success
;
return
pec
::
success
;
}
}
...
...
libcaf_core/src/detail/parse.cpp
View file @
dbdf9b26
...
@@ -165,17 +165,62 @@ void parse(string_parser_state& ps, uri& x) {
...
@@ -165,17 +165,62 @@ void parse(string_parser_state& ps, uri& x) {
void
parse
(
string_parser_state
&
ps
,
config_value
&
x
)
{
void
parse
(
string_parser_state
&
ps
,
config_value
&
x
)
{
ps
.
skip_whitespaces
();
ps
.
skip_whitespaces
();
if
(
ps
.
at_end
())
{
if
(
!
ps
.
at_end
())
{
detail
::
config_value_consumer
f
;
parser
::
read_config_value
(
ps
,
f
);
if
(
ps
.
code
<=
pec
::
trailing_character
)
x
=
std
::
move
(
f
.
result
);
}
else
{
ps
.
code
=
pec
::
unexpected_eof
;
}
}
void
parse
(
string_parser_state
&
ps
,
std
::
vector
<
config_value
>&
x
)
{
ps
.
skip_whitespaces
();
if
(
!
ps
.
at_end
())
{
detail
::
config_list_consumer
f
;
auto
fallback
=
ps
;
if
(
ps
.
consume
(
'['
))
{
parser
::
read_config_list
(
ps
,
f
);
if
(
ps
.
code
==
pec
::
success
)
{
x
=
std
::
move
(
f
.
result
);
}
else
{
// Rewind parser state and try parsing again as a list without
// surrounding '[]' characters. This catches edge cases like
// '[1, 2], [3, 4]'. On error, we restore the parser state after the
// first error.
auto
first_failure
=
ps
;
ps
=
fallback
;
f
.
result
.
clear
();
parser
::
lift_config_list
(
ps
,
f
);
if
(
ps
.
code
<=
pec
::
trailing_character
)
x
=
std
::
move
(
f
.
result
);
else
ps
=
first_failure
;
}
}
else
{
// If the string isn't surrounded by '[]' in the first place, we call
// lift_config_list and keep it's result in any case.
parser
::
lift_config_list
(
ps
,
f
);
if
(
ps
.
code
==
pec
::
success
)
x
=
std
::
move
(
f
.
result
);
}
}
else
{
ps
.
code
=
pec
::
unexpected_eof
;
}
}
void
parse
(
string_parser_state
&
ps
,
dictionary
<
config_value
>&
x
)
{
ps
.
skip_whitespaces
();
if
(
!
ps
.
at_end
())
{
detail
::
config_consumer
f
{
x
};
if
(
ps
.
consume
(
'{'
))
parser
::
read_config_map
(
ps
,
f
);
else
parser
::
read_config_map
<
false
>
(
ps
,
f
);
}
else
{
ps
.
code
=
pec
::
unexpected_eof
;
ps
.
code
=
pec
::
unexpected_eof
;
return
;
}
}
// Safe the string as fallback.
string_view
str
{
ps
.
i
,
ps
.
e
};
// Dispatch to parser.
detail
::
config_value_consumer
f
;
parser
::
read_config_value
(
ps
,
f
);
if
(
ps
.
code
<=
pec
::
trailing_character
)
x
=
std
::
move
(
f
.
result
);
}
}
PARSE_IMPL
(
ipv4_address
,
ipv4_address
)
PARSE_IMPL
(
ipv4_address
,
ipv4_address
)
...
...
libcaf_core/src/logger.cpp
View file @
dbdf9b26
...
@@ -310,7 +310,7 @@ void logger::init(actor_system_config& cfg) {
...
@@ -310,7 +310,7 @@ void logger::init(actor_system_config& cfg) {
return
CAF_LOG_LEVEL_QUIET
;
return
CAF_LOG_LEVEL_QUIET
;
};
};
auto
read_filter
=
[
&
cfg
](
string_list
&
var
,
string_view
key
)
{
auto
read_filter
=
[
&
cfg
](
string_list
&
var
,
string_view
key
)
{
if
(
auto
lst
=
get_
if
<
string_list
>
(
&
cfg
,
key
))
if
(
auto
lst
=
get_
as
<
string_list
>
(
cfg
,
key
))
var
=
std
::
move
(
*
lst
);
var
=
std
::
move
(
*
lst
);
};
};
cfg_
.
file_verbosity
=
get_verbosity
(
"caf.logger.file.verbosity"
);
cfg_
.
file_verbosity
=
get_verbosity
(
"caf.logger.file.verbosity"
);
...
...
libcaf_core/src/make_config_option.cpp
View file @
dbdf9b26
...
@@ -23,73 +23,42 @@
...
@@ -23,73 +23,42 @@
#include "caf/config_value.hpp"
#include "caf/config_value.hpp"
#include "caf/optional.hpp"
#include "caf/optional.hpp"
#define DEFAULT_META(type, parse_fun) \
config_option::meta_state type##_meta_state{ \
default_config_option_check<type>, default_config_option_store<type>, \
get_impl<type>, parse_fun, \
detail::config_value_access_t<type>::type_name()};
using
std
::
string
;
namespace
caf
{
namespace
caf
{
namespace
detail
{
expected
<
config_value
>
parse_impl
(
std
::
string
*
ptr
,
string_view
str
)
{
// Parse quoted strings, otherwise consume the entire string.
auto
e
=
str
.
end
();
auto
i
=
std
::
find_if
(
str
.
begin
(),
e
,
[](
char
c
)
{
return
!
isspace
(
c
);
});
if
(
i
==
e
)
{
if
(
ptr
!=
nullptr
)
ptr
->
assign
(
i
,
e
);
return
config_value
{
std
::
string
{
i
,
e
}};
}
if
(
*
i
==
'"'
)
{
if
(
ptr
==
nullptr
)
{
std
::
string
tmp
;
if
(
auto
err
=
parse
(
str
,
tmp
))
return
err
;
return
config_value
{
std
::
move
(
tmp
)};
}
else
{
if
(
auto
err
=
parse
(
str
,
*
ptr
))
return
err
;
return
config_value
{
*
ptr
};
}
}
if
(
ptr
!=
nullptr
)
ptr
->
assign
(
str
.
begin
(),
str
.
end
());
return
config_value
{
std
::
string
{
str
.
begin
(),
str
.
end
()}};
}
}
// namespace detail
namespace
{
namespace
{
using
meta_state
=
config_option
::
meta_state
;
using
meta_state
=
config_option
::
meta_state
;
void
bool_store_neg
(
void
*
ptr
,
const
config_value
&
x
)
{
error
bool_sync_neg
(
void
*
ptr
,
config_value
&
x
)
{
*
static_cast
<
bool
*>
(
ptr
)
=
!
get
<
bool
>
(
x
);
if
(
auto
val
=
get_as
<
bool
>
(
x
))
{
x
=
config_value
{
*
val
};
if
(
ptr
)
*
static_cast
<
bool
*>
(
ptr
)
=
!*
val
;
return
none
;
}
else
{
return
std
::
move
(
val
.
error
());
}
}
}
config_value
bool_get_neg
(
const
void
*
ptr
)
{
config_value
bool_get_neg
(
const
void
*
ptr
)
{
return
config_value
{
!*
static_cast
<
const
bool
*>
(
ptr
)};
return
config_value
{
!*
static_cast
<
const
bool
*>
(
ptr
)};
}
}
meta_state
bool_neg_meta
{
detail
::
check_impl
<
bool
>
,
bool_store_neg
,
bool_get_neg
,
meta_state
bool_neg_meta
{
bool_sync_neg
,
bool_get_neg
,
"bool"
};
nullptr
,
detail
::
config_value_access_t
<
bool
>::
type_name
()};
error
check_timespan
(
const
config_value
&
x
)
{
template
<
uint64_t
Denominator
>
if
(
holds_alternative
<
timespan
>
(
x
))
error
sync_timespan
(
void
*
ptr
,
config_value
&
x
)
{
if
(
auto
val
=
get_as
<
timespan
>
(
x
))
{
x
=
config_value
{
*
val
};
if
(
ptr
)
*
static_cast
<
size_t
*>
(
ptr
)
=
static_cast
<
size_t
>
(
get
<
timespan
>
(
x
).
count
())
/
Denominator
;
return
none
;
return
none
;
return
make_error
(
pec
::
type_mismatch
);
}
else
{
return
std
::
move
(
val
.
error
());
}
}
}
template
<
uint64_t
Denominator
>
void
store_timespan
(
void
*
ptr
,
const
config_value
&
x
)
{
*
static_cast
<
size_t
*>
(
ptr
)
=
static_cast
<
size_t
>
(
get
<
timespan
>
(
x
).
count
())
/
Denominator
;
}
template
<
uint64_t
Denominator
>
template
<
uint64_t
Denominator
>
config_value
get_timespan
(
const
void
*
ptr
)
{
config_value
get_timespan
(
const
void
*
ptr
)
{
auto
ival
=
static_cast
<
int64_t
>
(
*
static_cast
<
const
size_t
*>
(
ptr
));
auto
ival
=
static_cast
<
int64_t
>
(
*
static_cast
<
const
size_t
*>
(
ptr
));
...
@@ -97,13 +66,10 @@ config_value get_timespan(const void* ptr) {
...
@@ -97,13 +66,10 @@ config_value get_timespan(const void* ptr) {
return
config_value
{
val
};
return
config_value
{
val
};
}
}
meta_state
us_res_meta
{
check_timespan
,
store_timespan
<
1000
>
,
get_timespan
<
1000
>
,
meta_state
us_res_meta
{
sync_timespan
<
1000
>
,
get_timespan
<
1000
>
,
"timespan"
};
nullptr
,
detail
::
config_value_access_t
<
timespan
>::
type_name
()};
meta_state
ms_res_meta
{
check_timespan
,
store_timespan
<
1000000
>
,
meta_state
ms_res_meta
{
sync_timespan
<
1000000
>
,
get_timespan
<
1000000
>
,
get_timespan
<
1000000
>
,
nullptr
,
"timespan"
};
detail
::
config_value_access_t
<
timespan
>::
type_name
()};
}
// namespace
}
// namespace
...
...
libcaf_core/src/scheduler/abstract_coordinator.cpp
View file @
dbdf9b26
...
@@ -249,10 +249,8 @@ void abstract_coordinator::init(actor_system_config& cfg) {
...
@@ -249,10 +249,8 @@ void abstract_coordinator::init(actor_system_config& cfg) {
namespace
sr
=
defaults
::
scheduler
;
namespace
sr
=
defaults
::
scheduler
;
max_throughput_
=
get_or
(
cfg
,
"caf.scheduler.max-throughput"
,
max_throughput_
=
get_or
(
cfg
,
"caf.scheduler.max-throughput"
,
sr
::
max_throughput
);
sr
::
max_throughput
);
if
(
auto
num_workers
=
get_if
<
size_t
>
(
&
cfg
,
"caf.scheduler.max-threads"
))
num_workers_
=
get_or
(
cfg
,
"caf.scheduler.max-threads"
,
num_workers_
=
*
num_workers
;
default_thread_count
());
else
num_workers_
=
default_thread_count
();
}
}
actor_system
::
module
::
id_t
abstract_coordinator
::
id
()
const
{
actor_system
::
module
::
id_t
abstract_coordinator
::
id
()
const
{
...
...
libcaf_core/src/sec_strings.cpp
View file @
dbdf9b26
...
@@ -146,6 +146,8 @@ std::string to_string(sec x) {
...
@@ -146,6 +146,8 @@ std::string to_string(sec x) {
return
"type_clash"
;
return
"type_clash"
;
case
sec
:
:
unsupported_operation
:
case
sec
:
:
unsupported_operation
:
return
"unsupported_operation"
;
return
"unsupported_operation"
;
case
sec
:
:
no_such_key
:
return
"no_such_key"
;
};
};
}
}
...
@@ -345,6 +347,9 @@ bool from_string(string_view in, sec& out) {
...
@@ -345,6 +347,9 @@ bool from_string(string_view in, sec& out) {
}
else
if
(
in
==
"unsupported_operation"
)
{
}
else
if
(
in
==
"unsupported_operation"
)
{
out
=
sec
::
unsupported_operation
;
out
=
sec
::
unsupported_operation
;
return
true
;
return
true
;
}
else
if
(
in
==
"no_such_key"
)
{
out
=
sec
::
no_such_key
;
return
true
;
}
else
{
}
else
{
return
false
;
return
false
;
}
}
...
@@ -421,6 +426,7 @@ bool from_integer(std::underlying_type_t<sec> in,
...
@@ -421,6 +426,7 @@ bool from_integer(std::underlying_type_t<sec> in,
case
sec
:
:
connection_closed
:
case
sec
:
:
connection_closed
:
case
sec
:
:
type_clash
:
case
sec
:
:
type_clash
:
case
sec
:
:
unsupported_operation
:
case
sec
:
:
unsupported_operation
:
case
sec
:
:
no_such_key
:
out
=
result
;
out
=
result
;
return
true
;
return
true
;
};
};
...
...
libcaf_core/src/settings.cpp
View file @
dbdf9b26
...
@@ -43,12 +43,12 @@ const config_value* get_if(const settings* xs, string_view name) {
...
@@ -43,12 +43,12 @@ const config_value* get_if(const settings* xs, string_view name) {
name
.
substr
(
pos
+
1
));
name
.
substr
(
pos
+
1
));
}
}
std
::
string
get_or
(
const
settings
&
xs
,
string_view
name
,
expected
<
std
::
string
>
get_or
(
const
settings
&
xs
,
string_view
name
,
string_view
default_value
)
{
const
char
*
fallback
)
{
auto
result
=
get_if
<
std
::
string
>
(
&
xs
,
name
);
if
(
auto
ptr
=
get_if
(
&
xs
,
name
))
if
(
result
)
return
get_as
<
std
::
string
>
(
*
ptr
);
return
std
::
move
(
*
result
);
else
return
std
::
string
{
default_value
.
begin
(),
default_value
.
end
()
};
return
{
std
::
string
{
fallback
}
};
}
}
config_value
&
put_impl
(
settings
&
dict
,
const
std
::
vector
<
string_view
>&
path
,
config_value
&
put_impl
(
settings
&
dict
,
const
std
::
vector
<
string_view
>&
path
,
...
...
libcaf_core/test/actor_system_config.cpp
View file @
dbdf9b26
...
@@ -33,6 +33,7 @@
...
@@ -33,6 +33,7 @@
#include <vector>
#include <vector>
using
namespace
caf
;
using
namespace
caf
;
using
namespace
caf
::
literals
;
using
namespace
std
::
string_literals
;
using
namespace
std
::
string_literals
;
...
@@ -161,12 +162,19 @@ CAF_TEST(file input overrides defaults but CLI args always win) {
...
@@ -161,12 +162,19 @@ CAF_TEST(file input overrides defaults but CLI args always win) {
#define CHECK_SYNCED(var, value) \
#define CHECK_SYNCED(var, value) \
do { \
do { \
CAF_CHECK_EQUAL(var, value); \
CAF_CHECK_EQUAL(var, value); \
CAF_CHECK_EQUAL(get<decltype(var)>(cfg, #var), value); \
if (auto maybe_val = get_as<decltype(var)>(cfg, #var)) { \
CAF_CHECK_EQUAL(*maybe_val, value); \
} else { \
auto cv = get_if(std::addressof(cfg.content), #var); \
CAF_ERROR("expected type " \
<< config_value::mapped_type_name<decltype(var)>() \
<< ", got: " << cv->type_name()); \
} \
} while (false)
} while (false)
// Checks whether an entry in content(cfg) is equal to `value`.
// Checks whether an entry in content(cfg) is equal to `value`.
#define CHECK_TEXT_ONLY(type, var, value) \
#define CHECK_TEXT_ONLY(type, var, value) \
CAF_CHECK_EQUAL(get<type>(cfg, #var), value)
CAF_CHECK_EQUAL(get
_as
<type>(cfg, #var), value)
#define ADD(var) add(var, #var, "...")
#define ADD(var) add(var, #var, "...")
...
...
libcaf_core/test/config_option.cpp
View file @
dbdf9b26
...
@@ -22,6 +22,8 @@
...
@@ -22,6 +22,8 @@
#include "core-test.hpp"
#include "core-test.hpp"
#include <sstream>
#include "caf/make_config_option.hpp"
#include "caf/make_config_option.hpp"
#include "caf/config_value.hpp"
#include "caf/config_value.hpp"
#include "caf/expected.hpp"
#include "caf/expected.hpp"
...
@@ -32,6 +34,155 @@ using std::string;
...
@@ -32,6 +34,155 @@ using std::string;
namespace
{
namespace
{
struct
state
;
struct
baseline
{
std
::
vector
<
std
::
string
>
cli
;
std
::
string
conf
;
settings
res
;
std
::
function
<
bool
(
const
state
&
)
>
predicate
;
};
struct
request_pair
{
my_request
first
;
my_request
second
;
};
template
<
class
Inspector
>
bool
inspect
(
Inspector
&
f
,
request_pair
&
x
)
{
return
f
.
object
(
x
).
fields
(
f
.
field
(
"first"
,
x
.
first
),
f
.
field
(
"second"
,
x
.
second
));
}
struct
state
{
s1
my_app_s1
;
std
::
vector
<
int32_t
>
my_app_vector
;
level
my_app_severity
=
level
::
trace
;
my_request
my_app_request
;
request_pair
my_app_request_pair
;
config_option_set
options
;
state
()
{
config_option_adder
{
options
,
"?my.app"
}
.
add
(
my_app_s1
,
"s1"
,
""
)
.
add
(
my_app_vector
,
"vector,v"
,
""
)
.
add
(
my_app_severity
,
"severity,s"
,
""
)
.
add
(
my_app_request
,
"request,r"
,
""
)
.
add
(
my_app_request_pair
,
"request-pair,R"
,
""
);
config_option_adder
{
options
,
"sys"
}
.
add
<
std
::
string
>
(
"query,q"
,
""
)
.
add
<
int8_t
>
(
"threads,tTd"
,
""
);
}
void
run
(
baseline
&
x
,
size_t
index
)
{
settings
res
;
std
::
istringstream
src
{
x
.
conf
};
if
(
auto
parsed
=
actor_system_config
::
parse_config
(
src
,
options
))
{
res
=
std
::
move
(
*
parsed
);
}
else
{
CAF_ERROR
(
"failed to parse baseline at index "
<<
index
<<
": "
<<
parsed
.
error
());
return
;
}
auto
[
code
,
pos
]
=
options
.
parse
(
res
,
x
.
cli
);
if
(
pos
!=
x
.
cli
.
end
())
{
CAF_ERROR
(
"failed to parse all arguments for baseline at index "
<<
index
<<
", stopped at: "
<<
*
pos
<<
" ("
<<
code
<<
')'
);
return
;
}
if
(
code
!=
pec
::
success
)
{
CAF_ERROR
(
"CLI arguments for baseline at index "
<<
index
<<
" failed to parse: "
<<
code
);
return
;
}
if
(
!
x
.
predicate
(
*
this
))
{
CAF_ERROR
(
"predicate for baseline at index "
<<
index
<<
"failed! "
);
return
;
}
MESSAGE
(
"all checks for baseline at index "
<<
index
<<
" passed"
);
}
};
struct
fixture
{
std
::
vector
<
baseline
>
baselines
;
template
<
class
Predicate
>
void
add_test
(
std
::
vector
<
std
::
string
>
cli
,
std
::
string
conf
,
settings
res
,
Predicate
f
)
{
baselines
.
emplace_back
(
baseline
{
std
::
move
(
cli
),
std
::
move
(
conf
),
std
::
move
(
res
),
f
,
});
}
template
<
class
Predicate
>
void
add_test
(
std
::
vector
<
std
::
string
>
cli
,
std
::
string
conf
,
std
::
string
res
,
Predicate
f
)
{
config_value
cv_res
{
res
};
if
(
auto
parsed
=
get_as
<
settings
>
(
cv_res
))
add_test
(
std
::
move
(
cli
),
std
::
move
(
conf
),
std
::
move
(
*
parsed
),
std
::
move
(
f
));
else
CAF_FAIL
(
"failed to parse result settings: "
<<
parsed
.
error
()
<<
"
\n
INPUT:
\n
"
<<
res
<<
'\n'
);
}
template
<
class
Res
>
void
add_test
(
std
::
vector
<
std
::
string
>
cli
,
std
::
string
conf
,
Res
&&
res
)
{
return
add_test
(
std
::
move
(
cli
),
std
::
move
(
conf
),
std
::
forward
<
Res
>
(
res
),
[](
const
state
&
)
{
return
true
;
});
}
fixture
()
{
using
ivec
=
std
::
vector
<
int32_t
>
;
add_test
({
"-s"
,
"error"
},
""
,
R"_(my { app { severity = "error" } })_"
,
[](
auto
&
st
)
{
return
CHECK_EQ
(
st
.
my_app_severity
,
level
::
error
);
});
add_test
({
"-v"
,
"1, 2, 3"
},
""
,
R"_(my { app { vector = [1, 2, 3] } })_"
,
[](
auto
&
st
)
{
return
CHECK_EQ
(
st
.
my_app_vector
,
ivec
({
1
,
2
,
3
}));
});
add_test
({
"-v"
,
"[1, 2, 3]"
},
""
,
R"_(my { app { vector = [1, 2, 3] } })_"
);
add_test
({
"-v[1, 2, 3]"
},
""
,
R"_(my { app { vector = [1, 2, 3] } })_"
);
add_test
({
"-v1, 2, 3,"
},
""
,
R"_(my { app { vector = [1, 2, 3] } })_"
);
add_test
({
"-r"
,
R"_({"a":1,"b":2})_"
},
""
,
R"_(my { app { request { a = 1, b = 2 } } })_"
);
add_test
({
"-r"
,
R"_(a=1,b=2)_"
},
""
,
R"_(my { app { request { a = 1, b = 2 } } })_"
);
add_test
({
R"_(--my.app.request={a=1,b=2})_"
},
""
,
R"_(my { app { request { a = 1, b = 2 } } })_"
);
add_test
({
R"_(--my.app.request=a=1,b=2,)_"
},
""
,
R"_(my { app { request { a = 1, b = 2 } } })_"
);
add_test
({
"-R"
,
R"_({"first": {"a": 1, "b": 2}, "second": {"a": 3, "b": 4}})_"
},
""
,
R"_(my { app { request-pair { first { a = 1, b = 2 },
second { a = 3, b = 4 } } } })_"
);
add_test
({},
"sys{threads=2}"
,
R"_(sys { threads = 2 })_"
);
add_test
({
"-t"
,
"1"
},
"sys{threads=2}"
,
R"_(sys { threads = 1 })_"
);
add_test
({
"-T"
,
"1"
},
"sys{threads=2}"
,
R"_(sys { threads = 1 })_"
);
add_test
({
"-d"
,
"1"
},
"sys{threads=2}"
,
R"_(sys { threads = 1 })_"
);
add_test
({
"--sys.threads=1"
},
"sys{threads=2}"
,
R"_(sys { threads = 1 })_"
);
add_test
({
"--sys.query=foo"
},
""
,
R"_(sys { query = "foo" })_"
);
add_test
({
"-q"
,
"
\"
a
\"
in b"
},
""
,
R"_(sys { query = "\"a\" in b" })_"
);
}
};
}
// namespace
BEGIN_FIXTURE_SCOPE
(
fixture
)
SCENARIO
(
"options on the CLI override config files that override defaults"
)
{
for
(
size_t
index
=
0
;
index
<
baselines
.
size
();
++
index
)
{
state
st
;
st
.
run
(
baselines
[
index
],
index
);
}
}
constexpr
string_view
category
=
"category"
;
constexpr
string_view
category
=
"category"
;
constexpr
string_view
name
=
"name"
;
constexpr
string_view
name
=
"name"
;
constexpr
string_view
explanation
=
"explanation"
;
constexpr
string_view
explanation
=
"explanation"
;
...
@@ -48,14 +199,13 @@ constexpr int64_t underflow() {
...
@@ -48,14 +199,13 @@ constexpr int64_t underflow() {
template
<
class
T
>
template
<
class
T
>
optional
<
T
>
read
(
string_view
arg
)
{
optional
<
T
>
read
(
string_view
arg
)
{
auto
co
=
make_config_option
<
T
>
(
category
,
name
,
explanation
);
auto
result
=
T
{};
auto
res
=
co
.
parse
(
arg
);
auto
co
=
make_config_option
<
T
>
(
result
,
category
,
name
,
explanation
);
if
(
res
&&
holds_alternative
<
T
>
(
*
res
))
{
config_value
val
{
arg
};
if
(
co
.
check
(
*
res
)
!=
none
)
if
(
auto
err
=
co
.
sync
(
val
);
!
err
)
CAF_ERROR
(
"co.parse() produced the wrong type!"
);
return
{
std
::
move
(
result
)};
return
get
<
T
>
(
*
res
);
else
}
return
none
;
return
none
;
}
}
// Unsigned integers.
// Unsigned integers.
...
@@ -98,8 +248,6 @@ void compare(const config_option& lhs, const config_option& rhs) {
...
@@ -98,8 +248,6 @@ void compare(const config_option& lhs, const config_option& rhs) {
CAF_CHECK_EQUAL
(
lhs
.
full_name
(),
rhs
.
full_name
());
CAF_CHECK_EQUAL
(
lhs
.
full_name
(),
rhs
.
full_name
());
}
}
}
// namespace
CAF_TEST
(
copy
constructor
)
{
CAF_TEST
(
copy
constructor
)
{
auto
one
=
make_config_option
<
int
>
(
"cat1"
,
"one"
,
"option 1"
);
auto
one
=
make_config_option
<
int
>
(
"cat1"
,
"one"
,
"option 1"
);
auto
two
=
one
;
auto
two
=
one
;
...
@@ -166,12 +314,12 @@ CAF_TEST(type double) {
...
@@ -166,12 +314,12 @@ CAF_TEST(type double) {
CAF_CHECK_EQUAL
(
unbox
(
read
<
double
>
(
"-1.0"
)),
-
1.0
);
CAF_CHECK_EQUAL
(
unbox
(
read
<
double
>
(
"-1.0"
)),
-
1.0
);
CAF_CHECK_EQUAL
(
unbox
(
read
<
double
>
(
"-0.1"
)),
-
0.1
);
CAF_CHECK_EQUAL
(
unbox
(
read
<
double
>
(
"-0.1"
)),
-
0.1
);
CAF_CHECK_EQUAL
(
read
<
double
>
(
"0"
),
0.
);
CAF_CHECK_EQUAL
(
read
<
double
>
(
"0"
),
0.
);
CAF_CHECK_EQUAL
(
read
<
double
>
(
"
\"
0.1
\"
"
),
none
);
CAF_CHECK_EQUAL
(
read
<
double
>
(
"
\"
0.1
\"
"
),
none
);
}
}
CAF_TEST
(
type
string
)
{
CAF_TEST
(
type
string
)
{
CAF_CHECK_EQUAL
(
unbox
(
read
<
string
>
(
"foo"
)),
"foo"
);
CAF_CHECK_EQUAL
(
unbox
(
read
<
string
>
(
"foo"
)),
"foo"
);
CAF_CHECK_EQUAL
(
unbox
(
read
<
string
>
(
"
\"
foo
\"
"
)),
"foo
"
);
CAF_CHECK_EQUAL
(
unbox
(
read
<
string
>
(
R"_("foo")_"
)),
R"_("foo")_
"
);
}
}
CAF_TEST
(
type
timespan
)
{
CAF_TEST
(
type
timespan
)
{
...
@@ -231,3 +379,5 @@ CAF_TEST(find by long opt) {
...
@@ -231,3 +379,5 @@ CAF_TEST(find by long opt) {
// No options to look through.
// No options to look through.
check
({},
false
,
false
);
check
({},
false
,
false
);
}
}
END_FIXTURE_SCOPE
()
libcaf_core/test/config_option_set.cpp
View file @
dbdf9b26
...
@@ -53,10 +53,11 @@ struct fixture {
...
@@ -53,10 +53,11 @@ struct fixture {
settings
cfg
;
settings
cfg
;
auto
res
=
opts
.
parse
(
cfg
,
std
::
move
(
args
));
auto
res
=
opts
.
parse
(
cfg
,
std
::
move
(
args
));
if
(
res
.
first
!=
pec
::
success
)
if
(
res
.
first
!=
pec
::
success
)
return
res
.
first
;
return
{
res
.
first
};
if
(
auto
x
=
get_if
<
T
>
(
&
cfg
,
key
))
else
if
(
auto
x
=
get_as
<
T
>
(
cfg
,
key
))
return
detail
::
move_if_not_ptr
(
x
);
return
{
std
::
move
(
*
x
)};
return
sec
::
invalid_argument
;
else
return
{
sec
::
invalid_argument
};
}
}
std
::
string
key
=
"value"
;
std
::
string
key
=
"value"
;
...
@@ -101,7 +102,7 @@ CAF_TEST(parse with ref syncing) {
...
@@ -101,7 +102,7 @@ CAF_TEST(parse with ref syncing) {
settings
cfg
;
settings
cfg
;
vector
<
string
>
args
{
"-i42"
,
vector
<
string
>
args
{
"-i42"
,
"-f"
,
"-f"
,
"1e
1
2"
,
"1e2"
,
"-shello"
,
"-shello"
,
"--bar.l=[
\"
hello
\"
,
\"
world
\"
]"
,
"--bar.l=[
\"
hello
\"
,
\"
world
\"
]"
,
"-d"
,
"-d"
,
...
@@ -114,34 +115,20 @@ CAF_TEST(parse with ref syncing) {
...
@@ -114,34 +115,20 @@ CAF_TEST(parse with ref syncing) {
CAF_FAIL
(
"parser stopped at: "
<<
*
res
.
second
);
CAF_FAIL
(
"parser stopped at: "
<<
*
res
.
second
);
CAF_MESSAGE
(
"verify referenced values"
);
CAF_MESSAGE
(
"verify referenced values"
);
CAF_CHECK_EQUAL
(
foo_i
,
42
);
CAF_CHECK_EQUAL
(
foo_i
,
42
);
CAF_CHECK_EQUAL
(
foo_f
,
1e
1
2
);
CAF_CHECK_EQUAL
(
foo_f
,
1e2
);
CAF_CHECK_EQUAL
(
foo_b
,
true
);
CAF_CHECK_EQUAL
(
foo_b
,
true
);
CAF_CHECK_EQUAL
(
bar_s
,
"hello"
);
CAF_CHECK_EQUAL
(
bar_s
,
"hello"
);
CAF_CHECK_EQUAL
(
bar_l
,
ls
({
"hello"
,
"world"
}));
CAF_CHECK_EQUAL
(
bar_l
,
ls
({
"hello"
,
"world"
}));
CAF_CHECK_EQUAL
(
bar_d
,
ds
({{
"a"
,
"a"
},
{
"b"
,
"b"
}}));
CAF_CHECK_EQUAL
(
bar_d
,
ds
({{
"a"
,
"a"
},
{
"b"
,
"b"
}}));
CAF_MESSAGE
(
"verify dictionary content"
);
CAF_MESSAGE
(
"verify dictionary content"
);
CAF_CHECK_EQUAL
(
get
<
int
>
(
cfg
,
"foo.i"
),
42
);
CAF_CHECK_EQUAL
(
get
_as
<
int
>
(
cfg
,
"foo.i"
),
42
);
}
}
CAF_TEST
(
string
parameters
)
{
CAF_TEST
(
string
parameters
)
{
opts
.
add
<
std
::
string
>
(
"value,v"
,
"some value"
);
opts
.
add
<
std
::
string
>
(
"value,v"
,
"some value"
);
CAF_MESSAGE
(
"test string option with and without quotes"
);
CAF_CHECK_EQUAL
(
read
<
std
::
string
>
({
"--value=
\"
foo
\\
tbar
\"
"
}),
"foo
\t
bar"
);
CAF_CHECK_EQUAL
(
read
<
std
::
string
>
({
"--value=foobar"
}),
"foobar"
);
CAF_CHECK_EQUAL
(
read
<
std
::
string
>
({
"--value=foobar"
}),
"foobar"
);
CAF_CHECK_EQUAL
(
read
<
std
::
string
>
({
"-v"
,
"
\"
foobar
\"
"
}),
"foobar"
);
CAF_CHECK_EQUAL
(
read
<
std
::
string
>
({
"-v"
,
"foobar"
}),
"foobar"
);
CAF_CHECK_EQUAL
(
read
<
std
::
string
>
({
"-v"
,
"foobar"
}),
"foobar"
);
CAF_CHECK_EQUAL
(
read
<
std
::
string
>
({
"-v
\"
foobar
\"
"
}),
"foobar"
);
CAF_CHECK_EQUAL
(
read
<
std
::
string
>
({
"-vfoobar"
}),
"foobar"
);
CAF_CHECK_EQUAL
(
read
<
std
::
string
>
({
"-vfoobar"
}),
"foobar"
);
CAF_CHECK_EQUAL
(
read
<
std
::
string
>
({
"--value=
\"
'abc'
\"
"
}),
"'abc'"
);
CAF_CHECK_EQUAL
(
read
<
std
::
string
>
({
"--value='abc'"
}),
"'abc'"
);
CAF_CHECK_EQUAL
(
read
<
std
::
string
>
({
"-v"
,
"
\"
'abc'
\"
"
}),
"'abc'"
);
CAF_CHECK_EQUAL
(
read
<
std
::
string
>
({
"-v"
,
"'abc'"
}),
"'abc'"
);
CAF_CHECK_EQUAL
(
read
<
std
::
string
>
({
"-v'abc'"
}),
"'abc'"
);
CAF_CHECK_EQUAL
(
read
<
std
::
string
>
({
"--value=
\"
123
\"
"
}),
"123"
);
CAF_CHECK_EQUAL
(
read
<
std
::
string
>
({
"--value=123"
}),
"123"
);
CAF_CHECK_EQUAL
(
read
<
std
::
string
>
({
"-v"
,
"
\"
123
\"
"
}),
"123"
);
CAF_CHECK_EQUAL
(
read
<
std
::
string
>
({
"-v"
,
"123"
}),
"123"
);
CAF_CHECK_EQUAL
(
read
<
std
::
string
>
({
"-v123"
}),
"123"
);
}
}
CAF_TEST
(
flat
CLI
options
)
{
CAF_TEST
(
flat
CLI
options
)
{
...
@@ -202,18 +189,19 @@ CAF_TEST(CLI arguments override defaults) {
...
@@ -202,18 +189,19 @@ CAF_TEST(CLI arguments override defaults) {
CAF_MESSAGE
(
"test integer lists"
);
CAF_MESSAGE
(
"test integer lists"
);
ints
=
int_list
{
1
,
2
,
3
};
ints
=
int_list
{
1
,
2
,
3
};
cfg
[
"bar"
]
=
config_value
{
ints
};
cfg
[
"bar"
]
=
config_value
{
ints
};
CAF_CHECK_EQUAL
(
get
<
int_list
>
(
cfg
,
"bar"
),
int_list
({
1
,
2
,
3
}));
CAF_CHECK_EQUAL
(
get
_as
<
int_list
>
(
cfg
,
"bar"
),
int_list
({
1
,
2
,
3
}));
CAF_CHECK_EQUAL
(
read
<
int_list
>
(
cfg
,
{
"--bar=[10, 20, 30]"
}),
none
);
CAF_CHECK_EQUAL
(
read
<
int_list
>
(
cfg
,
{
"--bar=[10, 20, 30]"
}),
none
);
CAF_CHECK_EQUAL
(
ints
,
int_list
({
10
,
20
,
30
}));
CAF_CHECK_EQUAL
(
ints
,
int_list
({
10
,
20
,
30
}));
CAF_CHECK_EQUAL
(
get
<
int_list
>
(
cfg
,
"bar"
),
int_list
({
10
,
20
,
30
}));
CAF_CHECK_EQUAL
(
get
_as
<
int_list
>
(
cfg
,
"bar"
),
int_list
({
10
,
20
,
30
}));
CAF_MESSAGE
(
"test string lists"
);
CAF_MESSAGE
(
"test string lists"
);
strings
=
string_list
{
"one"
,
"two"
,
"three"
};
strings
=
string_list
{
"one"
,
"two"
,
"three"
};
cfg
[
"foo"
]
=
config_value
{
strings
};
cfg
[
"foo"
]
=
config_value
{
strings
};
CAF_CHECK_EQUAL
(
get
<
string_list
>
(
cfg
,
"foo"
),
CAF_CHECK_EQUAL
(
get
_as
<
string_list
>
(
cfg
,
"foo"
),
string_list
({
"one"
,
"two"
,
"three"
}));
string_list
({
"one"
,
"two"
,
"three"
}));
CAF_CHECK_EQUAL
(
read
<
string_list
>
(
cfg
,
{
"--foo=[hello, world]"
}),
none
);
CAF_CHECK_EQUAL
(
read
<
string_list
>
(
cfg
,
{
R"_(--foo=["hello", "world"])_"
}),
none
);
CAF_CHECK_EQUAL
(
strings
,
string_list
({
"hello"
,
"world"
}));
CAF_CHECK_EQUAL
(
strings
,
string_list
({
"hello"
,
"world"
}));
CAF_CHECK_EQUAL
(
get
<
string_list
>
(
cfg
,
"foo"
),
CAF_CHECK_EQUAL
(
get
_as
<
string_list
>
(
cfg
,
"foo"
),
string_list
({
"hello"
,
"world"
}));
string_list
({
"hello"
,
"world"
}));
}
}
SUBTEST
(
"without ref syncing"
)
{
SUBTEST
(
"without ref syncing"
)
{
...
@@ -223,15 +211,16 @@ CAF_TEST(CLI arguments override defaults) {
...
@@ -223,15 +211,16 @@ CAF_TEST(CLI arguments override defaults) {
opts
.
add
<
int_list
>
(
"global"
,
"bar,b"
,
"some list"
);
opts
.
add
<
int_list
>
(
"global"
,
"bar,b"
,
"some list"
);
CAF_MESSAGE
(
"test integer lists"
);
CAF_MESSAGE
(
"test integer lists"
);
cfg
[
"bar"
]
=
config_value
{
int_list
{
1
,
2
,
3
}};
cfg
[
"bar"
]
=
config_value
{
int_list
{
1
,
2
,
3
}};
CAF_CHECK_EQUAL
(
get
<
int_list
>
(
cfg
,
"bar"
),
int_list
({
1
,
2
,
3
}));
CAF_CHECK_EQUAL
(
get
_as
<
int_list
>
(
cfg
,
"bar"
),
int_list
({
1
,
2
,
3
}));
CAF_CHECK_EQUAL
(
read
<
int_list
>
(
cfg
,
{
"--bar=[10, 20, 30]"
}),
none
);
CAF_CHECK_EQUAL
(
read
<
int_list
>
(
cfg
,
{
"--bar=[10, 20, 30]"
}),
none
);
CAF_CHECK_EQUAL
(
get
<
int_list
>
(
cfg
,
"bar"
),
int_list
({
10
,
20
,
30
}));
CAF_CHECK_EQUAL
(
get
_as
<
int_list
>
(
cfg
,
"bar"
),
int_list
({
10
,
20
,
30
}));
CAF_MESSAGE
(
"test string lists"
);
CAF_MESSAGE
(
"test string lists"
);
cfg
[
"foo"
]
=
config_value
{
string_list
{
"one"
,
"two"
,
"three"
}};
cfg
[
"foo"
]
=
config_value
{
string_list
{
"one"
,
"two"
,
"three"
}};
CAF_CHECK_EQUAL
(
get
<
string_list
>
(
cfg
,
"foo"
),
CAF_CHECK_EQUAL
(
get
_as
<
string_list
>
(
cfg
,
"foo"
),
string_list
({
"one"
,
"two"
,
"three"
}));
string_list
({
"one"
,
"two"
,
"three"
}));
CAF_CHECK_EQUAL
(
read
<
string_list
>
(
cfg
,
{
"--foo=[hello, world]"
}),
none
);
CAF_CHECK_EQUAL
(
read
<
string_list
>
(
cfg
,
{
R"_(--foo=["hello", "world"])_"
}),
CAF_CHECK_EQUAL
(
get
<
string_list
>
(
cfg
,
"foo"
),
none
);
CAF_CHECK_EQUAL
(
get_as
<
string_list
>
(
cfg
,
"foo"
),
string_list
({
"hello"
,
"world"
}));
string_list
({
"hello"
,
"world"
}));
}
}
}
}
...
@@ -240,8 +229,7 @@ CAF_TEST(CLI arguments may use custom types) {
...
@@ -240,8 +229,7 @@ CAF_TEST(CLI arguments may use custom types) {
settings
cfg
;
settings
cfg
;
opts
.
add
<
foobar
>
(
"global"
,
"foobar,f"
,
"test option"
);
opts
.
add
<
foobar
>
(
"global"
,
"foobar,f"
,
"test option"
);
CAF_CHECK_EQUAL
(
read
<
foobar
>
(
cfg
,
{
"-f{foo=
\"
hello
\"
,bar=
\"
world
\"
}"
}),
none
);
CAF_CHECK_EQUAL
(
read
<
foobar
>
(
cfg
,
{
"-f{foo=
\"
hello
\"
,bar=
\"
world
\"
}"
}),
none
);
auto
fb
=
get_if
<
foobar
>
(
&
cfg
,
"foobar"
);
if
(
auto
fb
=
get_as
<
foobar
>
(
cfg
,
"foobar"
);
CAF_CHECK
(
fb
))
if
(
CAF_CHECK
(
fb
))
CAF_CHECK_EQUAL
(
*
fb
,
foobar
(
"hello"
,
"world"
));
CAF_CHECK_EQUAL
(
*
fb
,
foobar
(
"hello"
,
"world"
));
}
}
...
...
libcaf_core/test/config_value.cpp
View file @
dbdf9b26
This diff is collapsed.
Click to expand it.
libcaf_core/test/config_value_writer.cpp
View file @
dbdf9b26
...
@@ -42,6 +42,7 @@ using i64_list = std::vector<i64>;
...
@@ -42,6 +42,7 @@ using i64_list = std::vector<i64>;
struct
fixture
{
struct
fixture
{
config_value
x
;
config_value
x
;
settings
dummy
;
template
<
class
T
>
template
<
class
T
>
void
set
(
const
T
&
value
)
{
void
set
(
const
T
&
value
)
{
...
@@ -50,19 +51,11 @@ struct fixture {
...
@@ -50,19 +51,11 @@ struct fixture {
CAF_FAIL
(
"failed two write to settings: "
<<
writer
.
get_error
());
CAF_FAIL
(
"failed two write to settings: "
<<
writer
.
get_error
());
}
}
template
<
class
T
>
const
settings
&
xs
()
const
{
optional
<
T
>
get
(
const
settings
&
cfg
,
string_view
key
)
{
if
(
auto
*
ptr
=
get_if
<
settings
>
(
&
x
))
if
(
auto
ptr
=
get_if
<
T
>
(
&
cfg
,
key
))
return
*
ptr
;
return
*
ptr
;
return
none
;
}
template
<
class
T
>
optional
<
T
>
get
(
string_view
key
)
{
if
(
auto
*
xs
=
get_if
<
settings
>
(
&
x
))
return
get
<
T
>
(
*
xs
,
key
);
else
else
CAF_FAIL
(
"fixture does not contain a dictionary"
)
;
return
dummy
;
}
}
};
};
...
@@ -72,18 +65,18 @@ CAF_TEST_FIXTURE_SCOPE(config_value_writer_tests, fixture)
...
@@ -72,18 +65,18 @@ CAF_TEST_FIXTURE_SCOPE(config_value_writer_tests, fixture)
CAF_TEST
(
structs
become
dictionaries
)
{
CAF_TEST
(
structs
become
dictionaries
)
{
set
(
foobar
{
"hello"
,
"world"
});
set
(
foobar
{
"hello"
,
"world"
});
CAF_CHECK_EQUAL
(
get
<
std
::
string
>
(
"foo"
),
"hello"
s
);
CAF_CHECK_EQUAL
(
get
_as
<
std
::
string
>
(
xs
(),
"foo"
),
"hello"
s
);
CAF_CHECK_EQUAL
(
get
<
std
::
string
>
(
"bar"
),
"world"
s
);
CAF_CHECK_EQUAL
(
get
_as
<
std
::
string
>
(
xs
(),
"bar"
),
"world"
s
);
}
}
CAF_TEST
(
nested
structs
become
nested
dictionaries
)
{
CAF_TEST
(
nested
structs
become
nested
dictionaries
)
{
set
(
line
{{
10
,
20
,
30
},
{
70
,
60
,
50
}});
set
(
line
{{
10
,
20
,
30
},
{
70
,
60
,
50
}});
CAF_CHECK_EQUAL
(
get
<
i64
>
(
"p1.x"
),
10
_i64
);
CAF_CHECK_EQUAL
(
get
_as
<
i64
>
(
xs
(),
"p1.x"
),
10
_i64
);
CAF_CHECK_EQUAL
(
get
<
i64
>
(
"p1.y"
),
20
_i64
);
CAF_CHECK_EQUAL
(
get
_as
<
i64
>
(
xs
(),
"p1.y"
),
20
_i64
);
CAF_CHECK_EQUAL
(
get
<
i64
>
(
"p1.z"
),
30
_i64
);
CAF_CHECK_EQUAL
(
get
_as
<
i64
>
(
xs
(),
"p1.z"
),
30
_i64
);
CAF_CHECK_EQUAL
(
get
<
i64
>
(
"p2.x"
),
70
_i64
);
CAF_CHECK_EQUAL
(
get
_as
<
i64
>
(
xs
(),
"p2.x"
),
70
_i64
);
CAF_CHECK_EQUAL
(
get
<
i64
>
(
"p2.y"
),
60
_i64
);
CAF_CHECK_EQUAL
(
get
_as
<
i64
>
(
xs
(),
"p2.y"
),
60
_i64
);
CAF_CHECK_EQUAL
(
get
<
i64
>
(
"p2.z"
),
50
_i64
);
CAF_CHECK_EQUAL
(
get
_as
<
i64
>
(
xs
(),
"p2.z"
),
50
_i64
);
}
}
CAF_TEST
(
empty
types
and
maps
become
dictionaries
)
{
CAF_TEST
(
empty
types
and
maps
become
dictionaries
)
{
...
@@ -100,36 +93,36 @@ CAF_TEST(empty types and maps become dictionaries) {
...
@@ -100,36 +93,36 @@ 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_CHECK_EQUAL
(
get
<
settings
>
(
"v1"
),
settings
{});
CAF_CHECK_EQUAL
(
get
_as
<
settings
>
(
xs
(),
"v1"
),
settings
{});
CAF_CHECK_EQUAL
(
get
<
i64
>
(
"v2"
),
42
_i64
);
CAF_CHECK_EQUAL
(
get
_as
<
i64
>
(
xs
(),
"v2"
),
42
_i64
);
CAF_CHECK_EQUAL
(
get
<
i64_list
>
(
"v3"
),
i64_list
({
-
1
,
-
2
,
-
3
,
-
4
}));
CAF_CHECK_EQUAL
(
get
_as
<
i64_list
>
(
xs
(),
"v3"
),
i64_list
({
-
1
,
-
2
,
-
3
,
-
4
}));
if
(
auto
v4
=
get
<
config_value
::
list
>
(
"v4"
);
if
(
auto
v4
=
get
_as
<
config_value
::
list
>
(
xs
(),
"v4"
);
CAF_CHECK
_EQUAL
(
v4
->
size
(),
2u
))
{
CAF_CHECK
(
v4
&&
v4
->
size
()
==
2u
))
{
if
(
auto
v1
=
v4
->
front
();
CAF_CHECK
(
holds_alternative
<
settings
>
(
v1
)))
{
if
(
auto
v1
=
v4
->
front
();
CAF_CHECK
(
holds_alternative
<
settings
>
(
v1
)))
{
auto
&
v1_xs
=
caf
::
get
<
settings
>
(
v1
);
auto
&
v1_xs
=
get
<
settings
>
(
v1
);
CAF_CHECK_EQUAL
(
get
<
double
>
(
v1_xs
,
"content"
),
0.0
);
CAF_CHECK_EQUAL
(
get
<
double
>
(
v1_xs
,
"content"
),
0.0
);
CAF_CHECK_EQUAL
(
get
<
std
::
string
>
(
v1_xs
,
"@content-type"
),
CAF_CHECK_EQUAL
(
get
<
std
::
string
>
(
v1_xs
,
"@content-type"
),
to_string
(
type_name_v
<
double
>
));
to_string
(
type_name_v
<
double
>
));
}
}
if
(
auto
v2
=
v4
->
back
();
CAF_CHECK
(
holds_alternative
<
settings
>
(
v2
)))
{
if
(
auto
v2
=
v4
->
back
();
CAF_CHECK
(
holds_alternative
<
settings
>
(
v2
)))
{
auto
&
v2_xs
=
caf
::
get
<
settings
>
(
v2
);
auto
&
v2_xs
=
get
<
settings
>
(
v2
);
CAF_CHECK_EQUAL
(
get
<
double
>
(
v2_xs
,
"content"
),
1.0
);
CAF_CHECK_EQUAL
(
get
<
double
>
(
v2_xs
,
"content"
),
1.0
);
CAF_CHECK_EQUAL
(
get
<
std
::
string
>
(
v2_xs
,
"@content-type"
),
CAF_CHECK_EQUAL
(
get
<
std
::
string
>
(
v2_xs
,
"@content-type"
),
to_string
(
type_name_v
<
double
>
));
to_string
(
type_name_v
<
double
>
));
}
}
}
}
CAF_CHECK_EQUAL
(
get
<
i64_list
>
(
"v5"
),
i64_list
({
10
,
20
}));
CAF_CHECK_EQUAL
(
get
_as
<
i64_list
>
(
xs
(),
"v5"
),
i64_list
({
10
,
20
}));
// TODO: check v6
// TODO: check v6
CAF_CHECK_EQUAL
(
get
<
i64
>
(
"v7.one"
),
1
_i64
);
CAF_CHECK_EQUAL
(
get
_as
<
i64
>
(
xs
(),
"v7.one"
),
1
_i64
);
CAF_CHECK_EQUAL
(
get
<
i64
>
(
"v7.two"
),
2
_i64
);
CAF_CHECK_EQUAL
(
get
_as
<
i64
>
(
xs
(),
"v7.two"
),
2
_i64
);
CAF_CHECK_EQUAL
(
get
<
i64
>
(
"v7.three"
),
3
_i64
);
CAF_CHECK_EQUAL
(
get
_as
<
i64
>
(
xs
(),
"v7.three"
),
3
_i64
);
CAF_CHECK_EQUAL
(
get
<
config_value
::
list
>
(
"v8"
),
config_value
::
list
());
CAF_CHECK_EQUAL
(
get
_as
<
config_value
::
list
>
(
xs
(),
"v8"
),
config_value
::
list
());
}
}
CAF_TEST
(
custom
inspect
overloads
may
produce
single
values
)
{
CAF_TEST
(
custom
inspect
overloads
may
produce
single
values
)
{
auto
tue
=
weekday
::
tuesday
;
auto
tue
=
weekday
::
tuesday
;
set
(
tue
);
set
(
tue
);
CAF_CHECK_EQUAL
(
x
,
"tuesday"
s
);
CAF_CHECK_EQUAL
(
get_as
<
std
::
string
>
(
x
)
,
"tuesday"
s
);
}
}
CAF_TEST_FIXTURE_SCOPE_END
()
CAF_TEST_FIXTURE_SCOPE_END
()
libcaf_core/test/core-test.cpp
View file @
dbdf9b26
...
@@ -4,6 +4,51 @@
...
@@ -4,6 +4,51 @@
#include "core-test.hpp"
#include "core-test.hpp"
std
::
string
to_string
(
level
lvl
)
{
switch
(
lvl
)
{
case
level
:
:
all
:
return
"all"
;
case
level
:
:
trace
:
return
"trace"
;
case
level
:
:
debug
:
return
"debug"
;
case
level
:
:
warning
:
return
"warning"
;
case
level
:
:
error
:
return
"error"
;
default:
return
"???"
;
}
}
bool
from_string
(
caf
::
string_view
str
,
level
&
lvl
)
{
auto
set
=
[
&
](
level
value
)
{
lvl
=
value
;
return
true
;
};
if
(
str
==
"all"
)
return
set
(
level
::
all
);
else
if
(
str
==
"trace"
)
return
set
(
level
::
trace
);
else
if
(
str
==
"debug"
)
return
set
(
level
::
debug
);
else
if
(
str
==
"warning"
)
return
set
(
level
::
warning
);
else
if
(
str
==
"error"
)
return
set
(
level
::
error
);
else
return
false
;
}
bool
from_integer
(
uint8_t
val
,
level
&
lvl
)
{
if
(
val
<
5
)
{
lvl
=
static_cast
<
level
>
(
val
);
return
true
;
}
else
{
return
false
;
}
}
int
main
(
int
argc
,
char
**
argv
)
{
int
main
(
int
argc
,
char
**
argv
)
{
using
namespace
caf
;
using
namespace
caf
;
init_global_meta_objects
<
id_block
::
core_test
>
();
init_global_meta_objects
<
id_block
::
core_test
>
();
...
...
libcaf_core/test/core-test.hpp
View file @
dbdf9b26
...
@@ -150,7 +150,7 @@ struct s1 {
...
@@ -150,7 +150,7 @@ struct s1 {
template
<
class
Inspector
>
template
<
class
Inspector
>
bool
inspect
(
Inspector
&
f
,
s1
&
x
)
{
bool
inspect
(
Inspector
&
f
,
s1
&
x
)
{
return
f
.
object
(
x
).
fields
(
f
.
field
(
"value"
,
x
.
value
)
);
return
f
.
apply
(
x
.
value
);
}
}
struct
s2
{
struct
s2
{
...
@@ -159,7 +159,7 @@ struct s2 {
...
@@ -159,7 +159,7 @@ struct s2 {
template
<
class
Inspector
>
template
<
class
Inspector
>
bool
inspect
(
Inspector
&
f
,
s2
&
x
)
{
bool
inspect
(
Inspector
&
f
,
s2
&
x
)
{
return
f
.
object
(
x
).
fields
(
f
.
field
(
"value"
,
x
.
value
)
);
return
f
.
apply
(
x
.
value
);
}
}
struct
s3
{
struct
s3
{
...
@@ -171,7 +171,7 @@ struct s3 {
...
@@ -171,7 +171,7 @@ struct s3 {
template
<
class
Inspector
>
template
<
class
Inspector
>
bool
inspect
(
Inspector
&
f
,
s3
&
x
)
{
bool
inspect
(
Inspector
&
f
,
s3
&
x
)
{
return
f
.
object
(
x
).
fields
(
f
.
field
(
"value"
,
x
.
value
)
);
return
f
.
apply
(
x
.
value
);
}
}
struct
test_array
{
struct
test_array
{
...
@@ -267,21 +267,17 @@ bool inspect(Inspector& f, dummy_enum_class& x) {
...
@@ -267,21 +267,17 @@ bool inspect(Inspector& f, dummy_enum_class& x) {
return
f
.
apply
(
get
,
set
);
return
f
.
apply
(
get
,
set
);
}
}
enum
class
level
{
all
,
trace
,
debug
,
warning
,
error
};
enum
class
level
:
uint8_t
{
all
,
trace
,
debug
,
warning
,
error
};
std
::
string
to_string
(
level
);
bool
from_string
(
caf
::
string_view
,
level
&
);
bool
from_integer
(
uint8_t
,
level
&
);
template
<
class
Inspector
>
template
<
class
Inspector
>
bool
inspect
(
Inspector
&
f
,
level
&
x
)
{
bool
inspect
(
Inspector
&
f
,
level
&
x
)
{
using
integer_type
=
std
::
underlying_type_t
<
level
>
;
return
caf
::
default_enum_inspect
(
f
,
x
);
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
};
...
...
libcaf_core/test/detail/config_consumer.cpp
View file @
dbdf9b26
...
@@ -82,12 +82,11 @@ CAF_TEST(config_consumer) {
...
@@ -82,12 +82,11 @@ CAF_TEST(config_consumer) {
detail
::
parser
::
read_config
(
res
,
consumer
);
detail
::
parser
::
read_config
(
res
,
consumer
);
CAF_CHECK_EQUAL
(
res
.
code
,
pec
::
success
);
CAF_CHECK_EQUAL
(
res
.
code
,
pec
::
success
);
CAF_CHECK_EQUAL
(
string_view
(
res
.
i
,
res
.
e
),
string_view
());
CAF_CHECK_EQUAL
(
string_view
(
res
.
i
,
res
.
e
),
string_view
());
CAF_CHECK_EQUAL
(
get
<
bool
>
(
config
,
"is_server"
),
true
);
CAF_CHECK_EQUAL
(
get_as
<
bool
>
(
config
,
"is_server"
),
true
);
CAF_CHECK_EQUAL
(
get
<
uint16_t
>
(
config
,
"port"
),
4242u
);
CAF_CHECK_EQUAL
(
get_as
<
uint16_t
>
(
config
,
"port"
),
4242u
);
CAF_CHECK_EQUAL
(
get
<
ls
>
(
config
,
"nodes"
),
ls
({
"sun"
,
"venus"
}));
CAF_CHECK_EQUAL
(
get_as
<
ls
>
(
config
,
"nodes"
),
ls
({
"sun"
,
"venus"
}));
CAF_CHECK_EQUAL
(
get
<
string
>
(
config
,
"logger.file-name"
),
"foobar.conf"
);
CAF_CHECK_EQUAL
(
get_as
<
string
>
(
config
,
"logger.file-name"
),
"foobar.conf"
);
CAF_MESSAGE
(
config
);
CAF_CHECK_EQUAL
(
get_as
<
timespan
>
(
config
,
"scheduler.timing"
),
timespan
(
2000
));
CAF_CHECK_EQUAL
(
get
<
timespan
>
(
config
,
"scheduler.timing"
),
timespan
(
2000
));
}
}
CAF_TEST
(
simplified
syntax
)
{
CAF_TEST
(
simplified
syntax
)
{
...
...
libcaf_core/test/detail/parse.cpp
View file @
dbdf9b26
...
@@ -171,41 +171,14 @@ CAF_TEST(strings) {
...
@@ -171,41 +171,14 @@ CAF_TEST(strings) {
CAF_CHECK_EQUAL
(
read
<
std
::
string
>
(
"
\"
foo
\t\"
"
),
" foo
\t
"
);
CAF_CHECK_EQUAL
(
read
<
std
::
string
>
(
"
\"
foo
\t\"
"
),
" foo
\t
"
);
}
}
CAF_TEST
(
lists
)
{
using
int_list
=
std
::
vector
<
int
>
;
using
string_list
=
std
::
vector
<
std
::
string
>
;
CAF_CHECK_EQUAL
(
read
<
int_list
>
(
"1"
),
int_list
({
1
}));
CAF_CHECK_EQUAL
(
read
<
int_list
>
(
"1, 2, 3"
),
int_list
({
1
,
2
,
3
}));
CAF_CHECK_EQUAL
(
read
<
int_list
>
(
"[1, 2, 3]"
),
int_list
({
1
,
2
,
3
}));
CAF_CHECK_EQUAL
(
read
<
string_list
>
(
"a, b ,
\"
c
\"
"
),
string_list
({
"a"
,
"b"
,
" c "
}));
}
CAF_TEST
(
maps
)
{
using
int_map
=
std
::
map
<
std
::
string
,
int
>
;
CAF_CHECK_EQUAL
(
read
<
int_map
>
(
R"(a=1, "b" = 42)"
),
int_map
({{
"a"
,
1
},
{
"b"
,
42
}}));
CAF_CHECK_EQUAL
(
read
<
int_map
>
(
R"({ a = 1 , b = 42 ,} )"
),
int_map
({{
"a"
,
1
},
{
"b"
,
42
}}));
}
CAF_TEST
(
uris
)
{
CAF_TEST
(
uris
)
{
using
uri_list
=
std
::
vector
<
uri
>
;
if
(
auto
x_res
=
read
<
uri
>
(
"foo:bar"
))
{
auto
x_res
=
read
<
uri
>
(
"foo:bar"
);
auto
x
=
*
x_res
;
if
(
x_res
==
none
)
{
CAF_CHECK_EQUAL
(
x
.
scheme
(),
"foo"
);
CAF_CHECK_EQUAL
(
x
.
path
(),
"bar"
);
}
else
{
CAF_ERROR
(
"my:path not recognized as URI"
);
CAF_ERROR
(
"my:path not recognized as URI"
);
return
;
}
}
auto
x
=
*
x_res
;
CAF_CHECK_EQUAL
(
x
.
scheme
(),
"foo"
);
CAF_CHECK_EQUAL
(
x
.
path
(),
"bar"
);
auto
ls
=
unbox
(
read
<
uri_list
>
(
"foo:bar, <http://actor-framework.org/doc>"
));
CAF_REQUIRE_EQUAL
(
ls
.
size
(),
2u
);
CAF_CHECK_EQUAL
(
ls
[
0
].
scheme
(),
"foo"
);
CAF_CHECK_EQUAL
(
ls
[
0
].
path
(),
"bar"
);
CAF_CHECK_EQUAL
(
ls
[
1
].
scheme
(),
"http"
);
CAF_CHECK_EQUAL
(
ls
[
1
].
authority
().
host
,
std
::
string
{
"actor-framework.org"
});
CAF_CHECK_EQUAL
(
ls
[
1
].
path
(),
"doc"
);
}
}
CAF_TEST
(
IPv4
address
)
{
CAF_TEST
(
IPv4
address
)
{
...
...
libcaf_core/test/detail/parser/read_bool.cpp
View file @
dbdf9b26
...
@@ -48,7 +48,8 @@ struct bool_parser {
...
@@ -48,7 +48,8 @@ struct bool_parser {
detail
::
parser
::
read_bool
(
res
,
f
);
detail
::
parser
::
read_bool
(
res
,
f
);
if
(
res
.
code
==
pec
::
success
)
if
(
res
.
code
==
pec
::
success
)
return
f
.
x
;
return
f
.
x
;
return
res
.
code
;
else
return
res
.
code
;
}
}
};
};
...
@@ -61,23 +62,23 @@ struct fixture {
...
@@ -61,23 +62,23 @@ struct fixture {
CAF_TEST_FIXTURE_SCOPE
(
read_bool_tests
,
fixture
)
CAF_TEST_FIXTURE_SCOPE
(
read_bool_tests
,
fixture
)
CAF_TEST
(
valid
booleans
)
{
CAF_TEST
(
valid
booleans
)
{
CAF_CHECK_EQUAL
(
p
(
"true"
),
true
);
CAF_CHECK_EQUAL
(
p
(
"true"
),
res_t
{
true
}
);
CAF_CHECK_EQUAL
(
p
(
"false"
),
false
);
CAF_CHECK_EQUAL
(
p
(
"false"
),
res_t
{
false
}
);
}
}
CAF_TEST
(
invalid
booleans
)
{
CAF_TEST
(
invalid
booleans
)
{
CAF_CHECK_EQUAL
(
p
(
""
),
pec
::
unexpected_eof
);
CAF_CHECK_EQUAL
(
p
(
""
),
res_t
{
pec
::
unexpected_eof
}
);
CAF_CHECK_EQUAL
(
p
(
"t"
),
pec
::
unexpected_eof
);
CAF_CHECK_EQUAL
(
p
(
"t"
),
res_t
{
pec
::
unexpected_eof
}
);
CAF_CHECK_EQUAL
(
p
(
"tr"
),
pec
::
unexpected_eof
);
CAF_CHECK_EQUAL
(
p
(
"tr"
),
res_t
{
pec
::
unexpected_eof
}
);
CAF_CHECK_EQUAL
(
p
(
"tru"
),
pec
::
unexpected_eof
);
CAF_CHECK_EQUAL
(
p
(
"tru"
),
res_t
{
pec
::
unexpected_eof
}
);
CAF_CHECK_EQUAL
(
p
(
" true"
),
pec
::
unexpected_character
);
CAF_CHECK_EQUAL
(
p
(
" true"
),
res_t
{
pec
::
unexpected_character
}
);
CAF_CHECK_EQUAL
(
p
(
"f"
),
pec
::
unexpected_eof
);
CAF_CHECK_EQUAL
(
p
(
"f"
),
res_t
{
pec
::
unexpected_eof
}
);
CAF_CHECK_EQUAL
(
p
(
"fa"
),
pec
::
unexpected_eof
);
CAF_CHECK_EQUAL
(
p
(
"fa"
),
res_t
{
pec
::
unexpected_eof
}
);
CAF_CHECK_EQUAL
(
p
(
"fal"
),
pec
::
unexpected_eof
);
CAF_CHECK_EQUAL
(
p
(
"fal"
),
res_t
{
pec
::
unexpected_eof
}
);
CAF_CHECK_EQUAL
(
p
(
"fals"
),
pec
::
unexpected_eof
);
CAF_CHECK_EQUAL
(
p
(
"fals"
),
res_t
{
pec
::
unexpected_eof
}
);
CAF_CHECK_EQUAL
(
p
(
" false"
),
pec
::
unexpected_character
);
CAF_CHECK_EQUAL
(
p
(
" false"
),
res_t
{
pec
::
unexpected_character
}
);
CAF_CHECK_EQUAL
(
p
(
"tr
\n
ue"
),
pec
::
unexpected_newline
);
CAF_CHECK_EQUAL
(
p
(
"tr
\n
ue"
),
res_t
{
pec
::
unexpected_newline
}
);
CAF_CHECK_EQUAL
(
p
(
"trues"
),
pec
::
trailing_character
);
CAF_CHECK_EQUAL
(
p
(
"trues"
),
res_t
{
pec
::
trailing_character
}
);
}
}
CAF_TEST_FIXTURE_SCOPE_END
()
CAF_TEST_FIXTURE_SCOPE_END
()
libcaf_core/test/load_inspector.cpp
View file @
dbdf9b26
...
@@ -409,9 +409,10 @@ end object)_");
...
@@ -409,9 +409,10 @@ end object)_");
CAF_TEST
(
load
inspectors
support
variant
fields
with
fallbacks
)
{
CAF_TEST
(
load
inspectors
support
variant
fields
with
fallbacks
)
{
fallback_dummy_message
d
;
fallback_dummy_message
d
;
using
content_type
=
decltype
(
d
.
content
);
d
.
content
=
std
::
string
{
"hello world"
};
d
.
content
=
std
::
string
{
"hello world"
};
CAF_CHECK
(
inspect
(
f
,
d
));
CAF_CHECK
(
inspect
(
f
,
d
));
CAF_CHECK_EQUAL
(
d
.
content
,
42.0
);
CAF_CHECK_EQUAL
(
d
.
content
,
content_type
{
42.0
}
);
CAF_CHECK_EQUAL
(
f
.
log
,
R"_(
CAF_CHECK_EQUAL
(
f
.
log
,
R"_(
begin object fallback_dummy_message
begin object fallback_dummy_message
begin optional variant field content
begin optional variant field content
...
...
libcaf_core/test/message.cpp
View file @
dbdf9b26
...
@@ -120,12 +120,12 @@ CAF_TEST(to_string converts messages to strings) {
...
@@ -120,12 +120,12 @@ CAF_TEST(to_string converts messages to strings) {
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([1, 2, 3], 4, 5)"
);
"message([1, 2, 3], 4, 5)"
);
CAF_CHECK_EQUAL
(
msg_as_string
(
s1
{}),
"message(
s1([10, 20, 30])
)"
);
CAF_CHECK_EQUAL
(
msg_as_string
(
s1
{}),
"message(
[10, 20, 30]
)"
);
s2
tmp
;
s2
tmp
;
tmp
.
value
[
0
][
1
]
=
100
;
tmp
.
value
[
0
][
1
]
=
100
;
CAF_CHECK_EQUAL
(
msg_as_string
(
s2
{}),
CAF_CHECK_EQUAL
(
msg_as_string
(
s2
{}),
"message(
s2([[1, 10], [2, 20], [3, 30], [4, 40]])
)"
);
"message(
[[1, 10], [2, 20], [3, 30], [4, 40]]
)"
);
CAF_CHECK_EQUAL
(
msg_as_string
(
s3
{}),
"message(
s3([1, 2, 3, 4])
)"
);
CAF_CHECK_EQUAL
(
msg_as_string
(
s3
{}),
"message(
[1, 2, 3, 4]
)"
);
}
}
CAF_TEST
(
match_elements
exposes
element
types
)
{
CAF_TEST
(
match_elements
exposes
element
types
)
{
...
...
libcaf_core/test/message_lifetime.cpp
View file @
dbdf9b26
...
@@ -120,7 +120,8 @@ CAF_TEST(message_lifetime_in_scoped_actor) {
...
@@ -120,7 +120,8 @@ CAF_TEST(message_lifetime_in_scoped_actor) {
self
->
send
(
self
,
msg
);
self
->
send
(
self
,
msg
);
CAF_CHECK_EQUAL
(
msg
.
cdata
().
get_reference_count
(),
2u
);
CAF_CHECK_EQUAL
(
msg
.
cdata
().
get_reference_count
(),
2u
);
self
->
receive
([
&
](
int
&
value
)
{
self
->
receive
([
&
](
int
&
value
)
{
CAF_CHECK_NOT_EQUAL
(
&
value
,
msg
.
cdata
().
at
(
0
));
auto
addr
=
static_cast
<
void
*>
(
&
value
);
CAF_CHECK_NOT_EQUAL
(
addr
,
msg
.
cdata
().
at
(
0
));
value
=
10
;
value
=
10
;
});
});
CAF_CHECK_EQUAL
(
msg
.
get_as
<
int
>
(
0
),
42
);
CAF_CHECK_EQUAL
(
msg
.
get_as
<
int
>
(
0
),
42
);
...
...
libcaf_core/test/mixin/requester.cpp
View file @
dbdf9b26
...
@@ -93,7 +93,7 @@ CAF_TEST(requests without result) {
...
@@ -93,7 +93,7 @@ CAF_TEST(requests without result) {
run_once
();
run_once
();
expect
((
int
,
int
),
from
(
client
).
to
(
server
).
with
(
1
,
2
));
expect
((
int
,
int
),
from
(
client
).
to
(
server
).
with
(
1
,
2
));
expect
((
void
),
from
(
server
).
to
(
client
));
expect
((
void
),
from
(
server
).
to
(
client
));
CAF_CHECK_EQUAL
(
*
result
,
unit
);
CAF_CHECK_EQUAL
(
*
result
,
result_type
{
unit
}
);
}
}
SUBTEST
(
"request.await"
)
{
SUBTEST
(
"request.await"
)
{
auto
client
=
sys
.
spawn
([
=
](
event_based_actor
*
self
)
{
auto
client
=
sys
.
spawn
([
=
](
event_based_actor
*
self
)
{
...
@@ -102,13 +102,13 @@ CAF_TEST(requests without result) {
...
@@ -102,13 +102,13 @@ CAF_TEST(requests without result) {
run_once
();
run_once
();
expect
((
int
,
int
),
from
(
client
).
to
(
server
).
with
(
1
,
2
));
expect
((
int
,
int
),
from
(
client
).
to
(
server
).
with
(
1
,
2
));
expect
((
void
),
from
(
server
).
to
(
client
));
expect
((
void
),
from
(
server
).
to
(
client
));
CAF_CHECK_EQUAL
(
*
result
,
unit
);
CAF_CHECK_EQUAL
(
*
result
,
result_type
{
unit
}
);
}
}
SUBTEST
(
"request.receive"
)
{
SUBTEST
(
"request.receive"
)
{
auto
res_hdl
=
self
->
request
(
server
,
infinite
,
1
,
2
);
auto
res_hdl
=
self
->
request
(
server
,
infinite
,
1
,
2
);
run
();
run
();
res_hdl
.
receive
([
&
]
{
*
result
=
unit
;
},
ERROR_HANDLER
);
res_hdl
.
receive
([
&
]
{
*
result
=
unit
;
},
ERROR_HANDLER
);
CAF_CHECK_EQUAL
(
*
result
,
unit
);
CAF_CHECK_EQUAL
(
*
result
,
result_type
{
unit
}
);
}
}
}
}
...
@@ -121,7 +121,7 @@ CAF_TEST(requests with integer result) {
...
@@ -121,7 +121,7 @@ CAF_TEST(requests with integer result) {
run_once
();
run_once
();
expect
((
int
,
int
),
from
(
client
).
to
(
server
).
with
(
1
,
2
));
expect
((
int
,
int
),
from
(
client
).
to
(
server
).
with
(
1
,
2
));
expect
((
int
),
from
(
server
).
to
(
client
).
with
(
3
));
expect
((
int
),
from
(
server
).
to
(
client
).
with
(
3
));
CAF_CHECK_EQUAL
(
*
result
,
3
);
CAF_CHECK_EQUAL
(
*
result
,
result_type
{
3
}
);
}
}
SUBTEST
(
"request.await"
)
{
SUBTEST
(
"request.await"
)
{
auto
client
=
sys
.
spawn
([
=
](
event_based_actor
*
self
)
{
auto
client
=
sys
.
spawn
([
=
](
event_based_actor
*
self
)
{
...
@@ -130,13 +130,13 @@ CAF_TEST(requests with integer result) {
...
@@ -130,13 +130,13 @@ CAF_TEST(requests with integer result) {
run_once
();
run_once
();
expect
((
int
,
int
),
from
(
client
).
to
(
server
).
with
(
1
,
2
));
expect
((
int
,
int
),
from
(
client
).
to
(
server
).
with
(
1
,
2
));
expect
((
int
),
from
(
server
).
to
(
client
).
with
(
3
));
expect
((
int
),
from
(
server
).
to
(
client
).
with
(
3
));
CAF_CHECK_EQUAL
(
*
result
,
3
);
CAF_CHECK_EQUAL
(
*
result
,
result_type
{
3
}
);
}
}
SUBTEST
(
"request.receive"
)
{
SUBTEST
(
"request.receive"
)
{
auto
res_hdl
=
self
->
request
(
server
,
infinite
,
1
,
2
);
auto
res_hdl
=
self
->
request
(
server
,
infinite
,
1
,
2
);
run
();
run
();
res_hdl
.
receive
([
&
](
int
x
)
{
*
result
=
x
;
},
ERROR_HANDLER
);
res_hdl
.
receive
([
&
](
int
x
)
{
*
result
=
x
;
},
ERROR_HANDLER
);
CAF_CHECK_EQUAL
(
*
result
,
3
);
CAF_CHECK_EQUAL
(
*
result
,
result_type
{
3
}
);
}
}
}
}
...
@@ -150,7 +150,7 @@ CAF_TEST(delegated request with integer result) {
...
@@ -150,7 +150,7 @@ CAF_TEST(delegated request with integer result) {
expect
((
int
,
int
),
from
(
client
).
to
(
server
).
with
(
1
,
2
));
expect
((
int
,
int
),
from
(
client
).
to
(
server
).
with
(
1
,
2
));
expect
((
int
,
int
),
from
(
client
).
to
(
worker
).
with
(
1
,
2
));
expect
((
int
,
int
),
from
(
client
).
to
(
worker
).
with
(
1
,
2
));
expect
((
int
),
from
(
worker
).
to
(
client
).
with
(
3
));
expect
((
int
),
from
(
worker
).
to
(
client
).
with
(
3
));
CAF_CHECK_EQUAL
(
*
result
,
3
);
CAF_CHECK_EQUAL
(
*
result
,
result_type
{
3
}
);
}
}
CAF_TEST
(
requesters
support
fan_out_request
)
{
CAF_TEST
(
requesters
support
fan_out_request
)
{
...
...
libcaf_core/test/settings.cpp
View file @
dbdf9b26
...
@@ -61,23 +61,22 @@ struct fixture {
...
@@ -61,23 +61,22 @@ struct fixture {
}
}
};
};
con
st
config_value
&
unpack
(
const
settings
&
x
,
string_view
key
)
{
con
fig_value
unpack
(
const
settings
&
x
,
string_view
key
)
{
auto
i
=
x
.
find
(
key
);
if
(
auto
i
=
x
.
find
(
key
);
i
!=
x
.
end
())
if
(
i
==
x
.
end
())
return
i
->
second
;
CAF_FAIL
(
"key not found in dictionary: "
<<
key
);
else
return
i
->
second
;
return
{}
;
}
}
template
<
class
...
Ts
>
template
<
class
...
Ts
>
const
config_value
&
unpack
(
const
settings
&
x
,
string_view
key
,
config_value
const
char
*
next_key
,
Ts
...
keys
)
{
unpack
(
const
settings
&
x
,
string_view
key
,
const
char
*
next_key
,
Ts
...
keys
)
{
auto
i
=
x
.
find
(
key
);
if
(
auto
i
=
x
.
find
(
key
);
i
==
x
.
end
())
if
(
i
==
x
.
end
())
return
{};
CAF_FAIL
(
"key not found in dictionary: "
<<
key
);
else
if
(
auto
ptr
=
get_if
<
settings
>
(
std
::
addressof
(
i
->
second
)))
if
(
!
holds_alternative
<
settings
>
(
i
->
second
))
return
unpack
(
*
ptr
,
{
next_key
,
strlen
(
next_key
)},
keys
...);
CAF_FAIL
(
"value is not a dictionary: "
<<
key
);
else
return
unpack
(
get
<
settings
>
(
i
->
second
),
{
next_key
,
strlen
(
next_key
)},
return
{};
keys
...);
}
}
struct
foobar
{
struct
foobar
{
...
@@ -85,45 +84,12 @@ struct foobar {
...
@@ -85,45 +84,12 @@ struct foobar {
int
bar
=
0
;
int
bar
=
0
;
};
};
}
// namespace
template
<
class
Inspector
>
bool
inspect
(
Inspector
&
f
,
foobar
&
x
)
{
namespace
caf
{
return
f
.
object
(
x
).
fields
(
f
.
field
(
"foo"
,
x
.
foo
),
f
.
field
(
"bar"
,
x
.
bar
));
}
// Enable users to configure foobar's like this:
// my-value {
// foo = 42
// bar = 23
// }
template
<
>
struct
config_value_access
<
foobar
>
{
static
bool
is
(
const
config_value
&
x
)
{
auto
dict
=
caf
::
get_if
<
config_value
::
dictionary
>
(
&
x
);
if
(
dict
!=
nullptr
)
{
return
caf
::
get_if
<
int
>
(
dict
,
"foo"
)
!=
none
&&
caf
::
get_if
<
int
>
(
dict
,
"bar"
)
!=
none
;
}
return
false
;
}
static
optional
<
foobar
>
get_if
(
const
config_value
*
x
)
{
foobar
result
;
if
(
!
is
(
*
x
))
return
none
;
const
auto
&
dict
=
caf
::
get
<
config_value
::
dictionary
>
(
*
x
);
result
.
foo
=
caf
::
get
<
int
>
(
dict
,
"foo"
);
result
.
bar
=
caf
::
get
<
int
>
(
dict
,
"bar"
);
return
result
;
}
static
foobar
get
(
const
config_value
&
x
)
{
auto
result
=
get_if
(
&
x
);
if
(
!
result
)
CAF_RAISE_ERROR
(
"invalid type found"
);
return
std
::
move
(
*
result
);
}
};
}
// namespace
caf
}
// namespace
CAF_TEST_FIXTURE_SCOPE
(
settings_tests
,
fixture
)
CAF_TEST_FIXTURE_SCOPE
(
settings_tests
,
fixture
)
...
@@ -135,11 +101,11 @@ CAF_TEST(put) {
...
@@ -135,11 +101,11 @@ CAF_TEST(put) {
CAF_CHECK
(
x
.
contains
(
"foo"
));
CAF_CHECK
(
x
.
contains
(
"foo"
));
CAF_CHECK
(
x
.
contains
(
"logger"
));
CAF_CHECK
(
x
.
contains
(
"logger"
));
CAF_CHECK
(
x
.
contains
(
"one"
));
CAF_CHECK
(
x
.
contains
(
"one"
));
CAF_CHECK_EQUAL
(
unpack
(
x
,
"foo"
),
"bar"
s
);
CAF_CHECK_EQUAL
(
unpack
(
x
,
"foo"
),
config_value
{
"bar"
s
}
);
CAF_CHECK_EQUAL
(
unpack
(
x
,
"logger"
,
"console"
),
"none"
s
);
CAF_CHECK_EQUAL
(
unpack
(
x
,
"logger"
,
"console"
),
config_value
{
"none"
s
}
);
CAF_CHECK_EQUAL
(
unpack
(
x
,
"one"
,
"two"
,
"three"
),
"four"
s
);
CAF_CHECK_EQUAL
(
unpack
(
x
,
"one"
,
"two"
,
"three"
),
config_value
{
"four"
s
}
);
put
(
x
,
"logger.console"
,
"trace"
);
put
(
x
,
"logger.console"
,
"trace"
);
CAF_CHECK_EQUAL
(
unpack
(
x
,
"logger"
,
"console"
),
"trace"
s
);
CAF_CHECK_EQUAL
(
unpack
(
x
,
"logger"
,
"console"
),
config_value
{
"trace"
s
}
);
}
}
CAF_TEST
(
put
missing
)
{
CAF_TEST
(
put
missing
)
{
...
@@ -150,11 +116,11 @@ CAF_TEST(put missing) {
...
@@ -150,11 +116,11 @@ CAF_TEST(put missing) {
CAF_CHECK
(
x
.
contains
(
"foo"
));
CAF_CHECK
(
x
.
contains
(
"foo"
));
CAF_CHECK
(
x
.
contains
(
"logger"
));
CAF_CHECK
(
x
.
contains
(
"logger"
));
CAF_CHECK
(
x
.
contains
(
"one"
));
CAF_CHECK
(
x
.
contains
(
"one"
));
CAF_CHECK_EQUAL
(
unpack
(
x
,
"foo"
),
"bar"
s
);
CAF_CHECK_EQUAL
(
unpack
(
x
,
"foo"
),
config_value
{
"bar"
s
}
);
CAF_CHECK_EQUAL
(
unpack
(
x
,
"logger"
,
"console"
),
"none"
s
);
CAF_CHECK_EQUAL
(
unpack
(
x
,
"logger"
,
"console"
),
config_value
{
"none"
s
}
);
CAF_CHECK_EQUAL
(
unpack
(
x
,
"one"
,
"two"
,
"three"
),
"four"
s
);
CAF_CHECK_EQUAL
(
unpack
(
x
,
"one"
,
"two"
,
"three"
),
config_value
{
"four"
s
}
);
put_missing
(
x
,
"logger.console"
,
"trace"
);
put_missing
(
x
,
"logger.console"
,
"trace"
);
CAF_CHECK_EQUAL
(
unpack
(
x
,
"logger"
,
"console"
),
"none"
s
);
CAF_CHECK_EQUAL
(
unpack
(
x
,
"logger"
,
"console"
),
config_value
{
"none"
s
}
);
}
}
CAF_TEST
(
put
list
)
{
CAF_TEST
(
put
list
)
{
...
@@ -170,11 +136,12 @@ CAF_TEST(put list) {
...
@@ -170,11 +136,12 @@ CAF_TEST(put list) {
CAF_TEST
(
put
dictionary
)
{
CAF_TEST
(
put
dictionary
)
{
put_dictionary
(
x
,
"logger"
).
emplace
(
"console"
,
"none"
);
put_dictionary
(
x
,
"logger"
).
emplace
(
"console"
,
"none"
);
CAF_CHECK
(
x
.
contains
(
"logger"
));
CAF_CHECK
(
x
.
contains
(
"logger"
));
CAF_CHECK_EQUAL
(
unpack
(
x
,
"logger"
,
"console"
),
"none"
s
);
CAF_CHECK_EQUAL
(
unpack
(
x
,
"logger"
,
"console"
),
config_value
{
"none"
s
}
);
put_dictionary
(
x
,
"foo.bar"
).
emplace
(
"value"
,
42
);
put_dictionary
(
x
,
"foo.bar"
).
emplace
(
"value"
,
42
);
CAF_CHECK_EQUAL
(
unpack
(
x
,
"foo"
,
"bar"
,
"value"
),
42
);
CAF_CHECK_EQUAL
(
unpack
(
x
,
"foo"
,
"bar"
,
"value"
),
config_value
{
42
}
);
put_dictionary
(
x
,
"one.two.three"
).
emplace
(
"four"
,
"five"
);
put_dictionary
(
x
,
"one.two.three"
).
emplace
(
"four"
,
"five"
);
CAF_CHECK_EQUAL
(
unpack
(
x
,
"one"
,
"two"
,
"three"
,
"four"
),
"five"
s
);
CAF_CHECK_EQUAL
(
unpack
(
x
,
"one"
,
"two"
,
"three"
,
"four"
),
config_value
{
"five"
s
});
}
}
CAF_TEST
(
get
and
get_if
)
{
CAF_TEST
(
get
and
get_if
)
{
...
@@ -186,8 +153,8 @@ CAF_TEST(get and get_if) {
...
@@ -186,8 +153,8 @@ CAF_TEST(get and get_if) {
CAF_CHECK
(
get
<
std
::
string
>
(
x
,
"logger.console"
)
==
"none"
s
);
CAF_CHECK
(
get
<
std
::
string
>
(
x
,
"logger.console"
)
==
"none"
s
);
CAF_CHECK
(
get_if
(
&
x
,
"one.two.three"
)
!=
nullptr
);
CAF_CHECK
(
get_if
(
&
x
,
"one.two.three"
)
!=
nullptr
);
CAF_CHECK
(
get_if
<
std
::
string
>
(
&
x
,
"one.two.three"
)
==
nullptr
);
CAF_CHECK
(
get_if
<
std
::
string
>
(
&
x
,
"one.two.three"
)
==
nullptr
);
CAF_REQUIRE
(
get_if
<
int
>
(
&
x
,
"one.two.three"
)
!=
none
);
if
(
CAF_CHECK
(
get_if
<
int64_t
>
(
&
x
,
"one.two.three"
)
!=
nullptr
))
CAF_CHECK
(
get
<
in
t
>
(
x
,
"one.two.three"
)
==
4
);
CAF_CHECK
(
get
<
int64_
t
>
(
x
,
"one.two.three"
)
==
4
);
}
}
CAF_TEST
(
get_or
)
{
CAF_TEST
(
get_or
)
{
...
@@ -199,11 +166,10 @@ CAF_TEST(get_or) {
...
@@ -199,11 +166,10 @@ CAF_TEST(get_or) {
CAF_TEST
(
custom
type
)
{
CAF_TEST
(
custom
type
)
{
put
(
x
,
"my-value.foo"
,
42
);
put
(
x
,
"my-value.foo"
,
42
);
put
(
x
,
"my-value.bar"
,
24
);
put
(
x
,
"my-value.bar"
,
24
);
CAF_REQUIRE
(
holds_alternative
<
foobar
>
(
x
,
"my-value"
));
if
(
auto
fb
=
get_as
<
foobar
>
(
x
,
"my-value"
);
CAF_CHECK
(
fb
))
{
CAF_REQUIRE
(
get_if
<
foobar
>
(
&
x
,
"my-value"
)
!=
caf
::
none
);
CAF_CHECK_EQUAL
(
fb
->
foo
,
42
);
auto
fb
=
get
<
foobar
>
(
x
,
"my-value"
);
CAF_CHECK_EQUAL
(
fb
->
bar
,
24
);
CAF_CHECK_EQUAL
(
fb
.
foo
,
42
);
}
CAF_CHECK_EQUAL
(
fb
.
bar
,
24
);
}
}
CAF_TEST
(
read_config
accepts
the
to_string
output
of
settings
)
{
CAF_TEST
(
read_config
accepts
the
to_string
output
of
settings
)
{
...
...
libcaf_core/test/span.cpp
View file @
dbdf9b26
...
@@ -86,10 +86,10 @@ CAF_TEST(subspans) {
...
@@ -86,10 +86,10 @@ CAF_TEST(subspans) {
CAF_TEST
(
free
iterator
functions
)
{
CAF_TEST
(
free
iterator
functions
)
{
auto
xs
=
make_span
(
chars
);
auto
xs
=
make_span
(
chars
);
CAF_CHECK
_EQUAL
(
xs
.
begin
(),
begin
(
xs
));
CAF_CHECK
(
xs
.
begin
()
==
begin
(
xs
));
CAF_CHECK
_EQUAL
(
xs
.
cbegin
(),
cbegin
(
xs
));
CAF_CHECK
(
xs
.
cbegin
()
==
cbegin
(
xs
));
CAF_CHECK
_EQUAL
(
xs
.
end
(),
end
(
xs
));
CAF_CHECK
(
xs
.
end
()
==
end
(
xs
));
CAF_CHECK
_EQUAL
(
xs
.
cend
(),
cend
(
xs
));
CAF_CHECK
(
xs
.
cend
()
==
cend
(
xs
));
}
}
CAF_TEST
(
as
bytes
)
{
CAF_TEST
(
as
bytes
)
{
...
@@ -108,10 +108,10 @@ CAF_TEST(make_span) {
...
@@ -108,10 +108,10 @@ CAF_TEST(make_span) {
CAF_CHECK
(
std
::
equal
(
xs
.
begin
(),
xs
.
end
(),
chars
.
begin
()));
CAF_CHECK
(
std
::
equal
(
xs
.
begin
(),
xs
.
end
(),
chars
.
begin
()));
CAF_CHECK
(
std
::
equal
(
ys
.
begin
(),
ys
.
end
(),
chars
.
begin
()));
CAF_CHECK
(
std
::
equal
(
ys
.
begin
(),
ys
.
end
(),
chars
.
begin
()));
CAF_CHECK
(
std
::
equal
(
zs
.
begin
(),
zs
.
end
(),
chars
.
begin
()));
CAF_CHECK
(
std
::
equal
(
zs
.
begin
(),
zs
.
end
(),
chars
.
begin
()));
CAF_CHECK
_EQUAL
(
end
(
xs
),
end
(
ys
));
CAF_CHECK
(
end
(
xs
)
==
end
(
ys
));
CAF_CHECK
_EQUAL
(
end
(
ys
),
end
(
zs
));
CAF_CHECK
(
end
(
ys
)
==
end
(
zs
));
CAF_CHECK
_EQUAL
(
begin
(
xs
),
begin
(
ys
));
CAF_CHECK
(
begin
(
xs
)
==
begin
(
ys
));
CAF_CHECK
_EQUAL
(
begin
(
ys
),
begin
(
zs
));
CAF_CHECK
(
begin
(
ys
)
==
begin
(
zs
));
}
}
CAF_TEST
(
spans
are
convertible
from
compatible
containers
)
{
CAF_TEST
(
spans
are
convertible
from
compatible
containers
)
{
...
...
libcaf_core/test/variant.cpp
View file @
dbdf9b26
...
@@ -81,8 +81,7 @@ using v20 = variant<i01, i02, i03, i04, i05, i06, i07, i08, i09, i10,
...
@@ -81,8 +81,7 @@ using v20 = variant<i01, i02, i03, i04, i05, i06, i07, i08, i09, i10,
do { \
do { \
using type = std::decay_t<decltype(y)>; \
using type = std::decay_t<decltype(y)>; \
auto&& tmp = x; \
auto&& tmp = x; \
CAF_CHECK(holds_alternative<type>(tmp)); \
if (CAF_CHECK(holds_alternative<type>(tmp))) \
if (holds_alternative<type>(tmp)) \
CAF_CHECK_EQUAL(get<type>(tmp), y); \
CAF_CHECK_EQUAL(get<type>(tmp), y); \
} while (false)
} while (false)
...
@@ -102,9 +101,6 @@ using v20 = variant<i01, i02, i03, i04, i05, i06, i07, i08, i09, i10,
...
@@ -102,9 +101,6 @@ using v20 = variant<i01, i02, i03, i04, i05, i06, i07, i08, i09, i10,
CAF_TEST
(
copying_moving_roundtrips
)
{
CAF_TEST
(
copying_moving_roundtrips
)
{
actor_system_config
cfg
;
actor_system_config
cfg
;
actor_system
sys
{
cfg
};
actor_system
sys
{
cfg
};
// default construction
variant
<
none_t
>
x1
;
CAF_CHECK_EQUAL
(
x1
,
none
);
variant
<
int
,
none_t
>
x2
;
variant
<
int
,
none_t
>
x2
;
VARIANT_EQ
(
x2
,
0
);
VARIANT_EQ
(
x2
,
0
);
v20
x3
;
v20
x3
;
...
@@ -129,11 +125,10 @@ CAF_TEST(constructors) {
...
@@ -129,11 +125,10 @@ CAF_TEST(constructors) {
variant
<
float
,
int
,
std
::
string
>
b
{
"bar"
s
};
variant
<
float
,
int
,
std
::
string
>
b
{
"bar"
s
};
variant
<
int
,
std
::
string
,
double
>
c
{
123
};
variant
<
int
,
std
::
string
,
double
>
c
{
123
};
variant
<
bool
,
uint8_t
>
d
{
uint8_t
{
252
}};
variant
<
bool
,
uint8_t
>
d
{
uint8_t
{
252
}};
CAF_CHECK_EQUAL
(
a
,
42
);
VARIANT_EQ
(
a
,
42
);
CAF_CHECK_EQUAL
(
b
,
"bar"
s
);
VARIANT_EQ
(
b
,
"bar"
s
);
CAF_CHECK_EQUAL
(
c
,
123
);
VARIANT_EQ
(
c
,
123
);
CAF_CHECK_NOT_EQUAL
(
c
,
"123"
s
);
VARIANT_EQ
(
d
,
uint8_t
{
252
});
CAF_CHECK_EQUAL
(
d
,
uint8_t
{
252
});
}
}
CAF_TEST
(
n_ary_visit
)
{
CAF_TEST
(
n_ary_visit
)
{
...
@@ -152,8 +147,7 @@ CAF_TEST(get_if) {
...
@@ -152,8 +147,7 @@ CAF_TEST(get_if) {
CAF_CHECK_EQUAL
(
get_if
<
int
>
(
&
b
),
nullptr
);
CAF_CHECK_EQUAL
(
get_if
<
int
>
(
&
b
),
nullptr
);
CAF_CHECK_NOT_EQUAL
(
get_if
<
std
::
string
>
(
&
b
),
nullptr
);
CAF_CHECK_NOT_EQUAL
(
get_if
<
std
::
string
>
(
&
b
),
nullptr
);
CAF_MESSAGE
(
"test get_if via unit test framework"
);
CAF_MESSAGE
(
"test get_if via unit test framework"
);
CAF_CHECK_NOT_EQUAL
(
b
,
42
);
VARIANT_EQ
(
b
,
"foo"
s
);
CAF_CHECK_EQUAL
(
b
,
"foo"
s
);
}
}
CAF_TEST
(
less_than
)
{
CAF_TEST
(
less_than
)
{
...
...
libcaf_io/src/io/basp/instance.cpp
View file @
dbdf9b26
...
@@ -46,7 +46,7 @@ instance::instance(abstract_broker* parent, callee& lstnr)
...
@@ -46,7 +46,7 @@ instance::instance(abstract_broker* parent, callee& lstnr)
:
tbl_
(
parent
),
this_node_
(
parent
->
system
().
node
()),
callee_
(
lstnr
)
{
:
tbl_
(
parent
),
this_node_
(
parent
->
system
().
node
()),
callee_
(
lstnr
)
{
CAF_ASSERT
(
this_node_
!=
none
);
CAF_ASSERT
(
this_node_
!=
none
);
size_t
workers
;
size_t
workers
;
if
(
auto
workers_cfg
=
get_
if
<
size_t
>
(
&
config
(),
"caf.middleman.workers"
))
if
(
auto
workers_cfg
=
get_
as
<
size_t
>
(
config
(),
"caf.middleman.workers"
))
workers
=
*
workers_cfg
;
workers
=
*
workers_cfg
;
else
else
workers
=
std
::
min
(
3u
,
std
::
thread
::
hardware_concurrency
()
/
4u
)
+
1
;
workers
=
std
::
min
(
3u
,
std
::
thread
::
hardware_concurrency
()
/
4u
)
+
1
;
...
@@ -250,7 +250,7 @@ void instance::write_server_handshake(execution_unit* ctx, byte_buffer& out_buf,
...
@@ -250,7 +250,7 @@ void instance::write_server_handshake(execution_unit* ctx, byte_buffer& out_buf,
auto
writer
=
make_callback
([
&
](
binary_serializer
&
sink
)
{
auto
writer
=
make_callback
([
&
](
binary_serializer
&
sink
)
{
using
string_list
=
std
::
vector
<
std
::
string
>
;
using
string_list
=
std
::
vector
<
std
::
string
>
;
string_list
app_ids
;
string_list
app_ids
;
if
(
auto
ids
=
get_
if
<
string_list
>
(
&
config
(),
if
(
auto
ids
=
get_
as
<
string_list
>
(
config
(),
"caf.middleman.app-identifiers"
))
"caf.middleman.app-identifiers"
))
app_ids
=
std
::
move
(
*
ids
);
app_ids
=
std
::
move
(
*
ids
);
else
else
...
@@ -349,7 +349,7 @@ connection_state instance::handle(execution_unit* ctx, connection_handle hdl,
...
@@ -349,7 +349,7 @@ connection_state instance::handle(execution_unit* ctx, connection_handle hdl,
}
}
// Check the application ID.
// Check the application ID.
string_list
whitelist
;
string_list
whitelist
;
if
(
auto
ls
=
get_
if
<
string_list
>
(
&
config
(),
if
(
auto
ls
=
get_
as
<
string_list
>
(
config
(),
"caf.middleman.app-identifiers"
))
"caf.middleman.app-identifiers"
))
whitelist
=
std
::
move
(
*
ls
);
whitelist
=
std
::
move
(
*
ls
);
else
else
...
...
libcaf_io/src/io/middleman.cpp
View file @
dbdf9b26
...
@@ -130,7 +130,7 @@ public:
...
@@ -130,7 +130,7 @@ public:
bool
start
(
const
config_value
::
dictionary
&
cfg
)
override
{
bool
start
(
const
config_value
::
dictionary
&
cfg
)
override
{
// Read port, address and reuse flag from the config.
// Read port, address and reuse flag from the config.
uint16_t
port
=
0
;
uint16_t
port
=
0
;
if
(
auto
cfg_port
=
get_
if
<
uint16_t
>
(
&
cfg
,
"port"
))
{
if
(
auto
cfg_port
=
get_
as
<
uint16_t
>
(
cfg
,
"port"
))
{
port
=
*
cfg_port
;
port
=
*
cfg_port
;
}
else
{
}
else
{
return
false
;
return
false
;
...
...
libcaf_test/caf/test/bdd_dsl.hpp
View file @
dbdf9b26
...
@@ -46,3 +46,8 @@
...
@@ -46,3 +46,8 @@
#define REQUIRE_GE(lhs, rhs) CAF_REQUIRE_GREATER_OR_EQUAL(lhs, rhs)
#define REQUIRE_GE(lhs, rhs) CAF_REQUIRE_GREATER_OR_EQUAL(lhs, rhs)
#define MESSAGE(what) CAF_MESSAGE(what)
#define MESSAGE(what) CAF_MESSAGE(what)
#define BEGIN_FIXTURE_SCOPE(fixture_class) \
CAF_TEST_FIXTURE_SCOPE(CAF_UNIFYN(tests), fixture_class)
#define END_FIXTURE_SCOPE() CAF_TEST_FIXTURE_SCOPE_END()
libcaf_test/caf/test/unit_test.hpp
View file @
dbdf9b26
...
@@ -483,6 +483,11 @@ bool check(test* parent, const char* file, size_t line, const char* expr,
...
@@ -483,6 +483,11 @@ bool check(test* parent, const char* file, size_t line, const char* expr,
return
result
;
return
result
;
}
}
bool
check_un
(
bool
result
,
const
char
*
file
,
size_t
line
,
const
char
*
expr
);
bool
check_bin
(
bool
result
,
const
char
*
file
,
size_t
line
,
const
char
*
expr
,
const
std
::
string
&
lhs
,
const
std
::
string
&
rhs
);
}
// namespace detail
}
// namespace detail
}
// namespace caf::test
}
// namespace caf::test
...
@@ -546,18 +551,13 @@ using caf_test_case_auto_fixture = caf::test::dummy_fixture;
...
@@ -546,18 +551,13 @@ using caf_test_case_auto_fixture = caf::test::dummy_fixture;
} while (false)
} while (false)
#define CAF_CHECK(...) \
#define CAF_CHECK(...) \
([](bool expr_result) { \
[](bool expr_result) { \
auto caf_check_res \
return ::caf::test::detail::check_un(expr_result, __FILE__, __LINE__, \
= ::caf::test::detail::check(::caf::test::engine::current_test(), \
#__VA_ARGS__); \
__FILE__, __LINE__, #__VA_ARGS__, false, \
}(static_cast<bool>(__VA_ARGS__))
expr_result); \
::caf::test::engine::last_check_file(__FILE__); \
::caf::test::engine::last_check_line(__LINE__); \
return caf_check_res; \
})(static_cast<bool>(__VA_ARGS__))
#define CAF_CHECK_FUNC(func, x_expr, y_expr) \
#define CAF_CHECK_FUNC(func, x_expr, y_expr) \
([](auto&& x_val, auto&& y_val) {
\
[](auto&& x_val, auto&& y_val) {
\
func comparator; \
func comparator; \
auto caf_check_res \
auto caf_check_res \
= ::caf::test::detail::check(::caf::test::engine::current_test(), \
= ::caf::test::detail::check(::caf::test::engine::current_test(), \
...
@@ -567,7 +567,7 @@ using caf_test_case_auto_fixture = caf::test::dummy_fixture;
...
@@ -567,7 +567,7 @@ using caf_test_case_auto_fixture = caf::test::dummy_fixture;
::caf::test::engine::last_check_file(__FILE__); \
::caf::test::engine::last_check_file(__FILE__); \
::caf::test::engine::last_check_line(__LINE__); \
::caf::test::engine::last_check_line(__LINE__); \
return caf_check_res; \
return caf_check_res; \
}
)
(x_expr, y_expr)
}(x_expr, y_expr)
#define CAF_CHECK_FAIL(...) \
#define CAF_CHECK_FAIL(...) \
do { \
do { \
...
@@ -642,32 +642,81 @@ using caf_test_case_auto_fixture = caf::test::dummy_fixture;
...
@@ -642,32 +642,81 @@ using caf_test_case_auto_fixture = caf::test::dummy_fixture;
// -- CAF_CHECK* predicate family ----------------------------------------------
// -- CAF_CHECK* predicate family ----------------------------------------------
#define CAF_CHECK_EQUAL(x, y) CAF_CHECK_FUNC(::caf::test::equal_to, x, y)
#define CAF_CHECK_EQUAL(x_expr, y_expr) \
[](const auto& x_val, const auto& y_val) { \
#define CAF_CHECK_NOT_EQUAL(x, y) \
return ::caf::test::detail::check_bin(x_val == y_val, __FILE__, __LINE__, \
CAF_CHECK_FUNC(::caf::test::not_equal_to, x, y)
#x_expr " == " #y_expr, \
caf::deep_to_string(x_val), \
#define CAF_CHECK_LESS(x, y) CAF_CHECK_FUNC(::caf::test::less_than, x, y)
caf::deep_to_string(y_val)); \
}(x_expr, y_expr)
#define CAF_CHECK_NOT_LESS(x, y) \
CAF_CHECK_FUNC(::caf::test::negated<::caf::test::less_than>, x, y)
#define CAF_CHECK_NOT_EQUAL(x_expr, y_expr) \
[](const auto& x_val, const auto& y_val) { \
#define CAF_CHECK_LESS_OR_EQUAL(x, y) \
return ::caf::test::detail::check_bin(x_val != y_val, __FILE__, __LINE__, \
CAF_CHECK_FUNC(::caf::test::less_than_or_equal, x, y)
#x_expr " != " #y_expr, \
caf::deep_to_string(x_val), \
#define CAF_CHECK_NOT_LESS_OR_EQUAL(x, y) \
caf::deep_to_string(y_val)); \
CAF_CHECK_FUNC(::caf::test::negated<::caf::test::less_than_or_equal>, x, y)
}(x_expr, y_expr)
#define CAF_CHECK_GREATER(x, y) CAF_CHECK_FUNC(::caf::test::greater_than, x, y)
#define CAF_CHECK_LESS(x_expr, y_expr) \
[](const auto& x_val, const auto& y_val) { \
#define CAF_CHECK_NOT_GREATER(x, y) \
return ::caf::test::detail::check_bin(x_val < y_val, __FILE__, __LINE__, \
CAF_CHECK_FUNC(::caf::test::negated<::caf::test::greater_than>, x, y)
#x_expr " < " #y_expr, \
caf::deep_to_string(x_val), \
#define CAF_CHECK_GREATER_OR_EQUAL(x, y) \
caf::deep_to_string(y_val)); \
CAF_CHECK_FUNC(::caf::test::greater_than_or_equal, x, y)
}(x_expr, y_expr)
#define CAF_CHECK_NOT_GREATER_OR_EQUAL(x, y) \
#define CAF_CHECK_NOT_LESS(x_expr, y_expr) \
CAF_CHECK_FUNC(::caf::test::negated<::caf::test::greater_than_or_equal>, x, y)
[](const auto& x_val, const auto& y_val) { \
return ::caf::test::detail::check_bin( \
!(x_val < y_val), __FILE__, __LINE__, "not " #x_expr " < " #y_expr, \
caf::deep_to_string(x_val), caf::deep_to_string(y_val)); \
}(x_expr, y_expr)
#define CAF_CHECK_LESS_OR_EQUAL(x_expr, y_expr) \
[](const auto& x_val, const auto& y_val) { \
return ::caf::test::detail::check_bin(x_val <= y_val, __FILE__, __LINE__, \
#x_expr " <= " #y_expr, \
caf::deep_to_string(x_val), \
caf::deep_to_string(y_val)); \
}(x_expr, y_expr)
#define CAF_CHECK_NOT_LESS_OR_EQUAL(x_expr, y_expr) \
[](const auto& x_val, const auto& y_val) { \
return ::caf::test::detail::check_bin( \
!(x_val <= y_val), __FILE__, __LINE__, "not " #x_expr " <= " #y_expr, \
caf::deep_to_string(x_val), caf::deep_to_string(y_val)); \
}(x_expr, y_expr)
#define CAF_CHECK_GREATER(x_expr, y_expr) \
[](const auto& x_val, const auto& y_val) { \
return ::caf::test::detail::check_bin(x_val > y_val, __FILE__, __LINE__, \
#x_expr " > " #y_expr, \
caf::deep_to_string(x_val), \
caf::deep_to_string(y_val)); \
}(x_expr, y_expr)
#define CAF_CHECK_NOT_GREATER(x_expr, y_expr) \
[](const auto& x_val, const auto& y_val) { \
return ::caf::test::detail::check_bin( \
!(x_val > y_val), __FILE__, __LINE__, "not " #x_expr " > " #y_expr, \
caf::deep_to_string(x_val), caf::deep_to_string(y_val)); \
}(x_expr, y_expr)
#define CAF_CHECK_GREATER_OR_EQUAL(x_expr, y_expr) \
[](const auto& x_val, const auto& y_val) { \
return ::caf::test::detail::check_bin(x_val >= y_val, __FILE__, __LINE__, \
#x_expr " >= " #y_expr, \
caf::deep_to_string(x_val), \
caf::deep_to_string(y_val)); \
}(x_expr, y_expr)
#define CAF_CHECK_NOT_GREATER_OR_EQUAL(x_expr, y_expr) \
[](const auto& x_val, const auto& y_val) { \
return ::caf::test::detail::check_bin( \
!(x_val >= y_val), __FILE__, __LINE__, "not " #x_expr " >= " #y_expr, \
caf::deep_to_string(x_val), caf::deep_to_string(y_val)); \
}(x_expr, y_expr)
// -- CAF_CHECK* predicate family ----------------------------------------------
// -- CAF_CHECK* predicate family ----------------------------------------------
...
...
libcaf_test/caf/test/unit_test_impl.hpp
View file @
dbdf9b26
...
@@ -165,6 +165,51 @@ bool check(test* parent, const char* file, size_t line, const char* expr,
...
@@ -165,6 +165,51 @@ bool check(test* parent, const char* file, size_t line, const char* expr,
return
result
;
return
result
;
}
}
bool
check_un
(
bool
result
,
const
char
*
file
,
size_t
line
,
const
char
*
expr
)
{
string_view
rel_up
=
"../"
;
while
(
strncmp
(
file
,
rel_up
.
data
(),
rel_up
.
size
())
==
0
)
file
+=
rel_up
.
size
();
auto
parent
=
engine
::
current_test
();
auto
out
=
logger
::
instance
().
massive
();
if
(
result
)
{
out
<<
term
::
green
<<
"** "
<<
term
::
blue
<<
file
<<
term
::
yellow
<<
":"
<<
term
::
blue
<<
line
<<
fill
(
line
)
<<
term
::
reset
<<
"passed"
<<
'\n'
;
parent
->
pass
();
}
else
{
out
<<
term
::
red
<<
"!! "
<<
term
::
blue
<<
file
<<
term
::
yellow
<<
":"
<<
term
::
blue
<<
line
<<
fill
(
line
)
<<
term
::
red
<<
"check failed: "
<<
expr
<<
term
::
reset
<<
'\n'
;
parent
->
fail
(
false
);
}
engine
::
last_check_file
(
file
);
engine
::
last_check_line
(
line
);
return
result
;
}
bool
check_bin
(
bool
result
,
const
char
*
file
,
size_t
line
,
const
char
*
expr
,
const
std
::
string
&
lhs
,
const
std
::
string
&
rhs
)
{
string_view
rel_up
=
"../"
;
while
(
strncmp
(
file
,
rel_up
.
data
(),
rel_up
.
size
())
==
0
)
file
+=
rel_up
.
size
();
auto
parent
=
engine
::
current_test
();
auto
out
=
logger
::
instance
().
massive
();
if
(
result
)
{
out
<<
term
::
green
<<
"** "
<<
term
::
blue
<<
file
<<
term
::
yellow
<<
":"
<<
term
::
blue
<<
line
<<
fill
(
line
)
<<
term
::
reset
<<
"passed"
<<
'\n'
;
parent
->
pass
();
}
else
{
out
<<
term
::
red
<<
"!! "
<<
term
::
blue
<<
file
<<
term
::
yellow
<<
":"
<<
term
::
blue
<<
line
<<
fill
(
line
)
<<
term
::
red
<<
"check failed: "
<<
expr
<<
term
::
reset
<<
'\n'
<<
" lhs: "
<<
lhs
<<
'\n'
<<
" rhs: "
<<
rhs
<<
'\n'
;
parent
->
fail
(
false
);
}
engine
::
last_check_file
(
file
);
engine
::
last_check_line
(
line
);
return
result
;
}
}
// namespace detail
}
// namespace detail
logger
::
stream
::
stream
(
logger
&
parent
,
logger
::
level
lvl
)
logger
::
stream
::
stream
(
logger
&
parent
,
logger
::
level
lvl
)
...
...
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