Skip to content

Commit be283fc

Browse files
committed
Amalgamate & bump version
1 parent 2004f6e commit be283fc

File tree

2 files changed

+67
-27
lines changed

2 files changed

+67
-27
lines changed

amalgamate.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
OUTPUT_PATH = "single_include/jsonh_cpp_amalgamated.hpp"
44

55
HEADER = "// JsonhCpp (JSON for Humans)
6-
// Version: 4.4
6+
// Version: 4.5
77
// Link: https://github.com/jsonh-org/JsonhCpp
88
// License: MIT"
99

single_include/jsonh_cpp_amalgamated.hpp

Lines changed: 66 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// JsonhCpp (JSON for Humans)
2-
// Version: 4.4
2+
// Version: 4.5
33
// Link: https://github.com/jsonh-org/JsonhCpp
44
// License: MIT
55

@@ -16261,7 +16261,7 @@ class binary_reader
1626116261
success = false;
1626216262
break;
1626316263
}
16264-
result.push_back(static_cast<std::uint8_t>(current));
16264+
result.push_back(static_cast<typename binary_t::value_type>(current));
1626516265
}
1626616266
return success;
1626716267
}
@@ -21057,9 +21057,9 @@ class binary_writer
2105721057
#pragma GCC diagnostic push
2105821058
#pragma GCC diagnostic ignored "-Wfloat-equal"
2105921059
#endif
21060-
if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
21061-
static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
21062-
static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
21060+
if (!std::isfinite(n) || ((static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
21061+
static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
21062+
static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))))
2106321063
{
2106421064
oa->write_character(format == detail::input_format_t::cbor
2106521065
? get_cbor_float_prefix(static_cast<float>(n))
@@ -29182,29 +29182,50 @@ class jsonh_number_parser final {
2918229182
/// Output: <c>5200</c>
2918329183
/// </summary>
2918429184
static nonstd::expected<long double, std::string> parse(std::string jsonh_number) noexcept {
29185+
// Remove underscores
29186+
std::erase(jsonh_number, '_');
29187+
std::string_view digits = jsonh_number;
29188+
29189+
// Get sign
29190+
int sign = 1;
29191+
if (digits.starts_with('-')) {
29192+
sign = -1;
29193+
digits = digits.substr(1);
29194+
}
29195+
else if (digits.starts_with('+')) {
29196+
sign = 1;
29197+
digits = digits.substr(1);
29198+
}
29199+
2918529200
// Decimal
2918629201
std::string base_digits = "0123456789";
2918729202
// Hexadecimal
29188-
if (jsonh_number.starts_with("0x") || jsonh_number.starts_with("0X")) {
29203+
if (digits.starts_with("0x") || digits.starts_with("0X")) {
2918929204
base_digits = "0123456789abcdef";
29190-
jsonh_number.erase(0, 2);
29205+
digits = digits.substr(2);
2919129206
}
2919229207
// Binary
29193-
else if (jsonh_number.starts_with("0b") || jsonh_number.starts_with("0B")) {
29208+
else if (digits.starts_with("0b") || digits.starts_with("0B")) {
2919429209
base_digits = "01";
29195-
jsonh_number.erase(0, 2);
29210+
digits = digits.substr(2);
2919629211
}
2919729212
// Octal
29198-
else if (jsonh_number.starts_with("0o") || jsonh_number.starts_with("0O")) {
29213+
else if (digits.starts_with("0o") || digits.starts_with("0O")) {
2919929214
base_digits = "01234567";
29200-
jsonh_number.erase(0, 2);
29215+
digits = digits.substr(2);
2920129216
}
2920229217

29203-
// Remove underscores
29204-
std::erase(jsonh_number, '_');
29205-
2920629218
// Parse number with base digits
29207-
return parse_fractional_number_with_exponent(jsonh_number, base_digits);
29219+
nonstd::expected<long double, std::string> number = parse_fractional_number_with_exponent(digits, base_digits);
29220+
if (!number) {
29221+
return nonstd::unexpected<std::string>(number.error());
29222+
}
29223+
29224+
// Apply sign
29225+
if (sign != 1) {
29226+
number.value() *= sign;
29227+
}
29228+
return number;
2920829229
}
2920929230

2921029231
private:
@@ -30496,46 +30517,57 @@ class jsonh_reader : utf8_reader {
3049630517
}
3049730518
}
3049830519
nonstd::expected<jsonh_token, std::string> read_number(std::string& number_builder) noexcept {
30520+
// Read sign
30521+
std::optional<std::string> sign = read_any({ "-", "+" });
30522+
if (sign) {
30523+
number_builder += sign.value();
30524+
}
30525+
3049930526
// Read base
3050030527
std::string base_digits = "0123456789";
30528+
bool has_base_specifier = false;
3050130529
if (read_one("0")) {
3050230530
number_builder += '0';
3050330531

3050430532
std::optional<std::string> hex_base_char = read_any({ "x", "X" });
3050530533
if (hex_base_char) {
3050630534
number_builder += hex_base_char.value();
3050730535
base_digits = "0123456789abcdef";
30536+
has_base_specifier = true;
3050830537
}
3050930538
else {
3051030539
std::optional<std::string> binary_base_char = read_any({ "b", "B" });
30511-
if (hex_base_char) {
30540+
if (binary_base_char) {
3051230541
number_builder += binary_base_char.value();
3051330542
base_digits = "01";
30543+
has_base_specifier = true;
3051430544
}
3051530545
else {
3051630546
std::optional<std::string> octal_base_char = read_any({ "o", "O" });
3051730547
if (octal_base_char) {
3051830548
number_builder += octal_base_char.value();
3051930549
base_digits = "01234567";
30550+
has_base_specifier = true;
3052030551
}
3052130552
}
3052230553
}
3052330554
}
3052430555

3052530556
// Read main number
30526-
nonstd::expected<void, std::string> main_result = read_number_no_exponent(number_builder, base_digits);
30557+
nonstd::expected<void, std::string> main_result = read_number_no_exponent(number_builder, base_digits, has_base_specifier);
3052730558
if (!main_result) {
3052830559
return nonstd::unexpected<std::string>(main_result.error());
3052930560
}
3053030561

3053130562
// Hexadecimal exponent
3053230563
if (number_builder.back() == 'e' || number_builder.back() == 'E') {
30564+
// Read sign
3053330565
std::optional<std::string> exponent_sign = read_any({ "+", "-" });
3053430566
if (exponent_sign) {
3053530567
number_builder += exponent_sign.value();
3053630568

3053730569
// Read exponent number
30538-
nonstd::expected<void, std::string> exponent_result = read_number_no_exponent(number_builder, base_digits);
30570+
nonstd::expected<void, std::string> exponent_result = read_number_no_exponent(number_builder, base_digits, has_base_specifier);
3053930571
if (!exponent_result) {
3054030572
return nonstd::unexpected<std::string>(exponent_result.error());
3054130573
}
@@ -30547,8 +30579,14 @@ class jsonh_reader : utf8_reader {
3054730579
if (exponent_char) {
3054830580
number_builder += exponent_char.value();
3054930581

30582+
// Read sign
30583+
std::optional<std::string> exponent_sign = read_any({ "-", "+" });
30584+
if (exponent_sign) {
30585+
number_builder += exponent_sign.value();
30586+
}
30587+
3055030588
// Read exponent number
30551-
nonstd::expected<void, std::string> exponent_result = read_number_no_exponent(number_builder, base_digits);
30589+
nonstd::expected<void, std::string> exponent_result = read_number_no_exponent(number_builder, base_digits, has_base_specifier);
3055230590
if (!exponent_result) {
3055330591
return nonstd::unexpected<std::string>(exponent_result.error());
3055430592
}
@@ -30558,12 +30596,9 @@ class jsonh_reader : utf8_reader {
3055830596
// End of number
3055930597
return jsonh_token(json_token_type::number, number_builder);
3056030598
}
30561-
nonstd::expected<void, std::string> read_number_no_exponent(std::string& number_builder, std::string_view base_digits) noexcept {
30562-
// Read sign
30563-
read_any({ "-", "+" });
30564-
30599+
nonstd::expected<void, std::string> read_number_no_exponent(std::string& number_builder, std::string_view base_digits, bool has_base_specifier) noexcept {
3056530600
// Leading underscore
30566-
if (read_one("_")) {
30601+
if (!has_base_specifier && peek() == "_") {
3056730602
return nonstd::unexpected<std::string>("Leading `_` in number");
3056830603
}
3056930604

@@ -30581,12 +30616,12 @@ class jsonh_reader : utf8_reader {
3058130616
read();
3058230617
number_builder += next.value();
3058330618
}
30584-
// Decimal point
30619+
// Dot
3058530620
else if (next.value() == ".") {
3058630621
read();
3058730622
number_builder += next.value();
3058830623

30589-
// Duplicate decimal point
30624+
// Duplicate dot
3059030625
if (is_fraction) {
3059130626
return nonstd::unexpected<std::string>("Duplicate `.` in number");
3059230627
}
@@ -30608,6 +30643,11 @@ class jsonh_reader : utf8_reader {
3060830643
return nonstd::unexpected<std::string>("Empty number");
3060930644
}
3061030645

30646+
// Ensure at least one digit
30647+
if (number_builder.find_first_not_of(".-+_") == std::string::npos) {
30648+
return nonstd::unexpected<std::string>("Number must have at least one digit");
30649+
}
30650+
3061130651
// Trailing underscore
3061230652
if (number_builder.ends_with('_')) {
3061330653
return nonstd::unexpected<std::string>("Trailing `_` in number");

0 commit comments

Comments
 (0)