Skip to content

Commit

Permalink
mode to not parse numbers
Browse files Browse the repository at this point in the history
  • Loading branch information
grisumbras committed Jun 22, 2023
1 parent 24cca5f commit 1803bd9
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 21 deletions.
28 changes: 21 additions & 7 deletions bench/bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -668,12 +668,6 @@ static bool parse_option( char const * s )

char opt = *s++;

if( opt == 'p' )
{
popts.precise_parsing = true;
return *s == 0;
}

if( *s++ != ':' )
{
return false;
Expand Down Expand Up @@ -711,6 +705,22 @@ static bool parse_option( char const * s )
case 'b':
s_branch = s;
break;
case 'm':
switch( *s )
{
case 'i':
popts.number_parse_mode = number_parse_mode_t::imprecise;
break;
case 'p':
popts.number_parse_mode = number_parse_mode_t::precise;
break;
case 'n':
popts.number_parse_mode = number_parse_mode_t::none;
break;
default:
return false;
}
break;
}

return true;
Expand Down Expand Up @@ -817,7 +827,11 @@ main(
" (default all)\n"
" -n:<number> Number of trials (default 6)\n"
" -b:<branch> Branch label for boost implementations\n"
" -p Enable precise parsing\n"
" -m:(i|p|n) Number parsing mode\n"
" (i: imprecise)\n"
" (p: precise)\n"
" (n: none)\n"
" (default imprecise)\n"
;

return 4;
Expand Down
26 changes: 18 additions & 8 deletions include/boost/json/basic_parser_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1984,7 +1984,10 @@ parse_number(const char* p,
bool const negative = first == '-';
bool const zero_first = first == '0';
bool const nonzero_first = first == '+';
bool const precise_parsing = opt_.precise_parsing;
bool const precise_parsing =
opt_.number_parse_mode == number_parse_mode_t::precise;
bool const no_parsing =
opt_.number_parse_mode == number_parse_mode_t::none;
detail::const_stream_wrapper cs(p, end_);
number num;
const char* begin = cs.begin();
Expand Down Expand Up @@ -2034,7 +2037,8 @@ parse_number(const char* p,
return fail(cs.begin(), error::syntax, &loc);
}

num.mant = detail::parse_unsigned( 0, cs.begin(), n1 );
if( !no_parsing )
num.mant = detail::parse_unsigned( 0, cs.begin(), n1 );

cs += n1;

Expand Down Expand Up @@ -2062,7 +2066,7 @@ parse_number(const char* p,
++cs;
goto do_exp1;
}
if(negative)
if( negative && !no_parsing )
num.mant = ~num.mant + 1;
goto finish_signed;
}
Expand All @@ -2089,7 +2093,8 @@ parse_number(const char* p,
goto do_num7;
}

num.mant = detail::parse_unsigned( num.mant, cs.begin(), n2 );
if( !no_parsing )
num.mant = detail::parse_unsigned( num.mant, cs.begin(), n2 );

BOOST_ASSERT(num.bias == 0);

Expand Down Expand Up @@ -2225,7 +2230,8 @@ parse_number(const char* p,
if( num.mant > 922337203685477580 || (
num.mant == 922337203685477580 && c > '8'))
break;
num.mant = 10 * num.mant + ( c - '0' );
else if( !no_parsing )
num.mant = 10 * num.mant + ( c - '0' );
continue;
}
goto do_num6; // [.eE]
Expand Down Expand Up @@ -2259,7 +2265,8 @@ parse_number(const char* p,
if( num.mant > 1844674407370955161 || (
num.mant == 1844674407370955161 && c > '5'))
break;
num.mant = 10 * num.mant + ( c - '0' );
else if( !no_parsing )
num.mant = 10 * num.mant + ( c - '0' );
}
else
{
Expand Down Expand Up @@ -2498,7 +2505,7 @@ parse_number(const char* p,
c >= '0' && c <= '9'))
{
++cs;
if(BOOST_JSON_LIKELY(
if(!no_parsing && BOOST_JSON_LIKELY(
num.mant <= 9007199254740991)) // 2^53-1
{
--num.bias;
Expand Down Expand Up @@ -2623,7 +2630,8 @@ parse_number(const char* p,
return fail(cs.begin(), error::exponent_overflow, &loc);
}
++cs;
num.exp = 10 * num.exp + ( c - '0' );
if( !no_parsing )
num.exp = 10 * num.exp + ( c - '0' );
continue;
}
}
Expand Down Expand Up @@ -2693,6 +2701,8 @@ parse_number(const char* p,
BOOST_ASSERT( err.ptr == data + full_size );
(void)err;
}
else if ( no_parsing )
d = 0;
else
d = detail::dec_to_float(
num.mant,
Expand Down
9 changes: 8 additions & 1 deletion include/boost/json/parse_options.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@
namespace boost {
namespace json {

enum class number_parse_mode_t : unsigned char
{
imprecise,
precise,
none,
};

/** Parser options
This structure is used for specifying
Expand Down Expand Up @@ -52,7 +59,7 @@ struct parse_options
@ref basic_parser,
@ref stream_parser.
*/
bool precise_parsing = false;
number_parse_mode_t number_parse_mode = number_parse_mode_t::imprecise;

/** Non-standard extension option
Expand Down
2 changes: 1 addition & 1 deletion test/doc_parsing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ testPrecise()
{
//[doc_parsing_precise
parse_options opt;
opt.precise_parsing = true;
opt.number_parse_mode = number_parse_mode_t::precise;
value jv = parse( "1002.9111801605201", storage_ptr(), opt );
//]
(void)jv;
Expand Down
13 changes: 10 additions & 3 deletions test/double.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,8 @@ class double_test
for (bool is_precise: {false, true})
{
parse_options po;
po.precise_parsing = is_precise;
po.number_parse_mode = is_precise ?
number_parse_mode_t::precise : number_parse_mode_t::imprecise;
double const got = f(s, po);
auto same = got == need;
auto close = same ?
Expand All @@ -241,6 +242,12 @@ class double_test
<< got << " != " << need << "\n";
}
}

// test that number_parse_mode_t::none works
parse_options po;
po.number_parse_mode = number_parse_mode_t::none;
double const got = f(s, po);
(void)got;
}

void
Expand Down Expand Up @@ -423,7 +430,7 @@ class double_test
sprintf( buffer, "%llu.%llue%d", x1, x2, x3 );

parse_options precise;
precise.precise_parsing = true;
precise.number_parse_mode = number_parse_mode_t::precise;
checkAccuracy( buffer, 2 );
checkAccuracy( buffer, 0, precise );
}
Expand All @@ -441,7 +448,7 @@ class double_test
testExtraPrecision()
{
parse_options opts;
opts.precise_parsing = true;
opts.number_parse_mode = number_parse_mode_t::precise;
BOOST_TEST(
parse("1002.9111801605201", {}, opts) == 1002.9111801605201 );
BOOST_TEST(
Expand Down
2 changes: 1 addition & 1 deletion test/limits.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ class limits_test
buffer.data()[1] = '.';

parse_options precise;
precise.precise_parsing = true;
precise.number_parse_mode = number_parse_mode_t::precise;

stream_parser p( {}, precise );
error_code ec;
Expand Down

0 comments on commit 1803bd9

Please sign in to comment.