Skip to content

Commit 31a853e

Browse files
committed
parse by 8 digits
1 parent 6339db4 commit 31a853e

File tree

1 file changed

+24
-18
lines changed

1 file changed

+24
-18
lines changed

include/boost/json/detail/sse2.hpp

+24-18
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,20 @@ inline int count_digits( char const* p ) noexcept
315315

316316
inline uint64_t parse_unsigned( uint64_t r, char const * p, std::size_t n ) noexcept
317317
{
318-
while( n >= 4 )
318+
char const* e = p + n;
319+
320+
if( n & 1 )
321+
{
322+
r = r * 10 + p[0] - '0';
323+
++p;
324+
}
325+
if( n & 2 )
326+
{
327+
r = r * 10 + p[0] - '0';
328+
r = r * 10 + p[1] - '0';
329+
p += 2;
330+
}
331+
if( n & 4 )
319332
{
320333
uint32_t v;
321334
std::memcpy( &v, p, 4 );
@@ -324,27 +337,20 @@ inline uint64_t parse_unsigned( uint64_t r, char const * p, std::size_t n ) noex
324337
v = (v & 0x00FF00FF) * 6553601 >> 16;
325338

326339
r = r * 10000 + v;
327-
328340
p += 4;
329-
n -= 4;
330341
}
331342

332-
switch( n )
343+
while( p != e )
333344
{
334-
case 0:
335-
break;
336-
case 1:
337-
r = r * 10 + p[0] - '0';
338-
break;
339-
case 2:
340-
r = r * 10 + p[0] - '0';
341-
r = r * 10 + p[1] - '0';
342-
break;
343-
case 3:
344-
r = r * 10 + p[0] - '0';
345-
r = r * 10 + p[1] - '0';
346-
r = r * 10 + p[2] - '0';
347-
break;
345+
uint64_t v;
346+
std::memcpy( &v, p, 8 );
347+
endian::native_to_little_inplace(v);
348+
v = (v & 0x0F0F0F0F0F0F0F0F) * 2561 >> 8;
349+
v = (v & 0x00FF00FF00FF00FF) * 6553601 >> 16;
350+
v = (v & 0x0000FFFF0000FFFF) * 42949672960001 >> 32;
351+
352+
r = r * 100000000 + v;
353+
p += 8;
348354
}
349355

350356
return r;

0 commit comments

Comments
 (0)