HOG2
Json.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <iostream>
4 #include <vector>
5 #include <memory>
6 #include <cstring>
7 #include <cassert>
8 
9 
11 class Json
12 {
13  public:
14  class Node;
15 
16  private:
17 
18  // Union type that abstracts node types into one object
19  class NodeValue
20  {
21  public:
22  NodeValue();
23  NodeValue(bool);
24  NodeValue(int);
25  NodeValue(double);
26  NodeValue(std::string);
27  NodeValue(const char*);
28  NodeValue(const NodeValue&);
29  NodeValue(std::shared_ptr<Json::Node>);
30  NodeValue(std::vector<std::unique_ptr<NodeValue>>);
31  NodeValue(std::unique_ptr<std::vector<std::unique_ptr<NodeValue>>>);
32  ~NodeValue();
33 
34  enum{NIL=1, BOOL=2, INT=3, DOUBLE=4, STRING=5, NODE=6, VECTOR=7} tag;
35  union Values
36  {
37  Values() { memset(this, 0, sizeof(*this)); }
38  Values(std::unique_ptr<bool> x) : b(std::move(x)) {}
39  Values(std::unique_ptr<int> x) : i(std::move(x)) {}
40  Values(std::unique_ptr<double> x) : d(std::move(x)) {}
41  Values(std::unique_ptr<std::string> x) : s(std::move(x)) {}
42  Values(std::shared_ptr<Json::Node> x) : n(std::move(x)) {}
43  Values(std::unique_ptr<std::vector<std::unique_ptr<NodeValue>>> x) : v(std::move(x)) {}
44  ~Values() { }
45  void destruct(int tag) {
46  switch (tag) {
47  case NIL:
48  b.~unique_ptr();
49  break;
50 
51  case BOOL:
52  b.~unique_ptr();
53  break;
54 
55  case INT:
56  i.~unique_ptr();
57  break;
58 
59  case DOUBLE:
60  d.~unique_ptr();
61  break;
62 
63  case STRING:
64  s.~unique_ptr();
65  break;
66 
67  case NODE:
68  n.~shared_ptr();
69  break;
70 
71  case VECTOR:
72  v.~unique_ptr();
73  break;
74 
75  default:
76  std::cout << "UNKONW TAG TYPE\n";
77  exit(0);
78  }
79 
80  this->~Values();
81  }
82  std::unique_ptr<bool> b;
83  std::unique_ptr<int> i;
84  std::unique_ptr<double> d;
85  std::unique_ptr<std::string> s;
86  std::shared_ptr<Node> n;
87  std::unique_ptr<std::vector<std::unique_ptr<NodeValue>>> v;
88  } value;
89  };
90 
91  std::unique_ptr<std::vector<std::shared_ptr<Node>>> root;
92 
93  public:
94  Json();
95  ~Json();
96 
97  std::shared_ptr<Node> addChild(std::string);
98  template <typename T>
99  std::shared_ptr<Node> addChild(std::string, T);
100 
101 
102  // Node object for Json format
103  class Node : public std::enable_shared_from_this<Node>
104  {
105  public:
106  Node(std::string);
107  Node(std::string, std::unique_ptr<NodeValue>);
108  ~Node();
109 
110  std::shared_ptr<Node> getPtr();
111 
112  std::shared_ptr<Node> addChild(std::string);
113  template <typename T>
114  std::shared_ptr<Node> addChild(std::string, T);
115  template<typename T>
116  void addData(T);
117 
118  private:
119  std::string name;
120  std::unique_ptr<Json::NodeValue> value;
121 
122  friend std::ostream &operator<<(std::ostream&, Node const&);
123  friend std::ostream &operator<<(std::ostream&, Json::NodeValue const&);
124  friend std::ostream &operator<<(std::ostream&, Json const&);
125  };
126 
127 
128  friend std::ostream &operator<<(std::ostream&, Json const&);
129  friend std::ostream &operator<<(std::ostream&, NodeValue const&);
130 };
131 
132 
134 
135 // Adds a new child to the Json root
136 template <typename T>
137 std::shared_ptr<Json::Node> Json::addChild(std::string name, T val)
138 {
139  std::unique_ptr<Json::NodeValue> value(new Json::NodeValue(val));
140  //std::shared_ptr<Json::Node> node(new Json::Node(name, std::move(value)));
141  std::shared_ptr<Json::Node> node = std::make_shared<Json::Node>(name, std::move(value));
142 
143  root->push_back(node);
144 
145  return node;
146 }
147 
148 // Adds a child node to the current node
149 template <typename T>
150 std::shared_ptr<Json::Node> Json::Node::addChild(std::string name, T val) {
151  // If there is no value yet overwrite child
152  if (value->tag == Json::NodeValue::NIL)
153  {
154  std::unique_ptr<Json::NodeValue> newValue(new Json::NodeValue(val));
155  std::shared_ptr<Json::Node> newNode(new Json::Node(name, std::move(newValue)));
156  std::unique_ptr<Json::NodeValue> nodeValue(new Json::NodeValue(newNode));
157 
158  value = std::move(nodeValue);
159 
160  return newNode;
161  }
162  // Else if it is a vector append new child
163  else if (value->tag == Json::NodeValue::VECTOR)
164  {
165  std::unique_ptr<Json::NodeValue> newValue(new Json::NodeValue(val));
166  std::shared_ptr<Json::Node> newNode(new Json::Node(name, std::move(newValue)));
167  std::unique_ptr<Json::NodeValue> nodeValue(new Json::NodeValue(newNode));
168 
169  value->value.v->push_back(std::move(nodeValue));
170 
171  return newNode;
172  }
173  // Otherwise make a new vector and add both the old child and the new child to it
174  else
175  {
176  std::unique_ptr<Json::NodeValue> newValue(new Json::NodeValue(val));
177  std::shared_ptr<Json::Node> newNode(new Json::Node(name, std::move(newValue)));
178  std::unique_ptr<Json::NodeValue> nodeValue(new Json::NodeValue(newNode));
179  std::unique_ptr<std::vector<std::unique_ptr<Json::NodeValue>>> vec(new std::vector<std::unique_ptr<Json::NodeValue>>());
180  vec->push_back(std::move(value));
181  vec->push_back(std::move(nodeValue));
182  value->value.~Values();
183  std::unique_ptr<Json::NodeValue> joinedValue(new Json::NodeValue(std::move(vec)));
184  value = std::move(joinedValue);
185 
186  return newNode;
187  }
188 
189  std::unique_ptr<Json::NodeValue> value(new Json::NodeValue(val));
190  std::shared_ptr<Json::Node> node(new Json::Node(name, std::move(value)));
191 
192  return node;
193 }
194 
195 // Adds or overwrites the data of a node. Note: should probably remove this method
196 template <typename T>
197 void Json::Node::addData(T data) {
198  // If there is no value yet overwrite child
199  if (value->tag == Json::NodeValue::NIL)
200  {
201  std::unique_ptr<Json::NodeValue> newValue(new Json::NodeValue(data));
202  value = std::move(newValue);
203  }
204  // Else if it is a vector append new child
205  else if (value->tag == Json::NodeValue::VECTOR)
206  {
207  // TODO
208  }
209  // Otherwise make a new vector and add both the old child and the new child to it
210  else
211  {
212  std::unique_ptr<Json::NodeValue> newValue(new Json::NodeValue(data));
213  std::unique_ptr<std::vector<std::unique_ptr<Json::NodeValue>>> vec(new std::vector<std::unique_ptr<Json::NodeValue>>());
214  vec->push_back(std::move(value));
215  vec->push_back(std::move(newValue));
216  value->value.~Values();
217  std::unique_ptr<Json::NodeValue> joinedValue(new Json::NodeValue(std::move(vec)));
218  value = std::move(joinedValue);
219  }
220 }
Json::NodeValue::Values::Values
Values(std::unique_ptr< bool > x)
Definition: Json.h:38
Json::Node::getPtr
std::shared_ptr< Node > getPtr()
Definition: Json.cpp:165
Json::NodeValue::Values::v
std::unique_ptr< std::vector< std::unique_ptr< NodeValue > > > v
Definition: Json.h:87
Json::NodeValue::Values::Values
Values(std::unique_ptr< double > x)
Definition: Json.h:40
Json::NodeValue::DOUBLE
@ DOUBLE
Definition: Json.h:34
Json::Node::~Node
~Node()
Definition: Json.cpp:162
Json::NodeValue::BOOL
@ BOOL
Definition: Json.h:34
Json::NodeValue::Values::Values
Values(std::unique_ptr< int > x)
Definition: Json.h:39
Json::NodeValue::INT
@ INT
Definition: Json.h:34
Json::NodeValue::Values::d
std::unique_ptr< double > d
Definition: Json.h:84
Json::NodeValue::Values::Values
Values(std::shared_ptr< Json::Node > x)
Definition: Json.h:42
Json::Node::addData
void addData(T)
Definition: Json.h:197
Json::NodeValue::Values::b
std::unique_ptr< bool > b
Definition: Json.h:82
Json::NodeValue
Definition: Json.h:19
Json::Node::Node
Node(std::string)
Definition: Json.cpp:156
Json::root
std::unique_ptr< std::vector< std::shared_ptr< Node > > > root
Definition: Json.h:91
Json::NodeValue::Values::destruct
void destruct(int tag)
Definition: Json.h:45
Json::Node::value
std::unique_ptr< Json::NodeValue > value
Definition: Json.h:120
Json::NodeValue::NODE
@ NODE
Definition: Json.h:34
Json::Json
Json()
Definition: Json.cpp:221
Json::Node::name
std::string name
Definition: Json.h:119
Json::Node::operator<<
friend std::ostream & operator<<(std::ostream &, Node const &)
Definition: Json.cpp:212
Json::addChild
std::shared_ptr< Node > addChild(std::string)
Definition: Json.cpp:227
Json::NodeValue::NIL
@ NIL
Definition: Json.h:34
Json::~Json
~Json()
Definition: Json.cpp:224
Json::NodeValue::tag
enum Json::NodeValue::@15 tag
Json::NodeValue::Values::s
std::unique_ptr< std::string > s
Definition: Json.h:85
Json::NodeValue::Values::Values
Values(std::unique_ptr< std::vector< std::unique_ptr< NodeValue >>> x)
Definition: Json.h:43
Json::NodeValue::Values
Definition: Json.h:35
Json::NodeValue::STRING
@ STRING
Definition: Json.h:34
Json::NodeValue::Values::Values
Values(std::unique_ptr< std::string > x)
Definition: Json.h:41
Json::operator<<
friend std::ostream & operator<<(std::ostream &, Json const &)
Definition: Json.cpp:238
Json::NodeValue::Values::n
std::shared_ptr< Node > n
Definition: Json.h:86
Json::NodeValue::value
union Json::NodeValue::Values value
std
Definition: CanonicalGraphEnvironment.h:26
Json::NodeValue::Values::Values
Values()
Definition: Json.h:37
Json::Node
Definition: Json.h:103
Json::NodeValue::VECTOR
@ VECTOR
Definition: Json.h:34
Json::NodeValue::~NodeValue
~NodeValue()
Definition: Json.cpp:83
Json::Node::addChild
std::shared_ptr< Node > addChild(std::string)
Definition: Json.cpp:171
Json::NodeValue::Values::~Values
~Values()
Definition: Json.h:44
Json::NodeValue::NodeValue
NodeValue()
Definition: Json.cpp:9
Json::NodeValue::Values::i
std::unique_ptr< int > i
Definition: Json.h:83
node
Nodes to be stored within a Graph.
Definition: Graph.h:170
Json
Simple class that alows for building a tree of data that can be serialized into Json format.
Definition: Json.h:11