Simplify and unify template parameter naming

Signed-off-by: Simon Rozman <simon@rozman.si>
This commit is contained in:
Simon Rozman 2023-12-18 17:52:30 +01:00
parent f5bce32d06
commit 37891e8a2a
15 changed files with 614 additions and 583 deletions

View File

@ -66,8 +66,8 @@ namespace stdex
/// \param[in] size Length of `data` in bytes
/// \param[in] is_last Is this the last block of data?
///
template<class _Elem, class _Traits, class _Ax>
void encode(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &out, _In_bytecount_(size) const void *data, _In_ size_t size, _In_opt_ bool is_last = true)
template<class T, class TR, class AX>
void encode(_Inout_ std::basic_string<T, TR, AX> &out, _In_bytecount_(size) const void *data, _In_ size_t size, _In_opt_ bool is_last = true)
{
_Assume_(data || !size);
@ -118,8 +118,8 @@ namespace stdex
///
/// Encodes one complete internal buffer of data
///
template<class _Elem, class _Traits, class _Ax>
void encode(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &out)
template<class T, class TR, class AX>
void encode(_Inout_ std::basic_string<T, TR, AX> &out)
{
out += base64_enc_lookup[ m_buf[0] >> 2 ];
out += base64_enc_lookup[((m_buf[0] << 4) | (m_buf[1] >> 4)) & 0x3f];
@ -130,8 +130,8 @@ namespace stdex
///
/// Encodes partial internal buffer of data
///
template<class _Elem, class _Traits, class _Ax>
void encode(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &out, _In_ size_t size)
template<class T, class TR, class AX>
void encode(_Inout_ std::basic_string<T, TR, AX> &out, _In_ size_t size)
{
if (size > 0) {
out += base64_enc_lookup[m_buf[0] >> 2];
@ -287,8 +287,8 @@ namespace stdex
/// \param[in] data Data to decode
/// \param[in] size Length of `data` in bytes
///
template<class _Ty, class _Ax, class _Tchr>
void decode(_Inout_ std::vector<_Ty, _Ax> &out, _Out_ bool &is_last, _In_z_count_(size) const _Tchr *data, _In_ size_t size)
template<class T_to, class AX, class T_from>
void decode(_Inout_ std::vector<T_to, AX> &out, _Out_ bool &is_last, _In_z_count_(size) const T_from *data, _In_ size_t size)
{
is_last = false;
@ -342,15 +342,15 @@ namespace stdex
///
/// Decodes one complete internal buffer of data
///
template<class _Ty, class _Ax>
size_t decode(_Inout_ std::vector<_Ty, _Ax> &out)
template<class T, class AX>
size_t decode(_Inout_ std::vector<T, AX> &out)
{
m_num = 0;
out.push_back((_Ty)(((m_buf[0] << 2) | (m_buf[1] >> 4)) & 0xff));
out.push_back((T)(((m_buf[0] << 2) | (m_buf[1] >> 4)) & 0xff));
if (m_buf[2] < 64) {
out.push_back((_Ty)(((m_buf[1] << 4) | (m_buf[2] >> 2)) & 0xff));
out.push_back((T)(((m_buf[1] << 4) | (m_buf[2] >> 2)) & 0xff));
if (m_buf[3] < 64) {
out.push_back((_Ty)(((m_buf[2] << 6) | m_buf[3]) & 0xff));
out.push_back((T)(((m_buf[2] << 6) | m_buf[3]) & 0xff));
return 3;
} else
return 2;

View File

@ -323,12 +323,12 @@ namespace stdex {
if (hour) *hour = static_cast<uint8_t>(u);
}
template<class _Traits = std::char_traits<char>, class _Ax = std::allocator<char>>
static std::basic_string<char, _Traits, _Ax> to_str(_In_ const time_point tp, _In_z_ const char* format, _In_opt_ locale_t locale)
template<class TR = std::char_traits<char>, class AX = std::allocator<char>>
static std::basic_string<char, TR, AX> to_str(_In_ const time_point tp, _In_z_ const char* format, _In_opt_ locale_t locale)
{
struct tm date;
to_system(tp, date);
std::basic_string<char, _Traits, _Ax> str;
std::basic_string<char, TR, AX> str;
char stack_buffer[1024 / sizeof(char)];
size_t n;
#if _WIN32
@ -356,12 +356,12 @@ namespace stdex {
}
}
template<class _Traits = std::char_traits<wchar_t>, class _Ax = std::allocator<wchar_t>>
static std::basic_string<wchar_t, _Traits, _Ax> to_str(_In_ const time_point tp, _In_z_ const wchar_t* format, _In_opt_ locale_t locale)
template<class TR = std::char_traits<wchar_t>, class AX = std::allocator<wchar_t>>
static std::basic_string<wchar_t, TR, AX> to_str(_In_ const time_point tp, _In_z_ const wchar_t* format, _In_opt_ locale_t locale)
{
struct tm date;
to_system(tp, date);
std::basic_string<wchar_t, _Traits, _Ax> str;
std::basic_string<wchar_t, TR, AX> str;
wchar_t stack_buffer[1024 / sizeof(wchar_t)];
size_t n;
#if _WIN32
@ -389,8 +389,8 @@ namespace stdex {
}
}
template<class _Traits = std::char_traits<char>, class _Ax = std::allocator<char>>
static std::basic_string<char, _Traits, _Ax> to_rfc822(_In_ const time_point tp)
template<class TR = std::char_traits<char>, class AX = std::allocator<char>>
static std::basic_string<char, TR, AX> to_rfc822(_In_ const time_point tp)
{
return to_str(tp, "%a, %d %b %Y %H:%M:%S GMT", locale_C.get());
}

View File

@ -185,7 +185,7 @@
#endif
#ifndef _WIN32
template <typename T, size_t N>
template <class T, size_t N>
size_t _countof(const T (&arr)[N])
{
return std::extent<T[N]>::value;

View File

@ -34,8 +34,8 @@ namespace stdex
/// \param[in] data Data to encode
/// \param[in] size Length of `data` in bytes
///
template<class _Elem, class _Traits, class _Ax>
void encode(_Inout_ std::basic_string<_Elem, _Traits, _Ax> &out, _In_bytecount_(size) const void *data, _In_ size_t size)
template<class T, class TR, class AX>
void encode(_Inout_ std::basic_string<T, TR, AX> &out, _In_bytecount_(size) const void *data, _In_ size_t size)
{
_Assume_(data || !size);
@ -93,8 +93,8 @@ namespace stdex
/// \param[in] data Data to decode
/// \param[in] size Length of `data` in bytes
///
template<class _Ty, class _Ax, class _Tchr>
void decode(_Inout_ std::vector<_Ty, _Ax> &out, _Out_ bool &is_last, _In_z_count_(size) const _Tchr *data, _In_ size_t size)
template<class T_to, class AX, class T_from>
void decode(_Inout_ std::vector<T_to, AX> &out, _Out_ bool &is_last, _In_z_count_(size) const T_from *data, _In_ size_t size)
{
is_last = false;

View File

@ -39,9 +39,9 @@ namespace stdex
/// \param[in] src Source string
/// \param[in] num_chars Code unit limit in string `src`
///
template<class _Traits = std::char_traits<char>, class _Alloc = std::allocator<char>>
template<class TR = std::char_traits<char>, class AX = std::allocator<char>>
void escape(
_Inout_ std::basic_string<char, _Traits, _Alloc>& dst,
_Inout_ std::basic_string<char, TR, AX>& dst,
_In_reads_or_z_opt_(num_chars) const char* src, _In_ size_t num_chars)
{
_Assume_(src || !num_chars);
@ -66,9 +66,9 @@ namespace stdex
/// \param[in] src Source string
/// \param[in] num_chars Code unit limit in string `src`
///
template<class _Traits = std::char_traits<wchar_t>, class _Alloc = std::allocator<wchar_t>>
template<class TR = std::char_traits<wchar_t>, class AX = std::allocator<wchar_t>>
void escape(
_Inout_ std::basic_string<wchar_t, _Traits, _Alloc>& dst,
_Inout_ std::basic_string<wchar_t, TR, AX>& dst,
_In_reads_or_z_opt_(num_chars) const wchar_t* src, _In_ size_t num_chars)
{
_Assume_(src || !num_chars);
@ -92,12 +92,12 @@ namespace stdex
/// \param[in,out] dst String to append to
/// \param[in] src Source string
///
template<class _Elem, size_t _Size, class _Traits = std::char_traits<_Elem>, class _Alloc = std::allocator<_Elem>>
template<class T, size_t N, class TR = std::char_traits<T>, class AX = std::allocator<T>>
void escape(
_Inout_ std::basic_string<_Elem, _Traits, _Alloc>& dst,
_In_ const _Elem (&src)[_Size])
_Inout_ std::basic_string<T, TR, AX>& dst,
_In_ const T (&src)[N])
{
escape(dst, src, _Size);
escape(dst, src, N);
}
///
@ -106,10 +106,10 @@ namespace stdex
/// \param[in,out] dst String to append to
/// \param[in] src Source string
///
template<class _Elem, class _Traits_dst = std::char_traits<_Elem>, class _Alloc_dst = std::allocator<_Elem>, class _Traits_src = std::char_traits<_Elem>, class _Alloc_src = std::allocator<_Elem>>
template<class T, class TR_dst = std::char_traits<T>, class AX_dst = std::allocator<T>, class TR_src = std::char_traits<T>, class AX_src = std::allocator<T>>
void escape(
_Inout_ std::basic_string<_Elem, _Traits_dst, _Alloc_dst>& dst,
_In_ const std::basic_string<_Elem, _Traits_src, _Alloc_src>& src)
_Inout_ std::basic_string<T, TR_dst, AX_dst>& dst,
_In_ const std::basic_string<T, TR_src, AX_src>& src)
{
escape(dst, src.data(), src.size());
}
@ -120,8 +120,8 @@ namespace stdex
/// \param[in,out] dst String to append to
/// \param[in] chr Source character
///
template<class _Traits = std::char_traits<char>, class _Alloc = std::allocator<char>>
void escape_min(_Inout_ std::basic_string<char, _Traits, _Alloc>& dst, _In_ char chr)
template<class TR = std::char_traits<char>, class AX = std::allocator<char>>
void escape_min(_Inout_ std::basic_string<char, TR, AX>& dst, _In_ char chr)
{
switch (chr) {
case '&': dst += "&amp;"; break;
@ -138,8 +138,8 @@ namespace stdex
/// \param[in,out] dst String to append to
/// \param[in] chr Source character
///
template<class _Traits = std::char_traits<wchar_t>, class _Alloc = std::allocator<wchar_t>>
void escape_min(_Inout_ std::basic_string<wchar_t, _Traits, _Alloc>& dst, _In_ wchar_t chr)
template<class TR = std::char_traits<wchar_t>, class AX = std::allocator<wchar_t>>
void escape_min(_Inout_ std::basic_string<wchar_t, TR, AX>& dst, _In_ wchar_t chr)
{
switch (chr) {
case L'&': dst += L"&amp;"; break;
@ -157,9 +157,9 @@ namespace stdex
/// \param[in] src Source string
/// \param[in] num_chars Code unit limit in string `src`
///
template<class _Traits = std::char_traits<char>, class _Alloc = std::allocator<char>>
template<class TR = std::char_traits<char>, class AX = std::allocator<char>>
void escape_min(
_Inout_ std::basic_string<char, _Traits, _Alloc>& dst,
_Inout_ std::basic_string<char, TR, AX>& dst,
_In_reads_or_z_opt_(num_chars) const char* src, _In_ size_t num_chars)
{
_Assume_(src || !num_chars);
@ -181,9 +181,9 @@ namespace stdex
/// \param[in] src Source string
/// \param[in] num_chars Code unit limit in string `src`
///
template<class _Traits = std::char_traits<wchar_t>, class _Alloc = std::allocator<wchar_t>>
template<class TR = std::char_traits<wchar_t>, class AX = std::allocator<wchar_t>>
void escape_min(
_Inout_ std::basic_string<wchar_t, _Traits, _Alloc>& dst,
_Inout_ std::basic_string<wchar_t, TR, AX>& dst,
_In_reads_or_z_opt_(num_chars) const wchar_t* src, _In_ size_t num_chars)
{
_Assume_(src || !num_chars);
@ -204,12 +204,12 @@ namespace stdex
/// \param[in,out] dst String to append to
/// \param[in] src Source string
///
template<class _Elem, size_t _Size, class _Traits = std::char_traits<_Elem>, class _Alloc = std::allocator<_Elem>>
template<class T, size_t N, class TR = std::char_traits<T>, class AX = std::allocator<T>>
void escape_min(
_Inout_ std::basic_string<_Elem, _Traits, _Alloc>& dst,
_In_ const _Elem (&src)[_Size])
_Inout_ std::basic_string<T, TR, AX>& dst,
_In_ const T (&src)[N])
{
escape_min(dst, src, _Size);
escape_min(dst, src, N);
}
///
@ -218,10 +218,10 @@ namespace stdex
/// \param[in,out] dst String to append to
/// \param[in] src Source string
///
template<class _Elem, class _Traits_dst = std::char_traits<_Elem>, class _Alloc_dst = std::allocator<_Elem>, class _Traits_src = std::char_traits<_Elem>, class _Alloc_src = std::allocator<_Elem>>
template<class T, class TR_dst = std::char_traits<T>, class AX_dst = std::allocator<T>, class TR_src = std::char_traits<T>, class AX_src = std::allocator<T>>
void escape_min(
_Inout_ std::basic_string<_Elem, _Traits_dst, _Alloc_dst>& dst,
_In_ const std::basic_string<_Elem, _Traits_src, _Alloc_src>& src)
_Inout_ std::basic_string<T, TR_dst, AX_dst>& dst,
_In_ const std::basic_string<T, TR_src, AX_src>& src)
{
escape_min(dst, src.data(), src.size());
}
@ -233,9 +233,9 @@ namespace stdex
/// \param[in] src Source string
/// \param[in] num_chars Code unit limit in string `src`
///
template<class _Traits = std::char_traits<char>, class _Alloc = std::allocator<char>>
template<class TR = std::char_traits<char>, class AX = std::allocator<char>>
void url_unescape(
_Inout_ std::basic_string<char, _Traits, _Alloc>& dst,
_Inout_ std::basic_string<char, TR, AX>& dst,
_In_reads_or_z_opt_(num_chars) const char* src, _In_ size_t num_chars)
{
_Assume_(src || !num_chars);
@ -274,12 +274,12 @@ namespace stdex
/// \param[in,out] dst String to append to
/// \param[in] src Source string
///
template<size_t _Size, class _Traits = std::char_traits<char>, class _Alloc = std::allocator<char>>
template<size_t N, class TR = std::char_traits<char>, class AX = std::allocator<char>>
void url_unescape(
_Inout_ std::basic_string<char, _Traits, _Alloc>& dst,
_In_ const char (&src)[_Size])
_Inout_ std::basic_string<char, TR, AX>& dst,
_In_ const char (&src)[N])
{
url_unescape(dst, src, _Size);
url_unescape(dst, src, N);
}
///
@ -288,10 +288,10 @@ namespace stdex
/// \param[in,out] dst String to append to
/// \param[in] src Source string
///
template<class _Traits_dst = std::char_traits<char>, class _Alloc_dst = std::allocator<char>>
template<class TR_dst = std::char_traits<char>, class AX_dst = std::allocator<char>>
void url_unescape(
_Inout_ std::basic_string<char, _Traits_dst, _Alloc_dst>& dst,
_In_ const std::string_view src)
_Inout_ std::basic_string<char, TR_dst, AX_dst>& dst,
_In_ const std::basic_string_view<char, std::char_traits<char>> src)
{
url_unescape(dst, src.data(), src.size());
}
@ -303,9 +303,9 @@ namespace stdex
/// \param[in] src Source string
/// \param[in] num_chars Code unit limit in string `src`
///
template<class _Traits = std::char_traits<char>, class _Alloc = std::allocator<char>>
template<class TR = std::char_traits<char>, class AX = std::allocator<char>>
void url_escape(
_Inout_ std::basic_string<char, _Traits, _Alloc>& dst,
_Inout_ std::basic_string<char, TR, AX>& dst,
_In_reads_or_z_opt_(num_chars) const char* src, _In_ size_t num_chars)
{
_Assume_(src || !num_chars);
@ -353,12 +353,12 @@ namespace stdex
/// \param[in,out] dst String to append to
/// \param[in] src Source string
///
template<size_t _Size, class _Traits = std::char_traits<char>, class _Alloc = std::allocator<char>>
template<size_t N, class TR = std::char_traits<char>, class AX = std::allocator<char>>
void url_escape(
_Inout_ std::basic_string<char, _Traits, _Alloc>& dst,
_In_ const char (&src)[_Size])
_Inout_ std::basic_string<char, TR, AX>& dst,
_In_ const char (&src)[N])
{
url_escape(dst, src, _Size);
url_escape(dst, src, N);
}
///
@ -367,10 +367,10 @@ namespace stdex
/// \param[in,out] dst String to append to
/// \param[in] src Source string
///
template<class _Traits_dst = std::char_traits<char>, class _Alloc_dst = std::allocator<char>>
template<class TR_dst = std::char_traits<char>, class AX_dst = std::allocator<char>>
void url_escape(
_Inout_ std::basic_string<char, _Traits_dst, _Alloc_dst>& dst,
_In_ const std::string_view src)
_Inout_ std::basic_string<char, TR_dst, AX_dst>& dst,
_In_ const std::basic_string_view<char, std::char_traits<char>> src)
{
url_escape(dst, src.data(), src.size());
}
@ -382,10 +382,10 @@ namespace stdex
/// \param[in] src Source string
/// \param[in] num_chars Code unit limit in string `src`
///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Alloc = std::allocator<_Elem>>
template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
void css_unescape(
_Inout_ std::basic_string<_Elem, _Traits, _Alloc>& dst,
_In_reads_or_z_opt_(num_chars) const _Elem* src, _In_ size_t num_chars)
_Inout_ std::basic_string<T, TR, AX>& dst,
_In_reads_or_z_opt_(num_chars) const T* src, _In_ size_t num_chars)
{
_Assume_(src || !num_chars);
for (size_t i = 0; i < num_chars && src[i];) {
@ -430,7 +430,7 @@ namespace stdex
else break;
}
dst += static_cast<_Elem>(chr);
dst += static_cast<T>(chr);
if (i < end && src[i] == ' ') {
// Skip space after `\nnnn`.
@ -451,12 +451,12 @@ namespace stdex
/// \param[in,out] dst String to append to
/// \param[in] src Source string
///
template<class _Elem, size_t _Size, class _Traits = std::char_traits<_Elem>, class _Alloc = std::allocator<_Elem>>
template<class T, size_t N, class TR = std::char_traits<T>, class AX = std::allocator<T>>
void css_unescape(
_Inout_ std::basic_string<_Elem, _Traits, _Alloc>& dst,
_In_ const _Elem (&src)[_Size])
_Inout_ std::basic_string<T, TR, AX>& dst,
_In_ const T (&src)[N])
{
css_unescape(dst, src, _Size);
css_unescape(dst, src, N);
}
///
@ -465,10 +465,10 @@ namespace stdex
/// \param[in,out] dst String to append to
/// \param[in] src Source string
///
template<class _Elem, class _Traits_dst = std::char_traits<_Elem>, class _Alloc_dst = std::allocator<_Elem>, class _Traits_src = std::char_traits<_Elem>, class _Alloc_src = std::allocator<_Elem>>
template<class T, class TR_dst = std::char_traits<T>, class AX_dst = std::allocator<T>, class TR_src = std::char_traits<T>, class AX_src = std::allocator<T>>
void css_unescape(
_Inout_ std::basic_string<_Elem, _Traits_dst, _Alloc_dst>& dst,
_In_ const std::basic_string<_Elem, _Traits_src, _Alloc_src>& src)
_Inout_ std::basic_string<T, TR_dst, AX_dst>& dst,
_In_ const std::basic_string<T, TR_src, AX_src>& src)
{
css_unescape(dst, src.data(), src.size());
}
@ -480,9 +480,9 @@ namespace stdex
/// \param[in] src Source string
/// \param[in] num_chars Code unit limit in string `src`
///
template<class _Traits = std::char_traits<char>, class _Alloc = std::allocator<char>>
template<class TR = std::char_traits<char>, class AX = std::allocator<char>>
void css_escape(
_Inout_ std::basic_string<char, _Traits, _Alloc>& dst,
_Inout_ std::basic_string<char, TR, AX>& dst,
_In_reads_or_z_opt_(num_chars) const char* src, _In_ size_t num_chars)
{
_Assume_(src || !num_chars);
@ -506,9 +506,9 @@ namespace stdex
/// \param[in] src Source string
/// \param[in] num_chars Code unit limit in string `src`
///
template<class _Traits = std::char_traits<wchar_t>, class _Alloc = std::allocator<wchar_t>>
template<class TR = std::char_traits<wchar_t>, class AX = std::allocator<wchar_t>>
void css_escape(
_Inout_ std::basic_string<wchar_t, _Traits, _Alloc>& dst,
_Inout_ std::basic_string<wchar_t, TR, AX>& dst,
_In_reads_or_z_opt_(num_chars) const wchar_t* src, _In_ size_t num_chars)
{
_Assume_(src || !num_chars);
@ -531,12 +531,12 @@ namespace stdex
/// \param[in,out] dst String to append to
/// \param[in] src Source string
///
template<class _Elem, size_t _Size, class _Traits = std::char_traits<_Elem>, class _Alloc = std::allocator<_Elem>>
template<class T, size_t N, class TR = std::char_traits<T>, class AX = std::allocator<T>>
void css_escape(
_Inout_ std::basic_string<_Elem, _Traits, _Alloc>& dst,
_In_ const _Elem (&src)[_Size])
_Inout_ std::basic_string<T, TR, AX>& dst,
_In_ const T (&src)[N])
{
css_escape(dst, src, _Size);
css_escape(dst, src, N);
}
///
@ -545,10 +545,10 @@ namespace stdex
/// \param[in,out] dst String to append to
/// \param[in] src Source string
///
template<class _Elem, class _Traits_dst = std::char_traits<_Elem>, class _Alloc_dst = std::allocator<_Elem>, class _Traits_src = std::char_traits<_Elem>, class _Alloc_src = std::allocator<_Elem>>
template<class T, class TR_dst = std::char_traits<T>, class AX_dst = std::allocator<T>, class TR_src = std::char_traits<T>, class AX_src = std::allocator<T>>
void css_escape(
_Inout_ std::basic_string<_Elem, _Traits_dst, _Alloc_dst>& dst,
_In_ const std::basic_string<_Elem, _Traits_src, _Alloc_src>& src)
_Inout_ std::basic_string<T, TR_dst, AX_dst>& dst,
_In_ const std::basic_string<T, TR_src, AX_src>& src)
{
css_escape(dst, src.data(), src.size());
}
@ -1581,23 +1581,23 @@ namespace stdex
///
/// HTML entity
///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Alloc = std::allocator<_Elem>>
template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
struct entity
{
stdex::interval<size_t> name; ///< Name position in source
std::basic_string<_Elem, _Traits, _Alloc> value; ///< Entity value
std::basic_string<T, TR, AX> value; ///< Entity value
};
///
/// HTML parser
///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Alloc = std::allocator<_Elem>>
template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
class parser;
///
/// HTML document
///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Alloc = std::allocator<_Elem>>
template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
class document
{
public:
@ -1639,7 +1639,7 @@ namespace stdex
///
/// Parses HTML source code by chunks
///
void append(_In_reads_or_z_opt_(num_chars) const _Elem* source, _In_ size_t num_chars)
void append(_In_reads_or_z_opt_(num_chars) const T* source, _In_ size_t num_chars)
{
_Assume_(source || !num_chars);
m_source.append(source, stdex::strnlen(source, num_chars));
@ -1770,7 +1770,7 @@ namespace stdex
}
if (is_content_type && content_attr) {
// <meta http-equiv="Content-Type" content="..."> found.
stdex::parser::basic_mime_type<_Elem> content;
stdex::parser::basic_mime_type<T> content;
if (content.match(source, content_attr->value.start, content_attr->value.end) &&
content.charset)
{
@ -1814,7 +1814,7 @@ namespace stdex
stdex::strncmp(source + m_tag.attributes[3].name.start, m_tag.attributes[3].name.size(), "SYSTEM", SIZE_MAX) &&
stdex::strncmp(source + m_tag.attributes[3].name.start, m_tag.attributes[3].name.size(), "PUBLIC", SIZE_MAX))
{
std::unique_ptr<entity<_Elem, _Traits, _Alloc>> e(new entity<_Elem, _Traits, _Alloc>());
std::unique_ptr<entity<T, TR, AX>> e(new entity<T, TR, AX>());
e->name = m_tag.attributes[2].name;
e->value = std::move(replace_entities(source + m_tag.attributes[3].name.start, m_tag.attributes[3].name.size()));
m_entities.push_back(std::move(e));
@ -1862,7 +1862,7 @@ namespace stdex
///
/// Parses HTML document source code
///
void assign(_In_reads_or_z_opt_(num_chars) const _Elem* source, _In_ size_t num_chars)
void assign(_In_reads_or_z_opt_(num_chars) const T* source, _In_ size_t num_chars)
{
clear();
append(source, num_chars);
@ -1872,9 +1872,9 @@ namespace stdex
///
/// Returns document HTML source code
///
const std::basic_string<_Elem, _Traits, _Alloc>& source() const { return m_source; }
const std::basic_string<T, TR, AX>& source() const { return m_source; }
friend class parser<_Elem, _Traits, _Alloc>;
friend class parser<T, TR, AX>;
protected:
///
@ -1888,12 +1888,12 @@ namespace stdex
///
/// Replaces entities with their content
///
std::basic_string<_Elem, _Traits, _Alloc> replace_entities(_In_reads_or_z_opt_(num_chars) const _Elem* input, _In_ size_t num_chars) const
std::basic_string<T, TR, AX> replace_entities(_In_reads_or_z_opt_(num_chars) const T* input, _In_ size_t num_chars) const
{
_Assume_(input || !num_chars);
const size_t num_entities = m_entities.size();
const _Elem* source = m_source.data();
std::basic_string<_Elem, _Traits, _Alloc> output;
const T* source = m_source.data();
std::basic_string<T, TR, AX> output;
for (size_t i = 0; i < num_chars && input[i];) {
if (input[i] == '%') {
for (size_t j = 0; j < num_entities; j++) {
@ -1917,7 +1917,7 @@ namespace stdex
}
protected:
std::basic_string<_Elem, _Traits, _Alloc> m_source; ///< Document HTML source code
std::basic_string<T, TR, AX> m_source; ///< Document HTML source code
size_t m_num_parsed; ///< Number of characters already parsed
stdex::charset_id m_charset; ///< Document charset
@ -1926,13 +1926,13 @@ namespace stdex
size_t m_num_invalid_conditions; ///< Number of started invalid conditions
bool m_is_cdata; ///< Inside of CDATA?
bool m_is_rcdata; ///< Inside of RCDATA?
stdex::parser::basic_html_declaration_condition_start<_Elem> m_condition_start;
stdex::parser::basic_html_declaration_condition_end<_Elem> m_condition_end;
stdex::parser::basic_any_cu<_Elem> m_any_char;
std::vector<std::unique_ptr<entity<_Elem, _Traits, _Alloc>>> m_entities; ///< Array of entities
stdex::parser::basic_html_declaration_condition_start<T> m_condition_start;
stdex::parser::basic_html_declaration_condition_end<T> m_condition_end;
stdex::parser::basic_any_cu<T> m_any_char;
std::vector<std::unique_ptr<entity<T, TR, AX>>> m_entities; ///< Array of entities
// Element parsing data
stdex::parser::basic_html_tag<_Elem> m_tag;
stdex::parser::basic_html_tag<T> m_tag;
sequence_store m_sequences; ///< Store of sequences
std::vector<element_start*> m_element_stack; ///< LIFO stack of started elements
bool m_is_special_element; ///< Inside of a special element (<SCRIPT>, <STYLE>, ...)?
@ -1981,7 +1981,7 @@ namespace stdex
data(_data)
{}
template<class _Elem, class _Traits, class _Alloc>
template<class T, class TR, class AX>
friend class parser;
public:
@ -1994,8 +1994,8 @@ namespace stdex
///
/// \returns Number of code units appended
///
template<class _Traits = std::char_traits<char>, class _Alloc = std::allocator<char>>
size_t append_tag(_Inout_ std::basic_string<char, _Traits, _Alloc>& str) const
template<class TR = std::char_traits<char>, class AX = std::allocator<char>>
size_t append_tag(_Inout_ std::basic_string<char, TR, AX>& str) const
{
size_t n = str.size();
// Use %X instead of %p to ommit leading zeros and save space.
@ -2010,8 +2010,8 @@ namespace stdex
///
/// \returns Number of code units appended
///
template<class _Traits = std::char_traits<wchar_t>, class _Alloc = std::allocator<wchar_t>>
size_t append_tag(_Inout_ std::basic_string<wchar_t, _Traits, _Alloc>& str) const
template<class TR = std::char_traits<wchar_t>, class AX = std::allocator<wchar_t>>
size_t append_tag(_Inout_ std::basic_string<wchar_t, TR, AX>& str) const
{
// Use %X instead of %p to ommit leading zeros and save space.
return stdex::appendf(str, L"%c%zX%c", stdex::locale_C.get(), static_cast<wchar_t>(token_tag_start), reinterpret_cast<uintptr_t>(this), static_cast<wchar_t>(token_tag_end));
@ -2062,13 +2062,13 @@ namespace stdex
///
/// Token representing part of HTML text
///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Alloc = std::allocator<_Elem>>
template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
class text_token : public token
{
protected:
text_token(
_In_ token_t type = token_t::complete,
_In_reads_or_z_opt_(num_chars) const _Elem* _text = nullptr, _In_ size_t num_chars = 0,
_In_reads_or_z_opt_(num_chars) const T* _text = nullptr, _In_ size_t num_chars = 0,
_In_ uint32_t _text_type = 0,
_In_opt_ stdex::html::sequence* sequence = nullptr, _In_ uintptr_t data = 0) :
token(type, sequence, data),
@ -2076,10 +2076,10 @@ namespace stdex
text_type(_text_type)
{}
friend class parser<_Elem, _Traits, _Alloc>;
friend class parser<T, TR, AX>;
public:
std::basic_string<_Elem, _Traits, _Alloc> text; ///< Token text
std::basic_string<T, TR, AX> text; ///< Token text
uint32_t text_type; ///< Mask of text_type_flag_t to specify text content
stdex::mapping_vector<size_t> mapping; ///< Mapping between source and text positions
};
@ -2087,13 +2087,13 @@ namespace stdex
///
/// Token representing start HTML tag
///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Alloc = std::allocator<_Elem>>
class starting_token : public text_token<_Elem, _Traits, _Alloc>
template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
class starting_token : public text_token<T, TR, AX>
{
protected:
starting_token(
_In_reads_or_z_opt_(num_chars_text) const _Elem* _text = nullptr, _In_ size_t num_chars_text = 0,
_In_reads_or_z_opt_(num_chars_name) const _Elem* _name = nullptr, _In_ size_t num_chars_name = 0,
_In_reads_or_z_opt_(num_chars_text) const T* _text = nullptr, _In_ size_t num_chars_text = 0,
_In_reads_or_z_opt_(num_chars_name) const T* _name = nullptr, _In_ size_t num_chars_name = 0,
_In_ uint32_t text_type = 0,
_In_opt_ stdex::html::sequence* sequence = nullptr,
_In_opt_ stdex::html::sequence* _end_sequence = nullptr,
@ -2103,10 +2103,10 @@ namespace stdex
end_sequence(_end_sequence)
{}
friend class parser<_Elem, _Traits, _Alloc>;
friend class parser<T, TR, AX>;
public:
std::basic_string<_Elem, _Traits, _Alloc> name; ///< Element name allowing later recreation of ending </tag>
std::basic_string<T, TR, AX> name; ///< Element name allowing later recreation of ending </tag>
stdex::html::sequence* end_sequence; ///< Ending tag sequence
};
@ -2122,12 +2122,12 @@ namespace stdex
///
/// HTTP token representing an URL
///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Alloc = std::allocator<_Elem>>
template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
class url_token : public token
{
protected:
url_token(
_In_reads_or_z_opt_(num_chars) const _Elem* _url = nullptr, _In_ size_t num_chars = 0,
_In_reads_or_z_opt_(num_chars) const T* _url = nullptr, _In_ size_t num_chars = 0,
token_url_t _encoding = token_url_t::plain,
_In_opt_ stdex::html::sequence* sequence = nullptr, _In_ uintptr_t data = 0) :
token(token_t::url, sequence, data),
@ -2135,10 +2135,10 @@ namespace stdex
encoding(_encoding)
{}
friend class parser<_Elem, _Traits, _Alloc>;
friend class parser<T, TR, AX>;
public:
std::basic_string<_Elem, _Traits, _Alloc> url; ///< URL
std::basic_string<T, TR, AX> url; ///< URL
token_url_t encoding; ///< URL encoding
};
@ -2154,12 +2154,12 @@ namespace stdex
using inserted_token_list = std::list<inserted_token>;
template<class _Elem, class _Traits, class _Alloc>
template<class T, class TR, class AX>
class parser
{
public:
parser(
_In_ const document<_Elem, _Traits, _Alloc>& document,
_In_ const document<T, TR, AX>& document,
_In_reads_or_z_opt_(num_chars) const stdex::schar_t* url = nullptr, _In_ size_t num_chars = 0,
_In_ bool parse_frames = false, _In_ stdex::progress<size_t>* progress = nullptr) :
m_document(document),
@ -2172,7 +2172,7 @@ namespace stdex
///
/// Parses HTML document
///
text_token<_Elem, _Traits, _Alloc>* parse()
text_token<T, TR, AX>* parse()
{
_Assume_(m_tokens.empty());
@ -2192,7 +2192,7 @@ namespace stdex
/// \param[in,out] source String to append source code to
/// \param[in ] t Document root token
///
static void link(_Inout_ std::basic_string<_Elem, _Traits, _Alloc>& source, _In_ const text_token<_Elem, _Traits, _Alloc>* t)
static void link(_Inout_ std::basic_string<T, TR, AX>& source, _In_ const text_token<T, TR, AX>* t)
{
_Assume_(t);
_Assume_(
@ -2202,7 +2202,7 @@ namespace stdex
t->type == token_t::root);
if (t->text_type & has_tokens) {
const _Elem* root = t->text.data();
const T* root = t->text.data();
for (size_t i = 0, num_chars = t->text.size(); i < num_chars && root[i];) {
_Assume_(root[i] != token_tag_end);
const token* t2 = token::parse_tag(root, i);
@ -2212,10 +2212,10 @@ namespace stdex
case token_t::starting:
case token_t::ending:
case token_t::root:
link(source, dynamic_cast<const text_token<_Elem, _Traits, _Alloc>*>(t2));
link(source, dynamic_cast<const text_token<T, TR, AX>*>(t2));
break;
case token_t::url: {
auto t2_url = dynamic_cast<const url_token<_Elem, _Traits, _Alloc>*>(t2);
auto t2_url = dynamic_cast<const url_token<T, TR, AX>*>(t2);
switch (t2_url->encoding) {
case token_url_t::plain:
source += t2_url->url;
@ -2259,7 +2259,7 @@ namespace stdex
/// \param[in] new_tokens New tokens to add
/// \param[in] from Token from `new_tokens` to start adding at
///
static void start_tokens(_Inout_ std::basic_string<_Elem, _Traits, _Alloc>& source, _Inout_ token_list& active_tokens, _In_ const token_list& new_tokens, _In_ token_list::const_iterator from)
static void start_tokens(_Inout_ std::basic_string<T, TR, AX>& source, _Inout_ token_list& active_tokens, _In_ const token_list& new_tokens, _In_ token_list::const_iterator from)
{
for (; from != new_tokens.cend(); ++from) {
auto t = *from;
@ -2277,7 +2277,7 @@ namespace stdex
///
/// \returns Position in `new_tokens` specifying where the cut was made
///
token_list::const_iterator end_tokens(_Inout_ std::basic_string<_Elem, _Traits, _Alloc>& source, _Inout_ token_list& active_tokens, _In_ const token_list& new_tokens)
token_list::const_iterator end_tokens(_Inout_ std::basic_string<T, TR, AX>& source, _Inout_ token_list& active_tokens, _In_ const token_list& new_tokens)
{
// Skip matching tokens in active_tokens and new_tokens.
token_list::const_iterator i1, i2;
@ -2286,10 +2286,10 @@ namespace stdex
// Got two tokens, where lists don't match anymore, or new_tokens list is out.
// End tokens not relevant anymore in reverse order of starting.
for (auto i = active_tokens.cend(); i != active_tokens.cbegin(); ) {
auto t1 = dynamic_cast<starting_token<_Elem, _Traits, _Alloc>*>(*(--i));
auto t1 = dynamic_cast<starting_token<T, TR, AX>*>(*(--i));
_Assume_(t1 && t1->type == token_t::starting);
std::unique_ptr<text_token<_Elem, _Traits, _Alloc>> t2(new text_token<_Elem, _Traits, _Alloc>(token_t::ending));
std::unique_ptr<text_token<T, TR, AX>> t2(new text_token<T, TR, AX>(token_t::ending));
t2->text.reserve(t1->name.size() + 3);
t2->text += '<';
t2->text += '/';
@ -2320,7 +2320,7 @@ namespace stdex
/// \param[in] after_word `false` if source code is before the word; `true` if after the word
/// \param[in,out] active_tokens Stack of active tokens
///
void append_inserted_tokens(_Inout_ std::basic_string<_Elem, _Traits, _Alloc>& source, _Inout_ inserted_token_list& inserted_tokens,
void append_inserted_tokens(_Inout_ std::basic_string<T, TR, AX>& source, _Inout_ inserted_token_list& inserted_tokens,
_In_ size_t word_index, _In_ bool after_word,
_Inout_ token_list& active_tokens)
{
@ -2363,7 +2363,7 @@ namespace stdex
///
/// Converts URL to absolute
///
void make_absolute_url(std::basic_string<_Elem, _Traits, _Alloc>& rel)
void make_absolute_url(std::basic_string<T, TR, AX>& rel)
{
_Unreferenced_(rel);
@ -2405,7 +2405,7 @@ namespace stdex
/// \returns Number of code units appended to the source code
///
template <class T>
size_t append_token(_Inout_ std::unique_ptr<T>&& token, _Inout_ std::basic_string<_Elem, _Traits, _Alloc>& source)
size_t append_token(_Inout_ std::unique_ptr<T>&& token, _Inout_ std::basic_string<T, TR, AX>& source)
{
if (!token)
return 0;
@ -2422,10 +2422,10 @@ namespace stdex
///
/// \returns Token represening sequences parsed
///
text_token<_Elem, _Traits, _Alloc>* parse(_In_ const sequence_store::const_iterator& end, _In_ uint32_t text_type = 0)
text_token<T, TR, AX>* parse(_In_ const sequence_store::const_iterator& end, _In_ uint32_t text_type = 0)
{
stdex::mapping<size_t> rel;
std::unique_ptr<text_token<_Elem, _Traits, _Alloc>> token(new text_token<_Elem, _Traits, _Alloc>(
std::unique_ptr<text_token<T, TR, AX>> token(new text_token<T, TR, AX>(
token_t::complete,
nullptr, 0,
text_type,
@ -2442,8 +2442,8 @@ namespace stdex
// No token_tag_start and token_tag_end chars, please.
_Assume_(
stdex::strnchr(m_source + s->interval.start, s->interval.size(), static_cast<_Elem>(token_tag_start)) == stdex::npos &&
stdex::strnchr(m_source + s->interval.start, s->interval.size(), static_cast<_Elem>(token_tag_end)) == stdex::npos);
stdex::strnchr(m_source + s->interval.start, s->interval.size(), static_cast<T>(token_tag_start)) == stdex::npos &&
stdex::strnchr(m_source + s->interval.start, s->interval.size(), static_cast<T>(token_tag_end)) == stdex::npos);
if (s->type == stdex::parser::html_sequence_t::text) {
rel.from = s->interval.start;
@ -2464,9 +2464,9 @@ namespace stdex
{
size_t offset = s->interval.start;
std::unique_ptr<text_token<_Elem, _Traits, _Alloc>> t(s->type == stdex::parser::html_sequence_t::element || element_traits::span(s_el_start->code) == element_span_t::immediate ?
new text_token<_Elem, _Traits, _Alloc>(token_t::complete, nullptr, 0, 0, s.get()) :
new starting_token<_Elem, _Traits, _Alloc>(nullptr, 0, m_source + s_el_start->name.start, s_el_start->name.size(), 0, s.get(), s_el_start->end));
std::unique_ptr<text_token<T, TR, AX>> t(s->type == stdex::parser::html_sequence_t::element || element_traits::span(s_el_start->code) == element_span_t::immediate ?
new text_token<T, TR, AX>(token_t::complete, nullptr, 0, 0, s.get()) :
new starting_token<T, TR, AX>(nullptr, 0, m_source + s_el_start->name.start, s_el_start->name.size(), 0, s.get(), s_el_start->end));
// Copy the tag contents, but mind any attributes containing localizable text.
for (auto& a : s_el->attributes) {
@ -2476,7 +2476,7 @@ namespace stdex
if (element_traits::is_uri(s_el->code, m_source + a.name.start, a.name.size())) {
t->text.append(m_source + offset, a.value.start - offset);
std::unique_ptr<url_token<_Elem, _Traits, _Alloc>> t_url(new url_token<_Elem, _Traits, _Alloc>(
std::unique_ptr<url_token<T, TR, AX>> t_url(new url_token<T, TR, AX>(
nullptr, 0,
token_url_t::sgml,
s.get()));
@ -2487,7 +2487,7 @@ namespace stdex
}
else if (element_traits::is_localizable(s_el->code, m_source + a.name.start, a.name.size())) {
t->text.append(m_source + offset, a.value.start - offset);
std::unique_ptr<text_token<_Elem, _Traits, _Alloc>> t_value(new text_token<_Elem, _Traits, _Alloc>(
std::unique_ptr<text_token<T, TR, AX>> t_value(new text_token<T, TR, AX>(
token_t::complete,
nullptr, 0,
has_text | is_title,
@ -2527,8 +2527,8 @@ namespace stdex
if (s_el_start->code != element_t::style) {
rel.from = s->interval.start;
token->mapping.push_back(rel);
rel.to += append_token(std::move(std::unique_ptr<text_token<_Elem, _Traits, _Alloc>>(
new text_token<_Elem, _Traits, _Alloc>(
rel.to += append_token(std::move(std::unique_ptr<text_token<T, TR, AX>>(
new text_token<T, TR, AX>(
token_t::complete,
m_source + s->interval.end, s_end->interval.start - s->interval.end,
0,
@ -2565,8 +2565,8 @@ namespace stdex
else if (s->type == stdex::parser::html_sequence_t::element_end) {
rel.from = s->interval.start;
token->mapping.push_back(rel);
rel.to += append_token(std::move(std::unique_ptr<text_token<_Elem, _Traits, _Alloc>>(
new text_token<_Elem, _Traits, _Alloc>(
rel.to += append_token(std::move(std::unique_ptr<text_token<T, TR, AX>>(
new text_token<T, TR, AX>(
token_t::ending,
m_source + s->interval.start, s->interval.size(),
0,
@ -2579,8 +2579,8 @@ namespace stdex
// Declaration, instruction, (P)CDATA section, comment...
rel.from = s->interval.start;
token->mapping.push_back(rel);
rel.to += append_token(std::move(std::unique_ptr<text_token<_Elem, _Traits, _Alloc>>(
new text_token<_Elem, _Traits, _Alloc>(
rel.to += append_token(std::move(std::unique_ptr<text_token<T, TR, AX>>(
new text_token<T, TR, AX>(
token_t::complete,
m_source + s->interval.start, s->interval.size(),
0,
@ -2597,11 +2597,11 @@ namespace stdex
///
/// Parses CSS
///
text_token<_Elem, _Traits, _Alloc>* parse_css(size_t start, size_t end)
text_token<T, TR, AX>* parse_css(size_t start, size_t end)
{
stdex::interval<size_t> section, content;
std::unique_ptr<text_token<_Elem, _Traits, _Alloc>> token(
new text_token<_Elem, _Traits, _Alloc>(
std::unique_ptr<text_token<T, TR, AX>> token(
new text_token<T, TR, AX>(
token_t::complete,
nullptr, 0,
0,
@ -2624,8 +2624,8 @@ namespace stdex
m_css_import.match(m_source, start, end) && (section = m_css_import.interval, content = m_css_import.content, true) ||
m_css_uri.match(m_source, start, end) && (section = m_css_uri.interval, content = m_css_uri.content, true))
{
std::unique_ptr<url_token<_Elem, _Traits, _Alloc>> t_url(
new url_token<_Elem, _Traits, _Alloc>(
std::unique_ptr<url_token<T, TR, AX>> t_url(
new url_token<T, TR, AX>(
nullptr, 0,
token_url_t::css,
m_offset->get()));
@ -2648,22 +2648,22 @@ namespace stdex
}
protected:
const document<_Elem, _Traits, _Alloc>& m_document; ///< Document being analyzed
const document<T, TR, AX>& m_document; ///< Document being analyzed
const stdex::sstring m_url; ///< Absolute document URL
const bool m_parse_frames; ///< Parse frames
stdex::progress<size_t>* m_progress; ///< Progress indicator
const _Elem* m_source; ///< HTML source code
const T* m_source; ///< HTML source code
token_vector m_tokens; ///< HTML token storage
sequence_store::const_iterator m_offset; ///< Index of active section
// For detecting URLs in CSS
stdex::parser::basic_css_cdo<_Elem> m_css_cdo;
stdex::parser::basic_css_cdc<_Elem> m_css_cdc;
stdex::parser::basic_css_comment<_Elem> m_css_comment;
stdex::parser::basic_css_string<_Elem> m_css_string;
stdex::parser::basic_css_uri<_Elem> m_css_uri;
stdex::parser::basic_css_import<_Elem> m_css_import;
stdex::parser::basic_any_cu<_Elem> m_any_char;
stdex::parser::basic_css_cdo<T> m_css_cdo;
stdex::parser::basic_css_cdc<T> m_css_cdc;
stdex::parser::basic_css_comment<T> m_css_comment;
stdex::parser::basic_css_string<T> m_css_string;
stdex::parser::basic_css_uri<T> m_css_uri;
stdex::parser::basic_css_import<T> m_css_import;
stdex::parser::basic_any_cu<T> m_any_char;
};
}
}

View File

@ -24,8 +24,8 @@ namespace stdex {
/// - \c true when succeeded
/// - \c false otherwise
///
template <class T_ID>
_Success_(return) bool read_id(_In_ std::istream& stream, _Out_ T_ID &id, _In_opt_ std::streamoff end = (std::streamoff)-1)
template <class T_id>
_Success_(return) bool read_id(_In_ std::istream& stream, _Out_ T_id &id, _In_opt_ std::streamoff end = (std::streamoff)-1)
{
if (end == (std::streamoff)-1 || stream.tellg() < end) {
stream.read((char*)&id, sizeof(id));
@ -45,8 +45,8 @@ namespace stdex {
/// - \c true when succeeded
/// - \c false otherwise
///
template <class T_ID>
_Success_(return) bool read_id(_In_ stdex::stream::basic_file& stream, _Out_ T_ID &id, _In_opt_ stdex::stream::fpos_t end = stdex::stream::fpos_max)
template <class T_id>
_Success_(return) bool read_id(_In_ stdex::stream::basic_file& stream, _Out_ T_id &id, _In_opt_ stdex::stream::fpos_t end = stdex::stream::fpos_max)
{
if (end == stdex::stream::fpos_max || stream.tell() < end) {
stream >> id;
@ -60,12 +60,12 @@ namespace stdex {
///
/// \param[in] size Actual data size
///
/// \return Number of bytes needed to add to the data to align it on `ALIGN` boundary
/// \return Number of bytes needed to add to the data to align it on `N_align` boundary
///
template <class T_SIZE, T_SIZE ALIGN>
T_SIZE padding(_In_ T_SIZE size)
template <class T_size, T_size N_align>
T_size padding(_In_ T_size size)
{
return (ALIGN - (size % ALIGN)) % ALIGN;
return (N_align - (size % N_align)) % N_align;
}
///
@ -77,16 +77,16 @@ namespace stdex {
/// - \c true when successful
/// - \c false otherwise
///
template <class T_SIZE, T_SIZE ALIGN>
template <class T_size, T_size N_align>
bool ignore(_In_ std::istream& stream)
{
// Read record size.
T_SIZE size;
T_size size;
stream.read((char*)&size, sizeof(size));
if (!stream.good()) _Unlikely_ return false;
// Skip the record data.
size += padding<T_SIZE, ALIGN>(size);
size += padding<T_size, N_align>(size);
stream.ignore(size);
if (!stream.good()) _Unlikely_ return false;
@ -102,16 +102,16 @@ namespace stdex {
/// - \c true when successful
/// - \c false otherwise
///
template <class T_SIZE, T_SIZE ALIGN>
template <class T_size, T_size N_align>
bool ignore(_In_ stdex::stream::basic& stream)
{
// Read record size.
T_SIZE size;
T_size size;
stream >> size;
if (!stream.ok()) _Unlikely_ return false;
// Skip the record data.
size += padding<T_SIZE, ALIGN>(size);
size += padding<T_size, N_align>(size);
stream.skip(size);
if (!stream.ok()) _Unlikely_ return false;
@ -129,10 +129,10 @@ namespace stdex {
/// - \c true when found
/// - \c false otherwise
///
template <class T_ID, class T_SIZE, T_SIZE ALIGN>
bool find(_In_ std::istream& stream, _In_ T_ID id, _In_opt_ std::streamoff end = (std::streamoff)-1)
template <class T_id, class T_size, T_size N_align>
bool find(_In_ std::istream& stream, _In_ T_id id, _In_opt_ std::streamoff end = (std::streamoff)-1)
{
T_ID _id;
T_id _id;
while (end == (std::streamoff)-1 || stream.tellg() < end) {
stream.read((char*)&_id, sizeof(_id));
if (!stream.good()) _Unlikely_ return false;
@ -140,7 +140,7 @@ namespace stdex {
// The record was found.
return true;
} else
ignore<T_SIZE, ALIGN>(stream);
ignore<T_size, N_align>(stream);
}
return false;
}
@ -156,10 +156,10 @@ namespace stdex {
/// - \c true when found
/// - \c false otherwise
///
template <class T_ID, class T_SIZE, T_SIZE ALIGN>
bool find(_In_ stdex::stream::basic_file& stream, _In_ T_ID id, _In_opt_ stdex::stream::fpos_t end = stdex::stream::fpos_max)
template <class T_id, class T_size, T_size N_align>
bool find(_In_ stdex::stream::basic_file& stream, _In_ T_id id, _In_opt_ stdex::stream::fpos_t end = stdex::stream::fpos_max)
{
T_ID _id;
T_id _id;
while (end == stdex::stream::fpos_max || stream.tell() < end) {
stream >> _id;
if (!stream.ok()) _Unlikely_ return false;
@ -167,7 +167,7 @@ namespace stdex {
// The record was found.
return true;
} else
ignore<T_SIZE, ALIGN>(stream);
ignore<T_size, N_align>(stream);
}
return false;
}
@ -180,8 +180,8 @@ namespace stdex {
///
/// \returns Position of the record header start in \p stream. Save for later \c close call.
///
template <class T_ID, class T_SIZE>
std::streamoff open(_In_ std::ostream& stream, _In_ T_ID id)
template <class T_id, class T_size>
std::streamoff open(_In_ std::ostream& stream, _In_ T_id id)
{
std::streamoff start = stream.tellp();
@ -191,7 +191,7 @@ namespace stdex {
// Write 0 as a placeholder for data size.
if (stream.fail()) _Unlikely_ return (std::streamoff)-1;
T_SIZE size = 0;
T_size size = 0;
stream.write((const char*)&size, sizeof(size));
return start;
@ -205,8 +205,8 @@ namespace stdex {
///
/// \returns Position of the record header start in \p stream. Save for later \c close call.
///
template <class T_ID, class T_SIZE>
stdex::stream::fpos_t open(_In_ stdex::stream::basic_file& stream, _In_ T_ID id)
template <class T_id, class T_size>
stdex::stream::fpos_t open(_In_ stdex::stream::basic_file& stream, _In_ T_id id)
{
auto start = stream.tell();
@ -214,7 +214,7 @@ namespace stdex {
stream << id;
// Write 0 as a placeholder for data size.
stream << static_cast<T_SIZE>(0);
stream << static_cast<T_size>(0);
return start;
}
@ -227,24 +227,24 @@ namespace stdex {
///
/// \returns Position of the record end in \p stream
///
template <class T_ID, class T_SIZE, T_SIZE ALIGN>
template <class T_id, class T_size, T_size N_align>
std::streamoff close(_In_ std::ostream& stream, _In_ std::streamoff start)
{
std::streamoff end = stream.tellp();
T_SIZE
size = static_cast<T_SIZE>(end - start - sizeof(T_ID) - sizeof(T_SIZE)),
remainder = padding<T_SIZE, ALIGN>(size);
T_size
size = static_cast<T_size>(end - start - sizeof(T_id) - sizeof(T_size)),
remainder = padding<T_size, N_align>(size);
if (remainder) {
// Append padding.
static const char padding[ALIGN] = {};
static const char padding[N_align] = {};
stream.write(padding, remainder);
end += remainder;
}
// Update the data size.
if (stream.fail()) _Unlikely_ return (std::streamoff)-1;
stream.seekp(start + sizeof(T_ID));
stream.seekp(start + sizeof(T_id));
stream.write(reinterpret_cast<const char*>(&size), sizeof(size));
stream.seekp(end);
@ -259,24 +259,24 @@ namespace stdex {
///
/// \returns Position of the record end in \p stream
///
template <class T_ID, class T_SIZE, T_SIZE ALIGN>
template <class T_id, class T_size, T_size N_align>
stdex::stream::fpos_t close(_In_ stdex::stream::basic_file& stream, _In_ stdex::stream::fpos_t start)
{
auto end = stream.tell();
T_SIZE
size = static_cast<T_SIZE>(end - start - sizeof(T_ID) - sizeof(T_SIZE)),
remainder = padding<T_SIZE, ALIGN>(size);
T_size
size = static_cast<T_size>(end - start - sizeof(T_id) - sizeof(T_size)),
remainder = padding<T_size, N_align>(size);
if (remainder) {
// Append padding.
static const char padding[ALIGN] = {};
static const char padding[N_align] = {};
stream.write_array(padding, sizeof(char), remainder);
end += remainder;
}
// Update the data size.
if (!stream.ok()) _Unlikely_ return stdex::stream::fpos_max;
stream.seek(start + sizeof(T_ID));
stream.seek(start + sizeof(T_id));
stream << size;
stream.seek(end);
@ -286,7 +286,7 @@ namespace stdex {
///
/// Helper class for read/write of records to/from memory
///
template <class T, class T_ID, const T_ID ID, class T_SIZE, T_SIZE ALIGN>
template <class T, class T_id, const T_id ID, class T_size, T_size N_align>
class record
{
public:
@ -307,7 +307,7 @@ namespace stdex {
///
/// Returns record id
///
static constexpr T_ID id()
static constexpr T_id id()
{
return ID;
}
@ -319,7 +319,7 @@ namespace stdex {
///
/// \returns A const reference to this struct
///
const record<T, T_ID, ID, T_SIZE, ALIGN>& operator =(_In_ const record<T, T_ID, ID, T_SIZE, ALIGN> &r)
const record<T, T_id, ID, T_size, N_align>& operator =(_In_ const record<T, T_id, ID, T_size, N_align> &r)
{
data = r.data;
return *this;
@ -334,7 +334,7 @@ namespace stdex {
///
static std::streamoff open(_In_ std::ostream& stream)
{
return stdex::idrec::open<T_ID, T_SIZE>(stream, ID);
return stdex::idrec::open<T_id, T_size>(stream, ID);
}
///
@ -346,7 +346,7 @@ namespace stdex {
///
static stdex::stream::foff_t open(_In_ stdex::stream::basic_file& stream)
{
return stdex::idrec::open<T_ID, T_SIZE>(stream, ID);
return stdex::idrec::open<T_id, T_size>(stream, ID);
}
///
@ -359,7 +359,7 @@ namespace stdex {
///
static std::streamoff close(_In_ std::ostream& stream, _In_ std::streamoff start)
{
return stdex::idrec::close<T_ID, T_SIZE, ALIGN>(stream, start);
return stdex::idrec::close<T_id, T_size, N_align>(stream, start);
}
///
@ -372,7 +372,7 @@ namespace stdex {
///
static stdex::stream::foff_t close(_In_ stdex::stream::basic_file& stream, _In_ stdex::stream::foff_t start)
{
return stdex::idrec::close<T_ID, T_SIZE, ALIGN>(stream, start);
return stdex::idrec::close<T_id, T_size, N_align>(stream, start);
}
///
@ -387,7 +387,7 @@ namespace stdex {
///
static bool find(_In_ std::istream& stream, _In_opt_ std::streamoff end = (std::streamoff)-1)
{
return stdex::idrec::find<T_ID, T_SIZE, ALIGN>(stream, ID, end);
return stdex::idrec::find<T_id, T_size, N_align>(stream, ID, end);
}
///
@ -402,7 +402,7 @@ namespace stdex {
///
static bool find(_In_ stdex::stream::basic_file& stream, _In_opt_ stdex::stream::foff_t end = stdex::stream::foff_max)
{
return stdex::idrec::find<T_ID, T_SIZE, ALIGN>(stream, ID, end);
return stdex::idrec::find<T_id, T_size, N_align>(stream, ID, end);
}
T &data; ///< Record data reference
@ -415,7 +415,7 @@ namespace stdex {
///
/// \returns The stream \p stream
///
friend std::ostream& operator <<(_In_ std::ostream& stream, _In_ const record<T, T_ID, ID, T_SIZE, ALIGN> r)
friend std::ostream& operator <<(_In_ std::ostream& stream, _In_ const record<T, T_id, ID, T_size, N_align> r)
{
// Parameter r does not need to be passed by reference. It has only one field (data), which is a reference itself already.
@ -435,7 +435,7 @@ namespace stdex {
///
/// \returns The stream \p stream
///
friend stdex::stream::basic_file& operator <<(_In_ stdex::stream::basic_file& stream, _In_ const record<T, T_ID, ID, T_SIZE, ALIGN> r)
friend stdex::stream::basic_file& operator <<(_In_ stdex::stream::basic_file& stream, _In_ const record<T, T_id, ID, T_size, N_align> r)
{
// Parameter r does not need to be passed by reference. It has only one field (data), which is a reference itself already.
@ -455,7 +455,7 @@ namespace stdex {
///
/// \returns The stream \p stream
///
friend stdex::stream::basic& operator <<(_In_ stdex::stream::basic& stream, _In_ const record<T, T_ID, ID, T_SIZE, ALIGN> r)
friend stdex::stream::basic& operator <<(_In_ stdex::stream::basic& stream, _In_ const record<T, T_id, ID, T_size, N_align> r)
{
// Parameter r does not need to be passed by reference. It has only one field (data), which is a reference itself already.
@ -478,12 +478,12 @@ namespace stdex {
///
/// \returns The stream \p stream
///
friend std::istream& operator >>(_In_ std::istream& stream, _In_ record<T, T_ID, ID, T_SIZE, ALIGN> r)
friend std::istream& operator >>(_In_ std::istream& stream, _In_ record<T, T_id, ID, T_size, N_align> r)
{
// Parameter r does not need to be passed by reference. It has only one field (data), which is a reference itself already.
// Read data size.
T_SIZE size;
T_size size;
stream.read((char*)&size, sizeof(size));
if (!stream.good()) _Unlikely_ return stream;
@ -492,7 +492,7 @@ namespace stdex {
stream >> r.data; // TODO: operator >> should not read past the record data! Make a size limited stream and read from it instead.
if (!stream.good()) _Unlikely_ return stream;
size += padding<T_SIZE, ALIGN>(size);
size += padding<T_size, N_align>(size);
stream.seekg(start + size);
return stream;
@ -506,12 +506,12 @@ namespace stdex {
///
/// \returns The stream \p stream
///
friend stdex::stream::basic_file& operator >>(_In_ stdex::stream::basic_file& stream, _In_ record<T, T_ID, ID, T_SIZE, ALIGN> r)
friend stdex::stream::basic_file& operator >>(_In_ stdex::stream::basic_file& stream, _In_ record<T, T_id, ID, T_size, N_align> r)
{
// Parameter r does not need to be passed by reference. It has only one field (data), which is a reference itself already.
// Read data size.
T_SIZE size;
T_size size;
stream >> size;
if (!stream.ok()) _Unlikely_ return stream;
@ -523,7 +523,7 @@ namespace stdex {
if (limiter.state() == stdex::stream::state_t::fail) _Unlikely_ return stream;
}
size += padding<T_SIZE, ALIGN>(size);
size += padding<T_size, N_align>(size);
stream.seek(start + size);
return stream;
@ -537,12 +537,12 @@ namespace stdex {
///
/// \returns The stream \p stream
///
friend stdex::stream::basic& operator >>(_In_ stdex::stream::basic& stream, _In_ record<T, T_ID, ID, T_SIZE, ALIGN> r)
friend stdex::stream::basic& operator >>(_In_ stdex::stream::basic& stream, _In_ record<T, T_id, ID, T_size, N_align> r)
{
// Parameter r does not need to be passed by reference. It has only one field (data), which is a reference itself already.
// Read data size.
T_SIZE size;
T_size size;
stream >> size;
if (!stream.ok()) _Unlikely_ return stream;
@ -552,7 +552,7 @@ namespace stdex {
if (limiter.state() == stdex::stream::state_t::fail) _Unlikely_ return stream;
limiter.skip(limiter.read_limit);
}
stream.skip(padding<T_SIZE, ALIGN>(size));
stream.skip(padding<T_size, N_align>(size));
return stream;
}

View File

@ -201,6 +201,6 @@ namespace stdex
}
};
template <class T, class _Alloc = std::allocator<interval<T>>>
using interval_vector = std::vector<interval<T>, _Alloc>;
template <class T, class AX = std::allocator<interval<T>>>
using interval_vector = std::vector<interval<T>, AX>;
}

View File

@ -57,6 +57,6 @@ namespace stdex
bool operator!=(const mapping& other) const { return !operator==(other); }
};
template <class T, class _Alloc = std::allocator<mapping<T>>>
using mapping_vector = std::vector<mapping<T>, _Alloc>;
template <class T, class AX = std::allocator<mapping<T>>>
using mapping_vector = std::vector<mapping<T>, AX>;
}

View File

@ -30,11 +30,11 @@ namespace stdex
struct no_delete<T[]> {
constexpr no_delete() noexcept = default;
template <class _Uty, std::enable_if_t<std::is_convertible_v<_Uty(*)[], T(*)[]>, int> = 0>
no_delete(const no_delete<_Uty[]>&) noexcept {}
template <class T2, std::enable_if_t<std::is_convertible_v<T2(*)[], T(*)[]>, int> = 0>
no_delete(const no_delete<T2[]>&) noexcept {}
template <class _Uty, std::enable_if_t<std::is_convertible_v<_Uty(*)[], T(*)[]>, int> = 0>
void operator()(_Uty* p) const noexcept { p; }
template <class T2, std::enable_if_t<std::is_convertible_v<T2(*)[], T(*)[]>, int> = 0>
void operator()(T2* p) const noexcept { p; }
};
///

View File

@ -7166,7 +7166,7 @@ namespace stdex
///
/// Collection of HTTP values
///
template <class _Key, class T>
template <class KEY, class T>
class http_value_collection : public T
{
public:
@ -7182,7 +7182,7 @@ namespace stdex
start++;
while (start < end&& text[start] && stdex::isspace(text[start])) start++;
}
_Key el;
KEY el;
if (el.match(text, start, end, flags)) {
start = el.interval.end;
T::insert(std::move(el));
@ -7204,8 +7204,8 @@ namespace stdex
///
/// Collection of weighted HTTP values
///
template <class T, class _Alloc = std::allocator<T>>
using http_weighted_collection = http_value_collection<T, std::multiset<T, http_factor_more<T>, _Alloc>>;
template <class T, class AX = std::allocator<T>>
using http_weighted_collection = http_value_collection<T, std::multiset<T, http_factor_more<T>, AX>>;
///
/// Test for JSON string

View File

@ -15,10 +15,10 @@ namespace stdex
///
/// Ring buffer
///
/// \tparam T Ring element type
/// \tparam CAPACITY Ring capacity (in number of elements)
/// \tparam T Ring element type
/// \tparam N_cap Ring capacity (in number of elements)
///
template <class T, size_t CAPACITY>
template <class T, size_t N_cap>
class ring
{
public:
@ -43,7 +43,7 @@ namespace stdex
return { nullptr, 0 };
}
size_t tail = wrap(m_head + m_size);
return { &m_data[tail], m_head <= tail ? CAPACITY - tail : m_head - tail };
return { &m_data[tail], m_head <= tail ? N_cap - tail : m_head - tail };
}
///
@ -57,7 +57,7 @@ namespace stdex
const std::lock_guard<std::mutex> lg(m_mutex);
#ifdef _DEBUG
size_t tail = wrap(m_head + m_size);
_Assume_(size <= (m_head <= tail ? CAPACITY - tail : m_head - tail));
_Assume_(size <= (m_head <= tail ? N_cap - tail : m_head - tail));
#endif
m_size += size;
}
@ -78,7 +78,7 @@ namespace stdex
return { nullptr, 0 };
}
size_t tail = wrap(m_head + m_size);
return { &m_data[m_head], m_head < tail ? m_size : CAPACITY - m_head };
return { &m_data[m_head], m_head < tail ? m_size : N_cap - m_head };
}
///
@ -92,7 +92,7 @@ namespace stdex
const std::lock_guard<std::mutex> lg(m_mutex);
#ifdef _DEBUG
size_t tail = wrap(m_head + m_size);
_Assume_(size <= (m_head < tail ? m_size : CAPACITY - m_head));
_Assume_(size <= (m_head < tail ? m_size : N_cap - m_head));
#endif
m_head = wrap(m_head + size);
m_size -= size;
@ -125,13 +125,13 @@ namespace stdex
protected:
size_t wrap(_In_ size_t idx) const
{
// TODO: When CAPACITY is power of 2, use & ~(CAPACITY - 1) instead.
return idx % CAPACITY;
// TODO: When N_cap is power of 2, use & ~(N_cap - 1) instead.
return idx % N_cap;
}
size_t space() const
{
return CAPACITY - m_size;
return N_cap - m_size;
}
bool empty() const
@ -144,6 +144,6 @@ namespace stdex
std::condition_variable m_head_moved, m_tail_moved;
size_t m_head, m_size;
bool m_quit;
T m_data[CAPACITY];
T m_data[N_cap];
};
}

View File

@ -88,10 +88,10 @@ namespace stdex
/// \param[in] offset Logical starting offset of source and destination strings. Unused when map parameter is nullptr.
/// \param[in,out] map The vector to append index mapping between source and destination string to.
///
template <class T>
template <class T_from, class TR_to = std::char_traits<wchar_t>, class AX_to = std::allocator<wchar_t>>
void sgml2strcat(
_Inout_ std::wstring& dst,
_In_reads_or_z_opt_(count_src) const T* src, _In_ size_t count_src,
_Inout_ std::basic_string<wchar_t, TR_to, AX_to>& dst,
_In_reads_or_z_opt_(count_src) const T_from* src, _In_ size_t count_src,
_In_ int skip = 0,
_In_ const mapping<size_t>& offset = mapping<size_t>(0, 0),
_Inout_opt_ mapping_vector<size_t>* map = nullptr)
@ -180,10 +180,10 @@ namespace stdex
/// \param[in] offset Logical starting offset of source and destination strings. Unused when map parameter is nullptr.
/// \param[in,out] map The vector to append index mapping between source and destination string to.
///
template <class T>
template <class T_from, class TR_to = std::char_traits<wchar_t>, class AX_to = std::allocator<wchar_t>, class TR_from = std::char_traits<T_from>, class AX_from = std::allocator<T_from>>
void sgml2strcat(
_Inout_ std::wstring& dst,
_In_ const std::basic_string<T>& src,
_Inout_ std::basic_string<wchar_t, TR_to, AX_to>& dst,
_In_ const std::basic_string<T_from, TR_from, AX_from>& src,
_In_ int skip = 0,
_In_ const mapping<size_t>& offset = mapping<size_t>(0, 0),
_Inout_opt_ mapping_vector<size_t>* map = nullptr)
@ -204,10 +204,10 @@ namespace stdex
///
/// \return Final length of SGML string in code points excluding zero-terminator
///
template <class T>
template <class T_from>
size_t sgml2strcat(
_Inout_cap_(count_dst) wchar_t* dst, _In_ size_t count_dst,
_In_reads_or_z_opt_(count_src) const T* src, _In_ size_t count_src,
_In_reads_or_z_opt_(count_src) const T_from* src, _In_ size_t count_src,
_In_ int skip = 0,
_In_ const mapping<size_t>& offset = mapping<size_t>(0, 0),
_Inout_opt_ mapping_vector<size_t>* map = nullptr)
@ -308,10 +308,10 @@ namespace stdex
/// \param[in] offset Logical starting offset of source and destination strings. Unused when map parameter is nullptr.
/// \param[in,out] map The vector to write index mapping between source and destination string to.
///
template <class T>
template <class T_from, class TR_to = std::char_traits<wchar_t>, class AX_to = std::allocator<wchar_t>>
void sgml2strcpy(
_Inout_ std::wstring& dst,
_In_reads_or_z_opt_(count_src) const T* src, _In_ size_t count_src,
_Inout_ std::basic_string<wchar_t, TR_to, AX_to>& dst,
_In_reads_or_z_opt_(count_src) const T_from* src, _In_ size_t count_src,
_In_ int skip = 0,
_In_ const mapping<size_t>& offset = mapping<size_t>(0, 0),
_Inout_opt_ mapping_vector<size_t>* map = nullptr)
@ -331,10 +331,10 @@ namespace stdex
/// \param[in] offset Logical starting offset of source and destination strings. Unused when map parameter is nullptr.
/// \param[in,out] map The vector to write index mapping between source and destination string to.
///
template<class _Elem, class _Traits, class _Ax>
template<class T_from, class TR_to = std::char_traits<wchar_t>, class AX_to = std::allocator<wchar_t>, class TR_from = std::char_traits<T_from>, class AX_from = std::allocator<T_from>>
void sgml2strcpy(
_Inout_ std::wstring& dst,
_In_ const std::basic_string<_Elem, _Traits, _Ax>& src,
_Inout_ std::basic_string<wchar_t, TR_to, AX_to>& dst,
_In_ const std::basic_string<T_from, TR_from, AX_from>& src,
_In_ int skip = 0,
_In_ const mapping<size_t>& offset = mapping<size_t>(0, 0),
_Inout_opt_ mapping_vector<size_t>* map = nullptr)
@ -355,10 +355,10 @@ namespace stdex
///
/// \return Final length of SGML string in code points excluding zero-terminator
///
template <class T>
template <class T_from>
size_t sgml2strcpy(
_Inout_cap_(count_dst) wchar_t* dst, _In_ size_t count_dst,
_In_reads_or_z_opt_(count_src) const T* src, _In_ size_t count_src,
_In_reads_or_z_opt_(count_src) const T_from* src, _In_ size_t count_src,
_In_ int skip = 0,
_In_ const mapping<size_t>& offset = mapping<size_t>(0, 0),
_Inout_opt_ mapping_vector<size_t>* map = nullptr)
@ -382,9 +382,9 @@ namespace stdex
///
/// \return Unicode string
///
template <class T>
template <class T_from>
std::wstring sgml2str(
_In_reads_or_z_opt_(count_src) const T* src, _In_ size_t count_src,
_In_reads_or_z_opt_(count_src) const T_from* src, _In_ size_t count_src,
_In_ int skip = 0,
_In_ const mapping<size_t>& offset = mapping<size_t>(0, 0),
_Inout_opt_ mapping_vector<size_t>* map = nullptr)
@ -404,9 +404,9 @@ namespace stdex
///
/// \return Unicode string
///
template <class T>
template <class T_from, class TR_from = std::char_traits<T_from>, class AX_from = std::allocator<T_from>>
std::wstring sgml2str(
_In_ const std::basic_string<T>& src,
_In_ const std::basic_string<T_from, TR_from, AX_from>& src,
_In_ int skip = 0,
_In_ const mapping<size_t>& offset = mapping<size_t>(0, 0),
_Inout_opt_ mapping_vector<size_t>* map = nullptr)
@ -451,8 +451,9 @@ namespace stdex
/// \param[in] count_src Unicode string character count limit
/// \param[in] what Bitwise flag of stdex::sgml_* constants that force extra characters otherwise not converted to SGML
///
template <class TR_to = std::char_traits<char>, class AX_to = std::allocator<char>>
inline void str2sgmlcat(
_Inout_ std::string& dst,
_Inout_ std::basic_string<char, TR_to, AX_to>& dst,
_In_reads_or_z_opt_(count_src) const wchar_t* src, _In_ size_t count_src,
_In_ int what = 0)
{
@ -553,10 +554,10 @@ namespace stdex
/// \param[in] src Unicode string
/// \param[in] what Bitwise flag of stdex::sgml_* constants that force extra characters otherwise not converted to SGML
///
template <class _Traits = std::char_traits<char>, class _Ax = std::allocator<char>>
template <class TR_to = std::char_traits<char>, class AX_to = std::allocator<char>>
void str2sgmlcat(
_Inout_ std::basic_string<char, _Traits, _Ax>& dst,
_In_ const std::wstring_view src,
_Inout_ std::basic_string<char, TR_to, AX_to>& dst,
_In_ const std::basic_string_view<wchar_t, std::char_traits<wchar_t>> src,
_In_ int what = 0)
{
str2sgmlcat(dst, src.data(), src.size(), what);
@ -702,8 +703,9 @@ namespace stdex
/// \param[in] count_src Unicode string character count limit
/// \param[in] what Bitwise flag of stdex::sgml_* constants that force extra characters otherwise not converted to SGML
///
template <class TR_to = std::char_traits<char>, class AX_to = std::allocator<char>>
inline void str2sgmlcpy(
_Inout_ std::string& dst,
_Inout_ std::basic_string<char, TR_to, AX_to>& dst,
_In_reads_or_z_opt_(count_src) const wchar_t* src, _In_ size_t count_src,
_In_ int what = 0)
{
@ -718,10 +720,10 @@ namespace stdex
/// \param[in] src Unicode string
/// \param[in] what Bitwise flag of stdex::sgml_* constants that force extra characters otherwise not converted to SGML
///
template <class _Traits = std::char_traits<char>, class _Ax = std::allocator<char>>
template <class TR_to = std::char_traits<char>, class AX_to = std::allocator<char>>
void str2sgmlcpy(
_Inout_ std::basic_string<char, _Traits, _Ax>& dst,
_In_ const std::wstring_view src,
_Inout_ std::basic_string<char, TR_to, AX_to>& dst,
_In_ const std::basic_string_view<wchar_t, std::char_traits<wchar_t>> src,
_In_ int what = 0)
{
str2sgmlcpy(dst, src.data(), src.size(), what);
@ -776,7 +778,7 @@ namespace stdex
/// \return SGML string
///
inline std::string str2sgml(
_In_ const std::wstring_view src,
_In_ const std::basic_string_view<wchar_t, std::char_traits<wchar_t>> src,
_In_ int what = 0)
{
return str2sgml(src.data(), src.size(), what);

View File

@ -302,8 +302,8 @@ namespace stdex
///
/// \return Number of read characters
///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>>
size_t readln(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& str)
template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
size_t readln(_Inout_ std::basic_string<T, TR, AX>& str)
{
str.clear();
return readln_and_attach(str);
@ -314,8 +314,8 @@ namespace stdex
///
/// \return Number of read characters
///
template<class T_from, class T_to, class _Traits = std::char_traits<T_to>, class _Ax = std::allocator<T_to>>
size_t readln(_Inout_ std::basic_string<T_to, _Traits, _Ax>& str, _In_ charset_encoder<T_from, T_to>& encoder)
template<class T_from, class T_to, class TR = std::char_traits<T_to>, class AX = std::allocator<T_to>>
size_t readln(_Inout_ std::basic_string<T_to, TR, AX>& str, _In_ charset_encoder<T_from, T_to>& encoder)
{
if (encoder.from_encoding() == encoder.to_encoding())
return readln(str);
@ -330,19 +330,19 @@ namespace stdex
///
/// \return Total number of chars in str
///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>>
size_t readln_and_attach(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& str)
template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
size_t readln_and_attach(_Inout_ std::basic_string<T, TR, AX>& str)
{
bool initial = true;
_Elem chr, previous = (_Elem)0;
T chr, previous = (T)0;
do {
read_array(&chr, sizeof(_Elem), 1);
if (!initial && !(previous == static_cast<_Elem>('\r') && chr == static_cast<_Elem>('\n')))
read_array(&chr, sizeof(T), 1);
if (!initial && !(previous == static_cast<T>('\r') && chr == static_cast<T>('\n')))
str += previous;
else
initial = false;
previous = chr;
} while (ok() && chr != static_cast<_Elem>('\n'));
} while (ok() && chr != static_cast<T>('\n'));
return str.size();
}
@ -351,8 +351,8 @@ namespace stdex
///
/// \return Total number of chars in str
///
template<class T_from, class T_to, class _Traits = std::char_traits<T_to>, class _Ax = std::allocator<T_to>>
size_t readln_and_attach(_Inout_ std::basic_string<T_to, _Traits, _Ax>& str, _In_ charset_encoder<T_from, T_to>& encoder)
template<class T_from, class T_to, class TR = std::char_traits<T_to>, class AX = std::allocator<T_to>>
size_t readln_and_attach(_Inout_ std::basic_string<T_to, TR, AX>& str, _In_ charset_encoder<T_from, T_to>& encoder)
{
if (encoder.from_encoding() == encoder.to_encoding())
return readln_and_attach(str);
@ -439,8 +439,8 @@ namespace stdex
///
/// \return Number of code units written
///
template<class T_from, class T_to, class _Traits = std::char_traits<T_from>, class _Ax = std::allocator<T_from>>
size_t write_array(_In_ const std::basic_string<T_from, _Traits, _Ax>& str, _In_ charset_encoder<T_from, T_to>& encoder)
template<class T_from, class T_to, class TR = std::char_traits<T_from>, class AX = std::allocator<T_from>>
size_t write_array(_In_ const std::basic_string<T_from, TR, AX>& str, _In_ charset_encoder<T_from, T_to>& encoder)
{
if (!ok()) _Unlikely_
return 0;
@ -461,8 +461,8 @@ namespace stdex
///
/// \return This stream
///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>>
basic& read_str(_Out_ std::basic_string<_Elem, _Traits, _Ax>& data)
template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
basic& read_str(_Out_ std::basic_string<T, TR, AX>& data)
{
data.clear();
if (!ok()) _Unlikely_
@ -473,8 +473,8 @@ namespace stdex
return *this;
data.reserve(num_chars);
for (;;) {
_Elem buf[0x400];
uint32_t num_read = static_cast<uint32_t>(read_array(buf, sizeof(_Elem), std::min<uint32_t>(num_chars, _countof(buf))));
T buf[0x400];
uint32_t num_read = static_cast<uint32_t>(read_array(buf, sizeof(T), std::min<uint32_t>(num_chars, _countof(buf))));
data.append(buf, num_read);
num_chars -= num_read;
if (!num_chars || !ok())
@ -518,8 +518,8 @@ namespace stdex
///
/// \return This stream
///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>>
basic& write_str(_In_ const std::basic_string<_Elem, _Traits, _Ax>& data)
template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
basic& write_str(_In_ const std::basic_string<T, TR, AX>& data)
{
// Stream state will be checked in write_data.
size_t num_chars = data.size();
@ -528,7 +528,7 @@ namespace stdex
write_data(static_cast<uint32_t>(num_chars));
if (!ok()) _Unlikely_
return *this;
write_array(data.data(), sizeof(_Elem), num_chars);
write_array(data.data(), sizeof(T), num_chars);
return *this;
}
@ -669,15 +669,15 @@ namespace stdex
basic& operator >>(_Out_ wchar_t& data) { return read_data(data); }
basic& operator <<(_In_ const wchar_t data) { return write_data(data); }
#endif
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>>
basic& operator >>(_Out_ std::basic_string<_Elem, _Traits, _Ax>& data) { return read_str(data); }
template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
basic& operator >>(_Out_ std::basic_string<T, TR, AX>& data) { return read_str(data); }
template <class T>
basic& operator <<(_In_ const T* data) { return write_str(data); }
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>>
basic& operator <<(_In_ const std::basic_string<_Elem, _Traits, _Ax>& data) { return write_str(data); }
template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
basic& operator <<(_In_ const std::basic_string<T, TR, AX>& data) { return write_str(data); }
template <class _Ty, class _Alloc = std::allocator<_Ty>>
basic& operator <<(_In_ const std::vector<_Ty, _Alloc>& data)
template <class T, class AX = std::allocator<T>>
basic& operator <<(_In_ const std::vector<T, AX>& data)
{
size_t num = data.size();
if (num > UINT32_MAX) _Unlikely_
@ -688,8 +688,8 @@ namespace stdex
return *this;
}
template <class _Ty, class _Alloc = std::allocator<_Ty>>
basic& operator >>(_Out_ std::vector<_Ty, _Alloc>& data)
template <class T, class AX = std::allocator<T>>
basic& operator >>(_Out_ std::vector<T, AX>& data)
{
data.clear();
uint32_t num;
@ -698,7 +698,7 @@ namespace stdex
return *this;
data.reserve(num);
for (uint32_t i = 0; i < num; ++i) {
_Ty el;
T el;
*this >> el;
if (!ok()) _Unlikely_
return *this;
@ -706,8 +706,8 @@ namespace stdex
}
}
template <class _Kty, class _Pr = std::less<_Kty>, class _Alloc = std::allocator<_Kty>>
basic& operator <<(_In_ const std::set<_Kty, _Pr, _Alloc>& data)
template <class KEY, class PR = std::less<KEY>, class AX = std::allocator<KEY>>
basic& operator <<(_In_ const std::set<KEY, PR, AX>& data)
{
size_t num = data.size();
if (num > UINT32_MAX) _Unlikely_
@ -718,8 +718,8 @@ namespace stdex
return *this;
}
template <class _Kty, class _Pr = std::less<_Kty>, class _Alloc = std::allocator<_Kty>>
basic& operator >>(_Out_ std::set<_Kty, _Pr, _Alloc>& data)
template <class KEY, class PR = std::less<KEY>, class AX = std::allocator<KEY>>
basic& operator >>(_Out_ std::set<KEY, PR, AX>& data)
{
data.clear();
uint32_t num;
@ -727,7 +727,7 @@ namespace stdex
if (!ok()) _Unlikely_
return *this;
for (uint32_t i = 0; i < num; ++i) {
_Kty el;
KEY el;
*this >> el;
if (!ok()) _Unlikely_
return *this;
@ -735,8 +735,8 @@ namespace stdex
}
}
template <class _Kty, class _Pr = std::less<_Kty>, class _Alloc = std::allocator<_Kty>>
basic& operator <<(_In_ const std::multiset<_Kty, _Pr, _Alloc>& data)
template <class KEY, class PR = std::less<KEY>, class AX = std::allocator<KEY>>
basic& operator <<(_In_ const std::multiset<KEY, PR, AX>& data)
{
size_t num = data.size();
if (num > UINT32_MAX) _Unlikely_
@ -747,8 +747,8 @@ namespace stdex
return *this;
}
template <class _Kty, class _Pr = std::less<_Kty>, class _Alloc = std::allocator<_Kty>>
basic& operator >>(_Out_ std::multiset<_Kty, _Pr, _Alloc>& data)
template <class KEY, class PR = std::less<KEY>, class AX = std::allocator<KEY>>
basic& operator >>(_Out_ std::multiset<KEY, PR, AX>& data)
{
data.clear();
uint32_t num;
@ -756,7 +756,7 @@ namespace stdex
if (!ok()) _Unlikely_
return *this;
for (uint32_t i = 0; i < num; ++i) {
_Kty el;
KEY el;
*this >> el;
if (!ok()) _Unlikely_
return *this;
@ -1237,9 +1237,9 @@ namespace stdex
///
/// Provides read-ahead stream capability
///
/// @tparam CAPACITY Read-ahead buffer size
/// \tparam N_cap Read-ahead buffer size
///
template <size_t CAPACITY = default_async_limit>
template <size_t N_cap = default_async_limit>
class async_reader : public converter
{
public:
@ -1297,16 +1297,16 @@ namespace stdex
}
protected:
ring<uint8_t, CAPACITY> m_ring;
ring<uint8_t, N_cap> m_ring;
std::thread m_worker;
};
///
/// Provides write-back stream capability
///
/// @tparam CAPACITY Write-back buffer size
/// \tparam N_cap Write-back buffer size
///
template <size_t CAPACITY = default_async_limit>
template <size_t N_cap = default_async_limit>
class async_writer : public converter
{
public:
@ -1369,7 +1369,7 @@ namespace stdex
}
protected:
ring<uint8_t, CAPACITY> m_ring;
ring<uint8_t, N_cap> m_ring;
std::thread m_worker;
};
@ -2707,7 +2707,8 @@ namespace stdex
/// \param[in] filename Filename
/// \param[in] mode Bitwise combination of mode_t flags
///
file(_In_ const stdex::sstring& filename, _In_ int mode) : file(filename.c_str(), mode) {}
template <class TR = std::char_traits<schar_t>, class AX = std::allocator<schar_t>>
file(_In_ const std::basic_string<TR, AX>& filename, _In_ int mode) : file(filename.c_str(), mode) {}
///
/// Opens file
@ -2788,7 +2789,8 @@ namespace stdex
/// \param[in] filename Filename
/// \param[in] mode Bitwise combination of mode_t flags
///
void open(_In_ const stdex::sstring& filename, _In_ int mode)
template <class TR = std::char_traits<schar_t>, class AX = std::allocator<schar_t>>
void open(_In_ const std::basic_string<TR, AX>& filename, _In_ int mode)
{
open(filename.c_str(), mode);
}
@ -3049,7 +3051,8 @@ namespace stdex
///
/// \param[in] filename Filename
///
static bool exists(_In_ const stdex::sstring& filename)
template <class TR = std::char_traits<schar_t>, class AX = std::allocator<schar_t>>
static bool exists(_In_ const std::basic_string<TR, AX>& filename)
{
return exists(filename.c_str());
}
@ -3079,7 +3082,8 @@ namespace stdex
///
/// \param[in] filename Filename
///
static bool readonly(_In_ const stdex::sstring& filename)
template <class TR = std::char_traits<schar_t>, class AX = std::allocator<schar_t>>
static bool readonly(_In_ const std::basic_string<TR, AX>& filename)
{
return readonly(filename.c_str());
}
@ -3120,7 +3124,8 @@ namespace stdex
/// \param[in] mode Bitwise combination of mode_t flags
/// \param[in] cache_size Size of the cache block
///
cached_file(_In_ const stdex::sstring& filename, _In_ int mode, _In_ size_t cache_size = default_cache_size) : cached_file(filename.c_str(), mode, cache_size) {}
template <class TR = std::char_traits<schar_t>, class AX = std::allocator<schar_t>>
cached_file(_In_ const std::basic_string<TR, AX>& filename, _In_ int mode, _In_ size_t cache_size = default_cache_size) : cached_file(filename.c_str(), mode, cache_size) {}
virtual ~cached_file()
{
@ -3154,7 +3159,8 @@ namespace stdex
/// \param[in] filename Filename
/// \param[in] mode Bitwise combination of mode_t flags
///
void open(_In_ const stdex::sstring& filename, _In_ int mode)
template <class TR = std::char_traits<schar_t>, class AX = std::allocator<schar_t>>
void open(_In_ const std::basic_string<TR, AX>& filename, _In_ int mode)
{
open(filename.c_str(), mode);
}
@ -3263,7 +3269,8 @@ namespace stdex
/// \param[in] filename Filename
/// \param[in] mode Bitwise combination of mode_t flags
///
memory_file(_In_ const stdex::sstring& filename, _In_ int mode) : memory_file(filename.c_str(), mode) {}
template <class TR = std::char_traits<schar_t>, class AX = std::allocator<schar_t>>
memory_file(_In_ const std::basic_string<TR, AX>& filename, _In_ int mode) : memory_file(filename.c_str(), mode) {}
///
/// Copies content from another file
@ -3454,7 +3461,8 @@ namespace stdex
/// \param[in] filename Filename
/// \param[in] mode Bitwise combination of mode_t flags
///
void load(_In_ const stdex::sstring& filename, _In_ int mode)
template <class TR = std::char_traits<schar_t>, class AX = std::allocator<schar_t>>
void load(_In_ const std::basic_string<TR, AX>& filename, _In_ int mode)
{
load(filename.c_str(), mode);
}
@ -3491,7 +3499,8 @@ namespace stdex
/// \param[in] filename Filename
/// \param[in] mode Bitwise combination of mode_t flags
///
void save(_In_ const stdex::sstring& filename, _In_ int mode)
template <class TR = std::char_traits<schar_t>, class AX = std::allocator<schar_t>>
void save(_In_ const std::basic_string<TR, AX>& filename, _In_ int mode)
{
save(filename.c_str(), mode);
}
@ -3579,8 +3588,8 @@ namespace stdex
///
/// \return This stream
///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>>
memory_file& read_str(_Inout_ std::basic_string<_Elem, _Traits, _Ax>&data)
template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
memory_file& read_str(_Inout_ std::basic_string<T, TR, AX>&data)
{
#if SET_FILE_OP_TIMES
m_atime = time_point::now();
@ -3593,8 +3602,8 @@ namespace stdex
if (end_offset <= m_size) {
uint32_t num_chars = LE2HE(*reinterpret_cast<uint32_t*>(m_data + m_offset));
m_offset = end_offset;
end_offset = stdex::add(m_offset, stdex::mul(num_chars, sizeof(_Elem)));
_Elem* start = reinterpret_cast<_Elem*>(m_data + m_offset);
end_offset = stdex::add(m_offset, stdex::mul(num_chars, sizeof(T)));
T* start = reinterpret_cast<T*>(m_data + m_offset);
if (end_offset <= m_size) {
data.assign(start, start + num_chars);
m_offset = end_offset;
@ -3604,7 +3613,7 @@ namespace stdex
return *this;
}
if (end_offset <= m_size)
data.assign(start, reinterpret_cast<_Elem*>(m_data + m_size));
data.assign(start, reinterpret_cast<T*>(m_data + m_size));
}
m_offset = m_size;
m_state = state_t::eof;
@ -3750,8 +3759,8 @@ namespace stdex
///
/// \return This stream
///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>>
memory_file& write_str(_In_ const std::basic_string<_Elem, _Traits, _Ax>& data)
template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
memory_file& write_str(_In_ const std::basic_string<T, TR, AX>& data)
{
#if SET_FILE_OP_TIMES
m_atime = m_mtime = time_point::now();
@ -3761,7 +3770,7 @@ namespace stdex
size_t num_chars = data.size();
if (num_chars > UINT32_MAX)
throw std::invalid_argument("string too long");
size_t size_chars = num_chars * sizeof(_Elem);
size_t size_chars = num_chars * sizeof(T);
size_t size = sizeof(uint32_t) + size_chars;
size_t end_offset = m_offset + size;
if (end_offset > m_reserved) {
@ -4012,12 +4021,12 @@ namespace stdex
memory_file& operator <<(_In_ const wchar_t data) { return write_data(data); }
memory_file& operator >>(_Out_ wchar_t& data) { return read_data(data); }
#endif
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>>
memory_file& operator >>(_Out_ std::basic_string<_Elem, _Traits, _Ax>&data) { return read_str(data); }
template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
memory_file& operator >>(_Out_ std::basic_string<T, TR, AX>&data) { return read_str(data); }
template <class T>
memory_file& operator <<(_In_ const T * data) { return write_str(data); }
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>>
memory_file& operator <<(_In_ const std::basic_string<_Elem, _Traits, _Ax>& data) { return write_str(data); }
template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
memory_file& operator <<(_In_ const std::basic_string<T, TR, AX>& data) { return write_str(data); }
protected:
uint8_t* m_data; ///< file data

View File

@ -276,10 +276,10 @@ namespace stdex
///
/// \return Number of code units excluding zero terminator in the string.
///
template <class T, size_t SIZE>
inline size_t strnlen(_In_ const T (&str)[SIZE])
template <class T, size_t N>
inline size_t strnlen(_In_ const T (&str)[N])
{
return strnlen(str, SIZE);
return strnlen(str, N);
}
///
@ -343,12 +343,12 @@ namespace stdex
///
/// \return Offset to the first occurence of chr code unit or stdex::npos if not found.
///
template <class T, size_t SIZE>
template <class T, size_t N>
inline size_t strnchr(
_In_ const T (&str)[SIZE],
_In_ const T (&str)[N],
_In_ T chr)
{
return strnchr(str, SIZE, chr);
return strnchr(str, N, chr);
}
///
@ -417,12 +417,12 @@ namespace stdex
///
/// \return Offset to the last occurence of chr code unit or stdex::npos if not found.
///
template <class T, size_t SIZE>
template <class T, size_t N>
inline size_t strrnchr(
_In_ const T (&str)[SIZE],
_In_ const T (&str)[N],
_In_ T chr)
{
return strrnchr(str, SIZE, chr);
return strrnchr(str, N, chr);
}
///
@ -537,12 +537,12 @@ namespace stdex
///
/// \return Offset to the first occurence of chr code unit or stdex::npos if not found.
///
template <class T, size_t SIZE>
template <class T, size_t N>
inline size_t strnichr(
_In_ const T (&str)[SIZE],
_In_ const T (&str)[N],
_In_ T chr)
{
return strnichr(str, SIZE, chr);
return strnichr(str, N, chr);
}
///
@ -554,13 +554,13 @@ namespace stdex
///
/// \return Offset to the first occurence of chr code unit or stdex::npos if not found.
///
template <class T, size_t SIZE>
template <class T, size_t N>
inline size_t strnichr(
_In_ const T (&str)[SIZE],
_In_ const T (&str)[N],
_In_ T chr,
_In_ const std::locale& locale)
{
return strnichr(str, SIZE, chr, locale);
return strnichr(str, N, chr, locale);
}
///
@ -699,12 +699,12 @@ namespace stdex
///
/// \return Offset to the last occurence of chr code unit or stdex::npos if not found.
///
template <class T, size_t SIZE>
template <class T, size_t N>
inline size_t strrnichr(
_In_ const T (&str)[SIZE],
_In_ const T (&str)[N],
_In_ T chr)
{
return strrnichr(str, SIZE, chr);
return strrnichr(str, N, chr);
}
///
@ -716,13 +716,13 @@ namespace stdex
///
/// \return Offset to the last occurence of chr code unit or stdex::npos if not found.
///
template <class T, size_t SIZE>
template <class T, size_t N>
inline size_t strrnichr(
_In_ const T (&str)[SIZE],
_In_ const T (&str)[N],
_In_ T chr,
_In_ const std::locale& locale)
{
return strrnichr(str, SIZE, chr, locale);
return strrnichr(str, N, chr, locale);
}
///
@ -847,10 +847,10 @@ namespace stdex
///
/// \return `true` if all characters are white-space or `false` when any non-white-space character is found in string.
///
template <class T, size_t SIZE>
inline bool isblank(_In_ const T (&str)[SIZE])
template <class T, size_t N>
inline bool isblank(_In_ const T (&str)[N])
{
return isblank(str, SIZE);
return isblank(str, N);
}
///
@ -861,12 +861,12 @@ namespace stdex
///
/// \return `true` if all characters are white-space or `false` when any non-white-space character is found in string.
///
template <class T, size_t SIZE>
template <class T, size_t N>
inline bool isblank(
_In_ const T (&str)[SIZE],
_In_ const T (&str)[N],
_In_ const std::locale& locale)
{
return isblank(str, SIZE, locale);
return isblank(str, N, locale);
}
///
@ -981,12 +981,12 @@ namespace stdex
///
/// \return Negative if str1<str2; positive if str1>str2; zero if str1==str2
///
template <class T1, size_t SIZE1, class T2, size_t SIZE2>
template <class T1, size_t N1, class T2, size_t N2>
inline int strncmp(
_In_ const T1 (&str1)[SIZE1],
_In_ const T2 (&str2)[SIZE2])
_In_ const T1 (&str1)[N1],
_In_ const T2 (&str2)[N2])
{
return strncmp(str1, SIZE, str2, SIZE);
return strncmp(str1, N1, str2, N2);
}
///
@ -998,7 +998,9 @@ namespace stdex
/// \return Negative if str1<str2; positive if str1>str2; zero if str1==str2
///
template <class T1, class T2>
inline int strncmp(_In_ const std::basic_string_view<T1> str1, _In_ const std::basic_string_view<T2> str2)
inline int strncmp(
_In_ const std::basic_string_view<T1, std::char_traits<T1>> str1,
_In_ const std::basic_string_view<T2, std::char_traits<T2>> str2)
{
return strncmp(str1.data(), str1.size(), str2.data(), str2.size());
}
@ -1169,12 +1171,12 @@ namespace stdex
///
/// \return Negative if str1<str2; positive if str1>str2; zero if str1==str2
///
template <class T1, size_t SIZE1, class T2, size_t SIZE2>
template <class T1, size_t N1, class T2, size_t N2>
inline int strnicmp(
_In_ const T1 (&str1)[SIZE1],
_In_ const T2 (&str2)[SIZE2])
_In_ const T1 (&str1)[N1],
_In_ const T2 (&str2)[N2])
{
strnicmp(str1, SIZE, str2, SIZE2);
strnicmp(str1, N1, str2, N2);
}
///
@ -1186,13 +1188,13 @@ namespace stdex
///
/// \return Negative if str1<str2; positive if str1>str2; zero if str1==str2
///
template <class T1, size_t SIZE1, class T2, size_t SIZE2>
template <class T1, size_t N1, class T2, size_t N2>
inline int strnicmp(
_In_ const T1 (&str1)[SIZE1],
_In_ const T2 (&str2)[SIZE2],
_In_ const T1 (&str1)[N1],
_In_ const T2 (&str2)[N2],
_In_ const std::locale& locale)
{
strnicmp(str1, SIZE, str2, SIZE2, locale);
strnicmp(str1, N1, str2, N2, locale);
}
///
@ -1204,7 +1206,9 @@ namespace stdex
/// \return Negative if str1<str2; positive if str1>str2; zero if str1==str2
///
template <class T1, class T2>
inline int strnicmp(_In_ const std::basic_string_view<T1> str1, _In_ const std::basic_string_view<T2> str2)
inline int strnicmp(
_In_ const std::basic_string_view<T1, std::char_traits<T1>> str1,
_In_ const std::basic_string_view<T2, std::char_traits<T2>> str2)
{
return strnicmp(str1.data(), str1.size(), str2.data(), str2.size());
}
@ -1220,8 +1224,8 @@ namespace stdex
///
template <class T1, class T2>
inline int strnicmp(
_In_ const std::basic_string_view<T1> str1,
_In_ const std::basic_string_view<T2> str2,
_In_ const std::basic_string_view<T1, std::char_traits<T1>> str1,
_In_ const std::basic_string_view<T2, std::char_traits<T2>> str2,
_In_ const std::locale& locale)
{
return strnicmp(str1.data(), str1.size(), str2.data(), str2.size(), locale);
@ -1280,13 +1284,13 @@ namespace stdex
///
/// \return Negative if str1<str2; positive if str1>str2; zero if str1==str2
///
template <class T, size_t SIZE1, size_t SIZE2>
template <class T, size_t N1, size_t N2>
inline int strncoll(
_In_ const T (&str1)[SIZE1],
_In_ const T (&str2)[SIZE2],
_In_ const T (&str1)[N1],
_In_ const T (&str2)[N2],
_In_ const std::locale& locale)
{
return strncoll(str1, SIZE1, str2, SIZE2, locale);
return strncoll(str1, N1, str2, N2, locale);
}
///
@ -1370,12 +1374,12 @@ namespace stdex
///
/// \return Offset inside str where sample string is found; stdex::npos if not found
///
template <class T1, size_t SIZE1, class T2>
template <class T1, size_t N1, class T2>
inline size_t strnstr(
_In_ const T1 (&str)[SIZE1],
_In_ const T1 (&str)[N1],
_In_z_ const T2* sample)
{
return strnstr(str, SIZE, sample);
return strnstr(str, N1, sample);
}
///
@ -1388,7 +1392,7 @@ namespace stdex
///
template <class T1, class T2>
inline size_t strnstr(
_In_ const std::basic_string_view<T1> str,
_In_ const std::basic_string_view<T1, std::char_traits<T1>> str,
_In_z_ const T2* sample)
{
return strnstr(str.data(), str.size(), sample);
@ -1522,12 +1526,12 @@ namespace stdex
///
/// \return Offset inside str where sample string is found; stdex::npos if not found
///
template <class T1, size_t SIZE1, class T2>
template <class T1, size_t N1, class T2>
inline size_t strnistr(
_In_ const T1 (&str)[SIZE1],
_In_ const T1 (&str)[N1],
_In_z_ const T2* sample)
{
return strnistr(str, SIZE1, sample);
return strnistr(str, N1, sample);
}
///
@ -1539,13 +1543,13 @@ namespace stdex
///
/// \return Offset inside str where sample string is found; stdex::npos if not found
///
template <class T1, size_t SIZE1, class T2>
template <class T1, size_t N1, class T2>
inline size_t strnistr(
_In_ const T1 (&str)[SIZE1],
_In_ const T1 (&str)[N1],
_In_z_ const T2* sample,
_In_ const std::locale& locale)
{
return strnistr(str, SIZE1, sample, locale);
return strnistr(str, N1, sample, locale);
}
///
@ -1558,7 +1562,7 @@ namespace stdex
///
template <class T1, class T2>
inline size_t strnistr(
_In_ const std::basic_string_view<T1> str,
_In_ const std::basic_string_view<T1, std::char_traits<T1>> str,
_In_z_ const T2* sample)
{
return strnistr(str.data(), str.size(), sample);
@ -1575,7 +1579,7 @@ namespace stdex
///
template <class T1, class T2>
inline size_t strnistr(
_In_ const std::basic_string_view<T1> str,
_In_ const std::basic_string_view<T1, std::char_traits<T1>> str,
_In_z_ const T2* sample,
_In_ const std::locale& locale)
{
@ -1784,10 +1788,10 @@ namespace stdex
///
/// \return Pointer to duplicated string; or nullptr if str is nullptr. Use delete operator to free the memory.
///
template <class T, size_t SIZE>
inline _Check_return_ _Ret_maybenull_z_ T* strndup(_In_ const T (&str)[SIZE])
template <class T, size_t N>
inline _Check_return_ _Ret_maybenull_z_ T* strndup(_In_ const T (&str)[N])
{
return strndup(str, SIZE);
return strndup(str, N);
}
///
@ -1839,8 +1843,8 @@ namespace stdex
/// \param[in] dst Destination string
/// \param[in] src Source string. Must not be dst.data().
///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>>
inline void crlf2nl(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& dst, _In_z_ const _Elem* src)
template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
inline void crlf2nl(_Inout_ std::basic_string<T, TR, AX>& dst, _In_z_ const T* src)
{
_Assume_(src);
_Assume_(src != dst.data());
@ -1861,8 +1865,8 @@ namespace stdex
///
/// \param[in] str String to convert
///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>>
inline void crlf2nl(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& str)
template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
inline void crlf2nl(_Inout_ std::basic_string<T, TR, AX>& str)
{
size_t i, j, n;
for (i = j = 0, n = str.size(); j < n;) {
@ -2044,13 +2048,13 @@ namespace stdex
///
/// \return Binary integer value
///
template <class T, size_t SIZE, class T_bin>
template <class T, size_t N, class T_bin>
T_bin strtoint(
_In_ const T (&str)[SIZE],
_In_ const T (&str)[N],
_Out_opt_ size_t* end,
_In_ int radix)
{
return strtoint<T, T_bin>(str, SIZE, end, radix);
return strtoint<T, T_bin>(str, N, end, radix);
}
///
@ -2113,13 +2117,13 @@ namespace stdex
///
/// \return Binary integer value
///
template <class T, size_t SIZE, class T_bin>
template <class T, size_t N, class T_bin>
inline T_bin strtouint(
_In_ const T (&str)[SIZE],
_In_ const T (&str)[N],
_Out_opt_ size_t* end,
_In_ int radix)
{
return strtouint<T, T_bin>(str, SIZE, end, radix);
return strtouint<T, T_bin>(str, N, end, radix);
}
///
@ -2168,13 +2172,13 @@ namespace stdex
///
/// \return Binary integer value
///
template <class T, size_t SIZE>
template <class T, size_t N>
inline int32_t strto32(
_In_ const T (&str)[SIZE],
_In_ const T (&str)[N],
_Out_opt_ size_t* end,
_In_ int radix)
{
return strto32<T>(str, SIZE, end, radix);
return strto32<T>(str, N, end, radix);
}
///
@ -2223,13 +2227,13 @@ namespace stdex
///
/// \return Binary integer value
///
template <class T, size_t SIZE>
template <class T, size_t N>
inline int64_t strto64(
_In_ const T (&str)[SIZE],
_In_ const T (&str)[N],
_Out_opt_ size_t* end,
_In_ int radix)
{
return strto64<T>(str, SIZE, end, radix);
return strto64<T>(str, N, end, radix);
}
///
@ -2284,13 +2288,13 @@ namespace stdex
///
/// \return Binary integer value
///
template <class T, size_t SIZE>
template <class T, size_t N>
inline intptr_t strtoi(
_In_ const T (&str)[SIZE],
_In_ const T (&str)[N],
_Out_opt_ size_t* end,
_In_ int radix)
{
return strtoi<T>(str, SIZE, end, radix);
return strtoi<T>(str, N, end, radix);
}
///
@ -2340,13 +2344,13 @@ namespace stdex
///
/// \return Binary integer value
///
template <class T, size_t SIZE>
template <class T, size_t N>
inline uint32_t strtou32(
_In_ const T (&str)[SIZE],
_In_ const T (&str)[N],
_Out_opt_ size_t* end,
_In_ int radix)
{
return strtou32(str, SIZE, end, radix);
return strtou32(str, N, end, radix);
}
///
@ -2395,13 +2399,13 @@ namespace stdex
///
/// \return Binary integer value
///
template <class T, size_t SIZE>
template <class T, size_t N>
inline uint64_t strtou64(
_In_ const T (&str)[SIZE],
_In_ const T (&str)[N],
_Out_opt_ size_t* end,
_In_ int radix)
{
return strtou64<T>(str, SIZE, end, radix);
return strtou64<T>(str, N, end, radix);
}
///
@ -2456,13 +2460,13 @@ namespace stdex
///
/// \return Binary integer value
///
template <class T, size_t SIZE>
template <class T, size_t N>
inline size_t strtoui(
_In_ const T (&str)[SIZE],
_In_ const T (&str)[N],
_Out_opt_ size_t* end,
_In_ int radix)
{
return strtoui<T>(str, SIZE, end, radix);
return strtoui<T>(str, N, end, radix);
}
///
@ -2536,10 +2540,10 @@ namespace stdex
///
/// \return Number of appended code units
///
template<class _Elem, class _Traits, class _Ax>
inline size_t vappendf(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& str, _In_z_ _Printf_format_string_params_(2) const _Elem* format, _In_opt_ locale_t locale, _In_ va_list arg)
template<class T, class TR, class AX>
inline size_t vappendf(_Inout_ std::basic_string<T, TR, AX>& str, _In_z_ _Printf_format_string_params_(2) const T* format, _In_opt_ locale_t locale, _In_ va_list arg)
{
_Elem buf[1024 / sizeof(_Elem)];
T buf[1024 / sizeof(T)];
// Try with stack buffer first.
int count = vsnprintf(buf, _countof(buf) - 1, format, locale, arg);
@ -2548,9 +2552,9 @@ namespace stdex
str.append(buf, count);
return count;
}
for (size_t capacity = 2 * 1024 / sizeof(_Elem);; capacity *= 2) {
for (size_t capacity = 2 * 1024 / sizeof(T);; capacity *= 2) {
// Allocate on heap and retry.
auto buf_dyn = std::make_unique<_Elem[]>(capacity);
auto buf_dyn = std::make_unique<T[]>(capacity);
count = vsnprintf(buf_dyn.get(), capacity - 1, format, locale, arg);
if (count >= 0) {
str.append(buf_dyn.get(), count);
@ -2568,8 +2572,8 @@ namespace stdex
///
/// \return Number of appended code units
///
template<class _Elem, class _Traits, class _Ax>
inline size_t appendf(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& str, _In_z_ _Printf_format_string_params_(2) const _Elem* format, _In_opt_ locale_t locale, ...)
template<class T, class TR, class AX>
inline size_t appendf(_Inout_ std::basic_string<T, TR, AX>& str, _In_z_ _Printf_format_string_params_(2) const T* format, _In_opt_ locale_t locale, ...)
{
va_list arg;
va_start(arg, locale);
@ -2586,8 +2590,8 @@ namespace stdex
/// \param[in ] locale Stdlib locale used to perform formatting. Use `NULL` to use locale globally set by `setlocale()`.
/// \param[in ] arg Arguments to `format`
///
template<class _Elem, class _Traits, class _Ax>
inline void vsprintf(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& str, _In_z_ _Printf_format_string_params_(2) const _Elem* format, _In_opt_ locale_t locale, _In_ va_list arg)
template<class T, class TR, class AX>
inline void vsprintf(_Inout_ std::basic_string<T, TR, AX>& str, _In_z_ _Printf_format_string_params_(2) const T* format, _In_opt_ locale_t locale, _In_ va_list arg)
{
str.clear();
vappendf(str, format, locale, arg);
@ -2600,8 +2604,8 @@ namespace stdex
/// \param[in ] format String template using `printf()` style
/// \param[in ] locale Stdlib locale used to perform formatting. Use `NULL` to use locale globally set by `setlocale()`.
///
template<class _Elem, class _Traits, class _Ax>
inline void sprintf(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& str, _In_z_ _Printf_format_string_params_(2) const _Elem* format, _In_opt_ locale_t locale, ...)
template<class T, class TR, class AX>
inline void sprintf(_Inout_ std::basic_string<T, TR, AX>& str, _In_z_ _Printf_format_string_params_(2) const T* format, _In_opt_ locale_t locale, ...)
{
va_list arg;
va_start(arg, locale);
@ -2618,10 +2622,10 @@ namespace stdex
///
/// \returns Formatted string
///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>>
inline std::basic_string<_Elem, _Traits, _Ax> vsprintf(_In_z_ _Printf_format_string_params_(2) const _Elem* format, _In_opt_ locale_t locale, _In_ va_list arg)
template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
inline std::basic_string<T, TR, AX> vsprintf(_In_z_ _Printf_format_string_params_(2) const T* format, _In_opt_ locale_t locale, _In_ va_list arg)
{
std::basic_string<_Elem, _Traits, _Ax> str;
std::basic_string<T, TR, AX> str;
vappendf(str, format, locale, arg);
return str;
}
@ -2634,8 +2638,8 @@ namespace stdex
///
/// \returns Formatted string
///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>>
inline std::basic_string<_Elem, _Traits, _Ax> sprintf(_In_z_ _Printf_format_string_params_(2) const _Elem* format, _In_opt_ locale_t locale, ...)
template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
inline std::basic_string<T, TR, AX> sprintf(_In_z_ _Printf_format_string_params_(2) const T* format, _In_opt_ locale_t locale, ...)
{
va_list arg;
va_start(arg, locale);
@ -2672,10 +2676,10 @@ namespace stdex
/// \param[in ] time Time
/// \param[in ] locale Stdlib locale used to perform formatting. Use `NULL` to use locale globally set by `setlocale()`.
///
template<class _Elem, class _Traits, class _Ax>
inline void strcatftime(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& str, _In_z_ _Printf_format_string_ const _Elem* format, _In_ const struct tm* time, _In_opt_ locale_t locale)
template<class T, class TR, class AX>
inline void strcatftime(_Inout_ std::basic_string<T, TR, AX>& str, _In_z_ _Printf_format_string_ const T* format, _In_ const struct tm* time, _In_opt_ locale_t locale)
{
_Elem buf[1024 / sizeof(_Elem)];
T buf[1024 / sizeof(T)];
// Try with stack buffer first.
size_t count = strftime(buf, _countof(buf), format, time, locale);
@ -2684,9 +2688,9 @@ namespace stdex
str.append(buf, count);
}
else {
for (size_t capacity = 2 * 1024 / sizeof(_Elem);; capacity *= 2) {
for (size_t capacity = 2 * 1024 / sizeof(T);; capacity *= 2) {
// Allocate on heap and retry.
auto buf_dyn = std::make_unique<_Elem[]>(capacity);
auto buf_dyn = std::make_unique<T[]>(capacity);
count = strftime(buf_dyn.get(), capacity, format, time, locale);
if (count) {
str.append(buf_dyn.get(), count);
@ -2704,8 +2708,8 @@ namespace stdex
/// \param[in ] time Time
/// \param[in ] locale Stdlib locale used to perform formatting. Use `NULL` to use locale globally set by `setlocale()`.
///
template<class _Elem, class _Traits, class _Ax>
inline void strftime(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& str, _In_z_ _Printf_format_string_ const _Elem* format, _In_ const struct tm* time, _In_opt_ locale_t locale)
template<class T, class TR, class AX>
inline void strftime(_Inout_ std::basic_string<T, TR, AX>& str, _In_z_ _Printf_format_string_ const T* format, _In_ const struct tm* time, _In_opt_ locale_t locale)
{
str.clear();
strcatftime(str, format, time, locale);
@ -2721,10 +2725,10 @@ namespace stdex
///
/// \returns Formatted string
///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>>
inline std::basic_string<_Elem, _Traits, _Ax> strftime(_In_z_ _Printf_format_string_ const _Elem* format, _In_ const struct tm* time, _In_opt_ locale_t locale)
template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
inline std::basic_string<T, TR, AX> strftime(_In_z_ _Printf_format_string_ const T* format, _In_ const struct tm* time, _In_opt_ locale_t locale)
{
std::basic_string<_Elem, _Traits, _Ax> str;
std::basic_string<T, TR, AX> str;
strcatftime(str, format, time, locale);
return str;
}
@ -2792,8 +2796,8 @@ namespace stdex
///
/// \param[in,out] str String
///
template<class T, size_t SIZE>
inline void strlwr(_Inout_ T (&str)[SIZE])
template<class T, size_t N>
inline void strlwr(_Inout_ T (&str)[N])
{
strlwr(str, count);
}
@ -2804,8 +2808,8 @@ namespace stdex
/// \param[in,out] str String
/// \param[in] locale C++ locale to use
///
template<class T, size_t SIZE>
inline void strlwr(_Inout_ T (&str)[SIZE], _In_ const std::locale& locale)
template<class T, size_t N>
inline void strlwr(_Inout_ T (&str)[N], _In_ const std::locale& locale)
{
strlwr(str, count, locale);
}
@ -2815,8 +2819,8 @@ namespace stdex
///
/// \param[in,out] str String
///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>>
inline void strlwr(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& str)
template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
inline void strlwr(_Inout_ std::basic_string<T, TR, AX>& str)
{
for (auto& c : str)
c = tolower(c);
@ -2828,10 +2832,10 @@ namespace stdex
/// \param[in,out] str String
/// \param[in] locale C++ locale to use
///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>>
inline void strlwr(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& str, _In_ const std::locale& locale)
template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
inline void strlwr(_Inout_ std::basic_string<T, TR, AX>& str, _In_ const std::locale& locale)
{
const auto& ctype = std::use_facet<std::ctype<_Elem>>(locale);
const auto& ctype = std::use_facet<std::ctype<T>>(locale);
for (auto& c : str)
c = ctype.tolower(c);
}
@ -2899,10 +2903,10 @@ namespace stdex
///
/// \param[in,out] str String
///
template<class T, size_t SIZE>
inline void strupr(_Inout_ T (&str)[SIZE])
template<class T, size_t N>
inline void strupr(_Inout_ T (&str)[N])
{
return strupr(str, SIZE);
return strupr(str, N);
}
///
@ -2911,10 +2915,10 @@ namespace stdex
/// \param[in,out] str String
/// \param[in] locale C++ locale to use
///
template<class T, size_t SIZE>
inline void strupr(_Inout_ T (&str)[SIZE], _In_ const std::locale& locale)
template<class T, size_t N>
inline void strupr(_Inout_ T (&str)[N], _In_ const std::locale& locale)
{
return strupr(str, SIZE, locale);
return strupr(str, N, locale);
}
///
@ -2922,8 +2926,8 @@ namespace stdex
///
/// \param[in,out] str String
///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>>
inline void strupr(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& str)
template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
inline void strupr(_Inout_ std::basic_string<T, TR, AX>& str)
{
for (auto& c : str)
c = toupper(c);
@ -2935,10 +2939,10 @@ namespace stdex
/// \param[in,out] str String
/// \param[in] locale C++ locale to use
///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>>
inline void strupr(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& str, _In_ const std::locale& locale)
template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
inline void strupr(_Inout_ std::basic_string<T, TR, AX>& str, _In_ const std::locale& locale)
{
const auto& ctype = std::use_facet<std::ctype<_Elem>>(locale);
const auto& ctype = std::use_facet<std::ctype<T>>(locale);
for (auto& c : str)
c = ctype.toupper(c);
}
@ -3013,15 +3017,15 @@ namespace stdex
///
/// \param[in,out] s String to trim
///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>>
inline void ltrim(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& s)
template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
inline void ltrim(_Inout_ std::basic_string<T, TR, AX>& s)
{
s.erase(
s.begin(),
std::find_if(
s.begin(),
s.end(),
[&](_In_ _Elem ch) { return !isspace(ch); }));
[&](_In_ T ch) { return !isspace(ch); }));
}
///
@ -3030,16 +3034,16 @@ namespace stdex
/// \param[in,out] s String to trim
/// \param[in] locale C++ locale to use
///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>>
inline void ltrim(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& s, _In_ const std::locale& locale)
template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
inline void ltrim(_Inout_ std::basic_string<T, TR, AX>& s, _In_ const std::locale& locale)
{
const auto& ctype = std::use_facet<std::ctype<_Elem>>(locale);
const auto& ctype = std::use_facet<std::ctype<T>>(locale);
s.erase(
s.begin(),
std::find_if(
s.begin(),
s.end(),
[&](_In_ _Elem ch) { return !ctype.is(ctype.space, ch); }));
[&](_In_ T ch) { return !ctype.is(ctype.space, ch); }));
}
///
@ -3098,14 +3102,14 @@ namespace stdex
///
/// \param[in,out] s String to trim
///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>>
static inline void rtrim(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& s)
template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
static inline void rtrim(_Inout_ std::basic_string<T, TR, AX>& s)
{
s.erase(
std::find_if(
s.rbegin(),
s.rend(),
[&](_In_ _Elem ch) { return !isspace(ch); }).base(),
[&](_In_ T ch) { return !isspace(ch); }).base(),
s.end());
}
@ -3115,15 +3119,15 @@ namespace stdex
/// \param[in,out] s String to trim
/// \param[in] locale C++ locale to use
///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>>
static inline void rtrim(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& s, _In_ const std::locale& locale)
template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
static inline void rtrim(_Inout_ std::basic_string<T, TR, AX>& s, _In_ const std::locale& locale)
{
const auto& ctype = std::use_facet<std::ctype<_Elem>>(locale);
const auto& ctype = std::use_facet<std::ctype<T>>(locale);
s.erase(
std::find_if(
s.rbegin(),
s.rend(),
[&](_In_ _Elem ch) { return !ctype.is(ctype.space, ch); }).base(),
[&](_In_ T ch) { return !ctype.is(ctype.space, ch); }).base(),
s.end());
}
@ -3164,10 +3168,10 @@ namespace stdex
///
/// \param[in,out] s String to trim
///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>>
static inline void trim(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& s)
template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
static inline void trim(_Inout_ std::basic_string<T, TR, AX>& s)
{
auto nonspace = [&](_In_ _Elem ch) { return !isspace(ch); };
auto nonspace = [&](_In_ T ch) { return !isspace(ch); };
s.erase(
s.begin(),
std::find_if(
@ -3188,11 +3192,11 @@ namespace stdex
/// \param[in,out] s String to trim
/// \param[in] locale C++ locale to use
///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>>
static inline void trim(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& s, _In_ const std::locale& locale)
template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
static inline void trim(_Inout_ std::basic_string<T, TR, AX>& s, _In_ const std::locale& locale)
{
const auto& ctype = std::use_facet<std::ctype<_Elem>>(locale);
auto nonspace = [&](_In_ _Elem ch) { return !ctype.is(ctype.space, ch); };
const auto& ctype = std::use_facet<std::ctype<T>>(locale);
auto nonspace = [&](_In_ T ch) { return !ctype.is(ctype.space, ch); };
s.erase(
s.begin(),
std::find_if(

View File

@ -62,11 +62,13 @@ namespace stdex
constexpr charset_id system_charset = charset_id::system;
#endif
/// <summary>
///
/// Parses charset name and returns matching charset code
/// </summary>
/// <param name="name">Charset name</param>
/// <returns>Charset code or `charset_id::system` if match not found</returns>
///
/// \param[in] name Charset name
///
/// \returns Charset code or `charset_id::system` if match not found
///
inline charset_id charset_from_name(_In_z_ const char* name)
{
struct charset_less {
@ -114,13 +116,15 @@ namespace stdex
return charset_id::system;
}
/// <summary>
///
/// Parses charset name and returns matching charset code
/// </summary>
/// <param name="name">Charset name</param>
/// <returns>Charset code or `charset_id::system` if match not found</returns>
template <class _Traits = std::char_traits<char>, class _Alloc = std::allocator<char>>
charset_id charset_from_name(_In_ const std::basic_string<char, _Traits, _Alloc>& name)
///
/// \param[in] name Charset name
///
/// \returns Charset code or `charset_id::system` if match not found
///
template <class TR = std::char_traits<char>, class AX = std::allocator<char>>
charset_id charset_from_name(_In_ const std::basic_string<char, TR, AX>& name)
{
return charset_from_name(name.c_str());
}
@ -166,9 +170,9 @@ namespace stdex
/// \param[in] src String to convert
/// \param[in] count_src String to convert code unit limit
///
template <class _Traits_to = std::char_traits<T_to>, class _Alloc_to = std::allocator<T_to>>
template <class TR_to = std::char_traits<T_to>, class AX_to = std::allocator<T_to>>
void strcat(
_Inout_ std::basic_string<T_to, _Traits_to, _Alloc_to>& dst,
_Inout_ std::basic_string<T_to, TR_to, AX_to>& dst,
_In_reads_or_z_opt_(count_src) const T_from* src, _In_ size_t count_src)
{
_Assume_(src || !count_src);
@ -308,9 +312,9 @@ namespace stdex
/// \param[in,out] dst String to append converted string to
/// \param[in] src Zero-terminated string to convert
///
template <class _Traits_to = std::char_traits<T_to>, class _Alloc_to = std::allocator<T_to>>
template <class TR_to = std::char_traits<T_to>, class AX_to = std::allocator<T_to>>
void strcat(
_Inout_ std::basic_string<T_to, _Traits_to, _Alloc_to>& dst,
_Inout_ std::basic_string<T_to, TR_to, AX_to>& dst,
_In_z_ const T_from* src)
{
strcat(dst, src, SIZE_MAX);
@ -322,10 +326,10 @@ namespace stdex
/// \param[in,out] dst String to append converted string to
/// \param[in] src String to convert
///
template <class _Traits_to = std::char_traits<T_to>, class _Alloc_to = std::allocator<T_to>, class _Traits_from = std::char_traits<T_from>, class _Alloc_from = std::allocator<T_from>>
template <class TR_to = std::char_traits<T_to>, class AX_to = std::allocator<T_to>>
void strcat(
_Inout_ std::basic_string<T_to, _Traits_to, _Alloc_to>& dst,
_In_ const std::basic_string<T_from, _Traits_from, _Alloc_from>& src)
_Inout_ std::basic_string<T_to, TR_to, AX_to>& dst,
_In_ const std::basic_string_view<T_from, std::char_traits<T_from>> src)
{
strcat(dst, src.data(), src.size());
}
@ -337,9 +341,9 @@ namespace stdex
/// \param[in] src String to convert
/// \param[in] count_src String to convert code unit limit
///
template <class _Traits_to = std::char_traits<T_to>, class _Alloc_to = std::allocator<T_to>>
template <class TR_to = std::char_traits<T_to>, class AX_to = std::allocator<T_to>>
void strcpy(
_Inout_ std::basic_string<T_to, _Traits_to, _Alloc_to>& dst,
_Inout_ std::basic_string<T_to, TR_to, AX_to>& dst,
_In_reads_or_z_opt_(count_src) const T_from* src, _In_ size_t count_src)
{
dst.clear();
@ -352,9 +356,9 @@ namespace stdex
/// \param[in,out] dst String to write converted string to
/// \param[in] src Zero-terminated string to convert
///
template <class _Traits_to = std::char_traits<T_to>, class _Alloc_to = std::allocator<T_to>>
template <class TR_to = std::char_traits<T_to>, class AX_to = std::allocator<T_to>>
void strcpy(
_Inout_ std::basic_string<T_to, _Traits_to, _Alloc_to>& dst,
_Inout_ std::basic_string<T_to, TR_to, AX_to>& dst,
_In_z_ const T_from* src)
{
strcpy(dst, src, SIZE_MAX);
@ -366,10 +370,10 @@ namespace stdex
/// \param[in,out] dst String to write converted string to
/// \param[in] src String to convert
///
template <class _Traits_to = std::char_traits<T_to>, class _Alloc_to = std::allocator<T_to>, class _Traits_from = std::char_traits<T_from>, class _Alloc_from = std::allocator<T_from>>
template <class TR_to = std::char_traits<T_to>, class AX_to = std::allocator<T_to>>
void strcpy(
_Inout_ std::basic_string<T_to, _Traits_to, _Alloc_to>& dst,
_In_ const std::basic_string<T_from, _Traits_from, _Alloc_from>& src)
_Inout_ std::basic_string<T_to, TR_to, AX_to>& dst,
_In_ const std::basic_string_view<T_from, std::char_traits<T_from>> src)
{
strcpy(dst, src.data(), src.size());
}
@ -380,10 +384,10 @@ namespace stdex
/// \param[in] src String to convert
/// \param[in] count_src String to convert code unit limit
///
template <class _Traits_to = std::char_traits<T_to>, class _Alloc_to = std::allocator<T_to>>
std::basic_string<T_to, _Traits_to, _Alloc_to> convert(_In_reads_or_z_opt_(count_src) const T_from* src, _In_ size_t count_src)
template <class TR_to = std::char_traits<T_to>, class AX_to = std::allocator<T_to>>
std::basic_string<T_to, TR_to, AX_to> convert(_In_reads_or_z_opt_(count_src) const T_from* src, _In_ size_t count_src)
{
std::basic_string<T_to, _Traits_to, _Alloc_to> dst;
std::basic_string<T_to, TR_to, AX_to> dst;
strcat(dst, src, count_src);
return dst;
}
@ -393,8 +397,8 @@ namespace stdex
///
/// \param[in] src Zero-terminated string to convert
///
template <class _Traits_to = std::char_traits<T_to>, class _Alloc_to = std::allocator<T_to>>
std::basic_string<T_to, _Traits_to, _Alloc_to> convert(_In_z_ const T_from* src)
template <class TR_to = std::char_traits<T_to>, class AX_to = std::allocator<T_to>>
std::basic_string<T_to, TR_to, AX_to> convert(_In_z_ const T_from* src)
{
return convert(src, SIZE_MAX);
}
@ -404,8 +408,8 @@ namespace stdex
///
/// \param[in] src String to convert
///
template <class _Traits_to = std::char_traits<T_to>, class _Alloc_to = std::allocator<T_to>, class _Traits_from = std::char_traits<T_from>, class _Alloc_from = std::allocator<T_from>>
std::basic_string<T_to, _Traits_to, _Alloc_to> convert(_In_ const std::basic_string<T_from, _Traits_from, _Alloc_from>& src)
template <class TR_to = std::char_traits<T_to>, class AX_to = std::allocator<T_to>>
std::basic_string<T_to, TR_to, AX_to> convert(_In_ const std::basic_string_view<T_from, std::char_traits<T_from>> src)
{
return convert(src.data(), src.size());
}
@ -477,20 +481,22 @@ namespace stdex
/// \param[in] count_src String character count limit
/// \param[in] charset Charset (stdex::charset_id::system - system default)
///
template <class TR_to = std::char_traits<wchar_t>, class AX_to = std::allocator<wchar_t>>
#ifndef _WIN32
_Deprecated_("For better performance, consider a reusable charset_encoder")
#endif
inline void strcat(
_Inout_ std::wstring& dst,
_Inout_ std::basic_string<wchar_t, TR_to, AX_to>& dst,
_In_reads_or_z_opt_(count_src) const char* src, _In_ size_t count_src,
_In_ charset_id charset = charset_id::system)
{
charset_encoder<char, wchar_t>(charset, wchar_t_charset).strcat(dst, src, count_src);
}
template <class TR_to = std::char_traits<wchar_t>, class AX_to = std::allocator<wchar_t>>
_Deprecated_("Use stdex::strcat")
inline void str2wstr(
_Inout_ std::wstring& dst,
_Inout_ std::basic_string<wchar_t, TR_to, AX_to>& dst,
_In_reads_or_z_opt_(count_src) const char* src, _In_ size_t count_src,
_In_ charset_id charset = charset_id::system)
{
@ -506,21 +512,23 @@ namespace stdex
/// \param[in] src String
/// \param[in] charset Charset (stdex::charset_id::system - system default)
///
template <class TR_to = std::char_traits<wchar_t>, class AX_to = std::allocator<wchar_t>>
#ifndef _WIN32
_Deprecated_("For better performance, consider a reusable charset_encoder")
#endif
inline void strcat(
_Inout_ std::wstring& dst,
_In_ const std::string_view src,
_Inout_ std::basic_string<wchar_t, TR_to, AX_to>& dst,
_In_ const std::basic_string_view<char, std::char_traits<char>> src,
_In_ charset_id charset = charset_id::system)
{
strcat(dst, src.data(), src.size(), charset);
}
template <class TR_to = std::char_traits<wchar_t>, class AX_to = std::allocator<wchar_t>>
_Deprecated_("Use stdex::strcat")
inline void str2wstr(
_Inout_ std::wstring& dst,
_In_ const std::string_view src,
_Inout_ std::basic_string<wchar_t, TR_to, AX_to>& dst,
_In_ const std::basic_string_view<char, std::char_traits<char>> src,
_In_ charset_id charset = charset_id::system)
{
strcat(dst, src, charset);
@ -536,11 +544,12 @@ namespace stdex
/// \param[in] count_src String character count limit
/// \param[in] charset Charset (stdex::charset_id::system - system default)
///
template <class TR_to = std::char_traits<wchar_t>, class AX_to = std::allocator<wchar_t>>
#ifndef _WIN32
_Deprecated_("For better performance, consider a reusable charset_encoder")
#endif
inline void strcpy(
_Inout_ std::wstring& dst,
_Inout_ std::basic_string<wchar_t, TR_to, AX_to>& dst,
_In_reads_or_z_opt_(count_src) const char* src, _In_ size_t count_src,
_In_ charset_id charset = charset_id::system)
{
@ -557,12 +566,13 @@ namespace stdex
/// \param[in] src String
/// \param[in] charset Charset (stdex::charset_id::system - system default)
///
template <class TR_to = std::char_traits<wchar_t>, class AX_to = std::allocator<wchar_t>>
#ifndef _WIN32
_Deprecated_("For better performance, consider a reusable charset_encoder")
#endif
inline void strcpy(
_Inout_ std::wstring& dst,
_In_ const std::string_view src,
_Inout_ std::basic_string<wchar_t, TR_to, AX_to>& dst,
_In_ const std::basic_string_view<char, std::char_traits<char>> src,
_In_ charset_id charset = charset_id::system)
{
strcpy(dst, src.data(), src.size(), charset);
@ -627,7 +637,7 @@ namespace stdex
_Deprecated_("For better performance, consider a reusable charset_encoder")
#endif
inline std::wstring str2wstr(
_In_ const std::string_view src,
_In_ const std::basic_string_view<char, std::char_traits<char>> src,
_In_ charset_id charset = charset_id::system)
{
return str2wstr(src.data(), src.size(), charset);
@ -643,20 +653,22 @@ namespace stdex
/// \param[in] count_src Unicode string character count limit
/// \param[in] charset Charset (stdex::charset_id::system - system default)
///
template <class TR_to = std::char_traits<char>, class AX_to = std::allocator<char>>
#ifndef _WIN32
_Deprecated_("For better performance, consider a reusable charset_encoder")
#endif
inline void strcat(
_Inout_ std::string& dst,
_Inout_ std::basic_string<char, TR_to, AX_to>& dst,
_In_reads_or_z_opt_(count_src) const wchar_t* src, _In_ size_t count_src,
_In_ charset_id charset = charset_id::system)
{
charset_encoder<wchar_t, char>(wchar_t_charset, charset).strcat(dst, src, count_src);
}
template <class TR_to = std::char_traits<char>, class AX_to = std::allocator<char>>
_Deprecated_("Use stdex::strcat")
inline void wstr2str(
_Inout_ std::string& dst,
_Inout_ std::basic_string<char, TR_to, AX_to>& dst,
_In_reads_or_z_opt_(count_src) const wchar_t* src, _In_ size_t count_src,
_In_ charset_id charset = charset_id::system)
{
@ -672,21 +684,23 @@ namespace stdex
/// \param[in] src Unicode string
/// \param[in] charset Charset (stdex::charset_id::system - system default)
///
template <class TR_to = std::char_traits<char>, class AX_to = std::allocator<char>>
#ifndef _WIN32
_Deprecated_("For better performance, consider a reusable charset_encoder")
#endif
inline void strcat(
_Inout_ std::string& dst,
_In_ const std::wstring_view src,
_Inout_ std::basic_string<char, TR_to, AX_to>& dst,
_In_ const std::basic_string_view<wchar_t, std::char_traits<wchar_t>> src,
_In_ charset_id charset = charset_id::system)
{
strcat(dst, src.data(), src.size(), charset);
}
template <class TR_to = std::char_traits<char>, class AX_to = std::allocator<char>>
_Deprecated_("Use stdex::strcat")
inline void wstr2str(
_Inout_ std::string& dst,
_In_ const std::wstring_view src,
_Inout_ std::basic_string<char, TR_to, AX_to>& dst,
_In_ const std::basic_string_view<wchar_t, std::char_traits<wchar_t>> src,
_In_ charset_id charset = charset_id::system)
{
strcat(dst, src, charset);
@ -702,11 +716,12 @@ namespace stdex
/// \param[in] count_src Unicode string character count limit
/// \param[in] charset Charset (stdex::charset_id::system - system default)
///
template <class TR_to = std::char_traits<char>, class AX_to = std::allocator<char>>
#ifndef _WIN32
_Deprecated_("For better performance, consider a reusable charset_encoder")
#endif
inline void strcpy(
_Inout_ std::string& dst,
_Inout_ std::basic_string<char, TR_to, AX_to>& dst,
_In_reads_or_z_opt_(count_src) const wchar_t* src, _In_ size_t count_src,
_In_ charset_id charset = charset_id::system)
{
@ -723,12 +738,13 @@ namespace stdex
/// \param[in] src Unicode string
/// \param[in] charset Charset (stdex::charset_id::system - system default)
///
template <class TR_to = std::char_traits<char>, class AX_to = std::allocator<char>>
#ifndef _WIN32
_Deprecated_("For better performance, consider a reusable charset_encoder")
#endif
inline void strcpy(
_Inout_ std::string& dst,
_In_ const std::wstring_view src,
_Inout_ std::basic_string<char, TR_to, AX_to>& dst,
_In_ const std::basic_string_view<wchar_t, std::char_traits<wchar_t>> src,
_In_ charset_id charset = charset_id::system)
{
strcpy(dst, src.data(), src.size(), charset);
@ -793,7 +809,7 @@ namespace stdex
_Deprecated_("For better performance, consider a reusable charset_encoder")
#endif
inline std::string wstr2str(
_In_ const std::wstring_view src,
_In_ const std::basic_string_view<wchar_t, std::char_traits<wchar_t>> src,
_In_ charset_id charset = charset_id::system)
{
return wstr2str(src.data(), src.size(), charset);
@ -809,9 +825,9 @@ namespace stdex
///
/// \return Number of code units excluding zero terminator in the dst string after the operation.
///
template <class _Traits = std::char_traits<wchar_t>, class _Alloc = std::allocator<wchar_t>>
template <class TR = std::char_traits<wchar_t>, class AX = std::allocator<wchar_t>>
size_t normalizecat(
_Inout_ std::basic_string<wchar_t, _Traits, _Alloc>& dst,
_Inout_ std::basic_string<wchar_t, TR, AX>& dst,
_In_reads_or_z_opt_(count_src) const wchar_t* src, _In_ size_t count_src)
{
count_src = strnlen(src, count_src);
@ -836,12 +852,12 @@ namespace stdex
///
/// \return Number of code units excluding zero terminator in the dst string after the operation.
///
template <size_t _Size, class _Traits = std::char_traits<wchar_t>, class _Alloc = std::allocator<wchar_t>>
template <size_t N, class TR = std::char_traits<wchar_t>, class AX = std::allocator<wchar_t>>
size_t normalizecat(
_Inout_ std::basic_string<wchar_t, _Traits, _Alloc>& dst,
_In_ const wchar_t (&src)[_Size])
_Inout_ std::basic_string<wchar_t, TR, AX>& dst,
_In_ const wchar_t (&src)[N])
{
return normalizecat(dst, src, _Size);
return normalizecat(dst, src, N);
}
///
@ -852,10 +868,10 @@ namespace stdex
///
/// \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>>
template <class TR_dst = std::char_traits<wchar_t>, class AX_dst = std::allocator<wchar_t>>
size_t normalizecat(
_Inout_ std::basic_string<wchar_t, _Traits_dst, _Alloc_dst>& dst,
_In_ const std::wstring_view src)
_Inout_ std::basic_string<wchar_t, TR_dst, AX_dst>& dst,
_In_ const std::basic_string_view<wchar_t, std::char_traits<wchar_t>> src)
{
return normalizecat(dst, src.data(), src.size());
}
@ -869,9 +885,9 @@ namespace stdex
///
/// \return Number of code units excluding zero terminator in the dst string after the operation.
///
template <class _Traits = std::char_traits<wchar_t>, class _Alloc = std::allocator<wchar_t>>
template <class TR = std::char_traits<wchar_t>, class AX = std::allocator<wchar_t>>
size_t normalize(
_Inout_ std::basic_string<wchar_t, _Traits, _Alloc>& dst,
_Inout_ std::basic_string<wchar_t, TR, AX>& dst,
_In_reads_or_z_opt_(count_src) const wchar_t* src, _In_ size_t count_src)
{
dst.clear();
@ -886,12 +902,12 @@ namespace stdex
///
/// \return Number of code units excluding zero terminator in the dst string after the operation.
///
template <size_t _Size, class _Traits = std::char_traits<wchar_t>, class _Alloc = std::allocator<wchar_t>>
template <size_t N, class TR = std::char_traits<wchar_t>, class AX = std::allocator<wchar_t>>
size_t normalize(
_Inout_ std::basic_string<wchar_t, _Traits, _Alloc>& dst,
_In_ const wchar_t(&src)[_Size])
_Inout_ std::basic_string<wchar_t, TR, AX>& dst,
_In_ const wchar_t(&src)[N])
{
return normalize(dst, src, _Size);
return normalize(dst, src, N);
}
///
@ -902,10 +918,10 @@ namespace stdex
///
/// \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>>
template <class TR_dst = std::char_traits<wchar_t>, class AX_dst = std::allocator<wchar_t>>
size_t normalize(
_Inout_ std::basic_string<wchar_t, _Traits_dst, _Alloc_dst>& dst,
_In_ const std::wstring_view src)
_Inout_ std::basic_string<wchar_t, TR_dst, AX_dst>& dst,
_In_ const std::basic_string_view<wchar_t, std::char_traits<wchar_t>> src)
{
return normalize(dst, src.data(), src.size());
}
@ -932,11 +948,11 @@ namespace stdex
///
/// \return Normalized string
///
template <size_t _Size>
std::wstring normalize(_In_ const wchar_t(&src)[_Size])
template <size_t N>
std::wstring normalize(_In_ const wchar_t(&src)[N])
{
std::wstring dst;
normalizecat(dst, src, _Size);
normalizecat(dst, src, N);
return dst;
}
@ -947,7 +963,7 @@ namespace stdex
///
/// \return Normalized string
///
inline std::wstring normalize(_In_ const std::wstring_view src)
inline std::wstring normalize(_In_ const std::basic_string_view<wchar_t, std::char_traits<wchar_t>> src)
{
std::wstring dst;
normalizecat(dst, src.data(), src.size());