Reworked rjp++ element/member addition

This commit is contained in:
rexy712 2020-03-24 16:34:07 -07:00
parent 86de4d2bb3
commit a4d1a98a0e
10 changed files with 254 additions and 15 deletions

View File

@ -30,7 +30,8 @@ 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}/string.hpp ${INCLUDE_PATH}/string_val.hpp ${INCLUDE_PATH}/value.hpp)
${INCLUDE_PATH}/string.hpp ${INCLUDE_PATH}/string_val.hpp ${INCLUDE_PATH}/value.hpp
${INCLUDE_PATH}/rjp_util.hpp)
if(ENABLE_PROFILING)

View File

@ -4,9 +4,15 @@
#include <rjp.h>
#include "iterator.hpp"
#include "value.hpp"
#include "integral.hpp"
#include "string_val.hpp"
#include "rjp_util.hpp"
namespace rjp{
class object;
class array_iterator : protected detail::iterator_base
{
protected:
@ -45,7 +51,30 @@ namespace rjp{
array& operator=(const array&) = default;
array& operator=(array&&) = default;
value add(void);
template<class Val>
std::decay_t<Val> add(typename std::decay_t<Val>::underlying_type t){
RJP_value* newelem = rjp_new_element(m_value);
detail::set_to_underlying<std::decay_t<Val>>(newelem, t);
return create_unmanaged(newelem);
}
template<class Val = null>
std::decay_t<Val> add(void){
RJP_value* newelem = rjp_new_element(m_value);
if constexpr(std::is_same<std::decay_t<Val>,rjp::array>::value)
rjp_set_array(newelem);
else if constexpr(std::is_same<std::decay_t<Val>,rjp::object>::value)
rjp_set_object(newelem);
else if constexpr(std::is_void<typename std::decay_t<Val>::underlying_type>::value)
rjp_set_null(newelem);
else
detail::set_to_underlying<std::decay_t<Val>>(newelem, 0);
return create_unmanaged(newelem);
}
string_val add(const RJP_string&);
string_val add(RJP_string&&);
string_val add(const char*, RJP_index len = 0);
string_val add(const rexy::string_base&);
string_val add(string&&);
value& remove(value& val);
void destroy(value&& val);

View File

@ -75,6 +75,8 @@ namespace rjp{
};
class null : public value
{
public:
using underlying_type = void;
public:
using value::value;
null(void);

View File

@ -13,11 +13,11 @@ namespace rjp::detail{
class value_wrapper
{
private:
member m_value;
member<void> m_value;
public:
value_wrapper(RJP_value* value, bool managed):
m_value(value, managed){}
member* operator->(void){
member<void>* operator->(void){
return &m_value;
}
};

View File

@ -9,7 +9,36 @@
namespace rjp{
class member : public value
template<class Type>
class member : public Type
{
public:
member(void) = default;
member(const member&) = default;
member(member&&) = default;
member(const Type& val):
Type(val){}
member(Type&& val):
value(std::move(val)){}
member(const value& val):
Type(val){}
member(value&& val):
Type(std::move(val)){}
using Type::Type;
~member(void) = default;
member& operator=(const member&) = default;
member& operator=(member&&) = default;
rexy::static_string key(void)const{
return rexy::static_string(rjp_member_key(this->m_value)->value, rjp_member_key(this->m_value)->length);
}
string steal_key(void){
return string(this->m_value);
}
};
template<>
class member<void> : public value
{
public:
member(void) = default;
@ -25,8 +54,12 @@ namespace rjp{
member& operator=(const member&) = default;
member& operator=(member&&) = default;
rexy::static_string key(void)const{return rexy::static_string(rjp_member_key(m_value)->value, rjp_member_key(m_value)->length);}
string steal_key(void){return string(m_value);}
rexy::static_string key(void)const{
return rexy::static_string(rjp_member_key(m_value)->value, rjp_member_key(m_value)->length);
}
string steal_key(void){
return string(m_value);
}
};
}

View File

@ -6,9 +6,14 @@
#include "value.hpp"
#include "iterator.hpp"
#include "member.hpp"
#include "integral.hpp"
#include "string_val.hpp"
#include "rjp_util.hpp"
namespace rjp{
class array;
class object_iterator : protected detail::iterator_base
{
protected:
@ -25,7 +30,7 @@ namespace rjp{
bool operator==(const object_iterator& o)const;
bool operator!=(const object_iterator& o)const;
member operator*(void)const;
member<void> operator*(void)const;
value_wrapper operator->(void)const;
object_iterator& operator++(void);
@ -48,7 +53,57 @@ namespace rjp{
object& operator=(const object&) = default;
object& operator=(object&&) = default;
member add(const rexy::string_base& key);
template<class Val>
member<std::decay_t<Val>> add(const rexy::string_base& key, typename std::decay_t<Val>::underlying_type t){
RJP_value* newmem = rjp_new_member_key_copy(m_value, key.get(), key.length());
detail::set_to_underlying<std::decay_t<Val>>(newmem, t);
return create_unmanaged(newmem);
}
template<class Val = null>
member<std::decay_t<Val>> add(const rexy::string_base& key){
RJP_value* newmem = rjp_new_member_key_copy(m_value, key.get(), key.length());
if constexpr(std::is_same<std::decay_t<Val>,rjp::array>::value)
rjp_set_array(newmem);
else if constexpr(std::is_same<std::decay_t<Val>,rjp::object>::value)
rjp_set_object(newmem);
else if constexpr(std::is_void<typename std::decay_t<Val>::underlying_type>::value)
rjp_set_null(newmem);
else
detail::set_to_underlying<std::decay_t<Val>>(newmem, 0);
return create_unmanaged(newmem);
}
member<string_val> add(const rexy::string_base& key, const RJP_string&);
member<string_val> add(const rexy::string_base& key, RJP_string&&);
member<string_val> add(const rexy::string_base& key, const char*, RJP_index len = 0);
member<string_val> add(const rexy::string_base& key, const rexy::string_base&);
member<string_val> add(const rexy::string_base& key, string&&);
template<class Val>
member<std::decay_t<Val>> add(string&& key, typename std::decay_t<Val>::underlying_type t){
auto len = key.length();
RJP_value* newmem = rjp_new_member(m_value, key.release(), len);
detail::set_to_underlying<std::decay_t<Val>>(newmem, t);
return create_unmanaged(newmem);
}
template<class Val = null>
member<std::decay_t<Val>> add(string&& key){
auto len = key.length();
RJP_value* newmem = rjp_new_member(m_value, key.release(), len);
if constexpr(std::is_same<std::decay_t<Val>,rjp::array>::value)
rjp_set_array(newmem);
else if constexpr(std::is_same<std::decay_t<Val>,rjp::object>::value)
rjp_set_object(newmem);
else if constexpr(std::is_void<typename std::decay_t<Val>::underlying_type>::value)
rjp_set_null(newmem);
else
detail::set_to_underlying<std::decay_t<Val>>(newmem, 0);
return create_unmanaged(newmem);
}
member<string_val> add(string&& key, const RJP_string&);
member<string_val> add(string&& key, RJP_string&&);
member<string_val> add(string&& key, const char*, RJP_index len = 0);
member<string_val> add(string&& key, const rexy::string_base&);
member<string_val> add(string&& key, string&&);
value remove(const rexy::string_base& key);
value& remove(value& val);

View File

@ -0,0 +1,36 @@
/**
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_UTIL_HPP
#define RJP_UTIL_HPP
#include <rjp.h>
#include "integral.hpp"
namespace rjp::detail{
template<class Val>
void set_to_underlying(RJP_value* val, typename Val::underlying_type);
template<>
void set_to_underlying<rjp::integer>(RJP_value* val, RJP_int i);
template<>
void set_to_underlying<rjp::dfloat>(RJP_value* val, RJP_float f);
template<>
void set_to_underlying<rjp::boolean>(RJP_value* val, RJP_bool b);
}
#endif

View File

@ -36,8 +36,28 @@ namespace rjp{
if(rjp_value_type(m_value) != rjp_json_array)
rjp_set_array(m_value);
}
value array::add(void){
string_val array::add(const RJP_string& s){
RJP_value* newelem = rjp_new_element(m_value);
rjp_set_string_copy(newelem, s.value, s.length);
return create_unmanaged(newelem);
}
string_val array::add(RJP_string&& s){
RJP_value* newelem = rjp_new_element(m_value);
rjp_set_string(newelem, s.value, s.length);
return create_unmanaged(newelem);
}
string_val array::add(const char* c, RJP_index len){
RJP_value* newelem = rjp_new_element(m_value);
rjp_set_string_copy(newelem, c, len);
return create_unmanaged(newelem);
}
string_val array::add(const rexy::string_base& s){
return add(s.get(), s.length());
}
string_val array::add(string&& s){
RJP_value* newelem = rjp_new_element(m_value);
auto len = s.length();
rjp_set_string(newelem, s.release(), len);
return create_unmanaged(newelem);
}

View File

@ -35,9 +35,58 @@ namespace rjp{
if(rjp_value_type(m_value) != rjp_json_object)
rjp_set_object(m_value);
}
member object::add(const rexy::string_base& key){
RJP_value* newmemb = rjp_new_member_key_copy(m_value, key.get(), key.length());
return create_unmanaged(newmemb);
member<string_val> object::add(const rexy::string_base& key, const RJP_string& s){
RJP_value* newmem = rjp_new_member_key_copy(m_value, key.get(), key.length());
rjp_set_string_copy(newmem, s.value, s.length);
return create_unmanaged(newmem);
}
member<string_val> object::add(const rexy::string_base& key, RJP_string&& s){
RJP_value* newmem = rjp_new_member_key_copy(m_value, key.get(), key.length());
rjp_set_string(newmem, s.value, s.length);
return create_unmanaged(newmem);
}
member<string_val> object::add(const rexy::string_base& key, const char* s, RJP_index len){
RJP_value* newmem = rjp_new_member_key_copy(m_value, key.get(), key.length());
rjp_set_string_copy(newmem, s, len);
return create_unmanaged(newmem);
}
member<string_val> object::add(const rexy::string_base& key, const rexy::string_base& s){
RJP_value* newmem = rjp_new_member_key_copy(m_value, key.get(), key.length());
rjp_set_string_copy(newmem, s.get(), s.length());
return create_unmanaged(newmem);
}
member<string_val> object::add(const rexy::string_base& key, string&& s){
RJP_value* newmem = rjp_new_member_key_copy(m_value, key.get(), key.length());
auto len = s.length();
rjp_set_string(newmem, s.release(), len);
return create_unmanaged(newmem);
}
member<string_val> object::add(string&& key, const RJP_string& s){
RJP_value* newmem = rjp_new_member(m_value, key.get(), key.length());
rjp_set_string_copy(newmem, s.value, s.length);
return create_unmanaged(newmem);
}
member<string_val> object::add(string&& key, RJP_string&& s){
RJP_value* newmem = rjp_new_member(m_value, key.get(), key.length());
rjp_set_string(newmem, s.value, s.length);
return create_unmanaged(newmem);
}
member<string_val> object::add(string&& key, const char* s, RJP_index len){
RJP_value* newmem = rjp_new_member(m_value, key.get(), key.length());
rjp_set_string_copy(newmem, s, len);
return create_unmanaged(newmem);
}
member<string_val> object::add(string&& key, const rexy::string_base& s){
RJP_value* newmem = rjp_new_member(m_value, key.get(), key.length());
rjp_set_string_copy(newmem, s.get(), s.length());
return create_unmanaged(newmem);
}
member<string_val> object::add(string&& key, string&& s){
RJP_value* newmem = rjp_new_member(m_value, key.get(), key.length());
auto len = s.length();
rjp_set_string(newmem, s.release(), len);
return create_unmanaged(newmem);
}
value object::remove(const rexy::string_base& key){
@ -100,8 +149,8 @@ namespace rjp{
bool object_iterator::operator!=(const object_iterator& o)const{
return !(*this == o);
}
member object_iterator::operator*(void)const{
return member(rjp_object_iterator_current(&m_it), false);
member<void> object_iterator::operator*(void)const{
return member<void>(rjp_object_iterator_current(&m_it), false);
}
auto object_iterator::operator->(void)const -> value_wrapper{
return value_wrapper(rjp_object_iterator_current(&m_it), false);

View File

@ -22,6 +22,7 @@
#include "rjp_internal.hpp"
#include "string.hpp"
#include "value.hpp"
#include "rjp_util.hpp"
namespace rjp{
@ -41,5 +42,18 @@ namespace rjp{
invoker* inv = static_cast<invoker*>(userdata);
return inv->run(dest, size);
}
template<>
void set_to_underlying<rjp::integer>(RJP_value* val, RJP_int i){
rjp_set_int(val, i);
}
template<>
void set_to_underlying<rjp::dfloat>(RJP_value* val, RJP_float f){
rjp_set_float(val, f);
}
template<>
void set_to_underlying<rjp::boolean>(RJP_value* val, RJP_bool b){
rjp_set_bool(val, b);
}
}
}