diff --git a/sycl/include/sycl/detail/string.hpp b/sycl/include/sycl/detail/string.hpp index f2846069a93d6..f23c4176e49e2 100644 --- a/sycl/include/sycl/detail/string.hpp +++ b/sycl/include/sycl/detail/string.hpp @@ -58,7 +58,7 @@ class string { const char *c_str() const noexcept { return str ? str : ""; } const char *data() const noexcept { return c_str(); } - bool empty() { return str ? str[0] : false; } + bool empty() const noexcept { return str == nullptr || *str == '\0'; } friend bool operator==(const string &lhs, std::string_view rhs) noexcept { return rhs == lhs.c_str(); diff --git a/sycl/unittests/misc/CMakeLists.txt b/sycl/unittests/misc/CMakeLists.txt index 4cccdd87bbc95..7c280a9de16e7 100644 --- a/sycl/unittests/misc/CMakeLists.txt +++ b/sycl/unittests/misc/CMakeLists.txt @@ -6,6 +6,7 @@ add_sycl_unittest(MiscTests SHARED CircularBuffer.cpp OsUtils.cpp PropertyUtils.cpp + DetailString.cpp ) endif() add_subdirectory(LinkGraph) diff --git a/sycl/unittests/misc/DetailString.cpp b/sycl/unittests/misc/DetailString.cpp new file mode 100644 index 0000000000000..d3914c20de7f3 --- /dev/null +++ b/sycl/unittests/misc/DetailString.cpp @@ -0,0 +1,92 @@ +#include +#include + +class SYCLDetailStringTest : public ::testing::Test {}; + +TEST_F(SYCLDetailStringTest, DefaultConstructor) { + sycl::detail::string empty_s; + EXPECT_TRUE(empty_s.empty()); + EXPECT_STREQ(empty_s.c_str(), ""); +} + +TEST_F(SYCLDetailStringTest, StringViewConstructor) { + std::string_view sv = "Hello, World!"; + sycl::detail::string s1(sv); + EXPECT_STREQ(s1.c_str(), "Hello, World!"); +} + +TEST_F(SYCLDetailStringTest, CopyConstructor) { + sycl::detail::string s1("Hello, World!"); + sycl::detail::string s2(s1); + EXPECT_STREQ(s2.c_str(), "Hello, World!"); + + // Check for deep copy: modifying the original should not affect the copy. + s1 = "Changed"; + EXPECT_STREQ(s2.c_str(), "Hello, World!"); +} + +TEST_F(SYCLDetailStringTest, MoveConstructor) { + sycl::detail::string s1("Changed"); + sycl::detail::string s2(std::move(s1)); + EXPECT_STREQ(s2.c_str(), "Changed"); +} + +TEST_F(SYCLDetailStringTest, StringViewAssignment) { + sycl::detail::string s; + s = "New String"; + EXPECT_STREQ(s.c_str(), "New String"); + std::string_view sv = "From String View"; + s = sv; + EXPECT_STREQ(s.c_str(), "From String View"); +} + +TEST_F(SYCLDetailStringTest, CopyAssignment) { + sycl::detail::string s1("Hello, World!"); + sycl::detail::string s2; + s2 = s1; + EXPECT_STREQ(s2.c_str(), "Hello, World!"); + + // Check for deep copy. + s1 = "Changed"; + EXPECT_STREQ(s2.c_str(), "Hello, World!"); +} + +TEST_F(SYCLDetailStringTest, MoveAssignment) { + sycl::detail::string s1("Changed"); + sycl::detail::string s2; + s2 = std::move(s1); + EXPECT_STREQ(s2.c_str(), "Changed"); +} + +TEST_F(SYCLDetailStringTest, Methods) { + sycl::detail::string s_not_empty("not empty"); + sycl::detail::string s_empty; + // Test c_str() and data(). + EXPECT_STREQ(s_not_empty.data(), "not empty"); + EXPECT_STREQ(s_not_empty.c_str(), "not empty"); + EXPECT_EQ(s_not_empty.data(), s_not_empty.c_str()); + + // Test empty(). Like really. + EXPECT_FALSE(s_not_empty.empty()); + EXPECT_TRUE(sycl::detail::string("").empty()); + EXPECT_TRUE(sycl::detail::string().empty()); + EXPECT_TRUE(s_empty.empty()); +} + +TEST_F(SYCLDetailStringTest, Swap) { + sycl::detail::string s1("first"); + sycl::detail::string s2("second"); + swap(s1, s2); + EXPECT_STREQ(s1.c_str(), "second"); + EXPECT_STREQ(s2.c_str(), "first"); +} + +TEST_F(SYCLDetailStringTest, ComparisonOperators) { + sycl::detail::string s("match"); + std::string_view sv_match("match"); + std::string_view sv_no_match("no match"); + + EXPECT_EQ(s, sv_match); + EXPECT_EQ(sv_match, s); + EXPECT_FALSE(s == sv_no_match); +}