Commit a6e40bca authored by liuzichao's avatar liuzichao

aajson

parents c4a514e1 832ad18a
......@@ -1075,7 +1075,9 @@ namespace ajson
};
template<typename ty, class enable = void>
struct json_impl;
struct json_impl_in;
template<typename ty, class enable = void>
struct json_impl_out;
inline bool is_true(token const& tok)
{
......@@ -1091,7 +1093,7 @@ namespace ajson
}
template<>
struct json_impl < bool, void >
struct json_impl_in < bool, void >
{
static inline void read(reader& rd, bool& val)
{
......@@ -1125,7 +1127,11 @@ namespace ajson
}
rd.next();
}
};
template<>
struct json_impl_out < bool, void >
{
template<typename write_ty>
static inline void write(write_ty& wt, bool const& val)
{
......@@ -1142,7 +1148,7 @@ namespace ajson
};
template<>
struct json_impl < __uint128_t, void >
struct json_impl_in < __uint128_t, void >
{
static inline void read(reader& rd, __uint128_t& val)
{
......@@ -1178,7 +1184,11 @@ namespace ajson
rd.next();
}
};
template<>
struct json_impl_out < __uint128_t, void >
{
template<typename write_ty>
static inline void write(write_ty& wt, __uint128_t const& val)
{
......@@ -1210,7 +1220,7 @@ namespace ajson
};
template<typename ty>
struct json_impl < ty,
struct json_impl_in < ty,
typename std::enable_if <detail::is_signed_intergral_like<ty>::value>::type >
{
static inline void read(reader& rd, ty& val)
......@@ -1257,6 +1267,11 @@ namespace ajson
}
rd.next();
}
};
template<typename ty>
struct json_impl_out < ty,
typename std::enable_if <detail::is_signed_intergral_like<ty>::value>::type >
{
template<typename write_ty>
static inline void write(write_ty& wt, ty const& val)
{
......@@ -1298,7 +1313,7 @@ namespace ajson
};
template<typename ty>
struct json_impl < ty,
struct json_impl_in < ty,
typename std::enable_if <detail::is_unsigned_intergral_like<ty>::value>::type >
{
static inline void read(reader& rd, ty& val)
......@@ -1349,6 +1364,11 @@ namespace ajson
}
rd.next();
}
};
template<typename ty>
struct json_impl_out < ty,
typename std::enable_if <detail::is_unsigned_intergral_like<ty>::value>::type >
{
template<typename write_ty>
static inline void write(write_ty& wt, ty const& val)
{
......@@ -1380,31 +1400,36 @@ namespace ajson
};
template<typename ty>
struct json_impl < ty,
struct json_impl_in < ty,
typename std::enable_if <std::is_enum<ty>::value>::type >
{
static inline void read(reader& rd, ty& val)
{
typedef typename std::underlying_type<ty>::type raw_type;
json_impl<raw_type>::read(rd, (raw_type&)val);
json_impl_in<raw_type>::read(rd, (raw_type&)val);
}
};
template<typename ty>
struct json_impl_out < ty,
typename std::enable_if <std::is_enum<ty>::value>::type >
{
template<typename write_ty>
static inline void write(write_ty& wt, ty const& val)
{
typedef typename std::underlying_type<ty>::type raw_type;
json_impl<raw_type>::write(wt, val);
json_impl_out<raw_type>::write(wt, val);
}
template<typename write_ty>
static inline void write_key(write_ty& wt, ty const& val)
{
typedef typename std::underlying_type<ty>::type raw_type;
json_impl<raw_type>::write_key(wt, val);
json_impl_out<raw_type>::write_key(wt, val);
}
};
template<typename ty>
struct json_impl < ty,
struct json_impl_in < ty,
typename std::enable_if <std::is_floating_point<ty>::value>::type >
{
static inline void read(reader& rd, ty& val)
......@@ -1444,6 +1469,11 @@ namespace ajson
}
rd.next();
}
};
template<typename ty>
struct json_impl_out < ty,
typename std::enable_if <std::is_floating_point<ty>::value>::type >
{
template<typename write_ty>
static inline void write(write_ty& wt, ty const& val)
{
......@@ -1626,7 +1656,7 @@ namespace ajson
}
template<typename ty>
struct json_impl < ty,
struct json_impl_in < ty,
typename std::enable_if <detail::is_stdstring<ty>::value>::type >
{
static inline void read(reader& rd, ty& val)
......@@ -1645,6 +1675,11 @@ namespace ajson
}
rd.next();
}
};
template<typename ty>
struct json_impl_out < ty,
typename std::enable_if <detail::is_stdstring<ty>::value>::type >
{
template<typename write_ty>
static inline void write(write_ty& wt, ty const& val)
{
......@@ -1689,13 +1724,16 @@ namespace ajson
}
template<size_t N>
struct json_impl <char[N]>
struct json_impl_in <char[N]>
{
static inline void read(reader& rd, char * val)
{
char_array_read(rd, val, N);
}
};
template<size_t N>
struct json_impl_out <char[N]>
{
template<typename write_ty>
static inline void write(write_ty& wt, const char * val)
{
......@@ -1704,13 +1742,17 @@ namespace ajson
};
template<size_t N>
struct json_impl <const char[N] >
struct json_impl_in <const char[N] >
{
static inline void read(reader& rd, char * val)
{
char_array_read(rd, val, N);
}
};
template<size_t N>
struct json_impl_out <const char[N] >
{
template<typename write_ty>
static inline void write(write_ty& wt, const char * val)
{
......@@ -1732,7 +1774,7 @@ namespace ajson
{
if (count < N)
{
json_impl<T>::read(rd, val[count]);
json_impl_in<T>::read(rd, val[count]);
}
else
{
......@@ -1766,7 +1808,7 @@ namespace ajson
int last = N - 1;
for (int i = 0; i < N; ++i)
{
json_impl<T>::write(wt, val[i]);
json_impl_out<T>::write(wt, val[i]);
if (i < last)
wt.put(',');
}
......@@ -1774,12 +1816,16 @@ namespace ajson
}
template<typename T, size_t N>
struct json_impl <T[N]>
struct json_impl_in <T[N]>
{
static inline void read(reader& rd, T * val)
{
array_read(rd, val, N);
}
};
template<typename T, size_t N>
struct json_impl_out <T[N]>
{
template<typename write_ty>
static inline void write(write_ty& wt, const T * val)
{
......@@ -1788,12 +1834,16 @@ namespace ajson
};
template<typename T, size_t N>
struct json_impl < const T[N]>
struct json_impl_in < const T[N]>
{
static inline void read(reader& rd, T * val)
{
array_read(rd, val, N);
}
};
template<typename T, size_t N>
struct json_impl_out < const T[N]>
{
template<typename write_ty>
static inline void write(write_ty& wt, const T * val)
{
......@@ -1816,7 +1866,7 @@ namespace ajson
}
template<typename ty>
struct json_impl < ty,
struct json_impl_in < ty,
typename std::enable_if <detail::is_sequence_container<ty>::value>::type >
{
static inline void read(reader& rd, ty& val)
......@@ -1830,7 +1880,7 @@ namespace ajson
while (tok->str.str[0] != ']')
{
::ajson::emplace_back(val);
json_impl<typename ty::value_type>::read(rd, val.back());
json_impl_in<typename ty::value_type>::read(rd, val.back());
tok = &rd.peek();
if (tok->str.str[0] == ',')
{
......@@ -1850,6 +1900,11 @@ namespace ajson
rd.next();
return;
}
};
template<typename ty>
struct json_impl_out < ty,
typename std::enable_if <detail::is_sequence_container<ty>::value>::type >
{
template<typename write_ty>
static inline void write(write_ty& wt, ty const& val)
{
......@@ -1857,7 +1912,7 @@ namespace ajson
auto sz = val.size();
for (auto& i : val)
{
json_impl<typename ty::value_type>::write(wt, i);
json_impl_out<typename ty::value_type>::write(wt, i);
if (sz-- > 1)
wt.put(',');
}
......@@ -1866,7 +1921,7 @@ namespace ajson
};
template<typename ty>
struct json_impl < ty,
struct json_impl_in < ty,
typename std::enable_if <detail::is_associat_container<ty>::value>::type >
{
static inline void read(reader& rd, ty& val)
......@@ -1881,13 +1936,13 @@ namespace ajson
{
typename ty::key_type key;
typename ty::mapped_type value;
json_impl<typename ty::key_type>::read(rd, key);
json_impl_in<typename ty::key_type>::read(rd, key);
if (rd.expect(':') == false)
{
rd.error("invalid object!");
}
rd.next();
json_impl<typename ty::mapped_type>::read(rd, value);
json_impl_in<typename ty::mapped_type>::read(rd, value);
val[key] = value;
tok = &rd.peek();
if (tok->str.str[0] == ',')
......@@ -1908,6 +1963,11 @@ namespace ajson
rd.next();
return;
}
};
template<typename ty>
struct json_impl_out < ty,
typename std::enable_if <detail::is_associat_container<ty>::value>::type >
{
template<typename write_ty>
static inline void write(write_ty& wt, ty const& val)
{
......@@ -1915,9 +1975,9 @@ namespace ajson
auto sz = val.size();
for (auto& i : val)
{
json_impl<typename ty::key_type>::write_key(wt, i.first);
json_impl_out<typename ty::key_type>::write_key(wt, i.first);
wt.put(':');
json_impl<typename ty::mapped_type>::write(wt, i.second);
json_impl_out<typename ty::mapped_type>::write(wt, i.second);
if (sz-- > 1)
wt.put(',');
}
......@@ -2044,7 +2104,7 @@ namespace ajson
{
if (member_ptr[pos] == member)
{
json_impl<head>::read(rd, val);
json_impl_in<head>::read(rd, val);
return 1;
}
if (sizeof...(args))
......@@ -2072,7 +2132,7 @@ namespace ajson
{
typedef typename std::remove_cv<ty>::type rty;
reader rd(buff, len);
json_impl<rty>::read(rd, val);
json_impl_in<rty>::read(rd, val);
}
template<typename ty>
......@@ -2124,7 +2184,7 @@ namespace ajson
}
reader rd(buffer, sz);
typedef typename std::remove_cv<ty>::type rty;
json_impl<rty>::read(rd, val);
json_impl_in<rty>::read(rd, val);
}
template<typename write_ty, typename head, typename... args>
......@@ -2142,7 +2202,7 @@ namespace ajson
{
wt.write_str(member_ptr[pos].str, member_ptr[pos].len);
wt.put(':');
json_impl<head>::write(wt, val);
json_impl_out<head>::write(wt, val);
if (sizeof...(args))
{
wt.put(',');
......@@ -2170,7 +2230,7 @@ namespace ajson
{
typedef typename std::remove_cv<ty>::type rty;
write_tp wt(ss);
json_impl<rty>::write(wt, val);
json_impl_out<rty>::write(wt, val);
}
template<typename ty, typename stream_ty = ajson_file_stream, class write_tp = lite_write<stream_ty> >
......@@ -2182,6 +2242,9 @@ namespace ajson
}
#define AJSON(TYPE,...) \
AJSON_IN(TYPE, __VA_ARGS__) \
AJSON_OUT(TYPE, __VA_ARGS__)
/*
namespace ajson\
{\
template<>\
......@@ -2246,4 +2309,87 @@ namespace ajson\
}\
};\
}
*/
#define AJSON_IN(TYPE,...) \
namespace ajson\
{\
template<>\
struct json_impl_in < TYPE, void >\
{\
struct json_helper_in : public TYPE\
{\
inline void read_(reader& rd)\
{\
auto& fields = this_field_list();\
if (rd.expect('{') == false){ rd.error("read object must start with {!"); }\
rd.next();\
if (rd.expect('}'))\
return;\
auto mber = rd.peek();\
do\
{\
if (mber.type != token::t_string){ rd.error("object key must be string"); }\
rd.next();\
if (rd.expect(':') == false){ rd.error("invalid json document!"); }\
rd.next();\
if (read_members(rd, &fields[0], mber.str, 0,__VA_ARGS__) == 0)\
{\
skip(rd);\
}\
if (rd.expect('}'))\
{\
rd.next();\
return;\
}\
else if (rd.expect(','))\
{\
rd.next();\
mber = rd.peek();\
continue;\
}\
rd.error("invalid json document!");\
} while (true);\
}\
};\
static inline detail::field_list& this_field_list()\
{\
static auto fields = detail::split_fields(STRINGFY_LIST(__VA_ARGS__));\
return fields;\
}\
static inline void read(reader& rd, TYPE& v)\
{\
reinterpret_cast<json_helper_in &>(v).read_(rd);\
}\
};\
}
#define AJSON_OUT(TYPE,...) \
namespace ajson\
{\
template<>\
struct json_impl_out < TYPE , void >\
{\
struct json_helper : public TYPE\
{\
template<typename write_ty>\
inline void write_(write_ty& wt) const\
{\
auto& fields = this_field_list();\
wt.put('{');\
::ajson::write_members(wt, &fields[0], 0,__VA_ARGS__);\
wt.put('}');\
}\
};\
static inline detail::field_list& this_field_list()\
{\
static auto fields = detail::split_fields(STRINGFY_LIST(__VA_ARGS__));\
return fields;\
}\
template<typename write_ty>\
static inline void write(write_ty& wt, TYPE const& v)\
{\
reinterpret_cast<json_helper const &>(v).write_(wt);\
}\
};\
}
......@@ -1075,7 +1075,9 @@ namespace ajson
};
template<typename ty, class enable = void>
struct json_impl;
struct json_impl_in;
template<typename ty, class enable = void>
struct json_impl_out;
inline bool is_true(token const& tok)
{
......@@ -1091,7 +1093,7 @@ namespace ajson
}
template<>
struct json_impl < bool, void >
struct json_impl_in < bool, void >
{
static inline void read(reader& rd, bool& val)
{
......@@ -1125,7 +1127,11 @@ namespace ajson
}
rd.next();
}
};
template<>
struct json_impl_out < bool, void >
{
template<typename write_ty>
static inline void write(write_ty& wt, bool const& val)
{
......@@ -1142,7 +1148,7 @@ namespace ajson
};
template<>
struct json_impl < __uint128_t, void >
struct json_impl_in < __uint128_t, void >
{
static inline void read(reader& rd, __uint128_t& val)
{
......@@ -1178,7 +1184,11 @@ namespace ajson
rd.next();
}
};
template<>
struct json_impl_out < __uint128_t, void >
{
template<typename write_ty>
static inline void write(write_ty& wt, __uint128_t const& val)
{
......@@ -1210,7 +1220,7 @@ namespace ajson
};
template<typename ty>
struct json_impl < ty,
struct json_impl_in < ty,
typename std::enable_if <detail::is_signed_intergral_like<ty>::value>::type >
{
static inline void read(reader& rd, ty& val)
......@@ -1257,6 +1267,11 @@ namespace ajson
}
rd.next();
}
};
template<typename ty>
struct json_impl_out < ty,
typename std::enable_if <detail::is_signed_intergral_like<ty>::value>::type >
{
template<typename write_ty>
static inline void write(write_ty& wt, ty const& val)
{
......@@ -1298,7 +1313,7 @@ namespace ajson
};
template<typename ty>
struct json_impl < ty,
struct json_impl_in < ty,
typename std::enable_if <detail::is_unsigned_intergral_like<ty>::value>::type >
{
static inline void read(reader& rd, ty& val)
......@@ -1349,6 +1364,11 @@ namespace ajson
}
rd.next();
}
};
template<typename ty>
struct json_impl_out < ty,
typename std::enable_if <detail::is_unsigned_intergral_like<ty>::value>::type >
{
template<typename write_ty>
static inline void write(write_ty& wt, ty const& val)
{
......@@ -1380,31 +1400,36 @@ namespace ajson
};
template<typename ty>
struct json_impl < ty,
struct json_impl_in < ty,
typename std::enable_if <std::is_enum<ty>::value>::type >
{
static inline void read(reader& rd, ty& val)
{
typedef typename std::underlying_type<ty>::type raw_type;
json_impl<raw_type>::read(rd, (raw_type&)val);
json_impl_in<raw_type>::read(rd, (raw_type&)val);
}
};
template<typename ty>
struct json_impl_out < ty,
typename std::enable_if <std::is_enum<ty>::value>::type >
{
template<typename write_ty>
static inline void write(write_ty& wt, ty const& val)
{
typedef typename std::underlying_type<ty>::type raw_type;
json_impl<raw_type>::write(wt, val);
json_impl_out<raw_type>::write(wt, val);
}
template<typename write_ty>
static inline void write_key(write_ty& wt, ty const& val)
{
typedef typename std::underlying_type<ty>::type raw_type;
json_impl<raw_type>::write_key(wt, val);
json_impl_out<raw_type>::write_key(wt, val);
}
};
template<typename ty>
struct json_impl < ty,
struct json_impl_in < ty,
typename std::enable_if <std::is_floating_point<ty>::value>::type >
{
static inline void read(reader& rd, ty& val)
......@@ -1444,6 +1469,11 @@ namespace ajson
}
rd.next();
}
};
template<typename ty>
struct json_impl_out < ty,
typename std::enable_if <std::is_floating_point<ty>::value>::type >
{
template<typename write_ty>
static inline void write(write_ty& wt, ty const& val)
{
......@@ -1451,7 +1481,8 @@ namespace ajson
#ifdef _MSC_VER
_gcvt_s(buffer, 63 , val, 8);
#else
gcvt(val, 62, buffer);
sprintf(buffer,"%.8f",val);
// gcvt(val, 62, buffer);
#endif // MSVC
size_t len = std::strlen(buffer);
if (buffer[len - 1] == '.')
......@@ -1625,7 +1656,7 @@ namespace ajson
}
template<typename ty>
struct json_impl < ty,
struct json_impl_in < ty,
typename std::enable_if <detail::is_stdstring<ty>::value>::type >
{
static inline void read(reader& rd, ty& val)
......@@ -1644,6 +1675,11 @@ namespace ajson
}
rd.next();
}
};
template<typename ty>
struct json_impl_out < ty,
typename std::enable_if <detail::is_stdstring<ty>::value>::type >
{
template<typename write_ty>
static inline void write(write_ty& wt, ty const& val)
{
......@@ -1688,13 +1724,16 @@ namespace ajson
}
template<size_t N>
struct json_impl <char[N]>
struct json_impl_in <char[N]>
{
static inline void read(reader& rd, char * val)
{
char_array_read(rd, val, N);
}
};
template<size_t N>
struct json_impl_out <char[N]>
{
template<typename write_ty>
static inline void write(write_ty& wt, const char * val)
{
......@@ -1703,13 +1742,17 @@ namespace ajson
};
template<size_t N>
struct json_impl <const char[N] >
struct json_impl_in <const char[N] >
{
static inline void read(reader& rd, char * val)
{
char_array_read(rd, val, N);
}
};
template<size_t N>
struct json_impl_out <const char[N] >
{
template<typename write_ty>
static inline void write(write_ty& wt, const char * val)
{
......@@ -1731,7 +1774,7 @@ namespace ajson
{
if (count < N)
{
json_impl<T>::read(rd, val[count]);
json_impl_in<T>::read(rd, val[count]);
}
else
{
......@@ -1765,7 +1808,7 @@ namespace ajson
int last = N - 1;
for (int i = 0; i < N; ++i)
{
json_impl<T>::write(wt, val[i]);
json_impl_out<T>::write(wt, val[i]);
if (i < last)
wt.put(',');
}
......@@ -1773,12 +1816,16 @@ namespace ajson
}
template<typename T, size_t N>
struct json_impl <T[N]>
struct json_impl_in <T[N]>
{
static inline void read(reader& rd, T * val)
{
array_read(rd, val, N);
}
};
template<typename T, size_t N>
struct json_impl_out <T[N]>
{
template<typename write_ty>
static inline void write(write_ty& wt, const T * val)
{
......@@ -1787,12 +1834,16 @@ namespace ajson
};
template<typename T, size_t N>
struct json_impl < const T[N]>
struct json_impl_in < const T[N]>
{
static inline void read(reader& rd, T * val)
{
array_read(rd, val, N);
}
};
template<typename T, size_t N>
struct json_impl_out < const T[N]>
{
template<typename write_ty>
static inline void write(write_ty& wt, const T * val)
{
......@@ -1815,7 +1866,7 @@ namespace ajson
}
template<typename ty>
struct json_impl < ty,
struct json_impl_in < ty,
typename std::enable_if <detail::is_sequence_container<ty>::value>::type >
{
static inline void read(reader& rd, ty& val)
......@@ -1829,7 +1880,7 @@ namespace ajson
while (tok->str.str[0] != ']')
{
::ajson::emplace_back(val);
json_impl<typename ty::value_type>::read(rd, val.back());
json_impl_in<typename ty::value_type>::read(rd, val.back());
tok = &rd.peek();
if (tok->str.str[0] == ',')
{
......@@ -1849,6 +1900,11 @@ namespace ajson
rd.next();
return;
}
};
template<typename ty>
struct json_impl_out < ty,
typename std::enable_if <detail::is_sequence_container<ty>::value>::type >
{
template<typename write_ty>
static inline void write(write_ty& wt, ty const& val)
{
......@@ -1856,7 +1912,7 @@ namespace ajson
auto sz = val.size();
for (auto& i : val)
{
json_impl<typename ty::value_type>::write(wt, i);
json_impl_out<typename ty::value_type>::write(wt, i);
if (sz-- > 1)
wt.put(',');
}
......@@ -1865,7 +1921,7 @@ namespace ajson
};
template<typename ty>
struct json_impl < ty,
struct json_impl_in < ty,
typename std::enable_if <detail::is_associat_container<ty>::value>::type >
{
static inline void read(reader& rd, ty& val)
......@@ -1880,13 +1936,13 @@ namespace ajson
{
typename ty::key_type key;
typename ty::mapped_type value;
json_impl<typename ty::key_type>::read(rd, key);
json_impl_in<typename ty::key_type>::read(rd, key);
if (rd.expect(':') == false)
{
rd.error("invalid object!");
}
rd.next();
json_impl<typename ty::mapped_type>::read(rd, value);
json_impl_in<typename ty::mapped_type>::read(rd, value);
val[key] = value;
tok = &rd.peek();
if (tok->str.str[0] == ',')
......@@ -1907,6 +1963,11 @@ namespace ajson
rd.next();
return;
}
};
template<typename ty>
struct json_impl_out < ty,
typename std::enable_if <detail::is_associat_container<ty>::value>::type >
{
template<typename write_ty>
static inline void write(write_ty& wt, ty const& val)
{
......@@ -1914,9 +1975,9 @@ namespace ajson
auto sz = val.size();
for (auto& i : val)
{
json_impl<typename ty::key_type>::write_key(wt, i.first);
json_impl_out<typename ty::key_type>::write_key(wt, i.first);
wt.put(':');
json_impl<typename ty::mapped_type>::write(wt, i.second);
json_impl_out<typename ty::mapped_type>::write(wt, i.second);
if (sz-- > 1)
wt.put(',');
}
......@@ -2043,7 +2104,7 @@ namespace ajson
{
if (member_ptr[pos] == member)
{
json_impl<head>::read(rd, val);
json_impl_in<head>::read(rd, val);
return 1;
}
if (sizeof...(args))
......@@ -2071,7 +2132,7 @@ namespace ajson
{
typedef typename std::remove_cv<ty>::type rty;
reader rd(buff, len);
json_impl<rty>::read(rd, val);
json_impl_in<rty>::read(rd, val);
}
template<typename ty>
......@@ -2123,7 +2184,7 @@ namespace ajson
}
reader rd(buffer, sz);
typedef typename std::remove_cv<ty>::type rty;
json_impl<rty>::read(rd, val);
json_impl_in<rty>::read(rd, val);
}
template<typename write_ty, typename head, typename... args>
......@@ -2141,7 +2202,7 @@ namespace ajson
{
wt.write_str(member_ptr[pos].str, member_ptr[pos].len);
wt.put(':');
json_impl<head>::write(wt, val);
json_impl_out<head>::write(wt, val);
if (sizeof...(args))
{
wt.put(',');
......@@ -2169,7 +2230,7 @@ namespace ajson
{
typedef typename std::remove_cv<ty>::type rty;
write_tp wt(ss);
json_impl<rty>::write(wt, val);
json_impl_out<rty>::write(wt, val);
}
template<typename ty, typename stream_ty = ajson_file_stream, class write_tp = lite_write<stream_ty> >
......@@ -2181,6 +2242,9 @@ namespace ajson
}
#define AJSON(TYPE,...) \
AJSON_IN(TYPE, __VA_ARGS__) \
AJSON_OUT(TYPE, __VA_ARGS__)
/*
namespace ajson\
{\
template<>\
......@@ -2245,4 +2309,87 @@ namespace ajson\
}\
};\
}
*/
#define AJSON_IN(TYPE,...) \
namespace ajson\
{\
template<>\
struct json_impl_in < TYPE, void >\
{\
struct json_helper_in : public TYPE\
{\
inline void read_(reader& rd)\
{\
auto& fields = this_field_list();\
if (rd.expect('{') == false){ rd.error("read object must start with {!"); }\
rd.next();\
if (rd.expect('}'))\
return;\
auto mber = rd.peek();\
do\
{\
if (mber.type != token::t_string){ rd.error("object key must be string"); }\
rd.next();\
if (rd.expect(':') == false){ rd.error("invalid json document!"); }\
rd.next();\
if (read_members(rd, &fields[0], mber.str, 0,__VA_ARGS__) == 0)\
{\
skip(rd);\
}\
if (rd.expect('}'))\
{\
rd.next();\
return;\
}\
else if (rd.expect(','))\
{\
rd.next();\
mber = rd.peek();\
continue;\
}\
rd.error("invalid json document!");\
} while (true);\
}\
};\
static inline detail::field_list& this_field_list()\
{\
static auto fields = detail::split_fields(STRINGFY_LIST(__VA_ARGS__));\
return fields;\
}\
static inline void read(reader& rd, TYPE& v)\
{\
reinterpret_cast<json_helper_in &>(v).read_(rd);\
}\
};\
}
#define AJSON_OUT(TYPE,...) \
namespace ajson\
{\
template<>\
struct json_impl_out < TYPE , void >\
{\
struct json_helper : public TYPE\
{\
template<typename write_ty>\
inline void write_(write_ty& wt) const\
{\
auto& fields = this_field_list();\
wt.put('{');\
::ajson::write_members(wt, &fields[0], 0,__VA_ARGS__);\
wt.put('}');\
}\
};\
static inline detail::field_list& this_field_list()\
{\
static auto fields = detail::split_fields(STRINGFY_LIST(__VA_ARGS__));\
return fields;\
}\
template<typename write_ty>\
static inline void write(write_ty& wt, TYPE const& v)\
{\
reinterpret_cast<json_helper const &>(v).write_(wt);\
}\
};\
}
......@@ -1075,7 +1075,9 @@ namespace ajson
};
template<typename ty, class enable = void>
struct json_impl;
struct json_impl_in;
template<typename ty, class enable = void>
struct json_impl_out;
inline bool is_true(token const& tok)
{
......@@ -1091,7 +1093,7 @@ namespace ajson
}
template<>
struct json_impl < bool, void >
struct json_impl_in < bool, void >
{
static inline void read(reader& rd, bool& val)
{
......@@ -1125,7 +1127,11 @@ namespace ajson
}
rd.next();
}
};
template<>
struct json_impl_out < bool, void >
{
template<typename write_ty>
static inline void write(write_ty& wt, bool const& val)
{
......@@ -1142,7 +1148,7 @@ namespace ajson
};
template<>
struct json_impl < __uint128_t, void >
struct json_impl_in < __uint128_t, void >
{
static inline void read(reader& rd, __uint128_t& val)
{
......@@ -1178,7 +1184,11 @@ namespace ajson
rd.next();
}
};
template<>
struct json_impl_out < __uint128_t, void >
{
template<typename write_ty>
static inline void write(write_ty& wt, __uint128_t const& val)
{
......@@ -1210,7 +1220,7 @@ namespace ajson
};
template<typename ty>
struct json_impl < ty,
struct json_impl_in < ty,
typename std::enable_if <detail::is_signed_intergral_like<ty>::value>::type >
{
static inline void read(reader& rd, ty& val)
......@@ -1257,6 +1267,11 @@ namespace ajson
}
rd.next();
}
};
template<typename ty>
struct json_impl_out < ty,
typename std::enable_if <detail::is_signed_intergral_like<ty>::value>::type >
{
template<typename write_ty>
static inline void write(write_ty& wt, ty const& val)
{
......@@ -1298,7 +1313,7 @@ namespace ajson
};
template<typename ty>
struct json_impl < ty,
struct json_impl_in < ty,
typename std::enable_if <detail::is_unsigned_intergral_like<ty>::value>::type >
{
static inline void read(reader& rd, ty& val)
......@@ -1349,6 +1364,11 @@ namespace ajson
}
rd.next();
}
};
template<typename ty>
struct json_impl_out < ty,
typename std::enable_if <detail::is_unsigned_intergral_like<ty>::value>::type >
{
template<typename write_ty>
static inline void write(write_ty& wt, ty const& val)
{
......@@ -1380,31 +1400,36 @@ namespace ajson
};
template<typename ty>
struct json_impl < ty,
struct json_impl_in < ty,
typename std::enable_if <std::is_enum<ty>::value>::type >
{
static inline void read(reader& rd, ty& val)
{
typedef typename std::underlying_type<ty>::type raw_type;
json_impl<raw_type>::read(rd, (raw_type&)val);
json_impl_in<raw_type>::read(rd, (raw_type&)val);
}
};
template<typename ty>
struct json_impl_out < ty,
typename std::enable_if <std::is_enum<ty>::value>::type >
{
template<typename write_ty>
static inline void write(write_ty& wt, ty const& val)
{
typedef typename std::underlying_type<ty>::type raw_type;
json_impl<raw_type>::write(wt, val);
json_impl_out<raw_type>::write(wt, val);
}
template<typename write_ty>
static inline void write_key(write_ty& wt, ty const& val)
{
typedef typename std::underlying_type<ty>::type raw_type;
json_impl<raw_type>::write_key(wt, val);
json_impl_out<raw_type>::write_key(wt, val);
}
};
template<typename ty>
struct json_impl < ty,
struct json_impl_in < ty,
typename std::enable_if <std::is_floating_point<ty>::value>::type >
{
static inline void read(reader& rd, ty& val)
......@@ -1444,6 +1469,11 @@ namespace ajson
}
rd.next();
}
};
template<typename ty>
struct json_impl_out < ty,
typename std::enable_if <std::is_floating_point<ty>::value>::type >
{
template<typename write_ty>
static inline void write(write_ty& wt, ty const& val)
{
......@@ -1451,7 +1481,8 @@ namespace ajson
#ifdef _MSC_VER
_gcvt_s(buffer, 63 , val, 8);
#else
gcvt(val, 62, buffer);
sprintf(buffer,"%.8f",val);
// gcvt(val, 62, buffer);
#endif // MSVC
size_t len = std::strlen(buffer);
if (buffer[len - 1] == '.')
......@@ -1625,7 +1656,7 @@ namespace ajson
}
template<typename ty>
struct json_impl < ty,
struct json_impl_in < ty,
typename std::enable_if <detail::is_stdstring<ty>::value>::type >
{
static inline void read(reader& rd, ty& val)
......@@ -1644,6 +1675,11 @@ namespace ajson
}
rd.next();
}
};
template<typename ty>
struct json_impl_out < ty,
typename std::enable_if <detail::is_stdstring<ty>::value>::type >
{
template<typename write_ty>
static inline void write(write_ty& wt, ty const& val)
{
......@@ -1688,13 +1724,16 @@ namespace ajson
}
template<size_t N>
struct json_impl <char[N]>
struct json_impl_in <char[N]>
{
static inline void read(reader& rd, char * val)
{
char_array_read(rd, val, N);
}
};
template<size_t N>
struct json_impl_out <char[N]>
{
template<typename write_ty>
static inline void write(write_ty& wt, const char * val)
{
......@@ -1703,13 +1742,17 @@ namespace ajson
};
template<size_t N>
struct json_impl <const char[N] >
struct json_impl_in <const char[N] >
{
static inline void read(reader& rd, char * val)
{
char_array_read(rd, val, N);
}
};
template<size_t N>
struct json_impl_out <const char[N] >
{
template<typename write_ty>
static inline void write(write_ty& wt, const char * val)
{
......@@ -1731,7 +1774,7 @@ namespace ajson
{
if (count < N)
{
json_impl<T>::read(rd, val[count]);
json_impl_in<T>::read(rd, val[count]);
}
else
{
......@@ -1765,7 +1808,7 @@ namespace ajson
int last = N - 1;
for (int i = 0; i < N; ++i)
{
json_impl<T>::write(wt, val[i]);
json_impl_out<T>::write(wt, val[i]);
if (i < last)
wt.put(',');
}
......@@ -1773,12 +1816,16 @@ namespace ajson
}
template<typename T, size_t N>
struct json_impl <T[N]>
struct json_impl_in <T[N]>
{
static inline void read(reader& rd, T * val)
{
array_read(rd, val, N);
}
};
template<typename T, size_t N>
struct json_impl_out <T[N]>
{
template<typename write_ty>
static inline void write(write_ty& wt, const T * val)
{
......@@ -1787,12 +1834,16 @@ namespace ajson
};
template<typename T, size_t N>
struct json_impl < const T[N]>
struct json_impl_in < const T[N]>
{
static inline void read(reader& rd, T * val)
{
array_read(rd, val, N);
}
};
template<typename T, size_t N>
struct json_impl_out < const T[N]>
{
template<typename write_ty>
static inline void write(write_ty& wt, const T * val)
{
......@@ -1815,7 +1866,7 @@ namespace ajson
}
template<typename ty>
struct json_impl < ty,
struct json_impl_in < ty,
typename std::enable_if <detail::is_sequence_container<ty>::value>::type >
{
static inline void read(reader& rd, ty& val)
......@@ -1829,7 +1880,7 @@ namespace ajson
while (tok->str.str[0] != ']')
{
::ajson::emplace_back(val);
json_impl<typename ty::value_type>::read(rd, val.back());
json_impl_in<typename ty::value_type>::read(rd, val.back());
tok = &rd.peek();
if (tok->str.str[0] == ',')
{
......@@ -1849,6 +1900,11 @@ namespace ajson
rd.next();
return;
}
};
template<typename ty>
struct json_impl_out < ty,
typename std::enable_if <detail::is_sequence_container<ty>::value>::type >
{
template<typename write_ty>
static inline void write(write_ty& wt, ty const& val)
{
......@@ -1856,7 +1912,7 @@ namespace ajson
auto sz = val.size();
for (auto& i : val)
{
json_impl<typename ty::value_type>::write(wt, i);
json_impl_out<typename ty::value_type>::write(wt, i);
if (sz-- > 1)
wt.put(',');
}
......@@ -1865,7 +1921,7 @@ namespace ajson
};
template<typename ty>
struct json_impl < ty,
struct json_impl_in < ty,
typename std::enable_if <detail::is_associat_container<ty>::value>::type >
{
static inline void read(reader& rd, ty& val)
......@@ -1880,13 +1936,13 @@ namespace ajson
{
typename ty::key_type key;
typename ty::mapped_type value;
json_impl<typename ty::key_type>::read(rd, key);
json_impl_in<typename ty::key_type>::read(rd, key);
if (rd.expect(':') == false)
{
rd.error("invalid object!");
}
rd.next();
json_impl<typename ty::mapped_type>::read(rd, value);
json_impl_in<typename ty::mapped_type>::read(rd, value);
val[key] = value;
tok = &rd.peek();
if (tok->str.str[0] == ',')
......@@ -1907,6 +1963,11 @@ namespace ajson
rd.next();
return;
}
};
template<typename ty>
struct json_impl_out < ty,
typename std::enable_if <detail::is_associat_container<ty>::value>::type >
{
template<typename write_ty>
static inline void write(write_ty& wt, ty const& val)
{
......@@ -1914,9 +1975,9 @@ namespace ajson
auto sz = val.size();
for (auto& i : val)
{
json_impl<typename ty::key_type>::write_key(wt, i.first);
json_impl_out<typename ty::key_type>::write_key(wt, i.first);
wt.put(':');
json_impl<typename ty::mapped_type>::write(wt, i.second);
json_impl_out<typename ty::mapped_type>::write(wt, i.second);
if (sz-- > 1)
wt.put(',');
}
......@@ -2043,7 +2104,7 @@ namespace ajson
{
if (member_ptr[pos] == member)
{
json_impl<head>::read(rd, val);
json_impl_in<head>::read(rd, val);
return 1;
}
if (sizeof...(args))
......@@ -2071,7 +2132,7 @@ namespace ajson
{
typedef typename std::remove_cv<ty>::type rty;
reader rd(buff, len);
json_impl<rty>::read(rd, val);
json_impl_in<rty>::read(rd, val);
}
template<typename ty>
......@@ -2123,7 +2184,7 @@ namespace ajson
}
reader rd(buffer, sz);
typedef typename std::remove_cv<ty>::type rty;
json_impl<rty>::read(rd, val);
json_impl_in<rty>::read(rd, val);
}
template<typename write_ty, typename head, typename... args>
......@@ -2141,7 +2202,7 @@ namespace ajson
{
wt.write_str(member_ptr[pos].str, member_ptr[pos].len);
wt.put(':');
json_impl<head>::write(wt, val);
json_impl_out<head>::write(wt, val);
if (sizeof...(args))
{
wt.put(',');
......@@ -2169,7 +2230,7 @@ namespace ajson
{
typedef typename std::remove_cv<ty>::type rty;
write_tp wt(ss);
json_impl<rty>::write(wt, val);
json_impl_out<rty>::write(wt, val);
}
template<typename ty, typename stream_ty = ajson_file_stream, class write_tp = lite_write<stream_ty> >
......@@ -2181,6 +2242,9 @@ namespace ajson
}
#define AJSON(TYPE,...) \
AJSON_IN(TYPE, __VA_ARGS__) \
AJSON_OUT(TYPE, __VA_ARGS__)
/*
namespace ajson\
{\
template<>\
......@@ -2245,4 +2309,87 @@ namespace ajson\
}\
};\
}
*/
#define AJSON_IN(TYPE,...) \
namespace ajson\
{\
template<>\
struct json_impl_in < TYPE, void >\
{\
struct json_helper_in : public TYPE\
{\
inline void read_(reader& rd)\
{\
auto& fields = this_field_list();\
if (rd.expect('{') == false){ rd.error("read object must start with {!"); }\
rd.next();\
if (rd.expect('}'))\
return;\
auto mber = rd.peek();\
do\
{\
if (mber.type != token::t_string){ rd.error("object key must be string"); }\
rd.next();\
if (rd.expect(':') == false){ rd.error("invalid json document!"); }\
rd.next();\
if (read_members(rd, &fields[0], mber.str, 0,__VA_ARGS__) == 0)\
{\
skip(rd);\
}\
if (rd.expect('}'))\
{\
rd.next();\
return;\
}\
else if (rd.expect(','))\
{\
rd.next();\
mber = rd.peek();\
continue;\
}\
rd.error("invalid json document!");\
} while (true);\
}\
};\
static inline detail::field_list& this_field_list()\
{\
static auto fields = detail::split_fields(STRINGFY_LIST(__VA_ARGS__));\
return fields;\
}\
static inline void read(reader& rd, TYPE& v)\
{\
reinterpret_cast<json_helper_in &>(v).read_(rd);\
}\
};\
}
#define AJSON_OUT(TYPE,...) \
namespace ajson\
{\
template<>\
struct json_impl_out < TYPE , void >\
{\
struct json_helper : public TYPE\
{\
template<typename write_ty>\
inline void write_(write_ty& wt) const\
{\
auto& fields = this_field_list();\
wt.put('{');\
::ajson::write_members(wt, &fields[0], 0,__VA_ARGS__);\
wt.put('}');\
}\
};\
static inline detail::field_list& this_field_list()\
{\
static auto fields = detail::split_fields(STRINGFY_LIST(__VA_ARGS__));\
return fields;\
}\
template<typename write_ty>\
static inline void write(write_ty& wt, TYPE const& v)\
{\
reinterpret_cast<json_helper const &>(v).write_(wt);\
}\
};\
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment