Skip to content
This repository was archived by the owner on Mar 22, 2023. It is now read-only.

Commit ca9562b

Browse files
authored
Merge pull request #938 from KFilipek/tests-access_api
string_view: implement access API and port libcxx tests
2 parents 3a9343d + 4e17da1 commit ca9562b

7 files changed

Lines changed: 416 additions & 23 deletions

File tree

include/libpmemobj++/string_view.hpp

Lines changed: 83 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include <algorithm>
1313
#include <cassert>
14+
#include <stdexcept>
1415
#include <string>
1516

1617
#if __cpp_lib_string_view
@@ -53,19 +54,24 @@ class basic_string_view {
5354
using pointer = value_type *;
5455
using const_pointer = const value_type *;
5556

56-
basic_string_view() noexcept;
57-
basic_string_view(const CharT *data, size_type size);
58-
basic_string_view(const std::basic_string<CharT, Traits> &s);
59-
basic_string_view(const CharT *data);
57+
constexpr basic_string_view() noexcept;
58+
constexpr basic_string_view(const CharT *data, size_type size);
59+
constexpr basic_string_view(const std::basic_string<CharT, Traits> &s);
60+
constexpr basic_string_view(const CharT *data);
6061

61-
basic_string_view(const basic_string_view &rhs) noexcept = default;
62+
constexpr basic_string_view(const basic_string_view &rhs) noexcept =
63+
default;
6264
basic_string_view &
6365
operator=(const basic_string_view &rhs) noexcept = default;
6466

65-
const CharT *data() const noexcept;
66-
size_type size() const noexcept;
67+
constexpr const CharT *data() const noexcept;
68+
constexpr size_type size() const noexcept;
69+
constexpr size_type length() const noexcept;
6770

68-
const CharT &operator[](size_type p) const noexcept;
71+
const CharT &at(size_type pos) const;
72+
constexpr const CharT &operator[](size_type pos) const noexcept;
73+
constexpr const_reference front() const noexcept;
74+
constexpr const_reference back() const noexcept;
6975

7076
int compare(const basic_string_view &other) const noexcept;
7177

@@ -83,7 +89,7 @@ using u32string_view = basic_string_view<char32_t>;
8389
* Default constructor with empty data.
8490
*/
8591
template <typename CharT, typename Traits>
86-
inline basic_string_view<CharT, Traits>::basic_string_view() noexcept
92+
constexpr inline basic_string_view<CharT, Traits>::basic_string_view() noexcept
8793
: data_(nullptr), size_(0)
8894
{
8995
}
@@ -96,8 +102,8 @@ inline basic_string_view<CharT, Traits>::basic_string_view() noexcept
96102
* @param[in] size length of the given data.
97103
*/
98104
template <typename CharT, typename Traits>
99-
inline basic_string_view<CharT, Traits>::basic_string_view(const CharT *data,
100-
size_type size)
105+
constexpr inline basic_string_view<CharT, Traits>::basic_string_view(
106+
const CharT *data, size_type size)
101107
: data_(data), size_(size)
102108
{
103109
}
@@ -108,7 +114,7 @@ inline basic_string_view<CharT, Traits>::basic_string_view(const CharT *data,
108114
* @param[in] s reference to the string to initialize with.
109115
*/
110116
template <typename CharT, typename Traits>
111-
inline basic_string_view<CharT, Traits>::basic_string_view(
117+
constexpr inline basic_string_view<CharT, Traits>::basic_string_view(
112118
const std::basic_string<CharT, Traits> &s)
113119
: data_(s.c_str()), size_(s.size())
114120
{
@@ -122,7 +128,8 @@ inline basic_string_view<CharT, Traits>::basic_string_view(
122128
* it has to end with the terminating null character.
123129
*/
124130
template <typename CharT, typename Traits>
125-
inline basic_string_view<CharT, Traits>::basic_string_view(const CharT *data)
131+
constexpr inline basic_string_view<CharT, Traits>::basic_string_view(
132+
const CharT *data)
126133
: data_(data), size_(Traits::length(data))
127134
{
128135
}
@@ -135,7 +142,7 @@ inline basic_string_view<CharT, Traits>::basic_string_view(const CharT *data)
135142
* character.
136143
*/
137144
template <typename CharT, typename Traits>
138-
inline const CharT *
145+
constexpr inline const CharT *
139146
basic_string_view<CharT, Traits>::data() const noexcept
140147
{
141148
return data_;
@@ -144,27 +151,80 @@ basic_string_view<CharT, Traits>::data() const noexcept
144151
/**
145152
* Returns count of characters stored in this pmem::obj::string_view data.
146153
*
147-
* @return pointer to C-like string (char *), it may not end with null
148-
* character.
154+
* @return the number of CharT elements in the view.
149155
*/
150156
template <typename CharT, typename Traits>
151-
inline typename basic_string_view<CharT, Traits>::size_type
157+
constexpr inline typename basic_string_view<CharT, Traits>::size_type
152158
basic_string_view<CharT, Traits>::size() const noexcept
153159
{
154160
return size_;
155161
}
156162

157163
/**
158-
* Returns reference to a character at position @param[in] p .
164+
* Returns count of characters stored in this pmem::obj::string_view data.
159165
*
160-
* @return reference to a char.
166+
* @return the number of CharT elements in the view.
161167
*/
162168
template <typename CharT, typename Traits>
163-
inline const CharT &basic_string_view<CharT, Traits>::operator[](size_t p) const
164-
noexcept
169+
constexpr inline typename basic_string_view<CharT, Traits>::size_type
170+
basic_string_view<CharT, Traits>::length() const noexcept
171+
{
172+
return size_;
173+
}
174+
175+
/**
176+
* Returns reference to a character at position @param[in] pos .
177+
*
178+
* @return reference to the char.
179+
*/
180+
template <typename CharT, typename Traits>
181+
constexpr inline const CharT &
182+
basic_string_view<CharT, Traits>::operator[](size_t pos) const noexcept
183+
{
184+
return data()[pos];
185+
}
186+
187+
/**
188+
* Returns reference to the character at position @param[in] pos and
189+
* performs bound checking.
190+
*
191+
* @return reference to the char.
192+
*
193+
* @throw std::out_of_range when out of bounds occurs.
194+
*/
195+
template <typename CharT, typename Traits>
196+
inline const CharT &
197+
basic_string_view<CharT, Traits>::at(size_t pos) const
198+
{
199+
if (pos >= size())
200+
throw std::out_of_range("Accessing a position out of bounds!");
201+
return data()[pos];
202+
}
203+
204+
/**
205+
* Returns reference to the last character in the view.
206+
* The behavior is undefined if empty() == true.
207+
*
208+
* @return reference to the last character.
209+
*/
210+
template <typename CharT, typename Traits>
211+
constexpr inline const CharT &
212+
basic_string_view<CharT, Traits>::back() const noexcept
213+
{
214+
return operator[](size() - 1);
215+
}
216+
217+
/**
218+
* Returns reference to the first character in the view.
219+
* The behavior is undefined if empty() == true.
220+
*
221+
* @return reference to the first character.
222+
*/
223+
template <typename CharT, typename Traits>
224+
constexpr inline const CharT &
225+
basic_string_view<CharT, Traits>::front() const noexcept
165226
{
166-
assert(p < size());
167-
return data()[p];
227+
return operator[](0);
168228
}
169229

170230
/**

tests/external/CMakeLists.txt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -740,6 +740,21 @@ if (TEST_STRING)
740740
# XXX: port libcxx test basic_string/string.cons/initializer_list_assignment.pass
741741
add_test_expect_failure(string_libcxx_string_view libcxx/basic_string/string.cons/string_view.fail.cpp)
742742

743+
build_test(string_libcxx_string_view_at libcxx/string.view/string.view.access/at.pass.cpp)
744+
add_test_generic(NAME string_libcxx_string_view_at TRACERS none pmemcheck memcheck)
745+
746+
build_test(string_libcxx_string_view_back libcxx/string.view/string.view.access/back.pass.cpp)
747+
add_test_generic(NAME string_libcxx_string_view_back TRACERS none pmemcheck memcheck)
748+
749+
build_test(string_libcxx_string_view_data libcxx/string.view/string.view.access/data.pass.cpp)
750+
add_test_generic(NAME string_libcxx_string_view_data TRACERS none pmemcheck memcheck)
751+
752+
build_test(string_libcxx_string_view_front libcxx/string.view/string.view.access/front.pass.cpp)
753+
add_test_generic(NAME string_libcxx_string_view_front TRACERS none pmemcheck memcheck)
754+
755+
build_test(string_libcxx_string_view_index libcxx/string.view/string.view.access/index.pass.cpp)
756+
add_test_generic(NAME string_libcxx_string_view_index TRACERS none pmemcheck memcheck)
757+
743758
if(MSVC_VERSION GREATER_EQUAL 1920)
744759
build_test(string_libcxx_string_view_opeq_string_view libcxx/string.view/string.view.comparison/opeq.string_view.string_view.pass.cpp)
745760
add_test_generic(NAME string_libcxx_string_view_opeq_string_view TRACERS none pmemcheck memcheck)
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// Copyright 2020, Intel Corporation
10+
//
11+
// Modified to test pmem::obj containers
12+
//
13+
14+
// NOTE: Older versions of clang have a bug where they fail to evaluate
15+
// string_view::at as a constant expression.
16+
// XFAIL: clang-3.4, clang-3.3
17+
18+
// <string_view>
19+
20+
// constexpr const _CharT& at(size_type _pos) const;
21+
22+
#include "unittest.hpp"
23+
24+
#include <libpmemobj++/string_view.hpp>
25+
26+
template <typename CharT>
27+
void
28+
test(const CharT *s, size_t len)
29+
{
30+
pmem::obj::basic_string_view<CharT> sv(s, len);
31+
UT_ASSERT(sv.length() == len);
32+
for (size_t i = 0; i < len; ++i) {
33+
UT_ASSERT(sv.at(i) == s[i]);
34+
UT_ASSERT(&sv.at(i) == s + i);
35+
}
36+
37+
try {
38+
(void)sv.at(len);
39+
} catch (const std::out_of_range &) {
40+
return;
41+
}
42+
UT_ASSERT(false);
43+
}
44+
45+
static void
46+
run()
47+
{
48+
test("ABCDE", 5);
49+
test("a", 1);
50+
51+
test(L"ABCDE", 5);
52+
test(L"a", 1);
53+
54+
test(u"ABCDE", 5);
55+
test(u"a", 1);
56+
57+
test(U"ABCDE", 5);
58+
test(U"a", 1);
59+
}
60+
61+
int
62+
main(int argc, char *argv[])
63+
{
64+
return run_test([&] { run(); });
65+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// Copyright 2020, Intel Corporation
10+
//
11+
// Modified to test pmem::obj containers
12+
//
13+
14+
// <string_view>
15+
16+
// constexpr const _CharT& front();
17+
18+
#include "unittest.hpp"
19+
20+
#include <libpmemobj++/string_view.hpp>
21+
22+
template <typename CharT>
23+
bool
24+
test(const CharT *s, size_t len)
25+
{
26+
typedef pmem::obj::basic_string_view<CharT> SV;
27+
SV sv(s, len);
28+
29+
static_assert(std::is_same<decltype(sv.back()),
30+
typename SV::const_reference>::value,
31+
"must be const_reference");
32+
static_assert(noexcept(sv.back()), "Operation must be noexcept");
33+
UT_ASSERT(sv.length() == len);
34+
UT_ASSERT(sv.back() == s[len - 1]);
35+
return &sv.back() == s + len - 1;
36+
}
37+
38+
static void
39+
run()
40+
{
41+
UT_ASSERT(test("ABCDE", 5));
42+
UT_ASSERT(test("a", 1));
43+
44+
UT_ASSERT(test(L"ABCDE", 5));
45+
UT_ASSERT(test(L"a", 1));
46+
47+
UT_ASSERT(test(u"ABCDE", 5));
48+
UT_ASSERT(test(u"a", 1));
49+
50+
UT_ASSERT(test(U"ABCDE", 5));
51+
UT_ASSERT(test(U"a", 1));
52+
53+
{
54+
constexpr pmem::obj::basic_string_view<char> sv("ABC", 2);
55+
static_assert(sv.length() == 2, "");
56+
static_assert(sv.back() == 'B', "");
57+
}
58+
}
59+
60+
int
61+
main(int argc, char *argv[])
62+
{
63+
return run_test([&] { run(); });
64+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// Copyright 2020, Intel Corporation
10+
//
11+
// Modified to test pmem::obj containers
12+
//
13+
14+
// <string_view>
15+
16+
// constexpr const _CharT* data() const noexcept;
17+
18+
#include "unittest.hpp"
19+
20+
#include <libpmemobj++/string_view.hpp>
21+
22+
template <typename CharT>
23+
void
24+
test(const CharT *s, size_t len)
25+
{
26+
pmem::obj::basic_string_view<CharT> sv(s, len);
27+
UT_ASSERT(sv.length() == len);
28+
UT_ASSERT(sv.data() == s);
29+
}
30+
31+
static void
32+
run()
33+
{
34+
test("ABCDE", 5);
35+
test("a", 1);
36+
37+
test(L"ABCDE", 5);
38+
test(L"a", 1);
39+
40+
test(u"ABCDE", 5);
41+
test(u"a", 1);
42+
43+
test(U"ABCDE", 5);
44+
test(U"a", 1);
45+
46+
{
47+
constexpr const char *s = "ABC";
48+
constexpr pmem::obj::basic_string_view<char> sv(s, 2);
49+
static_assert(sv.length() == 2, "");
50+
static_assert(sv.data() == s, "");
51+
}
52+
}
53+
54+
int
55+
main(int argc, char *argv[])
56+
{
57+
return run_test([&] { run(); });
58+
}

0 commit comments

Comments
 (0)