mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-11 00:11:07 -06:00
String: Add support for a ""_s string literal syntax
Create a `static_string_view` type that binds only to the static storage of string literals. Teach `cm::String` to borrow from these implicitly.
This commit is contained in:
@@ -377,6 +377,7 @@ set(SRCS
|
||||
cmake.h
|
||||
cm_string_view.cxx
|
||||
cm_string_view.hxx
|
||||
cm_static_string_view.hxx
|
||||
|
||||
cmCommand.cxx
|
||||
cmCommand.h
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include "cmConfigure.h" // IWYU pragma: keep
|
||||
|
||||
#include "cm_static_string_view.hxx"
|
||||
#include "cm_string_view.hxx"
|
||||
|
||||
#include <algorithm>
|
||||
@@ -89,6 +90,12 @@ struct IntoString<string_view> : std::true_type
|
||||
static std::string into_string(string_view s) { return std::string(s); }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct IntoString<static_string_view> : std::true_type
|
||||
{
|
||||
static string_view into_string(static_string_view s) { return s; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct IntoString<char> : std::true_type
|
||||
{
|
||||
@@ -156,6 +163,12 @@ struct AsStringView<string_view> : std::true_type
|
||||
static string_view view(string_view const& s) { return s; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct AsStringView<static_string_view> : std::true_type
|
||||
{
|
||||
static string_view view(static_string_view const& s) { return s; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct AsStringView<String> : std::true_type
|
||||
{
|
||||
@@ -370,7 +383,7 @@ public:
|
||||
}
|
||||
|
||||
/** Assign to an empty string. */
|
||||
void clear() { *this = String(string_view("", 0), Private()); }
|
||||
void clear() { *this = ""_s; }
|
||||
|
||||
/** Insert 'count' copies of 'ch' at position 'index'. */
|
||||
String& insert(size_type index, size_type count, char ch);
|
||||
|
||||
41
Source/cm_static_string_view.hxx
Normal file
41
Source/cm_static_string_view.hxx
Normal file
@@ -0,0 +1,41 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#ifndef cm_static_string_view_hxx
|
||||
#define cm_static_string_view_hxx
|
||||
|
||||
#include "cmConfigure.h" // IWYU pragma: keep
|
||||
|
||||
#include "cm_string_view.hxx"
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace cm {
|
||||
|
||||
/** A string_view that only binds to static storage.
|
||||
*
|
||||
* This is used together with the `""_s` user-defined literal operator
|
||||
* to construct a type-safe abstraction of a string_view that only views
|
||||
* statically allocated strings. These strings are const and available
|
||||
* for the entire lifetime of the program.
|
||||
*/
|
||||
class static_string_view : public string_view
|
||||
{
|
||||
static_string_view(string_view v)
|
||||
: string_view(v)
|
||||
{
|
||||
}
|
||||
|
||||
friend static_string_view operator"" _s(const char* data, size_t size);
|
||||
};
|
||||
|
||||
/** Create a static_string_view using `""_s` literal syntax. */
|
||||
inline static_string_view operator"" _s(const char* data, size_t size)
|
||||
{
|
||||
return string_view(data, size);
|
||||
}
|
||||
|
||||
} // namespace cm
|
||||
|
||||
using cm::operator"" _s;
|
||||
|
||||
#endif
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "cmString.hxx"
|
||||
|
||||
#include "cm_static_string_view.hxx"
|
||||
#include "cm_string_view.hxx"
|
||||
|
||||
#include <cstring>
|
||||
@@ -254,6 +255,36 @@ static bool testConstructFromN()
|
||||
return true;
|
||||
}
|
||||
|
||||
static const auto staticStringView = "abc"_s;
|
||||
|
||||
static bool testFromStaticStringView(cm::String str)
|
||||
{
|
||||
cm::String const& str_const = str;
|
||||
ASSERT_TRUE(str_const.data() == staticStringView.data());
|
||||
ASSERT_TRUE(str_const.size() == staticStringView.size());
|
||||
ASSERT_TRUE(str.c_str() == staticStringView);
|
||||
cm::String substr = str.substr(1);
|
||||
cm::String const& substr_const = substr;
|
||||
ASSERT_TRUE(substr_const.data() == &staticStringView[1]);
|
||||
ASSERT_TRUE(substr_const.size() == 2);
|
||||
ASSERT_TRUE(substr.c_str() == &staticStringView[1]);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool testConstructFromStaticStringView()
|
||||
{
|
||||
std::cout << "testConstructFromStaticStringView()\n";
|
||||
return testFromStaticStringView(staticStringView);
|
||||
}
|
||||
|
||||
static bool testAssignFromStaticStringView()
|
||||
{
|
||||
std::cout << "testAssignFromStaticStringView()\n";
|
||||
cm::String str;
|
||||
str = staticStringView;
|
||||
return testFromStaticStringView(str);
|
||||
}
|
||||
|
||||
static bool testConstructCopy()
|
||||
{
|
||||
std::cout << "testConstructCopy()\n";
|
||||
@@ -730,7 +761,7 @@ static bool testMethod_substr_AtEnd(cm::String str)
|
||||
static bool testMethod_substr_AtEndBorrowed()
|
||||
{
|
||||
std::cout << "testMethod_substr_AtEndBorrowed()\n";
|
||||
return testMethod_substr_AtEnd(cm::String::borrow("abc"));
|
||||
return testMethod_substr_AtEnd("abc"_s);
|
||||
}
|
||||
|
||||
static bool testMethod_substr_AtEndOwned()
|
||||
@@ -784,7 +815,7 @@ static bool testMethod_substr_AtStart(cm::String str)
|
||||
static bool testMethod_substr_AtStartBorrowed()
|
||||
{
|
||||
std::cout << "testMethod_substr_AtStartBorrowed()\n";
|
||||
return testMethod_substr_AtStart(cm::String::borrow("abc"));
|
||||
return testMethod_substr_AtStart("abc"_s);
|
||||
}
|
||||
|
||||
static bool testMethod_substr_AtStartOwned()
|
||||
@@ -977,6 +1008,14 @@ static bool testAddition()
|
||||
ASSERT_TRUE("a" + (cm::String("b") + "c") + "d" == "abcd");
|
||||
ASSERT_TRUE("abcd" == "a" + (cm::String("b") + "c") + "d");
|
||||
}
|
||||
{
|
||||
ASSERT_TRUE(cm::String("a"_s) + "b"_s == "ab"_s);
|
||||
ASSERT_TRUE("ab"_s == "a"_s + cm::String("b"_s));
|
||||
ASSERT_TRUE("a"_s + cm::String("b"_s) + "c"_s == "abc"_s);
|
||||
ASSERT_TRUE("abc"_s == "a"_s + cm::String("b"_s) + "c"_s);
|
||||
ASSERT_TRUE("a"_s + (cm::String("b"_s) + "c"_s) + "d"_s == "abcd"_s);
|
||||
ASSERT_TRUE("abcd"_s == "a"_s + (cm::String("b"_s) + "c"_s) + "d"_s);
|
||||
}
|
||||
{
|
||||
const char* a = "a";
|
||||
const char* b = "b";
|
||||
@@ -1101,6 +1140,9 @@ int testString(int /*unused*/, char* /*unused*/ [])
|
||||
if (!testConstructFromN()) {
|
||||
return 1;
|
||||
}
|
||||
if (!testConstructFromStaticStringView()) {
|
||||
return 1;
|
||||
}
|
||||
if (!testConstructCopy()) {
|
||||
return 1;
|
||||
}
|
||||
@@ -1137,6 +1179,9 @@ int testString(int /*unused*/, char* /*unused*/ [])
|
||||
if (!testAssignFromInitList()) {
|
||||
return 1;
|
||||
}
|
||||
if (!testAssignFromStaticStringView()) {
|
||||
return 1;
|
||||
}
|
||||
if (!testOperatorBool()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user