/** rjp++ Copyright (C) 2020 rexy712 This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef RJP_PARSE_HPP #define RJP_PARSE_HPP #include #include "string.hpp" #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 rexy::string_base& str, RJP_parse_flag, RJP_parse_error&); value parse_json(const char* str, RJP_parse_flag = RJP_PARSE_NONE); value parse_json(const char* str, RJP_parse_flag, RJP_parse_error&); 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{}); } }; RJP_value* parse_cback(RJP_parse_flag f, RJP_parse_callback* cb, RJP_parse_error& err); RJP_value* parse_cback(RJP_parse_flag f, RJP_parse_callback* cb); 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(detail::parse_cback(f, &cb), true); } template value parse_json(RJP_parse_flag f, RJP_parse_error& err, 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(detail::parse_cback(f, &cb, err), true); } } #endif