1
+ // Copyright (c) Microsoft Corporation. All rights reserved.
2
+ // Licensed under the MIT License.
3
+
4
+ #include " GraphQLResponse.h"
5
+
6
+ #include < stdexcept>
7
+
8
+ namespace facebook {
9
+ namespace graphql {
10
+ namespace response {
11
+
12
+ Value::Value (Type type /* = Type::Null*/ )
13
+ : _type(type)
14
+ {
15
+ switch (type)
16
+ {
17
+ case Type::Map:
18
+ _members.reset (new std::unordered_map<std::string, size_t >());
19
+ _map.reset (new MapType ());
20
+ break ;
21
+
22
+ case Type::List:
23
+ _list.reset (new ListType ());
24
+ break ;
25
+
26
+ case Type::String:
27
+ case Type::EnumValue:
28
+ _string.reset (new StringType ());
29
+ break ;
30
+
31
+ case Type::Boolean:
32
+ _boolean = false ;
33
+ break ;
34
+
35
+ case Type::Int:
36
+ _int = 0 ;
37
+ break ;
38
+
39
+ case Type::Float:
40
+ _float = 0 ;
41
+ break ;
42
+
43
+ case Type::Scalar:
44
+ _scalar.reset (new Value ());
45
+ break ;
46
+
47
+ default :
48
+ break ;
49
+ }
50
+ }
51
+
52
+ Value::Value (StringType&& value)
53
+ : _type(Type::String)
54
+ , _string(new StringType(std::move(value)))
55
+ {
56
+ }
57
+
58
+ Value::Value (BooleanType value)
59
+ : _type(Type::Boolean)
60
+ , _boolean(value)
61
+ {
62
+ }
63
+
64
+ Value::Value (IntType value)
65
+ : _type(Type::Int)
66
+ , _int(value)
67
+ {
68
+ }
69
+
70
+ Value::Value (FloatType value)
71
+ : _type(Type::Float)
72
+ , _float(value)
73
+ {
74
+ }
75
+
76
+ Value::Value (Value&& other)
77
+ : _type(other._type)
78
+ , _members(std::move(other._members))
79
+ , _map(std::move(other._map))
80
+ , _list(std::move(other._list))
81
+ , _string(std::move(other._string))
82
+ , _scalar(std::move(other._scalar))
83
+ {
84
+ switch (_type)
85
+ {
86
+ case Type::Boolean:
87
+ _boolean = other._boolean ;
88
+ break ;
89
+
90
+ case Type::Int:
91
+ _int = other._int ;
92
+ break ;
93
+
94
+ case Type::Float:
95
+ _float = other._float ;
96
+ break ;
97
+
98
+ default :
99
+ break ;
100
+ }
101
+ }
102
+
103
+ Value::Value (const Value& other)
104
+ : _type(other._type)
105
+ {
106
+ switch (_type)
107
+ {
108
+ case Type::Map:
109
+ _members.reset (new std::unordered_map<std::string, size_t >(*other._members ));
110
+ _map.reset (new MapType (*other._map ));
111
+ break ;
112
+
113
+ case Type::List:
114
+ _list.reset (new ListType (*other._list ));
115
+ break ;
116
+
117
+ case Type::String:
118
+ case Type::EnumValue:
119
+ _string.reset (new StringType (*other._string ));
120
+ break ;
121
+
122
+ case Type::Boolean:
123
+ _boolean = other._boolean ;
124
+ break ;
125
+
126
+ case Type::Int:
127
+ _int = other._int ;
128
+ break ;
129
+
130
+ case Type::Float:
131
+ _float = other._float ;
132
+ break ;
133
+
134
+ case Type::Scalar:
135
+ _scalar.reset (new Value (*other._scalar ));
136
+ break ;
137
+
138
+ default :
139
+ break ;
140
+ }
141
+ }
142
+
143
+ Value& Value::operator =(Value&& rhs)
144
+ {
145
+ const_cast <Type&>(_type) = rhs._type ;
146
+ const_cast <Type&>(rhs._type ) = Type::Null;
147
+
148
+ _members = std::move (rhs._members );
149
+ _map = std::move (rhs._map );
150
+ _list = std::move (rhs._list );
151
+ _string = std::move (rhs._string );
152
+ _scalar = std::move (rhs._scalar );
153
+
154
+ switch (_type)
155
+ {
156
+ case Type::Boolean:
157
+ _boolean = rhs._boolean ;
158
+ break ;
159
+
160
+ case Type::Int:
161
+ _int = rhs._int ;
162
+ break ;
163
+
164
+ case Type::Float:
165
+ _float = rhs._float ;
166
+ break ;
167
+
168
+ default :
169
+ break ;
170
+ }
171
+
172
+ return *this ;
173
+ }
174
+
175
+ Value::Type Value::type () const
176
+ {
177
+ return _type;
178
+ }
179
+
180
+ void Value::reserve (size_t count)
181
+ {
182
+ switch (_type)
183
+ {
184
+ case Type::Map:
185
+ _members->reserve (count);
186
+ _map->reserve (count);
187
+ break ;
188
+
189
+ case Type::List:
190
+ _list->reserve (count);
191
+ break ;
192
+
193
+ default :
194
+ throw std::logic_error (" Invalid call to Value::reserve" );
195
+ }
196
+ }
197
+
198
+ size_t Value::size () const
199
+ {
200
+ switch (_type)
201
+ {
202
+ case Type::Map:
203
+ return _map->size ();
204
+
205
+ case Type::List:
206
+ return _list->size ();
207
+
208
+ default :
209
+ throw std::logic_error (" Invalid call to Value::size" );
210
+ }
211
+ }
212
+
213
+ void Value::emplace_back (std::string&& name, Value&& value)
214
+ {
215
+ if (_type != Type::Map)
216
+ {
217
+ throw std::logic_error (" Invalid call to Value::emplace_back for MapType" );
218
+ }
219
+
220
+ if (_members->find (name) != _members->cend ())
221
+ {
222
+ throw std::runtime_error (" Duplicate Map member" );
223
+ }
224
+
225
+ _members->insert ({ name, _map->size () });
226
+ _map->emplace_back (std::make_pair (std::move (name), std::move (value)));
227
+ }
228
+
229
+ Value::MapType::const_iterator Value::find (const std::string& name) const
230
+ {
231
+ if (_type != Type::Map)
232
+ {
233
+ throw std::logic_error (" Invalid call to Value::find for MapType" );
234
+ }
235
+
236
+ const auto itr = _members->find (name);
237
+
238
+ if (itr == _members->cend ())
239
+ {
240
+ return _map->cend ();
241
+ }
242
+
243
+ return _map->cbegin () + itr->second ;
244
+ }
245
+
246
+ const Value& Value::operator [](const std::string& name) const
247
+ {
248
+ const auto itr = find (name);
249
+
250
+ if (itr == _map->cend ())
251
+ {
252
+ throw std::runtime_error (" Missing Map member" );
253
+ }
254
+
255
+ return itr->second ;
256
+ }
257
+
258
+ void Value::emplace_back (Value&& value)
259
+ {
260
+ if (_type != Type::List)
261
+ {
262
+ throw std::logic_error (" Invalid call to Value::emplace_back for ListType" );
263
+ }
264
+
265
+ _list->emplace_back (std::move (value));
266
+ }
267
+
268
+ const Value& Value::operator [](size_t index) const
269
+ {
270
+ if (_type != Type::List)
271
+ {
272
+ throw std::logic_error (" Invalid call to Value::emplace_back for ListType" );
273
+ }
274
+
275
+ return _list->at (index);
276
+ }
277
+
278
+ } /* namespace response */
279
+ } /* namespace graphql */
280
+ } /* namespace facebook */
0 commit comments