diff --git a/rjp++/include/rjp_internal.hpp b/rjp++/include/rjp_internal.hpp index b9866c6..e663a56 100644 --- a/rjp++/include/rjp_internal.hpp +++ b/rjp++/include/rjp_internal.hpp @@ -24,12 +24,59 @@ #include "value.hpp" #include //move +#include namespace rjp{ string to_json(const value& val, int format = RJP_FORMAT_PRETTY); value parse_json(const rexy::string_base& str, RJP_parse_flag = RJP_PARSE_NONE); value parse_json(const char* str, RJP_parse_flag = RJP_PARSE_NONE); + namespace detail{ + template + struct sequence_tup{}; + template + struct sequence_gen : public sequence_gen{}; + template + struct sequence_gen<0, Indexes...>{ + using type = sequence_tup; + }; + + template + struct parse_helper{ + Func&& func; + std::tuple tup; + + template + int operator()(char* c, int size, sequence_tup)const{ + return std::forward(func)(c, size, std::get(tup)...); + } + }; + struct invoker{ + virtual ~invoker(void){} + virtual int run(char*, int)const = 0; + }; + template + struct invoker_impl : public invoker{ + parse_helper ph; + + template + invoker_impl(Fn&& fn, Ts&&... ts): + ph{std::forward(fn), {std::forward(ts)...}}{} + int run(char* c, int size)const override{ + return ph(c, size, typename sequence_gen::type{}); + } + }; + + int irjp_parse_callback(char* dest, int size, void* userdata); + } + template + value parse_json(RJP_parse_flag f, Func&& func, Args&&... args){ + RJP_parse_callback cb; + detail::invoker_impl inv(std::forward(func), std::forward(args)...); + cb.data = static_cast(&inv); + cb.read = detail::irjp_parse_callback; + return value(rjp_parse_cback(f, &cb), true); + } namespace detail{ template,std::remove_reference_t>::value> diff --git a/rjp++/include/value.hpp b/rjp++/include/value.hpp index 2f40f12..0cad6f0 100644 --- a/rjp++/include/value.hpp +++ b/rjp++/include/value.hpp @@ -22,6 +22,9 @@ namespace rjp{ value& operator=(const value& val); value& operator=(value&& val); + operator bool(void)const; + bool valid(void)const; + const RJP_value* raw(void)const; RJP_value* raw(void); diff --git a/rjp++/src/rjp.cpp b/rjp++/src/rjp.cpp index 27e4e6a..25261e7 100644 --- a/rjp++/src/rjp.cpp +++ b/rjp++/src/rjp.cpp @@ -32,4 +32,10 @@ namespace rjp{ value parse_json(const char* str, RJP_parse_flag flags){ return value(rjp_parse(str, flags), true); } + namespace detail{ + int irjp_parse_callback(char* dest, int size, void* userdata){ + invoker* inv = static_cast(userdata); + return inv->run(dest, size); + } + } } diff --git a/rjp++/src/value.cpp b/rjp++/src/value.cpp index 090025b..a059295 100644 --- a/rjp++/src/value.cpp +++ b/rjp++/src/value.cpp @@ -49,6 +49,12 @@ namespace rjp{ std::swap(val.m_managed, m_managed); return *this; } + value::operator bool(void)const{ + return m_value != nullptr; + } + bool value::valid(void)const{ + return m_value != nullptr; + } const RJP_value* value::raw(void)const{ return m_value;