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
69504271
Commit
69504271
authored
Oct 09, 2019
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refactor parsing of config options
parent
baa4241b
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
134 additions
and
17 deletions
+134
-17
libcaf_core/caf/config_value.hpp
libcaf_core/caf/config_value.hpp
+116
-7
libcaf_core/caf/detail/parser/state.hpp
libcaf_core/caf/detail/parser/state.hpp
+6
-0
libcaf_core/caf/make_config_option.hpp
libcaf_core/caf/make_config_option.hpp
+10
-9
libcaf_core/caf/pec.hpp
libcaf_core/caf/pec.hpp
+2
-0
libcaf_core/test/config_option.cpp
libcaf_core/test/config_option.cpp
+0
-1
No files found.
libcaf_core/caf/config_value.hpp
View file @
69504271
...
@@ -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"
...
@@ -75,6 +76,8 @@ public:
...
@@ -75,6 +76,8 @@ public:
using
variant_type
=
detail
::
tl_apply_t
<
types
,
variant
>
;
using
variant_type
=
detail
::
tl_apply_t
<
types
,
variant
>
;
using
parse_state
=
detail
::
parse_state
;
// -- constructors, destructors, and assignment operators --------------------
// -- constructors, destructors, and assignment operators --------------------
config_value
()
=
default
;
config_value
()
=
default
;
...
@@ -230,6 +233,14 @@ struct default_config_value_access {
...
@@ -230,6 +233,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
(
config_value
::
parse_state
&
ps
,
T
&
x
)
{
detail
::
parse
(
ps
,
x
);
}
};
};
struct
config_value_access_unspecialized
{};
struct
config_value_access_unspecialized
{};
...
@@ -266,7 +277,7 @@ enum class select_config_value_hint {
...
@@ -266,7 +277,7 @@ enum class select_config_value_hint {
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_integral
<
T
>::
value
return
std
::
is_integral
<
T
>::
value
&&
!
std
::
is_same
<
T
,
bool
>::
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
...
@@ -288,8 +299,8 @@ struct select_config_value_access {
...
@@ -288,8 +299,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
>
{
...
@@ -395,6 +406,14 @@ struct select_config_value_access<T, select_config_value_hint::is_integral> {
...
@@ -395,6 +406,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
(
config_value
::
parse_state
&
ps
,
T
&
x
)
{
detail
::
parse
(
ps
,
x
);
}
};
};
};
};
...
@@ -444,6 +463,34 @@ struct select_config_value_access<T, select_config_value_hint::is_list> {
...
@@ -444,6 +463,34 @@ 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
(
config_value
::
parse_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
(
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
;
}
};
};
};
};
...
@@ -496,28 +543,47 @@ struct select_config_value_access<T, select_config_value_hint::is_map> {
...
@@ -496,28 +543,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
(
config_value
::
parse_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
std
::
string
type_name
()
{
static
inline
std
::
string
type_name
()
{
return
"real32"
;
return
"real32"
;
}
}
static
bool
is
(
const
config_value
&
x
)
{
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
)
{
if
(
auto
res
=
caf
::
get_if
<
double
>
(
&
(
x
->
get_data
())))
if
(
auto
res
=
caf
::
get_if
<
double
>
(
&
(
x
->
get_data
())))
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
(
config_value
::
parse_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
...
@@ -561,6 +627,16 @@ struct config_value_access<std::tuple<Ts...>> {
...
@@ -561,6 +627,16 @@ 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
(
config_value
::
parse_state
&
ps
,
tuple_type
&
xs
)
{
rec_parse
(
ps
,
xs
,
detail
::
int_token
<
0
>
(),
detail
::
type_list
<
Ts
...
>
());
}
private:
private:
template
<
int
Pos
>
template
<
int
Pos
>
static
void
rec_name
(
std
::
string
&
,
bool
,
detail
::
int_token
<
Pos
>
,
static
void
rec_name
(
std
::
string
&
,
bool
,
detail
::
int_token
<
Pos
>
,
...
@@ -610,6 +686,39 @@ private:
...
@@ -610,6 +686,39 @@ private:
}
}
return
false
;
return
false
;
}
}
template
<
int
Pos
>
static
void
rec_convert
(
config_value
::
list
&
,
const
tuple_type
&
,
detail
::
int_token
<
Pos
>
,
detail
::
type_list
<>
)
{
// nop
}
template
<
int
Pos
,
class
U
,
class
...
Us
>
static
void
rec_convert
(
config_value
::
list
&
result
,
const
tuple_type
&
xs
,
detail
::
int_token
<
Pos
>
,
detail
::
type_list
<
U
,
Us
...
>
)
{
using
trait
=
select_config_value_access_t
<
U
>
;
result
.
emplace_back
(
trait
::
convert
(
std
::
get
<
Pos
>
(
xs
)));
return
rec_convert
(
result
,
xs
,
detail
::
int_token
<
Pos
+
1
>
(),
detail
::
type_list
<
Us
...
>
());
}
template
<
int
Pos
>
static
void
rec_parse
(
config_value
::
parse_state
&
,
tuple_type
&
,
detail
::
int_token
<
Pos
>
,
detail
::
type_list
<>
)
{
// nop
}
template
<
int
Pos
,
class
U
,
class
...
Us
>
static
void
rec_parse
(
config_value
::
parse_state
&
ps
,
tuple_type
&
xs
,
detail
::
int_token
<
Pos
>
,
detail
::
type_list
<
U
,
Us
...
>
)
{
using
trait
=
select_config_value_access_t
<
U
>
;
trait
::
parse
(
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
...
>
());
}
};
};
// -- SumType-like access of dictionary values ---------------------------------
// -- SumType-like access of dictionary values ---------------------------------
...
...
libcaf_core/caf/detail/parser/state.hpp
View file @
69504271
...
@@ -21,6 +21,7 @@
...
@@ -21,6 +21,7 @@
#include <cctype>
#include <cctype>
#include <cstdint>
#include <cstdint>
#include "caf/error.hpp"
#include "caf/pec.hpp"
#include "caf/pec.hpp"
namespace
caf
{
namespace
caf
{
...
@@ -90,6 +91,11 @@ struct state {
...
@@ -90,6 +91,11 @@ struct state {
}
}
return
false
;
return
false
;
}
}
error
make_error
(
pec
code
)
{
return
caf
::
make_error
(
code
,
static_cast
<
size_t
>
(
line
),
static_cast
<
size_t
>
(
column
));
}
};
};
}
// namespace parser
}
// namespace parser
...
...
libcaf_core/caf/make_config_option.hpp
View file @
69504271
...
@@ -53,15 +53,16 @@ config_value get_impl(const void* ptr) {
...
@@ -53,15 +53,16 @@ config_value get_impl(const void* 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
)
{
T
tmp
;
T
tmp
;
if
(
auto
err
=
parse
(
str
,
tmp
))
return
parse_impl
(
&
tmp
,
str
);
return
err
;
}
config_value
result
{
std
::
move
(
tmp
)}
;
using
trait
=
select_config_value_access_t
<
T
>
;
if
(
!
holds_alternative
<
T
>
(
result
))
config_value
::
parse_state
ps
{
str
.
begin
(),
str
.
end
()};
return
pec
::
type_mismatch
;
trait
::
parse
(
ps
,
*
ptr
)
;
if
(
p
tr
!=
nullptr
)
if
(
p
s
.
code
!=
pec
::
success
)
*
ptr
=
get
<
T
>
(
result
);
return
ps
.
make_error
(
ps
.
code
);
return
std
::
move
(
result
)
;
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
);
...
...
libcaf_core/caf/pec.hpp
View file @
69504271
...
@@ -65,6 +65,8 @@ enum class pec : uint8_t {
...
@@ -65,6 +65,8 @@ 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
,
};
};
/// Returns an error object from given error code.
/// Returns an error object from given error code.
...
...
libcaf_core/test/config_option.cpp
View file @
69504271
...
@@ -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
}));
...
...
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