mirror of
https://github.com/boostorg/json.git
synced 2025-05-11 13:44:06 +00:00
UDT serialization of tuples
This commit is contained in:
parent
d291537423
commit
5666575e7b
@ -41,9 +41,9 @@ struct writer
|
||||
bool
|
||||
suspend(state st);
|
||||
|
||||
template<class T>
|
||||
template<class U, class T>
|
||||
bool
|
||||
suspend(state st, iterator_type<T const> it, T const* po);
|
||||
suspend(state st, U u, T const* po);
|
||||
};
|
||||
|
||||
bool
|
||||
|
@ -11,6 +11,7 @@
|
||||
#define BOOST_JSON_IMPL_SERIALIZER_HPP
|
||||
|
||||
#include <boost/json/conversion.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost {
|
||||
namespace json {
|
||||
@ -33,13 +34,13 @@ suspend(state st)
|
||||
return false;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
template<class U, class T>
|
||||
bool
|
||||
writer::
|
||||
suspend(state st, iterator_type<T const> it, T const* pt)
|
||||
suspend(state st, U u, T const* pt)
|
||||
{
|
||||
st_.push(pt);
|
||||
st_.push(it);
|
||||
st_.push(u);
|
||||
st_.push(st);
|
||||
return false;
|
||||
}
|
||||
@ -366,6 +367,94 @@ do_obj6:
|
||||
return w.suspend(writer::state::obj6, it, pt);
|
||||
}
|
||||
|
||||
template< class T, bool StackEmpty >
|
||||
struct serialize_tuple_elem_helper
|
||||
{
|
||||
writer& w;
|
||||
stream& ss;
|
||||
T const* pt;
|
||||
|
||||
template< std::size_t I >
|
||||
bool
|
||||
operator()( std::integral_constant<std::size_t, I> ) const
|
||||
{
|
||||
using std::get;
|
||||
w.p_ = std::addressof( get<I>(*pt) );
|
||||
|
||||
using Elem = tuple_element_t<I, T>;
|
||||
return write_impl<Elem, StackEmpty>(w, ss);
|
||||
}
|
||||
};
|
||||
|
||||
template<class T, bool StackEmpty>
|
||||
BOOST_FORCEINLINE
|
||||
bool
|
||||
write_impl(tuple_conversion_tag, writer& w, stream& ss0)
|
||||
{
|
||||
T const* pt;
|
||||
local_stream ss(ss0);
|
||||
std::size_t cur;
|
||||
constexpr std::size_t N = std::tuple_size<T>::value;
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning( push )
|
||||
# pragma warning( disable : 4127 )
|
||||
#endif
|
||||
if(StackEmpty || w.st_.empty())
|
||||
{
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning( pop )
|
||||
#endif
|
||||
BOOST_ASSERT( w.p_ );
|
||||
pt = reinterpret_cast<T const*>(w.p_);
|
||||
cur = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
writer::state st;
|
||||
w.st_.pop(st);
|
||||
w.st_.pop(cur);
|
||||
w.st_.pop(pt);
|
||||
switch(st)
|
||||
{
|
||||
default:
|
||||
case writer::state::arr1: goto do_arr1;
|
||||
case writer::state::arr2: goto do_arr2;
|
||||
case writer::state::arr3: goto do_arr3;
|
||||
case writer::state::arr4: goto do_arr4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
do_arr1:
|
||||
if(BOOST_JSON_LIKELY(ss))
|
||||
ss.append('[');
|
||||
else
|
||||
return w.suspend(writer::state::arr1, cur, pt);
|
||||
for(;;)
|
||||
{
|
||||
do_arr2:
|
||||
{
|
||||
bool const stop = !mp11::mp_with_index<N>(
|
||||
cur,
|
||||
serialize_tuple_elem_helper<T, StackEmpty>{w, ss, pt});
|
||||
if(BOOST_JSON_UNLIKELY( stop ))
|
||||
return w.suspend(writer::state::arr2, cur, pt);
|
||||
}
|
||||
if(BOOST_JSON_UNLIKELY( ++cur == N ))
|
||||
break;
|
||||
do_arr3:
|
||||
if(BOOST_JSON_LIKELY(ss))
|
||||
ss.append(',');
|
||||
else
|
||||
return w.suspend(writer::state::arr3, cur, pt);
|
||||
}
|
||||
do_arr4:
|
||||
if(BOOST_JSON_LIKELY(ss))
|
||||
ss.append(']');
|
||||
else
|
||||
return w.suspend(writer::state::arr4, cur, pt);
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class T, bool StackEmpty>
|
||||
bool
|
||||
write_impl(writer& w, stream& ss)
|
||||
|
@ -800,6 +800,15 @@ public:
|
||||
{"a", 1}, {"b", 2}, {"c", 3}, {"d", 4}, {"e", 5}};
|
||||
check_udt(v, R"({"a":1,"b":2,"c":3,"d":4,"e":5})");
|
||||
}
|
||||
{
|
||||
check_udt(
|
||||
std::tuple<std::string, int, bool>("a string", 12, true),
|
||||
R"(["a string",12,true])");
|
||||
check_udt(
|
||||
std::tuple<std::string, std::pair<int, bool>>(
|
||||
"a string", {12, true}),
|
||||
R"(["a string",[12,true]])");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
Loading…
x
Reference in New Issue
Block a user