From db365b19a7a6e23b5bb354ba52cdfb7164bbf421 Mon Sep 17 00:00:00 2001 From: nekosu Date: Wed, 15 May 2024 09:57:59 +0800 Subject: [PATCH] Feat/optimize (#62) --- include/common/array.hpp | 2 ++ include/common/exception.hpp | 2 ++ include/common/object.hpp | 2 ++ include/common/serialization.hpp | 6 ++++-- include/common/types.hpp | 2 ++ include/common/utils.hpp | 30 ++++++++++++++++++++++++----- include/common/value.hpp | 14 ++++++++------ include/json.hpp | 4 ++++ include/json5.hpp | 4 ++++ include/parser/bitops.hpp | 2 ++ include/parser/packed_bytes.hpp | 2 ++ include/parser/packed_bytes_arm.hpp | 2 ++ include/parser/packed_bytes_x86.hpp | 3 +++ include/parser/parser.hpp | 2 ++ include/parser5/parser5.hpp | 2 ++ include/parser5/unicode.h | 2 ++ include/reflection/jsonization.hpp | 2 ++ test/main.cpp | 4 ++++ test/precision_test.cpp | 18 +++++++++++++++++ test/precision_test.h | 3 +++ 20 files changed, 95 insertions(+), 13 deletions(-) create mode 100644 test/precision_test.cpp create mode 100644 test/precision_test.h diff --git a/include/common/array.hpp b/include/common/array.hpp index 78602cc..3ec8b7c 100644 --- a/include/common/array.hpp +++ b/include/common/array.hpp @@ -1,3 +1,5 @@ +// IWYU pragma: private, include + #pragma once #include diff --git a/include/common/exception.hpp b/include/common/exception.hpp index 9c0412d..ec102e1 100644 --- a/include/common/exception.hpp +++ b/include/common/exception.hpp @@ -1,3 +1,5 @@ +// IWYU pragma: private, include + #pragma once #include diff --git a/include/common/object.hpp b/include/common/object.hpp index 87d8c15..7c58f48 100644 --- a/include/common/object.hpp +++ b/include/common/object.hpp @@ -1,3 +1,5 @@ +// IWYU pragma: private, include + #pragma once #include diff --git a/include/common/serialization.hpp b/include/common/serialization.hpp index 8f24f0c..445f8a1 100644 --- a/include/common/serialization.hpp +++ b/include/common/serialization.hpp @@ -1,3 +1,5 @@ +// IWYU pragma: private, include + #pragma once #include @@ -13,8 +15,8 @@ template class is_serializable { template - static auto - test(int) -> decltype(std::declval()(std::declval()), std::true_type()); + static auto test(int) + -> decltype(std::declval()(std::declval()), std::true_type()); template static std::false_type test(...); diff --git a/include/common/types.hpp b/include/common/types.hpp index 35370a6..93f9e2c 100644 --- a/include/common/types.hpp +++ b/include/common/types.hpp @@ -1,3 +1,5 @@ +// IWYU pragma: private, include + #pragma once #include "array.hpp" diff --git a/include/common/utils.hpp b/include/common/utils.hpp index 2f6177f..e7219b1 100644 --- a/include/common/utils.hpp +++ b/include/common/utils.hpp @@ -1,5 +1,10 @@ +// IWYU pragma: private, include + #pragma once +#include +#include +#include #include #include @@ -163,7 +168,7 @@ class has_from_json_in_templ_spec }; template -static constexpr string_t unescape_string(const string_t& str) +inline constexpr string_t unescape_string(const string_t& str) { using char_t = typename string_t::value_type; @@ -211,26 +216,41 @@ static constexpr string_t unescape_string(const string_t& str) } template -static constexpr string_t true_string() +inline constexpr string_t true_string() { return { 't', 'r', 'u', 'e' }; } template -static constexpr string_t false_string() +inline constexpr string_t false_string() { return { 'f', 'a', 'l', 's', 'e' }; } template -static constexpr string_t null_string() +inline constexpr string_t null_string() { return { 'n', 'u', 'l', 'l' }; } template -string_t to_basic_string(any_t&& arg) +inline string_t to_basic_string(any_t&& arg) { +#ifdef MEOJSON_KEEP_FLOATING_PRECISION + using real_type = std::remove_reference_t; + if constexpr (std::is_floating_point_v) { + if constexpr (std::is_same_v) { + std::ostringstream oss; + oss << std::setprecision(std::numeric_limits::max_digits10) << arg; + return oss.str(); + } + else if constexpr (std::is_same_v) { + std::wostringstream oss; + oss << std::setprecision(std::numeric_limits::max_digits10) << arg; + return oss.str(); + } + } +#endif if constexpr (std::is_same_v) { return std::to_string(std::forward(arg)); } diff --git a/include/common/value.hpp b/include/common/value.hpp index 502fd16..c78b7ae 100644 --- a/include/common/value.hpp +++ b/include/common/value.hpp @@ -1,3 +1,5 @@ +// IWYU pragma: private, include + #pragma once #include @@ -611,16 +613,16 @@ inline auto basic_value::get_helper( { if constexpr (std::is_constructible_v) { return is_object() ? as_object().get_helper( - default_value, - std::forward(first), - std::forward(rest)...) + default_value, + std::forward(first), + std::forward(rest)...) : default_value; } else if constexpr (std::is_integral_v>) { return is_array() ? as_array().get_helper( - default_value, - std::forward(first), - std::forward(rest)...) + default_value, + std::forward(first), + std::forward(rest)...) : default_value; } else { diff --git a/include/json.hpp b/include/json.hpp index fa4583c..ada6075 100644 --- a/include/json.hpp +++ b/include/json.hpp @@ -1,6 +1,10 @@ #pragma once +// IWYU pragma: begin_exports + #include "common/serialization.hpp" #include "common/types.hpp" #include "parser/parser.hpp" #include "reflection/jsonization.hpp" + +// IWYU pragma: end_exports diff --git a/include/json5.hpp b/include/json5.hpp index e6d3919..f2abdc7 100644 --- a/include/json5.hpp +++ b/include/json5.hpp @@ -1,4 +1,8 @@ #pragma once +// IWYU pragma: begin_exports + #include "common/types.hpp" #include "parser5/parser5.hpp" + +// IWYU pragma: end_exports diff --git a/include/parser/bitops.hpp b/include/parser/bitops.hpp index c74dbbe..dd005e0 100644 --- a/include/parser/bitops.hpp +++ b/include/parser/bitops.hpp @@ -1,3 +1,5 @@ +// IWYU pragma: private, include + #pragma once #if __cplusplus >= 202002L || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L) diff --git a/include/parser/packed_bytes.hpp b/include/parser/packed_bytes.hpp index 717d77c..8d6c8e5 100644 --- a/include/parser/packed_bytes.hpp +++ b/include/parser/packed_bytes.hpp @@ -1,3 +1,5 @@ +// IWYU pragma: private, include + #pragma once #include diff --git a/include/parser/packed_bytes_arm.hpp b/include/parser/packed_bytes_arm.hpp index 0830647..3a8cd1c 100644 --- a/include/parser/packed_bytes_arm.hpp +++ b/include/parser/packed_bytes_arm.hpp @@ -1,3 +1,5 @@ +// IWYU pragma: private, include + #pragma once // current NEON implementation doesn't outperform 64-bit scalar implementation diff --git a/include/parser/packed_bytes_x86.hpp b/include/parser/packed_bytes_x86.hpp index e01e502..88efe12 100644 --- a/include/parser/packed_bytes_x86.hpp +++ b/include/parser/packed_bytes_x86.hpp @@ -1,4 +1,7 @@ +// IWYU pragma: private, include + #pragma once + #include "packed_bytes.hpp" #include diff --git a/include/parser/parser.hpp b/include/parser/parser.hpp index 5a87f46..8b2581a 100644 --- a/include/parser/parser.hpp +++ b/include/parser/parser.hpp @@ -1,3 +1,5 @@ +// IWYU pragma: private, include + #pragma once #include diff --git a/include/parser5/parser5.hpp b/include/parser5/parser5.hpp index 173665d..8c90528 100644 --- a/include/parser5/parser5.hpp +++ b/include/parser5/parser5.hpp @@ -1,3 +1,5 @@ +// IWYU pragma: private, include + #pragma once #include diff --git a/include/parser5/unicode.h b/include/parser5/unicode.h index b9179b4..330058e 100644 --- a/include/parser5/unicode.h +++ b/include/parser5/unicode.h @@ -1,3 +1,5 @@ +// IWYU pragma: private, include + // This is a generated file. Do not edit. #pragma once #include diff --git a/include/reflection/jsonization.hpp b/include/reflection/jsonization.hpp index d859356..1883436 100644 --- a/include/reflection/jsonization.hpp +++ b/include/reflection/jsonization.hpp @@ -1,3 +1,5 @@ +// IWYU pragma: private, include + #pragma once #include diff --git a/test/main.cpp b/test/main.cpp index 90f5a0f..3316cea 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -2,6 +2,7 @@ #include "include_test.h" #include "json5_test.h" +#include "precision_test.h" #include "serializing_test.h" int main() @@ -23,6 +24,9 @@ int main() std::cout << "\n*** json5_test ***\n" << std::endl; success &= test_json5(); + std::cout << "\n*** precision_test ***\n" << std::endl; + success &= precision_test(); + if (!success) { std::cout << "\n****** Test failed ******\n" << std::endl; return -1; diff --git a/test/precision_test.cpp b/test/precision_test.cpp new file mode 100644 index 0000000..52caa22 --- /dev/null +++ b/test/precision_test.cpp @@ -0,0 +1,18 @@ +#define MEOJSON_KEEP_FLOATING_PRECISION + +#include "../include/json.hpp" + +#include +#include + +bool precision_test() +{ + double value = 3.141592653589793; + json::object obj_old = json::object { { "double", value } }; + std::string obj_str = obj_old.to_string(); + std::cout << obj_str << std::endl; + json::object obj_new = json::parse(obj_str).value().as_object(); + std::cout << "old:" << std::hexfloat << value << std::endl; + std::cout << "new:" << std::hexfloat << obj_new.at("double").as_double() << std::endl; + return obj_new.at("double").as_double() == value; +} diff --git a/test/precision_test.h b/test/precision_test.h new file mode 100644 index 0000000..42cccaa --- /dev/null +++ b/test/precision_test.h @@ -0,0 +1,3 @@ +#pragma once + +extern bool precision_test();