From fd5938892b0d774d76b6d12f27aed588a6589047 Mon Sep 17 00:00:00 2001 From: wangfengtu <1148791151@qq.com> Date: Sat, 20 Dec 2025 19:41:39 +0800 Subject: [PATCH 1/4] feat: support more map key type fix bug https://github.com/injae/serdepp/issues/64#issue-3747963973 --- include/serdepp/serializer.hpp | 99 +++++++++++++++++++++++++++++++--- 1 file changed, 93 insertions(+), 6 deletions(-) diff --git a/include/serdepp/serializer.hpp b/include/serdepp/serializer.hpp index 22e0e3f..41c1604 100644 --- a/include/serdepp/serializer.hpp +++ b/include/serdepp/serializer.hpp @@ -4,6 +4,7 @@ #define __CPPSER_SERIALIZER_HPP__ #include +#include #include #include #include @@ -89,7 +90,7 @@ namespace serde constexpr serde_context(T& format) : adaptor(format) {} T& adaptor; size_t read_count_ = 0; - bool skip_all_ = false; + bool skip_all_ = false; constexpr void read() { read_count_++; } }; @@ -211,7 +212,7 @@ namespace serde } template - inline void into(serde_ctx& ctx, T& data, std::string_view key) const { + inline void into(serde_ctx& ctx, T& data, std::string_view key) const { serde::serde_serializer::into(ctx, data, key); } }; @@ -344,7 +345,7 @@ namespace serde } return serde_struct(context_, value_); } - + inline constexpr serde_struct& no_remain() { using namespace std::literals; if(context_.skip_all_) return *this; @@ -463,7 +464,8 @@ namespace serde template struct serde_serializer && - is_emptyable_v >> { + is_emptyable_v && + is_str_v >> { constexpr inline static auto from(serde_ctx& ctx, T& data, std::string_view key) { serde_adaptor::from(ctx.adaptor, key, data); ctx.read(); @@ -474,6 +476,91 @@ namespace serde } }; + namespace { + template + std::string to_string(const T& key) { + if constexpr (std::is_arithmetic_v) { + return std::to_string(key); + } else { + std::ostringstream oss; + oss << key; + return oss.str(); + } + } + } + template + struct from_string { + static K from(const std::string& key) { + K result; + std::stringstream ss(key); + ss >> result; + if (ss.fail()) { + throw std::runtime_error("Cannot convert JSON key to type " + std::string(typeid(K).name())); + } + return result; + } + }; + + + template <> + struct from_string { + static std::string from(const std::string& key) { + return key; + } + }; + + template + struct from_string && !std::is_same_v>> { + static K from(const std::string& key) { + return static_cast(std::stoll(key)); + } + }; + + template <> + struct from_string { + static bool from(const std::string& key) { + if (key == "true" || key == "1") return true; + if (key == "false" || key == "0") return false; + throw std::invalid_argument("Invalid boolean key: " + key); + } + }; + + template + struct from_string>> { + static K from(const std::string& key) { + return static_cast(std::stoi(key)); + } + }; + template + struct serde_serializer && + is_emptyable_v && + !is_str_v >> { + constexpr inline static auto from(serde_ctx& ctx, T& data, std::string_view key) { + using key_type = typename T::key_type; + using new_T = std::unordered_map; + new_T map_data; + serde_adaptor::from(ctx.adaptor, key, map_data); + std::transform(map_data.begin(), map_data.end(), std::inserter(data, data.begin()), + [](const auto& pair) { + return std::make_pair(from_string::from(pair.first), pair.second); + }); + ctx.read(); + } + constexpr inline static auto into(serde_ctx& ctx, const T& data, std::string_view key) { + + using value_type = typename T::mapped_type; + using new_T = std::unordered_map; + new_T map_data; + std::transform(data.begin(), data.end(), std::inserter(map_data, map_data.begin()), + [](const auto& pair) { + return std::make_pair(to_string(pair.first), pair.second); + }); + serde_adaptor::into(ctx.adaptor, key, map_data); + + ctx.read(); + } + }; + template struct serde_serializer && is_emptyable_v && @@ -559,7 +646,7 @@ namespace serde case SERDE_TYPE::MAP: if(!serde_type_checker::is_map(format)) return true; break; - case SERDE_TYPE::STRUCT: + case SERDE_TYPE::STRUCT: if(!serde_type_checker::is_struct(format)) return true; break; case SERDE_TYPE::INTEGER: @@ -575,7 +662,7 @@ namespace serde if(!serde_type_checker::is_string(format)) return true; break; default: return true; - //case SERDE_TYPE::UNKNOWN: + //case SERDE_TYPE::UNKNOWN: } try { data = deserialize(format); From 210eb33b5060c41bb4bd5f646c34f7d88964aa7c Mon Sep 17 00:00:00 2001 From: wangfengtu <1148791151@qq.com> Date: Mon, 22 Dec 2025 09:44:16 +0800 Subject: [PATCH 2/4] Move to_string function to detail namespace --- include/serdepp/serializer.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/serdepp/serializer.hpp b/include/serdepp/serializer.hpp index 41c1604..6b534cf 100644 --- a/include/serdepp/serializer.hpp +++ b/include/serdepp/serializer.hpp @@ -476,7 +476,7 @@ namespace serde } }; - namespace { + namespace detail { template std::string to_string(const T& key) { if constexpr (std::is_arithmetic_v) { @@ -553,7 +553,7 @@ namespace serde new_T map_data; std::transform(data.begin(), data.end(), std::inserter(map_data, map_data.begin()), [](const auto& pair) { - return std::make_pair(to_string(pair.first), pair.second); + return std::make_pair(detail::to_string(pair.first), pair.second); }); serde_adaptor::into(ctx.adaptor, key, map_data); From 7a80c153341899b7d86cea99d52e92ea1f7a63fc Mon Sep 17 00:00:00 2001 From: wangfengtu <1148791151@qq.com> Date: Mon, 22 Dec 2025 22:27:50 +0800 Subject: [PATCH 3/4] Refactor serialize and deserialize functions <=> std::string Refactor serialization and deserialization functions for improved type handling. --- include/serdepp/serializer.hpp | 68 +++++++++------------------------- 1 file changed, 18 insertions(+), 50 deletions(-) diff --git a/include/serdepp/serializer.hpp b/include/serdepp/serializer.hpp index 6b534cf..b972755 100644 --- a/include/serdepp/serializer.hpp +++ b/include/serdepp/serializer.hpp @@ -476,61 +476,29 @@ namespace serde } }; - namespace detail { - template - std::string to_string(const T& key) { - if constexpr (std::is_arithmetic_v) { - return std::to_string(key); - } else { - std::ostringstream oss; - oss << key; - return oss.str(); - } + template + constexpr inline std::string serialize(const T& data) { + if constexpr(std::is_arithmetic_v) { + return std::to_string(data); + } else { + std::ostringstream oss; + oss << data; + return oss.str(); } } - template - struct from_string { - static K from(const std::string& key) { - K result; - std::stringstream ss(key); - ss >> result; - if (ss.fail()) { - throw std::runtime_error("Cannot convert JSON key to type " + std::string(typeid(K).name())); - } - return result; - } - }; - - template <> - struct from_string { - static std::string from(const std::string& key) { - return key; - } - }; - - template - struct from_string && !std::is_same_v>> { - static K from(const std::string& key) { - return static_cast(std::stoll(key)); - } - }; - - template <> - struct from_string { - static bool from(const std::string& key) { - if (key == "true" || key == "1") return true; - if (key == "false" || key == "0") return false; - throw std::invalid_argument("Invalid boolean key: " + key); + template + constexpr inline T deserialize( const std::string & data ) { + if constexpr (std::is_integral_v && !std::is_same_v) { + return static_cast(std::stoll(data)); + } else if constexpr (std::is_same_v) { + if (data == "true" || data == "1") return true; + if (data == "false" || data == "0") return false; + } else { + throw serde::unimplemented_error("unsupported type!!!"); } - }; + } - template - struct from_string>> { - static K from(const std::string& key) { - return static_cast(std::stoi(key)); - } - }; template struct serde_serializer && is_emptyable_v && From ab05778752d6f0f4417c8ec27f10ddae03a97ae6 Mon Sep 17 00:00:00 2001 From: wangfengtu <1148791151@qq.com> Date: Mon, 22 Dec 2025 22:31:55 +0800 Subject: [PATCH 4/4] Replace from_string with deserialize in serializer --- include/serdepp/serializer.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/serdepp/serializer.hpp b/include/serdepp/serializer.hpp index b972755..b0b86db 100644 --- a/include/serdepp/serializer.hpp +++ b/include/serdepp/serializer.hpp @@ -510,7 +510,7 @@ namespace serde serde_adaptor::from(ctx.adaptor, key, map_data); std::transform(map_data.begin(), map_data.end(), std::inserter(data, data.begin()), [](const auto& pair) { - return std::make_pair(from_string::from(pair.first), pair.second); + return std::make_pair(deserialize(pair.first), pair.second); }); ctx.read(); } @@ -521,7 +521,7 @@ namespace serde new_T map_data; std::transform(data.begin(), data.end(), std::inserter(map_data, map_data.begin()), [](const auto& pair) { - return std::make_pair(detail::to_string(pair.first), pair.second); + return std::make_pair(serialize(pair.first), pair.second); }); serde_adaptor::into(ctx.adaptor, key, map_data);