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
11c4eaca
Unverified
Commit
11c4eaca
authored
Oct 12, 2019
by
Dominik Charousset
Committed by
GitHub
Oct 12, 2019
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #929
Allow users to extend config_value API
parents
41df839f
25a601e1
Changes
50
Show whitespace changes
Inline
Side-by-side
Showing
50 changed files
with
1336 additions
and
326 deletions
+1336
-326
libcaf_core/caf/all.hpp
libcaf_core/caf/all.hpp
+3
-0
libcaf_core/caf/config_value.hpp
libcaf_core/caf/config_value.hpp
+220
-85
libcaf_core/caf/config_value_field.hpp
libcaf_core/caf/config_value_field.hpp
+66
-0
libcaf_core/caf/config_value_object_access.hpp
libcaf_core/caf/config_value_object_access.hpp
+173
-0
libcaf_core/caf/detail/config_value_field_impl.hpp
libcaf_core/caf/detail/config_value_field_impl.hpp
+195
-0
libcaf_core/caf/detail/dispatch_parse_cli.hpp
libcaf_core/caf/detail/dispatch_parse_cli.hpp
+62
-0
libcaf_core/caf/detail/parse.hpp
libcaf_core/caf/detail/parse.hpp
+30
-30
libcaf_core/caf/detail/parser/read_atom.hpp
libcaf_core/caf/detail/parser/read_atom.hpp
+2
-4
libcaf_core/caf/detail/parser/read_bool.hpp
libcaf_core/caf/detail/parser/read_bool.hpp
+2
-3
libcaf_core/caf/detail/parser/read_floating_point.hpp
libcaf_core/caf/detail/parser/read_floating_point.hpp
+4
-5
libcaf_core/caf/detail/parser/read_ini.hpp
libcaf_core/caf/detail/parser/read_ini.hpp
+18
-18
libcaf_core/caf/detail/parser/read_ipv4_address.hpp
libcaf_core/caf/detail/parser/read_ipv4_address.hpp
+4
-5
libcaf_core/caf/detail/parser/read_ipv6_address.hpp
libcaf_core/caf/detail/parser/read_ipv6_address.hpp
+6
-7
libcaf_core/caf/detail/parser/read_number.hpp
libcaf_core/caf/detail/parser/read_number.hpp
+2
-3
libcaf_core/caf/detail/parser/read_number_or_timespan.hpp
libcaf_core/caf/detail/parser/read_number_or_timespan.hpp
+2
-4
libcaf_core/caf/detail/parser/read_signed_integer.hpp
libcaf_core/caf/detail/parser/read_signed_integer.hpp
+2
-3
libcaf_core/caf/detail/parser/read_string.hpp
libcaf_core/caf/detail/parser/read_string.hpp
+2
-3
libcaf_core/caf/detail/parser/read_timespan.hpp
libcaf_core/caf/detail/parser/read_timespan.hpp
+2
-3
libcaf_core/caf/detail/parser/read_unsigned_integer.hpp
libcaf_core/caf/detail/parser/read_unsigned_integer.hpp
+2
-3
libcaf_core/caf/detail/parser/read_uri.hpp
libcaf_core/caf/detail/parser/read_uri.hpp
+6
-7
libcaf_core/caf/detail/type_traits.hpp
libcaf_core/caf/detail/type_traits.hpp
+4
-0
libcaf_core/caf/fwd.hpp
libcaf_core/caf/fwd.hpp
+2
-0
libcaf_core/caf/make_config_option.hpp
libcaf_core/caf/make_config_option.hpp
+14
-11
libcaf_core/caf/make_config_value_field.hpp
libcaf_core/caf/make_config_value_field.hpp
+92
-0
libcaf_core/caf/parser_state.hpp
libcaf_core/caf/parser_state.hpp
+29
-10
libcaf_core/caf/pec.hpp
libcaf_core/caf/pec.hpp
+8
-1
libcaf_core/caf/span.hpp
libcaf_core/caf/span.hpp
+7
-0
libcaf_core/caf/uri.hpp
libcaf_core/caf/uri.hpp
+0
-1
libcaf_core/src/actor_system_config.cpp
libcaf_core/src/actor_system_config.cpp
+1
-2
libcaf_core/src/config_value.cpp
libcaf_core/src/config_value.cpp
+3
-3
libcaf_core/src/detail/parse.cpp
libcaf_core/src/detail/parse.cpp
+13
-13
libcaf_core/src/ipv4_address.cpp
libcaf_core/src/ipv4_address.cpp
+2
-1
libcaf_core/src/ipv6_address.cpp
libcaf_core/src/ipv6_address.cpp
+2
-1
libcaf_core/src/make_config_option.cpp
libcaf_core/src/make_config_option.cpp
+33
-40
libcaf_core/src/pec.cpp
libcaf_core/src/pec.cpp
+1
-1
libcaf_core/src/uri.cpp
libcaf_core/src/uri.cpp
+2
-3
libcaf_core/test/config_option.cpp
libcaf_core/test/config_option.cpp
+0
-1
libcaf_core/test/detail/ini_consumer.cpp
libcaf_core/test/detail/ini_consumer.cpp
+9
-14
libcaf_core/test/detail/parse.cpp
libcaf_core/test/detail/parse.cpp
+2
-2
libcaf_core/test/detail/parser/read_atom.cpp
libcaf_core/test/detail/parser/read_atom.cpp
+4
-4
libcaf_core/test/detail/parser/read_bool.cpp
libcaf_core/test/detail/parser/read_bool.cpp
+4
-4
libcaf_core/test/detail/parser/read_floating_point.cpp
libcaf_core/test/detail/parser/read_floating_point.cpp
+4
-3
libcaf_core/test/detail/parser/read_ini.cpp
libcaf_core/test/detail/parser/read_ini.cpp
+11
-8
libcaf_core/test/detail/parser/read_number.cpp
libcaf_core/test/detail/parser/read_number.cpp
+4
-4
libcaf_core/test/detail/parser/read_number_or_timespan.cpp
libcaf_core/test/detail/parser/read_number_or_timespan.cpp
+4
-4
libcaf_core/test/detail/parser/read_signed_integer.cpp
libcaf_core/test/detail/parser/read_signed_integer.cpp
+5
-4
libcaf_core/test/detail/parser/read_string.cpp
libcaf_core/test/detail/parser/read_string.cpp
+4
-4
libcaf_core/test/detail/parser/read_timespan.cpp
libcaf_core/test/detail/parser/read_timespan.cpp
+5
-1
libcaf_core/test/detail/parser/read_unsigned_integer.cpp
libcaf_core/test/detail/parser/read_unsigned_integer.cpp
+4
-3
libcaf_core/test/make_config_value_field.cpp
libcaf_core/test/make_config_value_field.cpp
+260
-0
No files found.
libcaf_core/caf/all.hpp
View file @
11c4eaca
...
@@ -50,6 +50,8 @@
...
@@ -50,6 +50,8 @@
#include "caf/config_option.hpp"
#include "caf/config_option.hpp"
#include "caf/config_option_adder.hpp"
#include "caf/config_option_adder.hpp"
#include "caf/config_value.hpp"
#include "caf/config_value.hpp"
#include "caf/config_value_field.hpp"
#include "caf/config_value_object_access.hpp"
#include "caf/deep_to_string.hpp"
#include "caf/deep_to_string.hpp"
#include "caf/defaults.hpp"
#include "caf/defaults.hpp"
#include "caf/deserializer.hpp"
#include "caf/deserializer.hpp"
...
@@ -69,6 +71,7 @@
...
@@ -69,6 +71,7 @@
#include "caf/local_actor.hpp"
#include "caf/local_actor.hpp"
#include "caf/logger.hpp"
#include "caf/logger.hpp"
#include "caf/make_config_option.hpp"
#include "caf/make_config_option.hpp"
#include "caf/make_config_value_field.hpp"
#include "caf/may_have_timeout.hpp"
#include "caf/may_have_timeout.hpp"
#include "caf/memory_managed.hpp"
#include "caf/memory_managed.hpp"
#include "caf/message.hpp"
#include "caf/message.hpp"
...
...
libcaf_core/caf/config_value.hpp
View file @
11c4eaca
...
@@ -31,6 +31,7 @@
...
@@ -31,6 +31,7 @@
#include "caf/atom.hpp"
#include "caf/atom.hpp"
#include "caf/detail/bounds_checker.hpp"
#include "caf/detail/bounds_checker.hpp"
#include "caf/detail/move_if_not_ptr.hpp"
#include "caf/detail/move_if_not_ptr.hpp"
#include "caf/detail/parse.hpp"
#include "caf/detail/type_traits.hpp"
#include "caf/detail/type_traits.hpp"
#include "caf/dictionary.hpp"
#include "caf/dictionary.hpp"
#include "caf/fwd.hpp"
#include "caf/fwd.hpp"
...
@@ -230,6 +231,14 @@ struct default_config_value_access {
...
@@ -230,6 +231,14 @@ struct default_config_value_access {
static
T
get
(
const
config_value
&
x
)
{
static
T
get
(
const
config_value
&
x
)
{
return
caf
::
get
<
T
>
(
x
.
get_data
());
return
caf
::
get
<
T
>
(
x
.
get_data
());
}
}
static
T
convert
(
T
x
)
{
return
x
;
}
static
void
parse_cli
(
string_parser_state
&
ps
,
T
&
x
)
{
detail
::
parse
(
ps
,
x
);
}
};
};
struct
config_value_access_unspecialized
{};
struct
config_value_access_unspecialized
{};
...
@@ -238,39 +247,59 @@ struct config_value_access_unspecialized {};
...
@@ -238,39 +247,59 @@ struct config_value_access_unspecialized {};
template
<
class
T
>
template
<
class
T
>
struct
config_value_access
:
config_value_access_unspecialized
{};
struct
config_value_access
:
config_value_access_unspecialized
{};
#define CAF_DEFAULT_CONFIG_VALUE_ACCESS(type
)
\
#define CAF_DEFAULT_CONFIG_VALUE_ACCESS(type
, name)
\
template <> \
template <> \
struct config_value_access<type> : default_config_value_access<type> {}
struct config_value_access<type> : default_config_value_access<type> { \
static std::string type_name() { \
return name; \
} \
}
CAF_DEFAULT_CONFIG_VALUE_ACCESS
(
bool
);
CAF_DEFAULT_CONFIG_VALUE_ACCESS
(
bool
,
"boolean"
);
CAF_DEFAULT_CONFIG_VALUE_ACCESS
(
double
);
CAF_DEFAULT_CONFIG_VALUE_ACCESS
(
double
,
"real64"
);
CAF_DEFAULT_CONFIG_VALUE_ACCESS
(
atom_value
);
CAF_DEFAULT_CONFIG_VALUE_ACCESS
(
atom_value
,
"atom"
);
CAF_DEFAULT_CONFIG_VALUE_ACCESS
(
timespan
);
CAF_DEFAULT_CONFIG_VALUE_ACCESS
(
timespan
,
"timespan"
);
CAF_DEFAULT_CONFIG_VALUE_ACCESS
(
std
::
string
);
CAF_DEFAULT_CONFIG_VALUE_ACCESS
(
config_value
::
list
,
"list"
);
CAF_DEFAULT_CONFIG_VALUE_ACCESS
(
config_value
::
list
);
CAF_DEFAULT_CONFIG_VALUE_ACCESS
(
config_value
::
dictionary
,
"dictionary"
);
CAF_DEFAULT_CONFIG_VALUE_ACCESS
(
config_value
::
dictionary
);
#undef CAF_DEFAULT_CONFIG_VALUE_ACCESS
#undef CAF_DEFAULT_CONFIG_VALUE_ACCESS
template
<
>
struct
config_value_access
<
std
::
string
>
:
default_config_value_access
<
std
::
string
>
{
using
super
=
default_config_value_access
<
std
::
string
>
;
static
std
::
string
type_name
()
{
return
"string"
;
}
using
super
::
parse_cli
;
static
void
parse_cli
(
string_parser_state
&
ps
,
std
::
string
&
x
,
const
char
*
char_blacklist
)
{
detail
::
parse_element
(
ps
,
x
,
char_blacklist
);
}
};
enum
class
select_config_value_hint
{
enum
class
select_config_value_hint
{
is_custom
,
is_integral
,
is_integral
,
is_list
,
is_map
,
is_map
,
is_list
,
is_custom
,
is_missing
,
is_missing
,
};
};
template
<
class
T
>
template
<
class
T
>
constexpr
select_config_value_hint
select_config_value_oracle
()
{
constexpr
select_config_value_hint
select_config_value_oracle
()
{
return
!
std
::
is_base_of
<
config_value_access_unspecialized
,
return
std
::
is_integral
<
T
>::
value
&&
!
std
::
is_same
<
T
,
bool
>::
value
config_value_access
<
T
>>::
value
?
select_config_value_hint
::
is_custom
:
(
std
::
is_integral
<
T
>::
value
?
select_config_value_hint
::
is_integral
?
select_config_value_hint
::
is_integral
:
(
detail
::
is_map_like
<
T
>::
value
:
(
detail
::
is_map_like
<
T
>::
value
?
select_config_value_hint
::
is_map
?
select_config_value_hint
::
is_map
:
(
detail
::
is_list_like
<
T
>::
value
:
(
detail
::
is_list_like
<
T
>::
value
?
select_config_value_hint
::
is_list
?
select_config_value_hint
::
is_list
:
(
!
std
::
is_base_of
<
config_value_access_unspecialized
,
config_value_access
<
T
>>::
value
?
select_config_value_hint
::
is_custom
:
select_config_value_hint
::
is_missing
)));
:
select_config_value_hint
::
is_missing
)));
}
}
...
@@ -284,8 +313,8 @@ struct select_config_value_access {
...
@@ -284,8 +313,8 @@ struct select_config_value_access {
};
};
template
<
class
T
>
template
<
class
T
>
using
select_config_value_access_t
=
using
select_config_value_access_t
=
typename
select_config_value_access
<
typename
select_config_value_access
<
T
>::
type
;
T
>::
type
;
template
<
>
template
<
>
struct
sum_type_access
<
config_value
>
{
struct
sum_type_access
<
config_value
>
{
...
@@ -362,13 +391,25 @@ struct sum_type_access<config_value> {
...
@@ -362,13 +391,25 @@ struct sum_type_access<config_value> {
template
<
class
T
>
template
<
class
T
>
struct
select_config_value_access
<
T
,
select_config_value_hint
::
is_integral
>
{
struct
select_config_value_access
<
T
,
select_config_value_hint
::
is_integral
>
{
struct
type
{
struct
type
{
using
integer_type
=
config_value
::
integer
;
static
std
::
string
type_name
()
{
std
::
string
result
;
if
(
std
::
is_signed
<
T
>::
value
)
result
=
"int"
;
else
result
=
"uint"
;
result
+=
std
::
to_string
(
sizeof
(
T
)
*
8
);
return
result
;
}
static
bool
is
(
const
config_value
&
x
)
{
static
bool
is
(
const
config_value
&
x
)
{
auto
ptr
=
caf
::
get_if
<
typename
config_value
::
integer
>
(
x
.
get_data_ptr
());
auto
ptr
=
caf
::
get_if
<
integer_type
>
(
x
.
get_data_ptr
());
return
ptr
!=
nullptr
&&
detail
::
bounds_checker
<
T
>::
check
(
*
ptr
);
return
ptr
!=
nullptr
&&
detail
::
bounds_checker
<
T
>::
check
(
*
ptr
);
}
}
static
optional
<
T
>
get_if
(
const
config_value
*
x
)
{
static
optional
<
T
>
get_if
(
const
config_value
*
x
)
{
auto
ptr
=
caf
::
get_if
<
typename
config_value
::
integer
>
(
x
->
get_data_ptr
());
auto
ptr
=
caf
::
get_if
<
integer_type
>
(
x
->
get_data_ptr
());
if
(
ptr
!=
nullptr
&&
detail
::
bounds_checker
<
T
>::
check
(
*
ptr
))
if
(
ptr
!=
nullptr
&&
detail
::
bounds_checker
<
T
>::
check
(
*
ptr
))
return
static_cast
<
T
>
(
*
ptr
);
return
static_cast
<
T
>
(
*
ptr
);
return
none
;
return
none
;
...
@@ -379,6 +420,14 @@ struct select_config_value_access<T, select_config_value_hint::is_integral> {
...
@@ -379,6 +420,14 @@ struct select_config_value_access<T, select_config_value_hint::is_integral> {
CAF_ASSERT
(
res
!=
none
);
CAF_ASSERT
(
res
!=
none
);
return
*
res
;
return
*
res
;
}
}
static
T
convert
(
T
x
)
{
return
x
;
}
static
void
parse_cli
(
string_parser_state
&
ps
,
T
&
x
)
{
detail
::
parse
(
ps
,
x
);
}
};
};
};
};
...
@@ -390,13 +439,19 @@ struct select_config_value_access<T, select_config_value_hint::is_list> {
...
@@ -390,13 +439,19 @@ struct select_config_value_access<T, select_config_value_hint::is_list> {
using
value_type
=
typename
list_type
::
value_type
;
using
value_type
=
typename
list_type
::
value_type
;
using
value_trait
=
select_config_value_access_t
<
value_type
>
;
static
std
::
string
type_name
()
{
return
"list of "
+
value_trait
::
type_name
();
}
static
bool
is
(
const
config_value
&
x
)
{
static
bool
is
(
const
config_value
&
x
)
{
auto
lst
=
caf
::
get_if
<
config_value
::
list
>
(
&
x
);
auto
lst
=
caf
::
get_if
<
config_value
::
list
>
(
&
x
);
if
(
lst
!=
nullptr
)
{
return
lst
!=
nullptr
return
std
::
all_of
(
lst
->
begin
(),
lst
->
end
(),
[](
const
config_value
&
y
)
{
&&
std
::
all_of
(
lst
->
begin
(),
lst
->
end
(),
[](
const
config_value
&
y
)
{
return
caf
::
holds_alternative
<
value_type
>
(
y
);
return
caf
::
holds_alternative
<
value_type
>
(
y
);
});
});
}
return
false
;
return
false
;
}
}
...
@@ -404,8 +459,7 @@ struct select_config_value_access<T, select_config_value_hint::is_list> {
...
@@ -404,8 +459,7 @@ struct select_config_value_access<T, select_config_value_hint::is_list> {
list_type
result
;
list_type
result
;
auto
out
=
std
::
inserter
(
result
,
result
.
end
());
auto
out
=
std
::
inserter
(
result
,
result
.
end
());
auto
extract
=
[
&
](
const
config_value
&
y
)
{
auto
extract
=
[
&
](
const
config_value
&
y
)
{
auto
opt
=
caf
::
get_if
<
value_type
>
(
&
y
);
if
(
auto
opt
=
caf
::
get_if
<
value_type
>
(
&
y
))
{
if
(
opt
)
{
*
out
++
=
move_if_optional
(
opt
);
*
out
++
=
move_if_optional
(
opt
);
return
true
;
return
true
;
}
}
...
@@ -423,10 +477,38 @@ struct select_config_value_access<T, select_config_value_hint::is_list> {
...
@@ -423,10 +477,38 @@ struct select_config_value_access<T, select_config_value_hint::is_list> {
CAF_RAISE_ERROR
(
"invalid type found"
);
CAF_RAISE_ERROR
(
"invalid type found"
);
return
std
::
move
(
*
result
);
return
std
::
move
(
*
result
);
}
}
static
config_value
::
list
convert
(
const
list_type
&
xs
)
{
config_value
::
list
result
;
for
(
const
auto
&
x
:
xs
)
result
.
emplace_back
(
value_trait
::
convert
(
x
));
return
result
;
}
static
void
parse_cli
(
string_parser_state
&
ps
,
T
&
xs
)
{
config_value
::
dictionary
result
;
bool
has_open_token
=
ps
.
consume
(
'['
);
do
{
if
(
has_open_token
&&
ps
.
consume
(
']'
))
{
ps
.
skip_whitespaces
();
ps
.
code
=
ps
.
at_end
()
?
pec
::
success
:
pec
::
trailing_character
;
return
;
}
value_type
tmp
;
value_trait
::
parse_cli
(
ps
,
tmp
);
if
(
ps
.
code
>
pec
::
trailing_character
)
return
;
xs
.
insert
(
xs
.
end
(),
std
::
move
(
tmp
));
}
while
(
ps
.
consume
(
','
));
if
(
has_open_token
&&
!
ps
.
consume
(
']'
))
ps
.
code
=
ps
.
at_end
()
?
pec
::
unexpected_eof
:
pec
::
unexpected_character
;
ps
.
skip_whitespaces
();
ps
.
code
=
ps
.
at_end
()
?
pec
::
success
:
pec
::
trailing_character
;
}
};
};
};
};
/// Catches all non-specialized
list
types.
/// Catches all non-specialized
map
types.
template
<
class
T
>
template
<
class
T
>
struct
select_config_value_access
<
T
,
select_config_value_hint
::
is_map
>
{
struct
select_config_value_access
<
T
,
select_config_value_hint
::
is_map
>
{
struct
type
{
struct
type
{
...
@@ -434,14 +516,22 @@ struct select_config_value_access<T, select_config_value_hint::is_map> {
...
@@ -434,14 +516,22 @@ struct select_config_value_access<T, select_config_value_hint::is_map> {
using
mapped_type
=
typename
map_type
::
mapped_type
;
using
mapped_type
=
typename
map_type
::
mapped_type
;
using
mapped_trait
=
select_config_value_access_t
<
mapped_type
>
;
static
std
::
string
type_name
()
{
std
::
string
result
=
"dictionary of "
;
auto
nested_name
=
mapped_trait
::
type_name
();
result
.
insert
(
result
.
end
(),
nested_name
.
begin
(),
nested_name
.
end
());
return
result
;
}
static
bool
is
(
const
config_value
&
x
)
{
static
bool
is
(
const
config_value
&
x
)
{
using
value_type
=
config_value
::
dictionary
::
value_type
;
using
value_type
=
config_value
::
dictionary
::
value_type
;
auto
dict
=
caf
::
get_if
<
config_value
::
dictionary
>
(
&
x
);
auto
is_mapped_type
=
[](
const
value_type
&
y
)
{
if
(
dict
!=
nullptr
)
{
return
std
::
all_of
(
dict
->
begin
(),
dict
->
end
(),
[](
const
value_type
&
y
)
{
return
caf
::
holds_alternative
<
mapped_type
>
(
y
.
second
);
return
caf
::
holds_alternative
<
mapped_type
>
(
y
.
second
);
});
};
}
if
(
auto
dict
=
caf
::
get_if
<
config_value
::
dictionary
>
(
&
x
))
return
std
::
all_of
(
dict
->
begin
(),
dict
->
end
(),
is_mapped_type
);
return
false
;
return
false
;
}
}
...
@@ -450,13 +540,13 @@ struct select_config_value_access<T, select_config_value_hint::is_map> {
...
@@ -450,13 +540,13 @@ struct select_config_value_access<T, select_config_value_hint::is_map> {
map_type
result
;
map_type
result
;
auto
extract
=
[
&
](
const
value_type
&
y
)
{
auto
extract
=
[
&
](
const
value_type
&
y
)
{
if
(
auto
opt
=
caf
::
get_if
<
mapped_type
>
(
&
y
.
second
))
{
if
(
auto
opt
=
caf
::
get_if
<
mapped_type
>
(
&
y
.
second
))
{
result
.
emplace
(
y
.
first
,
*
opt
);
result
.
emplace
(
y
.
first
,
move_if_optional
(
opt
)
);
return
true
;
return
true
;
}
}
return
false
;
return
false
;
};
};
auto
dict
=
caf
::
get_if
<
config_value
::
dictionary
>
(
x
);
if
(
auto
dict
=
caf
::
get_if
<
config_value
::
dictionary
>
(
x
))
if
(
dict
!=
nullptr
&&
std
::
all_of
(
dict
->
begin
(),
dict
->
end
(),
extract
))
if
(
std
::
all_of
(
dict
->
begin
(),
dict
->
end
(),
extract
))
return
result
;
return
result
;
return
none
;
return
none
;
}
}
...
@@ -467,25 +557,47 @@ struct select_config_value_access<T, select_config_value_hint::is_map> {
...
@@ -467,25 +557,47 @@ struct select_config_value_access<T, select_config_value_hint::is_map> {
CAF_RAISE_ERROR
(
"invalid type found"
);
CAF_RAISE_ERROR
(
"invalid type found"
);
return
std
::
move
(
*
result
);
return
std
::
move
(
*
result
);
}
}
static
void
parse_cli
(
string_parser_state
&
ps
,
map_type
&
xs
)
{
detail
::
parse
(
ps
,
xs
);
}
static
config_value
::
dictionary
convert
(
const
map_type
&
xs
)
{
config_value
::
dictionary
result
;
for
(
const
auto
&
x
:
xs
)
result
.
emplace
(
x
.
first
,
mapped_trait
::
convert
(
x
.
second
));
return
result
;
}
};
};
};
};
template
<
>
template
<
>
struct
config_value_access
<
float
>
{
struct
config_value_access
<
float
>
{
static
bool
is
(
const
config_value
&
x
)
{
static
inline
std
::
string
type_name
()
{
return
"real32"
;
}
static
inline
bool
is
(
const
config_value
&
x
)
{
return
holds_alternative
<
double
>
(
x
.
get_data
());
return
holds_alternative
<
double
>
(
x
.
get_data
());
}
}
static
optional
<
float
>
get_if
(
const
config_value
*
x
)
{
static
inline
optional
<
float
>
get_if
(
const
config_value
*
x
)
{
auto
res
=
caf
::
get_if
<
double
>
(
&
(
x
->
get_data
()));
if
(
auto
res
=
caf
::
get_if
<
double
>
(
&
(
x
->
get_data
())))
if
(
res
)
return
static_cast
<
float
>
(
*
res
);
return
static_cast
<
float
>
(
*
res
);
return
none
;
return
none
;
}
}
static
float
get
(
const
config_value
&
x
)
{
static
inline
float
get
(
const
config_value
&
x
)
{
return
static_cast
<
float
>
(
caf
::
get
<
double
>
(
x
.
get_data
()));
return
static_cast
<
float
>
(
caf
::
get
<
double
>
(
x
.
get_data
()));
}
}
static
inline
double
convert
(
float
x
)
{
return
x
;
}
static
inline
void
parse_cli
(
string_parser_state
&
ps
,
float
&
x
)
{
detail
::
parse
(
ps
,
x
);
}
};
};
/// Implements automagic unboxing of `std::tuple<Ts...>` from a heterogeneous
/// Implements automagic unboxing of `std::tuple<Ts...>` from a heterogeneous
...
@@ -495,6 +607,13 @@ template <class... Ts>
...
@@ -495,6 +607,13 @@ template <class... Ts>
struct
config_value_access
<
std
::
tuple
<
Ts
...
>>
{
struct
config_value_access
<
std
::
tuple
<
Ts
...
>>
{
using
tuple_type
=
std
::
tuple
<
Ts
...
>
;
using
tuple_type
=
std
::
tuple
<
Ts
...
>
;
static
std
::
string
type_name
()
{
auto
result
=
"tuple["
;
rec_name
(
result
,
true
,
detail
::
int_token
<
0
>
(),
detail
::
type_list
<
Ts
...
>
());
result
+=
']'
;
return
result
;
}
static
bool
is
(
const
config_value
&
x
)
{
static
bool
is
(
const
config_value
&
x
)
{
if
(
auto
lst
=
caf
::
get_if
<
config_value
::
list
>
(
&
x
))
{
if
(
auto
lst
=
caf
::
get_if
<
config_value
::
list
>
(
&
x
))
{
if
(
lst
->
size
()
!=
sizeof
...(
Ts
))
if
(
lst
->
size
()
!=
sizeof
...(
Ts
))
...
@@ -522,11 +641,38 @@ struct config_value_access<std::tuple<Ts...>> {
...
@@ -522,11 +641,38 @@ struct config_value_access<std::tuple<Ts...>> {
CAF_RAISE_ERROR
(
"invalid type found"
);
CAF_RAISE_ERROR
(
"invalid type found"
);
}
}
static
config_value
::
list
convert
(
const
tuple_type
&
xs
)
{
config_value
::
list
result
;
rec_convert
(
result
,
xs
,
detail
::
int_token
<
0
>
(),
detail
::
type_list
<
Ts
...
>
());
return
result
;
}
static
void
parse_cli
(
string_parser_state
&
ps
,
tuple_type
&
xs
)
{
rec_parse
(
ps
,
xs
,
detail
::
int_token
<
0
>
(),
detail
::
type_list
<
Ts
...
>
());
}
private:
private:
template
<
int
Pos
>
static
void
rec_name
(
std
::
string
&
,
bool
,
detail
::
int_token
<
Pos
>
,
detail
::
type_list
<>
)
{
// nop
}
template
<
int
Pos
,
class
U
,
class
...
Us
>
static
void
rec_name
(
std
::
string
&
result
,
bool
is_first
,
detail
::
int_token
<
Pos
>
,
detail
::
type_list
<
U
,
Us
...
>
)
{
if
(
!
is_first
)
result
+=
", "
;
using
nested
=
config_value_access
<
U
>
;
auto
nested_name
=
nested
::
type_name
();
result
.
insert
(
result
.
end
(),
nested_name
.
begin
(),
nested_name
.
end
());
return
rec_name
(
result
,
false
,
detail
::
int_token
<
Pos
+
1
>
(),
detail
::
type_list
<
Us
...
>
());
}
template
<
int
Pos
>
template
<
int
Pos
>
static
bool
rec_is
(
const
config_value
::
list
&
,
detail
::
int_token
<
Pos
>
,
static
bool
rec_is
(
const
config_value
::
list
&
,
detail
::
int_token
<
Pos
>
,
detail
::
type_list
<>
)
{
detail
::
type_list
<>
)
{
// End of recursion.
return
true
;
return
true
;
}
}
...
@@ -541,7 +687,6 @@ private:
...
@@ -541,7 +687,6 @@ private:
template
<
int
Pos
>
template
<
int
Pos
>
static
bool
rec_get
(
const
config_value
::
list
&
,
tuple_type
&
,
static
bool
rec_get
(
const
config_value
::
list
&
,
tuple_type
&
,
detail
::
int_token
<
Pos
>
,
detail
::
type_list
<>
)
{
detail
::
int_token
<
Pos
>
,
detail
::
type_list
<>
)
{
// End of recursion.
return
true
;
return
true
;
}
}
...
@@ -555,48 +700,38 @@ private:
...
@@ -555,48 +700,38 @@ private:
}
}
return
false
;
return
false
;
}
}
};
/// Implements automagic unboxing of `dictionary<V>` from a homogeneous
/// `config_value::dictionary`.
/// @relates config_value
template
<
class
V
>
struct
config_value_access
<
dictionary
<
V
>>
{
using
map_type
=
dictionary
<
V
>
;
using
kvp
=
std
::
pair
<
const
std
::
string
,
config_value
>
;
static
bool
is
(
const
config_value
&
x
)
{
template
<
int
Pos
>
auto
lst
=
caf
::
get_if
<
config_value
::
dictionary
>
(
&
x
);
static
void
rec_convert
(
config_value
::
list
&
,
const
tuple_type
&
,
if
(
lst
!=
nullptr
)
{
detail
::
int_token
<
Pos
>
,
detail
::
type_list
<>
)
{
return
std
::
all_of
(
lst
->
begin
(),
lst
->
end
(),
[](
const
kvp
&
y
)
{
// nop
return
holds_alternative
<
V
>
(
y
.
second
);
});
}
return
false
;
}
}
static
optional
<
map_type
>
get_if
(
const
config_value
*
x
)
{
template
<
int
Pos
,
class
U
,
class
...
Us
>
map_type
result
;
static
void
rec_convert
(
config_value
::
list
&
result
,
const
tuple_type
&
xs
,
auto
extract
=
[
&
](
const
kvp
&
y
)
{
detail
::
int_token
<
Pos
>
,
detail
::
type_list
<
U
,
Us
...
>
)
{
auto
opt
=
caf
::
get_if
<
V
>
(
&
(
y
.
second
))
;
using
trait
=
select_config_value_access_t
<
U
>
;
if
(
opt
)
{
result
.
emplace_back
(
trait
::
convert
(
std
::
get
<
Pos
>
(
xs
)));
result
.
emplace
(
y
.
first
,
std
::
move
(
*
opt
));
return
rec_convert
(
result
,
xs
,
detail
::
int_token
<
Pos
+
1
>
(),
return
true
;
detail
::
type_list
<
Us
...
>
())
;
}
}
return
false
;
};
template
<
int
Pos
>
auto
lst
=
caf
::
get_if
<
config_value
::
dictionary
>
(
x
);
static
void
rec_parse
(
string_parser_state
&
,
tuple_type
&
,
if
(
lst
!=
nullptr
&&
std
::
all_of
(
lst
->
begin
(),
lst
->
end
(),
extract
))
detail
::
int_token
<
Pos
>
,
detail
::
type_list
<>
)
{
return
result
;
// nop
return
none
;
}
}
static
map_type
get
(
const
config_value
&
x
)
{
template
<
int
Pos
,
class
U
,
class
...
Us
>
auto
result
=
get_if
(
&
x
);
static
void
rec_parse
(
string_parser_state
&
ps
,
tuple_type
&
xs
,
if
(
!
result
)
detail
::
int_token
<
Pos
>
,
detail
::
type_list
<
U
,
Us
...
>
)
{
CAF_RAISE_ERROR
(
"invalid type found"
);
using
trait
=
select_config_value_access_t
<
U
>
;
return
std
::
move
(
*
result
);
trait
::
parse_cli
(
std
::
get
<
Pos
>
(
xs
));
if
(
ps
.
code
>
pec
::
trailing_character
)
return
;
if
(
sizeof
...(
Us
)
>
0
&&
!
ps
.
consume
(
','
))
ps
.
code
=
ps
.
at_end
()
?
pec
::
unexpected_eof
:
pec
::
unexpected_character
;
rec_parse
(
ps
,
xs
,
detail
::
int_token
<
Pos
+
1
>
(),
detail
::
type_list
<
Us
...
>
());
}
}
};
};
...
...
libcaf_core/caf/config_value_field.hpp
0 → 100644
View file @
11c4eaca
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| 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 "caf/fwd.hpp"
#include "caf/parser_state.hpp"
namespace
caf
{
/// Describes a field of `Object`.
template
<
class
Object
>
class
config_value_field
{
public:
using
object_type
=
Object
;
virtual
~
config_value_field
()
=
default
;
// -- observers --------------------------------------------------------------
/// Checks whether `x` matches the type of this field.
virtual
bool
type_check
(
const
config_value
&
x
)
const
noexcept
=
0
;
/// Returns whether this field in `object` contains valid data.
virtual
bool
valid
(
const
Object
&
object
)
const
noexcept
=
0
;
/// Returns whether this field has a default value.
virtual
bool
has_default
()
const
noexcept
=
0
;
/// Returns the name of this field.
virtual
string_view
name
()
const
noexcept
=
0
;
/// Returns the value of this field in `object` as config value.
virtual
config_value
get
(
const
Object
&
object
)
const
=
0
;
// -- modifiers --------------------------------------------------------------
/// Sets this field in `object` to `x`.
/// @pre `can_set(x)`
virtual
void
set
(
Object
&
object
,
const
config_value
&
x
)
const
=
0
;
/// Restores the default value for this field in `object`.
/// @pre `has_default()`
virtual
void
set_default
(
Object
&
object
)
const
=
0
;
/// Parses the content for this field in `object` from `ps`.
virtual
void
parse_cli
(
string_parser_state
&
ps
,
Object
&
object
,
const
char
*
char_blacklist
=
""
)
const
=
0
;
};
}
// namespace caf
libcaf_core/caf/config_value_object_access.hpp
0 → 100644
View file @
11c4eaca
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| 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 "caf/config_value.hpp"
#include "caf/config_value_field.hpp"
namespace
caf
{
/// Enables user-defined types in config files and on the CLI by converting
/// them to and from `config_value::dictionary`.
///
/// ~~
/// struct trait {
/// using object_type = ...;
///
/// static string_value type_name();
///
/// static span<config_value_field<object_type>*> fields();
/// };
/// ~~
template
<
class
Trait
>
struct
config_value_object_access
{
using
object_type
=
typename
Trait
::
object_type
;
static
std
::
string
type_name
()
{
return
Trait
::
type_name
();
}
static
bool
extract
(
const
config_value
*
src
,
object_type
*
dst
)
{
auto
dict
=
caf
::
get_if
<
config_value
::
dictionary
>
(
src
);
if
(
!
dict
)
return
false
;
for
(
auto
field
:
Trait
::
fields
())
{
auto
value
=
caf
::
get_if
(
dict
,
field
->
name
());
if
(
!
value
)
{
if
(
!
field
->
has_default
())
return
false
;
if
(
dst
)
field
->
set_default
(
*
dst
);
}
else
if
(
field
->
type_check
(
*
value
))
{
if
(
dst
)
field
->
set
(
*
dst
,
*
value
);
}
else
{
return
false
;
}
}
return
true
;
}
static
bool
is
(
const
config_value
&
x
)
{
return
extract
(
&
x
,
nullptr
);
}
static
optional
<
object_type
>
get_if
(
const
config_value
*
x
)
{
object_type
result
;
if
(
extract
(
x
,
&
result
))
return
result
;
return
none
;
}
static
object_type
get
(
const
config_value
&
x
)
{
auto
result
=
get_if
(
&
x
);
if
(
!
result
)
CAF_RAISE_ERROR
(
"config_value does not contain requested object"
);
return
std
::
move
(
*
result
);
}
static
config_value
::
dictionary
convert
(
const
object_type
&
x
)
{
config_value
::
dictionary
result
;
for
(
auto
field
:
Trait
::
fields
())
result
.
emplace
(
field
->
name
(),
field
->
get
(
x
));
return
result
;
}
static
void
parse_cli
(
string_parser_state
&
ps
,
object_type
&
x
)
{
using
field_type
=
config_value_field
<
object_type
>
;
std
::
vector
<
field_type
*>
parsed_fields
;
auto
got
=
[
&
](
field_type
*
f
)
{
auto
e
=
parsed_fields
.
end
();
return
std
::
find
(
parsed_fields
.
begin
(),
e
,
f
)
!=
e
;
};
auto
push
=
[
&
](
field_type
*
f
)
{
if
(
got
(
f
))
return
false
;
parsed_fields
.
emplace_back
(
f
);
return
true
;
};
auto
finalize
=
[
&
]
{
for
(
auto
field
:
Trait
::
fields
())
{
if
(
!
got
(
field
))
{
if
(
field
->
has_default
())
{
field
->
set_default
(
x
);
}
else
{
ps
.
code
=
pec
::
missing_field
;
return
;
}
}
}
ps
.
skip_whitespaces
();
ps
.
code
=
ps
.
at_end
()
?
pec
::
success
:
pec
::
trailing_character
;
};
auto
fs
=
Trait
::
fields
();
if
(
!
ps
.
consume
(
'{'
))
{
ps
.
code
=
pec
::
unexpected_character
;
return
;
}
using
string_access
=
select_config_value_access_t
<
std
::
string
>
;
config_value
::
dictionary
result
;
do
{
if
(
ps
.
consume
(
'}'
))
{
finalize
();
return
;
}
std
::
string
field_name
;
string_access
::
parse_cli
(
ps
,
field_name
,
"=}"
);
if
(
ps
.
code
>
pec
::
trailing_character
)
return
;
if
(
!
ps
.
consume
(
'='
))
{
ps
.
code
=
ps
.
at_end
()
?
pec
::
unexpected_eof
:
pec
::
unexpected_character
;
return
;
}
auto
predicate
=
[
&
](
config_value_field
<
object_type
>*
x
)
{
return
x
->
name
()
==
field_name
;
};
auto
f
=
std
::
find_if
(
fs
.
begin
(),
fs
.
end
(),
predicate
);
if
(
f
==
fs
.
end
())
{
ps
.
code
=
pec
::
invalid_field_name
;
return
;
}
auto
fptr
=
*
f
;
if
(
!
push
(
fptr
))
{
ps
.
code
=
pec
::
repeated_field_name
;
return
;
}
fptr
->
parse_cli
(
ps
,
x
,
",}"
);
if
(
ps
.
code
>
pec
::
trailing_character
)
return
;
if
(
ps
.
at_end
())
{
ps
.
code
=
pec
::
unexpected_eof
;
return
;
}
if
(
!
fptr
->
valid
(
x
))
{
ps
.
code
=
pec
::
illegal_argument
;
return
;
}
result
[
fptr
->
name
()]
=
fptr
->
get
(
x
);
}
while
(
ps
.
consume
(
','
));
if
(
!
ps
.
consume
(
'}'
))
{
ps
.
code
=
ps
.
at_end
()
?
pec
::
unexpected_eof
:
pec
::
unexpected_character
;
return
;
}
finalize
();
}
};
}
// namespace caf
libcaf_core/caf/detail/config_value_field_impl.hpp
0 → 100644
View file @
11c4eaca
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| 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 <string>
#include <utility>
#include "caf/config_value.hpp"
#include "caf/config_value_field.hpp"
#include "caf/detail/dispatch_parse_cli.hpp"
#include "caf/detail/parse.hpp"
#include "caf/detail/type_traits.hpp"
#include "caf/optional.hpp"
#include "caf/string_view.hpp"
namespace
caf
{
namespace
detail
{
template
<
class
MemberObjectPointer
>
class
config_value_field_impl
;
// A config value with direct access to a field via member object pointer.
template
<
class
Value
,
class
Object
>
class
config_value_field_impl
<
Value
Object
::*>
:
public
config_value_field
<
Object
>
{
public:
using
member_pointer
=
Value
Object
::*
;
using
object_type
=
Object
;
using
value_type
=
Value
;
using
predicate_pointer
=
bool
(
*
)(
const
value_type
&
);
constexpr
config_value_field_impl
(
string_view
name
,
member_pointer
ptr
,
optional
<
value_type
>
default_value
=
none
,
predicate_pointer
predicate
=
nullptr
)
:
name_
(
name
),
ptr_
(
ptr
),
default_value_
(
std
::
move
(
default_value
)),
predicate_
(
predicate
)
{
// nop
}
constexpr
config_value_field_impl
(
config_value_field_impl
&&
)
=
default
;
bool
type_check
(
const
config_value
&
x
)
const
noexcept
override
{
return
holds_alternative
<
value_type
>
(
x
);
}
bool
valid
(
const
object_type
&
x
)
const
noexcept
override
{
return
predicate_
?
predicate_
(
x
.
*
ptr_
)
:
true
;
}
void
set
(
object_type
&
x
,
const
config_value
&
y
)
const
override
{
x
.
*
ptr_
=
caf
::
get
<
value_type
>
(
y
);
}
config_value
get
(
const
object_type
&
x
)
const
override
{
using
access
=
select_config_value_access_t
<
value_type
>
;
return
config_value
{
access
::
convert
(
x
.
*
ptr_
)};
}
void
parse_cli
(
string_parser_state
&
ps
,
object_type
&
x
,
const
char
*
char_blacklist
)
const
override
{
detail
::
dispatch_parse_cli
(
ps
,
x
.
*
ptr_
,
char_blacklist
);
}
string_view
name
()
const
noexcept
override
{
return
name_
;
}
bool
has_default
()
const
noexcept
override
{
return
static_cast
<
bool
>
(
default_value_
);
}
void
set_default
(
object_type
&
x
)
const
override
{
x
.
*
ptr_
=
*
default_value_
;
}
private:
string_view
name_
;
member_pointer
ptr_
;
optional
<
value_type
>
default_value_
;
predicate_pointer
predicate_
;
};
template
<
class
Get
>
struct
config_value_field_base
{
using
trait
=
get_callable_trait_t
<
Get
>
;
static_assert
(
trait
::
num_args
==
1
,
"Get must take exactly one argument (the object)"
);
using
arg_type
=
tl_head_t
<
typename
trait
::
arg_types
>
;
using
value_type
=
decay_t
<
typename
trait
::
result_type
>
;
using
type
=
config_value_field
<
decay_t
<
arg_type
>>
;
};
template
<
class
Get
>
using
config_value_field_base_t
=
typename
config_value_field_base
<
Get
>::
type
;
// A config value with access to a field via getter and setter.
template
<
class
Get
,
class
Set
>
class
config_value_field_impl
<
std
::
pair
<
Get
,
Set
>>
:
public
config_value_field_base_t
<
Get
>
{
public:
using
super
=
config_value_field_base_t
<
Get
>
;
using
object_type
=
typename
super
::
object_type
;
using
get_trait
=
get_callable_trait_t
<
Get
>
;
using
value_type
=
decay_t
<
typename
get_trait
::
result_type
>
;
using
predicate_pointer
=
bool
(
*
)(
const
value_type
&
);
constexpr
config_value_field_impl
(
string_view
name
,
Get
getter
,
Set
setter
,
optional
<
value_type
>
default_value
=
none
,
predicate_pointer
predicate
=
nullptr
)
:
name_
(
name
),
get_
(
std
::
move
(
getter
)),
set_
(
std
::
move
(
setter
)),
default_value_
(
std
::
move
(
default_value
)),
predicate_
(
predicate
)
{
// nop
}
constexpr
config_value_field_impl
(
config_value_field_impl
&&
)
=
default
;
bool
type_check
(
const
config_value
&
x
)
const
noexcept
override
{
return
holds_alternative
<
value_type
>
(
x
);
}
void
set
(
object_type
&
x
,
const
config_value
&
y
)
const
override
{
set_
(
x
,
caf
::
get
<
value_type
>
(
y
));
}
config_value
get
(
const
object_type
&
x
)
const
override
{
using
access
=
select_config_value_access_t
<
value_type
>
;
return
config_value
{
access
::
convert
(
get_
(
x
))};
}
bool
valid
(
const
object_type
&
x
)
const
noexcept
override
{
return
predicate_
?
predicate_
(
get_
(
x
))
:
true
;
}
void
parse_cli
(
string_parser_state
&
ps
,
object_type
&
x
,
const
char
*
char_blacklist
)
const
override
{
value_type
tmp
;
detail
::
dispatch_parse_cli
(
ps
,
tmp
,
char_blacklist
);
if
(
ps
.
code
<=
pec
::
trailing_character
)
set_
(
x
,
std
::
move
(
tmp
));
}
string_view
name
()
const
noexcept
override
{
return
name_
;
}
bool
has_default
()
const
noexcept
override
{
return
static_cast
<
bool
>
(
default_value_
);
}
void
set_default
(
object_type
&
x
)
const
override
{
set_
(
x
,
*
default_value_
);
}
private:
string_view
name_
;
Get
get_
;
Set
set_
;
optional
<
value_type
>
default_value_
;
predicate_pointer
predicate_
;
};
}
// namespace detail
}
// namespace caf
libcaf_core/caf/detail/
type_name
.hpp
→
libcaf_core/caf/detail/
dispatch_parse_cli
.hpp
View file @
11c4eaca
...
@@ -5,7 +5,7 @@
...
@@ -5,7 +5,7 @@
* | |___ / ___ \| _| Framework *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* \____/_/ \_|_| *
* *
* *
* Copyright 2011-201
8
Dominik Charousset *
* Copyright 2011-201
9
Dominik Charousset *
* *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* 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 *
* (at your option) under the terms and conditions of the Boost Software *
...
@@ -18,116 +18,44 @@
...
@@ -18,116 +18,44 @@
#pragma once
#pragma once
#include <string>
#include <type_traits>
#include <type_traits>
#include <vector>
#include "caf/dictionary.hpp"
#include "caf/config_value.hpp"
#include "caf/fwd.hpp"
#include "caf/detail/type_traits.hpp"
#include "caf/timestamp.hpp"
namespace
caf
{
namespace
caf
{
namespace
detail
{
namespace
detail
{
template
<
size_t
Bytes
>
template
<
class
Trait
>
struct
type_name_builder_int_size
;
struct
dispatch_parse_cli_helper
{
template
<
class
...
Ts
>
template
<
>
auto
operator
()(
Ts
&&
...
xs
)
struct
type_name_builder_int_size
<
1
>
{
->
decltype
(
Trait
::
parse_cli
(
std
::
forward
<
Ts
>
(
xs
)...))
{
void
operator
()(
std
::
string
&
result
)
const
{
return
Trait
::
parse_cli
(
std
::
forward
<
Ts
>
(
xs
)...);
result
+=
"8"
;
}
};
template
<
>
struct
type_name_builder_int_size
<
2
>
{
void
operator
()(
std
::
string
&
result
)
const
{
result
+=
"16"
;
}
};
template
<
>
struct
type_name_builder_int_size
<
4
>
{
void
operator
()(
std
::
string
&
result
)
const
{
result
+=
"32"
;
}
};
template
<
>
struct
type_name_builder_int_size
<
8
>
{
void
operator
()(
std
::
string
&
result
)
const
{
result
+=
"64"
;
}
};
template
<
class
T
,
bool
IsInteger
=
std
::
is_integral
<
T
>
::
value
>
struct
type_name_builder
;
template
<
>
struct
type_name_builder
<
bool
,
true
>
{
void
operator
()(
std
::
string
&
result
)
const
{
result
+=
"boolean"
;
}
}
};
};
#define CAF_TYPE_NAME_BUILDER_NOINT(class_name, pretty_name) \
template
<
class
Access
,
class
T
>
template <> \
void
dispatch_parse_cli
(
std
::
true_type
,
string_parser_state
&
ps
,
T
&
x
,
struct type_name_builder<class_name, false> { \
const
char
*
char_blacklist
)
{
void operator()(std::string& result) const { \
Access
::
parse_cli
(
ps
,
x
,
char_blacklist
);
result += pretty_name; \
}
} \
}
CAF_TYPE_NAME_BUILDER_NOINT
(
float
,
"32-bit real"
);
CAF_TYPE_NAME_BUILDER_NOINT
(
double
,
"64-bit real"
);
CAF_TYPE_NAME_BUILDER_NOINT
(
timespan
,
"timespan"
);
CAF_TYPE_NAME_BUILDER_NOINT
(
std
::
string
,
"string"
);
CAF_TYPE_NAME_BUILDER_NOINT
(
atom_value
,
"atom"
);
CAF_TYPE_NAME_BUILDER_NOINT
(
uri
,
"uri"
);
#undef CAF_TYPE_NAME_BUILDER
template
<
class
T
>
struct
type_name_builder
<
T
,
true
>
{
void
operator
()(
std
::
string
&
result
)
const
{
// TODO: replace with if constexpr when switching to C++17
if
(
!
std
::
is_signed
<
T
>::
value
)
result
+=
'u'
;
result
+=
"int"
;
type_name_builder_int_size
<
sizeof
(
T
)
>
g
;
g
(
result
);
}
};
template
<
class
T
>
struct
type_name_builder
<
std
::
vector
<
T
>
,
false
>
{
void
operator
()(
std
::
string
&
result
)
const
{
result
+=
"list of "
;
type_name_builder
<
T
>
g
;
g
(
result
);
}
};
template
<
class
T
>
template
<
class
Access
,
class
T
>
struct
type_name_builder
<
dictionary
<
T
>
,
false
>
{
void
dispatch_parse_cli
(
std
::
false_type
,
string_parser_state
&
ps
,
T
&
x
,
void
operator
()(
std
::
string
&
result
)
const
{
const
char
*
)
{
result
+=
"dictionary of "
;
Access
::
parse_cli
(
ps
,
x
);
type_name_builder
<
T
>
g
;
}
g
(
result
);
}
};
template
<
class
T
>
template
<
class
T
>
std
::
string
type_name
()
{
void
dispatch_parse_cli
(
string_parser_state
&
ps
,
T
&
x
,
std
::
string
result
;
const
char
*
char_blacklist
)
{
type_name_builder
<
T
>
f
;
using
access
=
caf
::
select_config_value_access_t
<
T
>
;
f
(
result
);
using
helper_fun
=
dispatch_parse_cli_helper
<
access
>
;
return
result
;
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 detail
}
// namespace detail
...
...
libcaf_core/caf/detail/parse.hpp
View file @
11c4eaca
...
@@ -25,94 +25,94 @@
...
@@ -25,94 +25,94 @@
#include <utility>
#include <utility>
#include <vector>
#include <vector>
#include "caf/detail/parser/state.hpp"
#include "caf/detail/squashed_int.hpp"
#include "caf/detail/squashed_int.hpp"
#include "caf/detail/type_traits.hpp"
#include "caf/detail/type_traits.hpp"
#include "caf/error.hpp"
#include "caf/error.hpp"
#include "caf/fwd.hpp"
#include "caf/fwd.hpp"
#include "caf/none.hpp"
#include "caf/none.hpp"
#include "caf/parser_state.hpp"
#include "caf/string_view.hpp"
#include "caf/string_view.hpp"
#include "caf/unit.hpp"
#include "caf/unit.hpp"
namespace
caf
{
namespace
caf
{
namespace
detail
{
namespace
detail
{
using
parse_state
=
parser
::
state
<
string_view
::
iterator
>
;
// -- boolean type -------------------------------------------------------------
// -- boolean type -------------------------------------------------------------
void
parse
(
parse
_state
&
ps
,
bool
&
x
);
void
parse
(
string_parser
_state
&
ps
,
bool
&
x
);
// -- signed integer types -----------------------------------------------------
// -- signed integer types -----------------------------------------------------
void
parse
(
parse
_state
&
ps
,
int8_t
&
x
);
void
parse
(
string_parser
_state
&
ps
,
int8_t
&
x
);
void
parse
(
parse
_state
&
ps
,
int16_t
&
x
);
void
parse
(
string_parser
_state
&
ps
,
int16_t
&
x
);
void
parse
(
parse
_state
&
ps
,
int32_t
&
x
);
void
parse
(
string_parser
_state
&
ps
,
int32_t
&
x
);
void
parse
(
parse
_state
&
ps
,
int64_t
&
x
);
void
parse
(
string_parser
_state
&
ps
,
int64_t
&
x
);
// -- unsigned integer types ---------------------------------------------------
// -- unsigned integer types ---------------------------------------------------
void
parse
(
parse
_state
&
ps
,
uint8_t
&
x
);
void
parse
(
string_parser
_state
&
ps
,
uint8_t
&
x
);
void
parse
(
parse
_state
&
ps
,
uint16_t
&
x
);
void
parse
(
string_parser
_state
&
ps
,
uint16_t
&
x
);
void
parse
(
parse
_state
&
ps
,
uint32_t
&
x
);
void
parse
(
string_parser
_state
&
ps
,
uint32_t
&
x
);
void
parse
(
parse
_state
&
ps
,
uint64_t
&
x
);
void
parse
(
string_parser
_state
&
ps
,
uint64_t
&
x
);
// -- non-fixed size integer types ---------------------------------------------
// -- non-fixed size integer types ---------------------------------------------
template
<
class
T
>
template
<
class
T
>
detail
::
enable_if_t
<
std
::
is_integral
<
T
>::
value
>
parse
(
parse_state
&
ps
,
T
&
x
)
{
detail
::
enable_if_t
<
std
::
is_integral
<
T
>::
value
>
parse
(
string_parser_state
&
ps
,
T
&
x
)
{
using
squashed_type
=
squashed_int_t
<
T
>
;
using
squashed_type
=
squashed_int_t
<
T
>
;
return
parse
(
ps
,
reinterpret_cast
<
squashed_type
&>
(
x
));
return
parse
(
ps
,
reinterpret_cast
<
squashed_type
&>
(
x
));
}
}
// -- floating point types -----------------------------------------------------
// -- floating point types -----------------------------------------------------
void
parse
(
parse
_state
&
ps
,
float
&
x
);
void
parse
(
string_parser
_state
&
ps
,
float
&
x
);
void
parse
(
parse
_state
&
ps
,
double
&
x
);
void
parse
(
string_parser
_state
&
ps
,
double
&
x
);
// -- CAF types ----------------------------------------------------------------
// -- CAF types ----------------------------------------------------------------
void
parse
(
parse
_state
&
ps
,
timespan
&
x
);
void
parse
(
string_parser
_state
&
ps
,
timespan
&
x
);
void
parse
(
parse
_state
&
ps
,
atom_value
&
x
);
void
parse
(
string_parser
_state
&
ps
,
atom_value
&
x
);
void
parse
(
parse
_state
&
ps
,
ipv4_address
&
x
);
void
parse
(
string_parser
_state
&
ps
,
ipv4_address
&
x
);
void
parse
(
parse
_state
&
ps
,
ipv4_subnet
&
x
);
void
parse
(
string_parser
_state
&
ps
,
ipv4_subnet
&
x
);
void
parse
(
parse
_state
&
ps
,
ipv4_endpoint
&
x
);
void
parse
(
string_parser
_state
&
ps
,
ipv4_endpoint
&
x
);
void
parse
(
parse
_state
&
ps
,
ipv6_address
&
x
);
void
parse
(
string_parser
_state
&
ps
,
ipv6_address
&
x
);
void
parse
(
parse
_state
&
ps
,
ipv6_subnet
&
x
);
void
parse
(
string_parser
_state
&
ps
,
ipv6_subnet
&
x
);
void
parse
(
parse
_state
&
ps
,
ipv6_endpoint
&
x
);
void
parse
(
string_parser
_state
&
ps
,
ipv6_endpoint
&
x
);
void
parse
(
parse
_state
&
ps
,
uri
&
x
);
void
parse
(
string_parser
_state
&
ps
,
uri
&
x
);
// -- STL types ----------------------------------------------------------------
// -- STL types ----------------------------------------------------------------
void
parse
(
parse
_state
&
ps
,
std
::
string
&
x
);
void
parse
(
string_parser
_state
&
ps
,
std
::
string
&
x
);
// -- container types ----------------------------------------------------------
// -- container types ----------------------------------------------------------
void
parse_element
(
parse_state
&
ps
,
std
::
string
&
x
,
const
char
*
char_blacklist
);
void
parse_element
(
string_parser_state
&
ps
,
std
::
string
&
x
,
const
char
*
char_blacklist
);
template
<
class
T
>
template
<
class
T
>
enable_if_t
<!
is_pair
<
T
>::
value
>
parse_element
(
parse
_state
&
ps
,
T
&
x
,
enable_if_t
<!
is_pair
<
T
>::
value
>
parse_element
(
string_parser
_state
&
ps
,
T
&
x
,
const
char
*
)
{
const
char
*
)
{
parse
(
ps
,
x
);
parse
(
ps
,
x
);
}
}
template
<
class
First
,
class
Second
,
size_t
N
>
template
<
class
First
,
class
Second
,
size_t
N
>
void
parse_element
(
parse
_state
&
ps
,
std
::
pair
<
First
,
Second
>&
kvp
,
void
parse_element
(
string_parser
_state
&
ps
,
std
::
pair
<
First
,
Second
>&
kvp
,
const
char
(
&
char_blacklist
)[
N
])
{
const
char
(
&
char_blacklist
)[
N
])
{
static_assert
(
N
>
0
,
"empty array"
);
static_assert
(
N
>
0
,
"empty array"
);
// TODO: consider to guard the blacklist computation with
// TODO: consider to guard the blacklist computation with
...
@@ -133,7 +133,7 @@ void parse_element(parse_state& ps, std::pair<First, Second>& kvp,
...
@@ -133,7 +133,7 @@ void parse_element(parse_state& ps, std::pair<First, Second>& kvp,
}
}
template
<
class
T
>
template
<
class
T
>
enable_if_tt
<
is_iterable
<
T
>>
parse
(
parse
_state
&
ps
,
T
&
xs
)
{
enable_if_tt
<
is_iterable
<
T
>>
parse
(
string_parser
_state
&
ps
,
T
&
xs
)
{
using
value_type
=
deconst_kvp_t
<
typename
T
::
value_type
>
;
using
value_type
=
deconst_kvp_t
<
typename
T
::
value_type
>
;
static
constexpr
auto
is_map_type
=
is_pair
<
value_type
>::
value
;
static
constexpr
auto
is_map_type
=
is_pair
<
value_type
>::
value
;
static
constexpr
auto
opening_char
=
is_map_type
?
'{'
:
'['
;
static
constexpr
auto
opening_char
=
is_map_type
?
'{'
:
'['
;
...
@@ -181,7 +181,7 @@ enable_if_tt<is_iterable<T>> parse(parse_state& ps, T& xs) {
...
@@ -181,7 +181,7 @@ enable_if_tt<is_iterable<T>> parse(parse_state& ps, T& xs) {
template
<
class
T
>
template
<
class
T
>
error
parse
(
string_view
str
,
T
&
x
)
{
error
parse
(
string_view
str
,
T
&
x
)
{
parse
_state
ps
{
str
.
begin
(),
str
.
end
()};
string_parser
_state
ps
{
str
.
begin
(),
str
.
end
()};
parse
(
ps
,
x
);
parse
(
ps
,
x
);
if
(
ps
.
code
==
pec
::
success
)
if
(
ps
.
code
==
pec
::
success
)
return
none
;
return
none
;
...
...
libcaf_core/caf/detail/parser/read_atom.hpp
View file @
11c4eaca
...
@@ -26,7 +26,6 @@
...
@@ -26,7 +26,6 @@
#include "caf/config.hpp"
#include "caf/config.hpp"
#include "caf/detail/parser/chars.hpp"
#include "caf/detail/parser/chars.hpp"
#include "caf/detail/parser/is_char.hpp"
#include "caf/detail/parser/is_char.hpp"
#include "caf/detail/parser/state.hpp"
#include "caf/detail/scope_guard.hpp"
#include "caf/detail/scope_guard.hpp"
#include "caf/pec.hpp"
#include "caf/pec.hpp"
...
@@ -40,9 +39,8 @@ namespace parser {
...
@@ -40,9 +39,8 @@ namespace parser {
/// Reads a number, i.e., on success produces either an `int64_t` or a
/// Reads a number, i.e., on success produces either an `int64_t` or a
/// `double`.
/// `double`.
template
<
class
Iterator
,
class
Sentinel
,
class
Consumer
>
template
<
class
State
,
class
Consumer
>
void
read_atom
(
state
<
Iterator
,
Sentinel
>&
ps
,
Consumer
&&
consumer
,
void
read_atom
(
State
&
ps
,
Consumer
&&
consumer
,
bool
accept_unquoted
=
false
)
{
bool
accept_unquoted
=
false
)
{
size_t
pos
=
0
;
size_t
pos
=
0
;
char
buf
[
11
];
char
buf
[
11
];
memset
(
buf
,
0
,
sizeof
(
buf
));
memset
(
buf
,
0
,
sizeof
(
buf
));
...
...
libcaf_core/caf/detail/parser/read_bool.hpp
View file @
11c4eaca
...
@@ -24,7 +24,6 @@
...
@@ -24,7 +24,6 @@
#include "caf/config.hpp"
#include "caf/config.hpp"
#include "caf/detail/parser/chars.hpp"
#include "caf/detail/parser/chars.hpp"
#include "caf/detail/parser/is_char.hpp"
#include "caf/detail/parser/is_char.hpp"
#include "caf/detail/parser/state.hpp"
#include "caf/detail/scope_guard.hpp"
#include "caf/detail/scope_guard.hpp"
#include "caf/pec.hpp"
#include "caf/pec.hpp"
...
@@ -37,8 +36,8 @@ namespace detail {
...
@@ -37,8 +36,8 @@ namespace detail {
namespace
parser
{
namespace
parser
{
/// Reads a boolean.
/// Reads a boolean.
template
<
class
Iterator
,
class
Sentinel
,
class
Consumer
>
template
<
class
State
,
class
Consumer
>
void
read_bool
(
state
<
Iterator
,
Sentinel
>
&
ps
,
Consumer
&&
consumer
)
{
void
read_bool
(
State
&
ps
,
Consumer
&&
consumer
)
{
bool
res
=
false
;
bool
res
=
false
;
auto
g
=
make_scope_guard
([
&
]
{
auto
g
=
make_scope_guard
([
&
]
{
if
(
ps
.
code
<=
pec
::
trailing_character
)
if
(
ps
.
code
<=
pec
::
trailing_character
)
...
...
libcaf_core/caf/detail/parser/read_floating_point.hpp
View file @
11c4eaca
...
@@ -26,7 +26,6 @@
...
@@ -26,7 +26,6 @@
#include "caf/detail/parser/chars.hpp"
#include "caf/detail/parser/chars.hpp"
#include "caf/detail/parser/is_char.hpp"
#include "caf/detail/parser/is_char.hpp"
#include "caf/detail/parser/is_digit.hpp"
#include "caf/detail/parser/is_digit.hpp"
#include "caf/detail/parser/state.hpp"
#include "caf/detail/parser/sub_ascii.hpp"
#include "caf/detail/parser/sub_ascii.hpp"
#include "caf/detail/scope_guard.hpp"
#include "caf/detail/scope_guard.hpp"
#include "caf/optional.hpp"
#include "caf/optional.hpp"
...
@@ -45,8 +44,8 @@ namespace parser {
...
@@ -45,8 +44,8 @@ namespace parser {
/// @param consumer Sink for generated values.
/// @param consumer Sink for generated values.
/// @param start_value Allows another parser to pre-initialize this parser with
/// @param start_value Allows another parser to pre-initialize this parser with
/// the pre-decimal value.
/// the pre-decimal value.
template
<
class
Iterator
,
class
Sentinel
,
class
Consumer
,
class
ValueType
>
template
<
class
State
,
class
Consumer
,
class
ValueType
>
void
read_floating_point
(
state
<
Iterator
,
Sentinel
>
&
ps
,
Consumer
&&
consumer
,
void
read_floating_point
(
State
&
ps
,
Consumer
&&
consumer
,
optional
<
ValueType
>
start_value
,
optional
<
ValueType
>
start_value
,
bool
negative
=
false
)
{
bool
negative
=
false
)
{
// Any exponent larger than 511 always overflows.
// Any exponent larger than 511 always overflows.
...
@@ -185,8 +184,8 @@ void read_floating_point(state<Iterator, Sentinel>& ps, Consumer&& consumer,
...
@@ -185,8 +184,8 @@ void read_floating_point(state<Iterator, Sentinel>& ps, Consumer&& consumer,
// clang-format on
// clang-format on
}
}
template
<
class
Iterator
,
class
Sentinel
,
class
Consumer
>
template
<
class
State
,
class
Consumer
>
void
read_floating_point
(
state
<
Iterator
,
Sentinel
>
&
ps
,
Consumer
&&
consumer
)
{
void
read_floating_point
(
State
&
ps
,
Consumer
&&
consumer
)
{
using
consumer_type
=
typename
std
::
decay
<
Consumer
>::
type
;
using
consumer_type
=
typename
std
::
decay
<
Consumer
>::
type
;
using
value_type
=
typename
consumer_type
::
value_type
;
using
value_type
=
typename
consumer_type
::
value_type
;
return
read_floating_point
(
ps
,
consumer
,
optional
<
value_type
>
{});
return
read_floating_point
(
ps
,
consumer
,
optional
<
value_type
>
{});
...
...
libcaf_core/caf/detail/parser/read_ini.hpp
View file @
11c4eaca
...
@@ -58,8 +58,8 @@ namespace parser {
...
@@ -58,8 +58,8 @@ namespace parser {
// }]
// }]
//
//
template
<
class
Iterator
,
class
Sentinel
,
class
Consumer
>
template
<
class
State
,
class
Consumer
>
void
read_ini_comment
(
state
<
Iterator
,
Sentinel
>
&
ps
,
Consumer
&&
)
{
void
read_ini_comment
(
State
&
ps
,
Consumer
&&
)
{
start
();
start
();
term_state
(
init
)
{
term_state
(
init
)
{
transition
(
done
,
'\n'
)
transition
(
done
,
'\n'
)
...
@@ -71,11 +71,11 @@ void read_ini_comment(state<Iterator, Sentinel>& ps, Consumer&&) {
...
@@ -71,11 +71,11 @@ void read_ini_comment(state<Iterator, Sentinel>& ps, Consumer&&) {
fin
();
fin
();
}
}
template
<
class
Iterator
,
class
Sentinel
,
class
Consumer
>
template
<
class
State
,
class
Consumer
>
void
read_ini_value
(
state
<
Iterator
,
Sentinel
>
&
ps
,
Consumer
&&
consumer
);
void
read_ini_value
(
State
&
ps
,
Consumer
&&
consumer
);
template
<
class
Iterator
,
class
Sentinel
,
class
Consumer
>
template
<
class
State
,
class
Consumer
>
void
read_ini_list
(
state
<
Iterator
,
Sentinel
>
&
ps
,
Consumer
&&
consumer
)
{
void
read_ini_list
(
State
&
ps
,
Consumer
&&
consumer
)
{
start
();
start
();
state
(
init
)
{
state
(
init
)
{
epsilon
(
before_value
)
epsilon
(
before_value
)
...
@@ -98,8 +98,8 @@ void read_ini_list(state<Iterator, Sentinel>& ps, Consumer&& consumer) {
...
@@ -98,8 +98,8 @@ void read_ini_list(state<Iterator, Sentinel>& ps, Consumer&& consumer) {
fin
();
fin
();
}
}
template
<
class
Iterator
,
class
Sentinel
,
class
Consumer
>
template
<
class
State
,
class
Consumer
>
void
read_ini_map
(
state
<
Iterator
,
Sentinel
>
&
ps
,
Consumer
&&
consumer
)
{
void
read_ini_map
(
State
&
ps
,
Consumer
&&
consumer
)
{
std
::
string
key
;
std
::
string
key
;
auto
alnum_or_dash
=
[](
char
x
)
{
auto
alnum_or_dash
=
[](
char
x
)
{
return
isalnum
(
x
)
||
x
==
'-'
||
x
==
'_'
;
return
isalnum
(
x
)
||
x
==
'-'
||
x
==
'_'
;
...
@@ -154,8 +154,8 @@ void read_ini_map(state<Iterator, Sentinel>& ps, Consumer&& consumer) {
...
@@ -154,8 +154,8 @@ void read_ini_map(state<Iterator, Sentinel>& ps, Consumer&& consumer) {
// clang-format on
// clang-format on
}
}
template
<
class
Iterator
,
class
Sentinel
,
class
Consumer
>
template
<
class
State
,
class
Consumer
>
void
read_ini_uri
(
state
<
Iterator
,
Sentinel
>
&
ps
,
Consumer
&&
consumer
)
{
void
read_ini_uri
(
State
&
ps
,
Consumer
&&
consumer
)
{
uri_builder
builder
;
uri_builder
builder
;
auto
g
=
make_scope_guard
([
&
]
{
auto
g
=
make_scope_guard
([
&
]
{
if
(
ps
.
code
<=
pec
::
trailing_character
)
if
(
ps
.
code
<=
pec
::
trailing_character
)
...
@@ -180,8 +180,8 @@ void read_ini_uri(state<Iterator, Sentinel>& ps, Consumer&& consumer) {
...
@@ -180,8 +180,8 @@ void read_ini_uri(state<Iterator, Sentinel>& ps, Consumer&& consumer) {
fin
();
fin
();
}
}
template
<
class
Iterator
,
class
Sentinel
,
class
Consumer
>
template
<
class
State
,
class
Consumer
>
void
read_ini_value
(
state
<
Iterator
,
Sentinel
>
&
ps
,
Consumer
&&
consumer
)
{
void
read_ini_value
(
State
&
ps
,
Consumer
&&
consumer
)
{
start
();
start
();
state
(
init
)
{
state
(
init
)
{
fsm_epsilon
(
read_string
(
ps
,
consumer
),
done
,
'"'
)
fsm_epsilon
(
read_string
(
ps
,
consumer
),
done
,
'"'
)
...
@@ -200,8 +200,8 @@ void read_ini_value(state<Iterator, Sentinel>& ps, Consumer&& consumer) {
...
@@ -200,8 +200,8 @@ void read_ini_value(state<Iterator, Sentinel>& ps, Consumer&& consumer) {
}
}
/// Reads an INI formatted input.
/// Reads an INI formatted input.
template
<
class
Iterator
,
class
Sentinel
,
class
Consumer
>
template
<
class
State
,
class
Consumer
>
void
read_ini_section
(
state
<
Iterator
,
Sentinel
>
&
ps
,
Consumer
&&
consumer
)
{
void
read_ini_section
(
State
&
ps
,
Consumer
&&
consumer
)
{
using
std
::
swap
;
using
std
::
swap
;
std
::
string
tmp
;
std
::
string
tmp
;
auto
alnum
=
[](
char
x
)
{
return
isalnum
(
x
)
||
x
==
'_'
;
};
auto
alnum
=
[](
char
x
)
{
return
isalnum
(
x
)
||
x
==
'_'
;
};
...
@@ -254,8 +254,8 @@ void read_ini_section(state<Iterator, Sentinel>& ps, Consumer&& consumer) {
...
@@ -254,8 +254,8 @@ void read_ini_section(state<Iterator, Sentinel>& ps, Consumer&& consumer) {
/// Reads a nested group, e.g., "[foo.bar]" would consume "[foo.]" in read_ini
/// Reads a nested group, e.g., "[foo.bar]" would consume "[foo.]" in read_ini
/// and then delegate to this function for parsing "bar]".
/// and then delegate to this function for parsing "bar]".
template
<
class
Iterator
,
class
Sentinel
,
class
Consumer
>
template
<
class
State
,
class
Consumer
>
void
read_nested_group
(
state
<
Iterator
,
Sentinel
>
&
ps
,
Consumer
&&
consumer
)
{
void
read_nested_group
(
State
&
ps
,
Consumer
&&
consumer
)
{
using
std
::
swap
;
using
std
::
swap
;
std
::
string
key
;
std
::
string
key
;
auto
alnum
=
[](
char
x
)
{
return
isalnum
(
x
)
||
x
==
'_'
;
};
auto
alnum
=
[](
char
x
)
{
return
isalnum
(
x
)
||
x
==
'_'
;
};
...
@@ -290,8 +290,8 @@ void read_nested_group(state<Iterator, Sentinel>& ps, Consumer&& consumer) {
...
@@ -290,8 +290,8 @@ void read_nested_group(state<Iterator, Sentinel>& ps, Consumer&& consumer) {
}
}
/// Reads an INI formatted input.
/// Reads an INI formatted input.
template
<
class
Iterator
,
class
Sentinel
,
class
Consumer
>
template
<
class
State
,
class
Consumer
>
void
read_ini
(
state
<
Iterator
,
Sentinel
>
&
ps
,
Consumer
&&
consumer
)
{
void
read_ini
(
State
&
ps
,
Consumer
&&
consumer
)
{
using
std
::
swap
;
using
std
::
swap
;
std
::
string
tmp
{
"global"
};
std
::
string
tmp
{
"global"
};
auto
alnum
=
[](
char
x
)
{
return
isalnum
(
x
)
||
x
==
'_'
;
};
auto
alnum
=
[](
char
x
)
{
return
isalnum
(
x
)
||
x
==
'_'
;
};
...
...
libcaf_core/caf/detail/parser/read_ipv4_address.hpp
View file @
11c4eaca
...
@@ -25,7 +25,6 @@
...
@@ -25,7 +25,6 @@
#include "caf/detail/parser/chars.hpp"
#include "caf/detail/parser/chars.hpp"
#include "caf/detail/parser/is_char.hpp"
#include "caf/detail/parser/is_char.hpp"
#include "caf/detail/parser/is_digit.hpp"
#include "caf/detail/parser/is_digit.hpp"
#include "caf/detail/parser/state.hpp"
#include "caf/detail/parser/sub_ascii.hpp"
#include "caf/detail/parser/sub_ascii.hpp"
#include "caf/detail/scope_guard.hpp"
#include "caf/detail/scope_guard.hpp"
#include "caf/ipv4_address.hpp"
#include "caf/ipv4_address.hpp"
...
@@ -48,8 +47,8 @@ struct read_ipv4_octet_consumer {
...
@@ -48,8 +47,8 @@ struct read_ipv4_octet_consumer {
}
}
};
};
template
<
class
Iterator
,
class
Sentinel
,
class
Consumer
>
template
<
class
State
,
class
Consumer
>
void
read_ipv4_octet
(
state
<
Iterator
,
Sentinel
>
&
ps
,
Consumer
&
consumer
)
{
void
read_ipv4_octet
(
State
&
ps
,
Consumer
&
consumer
)
{
uint8_t
res
=
0
;
uint8_t
res
=
0
;
// Reads the a decimal place.
// Reads the a decimal place.
auto
rd_decimal
=
[
&
](
char
c
)
{
auto
rd_decimal
=
[
&
](
char
c
)
{
...
@@ -72,8 +71,8 @@ void read_ipv4_octet(state<Iterator, Sentinel>& ps, Consumer& consumer) {
...
@@ -72,8 +71,8 @@ void read_ipv4_octet(state<Iterator, Sentinel>& ps, Consumer& consumer) {
/// Reads a number, i.e., on success produces either an `int64_t` or a
/// Reads a number, i.e., on success produces either an `int64_t` or a
/// `double`.
/// `double`.
template
<
class
Iterator
,
class
Sentinel
,
class
Consumer
>
template
<
class
State
,
class
Consumer
>
void
read_ipv4_address
(
state
<
Iterator
,
Sentinel
>
&
ps
,
Consumer
&&
consumer
)
{
void
read_ipv4_address
(
State
&
ps
,
Consumer
&&
consumer
)
{
read_ipv4_octet_consumer
f
;
read_ipv4_octet_consumer
f
;
auto
g
=
make_scope_guard
([
&
]
{
auto
g
=
make_scope_guard
([
&
]
{
if
(
ps
.
code
<=
pec
::
trailing_character
)
{
if
(
ps
.
code
<=
pec
::
trailing_character
)
{
...
...
libcaf_core/caf/detail/parser/read_ipv6_address.hpp
View file @
11c4eaca
...
@@ -27,7 +27,6 @@
...
@@ -27,7 +27,6 @@
#include "caf/detail/parser/chars.hpp"
#include "caf/detail/parser/chars.hpp"
#include "caf/detail/parser/is_char.hpp"
#include "caf/detail/parser/is_char.hpp"
#include "caf/detail/parser/is_digit.hpp"
#include "caf/detail/parser/is_digit.hpp"
#include "caf/detail/parser/state.hpp"
#include "caf/detail/parser/sub_ascii.hpp"
#include "caf/detail/parser/sub_ascii.hpp"
#include "caf/detail/scope_guard.hpp"
#include "caf/detail/scope_guard.hpp"
#include "caf/ipv4_address.hpp"
#include "caf/ipv4_address.hpp"
...
@@ -57,8 +56,8 @@ namespace parser {
...
@@ -57,8 +56,8 @@ namespace parser {
// h16 = 1*4HEXDIG
// h16 = 1*4HEXDIG
/// Reads 16 (hex) bits of an IPv6 address.
/// Reads 16 (hex) bits of an IPv6 address.
template
<
class
Iterator
,
class
Sentinel
,
class
Consumer
>
template
<
class
State
,
class
Consumer
>
void
read_ipv6_h16
(
state
<
Iterator
,
Sentinel
>
&
ps
,
Consumer
&
consumer
)
{
void
read_ipv6_h16
(
State
&
ps
,
Consumer
&
consumer
)
{
uint16_t
res
=
0
;
uint16_t
res
=
0
;
size_t
digits
=
0
;
size_t
digits
=
0
;
// Reads the a hexadecimal place.
// Reads the a hexadecimal place.
...
@@ -83,8 +82,8 @@ void read_ipv6_h16(state<Iterator, Sentinel>& ps, Consumer& consumer) {
...
@@ -83,8 +82,8 @@ void read_ipv6_h16(state<Iterator, Sentinel>& ps, Consumer& consumer) {
}
}
/// Reads 16 (hex) or 32 (IPv4 notation) bits of an IPv6 address.
/// Reads 16 (hex) or 32 (IPv4 notation) bits of an IPv6 address.
template
<
class
Iterator
,
class
Sentinel
,
class
Consumer
>
template
<
class
State
,
class
Consumer
>
void
read_ipv6_h16_or_l32
(
state
<
Iterator
,
Sentinel
>
&
ps
,
Consumer
&
consumer
)
{
void
read_ipv6_h16_or_l32
(
State
&
ps
,
Consumer
&
consumer
)
{
enum
mode_t
{
indeterminate
,
v6_bits
,
v4_octets
};
enum
mode_t
{
indeterminate
,
v6_bits
,
v4_octets
};
mode_t
mode
=
indeterminate
;
mode_t
mode
=
indeterminate
;
uint16_t
hex_res
=
0
;
uint16_t
hex_res
=
0
;
...
@@ -173,8 +172,8 @@ read_ipv6_address_piece_consumer<F> make_read_ipv6_address_piece_consumer(F f) {
...
@@ -173,8 +172,8 @@ read_ipv6_address_piece_consumer<F> make_read_ipv6_address_piece_consumer(F f) {
/// Reads a number, i.e., on success produces either an `int64_t` or a
/// Reads a number, i.e., on success produces either an `int64_t` or a
/// `double`.
/// `double`.
template
<
class
Iterator
,
class
Sentinel
,
class
Consumer
>
template
<
class
State
,
class
Consumer
>
void
read_ipv6_address
(
state
<
Iterator
,
Sentinel
>
&
ps
,
Consumer
&&
consumer
)
{
void
read_ipv6_address
(
State
&
ps
,
Consumer
&&
consumer
)
{
// IPv6 allows omitting blocks of zeros, splitting the string into a part
// IPv6 allows omitting blocks of zeros, splitting the string into a part
// before the zeros (prefix) and a part after the zeros (suffix). For example,
// before the zeros (prefix) and a part after the zeros (suffix). For example,
// ff::1 is 00FF0000000000000000000000000001
// ff::1 is 00FF0000000000000000000000000001
...
...
libcaf_core/caf/detail/parser/read_number.hpp
View file @
11c4eaca
...
@@ -26,7 +26,6 @@
...
@@ -26,7 +26,6 @@
#include "caf/detail/parser/is_char.hpp"
#include "caf/detail/parser/is_char.hpp"
#include "caf/detail/parser/is_digit.hpp"
#include "caf/detail/parser/is_digit.hpp"
#include "caf/detail/parser/read_floating_point.hpp"
#include "caf/detail/parser/read_floating_point.hpp"
#include "caf/detail/parser/state.hpp"
#include "caf/detail/parser/sub_ascii.hpp"
#include "caf/detail/parser/sub_ascii.hpp"
#include "caf/detail/scope_guard.hpp"
#include "caf/detail/scope_guard.hpp"
#include "caf/pec.hpp"
#include "caf/pec.hpp"
...
@@ -41,8 +40,8 @@ namespace parser {
...
@@ -41,8 +40,8 @@ namespace parser {
/// Reads a number, i.e., on success produces either an `int64_t` or a
/// Reads a number, i.e., on success produces either an `int64_t` or a
/// `double`.
/// `double`.
template
<
class
Iterator
,
class
Sentinel
,
class
Consumer
>
template
<
class
State
,
class
Consumer
>
void
read_number
(
state
<
Iterator
,
Sentinel
>
&
ps
,
Consumer
&
consumer
)
{
void
read_number
(
State
&
ps
,
Consumer
&
consumer
)
{
// Our result when reading an integer number.
// Our result when reading an integer number.
int64_t
result
=
0
;
int64_t
result
=
0
;
// Computes the result on success.
// Computes the result on success.
...
...
libcaf_core/caf/detail/parser/read_number_or_timespan.hpp
View file @
11c4eaca
...
@@ -27,7 +27,6 @@
...
@@ -27,7 +27,6 @@
#include "caf/detail/parser/is_char.hpp"
#include "caf/detail/parser/is_char.hpp"
#include "caf/detail/parser/read_number.hpp"
#include "caf/detail/parser/read_number.hpp"
#include "caf/detail/parser/read_timespan.hpp"
#include "caf/detail/parser/read_timespan.hpp"
#include "caf/detail/parser/state.hpp"
#include "caf/detail/scope_guard.hpp"
#include "caf/detail/scope_guard.hpp"
#include "caf/none.hpp"
#include "caf/none.hpp"
#include "caf/optional.hpp"
#include "caf/optional.hpp"
...
@@ -45,9 +44,8 @@ namespace parser {
...
@@ -45,9 +44,8 @@ namespace parser {
/// Reads a number or a duration, i.e., on success produces an `int64_t`, a
/// Reads a number or a duration, i.e., on success produces an `int64_t`, a
/// `double`, or a `timespan`.
/// `double`, or a `timespan`.
template
<
class
Iterator
,
class
Sentinel
,
class
Consumer
>
template
<
class
State
,
class
Consumer
>
void
read_number_or_timespan
(
state
<
Iterator
,
Sentinel
>&
ps
,
void
read_number_or_timespan
(
State
&
ps
,
Consumer
&
consumer
)
{
Consumer
&
consumer
)
{
using
namespace
std
::
chrono
;
using
namespace
std
::
chrono
;
struct
interim_consumer
{
struct
interim_consumer
{
variant
<
none_t
,
int64_t
,
double
>
interim
;
variant
<
none_t
,
int64_t
,
double
>
interim
;
...
...
libcaf_core/caf/detail/parser/read_signed_integer.hpp
View file @
11c4eaca
...
@@ -26,7 +26,6 @@
...
@@ -26,7 +26,6 @@
#include "caf/detail/parser/chars.hpp"
#include "caf/detail/parser/chars.hpp"
#include "caf/detail/parser/is_char.hpp"
#include "caf/detail/parser/is_char.hpp"
#include "caf/detail/parser/is_digit.hpp"
#include "caf/detail/parser/is_digit.hpp"
#include "caf/detail/parser/state.hpp"
#include "caf/detail/parser/sub_ascii.hpp"
#include "caf/detail/parser/sub_ascii.hpp"
#include "caf/detail/scope_guard.hpp"
#include "caf/detail/scope_guard.hpp"
#include "caf/pec.hpp"
#include "caf/pec.hpp"
...
@@ -41,8 +40,8 @@ namespace parser {
...
@@ -41,8 +40,8 @@ namespace parser {
/// Reads a number, i.e., on success produces either an `int64_t` or a
/// Reads a number, i.e., on success produces either an `int64_t` or a
/// `double`.
/// `double`.
template
<
class
Iterator
,
class
Sentinel
,
class
Consumer
>
template
<
class
State
,
class
Consumer
>
void
read_signed_integer
(
state
<
Iterator
,
Sentinel
>
&
ps
,
Consumer
&&
consumer
)
{
void
read_signed_integer
(
State
&
ps
,
Consumer
&&
consumer
)
{
using
consumer_type
=
typename
std
::
decay
<
Consumer
>::
type
;
using
consumer_type
=
typename
std
::
decay
<
Consumer
>::
type
;
using
value_type
=
typename
consumer_type
::
value_type
;
using
value_type
=
typename
consumer_type
::
value_type
;
static_assert
(
std
::
is_integral
<
value_type
>::
value
static_assert
(
std
::
is_integral
<
value_type
>::
value
...
...
libcaf_core/caf/detail/parser/read_string.hpp
View file @
11c4eaca
...
@@ -23,7 +23,6 @@
...
@@ -23,7 +23,6 @@
#include "caf/config.hpp"
#include "caf/config.hpp"
#include "caf/detail/parser/chars.hpp"
#include "caf/detail/parser/chars.hpp"
#include "caf/detail/parser/state.hpp"
#include "caf/detail/scope_guard.hpp"
#include "caf/detail/scope_guard.hpp"
#include "caf/pec.hpp"
#include "caf/pec.hpp"
...
@@ -37,8 +36,8 @@ namespace parser {
...
@@ -37,8 +36,8 @@ namespace parser {
/// Reads a quoted or unquoted string. Quoted strings allow escaping, while
/// Reads a quoted or unquoted string. Quoted strings allow escaping, while
/// unquoted strings may only include alphanumeric characters.
/// unquoted strings may only include alphanumeric characters.
template
<
class
Iterator
,
class
Sentinel
,
class
Consumer
>
template
<
class
State
,
class
Consumer
>
void
read_string
(
state
<
Iterator
,
Sentinel
>
&
ps
,
Consumer
&&
consumer
)
{
void
read_string
(
State
&
ps
,
Consumer
&&
consumer
)
{
std
::
string
res
;
std
::
string
res
;
auto
g
=
caf
::
detail
::
make_scope_guard
([
&
]
{
auto
g
=
caf
::
detail
::
make_scope_guard
([
&
]
{
if
(
ps
.
code
<=
pec
::
trailing_character
)
if
(
ps
.
code
<=
pec
::
trailing_character
)
...
...
libcaf_core/caf/detail/parser/read_timespan.hpp
View file @
11c4eaca
...
@@ -24,7 +24,6 @@
...
@@ -24,7 +24,6 @@
#include "caf/config.hpp"
#include "caf/config.hpp"
#include "caf/detail/parser/read_signed_integer.hpp"
#include "caf/detail/parser/read_signed_integer.hpp"
#include "caf/detail/parser/state.hpp"
#include "caf/detail/scope_guard.hpp"
#include "caf/detail/scope_guard.hpp"
#include "caf/optional.hpp"
#include "caf/optional.hpp"
#include "caf/pec.hpp"
#include "caf/pec.hpp"
...
@@ -39,8 +38,8 @@ namespace detail {
...
@@ -39,8 +38,8 @@ namespace detail {
namespace
parser
{
namespace
parser
{
/// Reads a timespan.
/// Reads a timespan.
template
<
class
Iterator
,
class
Sentinel
,
class
Consumer
>
template
<
class
State
,
class
Consumer
>
void
read_timespan
(
state
<
Iterator
,
Sentinel
>
&
ps
,
Consumer
&&
consumer
,
void
read_timespan
(
State
&
ps
,
Consumer
&&
consumer
,
optional
<
int64_t
>
num
=
none
)
{
optional
<
int64_t
>
num
=
none
)
{
using
namespace
std
::
chrono
;
using
namespace
std
::
chrono
;
struct
interim_consumer
{
struct
interim_consumer
{
...
...
libcaf_core/caf/detail/parser/read_unsigned_integer.hpp
View file @
11c4eaca
...
@@ -26,7 +26,6 @@
...
@@ -26,7 +26,6 @@
#include "caf/detail/parser/chars.hpp"
#include "caf/detail/parser/chars.hpp"
#include "caf/detail/parser/is_char.hpp"
#include "caf/detail/parser/is_char.hpp"
#include "caf/detail/parser/is_digit.hpp"
#include "caf/detail/parser/is_digit.hpp"
#include "caf/detail/parser/state.hpp"
#include "caf/detail/parser/sub_ascii.hpp"
#include "caf/detail/parser/sub_ascii.hpp"
#include "caf/detail/scope_guard.hpp"
#include "caf/detail/scope_guard.hpp"
#include "caf/pec.hpp"
#include "caf/pec.hpp"
...
@@ -41,8 +40,8 @@ namespace parser {
...
@@ -41,8 +40,8 @@ namespace parser {
/// Reads a number, i.e., on success produces either an `int64_t` or a
/// Reads a number, i.e., on success produces either an `int64_t` or a
/// `double`.
/// `double`.
template
<
class
Iterator
,
class
Sentinel
,
class
Consumer
>
template
<
class
State
,
class
Consumer
>
void
read_unsigned_integer
(
state
<
Iterator
,
Sentinel
>
&
ps
,
Consumer
&&
consumer
)
{
void
read_unsigned_integer
(
State
&
ps
,
Consumer
&&
consumer
)
{
using
consumer_type
=
typename
std
::
decay
<
Consumer
>::
type
;
using
consumer_type
=
typename
std
::
decay
<
Consumer
>::
type
;
using
value_type
=
typename
consumer_type
::
value_type
;
using
value_type
=
typename
consumer_type
::
value_type
;
static_assert
(
std
::
is_integral
<
value_type
>::
value
static_assert
(
std
::
is_integral
<
value_type
>::
value
...
...
libcaf_core/caf/detail/parser/read_uri.hpp
View file @
11c4eaca
...
@@ -22,7 +22,6 @@
...
@@ -22,7 +22,6 @@
#include "caf/detail/parser/add_ascii.hpp"
#include "caf/detail/parser/add_ascii.hpp"
#include "caf/detail/parser/chars.hpp"
#include "caf/detail/parser/chars.hpp"
#include "caf/detail/parser/read_ipv6_address.hpp"
#include "caf/detail/parser/read_ipv6_address.hpp"
#include "caf/detail/parser/state.hpp"
#include "caf/detail/scope_guard.hpp"
#include "caf/detail/scope_guard.hpp"
#include "caf/pec.hpp"
#include "caf/pec.hpp"
#include "caf/uri.hpp"
#include "caf/uri.hpp"
...
@@ -47,8 +46,8 @@ namespace parser {
...
@@ -47,8 +46,8 @@ namespace parser {
// generate ranges for the subcomponents. URIs can't have linebreaks, so we can
// generate ranges for the subcomponents. URIs can't have linebreaks, so we can
// safely keep track of the position by looking at the column.
// safely keep track of the position by looking at the column.
template
<
class
Iterator
,
class
Sentinel
>
template
<
class
State
>
void
read_uri_percent_encoded
(
state
<
Iterator
,
Sentinel
>
&
ps
,
std
::
string
&
str
)
{
void
read_uri_percent_encoded
(
State
&
ps
,
std
::
string
&
str
)
{
uint8_t
char_code
=
0
;
uint8_t
char_code
=
0
;
auto
g
=
make_scope_guard
([
&
]
{
auto
g
=
make_scope_guard
([
&
]
{
if
(
ps
.
code
<=
pec
::
trailing_character
)
if
(
ps
.
code
<=
pec
::
trailing_character
)
...
@@ -75,8 +74,8 @@ inline bool uri_unprotected_char(char c) {
...
@@ -75,8 +74,8 @@ inline bool uri_unprotected_char(char c) {
transition(next_state, uri_unprotected_char, dest += ch) \
transition(next_state, uri_unprotected_char, dest += ch) \
fsm_transition(read_uri_percent_encoded(ps, dest), next_state, '%')
fsm_transition(read_uri_percent_encoded(ps, dest), next_state, '%')
template
<
class
Iterator
,
class
Sentinel
,
class
Consumer
>
template
<
class
State
,
class
Consumer
>
void
read_uri_query
(
state
<
Iterator
,
Sentinel
>
&
ps
,
Consumer
&&
consumer
)
{
void
read_uri_query
(
State
&
ps
,
Consumer
&&
consumer
)
{
// Local variables.
// Local variables.
uri
::
query_map
result
;
uri
::
query_map
result
;
std
::
string
key
;
std
::
string
key
;
...
@@ -113,8 +112,8 @@ void read_uri_query(state<Iterator, Sentinel>& ps, Consumer&& consumer) {
...
@@ -113,8 +112,8 @@ void read_uri_query(state<Iterator, Sentinel>& ps, Consumer&& consumer) {
fin
();
fin
();
}
}
template
<
class
Iterator
,
class
Sentinel
,
class
Consumer
>
template
<
class
State
,
class
Consumer
>
void
read_uri
(
state
<
Iterator
,
Sentinel
>
&
ps
,
Consumer
&&
consumer
)
{
void
read_uri
(
State
&
ps
,
Consumer
&&
consumer
)
{
// Local variables.
// Local variables.
std
::
string
str
;
std
::
string
str
;
uint16_t
port
=
0
;
uint16_t
port
=
0
;
...
...
libcaf_core/caf/detail/type_traits.hpp
View file @
11c4eaca
...
@@ -445,6 +445,7 @@ struct callable_trait<R (Ts...)> {
...
@@ -445,6 +445,7 @@ struct callable_trait<R (Ts...)> {
using
arg_types
=
type_list
<
Ts
...
>
;
using
arg_types
=
type_list
<
Ts
...
>
;
using
fun_sig
=
R
(
Ts
...);
using
fun_sig
=
R
(
Ts
...);
using
fun_type
=
std
::
function
<
R
(
Ts
...)
>
;
using
fun_type
=
std
::
function
<
R
(
Ts
...)
>
;
static
constexpr
size_t
num_args
=
sizeof
...(
Ts
);
};
};
// member const function pointer
// member const function pointer
...
@@ -508,6 +509,9 @@ struct get_callable_trait_helper<T, false, false> {};
...
@@ -508,6 +509,9 @@ struct get_callable_trait_helper<T, false, false> {};
template
<
class
T
>
template
<
class
T
>
struct
get_callable_trait
:
get_callable_trait_helper
<
decay_t
<
T
>>
{};
struct
get_callable_trait
:
get_callable_trait_helper
<
decay_t
<
T
>>
{};
template
<
class
T
>
using
get_callable_trait_t
=
typename
get_callable_trait
<
T
>::
type
;
/// Checks wheter `T` is a function or member function.
/// Checks wheter `T` is a function or member function.
template
<
class
T
>
template
<
class
T
>
struct
is_callable
{
struct
is_callable
{
...
...
libcaf_core/caf/fwd.hpp
View file @
11c4eaca
...
@@ -56,6 +56,8 @@ template <class> struct timeout_definition;
...
@@ -56,6 +56,8 @@ template <class> struct timeout_definition;
template
<
class
,
class
>
class
stream_stage
;
template
<
class
,
class
>
class
stream_stage
;
template
<
class
Iterator
,
class
Sentinel
=
Iterator
>
struct
parser_state
;
// -- 3 param templates --------------------------------------------------------
// -- 3 param templates --------------------------------------------------------
template
<
class
,
class
,
int
>
class
actor_cast_access
;
template
<
class
,
class
,
int
>
class
actor_cast_access
;
...
...
libcaf_core/caf/make_config_option.hpp
View file @
11c4eaca
...
@@ -23,7 +23,7 @@
...
@@ -23,7 +23,7 @@
#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/parse.hpp"
#include "caf/detail/type_
name
.hpp"
#include "caf/detail/type_
traits
.hpp"
#include "caf/error.hpp"
#include "caf/error.hpp"
#include "caf/expected.hpp"
#include "caf/expected.hpp"
#include "caf/fwd.hpp"
#include "caf/fwd.hpp"
...
@@ -48,20 +48,22 @@ void store_impl(void* ptr, const config_value& x) {
...
@@ -48,20 +48,22 @@ void store_impl(void* ptr, const config_value& x) {
template
<
class
T
>
template
<
class
T
>
config_value
get_impl
(
const
void
*
ptr
)
{
config_value
get_impl
(
const
void
*
ptr
)
{
return
config_value
{
*
reinterpret_cast
<
const
T
*>
(
ptr
)};
using
trait
=
select_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
)
{
expected
<
config_value
>
parse_impl
(
T
*
ptr
,
string_view
str
)
{
if
(
ptr
!=
nullptr
)
{
if
(
!
ptr
)
{
if
(
auto
err
=
parse
(
str
,
*
ptr
))
return
err
;
return
config_value
{
*
ptr
};
}
T
tmp
;
T
tmp
;
if
(
auto
err
=
parse
(
str
,
tmp
))
return
parse_impl
(
&
tmp
,
str
);
return
err
;
}
return
config_value
{
std
::
move
(
tmp
)};
using
trait
=
select_config_value_access_t
<
T
>
;
string_parser_state
ps
{
str
.
begin
(),
str
.
end
()};
trait
::
parse_cli
(
ps
,
*
ptr
);
if
(
ps
.
code
!=
pec
::
success
)
return
make_error
(
ps
);
return
config_value
{
trait
::
convert
(
*
ptr
)};
}
}
expected
<
config_value
>
parse_impl
(
std
::
string
*
ptr
,
string_view
str
);
expected
<
config_value
>
parse_impl
(
std
::
string
*
ptr
,
string_view
str
);
...
@@ -73,9 +75,10 @@ expected<config_value> parse_impl_delegate(void* ptr, string_view str) {
...
@@ -73,9 +75,10 @@ expected<config_value> parse_impl_delegate(void* ptr, string_view str) {
template
<
class
T
>
template
<
class
T
>
config_option
::
meta_state
*
option_meta_state_instance
()
{
config_option
::
meta_state
*
option_meta_state_instance
()
{
using
trait
=
select_config_value_access_t
<
T
>
;
static
config_option
::
meta_state
obj
{
check_impl
<
T
>
,
store_impl
<
T
>
,
static
config_option
::
meta_state
obj
{
check_impl
<
T
>
,
store_impl
<
T
>
,
get_impl
<
T
>
,
parse_impl_delegate
<
T
>
,
get_impl
<
T
>
,
parse_impl_delegate
<
T
>
,
detail
::
type_name
<
T
>
()};
trait
::
type_name
()};
return
&
obj
;
return
&
obj
;
}
}
...
...
libcaf_core/caf/make_config_value_field.hpp
0 → 100644
View file @
11c4eaca
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| 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 <array>
#include <tuple>
#include <type_traits>
#include "caf/config_value_field.hpp"
#include "caf/detail/config_value_field_impl.hpp"
#include "caf/detail/int_list.hpp"
#include "caf/detail/type_traits.hpp"
namespace
caf
{
/// Creates a field with direct access to a member in `T` via member-to-object
/// pointer.
template
<
class
T
,
class
U
,
class
...
Args
>
detail
::
config_value_field_impl
<
U
T
::*>
make_config_value_field
(
string_view
name
,
U
T
::*
ptr
,
Args
&&
...
xs
)
{
return
{
name
,
ptr
,
std
::
forward
<
Args
>
(
xs
)...};
}
/// Creates a field with access to a member in `T` via `getter` and `setter`.
template
<
class
Getter
,
class
Setter
,
class
E
=
detail
::
enable_if_t
<!
std
::
is_member_pointer
<
Getter
>
::
value
>
,
class
...
Args
>
detail
::
config_value_field_impl
<
std
::
pair
<
Getter
,
Setter
>>
make_config_value_field
(
string_view
name
,
Getter
getter
,
Setter
setter
,
Args
&&
...
xs
)
{
return
{
name
,
std
::
move
(
getter
),
std
::
move
(
setter
),
std
::
forward
<
Args
>
(
xs
)...};
}
template
<
class
T
,
class
...
Ts
>
class
config_value_field_storage
{
public:
using
tuple_type
=
std
::
tuple
<
T
,
Ts
...
>
;
using
object_type
=
typename
T
::
object_type
;
using
indices
=
typename
detail
::
il_indices
<
tuple_type
>::
type
;
using
array_type
=
std
::
array
<
config_value_field
<
object_type
>*
,
sizeof
...(
Ts
)
+
1
>
;
template
<
class
...
Us
>
config_value_field_storage
(
T
x
,
Us
&&
...
xs
)
:
fields_
(
std
::
move
(
x
),
std
::
forward
<
Us
>
(
xs
)...)
{
init
(
detail
::
get_indices
(
fields_
));
}
config_value_field_storage
(
config_value_field_storage
&&
)
=
default
;
span
<
config_value_field
<
object_type
>*>
fields
()
{
return
make_span
(
ptr_fields_
);
}
private:
template
<
long
...
Pos
>
void
init
(
detail
::
int_list
<
Pos
...
>
)
{
ptr_fields_
=
array_type
{{
&
std
::
get
<
Pos
>
(
fields_
)...}};
}
std
::
tuple
<
T
,
Ts
...
>
fields_
;
array_type
ptr_fields_
;
};
template
<
class
...
Ts
>
config_value_field_storage
<
Ts
...
>
make_config_value_field_storage
(
Ts
...
fields
)
{
return
{
std
::
move
(
fields
)...};
}
}
// namespace caf
libcaf_core/caf/
detail/parser/
state.hpp
→
libcaf_core/caf/
parser_
state.hpp
View file @
11c4eaca
...
@@ -5,7 +5,7 @@
...
@@ -5,7 +5,7 @@
* | |___ / ___ \| _| Framework *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* \____/_/ \_|_| *
* *
* *
* Copyright 2011-201
8
Dominik Charousset *
* Copyright 2011-201
9
Dominik Charousset *
* *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* 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 *
* (at your option) under the terms and conditions of the Boost Software *
...
@@ -21,29 +21,39 @@
...
@@ -21,29 +21,39 @@
#include <cctype>
#include <cctype>
#include <cstdint>
#include <cstdint>
#include "caf/fwd.hpp"
#include "caf/pec.hpp"
#include "caf/pec.hpp"
#include "caf/string_view.hpp"
namespace
caf
{
namespace
caf
{
namespace
detail
{
namespace
parser
{
template
<
class
Iterator
,
class
Sentinel
=
Iterator
>
/// Stores all informations necessary for implementing an FSM-based parser.
struct
state
{
template
<
class
Iterator
,
class
Sentinel
>
struct
parser_state
{
/// Current position of the parser.
Iterator
i
;
Iterator
i
;
/// End-of-input marker.
Sentinel
e
;
Sentinel
e
;
/// Current state of the parser.
pec
code
;
pec
code
;
/// Current line in the input.
int32_t
line
;
int32_t
line
;
/// Position in the current line.
int32_t
column
;
int32_t
column
;
state
()
noexcept
:
i
(),
e
(),
code
(
pec
::
success
),
line
(
1
),
column
(
1
)
{
parser_
state
()
noexcept
:
i
(),
e
(),
code
(
pec
::
success
),
line
(
1
),
column
(
1
)
{
// nop
// nop
}
}
explicit
state
(
Iterator
first
)
noexcept
:
state
()
{
explicit
parser_state
(
Iterator
first
)
noexcept
:
parser_
state
()
{
i
=
first
;
i
=
first
;
}
}
state
(
Iterator
first
,
Sentinel
last
)
noexcept
:
state
()
{
parser_state
(
Iterator
first
,
Sentinel
last
)
noexcept
:
parser_
state
()
{
i
=
first
;
i
=
first
;
e
=
last
;
e
=
last
;
}
}
...
@@ -92,6 +102,15 @@ struct state {
...
@@ -92,6 +102,15 @@ struct state {
}
}
};
};
}
// namespace parser
/// Returns an error object from the current code in `ps` as well as its
}
// namespace detail
/// current position.
template
<
class
Iterator
,
class
Sentinel
>
auto
make_error
(
const
parser_state
<
Iterator
,
Sentinel
>&
ps
)
->
decltype
(
make_error
(
ps
.
code
,
ps
.
line
,
ps
.
column
))
{
return
make_error
(
ps
.
code
,
ps
.
line
,
ps
.
column
);
}
/// Specialization for parsers operating on string views.
using
string_parser_state
=
parser_state
<
string_view
::
iterator
>
;
}
// namespace caf
}
// namespace caf
libcaf_core/caf/pec.hpp
View file @
11c4eaca
...
@@ -65,6 +65,13 @@ enum class pec : uint8_t {
...
@@ -65,6 +65,13 @@ enum class pec : uint8_t {
missing_argument
,
missing_argument
,
/// Stopped because the key of a category was taken.
/// Stopped because the key of a category was taken.
illegal_category
,
illegal_category
,
/// Stopped at an unexpected field name while reading a user-defined type.
invalid_field_name
,
/// Stopped at a repeated field name while reading a user-defined type.
repeated_field_name
,
/// Stopped while reading a user-defined type with one or more missing
/// mandatory fields.
missing_field
,
};
};
/// Returns an error object from given error code.
/// Returns an error object from given error code.
...
@@ -72,7 +79,7 @@ error make_error(pec code);
...
@@ -72,7 +79,7 @@ error make_error(pec code);
/// Returns an error object from given error code with additional context
/// Returns an error object from given error code with additional context
/// information for where the parser stopped in the input.
/// information for where the parser stopped in the input.
error
make_error
(
pec
code
,
size_t
line
,
size
_t
column
);
error
make_error
(
pec
code
,
int32_t
line
,
int32
_t
column
);
/// Returns an error object from given error code with additional context
/// Returns an error object from given error code with additional context
/// information for where the parser stopped in the argument.
/// information for where the parser stopped in the argument.
...
...
libcaf_core/caf/span.hpp
View file @
11c4eaca
...
@@ -221,6 +221,13 @@ auto make_span(T& xs) -> span<detail::remove_reference_t<decltype(xs[0])>> {
...
@@ -221,6 +221,13 @@ auto make_span(T& xs) -> span<detail::remove_reference_t<decltype(xs[0])>> {
return
{
xs
.
data
(),
xs
.
size
()};
return
{
xs
.
data
(),
xs
.
size
()};
}
}
/// Convenience function to make using `caf::span` more convenient without the
/// deduction guides.
template
<
class
T
,
size_t
N
>
span
<
T
>
make_span
(
T
(
&
xs
)[
N
])
{
return
{
xs
,
N
};
}
/// Convenience function to make using `caf::span` more convenient without the
/// Convenience function to make using `caf::span` more convenient without the
/// deduction guides.
/// deduction guides.
template
<
class
T
>
template
<
class
T
>
...
...
libcaf_core/caf/uri.hpp
View file @
11c4eaca
...
@@ -22,7 +22,6 @@
...
@@ -22,7 +22,6 @@
#include <vector>
#include <vector>
#include "caf/detail/comparable.hpp"
#include "caf/detail/comparable.hpp"
#include "caf/detail/parser/state.hpp"
#include "caf/detail/unordered_flat_map.hpp"
#include "caf/detail/unordered_flat_map.hpp"
#include "caf/fwd.hpp"
#include "caf/fwd.hpp"
#include "caf/intrusive_ptr.hpp"
#include "caf/intrusive_ptr.hpp"
...
...
libcaf_core/src/actor_system_config.cpp
View file @
11c4eaca
...
@@ -494,8 +494,7 @@ error actor_system_config::parse_config(std::istream& source,
...
@@ -494,8 +494,7 @@ error actor_system_config::parse_config(std::istream& source,
if
(
!
source
)
if
(
!
source
)
return
make_error
(
sec
::
runtime_error
,
"source stream invalid"
);
return
make_error
(
sec
::
runtime_error
,
"source stream invalid"
);
detail
::
ini_consumer
consumer
{
opts
,
result
};
detail
::
ini_consumer
consumer
{
opts
,
result
};
detail
::
parser
::
state
<
ini_iter
,
ini_sentinel
>
res
;
parser_state
<
ini_iter
,
ini_sentinel
>
res
{
ini_iter
{
&
source
}};
res
.
i
=
ini_iter
{
&
source
};
detail
::
parser
::
read_ini
(
res
,
consumer
);
detail
::
parser
::
read_ini
(
res
,
consumer
);
if
(
res
.
i
!=
res
.
e
)
if
(
res
.
i
!=
res
.
e
)
return
make_error
(
res
.
code
,
res
.
line
,
res
.
column
);
return
make_error
(
res
.
code
,
res
.
line
,
res
.
column
);
...
...
libcaf_core/src/config_value.cpp
View file @
11c4eaca
...
@@ -26,7 +26,9 @@
...
@@ -26,7 +26,9 @@
#include "caf/detail/parser/read_ini.hpp"
#include "caf/detail/parser/read_ini.hpp"
#include "caf/detail/type_traits.hpp"
#include "caf/detail/type_traits.hpp"
#include "caf/expected.hpp"
#include "caf/expected.hpp"
#include "caf/parser_state.hpp"
#include "caf/pec.hpp"
#include "caf/pec.hpp"
#include "caf/string_view.hpp"
namespace
caf
{
namespace
caf
{
...
@@ -66,10 +68,8 @@ expected<config_value> config_value::parse(string_view::iterator first,
...
@@ -66,10 +68,8 @@ expected<config_value> config_value::parse(string_view::iterator first,
if
(
++
i
==
last
)
if
(
++
i
==
last
)
return
make_error
(
pec
::
unexpected_eof
);
return
make_error
(
pec
::
unexpected_eof
);
// Dispatch to parser.
// Dispatch to parser.
parser
::
state
<
string_view
::
iterator
>
res
;
detail
::
ini_value_consumer
f
;
detail
::
ini_value_consumer
f
;
res
.
i
=
i
;
string_parser_state
res
{
i
,
last
};
res
.
e
=
last
;
parser
::
read_ini_value
(
res
,
f
);
parser
::
read_ini_value
(
res
,
f
);
if
(
res
.
code
==
pec
::
success
)
if
(
res
.
code
==
pec
::
success
)
return
std
::
move
(
f
.
result
);
return
std
::
move
(
f
.
result
);
...
...
libcaf_core/src/detail/parse.cpp
View file @
11c4eaca
...
@@ -39,7 +39,7 @@
...
@@ -39,7 +39,7 @@
#include "caf/uri_builder.hpp"
#include "caf/uri_builder.hpp"
#define PARSE_IMPL(type, parser_name) \
#define PARSE_IMPL(type, parser_name) \
void parse(
parse_state& ps, type& x) {
\
void parse(
string_parser_state& ps, type& x) {
\
parser::read_##parser_name(ps, make_consumer(x)); \
parser::read_##parser_name(ps, make_consumer(x)); \
}
}
...
@@ -55,7 +55,7 @@ struct literal {
...
@@ -55,7 +55,7 @@ struct literal {
}
}
};
};
void
parse
(
parse
_state
&
ps
,
literal
&
x
)
{
void
parse
(
string_parser
_state
&
ps
,
literal
&
x
)
{
CAF_ASSERT
(
x
.
str
.
size
()
>
0
);
CAF_ASSERT
(
x
.
str
.
size
()
>
0
);
if
(
ps
.
current
()
!=
x
.
str
[
0
])
{
if
(
ps
.
current
()
!=
x
.
str
[
0
])
{
ps
.
code
=
pec
::
unexpected_character
;
ps
.
code
=
pec
::
unexpected_character
;
...
@@ -72,12 +72,12 @@ void parse(parse_state& ps, literal& x) {
...
@@ -72,12 +72,12 @@ void parse(parse_state& ps, literal& x) {
ps
.
code
=
ps
.
at_end
()
?
pec
::
success
:
pec
::
trailing_character
;
ps
.
code
=
ps
.
at_end
()
?
pec
::
success
:
pec
::
trailing_character
;
}
}
void
parse_sequence
(
parse
_state
&
)
{
void
parse_sequence
(
string_parser
_state
&
)
{
// End of recursion.
// End of recursion.
}
}
template
<
class
T
,
class
...
Ts
>
template
<
class
T
,
class
...
Ts
>
void
parse_sequence
(
parse
_state
&
ps
,
T
&&
x
,
Ts
&&
...
xs
)
{
void
parse_sequence
(
string_parser
_state
&
ps
,
T
&&
x
,
Ts
&&
...
xs
)
{
parse
(
ps
,
x
);
parse
(
ps
,
x
);
// TODO: use `if constexpr` when switching to C++17
// TODO: use `if constexpr` when switching to C++17
if
(
sizeof
...(
Ts
)
>
0
)
{
if
(
sizeof
...(
Ts
)
>
0
)
{
...
@@ -111,11 +111,11 @@ PARSE_IMPL(double, floating_point)
...
@@ -111,11 +111,11 @@ PARSE_IMPL(double, floating_point)
PARSE_IMPL
(
timespan
,
timespan
)
PARSE_IMPL
(
timespan
,
timespan
)
void
parse
(
parse
_state
&
ps
,
atom_value
&
x
)
{
void
parse
(
string_parser
_state
&
ps
,
atom_value
&
x
)
{
parser
::
read_atom
(
ps
,
make_consumer
(
x
),
true
);
parser
::
read_atom
(
ps
,
make_consumer
(
x
),
true
);
}
}
void
parse
(
parse
_state
&
ps
,
uri
&
x
)
{
void
parse
(
string_parser
_state
&
ps
,
uri
&
x
)
{
uri_builder
builder
;
uri_builder
builder
;
if
(
ps
.
consume
(
'<'
))
{
if
(
ps
.
consume
(
'<'
))
{
parser
::
read_uri
(
ps
,
builder
);
parser
::
read_uri
(
ps
,
builder
);
...
@@ -126,7 +126,7 @@ void parse(parse_state& ps, uri& x) {
...
@@ -126,7 +126,7 @@ void parse(parse_state& ps, uri& x) {
return
;
return
;
}
}
}
else
{
}
else
{
read_uri
(
ps
,
builder
);
parser
::
read_uri
(
ps
,
builder
);
}
}
if
(
ps
.
code
<=
pec
::
trailing_character
)
if
(
ps
.
code
<=
pec
::
trailing_character
)
x
=
builder
.
make
();
x
=
builder
.
make
();
...
@@ -134,7 +134,7 @@ void parse(parse_state& ps, uri& x) {
...
@@ -134,7 +134,7 @@ void parse(parse_state& ps, uri& x) {
PARSE_IMPL
(
ipv4_address
,
ipv4_address
)
PARSE_IMPL
(
ipv4_address
,
ipv4_address
)
void
parse
(
parse
_state
&
ps
,
ipv4_subnet
&
x
)
{
void
parse
(
string_parser
_state
&
ps
,
ipv4_subnet
&
x
)
{
ipv4_address
addr
;
ipv4_address
addr
;
uint8_t
prefix_length
;
uint8_t
prefix_length
;
parse_sequence
(
ps
,
addr
,
literal
{
"/"
},
prefix_length
);
parse_sequence
(
ps
,
addr
,
literal
{
"/"
},
prefix_length
);
...
@@ -147,7 +147,7 @@ void parse(parse_state& ps, ipv4_subnet& x) {
...
@@ -147,7 +147,7 @@ void parse(parse_state& ps, ipv4_subnet& x) {
}
}
}
}
void
parse
(
parse
_state
&
ps
,
ipv4_endpoint
&
x
)
{
void
parse
(
string_parser
_state
&
ps
,
ipv4_endpoint
&
x
)
{
ipv4_address
addr
;
ipv4_address
addr
;
uint16_t
port
;
uint16_t
port
;
parse_sequence
(
ps
,
addr
,
literal
{
":"
},
port
);
parse_sequence
(
ps
,
addr
,
literal
{
":"
},
port
);
...
@@ -157,7 +157,7 @@ void parse(parse_state& ps, ipv4_endpoint& x) {
...
@@ -157,7 +157,7 @@ void parse(parse_state& ps, ipv4_endpoint& x) {
PARSE_IMPL
(
ipv6_address
,
ipv6_address
)
PARSE_IMPL
(
ipv6_address
,
ipv6_address
)
void
parse
(
parse
_state
&
ps
,
ipv6_subnet
&
x
)
{
void
parse
(
string_parser
_state
&
ps
,
ipv6_subnet
&
x
)
{
// TODO: this algorithm is currently not one-pass. The reason we need to
// TODO: this algorithm is currently not one-pass. The reason we need to
// check whether the input is a valid ipv4_subnet first is that "1.2.3.0" is
// check whether the input is a valid ipv4_subnet first is that "1.2.3.0" is
// a valid IPv6 address, but "1.2.3.0/16" results in the wrong subnet when
// a valid IPv6 address, but "1.2.3.0/16" results in the wrong subnet when
...
@@ -185,7 +185,7 @@ void parse(parse_state& ps, ipv6_subnet& x) {
...
@@ -185,7 +185,7 @@ void parse(parse_state& ps, ipv6_subnet& x) {
}
}
}
}
void
parse
(
parse
_state
&
ps
,
ipv6_endpoint
&
x
)
{
void
parse
(
string_parser
_state
&
ps
,
ipv6_endpoint
&
x
)
{
ipv6_address
addr
;
ipv6_address
addr
;
uint16_t
port
;
uint16_t
port
;
if
(
ps
.
consume
(
'['
))
{
if
(
ps
.
consume
(
'['
))
{
...
@@ -200,7 +200,7 @@ void parse(parse_state& ps, ipv6_endpoint& x) {
...
@@ -200,7 +200,7 @@ void parse(parse_state& ps, ipv6_endpoint& x) {
x
=
ipv6_endpoint
{
addr
,
port
};
x
=
ipv6_endpoint
{
addr
,
port
};
}
}
void
parse
(
parse
_state
&
ps
,
std
::
string
&
x
)
{
void
parse
(
string_parser
_state
&
ps
,
std
::
string
&
x
)
{
ps
.
skip_whitespaces
();
ps
.
skip_whitespaces
();
if
(
ps
.
current
()
==
'"'
)
{
if
(
ps
.
current
()
==
'"'
)
{
parser
::
read_string
(
ps
,
make_consumer
(
x
));
parser
::
read_string
(
ps
,
make_consumer
(
x
));
...
@@ -213,7 +213,7 @@ void parse(parse_state& ps, std::string& x) {
...
@@ -213,7 +213,7 @@ void parse(parse_state& ps, std::string& x) {
ps
.
code
=
pec
::
success
;
ps
.
code
=
pec
::
success
;
}
}
void
parse_element
(
parse
_state
&
ps
,
std
::
string
&
x
,
void
parse_element
(
string_parser
_state
&
ps
,
std
::
string
&
x
,
const
char
*
char_blacklist
)
{
const
char
*
char_blacklist
)
{
ps
.
skip_whitespaces
();
ps
.
skip_whitespaces
();
if
(
ps
.
current
()
==
'"'
)
{
if
(
ps
.
current
()
==
'"'
)
{
...
...
libcaf_core/src/ipv4_address.cpp
View file @
11c4eaca
...
@@ -21,6 +21,7 @@
...
@@ -21,6 +21,7 @@
#include "caf/detail/network_order.hpp"
#include "caf/detail/network_order.hpp"
#include "caf/detail/parser/read_ipv4_address.hpp"
#include "caf/detail/parser/read_ipv4_address.hpp"
#include "caf/error.hpp"
#include "caf/error.hpp"
#include "caf/parser_state.hpp"
#include "caf/pec.hpp"
#include "caf/pec.hpp"
#include "caf/string_view.hpp"
#include "caf/string_view.hpp"
...
@@ -89,8 +90,8 @@ std::string to_string(const ipv4_address& x) {
...
@@ -89,8 +90,8 @@ std::string to_string(const ipv4_address& x) {
error
parse
(
string_view
str
,
ipv4_address
&
dest
)
{
error
parse
(
string_view
str
,
ipv4_address
&
dest
)
{
using
namespace
detail
;
using
namespace
detail
;
parser
::
state
<
string_view
::
iterator
>
res
{
str
.
begin
(),
str
.
end
()};
ipv4_address_consumer
f
{
dest
};
ipv4_address_consumer
f
{
dest
};
string_parser_state
res
{
str
.
begin
(),
str
.
end
()};
parser
::
read_ipv4_address
(
res
,
f
);
parser
::
read_ipv4_address
(
res
,
f
);
if
(
res
.
code
==
pec
::
success
)
if
(
res
.
code
==
pec
::
success
)
return
none
;
return
none
;
...
...
libcaf_core/src/ipv6_address.cpp
View file @
11c4eaca
...
@@ -23,6 +23,7 @@
...
@@ -23,6 +23,7 @@
#include "caf/detail/parser/read_ipv6_address.hpp"
#include "caf/detail/parser/read_ipv6_address.hpp"
#include "caf/error.hpp"
#include "caf/error.hpp"
#include "caf/ipv4_address.hpp"
#include "caf/ipv4_address.hpp"
#include "caf/parser_state.hpp"
#include "caf/pec.hpp"
#include "caf/pec.hpp"
#include "caf/string_view.hpp"
#include "caf/string_view.hpp"
...
@@ -212,8 +213,8 @@ std::string to_string(ipv6_address x) {
...
@@ -212,8 +213,8 @@ std::string to_string(ipv6_address x) {
error
parse
(
string_view
str
,
ipv6_address
&
dest
)
{
error
parse
(
string_view
str
,
ipv6_address
&
dest
)
{
using
namespace
detail
;
using
namespace
detail
;
parser
::
state
<
string_view
::
iterator
>
res
{
str
.
begin
(),
str
.
end
()};
ipv6_address_consumer
f
{
dest
};
ipv6_address_consumer
f
{
dest
};
string_parser_state
res
{
str
.
begin
(),
str
.
end
()};
parser
::
read_ipv6_address
(
res
,
f
);
parser
::
read_ipv6_address
(
res
,
f
);
if
(
res
.
code
==
pec
::
success
)
if
(
res
.
code
==
pec
::
success
)
return
none
;
return
none
;
...
...
libcaf_core/src/make_config_option.cpp
View file @
11c4eaca
...
@@ -24,9 +24,11 @@
...
@@ -24,9 +24,11 @@
#include "caf/optional.hpp"
#include "caf/optional.hpp"
#define DEFAULT_META(type, parse_fun) \
#define DEFAULT_META(type, parse_fun) \
config_option::meta_state type##_meta_state{ \
config_option::meta_state \
default_config_option_check<type>, default_config_option_store<type>, \
type##_meta_state{default_config_option_check<type>, \
get_impl<type>, parse_fun, detail::type_name<type>()};
default_config_option_store<type>, get_impl<type>, \
parse_fun, \
select_config_value_access_t<type>::type_name()};
using
std
::
string
;
using
std
::
string
;
...
@@ -75,43 +77,34 @@ config_value bool_get_neg(const void* ptr) {
...
@@ -75,43 +77,34 @@ config_value bool_get_neg(const void* ptr) {
}
}
meta_state
bool_neg_meta
{
detail
::
check_impl
<
bool
>
,
bool_store_neg
,
bool_get_neg
,
meta_state
bool_neg_meta
{
detail
::
check_impl
<
bool
>
,
bool_store_neg
,
bool_get_neg
,
nullptr
,
detail
::
type_name
<
bool
>
()};
nullptr
,
select_config_value_access_t
<
bool
>::
type_name
()};
meta_state
us_res_meta
{
error
check_timespan
(
const
config_value
&
x
)
{
[](
const
config_value
&
x
)
->
error
{
if
(
holds_alternative
<
timespan
>
(
x
))
if
(
holds_alternative
<
timespan
>
(
x
))
return
none
;
return
none
;
return
make_error
(
pec
::
type_mismatch
);
return
make_error
(
pec
::
type_mismatch
);
},
}
[](
void
*
ptr
,
const
config_value
&
x
)
{
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
())
*
static_cast
<
size_t
*>
(
ptr
)
=
static_cast
<
size_t
>
(
get
<
timespan
>
(
x
).
count
())
/
1000
;
/
Denominator
;
},
}
[](
const
void
*
ptr
)
->
config_value
{
template
<
uint64_t
Denominator
>
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
));
timespan
val
{
ival
*
1000
};
timespan
val
{
ival
*
Denominator
};
return
config_value
{
val
};
return
config_value
{
val
};
},
}
meta_state
us_res_meta
{
check_timespan
,
store_timespan
<
1000
>
,
get_timespan
<
1000
>
,
nullptr
,
nullptr
,
detail
::
type_name
<
timespan
>
()
select_config_value_access_t
<
timespan
>::
type_name
()};
};
meta_state
ms_res_meta
{[](
const
config_value
&
x
)
->
error
{
meta_state
ms_res_meta
{
check_timespan
,
store_timespan
<
1000000
>
,
if
(
holds_alternative
<
timespan
>
(
x
))
get_timespan
<
1000000
>
,
nullptr
,
return
none
;
select_config_value_access_t
<
timespan
>::
type_name
()};
return
make_error
(
pec
::
type_mismatch
);
},
[](
void
*
ptr
,
const
config_value
&
x
)
{
*
static_cast
<
size_t
*>
(
ptr
)
=
static_cast
<
size_t
>
(
get
<
timespan
>
(
x
).
count
()
/
1000000
);
},
[](
const
void
*
ptr
)
->
config_value
{
auto
ival
=
static_cast
<
int64_t
>
(
*
static_cast
<
const
size_t
*>
(
ptr
));
timespan
val
{
ival
*
1000000
};
return
config_value
{
val
};
},
nullptr
,
detail
::
type_name
<
timespan
>
()};
}
// namespace
}
// namespace
...
...
libcaf_core/src/pec.cpp
View file @
11c4eaca
...
@@ -29,7 +29,7 @@ error make_error(pec code) {
...
@@ -29,7 +29,7 @@ error make_error(pec code) {
return
{
static_cast
<
uint8_t
>
(
code
),
atom
(
"parser"
)};
return
{
static_cast
<
uint8_t
>
(
code
),
atom
(
"parser"
)};
}
}
error
make_error
(
pec
code
,
size_t
line
,
size
_t
column
)
{
error
make_error
(
pec
code
,
int32_t
line
,
int32
_t
column
)
{
config_value
::
dictionary
context
;
config_value
::
dictionary
context
;
context
[
"line"
]
=
line
;
context
[
"line"
]
=
line
;
context
[
"column"
]
=
column
;
context
[
"column"
]
=
column
;
...
...
libcaf_core/src/uri.cpp
View file @
11c4eaca
...
@@ -146,12 +146,11 @@ std::string to_string(const uri::authority_type& x) {
...
@@ -146,12 +146,11 @@ std::string to_string(const uri::authority_type& x) {
}
}
error
parse
(
string_view
str
,
uri
&
dest
)
{
error
parse
(
string_view
str
,
uri
&
dest
)
{
detail
::
parse
_state
ps
{
str
.
begin
(),
str
.
end
()};
string_parser
_state
ps
{
str
.
begin
(),
str
.
end
()};
parse
(
ps
,
dest
);
parse
(
ps
,
dest
);
if
(
ps
.
code
==
pec
::
success
)
if
(
ps
.
code
==
pec
::
success
)
return
none
;
return
none
;
return
make_error
(
ps
.
code
,
static_cast
<
size_t
>
(
ps
.
line
),
return
make_error
(
ps
);
static_cast
<
size_t
>
(
ps
.
column
));
}
}
expected
<
uri
>
make_uri
(
string_view
str
)
{
expected
<
uri
>
make_uri
(
string_view
str
)
{
...
...
libcaf_core/test/config_option.cpp
View file @
11c4eaca
...
@@ -185,7 +185,6 @@ CAF_TEST(type timespan) {
...
@@ -185,7 +185,6 @@ CAF_TEST(type timespan) {
CAF_TEST
(
lists
)
{
CAF_TEST
(
lists
)
{
using
int_list
=
std
::
vector
<
int
>
;
using
int_list
=
std
::
vector
<
int
>
;
CAF_CHECK_EQUAL
(
read
<
int_list
>
(
""
),
int_list
({}));
CAF_CHECK_EQUAL
(
read
<
int_list
>
(
"[]"
),
int_list
({}));
CAF_CHECK_EQUAL
(
read
<
int_list
>
(
"[]"
),
int_list
({}));
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
<
int_list
>
(
"[1, 2, 3]"
),
int_list
({
1
,
2
,
3
}));
CAF_CHECK_EQUAL
(
read
<
int_list
>
(
"[1, 2, 3]"
),
int_list
({
1
,
2
,
3
}));
...
...
libcaf_core/test/detail/ini_consumer.cpp
View file @
11c4eaca
...
@@ -33,7 +33,7 @@ using ls = std::vector<std::string>;
...
@@ -33,7 +33,7 @@ using ls = std::vector<std::string>;
namespace
{
namespace
{
const
char
test_ini
[]
=
R"(
const
expr
const
string_view
test_ini
=
R"(
is_server=true
is_server=true
port=4242
port=4242
nodes=["sun", "venus", ]
nodes=["sun", "venus", ]
...
@@ -44,7 +44,7 @@ file-name = "foobar.ini" ; our file name
...
@@ -44,7 +44,7 @@ file-name = "foobar.ini" ; our file name
impl = 'foo';some atom
impl = 'foo';some atom
)"
;
)"
;
const
char
test_ini2
[]
=
R"(
const
expr
const
string_view
test_ini2
=
R"(
is_server = true
is_server = true
logger = {
logger = {
file-name = "foobar.ini"
file-name = "foobar.ini"
...
@@ -58,7 +58,6 @@ nodes = ["sun", "venus"]
...
@@ -58,7 +58,6 @@ nodes = ["sun", "venus"]
)"
;
)"
;
struct
fixture
{
struct
fixture
{
detail
::
parser
::
state
<
std
::
string
::
const_iterator
>
res
;
config_option_set
options
;
config_option_set
options
;
settings
config
;
settings
config
;
...
@@ -78,20 +77,18 @@ struct fixture {
...
@@ -78,20 +77,18 @@ struct fixture {
CAF_TEST_FIXTURE_SCOPE
(
ini_consumer_tests
,
fixture
)
CAF_TEST_FIXTURE_SCOPE
(
ini_consumer_tests
,
fixture
)
CAF_TEST
(
ini_value_consumer
)
{
CAF_TEST
(
ini_value_consumer
)
{
st
d
::
string
str
=
R"("hello world")"
;
st
ring_view
str
=
R"("hello world")"
;
detail
::
ini_value_consumer
consumer
;
detail
::
ini_value_consumer
consumer
;
res
.
i
=
str
.
begin
();
string_parser_state
res
{
str
.
begin
(),
str
.
end
()};
res
.
e
=
str
.
end
();
detail
::
parser
::
read_ini_value
(
res
,
consumer
);
detail
::
parser
::
read_ini_value
(
res
,
consumer
);
CAF_CHECK_EQUAL
(
res
.
code
,
pec
::
success
);
CAF_CHECK_EQUAL
(
res
.
code
,
pec
::
success
);
CAF_CHECK_EQUAL
(
get
<
string
>
(
consumer
.
result
),
"hello world"
);
CAF_CHECK_EQUAL
(
get
<
string
>
(
consumer
.
result
),
"hello world"
);
}
}
CAF_TEST
(
ini_consumer
)
{
CAF_TEST
(
ini_consumer
)
{
st
d
::
string
str
=
test_ini
;
st
ring_view
str
=
test_ini
;
detail
::
ini_consumer
consumer
{
options
,
config
};
detail
::
ini_consumer
consumer
{
options
,
config
};
res
.
i
=
str
.
begin
();
string_parser_state
res
{
str
.
begin
(),
str
.
end
()};
res
.
e
=
str
.
end
();
detail
::
parser
::
read_ini
(
res
,
consumer
);
detail
::
parser
::
read_ini
(
res
,
consumer
);
CAF_CHECK_EQUAL
(
res
.
code
,
pec
::
success
);
CAF_CHECK_EQUAL
(
res
.
code
,
pec
::
success
);
CAF_CHECK_EQUAL
(
get
<
bool
>
(
config
,
"is_server"
),
true
);
CAF_CHECK_EQUAL
(
get
<
bool
>
(
config
,
"is_server"
),
true
);
...
@@ -103,12 +100,11 @@ CAF_TEST(ini_consumer) {
...
@@ -103,12 +100,11 @@ CAF_TEST(ini_consumer) {
}
}
CAF_TEST
(
simplified
syntax
)
{
CAF_TEST
(
simplified
syntax
)
{
st
d
::
string
str
=
test_ini
;
st
ring_view
str
=
test_ini
;
CAF_MESSAGE
(
"read test_ini"
);
CAF_MESSAGE
(
"read test_ini"
);
{
{
detail
::
ini_consumer
consumer
{
options
,
config
};
detail
::
ini_consumer
consumer
{
options
,
config
};
res
.
i
=
str
.
begin
();
string_parser_state
res
{
str
.
begin
(),
str
.
end
()};
res
.
e
=
str
.
end
();
detail
::
parser
::
read_ini
(
res
,
consumer
);
detail
::
parser
::
read_ini
(
res
,
consumer
);
CAF_CHECK_EQUAL
(
res
.
code
,
pec
::
success
);
CAF_CHECK_EQUAL
(
res
.
code
,
pec
::
success
);
}
}
...
@@ -117,8 +113,7 @@ CAF_TEST(simplified syntax) {
...
@@ -117,8 +113,7 @@ CAF_TEST(simplified syntax) {
CAF_MESSAGE
(
"read test_ini2"
);
CAF_MESSAGE
(
"read test_ini2"
);
{
{
detail
::
ini_consumer
consumer
{
options
,
config2
};
detail
::
ini_consumer
consumer
{
options
,
config2
};
res
.
i
=
str
.
begin
();
string_parser_state
res
{
str
.
begin
(),
str
.
end
()};
res
.
e
=
str
.
end
();
detail
::
parser
::
read_ini
(
res
,
consumer
);
detail
::
parser
::
read_ini
(
res
,
consumer
);
CAF_CHECK_EQUAL
(
res
.
code
,
pec
::
success
);
CAF_CHECK_EQUAL
(
res
.
code
,
pec
::
success
);
}
}
...
...
libcaf_core/test/detail/parse.cpp
View file @
11c4eaca
...
@@ -61,11 +61,11 @@ timespan operator"" _h(unsigned long long x) {
...
@@ -61,11 +61,11 @@ timespan operator"" _h(unsigned long long x) {
template
<
class
T
>
template
<
class
T
>
expected
<
T
>
read
(
string_view
str
)
{
expected
<
T
>
read
(
string_view
str
)
{
T
result
;
T
result
;
detail
::
parse
_state
ps
{
str
.
begin
(),
str
.
end
()};
string_parser
_state
ps
{
str
.
begin
(),
str
.
end
()};
detail
::
parse
(
ps
,
result
);
detail
::
parse
(
ps
,
result
);
if
(
ps
.
code
==
pec
::
success
)
if
(
ps
.
code
==
pec
::
success
)
return
result
;
return
result
;
return
make_error
(
ps
.
code
,
ps
.
line
,
ps
.
column
);
return
make_error
(
ps
);
}
}
}
// namespace
}
// namespace
...
...
libcaf_core/test/detail/parser/read_atom.cpp
View file @
11c4eaca
...
@@ -24,6 +24,8 @@
...
@@ -24,6 +24,8 @@
#include <string>
#include <string>
#include "caf/parser_state.hpp"
#include "caf/string_view.hpp"
#include "caf/variant.hpp"
#include "caf/variant.hpp"
using
namespace
caf
;
using
namespace
caf
;
...
@@ -40,11 +42,9 @@ struct atom_parser_consumer {
...
@@ -40,11 +42,9 @@ struct atom_parser_consumer {
using
res_t
=
variant
<
pec
,
atom_value
>
;
using
res_t
=
variant
<
pec
,
atom_value
>
;
struct
atom_parser
{
struct
atom_parser
{
res_t
operator
()(
std
::
string
str
)
{
res_t
operator
()(
string_view
str
)
{
detail
::
parser
::
state
<
std
::
string
::
iterator
>
res
;
atom_parser_consumer
f
;
atom_parser_consumer
f
;
res
.
i
=
str
.
begin
();
string_parser_state
res
{
str
.
begin
(),
str
.
end
()};
res
.
e
=
str
.
end
();
detail
::
parser
::
read_atom
(
res
,
f
);
detail
::
parser
::
read_atom
(
res
,
f
);
if
(
res
.
code
==
pec
::
success
)
if
(
res
.
code
==
pec
::
success
)
return
f
.
x
;
return
f
.
x
;
...
...
libcaf_core/test/detail/parser/read_bool.cpp
View file @
11c4eaca
...
@@ -24,6 +24,8 @@
...
@@ -24,6 +24,8 @@
#include <string>
#include <string>
#include "caf/parser_state.hpp"
#include "caf/string_view.hpp"
#include "caf/variant.hpp"
#include "caf/variant.hpp"
using
namespace
caf
;
using
namespace
caf
;
...
@@ -40,11 +42,9 @@ struct bool_parser_consumer {
...
@@ -40,11 +42,9 @@ struct bool_parser_consumer {
using
res_t
=
variant
<
pec
,
bool
>
;
using
res_t
=
variant
<
pec
,
bool
>
;
struct
bool_parser
{
struct
bool_parser
{
res_t
operator
()(
std
::
string
str
)
{
res_t
operator
()(
string_view
str
)
{
detail
::
parser
::
state
<
std
::
string
::
iterator
>
res
;
bool_parser_consumer
f
;
bool_parser_consumer
f
;
res
.
i
=
str
.
begin
();
string_parser_state
res
{
str
.
begin
(),
str
.
end
()};
res
.
e
=
str
.
end
();
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
;
...
...
libcaf_core/test/detail/parser/read_floating_point.cpp
View file @
11c4eaca
...
@@ -24,8 +24,9 @@
...
@@ -24,8 +24,9 @@
#include <string>
#include <string>
#include "caf/detail/parser/state.hpp"
#include "caf/parser_state.hpp"
#include "caf/pec.hpp"
#include "caf/string_view.hpp"
#include "caf/variant.hpp"
using
namespace
caf
;
using
namespace
caf
;
...
@@ -43,7 +44,7 @@ struct double_consumer {
...
@@ -43,7 +44,7 @@ struct double_consumer {
optional
<
double
>
read
(
string_view
str
)
{
optional
<
double
>
read
(
string_view
str
)
{
double_consumer
consumer
;
double_consumer
consumer
;
detail
::
parser
::
state
<
string_view
::
iterator
>
ps
{
str
.
begin
(),
str
.
end
()};
string_parser_state
ps
{
str
.
begin
(),
str
.
end
()};
detail
::
parser
::
read_floating_point
(
ps
,
consumer
);
detail
::
parser
::
read_floating_point
(
ps
,
consumer
);
if
(
ps
.
code
!=
pec
::
success
)
if
(
ps
.
code
!=
pec
::
success
)
return
none
;
return
none
;
...
...
libcaf_core/test/detail/parser/read_ini.cpp
View file @
11c4eaca
...
@@ -25,6 +25,11 @@
...
@@ -25,6 +25,11 @@
#include <string>
#include <string>
#include <vector>
#include <vector>
#include "caf/config_value.hpp"
#include "caf/parser_state.hpp"
#include "caf/pec.hpp"
#include "caf/string_view.hpp"
using
namespace
caf
;
using
namespace
caf
;
namespace
{
namespace
{
...
@@ -85,11 +90,9 @@ struct ini_consumer {
...
@@ -85,11 +90,9 @@ struct ini_consumer {
};
};
struct
fixture
{
struct
fixture
{
expected
<
log_type
>
parse
(
std
::
string
str
,
bool
expect_success
=
true
)
{
expected
<
log_type
>
parse
(
string_view
str
,
bool
expect_success
=
true
)
{
detail
::
parser
::
state
<
std
::
string
::
iterator
>
res
;
test_consumer
f
;
test_consumer
f
;
res
.
i
=
str
.
begin
();
string_parser_state
res
{
str
.
begin
(),
str
.
end
()};
res
.
e
=
str
.
end
();
detail
::
parser
::
read_ini
(
res
,
f
);
detail
::
parser
::
read_ini
(
res
,
f
);
if
((
res
.
code
==
pec
::
success
)
!=
expect_success
)
{
if
((
res
.
code
==
pec
::
success
)
!=
expect_success
)
{
CAF_MESSAGE
(
"unexpected parser result state: "
<<
res
.
code
);
CAF_MESSAGE
(
"unexpected parser result state: "
<<
res
.
code
);
...
@@ -105,7 +108,7 @@ log_type make_log(Ts&&... xs) {
...
@@ -105,7 +108,7 @@ log_type make_log(Ts&&... xs) {
}
}
// Tests basic functionality.
// Tests basic functionality.
const
auto
ini0
=
R"(
const
expr
const
string_view
ini0
=
R"(
[1group]
[1group]
1value=321
1value=321
[_foo]
[_foo]
...
@@ -204,7 +207,7 @@ const auto ini0_log = make_log(
...
@@ -204,7 +207,7 @@ const auto ini0_log = make_log(
// clang-format on
// clang-format on
// Tests nested parameters.
// Tests nested parameters.
const
auto
ini1
=
R"(
const
expr
const
string_view
ini1
=
R"(
foo {
foo {
bar = {
bar = {
value1 = 1
value1 = 1
...
@@ -241,11 +244,11 @@ const auto ini1_log = make_log(
...
@@ -241,11 +244,11 @@ const auto ini1_log = make_log(
);
);
// clang-format on
// clang-format on
const
auto
ini2
=
"#"
;
const
expr
const
string_view
ini2
=
"#"
;
const
auto
ini2_log
=
make_log
();
const
auto
ini2_log
=
make_log
();
const
auto
ini3
=
"; foobar
\n
!"
;
const
expr
const
string_view
ini3
=
"; foobar
\n
!"
;
const
auto
ini3_log
=
make_log
();
const
auto
ini3_log
=
make_log
();
...
...
libcaf_core/test/detail/parser/read_number.cpp
View file @
11c4eaca
...
@@ -27,7 +27,9 @@
...
@@ -27,7 +27,9 @@
#include "caf/detail/parser/add_ascii.hpp"
#include "caf/detail/parser/add_ascii.hpp"
#include "caf/detail/parser/sub_ascii.hpp"
#include "caf/detail/parser/sub_ascii.hpp"
#include "caf/expected.hpp"
#include "caf/expected.hpp"
#include "caf/parser_state.hpp"
#include "caf/pec.hpp"
#include "caf/pec.hpp"
#include "caf/string_view.hpp"
#include "caf/variant.hpp"
#include "caf/variant.hpp"
using
namespace
caf
;
using
namespace
caf
;
...
@@ -67,11 +69,9 @@ bool operator==(const res_t& x, const res_t& y) {
...
@@ -67,11 +69,9 @@ bool operator==(const res_t& x, const res_t& y) {
}
}
struct
numbers_parser
{
struct
numbers_parser
{
res_t
operator
()(
std
::
string
str
)
{
res_t
operator
()(
string_view
str
)
{
detail
::
parser
::
state
<
std
::
string
::
iterator
>
res
;
numbers_parser_consumer
f
;
numbers_parser_consumer
f
;
res
.
i
=
str
.
begin
();
string_parser_state
res
{
str
.
begin
(),
str
.
end
()};
res
.
e
=
str
.
end
();
detail
::
parser
::
read_number
(
res
,
f
);
detail
::
parser
::
read_number
(
res
,
f
);
if
(
res
.
code
==
pec
::
success
)
if
(
res
.
code
==
pec
::
success
)
return
f
.
x
;
return
f
.
x
;
...
...
libcaf_core/test/detail/parser/read_number_or_timespan.cpp
View file @
11c4eaca
...
@@ -24,6 +24,8 @@
...
@@ -24,6 +24,8 @@
#include <string>
#include <string>
#include "caf/parser_state.hpp"
#include "caf/string_view.hpp"
#include "caf/variant.hpp"
#include "caf/variant.hpp"
using
namespace
caf
;
using
namespace
caf
;
...
@@ -68,11 +70,9 @@ bool operator==(const res_t& x, const res_t& y) {
...
@@ -68,11 +70,9 @@ bool operator==(const res_t& x, const res_t& y) {
}
}
struct
number_or_timespan_parser
{
struct
number_or_timespan_parser
{
res_t
operator
()(
std
::
string
str
)
{
res_t
operator
()(
string_view
str
)
{
detail
::
parser
::
state
<
std
::
string
::
iterator
>
res
;
number_or_timespan_parser_consumer
f
;
number_or_timespan_parser_consumer
f
;
res
.
i
=
str
.
begin
();
string_parser_state
res
{
str
.
begin
(),
str
.
end
()};
res
.
e
=
str
.
end
();
detail
::
parser
::
read_number_or_timespan
(
res
,
f
);
detail
::
parser
::
read_number_or_timespan
(
res
,
f
);
if
(
res
.
code
==
pec
::
success
)
if
(
res
.
code
==
pec
::
success
)
return
f
.
x
;
return
f
.
x
;
...
...
libcaf_core/test/detail/parser/read_signed_integer.cpp
View file @
11c4eaca
...
@@ -22,8 +22,9 @@
...
@@ -22,8 +22,9 @@
#include "caf/test/dsl.hpp"
#include "caf/test/dsl.hpp"
#include "caf/
detail/parser/
state.hpp"
#include "caf/
parser_
state.hpp"
#include "caf/string_view.hpp"
#include "caf/string_view.hpp"
#include "caf/variant.hpp"
using
namespace
caf
;
using
namespace
caf
;
...
@@ -43,7 +44,7 @@ struct signed_integer_consumer {
...
@@ -43,7 +44,7 @@ struct signed_integer_consumer {
template
<
class
T
>
template
<
class
T
>
optional
<
T
>
read
(
string_view
str
)
{
optional
<
T
>
read
(
string_view
str
)
{
signed_integer_consumer
<
T
>
consumer
;
signed_integer_consumer
<
T
>
consumer
;
detail
::
parser
::
state
<
string_view
::
iterator
>
ps
{
str
.
begin
(),
str
.
end
()};
string_parser_state
ps
{
str
.
begin
(),
str
.
end
()};
detail
::
parser
::
read_signed_integer
(
ps
,
consumer
);
detail
::
parser
::
read_signed_integer
(
ps
,
consumer
);
if
(
ps
.
code
!=
pec
::
success
)
if
(
ps
.
code
!=
pec
::
success
)
return
none
;
return
none
;
...
@@ -53,7 +54,7 @@ optional<T> read(string_view str) {
...
@@ -53,7 +54,7 @@ optional<T> read(string_view str) {
template
<
class
T
>
template
<
class
T
>
bool
underflow
(
string_view
str
)
{
bool
underflow
(
string_view
str
)
{
signed_integer_consumer
<
T
>
consumer
;
signed_integer_consumer
<
T
>
consumer
;
detail
::
parser
::
state
<
string_view
::
iterator
>
ps
{
str
.
begin
(),
str
.
end
()};
string_parser_state
ps
{
str
.
begin
(),
str
.
end
()};
detail
::
parser
::
read_signed_integer
(
ps
,
consumer
);
detail
::
parser
::
read_signed_integer
(
ps
,
consumer
);
return
ps
.
code
==
pec
::
integer_underflow
;
return
ps
.
code
==
pec
::
integer_underflow
;
}
}
...
@@ -61,7 +62,7 @@ bool underflow(string_view str) {
...
@@ -61,7 +62,7 @@ bool underflow(string_view str) {
template
<
class
T
>
template
<
class
T
>
bool
overflow
(
string_view
str
)
{
bool
overflow
(
string_view
str
)
{
signed_integer_consumer
<
T
>
consumer
;
signed_integer_consumer
<
T
>
consumer
;
detail
::
parser
::
state
<
string_view
::
iterator
>
ps
{
str
.
begin
(),
str
.
end
()};
string_parser_state
ps
{
str
.
begin
(),
str
.
end
()};
detail
::
parser
::
read_signed_integer
(
ps
,
consumer
);
detail
::
parser
::
read_signed_integer
(
ps
,
consumer
);
return
ps
.
code
==
pec
::
integer_overflow
;
return
ps
.
code
==
pec
::
integer_overflow
;
}
}
...
...
libcaf_core/test/detail/parser/read_string.cpp
View file @
11c4eaca
...
@@ -24,6 +24,8 @@
...
@@ -24,6 +24,8 @@
#include <string>
#include <string>
#include "caf/parser_state.hpp"
#include "caf/string_view.hpp"
#include "caf/variant.hpp"
#include "caf/variant.hpp"
using
namespace
caf
;
using
namespace
caf
;
...
@@ -40,11 +42,9 @@ struct string_parser_consumer {
...
@@ -40,11 +42,9 @@ struct string_parser_consumer {
using
res_t
=
variant
<
pec
,
std
::
string
>
;
using
res_t
=
variant
<
pec
,
std
::
string
>
;
struct
string_parser
{
struct
string_parser
{
res_t
operator
()(
std
::
string
str
)
{
res_t
operator
()(
string_view
str
)
{
detail
::
parser
::
state
<
std
::
string
::
iterator
>
res
;
string_parser_consumer
f
;
string_parser_consumer
f
;
res
.
i
=
str
.
begin
();
string_parser_state
res
{
str
.
begin
(),
str
.
end
()};
res
.
e
=
str
.
end
();
detail
::
parser
::
read_string
(
res
,
f
);
detail
::
parser
::
read_string
(
res
,
f
);
if
(
res
.
code
==
pec
::
success
)
if
(
res
.
code
==
pec
::
success
)
return
f
.
x
;
return
f
.
x
;
...
...
libcaf_core/test/detail/parser/read_timespan.cpp
View file @
11c4eaca
...
@@ -24,6 +24,10 @@
...
@@ -24,6 +24,10 @@
#include <chrono>
#include <chrono>
#include "caf/parser_state.hpp"
#include "caf/string_view.hpp"
#include "caf/variant.hpp"
using
namespace
caf
;
using
namespace
caf
;
namespace
{
namespace
{
...
@@ -62,7 +66,7 @@ struct timespan_consumer {
...
@@ -62,7 +66,7 @@ struct timespan_consumer {
optional
<
timespan
>
read
(
string_view
str
)
{
optional
<
timespan
>
read
(
string_view
str
)
{
timespan_consumer
consumer
;
timespan_consumer
consumer
;
detail
::
parser
::
state
<
string_view
::
iterator
>
ps
{
str
.
begin
(),
str
.
end
()};
string_parser_state
ps
{
str
.
begin
(),
str
.
end
()};
detail
::
parser
::
read_timespan
(
ps
,
consumer
);
detail
::
parser
::
read_timespan
(
ps
,
consumer
);
if
(
ps
.
code
!=
pec
::
success
)
if
(
ps
.
code
!=
pec
::
success
)
return
none
;
return
none
;
...
...
libcaf_core/test/detail/parser/read_unsigned_integer.cpp
View file @
11c4eaca
...
@@ -22,8 +22,9 @@
...
@@ -22,8 +22,9 @@
#include "caf/test/dsl.hpp"
#include "caf/test/dsl.hpp"
#include "caf/
detail/parser/
state.hpp"
#include "caf/
parser_
state.hpp"
#include "caf/string_view.hpp"
#include "caf/string_view.hpp"
#include "caf/variant.hpp"
using
namespace
caf
;
using
namespace
caf
;
...
@@ -43,7 +44,7 @@ struct unsigned_integer_consumer {
...
@@ -43,7 +44,7 @@ struct unsigned_integer_consumer {
template
<
class
T
>
template
<
class
T
>
optional
<
T
>
read
(
string_view
str
)
{
optional
<
T
>
read
(
string_view
str
)
{
unsigned_integer_consumer
<
T
>
consumer
;
unsigned_integer_consumer
<
T
>
consumer
;
detail
::
parser
::
state
<
string_view
::
iterator
>
ps
{
str
.
begin
(),
str
.
end
()};
string_parser_state
ps
{
str
.
begin
(),
str
.
end
()};
detail
::
parser
::
read_unsigned_integer
(
ps
,
consumer
);
detail
::
parser
::
read_unsigned_integer
(
ps
,
consumer
);
if
(
ps
.
code
!=
pec
::
success
)
if
(
ps
.
code
!=
pec
::
success
)
return
none
;
return
none
;
...
@@ -53,7 +54,7 @@ optional<T> read(string_view str) {
...
@@ -53,7 +54,7 @@ optional<T> read(string_view str) {
template
<
class
T
>
template
<
class
T
>
bool
overflow
(
string_view
str
)
{
bool
overflow
(
string_view
str
)
{
unsigned_integer_consumer
<
T
>
consumer
;
unsigned_integer_consumer
<
T
>
consumer
;
detail
::
parser
::
state
<
string_view
::
iterator
>
ps
{
str
.
begin
(),
str
.
end
()};
string_parser_state
ps
{
str
.
begin
(),
str
.
end
()};
detail
::
parser
::
read_unsigned_integer
(
ps
,
consumer
);
detail
::
parser
::
read_unsigned_integer
(
ps
,
consumer
);
return
ps
.
code
==
pec
::
integer_overflow
;
return
ps
.
code
==
pec
::
integer_overflow
;
}
}
...
...
libcaf_core/test/make_config_value_field.cpp
0 → 100644
View file @
11c4eaca
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| 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. *
******************************************************************************/
#define CAF_SUITE make_config_value_field
#include "caf/make_config_value_field.hpp"
#include "caf/test/dsl.hpp"
#include "caf/config_option_set.hpp"
#include "caf/config_value_object_access.hpp"
using
namespace
caf
;
namespace
{
struct
foobar
{
int
foo
=
0
;
std
::
string
bar
;
foobar
()
=
default
;
foobar
(
int
foo
,
std
::
string
bar
)
:
foo
(
foo
),
bar
(
std
::
move
(
bar
))
{
// nop
}
};
std
::
string
to_string
(
const
foobar
&
x
)
{
return
deep_to_string
(
std
::
forward_as_tuple
(
x
.
foo
,
x
.
bar
));
}
bool
operator
==
(
const
foobar
&
x
,
const
foobar
&
y
)
{
return
x
.
foo
==
y
.
foo
&&
x
.
bar
==
y
.
bar
;
}
bool
foo_valid
(
const
int
&
x
)
{
return
x
>=
0
;
}
int
get_foo_fun
(
foobar
x
)
{
return
x
.
foo
;
}
void
set_foo_fun
(
foobar
&
x
,
const
int
&
value
)
{
x
.
foo
=
value
;
}
struct
get_foo_t
{
int
operator
()(
const
foobar
&
x
)
const
noexcept
{
return
x
.
foo
;
}
};
struct
set_foo_t
{
int
&
operator
()(
foobar
&
x
,
int
value
)
const
noexcept
{
x
.
foo
=
value
;
return
x
.
foo
;
}
};
struct
foobar_trait
{
using
object_type
=
foobar
;
static
std
::
string
type_name
()
{
return
"foobar"
;
}
static
span
<
config_value_field
<
object_type
>*>
fields
()
{
static
auto
singleton
=
make_config_value_field_storage
(
make_config_value_field
(
"foo"
,
&
foobar
::
foo
,
123
),
make_config_value_field
(
"bar"
,
&
foobar
::
bar
));
return
singleton
.
fields
();
}
};
struct
foobar_foobar
{
foobar
x
;
foobar
y
;
foobar_foobar
()
=
default
;
foobar_foobar
(
foobar
x
,
foobar
y
)
:
x
(
x
),
y
(
y
)
{
// nop
}
};
std
::
string
to_string
(
const
foobar_foobar
&
x
)
{
return
deep_to_string
(
std
::
forward_as_tuple
(
x
.
x
,
x
.
y
));
}
bool
operator
==
(
const
foobar_foobar
&
x
,
const
foobar_foobar
&
y
)
{
return
x
.
x
==
y
.
x
&&
x
.
y
==
y
.
y
;
}
struct
foobar_foobar_trait
{
using
object_type
=
foobar_foobar
;
static
std
::
string
type_name
()
{
return
"foobar-foobar"
;
}
static
span
<
config_value_field
<
object_type
>*>
fields
()
{
static
auto
singleton
=
make_config_value_field_storage
(
make_config_value_field
(
"x"
,
&
foobar_foobar
::
x
),
make_config_value_field
(
"y"
,
&
foobar_foobar
::
y
));
return
singleton
.
fields
();
}
};
struct
fixture
{
get_foo_t
get_foo
;
set_foo_t
set_foo
;
config_option_set
opts
;
void
test_foo_field
(
config_value_field
<
foobar
>&
foo_field
)
{
foobar
x
;
CAF_CHECK_EQUAL
(
foo_field
.
name
(),
"foo"
);
CAF_REQUIRE
(
foo_field
.
has_default
());
CAF_CHECK
(
foo_field
.
valid
(
x
));
CAF_CHECK_EQUAL
(
foo_field
.
get
(
x
),
config_value
(
0
));
foo_field
.
set_default
(
x
);
CAF_CHECK_EQUAL
(
foo_field
.
get
(
x
),
config_value
(
42
));
CAF_CHECK
(
!
foo_field
.
type_check
(
config_value
(
1.
)));
CAF_CHECK
(
foo_field
.
type_check
(
config_value
(
-
1
)));
foo_field
.
set
(
x
,
config_value
(
-
1
));
CAF_CHECK_EQUAL
(
foo_field
.
get
(
x
),
config_value
(
-
1
));
CAF_CHECK
(
!
foo_field
.
valid
(
x
));
string_view
input
=
"123"
;
string_parser_state
ps
{
input
.
begin
(),
input
.
end
()};
foo_field
.
parse_cli
(
ps
,
x
);
CAF_CHECK_EQUAL
(
ps
.
code
,
pec
::
success
);
CAF_CHECK_EQUAL
(
foo_field
.
get
(
x
),
config_value
(
123
));
}
template
<
class
T
>
expected
<
T
>
read
(
std
::
vector
<
std
::
string
>
args
)
{
settings
cfg
;
auto
res
=
opts
.
parse
(
cfg
,
args
);
if
(
res
.
first
!=
pec
::
success
)
return
make_error
(
res
.
first
,
*
res
.
second
);
auto
x
=
get_if
<
T
>
(
&
cfg
,
"value"
);
if
(
x
==
none
)
return
sec
::
invalid_argument
;
return
*
x
;
};
};
}
// namespace
namespace
caf
{
template
<
>
struct
config_value_access
<
foobar
>
:
config_value_object_access
<
foobar_trait
>
{
};
template
<
>
struct
config_value_access
<
foobar_foobar
>
:
config_value_object_access
<
foobar_foobar_trait
>
{};
}
// namespace caf
CAF_TEST_FIXTURE_SCOPE
(
make_config_value_field_tests
,
fixture
)
CAF_TEST
(
construction
from
pointer
to
member
)
{
make_config_value_field
(
"foo"
,
&
foobar
::
foo
);
make_config_value_field
(
"foo"
,
&
foobar
::
foo
,
none
);
make_config_value_field
(
"foo"
,
&
foobar
::
foo
,
none
,
nullptr
);
make_config_value_field
(
"foo"
,
&
foobar
::
foo
,
42
);
make_config_value_field
(
"foo"
,
&
foobar
::
foo
,
42
,
nullptr
);
make_config_value_field
(
"foo"
,
&
foobar
::
foo
,
42
,
foo_valid
);
make_config_value_field
(
"foo"
,
&
foobar
::
foo
,
42
,
[](
const
int
&
x
)
{
return
x
!=
0
;
});
}
CAF_TEST
(
pointer
to
member
access
)
{
auto
foo_field
=
make_config_value_field
(
"foo"
,
&
foobar
::
foo
,
42
,
foo_valid
);
test_foo_field
(
foo_field
);
}
CAF_TEST
(
construction
from
getter
and
setter
)
{
auto
get_foo_lambda
=
[](
const
foobar
&
x
)
{
return
x
.
foo
;
};
auto
set_foo_lambda
=
[](
foobar
&
x
,
int
value
)
{
x
.
foo
=
value
;
};
make_config_value_field
(
"foo"
,
get_foo
,
set_foo
);
make_config_value_field
(
"foo"
,
get_foo_fun
,
set_foo
);
make_config_value_field
(
"foo"
,
get_foo_fun
,
set_foo_fun
);
make_config_value_field
(
"foo"
,
get_foo_lambda
,
set_foo_lambda
);
}
CAF_TEST
(
getter
and
setter
access
)
{
auto
foo_field
=
make_config_value_field
(
"foo"
,
get_foo
,
set_foo
,
42
,
foo_valid
);
test_foo_field
(
foo_field
);
}
CAF_TEST
(
oject
access
from
dictionary
-
foobar
)
{
settings
x
;
put
(
x
,
"my-value.bar"
,
"hello"
);
CAF_MESSAGE
(
"without foo member"
);
{
CAF_REQUIRE
(
holds_alternative
<
foobar
>
(
x
,
"my-value"
));
CAF_REQUIRE
(
get_if
<
foobar
>
(
&
x
,
"my-value"
)
!=
caf
::
none
);
auto
fb
=
get
<
foobar
>
(
x
,
"my-value"
);
CAF_CHECK_EQUAL
(
fb
.
foo
,
123
);
CAF_CHECK_EQUAL
(
fb
.
bar
,
"hello"
);
}
CAF_MESSAGE
(
"with foo member"
);
put
(
x
,
"my-value.foo"
,
42
);
{
CAF_REQUIRE
(
holds_alternative
<
foobar
>
(
x
,
"my-value"
));
CAF_REQUIRE
(
get_if
<
foobar
>
(
&
x
,
"my-value"
)
!=
caf
::
none
);
auto
fb
=
get
<
foobar
>
(
x
,
"my-value"
);
CAF_CHECK_EQUAL
(
fb
.
foo
,
42
);
CAF_CHECK_EQUAL
(
fb
.
bar
,
"hello"
);
}
}
CAF_TEST
(
oject
access
from
dictionary
-
foobar_foobar
)
{
settings
x
;
put
(
x
,
"my-value.x.foo"
,
1
);
put
(
x
,
"my-value.x.bar"
,
"hello"
);
put
(
x
,
"my-value.y.bar"
,
"world"
);
CAF_REQUIRE
(
holds_alternative
<
foobar_foobar
>
(
x
,
"my-value"
));
CAF_REQUIRE
(
get_if
<
foobar_foobar
>
(
&
x
,
"my-value"
)
!=
caf
::
none
);
auto
fbfb
=
get
<
foobar_foobar
>
(
x
,
"my-value"
);
CAF_CHECK_EQUAL
(
fbfb
.
x
.
foo
,
1
);
CAF_CHECK_EQUAL
(
fbfb
.
x
.
bar
,
"hello"
);
CAF_CHECK_EQUAL
(
fbfb
.
y
.
foo
,
123
);
CAF_CHECK_EQUAL
(
fbfb
.
y
.
bar
,
"world"
);
}
CAF_TEST
(
object
access
from
CLI
arguments
-
foobar
)
{
opts
.
add
<
foobar
>
(
"value,v"
,
"some value"
);
CAF_CHECK_EQUAL
(
read
<
foobar
>
({
"--value={foo = 1, bar = hello}"
}),
foobar
(
1
,
"hello"
));
CAF_CHECK_EQUAL
(
read
<
foobar
>
({
"-v{bar =
\"
hello
\"
}"
}),
foobar
(
123
,
"hello"
));
CAF_CHECK_EQUAL
(
read
<
foobar
>
({
"-v"
,
"{foo = 1, bar =hello ,}"
}),
foobar
(
1
,
"hello"
));
}
CAF_TEST
(
object
access
from
CLI
arguments
-
foobar_foobar
)
{
using
fbfb
=
foobar_foobar
;
opts
.
add
<
fbfb
>
(
"value,v"
,
"some value"
);
CAF_CHECK_EQUAL
(
read
<
fbfb
>
({
"-v{x={bar = hello},y={foo=1,bar=world!},}"
}),
fbfb
({
123
,
"hello"
},
{
1
,
"world!"
}));
}
CAF_TEST_FIXTURE_SCOPE_END
()
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment