#ifndef NLOHMANN_JSON_DETAIL_CONVERSIONS_TO_JSON_HPP #define NLOHMANN_JSON_DETAIL_CONVERSIONS_TO_JSON_HPP #include // or, and, not #include // begin, end #include // tuple, get #include // is_same, is_constructible, is_floating_point, is_enum, underlying_type #include // move, forward, declval, pair #include // valarray #include // vector #include "detail/meta.hpp" #include "detail/value_t.hpp" namespace nlohmann { namespace detail { ////////////////// // constructors // ////////////////// template struct external_constructor; template<> struct external_constructor { template static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept { j.m_type = value_t::boolean; j.m_value = b; j.assert_invariant(); } }; template<> struct external_constructor { template static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s) { j.m_type = value_t::string; j.m_value = s; j.assert_invariant(); } template static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s) { j.m_type = value_t::string; j.m_value = std::move(s); j.assert_invariant(); } }; template<> struct external_constructor { template static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept { j.m_type = value_t::number_float; j.m_value = val; j.assert_invariant(); } }; template<> struct external_constructor { template static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept { j.m_type = value_t::number_unsigned; j.m_value = val; j.assert_invariant(); } }; template<> struct external_constructor { template static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept { j.m_type = value_t::number_integer; j.m_value = val; j.assert_invariant(); } }; template<> struct external_constructor { template static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr) { j.m_type = value_t::array; j.m_value = arr; j.assert_invariant(); } template static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr) { j.m_type = value_t::array; j.m_value = std::move(arr); j.assert_invariant(); } template::value, int> = 0> static void construct(BasicJsonType& j, const CompatibleArrayType& arr) { using std::begin; using std::end; j.m_type = value_t::array; j.m_value.array = j.template create(begin(arr), end(arr)); j.assert_invariant(); } template static void construct(BasicJsonType& j, const std::vector& arr) { j.m_type = value_t::array; j.m_value = value_t::array; j.m_value.array->reserve(arr.size()); for (const bool x : arr) { j.m_value.array->push_back(x); } j.assert_invariant(); } template::value, int> = 0> static void construct(BasicJsonType& j, const std::valarray& arr) { j.m_type = value_t::array; j.m_value = value_t::array; j.m_value.array->resize(arr.size()); std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin()); j.assert_invariant(); } }; template<> struct external_constructor { template static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj) { j.m_type = value_t::object; j.m_value = obj; j.assert_invariant(); } template static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj) { j.m_type = value_t::object; j.m_value = std::move(obj); j.assert_invariant(); } template::value, int> = 0> static void construct(BasicJsonType& j, const CompatibleObjectType& obj) { using std::begin; using std::end; j.m_type = value_t::object; j.m_value.object = j.template create(begin(obj), end(obj)); j.assert_invariant(); } }; ///////////// // to_json // ///////////// template::value, int> = 0> void to_json(BasicJsonType& j, T b) noexcept { external_constructor::construct(j, b); } template::value, int> = 0> void to_json(BasicJsonType& j, const CompatibleString& s) { external_constructor::construct(j, s); } template void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s) { external_constructor::construct(j, std::move(s)); } template::value, int> = 0> void to_json(BasicJsonType& j, FloatType val) noexcept { external_constructor::construct(j, static_cast(val)); } template::value, int> = 0> void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept { external_constructor::construct(j, static_cast(val)); } template::value, int> = 0> void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept { external_constructor::construct(j, static_cast(val)); } template::value, int> = 0> void to_json(BasicJsonType& j, EnumType e) noexcept { using underlying_type = typename std::underlying_type::type; external_constructor::construct(j, static_cast(e)); } template void to_json(BasicJsonType& j, const std::vector& e) { external_constructor::construct(j, e); } template::value or std::is_same::value, int> = 0> void to_json(BasicJsonType& j, const CompatibleArrayType& arr) { external_constructor::construct(j, arr); } template::value, int> = 0> void to_json(BasicJsonType& j, std::valarray arr) { external_constructor::construct(j, std::move(arr)); } template void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr) { external_constructor::construct(j, std::move(arr)); } template::value, int> = 0> void to_json(BasicJsonType& j, const CompatibleObjectType& obj) { external_constructor::construct(j, obj); } template void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj) { external_constructor::construct(j, std::move(obj)); } template::value, int> = 0> void to_json(BasicJsonType& j, T (&arr)[N]) { external_constructor::construct(j, arr); } template void to_json(BasicJsonType& j, const std::pair& p) { j = {p.first, p.second}; } template void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence) { j = {std::get(t)...}; } template void to_json(BasicJsonType& j, const std::tuple& t) { to_json_tuple_impl(j, t, index_sequence_for {}); } struct to_json_fn { private: template auto call(BasicJsonType& j, T&& val, priority_tag<1> /*unused*/) const noexcept(noexcept(to_json(j, std::forward(val)))) -> decltype(to_json(j, std::forward(val)), void()) { return to_json(j, std::forward(val)); } template void call(BasicJsonType& /*unused*/, T&& /*unused*/, priority_tag<0> /*unused*/) const noexcept { static_assert(sizeof(BasicJsonType) == 0, "could not find to_json() method in T's namespace"); #ifdef _MSC_VER // MSVC does not show a stacktrace for the above assert using decayed = uncvref_t; static_assert(sizeof(typename decayed::force_msvc_stacktrace) == 0, "forcing MSVC stacktrace to show which T we're talking about."); #endif } public: template void operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(std::declval().call(j, std::forward(val), priority_tag<1> {}))) { return call(j, std::forward(val), priority_tag<1> {}); } }; } /// namespace to hold default `to_json` function namespace { constexpr const auto& to_json = detail::static_const::value; } } #endif