// 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_JSON_CONVERSION_TRAITS_HPP #define JSONCONS_JSON_CONVERSION_TRAITS_HPP #include #include #include #include #include // std::enable_if #include #include #include #include #include #include #include namespace jsoncons { template void read_from(const Json& j, basic_staj_reader& reader, T& val, std::error_code& ec); template void read_from(const Json& j, basic_staj_reader& reader, T& val) { std::error_code ec; read_from(j, reader, val, ec); if (ec) { throw ser_error(ec, reader.context().line(), reader.context().column()); } } template void write_to(const T&val, basic_json_content_handler& receiver); } // namespace jsoncons #include namespace jsoncons { template struct json_conversion_traits { template static T decode(basic_staj_reader& reader, std::error_code& ec) { json_decoder decoder; reader.accept(decoder, ec); return decoder.get_result().template as(); } template static void encode(const T& val, basic_json_content_handler& receiver) { auto j = json_type_traits::to_json(val); j.dump(receiver); } }; // specializations // vector like template struct json_conversion_traits::value && jsoncons::detail::is_vector_like::value >::type> { typedef typename T::value_type value_type; template static T decode(basic_staj_reader& reader, std::error_code& ec) { T v; basic_staj_array_iterator end; basic_staj_array_iterator it(reader, ec); while (it != end && !ec) { v.push_back(*it); it.increment(ec); } return v; } template static void encode(const T& val, basic_json_content_handler& receiver) { receiver.begin_array(); for (auto it = std::begin(val); it != std::end(val); ++it) { json_conversion_traits::template encode(*it,receiver); } receiver.end_array(); receiver.flush(); } }; // std::array template struct json_conversion_traits> { typedef typename std::array::value_type value_type; template static std::array decode(basic_staj_reader& reader, std::error_code& ec) { std::array v; v.fill(T{}); basic_staj_array_iterator end; basic_staj_array_iterator it(reader, ec); for (size_t i = 0; it != end && i < N && !ec; ++i) { v[i] = *it; it.increment(ec); } return v; } template static void encode(const std::array& val, basic_json_content_handler& receiver) { receiver.begin_array(); for (auto it = std::begin(val); it != std::end(val); ++it) { json_conversion_traits::template encode(*it,receiver); } receiver.end_array(); receiver.flush(); } }; // map like template struct json_conversion_traits::value && jsoncons::detail::is_map_like::value >::type> { typedef typename T::mapped_type mapped_type; typedef typename T::value_type value_type; typedef typename T::key_type key_type; template static T decode(basic_staj_reader& reader, std::error_code& ec) { T m; basic_staj_object_iterator end; basic_staj_object_iterator it(reader, ec); while (it != end && !ec) { m.emplace(it->first,it->second); it.increment(ec); } return m; } template static void encode(const T& val, basic_json_content_handler& receiver) { receiver.begin_object(); for (auto it = std::begin(val); it != std::end(val); ++it) { receiver.name(it->first); json_conversion_traits::template encode(it->second,receiver); } receiver.end_object(); receiver.flush(); } }; template void read_from(const Json&, basic_staj_reader& reader, T& val, std::error_code& ec) { val = json_conversion_traits::template decode(reader,ec); } template void write_to(const Json&, const T&val, basic_json_content_handler& receiver) { json_conversion_traits::template encode(val, receiver); } } #endif