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

View File

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

View File

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

View File

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

View File

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

View File

@ -24,8 +24,8 @@ namespace stdex {
/// - \c true when succeeded /// - \c true when succeeded
/// - \c false otherwise /// - \c false otherwise
/// ///
template <class T_ID> 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) _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) { if (end == (std::streamoff)-1 || stream.tellg() < end) {
stream.read((char*)&id, sizeof(id)); stream.read((char*)&id, sizeof(id));
@ -45,8 +45,8 @@ namespace stdex {
/// - \c true when succeeded /// - \c true when succeeded
/// - \c false otherwise /// - \c false otherwise
/// ///
template <class T_ID> 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) _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) { if (end == stdex::stream::fpos_max || stream.tell() < end) {
stream >> id; stream >> id;
@ -60,12 +60,12 @@ namespace stdex {
/// ///
/// \param[in] size Actual data size /// \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> template <class T_size, T_size N_align>
T_SIZE padding(_In_ T_SIZE size) 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 true when successful
/// - \c false otherwise /// - \c false otherwise
/// ///
template <class T_SIZE, T_SIZE ALIGN> template <class T_size, T_size N_align>
bool ignore(_In_ std::istream& stream) bool ignore(_In_ std::istream& stream)
{ {
// Read record size. // Read record size.
T_SIZE size; T_size size;
stream.read((char*)&size, sizeof(size)); stream.read((char*)&size, sizeof(size));
if (!stream.good()) _Unlikely_ return false; if (!stream.good()) _Unlikely_ return false;
// Skip the record data. // Skip the record data.
size += padding<T_SIZE, ALIGN>(size); size += padding<T_size, N_align>(size);
stream.ignore(size); stream.ignore(size);
if (!stream.good()) _Unlikely_ return false; if (!stream.good()) _Unlikely_ return false;
@ -102,16 +102,16 @@ namespace stdex {
/// - \c true when successful /// - \c true when successful
/// - \c false otherwise /// - \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) bool ignore(_In_ stdex::stream::basic& stream)
{ {
// Read record size. // Read record size.
T_SIZE size; T_size size;
stream >> size; stream >> size;
if (!stream.ok()) _Unlikely_ return false; if (!stream.ok()) _Unlikely_ return false;
// Skip the record data. // Skip the record data.
size += padding<T_SIZE, ALIGN>(size); size += padding<T_size, N_align>(size);
stream.skip(size); stream.skip(size);
if (!stream.ok()) _Unlikely_ return false; if (!stream.ok()) _Unlikely_ return false;
@ -129,10 +129,10 @@ namespace stdex {
/// - \c true when found /// - \c true when found
/// - \c false otherwise /// - \c false otherwise
/// ///
template <class T_ID, class T_SIZE, T_SIZE ALIGN> 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) 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) { while (end == (std::streamoff)-1 || stream.tellg() < end) {
stream.read((char*)&_id, sizeof(_id)); stream.read((char*)&_id, sizeof(_id));
if (!stream.good()) _Unlikely_ return false; if (!stream.good()) _Unlikely_ return false;
@ -140,7 +140,7 @@ namespace stdex {
// The record was found. // The record was found.
return true; return true;
} else } else
ignore<T_SIZE, ALIGN>(stream); ignore<T_size, N_align>(stream);
} }
return false; return false;
} }
@ -156,10 +156,10 @@ namespace stdex {
/// - \c true when found /// - \c true when found
/// - \c false otherwise /// - \c false otherwise
/// ///
template <class T_ID, class T_SIZE, T_SIZE ALIGN> 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) 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) { while (end == stdex::stream::fpos_max || stream.tell() < end) {
stream >> _id; stream >> _id;
if (!stream.ok()) _Unlikely_ return false; if (!stream.ok()) _Unlikely_ return false;
@ -167,7 +167,7 @@ namespace stdex {
// The record was found. // The record was found.
return true; return true;
} else } else
ignore<T_SIZE, ALIGN>(stream); ignore<T_size, N_align>(stream);
} }
return false; return false;
} }
@ -180,8 +180,8 @@ namespace stdex {
/// ///
/// \returns Position of the record header start in \p stream. Save for later \c close call. /// \returns Position of the record header start in \p stream. Save for later \c close call.
/// ///
template <class T_ID, class T_SIZE> template <class T_id, class T_size>
std::streamoff open(_In_ std::ostream& stream, _In_ T_ID id) std::streamoff open(_In_ std::ostream& stream, _In_ T_id id)
{ {
std::streamoff start = stream.tellp(); std::streamoff start = stream.tellp();
@ -191,7 +191,7 @@ namespace stdex {
// Write 0 as a placeholder for data size. // Write 0 as a placeholder for data size.
if (stream.fail()) _Unlikely_ return (std::streamoff)-1; if (stream.fail()) _Unlikely_ return (std::streamoff)-1;
T_SIZE size = 0; T_size size = 0;
stream.write((const char*)&size, sizeof(size)); stream.write((const char*)&size, sizeof(size));
return start; return start;
@ -205,8 +205,8 @@ namespace stdex {
/// ///
/// \returns Position of the record header start in \p stream. Save for later \c close call. /// \returns Position of the record header start in \p stream. Save for later \c close call.
/// ///
template <class T_ID, class T_SIZE> template <class T_id, class T_size>
stdex::stream::fpos_t open(_In_ stdex::stream::basic_file& stream, _In_ T_ID id) stdex::stream::fpos_t open(_In_ stdex::stream::basic_file& stream, _In_ T_id id)
{ {
auto start = stream.tell(); auto start = stream.tell();
@ -214,7 +214,7 @@ namespace stdex {
stream << id; stream << id;
// Write 0 as a placeholder for data size. // Write 0 as a placeholder for data size.
stream << static_cast<T_SIZE>(0); stream << static_cast<T_size>(0);
return start; return start;
} }
@ -227,24 +227,24 @@ namespace stdex {
/// ///
/// \returns Position of the record end in \p stream /// \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 close(_In_ std::ostream& stream, _In_ std::streamoff start)
{ {
std::streamoff end = stream.tellp(); std::streamoff end = stream.tellp();
T_SIZE T_size
size = static_cast<T_SIZE>(end - start - sizeof(T_ID) - sizeof(T_SIZE)), size = static_cast<T_size>(end - start - sizeof(T_id) - sizeof(T_size)),
remainder = padding<T_SIZE, ALIGN>(size); remainder = padding<T_size, N_align>(size);
if (remainder) { if (remainder) {
// Append padding. // Append padding.
static const char padding[ALIGN] = {}; static const char padding[N_align] = {};
stream.write(padding, remainder); stream.write(padding, remainder);
end += remainder; end += remainder;
} }
// Update the data size. // Update the data size.
if (stream.fail()) _Unlikely_ return (std::streamoff)-1; 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.write(reinterpret_cast<const char*>(&size), sizeof(size));
stream.seekp(end); stream.seekp(end);
@ -259,24 +259,24 @@ namespace stdex {
/// ///
/// \returns Position of the record end in \p stream /// \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) stdex::stream::fpos_t close(_In_ stdex::stream::basic_file& stream, _In_ stdex::stream::fpos_t start)
{ {
auto end = stream.tell(); auto end = stream.tell();
T_SIZE T_size
size = static_cast<T_SIZE>(end - start - sizeof(T_ID) - sizeof(T_SIZE)), size = static_cast<T_size>(end - start - sizeof(T_id) - sizeof(T_size)),
remainder = padding<T_SIZE, ALIGN>(size); remainder = padding<T_size, N_align>(size);
if (remainder) { if (remainder) {
// Append padding. // Append padding.
static const char padding[ALIGN] = {}; static const char padding[N_align] = {};
stream.write_array(padding, sizeof(char), remainder); stream.write_array(padding, sizeof(char), remainder);
end += remainder; end += remainder;
} }
// Update the data size. // Update the data size.
if (!stream.ok()) _Unlikely_ return stdex::stream::fpos_max; if (!stream.ok()) _Unlikely_ return stdex::stream::fpos_max;
stream.seek(start + sizeof(T_ID)); stream.seek(start + sizeof(T_id));
stream << size; stream << size;
stream.seek(end); stream.seek(end);
@ -286,7 +286,7 @@ namespace stdex {
/// ///
/// Helper class for read/write of records to/from memory /// 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 class record
{ {
public: public:
@ -307,7 +307,7 @@ namespace stdex {
/// ///
/// Returns record id /// Returns record id
/// ///
static constexpr T_ID id() static constexpr T_id id()
{ {
return ID; return ID;
} }
@ -319,7 +319,7 @@ namespace stdex {
/// ///
/// \returns A const reference to this struct /// \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; data = r.data;
return *this; return *this;
@ -334,7 +334,7 @@ namespace stdex {
/// ///
static std::streamoff open(_In_ std::ostream& stream) 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) 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) 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) 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) 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) 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 T &data; ///< Record data reference
@ -415,7 +415,7 @@ namespace stdex {
/// ///
/// \returns The stream \p stream /// \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. // 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 /// \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. // 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 /// \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. // 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 /// \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. // 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. // Read data size.
T_SIZE size; T_size size;
stream.read((char*)&size, sizeof(size)); stream.read((char*)&size, sizeof(size));
if (!stream.good()) _Unlikely_ return stream; 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. 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; if (!stream.good()) _Unlikely_ return stream;
size += padding<T_SIZE, ALIGN>(size); size += padding<T_size, N_align>(size);
stream.seekg(start + size); stream.seekg(start + size);
return stream; return stream;
@ -506,12 +506,12 @@ namespace stdex {
/// ///
/// \returns The stream \p stream /// \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. // 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. // Read data size.
T_SIZE size; T_size size;
stream >> size; stream >> size;
if (!stream.ok()) _Unlikely_ return stream; if (!stream.ok()) _Unlikely_ return stream;
@ -523,7 +523,7 @@ namespace stdex {
if (limiter.state() == stdex::stream::state_t::fail) _Unlikely_ return stream; 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); stream.seek(start + size);
return stream; return stream;
@ -537,12 +537,12 @@ namespace stdex {
/// ///
/// \returns The stream \p stream /// \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. // 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. // Read data size.
T_SIZE size; T_size size;
stream >> size; stream >> size;
if (!stream.ok()) _Unlikely_ return stream; if (!stream.ok()) _Unlikely_ return stream;
@ -552,7 +552,7 @@ namespace stdex {
if (limiter.state() == stdex::stream::state_t::fail) _Unlikely_ return stream; if (limiter.state() == stdex::stream::state_t::fail) _Unlikely_ return stream;
limiter.skip(limiter.read_limit); limiter.skip(limiter.read_limit);
} }
stream.skip(padding<T_SIZE, ALIGN>(size)); stream.skip(padding<T_size, N_align>(size));
return stream; return stream;
} }

View File

@ -201,6 +201,6 @@ namespace stdex
} }
}; };
template <class T, class _Alloc = std::allocator<interval<T>>> template <class T, class AX = std::allocator<interval<T>>>
using interval_vector = std::vector<interval<T>, _Alloc>; 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); } bool operator!=(const mapping& other) const { return !operator==(other); }
}; };
template <class T, class _Alloc = std::allocator<mapping<T>>> template <class T, class AX = std::allocator<mapping<T>>>
using mapping_vector = std::vector<mapping<T>, _Alloc>; using mapping_vector = std::vector<mapping<T>, AX>;
} }

View File

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

View File

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

View File

@ -15,10 +15,10 @@ namespace stdex
/// ///
/// Ring buffer /// Ring buffer
/// ///
/// \tparam T Ring element type /// \tparam T Ring element type
/// \tparam CAPACITY Ring capacity (in number of elements) /// \tparam N_cap Ring capacity (in number of elements)
/// ///
template <class T, size_t CAPACITY> template <class T, size_t N_cap>
class ring class ring
{ {
public: public:
@ -43,7 +43,7 @@ namespace stdex
return { nullptr, 0 }; return { nullptr, 0 };
} }
size_t tail = wrap(m_head + m_size); 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); const std::lock_guard<std::mutex> lg(m_mutex);
#ifdef _DEBUG #ifdef _DEBUG
size_t tail = wrap(m_head + m_size); 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 #endif
m_size += size; m_size += size;
} }
@ -78,7 +78,7 @@ namespace stdex
return { nullptr, 0 }; return { nullptr, 0 };
} }
size_t tail = wrap(m_head + m_size); 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); const std::lock_guard<std::mutex> lg(m_mutex);
#ifdef _DEBUG #ifdef _DEBUG
size_t tail = wrap(m_head + m_size); 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 #endif
m_head = wrap(m_head + size); m_head = wrap(m_head + size);
m_size -= size; m_size -= size;
@ -125,13 +125,13 @@ namespace stdex
protected: protected:
size_t wrap(_In_ size_t idx) const size_t wrap(_In_ size_t idx) const
{ {
// TODO: When CAPACITY is power of 2, use & ~(CAPACITY - 1) instead. // TODO: When N_cap is power of 2, use & ~(N_cap - 1) instead.
return idx % CAPACITY; return idx % N_cap;
} }
size_t space() const size_t space() const
{ {
return CAPACITY - m_size; return N_cap - m_size;
} }
bool empty() const bool empty() const
@ -144,6 +144,6 @@ namespace stdex
std::condition_variable m_head_moved, m_tail_moved; std::condition_variable m_head_moved, m_tail_moved;
size_t m_head, m_size; size_t m_head, m_size;
bool m_quit; 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] 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. /// \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( void sgml2strcat(
_Inout_ std::wstring& dst, _Inout_ std::basic_string<wchar_t, TR_to, AX_to>& 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_ int skip = 0,
_In_ const mapping<size_t>& offset = mapping<size_t>(0, 0), _In_ const mapping<size_t>& offset = mapping<size_t>(0, 0),
_Inout_opt_ mapping_vector<size_t>* map = nullptr) _Inout_opt_ mapping_vector<size_t>* map = nullptr)
@ -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] 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. /// \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( void sgml2strcat(
_Inout_ std::wstring& dst, _Inout_ std::basic_string<wchar_t, TR_to, AX_to>& dst,
_In_ const std::basic_string<T>& src, _In_ const std::basic_string<T_from, TR_from, AX_from>& src,
_In_ int skip = 0, _In_ int skip = 0,
_In_ const mapping<size_t>& offset = mapping<size_t>(0, 0), _In_ const mapping<size_t>& offset = mapping<size_t>(0, 0),
_Inout_opt_ mapping_vector<size_t>* map = nullptr) _Inout_opt_ mapping_vector<size_t>* map = nullptr)
@ -204,10 +204,10 @@ namespace stdex
/// ///
/// \return Final length of SGML string in code points excluding zero-terminator /// \return Final length of SGML string in code points excluding zero-terminator
/// ///
template <class T> template <class T_from>
size_t sgml2strcat( size_t sgml2strcat(
_Inout_cap_(count_dst) wchar_t* dst, _In_ size_t count_dst, _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_ int skip = 0,
_In_ const mapping<size_t>& offset = mapping<size_t>(0, 0), _In_ const mapping<size_t>& offset = mapping<size_t>(0, 0),
_Inout_opt_ mapping_vector<size_t>* map = nullptr) _Inout_opt_ mapping_vector<size_t>* map = nullptr)
@ -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] 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. /// \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( void sgml2strcpy(
_Inout_ std::wstring& dst, _Inout_ std::basic_string<wchar_t, TR_to, AX_to>& 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_ int skip = 0,
_In_ const mapping<size_t>& offset = mapping<size_t>(0, 0), _In_ const mapping<size_t>& offset = mapping<size_t>(0, 0),
_Inout_opt_ mapping_vector<size_t>* map = nullptr) _Inout_opt_ mapping_vector<size_t>* map = nullptr)
@ -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] 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. /// \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( void sgml2strcpy(
_Inout_ std::wstring& dst, _Inout_ std::basic_string<wchar_t, TR_to, AX_to>& dst,
_In_ const std::basic_string<_Elem, _Traits, _Ax>& src, _In_ const std::basic_string<T_from, TR_from, AX_from>& src,
_In_ int skip = 0, _In_ int skip = 0,
_In_ const mapping<size_t>& offset = mapping<size_t>(0, 0), _In_ const mapping<size_t>& offset = mapping<size_t>(0, 0),
_Inout_opt_ mapping_vector<size_t>* map = nullptr) _Inout_opt_ mapping_vector<size_t>* map = nullptr)
@ -355,10 +355,10 @@ namespace stdex
/// ///
/// \return Final length of SGML string in code points excluding zero-terminator /// \return Final length of SGML string in code points excluding zero-terminator
/// ///
template <class T> template <class T_from>
size_t sgml2strcpy( size_t sgml2strcpy(
_Inout_cap_(count_dst) wchar_t* dst, _In_ size_t count_dst, _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_ int skip = 0,
_In_ const mapping<size_t>& offset = mapping<size_t>(0, 0), _In_ const mapping<size_t>& offset = mapping<size_t>(0, 0),
_Inout_opt_ mapping_vector<size_t>* map = nullptr) _Inout_opt_ mapping_vector<size_t>* map = nullptr)
@ -382,9 +382,9 @@ namespace stdex
/// ///
/// \return Unicode string /// \return Unicode string
/// ///
template <class T> template <class T_from>
std::wstring sgml2str( 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_ int skip = 0,
_In_ const mapping<size_t>& offset = mapping<size_t>(0, 0), _In_ const mapping<size_t>& offset = mapping<size_t>(0, 0),
_Inout_opt_ mapping_vector<size_t>* map = nullptr) _Inout_opt_ mapping_vector<size_t>* map = nullptr)
@ -404,9 +404,9 @@ namespace stdex
/// ///
/// \return Unicode string /// \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( 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_ int skip = 0,
_In_ const mapping<size_t>& offset = mapping<size_t>(0, 0), _In_ const mapping<size_t>& offset = mapping<size_t>(0, 0),
_Inout_opt_ mapping_vector<size_t>* map = nullptr) _Inout_opt_ mapping_vector<size_t>* map = nullptr)
@ -451,8 +451,9 @@ namespace stdex
/// \param[in] count_src Unicode string character count limit /// \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 /// \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( 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_reads_or_z_opt_(count_src) const wchar_t* src, _In_ size_t count_src,
_In_ int what = 0) _In_ int what = 0)
{ {
@ -553,10 +554,10 @@ namespace stdex
/// \param[in] src Unicode string /// \param[in] src Unicode string
/// \param[in] what Bitwise flag of stdex::sgml_* constants that force extra characters otherwise not converted to SGML /// \param[in] what Bitwise flag of stdex::sgml_* constants that force extra characters otherwise not converted to SGML
/// ///
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( void str2sgmlcat(
_Inout_ std::basic_string<char, _Traits, _Ax>& dst, _Inout_ std::basic_string<char, TR_to, AX_to>& dst,
_In_ const std::wstring_view src, _In_ const std::basic_string_view<wchar_t, std::char_traits<wchar_t>> src,
_In_ int what = 0) _In_ int what = 0)
{ {
str2sgmlcat(dst, src.data(), src.size(), what); str2sgmlcat(dst, src.data(), src.size(), what);
@ -702,8 +703,9 @@ namespace stdex
/// \param[in] count_src Unicode string character count limit /// \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 /// \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( 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_reads_or_z_opt_(count_src) const wchar_t* src, _In_ size_t count_src,
_In_ int what = 0) _In_ int what = 0)
{ {
@ -718,10 +720,10 @@ namespace stdex
/// \param[in] src Unicode string /// \param[in] src Unicode string
/// \param[in] what Bitwise flag of stdex::sgml_* constants that force extra characters otherwise not converted to SGML /// \param[in] what Bitwise flag of stdex::sgml_* constants that force extra characters otherwise not converted to SGML
/// ///
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( void str2sgmlcpy(
_Inout_ std::basic_string<char, _Traits, _Ax>& dst, _Inout_ std::basic_string<char, TR_to, AX_to>& dst,
_In_ const std::wstring_view src, _In_ const std::basic_string_view<wchar_t, std::char_traits<wchar_t>> src,
_In_ int what = 0) _In_ int what = 0)
{ {
str2sgmlcpy(dst, src.data(), src.size(), what); str2sgmlcpy(dst, src.data(), src.size(), what);
@ -776,7 +778,7 @@ namespace stdex
/// \return SGML string /// \return SGML string
/// ///
inline std::string str2sgml( 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) _In_ int what = 0)
{ {
return str2sgml(src.data(), src.size(), what); return str2sgml(src.data(), src.size(), what);

View File

@ -302,8 +302,8 @@ namespace stdex
/// ///
/// \return Number of read characters /// \return Number of read characters
/// ///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>> template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
size_t readln(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& str) size_t readln(_Inout_ std::basic_string<T, TR, AX>& str)
{ {
str.clear(); str.clear();
return readln_and_attach(str); return readln_and_attach(str);
@ -314,8 +314,8 @@ namespace stdex
/// ///
/// \return Number of read characters /// \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>> 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, _Traits, _Ax>& str, _In_ charset_encoder<T_from, T_to>& encoder) 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()) if (encoder.from_encoding() == encoder.to_encoding())
return readln(str); return readln(str);
@ -330,19 +330,19 @@ namespace stdex
/// ///
/// \return Total number of chars in str /// \return Total number of chars in str
/// ///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>> template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
size_t readln_and_attach(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& str) size_t readln_and_attach(_Inout_ std::basic_string<T, TR, AX>& str)
{ {
bool initial = true; bool initial = true;
_Elem chr, previous = (_Elem)0; T chr, previous = (T)0;
do { do {
read_array(&chr, sizeof(_Elem), 1); read_array(&chr, sizeof(T), 1);
if (!initial && !(previous == static_cast<_Elem>('\r') && chr == static_cast<_Elem>('\n'))) if (!initial && !(previous == static_cast<T>('\r') && chr == static_cast<T>('\n')))
str += previous; str += previous;
else else
initial = false; initial = false;
previous = chr; previous = chr;
} while (ok() && chr != static_cast<_Elem>('\n')); } while (ok() && chr != static_cast<T>('\n'));
return str.size(); return str.size();
} }
@ -351,8 +351,8 @@ namespace stdex
/// ///
/// \return Total number of chars in str /// \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>> 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, _Traits, _Ax>& str, _In_ charset_encoder<T_from, T_to>& encoder) 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()) if (encoder.from_encoding() == encoder.to_encoding())
return readln_and_attach(str); return readln_and_attach(str);
@ -439,8 +439,8 @@ namespace stdex
/// ///
/// \return Number of code units written /// \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>> 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, _Traits, _Ax>& str, _In_ charset_encoder<T_from, T_to>& encoder) 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_ if (!ok()) _Unlikely_
return 0; return 0;
@ -461,8 +461,8 @@ namespace stdex
/// ///
/// \return This stream /// \return This stream
/// ///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>> template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
basic& read_str(_Out_ std::basic_string<_Elem, _Traits, _Ax>& data) basic& read_str(_Out_ std::basic_string<T, TR, AX>& data)
{ {
data.clear(); data.clear();
if (!ok()) _Unlikely_ if (!ok()) _Unlikely_
@ -473,8 +473,8 @@ namespace stdex
return *this; return *this;
data.reserve(num_chars); data.reserve(num_chars);
for (;;) { for (;;) {
_Elem buf[0x400]; T buf[0x400];
uint32_t num_read = static_cast<uint32_t>(read_array(buf, sizeof(_Elem), std::min<uint32_t>(num_chars, _countof(buf)))); 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); data.append(buf, num_read);
num_chars -= num_read; num_chars -= num_read;
if (!num_chars || !ok()) if (!num_chars || !ok())
@ -518,8 +518,8 @@ namespace stdex
/// ///
/// \return This stream /// \return This stream
/// ///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>> template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
basic& write_str(_In_ const std::basic_string<_Elem, _Traits, _Ax>& data) basic& write_str(_In_ const std::basic_string<T, TR, AX>& data)
{ {
// Stream state will be checked in write_data. // Stream state will be checked in write_data.
size_t num_chars = data.size(); size_t num_chars = data.size();
@ -528,7 +528,7 @@ namespace stdex
write_data(static_cast<uint32_t>(num_chars)); write_data(static_cast<uint32_t>(num_chars));
if (!ok()) _Unlikely_ if (!ok()) _Unlikely_
return *this; return *this;
write_array(data.data(), sizeof(_Elem), num_chars); write_array(data.data(), sizeof(T), num_chars);
return *this; return *this;
} }
@ -669,15 +669,15 @@ namespace stdex
basic& operator >>(_Out_ wchar_t& data) { return read_data(data); } basic& operator >>(_Out_ wchar_t& data) { return read_data(data); }
basic& operator <<(_In_ const wchar_t data) { return write_data(data); } basic& operator <<(_In_ const wchar_t data) { return write_data(data); }
#endif #endif
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>> template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
basic& operator >>(_Out_ std::basic_string<_Elem, _Traits, _Ax>& data) { return read_str(data); } basic& operator >>(_Out_ std::basic_string<T, TR, AX>& data) { return read_str(data); }
template <class T> template <class T>
basic& operator <<(_In_ const T* data) { return write_str(data); } basic& operator <<(_In_ const T* data) { return write_str(data); }
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>> template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
basic& operator <<(_In_ const std::basic_string<_Elem, _Traits, _Ax>& data) { return write_str(data); } basic& operator <<(_In_ const std::basic_string<T, TR, AX>& data) { return write_str(data); }
template <class _Ty, class _Alloc = std::allocator<_Ty>> template <class T, class AX = std::allocator<T>>
basic& operator <<(_In_ const std::vector<_Ty, _Alloc>& data) basic& operator <<(_In_ const std::vector<T, AX>& data)
{ {
size_t num = data.size(); size_t num = data.size();
if (num > UINT32_MAX) _Unlikely_ if (num > UINT32_MAX) _Unlikely_
@ -688,8 +688,8 @@ namespace stdex
return *this; return *this;
} }
template <class _Ty, class _Alloc = std::allocator<_Ty>> template <class T, class AX = std::allocator<T>>
basic& operator >>(_Out_ std::vector<_Ty, _Alloc>& data) basic& operator >>(_Out_ std::vector<T, AX>& data)
{ {
data.clear(); data.clear();
uint32_t num; uint32_t num;
@ -698,7 +698,7 @@ namespace stdex
return *this; return *this;
data.reserve(num); data.reserve(num);
for (uint32_t i = 0; i < num; ++i) { for (uint32_t i = 0; i < num; ++i) {
_Ty el; T el;
*this >> el; *this >> el;
if (!ok()) _Unlikely_ if (!ok()) _Unlikely_
return *this; return *this;
@ -706,8 +706,8 @@ namespace stdex
} }
} }
template <class _Kty, class _Pr = std::less<_Kty>, class _Alloc = std::allocator<_Kty>> template <class KEY, class PR = std::less<KEY>, class AX = std::allocator<KEY>>
basic& operator <<(_In_ const std::set<_Kty, _Pr, _Alloc>& data) basic& operator <<(_In_ const std::set<KEY, PR, AX>& data)
{ {
size_t num = data.size(); size_t num = data.size();
if (num > UINT32_MAX) _Unlikely_ if (num > UINT32_MAX) _Unlikely_
@ -718,8 +718,8 @@ namespace stdex
return *this; return *this;
} }
template <class _Kty, class _Pr = std::less<_Kty>, class _Alloc = std::allocator<_Kty>> template <class KEY, class PR = std::less<KEY>, class AX = std::allocator<KEY>>
basic& operator >>(_Out_ std::set<_Kty, _Pr, _Alloc>& data) basic& operator >>(_Out_ std::set<KEY, PR, AX>& data)
{ {
data.clear(); data.clear();
uint32_t num; uint32_t num;
@ -727,7 +727,7 @@ namespace stdex
if (!ok()) _Unlikely_ if (!ok()) _Unlikely_
return *this; return *this;
for (uint32_t i = 0; i < num; ++i) { for (uint32_t i = 0; i < num; ++i) {
_Kty el; KEY el;
*this >> el; *this >> el;
if (!ok()) _Unlikely_ if (!ok()) _Unlikely_
return *this; return *this;
@ -735,8 +735,8 @@ namespace stdex
} }
} }
template <class _Kty, class _Pr = std::less<_Kty>, class _Alloc = std::allocator<_Kty>> template <class KEY, class PR = std::less<KEY>, class AX = std::allocator<KEY>>
basic& operator <<(_In_ const std::multiset<_Kty, _Pr, _Alloc>& data) basic& operator <<(_In_ const std::multiset<KEY, PR, AX>& data)
{ {
size_t num = data.size(); size_t num = data.size();
if (num > UINT32_MAX) _Unlikely_ if (num > UINT32_MAX) _Unlikely_
@ -747,8 +747,8 @@ namespace stdex
return *this; return *this;
} }
template <class _Kty, class _Pr = std::less<_Kty>, class _Alloc = std::allocator<_Kty>> template <class KEY, class PR = std::less<KEY>, class AX = std::allocator<KEY>>
basic& operator >>(_Out_ std::multiset<_Kty, _Pr, _Alloc>& data) basic& operator >>(_Out_ std::multiset<KEY, PR, AX>& data)
{ {
data.clear(); data.clear();
uint32_t num; uint32_t num;
@ -756,7 +756,7 @@ namespace stdex
if (!ok()) _Unlikely_ if (!ok()) _Unlikely_
return *this; return *this;
for (uint32_t i = 0; i < num; ++i) { for (uint32_t i = 0; i < num; ++i) {
_Kty el; KEY el;
*this >> el; *this >> el;
if (!ok()) _Unlikely_ if (!ok()) _Unlikely_
return *this; return *this;
@ -1237,9 +1237,9 @@ namespace stdex
/// ///
/// Provides read-ahead stream capability /// 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 class async_reader : public converter
{ {
public: public:
@ -1297,16 +1297,16 @@ namespace stdex
} }
protected: protected:
ring<uint8_t, CAPACITY> m_ring; ring<uint8_t, N_cap> m_ring;
std::thread m_worker; std::thread m_worker;
}; };
/// ///
/// Provides write-back stream capability /// 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 class async_writer : public converter
{ {
public: public:
@ -1369,7 +1369,7 @@ namespace stdex
} }
protected: protected:
ring<uint8_t, CAPACITY> m_ring; ring<uint8_t, N_cap> m_ring;
std::thread m_worker; std::thread m_worker;
}; };
@ -2707,7 +2707,8 @@ namespace stdex
/// \param[in] filename Filename /// \param[in] filename Filename
/// \param[in] mode Bitwise combination of mode_t flags /// \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 /// Opens file
@ -2788,7 +2789,8 @@ namespace stdex
/// \param[in] filename Filename /// \param[in] filename Filename
/// \param[in] mode Bitwise combination of mode_t flags /// \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); open(filename.c_str(), mode);
} }
@ -3049,7 +3051,8 @@ namespace stdex
/// ///
/// \param[in] filename Filename /// \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()); return exists(filename.c_str());
} }
@ -3079,7 +3082,8 @@ namespace stdex
/// ///
/// \param[in] filename Filename /// \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()); return readonly(filename.c_str());
} }
@ -3120,7 +3124,8 @@ namespace stdex
/// \param[in] mode Bitwise combination of mode_t flags /// \param[in] mode Bitwise combination of mode_t flags
/// \param[in] cache_size Size of the cache block /// \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() virtual ~cached_file()
{ {
@ -3154,7 +3159,8 @@ namespace stdex
/// \param[in] filename Filename /// \param[in] filename Filename
/// \param[in] mode Bitwise combination of mode_t flags /// \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); open(filename.c_str(), mode);
} }
@ -3263,7 +3269,8 @@ namespace stdex
/// \param[in] filename Filename /// \param[in] filename Filename
/// \param[in] mode Bitwise combination of mode_t flags /// \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 /// Copies content from another file
@ -3454,7 +3461,8 @@ namespace stdex
/// \param[in] filename Filename /// \param[in] filename Filename
/// \param[in] mode Bitwise combination of mode_t flags /// \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); load(filename.c_str(), mode);
} }
@ -3491,7 +3499,8 @@ namespace stdex
/// \param[in] filename Filename /// \param[in] filename Filename
/// \param[in] mode Bitwise combination of mode_t flags /// \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); save(filename.c_str(), mode);
} }
@ -3579,8 +3588,8 @@ namespace stdex
/// ///
/// \return This stream /// \return This stream
/// ///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>> template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
memory_file& read_str(_Inout_ std::basic_string<_Elem, _Traits, _Ax>&data) memory_file& read_str(_Inout_ std::basic_string<T, TR, AX>&data)
{ {
#if SET_FILE_OP_TIMES #if SET_FILE_OP_TIMES
m_atime = time_point::now(); m_atime = time_point::now();
@ -3593,8 +3602,8 @@ namespace stdex
if (end_offset <= m_size) { if (end_offset <= m_size) {
uint32_t num_chars = LE2HE(*reinterpret_cast<uint32_t*>(m_data + m_offset)); uint32_t num_chars = LE2HE(*reinterpret_cast<uint32_t*>(m_data + m_offset));
m_offset = end_offset; m_offset = end_offset;
end_offset = stdex::add(m_offset, stdex::mul(num_chars, sizeof(_Elem))); end_offset = stdex::add(m_offset, stdex::mul(num_chars, sizeof(T)));
_Elem* start = reinterpret_cast<_Elem*>(m_data + m_offset); T* start = reinterpret_cast<T*>(m_data + m_offset);
if (end_offset <= m_size) { if (end_offset <= m_size) {
data.assign(start, start + num_chars); data.assign(start, start + num_chars);
m_offset = end_offset; m_offset = end_offset;
@ -3604,7 +3613,7 @@ namespace stdex
return *this; return *this;
} }
if (end_offset <= m_size) 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_offset = m_size;
m_state = state_t::eof; m_state = state_t::eof;
@ -3750,8 +3759,8 @@ namespace stdex
/// ///
/// \return This stream /// \return This stream
/// ///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>> template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
memory_file& write_str(_In_ const std::basic_string<_Elem, _Traits, _Ax>& data) memory_file& write_str(_In_ const std::basic_string<T, TR, AX>& data)
{ {
#if SET_FILE_OP_TIMES #if SET_FILE_OP_TIMES
m_atime = m_mtime = time_point::now(); m_atime = m_mtime = time_point::now();
@ -3761,7 +3770,7 @@ namespace stdex
size_t num_chars = data.size(); size_t num_chars = data.size();
if (num_chars > UINT32_MAX) if (num_chars > UINT32_MAX)
throw std::invalid_argument("string too long"); 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 size = sizeof(uint32_t) + size_chars;
size_t end_offset = m_offset + size; size_t end_offset = m_offset + size;
if (end_offset > m_reserved) { 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 <<(_In_ const wchar_t data) { return write_data(data); }
memory_file& operator >>(_Out_ wchar_t& data) { return read_data(data); } memory_file& operator >>(_Out_ wchar_t& data) { return read_data(data); }
#endif #endif
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>> template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
memory_file& operator >>(_Out_ std::basic_string<_Elem, _Traits, _Ax>&data) { return read_str(data); } memory_file& operator >>(_Out_ std::basic_string<T, TR, AX>&data) { return read_str(data); }
template <class T> template <class T>
memory_file& operator <<(_In_ const T * data) { return write_str(data); } 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>> template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
memory_file& operator <<(_In_ const std::basic_string<_Elem, _Traits, _Ax>& data) { return write_str(data); } memory_file& operator <<(_In_ const std::basic_string<T, TR, AX>& data) { return write_str(data); }
protected: protected:
uint8_t* m_data; ///< file data 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. /// \return Number of code units excluding zero terminator in the string.
/// ///
template <class T, size_t SIZE> template <class T, size_t N>
inline size_t strnlen(_In_ const T (&str)[SIZE]) 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. /// \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( inline size_t strnchr(
_In_ const T (&str)[SIZE], _In_ const T (&str)[N],
_In_ T chr) _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. /// \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( inline size_t strrnchr(
_In_ const T (&str)[SIZE], _In_ const T (&str)[N],
_In_ T chr) _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. /// \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( inline size_t strnichr(
_In_ const T (&str)[SIZE], _In_ const T (&str)[N],
_In_ T chr) _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. /// \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( inline size_t strnichr(
_In_ const T (&str)[SIZE], _In_ const T (&str)[N],
_In_ T chr, _In_ T chr,
_In_ const std::locale& locale) _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. /// \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( inline size_t strrnichr(
_In_ const T (&str)[SIZE], _In_ const T (&str)[N],
_In_ T chr) _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. /// \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( inline size_t strrnichr(
_In_ const T (&str)[SIZE], _In_ const T (&str)[N],
_In_ T chr, _In_ T chr,
_In_ const std::locale& locale) _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. /// \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]) 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. /// \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( inline bool isblank(
_In_ const T (&str)[SIZE], _In_ const T (&str)[N],
_In_ const std::locale& locale) _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 /// \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( inline int strncmp(
_In_ const T1 (&str1)[SIZE1], _In_ const T1 (&str1)[N1],
_In_ const T2 (&str2)[SIZE2]) _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 /// \return Negative if str1<str2; positive if str1>str2; zero if str1==str2
/// ///
template <class T1, class T2> 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()); 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 /// \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( inline int strnicmp(
_In_ const T1 (&str1)[SIZE1], _In_ const T1 (&str1)[N1],
_In_ const T2 (&str2)[SIZE2]) _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 /// \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( inline int strnicmp(
_In_ const T1 (&str1)[SIZE1], _In_ const T1 (&str1)[N1],
_In_ const T2 (&str2)[SIZE2], _In_ const T2 (&str2)[N2],
_In_ const std::locale& locale) _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 /// \return Negative if str1<str2; positive if str1>str2; zero if str1==str2
/// ///
template <class T1, class T2> 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()); return strnicmp(str1.data(), str1.size(), str2.data(), str2.size());
} }
@ -1220,8 +1224,8 @@ namespace stdex
/// ///
template <class T1, class T2> template <class T1, class T2>
inline int strnicmp( inline int strnicmp(
_In_ const std::basic_string_view<T1> str1, _In_ const std::basic_string_view<T1, std::char_traits<T1>> str1,
_In_ const std::basic_string_view<T2> str2, _In_ const std::basic_string_view<T2, std::char_traits<T2>> str2,
_In_ const std::locale& locale) _In_ const std::locale& locale)
{ {
return strnicmp(str1.data(), str1.size(), str2.data(), str2.size(), 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 /// \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( inline int strncoll(
_In_ const T (&str1)[SIZE1], _In_ const T (&str1)[N1],
_In_ const T (&str2)[SIZE2], _In_ const T (&str2)[N2],
_In_ const std::locale& locale) _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 /// \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( inline size_t strnstr(
_In_ const T1 (&str)[SIZE1], _In_ const T1 (&str)[N1],
_In_z_ const T2* sample) _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> template <class T1, class T2>
inline size_t strnstr( 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) _In_z_ const T2* sample)
{ {
return strnstr(str.data(), str.size(), 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 /// \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( inline size_t strnistr(
_In_ const T1 (&str)[SIZE1], _In_ const T1 (&str)[N1],
_In_z_ const T2* sample) _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 /// \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( inline size_t strnistr(
_In_ const T1 (&str)[SIZE1], _In_ const T1 (&str)[N1],
_In_z_ const T2* sample, _In_z_ const T2* sample,
_In_ const std::locale& locale) _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> template <class T1, class T2>
inline size_t strnistr( 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_z_ const T2* sample)
{ {
return strnistr(str.data(), str.size(), sample); return strnistr(str.data(), str.size(), sample);
@ -1575,7 +1579,7 @@ namespace stdex
/// ///
template <class T1, class T2> template <class T1, class T2>
inline size_t strnistr( 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_z_ const T2* sample,
_In_ const std::locale& locale) _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. /// \return Pointer to duplicated string; or nullptr if str is nullptr. Use delete operator to free the memory.
/// ///
template <class T, size_t SIZE> template <class T, size_t N>
inline _Check_return_ _Ret_maybenull_z_ T* strndup(_In_ const T (&str)[SIZE]) 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] dst Destination string
/// \param[in] src Source string. Must not be dst.data(). /// \param[in] src Source string. Must not be dst.data().
/// ///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>> template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
inline void crlf2nl(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& dst, _In_z_ const _Elem* src) inline void crlf2nl(_Inout_ std::basic_string<T, TR, AX>& dst, _In_z_ const T* src)
{ {
_Assume_(src); _Assume_(src);
_Assume_(src != dst.data()); _Assume_(src != dst.data());
@ -1861,8 +1865,8 @@ namespace stdex
/// ///
/// \param[in] str String to convert /// \param[in] str String to convert
/// ///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>> template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
inline void crlf2nl(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& str) inline void crlf2nl(_Inout_ std::basic_string<T, TR, AX>& str)
{ {
size_t i, j, n; size_t i, j, n;
for (i = j = 0, n = str.size(); j < n;) { for (i = j = 0, n = str.size(); j < n;) {
@ -2044,13 +2048,13 @@ namespace stdex
/// ///
/// \return Binary integer value /// \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( T_bin strtoint(
_In_ const T (&str)[SIZE], _In_ const T (&str)[N],
_Out_opt_ size_t* end, _Out_opt_ size_t* end,
_In_ int radix) _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 /// \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( inline T_bin strtouint(
_In_ const T (&str)[SIZE], _In_ const T (&str)[N],
_Out_opt_ size_t* end, _Out_opt_ size_t* end,
_In_ int radix) _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 /// \return Binary integer value
/// ///
template <class T, size_t SIZE> template <class T, size_t N>
inline int32_t strto32( inline int32_t strto32(
_In_ const T (&str)[SIZE], _In_ const T (&str)[N],
_Out_opt_ size_t* end, _Out_opt_ size_t* end,
_In_ int radix) _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 /// \return Binary integer value
/// ///
template <class T, size_t SIZE> template <class T, size_t N>
inline int64_t strto64( inline int64_t strto64(
_In_ const T (&str)[SIZE], _In_ const T (&str)[N],
_Out_opt_ size_t* end, _Out_opt_ size_t* end,
_In_ int radix) _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 /// \return Binary integer value
/// ///
template <class T, size_t SIZE> template <class T, size_t N>
inline intptr_t strtoi( inline intptr_t strtoi(
_In_ const T (&str)[SIZE], _In_ const T (&str)[N],
_Out_opt_ size_t* end, _Out_opt_ size_t* end,
_In_ int radix) _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 /// \return Binary integer value
/// ///
template <class T, size_t SIZE> template <class T, size_t N>
inline uint32_t strtou32( inline uint32_t strtou32(
_In_ const T (&str)[SIZE], _In_ const T (&str)[N],
_Out_opt_ size_t* end, _Out_opt_ size_t* end,
_In_ int radix) _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 /// \return Binary integer value
/// ///
template <class T, size_t SIZE> template <class T, size_t N>
inline uint64_t strtou64( inline uint64_t strtou64(
_In_ const T (&str)[SIZE], _In_ const T (&str)[N],
_Out_opt_ size_t* end, _Out_opt_ size_t* end,
_In_ int radix) _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 /// \return Binary integer value
/// ///
template <class T, size_t SIZE> template <class T, size_t N>
inline size_t strtoui( inline size_t strtoui(
_In_ const T (&str)[SIZE], _In_ const T (&str)[N],
_Out_opt_ size_t* end, _Out_opt_ size_t* end,
_In_ int radix) _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 /// \return Number of appended code units
/// ///
template<class _Elem, class _Traits, class _Ax> template<class T, class TR, 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) 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. // Try with stack buffer first.
int count = vsnprintf(buf, _countof(buf) - 1, format, locale, arg); int count = vsnprintf(buf, _countof(buf) - 1, format, locale, arg);
@ -2548,9 +2552,9 @@ namespace stdex
str.append(buf, count); str.append(buf, count);
return 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. // 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); count = vsnprintf(buf_dyn.get(), capacity - 1, format, locale, arg);
if (count >= 0) { if (count >= 0) {
str.append(buf_dyn.get(), count); str.append(buf_dyn.get(), count);
@ -2568,8 +2572,8 @@ namespace stdex
/// ///
/// \return Number of appended code units /// \return Number of appended code units
/// ///
template<class _Elem, class _Traits, class _Ax> template<class T, class TR, 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, ...) 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_list arg;
va_start(arg, locale); 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 ] locale Stdlib locale used to perform formatting. Use `NULL` to use locale globally set by `setlocale()`.
/// \param[in ] arg Arguments to `format` /// \param[in ] arg Arguments to `format`
/// ///
template<class _Elem, class _Traits, class _Ax> template<class T, class TR, 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) 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(); str.clear();
vappendf(str, format, locale, arg); vappendf(str, format, locale, arg);
@ -2600,8 +2604,8 @@ namespace stdex
/// \param[in ] format String template using `printf()` style /// \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()`. /// \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> template<class T, class TR, 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, ...) 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_list arg;
va_start(arg, locale); va_start(arg, locale);
@ -2618,10 +2622,10 @@ namespace stdex
/// ///
/// \returns Formatted string /// \returns Formatted string
/// ///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>> template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
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) 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); vappendf(str, format, locale, arg);
return str; return str;
} }
@ -2634,8 +2638,8 @@ namespace stdex
/// ///
/// \returns Formatted string /// \returns Formatted string
/// ///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>> template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
inline std::basic_string<_Elem, _Traits, _Ax> sprintf(_In_z_ _Printf_format_string_params_(2) const _Elem* format, _In_opt_ locale_t locale, ...) 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_list arg;
va_start(arg, locale); va_start(arg, locale);
@ -2672,10 +2676,10 @@ namespace stdex
/// \param[in ] time Time /// \param[in ] time Time
/// \param[in ] locale Stdlib locale used to perform formatting. Use `NULL` to use locale globally set by `setlocale()`. /// \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> template<class T, class TR, 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) 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. // Try with stack buffer first.
size_t count = strftime(buf, _countof(buf), format, time, locale); size_t count = strftime(buf, _countof(buf), format, time, locale);
@ -2684,9 +2688,9 @@ namespace stdex
str.append(buf, count); str.append(buf, count);
} }
else { 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. // 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); count = strftime(buf_dyn.get(), capacity, format, time, locale);
if (count) { if (count) {
str.append(buf_dyn.get(), count); str.append(buf_dyn.get(), count);
@ -2704,8 +2708,8 @@ namespace stdex
/// \param[in ] time Time /// \param[in ] time Time
/// \param[in ] locale Stdlib locale used to perform formatting. Use `NULL` to use locale globally set by `setlocale()`. /// \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> template<class T, class TR, 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) 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(); str.clear();
strcatftime(str, format, time, locale); strcatftime(str, format, time, locale);
@ -2721,10 +2725,10 @@ namespace stdex
/// ///
/// \returns Formatted string /// \returns Formatted string
/// ///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>> template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
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) 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); strcatftime(str, format, time, locale);
return str; return str;
} }
@ -2792,8 +2796,8 @@ namespace stdex
/// ///
/// \param[in,out] str String /// \param[in,out] str String
/// ///
template<class T, size_t SIZE> template<class T, size_t N>
inline void strlwr(_Inout_ T (&str)[SIZE]) inline void strlwr(_Inout_ T (&str)[N])
{ {
strlwr(str, count); strlwr(str, count);
} }
@ -2804,8 +2808,8 @@ namespace stdex
/// \param[in,out] str String /// \param[in,out] str String
/// \param[in] locale C++ locale to use /// \param[in] locale C++ locale to use
/// ///
template<class T, size_t SIZE> template<class T, size_t N>
inline void strlwr(_Inout_ T (&str)[SIZE], _In_ const std::locale& locale) inline void strlwr(_Inout_ T (&str)[N], _In_ const std::locale& locale)
{ {
strlwr(str, count, locale); strlwr(str, count, locale);
} }
@ -2815,8 +2819,8 @@ namespace stdex
/// ///
/// \param[in,out] str String /// \param[in,out] str String
/// ///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>> template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
inline void strlwr(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& str) inline void strlwr(_Inout_ std::basic_string<T, TR, AX>& str)
{ {
for (auto& c : str) for (auto& c : str)
c = tolower(c); c = tolower(c);
@ -2828,10 +2832,10 @@ namespace stdex
/// \param[in,out] str String /// \param[in,out] str String
/// \param[in] locale C++ locale to use /// \param[in] locale C++ locale to use
/// ///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>> template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
inline void strlwr(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& str, _In_ const std::locale& locale) 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) for (auto& c : str)
c = ctype.tolower(c); c = ctype.tolower(c);
} }
@ -2899,10 +2903,10 @@ namespace stdex
/// ///
/// \param[in,out] str String /// \param[in,out] str String
/// ///
template<class T, size_t SIZE> template<class T, size_t N>
inline void strupr(_Inout_ T (&str)[SIZE]) 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,out] str String
/// \param[in] locale C++ locale to use /// \param[in] locale C++ locale to use
/// ///
template<class T, size_t SIZE> template<class T, size_t N>
inline void strupr(_Inout_ T (&str)[SIZE], _In_ const std::locale& locale) 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 /// \param[in,out] str String
/// ///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>> template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
inline void strupr(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& str) inline void strupr(_Inout_ std::basic_string<T, TR, AX>& str)
{ {
for (auto& c : str) for (auto& c : str)
c = toupper(c); c = toupper(c);
@ -2935,10 +2939,10 @@ namespace stdex
/// \param[in,out] str String /// \param[in,out] str String
/// \param[in] locale C++ locale to use /// \param[in] locale C++ locale to use
/// ///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>> template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
inline void strupr(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& str, _In_ const std::locale& locale) 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) for (auto& c : str)
c = ctype.toupper(c); c = ctype.toupper(c);
} }
@ -3013,15 +3017,15 @@ namespace stdex
/// ///
/// \param[in,out] s String to trim /// \param[in,out] s String to trim
/// ///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>> template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
inline void ltrim(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& s) inline void ltrim(_Inout_ std::basic_string<T, TR, AX>& s)
{ {
s.erase( s.erase(
s.begin(), s.begin(),
std::find_if( std::find_if(
s.begin(), s.begin(),
s.end(), 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,out] s String to trim
/// \param[in] locale C++ locale to use /// \param[in] locale C++ locale to use
/// ///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>> template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
inline void ltrim(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& s, _In_ const std::locale& locale) 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.erase(
s.begin(), s.begin(),
std::find_if( std::find_if(
s.begin(), s.begin(),
s.end(), 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 /// \param[in,out] s String to trim
/// ///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>> template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
static inline void rtrim(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& s) static inline void rtrim(_Inout_ std::basic_string<T, TR, AX>& s)
{ {
s.erase( s.erase(
std::find_if( std::find_if(
s.rbegin(), s.rbegin(),
s.rend(), s.rend(),
[&](_In_ _Elem ch) { return !isspace(ch); }).base(), [&](_In_ T ch) { return !isspace(ch); }).base(),
s.end()); s.end());
} }
@ -3115,15 +3119,15 @@ namespace stdex
/// \param[in,out] s String to trim /// \param[in,out] s String to trim
/// \param[in] locale C++ locale to use /// \param[in] locale C++ locale to use
/// ///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>> template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
static inline void rtrim(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& s, _In_ const std::locale& locale) 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( s.erase(
std::find_if( std::find_if(
s.rbegin(), s.rbegin(),
s.rend(), s.rend(),
[&](_In_ _Elem ch) { return !ctype.is(ctype.space, ch); }).base(), [&](_In_ T ch) { return !ctype.is(ctype.space, ch); }).base(),
s.end()); s.end());
} }
@ -3164,10 +3168,10 @@ namespace stdex
/// ///
/// \param[in,out] s String to trim /// \param[in,out] s String to trim
/// ///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>> template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
static inline void trim(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& s) 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.erase(
s.begin(), s.begin(),
std::find_if( std::find_if(
@ -3188,11 +3192,11 @@ namespace stdex
/// \param[in,out] s String to trim /// \param[in,out] s String to trim
/// \param[in] locale C++ locale to use /// \param[in] locale C++ locale to use
/// ///
template<class _Elem, class _Traits = std::char_traits<_Elem>, class _Ax = std::allocator<_Elem>> template<class T, class TR = std::char_traits<T>, class AX = std::allocator<T>>
static inline void trim(_Inout_ std::basic_string<_Elem, _Traits, _Ax>& s, _In_ const std::locale& locale) 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); const auto& ctype = std::use_facet<std::ctype<T>>(locale);
auto nonspace = [&](_In_ _Elem ch) { return !ctype.is(ctype.space, ch); }; auto nonspace = [&](_In_ T ch) { return !ctype.is(ctype.space, ch); };
s.erase( s.erase(
s.begin(), s.begin(),
std::find_if( std::find_if(

View File

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