Skip to content

Commit

Permalink
Better picojson::value handling (no static variable).
Browse files Browse the repository at this point in the history
Still easyjson is not copyable (should it be ?)
  • Loading branch information
gbittoun committed Nov 15, 2017
1 parent a3cf2a3 commit 2527d8a
Showing 1 changed file with 57 additions and 61 deletions.
118 changes: 57 additions & 61 deletions picojson.h
Original file line number Diff line number Diff line change
Expand Up @@ -1139,166 +1139,162 @@ inline bool operator!=(const value &x, const value &y) {

class value_holder
{
private:
static value static_null_value;
public:
virtual value & get() = 0;
};

class value_ptr_holder : public value_holder
{
public:
value_holder() :
value_ref(static_null_value),
value_ptr_holder() :
value_ptr(std::make_unique<value>())
{
}

value_holder(bool b) :
value_ref(static_null_value),
value_ptr_holder(bool b) :
value_ptr(std::make_unique<value>(b))
{
}

value_holder(const std::string & s) :
value_ref(static_null_value),
value_ptr_holder(const std::string & s) :
value_ptr(std::make_unique<value>(s))
{
}

value_holder(double d) :
value_ref(static_null_value),
value_ptr_holder(double d) :
value_ptr(std::make_unique<value>(d))
{
}

value_holder(value & value) :
value_ref(value),
value_ptr()
{
}

value & get()
{
if (value_ptr)
return *value_ptr;
else
return value_ref;
return *value_ptr;
}

value & operator*()
private:
std::unique_ptr<picojson::value> value_ptr;
};

class value_ref_holder : public value_holder
{
public:
value_ref_holder(picojson::value & v) :
value_ref(v)
{
return get();
}

value * operator->()
{
return &get();
value & get() {
return value_ref;
}

private:
picojson::value & value_ref;
std::unique_ptr<picojson::value> value_ptr;
value & value_ref;
};

value value_holder::static_null_value;

class easyjson
{
public:

//Constructors

easyjson() :
holder() {
holder(std::make_unique<value_ptr_holder>()) {
}

easyjson(picojson::value & v) :
holder(v) {
holder(std::make_unique<value_ref_holder>(v)) {
}

easyjson(bool b):
holder(b) {
holder(std::make_unique<value_ptr_holder>(b)) {
}

easyjson(const char * c):
holder(std::string(c)) {
holder(std::make_unique<value_ptr_holder>(std::string(c))) {
}

easyjson(const std::string & s):
holder(s) {
holder(std::make_unique<value_ptr_holder>(s)) {
}

easyjson(int value):
holder(double(value)) {
holder(std::make_unique<value_ptr_holder>(double(value))) {
}

easyjson(double d):
holder(d) {
holder(std::make_unique<value_ptr_holder>(d)) {
}

// picojson::value accessor

value & get_value()
{
return holder->get();
}

// Equality operators

easyjson & operator=(bool value) {
PICOJSON_ASSERT(holder->get_type() == null_type || holder->get_type() == boolean_type);
*holder = picojson::value(value);
PICOJSON_ASSERT(get_value().get_type() == null_type || get_value().get_type() == boolean_type);
get_value() = picojson::value(value);
return *this;
}

easyjson & operator=(const char * value) {
PICOJSON_ASSERT(holder->get_type() == null_type || holder->get_type() == string_type);
*holder = picojson::value(std::string(value));
PICOJSON_ASSERT(get_value().get_type() == null_type || get_value().get_type() == string_type);
get_value() = picojson::value(std::string(value));
return *this;
}

easyjson & operator=(const std::string & value) {
PICOJSON_ASSERT(holder->get_type() == null_type || holder->get_type() == string_type);
*holder = picojson::value(value);
PICOJSON_ASSERT(get_value().get_type() == null_type || get_value().get_type() == string_type);
get_value() = picojson::value(value);
return *this;
}

easyjson & operator=(int value) {
PICOJSON_ASSERT(holder->get_type() == null_type || holder->get_type() == number_type);
*holder = picojson::value(double(value));
PICOJSON_ASSERT(get_value().get_type() == null_type || get_value().get_type() == number_type);
get_value() = picojson::value(double(value));
return *this;
}

easyjson & operator=(double value) {
PICOJSON_ASSERT(holder->get_type() == null_type || holder->get_type() == number_type);
*holder = picojson::value(value);
PICOJSON_ASSERT(get_value().get_type() == null_type || get_value().get_type() == number_type);
get_value() = picojson::value(value);
return *this;
}

picojson::value & get_value() {
return *holder;
}

// Assignment operators

easyjson operator[](const std::string & s) {
PICOJSON_ASSERT(holder->get_type() == null_type || holder->get_type() == object_type);
PICOJSON_ASSERT(get_value().get_type() == null_type || get_value().get_type() == object_type);

if (holder->get_type() == null_type)
holder->set<picojson::value::object>(picojson::value::object());
if (get_value().get_type() == null_type)
get_value().set<picojson::value::object>(picojson::value::object());

return holder->get<picojson::value::object>()[std::string(s)];
return get_value().get<picojson::value::object>()[std::string(s)];
}

easyjson operator[](const char * c) {
return operator[](std::string(c));
}

easyjson operator[](picojson::value::array::size_type index) {
PICOJSON_ASSERT(holder->get_type() == null_type || holder->get_type() == array_type);
PICOJSON_ASSERT(get_value().get_type() == null_type || get_value().get_type() == array_type);

if (holder->get_type() == null_type) {
holder->set<picojson::value::array>(picojson::value::array(index + 1));
if (get_value().get_type() == null_type) {
get_value().set<picojson::value::array>(picojson::value::array(index + 1));
}

if (holder->get<picojson::value::array>().size() <= index) {
holder->get<picojson::value::array>().resize(index + 1);
if (get_value().get<picojson::value::array>().size() <= index) {
get_value().get<picojson::value::array>().resize(index + 1);
}

return holder->get<picojson::value::array>().at(index);
return get_value().get<picojson::value::array>().at(index);
}

private:
value_holder holder;
std::unique_ptr<value_holder> holder;
};

}
Expand Down

0 comments on commit 2527d8a

Please sign in to comment.