Skip to content

Commit 1692b18

Browse files
committed
feat universal: delete unsafe methods of zstring_view and StringLiteral
Tests: протестировано CI commit_hash:eef2b763e273af79199c3ad02f663a1b0cedb2ba
1 parent 3068c02 commit 1692b18

File tree

4 files changed

+57
-0
lines changed

4 files changed

+57
-0
lines changed

universal/include/userver/utils/string_literal.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ class StringLiteral : public zstring_view {
3939
// data()[size()] == '\0' is guaranteed by std::string_view that calls std::strlen(literal)
4040
}
4141

42+
void swap(zstring_view&) = delete; // loses guarantee on lifetime because zstring_view may refer to non-literal
43+
void swap(StringLiteral& other) noexcept { zstring_view::swap(other); }
44+
4245
/// Constructs a StringLiteral from a pointer and size.
4346
/// @warning `str[len]` should be '\0' and `str` should point to compile time literal.
4447
static constexpr StringLiteral UnsafeMake(const char* str, std::size_t len) noexcept {

universal/include/userver/utils/zstring_view.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ class zstring_view : public std::string_view { // NOLINT(readability-identifier
3434
zstring_view& operator=(std::string_view) = delete;
3535
zstring_view& operator=(const zstring_view&) = default;
3636

37+
void remove_suffix(std::size_t) = delete; // zstring_view becomes not null-terminated after that function call
38+
void swap(std::string_view&) = delete; // zstring_view may become not null-terminated after that function call
39+
void swap(zstring_view& other) noexcept { std::string_view::swap(other); }
40+
3741
constexpr const char* c_str() const noexcept { return std::string_view::data(); }
3842

3943
/// Constructs a zstring_view from a pointer and size.

universal/src/utils/string_literal_test.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
#include <userver/utils/string_literal.hpp>
22

3+
#ifdef __cpp_concepts
4+
#include <concepts>
5+
#endif
6+
37
#include <type_traits>
48

59
#include <gtest/gtest.h>
@@ -18,6 +22,16 @@ static_assert(!std::is_assignable_v<utils::StringLiteral, utils::zstring_view>);
1822
static_assert(std::is_assignable_v<std::string_view, utils::StringLiteral>);
1923
static_assert(std::is_assignable_v<utils::zstring_view, utils::StringLiteral>);
2024

25+
#ifdef __cpp_concepts
26+
template <typename T>
27+
concept SuffixRemovable = requires(T t) { t.remove_suffix(10); };
28+
29+
static_assert(std::swappable<utils::StringLiteral>);
30+
static_assert(!std::swappable_with<utils::StringLiteral, utils::zstring_view>);
31+
static_assert(!std::swappable_with<utils::StringLiteral, std::string_view>);
32+
static_assert(!SuffixRemovable<utils::StringLiteral>);
33+
#endif
34+
2135
static constexpr utils::StringLiteral kLongString = "some long long long long long long long long long string";
2236

2337
TEST(StringLiteral, UnsafeMake) {
@@ -44,4 +58,16 @@ TEST(StringLiteral, UnsafeMake) {
4458
static_assert(kLongString == utils::StringLiteral::UnsafeMake(kLongString.c_str(), kLongString.size()));
4559
}
4660

61+
TEST(StringLiteral, Swap) {
62+
constexpr utils::StringLiteral kShortString = "short";
63+
constexpr utils::StringLiteral kLongString = "some long long long long long long long long long string";
64+
65+
auto v1 = kShortString;
66+
auto v2 = kLongString;
67+
v1.swap(v2);
68+
69+
EXPECT_EQ(v1, kLongString);
70+
EXPECT_EQ(v2, kShortString);
71+
}
72+
4773
USERVER_NAMESPACE_END

universal/src/utils/zstring_view_test.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
#include <userver/utils/zstring_view.hpp>
22

3+
#ifdef __cpp_concepts
4+
#include <concepts>
5+
#endif
6+
37
#include <type_traits>
48

59
#include <gtest/gtest.h>
@@ -15,6 +19,15 @@ static_assert(!std::is_assignable_v<utils::zstring_view, std::string_view>);
1519

1620
static_assert(std::is_assignable_v<std::string_view, utils::zstring_view>);
1721

22+
#ifdef __cpp_concepts
23+
template <typename T>
24+
concept SuffixRemovable = requires(T t) { t.remove_suffix(10); };
25+
26+
static_assert(std::swappable<utils::zstring_view>);
27+
static_assert(!std::swappable_with<utils::zstring_view, std::string_view>);
28+
static_assert(!SuffixRemovable<utils::zstring_view>);
29+
#endif
30+
1831
TEST(ZstringView, UnsafeMake) {
1932
static constexpr utils::zstring_view kShortString = "short";
2033
static constexpr utils::zstring_view kLongString = "some long long long long long long long long long string";
@@ -40,4 +53,15 @@ TEST(ZstringView, UnsafeMake) {
4053
static_assert(kLongString == utils::zstring_view::UnsafeMake(kLongString.c_str(), kLongString.size()));
4154
}
4255

56+
TEST(ZstringView, Swap) {
57+
constexpr utils::zstring_view kShortString = "short";
58+
constexpr utils::zstring_view kLongString = "some long long long long long long long long long string";
59+
60+
auto v1 = kShortString;
61+
auto v2 = kLongString;
62+
v1.swap(v2);
63+
64+
EXPECT_EQ(v1, kLongString);
65+
EXPECT_EQ(v2, kShortString);
66+
}
4367
USERVER_NAMESPACE_END

0 commit comments

Comments
 (0)