From 1d055261b4144dbf86b2658437015b15d4dd9bff Mon Sep 17 00:00:00 2001 From: Richard Date: Sun, 4 Sep 2022 00:32:56 +0100 Subject: initial --- include/jsoncons/encode_traits.hpp | 378 +++++++++++++++++++++++++++++++++++++ 1 file changed, 378 insertions(+) create mode 100644 include/jsoncons/encode_traits.hpp (limited to 'include/jsoncons/encode_traits.hpp') diff --git a/include/jsoncons/encode_traits.hpp b/include/jsoncons/encode_traits.hpp new file mode 100644 index 0000000..ae981af --- /dev/null +++ b/include/jsoncons/encode_traits.hpp @@ -0,0 +1,378 @@ +// Copyright 2017 Daniel Parker +// Distributed under the Boost license, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See https://github.com/danielaparker/jsoncons for latest version + +#ifndef JSONCONS_ENCODE_TRAITS_HPP +#define JSONCONS_ENCODE_TRAITS_HPP + +#include +#include +#include +#include +#include // std::enable_if, std::true_type, std::false_type +#include +#include +#include +#include +#include +#include + +namespace jsoncons { + + // encode_traits + + template + struct encode_traits + { + template + static void encode(const T& val, + basic_json_visitor& encoder, + const Json& proto, + std::error_code& ec) + { + encode(std::integral_constant::value>(), + val, encoder, proto, ec); + } + private: + template + static void encode(std::true_type, + const T& val, + basic_json_visitor& encoder, + const Json& /*proto*/, + std::error_code& ec) + { + auto j = json_type_traits::to_json(val); + j.dump(encoder, ec); + } + template + static void encode(std::false_type, + const T& val, + basic_json_visitor& encoder, + const Json& proto, + std::error_code& ec) + { + auto j = json_type_traits::to_json(val, proto.get_allocator()); + j.dump(encoder, ec); + } + }; + + // specializations + + // bool + template + struct encode_traits::value + >::type> + { + template + static void encode(const T& val, + basic_json_visitor& encoder, + const Json&, + std::error_code& ec) + { + encoder.bool_value(val,semantic_tag::none,ser_context(),ec); + } + }; + + // uint + template + struct encode_traits::value + >::type> + { + template + static void encode(const T& val, + basic_json_visitor& encoder, + const Json&, + std::error_code& ec) + { + encoder.uint64_value(val,semantic_tag::none,ser_context(),ec); + } + }; + + // int + template + struct encode_traits::value + >::type> + { + template + static void encode(const T& val, + basic_json_visitor& encoder, + const Json&, + std::error_code& ec) + { + encoder.int64_value(val,semantic_tag::none,ser_context(),ec); + } + }; + + // float or double + template + struct encode_traits::value + >::type> + { + template + static void encode(const T& val, + basic_json_visitor& encoder, + const Json&, + std::error_code& ec) + { + encoder.double_value(val,semantic_tag::none,ser_context(),ec); + } + }; + + // string + template + struct encode_traits::value && + std::is_same::value + >::type> + { + template + static void encode(const T& val, + basic_json_visitor& encoder, + const Json&, + std::error_code& ec) + { + encoder.string_value(val,semantic_tag::none,ser_context(),ec); + } + }; + template + struct encode_traits::value && + !std::is_same::value + >::type> + { + template + static void encode(const T& val, + basic_json_visitor& encoder, + const Json&, + std::error_code& ec) + { + std::basic_string s; + unicode_traits::convert(val.data(), val.size(), s); + encoder.string_value(s,semantic_tag::none,ser_context(),ec); + } + }; + + // std::pair + + template + struct encode_traits, CharT> + { + using value_type = std::pair; + + template + static void encode(const value_type& val, + basic_json_visitor& encoder, + const Json& proto, + std::error_code& ec) + { + encoder.begin_array(2,semantic_tag::none,ser_context(),ec); + if (ec) return; + encode_traits::encode(val.first, encoder, proto, ec); + if (ec) return; + encode_traits::encode(val.second, encoder, proto, ec); + if (ec) return; + encoder.end_array(ser_context(),ec); + } + }; + + // std::tuple + + namespace detail + { + template + struct json_serialize_tuple_helper + { + using char_type = typename Json::char_type; + using element_type = typename std::tuple_element::type; + using next = json_serialize_tuple_helper; + + static void encode(const Tuple& tuple, + basic_json_visitor& encoder, + const Json& proto, + std::error_code& ec) + { + encode_traits::encode(std::get(tuple), encoder, proto, ec); + if (ec) return; + next::encode(tuple, encoder, proto, ec); + } + }; + + template + struct json_serialize_tuple_helper<0, Size, Json, Tuple> + { + using char_type = typename Json::char_type; + static void encode(const Tuple&, + basic_json_visitor&, + const Json&, + std::error_code&) + { + } + }; + } // namespace detail + + + template + struct encode_traits, CharT> + { + using value_type = std::tuple; + static constexpr std::size_t size = sizeof...(E); + + template + static void encode(const value_type& val, + basic_json_visitor& encoder, + const Json& proto, + std::error_code& ec) + { + using helper = jsoncons::detail::json_serialize_tuple_helper>; + encoder.begin_array(size,semantic_tag::none,ser_context(),ec); + if (ec) return; + helper::encode(val, encoder, proto, ec); + if (ec) return; + encoder.end_array(ser_context(),ec); + } + }; + + // vector like + template + struct encode_traits::value && + type_traits::is_list_like::value && + !type_traits::is_typed_array::value + >::type> + { + using value_type = typename T::value_type; + + template + static void encode(const T& val, + basic_json_visitor& encoder, + const Json& proto, + std::error_code& ec) + { + encoder.begin_array(val.size(),semantic_tag::none,ser_context(),ec); + if (ec) return; + for (auto it = std::begin(val); it != std::end(val); ++it) + { + encode_traits::encode(*it, encoder, proto, ec); + if (ec) return; + } + encoder.end_array(ser_context(), ec); + } + }; + + template + struct encode_traits::value && + type_traits::is_list_like::value && + type_traits::is_typed_array::value + >::type> + { + using value_type = typename T::value_type; + + template + static void encode(const T& val, + basic_json_visitor& encoder, + const Json&, + std::error_code& ec) + { + encoder.typed_array(jsoncons::span(val), semantic_tag::none, ser_context(), ec); + } + }; + + // std::array + + template + struct encode_traits,CharT> + { + using value_type = typename std::array::value_type; + + template + static void encode(const std::array& val, + basic_json_visitor& encoder, + const Json& proto, + std::error_code& ec) + { + encoder.begin_array(val.size(),semantic_tag::none,ser_context(),ec); + if (ec) return; + for (auto it = std::begin(val); it != std::end(val); ++it) + { + encode_traits::encode(*it, encoder, proto, ec); + if (ec) return; + } + encoder.end_array(ser_context(),ec); + } + }; + + // map like + + template + struct encode_traits::value && + type_traits::is_map_like::value && + type_traits::is_constructible_from_const_pointer_and_size::value + >::type> + { + using mapped_type = typename T::mapped_type; + using value_type = typename T::value_type; + using key_type = typename T::key_type; + + template + static void encode(const T& val, + basic_json_visitor& encoder, + const Json& proto, + std::error_code& ec) + { + encoder.begin_object(val.size(), semantic_tag::none, ser_context(), ec); + if (ec) return; + for (auto it = std::begin(val); it != std::end(val); ++it) + { + encoder.key(it->first); + encode_traits::encode(it->second, encoder, proto, ec); + if (ec) return; + } + encoder.end_object(ser_context(), ec); + if (ec) return; + } + }; + + template + struct encode_traits::value && + type_traits::is_map_like::value && + std::is_integral::value + >::type> + { + using mapped_type = typename T::mapped_type; + using value_type = typename T::value_type; + using key_type = typename T::key_type; + + template + static void encode(const T& val, + basic_json_visitor& encoder, + const Json& proto, + std::error_code& ec) + { + encoder.begin_object(val.size(), semantic_tag::none, ser_context(), ec); + if (ec) return; + for (auto it = std::begin(val); it != std::end(val); ++it) + { + std::basic_string s; + jsoncons::detail::from_integer(it->first,s); + encoder.key(s); + encode_traits::encode(it->second, encoder, proto, ec); + if (ec) return; + } + encoder.end_object(ser_context(), ec); + if (ec) return; + } + }; + +} // jsoncons + +#endif + -- cgit v1.2.3