8
8
#include < unordered_map>
9
9
#include < functional>
10
10
#include < concepts>
11
+ #include < vector>
11
12
12
13
namespace cppjson
13
14
{
@@ -18,17 +19,17 @@ namespace cppjson
18
19
Object,
19
20
Number,
20
21
Bool,
21
- // TODO: Array
22
+ Array
22
23
};
23
24
24
25
class JsonObject
25
26
{
26
27
public:
27
28
explicit JsonObject ();
28
29
JsonObject (const JsonObject& other);
29
- JsonObject (JsonObject&& other);
30
+ JsonObject (JsonObject&& other) noexcept ;
30
31
JsonObject& operator =(const JsonObject& other);
31
- JsonObject& operator =(JsonObject&& other);
32
+ JsonObject& operator =(JsonObject&& other) noexcept ;
32
33
~JsonObject ();
33
34
34
35
template <typename T>
@@ -86,9 +87,10 @@ namespace cppjson
86
87
}
87
88
88
89
template <typename T>
89
- T& operator =(T&& assignment)
90
+ std:: conditional_t <std::integral<T> && !std::same_as<T, bool >, void , T&> operator =(T&& assignment)
90
91
{
91
- return static_cast <T&>(*this ) = std::forward<T>(assignment);
92
+ if constexpr (std::integral<T> && !std::same_as<T, bool >) static_cast <double &>(*this ) = static_cast <double >(assignment);
93
+ else return static_cast <T&>(*this ) = std::forward<T>(assignment);
92
94
}
93
95
94
96
template <std::size_t N>
@@ -142,6 +144,35 @@ namespace cppjson
142
144
friend struct std ::formatter<cppjson::JsonObject>;
143
145
friend struct std ::formatter<cppjson::Object>;
144
146
};
147
+
148
+ class Array
149
+ {
150
+ public:
151
+ explicit Array () = default;
152
+ ~Array () = default ;
153
+
154
+ Object::ObjectProxy operator []()
155
+ {
156
+ return Object::ObjectProxy{ this ->_objects .emplace_back () };
157
+ }
158
+
159
+ Object::ObjectProxy operator [](const int index)
160
+ {
161
+ if (index >= this ->_objects .size ()) throw std::logic_error (" Out of bound" );
162
+ return Object::ObjectProxy{ this ->_objects .at (index) };
163
+ }
164
+
165
+ Object::ConstObjectProxy operator [](const int index) const
166
+ {
167
+ if (index >= this ->_objects .size ()) throw std::logic_error (" Out of bound" );
168
+ return Object::ConstObjectProxy{ this ->_objects .at (index) };
169
+ }
170
+ private:
171
+ std::vector<JsonObject> _objects{};
172
+
173
+ friend struct std ::formatter<cppjson::JsonObject>;
174
+ friend struct std ::formatter<cppjson::Array>;
175
+ };
145
176
} // namespace cppjson
146
177
147
178
@@ -176,6 +207,24 @@ struct std::formatter<cppjson::JsonObject>
176
207
177
208
return std::format_to (context.out (), " {}" , built);
178
209
}
210
+ case cppjson::JsonType::Array:
211
+ {
212
+ const auto & array = object.DangerousAs <cppjson::Array>();
213
+
214
+ std::string built = " [ " ;
215
+ for (const auto & element : array._objects )
216
+ built += std::format (" {}, " , element);
217
+
218
+ if (!array._objects .empty ()) // remove trailing commas
219
+ {
220
+ built.pop_back ();
221
+ built.pop_back ();
222
+ built += " ]" ;
223
+ }
224
+ else built += " ]" ;
225
+
226
+ return std::format_to (context.out (), " {}" , built);
227
+ }
179
228
}
180
229
181
230
throw std::logic_error (" Unknown type" );
@@ -205,6 +254,29 @@ struct std::formatter<cppjson::Object>
205
254
}
206
255
};
207
256
257
+ template <>
258
+ struct std ::formatter<cppjson::Array>
259
+ {
260
+ constexpr auto parse (std::format_parse_context& context) { return context.begin (); }
261
+
262
+ auto format (const cppjson::Array& array, std::format_context& context) const
263
+ {
264
+ std::string built = " [ " ;
265
+ for (const auto & element : array._objects )
266
+ built += std::format (" {}, " , element);
267
+
268
+ if (!array._objects .empty ()) // remove trailing commas
269
+ {
270
+ built.pop_back ();
271
+ built.pop_back ();
272
+ built += " ]" ;
273
+ }
274
+ else built += " ]" ;
275
+
276
+ return std::format_to (context.out (), " {}" , built);
277
+ }
278
+ };
279
+
208
280
209
281
template <>
210
282
struct std ::formatter<cppjson::Object::ObjectProxy>
0 commit comments