84 lines
2.5 KiB
C++
84 lines
2.5 KiB
C++
/**
|
|
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 <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#ifndef RJP_PARSE_HPP
|
|
#define RJP_PARSE_HPP
|
|
|
|
#include <rjp.h>
|
|
#include "string.hpp"
|
|
#include "value.hpp"
|
|
|
|
#include <utility> //move
|
|
#include <tuple>
|
|
|
|
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<int... Indexes>
|
|
struct sequence_tup{};
|
|
template<int N, int... Indexes>
|
|
struct sequence_gen : public sequence_gen<N-1, Indexes..., sizeof...(Indexes)>{};
|
|
template<int... Indexes>
|
|
struct sequence_gen<0, Indexes...>{
|
|
using type = sequence_tup<Indexes...>;
|
|
};
|
|
|
|
template<class Func, class... Args>
|
|
struct parse_helper{
|
|
Func&& func;
|
|
std::tuple<Args...> tup;
|
|
|
|
template<int... Indexes>
|
|
int operator()(char* c, int size, sequence_tup<Indexes...>)const{
|
|
return std::forward<Func>(func)(c, size, std::get<Indexes>(tup)...);
|
|
}
|
|
};
|
|
struct invoker{
|
|
virtual ~invoker(void){}
|
|
virtual int run(char*, int)const = 0;
|
|
};
|
|
template<class Func, class... Args>
|
|
struct invoker_impl : public invoker{
|
|
parse_helper<Func,Args...> ph;
|
|
|
|
template<class Fn, class... Ts>
|
|
invoker_impl(Fn&& fn, Ts&&... ts):
|
|
ph{std::forward<Fn>(fn), {std::forward<Ts>(ts)...}}{}
|
|
int run(char* c, int size)const override{
|
|
return ph(c, size, typename sequence_gen<sizeof...(Args)>::type{});
|
|
}
|
|
};
|
|
RJP_value* parse_cback(RJP_parse_flag f, RJP_parse_callback* cb);
|
|
int irjp_parse_callback(char* dest, int size, void* userdata);
|
|
}
|
|
template<class Func, class... Args>
|
|
value parse_json(RJP_parse_flag f, Func&& func, Args&&... args){
|
|
RJP_parse_callback cb;
|
|
detail::invoker_impl<Func,Args...> inv(std::forward<Func>(func), std::forward<Args>(args)...);
|
|
cb.data = static_cast<void*>(&inv);
|
|
cb.read = detail::irjp_parse_callback;
|
|
return value(detail::parse_cback(f, &cb), true);
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|