[libc-commits] [libc] a7eaec7 - [libc] Change cpp::string_view into cpp::basic_string_view<CharT> (#203355)
via libc-commits
libc-commits at lists.llvm.org
Fri Jun 26 04:14:13 PDT 2026
Author: Alex Strelnikov
Date: 2026-06-26T11:14:08Z
New Revision: a7eaec767388a4ba00897156762f0387afcf15a5
URL: https://github.com/llvm/llvm-project/commit/a7eaec767388a4ba00897156762f0387afcf15a5
DIFF: https://github.com/llvm/llvm-project/commit/a7eaec767388a4ba00897156762f0387afcf15a5.diff
LOG: [libc] Change cpp::string_view into cpp::basic_string_view<CharT> (#203355)
This will allow some of the types in src/stdio/printf_core/ to be
templated on character type for the implementation of `swprintf`.
Added:
Modified:
libc/src/__support/CPP/string_view.h
libc/src/__support/CPP/type_traits/is_integral.h
libc/test/UnitTest/LibcTest.cpp
libc/test/UnitTest/LibcTest.h
libc/test/src/__support/CPP/CMakeLists.txt
libc/test/src/__support/CPP/stringview_test.cpp
Removed:
################################################################################
diff --git a/libc/src/__support/CPP/string_view.h b/libc/src/__support/CPP/string_view.h
index 7b98b7e5fb6c8..68056f753c314 100644
--- a/libc/src/__support/CPP/string_view.h
+++ b/libc/src/__support/CPP/string_view.h
@@ -18,48 +18,52 @@
namespace LIBC_NAMESPACE_DECL {
namespace cpp {
-// This is very simple alternate of the std::string_view class. There is no
-// bounds check performed in any of the methods. The callers are expected to
-// do the checks before invoking the methods.
+template <typename CharT> class basic_string_view;
+
+using string_view = basic_string_view<char>;
+using wstring_view = basic_string_view<wchar_t>;
+
+// This is a very simple alternate of the std::basic_string_view class template.
+// There is no bounds check performed in any of the methods. The callers are
+// expected to do the checks before invoking the methods.
//
// This class will be extended as needed in future.
-class string_view {
+template <typename CharT> class basic_string_view {
private:
- const char *Data;
+ const CharT *Data;
size_t Len;
LIBC_INLINE static constexpr size_t min(size_t A, size_t B) {
return A <= B ? A : B;
}
- LIBC_INLINE static constexpr int
- compareMemory(const char *Lhs, const char *Rhs, size_t Length) {
+ LIBC_INLINE static constexpr int compareN(const CharT *Lhs, const CharT *Rhs,
+ size_t Length) {
for (size_t i = 0; i < Length; ++i)
- if (int Diff = (int)Lhs[i] - (int)Rhs[i])
- return Diff;
+ if (Lhs[i] != Rhs[i])
+ return Lhs[i] < Rhs[i] ? -1 : 1;
return 0;
}
- LIBC_INLINE static constexpr size_t length(const char *Str) {
- for (const char *End = Str;; ++End)
- if (*End == '\0')
+ LIBC_INLINE static constexpr size_t length(const CharT *Str) {
+ for (const CharT *End = Str;; ++End)
+ if (*End == CharT{0})
return static_cast<size_t>(End - Str);
}
- LIBC_INLINE constexpr bool equals(string_view Other) const {
- return (Len == Other.Len &&
- compareMemory(Data, Other.Data, Other.Len) == 0);
+ LIBC_INLINE constexpr bool equals(basic_string_view Other) const {
+ return (Len == Other.Len && compareN(Data, Other.Data, Other.Len) == 0);
}
public:
- using value_type = char;
+ using value_type = CharT;
using size_type = size_t;
using
diff erence_type = ptr
diff _t;
- using pointer = char *;
- using const_pointer = const char *;
- using reference = char &;
- using const_reference = const char &;
- using const_iterator = char *;
+ using pointer = CharT *;
+ using const_pointer = const CharT *;
+ using reference = CharT &;
+ using const_reference = const CharT &;
+ using const_iterator = CharT *;
using iterator = const_iterator;
// special value equal to the maximum value representable by the type
@@ -67,68 +71,68 @@ class string_view {
LIBC_INLINE_VAR static constexpr size_t npos =
cpp::numeric_limits<size_t>::max();
- LIBC_INLINE constexpr string_view() : Data(nullptr), Len(0) {}
+ LIBC_INLINE constexpr basic_string_view() : Data(nullptr), Len(0) {}
// Assumes Str is a null-terminated string. The length of the string does
// not include the terminating null character.
// Preconditions: [Str, Str + ​length(Str)) is a valid range.
- LIBC_INLINE constexpr string_view(const char *Str)
+ LIBC_INLINE constexpr basic_string_view(const CharT *Str)
: Data(Str), Len(length(Str)) {}
// Preconditions: [Str, Str + N) is a valid range.
- LIBC_INLINE constexpr string_view(const char *Str, size_t N)
+ LIBC_INLINE constexpr basic_string_view(const CharT *Str, size_t N)
: Data(Str), Len(N) {}
- LIBC_INLINE constexpr const char *data() const { return Data; }
+ LIBC_INLINE constexpr const CharT *data() const { return Data; }
- // Returns the size of the string_view.
+ // Returns the size of the basic_string_view.
LIBC_INLINE constexpr size_t size() const { return Len; }
- // Returns whether the string_view is empty.
+ // Returns whether the basic_string_view is empty.
LIBC_INLINE constexpr bool empty() const { return Len == 0; }
// Returns an iterator to the first character of the view.
- LIBC_INLINE constexpr const char *begin() const { return Data; }
+ LIBC_INLINE constexpr const CharT *begin() const { return Data; }
// Returns an iterator to the character following the last character of the
// view.
- LIBC_INLINE constexpr const char *end() const { return Data + Len; }
+ LIBC_INLINE constexpr const CharT *end() const { return Data + Len; }
// Returns a const reference to the character at specified location pos.
// No bounds checking is performed: the behavior is undefined if pos >=
// size().
- LIBC_INLINE constexpr const char &operator[](size_t Index) const {
+ LIBC_INLINE constexpr const CharT &operator[](size_t Index) const {
return Data[Index];
}
/// compare - Compare two strings; the result is -1, 0, or 1 if this string
/// is lexicographically less than, equal to, or greater than the \p Other.
- LIBC_INLINE constexpr int compare(string_view Other) const {
+ LIBC_INLINE constexpr int compare(basic_string_view Other) const {
// Check the prefix for a mismatch.
- if (int Res = compareMemory(Data, Other.Data, min(Len, Other.Len)))
- return Res < 0 ? -1 : 1;
+ if (int Res = compareN(Data, Other.Data, min(Len, Other.Len)))
+ return Res;
// Otherwise the prefixes match, so we only need to check the lengths.
if (Len == Other.Len)
return 0;
return Len < Other.Len ? -1 : 1;
}
- LIBC_INLINE constexpr bool operator==(string_view Other) const {
+ LIBC_INLINE constexpr bool operator==(basic_string_view Other) const {
return equals(Other);
}
- LIBC_INLINE constexpr bool operator!=(string_view Other) const {
+ LIBC_INLINE constexpr bool operator!=(basic_string_view Other) const {
return !(*this == Other);
}
- LIBC_INLINE constexpr bool operator<(string_view Other) const {
+ LIBC_INLINE constexpr bool operator<(basic_string_view Other) const {
return compare(Other) == -1;
}
- LIBC_INLINE constexpr bool operator<=(string_view Other) const {
+ LIBC_INLINE constexpr bool operator<=(basic_string_view Other) const {
return compare(Other) != 1;
}
- LIBC_INLINE constexpr bool operator>(string_view Other) const {
+ LIBC_INLINE constexpr bool operator>(basic_string_view Other) const {
return compare(Other) == 1;
}
- LIBC_INLINE constexpr bool operator>=(string_view Other) const {
+ LIBC_INLINE constexpr bool operator>=(basic_string_view Other) const {
return compare(Other) != -1;
}
@@ -144,25 +148,24 @@ class string_view {
LIBC_INLINE constexpr void remove_suffix(size_t N) { Len -= N; }
// Check if this string starts with the given Prefix.
- LIBC_INLINE constexpr bool starts_with(string_view Prefix) const {
- return Len >= Prefix.Len &&
- compareMemory(Data, Prefix.Data, Prefix.Len) == 0;
+ LIBC_INLINE constexpr bool starts_with(basic_string_view Prefix) const {
+ return Len >= Prefix.Len && compareN(Data, Prefix.Data, Prefix.Len) == 0;
}
// Check if this string starts with the given Prefix.
- LIBC_INLINE constexpr bool starts_with(const char Prefix) const {
+ LIBC_INLINE constexpr bool starts_with(const CharT Prefix) const {
return !empty() && front() == Prefix;
}
// Check if this string ends with the given Prefix.
- LIBC_INLINE constexpr bool ends_with(const char Suffix) const {
+ LIBC_INLINE constexpr bool ends_with(const CharT Suffix) const {
return !empty() && back() == Suffix;
}
// Check if this string ends with the given Suffix.
- LIBC_INLINE constexpr bool ends_with(string_view Suffix) const {
+ LIBC_INLINE constexpr bool ends_with(basic_string_view Suffix) const {
return Len >= Suffix.Len &&
- compareMemory(end() - Suffix.Len, Suffix.Data, Suffix.Len) == 0;
+ compareN(end() - Suffix.Len, Suffix.Data, Suffix.Len) == 0;
}
// Return a reference to the substring from [Start, Start + N).
@@ -174,20 +177,20 @@ class string_view {
// N The number of characters to included in the substring. If N exceeds the
// number of characters remaining in the string, the string suffix (starting
// with Start) will be returned.
- LIBC_INLINE constexpr string_view substr(size_t Start,
- size_t N = npos) const {
+ LIBC_INLINE constexpr basic_string_view substr(size_t Start,
+ size_t N = npos) const {
Start = min(Start, Len);
- return string_view(Data + Start, min(N, Len - Start));
+ return basic_string_view(Data + Start, min(N, Len - Start));
}
// front - Get the first character in the string.
- LIBC_INLINE constexpr char front() const { return Data[0]; }
+ LIBC_INLINE constexpr CharT front() const { return Data[0]; }
// back - Get the last character in the string.
- LIBC_INLINE constexpr char back() const { return Data[Len - 1]; }
+ LIBC_INLINE constexpr CharT back() const { return Data[Len - 1]; }
// Finds the first occurence of c in this view, starting at position From.
- LIBC_INLINE constexpr size_t find_first_of(const char c,
+ LIBC_INLINE constexpr size_t find_first_of(const CharT c,
size_t From = 0) const {
for (size_t Pos = From; Pos < size(); ++Pos)
if ((*this)[Pos] == c)
@@ -196,7 +199,7 @@ class string_view {
}
// Finds the last occurence of c in this view, ending at position End.
- LIBC_INLINE constexpr size_t find_last_of(const char c,
+ LIBC_INLINE constexpr size_t find_last_of(const CharT c,
size_t End = npos) const {
End = End >= size() ? size() : End + 1;
for (; End > 0; --End)
@@ -216,7 +219,7 @@ class string_view {
// Finds the first character not equal to c in this view, starting at
// position From.
- LIBC_INLINE constexpr size_t find_first_not_of(const char c,
+ LIBC_INLINE constexpr size_t find_first_not_of(const CharT c,
size_t From = 0) const {
for (size_t Pos = From; Pos < size(); ++Pos)
if ((*this)[Pos] != c)
@@ -225,7 +228,7 @@ class string_view {
}
// Check if this view contains the given character.
- LIBC_INLINE constexpr bool contains(char c) const {
+ LIBC_INLINE constexpr bool contains(CharT c) const {
return find_first_of(c) != npos;
}
};
diff --git a/libc/src/__support/CPP/type_traits/is_integral.h b/libc/src/__support/CPP/type_traits/is_integral.h
index 09047cb00bf75..c02bfcd50fea6 100644
--- a/libc/src/__support/CPP/type_traits/is_integral.h
+++ b/libc/src/__support/CPP/type_traits/is_integral.h
@@ -34,7 +34,7 @@ template <typename T> struct is_integral {
#ifdef __cpp_char8_t
char8_t,
#endif
- char16_t, char32_t, char, signed char,
+ char16_t, char32_t, wchar_t, char, signed char,
unsigned char, short, unsigned short, int,
unsigned int, long, unsigned long, long long,
unsigned long long, bool>();
diff --git a/libc/test/UnitTest/LibcTest.cpp b/libc/test/UnitTest/LibcTest.cpp
index fec45982f3e63..b03ceb6c7c77d 100644
--- a/libc/test/UnitTest/LibcTest.cpp
+++ b/libc/test/UnitTest/LibcTest.cpp
@@ -70,6 +70,22 @@ cpp::enable_if_t<cpp::is_fixed_point_v<T>, cpp::string> describeValue(T Value) {
cpp::string_view describeValue(const cpp::string &Value) { return Value; }
cpp::string_view describeValue(cpp::string_view Value) { return Value; }
+cpp::string describeValue(cpp::wstring_view Value) {
+ // TODO: Print `Value` as UTF-8 once `StringConverter` supports `wchar_t`.
+ if (Value.empty())
+ return "{}";
+
+ cpp::string S;
+ S += '{';
+ for (const wchar_t *Iter = Value.begin(); Iter + 1 != Value.end(); ++Iter) {
+ S += cpp::to_string(*Iter);
+ S += ',';
+ }
+ S += cpp::to_string(Value.back());
+ S += '}';
+ return S;
+}
+
template <typename ValType>
bool test(RunContext *Ctx, TestCond Cond, ValType LHS, ValType RHS,
const char *LHSStr, const char *RHSStr, Location Loc) {
@@ -217,6 +233,8 @@ namespace internal {
TYPE RHS, const char *LHSStr, const char *RHSStr, \
Location Loc)
+TEST_SPECIALIZATION(wchar_t);
+
TEST_SPECIALIZATION(char);
TEST_SPECIALIZATION(short);
TEST_SPECIALIZATION(int);
@@ -249,6 +267,7 @@ TEST_SPECIALIZATION(LIBC_NAMESPACE::UInt<256>);
TEST_SPECIALIZATION(LIBC_NAMESPACE::UInt<320>);
TEST_SPECIALIZATION(LIBC_NAMESPACE::cpp::string_view);
+TEST_SPECIALIZATION(LIBC_NAMESPACE::cpp::wstring_view);
TEST_SPECIALIZATION(LIBC_NAMESPACE::cpp::string);
#ifdef LIBC_COMPILER_HAS_FIXED_POINT
diff --git a/libc/test/UnitTest/LibcTest.h b/libc/test/UnitTest/LibcTest.h
index 133c198d42f15..65884b56f1dde 100644
--- a/libc/test/UnitTest/LibcTest.h
+++ b/libc/test/UnitTest/LibcTest.h
@@ -180,6 +180,15 @@ class Test {
return internal::test(Ctx, Cond, LHS, RHS, LHSStr, RHSStr, Loc);
}
+ template <
+ typename ValType,
+ cpp::enable_if_t<
+ cpp::is_same_v<ValType, LIBC_NAMESPACE::cpp::wstring_view>, int> = 0>
+ bool test(TestCond Cond, ValType LHS, ValType RHS, const char *LHSStr,
+ const char *RHSStr, internal::Location Loc) {
+ return internal::test(Ctx, Cond, LHS, RHS, LHSStr, RHSStr, Loc);
+ }
+
template <typename ValType,
cpp::enable_if_t<
cpp::is_same_v<ValType, LIBC_NAMESPACE::cpp::string>, int> = 0>
diff --git a/libc/test/src/__support/CPP/CMakeLists.txt b/libc/test/src/__support/CPP/CMakeLists.txt
index 1d47455dcd31f..9c09684be192d 100644
--- a/libc/test/src/__support/CPP/CMakeLists.txt
+++ b/libc/test/src/__support/CPP/CMakeLists.txt
@@ -61,6 +61,8 @@ add_libc_test(
stringview_test.cpp
DEPENDS
libc.src.__support.CPP.string_view
+ libc.src.__support.CPP.type_traits
+ libc.src.string.memory_utils.inline_memcpy
)
add_libc_test(
diff --git a/libc/test/src/__support/CPP/stringview_test.cpp b/libc/test/src/__support/CPP/stringview_test.cpp
index c9348243745a7..d8c2e03a4e9b2 100644
--- a/libc/test/src/__support/CPP/stringview_test.cpp
+++ b/libc/test/src/__support/CPP/stringview_test.cpp
@@ -7,279 +7,332 @@
//===----------------------------------------------------------------------===//
#include "src/__support/CPP/string_view.h"
+#include "src/__support/CPP/type_traits.h"
+#include "src/string/memory_utils/inline_memcpy.h"
#include "test/UnitTest/Test.h"
-using LIBC_NAMESPACE::cpp::string_view;
+using TestCharTypes = LIBC_NAMESPACE::testing::TypeList<char, wchar_t>;
-TEST(LlvmLibcStringViewTest, InitializeCheck) {
- string_view v;
- ASSERT_EQ(v.size(), size_t(0));
- ASSERT_TRUE(v.data() == nullptr);
+template <typename CharT>
+const CharT *chooseLiteral(const char *CharStr, const wchar_t *WCharStr) {
+ if constexpr (LIBC_NAMESPACE::cpp::is_same_v<CharT, char>)
+ return CharStr;
+ else {
+ static_assert(LIBC_NAMESPACE::cpp::is_same_v<CharT, wchar_t>);
+ return WCharStr;
+ }
+}
+
+template <typename CharT>
+CharT chooseLiteral(char CharValue, wchar_t WCharValue) {
+ if constexpr (LIBC_NAMESPACE::cpp::is_same_v<CharT, char>)
+ return CharValue;
+ else {
+ static_assert(LIBC_NAMESPACE::cpp::is_same_v<CharT, wchar_t>);
+ return WCharValue;
+ }
+}
+
+#define ENCODED(CharT, S) chooseLiteral<CharT>(S, L##S)
- v = string_view("");
- ASSERT_EQ(v.size(), size_t(0));
- ASSERT_TRUE(v.data() != nullptr);
+TYPED_TEST(LlvmLibcStringViewTest, InitializeCheck, TestCharTypes) {
+ using CharT = ParamType;
+ using StringView = LIBC_NAMESPACE::cpp::basic_string_view<CharT>;
- v = string_view("abc", 0);
- ASSERT_EQ(v.size(), size_t(0));
- ASSERT_TRUE(v.data() != nullptr);
+ StringView S;
+ ASSERT_EQ(S.size(), size_t(0));
+ ASSERT_TRUE(S.data() == nullptr);
- v = string_view("123456789");
- ASSERT_EQ(v.size(), size_t(9));
+ S = StringView(ENCODED(CharT, ""));
+ ASSERT_EQ(S.size(), size_t(0));
+ ASSERT_TRUE(S.data() != nullptr);
+
+ S = StringView(ENCODED(CharT, "abc"), 0);
+ ASSERT_EQ(S.size(), size_t(0));
+ ASSERT_TRUE(S.data() != nullptr);
+
+ S = StringView(ENCODED(CharT, "123456789"));
+ ASSERT_EQ(S.size(), size_t(9));
+
+ S = StringView(ENCODED(CharT, "123456789"), 5);
+ ASSERT_EQ(S.size(), size_t(5));
}
-TEST(LlvmLibcStringViewTest, Equals) {
- string_view v("abc");
- ASSERT_EQ(v, string_view("abc"));
- ASSERT_NE(v, string_view());
- ASSERT_NE(v, string_view(""));
- ASSERT_NE(v, string_view("123"));
- ASSERT_NE(v, string_view("abd"));
- ASSERT_NE(v, string_view("aaa"));
- ASSERT_NE(v, string_view("abcde"));
+TYPED_TEST(LlvmLibcStringViewTest, Equals, TestCharTypes) {
+ using CharT = ParamType;
+ using StringView = LIBC_NAMESPACE::cpp::basic_string_view<CharT>;
+
+ StringView S(ENCODED(CharT, "abc"));
+ ASSERT_EQ(S, StringView(ENCODED(CharT, "abc")));
+ ASSERT_NE(S, StringView());
+ ASSERT_NE(S, StringView(ENCODED(CharT, "")));
+ ASSERT_NE(S, StringView(ENCODED(CharT, "123")));
+ ASSERT_NE(S, StringView(ENCODED(CharT, "abd")));
+ ASSERT_NE(S, StringView(ENCODED(CharT, "aaa")));
+ ASSERT_NE(S, StringView(ENCODED(CharT, "abcde")));
}
-TEST(LlvmLibcStringViewTest, startsWith) {
- string_view v("abc");
- ASSERT_TRUE(v.starts_with('a'));
- ASSERT_TRUE(v.starts_with(string_view("a")));
- ASSERT_TRUE(v.starts_with(string_view("ab")));
- ASSERT_TRUE(v.starts_with(string_view("abc")));
- ASSERT_TRUE(v.starts_with(string_view()));
- ASSERT_TRUE(v.starts_with(string_view("")));
- ASSERT_FALSE(v.starts_with('1'));
- ASSERT_FALSE(v.starts_with(string_view("123")));
- ASSERT_FALSE(v.starts_with(string_view("abd")));
- ASSERT_FALSE(v.starts_with(string_view("aaa")));
- ASSERT_FALSE(v.starts_with(string_view("abcde")));
+TYPED_TEST(LlvmLibcStringViewTest, startsWith, TestCharTypes) {
+ using CharT = ParamType;
+ using StringView = LIBC_NAMESPACE::cpp::basic_string_view<CharT>;
+
+ StringView S(ENCODED(CharT, "abc"));
+ ASSERT_TRUE(S.starts_with(ENCODED(CharT, 'a')));
+ ASSERT_TRUE(S.starts_with(StringView(ENCODED(CharT, "a"))));
+ ASSERT_TRUE(S.starts_with(StringView(ENCODED(CharT, "ab"))));
+ ASSERT_TRUE(S.starts_with(StringView(ENCODED(CharT, "abc"))));
+ ASSERT_TRUE(S.starts_with(StringView()));
+ ASSERT_TRUE(S.starts_with(StringView(ENCODED(CharT, ""))));
+ ASSERT_FALSE(S.starts_with(ENCODED(CharT, '1')));
+ ASSERT_FALSE(S.starts_with(StringView(ENCODED(CharT, "123"))));
+ ASSERT_FALSE(S.starts_with(StringView(ENCODED(CharT, "abd"))));
+ ASSERT_FALSE(S.starts_with(StringView(ENCODED(CharT, "aaa"))));
+ ASSERT_FALSE(S.starts_with(StringView(ENCODED(CharT, "abcde"))));
}
-TEST(LlvmLibcStringViewTest, endsWith) {
- string_view v("abc");
- ASSERT_TRUE(v.ends_with('c'));
- ASSERT_TRUE(v.ends_with(string_view("c")));
- ASSERT_TRUE(v.ends_with(string_view("bc")));
- ASSERT_TRUE(v.ends_with(string_view("abc")));
- ASSERT_TRUE(v.ends_with(string_view()));
- ASSERT_TRUE(v.ends_with(string_view("")));
- ASSERT_FALSE(v.ends_with('1'));
- ASSERT_FALSE(v.ends_with(string_view("123")));
- ASSERT_FALSE(v.ends_with(string_view("abd")));
- ASSERT_FALSE(v.ends_with(string_view("aaa")));
- ASSERT_FALSE(v.ends_with(string_view("abcde")));
+TYPED_TEST(LlvmLibcStringViewTest, endsWith, TestCharTypes) {
+ using CharT = ParamType;
+ using StringView = LIBC_NAMESPACE::cpp::basic_string_view<CharT>;
+
+ StringView S(ENCODED(CharT, "abc"));
+ ASSERT_TRUE(S.ends_with(ENCODED(CharT, 'c')));
+ ASSERT_TRUE(S.ends_with(StringView(ENCODED(CharT, "c"))));
+ ASSERT_TRUE(S.ends_with(StringView(ENCODED(CharT, "bc"))));
+ ASSERT_TRUE(S.ends_with(StringView(ENCODED(CharT, "abc"))));
+ ASSERT_TRUE(S.ends_with(StringView()));
+ ASSERT_TRUE(S.ends_with(StringView(ENCODED(CharT, ""))));
+ ASSERT_FALSE(S.ends_with(ENCODED(CharT, '1')));
+ ASSERT_FALSE(S.ends_with(StringView(ENCODED(CharT, "123"))));
+ ASSERT_FALSE(S.ends_with(StringView(ENCODED(CharT, "abd"))));
+ ASSERT_FALSE(S.ends_with(StringView(ENCODED(CharT, "aaa"))));
+ ASSERT_FALSE(S.ends_with(StringView(ENCODED(CharT, "abcde"))));
}
-TEST(LlvmLibcStringViewTest, RemovePrefix) {
- string_view a("123456789");
- a.remove_prefix(0);
- ASSERT_EQ(a.size(), size_t(9));
- ASSERT_TRUE(a == "123456789");
+TYPED_TEST(LlvmLibcStringViewTest, RemovePrefix, TestCharTypes) {
+ using CharT = ParamType;
+ using StringView = LIBC_NAMESPACE::cpp::basic_string_view<CharT>;
+
+ StringView A(ENCODED(CharT, "123456789"));
+ A.remove_prefix(0);
+ ASSERT_EQ(A.size(), size_t(9));
+ ASSERT_TRUE(A == ENCODED(CharT, "123456789"));
- string_view b("123456789");
- b.remove_prefix(4);
- ASSERT_EQ(b.size(), size_t(5));
- ASSERT_TRUE(b == "56789");
+ StringView B(ENCODED(CharT, "123456789"));
+ B.remove_prefix(4);
+ ASSERT_EQ(B.size(), size_t(5));
+ ASSERT_TRUE(B == ENCODED(CharT, "56789"));
- string_view c("123456789");
- c.remove_prefix(9);
- ASSERT_EQ(c.size(), size_t(0));
+ StringView C(ENCODED(CharT, "123456789"));
+ C.remove_prefix(9);
+ ASSERT_EQ(C.size(), size_t(0));
}
-TEST(LlvmLibcStringViewTest, RemoveSuffix) {
- string_view a("123456789");
- a.remove_suffix(0);
- ASSERT_EQ(a.size(), size_t(9));
- ASSERT_TRUE(a == "123456789");
+TYPED_TEST(LlvmLibcStringViewTest, RemoveSuffix, TestCharTypes) {
+ using CharT = ParamType;
+ using StringView = LIBC_NAMESPACE::cpp::basic_string_view<CharT>;
- string_view b("123456789");
- b.remove_suffix(4);
- ASSERT_EQ(b.size(), size_t(5));
- ASSERT_TRUE(b == "12345");
+ StringView A(ENCODED(CharT, "123456789"));
+ A.remove_suffix(0);
+ ASSERT_EQ(A.size(), size_t(9));
+ ASSERT_TRUE(A == ENCODED(CharT, "123456789"));
- string_view c("123456789");
- c.remove_suffix(9);
- ASSERT_EQ(c.size(), size_t(0));
+ StringView B(ENCODED(CharT, "123456789"));
+ B.remove_suffix(4);
+ ASSERT_EQ(B.size(), size_t(5));
+ ASSERT_TRUE(B == ENCODED(CharT, "12345"));
+
+ StringView C(ENCODED(CharT, "123456789"));
+ C.remove_suffix(9);
+ ASSERT_EQ(C.size(), size_t(0));
}
-TEST(LlvmLibcStringViewTest, Observer) {
- string_view ABC("abc");
+TYPED_TEST(LlvmLibcStringViewTest, Observer, TestCharTypes) {
+ using CharT = ParamType;
+ using StringView = LIBC_NAMESPACE::cpp::basic_string_view<CharT>;
+
+ StringView ABC(ENCODED(CharT, "abc"));
ASSERT_EQ(ABC.size(), size_t(3));
ASSERT_FALSE(ABC.empty());
- ASSERT_EQ(ABC.front(), 'a');
- ASSERT_EQ(ABC.back(), 'c');
+ ASSERT_EQ(ABC.front(), ENCODED(CharT, 'a'));
+ ASSERT_EQ(ABC.back(), ENCODED(CharT, 'c'));
+}
+
+TYPED_TEST(LlvmLibcStringViewTest, FindFirstOf, TestCharTypes) {
+ using CharT = ParamType;
+ using StringView = LIBC_NAMESPACE::cpp::basic_string_view<CharT>;
+
+ StringView Tmp(ENCODED(CharT, "abca"));
+ ASSERT_TRUE(Tmp.find_first_of(ENCODED(CharT, 'a')) == 0);
+ ASSERT_TRUE(Tmp.find_first_of(ENCODED(CharT, 'd')) == StringView::npos);
+ ASSERT_TRUE(Tmp.find_first_of(ENCODED(CharT, 'b')) == 1);
+ ASSERT_TRUE(Tmp.find_first_of(ENCODED(CharT, 'a'), 0) == 0);
+ ASSERT_TRUE(Tmp.find_first_of(ENCODED(CharT, 'b'), 1) == 1);
+ ASSERT_TRUE(Tmp.find_first_of(ENCODED(CharT, 'a'), 1) == 3);
+ ASSERT_TRUE(Tmp.find_first_of(ENCODED(CharT, 'a'), 42) == StringView::npos);
+ ASSERT_FALSE(Tmp.find_first_of(ENCODED(CharT, 'c')) == 1);
+ ASSERT_FALSE(Tmp.find_first_of(ENCODED(CharT, 'c'), 0) == 1);
+ ASSERT_FALSE(Tmp.find_first_of(ENCODED(CharT, 'c'), 1) == 1);
}
-TEST(LlvmLibcStringViewTest, FindFirstOf) {
- string_view Tmp("abca");
- ASSERT_TRUE(Tmp.find_first_of('a') == 0);
- ASSERT_TRUE(Tmp.find_first_of('d') == string_view::npos);
- ASSERT_TRUE(Tmp.find_first_of('b') == 1);
- ASSERT_TRUE(Tmp.find_first_of('a', 0) == 0);
- ASSERT_TRUE(Tmp.find_first_of('b', 1) == 1);
- ASSERT_TRUE(Tmp.find_first_of('a', 1) == 3);
- ASSERT_TRUE(Tmp.find_first_of('a', 42) == string_view::npos);
- ASSERT_FALSE(Tmp.find_first_of('c') == 1);
- ASSERT_FALSE(Tmp.find_first_of('c', 0) == 1);
- ASSERT_FALSE(Tmp.find_first_of('c', 1) == 1);
+TYPED_TEST(LlvmLibcStringViewTest, FindLastOf, TestCharTypes) {
+ using CharT = ParamType;
+ using StringView = LIBC_NAMESPACE::cpp::basic_string_view<CharT>;
+
+ StringView Tmp(ENCODED(CharT, "abada"));
+
+ ASSERT_EQ(Tmp.find_last_of(ENCODED(CharT, 'a')), size_t(4));
+ ASSERT_EQ(Tmp.find_last_of(ENCODED(CharT, 'a'), 123), size_t(4));
+ ASSERT_EQ(Tmp.find_last_of(ENCODED(CharT, 'a'), 5), size_t(4));
+ ASSERT_EQ(Tmp.find_last_of(ENCODED(CharT, 'a'), 4), size_t(4));
+ ASSERT_EQ(Tmp.find_last_of(ENCODED(CharT, 'a'), 3), size_t(2));
+ ASSERT_EQ(Tmp.find_last_of(ENCODED(CharT, 'a'), 2), size_t(2));
+ ASSERT_EQ(Tmp.find_last_of(ENCODED(CharT, 'a'), 1), size_t(0));
+ ASSERT_EQ(Tmp.find_last_of(ENCODED(CharT, 'a'), 0), size_t(0));
+
+ ASSERT_EQ(Tmp.find_last_of(ENCODED(CharT, 'b')), size_t(1));
+ ASSERT_EQ(Tmp.find_last_of(ENCODED(CharT, 'b'), 123), size_t(1));
+ ASSERT_EQ(Tmp.find_last_of(ENCODED(CharT, 'b'), 5), size_t(1));
+ ASSERT_EQ(Tmp.find_last_of(ENCODED(CharT, 'b'), 4), size_t(1));
+ ASSERT_EQ(Tmp.find_last_of(ENCODED(CharT, 'b'), 3), size_t(1));
+ ASSERT_EQ(Tmp.find_last_of(ENCODED(CharT, 'b'), 2), size_t(1));
+ ASSERT_EQ(Tmp.find_last_of(ENCODED(CharT, 'b'), 1), size_t(1));
+ ASSERT_EQ(Tmp.find_last_of(ENCODED(CharT, 'b'), 0), StringView::npos);
+
+ ASSERT_EQ(Tmp.find_last_of(ENCODED(CharT, 'd')), size_t(3));
+ ASSERT_EQ(Tmp.find_last_of(ENCODED(CharT, 'd'), 123), size_t(3));
+ ASSERT_EQ(Tmp.find_last_of(ENCODED(CharT, 'd'), 5), size_t(3));
+ ASSERT_EQ(Tmp.find_last_of(ENCODED(CharT, 'd'), 4), size_t(3));
+ ASSERT_EQ(Tmp.find_last_of(ENCODED(CharT, 'd'), 3), size_t(3));
+ ASSERT_EQ(Tmp.find_last_of(ENCODED(CharT, 'd'), 2), StringView::npos);
+ ASSERT_EQ(Tmp.find_last_of(ENCODED(CharT, 'd'), 1), StringView::npos);
+ ASSERT_EQ(Tmp.find_last_of(ENCODED(CharT, 'd'), 0), StringView::npos);
+
+ ASSERT_EQ(Tmp.find_last_of(ENCODED(CharT, 'e')), StringView::npos);
+ ASSERT_EQ(Tmp.find_last_of(ENCODED(CharT, 'e'), 123), StringView::npos);
+ ASSERT_EQ(Tmp.find_last_of(ENCODED(CharT, 'e'), 5), StringView::npos);
+ ASSERT_EQ(Tmp.find_last_of(ENCODED(CharT, 'e'), 4), StringView::npos);
+ ASSERT_EQ(Tmp.find_last_of(ENCODED(CharT, 'e'), 3), StringView::npos);
+ ASSERT_EQ(Tmp.find_last_of(ENCODED(CharT, 'e'), 2), StringView::npos);
+ ASSERT_EQ(Tmp.find_last_of(ENCODED(CharT, 'e'), 1), StringView::npos);
+ ASSERT_EQ(Tmp.find_last_of(ENCODED(CharT, 'e'), 0), StringView::npos);
+
+ StringView Empty;
+ ASSERT_EQ(Empty.find_last_of(ENCODED(CharT, 'a')), StringView::npos);
+ ASSERT_EQ(Empty.find_last_of(ENCODED(CharT, 'a'), 0), StringView::npos);
+ ASSERT_EQ(Empty.find_last_of(ENCODED(CharT, 'a'), 123), StringView::npos);
+
+ StringView Empty1(ENCODED(CharT, ""));
+ ASSERT_EQ(Empty1.find_last_of(ENCODED(CharT, 'a')), StringView::npos);
+ ASSERT_EQ(Empty1.find_last_of(ENCODED(CharT, 'a'), 0), StringView::npos);
+ ASSERT_EQ(Empty1.find_last_of(ENCODED(CharT, 'a'), 123), StringView::npos);
}
-TEST(LlvmLibcStringViewTest, FindLastOf) {
- string_view Tmp("abada");
-
- ASSERT_EQ(Tmp.find_last_of('a'), size_t(4));
- ASSERT_EQ(Tmp.find_last_of('a', 123), size_t(4));
- ASSERT_EQ(Tmp.find_last_of('a', 5), size_t(4));
- ASSERT_EQ(Tmp.find_last_of('a', 4), size_t(4));
- ASSERT_EQ(Tmp.find_last_of('a', 3), size_t(2));
- ASSERT_EQ(Tmp.find_last_of('a', 2), size_t(2));
- ASSERT_EQ(Tmp.find_last_of('a', 1), size_t(0));
- ASSERT_EQ(Tmp.find_last_of('a', 0), size_t(0));
-
- ASSERT_EQ(Tmp.find_last_of('b'), size_t(1));
- ASSERT_EQ(Tmp.find_last_of('b', 123), size_t(1));
- ASSERT_EQ(Tmp.find_last_of('b', 5), size_t(1));
- ASSERT_EQ(Tmp.find_last_of('b', 4), size_t(1));
- ASSERT_EQ(Tmp.find_last_of('b', 3), size_t(1));
- ASSERT_EQ(Tmp.find_last_of('b', 2), size_t(1));
- ASSERT_EQ(Tmp.find_last_of('b', 1), size_t(1));
- ASSERT_EQ(Tmp.find_last_of('b', 0), string_view::npos);
-
- ASSERT_EQ(Tmp.find_last_of('d'), size_t(3));
- ASSERT_EQ(Tmp.find_last_of('d', 123), size_t(3));
- ASSERT_EQ(Tmp.find_last_of('d', 5), size_t(3));
- ASSERT_EQ(Tmp.find_last_of('d', 4), size_t(3));
- ASSERT_EQ(Tmp.find_last_of('d', 3), size_t(3));
- ASSERT_EQ(Tmp.find_last_of('d', 2), string_view::npos);
- ASSERT_EQ(Tmp.find_last_of('d', 1), string_view::npos);
- ASSERT_EQ(Tmp.find_last_of('d', 0), string_view::npos);
-
- ASSERT_EQ(Tmp.find_last_of('e'), string_view::npos);
- ASSERT_EQ(Tmp.find_last_of('e', 123), string_view::npos);
- ASSERT_EQ(Tmp.find_last_of('e', 5), string_view::npos);
- ASSERT_EQ(Tmp.find_last_of('e', 4), string_view::npos);
- ASSERT_EQ(Tmp.find_last_of('e', 3), string_view::npos);
- ASSERT_EQ(Tmp.find_last_of('e', 2), string_view::npos);
- ASSERT_EQ(Tmp.find_last_of('e', 1), string_view::npos);
- ASSERT_EQ(Tmp.find_last_of('e', 0), string_view::npos);
-
- string_view Empty;
- ASSERT_EQ(Empty.find_last_of('a'), string_view::npos);
- ASSERT_EQ(Empty.find_last_of('a', 0), string_view::npos);
- ASSERT_EQ(Empty.find_last_of('a', 123), string_view::npos);
-
- string_view Empty1("");
- ASSERT_EQ(Empty1.find_last_of('a'), string_view::npos);
- ASSERT_EQ(Empty1.find_last_of('a', 0), string_view::npos);
- ASSERT_EQ(Empty1.find_last_of('a', 123), string_view::npos);
+TYPED_TEST(LlvmLibcStringViewTest, FindFirstNotOf, TestCharTypes) {
+ using CharT = ParamType;
+ using StringView = LIBC_NAMESPACE::cpp::basic_string_view<CharT>;
+
+ StringView Tmp(ENCODED(CharT, "abada"));
+
+ EXPECT_EQ(Tmp.find_first_not_of(ENCODED(CharT, 'a')), size_t(1));
+ EXPECT_EQ(Tmp.find_first_not_of(ENCODED(CharT, 'a'), 123), StringView::npos);
+ EXPECT_EQ(Tmp.find_first_not_of(ENCODED(CharT, 'a'), 5), StringView::npos);
+ EXPECT_EQ(Tmp.find_first_not_of(ENCODED(CharT, 'a'), 4), StringView::npos);
+ EXPECT_EQ(Tmp.find_first_not_of(ENCODED(CharT, 'a'), 3), size_t(3));
+ EXPECT_EQ(Tmp.find_first_not_of(ENCODED(CharT, 'a'), 2), size_t(3));
+ EXPECT_EQ(Tmp.find_first_not_of(ENCODED(CharT, 'a'), 1), size_t(1));
+ EXPECT_EQ(Tmp.find_first_not_of(ENCODED(CharT, 'a'), 0), size_t(1));
+
+ EXPECT_EQ(Tmp.find_first_not_of(ENCODED(CharT, 'b')), size_t(0));
+ EXPECT_EQ(Tmp.find_first_not_of(ENCODED(CharT, 'b'), 123), StringView::npos);
+ EXPECT_EQ(Tmp.find_first_not_of(ENCODED(CharT, 'b'), 5), StringView::npos);
+ EXPECT_EQ(Tmp.find_first_not_of(ENCODED(CharT, 'b'), 4), size_t(4));
+ EXPECT_EQ(Tmp.find_first_not_of(ENCODED(CharT, 'b'), 3), size_t(3));
+ EXPECT_EQ(Tmp.find_first_not_of(ENCODED(CharT, 'b'), 2), size_t(2));
+ EXPECT_EQ(Tmp.find_first_not_of(ENCODED(CharT, 'b'), 1), size_t(2));
+ EXPECT_EQ(Tmp.find_first_not_of(ENCODED(CharT, 'b'), 0), size_t(0));
+
+ EXPECT_EQ(Tmp.find_first_not_of(ENCODED(CharT, 'd')), size_t(0));
+ EXPECT_EQ(Tmp.find_first_not_of(ENCODED(CharT, 'd'), 123), StringView::npos);
+ EXPECT_EQ(Tmp.find_first_not_of(ENCODED(CharT, 'd'), 5), StringView::npos);
+ EXPECT_EQ(Tmp.find_first_not_of(ENCODED(CharT, 'd'), 4), size_t(4));
+ EXPECT_EQ(Tmp.find_first_not_of(ENCODED(CharT, 'd'), 3), size_t(4));
+ EXPECT_EQ(Tmp.find_first_not_of(ENCODED(CharT, 'd'), 2), size_t(2));
+ EXPECT_EQ(Tmp.find_first_not_of(ENCODED(CharT, 'd'), 1), size_t(1));
+ EXPECT_EQ(Tmp.find_first_not_of(ENCODED(CharT, 'd'), 0), size_t(0));
+
+ EXPECT_EQ(Tmp.find_first_not_of(ENCODED(CharT, 'e')), size_t(0));
+ EXPECT_EQ(Tmp.find_first_not_of(ENCODED(CharT, 'e'), 123), StringView::npos);
+ EXPECT_EQ(Tmp.find_first_not_of(ENCODED(CharT, 'e'), 5), StringView::npos);
+ EXPECT_EQ(Tmp.find_first_not_of(ENCODED(CharT, 'e'), 4), size_t(4));
+ EXPECT_EQ(Tmp.find_first_not_of(ENCODED(CharT, 'e'), 3), size_t(3));
+ EXPECT_EQ(Tmp.find_first_not_of(ENCODED(CharT, 'e'), 2), size_t(2));
+ EXPECT_EQ(Tmp.find_first_not_of(ENCODED(CharT, 'e'), 1), size_t(1));
+ EXPECT_EQ(Tmp.find_first_not_of(ENCODED(CharT, 'e'), 0), size_t(0));
+
+ StringView Empty;
+ EXPECT_EQ(Empty.find_first_not_of(ENCODED(CharT, 'a')), StringView::npos);
+ EXPECT_EQ(Empty.find_first_not_of(ENCODED(CharT, 'a'), 0), StringView::npos);
+ EXPECT_EQ(Empty.find_first_not_of(ENCODED(CharT, 'a'), 123),
+ StringView::npos);
+
+ StringView Empty1(ENCODED(CharT, ""));
+ EXPECT_EQ(Empty1.find_first_not_of(ENCODED(CharT, 'a')), StringView::npos);
+ EXPECT_EQ(Empty1.find_first_not_of(ENCODED(CharT, 'a'), 0), StringView::npos);
+ EXPECT_EQ(Empty1.find_first_not_of(ENCODED(CharT, 'a'), 123),
+ StringView::npos);
+
+ StringView Full(ENCODED(CharT, "aaaaaaa"));
+ EXPECT_EQ(Full.find_first_not_of(ENCODED(CharT, 'a')), StringView::npos);
+ EXPECT_EQ(Full.find_first_not_of(ENCODED(CharT, 'a'), 0), StringView::npos);
+ EXPECT_EQ(Full.find_first_not_of(ENCODED(CharT, 'a'), 123), StringView::npos);
+
+ EXPECT_EQ(Full.find_first_not_of(ENCODED(CharT, 'b')), size_t(0));
+ EXPECT_EQ(Full.find_first_not_of(ENCODED(CharT, 'b'), 0), size_t(0));
+ EXPECT_EQ(Full.find_first_not_of(ENCODED(CharT, 'b'), 123), StringView::npos);
}
-TEST(LlvmLibcStringViewTest, FindFirstNotOf) {
- string_view Tmp("abada");
-
- EXPECT_EQ(Tmp.find_first_not_of('a'), size_t(1));
- EXPECT_EQ(Tmp.find_first_not_of('a', 123), string_view::npos);
- EXPECT_EQ(Tmp.find_first_not_of('a', 5), string_view::npos);
- EXPECT_EQ(Tmp.find_first_not_of('a', 4), string_view::npos);
- EXPECT_EQ(Tmp.find_first_not_of('a', 3), size_t(3));
- EXPECT_EQ(Tmp.find_first_not_of('a', 2), size_t(3));
- EXPECT_EQ(Tmp.find_first_not_of('a', 1), size_t(1));
- EXPECT_EQ(Tmp.find_first_not_of('a', 0), size_t(1));
-
- EXPECT_EQ(Tmp.find_first_not_of('b'), size_t(0));
- EXPECT_EQ(Tmp.find_first_not_of('b', 123), string_view::npos);
- EXPECT_EQ(Tmp.find_first_not_of('b', 5), string_view::npos);
- EXPECT_EQ(Tmp.find_first_not_of('b', 4), size_t(4));
- EXPECT_EQ(Tmp.find_first_not_of('b', 3), size_t(3));
- EXPECT_EQ(Tmp.find_first_not_of('b', 2), size_t(2));
- EXPECT_EQ(Tmp.find_first_not_of('b', 1), size_t(2));
- EXPECT_EQ(Tmp.find_first_not_of('b', 0), size_t(0));
-
- EXPECT_EQ(Tmp.find_first_not_of('d'), size_t(0));
- EXPECT_EQ(Tmp.find_first_not_of('d', 123), string_view::npos);
- EXPECT_EQ(Tmp.find_first_not_of('d', 5), string_view::npos);
- EXPECT_EQ(Tmp.find_first_not_of('d', 4), size_t(4));
- EXPECT_EQ(Tmp.find_first_not_of('d', 3), size_t(4));
- EXPECT_EQ(Tmp.find_first_not_of('d', 2), size_t(2));
- EXPECT_EQ(Tmp.find_first_not_of('d', 1), size_t(1));
- EXPECT_EQ(Tmp.find_first_not_of('d', 0), size_t(0));
-
- EXPECT_EQ(Tmp.find_first_not_of('e'), size_t(0));
- EXPECT_EQ(Tmp.find_first_not_of('e', 123), string_view::npos);
- EXPECT_EQ(Tmp.find_first_not_of('e', 5), string_view::npos);
- EXPECT_EQ(Tmp.find_first_not_of('e', 4), size_t(4));
- EXPECT_EQ(Tmp.find_first_not_of('e', 3), size_t(3));
- EXPECT_EQ(Tmp.find_first_not_of('e', 2), size_t(2));
- EXPECT_EQ(Tmp.find_first_not_of('e', 1), size_t(1));
- EXPECT_EQ(Tmp.find_first_not_of('e', 0), size_t(0));
-
- string_view Empty;
- EXPECT_EQ(Empty.find_first_not_of('a'), string_view::npos);
- EXPECT_EQ(Empty.find_first_not_of('a', 0), string_view::npos);
- EXPECT_EQ(Empty.find_first_not_of('a', 123), string_view::npos);
-
- string_view Empty1("");
- EXPECT_EQ(Empty1.find_first_not_of('a'), string_view::npos);
- EXPECT_EQ(Empty1.find_first_not_of('a', 0), string_view::npos);
- EXPECT_EQ(Empty1.find_first_not_of('a', 123), string_view::npos);
-
- string_view Full("aaaaaaa");
- EXPECT_EQ(Full.find_first_not_of('a'), string_view::npos);
- EXPECT_EQ(Full.find_first_not_of('a', 0), string_view::npos);
- EXPECT_EQ(Full.find_first_not_of('a', 123), string_view::npos);
-
- EXPECT_EQ(Full.find_first_not_of('b'), size_t(0));
- EXPECT_EQ(Full.find_first_not_of('b', 0), size_t(0));
- EXPECT_EQ(Full.find_first_not_of('b', 123), string_view::npos);
+TYPED_TEST(LlvmLibcStringViewTest, Contains, TestCharTypes) {
+ using CharT = ParamType;
+ using StringView = LIBC_NAMESPACE::cpp::basic_string_view<CharT>;
+
+ StringView Empty;
+ EXPECT_FALSE(Empty.contains(ENCODED(CharT, 'a')));
+ EXPECT_FALSE(Empty.contains(ENCODED(CharT, 'g')));
+ EXPECT_FALSE(Empty.contains(ENCODED(CharT, 'q')));
+
+ StringView S = ENCODED(CharT, "abada");
+ EXPECT_TRUE(S.contains(ENCODED(CharT, 'a')));
+ EXPECT_TRUE(S.contains(ENCODED(CharT, 'b')));
+ EXPECT_FALSE(S.contains(ENCODED(CharT, 'c')));
+ EXPECT_TRUE(S.contains(ENCODED(CharT, 'd')));
+ EXPECT_FALSE(S.contains(ENCODED(CharT, 'e')));
}
-TEST(LlvmLibcStringViewTest, Contains) {
- string_view Empty;
- static_assert(
- 'a' < 'z',
- "This test only supports character encodings where 'a' is below 'z'");
- for (char c = 'a'; c < 'z'; ++c)
- EXPECT_FALSE(Empty.contains(c));
-
- string_view Tmp("abada");
- EXPECT_TRUE(Tmp.contains('a'));
- EXPECT_TRUE(Tmp.contains('b'));
- EXPECT_FALSE(Tmp.contains('c'));
- EXPECT_TRUE(Tmp.contains('d'));
- EXPECT_FALSE(Tmp.contains('e'));
-
- EXPECT_TRUE(Tmp.substr(1).contains('a'));
- EXPECT_TRUE(Tmp.substr(1).contains('b'));
- EXPECT_FALSE(Tmp.substr(1).contains('c'));
- EXPECT_TRUE(Tmp.substr(1).contains('d'));
- EXPECT_FALSE(Tmp.substr(1).contains('e'));
-
- EXPECT_TRUE(Tmp.substr(2).contains('a'));
- EXPECT_FALSE(Tmp.substr(2).contains('b'));
- EXPECT_FALSE(Tmp.substr(2).contains('c'));
- EXPECT_TRUE(Tmp.substr(2).contains('d'));
- EXPECT_FALSE(Tmp.substr(2).contains('e'));
-
- EXPECT_TRUE(Tmp.substr(3).contains('a'));
- EXPECT_FALSE(Tmp.substr(3).contains('b'));
- EXPECT_FALSE(Tmp.substr(3).contains('c'));
- EXPECT_TRUE(Tmp.substr(3).contains('d'));
- EXPECT_FALSE(Tmp.substr(3).contains('e'));
-
- EXPECT_TRUE(Tmp.substr(4).contains('a'));
- EXPECT_FALSE(Tmp.substr(4).contains('b'));
- EXPECT_FALSE(Tmp.substr(4).contains('c'));
- EXPECT_FALSE(Tmp.substr(4).contains('d'));
- EXPECT_FALSE(Tmp.substr(4).contains('e'));
-
- EXPECT_FALSE(Tmp.substr(5).contains('a'));
- EXPECT_FALSE(Tmp.substr(5).contains('b'));
- EXPECT_FALSE(Tmp.substr(5).contains('c'));
- EXPECT_FALSE(Tmp.substr(5).contains('d'));
- EXPECT_FALSE(Tmp.substr(5).contains('e'));
-
- EXPECT_FALSE(Tmp.substr(6).contains('a'));
- EXPECT_FALSE(Tmp.substr(6).contains('b'));
- EXPECT_FALSE(Tmp.substr(6).contains('c'));
- EXPECT_FALSE(Tmp.substr(6).contains('d'));
- EXPECT_FALSE(Tmp.substr(6).contains('e'));
+TYPED_TEST(LlvmLibcStringViewTest, Substr, TestCharTypes) {
+ using CharT = ParamType;
+ using StringView = LIBC_NAMESPACE::cpp::basic_string_view<CharT>;
+
+ StringView S = ENCODED(CharT, "abada");
+ EXPECT_EQ(S.substr(0), StringView(ENCODED(CharT, "abada")));
+ EXPECT_EQ(S.substr(1), StringView(ENCODED(CharT, "bada")));
+ EXPECT_EQ(S.substr(3), StringView(ENCODED(CharT, "da")));
+ EXPECT_EQ(S.substr(5), StringView(ENCODED(CharT, "")));
+ EXPECT_EQ(S.substr(1, 3), StringView(ENCODED(CharT, "bad")));
+ EXPECT_EQ(S.substr(3, 1), StringView(ENCODED(CharT, "d")));
+}
+
+TEST(LlvmLibcStringViewTest, WideCharacterComparison) {
+ // Check that wide character comparison is lexicographic by character and not
+ // equivalent to memcmp, which would be incorrect on little endian.
+ char BytesA[] = {1, 2, 3, 4};
+ char BytesB[] = {4, 3, 2, 1};
+ char32_t CharA;
+ char32_t CharB;
+ LIBC_NAMESPACE::inline_memcpy(&CharA, BytesA, sizeof(CharA));
+ LIBC_NAMESPACE::inline_memcpy(&CharB, BytesB, sizeof(CharB));
+
+ LIBC_NAMESPACE::cpp::basic_string_view<char32_t> StringViewA(&CharA, 1);
+ LIBC_NAMESPACE::cpp::basic_string_view<char32_t> StringViewB(&CharB, 1);
+
+ EXPECT_EQ(StringViewA < StringViewB, CharA < CharB);
}
More information about the libc-commits
mailing list