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
21b8e8c5
Commit
21b8e8c5
authored
Jun 27, 2018
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'topic/string-view'
parents
99b35153
e3060212
Changes
25
Hide whitespace changes
Inline
Side-by-side
Showing
25 changed files
with
1552 additions
and
187 deletions
+1552
-187
libcaf_core/CMakeLists.txt
libcaf_core/CMakeLists.txt
+1
-0
libcaf_core/caf/actor_system_config.hpp
libcaf_core/caf/actor_system_config.hpp
+5
-4
libcaf_core/caf/config_option.hpp
libcaf_core/caf/config_option.hpp
+21
-21
libcaf_core/caf/config_option_adder.hpp
libcaf_core/caf/config_option_adder.hpp
+10
-10
libcaf_core/caf/config_option_set.hpp
libcaf_core/caf/config_option_set.hpp
+11
-10
libcaf_core/caf/config_value.hpp
libcaf_core/caf/config_value.hpp
+23
-24
libcaf_core/caf/detail/ini_consumer.hpp
libcaf_core/caf/detail/ini_consumer.hpp
+2
-2
libcaf_core/caf/detail/type_name.hpp
libcaf_core/caf/detail/type_name.hpp
+2
-2
libcaf_core/caf/dictionary.hpp
libcaf_core/caf/dictionary.hpp
+342
-0
libcaf_core/caf/fwd.hpp
libcaf_core/caf/fwd.hpp
+7
-6
libcaf_core/caf/make_config_option.hpp
libcaf_core/caf/make_config_option.hpp
+13
-13
libcaf_core/caf/string_algorithms.hpp
libcaf_core/caf/string_algorithms.hpp
+3
-4
libcaf_core/caf/string_view.hpp
libcaf_core/caf/string_view.hpp
+295
-0
libcaf_core/src/actor_system_config.cpp
libcaf_core/src/actor_system_config.cpp
+2
-2
libcaf_core/src/config_option.cpp
libcaf_core/src/config_option.cpp
+67
-29
libcaf_core/src/config_option_adder.cpp
libcaf_core/src/config_option_adder.cpp
+7
-7
libcaf_core/src/config_option_set.cpp
libcaf_core/src/config_option_set.cpp
+16
-20
libcaf_core/src/config_value.cpp
libcaf_core/src/config_value.cpp
+7
-7
libcaf_core/src/make_config_option.cpp
libcaf_core/src/make_config_option.cpp
+9
-9
libcaf_core/src/string_view.cpp
libcaf_core/src/string_view.cpp
+318
-0
libcaf_core/test/config_option.cpp
libcaf_core/test/config_option.cpp
+4
-4
libcaf_core/test/config_option_set.cpp
libcaf_core/test/config_option_set.cpp
+4
-4
libcaf_core/test/config_value.cpp
libcaf_core/test/config_value.cpp
+11
-9
libcaf_core/test/dictionary.cpp
libcaf_core/test/dictionary.cpp
+145
-0
libcaf_core/test/string_view.cpp
libcaf_core/test/string_view.cpp
+227
-0
No files found.
libcaf_core/CMakeLists.txt
View file @
21b8e8c5
...
...
@@ -104,6 +104,7 @@ set(LIBCAF_CORE_SRCS
src/stream_aborter.cpp
src/stream_manager.cpp
src/stream_priority.cpp
src/string_view.cpp
src/stringification_inspector.cpp
src/sync_request_bouncer.cpp
src/term.cpp
...
...
libcaf_core/caf/actor_system_config.hpp
View file @
21b8e8c5
...
...
@@ -30,6 +30,7 @@
#include "caf/config_option.hpp"
#include "caf/config_option_set.hpp"
#include "caf/config_value.hpp"
#include "caf/dictionary.hpp"
#include "caf/fwd.hpp"
#include "caf/is_typed_actor.hpp"
#include "caf/named_actor_config.hpp"
...
...
@@ -79,7 +80,7 @@ public:
using
group_module_factory_vector
=
std
::
vector
<
group_module_factory
>
;
using
config_map
=
std
::
map
<
std
::
string
,
config_value
::
dictionary
>
;
using
config_map
=
dictionary
<
config_value
::
dictionary
>
;
using
string_list
=
std
::
vector
<
std
::
string
>
;
...
...
@@ -101,11 +102,11 @@ public:
// -- properties -------------------------------------------------------------
/// @private
std
::
map
<
std
::
string
,
config_value
::
dictionary
>
content
;
dictionary
<
config_value
::
dictionary
>
content
;
/// Sets a config by using its INI name `config_name` to `config_value`.
template
<
class
T
>
actor_system_config
&
set
(
const
char
*
name
,
T
&&
value
)
{
actor_system_config
&
set
(
string_view
name
,
T
&&
value
)
{
return
set_impl
(
name
,
config_value
{
std
::
forward
<
T
>
(
value
)});
}
...
...
@@ -403,7 +404,7 @@ private:
&
make_type_erased_value
<
T
>
);
}
actor_system_config
&
set_impl
(
const
char
*
name
,
config_value
value
);
actor_system_config
&
set_impl
(
string_view
name
,
config_value
value
);
static
std
::
string
render_sec
(
uint8_t
,
atom_value
,
const
message
&
);
...
...
libcaf_core/caf/config_option.hpp
View file @
21b8e8c5
...
...
@@ -18,9 +18,11 @@
#pragma once
#include <memory>
#include <string>
#include "caf/fwd.hpp"
#include "caf/string_view.hpp"
namespace
caf
{
...
...
@@ -49,8 +51,8 @@ public:
// -- constructors, destructors, and assignment operators --------------------
/// Constructs a config option.
config_option
(
st
d
::
string
category
,
const
char
*
name
,
std
::
string
description
,
const
meta_state
*
meta
,
void
*
storag
e
=
nullptr
);
config_option
(
st
ring_view
category
,
string_view
name
,
string_view
description
,
const
meta_state
*
meta
,
void
*
valu
e
=
nullptr
);
config_option
(
config_option
&&
)
=
default
;
...
...
@@ -58,25 +60,20 @@ public:
// -- properties -------------------------------------------------------------
inline
const
std
::
string
&
category
()
const
noexcept
{
return
category_
;
}
/// Returns the category of the option.
string_view
category
()
const
noexcept
;
/// Returns the
inline
const
std
::
string
&
long_name
()
const
noexcept
{
return
long_name_
;
}
/// Returns the name of the option.
string_view
long_name
()
const
noexcept
;
inline
const
std
::
string
&
short_names
()
const
noexcept
{
return
short_names_
;
}
/// Returns (optional) one-letter short names of the option.
string_view
short_names
()
const
noexcept
;
inline
const
std
::
string
&
description
()
const
noexcept
{
return
description_
;
}
/// Returns a human-readable description of the option.
string_view
description
()
const
noexcept
;
/// Returns the full name for this config option as "<category>.<long name>".
st
d
::
string
full_name
()
cons
t
;
st
ring_view
full_name
()
const
noexcep
t
;
/// Checks whether `x` holds a legal value for this option.
error
check
(
const
config_value
&
x
)
const
;
...
...
@@ -86,7 +83,7 @@ public:
void
store
(
const
config_value
&
x
)
const
;
/// Returns a human-readable representation of this option's expected type.
const
std
::
string
&
type_name
()
const
noexcept
;
string_view
type_name
()
const
noexcept
;
/// Returns whether this config option stores a boolean flag.
bool
is_flag
()
const
noexcept
;
...
...
@@ -96,10 +93,13 @@ public:
optional
<
config_value
>
get
()
const
;
private:
std
::
string
category_
;
std
::
string
long_name_
;
std
::
string
short_names_
;
std
::
string
description_
;
string_view
buf_slice
(
size_t
from
,
size_t
to
)
const
noexcept
;
std
::
unique_ptr
<
char
[]
>
buf_
;
uint16_t
category_separator_
;
uint16_t
long_name_separator_
;
uint16_t
short_names_separator_
;
uint16_t
buf_size_
;
const
meta_state
*
meta_
;
mutable
void
*
value_
;
};
...
...
libcaf_core/caf/config_option_adder.hpp
View file @
21b8e8c5
...
...
@@ -30,36 +30,36 @@ class config_option_adder {
public:
// -- constructors, destructors, and assignment operators --------------------
config_option_adder
(
config_option_set
&
target
,
const
char
*
category
);
config_option_adder
(
config_option_set
&
target
,
string_view
category
);
// -- properties -------------------------------------------------------------
/// Adds a config option to the category that synchronizes with `ref`.
template
<
class
T
>
config_option_adder
&
add
(
T
&
ref
,
const
char
*
name
,
const
char
*
description
)
{
config_option_adder
&
add
(
T
&
ref
,
string_view
name
,
string_view
description
)
{
return
add_impl
(
make_config_option
(
ref
,
category_
,
name
,
description
));
}
/// Adds a config option to the category.
template
<
class
T
>
config_option_adder
&
add
(
const
char
*
name
,
const
char
*
description
)
{
config_option_adder
&
add
(
string_view
name
,
string_view
description
)
{
return
add_impl
(
make_config_option
<
T
>
(
category_
,
name
,
description
));
}
/// For backward compatibility only. Do not use for new code!
/// @private
config_option_adder
&
add_neg
(
bool
&
ref
,
const
char
*
name
,
const
char
*
description
);
config_option_adder
&
add_neg
(
bool
&
ref
,
string_view
name
,
string_view
description
);
/// For backward compatibility only. Do not use for new code!
/// @private
config_option_adder
&
add_us
(
size_t
&
ref
,
const
char
*
name
,
const
char
*
description
);
config_option_adder
&
add_us
(
size_t
&
ref
,
string_view
name
,
string_view
description
);
/// For backward compatibility only. Do not use for new code!
/// @private
config_option_adder
&
add_ms
(
size_t
&
ref
,
const
char
*
name
,
const
char
*
description
);
config_option_adder
&
add_ms
(
size_t
&
ref
,
string_view
name
,
string_view
description
);
private:
// -- properties -------------------------------------------------------------
...
...
@@ -72,7 +72,7 @@ private:
config_option_set
&
xs_
;
/// Category for all options generated by this adder.
const
char
*
category_
;
string_view
category_
;
};
}
// namespace caf
libcaf_core/caf/config_option_set.hpp
View file @
21b8e8c5
...
...
@@ -28,6 +28,7 @@
#include "caf/fwd.hpp"
#include "caf/make_config_option.hpp"
#include "caf/pec.hpp"
#include "caf/string_view.hpp"
namespace
caf
{
...
...
@@ -53,10 +54,10 @@ public:
using
iterator
=
option_vector
::
iterator
;
/// Maps string keys to arbitrary (config) values.
using
dictionary
=
std
::
map
<
std
::
string
,
config_value
>
;
using
dictionary
=
dictionary
<
config_value
>
;
/// Categorized settings.
using
config_map
=
std
::
map
<
std
::
string
,
dictionary
>
;
using
config_map
=
caf
::
dictionary
<
dictionary
>
;
// -- constructors, destructors, and assignment operators --------------------
...
...
@@ -69,18 +70,18 @@ public:
/// `<prefix>#<category>.<long-name>`. Users can omit `<prefix>`
/// for options that have an empty prefix and `<category>`
/// if the category is "global".
option_pointer
cli_long_name_lookup
(
const
std
::
string
&
name
)
const
;
option_pointer
cli_long_name_lookup
(
string_view
name
)
const
;
/// Returns the first `config_option` that matches the CLI short option name.
option_pointer
cli_short_name_lookup
(
char
short_name
)
const
;
/// Returns the first `config_option` that matches category and long name.
option_pointer
qualified_name_lookup
(
const
std
::
string
&
category
,
const
std
::
string
&
long_name
)
const
;
option_pointer
qualified_name_lookup
(
string_view
category
,
string_view
long_name
)
const
;
/// Returns the first `config_option` that matches the qualified name.
/// @param name Config option name formatted as `<category>.<long-name>`.
option_pointer
qualified_name_lookup
(
const
std
::
string
&
name
)
const
;
option_pointer
qualified_name_lookup
(
string_view
name
)
const
;
/// Returns the number of stored config options.
inline
size_t
size
()
const
noexcept
{
...
...
@@ -99,15 +100,15 @@ public:
/// Adds a config option to the set.
template
<
class
T
>
config_option_set
&
add
(
const
char
*
category
,
const
char
*
name
,
const
char
*
description
=
""
)
{
config_option_set
&
add
(
string_view
category
,
string_view
name
,
string_view
description
=
""
)
{
return
add
(
make_config_option
<
T
>
(
category
,
name
,
description
));
}
/// Adds a config option to the set that synchronizes its value with `ref`.
template
<
class
T
>
config_option_set
&
add
(
T
&
ref
,
const
char
*
category
,
const
char
*
name
,
const
char
*
description
=
""
)
{
config_option_set
&
add
(
T
&
ref
,
string_view
category
,
string_view
name
,
string_view
description
=
""
)
{
return
add
(
make_config_option
<
T
>
(
ref
,
category
,
name
,
description
));
}
...
...
libcaf_core/caf/config_value.hpp
View file @
21b8e8c5
...
...
@@ -27,6 +27,7 @@
#include "caf/atom.hpp"
#include "caf/detail/bounds_checker.hpp"
#include "caf/detail/type_traits.hpp"
#include "caf/dictionary.hpp"
#include "caf/fwd.hpp"
#include "caf/optional.hpp"
#include "caf/string_algorithms.hpp"
...
...
@@ -59,7 +60,7 @@ public:
using
list
=
std
::
vector
<
config_value
>
;
using
dictionary
=
std
::
map
<
std
::
string
,
config_value
>
;
using
dictionary
=
dictionary
<
config_value
>
;
using
types
=
detail
::
type_list
<
integer
,
boolean
,
real
,
atom
,
timespan
,
string
,
list
,
dictionary
>
;
...
...
@@ -96,11 +97,11 @@ public:
// -- parsing ----------------------------------------------------------------
/// Tries to parse a value from `str`.
static
expected
<
config_value
>
parse
(
st
d
::
string
::
const_
iterator
first
,
st
d
::
string
::
const_
iterator
last
);
static
expected
<
config_value
>
parse
(
st
ring_view
::
iterator
first
,
st
ring_view
::
iterator
last
);
/// Tries to parse a value from `str`.
static
expected
<
config_value
>
parse
(
const
std
::
string
&
str
);
static
expected
<
config_value
>
parse
(
string_view
str
);
// -- properties -------------------------------------------------------------
...
...
@@ -175,7 +176,7 @@ private:
/// Organizes config values into categories.
/// @relates config_value
using
config_value_map
=
std
::
map
<
std
::
string
,
config_value
::
dictionary
>
;
using
config_value_map
=
dictionary
<
config_value
::
dictionary
>
;
// -- SumType-like access ------------------------------------------------------
...
...
@@ -351,12 +352,12 @@ struct config_value_access<std::vector<T>> {
}
};
/// Implements automagic unboxing of `
std::map<std::string, V>` from a
///
homogeneous
`config_value::dictionary`.
/// Implements automagic unboxing of `
dictionary<V>` from a homogeneous
/// `config_value::dictionary`.
/// @relates config_value
template
<
class
V
>
struct
config_value_access
<
std
::
map
<
std
::
string
,
V
>>
{
using
map_type
=
std
::
map
<
std
::
string
,
V
>
;
struct
config_value_access
<
dictionary
<
V
>>
{
using
map_type
=
dictionary
<
V
>
;
using
kvp
=
std
::
pair
<
const
std
::
string
,
config_value
>
;
...
...
@@ -401,10 +402,9 @@ struct config_value_access<std::map<std::string, V>> {
/// Tries to retrieve the value associated to `name` from `xs`.
/// @relates config_value
template
<
class
T
>
optional
<
T
>
get_if
(
const
config_value
::
dictionary
*
xs
,
const
std
::
string
&
name
)
{
optional
<
T
>
get_if
(
const
config_value
::
dictionary
*
xs
,
string_view
name
)
{
// Split the name into a path.
std
::
vector
<
st
d
::
string
>
path
;
std
::
vector
<
st
ring_view
>
path
;
split
(
path
,
name
,
"."
);
// Sanity check.
if
(
path
.
size
()
==
0
)
...
...
@@ -433,7 +433,7 @@ optional<T> get_if(const config_value::dictionary* xs,
/// Retrieves the value associated to `name` from `xs`.
/// @relates config_value
template
<
class
T
>
T
get
(
const
config_value
::
dictionary
&
xs
,
const
std
::
string
&
name
)
{
T
get
(
const
config_value
::
dictionary
&
xs
,
string_view
name
)
{
auto
result
=
get_if
<
T
>
(
&
xs
,
name
);
if
(
result
)
return
std
::
move
(
*
result
);
...
...
@@ -444,7 +444,7 @@ T get(const config_value::dictionary& xs, const std::string& name) {
/// `default_value`.
/// @relates config_value
template
<
class
T
,
class
E
=
detail
::
enable_if_t
<!
std
::
is_pointer
<
T
>
::
value
>>
T
get_or
(
const
config_value
::
dictionary
&
xs
,
const
std
::
string
&
name
,
T
get_or
(
const
config_value
::
dictionary
&
xs
,
string_view
name
,
const
T
&
default_value
)
{
auto
result
=
get_if
<
T
>
(
&
xs
,
name
);
if
(
result
)
...
...
@@ -455,13 +455,13 @@ T get_or(const config_value::dictionary& xs, const std::string& name,
/// Retrieves the value associated to `name` from `xs` or returns
/// `default_value`.
/// @relates config_value
std
::
string
get_or
(
const
config_value
::
dictionary
&
xs
,
const
std
::
string
&
name
,
std
::
string
get_or
(
const
config_value
::
dictionary
&
xs
,
string_view
name
,
const
char
*
default_value
);
/// Tries to retrieve the value associated to `name` from `xs`.
/// @relates config_value
template
<
class
T
>
optional
<
T
>
get_if
(
const
config_value_map
*
xs
,
const
std
::
string
&
name
)
{
optional
<
T
>
get_if
(
const
config_value_map
*
xs
,
string_view
name
)
{
// Get the category.
auto
pos
=
name
.
find
(
'.'
);
if
(
pos
==
std
::
string
::
npos
)
{
...
...
@@ -479,7 +479,7 @@ optional<T> get_if(const config_value_map* xs, const std::string& name) {
/// Retrieves the value associated to `name` from `xs`.
/// @relates config_value
template
<
class
T
>
T
get
(
const
config_value_map
&
xs
,
const
std
::
string
&
name
)
{
T
get
(
const
config_value_map
&
xs
,
string_view
name
)
{
auto
result
=
get_if
<
T
>
(
&
xs
,
name
);
if
(
result
)
return
std
::
move
(
*
result
);
...
...
@@ -490,8 +490,7 @@ T get(const config_value_map& xs, const std::string& name) {
/// `default_value`.
/// @relates config_value
template
<
class
T
,
class
E
=
detail
::
enable_if_t
<!
std
::
is_pointer
<
T
>
::
value
>>
T
get_or
(
const
config_value_map
&
xs
,
const
std
::
string
&
name
,
const
T
&
default_value
)
{
T
get_or
(
const
config_value_map
&
xs
,
string_view
name
,
const
T
&
default_value
)
{
auto
result
=
get_if
<
T
>
(
&
xs
,
name
);
if
(
result
)
return
std
::
move
(
*
result
);
...
...
@@ -501,20 +500,20 @@ T get_or(const config_value_map& xs, const std::string& name,
/// Retrieves the value associated to `name` from `xs` or returns
/// `default_value`.
/// @relates config_value
std
::
string
get_or
(
const
config_value_map
&
xs
,
const
std
::
string
&
name
,
std
::
string
get_or
(
const
config_value_map
&
xs
,
string_view
name
,
const
char
*
default_value
);
/// Tries to retrieve the value associated to `name` from `cfg`.
/// @relates config_value
template
<
class
T
>
optional
<
T
>
get_if
(
const
actor_system_config
*
cfg
,
const
std
::
string
&
name
)
{
optional
<
T
>
get_if
(
const
actor_system_config
*
cfg
,
string_view
name
)
{
return
get_if
<
T
>
(
&
content
(
*
cfg
),
name
);
}
/// Retrieves the value associated to `name` from `cfg`.
/// @relates config_value
template
<
class
T
>
T
get
(
const
actor_system_config
&
cfg
,
const
std
::
string
&
name
)
{
T
get
(
const
actor_system_config
&
cfg
,
string_view
name
)
{
return
get
<
T
>
(
content
(
cfg
),
name
);
}
...
...
@@ -522,12 +521,12 @@ T get(const actor_system_config& cfg, const std::string& name) {
/// `default_value`.
/// @relates config_value
template
<
class
T
,
class
E
=
detail
::
enable_if_t
<!
std
::
is_pointer
<
T
>
::
value
>>
T
get_or
(
const
actor_system_config
&
cfg
,
const
std
::
string
&
name
,
T
get_or
(
const
actor_system_config
&
cfg
,
string_view
name
,
const
T
&
default_value
)
{
return
get_or
(
content
(
cfg
),
name
,
default_value
);
}
std
::
string
get_or
(
const
actor_system_config
&
cfg
,
const
std
::
string
&
name
,
std
::
string
get_or
(
const
actor_system_config
&
cfg
,
string_view
name
,
const
char
*
default_value
);
/// @relates config_value
bool
operator
<
(
const
config_value
&
x
,
const
config_value
&
y
);
...
...
libcaf_core/caf/detail/ini_consumer.hpp
View file @
21b8e8c5
...
...
@@ -18,11 +18,11 @@
#pragma once
#include <map>
#include <string>
#include "caf/config_option_set.hpp"
#include "caf/config_value.hpp"
#include "caf/dictionary.hpp"
namespace
caf
{
namespace
detail
{
...
...
@@ -183,7 +183,7 @@ public:
using
super
=
abstract_ini_consumer
;
using
config_map
=
std
::
map
<
std
::
string
,
config_value
::
dictionary
>
;
using
config_map
=
dictionary
<
config_value
::
dictionary
>
;
// -- constructors, destructors, and assignment operators --------------------
...
...
libcaf_core/caf/detail/type_name.hpp
View file @
21b8e8c5
...
...
@@ -18,11 +18,11 @@
#pragma once
#include <map>
#include <string>
#include <type_traits>
#include <vector>
#include "caf/dictionary.hpp"
#include "caf/fwd.hpp"
#include "caf/timestamp.hpp"
...
...
@@ -127,7 +127,7 @@ struct type_name_builder<std::vector<T>, false> {
};
template
<
class
T
>
struct
type_name_builder
<
std
::
map
<
std
::
string
,
T
>
,
false
>
{
struct
type_name_builder
<
dictionary
<
T
>
,
false
>
{
void
operator
()(
std
::
string
&
result
)
const
{
result
+=
"dictionary of "
;
type_name_builder
<
T
>
g
;
...
...
libcaf_core/caf/dictionary.hpp
0 → 100644
View file @
21b8e8c5
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2018 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 <algorithm>
#include <iterator>
#include <map>
#include <string>
#include "caf/string_view.hpp"
namespace
caf
{
/// Maps strings to values of type `V`, but unlike `std::map<std::string, V>`
/// accepts `string_view` for looking up keys efficiently.
template
<
class
V
>
class
dictionary
{
public:
// -- member types ----------------------------------------------------------
using
map_type
=
std
::
map
<
std
::
string
,
V
>
;
using
key_type
=
typename
map_type
::
key_type
;
using
mapped_type
=
typename
map_type
::
mapped_type
;
using
value_type
=
typename
map_type
::
value_type
;
using
allocator_type
=
typename
map_type
::
allocator_type
;
using
size_type
=
typename
map_type
::
size_type
;
using
difference_type
=
typename
map_type
::
difference_type
;
using
reference
=
typename
map_type
::
reference
;
using
const_reference
=
typename
map_type
::
const_reference
;
using
pointer
=
typename
map_type
::
pointer
;
using
const_pointer
=
typename
map_type
::
const_pointer
;
using
iterator
=
typename
map_type
::
iterator
;
using
const_iterator
=
typename
map_type
::
const_iterator
;
using
reverse_iterator
=
typename
map_type
::
reverse_iterator
;
using
const_reverse_iterator
=
typename
map_type
::
const_reverse_iterator
;
using
iterator_bool_pair
=
std
::
pair
<
iterator
,
bool
>
;
struct
mapped_type_less
{
inline
bool
operator
()(
const
value_type
&
x
,
string_view
y
)
const
{
return
x
.
first
<
y
;
}
inline
bool
operator
()(
const
value_type
&
x
,
const
value_type
&
y
)
const
{
return
x
.
first
<
y
.
first
;
}
inline
bool
operator
()(
string_view
x
,
const
value_type
&
y
)
const
{
return
x
<
y
.
first
;
}
};
// -- constructors, destructors, and assignment operators -------------------
dictionary
()
=
default
;
dictionary
(
std
::
initializer_list
<
value_type
>
xs
)
:
xs_
(
xs
)
{
// nop
}
template
<
class
InputIterator
>
dictionary
(
InputIterator
first
,
InputIterator
last
)
:
xs_
(
first
,
last
)
{
// nop
}
// -- iterator access --------------------------------------------------------
iterator
begin
()
noexcept
{
return
xs_
.
begin
();
}
const_iterator
begin
()
const
noexcept
{
return
xs_
.
begin
();
}
const_iterator
cbegin
()
const
noexcept
{
return
begin
();
}
reverse_iterator
rbegin
()
noexcept
{
return
xs_
.
rbegin
();
}
const_reverse_iterator
rbegin
()
const
noexcept
{
return
xs_
.
rbegin
();
}
const_reverse_iterator
crbegin
()
const
noexcept
{
return
rbegin
();
}
iterator
end
()
noexcept
{
return
xs_
.
end
();
}
const_iterator
end
()
const
noexcept
{
return
xs_
.
end
();
}
const_iterator
cend
()
const
noexcept
{
return
end
();
}
reverse_iterator
rend
()
noexcept
{
return
xs_
.
rend
();
}
const_reverse_iterator
rend
()
const
noexcept
{
return
xs_
.
rend
();
}
const_reverse_iterator
crend
()
const
noexcept
{
return
rend
();
}
// -- size -------------------------------------------------------------------
bool
empty
()
const
noexcept
{
return
xs_
.
empty
();
}
size_type
size
()
const
noexcept
{
return
xs_
.
size
();
}
// -- access to members ------------------------------------------------------
/// Gives raw access to the underlying container.
map_type
&
container
()
noexcept
{
return
xs_
;
}
/// Gives raw access to the underlying container.
const
map_type
&
container
()
const
noexcept
{
return
xs_
;
}
// -- modifiers -------------------------------------------------------------
void
clear
()
noexcept
{
return
xs_
.
clear
();
}
void
swap
(
dictionary
&
other
)
{
xs_
.
swap
(
other
.
xs_
);
}
// -- insertion --------------------------------------------------------------
template
<
class
K
,
class
T
>
iterator_bool_pair
emplace
(
K
&&
key
,
T
&&
value
)
{
auto
i
=
lower_bound
(
key
);
if
(
i
==
end
())
return
xs_
.
emplace
(
copy
(
std
::
forward
<
K
>
(
key
)),
std
::
forward
<
T
>
(
value
));
if
(
i
->
first
==
key
)
return
{
i
,
false
};
return
{
xs_
.
emplace_hint
(
i
,
copy
(
std
::
forward
<
K
>
(
key
)),
std
::
forward
<
T
>
(
value
)),
true
};
}
template
<
class
T
>
iterator_bool_pair
insert
(
string_view
key
,
T
&&
value
)
{
return
emplace
(
key
,
std
::
forward
<
T
>
(
value
));
}
template
<
class
K
,
class
T
>
iterator
emplace_hint
(
iterator
hint
,
K
&&
key
,
T
&&
value
)
{
if
(
hint
==
end
()
||
hint
->
first
>
key
)
return
xs_
.
emplace
(
copy
(
std
::
forward
<
K
>
(
key
)),
std
::
forward
<
T
>
(
value
))
.
first
;
if
(
hint
->
first
==
key
)
return
hint
;
return
xs_
.
emplace_hint
(
hint
,
copy
(
std
::
forward
<
K
>
(
key
)),
std
::
forward
<
T
>
(
value
));
}
template
<
class
T
>
iterator
insert
(
iterator
hint
,
string_view
key
,
T
&&
value
)
{
return
emplace_hint
(
hint
,
key
,
std
::
forward
<
T
>
(
value
));
}
template
<
class
T
>
iterator_bool_pair
insert_or_assign
(
string_view
key
,
T
&&
value
)
{
auto
i
=
lower_bound
(
key
);
if
(
i
==
end
())
return
xs_
.
emplace
(
copy
(
key
),
std
::
forward
<
T
>
(
value
));
if
(
i
->
first
==
key
)
{
i
->
second
=
std
::
forward
<
T
>
(
value
);
return
{
i
,
false
};
}
return
{
xs_
.
emplace_hint
(
i
,
copy
(
key
),
std
::
forward
<
T
>
(
value
)),
true
};
}
template
<
class
T
>
iterator
insert_or_assign
(
iterator
hint
,
string_view
key
,
T
&&
value
)
{
if
(
hint
==
end
()
||
hint
->
first
>
key
)
return
insert_or_assign
(
key
,
std
::
forward
<
T
>
(
value
)).
first
;
hint
=
lower_bound
(
hint
,
key
);
if
(
hint
!=
end
()
&&
hint
->
first
==
key
)
{
hint
->
second
=
std
::
forward
<
T
>
(
value
);
return
hint
;
}
return
xs_
.
emplace_hint
(
hint
,
copy
(
key
),
std
::
forward
<
T
>
(
value
));
}
// -- lookup -----------------------------------------------------------------
bool
contains
(
string_view
key
)
const
noexcept
{
auto
i
=
lower_bound
(
key
);
return
!
(
i
==
end
()
||
i
->
first
!=
key
);
}
size_t
count
(
string_view
key
)
const
noexcept
{
return
contains
(
key
)
?
1u
:
0u
;
}
iterator
find
(
string_view
key
)
noexcept
{
auto
i
=
lower_bound
(
key
);
return
i
!=
end
()
&&
i
->
first
==
key
?
i
:
end
();
}
const_iterator
find
(
string_view
key
)
const
noexcept
{
auto
i
=
lower_bound
(
key
);
return
i
!=
end
()
&&
i
->
first
==
key
?
i
:
end
();
}
iterator
lower_bound
(
string_view
key
)
{
return
lower_bound
(
begin
(),
key
);
}
const_iterator
lower_bound
(
string_view
key
)
const
{
return
lower_bound
(
begin
(),
key
);
}
iterator
upper_bound
(
string_view
key
)
{
mapped_type_less
cmp
;
return
std
::
upper_bound
(
begin
(),
end
(),
key
,
cmp
);
}
const_iterator
upper_bound
(
string_view
key
)
const
{
mapped_type_less
cmp
;
return
std
::
upper_bound
(
begin
(),
end
(),
key
,
cmp
);
}
// -- element access ---------------------------------------------------------
mapped_type
&
operator
[](
string_view
key
)
{
return
insert
(
key
,
mapped_type
{}).
first
->
second
;
}
private:
iterator
lower_bound
(
iterator
from
,
string_view
key
)
{
mapped_type_less
cmp
;
return
std
::
lower_bound
(
from
,
end
(),
key
,
cmp
);
}
const_iterator
lower_bound
(
const_iterator
from
,
string_view
key
)
const
{
mapped_type_less
cmp
;
return
std
::
lower_bound
(
from
,
end
(),
key
,
cmp
);
}
// Copies the content of `str` into a new string.
static
inline
std
::
string
copy
(
string_view
str
)
{
return
std
::
string
{
str
.
begin
(),
str
.
end
()};
}
// Moves the content of `str` into a new string.
static
inline
std
::
string
copy
(
std
::
string
str
)
{
return
str
;
}
map_type
xs_
;
};
// @relates dictionary
template
<
class
T
>
bool
operator
==
(
const
dictionary
<
T
>&
xs
,
const
dictionary
<
T
>&
ys
)
{
return
xs
.
container
()
==
ys
.
container
();
}
// @relates dictionary
template
<
class
T
>
bool
operator
!=
(
const
dictionary
<
T
>&
xs
,
const
dictionary
<
T
>&
ys
)
{
return
xs
.
container
()
!=
ys
.
container
();
}
// @relates dictionary
template
<
class
T
>
bool
operator
<
(
const
dictionary
<
T
>&
xs
,
const
dictionary
<
T
>&
ys
)
{
return
xs
.
container
()
<
ys
.
container
();
}
// @relates dictionary
template
<
class
T
>
bool
operator
<=
(
const
dictionary
<
T
>&
xs
,
const
dictionary
<
T
>&
ys
)
{
return
xs
.
container
()
<=
ys
.
container
();
}
// @relates dictionary
template
<
class
T
>
bool
operator
>
(
const
dictionary
<
T
>&
xs
,
const
dictionary
<
T
>&
ys
)
{
return
xs
.
container
()
>
ys
.
container
();
}
// @relates dictionary
template
<
class
T
>
bool
operator
>=
(
const
dictionary
<
T
>&
xs
,
const
dictionary
<
T
>&
ys
)
{
return
xs
.
container
()
>=
ys
.
container
();
}
}
// namespace caf
libcaf_core/caf/fwd.hpp
View file @
21b8e8c5
...
...
@@ -32,6 +32,7 @@ namespace caf {
// -- 1 param templates --------------------------------------------------------
template
<
class
>
class
behavior_type_of
;
template
<
class
>
class
dictionary
;
template
<
class
>
class
downstream
;
template
<
class
>
class
expected
;
template
<
class
>
class
intrusive_ptr
;
...
...
@@ -119,6 +120,7 @@ class scheduled_actor;
class
scoped_actor
;
class
serializer
;
class
stream_manager
;
class
string_view
;
class
type_erased_tuple
;
class
type_erased_value
;
class
uniform_type_info_map
;
...
...
@@ -142,12 +144,12 @@ struct prohibit_top_level_spawn_marker;
// -- free template functions --------------------------------------------------
template
<
class
T
>
config_option
make_config_option
(
const
char
*
category
,
const
char
*
name
,
const
char
*
description
);
config_option
make_config_option
(
string_view
category
,
string_view
name
,
string_view
description
);
template
<
class
T
>
config_option
make_config_option
(
T
&
storage
,
const
char
*
category
,
const
char
*
name
,
const
char
*
description
);
config_option
make_config_option
(
T
&
storage
,
string_view
category
,
string_view
name
,
string_view
description
);
// -- enums --------------------------------------------------------------------
...
...
@@ -162,8 +164,7 @@ using stream_slot = uint16_t;
// -- functions ----------------------------------------------------------------
/// @relates actor_system_config
const
std
::
map
<
std
::
string
,
std
::
map
<
std
::
string
,
config_value
>>&
content
(
const
actor_system_config
&
);
const
dictionary
<
dictionary
<
config_value
>>&
content
(
const
actor_system_config
&
);
// -- intrusive containers -----------------------------------------------------
...
...
libcaf_core/caf/make_config_option.hpp
View file @
21b8e8c5
...
...
@@ -50,15 +50,15 @@ config_option::meta_state* option_meta_state_instance() {
/// Creates a config option that synchronizes with `storage`.
template
<
class
T
>
config_option
make_config_option
(
const
char
*
category
,
const
char
*
name
,
const
char
*
description
)
{
config_option
make_config_option
(
string_view
category
,
string_view
name
,
string_view
description
)
{
return
{
category
,
name
,
description
,
detail
::
option_meta_state_instance
<
T
>
()};
}
/// Creates a config option that synchronizes with `storage`.
template
<
class
T
>
config_option
make_config_option
(
T
&
storage
,
const
char
*
category
,
const
char
*
name
,
const
char
*
description
)
{
config_option
make_config_option
(
T
&
storage
,
string_view
category
,
string_view
name
,
string_view
description
)
{
return
{
category
,
name
,
description
,
detail
::
option_meta_state_instance
<
T
>
(),
std
::
addressof
(
storage
)};
}
...
...
@@ -66,21 +66,21 @@ config_option make_config_option(T& storage, const char* category,
// -- backward compatbility, do not use for new code ! -------------------------
// Inverts the value when writing to `storage`.
config_option
make_negated_config_option
(
bool
&
storage
,
const
char
*
category
,
const
char
*
name
,
const
char
*
description
);
config_option
make_negated_config_option
(
bool
&
storage
,
string_view
category
,
string_view
name
,
string_view
description
);
// Reads timespans, but stores an integer representing microsecond resolution.
config_option
make_us_resolution_config_option
(
size_t
&
storage
,
const
char
*
category
,
const
char
*
name
,
const
char
*
description
);
string_view
category
,
string_view
name
,
string_view
description
);
// Reads timespans, but stores an integer representing millisecond resolution.
config_option
make_ms_resolution_config_option
(
size_t
&
storage
,
const
char
*
category
,
const
char
*
name
,
const
char
*
description
);
string_view
category
,
string_view
name
,
string_view
description
);
// -- specializations for common types -----------------------------------------
...
...
libcaf_core/caf/string_algorithms.hpp
View file @
21b8e8c5
...
...
@@ -39,8 +39,8 @@ inline std::string is_any_of(std::string arg) {
constexpr
bool
token_compress_on
=
false
;
template
<
class
Container
,
class
Delim
>
void
split
(
Container
&
result
,
const
std
::
string
&
str
,
const
Delim
&
delims
,
template
<
class
Container
,
class
Str
,
class
Delim
>
void
split
(
Container
&
result
,
const
Str
&
str
,
const
Delim
&
delims
,
bool
keep_all
=
true
)
{
size_t
pos
=
0
;
size_t
prev
=
0
;
...
...
@@ -53,9 +53,8 @@ void split(Container& result, const std::string& str, const Delim& delims,
}
prev
=
pos
+
1
;
}
if
(
prev
<
str
.
size
())
{
if
(
prev
<
str
.
size
())
result
.
push_back
(
str
.
substr
(
prev
,
std
::
string
::
npos
));
}
}
template
<
class
Iterator
>
...
...
libcaf_core/caf/string_view.hpp
0 → 100644
View file @
21b8e8c5
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2018 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 <cstddef>
#include <iosfwd>
#include <iterator>
#include <limits>
#include <type_traits>
#include "caf/detail/comparable.hpp"
namespace
caf
{
namespace
detail
{
// Catches `std::string`, `std::string_view` and all classes mimicing those,
// but not `std::vector<char>` or other buffers.
template
<
class
T
>
struct
is_string_like
{
// SFINAE checks.
template
<
class
U
>
static
bool
sfinae
(
const
U
*
x
,
// check if `(*x)[0]` returns `const char&`
typename
std
::
enable_if
<
std
::
is_same
<
const
char
&
,
decltype
((
*
x
)[
0
])
>::
value
>::
type
*
=
nullptr
,
// check if `x->size()` returns an integer
typename
std
::
enable_if
<
std
::
is_integral
<
decltype
(
x
->
size
())
>::
value
>::
type
*
=
nullptr
,
// check if `x->compare(*x)` is well-formed and returns an integer
// (distinguishes vectors from strings)
typename
std
::
enable_if
<
std
::
is_integral
<
decltype
(
x
->
compare
(
*
x
))
>::
value
>::
type
*
=
nullptr
);
// SFINAE fallback.
static
void
sfinae
(
void
*
);
// Result of SFINAE test.
using
result_type
=
decltype
(
sfinae
(
static_cast
<
typename
std
::
decay
<
T
>::
type
*>
(
nullptr
)));
// Trait result.
static
constexpr
bool
value
=
std
::
is_same
<
bool
,
result_type
>::
value
;
};
}
// namespace detail
/// Drop-in replacement for C++17 std::string_view.
class
string_view
:
detail
::
comparable
<
string_view
>
{
public:
// -- member types -----------------------------------------------------------
using
value_type
=
char
;
using
pointer
=
value_type
*
;
using
const_pointer
=
const
value_type
*
;
using
reference
=
value_type
&
;
using
const_reference
=
const
value_type
&
;
using
const_iterator
=
const_pointer
;
using
iterator
=
const_iterator
;
using
const_reverse_iterator
=
std
::
reverse_iterator
<
const_iterator
>
;
using
reverse_iterator
=
const_reverse_iterator
;
using
size_type
=
size_t
;
using
difference_type
=
ptrdiff_t
;
// -- constants --------------------------------------------------------------
static
constexpr
size_type
npos
=
std
::
numeric_limits
<
size_type
>::
max
();
// -- constructors, destructors, and assignment operators --------------------
constexpr
string_view
()
noexcept
:
data_
(
nullptr
),
size_
(
0
)
{
// nop
}
constexpr
string_view
(
const
char
*
cstr
,
size_t
length
)
noexcept
:
data_
(
cstr
),
size_
(
length
)
{
// nop
}
template
<
size_t
N
>
constexpr
string_view
(
const
char
(
&
cstr
)[
N
])
noexcept
:
data_
(
cstr
),
size_
(
N
-
1
)
{
static_assert
(
N
>
0
,
""
);
}
constexpr
string_view
(
const
string_view
&
)
noexcept
=
default
;
template
<
class
T
,
class
=
typename
std
::
enable_if
<
detail
::
is_string_like
<
T
>
::
value
>::
type
>
string_view
(
const
T
&
str
)
noexcept
{
auto
len
=
str
.
size
();
if
(
len
==
0
)
{
data_
=
nullptr
;
size_
=
0
;
}
else
{
data_
=
&
(
str
[
0
]);
size_
=
str
.
size
();
}
}
string_view
&
operator
=
(
const
string_view
&
)
noexcept
=
default
;
// -- capacity ---------------------------------------------------------------
constexpr
size_type
size
()
const
noexcept
{
return
size_
;
}
constexpr
size_type
length
()
const
noexcept
{
return
size_
;
}
constexpr
size_type
max_size
()
const
noexcept
{
return
std
::
numeric_limits
<
size_type
>::
max
();
}
constexpr
bool
empty
()
const
noexcept
{
return
size_
==
0
;
}
// -- iterator access --------------------------------------------------------
constexpr
const_iterator
begin
()
const
noexcept
{
return
data_
;
}
constexpr
const_iterator
end
()
const
noexcept
{
return
data_
+
size_
;
}
constexpr
const_iterator
cbegin
()
const
noexcept
{
return
begin
();
}
constexpr
const_iterator
cend
()
const
noexcept
{
return
end
();
}
const_reverse_iterator
rbegin
()
const
noexcept
;
const_reverse_iterator
rend
()
const
noexcept
;
const_reverse_iterator
crbegin
()
const
noexcept
;
const_reverse_iterator
crend
()
const
noexcept
;
// -- element access ---------------------------------------------------------
constexpr
const_reference
operator
[](
size_type
pos
)
const
{
return
data_
[
pos
];
}
const_reference
at
(
size_type
pos
)
const
;
constexpr
const_reference
front
()
const
{
return
*
data_
;
}
constexpr
const_reference
back
()
const
{
return
data_
[
size_
-
1
];
}
constexpr
const_pointer
data
()
const
noexcept
{
return
data_
;
}
// -- modifiers --------------------------------------------------------------
void
remove_prefix
(
size_type
n
);
void
remove_suffix
(
size_type
n
);
void
assign
(
const_pointer
data
,
size_type
len
);
// -- algortihms -------------------------------------------------------------
size_type
copy
(
pointer
dest
,
size_type
n
,
size_type
pos
=
0
)
const
;
string_view
substr
(
size_type
pos
=
0
,
size_type
n
=
npos
)
const
noexcept
;
int
compare
(
string_view
s
)
const
noexcept
;
int
compare
(
size_type
pos1
,
size_type
n1
,
string_view
str
)
const
noexcept
;
int
compare
(
size_type
pos1
,
size_type
n1
,
string_view
str
,
size_type
pos2
,
size_type
n2
)
const
noexcept
;
int
compare
(
const_pointer
str
)
const
noexcept
;
int
compare
(
size_type
pos
,
size_type
n
,
const_pointer
str
)
const
noexcept
;
int
compare
(
size_type
pos1
,
size_type
n1
,
const_pointer
s
,
size_type
n2
)
const
noexcept
;
size_type
find
(
string_view
str
,
size_type
pos
=
0
)
const
noexcept
;
size_type
find
(
value_type
ch
,
size_type
pos
=
0
)
const
noexcept
;
size_type
find
(
const_pointer
str
,
size_type
pos
,
size_type
n
)
const
noexcept
;
size_type
find
(
const_pointer
str
,
size_type
pos
=
0
)
const
noexcept
;
size_type
rfind
(
string_view
str
,
size_type
pos
=
npos
)
const
noexcept
;
size_type
rfind
(
value_type
ch
,
size_type
pos
=
npos
)
const
noexcept
;
size_type
rfind
(
const_pointer
str
,
size_type
pos
,
size_type
n
)
const
noexcept
;
size_type
rfind
(
const_pointer
str
,
size_type
pos
=
npos
)
const
noexcept
;
size_type
find_first_of
(
string_view
str
,
size_type
pos
=
0
)
const
noexcept
;
size_type
find_first_of
(
value_type
ch
,
size_type
pos
=
0
)
const
noexcept
;
size_type
find_first_of
(
const_pointer
str
,
size_type
pos
,
size_type
n
)
const
noexcept
;
size_type
find_first_of
(
const_pointer
str
,
size_type
pos
=
0
)
const
noexcept
;
size_type
find_last_of
(
string_view
str
,
size_type
pos
=
npos
)
const
noexcept
;
size_type
find_last_of
(
value_type
ch
,
size_type
pos
=
npos
)
const
noexcept
;
size_type
find_last_of
(
const_pointer
str
,
size_type
pos
,
size_type
n
)
const
noexcept
;
size_type
find_last_of
(
const_pointer
str
,
size_type
pos
=
npos
)
const
noexcept
;
size_type
find_first_not_of
(
string_view
str
,
size_type
pos
=
0
)
const
noexcept
;
size_type
find_first_not_of
(
value_type
ch
,
size_type
pos
=
0
)
const
noexcept
;
size_type
find_first_not_of
(
const_pointer
str
,
size_type
pos
,
size_type
n
)
const
noexcept
;
size_type
find_first_not_of
(
const_pointer
str
,
size_type
pos
=
0
)
const
noexcept
;
size_type
find_last_not_of
(
string_view
str
,
size_type
pos
=
npos
)
const
noexcept
;
size_type
find_last_not_of
(
value_type
ch
,
size_type
pos
=
npos
)
const
noexcept
;
size_type
find_last_not_of
(
const_pointer
str
,
size_type
pos
,
size_type
n
)
const
noexcept
;
size_type
find_last_not_of
(
const_pointer
str
,
size_type
pos
=
npos
)
const
noexcept
;
private:
const
char
*
data_
;
size_t
size_
;
};
}
// namespace caf
namespace
std
{
std
::
ostream
&
operator
<<
(
std
::
ostream
&
out
,
caf
::
string_view
);
}
// namespace std
libcaf_core/src/actor_system_config.cpp
View file @
21b8e8c5
...
...
@@ -388,7 +388,7 @@ actor_system_config::add_error_category(atom_value x, error_renderer y) {
return
*
this
;
}
actor_system_config
&
actor_system_config
::
set_impl
(
const
char
*
name
,
actor_system_config
&
actor_system_config
::
set_impl
(
string_view
name
,
config_value
value
)
{
auto
opt
=
custom_options_
.
qualified_name_lookup
(
name
);
if
(
opt
!=
nullptr
&&
opt
->
check
(
value
)
==
none
)
{
...
...
@@ -454,7 +454,7 @@ void actor_system_config::extract_config_file_path(string_list& args) {
args
.
erase
(
i
);
}
const
std
::
map
<
std
::
string
,
std
::
map
<
std
::
string
,
config_value
>>&
const
dictionary
<
dictionary
<
config_value
>>&
content
(
const
actor_system_config
&
cfg
)
{
return
cfg
.
content
;
}
...
...
libcaf_core/src/config_option.cpp
View file @
21b8e8c5
...
...
@@ -18,8 +18,9 @@
#include "caf/config_option.hpp"
#include <cstring>
#include <iostream>
#include <algorithm>
#include <limits>
#include <numeric>
#include "caf/config.hpp"
#include "caf/config_value.hpp"
...
...
@@ -29,41 +30,73 @@
using
std
::
move
;
using
std
::
string
;
namespace
{
namespace
caf
{
// -- constructors, destructors, and assignment operators ----------------------
string
get_long_name
(
const
char
*
name
)
{
auto
i
=
strchr
(
name
,
','
);
return
i
!=
nullptr
?
string
{
name
,
i
}
:
string
{
name
};
config_option
::
config_option
(
string_view
category
,
string_view
name
,
string_view
description
,
const
meta_state
*
meta
,
void
*
value
)
:
meta_
(
meta
),
value_
(
value
)
{
using
std
::
copy
;
using
std
::
accumulate
;
auto
comma
=
name
.
find
(
','
);
auto
long_name
=
name
.
substr
(
0
,
comma
);
auto
short_names
=
comma
==
string_view
::
npos
?
string_view
{}
:
name
.
substr
(
comma
+
1
);
auto
total_size
=
[](
std
::
initializer_list
<
string_view
>
xs
)
{
return
(
xs
.
size
()
-
1
)
// one separator between all fields
+
accumulate
(
xs
.
begin
(),
xs
.
end
(),
size_t
{
0
},
[](
size_t
x
,
string_view
sv
)
{
return
x
+
sv
.
size
();
});
};
auto
ts
=
total_size
({
category
,
long_name
,
short_names
,
description
});
CAF_ASSERT
(
ts
<=
std
::
numeric_limits
<
uint16_t
>::
max
());
buf_size_
=
static_cast
<
uint16_t
>
(
ts
);
buf_
.
reset
(
new
char
[
ts
]);
// fille the buffer with "<category>.<long-name>,<short-name>,<descriptions>"
auto
first
=
buf_
.
get
();
auto
i
=
first
;
auto
pos
=
[
&
]
{
return
static_cast
<
uint16_t
>
(
std
::
distance
(
first
,
i
));
};
// <category>.
i
=
copy
(
category
.
begin
(),
category
.
end
(),
i
);
category_separator_
=
pos
();
*
i
++
=
'.'
;
// <long-name>,
i
=
copy
(
long_name
.
begin
(),
long_name
.
end
(),
i
);
long_name_separator_
=
pos
();
*
i
++
=
','
;
// <short-names>,
i
=
copy
(
short_names
.
begin
(),
short_names
.
end
(),
i
);
short_names_separator_
=
pos
();
*
i
++
=
','
;
// <description>
copy
(
description
.
begin
(),
description
.
end
(),
i
);
CAF_ASSERT
(
pos
()
==
buf_size_
);
}
string
get_short_names
(
const
char
*
name
)
{
auto
substr
=
strchr
(
name
,
','
);
if
(
substr
!=
nullptr
)
return
++
substr
;
return
string
{};
// -- properties ---------------------------------------------------------------
string_view
config_option
::
category
()
const
noexcept
{
return
buf_slice
(
0
,
category_separator_
);
}
}
// namespace <anonymous>
string_view
config_option
::
long_name
()
const
noexcept
{
return
buf_slice
(
category_separator_
+
1
,
long_name_separator_
);
}
namespace
caf
{
string_view
config_option
::
short_names
()
const
noexcept
{
return
buf_slice
(
long_name_separator_
+
1
,
short_names_separator_
);
}
config_option
::
config_option
(
string
category
,
const
char
*
name
,
string
description
,
const
meta_state
*
meta
,
void
*
value
)
:
category_
(
move
(
category
)),
long_name_
(
get_long_name
(
name
)),
short_names_
(
get_short_names
(
name
)),
description_
(
move
(
description
)),
meta_
(
meta
),
value_
(
value
)
{
CAF_ASSERT
(
meta_
!=
nullptr
);
string_view
config_option
::
description
()
const
noexcept
{
return
buf_slice
(
short_names_separator_
+
1
,
buf_size_
);
}
string
config_option
::
full_name
()
const
{
std
::
string
result
=
category
();
result
+=
'.'
;
result
+=
long_name_
;
return
result
;
string_view
config_option
::
full_name
()
const
noexcept
{
return
buf_slice
(
0
,
long_name_separator_
);
}
error
config_option
::
check
(
const
config_value
&
x
)
const
{
...
...
@@ -78,7 +111,7 @@ void config_option::store(const config_value& x) const {
}
}
const
std
::
string
&
config_option
::
type_name
()
const
noexcept
{
string_view
config_option
::
type_name
()
const
noexcept
{
return
meta_
->
type_name
;
}
...
...
@@ -92,4 +125,9 @@ optional<config_value> config_option::get() const {
return
none
;
}
string_view
config_option
::
buf_slice
(
size_t
from
,
size_t
to
)
const
noexcept
{
CAF_ASSERT
(
from
<=
to
);
return
{
buf_
.
get
()
+
from
,
to
-
from
};
}
}
// namespace caf
libcaf_core/src/config_option_adder.cpp
View file @
21b8e8c5
...
...
@@ -23,26 +23,26 @@
namespace
caf
{
config_option_adder
::
config_option_adder
(
config_option_set
&
target
,
const
char
*
category
)
string_view
category
)
:
xs_
(
target
),
category_
(
category
)
{
// nop
}
config_option_adder
&
config_option_adder
::
add_neg
(
bool
&
ref
,
const
char
*
name
,
const
char
*
description
)
{
config_option_adder
&
config_option_adder
::
add_neg
(
bool
&
ref
,
string_view
name
,
string_view
description
)
{
return
add_impl
(
make_negated_config_option
(
ref
,
category_
,
name
,
description
));
}
config_option_adder
&
config_option_adder
::
add_us
(
size_t
&
ref
,
const
char
*
name
,
const
char
*
description
)
{
config_option_adder
&
config_option_adder
::
add_us
(
size_t
&
ref
,
string_view
name
,
string_view
description
)
{
return
add_impl
(
make_us_resolution_config_option
(
ref
,
category_
,
name
,
description
));
}
config_option_adder
&
config_option_adder
::
add_ms
(
size_t
&
ref
,
const
char
*
name
,
const
char
*
description
)
{
config_option_adder
&
config_option_adder
::
add_ms
(
size_t
&
ref
,
string_view
name
,
string_view
description
)
{
return
add_impl
(
make_ms_resolution_config_option
(
ref
,
category_
,
name
,
description
));
}
...
...
libcaf_core/src/config_option_set.cpp
View file @
21b8e8c5
...
...
@@ -34,19 +34,13 @@ struct string_builder {
std
::
string
result
;
};
template
<
size_t
N
>
string_builder
&
operator
<<
(
string_builder
&
builder
,
const
char
(
&
cstr
)[
N
])
{
builder
.
result
.
append
(
cstr
,
N
-
1
);
string_builder
&
operator
<<
(
string_builder
&
builder
,
char
ch
)
{
builder
.
result
+=
ch
;
return
builder
;
}
string_builder
&
operator
<<
(
string_builder
&
builder
,
char
c
)
{
builder
.
result
+=
c
;
return
builder
;
}
string_builder
&
operator
<<
(
string_builder
&
builder
,
const
std
::
string
&
str
)
{
builder
.
result
+=
str
;
string_builder
&
operator
<<
(
string_builder
&
builder
,
caf
::
string_view
str
)
{
builder
.
result
.
append
(
str
.
data
(),
str
.
size
());
return
builder
;
}
...
...
@@ -94,8 +88,8 @@ std::string config_option_set::help_text(bool global_only) const {
};
// Sort argument + description by category.
using
pair
=
std
::
pair
<
std
::
string
,
option_pointer
>
;
std
::
set
<
st
d
::
string
>
categories
;
std
::
multimap
<
st
d
::
string
,
pair
>
args
;
std
::
set
<
st
ring_view
>
categories
;
std
::
multimap
<
st
ring_view
,
pair
>
args
;
size_t
max_arg_size
=
0
;
for
(
auto
&
opt
:
opts_
)
{
if
(
!
global_only
||
opt
.
category
()
==
"global"
)
{
...
...
@@ -132,7 +126,7 @@ auto config_option_set::parse(config_map& config, argument_iterator first,
auto
consume
=
[
&
](
const
config_option
&
opt
,
iter
arg_begin
,
iter
arg_end
)
{
// Extract option name and category.
auto
opt_name
=
opt
.
long_name
();
string
opt_ctg
=
opt
.
category
();
auto
opt_ctg
=
opt
.
category
();
// Try inserting a new submap into the config or fill existing one.
auto
&
submap
=
config
[
opt_ctg
];
// Flags only consume the current element.
...
...
@@ -145,7 +139,9 @@ auto config_option_set::parse(config_map& config, argument_iterator first,
}
else
{
if
(
arg_begin
==
arg_end
)
return
pec
::
missing_argument
;
auto
val
=
config_value
::
parse
(
arg_begin
,
arg_end
);
auto
slice_size
=
static_cast
<
size_t
>
(
std
::
distance
(
arg_begin
,
arg_end
));
string_view
slice
{
&*
arg_begin
,
slice_size
};
auto
val
=
config_value
::
parse
(
slice
);
if
(
!
val
)
return
pec
::
illegal_argument
;
if
(
opt
.
check
(
*
val
)
!=
none
)
...
...
@@ -224,12 +220,12 @@ config_option_set::parse(config_map& config,
}
config_option_set
::
option_pointer
config_option_set
::
cli_long_name_lookup
(
const
string
&
name
)
const
{
config_option_set
::
cli_long_name_lookup
(
string_view
name
)
const
{
// We accept "caf#" prefixes for backward compatibility, but ignore them.
size_t
offset
=
name
.
compare
(
0
,
4
,
"caf#"
)
!=
0
?
0u
:
4u
;
// Extract category and long name.
string
category
;
string
long_name
;
string
_view
category
;
string
_view
long_name
;
auto
sep
=
name
.
find
(
'.'
,
offset
);
if
(
sep
==
string
::
npos
)
{
category
=
"global"
;
...
...
@@ -255,15 +251,15 @@ config_option_set::cli_short_name_lookup(char short_name) const {
}
config_option_set
::
option_pointer
config_option_set
::
qualified_name_lookup
(
const
std
::
string
&
category
,
const
std
::
string
&
long_name
)
const
{
config_option_set
::
qualified_name_lookup
(
string_view
category
,
string_view
long_name
)
const
{
return
detail
::
ptr_find_if
(
opts_
,
[
&
](
const
config_option
&
opt
)
{
return
opt
.
category
()
==
category
&&
opt
.
long_name
()
==
long_name
;
});
}
config_option_set
::
option_pointer
config_option_set
::
qualified_name_lookup
(
const
std
::
string
&
name
)
const
{
config_option_set
::
qualified_name_lookup
(
string_view
name
)
const
{
auto
sep
=
name
.
find
(
'.'
);
if
(
sep
==
string
::
npos
)
return
nullptr
;
...
...
libcaf_core/src/config_value.cpp
View file @
21b8e8c5
...
...
@@ -50,8 +50,8 @@ config_value::~config_value() {
// -- parsing ------------------------------------------------------------------
expected
<
config_value
>
config_value
::
parse
(
st
d
::
string
::
const_
iterator
first
,
st
d
::
string
::
const_
iterator
last
)
{
expected
<
config_value
>
config_value
::
parse
(
st
ring_view
::
iterator
first
,
st
ring_view
::
iterator
last
)
{
using
namespace
detail
;
auto
i
=
first
;
// Sanity check.
...
...
@@ -62,7 +62,7 @@ expected<config_value> config_value::parse(std::string::const_iterator first,
if
(
++
i
==
last
)
return
make_error
(
pec
::
unexpected_eof
);
// Dispatch to parser.
parser
::
state
<
st
d
::
string
::
const_
iterator
>
res
;
parser
::
state
<
st
ring_view
::
iterator
>
res
;
detail
::
ini_value_consumer
f
;
res
.
i
=
i
;
res
.
e
=
last
;
...
...
@@ -84,7 +84,7 @@ expected<config_value> config_value::parse(std::string::const_iterator first,
}
}
expected
<
config_value
>
config_value
::
parse
(
const
std
::
string
&
str
)
{
expected
<
config_value
>
config_value
::
parse
(
string_view
str
)
{
return
parse
(
str
.
begin
(),
str
.
end
());
}
...
...
@@ -132,15 +132,15 @@ std::string get_or(const config_value::dictionary& xs, const std::string& name,
return
default_value
;
}
std
::
string
get_or
(
const
std
::
map
<
std
::
string
,
config_value
::
dictionary
>&
xs
,
const
std
::
string
&
name
,
const
char
*
default_value
)
{
std
::
string
get_or
(
const
dictionary
<
config_value
::
dictionary
>&
xs
,
string_view
name
,
const
char
*
default_value
)
{
auto
result
=
get_if
<
std
::
string
>
(
&
xs
,
name
);
if
(
result
)
return
std
::
move
(
*
result
);
return
default_value
;
}
std
::
string
get_or
(
const
actor_system_config
&
cfg
,
const
std
::
string
&
name
,
std
::
string
get_or
(
const
actor_system_config
&
cfg
,
string_view
name
,
const
char
*
default_value
)
{
return
get_or
(
content
(
cfg
),
name
,
default_value
);
}
...
...
libcaf_core/src/make_config_option.cpp
View file @
21b8e8c5
...
...
@@ -129,23 +129,23 @@ config_option::meta_state bool_meta_state{
}
// namespace detail
config_option
make_negated_config_option
(
bool
&
storage
,
const
char
*
category
,
const
char
*
name
,
const
char
*
description
)
{
config_option
make_negated_config_option
(
bool
&
storage
,
string_view
category
,
string_view
name
,
string_view
description
)
{
return
{
category
,
name
,
description
,
&
bool_neg_meta
,
&
storage
};
}
config_option
make_us_resolution_config_option
(
size_t
&
storage
,
const
char
*
category
,
const
char
*
name
,
const
char
*
description
)
{
string_view
category
,
string_view
name
,
string_view
description
)
{
return
{
category
,
name
,
description
,
&
us_res_meta
,
&
storage
};
}
config_option
make_ms_resolution_config_option
(
size_t
&
storage
,
const
char
*
category
,
const
char
*
name
,
const
char
*
description
)
{
string_view
category
,
string_view
name
,
string_view
description
)
{
return
{
category
,
name
,
description
,
&
ms_res_meta
,
&
storage
};
}
...
...
libcaf_core/src/string_view.cpp
0 → 100644
View file @
21b8e8c5
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2018 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. *
******************************************************************************/
#include "caf/string_view.hpp"
#include <algorithm>
#include <cstring>
#include <iostream>
#include <stdexcept>
#include "caf/config.hpp"
namespace
{
using
size_type
=
caf
::
string_view
::
size_type
;
}
// namespace anonymous
namespace
caf
{
// -- iterator access ----------------------------------------------------------
string_view
::
const_reverse_iterator
string_view
::
rbegin
()
const
noexcept
{
return
reverse_iterator
{
end
()};
}
string_view
::
const_reverse_iterator
string_view
::
rend
()
const
noexcept
{
return
reverse_iterator
{
begin
()};
}
string_view
::
const_reverse_iterator
string_view
::
crbegin
()
const
noexcept
{
return
rbegin
();
}
string_view
::
const_reverse_iterator
string_view
::
crend
()
const
noexcept
{
return
rend
();
}
// -- element access -----------------------------------------------------------
string_view
::
const_reference
string_view
::
at
(
size_type
pos
)
const
{
if
(
pos
<
size_
)
return
data_
[
pos
];
CAF_RAISE_ERROR
(
"string_view::at out of range"
);
}
// -- modifiers ----------------------------------------------------------------
void
string_view
::
remove_prefix
(
size_type
n
)
{
if
(
n
<
size
())
{
data_
+=
n
;
size_
-=
n
;
}
else
{
size_
=
0
;
}
}
void
string_view
::
remove_suffix
(
size_type
n
)
{
if
(
n
<
size
())
size_
-=
n
;
else
size_
=
0
;
}
void
string_view
::
assign
(
const_pointer
data
,
size_type
len
)
{
data_
=
data
;
size_
=
len
;
}
// -- algortihms ---------------------------------------------------------------
string_view
::
size_type
string_view
::
copy
(
pointer
dest
,
size_type
n
,
size_type
pos
)
const
{
if
(
pos
>
size_
)
CAF_RAISE_ERROR
(
"string_view::copy out of range"
);
auto
first
=
begin
()
+
pos
;
auto
end
=
first
+
std
::
min
(
n
,
size
()
-
pos
);
auto
cpy_end
=
std
::
copy
(
first
,
end
,
dest
);
return
static_cast
<
size_type
>
(
std
::
distance
(
dest
,
cpy_end
));
}
string_view
string_view
::
substr
(
size_type
pos
,
size_type
n
)
const
noexcept
{
if
(
pos
>=
size
())
return
{};
return
{
data_
+
pos
,
std
::
min
(
size_
-
pos
,
n
)};
}
int
string_view
::
compare
(
string_view
str
)
const
noexcept
{
return
strncmp
(
data
(),
str
.
data
(),
std
::
min
(
size
(),
str
.
size
()));
}
int
string_view
::
compare
(
size_type
pos1
,
size_type
n1
,
string_view
str
)
const
noexcept
{
return
substr
(
pos1
,
n1
).
compare
(
str
);
}
int
string_view
::
compare
(
size_type
pos1
,
size_type
n1
,
string_view
str
,
size_type
pos2
,
size_type
n2
)
const
noexcept
{
return
substr
(
pos1
,
n1
).
compare
(
str
.
substr
(
pos2
,
n2
));
}
int
string_view
::
compare
(
const_pointer
str
)
const
noexcept
{
return
strncmp
(
data
(),
str
,
size
());
}
int
string_view
::
compare
(
size_type
pos
,
size_type
n
,
const_pointer
str
)
const
noexcept
{
return
substr
(
pos
,
n
).
compare
(
str
);
}
int
string_view
::
compare
(
size_type
pos1
,
size_type
n1
,
const_pointer
str
,
size_type
n2
)
const
noexcept
{
return
substr
(
pos1
,
n1
).
compare
(
string_view
{
str
,
n2
});
}
size_type
string_view
::
find
(
string_view
str
,
size_type
pos
)
const
noexcept
{
string_view
tmp
;
if
(
pos
<
size_
)
tmp
.
assign
(
data_
+
pos
,
size_
-
pos
);
auto
first
=
tmp
.
begin
();
auto
last
=
tmp
.
end
();
auto
i
=
std
::
search
(
first
,
last
,
str
.
begin
(),
str
.
end
());
if
(
i
!=
last
)
return
static_cast
<
size_type
>
(
std
::
distance
(
first
,
i
))
+
pos
;
return
npos
;
}
size_type
string_view
::
find
(
value_type
ch
,
size_type
pos
)
const
noexcept
{
return
find
(
string_view
{
&
ch
,
1
},
pos
);
}
size_type
string_view
::
find
(
const_pointer
str
,
size_type
pos
,
size_type
n
)
const
noexcept
{
return
find
(
string_view
{
str
,
n
},
pos
);
}
size_type
string_view
::
find
(
const_pointer
str
,
size_type
pos
)
const
noexcept
{
return
find
(
string_view
{
str
,
strlen
(
str
)},
pos
);
}
size_type
string_view
::
rfind
(
string_view
str
,
size_type
pos
)
const
noexcept
{
if
(
size
()
<
str
.
size
())
return
npos
;
if
(
str
.
empty
())
return
std
::
min
(
size
(),
pos
);
string_view
tmp
{
data_
,
std
::
min
(
size
()
-
str
.
size
(),
pos
)
+
str
.
size
()};
auto
first
=
tmp
.
begin
();
auto
last
=
tmp
.
end
();
auto
i
=
std
::
find_end
(
first
,
last
,
str
.
begin
(),
str
.
end
());
return
i
!=
last
?
static_cast
<
size_type
>
(
std
::
distance
(
first
,
i
))
:
npos
;
}
size_type
string_view
::
rfind
(
value_type
ch
,
size_type
pos
)
const
noexcept
{
return
rfind
(
string_view
{
&
ch
,
1
},
pos
);
}
size_type
string_view
::
rfind
(
const_pointer
str
,
size_type
pos
,
size_type
n
)
const
noexcept
{
return
rfind
(
string_view
{
str
,
n
},
pos
);
}
size_type
string_view
::
rfind
(
const_pointer
str
,
size_type
pos
)
const
noexcept
{
return
rfind
(
string_view
{
str
,
strlen
(
str
)},
pos
);
}
size_type
string_view
::
find_first_of
(
string_view
str
,
size_type
pos
)
const
noexcept
{
if
(
empty
()
||
str
.
empty
())
return
npos
;
if
(
pos
>=
size
())
return
npos
;
if
(
str
.
size
()
==
1
)
return
find
(
str
.
front
(),
pos
);
string_view
tmp
{
data_
+
pos
,
size_
-
pos
};
auto
first
=
tmp
.
begin
();
auto
last
=
tmp
.
end
();
auto
i
=
std
::
find_first_of
(
first
,
last
,
str
.
begin
(),
str
.
end
());
return
i
!=
last
?
static_cast
<
size_type
>
(
std
::
distance
(
first
,
i
))
+
pos
:
npos
;
}
size_type
string_view
::
find_first_of
(
value_type
ch
,
size_type
pos
)
const
noexcept
{
return
find
(
ch
,
pos
);
}
size_type
string_view
::
find_first_of
(
const_pointer
str
,
size_type
pos
,
size_type
n
)
const
noexcept
{
return
find_first_of
(
string_view
{
str
,
n
},
pos
);
}
size_type
string_view
::
find_first_of
(
const_pointer
str
,
size_type
pos
)
const
noexcept
{
return
find_first_of
(
string_view
{
str
,
strlen
(
str
)},
pos
);
}
size_type
string_view
::
find_last_of
(
string_view
str
,
size_type
pos
)
const
noexcept
{
string_view
tmp
{
data_
,
pos
<
size_
?
pos
+
1
:
size_
};
auto
result
=
tmp
.
find_first_of
(
str
);
if
(
result
==
npos
)
return
npos
;
for
(;;)
{
auto
next
=
tmp
.
find_first_of
(
str
,
result
+
1
);
if
(
next
==
npos
)
return
result
;
result
=
next
;
}
}
size_type
string_view
::
find_last_of
(
value_type
ch
,
size_type
pos
)
const
noexcept
{
return
rfind
(
ch
,
pos
);
}
size_type
string_view
::
find_last_of
(
const_pointer
str
,
size_type
pos
,
size_type
n
)
const
noexcept
{
return
find_last_of
(
string_view
{
str
,
n
},
pos
);
}
size_type
string_view
::
find_last_of
(
const_pointer
str
,
size_type
pos
)
const
noexcept
{
return
find_last_of
(
string_view
{
str
,
strlen
(
str
)},
pos
);
}
size_type
string_view
::
find_first_not_of
(
string_view
str
,
size_type
pos
)
const
noexcept
{
if
(
str
.
size
()
==
1
)
return
find_first_not_of
(
str
.
front
(),
pos
);
if
(
pos
>=
size
())
return
npos
;
auto
pred
=
[
&
](
value_type
x
)
{
return
str
.
find
(
x
)
==
npos
;
};
string_view
tmp
{
data_
+
pos
,
size_
-
pos
};
auto
first
=
tmp
.
begin
();
auto
last
=
tmp
.
end
();
auto
i
=
std
::
find_if
(
first
,
last
,
pred
);
return
i
!=
last
?
static_cast
<
size_type
>
(
std
::
distance
(
first
,
i
))
+
pos
:
npos
;
}
size_type
string_view
::
find_first_not_of
(
value_type
ch
,
size_type
pos
)
const
noexcept
{
if
(
pos
>=
size
())
return
npos
;
auto
pred
=
[
=
](
value_type
x
)
{
return
x
!=
ch
;
};
string_view
tmp
{
data_
+
pos
,
size_
-
pos
};
auto
first
=
tmp
.
begin
();
auto
last
=
tmp
.
end
();
auto
i
=
std
::
find_if
(
first
,
last
,
pred
);
return
i
!=
last
?
static_cast
<
size_type
>
(
std
::
distance
(
first
,
i
))
+
pos
:
npos
;
}
size_type
string_view
::
find_first_not_of
(
const_pointer
str
,
size_type
pos
,
size_type
n
)
const
noexcept
{
return
find_first_not_of
(
string_view
{
str
,
n
},
pos
);
}
size_type
string_view
::
find_first_not_of
(
const_pointer
str
,
size_type
pos
)
const
noexcept
{
return
find_first_not_of
(
string_view
{
str
,
strlen
(
str
)},
pos
);
}
size_type
string_view
::
find_last_not_of
(
string_view
str
,
size_type
pos
)
const
noexcept
{
string_view
tmp
{
data_
,
pos
<
size_
?
pos
+
1
:
size_
};
auto
result
=
tmp
.
find_first_not_of
(
str
);
if
(
result
==
npos
)
return
npos
;
for
(;;)
{
auto
next
=
tmp
.
find_first_not_of
(
str
,
result
+
1
);
if
(
next
==
npos
)
return
result
;
result
=
next
;
}
}
size_type
string_view
::
find_last_not_of
(
value_type
ch
,
size_type
pos
)
const
noexcept
{
return
find_last_not_of
(
string_view
{
&
ch
,
1
},
pos
);
}
size_type
string_view
::
find_last_not_of
(
const_pointer
str
,
size_type
pos
,
size_type
n
)
const
noexcept
{
return
find_last_not_of
(
string_view
{
str
,
n
},
pos
);
}
size_type
string_view
::
find_last_not_of
(
const_pointer
str
,
size_type
pos
)
const
noexcept
{
return
find_last_not_of
(
string_view
{
str
,
strlen
(
str
)},
pos
);
}
}
// namespace caf
namespace
std
{
std
::
ostream
&
operator
<<
(
std
::
ostream
&
out
,
caf
::
string_view
str
)
{
for
(
auto
ch
:
str
)
out
.
put
(
ch
);
return
out
;
}
}
// namespace std
libcaf_core/test/config_option.cpp
View file @
21b8e8c5
...
...
@@ -30,9 +30,9 @@ using std::string;
namespace
{
constexpr
const
char
*
category
=
"category"
;
constexpr
const
char
*
name
=
"name"
;
constexpr
const
char
*
explanation
=
"explanation"
;
constexpr
string_view
category
=
"category"
;
constexpr
string_view
name
=
"name"
;
constexpr
string_view
explanation
=
"explanation"
;
template
<
class
T
>
constexpr
int64_t
overflow
()
{
...
...
@@ -45,7 +45,7 @@ constexpr int64_t underflow() {
}
template
<
class
T
>
optional
<
T
>
read
(
const
std
::
string
&
arg
)
{
optional
<
T
>
read
(
string_view
arg
)
{
auto
co
=
make_config_option
<
T
>
(
category
,
name
,
explanation
);
auto
res
=
config_value
::
parse
(
arg
);
if
(
res
&&
holds_alternative
<
T
>
(
*
res
))
{
...
...
libcaf_core/test/config_option_set.cpp
View file @
21b8e8c5
...
...
@@ -62,7 +62,7 @@ CAF_TEST(lookup) {
CAF_TEST
(
parse
with
ref
syncing
)
{
using
ls
=
vector
<
string
>
;
// list of strings
using
ds
=
std
::
map
<
string
,
string
>
;
// dictionary of strings
using
ds
=
dictionary
<
string
>
;
// dictionary of strings
auto
foo_i
=
0
;
auto
foo_f
=
0.
f
;
auto
foo_b
=
false
;
...
...
@@ -74,8 +74,8 @@ CAF_TEST(parse with ref syncing) {
.
add
<
bool
>
(
foo_b
,
"foo"
,
"b,b"
,
""
)
.
add
<
string
>
(
bar_s
,
"bar"
,
"s,s"
,
""
)
.
add
<
vector
<
string
>>
(
bar_l
,
"bar"
,
"l,l"
,
""
)
.
add
<
std
::
map
<
string
,
string
>>
(
bar_d
,
"bar"
,
"d,d"
,
""
);
std
::
map
<
std
::
string
,
config_value
::
dictionary
>
cfg
;
.
add
<
dictionary
<
string
>>
(
bar_d
,
"bar"
,
"d,d"
,
""
);
dictionary
<
config_value
::
dictionary
>
cfg
;
vector
<
string
>
args
{
"-i42"
,
"-f"
,
"1e12"
,
...
...
@@ -103,7 +103,7 @@ CAF_TEST(parse with ref syncing) {
CAF_TEST
(
implicit
global
)
{
opts
.
add
<
int
>
(
"global"
,
"value"
).
add
<
bool
>
(
"global"
,
"help"
);
CAF_MESSAGE
(
"test long option with argument"
);
std
::
map
<
std
::
string
,
config_value
::
dictionary
>
cfg
;
dictionary
<
config_value
::
dictionary
>
cfg
;
auto
res
=
opts
.
parse
(
cfg
,
{
"--value=42"
});
CAF_CHECK_EQUAL
(
res
.
first
,
pec
::
success
);
CAF_CHECK_EQUAL
(
get_if
<
int
>
(
&
cfg
,
"global.value"
),
42
);
...
...
libcaf_core/test/config_value.cpp
View file @
21b8e8c5
...
...
@@ -31,8 +31,10 @@
#include "caf/none.hpp"
#include "caf/pec.hpp"
#include "caf/variant.hpp"
#include "caf/string_view.hpp"
using
std
::
string
;
using
namespace
std
;
using
namespace
caf
;
namespace
{
...
...
@@ -44,7 +46,7 @@ using dictionary = config_value::dictionary;
struct
dictionary_builder
{
dictionary
dict
;
dictionary_builder
&&
add
(
const
char
*
key
,
config_value
value
)
&&
{
dictionary_builder
&&
add
(
string_view
key
,
config_value
value
)
&&
{
dict
.
emplace
(
key
,
std
::
move
(
value
));
return
std
::
move
(
*
this
);
}
...
...
@@ -69,8 +71,8 @@ config_value cfg_lst(Ts&&... xs) {
}
// TODO: switch to std::operator""s when switching to C++14
st
d
::
st
ring
operator
""
_s
(
const
char
*
str
,
size_t
size
)
{
return
st
d
::
st
ring
(
str
,
size
);
string
operator
""
_s
(
const
char
*
str
,
size_t
size
)
{
return
string
(
str
,
size
);
}
}
// namespace <anonymous>
...
...
@@ -158,7 +160,7 @@ CAF_TEST(append) {
}
CAF_TEST
(
homogeneous
dictionary
)
{
using
integer_map
=
std
::
map
<
std
::
string
,
int64_t
>
;
using
integer_map
=
caf
::
dictionary
<
int64_t
>
;
auto
xs
=
dict
()
.
add
(
"value-1"
,
config_value
{
100000
})
.
add
(
"value-2"
,
config_value
{
2
})
...
...
@@ -182,7 +184,7 @@ CAF_TEST(homogeneous dictionary) {
}
CAF_TEST
(
heterogeneous
dictionary
)
{
using
string_list
=
std
::
vector
<
st
d
::
st
ring
>
;
using
string_list
=
std
::
vector
<
string
>
;
auto
xs
=
dict
()
.
add
(
"scheduler"
,
dict
()
.
add
(
"policy"
,
config_value
{
atom
(
"none"
)})
...
...
@@ -206,7 +208,7 @@ CAF_TEST(successful parsing) {
// references when comparing values. Since we call get<T>() on the result of
// parse(), we would end up with a reference to a temporary.
config_value
parsed
;
auto
parse
=
[
&
](
const
st
d
::
st
ring
&
str
)
->
config_value
&
{
auto
parse
=
[
&
](
const
string
&
str
)
->
config_value
&
{
auto
x
=
config_value
::
parse
(
str
);
if
(
!
x
)
CAF_FAIL
(
"cannot parse "
<<
str
<<
": assumed a result but error "
...
...
@@ -214,7 +216,7 @@ CAF_TEST(successful parsing) {
parsed
=
std
::
move
(
*
x
);
return
parsed
;
};
using
di
=
std
::
map
<
string
,
int
>
;
// Dictionary-of-integers.
using
di
=
caf
::
dictionary
<
int
>
;
// Dictionary-of-integers.
using
ls
=
std
::
vector
<
string
>
;
// List-of-strings.
using
li
=
std
::
vector
<
int
>
;
// List-of-integers.
using
lli
=
std
::
vector
<
li
>
;
// List-of-list-of-integers.
...
...
@@ -235,7 +237,7 @@ CAF_TEST(successful parsing) {
}
CAF_TEST
(
unsuccessful
parsing
)
{
auto
parse
=
[](
const
st
d
::
st
ring
&
str
)
{
auto
parse
=
[](
const
string
&
str
)
{
auto
x
=
config_value
::
parse
(
str
);
if
(
x
)
CAF_FAIL
(
"assumed an error but got a result"
);
...
...
libcaf_core/test/dictionary.cpp
0 → 100644
View file @
21b8e8c5
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2018 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. *
******************************************************************************/
#include "caf/config.hpp"
#define CAF_SUITE dictionary
#include "caf/test/dsl.hpp"
#include "caf/dictionary.hpp"
using
namespace
caf
;
namespace
{
using
int_dict
=
dictionary
<
int
>
;
struct
fixture
{
};
}
// namespace <anonymous>
CAF_TEST_FIXTURE_SCOPE
(
dictionary_tests
,
fixture
)
CAF_TEST
(
construction
and
comparions
)
{
int_dict
xs
;
CAF_CHECK_EQUAL
(
xs
.
empty
(),
true
);
CAF_CHECK_EQUAL
(
xs
.
size
(),
0u
);
int_dict
ys
{{
"foo"
,
1
},
{
"bar"
,
2
}};
CAF_CHECK_EQUAL
(
ys
.
empty
(),
false
);
CAF_CHECK_EQUAL
(
ys
.
size
(),
2u
);
CAF_CHECK_NOT_EQUAL
(
xs
,
ys
);
int_dict
zs
{
ys
.
begin
(),
ys
.
end
()};
CAF_CHECK_EQUAL
(
zs
.
empty
(),
false
);
CAF_CHECK_EQUAL
(
zs
.
size
(),
2u
);
CAF_CHECK_EQUAL
(
ys
,
zs
);
zs
.
clear
();
CAF_CHECK_EQUAL
(
zs
.
empty
(),
true
);
CAF_CHECK_EQUAL
(
zs
.
size
(),
0u
);
CAF_CHECK_EQUAL
(
xs
,
zs
);
}
CAF_TEST
(
iterators
)
{
using
std
::
equal
;
using
vector_type
=
std
::
vector
<
int_dict
::
value_type
>
;
int_dict
xs
{{
"a"
,
1
},
{
"b"
,
2
},
{
"c"
,
3
}};
vector_type
ys
{{
"a"
,
1
},
{
"b"
,
2
},
{
"c"
,
3
}};
CAF_CHECK
(
equal
(
xs
.
begin
(),
xs
.
end
(),
ys
.
begin
()));
CAF_CHECK
(
equal
(
xs
.
cbegin
(),
xs
.
cend
(),
ys
.
cbegin
()));
CAF_CHECK
(
equal
(
xs
.
rbegin
(),
xs
.
rend
(),
ys
.
rbegin
()));
CAF_CHECK
(
equal
(
xs
.
crbegin
(),
xs
.
crend
(),
ys
.
crbegin
()));
}
CAF_TEST
(
swapping
)
{
int_dict
xs
{{
"foo"
,
1
},
{
"bar"
,
2
}};
int_dict
ys
;
int_dict
zs
{{
"foo"
,
1
},
{
"bar"
,
2
}};
CAF_CHECK_NOT_EQUAL
(
xs
,
ys
);
CAF_CHECK_NOT_EQUAL
(
ys
,
zs
);
CAF_CHECK_EQUAL
(
xs
,
zs
);
xs
.
swap
(
ys
);
CAF_CHECK_NOT_EQUAL
(
xs
,
ys
);
CAF_CHECK_EQUAL
(
ys
,
zs
);
CAF_CHECK_NOT_EQUAL
(
xs
,
zs
);
}
CAF_TEST
(
insertion
)
{
int_dict
xs
;
CAF_CHECK_EQUAL
(
xs
.
insert
(
"a"
,
1
).
second
,
true
);
CAF_CHECK_EQUAL
(
xs
.
insert
(
"b"
,
2
).
second
,
true
);
CAF_CHECK_EQUAL
(
xs
.
insert
(
"c"
,
3
).
second
,
true
);
CAF_CHECK_EQUAL
(
xs
.
insert
(
"c"
,
4
).
second
,
false
);
int_dict
ys
;
CAF_CHECK_EQUAL
(
ys
.
insert_or_assign
(
"a"
,
1
).
second
,
true
);
CAF_CHECK_EQUAL
(
ys
.
insert_or_assign
(
"b"
,
2
).
second
,
true
);
CAF_CHECK_EQUAL
(
ys
.
insert_or_assign
(
"c"
,
0
).
second
,
true
);
CAF_CHECK_EQUAL
(
ys
.
insert_or_assign
(
"c"
,
3
).
second
,
false
);
CAF_CHECK_EQUAL
(
xs
,
ys
);
}
CAF_TEST
(
insertion
with
hint
)
{
int_dict
xs
;
auto
xs_last
=
xs
.
end
();
auto
xs_insert
=
[
&
](
string_view
key
,
int
val
)
{
xs_last
=
xs
.
insert
(
xs_last
,
key
,
val
);
};
xs_insert
(
"a"
,
1
);
xs_insert
(
"c"
,
3
);
xs_insert
(
"b"
,
2
);
xs_insert
(
"c"
,
4
);
int_dict
ys
;
auto
ys_last
=
ys
.
end
();
auto
ys_insert_or_assign
=
[
&
](
string_view
key
,
int
val
)
{
ys_last
=
ys
.
insert_or_assign
(
ys_last
,
key
,
val
);
};
ys_insert_or_assign
(
"a"
,
1
);
ys_insert_or_assign
(
"c"
,
0
);
ys_insert_or_assign
(
"b"
,
2
);
ys_insert_or_assign
(
"c"
,
3
);
CAF_CHECK_EQUAL
(
xs
,
ys
);
}
CAF_TEST
(
bounds
)
{
int_dict
xs
{{
"a"
,
1
},
{
"b"
,
2
},
{
"c"
,
3
},
{
"d"
,
4
}};
const
int_dict
&
const_xs
=
xs
;
CAF_CHECK_EQUAL
(
xs
.
lower_bound
(
"c"
)
->
first
,
"c"
);
CAF_CHECK_EQUAL
(
xs
.
upper_bound
(
"c"
)
->
first
,
"d"
);
CAF_CHECK_EQUAL
(
const_xs
.
lower_bound
(
"c"
)
->
first
,
"c"
);
CAF_CHECK_EQUAL
(
const_xs
.
upper_bound
(
"c"
)
->
first
,
"d"
);
}
CAF_TEST
(
find
)
{
int_dict
xs
{{
"a"
,
1
},
{
"b"
,
2
},
{
"c"
,
3
},
{
"d"
,
4
}};
const
int_dict
&
const_xs
=
xs
;
CAF_CHECK_EQUAL
(
xs
.
find
(
"e"
),
xs
.
end
());
CAF_CHECK_EQUAL
(
xs
.
find
(
"a"
)
->
second
,
1
);
CAF_CHECK_EQUAL
(
xs
.
find
(
"c"
)
->
second
,
3
);
CAF_CHECK_EQUAL
(
const_xs
.
find
(
"e"
),
xs
.
end
());
CAF_CHECK_EQUAL
(
const_xs
.
find
(
"a"
)
->
second
,
1
);
CAF_CHECK_EQUAL
(
const_xs
.
find
(
"c"
)
->
second
,
3
);
}
CAF_TEST
(
element
access
)
{
int_dict
xs
{{
"a"
,
1
},
{
"b"
,
2
},
{
"c"
,
3
},
{
"d"
,
4
}};
CAF_CHECK_EQUAL
(
xs
[
"a"
],
1
);
CAF_CHECK_EQUAL
(
xs
[
"b"
],
2
);
CAF_CHECK_EQUAL
(
xs
[
"e"
],
0
);
}
CAF_TEST_FIXTURE_SCOPE_END
()
libcaf_core/test/string_view.cpp
0 → 100644
View file @
21b8e8c5
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2018 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. *
******************************************************************************/
#include "caf/config.hpp"
#define CAF_SUITE string_view
#include "caf/test/dsl.hpp"
#include "caf/string_view.hpp"
using
namespace
caf
;
namespace
{
struct
fixture
{
};
}
// namespace <anonymous>
CAF_TEST_FIXTURE_SCOPE
(
string_view_tests
,
fixture
)
CAF_TEST
(
default
construction
)
{
string_view
x
;
string_view
y
;
CAF_CHECK
(
x
.
empty
());
CAF_CHECK_EQUAL
(
x
.
size
(),
0u
);
CAF_CHECK_EQUAL
(
x
.
data
(),
nullptr
);
CAF_CHECK_EQUAL
(
y
,
y
);
}
CAF_TEST
(
cstring
conversion
)
{
string_view
x
=
"abc"
;
CAF_CHECK_EQUAL
(
x
.
size
(),
3u
);
CAF_CHECK_EQUAL
(
x
[
0
],
'a'
);
CAF_CHECK_EQUAL
(
x
[
1
],
'b'
);
CAF_CHECK_EQUAL
(
x
[
2
],
'c'
);
CAF_CHECK_EQUAL
(
x
,
"abc"
);
x
=
"def"
;
CAF_CHECK_NOT_EQUAL
(
x
,
"abc"
);
CAF_CHECK_EQUAL
(
x
,
"def"
);
}
CAF_TEST
(
string
conversion
)
{
std
::
string
x
=
"abc"
;
string_view
y
;
y
=
x
;
CAF_CHECK_EQUAL
(
x
,
y
);
auto
f
=
[
&
](
string_view
z
)
{
CAF_CHECK_EQUAL
(
x
,
z
);
};
f
(
x
);
}
CAF_TEST
(
substrings
)
{
string_view
x
=
"abcdefghi"
;
CAF_CHECK
(
x
.
remove_prefix
(
3
),
"defghi"
);
CAF_CHECK
(
x
.
remove_suffix
(
3
),
"abcdef"
);
CAF_CHECK
(
x
.
substr
(
3
,
3
),
"def"
);
CAF_CHECK
(
x
.
remove_prefix
(
9
),
""
);
CAF_CHECK
(
x
.
remove_suffix
(
9
),
""
);
CAF_CHECK
(
x
.
substr
(
9
),
""
);
CAF_CHECK
(
x
.
substr
(
0
,
0
),
""
);
}
CAF_TEST
(
compare
)
{
// testees
string_view
x
=
"abc"
;
string_view
y
=
"bcd"
;
string_view
z
=
"cde"
;
// x.compare full strings
CAF_CHECK
(
x
.
compare
(
"abc"
)
==
0
);
CAF_CHECK
(
x
.
compare
(
y
)
<
0
);
CAF_CHECK
(
x
.
compare
(
z
)
<
0
);
// y.compare full strings
CAF_CHECK
(
y
.
compare
(
x
)
>
0
);
CAF_CHECK
(
y
.
compare
(
"bcd"
)
==
0
);
CAF_CHECK
(
y
.
compare
(
z
)
<
0
);
// z.compare full strings
CAF_CHECK
(
z
.
compare
(
x
)
>
0
);
CAF_CHECK
(
z
.
compare
(
y
)
>
0
);
CAF_CHECK
(
z
.
compare
(
"cde"
)
==
0
);
// x.compare substrings
CAF_CHECK
(
x
.
compare
(
0
,
3
,
"abc"
)
==
0
);
CAF_CHECK
(
x
.
compare
(
1
,
2
,
y
,
0
,
2
)
==
0
);
CAF_CHECK
(
x
.
compare
(
2
,
1
,
z
,
0
,
1
)
==
0
);
CAF_CHECK
(
x
.
compare
(
2
,
1
,
z
,
0
,
2
)
==
0
);
}
CAF_TEST
(
copy
)
{
char
buf
[
10
];
string_view
str
=
"hello"
;
auto
n
=
str
.
copy
(
buf
,
str
.
size
());
CAF_CHECK_EQUAL
(
n
,
5u
);
buf
[
n
]
=
'\0'
;
CAF_CHECK_EQUAL
(
str
,
string_view
(
buf
,
n
));
CAF_CHECK
(
strcmp
(
"hello"
,
buf
)
==
0
);
n
=
str
.
copy
(
buf
,
10
,
3
);
buf
[
n
]
=
'\0'
;
CAF_CHECK_EQUAL
(
string_view
(
buf
,
n
),
"lo"
);
CAF_CHECK
(
strcmp
(
"lo"
,
buf
)
==
0
);
}
CAF_TEST
(
find
)
{
// Check whether string_view behaves exactly like std::string.
string_view
x
=
"abcdef"
;
std
::
string
y
=
"abcdef"
;
CAF_CHECK_EQUAL
(
x
.
find
(
'a'
),
y
.
find
(
'a'
));
CAF_CHECK_EQUAL
(
x
.
find
(
'b'
),
y
.
find
(
'b'
));
CAF_CHECK_EQUAL
(
x
.
find
(
'g'
),
y
.
find
(
'g'
));
CAF_CHECK_EQUAL
(
x
.
find
(
'a'
,
1
),
y
.
find
(
'a'
,
1
));
CAF_CHECK_EQUAL
(
x
.
find
(
"a"
),
y
.
find
(
"a"
));
CAF_CHECK_EQUAL
(
x
.
find
(
"bc"
),
y
.
find
(
"bc"
));
CAF_CHECK_EQUAL
(
x
.
find
(
"ce"
),
y
.
find
(
"ce"
));
CAF_CHECK_EQUAL
(
x
.
find
(
"bc"
,
1
),
y
.
find
(
"bc"
,
1
));
CAF_CHECK_EQUAL
(
x
.
find
(
"bc"
,
1
,
0
),
y
.
find
(
"bc"
,
1
,
0
));
CAF_CHECK_EQUAL
(
x
.
find
(
"bc"
,
0
,
1
),
y
.
find
(
"bc"
,
0
,
1
));
CAF_CHECK_EQUAL
(
x
.
find
(
"bc"
,
2
,
10
),
y
.
find
(
"bc"
,
2
,
10
));
}
CAF_TEST
(
rfind
)
{
// Check whether string_view behaves exactly like std::string.
string_view
x
=
"abccba"
;
std
::
string
y
=
"abccba"
;
CAF_CHECK_EQUAL
(
x
.
rfind
(
'a'
),
y
.
rfind
(
'a'
));
CAF_CHECK_EQUAL
(
x
.
rfind
(
'b'
),
y
.
rfind
(
'b'
));
CAF_CHECK_EQUAL
(
x
.
rfind
(
'g'
),
y
.
rfind
(
'g'
));
CAF_CHECK_EQUAL
(
x
.
rfind
(
'a'
,
1
),
y
.
rfind
(
'a'
,
1
));
CAF_CHECK_EQUAL
(
x
.
rfind
(
"a"
),
y
.
rfind
(
"a"
));
CAF_CHECK_EQUAL
(
x
.
rfind
(
"bc"
),
y
.
rfind
(
"bc"
));
CAF_CHECK_EQUAL
(
x
.
rfind
(
"ce"
),
y
.
rfind
(
"ce"
));
CAF_CHECK_EQUAL
(
x
.
rfind
(
"bc"
,
1
),
y
.
rfind
(
"bc"
,
1
));
CAF_CHECK_EQUAL
(
x
.
rfind
(
"bc"
,
1
,
0
),
y
.
rfind
(
"bc"
,
1
,
0
));
CAF_CHECK_EQUAL
(
x
.
rfind
(
"bc"
,
0
,
1
),
y
.
rfind
(
"bc"
,
0
,
1
));
CAF_CHECK_EQUAL
(
x
.
rfind
(
"bc"
,
2
,
10
),
y
.
rfind
(
"bc"
,
2
,
10
));
}
CAF_TEST
(
find_first_of
)
{
// Check whether string_view behaves exactly like std::string.
string_view
x
=
"abcdef"
;
std
::
string
y
=
"abcdef"
;
CAF_CHECK_EQUAL
(
x
.
find_first_of
(
'a'
),
y
.
find_first_of
(
'a'
));
CAF_CHECK_EQUAL
(
x
.
find_first_of
(
'b'
),
y
.
find_first_of
(
'b'
));
CAF_CHECK_EQUAL
(
x
.
find_first_of
(
'g'
),
y
.
find_first_of
(
'g'
));
CAF_CHECK_EQUAL
(
x
.
find_first_of
(
'a'
,
1
),
y
.
find_first_of
(
'a'
,
1
));
CAF_CHECK_EQUAL
(
x
.
find_first_of
(
"a"
),
y
.
find_first_of
(
"a"
));
CAF_CHECK_EQUAL
(
x
.
find_first_of
(
"bc"
),
y
.
find_first_of
(
"bc"
));
CAF_CHECK_EQUAL
(
x
.
find_first_of
(
"ce"
),
y
.
find_first_of
(
"ce"
));
CAF_CHECK_EQUAL
(
x
.
find_first_of
(
"bc"
,
1
),
y
.
find_first_of
(
"bc"
,
1
));
CAF_CHECK_EQUAL
(
x
.
find_first_of
(
"bc"
,
1
,
0
),
y
.
find_first_of
(
"bc"
,
1
,
0
));
CAF_CHECK_EQUAL
(
x
.
find_first_of
(
"bc"
,
0
,
1
),
y
.
find_first_of
(
"bc"
,
0
,
1
));
CAF_CHECK_EQUAL
(
x
.
find_first_of
(
"bc"
,
2
,
10
),
y
.
find_first_of
(
"bc"
,
2
,
10
));
}
CAF_TEST
(
find_last_of
)
{
// Check whether string_view behaves exactly like std::string.
string_view
x
=
"abcdef"
;
std
::
string
y
=
"abcdef"
;
CAF_CHECK_EQUAL
(
x
.
find_last_of
(
'a'
),
y
.
find_last_of
(
'a'
));
CAF_CHECK_EQUAL
(
x
.
find_last_of
(
'b'
),
y
.
find_last_of
(
'b'
));
CAF_CHECK_EQUAL
(
x
.
find_last_of
(
'g'
),
y
.
find_last_of
(
'g'
));
CAF_CHECK_EQUAL
(
x
.
find_last_of
(
'a'
,
1
),
y
.
find_last_of
(
'a'
,
1
));
CAF_CHECK_EQUAL
(
x
.
find_last_of
(
"a"
),
y
.
find_last_of
(
"a"
));
CAF_CHECK_EQUAL
(
x
.
find_last_of
(
"bc"
),
y
.
find_last_of
(
"bc"
));
CAF_CHECK_EQUAL
(
x
.
find_last_of
(
"ce"
),
y
.
find_last_of
(
"ce"
));
CAF_CHECK_EQUAL
(
x
.
find_last_of
(
"bc"
,
1
),
y
.
find_last_of
(
"bc"
,
1
));
CAF_CHECK_EQUAL
(
x
.
find_last_of
(
"bc"
,
1
,
0
),
y
.
find_last_of
(
"bc"
,
1
,
0
));
CAF_CHECK_EQUAL
(
x
.
find_last_of
(
"bc"
,
0
,
1
),
y
.
find_last_of
(
"bc"
,
0
,
1
));
CAF_CHECK_EQUAL
(
x
.
find_last_of
(
"bc"
,
2
,
10
),
y
.
find_last_of
(
"bc"
,
2
,
10
));
}
CAF_TEST
(
find_first_not_of
)
{
// Check whether string_view behaves exactly like std::string.
string_view
x
=
"abcdef"
;
std
::
string
y
=
"abcdef"
;
CAF_CHECK_EQUAL
(
x
.
find_first_not_of
(
'a'
),
y
.
find_first_not_of
(
'a'
));
CAF_CHECK_EQUAL
(
x
.
find_first_not_of
(
'b'
),
y
.
find_first_not_of
(
'b'
));
CAF_CHECK_EQUAL
(
x
.
find_first_not_of
(
'g'
),
y
.
find_first_not_of
(
'g'
));
CAF_CHECK_EQUAL
(
x
.
find_first_not_of
(
'a'
,
1
),
y
.
find_first_not_of
(
'a'
,
1
));
CAF_CHECK_EQUAL
(
x
.
find_first_not_of
(
"a"
),
y
.
find_first_not_of
(
"a"
));
CAF_CHECK_EQUAL
(
x
.
find_first_not_of
(
"bc"
),
y
.
find_first_not_of
(
"bc"
));
CAF_CHECK_EQUAL
(
x
.
find_first_not_of
(
"ce"
),
y
.
find_first_not_of
(
"ce"
));
CAF_CHECK_EQUAL
(
x
.
find_first_not_of
(
"bc"
,
1
),
y
.
find_first_not_of
(
"bc"
,
1
));
CAF_CHECK_EQUAL
(
x
.
find_first_not_of
(
"bc"
,
1
,
0
),
y
.
find_first_not_of
(
"bc"
,
1
,
0
));
CAF_CHECK_EQUAL
(
x
.
find_first_not_of
(
"bc"
,
0
,
1
),
y
.
find_first_not_of
(
"bc"
,
0
,
1
));
CAF_CHECK_EQUAL
(
x
.
find_first_not_of
(
"bc"
,
2
,
10
),
y
.
find_first_not_of
(
"bc"
,
2
,
10
));
}
CAF_TEST
(
find_last_not_of
)
{
// Check whether string_view behaves exactly like std::string.
string_view
x
=
"abcdef"
;
std
::
string
y
=
"abcdef"
;
CAF_CHECK_EQUAL
(
x
.
find_last_not_of
(
'a'
),
y
.
find_last_not_of
(
'a'
));
CAF_CHECK_EQUAL
(
x
.
find_last_not_of
(
'b'
),
y
.
find_last_not_of
(
'b'
));
CAF_CHECK_EQUAL
(
x
.
find_last_not_of
(
'g'
),
y
.
find_last_not_of
(
'g'
));
CAF_CHECK_EQUAL
(
x
.
find_last_not_of
(
'a'
,
1
),
y
.
find_last_not_of
(
'a'
,
1
));
CAF_CHECK_EQUAL
(
x
.
find_last_not_of
(
"a"
),
y
.
find_last_not_of
(
"a"
));
CAF_CHECK_EQUAL
(
x
.
find_last_not_of
(
"bc"
),
y
.
find_last_not_of
(
"bc"
));
CAF_CHECK_EQUAL
(
x
.
find_last_not_of
(
"ce"
),
y
.
find_last_not_of
(
"ce"
));
CAF_CHECK_EQUAL
(
x
.
find_last_not_of
(
"bc"
,
1
),
y
.
find_last_not_of
(
"bc"
,
1
));
CAF_CHECK_EQUAL
(
x
.
find_last_not_of
(
"bc"
,
1
,
0
),
y
.
find_last_not_of
(
"bc"
,
1
,
0
));
CAF_CHECK_EQUAL
(
x
.
find_last_not_of
(
"bc"
,
0
,
1
),
y
.
find_last_not_of
(
"bc"
,
0
,
1
));
CAF_CHECK_EQUAL
(
x
.
find_last_not_of
(
"bc"
,
2
,
10
),
y
.
find_last_not_of
(
"bc"
,
2
,
10
));
}
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