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
e1c3146d
Commit
e1c3146d
authored
Jun 22, 2018
by
Dominik Charousset
Committed by
Dominik Charousset
Jun 24, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add C++17-compatible string_view class
parent
eb1cc7b1
Changes
4
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
824 additions
and
0 deletions
+824
-0
libcaf_core/CMakeLists.txt
libcaf_core/CMakeLists.txt
+1
-0
libcaf_core/caf/string_view.hpp
libcaf_core/caf/string_view.hpp
+288
-0
libcaf_core/src/string_view.cpp
libcaf_core/src/string_view.cpp
+308
-0
libcaf_core/test/string_view.cpp
libcaf_core/test/string_view.cpp
+227
-0
No files found.
libcaf_core/CMakeLists.txt
View file @
e1c3146d
...
@@ -103,6 +103,7 @@ set(LIBCAF_CORE_SRCS
...
@@ -103,6 +103,7 @@ set(LIBCAF_CORE_SRCS
src/stream_aborter.cpp
src/stream_aborter.cpp
src/stream_manager.cpp
src/stream_manager.cpp
src/stream_priority.cpp
src/stream_priority.cpp
src/string_view.cpp
src/stringification_inspector.cpp
src/stringification_inspector.cpp
src/sync_request_bouncer.cpp
src/sync_request_bouncer.cpp
src/term.cpp
src/term.cpp
...
...
libcaf_core/caf/string_view.hpp
0 → 100644
View file @
e1c3146d
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| 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 <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
libcaf_core/src/string_view.cpp
0 → 100644
View file @
e1c3146d
This diff is collapsed.
Click to expand it.
libcaf_core/test/string_view.cpp
0 → 100644
View file @
e1c3146d
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| 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