Skip to content

Commit 6a034f2

Browse files
committed
split parse_number into separate instatntiations per number parsing mode
1 parent 285c3aa commit 6a034f2

File tree

2 files changed

+66
-30
lines changed

2 files changed

+66
-30
lines changed

include/boost/json/basic_parser.hpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,9 @@ class basic_parser
292292
bool neg;
293293
};
294294

295+
template< bool StackEmpty_, char First_ >
296+
struct parse_number_helper;
297+
295298
// optimization: must come first
296299
Handler h_;
297300

@@ -440,10 +443,11 @@ class basic_parser
440443
std::integral_constant<bool, IsKey_> is_key,
441444
/*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8);
442445

443-
template<bool StackEmpty_, char First_>
446+
template<bool StackEmpty_, char First_, number_precision Numbers_>
444447
const char* parse_number(const char* p,
445448
std::integral_constant<bool, StackEmpty_> stack_empty,
446-
std::integral_constant<char, First_> first);
449+
std::integral_constant<char, First_> first,
450+
std::integral_constant<number_precision, Numbers_> numbers);
447451

448452
template<bool StackEmpty_, bool IsKey_/*,
449453
bool AllowBadUTF8_*/>

include/boost/json/basic_parser_impl.hpp

Lines changed: 60 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,29 @@ enum json_literal
199199

200200
//----------------------------------------------------------
201201

202+
template< class Handler >
203+
template< bool StackEmpty_, char First_ >
204+
struct basic_parser<Handler>::
205+
parse_number_helper
206+
{
207+
basic_parser* parser;
208+
char const* p;
209+
210+
template< std::size_t N >
211+
char const*
212+
operator()( mp11::mp_size_t<N> ) const
213+
{
214+
return parser->parse_number(
215+
p,
216+
std::integral_constant<bool, StackEmpty_>(),
217+
std::integral_constant<char, First_>(),
218+
std::integral_constant<
219+
number_precision, static_cast<number_precision>(N)>() );
220+
}
221+
};
222+
223+
//----------------------------------------------------------
224+
202225
template<class Handler>
203226
void
204227
basic_parser<Handler>::
@@ -616,13 +639,19 @@ parse_value(const char* p,
616639
switch(*p)
617640
{
618641
case '0':
619-
return parse_number(p, std::true_type(), std::integral_constant<char, '0'>());
642+
return mp11::mp_with_index<3>(
643+
static_cast<unsigned char>(opt_.numbers),
644+
parse_number_helper<true, '0'>{ this, p });
620645
case '-':
621-
return parse_number(p, std::true_type(), std::integral_constant<char, '-'>());
646+
return mp11::mp_with_index<3>(
647+
static_cast<unsigned char>(opt_.numbers),
648+
parse_number_helper<true, '-'>{ this, p });
622649
case '1': case '2': case '3':
623650
case '4': case '5': case '6':
624651
case '7': case '8': case '9':
625-
return parse_number(p, std::true_type(), std::integral_constant<char, '+'>());
652+
return mp11::mp_with_index<3>(
653+
static_cast<unsigned char>(opt_.numbers),
654+
parse_number_helper<true, '+'>{ this, p });
626655
case 'n':
627656
return parse_literal( p, mp11::mp_int<detail::null_literal>() );
628657
case 't':
@@ -735,7 +764,9 @@ resume_value(const char* p,
735764
case state::num7: case state::num8:
736765
case state::exp1: case state::exp2:
737766
case state::exp3:
738-
return parse_number(p, std::false_type(), std::integral_constant<char, 0>());
767+
return mp11::mp_with_index<3>(
768+
static_cast<unsigned char>(opt_.numbers),
769+
parse_number_helper<false, 0>{ this, p });
739770

740771
// KRYSTIAN NOTE: these are special cases
741772
case state::val1:
@@ -1970,15 +2001,16 @@ parse_array(const char* p,
19702001
//----------------------------------------------------------
19712002

19722003
template<class Handler>
1973-
template<bool StackEmpty_, char First_>
2004+
template<bool StackEmpty_, char First_, number_precision Numbers_>
19742005
const char*
19752006
basic_parser<Handler>::
19762007
parse_number(const char* p,
19772008
std::integral_constant<bool, StackEmpty_> stack_empty,
1978-
std::integral_constant<char, First_> first)
2009+
std::integral_constant<char, First_> first,
2010+
std::integral_constant<number_precision, Numbers_> mode)
19792011
{
1980-
bool const precise_parsing = opt_.numbers == number_precision::precise;
1981-
bool const no_parsing = opt_.numbers == number_precision::none;
2012+
constexpr bool precise_parsing = mode == number_precision::precise;
2013+
constexpr bool no_parsing = mode == number_precision::none;
19822014

19832015
// only one of these will be true if we are not resuming
19842016
// if negative then !zero_first && !nonzero_first
@@ -2036,7 +2068,7 @@ parse_number(const char* p,
20362068
return fail(cs.begin(), error::syntax, &loc);
20372069
}
20382070

2039-
if( !no_parsing )
2071+
BOOST_IF_CONSTEXPR( !no_parsing )
20402072
num.mant = detail::parse_unsigned( 0, cs.begin(), n1 );
20412073
else
20422074
num.mant = 0;
@@ -2067,7 +2099,7 @@ parse_number(const char* p,
20672099
++cs;
20682100
goto do_exp1;
20692101
}
2070-
if( negative && !no_parsing )
2102+
BOOST_IF_CONSTEXPR( negative && !no_parsing )
20712103
num.mant = ~num.mant + 1;
20722104
goto finish_signed;
20732105
}
@@ -2094,7 +2126,7 @@ parse_number(const char* p,
20942126
goto do_num7;
20952127
}
20962128

2097-
if( !no_parsing )
2129+
BOOST_IF_CONSTEXPR( !no_parsing )
20982130
num.mant = detail::parse_unsigned( num.mant, cs.begin(), n2 );
20992131

21002132
BOOST_ASSERT(num.bias == 0);
@@ -2191,7 +2223,7 @@ parse_number(const char* p,
21912223
{begin, cs.used(begin)}, ec_)))
21922224
return fail(cs.begin());
21932225

2194-
if( precise_parsing )
2226+
BOOST_IF_CONSTEXPR( precise_parsing )
21952227
num_buf_.append( begin, cs.used(begin) );
21962228
return maybe_suspend(
21972229
cs.begin(), state::num1, num);
@@ -2216,7 +2248,7 @@ parse_number(const char* p,
22162248
{begin, cs.used(begin)}, ec_)))
22172249
return fail(cs.begin());
22182250

2219-
if( precise_parsing )
2251+
BOOST_IF_CONSTEXPR( precise_parsing )
22202252
num_buf_.append( begin, cs.used(begin) );
22212253
return suspend(cs.begin(), state::num2, num);
22222254
}
@@ -2231,7 +2263,7 @@ parse_number(const char* p,
22312263
if( num.mant > 922337203685477580 || (
22322264
num.mant == 922337203685477580 && c > '8'))
22332265
break;
2234-
else if( !no_parsing )
2266+
BOOST_IF_CONSTEXPR( !no_parsing )
22352267
num.mant = 10 * num.mant + ( c - '0' );
22362268
continue;
22372269
}
@@ -2251,7 +2283,7 @@ parse_number(const char* p,
22512283
{begin, cs.used(begin)}, ec_)))
22522284
return fail(cs.begin());
22532285

2254-
if( precise_parsing )
2286+
BOOST_IF_CONSTEXPR( precise_parsing )
22552287
num_buf_.append( begin, cs.used(begin) );
22562288
return suspend(cs.begin(), state::num2, num);
22572289
}
@@ -2266,7 +2298,7 @@ parse_number(const char* p,
22662298
if( num.mant > 1844674407370955161 || (
22672299
num.mant == 1844674407370955161 && c > '5'))
22682300
break;
2269-
else if( !no_parsing )
2301+
BOOST_IF_CONSTEXPR( !no_parsing )
22702302
num.mant = 10 * num.mant + ( c - '0' );
22712303
}
22722304
else
@@ -2294,7 +2326,7 @@ parse_number(const char* p,
22942326
{begin, cs.used(begin)}, ec_)))
22952327
return fail(cs.begin());
22962328

2297-
if( precise_parsing )
2329+
BOOST_IF_CONSTEXPR( precise_parsing )
22982330
num_buf_.append( begin, cs.used(begin) );
22992331
return suspend(cs.begin(), state::num3, num);
23002332
}
@@ -2340,7 +2372,7 @@ parse_number(const char* p,
23402372
{begin, cs.used(begin)}, ec_)))
23412373
return fail(cs.begin());
23422374

2343-
if( precise_parsing )
2375+
BOOST_IF_CONSTEXPR( precise_parsing )
23442376
num_buf_.append( begin, cs.used(begin) );
23452377
return maybe_suspend(
23462378
cs.begin(), state::num4, num);
@@ -2379,7 +2411,7 @@ parse_number(const char* p,
23792411
{begin, cs.used(begin)}, ec_)))
23802412
return fail(cs.begin());
23812413

2382-
if( precise_parsing )
2414+
BOOST_IF_CONSTEXPR( precise_parsing )
23832415
num_buf_.append( begin, cs.used(begin) );
23842416
return suspend(cs.begin(), state::num5, num);
23852417
}
@@ -2417,7 +2449,7 @@ parse_number(const char* p,
24172449
{begin, cs.used(begin)}, ec_)))
24182450
return fail(cs.begin());
24192451

2420-
if( precise_parsing )
2452+
BOOST_IF_CONSTEXPR( precise_parsing )
24212453
num_buf_.append( begin, cs.used(begin) );
24222454
return suspend(cs.begin(), state::num6, num);
24232455
}
@@ -2457,7 +2489,7 @@ parse_number(const char* p,
24572489
{begin, cs.used(begin)}, ec_)))
24582490
return fail(cs.begin());
24592491

2460-
if( precise_parsing )
2492+
BOOST_IF_CONSTEXPR( precise_parsing )
24612493
num_buf_.append( begin, cs.used(begin) );
24622494
return suspend(cs.begin(), state::num7, num);
24632495
}
@@ -2495,7 +2527,7 @@ parse_number(const char* p,
24952527
{begin, cs.used(begin)}, ec_)))
24962528
return fail(cs.begin());
24972529

2498-
if( precise_parsing )
2530+
BOOST_IF_CONSTEXPR( precise_parsing )
24992531
num_buf_.append( begin, cs.used(begin) );
25002532
return suspend(cs.begin(), state::num8, num);
25012533
}
@@ -2540,7 +2572,7 @@ parse_number(const char* p,
25402572
{begin, cs.used(begin)}, ec_)))
25412573
return fail(cs.begin());
25422574

2543-
if( precise_parsing )
2575+
BOOST_IF_CONSTEXPR( precise_parsing )
25442576
num_buf_.append( begin, cs.used(begin) );
25452577
return maybe_suspend(
25462578
cs.begin(), state::exp1, num);
@@ -2571,7 +2603,7 @@ parse_number(const char* p,
25712603
{begin, cs.used(begin)}, ec_)))
25722604
return fail(cs.begin());
25732605

2574-
if( precise_parsing )
2606+
BOOST_IF_CONSTEXPR( precise_parsing )
25752607
num_buf_.append( begin, cs.used(begin) );
25762608
return suspend(cs.begin(), state::exp2, num);
25772609
}
@@ -2610,7 +2642,7 @@ parse_number(const char* p,
26102642
{begin, cs.used(begin)}, ec_)))
26112643
return fail(cs.begin());
26122644

2613-
if( precise_parsing )
2645+
BOOST_IF_CONSTEXPR( precise_parsing )
26142646
num_buf_.append( begin, cs.used(begin) );
26152647
return suspend(cs.begin(), state::exp3, num);
26162648
}
@@ -2631,7 +2663,7 @@ parse_number(const char* p,
26312663
return fail(cs.begin(), error::exponent_overflow, &loc);
26322664
}
26332665
++cs;
2634-
if( !no_parsing )
2666+
BOOST_IF_CONSTEXPR( !no_parsing )
26352667
num.exp = 10 * num.exp + ( c - '0' );
26362668
continue;
26372669
}
@@ -2684,7 +2716,7 @@ parse_number(const char* p,
26842716
double d;
26852717
std::size_t const size = cs.used(begin);
26862718
BOOST_ASSERT( !num_buf_.size() || precise_parsing );
2687-
if( precise_parsing )
2719+
BOOST_IF_CONSTEXPR( precise_parsing )
26882720
{
26892721
char const* data = begin;
26902722
std::size_t full_size = size;
@@ -2702,7 +2734,7 @@ parse_number(const char* p,
27022734
BOOST_ASSERT( err.ptr == data + full_size );
27032735
(void)err;
27042736
}
2705-
else if ( no_parsing )
2737+
else BOOST_IF_CONSTEXPR( no_parsing )
27062738
d = 0;
27072739
else
27082740
d = detail::dec_to_float(

0 commit comments

Comments
 (0)