diff --git a/include/string_span.h b/include/string_span.h index e18e07a..7d7b81f 100644 --- a/include/string_span.h +++ b/include/string_span.h @@ -44,6 +44,7 @@ #define GSL_MSVC_HAS_TYPE_DEDUCTION_BUG #define GSL_MSVC_HAS_SFINAE_SUBSTITUTION_ICE +#define GSL_MSVC_NO_CPP11_CHAR_TYPES #define GSL_MSVC_NO_CPP14_STD_EQUAL #define GSL_MSVC_NO_DEFAULT_MOVE_CTOR @@ -95,6 +96,22 @@ using zstring = basic_zstring; template using wzstring = basic_zstring; +#ifndef GSL_MSVC_NO_CPP11_CHAR_TYPES + +template +using cu16zstring = const char16_t*; + +template +using cu32zstring = const char32_t*; + +template +using u16zstring = char16_t*; + +template +using u32zstring = char32_t*; + +#endif + // // ensure_sentinel() // @@ -153,6 +170,38 @@ inline span ensure_z(const wchar_t* const& sz, st return {sz, static_cast(len)}; } +#ifndef GSL_MSVC_NO_CPP11_CHAR_TYPES + +inline span ensure_z(char16_t* const& sz, std::ptrdiff_t max) +{ + auto len = details::u16strnlen(sz, narrow_cast(max)); + Ensures(sz[len] == 0); + return{ sz, static_cast(len) }; +} + +inline span ensure_z(const char16_t* const& sz, std::ptrdiff_t max) +{ + auto len = details::u16strnlen(sz, narrow_cast(max)); + Ensures(sz[len] == 0); + return{ sz, static_cast(len) }; +} + +inline span ensure_z(char32_t* const& sz, std::ptrdiff_t max) +{ + auto len = details::u32strnlen(sz, narrow_cast(max)); + Ensures(sz[len] == 0); + return{ sz, static_cast(len) }; +} + +inline span ensure_z(const char32_t* const& sz, std::ptrdiff_t max) +{ + auto len = details::u32strnlen(sz, narrow_cast(max)); + Ensures(sz[len] == 0); + return{ sz, static_cast(len) }; +} + +#endif + template span ensure_z(T (&sz)[N]) { @@ -226,6 +275,62 @@ namespace details return narrow_cast(wcsnlen(ptr, narrow_cast(length))); } }; + +#ifndef GSL_MSVC_NO_CPP11_CHAR_TYPES + + size_t u16strnlen(const char16_t *str, size_t maxlen) + { + const char16_t* ptr = str; + size_t len = 0; + for (; *ptr && len < maxlen; ptr++, len++); + return len; + } + + size_t u32strnlen(const char32_t *str, size_t maxlen) + { + const char32_t* ptr = str; + size_t len = 0; + for (; *ptr && len < maxlen; ptr++, len++); + return len; + } + + template <> + struct length_func + { + std::ptrdiff_t operator()(char16_t* const ptr, std::ptrdiff_t length) noexcept + { + return narrow_cast(u16strnlen(ptr, narrow_cast(length))); + } + }; + + template <> + struct length_func + { + std::ptrdiff_t operator()(const char16_t* const ptr, std::ptrdiff_t length) noexcept + { + return narrow_cast(u16strnlen(ptr, narrow_cast(length))); + } + }; + + template <> + struct length_func + { + std::ptrdiff_t operator()(char32_t* const ptr, std::ptrdiff_t length) noexcept + { + return narrow_cast(u32strnlen(ptr, narrow_cast(length))); + } + }; + + template <> + struct length_func + { + std::ptrdiff_t operator()(const char32_t* const ptr, std::ptrdiff_t length) noexcept + { + return narrow_cast(u32strnlen(ptr, narrow_cast(length))); + } + }; + +#endif } // @@ -425,6 +530,22 @@ using wstring_span = basic_string_span; template using cwstring_span = basic_string_span; +#ifndef GSL_MSVC_NO_CPP11_CHAR_TYPES + +template +using u16string_span = basic_string_span; + +template +using cu16string_span = basic_string_span; + +template +using u32string_span = basic_string_span; + +template +using cu32string_span = basic_string_span; + +#endif + // // to_string() allow (explicit) conversions from string_span to string // @@ -459,6 +580,30 @@ inline std::wstring to_string(wstring_span<> view) return {view.data(), static_cast(view.length())}; } +#ifndef GSL_MSVC_NO_CPP11_CHAR_TYPES + +inline std::u16string to_string(cu16string_span<> view) +{ + return{ view.data(), static_cast(view.length()) }; +} + +inline std::u16string to_string(u16string_span<> view) +{ + return{ view.data(), static_cast(view.length()) }; +} + +inline std::u32string to_string(cu32string_span<> view) +{ + return{ view.data(), static_cast(view.length()) }; +} + +inline std::u32string to_string(u32string_span<> view) +{ + return{ view.data(), static_cast(view.length()) }; +} + +#endif + #endif // zero-terminated string span, used to convert @@ -536,6 +681,24 @@ using czstring_span = basic_zstring_span; template using cwzstring_span = basic_zstring_span; +#ifndef GSL_MSVC_NO_CPP11_CHAR_TYPES + +template +using u16zstring_span = basic_zstring_span; + +template +using u32zstring_span = basic_zstring_span; + +template +using cu16zstring_span = basic_zstring_span; + +template +using cu32zstring_span = basic_zstring_span; + +#endif + +} // namespace GSL + // operator == template