diff --git a/rjp++/include/rjp.hpp b/rjp++/include/rjp.hpp index 25e292b..2099407 100644 --- a/rjp++/include/rjp.hpp +++ b/rjp++/include/rjp.hpp @@ -37,7 +37,6 @@ namespace rjp{ class string : public rexy::string_intermediary { - protected: public: string(const string&) = default; string(string&&) = default; @@ -70,9 +69,15 @@ namespace rjp{ const RJP_value* raw(void)const; RJP_value* raw(void); + value parent(void)const; + bool is_child_of(const value&)const; + + string to_json(int flags = RJP_FORMAT_PRETTY); protected: static value create_unmanaged(RJP_value* val); + static value create_managed(RJP_value* val); static void remove_management(value& val); + static void add_management(value& val); }; class integer : public value @@ -181,6 +186,22 @@ namespace rjp{ void set(string&& str); }; + + class member : public value + { + public: + member(void) = default; + member(const member&) = default; + member(member&&) = default; + using value::value; + ~member(void) = default; + + member& operator=(const member&) = default; + member& operator=(member&&) = default; + + rexy::static_string key(void)const; + string steal_key(void); + }; class object : public value { public: @@ -194,58 +215,29 @@ namespace rjp{ object& operator=(const object&) = default; object& operator=(object&&) = default; - template - T add(const rexy::string_base& key){ - RJP_value* newmemb = rjp_add_member_key_copy(m_value, key.get(), key.length()); - return T(create_unmanaged(newmemb)); - } template T add(rjp::string&& key, typename T::underlying_type i){ RJP_value* newmemb = rjp_add_member(m_value, key.get(), key.length()); key.release(); return T(create_unmanaged(newmemb), i); } - template - string_val add(const rexy::string_base& key, const rexy::string_base& val){ - RJP_value* newmemb = rjp_add_member_key_copy(m_value, key.get(), key.length()); - return string_val(create_unmanaged(newmemb), val); - } - template - string_val add(const rexy::string_base& key, string&& val){ - RJP_value* newmemb = rjp_add_member_key_copy(m_value, key.get(), key.length()); - return string_val(create_unmanaged(newmemb), std::move(val)); - } - template - string_val add(string&& key, const rexy::string_base& val){ - auto keylen = key.length(); - RJP_value* newmemb = rjp_add_member(m_value, key.release(), keylen); - return string_val(create_unmanaged(newmemb), val); - } - template - string_val add(string&& key, string&& val){ - auto keylen = key.length(); - RJP_value* newmemb = rjp_add_member(m_value, key.release(), keylen); - return string_val(create_unmanaged(newmemb), std::move(val)); - } + value add(const rexy::string_base& key); + string_val add(const rexy::string_base& key, const rexy::string_base& val); + string_val add(const rexy::string_base& key, string&& val); + string_val add(string&& key, const rexy::string_base& val); + string_val add(string&& key, string&& val); - template - T remove(const rexy::string_base& key){ - RJP_value* removed = rjp_remove_member_by_key(m_value, key.get()); - return T(value(removed)); - } - template - T remove(Value&& val){ - RJP_value* removed = rjp_remove_member(m_value, val.m_value); - return T(value(removed)); - } + value remove(const rexy::string_base& key); + value& remove(value& val); void destroy(const rexy::string_base& key); void destroy(value&& val); - template - value& search(const rexy::string_base& key){ + bool has_child(const value&); + + value search(const rexy::string_base& key){ RJP_value* result = rjp_search_member(m_value, key.get()); - return T(create_unmanaged(result)); + return create_unmanaged(result); } }; @@ -263,39 +255,30 @@ namespace rjp{ array& operator=(const array&) = default; array& operator=(array&&) = default; - template - T add(void){ + value add(void){ RJP_value* newelem = rjp_add_element(m_value); - return T(create_unmanaged(newelem)); + return create_unmanaged(newelem); } template T add(typename T::underlying_type i){ RJP_value* newelem = rjp_add_element(m_value); return T(create_unmanaged(newelem), i); } - template - string_val add(const rexy::string_base& val){ - RJP_value* newelem = rjp_add_element(m_value); - return string_val(create_unmanaged(newelem), val); - } - template - string_val add(string&& val){ - RJP_value* newelem = rjp_add_element(m_value); - return string_val(create_unmanaged(newelem), std::move(val)); - } + string_val add(const rexy::string_base& val); + string_val add(string&& val); - template - T remove(Value&& val){ - RJP_value* removed = rjp_remove_element(m_value, val.raw()); - remove_management(val); - return T(value(removed)); - } + value& remove(value& val); void destroy(value&& val); }; string to_json(const value& val, int format = RJP_FORMAT_PRETTY); + + template::value,void>::type* = nullptr> + To cast(From&& from){ + return To(std::move(from)); + } } #endif diff --git a/rjp++/src/array.cpp b/rjp++/src/array.cpp index 453275f..e8e26f1 100644 --- a/rjp++/src/array.cpp +++ b/rjp++/src/array.cpp @@ -35,6 +35,20 @@ namespace rjp{ if(rjp_value_type(m_value) != rjp_json_array) rjp_set_array(m_value); } + string_val array::add(const rexy::string_base& val){ + RJP_value* newelem = rjp_add_element(m_value); + return string_val(create_unmanaged(newelem), val); + } + string_val array::add(string&& val){ + RJP_value* newelem = rjp_add_element(m_value); + return string_val(create_unmanaged(newelem), std::move(val)); + } + + value& array::remove(value& val){ + rjp_remove_element(m_value, val.raw()); + add_management(val); + return val; + } void array::destroy(value&& val){ rjp_free_element(m_value, val.raw()); } diff --git a/rjp++/src/object.cpp b/rjp++/src/object.cpp index 77141a7..0648b31 100644 --- a/rjp++/src/object.cpp +++ b/rjp++/src/object.cpp @@ -35,6 +35,38 @@ namespace rjp{ if(rjp_value_type(m_value) != rjp_json_object) rjp_set_object(m_value); } + value object::add(const rexy::string_base& key){ + RJP_value* newmemb = rjp_add_member_key_copy(m_value, key.get(), key.length()); + return create_unmanaged(newmemb); + } + string_val object::add(const rexy::string_base& key, const rexy::string_base& val){ + RJP_value* newmemb = rjp_add_member_key_copy(m_value, key.get(), key.length()); + return string_val(create_unmanaged(newmemb), val); + } + string_val object::add(const rexy::string_base& key, string&& val){ + RJP_value* newmemb = rjp_add_member_key_copy(m_value, key.get(), key.length()); + return string_val(create_unmanaged(newmemb), std::move(val)); + } + string_val object::add(string&& key, const rexy::string_base& val){ + auto keylen = key.length(); + RJP_value* newmemb = rjp_add_member(m_value, key.release(), keylen); + return string_val(create_unmanaged(newmemb), val); + } + string_val object::add(string&& key, string&& val){ + auto keylen = key.length(); + RJP_value* newmemb = rjp_add_member(m_value, key.release(), keylen); + return string_val(create_unmanaged(newmemb), std::move(val)); + } + + value object::remove(const rexy::string_base& key){ + RJP_value* removed = rjp_remove_member_by_key(m_value, key.get()); + return create_managed(removed); + } + value& object::remove(value& val){ + rjp_remove_member(m_value, val.raw()); + add_management(val); + return val; + } void object::destroy(const rexy::string_base& key){ rjp_free_member_by_key(m_value, key.get()); @@ -42,4 +74,8 @@ namespace rjp{ void object::destroy(value&& val){ rjp_free_member(m_value, val.raw()); } + + bool object::has_child(const value& val){ + return val.parent().raw() == m_value; + } } diff --git a/rjp++/src/value.cpp b/rjp++/src/value.cpp index a4d5a0d..14a51a2 100644 --- a/rjp++/src/value.cpp +++ b/rjp++/src/value.cpp @@ -55,6 +55,19 @@ namespace rjp{ return m_value; } + value value::parent(void)const{ + return create_unmanaged(rjp_value_parent(m_value)); + } + bool value::is_child_of(const value& val)const{ + return rjp_value_parent(m_value) == val.raw(); + } + + string value::to_json(int flags){ + string s; + s.reset(rjp_to_json(m_value, flags)); + return s; + } + value value::create_unmanaged(RJP_value* val){ value retval(val); retval.m_managed = false; @@ -63,5 +76,11 @@ namespace rjp{ void value::remove_management(value& val){ val.m_managed = false; } + value value::create_managed(RJP_value* val){ + return value(val); + } + void value::add_management(value& val){ + val.m_managed = true; + } }