20#pragma warning(disable: 4752)
36template <strnlen_mode Mode>
39 void const*
const last
48 void const*
const last
60template <strnlen_mode Mode,
typename Element>
64static __forceinline
size_t __cdecl common_strnlen_c(
66 size_t const maximum_count
69 Element
const*
const last =
string + maximum_count;
70 Element
const* it =
string;
72 for (; !last_reached<Mode>(it,
last) && *it !=
'\0'; ++it)
76 return static_cast<size_t>(it -
string);
79#ifdef _CRT_SIMD_SUPPORT_AVAILABLE
81_UCRT_ENABLE_EXTENDED_ISA
83 template <strnlen_mode Mode, __crt_simd_isa Isa,
typename Element>
88 Element
const*
const string,
89 size_t const maximum_count
92 using traits = __crt_simd_traits<Isa, Element>;
117 if (string_integer % traits::element_size != 0)
122 return common_strnlen_c<Mode>(
string, maximum_count);
126 uintptr_t const prefix_forward_offset = string_integer % traits::pack_size;
127 uintptr_t const prefix_reverse_offset = prefix_forward_offset == 0
129 : traits::pack_size - prefix_forward_offset;
131 size_t const prefix_count =
__min(maximum_count, prefix_reverse_offset / traits::element_size);
132 size_t const prefix_result = common_strnlen_c<bounded>(
string, prefix_count);
133 if (prefix_result != prefix_count)
135 return prefix_result;
138 Element
const* it =
string + prefix_result;
141 __crt_simd_cleanup_guard<Isa>
const simd_cleanup;
143 typename traits::pack_type
const zero = traits::get_zero_pack();
145 size_t const middle_and_suffix_count = maximum_count - prefix_count;
146 size_t const suffix_count = middle_and_suffix_count % traits::pack_size;
147 size_t const middle_count = middle_and_suffix_count - suffix_count;
149 Element
const*
const middle_last = it + middle_count;
150 while (!last_reached<Mode>(it, middle_last))
152 auto const element_it =
reinterpret_cast<typename traits::pack_type
const*
>(it);
154 bool const element_has_terminator = traits::compute_byte_mask(traits::compare_equals(*element_it,
zero)) != 0;
155 if (element_has_terminator)
160 it += traits::elements_per_pack;
164 Element
const*
const suffix_last =
string + maximum_count;
165 for (; !last_reached<Mode>(it, suffix_last) && *it !=
'\0'; ++it)
170 return static_cast<size_t>(it -
string);
173_UCRT_RESTORE_DEFAULT_ISA
177template <strnlen_mode Mode,
typename Element>
181static __forceinline
size_t __cdecl common_strnlen(
182 Element
const*
const string,
183 size_t const maximum_count
186 #ifdef _CRT_SIMD_SUPPORT_AVAILABLE
189 return common_strnlen_simd<Mode, __crt_simd_isa::avx2>(
string, maximum_count);
193 return common_strnlen_simd<Mode, __crt_simd_isa::sse2>(
string, maximum_count);
197 return common_strnlen_c<Mode>(
string, maximum_count);
200#if !defined(_M_ARM64) && !defined(_M_ARM64EC)
203 char const*
const string,
204 size_t const maximum_count
207 return common_strnlen<bounded>(
reinterpret_cast<uint8_t const*
>(
string), maximum_count);
211 wchar_t const*
const string,
212 size_t const maximum_count
215 return common_strnlen<bounded>(
reinterpret_cast<uint16_t const*
>(
string), maximum_count);
218#pragma function(wcslen)
221 wchar_t const*
const string
unsigned short int uint16_t
#define _CRT_UNBOUNDED_BUFFER_SIZE
#define _Post_satisfies_(e)
#define UNREFERENCED_PARAMETER(P)
size_t __cdecl strnlen(char const *const string, size_t const maximum_count)
static __forceinline bool __cdecl last_reached(void const *const it, void const *const last)
size_t __cdecl wcslen(wchar_t const *const string)
__forceinline bool __cdecl last_reached< unbounded >(void const *const it, void const *const last)
size_t __cdecl wcsnlen(wchar_t const *const string, size_t const maximum_count)
_Check_return_ size_t const maximum_count throw()