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
595a8e30
Commit
595a8e30
authored
Oct 11, 2019
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add field base type to reduce code duplication
parent
11c4eaca
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
169 additions
and
116 deletions
+169
-116
libcaf_core/caf/config_value_field.hpp
libcaf_core/caf/config_value_field.hpp
+4
-8
libcaf_core/caf/config_value_object_access.hpp
libcaf_core/caf/config_value_object_access.hpp
+9
-11
libcaf_core/caf/detail/config_value_field_base.hpp
libcaf_core/caf/detail/config_value_field_base.hpp
+108
-0
libcaf_core/caf/detail/config_value_field_impl.hpp
libcaf_core/caf/detail/config_value_field_impl.hpp
+45
-91
libcaf_core/test/make_config_value_field.cpp
libcaf_core/test/make_config_value_field.cpp
+3
-6
No files found.
libcaf_core/caf/config_value_field.hpp
View file @
595a8e30
...
@@ -33,12 +33,6 @@ public:
...
@@ -33,12 +33,6 @@ public:
// -- observers --------------------------------------------------------------
// -- 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.
/// Returns whether this field has a default value.
virtual
bool
has_default
()
const
noexcept
=
0
;
virtual
bool
has_default
()
const
noexcept
=
0
;
...
@@ -48,11 +42,13 @@ public:
...
@@ -48,11 +42,13 @@ public:
/// Returns the value of this field in `object` as config value.
/// Returns the value of this field in `object` as config value.
virtual
config_value
get
(
const
Object
&
object
)
const
=
0
;
virtual
config_value
get
(
const
Object
&
object
)
const
=
0
;
/// Returns whether calling `set` with `x` would succeed.
virtual
bool
valid_input
(
const
config_value
&
x
)
const
=
0
;
// -- modifiers --------------------------------------------------------------
// -- modifiers --------------------------------------------------------------
/// Sets this field in `object` to `x`.
/// Sets this field in `object` to `x`.
/// @pre `can_set(x)`
virtual
bool
set
(
Object
&
object
,
const
config_value
&
x
)
const
=
0
;
virtual
void
set
(
Object
&
object
,
const
config_value
&
x
)
const
=
0
;
/// Restores the default value for this field in `object`.
/// Restores the default value for this field in `object`.
/// @pre `has_default()`
/// @pre `has_default()`
...
...
libcaf_core/caf/config_value_object_access.hpp
View file @
595a8e30
...
@@ -48,17 +48,19 @@ struct config_value_object_access {
...
@@ -48,17 +48,19 @@ struct config_value_object_access {
if
(
!
dict
)
if
(
!
dict
)
return
false
;
return
false
;
for
(
auto
field
:
Trait
::
fields
())
{
for
(
auto
field
:
Trait
::
fields
())
{
auto
value
=
caf
::
get_if
(
dict
,
field
->
name
());
if
(
auto
value
=
caf
::
get_if
(
dict
,
field
->
name
()))
{
if
(
!
value
)
{
if
(
dst
)
{
if
(
!
field
->
set
(
*
dst
,
*
value
))
return
false
;
}
else
{
if
(
!
field
->
valid_input
(
*
value
))
return
false
;
}
}
else
{
if
(
!
field
->
has_default
())
if
(
!
field
->
has_default
())
return
false
;
return
false
;
if
(
dst
)
if
(
dst
)
field
->
set_default
(
*
dst
);
field
->
set_default
(
*
dst
);
}
else
if
(
field
->
type_check
(
*
value
))
{
if
(
dst
)
field
->
set
(
*
dst
,
*
value
);
}
else
{
return
false
;
}
}
}
}
return
true
;
return
true
;
...
@@ -156,10 +158,6 @@ struct config_value_object_access {
...
@@ -156,10 +158,6 @@ struct config_value_object_access {
ps
.
code
=
pec
::
unexpected_eof
;
ps
.
code
=
pec
::
unexpected_eof
;
return
;
return
;
}
}
if
(
!
fptr
->
valid
(
x
))
{
ps
.
code
=
pec
::
illegal_argument
;
return
;
}
result
[
fptr
->
name
()]
=
fptr
->
get
(
x
);
result
[
fptr
->
name
()]
=
fptr
->
get
(
x
);
}
while
(
ps
.
consume
(
','
));
}
while
(
ps
.
consume
(
','
));
if
(
!
ps
.
consume
(
'}'
))
{
if
(
!
ps
.
consume
(
'}'
))
{
...
...
libcaf_core/caf/detail/config_value_field_base.hpp
0 → 100644
View file @
595a8e30
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| 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"
#include "caf/detail/dispatch_parse_cli.hpp"
#include "caf/optional.hpp"
namespace
caf
{
namespace
detail
{
template
<
class
Object
,
class
Value
>
class
config_value_field_base
:
public
config_value_field
<
Object
>
{
public:
using
super
=
config_value_field
<
Object
>
;
using
object_type
=
typename
super
::
object_type
;
using
value_type
=
Value
;
using
predicate_type
=
bool
(
*
)(
const
value_type
&
);
config_value_field_base
(
string_view
name
,
optional
<
value_type
>
default_value
,
predicate_type
predicate
)
:
name_
(
name
),
default_value_
(
std
::
move
(
default_value
)),
predicate_
(
predicate
)
{
// nop
}
config_value_field_base
(
config_value_field_base
&&
)
=
default
;
bool
has_default
()
const
noexcept
override
{
return
static_cast
<
bool
>
(
default_value_
);
}
string_view
name
()
const
noexcept
override
{
return
name_
;
}
config_value
get
(
const
object_type
&
object
)
const
override
{
using
access
=
caf
::
select_config_value_access_t
<
value_type
>
;
return
config_value
{
access
::
convert
(
get_value
(
object
))};
}
bool
valid_input
(
const
config_value
&
x
)
const
override
{
if
(
!
predicate_
)
return
holds_alternative
<
value_type
>
(
x
);
if
(
auto
value
=
get_if
<
value_type
>
(
&
x
))
return
predicate_
(
*
value
);
return
false
;
}
bool
set
(
object_type
&
x
,
const
config_value
&
y
)
const
override
{
if
(
auto
value
=
get_if
<
value_type
>
(
&
y
))
{
if
(
predicate_
&&
!
predicate_
(
*
value
))
return
false
;
set_value
(
x
,
move_if_optional
(
value
));
return
true
;
}
return
false
;
}
void
set_default
(
object_type
&
x
)
const
override
{
set_value
(
x
,
*
default_value_
);
}
void
parse_cli
(
string_parser_state
&
ps
,
object_type
&
x
,
const
char
*
char_blacklist
)
const
override
{
value_type
tmp
;
dispatch_parse_cli
(
ps
,
tmp
,
char_blacklist
);
if
(
ps
.
code
<=
pec
::
trailing_character
)
{
if
(
predicate_
&&
!
predicate_
(
tmp
))
ps
.
code
=
pec
::
illegal_argument
;
else
set_value
(
x
,
std
::
move
(
tmp
));
}
}
virtual
const
value_type
&
get_value
(
const
object_type
&
object
)
const
=
0
;
virtual
void
set_value
(
object_type
&
object
,
value_type
value
)
const
=
0
;
protected:
string_view
name_
;
optional
<
value_type
>
default_value_
;
predicate_type
predicate_
;
};
}
// namespace detail
}
// namespace caf
libcaf_core/caf/detail/config_value_field_impl.hpp
View file @
595a8e30
...
@@ -23,6 +23,7 @@
...
@@ -23,6 +23,7 @@
#include "caf/config_value.hpp"
#include "caf/config_value.hpp"
#include "caf/config_value_field.hpp"
#include "caf/config_value_field.hpp"
#include "caf/detail/config_value_field_base.hpp"
#include "caf/detail/dispatch_parse_cli.hpp"
#include "caf/detail/dispatch_parse_cli.hpp"
#include "caf/detail/parse.hpp"
#include "caf/detail/parse.hpp"
#include "caf/detail/type_traits.hpp"
#include "caf/detail/type_traits.hpp"
...
@@ -38,157 +39,110 @@ class config_value_field_impl;
...
@@ -38,157 +39,110 @@ class config_value_field_impl;
// A config value with direct access to a field via member object pointer.
// A config value with direct access to a field via member object pointer.
template
<
class
Value
,
class
Object
>
template
<
class
Value
,
class
Object
>
class
config_value_field_impl
<
Value
Object
::*>
class
config_value_field_impl
<
Value
Object
::*>
:
public
config_value_field
<
Object
>
{
:
public
config_value_field
_base
<
Object
,
Value
>
{
public:
public:
using
super
=
config_value_field_base
<
Object
,
Value
>
;
using
member_pointer
=
Value
Object
::*
;
using
member_pointer
=
Value
Object
::*
;
using
object_type
=
Object
;
using
object_type
=
Object
;
using
value_type
=
Value
;
using
value_type
=
Value
;
using
predicate_
pointer
=
bool
(
*
)(
const
value_type
&
);
using
predicate_
type
=
bool
(
*
)(
const
value_type
&
);
constexpr
config_value_field_impl
(
string_view
name
,
member_pointer
ptr
,
constexpr
config_value_field_impl
(
string_view
name
,
member_pointer
ptr
,
optional
<
value_type
>
default_value
=
none
,
optional
<
value_type
>
default_value
=
none
,
predicate_pointer
predicate
=
nullptr
)
predicate_type
predicate
=
nullptr
)
:
name_
(
name
),
:
super
(
name
,
std
::
move
(
default_value
),
predicate
),
ptr_
(
ptr
)
{
ptr_
(
ptr
),
default_value_
(
std
::
move
(
default_value
)),
predicate_
(
predicate
)
{
// nop
// nop
}
}
constexpr
config_value_field_impl
(
config_value_field_impl
&&
)
=
default
;
constexpr
config_value_field_impl
(
config_value_field_impl
&&
)
=
default
;
bool
type_check
(
const
config_value
&
x
)
const
noexcept
override
{
const
value_type
&
get_value
(
const
object_type
&
x
)
const
override
{
return
holds_alternative
<
value_type
>
(
x
);
return
x
.
*
ptr_
;
}
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
,
void
set_value
(
object_type
&
x
,
value_type
y
)
const
override
{
const
char
*
char_blacklist
)
const
override
{
x
.
*
ptr_
=
std
::
move
(
y
);
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:
private:
string_view
name_
;
member_pointer
ptr_
;
member_pointer
ptr_
;
optional
<
value_type
>
default_value_
;
predicate_pointer
predicate_
;
};
};
template
<
class
Get
>
template
<
class
Get
>
struct
config_value_field_
base
{
struct
config_value_field_
trait
{
using
trait
=
get_callable_trait_t
<
Get
>
;
using
trait
=
get_callable_trait_t
<
Get
>
;
static_assert
(
trait
::
num_args
==
1
,
static_assert
(
trait
::
num_args
==
1
,
"Get must take exactly one argument (the object)"
);
"Get must take exactly one argument (the object)"
);
using
arg
_type
=
tl_head_t
<
typename
trait
::
arg_types
>
;
using
get_argument
_type
=
tl_head_t
<
typename
trait
::
arg_types
>
;
using
value_type
=
decay_t
<
typename
trait
::
resul
t_type
>
;
using
object_type
=
decay_t
<
get_argumen
t_type
>
;
using
type
=
config_value_field
<
decay_t
<
arg_type
>>
;
using
get_result_type
=
typename
trait
::
result_type
;
};
template
<
class
Get
>
using
value_type
=
decay_t
<
get_result_type
>
;
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.
// A config value with access to a field via getter and setter.
template
<
class
Get
,
class
Set
>
template
<
class
Get
,
class
Set
>
class
config_value_field_impl
<
std
::
pair
<
Get
,
Set
>>
class
config_value_field_impl
<
std
::
pair
<
Get
,
Set
>>
:
public
config_value_field_base_t
<
Get
>
{
:
public
config_value_field_base
<
typename
config_value_field_trait
<
Get
>::
object_type
,
typename
config_value_field_trait
<
Get
>::
value_type
>
{
public:
public:
using
super
=
config_value_field_base_t
<
Get
>
;
using
trait
=
config_value_field_trait
<
Get
>
;
using
object_type
=
typename
trait
::
object_type
;
using
object_type
=
typename
super
::
objec
t_type
;
using
get_result_type
=
typename
trait
::
get_resul
t_type
;
using
get_trait
=
get_callable_trait_t
<
Get
>
;
using
value_type
=
typename
trait
::
value_type
;
using
value_type
=
decay_t
<
typename
get_trait
::
result_type
>
;
using
predicate_type
=
bool
(
*
)(
const
value_type
&
)
;
using
predicate_pointer
=
bool
(
*
)(
const
value_type
&
)
;
using
super
=
config_value_field_base
<
object_type
,
value_type
>
;
constexpr
config_value_field_impl
(
string_view
name
,
Get
getter
,
Set
setter
,
constexpr
config_value_field_impl
(
string_view
name
,
Get
getter
,
Set
setter
,
optional
<
value_type
>
default_value
=
none
,
optional
<
value_type
>
default_value
=
none
,
predicate_
pointer
predicate
=
nullptr
)
predicate_
type
predicate
=
nullptr
)
:
name_
(
nam
e
),
:
super
(
name
,
std
::
move
(
default_value
),
predicat
e
),
get_
(
std
::
move
(
getter
)),
get_
(
std
::
move
(
getter
)),
set_
(
std
::
move
(
setter
)),
set_
(
std
::
move
(
setter
))
{
default_value_
(
std
::
move
(
default_value
)),
predicate_
(
predicate
)
{
// nop
// nop
}
}
constexpr
config_value_field_impl
(
config_value_field_impl
&&
)
=
default
;
constexpr
config_value_field_impl
(
config_value_field_impl
&&
)
=
default
;
bool
type_check
(
const
config_value
&
x
)
const
noexcept
override
{
const
value_type
&
get_value
(
const
object_type
&
x
)
const
override
{
return
holds_alternative
<
value_type
>
(
x
);
bool_token
<
std
::
is_lvalue_reference
<
get_result_type
>::
value
>
token
;
}
return
get_value_impl
(
x
,
token
);
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
,
void
set_value
(
object_type
&
x
,
value_type
y
)
const
override
{
const
char
*
char_blacklist
)
const
override
{
set_
(
x
,
std
::
move
(
y
));
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
{
private:
return
name_
;
template
<
class
O
>
}
const
value_type
&
get_value_impl
(
const
O
&
x
,
std
::
true_type
)
const
{
return
get_
(
x
);
bool
has_default
()
const
noexcept
override
{
return
static_cast
<
bool
>
(
default_value_
);
}
}
void
set_default
(
object_type
&
x
)
const
override
{
template
<
class
O
>
set_
(
x
,
*
default_value_
);
const
value_type
&
get_value_impl
(
const
O
&
x
,
std
::
false_type
)
const
{
dummy_
=
get_
(
x
);
return
dummy_
;
}
}
private:
string_view
name_
;
Get
get_
;
Get
get_
;
Set
set_
;
Set
set_
;
optional
<
value_type
>
default_value_
;
mutable
value_type
dummy_
;
predicate_pointer
predicate_
;
};
};
}
// namespace detail
}
// namespace detail
...
...
libcaf_core/test/make_config_value_field.cpp
View file @
595a8e30
...
@@ -130,15 +130,12 @@ struct fixture {
...
@@ -130,15 +130,12 @@ struct fixture {
foobar
x
;
foobar
x
;
CAF_CHECK_EQUAL
(
foo_field
.
name
(),
"foo"
);
CAF_CHECK_EQUAL
(
foo_field
.
name
(),
"foo"
);
CAF_REQUIRE
(
foo_field
.
has_default
());
CAF_REQUIRE
(
foo_field
.
has_default
());
CAF_CHECK
(
foo_field
.
valid
(
x
));
CAF_CHECK_EQUAL
(
foo_field
.
get
(
x
),
config_value
(
0
));
CAF_CHECK_EQUAL
(
foo_field
.
get
(
x
),
config_value
(
0
));
foo_field
.
set_default
(
x
);
foo_field
.
set_default
(
x
);
CAF_CHECK_EQUAL
(
foo_field
.
get
(
x
),
config_value
(
42
));
CAF_CHECK_EQUAL
(
foo_field
.
get
(
x
),
config_value
(
42
));
CAF_CHECK
(
!
foo_field
.
type_check
(
config_value
(
1.
)));
CAF_CHECK
(
!
foo_field
.
valid_input
(
config_value
(
1.
)));
CAF_CHECK
(
foo_field
.
type_check
(
config_value
(
-
1
)));
CAF_CHECK
(
!
foo_field
.
valid_input
(
config_value
(
-
1
)));
foo_field
.
set
(
x
,
config_value
(
-
1
));
CAF_CHECK
(
!
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_view
input
=
"123"
;
string_parser_state
ps
{
input
.
begin
(),
input
.
end
()};
string_parser_state
ps
{
input
.
begin
(),
input
.
end
()};
foo_field
.
parse_cli
(
ps
,
x
);
foo_field
.
parse_cli
(
ps
,
x
);
...
...
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