Sfoglia il codice sorgente

Add StartsWith string utility, and string literal constructor for StringView

Michael Ragazzon 2 anni fa
parent
commit
b8cca82dd5

+ 10 - 0
Include/RmlUi/Core/StringUtilities.h

@@ -102,6 +102,9 @@ namespace StringUtilities
 	/// @warning If the string does not represent a number _with_ a decimal point, the result is ill-defined.
 	RMLUICORE_API void TrimTrailingDotZeros(String& string);
 
+	/// Returns true if the string starts with the given value.
+	RMLUICORE_API bool StartsWith(StringView string, StringView start);
+
 	/// Case insensitive string comparison. Returns true if they compare equal.
 	RMLUICORE_API bool StringCompareCaseInsensitive(StringView lhs, StringView rhs);
 
@@ -148,6 +151,13 @@ public:
 	StringView(const String& string, size_t offset);
 	StringView(const String& string, size_t offset, size_t count);
 
+	// Constructor for null-terminated string literals.
+	template <size_t N>
+	StringView(const char (&string)[N]) : p_begin(string), p_end(string + (N - 1))
+	{
+		static_assert(N >= 1, "");
+	}
+
 	// String comparison to another view
 	bool operator==(const StringView& other) const;
 	inline bool operator!=(const StringView& other) const { return !(*this == other); }

+ 9 - 0
Source/Core/StringUtilities.cpp

@@ -390,6 +390,15 @@ void StringUtilities::TrimTrailingDotZeros(String& string)
 		string.resize(new_size);
 }
 
+bool StringUtilities::StartsWith(StringView string, StringView start)
+{
+	if (string.size() < start.size())
+		return false;
+
+	StringView substring(string.begin(), string.begin() + start.size());
+	return substring == start;
+}
+
 bool StringUtilities::StringCompareCaseInsensitive(const StringView lhs, const StringView rhs)
 {
 	if (lhs.size() != rhs.size())

+ 38 - 0
Tests/Source/UnitTests/StringUtilities.cpp

@@ -64,4 +64,42 @@ TEST_CASE("StringUtilities::TrimTrailingDotZeros")
 	WARN(RunTrimTrailingDotZeros("11") == "11");
 }
 
+TEST_CASE("StringUtilities::StartsWith")
+{
+	using namespace Rml::StringUtilities;
+
+	CHECK(StartsWith("abc", "abc"));
+	CHECK(StartsWith("abc", "ab"));
+	CHECK(StartsWith("abc", "a"));
+	CHECK(StartsWith("abc", ""));
+	
+	CHECK(!StartsWith("abc", "abcd"));
+	CHECK(!StartsWith("abc", "abd"));
+	CHECK(!StartsWith("abc", "bbc"));
+	CHECK(!StartsWith("abc", "bc"));
+	CHECK(!StartsWith("abc", "x"));
+}
+
+TEST_CASE("StringView")
+{
+	const char abc[] = "abc";
+	const String str_abc = abc;
 
+	CHECK(StringView("abc") == StringView("abc"));
+	CHECK(StringView("abc") == String("abc"));
+	CHECK(StringView("abc") == "abc");
+	CHECK(StringView("abc") == abc);
+
+	CHECK(StringView(String(abc)) == abc);
+	CHECK(StringView(abc) == abc);
+	CHECK(StringView(abc, abc + 3) == abc);
+	CHECK(StringView(str_abc, 1) == "bc");
+	CHECK(StringView(str_abc, 1, 1) == "b");
+
+	CHECK(StringView("abcd") != abc);
+	CHECK(StringView("ab") != abc);
+	CHECK(StringView() != abc);
+
+	CHECK(StringView() == String());
+	CHECK(StringView() == "");
+}