From 3dfb2a5ac1c260b9259fd5fc284346d76ca4777d Mon Sep 17 00:00:00 2001 From: Ian McInerney Date: Thu, 13 Jul 2023 10:26:40 +0100 Subject: [PATCH] Add std::string_view constructors to wxString --- include/wx/string.h | 29 +++++++++++++++++++++++++++++ interface/wx/string.h | 34 ++++++++++++++++++++++++++++++++++ tests/strings/stdstrings.cpp | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+) diff --git a/include/wx/string.h b/include/wx/string.h index 0b854a3b91..6b950af8d1 100644 --- a/include/wx/string.h +++ b/include/wx/string.h @@ -44,6 +44,17 @@ #include "wx/beforestd.h" #include #include + +// Check if C++17 is available +#ifdef __has_include + #if __has_include() + #include + #ifdef __cpp_lib_string_view + #define wxHAS_STD_STRING_VIEW + #endif + #endif +#endif + #include "wx/afterstd.h" // by default we cache the mapping of the positions in UTF-8 string to the byte @@ -1253,9 +1264,19 @@ public: { assign(str.c_str(), str.length()); } #endif +#ifdef wxHAS_STD_STRING_VIEW + wxString(std::wstring_view view) + { assign(view.data(), view.length()); } +#endif // wxHAS_STD_STRING_VIEW + #ifndef wxNO_IMPLICIT_WXSTRING_ENCODING wxString(const std::string& str) { assign(str.c_str(), str.length()); } + + #ifdef wxHAS_STD_STRING_VIEW + wxString(std::string_view view) + { assign(view.data(), view.length()); } + #endif // wxHAS_STD_STRING_VIEW #endif // wxNO_IMPLICIT_WXSTRING_ENCODING // Also always provide explicit conversions to std::[w]string in any case, @@ -1700,6 +1721,14 @@ public: const wxScopedCharBuffer utf8_str() const { return mb_str(wxMBConvUTF8()); } #endif // wxUSE_UNICODE_UTF8/wxUSE_UNICODE_WCHAR +// Conversion from std::string_view is the same for both of the two cases above +#ifdef wxHAS_STD_STRING_VIEW + static wxString FromUTF8Unchecked(std::string_view view) + { return FromUTF8Unchecked(view.data(), view.length()); } + static wxString FromUTF8(std::string_view view) + { return FromUTF8(view.data(), view.length()); } +#endif // wxHAS_STD_STRING_VIEW + const wxScopedCharBuffer ToUTF8() const { return utf8_str(); } // functions for storing binary data in wxString: diff --git a/interface/wx/string.h b/interface/wx/string.h index 48641a121a..7608c49658 100644 --- a/interface/wx/string.h +++ b/interface/wx/string.h @@ -68,10 +68,17 @@ Notice that this constructor supposes that the string contains data in the current locale encoding, use FromUTF8() if the string contains UTF-8-encoded data instead. + - Standard @c std::string_view using implicit wxString::wxString(std::string_view) + constructor. + Notice that this constructor supposes that the string contains data in + the current locale encoding, use FromUTF8() if the string contains + UTF-8-encoded data instead. - Wide @c wchar_t* string using implicit wxString::wxString(const wchar_t*) constructor. - Standard @c std::wstring using implicit wxString::wxString(const std::wstring&) constructor. + - Standard @c std::wstring_view using implicit + wxString::wxString(std::wstring_view) constructor. Notice that many of the constructors are implicit, meaning that you don't even need to write them at all to pass the existing string to some @@ -477,6 +484,16 @@ public: */ wxString(const std::string& str); + /** + Constructs a string from @a str using the using the current locale encoding + to convert it to Unicode (wxConvLibc). + + @note Requires the application to be compiled with C++17 + + @since 3.3.0 + */ + wxString(std::string_view str); + /** Constructs a string from @a str. @@ -484,6 +501,15 @@ public: */ wxString(const std::wstring& str); + /** + Constructs a string from @a str. + + @note Requires the application to be compiled with C++17 + + @since 3.3.0 + */ + wxString(std::wstring_view str); + /** String destructor. @@ -1931,11 +1957,15 @@ public: The overload taking @c std::string is only available starting with wxWidgets 3.1.1. + The overload taking @c std::string_view is only available starting with + wxWidgets 3.3.0 and requires the consumer application to use C++17. + @since 2.8.4 */ static wxString FromUTF8(const char* s); static wxString FromUTF8(const char* s, size_t len); static wxString FromUTF8(const std::string& s); + static wxString FromUTF8(std::string_view s); ///@} ///@{ @@ -1955,11 +1985,15 @@ public: The overload taking @c std::string is only available starting with wxWidgets 3.1.1. + The overload taking @c std::string_view is only available starting with + wxWidgets 3.3.0 and requires the consumer application to use C++17. + @since 2.8.9 */ static wxString FromUTF8Unchecked(const char* s); static wxString FromUTF8Unchecked(const char* s, size_t len); static wxString FromUTF8Unchecked(const std::string& s); + static wxString FromUTF8Unchecked(std::string_view s); ///@} }; diff --git a/tests/strings/stdstrings.cpp b/tests/strings/stdstrings.cpp index 62aa30721b..a87f6962ef 100644 --- a/tests/strings/stdstrings.cpp +++ b/tests/strings/stdstrings.cpp @@ -657,3 +657,38 @@ TEST_CASE("StdString::Algo", "[stdstring]") std::reverse(s.begin(), s.end()); CHECK( s == "BA" ); } + +#ifdef wxHAS_STD_STRING_VIEW +TEST_CASE("StdString::View", "[stdstring]") +{ + std::string strStd("std::string value"); + std::wstring strStdWide(L"std::wstring value"); + + std::string_view strStdView(strStd); + std::wstring_view strStdWideView(strStdWide); + + wxString s1(strStdView); + CHECK( s1 == "std::string value" ); + + wxString s2(strStdWideView); + CHECK( s2 == "std::wstring value" ); + + wxString s3; + s3 = strStdView; + CHECK( s3 == "std::string value" ); + s3 = strStdWideView; + CHECK( s3 == "std::wstring value" ); + + std::string strUTF("\xF0\x9F\x90\xB1\0\xE7\x8C\xAB", 9); /* U+1F431 U+0000 U+732B */ + std::string_view strViewUTF(strUTF); + + wxString wxstrUTF = wxString::FromUTF8(strViewUTF); + CHECK( wxstrUTF.ToStdString(wxConvUTF8) == strUTF ); + CHECK( wxstrUTF.utf8_string() == strUTF ); + + std::string strInvalidUTF("xyz\0\xFF", 5); /* an invalid UTF-8 sequence */ + std::string_view strViewInvalidUTF(strInvalidUTF); + + CHECK( "" == wxString::FromUTF8(strViewInvalidUTF) ); +} +#endif