@@ -268,11 +268,10 @@ struct is_supported_char_type
268268 > {
269269};
270270
271- // Compares two ASCII strings in a case insensitive manner.
272271template <typename UC>
273272inline FASTFLOAT_CONSTEXPR14 bool
274- fastfloat_strncasecmp (UC const *actual_mixedcase, UC const *expected_lowercase ,
275- size_t length ) {
273+ fastfloat_strncasecmp3 (UC const *actual_mixedcase,
274+ UC const *expected_lowercase ) {
276275 uint64_t mask{0 };
277276 FASTFLOAT_IF_CONSTEXPR17 (sizeof (UC) == 1 ) { mask = 0x2020202020202020 ; }
278277 else FASTFLOAT_IF_CONSTEXPR17 (sizeof (UC) == 2 ) {
@@ -284,22 +283,138 @@ fastfloat_strncasecmp(UC const *actual_mixedcase, UC const *expected_lowercase,
284283 else {
285284 return false ;
286285 }
286+
287+ uint64_t val1{0 }, val2{0 };
288+ if (cpp20_and_in_constexpr ()) {
289+ for (size_t i = 0 ; i < 3 ; i++) {
290+ if ((actual_mixedcase[i] | 32 ) != expected_lowercase[i]) {
291+ return false ;
292+ }
293+ return true ;
294+ }
295+ } else {
296+ FASTFLOAT_IF_CONSTEXPR17 (sizeof (UC) == 1 || sizeof (UC) == 2 ) {
297+ ::memcpy (&val1, actual_mixedcase, 3 * sizeof (UC));
298+ ::memcpy (&val2, expected_lowercase, 3 * sizeof (UC));
299+ val1 |= mask;
300+ val2 |= mask;
301+ return val1 == val2;
302+ }
303+ else FASTFLOAT_IF_CONSTEXPR17 (sizeof (UC) == 4 ) {
304+ ::memcpy (&val1, actual_mixedcase, 2 * sizeof (UC));
305+ ::memcpy (&val2, expected_lowercase, 2 * sizeof (UC));
306+ val1 |= mask;
307+ if (val1 != val2) {
308+ return false ;
309+ }
310+ return (actual_mixedcase[2 ] | 32 ) == (expected_lowercase[2 ]);
311+ }
312+ else {
313+ return false ;
314+ }
315+ }
316+
317+ return true ;
318+ }
319+
320+ template <typename UC>
321+ inline FASTFLOAT_CONSTEXPR14 bool
322+ fastfloat_strncasecmp5 (UC const *actual_mixedcase,
323+ UC const *expected_lowercase) {
324+ uint64_t mask{0 };
287325 uint64_t val1{0 }, val2{0 };
288- size_t sz{8 / (sizeof (UC))};
289- for (size_t i = 0 ; i < length; i += sz) {
290- val1 = val2 = 0 ;
291- sz = std::min (sz, length - i);
292- ::memcpy (&val1, actual_mixedcase + i, sz * sizeof (UC));
293- ::memcpy (&val2, expected_lowercase + i, sz * sizeof (UC));
294- val1 |= mask;
295- val2 |= mask;
296- if (val1 != val2) {
326+ if (cpp20_and_in_constexpr ()) {
327+ for (size_t i = 0 ; i < 5 ; i++) {
328+ if ((actual_mixedcase[i] | 32 ) != expected_lowercase[i]) {
329+ return false ;
330+ }
331+ return true ;
332+ }
333+ } else {
334+ FASTFLOAT_IF_CONSTEXPR17 (sizeof (UC) == 1 ) {
335+ mask = 0x2020202020202020 ;
336+ ::memcpy (&val1, actual_mixedcase, 5 * sizeof (UC));
337+ ::memcpy (&val2, expected_lowercase, 5 * sizeof (UC));
338+ val1 |= mask;
339+ val2 |= mask;
340+ return val1 == val2;
341+ }
342+ else FASTFLOAT_IF_CONSTEXPR17 (sizeof (UC) == 2 ) {
343+ mask = 0x0020002000200020 ;
344+ ::memcpy (&val1, actual_mixedcase, 4 * sizeof (UC));
345+ ::memcpy (&val2, expected_lowercase, 4 * sizeof (UC));
346+ val1 |= mask;
347+ if (val1 != val2) {
348+ return false ;
349+ }
350+ return (actual_mixedcase[4 ] | 32 ) == (expected_lowercase[4 ]);
351+ }
352+ else FASTFLOAT_IF_CONSTEXPR17 (sizeof (UC) == 4 ) {
353+ mask = 0x0000002000000020 ;
354+ ::memcpy (&val1, actual_mixedcase, 2 * sizeof (UC));
355+ ::memcpy (&val2, expected_lowercase, 2 * sizeof (UC));
356+ val1 |= mask;
357+ if (val1 != val2) {
358+ return false ;
359+ }
360+ ::memcpy (&val1, actual_mixedcase + 2 , 2 * sizeof (UC));
361+ ::memcpy (&val2, expected_lowercase + 2 , 2 * sizeof (UC));
362+ val1 |= mask;
363+ if (val1 != val2) {
364+ return false ;
365+ }
366+ return (actual_mixedcase[4 ] | 32 ) == (expected_lowercase[4 ]);
367+ }
368+ else {
297369 return false ;
298370 }
299371 }
372+
300373 return true ;
301374}
302375
376+ // Compares two ASCII strings in a case insensitive manner.
377+ template <typename UC>
378+ inline FASTFLOAT_CONSTEXPR14 bool
379+ fastfloat_strncasecmp (UC const *actual_mixedcase, UC const *expected_lowercase,
380+ size_t length) {
381+ uint64_t mask{0 };
382+ FASTFLOAT_IF_CONSTEXPR17 (sizeof (UC) == 1 ) { mask = 0x2020202020202020 ; }
383+ else FASTFLOAT_IF_CONSTEXPR17 (sizeof (UC) == 2 ) {
384+ mask = 0x0020002000200020 ;
385+ }
386+ else FASTFLOAT_IF_CONSTEXPR17 (sizeof (UC) == 4 ) {
387+ mask = 0x0000002000000020 ;
388+ }
389+ else {
390+ return false ;
391+ }
392+
393+ if (cpp20_and_in_constexpr ()) {
394+ for (size_t i = 0 ; i < length; i++) {
395+ if ((actual_mixedcase[i] | 32 ) != expected_lowercase[i]) {
396+ return false ;
397+ }
398+ return true ;
399+ }
400+ } else {
401+ uint64_t val1{0 }, val2{0 };
402+ size_t sz{8 / (sizeof (UC))};
403+ for (size_t i = 0 ; i < length; i += sz) {
404+ val1 = val2 = 0 ;
405+ sz = std::min (sz, length - i);
406+ ::memcpy (&val1, actual_mixedcase + i, sz * sizeof (UC));
407+ ::memcpy (&val2, expected_lowercase + i, sz * sizeof (UC));
408+ val1 |= mask;
409+ val2 |= mask;
410+ if (val1 != val2) {
411+ return false ;
412+ }
413+ }
414+ return true ;
415+ }
416+ }
417+
303418#ifndef FLT_EVAL_METHOD
304419#error "FLT_EVAL_METHOD should be defined, please include cfloat."
305420#endif
0 commit comments