Use std::string_view where possible

Unfortunately, MSVC cannot deduce template parameters properly where
`const std::basic_string_view<...>` is the parameter. It requires
explicit type cast or explicit template type specification. Which kind
of voids the whole purpose of using std::basic_string_view to make the
client code simpler.

Example: https://gist.github.com/rozmansi/493911be70bdac08dc6826c976c5bbe4
Signed-off-by: Simon Rozman <simon@rozman.si>
This commit is contained in:
Simon Rozman 2023-12-14 16:58:20 +01:00
parent da9dcc9c1a
commit f5bce32d06
5 changed files with 1265 additions and 256 deletions

View File

@ -20,6 +20,8 @@
#include <map> #include <map>
#include <memory> #include <memory>
#include <stdexcept> #include <stdexcept>
#include <string_view>
#include <string>
#include <vector> #include <vector>
#ifdef _WIN32 #ifdef _WIN32
@ -286,10 +288,10 @@ namespace stdex
/// \param[in,out] dst String to append to /// \param[in,out] dst String to append to
/// \param[in] src Source string /// \param[in] src Source string
/// ///
template<class _Traits_dst = std::char_traits<char>, class _Alloc_dst = std::allocator<char>, class _Traits_src = std::char_traits<char>, class _Alloc_src = std::allocator<char>> template<class _Traits_dst = std::char_traits<char>, class _Alloc_dst = std::allocator<char>>
void url_unescape( void url_unescape(
_Inout_ std::basic_string<char, _Traits_dst, _Alloc_dst>& dst, _Inout_ std::basic_string<char, _Traits_dst, _Alloc_dst>& dst,
_In_ const std::basic_string<char, _Traits_src, _Alloc_src>& src) _In_ const std::string_view src)
{ {
url_unescape(dst, src.data(), src.size()); url_unescape(dst, src.data(), src.size());
} }
@ -365,10 +367,10 @@ namespace stdex
/// \param[in,out] dst String to append to /// \param[in,out] dst String to append to
/// \param[in] src Source string /// \param[in] src Source string
/// ///
template<class _Traits_dst = std::char_traits<char>, class _Alloc_dst = std::allocator<char>, class _Traits_src = std::char_traits<char>, class _Alloc_src = std::allocator<char>> template<class _Traits_dst = std::char_traits<char>, class _Alloc_dst = std::allocator<char>>
void url_escape( void url_escape(
_Inout_ std::basic_string<char, _Traits_dst, _Alloc_dst>& dst, _Inout_ std::basic_string<char, _Traits_dst, _Alloc_dst>& dst,
_In_ const std::basic_string<char, _Traits_src, _Alloc_src>& src) _In_ const std::string_view src)
{ {
url_escape(dst, src.data(), src.size()); url_escape(dst, src.data(), src.size());
} }
@ -1678,13 +1680,13 @@ namespace stdex
if (m_condition_start.match(source, i, num_chars)) { if (m_condition_start.match(source, i, num_chars)) {
auto condition_src(replace_entities(source + m_condition_start.condition.start, m_condition_start.condition.size())); auto condition_src(replace_entities(source + m_condition_start.condition.start, m_condition_start.condition.size()));
if (!stdex::strcmp(condition_src.c_str(), "CDATA")) if (condition_src == "CDATA")
m_is_cdata = true; m_is_cdata = true;
else if (!stdex::strcmp(condition_src.c_str(), "RCDATA")) else if (condition_src == "RCDATA")
m_is_rcdata = true; m_is_rcdata = true;
if (m_num_invalid_conditions) if (m_num_invalid_conditions)
m_num_invalid_conditions++; m_num_invalid_conditions++;
else if (!stdex::strcmp(condition_src.c_str(), "IGNORE")) else if (condition_src == "IGNORE")
m_num_invalid_conditions++; m_num_invalid_conditions++;
else else
m_num_valid_conditions++; m_num_valid_conditions++;
@ -1776,7 +1778,7 @@ namespace stdex
str.reserve(content.charset.size()); str.reserve(content.charset.size());
for (size_t j = content.charset.start; j < content.charset.end; ++j) for (size_t j = content.charset.start; j < content.charset.end; ++j)
str.push_back(static_cast<char>(source[j])); str.push_back(static_cast<char>(source[j]));
m_charset = stdex::charset_from_name(str.c_str()); m_charset = stdex::charset_from_name(str);
} }
} }
} }

View File

@ -11,6 +11,7 @@
#include "string.hpp" #include "string.hpp"
#include <string.h> #include <string.h>
#include <exception> #include <exception>
#include <string_view>
#include <string> #include <string>
namespace stdex namespace stdex
@ -229,7 +230,7 @@ namespace stdex
skip_lcub_rcub = (skip & sgml_lcub_rcub) == 0, skip_lcub_rcub = (skip & sgml_lcub_rcub) == 0,
skip_lsqb_rsqb = (skip & sgml_lsqb_rsqb) == 0; skip_lsqb_rsqb = (skip & sgml_lsqb_rsqb) == 0;
size_t j = wcsnlen(dst, count_dst); size_t j = strnlen(dst, count_dst);
count_src = strnlen(src, count_src); count_src = strnlen(src, count_src);
for (size_t i = 0; i < count_src;) { for (size_t i = 0; i < count_src;) {
if (src[i] == '&') { if (src[i] == '&') {
@ -410,7 +411,7 @@ namespace stdex
_In_ const mapping<size_t>& offset = mapping<size_t>(0, 0), _In_ const mapping<size_t>& offset = mapping<size_t>(0, 0),
_Inout_opt_ mapping_vector<size_t>* map = nullptr) _Inout_opt_ mapping_vector<size_t>* map = nullptr)
{ {
return sgml2str(src.c_str(), src.size(), skip, offset, map); return sgml2str(src.data(), src.size(), skip, offset, map);
} }
/// \cond internal /// \cond internal
@ -471,7 +472,7 @@ namespace stdex
do_lcub_rcub = (what & sgml_lcub_rcub) == 0, do_lcub_rcub = (what & sgml_lcub_rcub) == 0,
do_lsqb_rsqb = (what & sgml_lsqb_rsqb) == 0; do_lsqb_rsqb = (what & sgml_lsqb_rsqb) == 0;
count_src = wcsnlen(src, count_src); count_src = strnlen(src, count_src);
dst.reserve(dst.size() + count_src); dst.reserve(dst.size() + count_src);
for (size_t i = 0; i < count_src;) { for (size_t i = 0; i < count_src;) {
size_t n = glyphlen(src + i, count_src - i); size_t n = glyphlen(src + i, count_src - i);
@ -552,12 +553,13 @@ namespace stdex
/// \param[in] src Unicode string /// \param[in] src Unicode string
/// \param[in] what Bitwise flag of stdex::sgml_* constants that force extra characters otherwise not converted to SGML /// \param[in] what Bitwise flag of stdex::sgml_* constants that force extra characters otherwise not converted to SGML
/// ///
inline void str2sgmlcat( template <class _Traits = std::char_traits<char>, class _Ax = std::allocator<char>>
_Inout_ std::string& dst, void str2sgmlcat(
_In_ const std::wstring& src, _Inout_ std::basic_string<char, _Traits, _Ax>& dst,
_In_ const std::wstring_view src,
_In_ int what = 0) _In_ int what = 0)
{ {
str2sgmlcat(dst, src.c_str(), src.size(), what); str2sgmlcat(dst, src.data(), src.size(), what);
} }
/// ///
@ -595,7 +597,7 @@ namespace stdex
do_lsqb_rsqb = (what & sgml_lsqb_rsqb) == 0; do_lsqb_rsqb = (what & sgml_lsqb_rsqb) == 0;
size_t j = strnlen(dst, count_dst); size_t j = strnlen(dst, count_dst);
count_src = wcsnlen(src, count_src); count_src = strnlen(src, count_src);
for (size_t i = 0; i < count_src;) { for (size_t i = 0; i < count_src;) {
size_t n = glyphlen(src + i, count_src - i); size_t n = glyphlen(src + i, count_src - i);
if (n == 1 && if (n == 1 &&
@ -716,9 +718,10 @@ namespace stdex
/// \param[in] src Unicode string /// \param[in] src Unicode string
/// \param[in] what Bitwise flag of stdex::sgml_* constants that force extra characters otherwise not converted to SGML /// \param[in] what Bitwise flag of stdex::sgml_* constants that force extra characters otherwise not converted to SGML
/// ///
inline void str2sgmlcpy( template <class _Traits = std::char_traits<char>, class _Ax = std::allocator<char>>
_Inout_ std::string& dst, void str2sgmlcpy(
_In_ const std::wstring& src, _Inout_ std::basic_string<char, _Traits, _Ax>& dst,
_In_ const std::wstring_view src,
_In_ int what = 0) _In_ int what = 0)
{ {
str2sgmlcpy(dst, src.data(), src.size(), what); str2sgmlcpy(dst, src.data(), src.size(), what);
@ -773,9 +776,9 @@ namespace stdex
/// \return SGML string /// \return SGML string
/// ///
inline std::string str2sgml( inline std::string str2sgml(
_In_ const std::wstring& src, _In_ const std::wstring_view src,
_In_ int what = 0) _In_ int what = 0)
{ {
return str2sgml(src.c_str(), src.size(), what); return str2sgml(src.data(), src.size(), what);
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -22,6 +22,7 @@
#endif #endif
#include <regex> #include <regex>
#include <stdexcept> #include <stdexcept>
#include <string_view>
#include <string> #include <string>
#if defined(_WIN32) #if defined(_WIN32)
@ -81,6 +82,11 @@ namespace stdex
/// ///
using sys_string = sstring; using sys_string = sstring;
///
/// String view for system functions
///
using sstring_view = std::basic_string_view<stdex::schar_t, std::char_traits<stdex::schar_t>>;
/// ///
/// Regular expressions for system strings /// Regular expressions for system strings
/// ///

View File

@ -72,7 +72,7 @@ namespace stdex
struct charset_less { struct charset_less {
bool operator()(_In_z_ const char* a, _In_z_ const char* b) const bool operator()(_In_z_ const char* a, _In_z_ const char* b) const
{ {
return stdex::stricmp(a, b) < 0; return stricmp(a, b) < 0;
} }
}; };
static const std::map<const char*, charset_id, charset_less> charsets = { static const std::map<const char*, charset_id, charset_less> charsets = {
@ -172,7 +172,7 @@ namespace stdex
_In_reads_or_z_opt_(count_src) const T_from* src, _In_ size_t count_src) _In_reads_or_z_opt_(count_src) const T_from* src, _In_ size_t count_src)
{ {
_Assume_(src || !count_src); _Assume_(src || !count_src);
count_src = stdex::strnlen<T_from>(src, count_src); count_src = strnlen<T_from>(src, count_src);
if (!count_src) _Unlikely_ if (!count_src) _Unlikely_
return; return;
@ -511,7 +511,7 @@ namespace stdex
#endif #endif
inline void strcat( inline void strcat(
_Inout_ std::wstring& dst, _Inout_ std::wstring& dst,
_In_ const std::string& src, _In_ const std::string_view src,
_In_ charset_id charset = charset_id::system) _In_ charset_id charset = charset_id::system)
{ {
strcat(dst, src.data(), src.size(), charset); strcat(dst, src.data(), src.size(), charset);
@ -520,7 +520,7 @@ namespace stdex
_Deprecated_("Use stdex::strcat") _Deprecated_("Use stdex::strcat")
inline void str2wstr( inline void str2wstr(
_Inout_ std::wstring& dst, _Inout_ std::wstring& dst,
_In_ const std::string& src, _In_ const std::string_view src,
_In_ charset_id charset = charset_id::system) _In_ charset_id charset = charset_id::system)
{ {
strcat(dst, src, charset); strcat(dst, src, charset);
@ -562,7 +562,7 @@ namespace stdex
#endif #endif
inline void strcpy( inline void strcpy(
_Inout_ std::wstring& dst, _Inout_ std::wstring& dst,
_In_ const std::string& src, _In_ const std::string_view src,
_In_ charset_id charset = charset_id::system) _In_ charset_id charset = charset_id::system)
{ {
strcpy(dst, src.data(), src.size(), charset); strcpy(dst, src.data(), src.size(), charset);
@ -627,10 +627,10 @@ namespace stdex
_Deprecated_("For better performance, consider a reusable charset_encoder") _Deprecated_("For better performance, consider a reusable charset_encoder")
#endif #endif
inline std::wstring str2wstr( inline std::wstring str2wstr(
_In_ const std::string& src, _In_ const std::string_view src,
_In_ charset_id charset = charset_id::system) _In_ charset_id charset = charset_id::system)
{ {
return str2wstr(src.c_str(), src.size(), charset); return str2wstr(src.data(), src.size(), charset);
} }
/// ///
@ -677,16 +677,16 @@ namespace stdex
#endif #endif
inline void strcat( inline void strcat(
_Inout_ std::string& dst, _Inout_ std::string& dst,
_In_ const std::wstring& src, _In_ const std::wstring_view src,
_In_ charset_id charset = charset_id::system) _In_ charset_id charset = charset_id::system)
{ {
strcat(dst, src.c_str(), src.size(), charset); strcat(dst, src.data(), src.size(), charset);
} }
_Deprecated_("Use stdex::strcat") _Deprecated_("Use stdex::strcat")
inline void wstr2str( inline void wstr2str(
_Inout_ std::string& dst, _Inout_ std::string& dst,
_In_ const std::wstring& src, _In_ const std::wstring_view src,
_In_ charset_id charset = charset_id::system) _In_ charset_id charset = charset_id::system)
{ {
strcat(dst, src, charset); strcat(dst, src, charset);
@ -728,7 +728,7 @@ namespace stdex
#endif #endif
inline void strcpy( inline void strcpy(
_Inout_ std::string& dst, _Inout_ std::string& dst,
_In_ const std::wstring& src, _In_ const std::wstring_view src,
_In_ charset_id charset = charset_id::system) _In_ charset_id charset = charset_id::system)
{ {
strcpy(dst, src.data(), src.size(), charset); strcpy(dst, src.data(), src.size(), charset);
@ -793,10 +793,10 @@ namespace stdex
_Deprecated_("For better performance, consider a reusable charset_encoder") _Deprecated_("For better performance, consider a reusable charset_encoder")
#endif #endif
inline std::string wstr2str( inline std::string wstr2str(
_In_ const std::wstring& src, _In_ const std::wstring_view src,
_In_ charset_id charset = charset_id::system) _In_ charset_id charset = charset_id::system)
{ {
return wstr2str(src.c_str(), src.size(), charset); return wstr2str(src.data(), src.size(), charset);
} }
#ifdef _WIN32 #ifdef _WIN32
@ -814,7 +814,7 @@ namespace stdex
_Inout_ std::basic_string<wchar_t, _Traits, _Alloc>& dst, _Inout_ std::basic_string<wchar_t, _Traits, _Alloc>& dst,
_In_reads_or_z_opt_(count_src) const wchar_t* src, _In_ size_t count_src) _In_reads_or_z_opt_(count_src) const wchar_t* src, _In_ size_t count_src)
{ {
count_src = stdex::strnlen(src, count_src); count_src = strnlen(src, count_src);
size_t count_dst = dst.size(); size_t count_dst = dst.size();
dst.resize(count_dst + count_src); dst.resize(count_dst + count_src);
_Assume_(count_src + 1 < INT_MAX); _Assume_(count_src + 1 < INT_MAX);
@ -852,10 +852,10 @@ namespace stdex
/// ///
/// \return Number of code units excluding zero terminator in the dst string after the operation. /// \return Number of code units excluding zero terminator in the dst string after the operation.
/// ///
template <class _Traits_dst = std::char_traits<wchar_t>, class _Alloc_dst = std::allocator<wchar_t>, class _Traits_src = std::char_traits<wchar_t>, class _Alloc_src = std::allocator<wchar_t>> template <class _Traits_dst = std::char_traits<wchar_t>, class _Alloc_dst = std::allocator<wchar_t>>
size_t normalizecat( size_t normalizecat(
_Inout_ std::basic_string<wchar_t, _Traits_dst, _Alloc_dst>& dst, _Inout_ std::basic_string<wchar_t, _Traits_dst, _Alloc_dst>& dst,
_In_ const std::basic_string<wchar_t, _Traits_src, _Alloc_src>& src) _In_ const std::wstring_view src)
{ {
return normalizecat(dst, src.data(), src.size()); return normalizecat(dst, src.data(), src.size());
} }
@ -902,10 +902,10 @@ namespace stdex
/// ///
/// \return Number of code units excluding zero terminator in the dst string after the operation. /// \return Number of code units excluding zero terminator in the dst string after the operation.
/// ///
template <class _Traits_dst = std::char_traits<wchar_t>, class _Alloc_dst = std::allocator<wchar_t>, class _Traits_src = std::char_traits<wchar_t>, class _Alloc_src = std::allocator<wchar_t>> template <class _Traits_dst = std::char_traits<wchar_t>, class _Alloc_dst = std::allocator<wchar_t>>
size_t normalize( size_t normalize(
_Inout_ std::basic_string<wchar_t, _Traits_dst, _Alloc_dst>& dst, _Inout_ std::basic_string<wchar_t, _Traits_dst, _Alloc_dst>& dst,
_In_ const std::basic_string<wchar_t, _Traits_src, _Alloc_src>& src) _In_ const std::wstring_view src)
{ {
return normalize(dst, src.data(), src.size()); return normalize(dst, src.data(), src.size());
} }
@ -947,8 +947,7 @@ namespace stdex
/// ///
/// \return Normalized string /// \return Normalized string
/// ///
template <class _Traits = std::char_traits<wchar_t>, class _Alloc = std::allocator<wchar_t>> inline std::wstring normalize(_In_ const std::wstring_view src)
std::wstring normalize(_In_ const std::basic_string<wchar_t, _Traits, _Alloc>& src)
{ {
std::wstring dst; std::wstring dst;
normalizecat(dst, src.data(), src.size()); normalizecat(dst, src.data(), src.size());