move number parsing to numerizer class

This commit is contained in:
Kevin Xu 2021-12-06 19:51:27 -05:00
parent 402da49c64
commit 125b0f4a6b
3 changed files with 56 additions and 24 deletions

View File

@ -13,6 +13,7 @@
#include <nlohmann/detail/input/input_adapters.hpp>
#include <nlohmann/detail/input/position_t.hpp>
#include <nlohmann/detail/macro_scope.hpp>
#include <nlohmann/detail/input/numerizer.hpp>
namespace nlohmann
{
@ -99,7 +100,7 @@ class lexer_base
This class organizes the lexical analysis during JSON deserialization.
*/
template<typename BasicJsonType, typename InputAdapterType>
template<typename BasicJsonType, typename InputAdapterType, typename NumerizerType = numerizer>
class lexer : public lexer_base<BasicJsonType>
{
using number_integer_t = typename BasicJsonType::number_integer_t;
@ -900,24 +901,6 @@ class lexer : public lexer_base<BasicJsonType>
}
}
JSON_HEDLEY_NON_NULL(2)
static void strtof(float& f, const char* str, char** endptr) noexcept
{
f = std::strtof(str, endptr);
}
JSON_HEDLEY_NON_NULL(2)
static void strtof(double& f, const char* str, char** endptr) noexcept
{
f = std::strtod(str, endptr);
}
JSON_HEDLEY_NON_NULL(2)
static void strtof(long double& f, const char* str, char** endptr) noexcept
{
f = std::strtold(str, endptr);
}
/*!
@brief scan a number literal
@ -1242,7 +1225,7 @@ scan_number_done:
// try to parse integers first and fall back to floats
if (number_type == token_type::value_unsigned)
{
const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
const auto x = NumerizerType::strtoull(token_buffer.data(), &endptr, 10);
// we checked the number format before
JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
@ -1258,7 +1241,7 @@ scan_number_done:
}
else if (number_type == token_type::value_integer)
{
const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
const auto x = NumerizerType::strtoll(token_buffer.data(), &endptr, 10);
// we checked the number format before
JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
@ -1275,7 +1258,7 @@ scan_number_done:
// this code is reached if we parse a floating-point number or if an
// integer conversion above failed
strtof(value_float, token_buffer.data(), &endptr);
NumerizerType::strtof(value_float, token_buffer.data(), &endptr);
// we checked the number format before
JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());

View File

@ -0,0 +1,44 @@
#include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
namespace nlohmann
{
namespace detail
{
struct numerizer
{
JSON_HEDLEY_NON_NULL(2)
static void strtof(float& f, const char* str, char** endptr) noexcept
{
f = std::strtof(str, endptr);
}
JSON_HEDLEY_NON_NULL(2)
static void strtof(double& f, const char* str, char** endptr) noexcept
{
f = std::strtod(str, endptr);
}
JSON_HEDLEY_NON_NULL(2)
static void strtof(long double& f, const char* str, char** endptr) noexcept
{
f = std::strtold(str, endptr);
}
JSON_HEDLEY_NON_NULL(2)
static auto strtoull(const char* str, char** endptr, int base)
{
return std::strtoull(str, endptr, base);
}
JSON_HEDLEY_NON_NULL(2)
static auto strtoll(const char* str, char** endptr, int base)
{
return std::strtoll(str, endptr, base);
}
};
}
}

View File

@ -26,9 +26,14 @@ struct adl_serializer;
namespace detail
{
template<typename BasicJsonType, typename InputAdapterType>
template<typename BasicJsonType, typename InputAdapterType, typename NumerizerType>
class lexer;
struct numerizer;
template<typename BasicJsonType, typename InputAdapterType>
using basic_lexer = lexer<BasicJsonType, InputAdapterType, numerizer>;
template<typename BasicJsonType>
class serializer;
}
@ -44,7 +49,7 @@ template<template<typename U, typename V, typename... Args> class ObjectType =
template<typename T, typename SFINAE = void> class JSONSerializer =
adl_serializer,
class BinaryType = std::vector<std::uint8_t>,
template<typename BasicJsonType, typename InputAdapterType> class LexerType = detail::lexer,
template<typename BasicJsonType, typename InputAdapterType> class LexerType = detail::basic_lexer,
template<typename BasicJsonType> class SerializerType = detail::serializer>
class basic_json;