#include <map>
#include <vector>
#include <string>
#include <iostream>
#include <cstring>
#include <utility>
#include <functional>
namespace json {
class value;
typedef std::vector<value> array;
typedef std::map<std::string, value> object;
typedef std::string string;
enum class type
{
null, // it is not realy a type but a value
boolean,
integer,
number,
string,
object,
array
};
class value
{
public:
value();
~value();
value(double number);
value(int integer);
value(bool b);
value(char const* str);
value(json::string const& str);
value(json::array const& arr);
value(json::object const& obj);
value(json::string&& str);
value(json::array&& arr);
value(json::object&& obj);
value(value const& val);
value(value&& val);
// assignment operators
value& operator=(double number);
value& operator=(int integer);
value& operator=(bool b);
value& operator=(json::string const& str);
value& operator=(json::array const& arr);
value& operator=(json::object const& obj);
value& operator=(json::string&& str);
value& operator=(json::array&& arr);
value& operator=(json::object&& obj);
value& operator=(value const& val);
value& operator=(value&& val);
void clear();
public:
json::type type;
union
{
int integer;
double number;
bool boolean;
json::string* str;
json::array* arr;
json::object* obj;
};
};
}
namespace json {
value::value() : type(json::type::null)
{
std::cerr << "default constructor null" << '\n';
}
value::~value()
{
std::cerr << "destructor" << '\n';
clear();
}
value::value(double number) : type(json::type::number), number(number)
{
std::cerr << "copy constructor number" << '\n';
}
value::value(int integer) : type(json::type::integer), integer(integer)
{
std::cerr << "copy constructor integer" << '\n';
}
value::value(bool b) : type(json::type::boolean), boolean(b)
{
std::cerr << "copy constructor boolean" << '\n';
}
value::value(char const* str) : value(json::string(str))
{
}
value::value(json::string const& str) : type(json::type::string), str(new json::string(str))
{
std::cerr << "copy constructor string" << '\n';
}
value::value(json::array const& arr) : type(json::type::array), arr(new json::array(arr))
{
std::cerr << "copy constructor array" << '\n';
}
value::value(json::object const& obj) : type(json::type::object), obj(new json::object(obj))
{
std::cerr << "copy constructor object" << '\n';
}
value::value(value const& val)
{
std::cerr << "copy constructor value" << '\n';
switch (val.type)
{
case json::type::array:
{
arr = new json::array(*val.arr);
type = json::type::array;
}
break;
case json::type::string:
{
str = new json::string(*val.str);
type = json::type::string;
}
break;
case json::type::object:
{
obj = new json::object(*val.obj);
type = json::type::object;
}
break;
default:
std::memcpy(this, &val, sizeof(val));
}
}
value::value(json::string && str)
: type(json::type::string)
, str(new json::string(std::move(str)))
{
std::cerr << "move constructor string" << '\n';
}
value::value(json::array && arr)
: type(json::type::array)
, arr(new json::array(std::move(arr)))
{
std::cerr << "move constructor array" << '\n';
}
value::value(json::object && obj)
: type(json::type::object)
, obj(new json::object(std::move(obj)))
{
std::cerr << "move constructor object" << '\n';
}
value::value(value && val)
{
std::cerr << "move constructor value" << '\n';
std::memcpy(this, &val, sizeof(val));
val.type = json::type::null;
}
value& value::operator=(double number)
{
std::cerr << "assignment number" << '\n';
clear();
type = json::type::number;
this->number = number;
return *this;
}
value& value::operator=(int integer)
{
std::cerr << "assignment integer" << '\n';
clear();
type = json::type::integer;
this->integer = integer;
return *this;
}
value& value::operator=(bool b)
{
std::cerr << "assignment bool" << '\n';
clear();
type = json::type::integer;
this->integer = integer;
return *this;
}
value& value::operator=(json::string const& str)
{
std::cerr << "assignment string" << '\n';
clear();
this->str = new json::string(str);
type = json::type::string;
return *this;
}
value& value::operator=(json::array const& arr)
{
std::cerr << "assignment array" << '\n';
clear();
this->arr = new json::array(arr);
type = json::type::array;
return *this;
}
value& value::operator=(json::object const& obj)
{
std::cerr << "assignment object" << '\n';
clear();
this->obj = new json::object(obj);
type = json::type::object;
return *this;
}
value& value::operator=(value const& val)
{
std::cerr << "assignment value" << '\n';
clear();
switch (val.type)
{
case json::type::array:
{
arr = new json::array(*val.arr);
type = json::type::array;
}
break;
case json::type::string:
{
str = new json::string(*val.str);
type = json::type::string;
}
break;
case json::type::object:
{
obj = new json::object(*val.obj);
type = json::type::object;
}
break;
default:
std::memcpy(this, &val, sizeof(val));
}
return *this;
}
value& value::operator=(json::string&& str)
{
std::cerr << "move assignment string" << '\n';
clear();
this->str = new json::string(std::move(str));
type = json::type::string;
return *this;
}
value& value::operator=(json::array&& arr)
{
std::cerr << "move assignment array" << '\n';
clear();
this->arr = new json::array(std::move(arr));
type = json::type::array;
return *this;
}
value& value::operator=(json::object&& obj)
{
std::cerr << "move assignment object" << '\n';
clear();
this->obj = new json::object(std::move(obj));
type = json::type::object;
return *this;
}
value& value::operator=(value && val)
{
std::cerr << "move assignment value" << '\n';
clear();
std::memcpy(this, &val, sizeof(val));
val.type = json::type::null;
return *this;
}
void value::clear()
{
switch (type)
{
case json::type::array:
{
delete arr;
}
break;
case json::type::string:
{
delete str;
}
break;
case json::type::object:
{
delete obj;
}
break;
}
type = json::type::null;
}
}
int main(int argc, char* argv [])
{
json::string s = "HelloWorld";
json::value v_str = std::move(s);
json::value v_arr = std::move(std::vector<json::value>{std::cref(v_str)});
return 0;
}