Rearrange some rjp++ files. Also realized that subobject return does not qualify for nrvo, so that's a problem.

This commit is contained in:
rexy712 2020-03-26 18:38:01 -07:00
parent 7121f8a26e
commit 295c27029b
14 changed files with 143 additions and 126 deletions

View File

@ -30,7 +30,7 @@ configure_file(
)
set_target_properties(rjp++ PROPERTIES PUBLIC_HEADER ${INCLUDE_PATH}/rjp.hpp)
set(CPP_HEADERS ${INCLUDE_PATH}/array.hpp ${INCLUDE_PATH}/integral.hpp ${INCLUDE_PATH}/iterator.hpp
${INCLUDE_PATH}/member.hpp ${INCLUDE_PATH}/object.hpp ${INCLUDE_PATH}/rjp_internal.hpp
${INCLUDE_PATH}/member.hpp ${INCLUDE_PATH}/object.hpp ${INCLUDE_PATH}/parse.hpp
${INCLUDE_PATH}/string.hpp ${INCLUDE_PATH}/string_val.hpp ${INCLUDE_PATH}/value.hpp
${INCLUDE_PATH}/rjp_util.hpp)

65
rjp++/include/parse.hpp Normal file
View File

@ -0,0 +1,65 @@
#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{});
}
};
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(rjp_parse_cback(f, &cb), true);
}
}
#endif

View File

@ -19,112 +19,15 @@
#ifndef RJP_HPP_INTERNAL
#define RJP_HPP_INTERNAL
#include <rjp.h>
#include "array.hpp"
#include "integral.hpp"
#include "iterator.hpp"
#include "member.hpp"
#include "object.hpp"
#include "rjp_internal.hpp"
#include "string.hpp"
#include "string_val.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{});
}
};
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(rjp_parse_cback(f, &cb), true);
}
namespace detail{
template<class To, class From, bool = std::is_same<std::remove_reference_t<To>,std::remove_reference_t<From>>::value>
struct convert_helper;
template<class To, class From>
struct convert_helper<To,From,false>{
static To perform(From&& t){
return To(std::move(t));
}
};
template<class To, class From>
struct convert_helper<To,From&,false>{
static To perform(const From& t){
return To(const_cast<RJP_value*>(t.raw()), false);
}
};
template<class To, class From>
struct convert_helper<To,From,true>{
static decltype(auto) perform(From&& t){
return std::forward<From>(t);
}
};
}
template<class To, class From>
To convert(From&& from){
return detail::convert_helper<To,From>::perform(std::forward<From>(from));
}
namespace detail{
template<class To, class From>
struct get_ref{
using type = std::remove_reference_t<To>;
};
template<class To, class From>
struct get_ref<To, From&>{
using type = std::remove_reference_t<To>&;
};
template<class To, class From>
struct get_ref<To, From&&>{
using type = std::remove_reference_t<To>&&;
};
}
template<class To, class From>
decltype(auto) cast(From&& from){
return static_cast<typename detail::get_ref<To,From&&>::type>(std::forward<From>(from));
}
}
#include "parse.hpp"
#endif

View File

@ -23,6 +23,54 @@
#include "integral.hpp"
namespace rjp::detail{
namespace detail{
template<class To, class From, bool = std::is_same<std::remove_reference_t<To>,std::remove_reference_t<From>>::value>
struct convert_helper;
template<class To, class From>
struct convert_helper<To,From,false>{
static To perform(From&& t){
return To(std::move(t));
}
};
template<class To, class From>
struct convert_helper<To,From&,false>{
static To perform(const From& t){
return To(const_cast<RJP_value*>(t.raw()), false);
}
};
template<class To, class From>
struct convert_helper<To,From,true>{
static decltype(auto) perform(From&& t){
return std::forward<From>(t);
}
};
}
template<class To, class From>
To convert(From&& from){
return detail::convert_helper<To,From>::perform(std::forward<From>(from));
}
namespace detail{
template<class To, class From>
struct get_ref{
using type = std::remove_reference_t<To>;
};
template<class To, class From>
struct get_ref<To, From&>{
using type = std::remove_reference_t<To>&;
};
template<class To, class From>
struct get_ref<To, From&&>{
using type = std::remove_reference_t<To>&&;
};
}
template<class To, class From>
decltype(auto) cast(From&& from){
return static_cast<typename detail::get_ref<To,From&&>::type>(std::forward<From>(from));
}
template<class Val>
void set_to_underlying(RJP_value* val, typename Val::underlying_type);
template<>

View File

@ -16,7 +16,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "rjp.h"
#include <rjp.h>
#include "string.hpp"
#include <cstring> //memcpy

View File

@ -17,7 +17,7 @@
*/
#include "array.hpp"
#include "rjp.h"
#include <rjp.h>
#include <utility> //move, swap
namespace rjp{

View File

@ -17,7 +17,7 @@
*/
#include "integral.hpp"
#include "rjp.h"
#include <rjp.h>
#include <utility> //move
namespace rjp{

View File

@ -17,7 +17,7 @@
*/
#include "object.hpp"
#include "rjp.h"
#include <rjp.h>
#include <utility> //move
namespace rjp{

View File

@ -20,6 +20,7 @@
#include <rexy/string_base.hpp>
#include "rjp_internal.hpp"
#include "parse.hpp"
#include "string.hpp"
#include "value.hpp"
#include "rjp_util.hpp"

View File

@ -17,7 +17,7 @@
*/
#include <rexy/string.hpp>
#include "rjp.h"
#include <rjp.h>
#include "string.hpp"
#include <utility> //exchange

View File

@ -17,7 +17,7 @@
*/
#include "string_val.hpp"
#include "rjp.h"
#include <rjp.h>
#include <utility> //move
namespace rjp{

View File

@ -17,7 +17,7 @@
*/
#include "value.hpp"
#include "rjp.h"
#include <rjp.h>
#include <utility> //swap, move, exchange
namespace rjp{

View File

@ -1,4 +1,4 @@
#include "rjp.hpp"
#include "rjp_internal.hpp"
#include <stdio.h>
#include <string.h>
@ -35,14 +35,14 @@ rjp::value case_6(void){
rjp::value case_8(void){
rjp::object obj;
obj.add<rjp::integer>("key"_ss, 7);
return obj;
return std::move(obj);
}
//handle object with subobject
rjp::value case_9(void){
rjp::object obj;
rjp::object sub = obj.add<rjp::object>("key"_ss);
sub.add<rjp::boolean>("subkey"_ss, false);
return obj;
return std::move(obj);
}
//handle object with multiple members
rjp::value case_10(void){
@ -50,7 +50,7 @@ rjp::value case_10(void){
rjp::object sub = obj.add<rjp::object>("key"_ss);
sub.add<rjp::boolean>("subkey"_ss, false);
sub.add<rjp::boolean>("subkey2"_ss, true);
return obj;
return std::move(obj);
}
//handle object member ordering
rjp::value case_11(void){
@ -58,7 +58,7 @@ rjp::value case_11(void){
rjp::object sub = obj.add<rjp::object>("key"_ss);
sub.add<rjp::boolean>("subkey2"_ss, true);
sub.add<rjp::boolean>("subkey"_ss, false);
return obj;
return std::move(obj);
}
//handle orderedobject member ordering
/*RJP_value* case_12(void){
@ -82,13 +82,13 @@ RJP_value* case_13(void){
rjp::value case_14(void){
rjp::array arr;
arr.add<rjp::integer>(5);
return arr;
return std::move(arr);
}
//handle array with subarray
rjp::value case_15(void){
rjp::array arr;
arr.add<rjp::array>().add<rjp::boolean>(false);
return arr;
return std::move(arr);
}
//handle array with multiple elements
rjp::value case_16(void){
@ -96,7 +96,7 @@ rjp::value case_16(void){
rjp::array sub = arr.add<rjp::array>();
sub.add<rjp::boolean>(false);
sub.add<rjp::boolean>(true);
return arr;
return std::move(arr);
}
//handle array with multiple elements and subarray
rjp::value case_17(void){
@ -105,7 +105,7 @@ rjp::value case_17(void){
rjp::array sub = arr.add<rjp::array>();
sub.add<rjp::boolean>(false);
sub.add<rjp::boolean>(true);
return arr;
return std::move(arr);
}
//handle array with subobject with subarray
rjp::value case_18(void){
@ -114,7 +114,7 @@ rjp::value case_18(void){
rjp::object subobj = arr.add<rjp::object>();
rjp::array subarr = subobj.add<rjp::array>("key"_ss);
subarr.add<rjp::boolean>(false);
return arr;
return std::move(arr);
}
//handle object with many members
rjp::value case_19(void){
@ -126,7 +126,7 @@ rjp::value case_19(void){
subobj.add<rjp::boolean>(rexy::static_string(c), i % 2 == 0);
c[3] += 1;
}
return arr;
return std::move(arr);
}
//handle orderedobject with many members as array element
/*RJP_value* case_20(void){
@ -151,7 +151,7 @@ rjp::value case_21(void){
rjp::array arr = obj.add<rjp::array>("arr"_ss);
for(int i = 0;i < 10;++i)
arr.add<rjp::integer>(i);
return obj;
return std::move(obj);
}
/*
//handle unorderedobject conversion

View File

@ -1,4 +1,4 @@
#include "rjp.hpp"
#include "rjp_internal.hpp"
#include <stdio.h>
#include <string.h>