benchmark silo added
[c11concurrency-benchmarks.git] / silo / masstree / jsontest.cc
1 // -*- c-basic-offset: 4 -*-
2 /*
3  * jsontest.{cc,hh} -- regression tests for Json
4  * Eddie Kohler
5  *
6  * Copyright (c) 2012-2014 Eddie Kohler
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a
9  * copy of this software and associated documentation files (the "Software"),
10  * to deal in the Software without restriction, subject to the conditions
11  * listed in the Click LICENSE file. These conditions include: you must
12  * preserve this copyright notice, and you cannot mention the copyright
13  * holders in advertising related to the Software without their permission.
14  * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
15  * notice is a summary of the Click LICENSE file; the license in that file is
16  * legally binding.
17  */
18
19 #include "json.hh"
20 #include <unordered_map>
21 using namespace lcdf;
22
23 #define CHECK(x) do { if (!(x)) { std::cerr << __FILE__ << ":" << __LINE__ << ": test '" << #x << "' failed\n"; exit(1); } } while (0)
24 #define CHECK_JUP(x, str) do { if ((x).unparse() != (str)) { std::cerr << __FILE__ << ":" << __LINE__ << ": '" #x "' is '" << (x) << "', not '" << (str) << "'\n"; exit(1); } } while (0)
25
26
27 #if 0
28 template <typename T> void incr(T& x) __attribute__((noinline));
29 template <typename T>
30 void incr(T& x) {
31     ++x;
32 }
33 #endif
34
35 void benchmark_parse() {
36     std::vector<String> parse_examples;
37     parse_examples.push_back("{}");
38     parse_examples.push_back("{\"foo\":\"bar\",\"baz\":\"flim\"}");
39     parse_examples.push_back("[1,2,3,4,5]");
40     parse_examples.push_back("[]");
41     parse_examples.push_back("[{},{\"b\":[]}]");
42     Json j;
43 #if 0
44     for (int i = 0; i < 10000000; ++i)
45         j.assign_parse(parse_examples[rand() % parse_examples.size()]);
46 #else
47     using std::swap;
48     Json::streaming_parser jsp;
49     for (int i = 0; i < 10000000; ++i) {
50         jsp.reset();
51         swap(jsp.result(), j);
52         const String& str = parse_examples[rand() % parse_examples.size()];
53         jsp.consume(str.begin(), str.end(), str, true);
54     }
55 #endif
56     exit(0);
57 }
58
59 int main(int argc, char** argv) {
60     (void) argc, (void) argv;
61     //benchmark_parse();
62
63     Json j;
64     CHECK(j.empty());
65     CHECK(!j);
66
67     j = Json::make_object();
68     CHECK(j.empty());
69     CHECK(j);
70
71     j.set("foo", "bar");
72     CHECK(j["foo"]);
73     CHECK(j["foo"].to_s() == "bar");
74     CHECK(j.size() == 1);
75
76     j.set("baz", "flim");
77     CHECK(j.size() == 2);
78     CHECK(j.unparse() == "{\"foo\":\"bar\",\"baz\":\"flim\"}");
79
80     j.erase("foo");
81     CHECK(j.size() == 1);
82
83     j.assign_parse("2");
84     CHECK(j == 2);
85
86     j.assign_parse("null");
87     CHECK(j == Json());
88
89     j.assign_parse("\"a\"");
90     CHECK(j == "a");
91
92     j.assign_parse("[1,2]");
93     CHECK(j.unparse() == "[1,2]");
94
95     j.assign_parse("[[[]],{\"a\":{}}]");
96     CHECK(j.unparse() == "[[[]],{\"a\":{}}]");
97
98     j = Json::parse("{\"x22\":{\n\
99       \"git-revision\":\"ebbd3d4767847300f552b181a10bda57a926f554M\",\n\
100       \"time\":\"Tue Feb  7 20:20:33 2012\",\n\
101       \"machine\":\"rtshanks-laptop\",\n\
102       \"cores\":2,\n\
103       \"runs\":[\"x22\\/rw2\\/mb\\/0\"]\n\
104     },\n\
105     \"x23\":{\n\
106       \"git-revision\":\"ebbd3d4767847300f552b181a10bda57a926f554M\",\n\
107       \"time\":\"Tue Feb  7 20:31:05 2012\",\n\
108       \"machine\":\"rtshanks-laptop\",\n\
109       \"cores\":2,\n\
110       \"runs\":[\"x23\\/rw2\\/mb\\/0\",\"x23\\/rw1\\/mb\\/0\",\"x23\\/rw3\\/mb\\/0\"]\n\
111     },\n\
112     \"x24\":{\n\
113       \"git-revision\":\"62e9970ca8ae9c6eebf2d71b7065ea694fb25282M\",\n\
114       \"time\":\"Sat Feb 11 15:54:01 2012\",\n\
115       \"machine\":\"rtshanks-laptop\",\n\
116       \"cores\":2,\n\
117       \"runs\":[\"x24\\/rw1\\/b\\/0\"]\n\
118     },\"b\":\"c\",\"c\":\"d\"}");
119     CHECK(j["x22"]["time"] == "Tue Feb  7 20:20:33 2012");
120     CHECK(j["x22"]["cores"] == 2);
121     {
122         Json::object_iterator it = j.obegin();
123         CHECK(it.key() == "x22");
124         ++it;
125         CHECK(it.key() == "x23");
126         ++it;
127         CHECK(it.key() == "x24");
128         ++it;
129         CHECK(it.key() == "b");
130         ++it;
131         CHECK(it.key() == "c");
132     }
133
134     {
135         Json jcopy = j;
136         CHECK(j.size() == 5);
137         int count = 0;
138         for (Json::iterator it = jcopy.begin(); it != jcopy.end(); ++it) {
139             it->second = Json();
140             ++count;
141         }
142         CHECK(!jcopy["x22"]);
143         CHECK(j["x22"]["cores"] == 2);
144         CHECK(count == jcopy.size());
145     }
146
147     CHECK(!j["x49"]);
148     CHECK(j.size() == 5);
149     CHECK(!j["x49"]["45"][2]["a"]);
150     CHECK(j.size() == 5);
151     j["x49"]["45"][2]["a"] = 1;
152     CHECK(j.size() == 6);
153     CHECK(j["x22"].is_object() && j.get("x22").is_object());
154     CHECK(j["x23"].is_object() && j.get("x23").is_object());
155     CHECK(j["b"].is_string() && j.get("b").is_string());
156     CHECK(j["x49"].is_object() && j.get("x49").is_object());
157     CHECK(j["x49"]["45"].is_array());
158     CHECK(j["x49"]["45"].size() == 3 && j["x49"]["45"][2].is_object());
159
160     j = Json::make_object();
161     j["a"] = j["b"];
162     CHECK(j.size() == 1);
163     CHECK(j["a"].is_null());
164     CHECK(j.count("a") == 1);
165
166     Json k = Json::make_array();
167     {
168         CHECK(k.size() == 0);
169         Json::array_iterator it = k.abegin();
170         CHECK(!it.live());
171     }
172     j = Json::make_object();
173     j["a"] = k[2];
174     CHECK(j.size() == 1);
175     CHECK(k.size() == 0);
176     CHECK(j["a"].is_null());
177     CHECK(j.count("a") == 1);
178
179     j = Json(1);
180     CHECK(j.get("a").is_null());
181
182     j.assign_parse("{\"a\":1,\"b\":true,\"c\":\"\"}");
183     {
184         int i = 0;
185         bool b = false;
186         String s;
187         CHECK(j.get("a", i));
188         CHECK(i == 1);
189         CHECK(j.get("a", i).get("b", b));
190         CHECK(b == true);
191         CHECK(!j.get("a", s).status());
192         CHECK(!j.get("a", s).status(b));
193         CHECK(b == false);
194         CHECK(j.get("a", k));
195         CHECK(k == Json(1));
196         CHECK(!j.get("cc", k));
197     }
198
199     j["a"] = Json(5);
200     j.set("a", Json(5));
201     j["b"] = Json::parse("[]");
202
203     {
204         Json j1 = Json::make_object(), j2 = Json::make_object();
205         j1.set("a", j2); // stores a COPY of j2 in j1
206         j2.set("b", 1);
207         CHECK(j1.unparse() == "{\"a\":{}}");
208         CHECK(j2.unparse() == "{\"b\":1}");
209     }
210
211     {
212         Json j = Json::parse("{\"a\":true}");
213         if (j["foo"]["bar"])
214             CHECK(false);
215         CHECK(j.unparse() == "{\"a\":true}");
216         j["foo"]["bar"] = true;
217         CHECK(j.unparse() == "{\"a\":true,\"foo\":{\"bar\":true}}");
218         j["a"]["2"] = false;
219         CHECK(j.unparse() == "{\"a\":{\"2\":false},\"foo\":{\"bar\":true}}");
220         j[3] = true;
221         CHECK(j.unparse() == "{\"a\":{\"2\":false},\"foo\":{\"bar\":true},\"3\":true}");
222         CHECK(j[3] == Json(true));
223         j = Json::parse("[1,2,3,4]");
224         CHECK(j["2"] == Json(3));
225         CHECK(j.unparse() == "[1,2,3,4]");
226         j["a"] = true;
227         CHECK(j.unparse() == "{\"0\":1,\"1\":2,\"2\":3,\"3\":4,\"a\":true}");
228         CHECK(j["2"] == Json(3));
229     }
230
231     {
232         Json j = Json::parse("{}");
233         j.set("foo", String::make_out_of_memory()).set(String::make_out_of_memory(), 2);
234         CHECK(j.unparse() == "{\"foo\":\"\360\237\222\243ENOMEM\360\237\222\243\",\"\360\237\222\243ENOMEM\360\237\222\243\":2}");
235         j.clear();
236         CHECK(j.unparse() == "{}");
237         CHECK(j.get("foo") == Json());
238     }
239
240     {
241         Json j = Json::array(1, 2, 3, 4, 5, 6, 7, 8);
242         CHECK(j.unparse() == "[1,2,3,4,5,6,7,8]");
243         Json jcopy = j;
244         CHECK(j.unparse() == "[1,2,3,4,5,6,7,8]");
245         CHECK(jcopy.unparse() == "[1,2,3,4,5,6,7,8]");
246         j.push_back(9);
247         CHECK(j.unparse() == "[1,2,3,4,5,6,7,8,9]");
248         CHECK(jcopy.unparse() == "[1,2,3,4,5,6,7,8]");
249         jcopy.push_back(10);
250         CHECK(j.unparse() == "[1,2,3,4,5,6,7,8,9]");
251         CHECK(jcopy.unparse() == "[1,2,3,4,5,6,7,8,10]");
252     }
253
254     {
255         unsigned long s = 77;
256         Json j = Json::array(0, 0, 0);
257         Json k = Json::array(0, s, "foo");
258         CHECK(j[1].is_i());
259         CHECK(k[1].is_u());
260         j[1] = k[1];
261         CHECK(j[1].is_u());
262     }
263
264 #if 0
265     {
266         Json j = Json::array(1, 2, 3);
267         //int j[3] = {1, 2, 3};
268         for (int i = 0; i < 1000000; ++i)
269             incr(j[1].value());
270         std::cout << j << "\n";
271     }
272 #endif
273
274     {
275         Json::streaming_parser jsp;
276         const uint8_t* x = reinterpret_cast<const uint8_t*>("\"abcdef\"");
277
278         const uint8_t* r = jsp.consume(x, x + 8, String());
279         CHECK(r == x + 8);
280         CHECK(jsp.success());
281         CHECK(jsp.result().unparse() == "\"abcdef\"");
282
283         x = reinterpret_cast<const uint8_t*>("\"\\\"\\\\fartbox\" amksdnsndfa");
284         jsp.reset();
285         r = jsp.consume(x, x + 9, String());
286         CHECK(r == x + 9);
287         CHECK(!jsp.done());
288         r = jsp.consume(x + 9, x + 17, String());
289         CHECK(r == x + 13);
290         CHECK(jsp.success());
291         CHECK(jsp.result().unparse() == "\"\\\"\\\\fartbox\"");
292
293         jsp.reset();
294         r = jsp.consume(x, x + 3, String());
295         CHECK(r == x + 3);
296         r = jsp.consume(x + 3, x + 6, String());
297         CHECK(r == x + 6);
298         r = jsp.consume(x + 6, x + 9, String());
299         CHECK(r == x + 9);
300         r = jsp.consume(x + 9, x + 13, String());
301         CHECK(r == x + 13);
302         CHECK(jsp.success());
303         CHECK(jsp.result().unparse() == "\"\\\"\\\\fartbox\"");
304
305         jsp.reset();
306         x = reinterpret_cast<const uint8_t*>("\"\\uD834\\uDD1E\"f");
307         r = jsp.consume(x, x + 15, String());
308         CHECK(r == x + 14);
309         CHECK(jsp.success());
310         CHECK(jsp.result().unparse() == "\"\xF0\x9D\x84\x9E\"");
311
312         jsp.reset();
313         r = jsp.consume(x, x + 2, String());
314         CHECK(r == x + 2);
315         r = jsp.consume(x + 2, x + 4, String());
316         CHECK(r == x + 4);
317         r = jsp.consume(x + 4, x + 6, String());
318         CHECK(r == x + 6);
319         r = jsp.consume(x + 6, x + 8, String());
320         CHECK(r == x + 8);
321         r = jsp.consume(x + 8, x + 10, String());
322         CHECK(r == x + 10);
323         r = jsp.consume(x + 10, x + 15, String());
324         CHECK(r == x + 14);
325         CHECK(jsp.success());
326         CHECK(jsp.result().unparse() == "\"\xF0\x9D\x84\x9E\"");
327
328         x = reinterpret_cast<const uint8_t*>("\"\xF0\x9D\x84\x9E\" fart");
329         jsp.reset();
330         r = jsp.consume(x, x + 3, String());
331         CHECK(r == x + 3);
332         r = jsp.consume(x + 5, x + 7, String());
333         CHECK(r == x + 5);
334         CHECK(jsp.error());
335
336         jsp.reset();
337         r = jsp.consume(x, x + 7, String());
338         CHECK(r == x + 6);
339         CHECK(jsp.success());
340         CHECK(jsp.result().unparse() == "\"\xF0\x9D\x84\x9E\"");
341
342         jsp.reset();
343         r = jsp.consume(x, x + 2, String());
344         CHECK(r == x + 2);
345         r = jsp.consume(x + 2, x + 4, String());
346         CHECK(r == x + 4);
347         r = jsp.consume(x + 4, x + 7, String());
348         CHECK(r == x + 6);
349         CHECK(jsp.success());
350         CHECK(jsp.result().unparse() == "\"\xF0\x9D\x84\x9E\"");
351
352         jsp.reset();
353         x = reinterpret_cast<const uint8_t*>("{}");
354         r = jsp.consume(x, x + 2, String());
355         CHECK(r == x + 2);
356         CHECK(jsp.success());
357         CHECK(jsp.result().unparse() == "{}");
358
359         jsp.reset();
360         x = reinterpret_cast<const uint8_t*>("\"ab cde\" ");
361         r = jsp.consume(x, x + 9, String());
362         CHECK(r == x + 8);
363         CHECK(jsp.success());
364         CHECK(jsp.result().unparse() == "\"ab cde\"");
365
366         jsp.reset();
367         x = reinterpret_cast<const uint8_t*>("{\"a\":\"b\"}");
368         r = jsp.consume(x, x + 9, String());
369         CHECK(r == x + 9);
370         CHECK(jsp.success());
371         CHECK(jsp.result().unparse() == "{\"a\":\"b\"}");
372
373         jsp.reset();
374         x = reinterpret_cast<const uint8_t*>("[]");
375         r = jsp.consume(x, x + 2, String());
376         CHECK(r == x + 2);
377         CHECK(jsp.success());
378         CHECK(jsp.result().unparse() == "[]");
379
380         jsp.reset();
381         x = reinterpret_cast<const uint8_t*>("[\"a\",\"b\"]");
382         r = jsp.consume(x, x + 9, String());
383         CHECK(r == x + 9);
384         CHECK(jsp.success());
385         CHECK(jsp.result().unparse() == "[\"a\",\"b\"]");
386
387         jsp.reset();
388         x = reinterpret_cast<const uint8_t*>("[[\"a\"],[[\"b\"]]]");
389         r = jsp.consume(x, x + 15, String());
390         CHECK(r == x + 15);
391         CHECK(jsp.success());
392         CHECK(jsp.result().unparse() == "[[\"a\"],[[\"b\"]]]");
393
394         jsp.reset();
395         x = reinterpret_cast<const uint8_t*>("[[],[[]]]");
396         r = jsp.consume(x, x + 9, String());
397         CHECK(r == x + 9);
398         CHECK(jsp.success());
399         CHECK(jsp.result().unparse() == "[[],[[]]]");
400
401         jsp.reset();
402         x = reinterpret_cast<const uint8_t*>("{\"abc\":\"def\"}");
403         r = jsp.consume(x, x + 3, String());
404         CHECK(r == x + 3);
405         r = jsp.consume(x + 3, x + 6, String());
406         CHECK(r == x + 6);
407         r = jsp.consume(x + 6, x + 9, String());
408         CHECK(r == x + 9);
409         r = jsp.consume(x + 9, x + 12, String());
410         CHECK(r == x + 12);
411         r = jsp.consume(x + 12, x + 13, String());
412         CHECK(r == x + 13);
413         CHECK(jsp.success());
414         CHECK(jsp.result().unparse() == "{\"abc\":\"def\"}");
415
416         jsp.reset();
417         x = reinterpret_cast<const uint8_t*>("{\"abc\":true }");
418         r = jsp.consume(x, x + 3, String());
419         CHECK(r == x + 3);
420         r = jsp.consume(x + 3, x + 6, String());
421         CHECK(r == x + 6);
422         r = jsp.consume(x + 6, x + 9, String());
423         CHECK(r == x + 9);
424         r = jsp.consume(x + 9, x + 12, String());
425         CHECK(r == x + 12);
426         r = jsp.consume(x + 12, x + 13, String());
427         CHECK(r == x + 13);
428         CHECK(jsp.success());
429         CHECK(jsp.result().unparse() == "{\"abc\":true}");
430
431         jsp.reset();
432         x = reinterpret_cast<const uint8_t*>("{\"abc\": null}");
433         r = jsp.consume(x, x + 3, String());
434         CHECK(r == x + 3);
435         r = jsp.consume(x + 3, x + 6, String());
436         CHECK(r == x + 6);
437         r = jsp.consume(x + 6, x + 9, String());
438         CHECK(r == x + 9);
439         r = jsp.consume(x + 9, x + 12, String());
440         CHECK(r == x + 12);
441         r = jsp.consume(x + 12, x + 13, String());
442         CHECK(r == x + 13);
443         CHECK(jsp.success());
444         CHECK(jsp.result().unparse() == "{\"abc\":null}");
445
446         jsp.reset();
447         x = reinterpret_cast<const uint8_t*>("{\"abc\":false}");
448         r = jsp.consume(x, x + 3, String());
449         CHECK(r == x + 3);
450         r = jsp.consume(x + 3, x + 6, String());
451         CHECK(r == x + 6);
452         r = jsp.consume(x + 6, x + 9, String());
453         CHECK(r == x + 9);
454         r = jsp.consume(x + 9, x + 12, String());
455         CHECK(r == x + 12);
456         r = jsp.consume(x + 12, x + 13, String());
457         CHECK(r == x + 13);
458         CHECK(jsp.success());
459         CHECK(jsp.result().unparse() == "{\"abc\":false}");
460
461         jsp.reset();
462         x = reinterpret_cast<const uint8_t*>("{\"abc\": -13 }");
463         r = jsp.consume(x, x + 3, String());
464         CHECK(r == x + 3);
465         r = jsp.consume(x + 3, x + 6, String());
466         CHECK(r == x + 6);
467         r = jsp.consume(x + 6, x + 9, String());
468         CHECK(r == x + 9);
469         r = jsp.consume(x + 9, x + 12, String());
470         CHECK(r == x + 12);
471         r = jsp.consume(x + 12, x + 13, String());
472         CHECK(r == x + 13);
473         CHECK(jsp.success());
474         CHECK(jsp.result().unparse() == "{\"abc\":-13}");
475
476         jsp.reset();
477         x = reinterpret_cast<const uint8_t*>("{\"abc\":0    }");
478         r = jsp.consume(x, x + 3, String());
479         CHECK(r == x + 3);
480         r = jsp.consume(x + 3, x + 6, String());
481         CHECK(r == x + 6);
482         r = jsp.consume(x + 6, x + 9, String());
483         CHECK(r == x + 9);
484         r = jsp.consume(x + 9, x + 12, String());
485         CHECK(r == x + 12);
486         r = jsp.consume(x + 12, x + 13, String());
487         CHECK(r == x + 13);
488         CHECK(jsp.success());
489         CHECK(jsp.result().unparse() == "{\"abc\":0}");
490
491         jsp.reset();
492         x = reinterpret_cast<const uint8_t*>("[0,1,2,3,4e5,10.2]");
493         r = jsp.consume(x, x + 3, String());
494         CHECK(r == x + 3);
495         r = jsp.consume(x + 3, x + 6, String());
496         CHECK(r == x + 6);
497         r = jsp.consume(x + 6, x + 9, String());
498         CHECK(r == x + 9);
499         r = jsp.consume(x + 9, x + 12, String());
500         CHECK(r == x + 12);
501         r = jsp.consume(x + 12, x + 18, String());
502         CHECK(r == x + 18);
503         CHECK(jsp.success());
504         CHECK(jsp.result().unparse() == "[0,1,2,3,400000,10.2]");
505     }
506
507     {
508         unsigned long s = 77;
509         Json j = Json::array(0, s, "foo");
510         CHECK(j.is_a());
511         CHECK(j[1].is_u());
512         CHECK(j[1] == s);
513         CHECK(j[1] == 77);
514
515         j = Json::array((uint64_t) -1, (int64_t) -1,
516                         (uint64_t) 1, (int64_t) 1,
517                         (uint64_t) 2, (int64_t) 2);
518         CHECK(j[0] != j[1]);
519         CHECK(j[2] == j[3]);
520         CHECK(j[4] == j[5]);
521         CHECK(j[0] != j[2]);
522         CHECK(j[2] != j[4]);
523         CHECK_JUP(j, "[18446744073709551615,-1,1,1,2,2]");
524     }
525
526     {
527         std::vector<int> v = {1, 2, 3, 4, 5};
528         Json j(v.begin(), v.end());
529         CHECK(j.unparse() == "[1,2,3,4,5]");
530     }
531
532     {
533         std::unordered_map<String, String> h;
534         h["a"] = "b";
535         h["c"] = "d";
536         h["x"] = "e";
537         Json j(h.begin(), h.end());
538         CHECK(j.is_o());
539         CHECK(j.size() == 3);
540         CHECK(j["a"] == "b");
541         CHECK(j["c"] == "d");
542         CHECK(j["x"] == "e");
543     }
544
545     {
546         Json j = Json::array(1, 2, 3, 4, 5, 6, 7, 8);
547         CHECK(j.unparse() == "[1,2,3,4,5,6,7,8]");
548         Json jcopy = j;
549         CHECK(j.unparse() == "[1,2,3,4,5,6,7,8]");
550         CHECK(jcopy.unparse() == "[1,2,3,4,5,6,7,8]");
551         auto it = j.erase(j.abegin() + 4);
552         CHECK_JUP(j, "[1,2,3,4,6,7,8]");
553         CHECK_JUP(jcopy, "[1,2,3,4,5,6,7,8]");
554         CHECK(it == j.abegin() + 4);
555         it = j.erase(j.aend(), j.aend());
556         CHECK_JUP(j, "[1,2,3,4,6,7,8]");
557         CHECK(it == j.aend());
558         it = j.erase(j.abegin(), j.abegin());
559         CHECK_JUP(j, "[1,2,3,4,6,7,8]");
560         CHECK(it == j.abegin());
561         it = j.erase(j.abegin(), j.abegin() + 3);
562         CHECK_JUP(j, "[4,6,7,8]");
563         CHECK(it == j.abegin());
564     }
565
566     {
567         Json j((uint64_t) 1 << 63);
568         CHECK(j.is_u());
569         CHECK(j.unparse() == "9223372036854775808");
570         j = Json::parse("9223372036854775808");
571         CHECK(j.is_u());
572         CHECK(j.to_u() == (uint64_t) 1 << 63);
573     }
574
575     {
576         Json j = Json::object("a", 1, "b", Json(2), "c", "9137471");
577         CHECK(j.unparse() == "{\"a\":1,\"b\":2,\"c\":\"9137471\"}");
578     }
579
580     {
581         Json a = Json::parse("[{\"a\":1},{\"b\":2},{\"c\":3},{\"d\":4}]");
582         Json b = Json::array(a[1], a[3], a[2], a[0]);
583         CHECK(&a[0]["a"].cvalue() == &b[3]["a"].cvalue());
584         b.push_back(a[5]);
585         CHECK(b[4] == Json());
586         CHECK(a.size() == 4);
587         b = Json::object("a5", a[5], "a3", a[3]);
588         CHECK(b.unparse() == "{\"a5\":null,\"a3\":{\"d\":4}}");
589         CHECK(a.size() == 4);
590         b.set_list("a6", a[6], "a2", a[2]);
591         CHECK(b.unparse() == "{\"a5\":null,\"a3\":{\"d\":4},\"a6\":null,\"a2\":{\"c\":3}}");
592         CHECK(a.size() == 4);
593     }
594
595     {
596         Json a = Json::parse("[{\"a\":\"\\\"\\\\\\/\"}]");
597         CHECK(a[0]["a"] == "\"\\/");
598         CHECK(a.unparse() == "[{\"a\":\"\\\"\\\\\\/\"}]");
599     }
600
601     std::cout << "All tests pass!\n";
602     return 0;
603 }