fixed adding file problem
[c11concurrency-benchmarks.git] / gdax-orderbook-hpp / demo / dependencies / rapidjson-1.1.0 / test / unittest / pointertest.cpp
1 // Tencent is pleased to support the open source community by making RapidJSON available.
2 // 
3 // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4 //
5 // Licensed under the MIT License (the "License"); you may not use this file except
6 // in compliance with the License. You may obtain a copy of the License at
7 //
8 // http://opensource.org/licenses/MIT
9 //
10 // Unless required by applicable law or agreed to in writing, software distributed 
11 // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
12 // CONDITIONS OF ANY KIND, either express or implied. See the License for the 
13 // specific language governing permissions and limitations under the License.
14
15 #include "unittest.h"
16 #include "rapidjson/pointer.h"
17 #include "rapidjson/stringbuffer.h"
18 #include <sstream>
19
20 using namespace rapidjson;
21
22 static const char kJson[] = "{\n"
23 "    \"foo\":[\"bar\", \"baz\"],\n"
24 "    \"\" : 0,\n"
25 "    \"a/b\" : 1,\n"
26 "    \"c%d\" : 2,\n"
27 "    \"e^f\" : 3,\n"
28 "    \"g|h\" : 4,\n"
29 "    \"i\\\\j\" : 5,\n"
30 "    \"k\\\"l\" : 6,\n"
31 "    \" \" : 7,\n"
32 "    \"m~n\" : 8\n"
33 "}";
34
35 TEST(Pointer, DefaultConstructor) {
36     Pointer p;
37     EXPECT_TRUE(p.IsValid());
38     EXPECT_EQ(0u, p.GetTokenCount());
39 }
40
41 TEST(Pointer, Parse) {
42     {
43         Pointer p("");
44         EXPECT_TRUE(p.IsValid());
45         EXPECT_EQ(0u, p.GetTokenCount());
46     }
47
48     {
49         Pointer p("/");
50         EXPECT_TRUE(p.IsValid());
51         EXPECT_EQ(1u, p.GetTokenCount());
52         EXPECT_EQ(0u, p.GetTokens()[0].length);
53         EXPECT_STREQ("", p.GetTokens()[0].name);
54         EXPECT_EQ(kPointerInvalidIndex, p.GetTokens()[0].index);
55     }
56
57     {
58         Pointer p("/foo");
59         EXPECT_TRUE(p.IsValid());
60         EXPECT_EQ(1u, p.GetTokenCount());
61         EXPECT_EQ(3u, p.GetTokens()[0].length);
62         EXPECT_STREQ("foo", p.GetTokens()[0].name);
63         EXPECT_EQ(kPointerInvalidIndex, p.GetTokens()[0].index);
64     }
65
66     #if RAPIDJSON_HAS_STDSTRING
67     {
68         Pointer p(std::string("/foo"));
69         EXPECT_TRUE(p.IsValid());
70         EXPECT_EQ(1u, p.GetTokenCount());
71         EXPECT_EQ(3u, p.GetTokens()[0].length);
72         EXPECT_STREQ("foo", p.GetTokens()[0].name);
73         EXPECT_EQ(kPointerInvalidIndex, p.GetTokens()[0].index);
74     }
75     #endif
76
77     {
78         Pointer p("/foo/0");
79         EXPECT_TRUE(p.IsValid());
80         EXPECT_EQ(2u, p.GetTokenCount());
81         EXPECT_EQ(3u, p.GetTokens()[0].length);
82         EXPECT_STREQ("foo", p.GetTokens()[0].name);
83         EXPECT_EQ(kPointerInvalidIndex, p.GetTokens()[0].index);
84         EXPECT_EQ(1u, p.GetTokens()[1].length);
85         EXPECT_STREQ("0", p.GetTokens()[1].name);
86         EXPECT_EQ(0u, p.GetTokens()[1].index);
87     }
88
89     {
90         // Unescape ~1
91         Pointer p("/a~1b");
92         EXPECT_TRUE(p.IsValid());
93         EXPECT_EQ(1u, p.GetTokenCount());
94         EXPECT_EQ(3u, p.GetTokens()[0].length);
95         EXPECT_STREQ("a/b", p.GetTokens()[0].name);
96     }
97
98     {
99         // Unescape ~0
100         Pointer p("/m~0n");
101         EXPECT_TRUE(p.IsValid());
102         EXPECT_EQ(1u, p.GetTokenCount());
103         EXPECT_EQ(3u, p.GetTokens()[0].length);
104         EXPECT_STREQ("m~n", p.GetTokens()[0].name);
105     }
106
107     {
108         // empty name
109         Pointer p("/");
110         EXPECT_TRUE(p.IsValid());
111         EXPECT_EQ(1u, p.GetTokenCount());
112         EXPECT_EQ(0u, p.GetTokens()[0].length);
113         EXPECT_STREQ("", p.GetTokens()[0].name);
114     }
115
116     {
117         // empty and non-empty name
118         Pointer p("//a");
119         EXPECT_TRUE(p.IsValid());
120         EXPECT_EQ(2u, p.GetTokenCount());
121         EXPECT_EQ(0u, p.GetTokens()[0].length);
122         EXPECT_STREQ("", p.GetTokens()[0].name);
123         EXPECT_EQ(1u, p.GetTokens()[1].length);
124         EXPECT_STREQ("a", p.GetTokens()[1].name);
125     }
126
127     {
128         // Null characters
129         Pointer p("/\0\0", 3);
130         EXPECT_TRUE(p.IsValid());
131         EXPECT_EQ(1u, p.GetTokenCount());
132         EXPECT_EQ(2u, p.GetTokens()[0].length);
133         EXPECT_EQ('\0', p.GetTokens()[0].name[0]);
134         EXPECT_EQ('\0', p.GetTokens()[0].name[1]);
135         EXPECT_EQ('\0', p.GetTokens()[0].name[2]);
136     }
137
138     {
139         // Valid index
140         Pointer p("/123");
141         EXPECT_TRUE(p.IsValid());
142         EXPECT_EQ(1u, p.GetTokenCount());
143         EXPECT_STREQ("123", p.GetTokens()[0].name);
144         EXPECT_EQ(123u, p.GetTokens()[0].index);
145     }
146
147     {
148         // Invalid index (with leading zero)
149         Pointer p("/01");
150         EXPECT_TRUE(p.IsValid());
151         EXPECT_EQ(1u, p.GetTokenCount());
152         EXPECT_STREQ("01", p.GetTokens()[0].name);
153         EXPECT_EQ(kPointerInvalidIndex, p.GetTokens()[0].index);
154     }
155
156     if (sizeof(SizeType) == 4) {
157         // Invalid index (overflow)
158         Pointer p("/4294967296");
159         EXPECT_TRUE(p.IsValid());
160         EXPECT_EQ(1u, p.GetTokenCount());
161         EXPECT_STREQ("4294967296", p.GetTokens()[0].name);
162         EXPECT_EQ(kPointerInvalidIndex, p.GetTokens()[0].index);
163     }
164
165     {
166         // kPointerParseErrorTokenMustBeginWithSolidus
167         Pointer p(" ");
168         EXPECT_FALSE(p.IsValid());
169         EXPECT_EQ(kPointerParseErrorTokenMustBeginWithSolidus, p.GetParseErrorCode());
170         EXPECT_EQ(0u, p.GetParseErrorOffset());
171     }
172
173     {
174         // kPointerParseErrorInvalidEscape
175         Pointer p("/~");
176         EXPECT_FALSE(p.IsValid());
177         EXPECT_EQ(kPointerParseErrorInvalidEscape, p.GetParseErrorCode());
178         EXPECT_EQ(2u, p.GetParseErrorOffset());
179     }
180
181     {
182         // kPointerParseErrorInvalidEscape
183         Pointer p("/~2");
184         EXPECT_FALSE(p.IsValid());
185         EXPECT_EQ(kPointerParseErrorInvalidEscape, p.GetParseErrorCode());
186         EXPECT_EQ(2u, p.GetParseErrorOffset());
187     }
188 }
189
190 TEST(Pointer, Parse_URIFragment) {
191     {
192         Pointer p("#");
193         EXPECT_TRUE(p.IsValid());
194         EXPECT_EQ(0u, p.GetTokenCount());
195     }
196
197     {
198         Pointer p("#/foo");
199         EXPECT_TRUE(p.IsValid());
200         EXPECT_EQ(1u, p.GetTokenCount());
201         EXPECT_EQ(3u, p.GetTokens()[0].length);
202         EXPECT_STREQ("foo", p.GetTokens()[0].name);
203     }
204
205     {
206         Pointer p("#/foo/0");
207         EXPECT_TRUE(p.IsValid());
208         EXPECT_EQ(2u, p.GetTokenCount());
209         EXPECT_EQ(3u, p.GetTokens()[0].length);
210         EXPECT_STREQ("foo", p.GetTokens()[0].name);
211         EXPECT_EQ(1u, p.GetTokens()[1].length);
212         EXPECT_STREQ("0", p.GetTokens()[1].name);
213         EXPECT_EQ(0u, p.GetTokens()[1].index);
214     }
215
216     {
217         // Unescape ~1
218         Pointer p("#/a~1b");
219         EXPECT_TRUE(p.IsValid());
220         EXPECT_EQ(1u, p.GetTokenCount());
221         EXPECT_EQ(3u, p.GetTokens()[0].length);
222         EXPECT_STREQ("a/b", p.GetTokens()[0].name);
223     }
224
225     {
226         // Unescape ~0
227         Pointer p("#/m~0n");
228         EXPECT_TRUE(p.IsValid());
229         EXPECT_EQ(1u, p.GetTokenCount());
230         EXPECT_EQ(3u, p.GetTokens()[0].length);
231         EXPECT_STREQ("m~n", p.GetTokens()[0].name);
232     }
233
234     {
235         // empty name
236         Pointer p("#/");
237         EXPECT_TRUE(p.IsValid());
238         EXPECT_EQ(1u, p.GetTokenCount());
239         EXPECT_EQ(0u, p.GetTokens()[0].length);
240         EXPECT_STREQ("", p.GetTokens()[0].name);
241     }
242
243     {
244         // empty and non-empty name
245         Pointer p("#//a");
246         EXPECT_TRUE(p.IsValid());
247         EXPECT_EQ(2u, p.GetTokenCount());
248         EXPECT_EQ(0u, p.GetTokens()[0].length);
249         EXPECT_STREQ("", p.GetTokens()[0].name);
250         EXPECT_EQ(1u, p.GetTokens()[1].length);
251         EXPECT_STREQ("a", p.GetTokens()[1].name);
252     }
253
254     {
255         // Null characters
256         Pointer p("#/%00%00");
257         EXPECT_TRUE(p.IsValid());
258         EXPECT_EQ(1u, p.GetTokenCount());
259         EXPECT_EQ(2u, p.GetTokens()[0].length);
260         EXPECT_EQ('\0', p.GetTokens()[0].name[0]);
261         EXPECT_EQ('\0', p.GetTokens()[0].name[1]);
262         EXPECT_EQ('\0', p.GetTokens()[0].name[2]);
263     }
264
265     {
266         // Percentage Escapes
267         EXPECT_STREQ("c%d", Pointer("#/c%25d").GetTokens()[0].name);
268         EXPECT_STREQ("e^f", Pointer("#/e%5Ef").GetTokens()[0].name);
269         EXPECT_STREQ("g|h", Pointer("#/g%7Ch").GetTokens()[0].name);
270         EXPECT_STREQ("i\\j", Pointer("#/i%5Cj").GetTokens()[0].name);
271         EXPECT_STREQ("k\"l", Pointer("#/k%22l").GetTokens()[0].name);
272         EXPECT_STREQ(" ", Pointer("#/%20").GetTokens()[0].name);
273     }
274
275     {
276         // Valid index
277         Pointer p("#/123");
278         EXPECT_TRUE(p.IsValid());
279         EXPECT_EQ(1u, p.GetTokenCount());
280         EXPECT_STREQ("123", p.GetTokens()[0].name);
281         EXPECT_EQ(123u, p.GetTokens()[0].index);
282     }
283
284     {
285         // Invalid index (with leading zero)
286         Pointer p("#/01");
287         EXPECT_TRUE(p.IsValid());
288         EXPECT_EQ(1u, p.GetTokenCount());
289         EXPECT_STREQ("01", p.GetTokens()[0].name);
290         EXPECT_EQ(kPointerInvalidIndex, p.GetTokens()[0].index);
291     }
292
293     if (sizeof(SizeType) == 4) {
294         // Invalid index (overflow)
295         Pointer p("#/4294967296");
296         EXPECT_TRUE(p.IsValid());
297         EXPECT_EQ(1u, p.GetTokenCount());
298         EXPECT_STREQ("4294967296", p.GetTokens()[0].name);
299         EXPECT_EQ(kPointerInvalidIndex, p.GetTokens()[0].index);
300     }
301
302     {
303         // Decode UTF-8 perecent encoding to UTF-8
304         Pointer p("#/%C2%A2");
305         EXPECT_TRUE(p.IsValid());
306         EXPECT_EQ(1u, p.GetTokenCount());
307         EXPECT_STREQ("\xC2\xA2", p.GetTokens()[0].name);
308     }
309
310     {
311         // Decode UTF-8 perecent encoding to UTF-16
312         GenericPointer<GenericValue<UTF16<> > > p(L"#/%C2%A2");
313         EXPECT_TRUE(p.IsValid());
314         EXPECT_EQ(1u, p.GetTokenCount());
315         EXPECT_EQ(static_cast<UTF16<>::Ch>(0x00A2), p.GetTokens()[0].name[0]);
316         EXPECT_EQ(1u, p.GetTokens()[0].length);
317     }
318
319     {
320         // Decode UTF-8 perecent encoding to UTF-16
321         GenericPointer<GenericValue<UTF16<> > > p(L"#/%E2%82%AC");
322         EXPECT_TRUE(p.IsValid());
323         EXPECT_EQ(1u, p.GetTokenCount());
324         EXPECT_EQ(static_cast<UTF16<>::Ch>(0x20AC), p.GetTokens()[0].name[0]);
325         EXPECT_EQ(1u, p.GetTokens()[0].length);
326     }
327
328     {
329         // kPointerParseErrorTokenMustBeginWithSolidus
330         Pointer p("# ");
331         EXPECT_FALSE(p.IsValid());
332         EXPECT_EQ(kPointerParseErrorTokenMustBeginWithSolidus, p.GetParseErrorCode());
333         EXPECT_EQ(1u, p.GetParseErrorOffset());
334     }
335
336     {
337         // kPointerParseErrorInvalidEscape
338         Pointer p("#/~");
339         EXPECT_FALSE(p.IsValid());
340         EXPECT_EQ(kPointerParseErrorInvalidEscape, p.GetParseErrorCode());
341         EXPECT_EQ(3u, p.GetParseErrorOffset());
342     }
343
344     {
345         // kPointerParseErrorInvalidEscape
346         Pointer p("#/~2");
347         EXPECT_FALSE(p.IsValid());
348         EXPECT_EQ(kPointerParseErrorInvalidEscape, p.GetParseErrorCode());
349         EXPECT_EQ(3u, p.GetParseErrorOffset());
350     }
351
352     {
353         // kPointerParseErrorInvalidPercentEncoding
354         Pointer p("#/%");
355         EXPECT_FALSE(p.IsValid());
356         EXPECT_EQ(kPointerParseErrorInvalidPercentEncoding, p.GetParseErrorCode());
357         EXPECT_EQ(2u, p.GetParseErrorOffset());
358     }
359
360     {
361         // kPointerParseErrorInvalidPercentEncoding (invalid hex)
362         Pointer p("#/%g0");
363         EXPECT_FALSE(p.IsValid());
364         EXPECT_EQ(kPointerParseErrorInvalidPercentEncoding, p.GetParseErrorCode());
365         EXPECT_EQ(2u, p.GetParseErrorOffset());
366     }
367
368     {
369         // kPointerParseErrorInvalidPercentEncoding (invalid hex)
370         Pointer p("#/%0g");
371         EXPECT_FALSE(p.IsValid());
372         EXPECT_EQ(kPointerParseErrorInvalidPercentEncoding, p.GetParseErrorCode());
373         EXPECT_EQ(2u, p.GetParseErrorOffset());
374     }
375
376     {
377         // kPointerParseErrorInvalidPercentEncoding (incomplete UTF-8 sequence)
378         Pointer p("#/%C2");
379         EXPECT_FALSE(p.IsValid());
380         EXPECT_EQ(kPointerParseErrorInvalidPercentEncoding, p.GetParseErrorCode());
381         EXPECT_EQ(2u, p.GetParseErrorOffset());
382     }
383
384     {
385         // kPointerParseErrorCharacterMustPercentEncode
386         Pointer p("#/ ");
387         EXPECT_FALSE(p.IsValid());
388         EXPECT_EQ(kPointerParseErrorCharacterMustPercentEncode, p.GetParseErrorCode());
389         EXPECT_EQ(2u, p.GetParseErrorOffset());
390     }
391
392     {
393         // kPointerParseErrorCharacterMustPercentEncode
394         Pointer p("#/\n");
395         EXPECT_FALSE(p.IsValid());
396         EXPECT_EQ(kPointerParseErrorCharacterMustPercentEncode, p.GetParseErrorCode());
397         EXPECT_EQ(2u, p.GetParseErrorOffset());
398     }
399 }
400
401 TEST(Pointer, Stringify) {
402     // Test by roundtrip
403     const char* sources[] = {
404         "",
405         "/foo",
406         "/foo/0",
407         "/",
408         "/a~1b",
409         "/c%d",
410         "/e^f",
411         "/g|h",
412         "/i\\j",
413         "/k\"l",
414         "/ ",
415         "/m~0n",
416         "/\xC2\xA2",
417         "/\xE2\x82\xAC",
418         "/\xF0\x9D\x84\x9E"
419     };
420
421     for (size_t i = 0; i < sizeof(sources) / sizeof(sources[0]); i++) {
422         Pointer p(sources[i]);
423         StringBuffer s;
424         EXPECT_TRUE(p.Stringify(s));
425         EXPECT_STREQ(sources[i], s.GetString());
426
427         // Stringify to URI fragment
428         StringBuffer s2;
429         EXPECT_TRUE(p.StringifyUriFragment(s2));
430         Pointer p2(s2.GetString(), s2.GetSize());
431         EXPECT_TRUE(p2.IsValid());
432         EXPECT_TRUE(p == p2);
433     }
434
435     {
436         // Strigify to URI fragment with an invalid UTF-8 sequence
437         Pointer p("/\xC2");
438         StringBuffer s;
439         EXPECT_FALSE(p.StringifyUriFragment(s));
440     }
441 }
442
443 // Construct a Pointer with static tokens, no dynamic allocation involved.
444 #define NAME(s) { s, sizeof(s) / sizeof(s[0]) - 1, kPointerInvalidIndex }
445 #define INDEX(i) { #i, sizeof(#i) - 1, i }
446
447 static const Pointer::Token kTokens[] = { NAME("foo"), INDEX(0) }; // equivalent to "/foo/0"
448
449 #undef NAME
450 #undef INDEX
451
452 TEST(Pointer, ConstructorWithToken) {
453     Pointer p(kTokens, sizeof(kTokens) / sizeof(kTokens[0]));
454     EXPECT_TRUE(p.IsValid());
455     EXPECT_EQ(2u, p.GetTokenCount());
456     EXPECT_EQ(3u, p.GetTokens()[0].length);
457     EXPECT_STREQ("foo", p.GetTokens()[0].name);
458     EXPECT_EQ(1u, p.GetTokens()[1].length);
459     EXPECT_STREQ("0", p.GetTokens()[1].name);
460     EXPECT_EQ(0u, p.GetTokens()[1].index);
461 }
462
463 TEST(Pointer, CopyConstructor) {
464     {
465         Pointer p("/foo/0");
466         Pointer q(p);
467         EXPECT_TRUE(q.IsValid());
468         EXPECT_EQ(2u, q.GetTokenCount());
469         EXPECT_EQ(3u, q.GetTokens()[0].length);
470         EXPECT_STREQ("foo", q.GetTokens()[0].name);
471         EXPECT_EQ(1u, q.GetTokens()[1].length);
472         EXPECT_STREQ("0", q.GetTokens()[1].name);
473         EXPECT_EQ(0u, q.GetTokens()[1].index);
474     }
475
476     // Static tokens
477     {
478         Pointer p(kTokens, sizeof(kTokens) / sizeof(kTokens[0]));
479         Pointer q(p);
480         EXPECT_TRUE(q.IsValid());
481         EXPECT_EQ(2u, q.GetTokenCount());
482         EXPECT_EQ(3u, q.GetTokens()[0].length);
483         EXPECT_STREQ("foo", q.GetTokens()[0].name);
484         EXPECT_EQ(1u, q.GetTokens()[1].length);
485         EXPECT_STREQ("0", q.GetTokens()[1].name);
486         EXPECT_EQ(0u, q.GetTokens()[1].index);
487     }
488 }
489
490 TEST(Pointer, Assignment) {
491     {
492         Pointer p("/foo/0");
493         Pointer q;
494         q = p;
495         EXPECT_TRUE(q.IsValid());
496         EXPECT_EQ(2u, q.GetTokenCount());
497         EXPECT_EQ(3u, q.GetTokens()[0].length);
498         EXPECT_STREQ("foo", q.GetTokens()[0].name);
499         EXPECT_EQ(1u, q.GetTokens()[1].length);
500         EXPECT_STREQ("0", q.GetTokens()[1].name);
501         EXPECT_EQ(0u, q.GetTokens()[1].index);
502         q = q;
503         EXPECT_TRUE(q.IsValid());
504         EXPECT_EQ(2u, q.GetTokenCount());
505         EXPECT_EQ(3u, q.GetTokens()[0].length);
506         EXPECT_STREQ("foo", q.GetTokens()[0].name);
507         EXPECT_EQ(1u, q.GetTokens()[1].length);
508         EXPECT_STREQ("0", q.GetTokens()[1].name);
509         EXPECT_EQ(0u, q.GetTokens()[1].index);
510     }
511
512     // Static tokens
513     {
514         Pointer p(kTokens, sizeof(kTokens) / sizeof(kTokens[0]));
515         Pointer q;
516         q = p;
517         EXPECT_TRUE(q.IsValid());
518         EXPECT_EQ(2u, q.GetTokenCount());
519         EXPECT_EQ(3u, q.GetTokens()[0].length);
520         EXPECT_STREQ("foo", q.GetTokens()[0].name);
521         EXPECT_EQ(1u, q.GetTokens()[1].length);
522         EXPECT_STREQ("0", q.GetTokens()[1].name);
523         EXPECT_EQ(0u, q.GetTokens()[1].index);
524     }
525 }
526
527 TEST(Pointer, Append) {
528     {
529         Pointer p;
530         Pointer q = p.Append("foo");
531         EXPECT_TRUE(Pointer("/foo") == q);
532         q = q.Append(1234);
533         EXPECT_TRUE(Pointer("/foo/1234") == q);
534         q = q.Append("");
535         EXPECT_TRUE(Pointer("/foo/1234/") == q);
536     }
537
538     {
539         Pointer p;
540         Pointer q = p.Append(Value("foo").Move());
541         EXPECT_TRUE(Pointer("/foo") == q);
542         q = q.Append(Value(1234).Move());
543         EXPECT_TRUE(Pointer("/foo/1234") == q);
544         q = q.Append(Value(kStringType).Move());
545         EXPECT_TRUE(Pointer("/foo/1234/") == q);
546     }
547
548 #if RAPIDJSON_HAS_STDSTRING
549     {
550         Pointer p;
551         Pointer q = p.Append(std::string("foo"));
552         EXPECT_TRUE(Pointer("/foo") == q);
553     }
554 #endif
555 }
556
557 TEST(Pointer, Equality) {
558     EXPECT_TRUE(Pointer("/foo/0") == Pointer("/foo/0"));
559     EXPECT_FALSE(Pointer("/foo/0") == Pointer("/foo/1"));
560     EXPECT_FALSE(Pointer("/foo/0") == Pointer("/foo/0/1"));
561     EXPECT_FALSE(Pointer("/foo/0") == Pointer("a"));
562     EXPECT_FALSE(Pointer("a") == Pointer("a")); // Invalid always not equal
563 }
564
565 TEST(Pointer, Inequality) {
566     EXPECT_FALSE(Pointer("/foo/0") != Pointer("/foo/0"));
567     EXPECT_TRUE(Pointer("/foo/0") != Pointer("/foo/1"));
568     EXPECT_TRUE(Pointer("/foo/0") != Pointer("/foo/0/1"));
569     EXPECT_TRUE(Pointer("/foo/0") != Pointer("a"));
570     EXPECT_TRUE(Pointer("a") != Pointer("a")); // Invalid always not equal
571 }
572
573 TEST(Pointer, Create) {
574     Document d;
575     {
576         Value* v = &Pointer("").Create(d, d.GetAllocator());
577         EXPECT_EQ(&d, v);
578     }
579     {
580         Value* v = &Pointer("/foo").Create(d, d.GetAllocator());
581         EXPECT_EQ(&d["foo"], v);
582     }
583     {
584         Value* v = &Pointer("/foo/0").Create(d, d.GetAllocator());
585         EXPECT_EQ(&d["foo"][0], v);
586     }
587     {
588         Value* v = &Pointer("/foo/-").Create(d, d.GetAllocator());
589         EXPECT_EQ(&d["foo"][1], v);
590     }
591
592     {
593         Value* v = &Pointer("/foo/-/-").Create(d, d.GetAllocator());
594         // "foo/-" is a newly created null value x.
595         // "foo/-/-" finds that x is not an array, it converts x to empty object
596         // and treats - as "-" member name
597         EXPECT_EQ(&d["foo"][2]["-"], v);
598     }
599
600     {
601         // Document with no allocator
602         Value* v = &Pointer("/foo/-").Create(d);
603         EXPECT_EQ(&d["foo"][3], v);
604     }
605
606     {
607         // Value (not document) must give allocator
608         Value* v = &Pointer("/-").Create(d["foo"], d.GetAllocator());
609         EXPECT_EQ(&d["foo"][4], v);
610     }
611 }
612
613 TEST(Pointer, Get) {
614     Document d;
615     d.Parse(kJson);
616
617     EXPECT_EQ(&d, Pointer("").Get(d));
618     EXPECT_EQ(&d["foo"], Pointer("/foo").Get(d));
619     EXPECT_EQ(&d["foo"][0], Pointer("/foo/0").Get(d));
620     EXPECT_EQ(&d[""], Pointer("/").Get(d));
621     EXPECT_EQ(&d["a/b"], Pointer("/a~1b").Get(d));
622     EXPECT_EQ(&d["c%d"], Pointer("/c%d").Get(d));
623     EXPECT_EQ(&d["e^f"], Pointer("/e^f").Get(d));
624     EXPECT_EQ(&d["g|h"], Pointer("/g|h").Get(d));
625     EXPECT_EQ(&d["i\\j"], Pointer("/i\\j").Get(d));
626     EXPECT_EQ(&d["k\"l"], Pointer("/k\"l").Get(d));
627     EXPECT_EQ(&d[" "], Pointer("/ ").Get(d));
628     EXPECT_EQ(&d["m~n"], Pointer("/m~0n").Get(d));
629     EXPECT_TRUE(Pointer("/abc").Get(d) == 0);
630     size_t unresolvedTokenIndex;
631     EXPECT_TRUE(Pointer("/foo/2").Get(d, &unresolvedTokenIndex) == 0); // Out of boundary
632     EXPECT_EQ(1, unresolvedTokenIndex);
633     EXPECT_TRUE(Pointer("/foo/a").Get(d, &unresolvedTokenIndex) == 0); // "/foo" is an array, cannot query by "a"
634     EXPECT_EQ(1, unresolvedTokenIndex);
635     EXPECT_TRUE(Pointer("/foo/0/0").Get(d, &unresolvedTokenIndex) == 0); // "/foo/0" is an string, cannot further query
636     EXPECT_EQ(2, unresolvedTokenIndex);
637     EXPECT_TRUE(Pointer("/foo/0/a").Get(d, &unresolvedTokenIndex) == 0); // "/foo/0" is an string, cannot further query
638     EXPECT_EQ(2, unresolvedTokenIndex);
639 }
640
641 TEST(Pointer, GetWithDefault) {
642     Document d;
643     d.Parse(kJson);
644
645     // Value version
646     Document::AllocatorType& a = d.GetAllocator();
647     const Value v("qux");
648     EXPECT_TRUE(Value("bar") == Pointer("/foo/0").GetWithDefault(d, v, a));
649     EXPECT_TRUE(Value("baz") == Pointer("/foo/1").GetWithDefault(d, v, a));
650     EXPECT_TRUE(Value("qux") == Pointer("/foo/2").GetWithDefault(d, v, a));
651     EXPECT_TRUE(Value("last") == Pointer("/foo/-").GetWithDefault(d, Value("last").Move(), a));
652     EXPECT_STREQ("last", d["foo"][3].GetString());
653
654     EXPECT_TRUE(Pointer("/foo/null").GetWithDefault(d, Value().Move(), a).IsNull());
655     EXPECT_TRUE(Pointer("/foo/null").GetWithDefault(d, "x", a).IsNull());
656
657     // Generic version
658     EXPECT_EQ(-1, Pointer("/foo/int").GetWithDefault(d, -1, a).GetInt());
659     EXPECT_EQ(-1, Pointer("/foo/int").GetWithDefault(d, -2, a).GetInt());
660     EXPECT_EQ(0x87654321, Pointer("/foo/uint").GetWithDefault(d, 0x87654321, a).GetUint());
661     EXPECT_EQ(0x87654321, Pointer("/foo/uint").GetWithDefault(d, 0x12345678, a).GetUint());
662
663     const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
664     EXPECT_EQ(i64, Pointer("/foo/int64").GetWithDefault(d, i64, a).GetInt64());
665     EXPECT_EQ(i64, Pointer("/foo/int64").GetWithDefault(d, i64 + 1, a).GetInt64());
666
667     const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
668     EXPECT_EQ(u64, Pointer("/foo/uint64").GetWithDefault(d, u64, a).GetUint64());
669     EXPECT_EQ(u64, Pointer("/foo/uint64").GetWithDefault(d, u64 - 1, a).GetUint64());
670
671     EXPECT_TRUE(Pointer("/foo/true").GetWithDefault(d, true, a).IsTrue());
672     EXPECT_TRUE(Pointer("/foo/true").GetWithDefault(d, false, a).IsTrue());
673
674     EXPECT_TRUE(Pointer("/foo/false").GetWithDefault(d, false, a).IsFalse());
675     EXPECT_TRUE(Pointer("/foo/false").GetWithDefault(d, true, a).IsFalse());
676
677     // StringRef version
678     EXPECT_STREQ("Hello", Pointer("/foo/hello").GetWithDefault(d, "Hello", a).GetString());
679
680     // Copy string version
681     {
682         char buffer[256];
683         strcpy(buffer, "World");
684         EXPECT_STREQ("World", Pointer("/foo/world").GetWithDefault(d, buffer, a).GetString());
685         memset(buffer, 0, sizeof(buffer));
686     }
687     EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
688
689 #if RAPIDJSON_HAS_STDSTRING
690     EXPECT_STREQ("C++", Pointer("/foo/C++").GetWithDefault(d, std::string("C++"), a).GetString());
691 #endif
692 }
693
694 TEST(Pointer, GetWithDefault_NoAllocator) {
695     Document d;
696     d.Parse(kJson);
697
698     // Value version
699     const Value v("qux");
700     EXPECT_TRUE(Value("bar") == Pointer("/foo/0").GetWithDefault(d, v));
701     EXPECT_TRUE(Value("baz") == Pointer("/foo/1").GetWithDefault(d, v));
702     EXPECT_TRUE(Value("qux") == Pointer("/foo/2").GetWithDefault(d, v));
703     EXPECT_TRUE(Value("last") == Pointer("/foo/-").GetWithDefault(d, Value("last").Move()));
704     EXPECT_STREQ("last", d["foo"][3].GetString());
705
706     EXPECT_TRUE(Pointer("/foo/null").GetWithDefault(d, Value().Move()).IsNull());
707     EXPECT_TRUE(Pointer("/foo/null").GetWithDefault(d, "x").IsNull());
708
709     // Generic version
710     EXPECT_EQ(-1, Pointer("/foo/int").GetWithDefault(d, -1).GetInt());
711     EXPECT_EQ(-1, Pointer("/foo/int").GetWithDefault(d, -2).GetInt());
712     EXPECT_EQ(0x87654321, Pointer("/foo/uint").GetWithDefault(d, 0x87654321).GetUint());
713     EXPECT_EQ(0x87654321, Pointer("/foo/uint").GetWithDefault(d, 0x12345678).GetUint());
714
715     const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
716     EXPECT_EQ(i64, Pointer("/foo/int64").GetWithDefault(d, i64).GetInt64());
717     EXPECT_EQ(i64, Pointer("/foo/int64").GetWithDefault(d, i64 + 1).GetInt64());
718
719     const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
720     EXPECT_EQ(u64, Pointer("/foo/uint64").GetWithDefault(d, u64).GetUint64());
721     EXPECT_EQ(u64, Pointer("/foo/uint64").GetWithDefault(d, u64 - 1).GetUint64());
722
723     EXPECT_TRUE(Pointer("/foo/true").GetWithDefault(d, true).IsTrue());
724     EXPECT_TRUE(Pointer("/foo/true").GetWithDefault(d, false).IsTrue());
725
726     EXPECT_TRUE(Pointer("/foo/false").GetWithDefault(d, false).IsFalse());
727     EXPECT_TRUE(Pointer("/foo/false").GetWithDefault(d, true).IsFalse());
728
729     // StringRef version
730     EXPECT_STREQ("Hello", Pointer("/foo/hello").GetWithDefault(d, "Hello").GetString());
731
732     // Copy string version
733     {
734         char buffer[256];
735         strcpy(buffer, "World");
736         EXPECT_STREQ("World", Pointer("/foo/world").GetWithDefault(d, buffer).GetString());
737         memset(buffer, 0, sizeof(buffer));
738     }
739     EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
740
741 #if RAPIDJSON_HAS_STDSTRING
742     EXPECT_STREQ("C++", Pointer("/foo/C++").GetWithDefault(d, std::string("C++")).GetString());
743 #endif
744 }
745
746 TEST(Pointer, Set) {
747     Document d;
748     d.Parse(kJson);
749     Document::AllocatorType& a = d.GetAllocator();
750     
751     // Value version
752     Pointer("/foo/0").Set(d, Value(123).Move(), a);
753     EXPECT_EQ(123, d["foo"][0].GetInt());
754
755     Pointer("/foo/-").Set(d, Value(456).Move(), a);
756     EXPECT_EQ(456, d["foo"][2].GetInt());
757
758     Pointer("/foo/null").Set(d, Value().Move(), a);
759     EXPECT_TRUE(GetValueByPointer(d, "/foo/null")->IsNull());
760
761     // Const Value version
762     const Value foo(d["foo"], a);
763     Pointer("/clone").Set(d, foo, a);
764     EXPECT_EQ(foo, *GetValueByPointer(d, "/clone"));
765
766     // Generic version
767     Pointer("/foo/int").Set(d, -1, a);
768     EXPECT_EQ(-1, GetValueByPointer(d, "/foo/int")->GetInt());
769
770     Pointer("/foo/uint").Set(d, 0x87654321, a);
771     EXPECT_EQ(0x87654321, GetValueByPointer(d, "/foo/uint")->GetUint());
772
773     const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
774     Pointer("/foo/int64").Set(d, i64, a);
775     EXPECT_EQ(i64, GetValueByPointer(d, "/foo/int64")->GetInt64());
776
777     const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
778     Pointer("/foo/uint64").Set(d, u64, a);
779     EXPECT_EQ(u64, GetValueByPointer(d, "/foo/uint64")->GetUint64());
780
781     Pointer("/foo/true").Set(d, true, a);
782     EXPECT_TRUE(GetValueByPointer(d, "/foo/true")->IsTrue());
783
784     Pointer("/foo/false").Set(d, false, a);
785     EXPECT_TRUE(GetValueByPointer(d, "/foo/false")->IsFalse());
786
787     // StringRef version
788     Pointer("/foo/hello").Set(d, "Hello", a);
789     EXPECT_STREQ("Hello", GetValueByPointer(d, "/foo/hello")->GetString());
790
791     // Copy string version
792     {
793         char buffer[256];
794         strcpy(buffer, "World");
795         Pointer("/foo/world").Set(d, buffer, a);
796         memset(buffer, 0, sizeof(buffer));
797     }
798     EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
799
800 #if RAPIDJSON_HAS_STDSTRING
801     Pointer("/foo/c++").Set(d, std::string("C++"), a);
802     EXPECT_STREQ("C++", GetValueByPointer(d, "/foo/c++")->GetString());
803 #endif
804 }
805
806 TEST(Pointer, Set_NoAllocator) {
807     Document d;
808     d.Parse(kJson);
809     
810     // Value version
811     Pointer("/foo/0").Set(d, Value(123).Move());
812     EXPECT_EQ(123, d["foo"][0].GetInt());
813
814     Pointer("/foo/-").Set(d, Value(456).Move());
815     EXPECT_EQ(456, d["foo"][2].GetInt());
816
817     Pointer("/foo/null").Set(d, Value().Move());
818     EXPECT_TRUE(GetValueByPointer(d, "/foo/null")->IsNull());
819
820     // Const Value version
821     const Value foo(d["foo"], d.GetAllocator());
822     Pointer("/clone").Set(d, foo);
823     EXPECT_EQ(foo, *GetValueByPointer(d, "/clone"));
824
825     // Generic version
826     Pointer("/foo/int").Set(d, -1);
827     EXPECT_EQ(-1, GetValueByPointer(d, "/foo/int")->GetInt());
828
829     Pointer("/foo/uint").Set(d, 0x87654321);
830     EXPECT_EQ(0x87654321, GetValueByPointer(d, "/foo/uint")->GetUint());
831
832     const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
833     Pointer("/foo/int64").Set(d, i64);
834     EXPECT_EQ(i64, GetValueByPointer(d, "/foo/int64")->GetInt64());
835
836     const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
837     Pointer("/foo/uint64").Set(d, u64);
838     EXPECT_EQ(u64, GetValueByPointer(d, "/foo/uint64")->GetUint64());
839
840     Pointer("/foo/true").Set(d, true);
841     EXPECT_TRUE(GetValueByPointer(d, "/foo/true")->IsTrue());
842
843     Pointer("/foo/false").Set(d, false);
844     EXPECT_TRUE(GetValueByPointer(d, "/foo/false")->IsFalse());
845
846     // StringRef version
847     Pointer("/foo/hello").Set(d, "Hello");
848     EXPECT_STREQ("Hello", GetValueByPointer(d, "/foo/hello")->GetString());
849
850     // Copy string version
851     {
852         char buffer[256];
853         strcpy(buffer, "World");
854         Pointer("/foo/world").Set(d, buffer);
855         memset(buffer, 0, sizeof(buffer));
856     }
857     EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
858
859 #if RAPIDJSON_HAS_STDSTRING
860     Pointer("/foo/c++").Set(d, std::string("C++"));
861     EXPECT_STREQ("C++", GetValueByPointer(d, "/foo/c++")->GetString());
862 #endif
863 }
864
865 TEST(Pointer, Swap) {
866     Document d;
867     d.Parse(kJson);
868     Document::AllocatorType& a = d.GetAllocator();
869     Pointer("/foo/0").Swap(d, *Pointer("/foo/1").Get(d), a);
870     EXPECT_STREQ("baz", d["foo"][0].GetString());
871     EXPECT_STREQ("bar", d["foo"][1].GetString());
872 }
873
874 TEST(Pointer, Swap_NoAllocator) {
875     Document d;
876     d.Parse(kJson);
877     Pointer("/foo/0").Swap(d, *Pointer("/foo/1").Get(d));
878     EXPECT_STREQ("baz", d["foo"][0].GetString());
879     EXPECT_STREQ("bar", d["foo"][1].GetString());
880 }
881
882 TEST(Pointer, Erase) {
883     Document d;
884     d.Parse(kJson);
885
886     EXPECT_FALSE(Pointer("").Erase(d));
887     EXPECT_FALSE(Pointer("/nonexist").Erase(d));
888     EXPECT_FALSE(Pointer("/nonexist/nonexist").Erase(d));
889     EXPECT_FALSE(Pointer("/foo/nonexist").Erase(d));
890     EXPECT_FALSE(Pointer("/foo/nonexist/nonexist").Erase(d));
891     EXPECT_FALSE(Pointer("/foo/0/nonexist").Erase(d));
892     EXPECT_FALSE(Pointer("/foo/0/nonexist/nonexist").Erase(d));
893     EXPECT_FALSE(Pointer("/foo/2/nonexist").Erase(d));
894     EXPECT_TRUE(Pointer("/foo/0").Erase(d));
895     EXPECT_EQ(1u, d["foo"].Size());
896     EXPECT_STREQ("baz", d["foo"][0].GetString());
897     EXPECT_TRUE(Pointer("/foo/0").Erase(d));
898     EXPECT_TRUE(d["foo"].Empty());
899     EXPECT_TRUE(Pointer("/foo").Erase(d));
900     EXPECT_TRUE(Pointer("/foo").Get(d) == 0);
901
902     Pointer("/a/0/b/0").Create(d);
903
904     EXPECT_TRUE(Pointer("/a/0/b/0").Get(d) != 0);
905     EXPECT_TRUE(Pointer("/a/0/b/0").Erase(d));
906     EXPECT_TRUE(Pointer("/a/0/b/0").Get(d) == 0);
907
908     EXPECT_TRUE(Pointer("/a/0/b").Get(d) != 0);
909     EXPECT_TRUE(Pointer("/a/0/b").Erase(d));
910     EXPECT_TRUE(Pointer("/a/0/b").Get(d) == 0);
911
912     EXPECT_TRUE(Pointer("/a/0").Get(d) != 0);
913     EXPECT_TRUE(Pointer("/a/0").Erase(d));
914     EXPECT_TRUE(Pointer("/a/0").Get(d) == 0);
915
916     EXPECT_TRUE(Pointer("/a").Get(d) != 0);
917     EXPECT_TRUE(Pointer("/a").Erase(d));
918     EXPECT_TRUE(Pointer("/a").Get(d) == 0);
919 }
920
921 TEST(Pointer, CreateValueByPointer) {
922     Document d;
923     Document::AllocatorType& a = d.GetAllocator();
924
925     {
926         Value& v = CreateValueByPointer(d, Pointer("/foo/0"), a);
927         EXPECT_EQ(&d["foo"][0], &v);
928     }
929     {
930         Value& v = CreateValueByPointer(d, "/foo/1", a);
931         EXPECT_EQ(&d["foo"][1], &v);
932     }
933 }
934
935 TEST(Pointer, CreateValueByPointer_NoAllocator) {
936     Document d;
937
938     {
939         Value& v = CreateValueByPointer(d, Pointer("/foo/0"));
940         EXPECT_EQ(&d["foo"][0], &v);
941     }
942     {
943         Value& v = CreateValueByPointer(d, "/foo/1");
944         EXPECT_EQ(&d["foo"][1], &v);
945     }
946 }
947
948 TEST(Pointer, GetValueByPointer) {
949     Document d;
950     d.Parse(kJson);
951
952     EXPECT_EQ(&d["foo"][0], GetValueByPointer(d, Pointer("/foo/0")));
953     EXPECT_EQ(&d["foo"][0], GetValueByPointer(d, "/foo/0"));
954
955     size_t unresolvedTokenIndex;
956     EXPECT_TRUE(GetValueByPointer(d, "/foo/2", &unresolvedTokenIndex) == 0); // Out of boundary
957     EXPECT_EQ(1, unresolvedTokenIndex);
958     EXPECT_TRUE(GetValueByPointer(d, "/foo/a", &unresolvedTokenIndex) == 0); // "/foo" is an array, cannot query by "a"
959     EXPECT_EQ(1, unresolvedTokenIndex);
960     EXPECT_TRUE(GetValueByPointer(d, "/foo/0/0", &unresolvedTokenIndex) == 0); // "/foo/0" is an string, cannot further query
961     EXPECT_EQ(2, unresolvedTokenIndex);
962     EXPECT_TRUE(GetValueByPointer(d, "/foo/0/a", &unresolvedTokenIndex) == 0); // "/foo/0" is an string, cannot further query
963     EXPECT_EQ(2, unresolvedTokenIndex);
964
965     // const version
966     const Value& v = d;
967     EXPECT_EQ(&d["foo"][0], GetValueByPointer(v, Pointer("/foo/0")));
968     EXPECT_EQ(&d["foo"][0], GetValueByPointer(v, "/foo/0"));
969
970     EXPECT_TRUE(GetValueByPointer(v, "/foo/2", &unresolvedTokenIndex) == 0); // Out of boundary
971     EXPECT_EQ(1, unresolvedTokenIndex);
972     EXPECT_TRUE(GetValueByPointer(v, "/foo/a", &unresolvedTokenIndex) == 0); // "/foo" is an array, cannot query by "a"
973     EXPECT_EQ(1, unresolvedTokenIndex);
974     EXPECT_TRUE(GetValueByPointer(v, "/foo/0/0", &unresolvedTokenIndex) == 0); // "/foo/0" is an string, cannot further query
975     EXPECT_EQ(2, unresolvedTokenIndex);
976     EXPECT_TRUE(GetValueByPointer(v, "/foo/0/a", &unresolvedTokenIndex) == 0); // "/foo/0" is an string, cannot further query
977     EXPECT_EQ(2, unresolvedTokenIndex);
978
979 }
980
981 TEST(Pointer, GetValueByPointerWithDefault_Pointer) {
982     Document d;
983     d.Parse(kJson);
984
985     Document::AllocatorType& a = d.GetAllocator();
986     const Value v("qux");
987     EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d, Pointer("/foo/0"), v, a));
988     EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d, Pointer("/foo/0"), v, a));
989     EXPECT_TRUE(Value("baz") == GetValueByPointerWithDefault(d, Pointer("/foo/1"), v, a));
990     EXPECT_TRUE(Value("qux") == GetValueByPointerWithDefault(d, Pointer("/foo/2"), v, a));
991     EXPECT_TRUE(Value("last") == GetValueByPointerWithDefault(d, Pointer("/foo/-"), Value("last").Move(), a));
992     EXPECT_STREQ("last", d["foo"][3].GetString());
993
994     EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/null"), Value().Move(), a).IsNull());
995     EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/null"), "x", a).IsNull());
996
997     // Generic version
998     EXPECT_EQ(-1, GetValueByPointerWithDefault(d, Pointer("/foo/int"), -1, a).GetInt());
999     EXPECT_EQ(-1, GetValueByPointerWithDefault(d, Pointer("/foo/int"), -2, a).GetInt());
1000     EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d, Pointer("/foo/uint"), 0x87654321, a).GetUint());
1001     EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d, Pointer("/foo/uint"), 0x12345678, a).GetUint());
1002
1003     const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
1004     EXPECT_EQ(i64, GetValueByPointerWithDefault(d, Pointer("/foo/int64"), i64, a).GetInt64());
1005     EXPECT_EQ(i64, GetValueByPointerWithDefault(d, Pointer("/foo/int64"), i64 + 1, a).GetInt64());
1006
1007     const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
1008     EXPECT_EQ(u64, GetValueByPointerWithDefault(d, Pointer("/foo/uint64"), u64, a).GetUint64());
1009     EXPECT_EQ(u64, GetValueByPointerWithDefault(d, Pointer("/foo/uint64"), u64 - 1, a).GetUint64());
1010
1011     EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/true"), true, a).IsTrue());
1012     EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/true"), false, a).IsTrue());
1013
1014     EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/false"), false, a).IsFalse());
1015     EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/false"), true, a).IsFalse());
1016
1017     // StringRef version
1018     EXPECT_STREQ("Hello", GetValueByPointerWithDefault(d, Pointer("/foo/hello"), "Hello", a).GetString());
1019
1020     // Copy string version
1021     {
1022         char buffer[256];
1023         strcpy(buffer, "World");
1024         EXPECT_STREQ("World", GetValueByPointerWithDefault(d, Pointer("/foo/world"), buffer, a).GetString());
1025         memset(buffer, 0, sizeof(buffer));
1026     }
1027     EXPECT_STREQ("World", GetValueByPointer(d, Pointer("/foo/world"))->GetString());
1028
1029 #if RAPIDJSON_HAS_STDSTRING
1030     EXPECT_STREQ("C++", GetValueByPointerWithDefault(d, Pointer("/foo/C++"), std::string("C++"), a).GetString());
1031 #endif
1032 }
1033
1034 TEST(Pointer, GetValueByPointerWithDefault_String) {
1035     Document d;
1036     d.Parse(kJson);
1037
1038     Document::AllocatorType& a = d.GetAllocator();
1039     const Value v("qux");
1040     EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d, "/foo/0", v, a));
1041     EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d, "/foo/0", v, a));
1042     EXPECT_TRUE(Value("baz") == GetValueByPointerWithDefault(d, "/foo/1", v, a));
1043     EXPECT_TRUE(Value("qux") == GetValueByPointerWithDefault(d, "/foo/2", v, a));
1044     EXPECT_TRUE(Value("last") == GetValueByPointerWithDefault(d, "/foo/-", Value("last").Move(), a));
1045     EXPECT_STREQ("last", d["foo"][3].GetString());
1046
1047     EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/null", Value().Move(), a).IsNull());
1048     EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/null", "x", a).IsNull());
1049
1050     // Generic version
1051     EXPECT_EQ(-1, GetValueByPointerWithDefault(d, "/foo/int", -1, a).GetInt());
1052     EXPECT_EQ(-1, GetValueByPointerWithDefault(d, "/foo/int", -2, a).GetInt());
1053     EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d, "/foo/uint", 0x87654321, a).GetUint());
1054     EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d, "/foo/uint", 0x12345678, a).GetUint());
1055
1056     const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
1057     EXPECT_EQ(i64, GetValueByPointerWithDefault(d, "/foo/int64", i64, a).GetInt64());
1058     EXPECT_EQ(i64, GetValueByPointerWithDefault(d, "/foo/int64", i64 + 1, a).GetInt64());
1059
1060     const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
1061     EXPECT_EQ(u64, GetValueByPointerWithDefault(d, "/foo/uint64", u64, a).GetUint64());
1062     EXPECT_EQ(u64, GetValueByPointerWithDefault(d, "/foo/uint64", u64 - 1, a).GetUint64());
1063
1064     EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/true", true, a).IsTrue());
1065     EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/true", false, a).IsTrue());
1066
1067     EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/false", false, a).IsFalse());
1068     EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/false", true, a).IsFalse());
1069
1070     // StringRef version
1071     EXPECT_STREQ("Hello", GetValueByPointerWithDefault(d, "/foo/hello", "Hello", a).GetString());
1072
1073     // Copy string version
1074     {
1075         char buffer[256];
1076         strcpy(buffer, "World");
1077         EXPECT_STREQ("World", GetValueByPointerWithDefault(d, "/foo/world", buffer, a).GetString());
1078         memset(buffer, 0, sizeof(buffer));
1079     }
1080     EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
1081
1082 #if RAPIDJSON_HAS_STDSTRING
1083     EXPECT_STREQ("C++", GetValueByPointerWithDefault(d, "/foo/C++", std::string("C++"), a).GetString());
1084 #endif
1085 }
1086
1087 TEST(Pointer, GetValueByPointerWithDefault_Pointer_NoAllocator) {
1088     Document d;
1089     d.Parse(kJson);
1090
1091     const Value v("qux");
1092     EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d, Pointer("/foo/0"), v));
1093     EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d, Pointer("/foo/0"), v));
1094     EXPECT_TRUE(Value("baz") == GetValueByPointerWithDefault(d, Pointer("/foo/1"), v));
1095     EXPECT_TRUE(Value("qux") == GetValueByPointerWithDefault(d, Pointer("/foo/2"), v));
1096     EXPECT_TRUE(Value("last") == GetValueByPointerWithDefault(d, Pointer("/foo/-"), Value("last").Move()));
1097     EXPECT_STREQ("last", d["foo"][3].GetString());
1098
1099     EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/null"), Value().Move()).IsNull());
1100     EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/null"), "x").IsNull());
1101
1102     // Generic version
1103     EXPECT_EQ(-1, GetValueByPointerWithDefault(d, Pointer("/foo/int"), -1).GetInt());
1104     EXPECT_EQ(-1, GetValueByPointerWithDefault(d, Pointer("/foo/int"), -2).GetInt());
1105     EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d, Pointer("/foo/uint"), 0x87654321).GetUint());
1106     EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d, Pointer("/foo/uint"), 0x12345678).GetUint());
1107
1108     const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
1109     EXPECT_EQ(i64, GetValueByPointerWithDefault(d, Pointer("/foo/int64"), i64).GetInt64());
1110     EXPECT_EQ(i64, GetValueByPointerWithDefault(d, Pointer("/foo/int64"), i64 + 1).GetInt64());
1111
1112     const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
1113     EXPECT_EQ(u64, GetValueByPointerWithDefault(d, Pointer("/foo/uint64"), u64).GetUint64());
1114     EXPECT_EQ(u64, GetValueByPointerWithDefault(d, Pointer("/foo/uint64"), u64 - 1).GetUint64());
1115
1116     EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/true"), true).IsTrue());
1117     EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/true"), false).IsTrue());
1118
1119     EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/false"), false).IsFalse());
1120     EXPECT_TRUE(GetValueByPointerWithDefault(d, Pointer("/foo/false"), true).IsFalse());
1121
1122     // StringRef version
1123     EXPECT_STREQ("Hello", GetValueByPointerWithDefault(d, Pointer("/foo/hello"), "Hello").GetString());
1124
1125     // Copy string version
1126     {
1127         char buffer[256];
1128         strcpy(buffer, "World");
1129         EXPECT_STREQ("World", GetValueByPointerWithDefault(d, Pointer("/foo/world"), buffer).GetString());
1130         memset(buffer, 0, sizeof(buffer));
1131     }
1132     EXPECT_STREQ("World", GetValueByPointer(d, Pointer("/foo/world"))->GetString());
1133
1134 #if RAPIDJSON_HAS_STDSTRING
1135     EXPECT_STREQ("C++", GetValueByPointerWithDefault(d, Pointer("/foo/C++"), std::string("C++")).GetString());
1136 #endif
1137 }
1138
1139 TEST(Pointer, GetValueByPointerWithDefault_String_NoAllocator) {
1140     Document d;
1141     d.Parse(kJson);
1142
1143     const Value v("qux");
1144     EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d, "/foo/0", v));
1145     EXPECT_TRUE(Value("bar") == GetValueByPointerWithDefault(d, "/foo/0", v));
1146     EXPECT_TRUE(Value("baz") == GetValueByPointerWithDefault(d, "/foo/1", v));
1147     EXPECT_TRUE(Value("qux") == GetValueByPointerWithDefault(d, "/foo/2", v));
1148     EXPECT_TRUE(Value("last") == GetValueByPointerWithDefault(d, "/foo/-", Value("last").Move()));
1149     EXPECT_STREQ("last", d["foo"][3].GetString());
1150
1151     EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/null", Value().Move()).IsNull());
1152     EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/null", "x").IsNull());
1153
1154     // Generic version
1155     EXPECT_EQ(-1, GetValueByPointerWithDefault(d, "/foo/int", -1).GetInt());
1156     EXPECT_EQ(-1, GetValueByPointerWithDefault(d, "/foo/int", -2).GetInt());
1157     EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d, "/foo/uint", 0x87654321).GetUint());
1158     EXPECT_EQ(0x87654321, GetValueByPointerWithDefault(d, "/foo/uint", 0x12345678).GetUint());
1159
1160     const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
1161     EXPECT_EQ(i64, GetValueByPointerWithDefault(d, "/foo/int64", i64).GetInt64());
1162     EXPECT_EQ(i64, GetValueByPointerWithDefault(d, "/foo/int64", i64 + 1).GetInt64());
1163
1164     const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
1165     EXPECT_EQ(u64, GetValueByPointerWithDefault(d, "/foo/uint64", u64).GetUint64());
1166     EXPECT_EQ(u64, GetValueByPointerWithDefault(d, "/foo/uint64", u64 - 1).GetUint64());
1167
1168     EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/true", true).IsTrue());
1169     EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/true", false).IsTrue());
1170
1171     EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/false", false).IsFalse());
1172     EXPECT_TRUE(GetValueByPointerWithDefault(d, "/foo/false", true).IsFalse());
1173
1174     // StringRef version
1175     EXPECT_STREQ("Hello", GetValueByPointerWithDefault(d, "/foo/hello", "Hello").GetString());
1176
1177     // Copy string version
1178     {
1179         char buffer[256];
1180         strcpy(buffer, "World");
1181         EXPECT_STREQ("World", GetValueByPointerWithDefault(d, "/foo/world", buffer).GetString());
1182         memset(buffer, 0, sizeof(buffer));
1183     }
1184     EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
1185
1186 #if RAPIDJSON_HAS_STDSTRING
1187     EXPECT_STREQ("C++", GetValueByPointerWithDefault(d, Pointer("/foo/C++"), std::string("C++")).GetString());
1188 #endif
1189 }
1190
1191 TEST(Pointer, SetValueByPointer_Pointer) {
1192     Document d;
1193     d.Parse(kJson);
1194     Document::AllocatorType& a = d.GetAllocator();
1195
1196     // Value version
1197     SetValueByPointer(d, Pointer("/foo/0"), Value(123).Move(), a);
1198     EXPECT_EQ(123, d["foo"][0].GetInt());
1199
1200     SetValueByPointer(d, Pointer("/foo/null"), Value().Move(), a);
1201     EXPECT_TRUE(GetValueByPointer(d, "/foo/null")->IsNull());
1202
1203     // Const Value version
1204     const Value foo(d["foo"], d.GetAllocator());
1205     SetValueByPointer(d, Pointer("/clone"), foo, a);
1206     EXPECT_EQ(foo, *GetValueByPointer(d, "/clone"));
1207
1208     // Generic version
1209     SetValueByPointer(d, Pointer("/foo/int"), -1, a);
1210     EXPECT_EQ(-1, GetValueByPointer(d, "/foo/int")->GetInt());
1211
1212     SetValueByPointer(d, Pointer("/foo/uint"), 0x87654321, a);
1213     EXPECT_EQ(0x87654321, GetValueByPointer(d, "/foo/uint")->GetUint());
1214
1215     const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
1216     SetValueByPointer(d, Pointer("/foo/int64"), i64, a);
1217     EXPECT_EQ(i64, GetValueByPointer(d, "/foo/int64")->GetInt64());
1218
1219     const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
1220     SetValueByPointer(d, Pointer("/foo/uint64"), u64, a);
1221     EXPECT_EQ(u64, GetValueByPointer(d, "/foo/uint64")->GetUint64());
1222
1223     SetValueByPointer(d, Pointer("/foo/true"), true, a);
1224     EXPECT_TRUE(GetValueByPointer(d, "/foo/true")->IsTrue());
1225
1226     SetValueByPointer(d, Pointer("/foo/false"), false, a);
1227     EXPECT_TRUE(GetValueByPointer(d, "/foo/false")->IsFalse());
1228
1229     // StringRef version
1230     SetValueByPointer(d, Pointer("/foo/hello"), "Hello", a);
1231     EXPECT_STREQ("Hello", GetValueByPointer(d, "/foo/hello")->GetString());
1232
1233     // Copy string version
1234     {
1235         char buffer[256];
1236         strcpy(buffer, "World");
1237         SetValueByPointer(d, Pointer("/foo/world"), buffer, a);
1238         memset(buffer, 0, sizeof(buffer));
1239     }
1240     EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
1241
1242 #if RAPIDJSON_HAS_STDSTRING
1243     SetValueByPointer(d, Pointer("/foo/c++"), std::string("C++"), a);
1244     EXPECT_STREQ("C++", GetValueByPointer(d, "/foo/c++")->GetString());
1245 #endif
1246 }
1247
1248 TEST(Pointer, SetValueByPointer_String) {
1249     Document d;
1250     d.Parse(kJson);
1251     Document::AllocatorType& a = d.GetAllocator();
1252
1253     // Value version
1254     SetValueByPointer(d, "/foo/0", Value(123).Move(), a);
1255     EXPECT_EQ(123, d["foo"][0].GetInt());
1256
1257     SetValueByPointer(d, "/foo/null", Value().Move(), a);
1258     EXPECT_TRUE(GetValueByPointer(d, "/foo/null")->IsNull());
1259
1260     // Const Value version
1261     const Value foo(d["foo"], d.GetAllocator());
1262     SetValueByPointer(d, "/clone", foo, a);
1263     EXPECT_EQ(foo, *GetValueByPointer(d, "/clone"));
1264
1265     // Generic version
1266     SetValueByPointer(d, "/foo/int", -1, a);
1267     EXPECT_EQ(-1, GetValueByPointer(d, "/foo/int")->GetInt());
1268
1269     SetValueByPointer(d, "/foo/uint", 0x87654321, a);
1270     EXPECT_EQ(0x87654321, GetValueByPointer(d, "/foo/uint")->GetUint());
1271
1272     const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
1273     SetValueByPointer(d, "/foo/int64", i64, a);
1274     EXPECT_EQ(i64, GetValueByPointer(d, "/foo/int64")->GetInt64());
1275
1276     const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
1277     SetValueByPointer(d, "/foo/uint64", u64, a);
1278     EXPECT_EQ(u64, GetValueByPointer(d, "/foo/uint64")->GetUint64());
1279
1280     SetValueByPointer(d, "/foo/true", true, a);
1281     EXPECT_TRUE(GetValueByPointer(d, "/foo/true")->IsTrue());
1282
1283     SetValueByPointer(d, "/foo/false", false, a);
1284     EXPECT_TRUE(GetValueByPointer(d, "/foo/false")->IsFalse());
1285
1286     // StringRef version
1287     SetValueByPointer(d, "/foo/hello", "Hello", a);
1288     EXPECT_STREQ("Hello", GetValueByPointer(d, "/foo/hello")->GetString());
1289
1290     // Copy string version
1291     {
1292         char buffer[256];
1293         strcpy(buffer, "World");
1294         SetValueByPointer(d, "/foo/world", buffer, a);
1295         memset(buffer, 0, sizeof(buffer));
1296     }
1297     EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
1298
1299 #if RAPIDJSON_HAS_STDSTRING
1300     SetValueByPointer(d, "/foo/c++", std::string("C++"), a);
1301     EXPECT_STREQ("C++", GetValueByPointer(d, "/foo/c++")->GetString());
1302 #endif
1303 }
1304
1305 TEST(Pointer, SetValueByPointer_Pointer_NoAllocator) {
1306     Document d;
1307     d.Parse(kJson);
1308
1309     // Value version
1310     SetValueByPointer(d, Pointer("/foo/0"), Value(123).Move());
1311     EXPECT_EQ(123, d["foo"][0].GetInt());
1312
1313     SetValueByPointer(d, Pointer("/foo/null"), Value().Move());
1314     EXPECT_TRUE(GetValueByPointer(d, "/foo/null")->IsNull());
1315
1316     // Const Value version
1317     const Value foo(d["foo"], d.GetAllocator());
1318     SetValueByPointer(d, Pointer("/clone"), foo);
1319     EXPECT_EQ(foo, *GetValueByPointer(d, "/clone"));
1320
1321     // Generic version
1322     SetValueByPointer(d, Pointer("/foo/int"), -1);
1323     EXPECT_EQ(-1, GetValueByPointer(d, "/foo/int")->GetInt());
1324
1325     SetValueByPointer(d, Pointer("/foo/uint"), 0x87654321);
1326     EXPECT_EQ(0x87654321, GetValueByPointer(d, "/foo/uint")->GetUint());
1327
1328     const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
1329     SetValueByPointer(d, Pointer("/foo/int64"), i64);
1330     EXPECT_EQ(i64, GetValueByPointer(d, "/foo/int64")->GetInt64());
1331
1332     const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
1333     SetValueByPointer(d, Pointer("/foo/uint64"), u64);
1334     EXPECT_EQ(u64, GetValueByPointer(d, "/foo/uint64")->GetUint64());
1335
1336     SetValueByPointer(d, Pointer("/foo/true"), true);
1337     EXPECT_TRUE(GetValueByPointer(d, "/foo/true")->IsTrue());
1338
1339     SetValueByPointer(d, Pointer("/foo/false"), false);
1340     EXPECT_TRUE(GetValueByPointer(d, "/foo/false")->IsFalse());
1341
1342     // StringRef version
1343     SetValueByPointer(d, Pointer("/foo/hello"), "Hello");
1344     EXPECT_STREQ("Hello", GetValueByPointer(d, "/foo/hello")->GetString());
1345
1346     // Copy string version
1347     {
1348         char buffer[256];
1349         strcpy(buffer, "World");
1350         SetValueByPointer(d, Pointer("/foo/world"), buffer);
1351         memset(buffer, 0, sizeof(buffer));
1352     }
1353     EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
1354
1355 #if RAPIDJSON_HAS_STDSTRING
1356     SetValueByPointer(d, Pointer("/foo/c++"), std::string("C++"));
1357     EXPECT_STREQ("C++", GetValueByPointer(d, "/foo/c++")->GetString());
1358 #endif
1359 }
1360
1361 TEST(Pointer, SetValueByPointer_String_NoAllocator) {
1362     Document d;
1363     d.Parse(kJson);
1364
1365     // Value version
1366     SetValueByPointer(d, "/foo/0", Value(123).Move());
1367     EXPECT_EQ(123, d["foo"][0].GetInt());
1368
1369     SetValueByPointer(d, "/foo/null", Value().Move());
1370     EXPECT_TRUE(GetValueByPointer(d, "/foo/null")->IsNull());
1371
1372     // Const Value version
1373     const Value foo(d["foo"], d.GetAllocator());
1374     SetValueByPointer(d, "/clone", foo);
1375     EXPECT_EQ(foo, *GetValueByPointer(d, "/clone"));
1376
1377     // Generic version
1378     SetValueByPointer(d, "/foo/int", -1);
1379     EXPECT_EQ(-1, GetValueByPointer(d, "/foo/int")->GetInt());
1380
1381     SetValueByPointer(d, "/foo/uint", 0x87654321);
1382     EXPECT_EQ(0x87654321, GetValueByPointer(d, "/foo/uint")->GetUint());
1383
1384     const int64_t i64 = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0));
1385     SetValueByPointer(d, "/foo/int64", i64);
1386     EXPECT_EQ(i64, GetValueByPointer(d, "/foo/int64")->GetInt64());
1387
1388     const uint64_t u64 = RAPIDJSON_UINT64_C2(0xFFFFFFFFF, 0xFFFFFFFFF);
1389     SetValueByPointer(d, "/foo/uint64", u64);
1390     EXPECT_EQ(u64, GetValueByPointer(d, "/foo/uint64")->GetUint64());
1391
1392     SetValueByPointer(d, "/foo/true", true);
1393     EXPECT_TRUE(GetValueByPointer(d, "/foo/true")->IsTrue());
1394
1395     SetValueByPointer(d, "/foo/false", false);
1396     EXPECT_TRUE(GetValueByPointer(d, "/foo/false")->IsFalse());
1397
1398     // StringRef version
1399     SetValueByPointer(d, "/foo/hello", "Hello");
1400     EXPECT_STREQ("Hello", GetValueByPointer(d, "/foo/hello")->GetString());
1401
1402     // Copy string version
1403     {
1404         char buffer[256];
1405         strcpy(buffer, "World");
1406         SetValueByPointer(d, "/foo/world", buffer);
1407         memset(buffer, 0, sizeof(buffer));
1408     }
1409     EXPECT_STREQ("World", GetValueByPointer(d, "/foo/world")->GetString());
1410
1411 #if RAPIDJSON_HAS_STDSTRING
1412     SetValueByPointer(d, "/foo/c++", std::string("C++"));
1413     EXPECT_STREQ("C++", GetValueByPointer(d, "/foo/c++")->GetString());
1414 #endif
1415 }
1416
1417 TEST(Pointer, SwapValueByPointer) {
1418     Document d;
1419     d.Parse(kJson);
1420     Document::AllocatorType& a = d.GetAllocator();
1421     SwapValueByPointer(d, Pointer("/foo/0"), *GetValueByPointer(d, "/foo/1"), a);
1422     EXPECT_STREQ("baz", d["foo"][0].GetString());
1423     EXPECT_STREQ("bar", d["foo"][1].GetString());
1424
1425     SwapValueByPointer(d, "/foo/0", *GetValueByPointer(d, "/foo/1"), a);
1426     EXPECT_STREQ("bar", d["foo"][0].GetString());
1427     EXPECT_STREQ("baz", d["foo"][1].GetString());
1428 }
1429
1430 TEST(Pointer, SwapValueByPointer_NoAllocator) {
1431     Document d;
1432     d.Parse(kJson);
1433     SwapValueByPointer(d, Pointer("/foo/0"), *GetValueByPointer(d, "/foo/1"));
1434     EXPECT_STREQ("baz", d["foo"][0].GetString());
1435     EXPECT_STREQ("bar", d["foo"][1].GetString());
1436
1437     SwapValueByPointer(d, "/foo/0", *GetValueByPointer(d, "/foo/1"));
1438     EXPECT_STREQ("bar", d["foo"][0].GetString());
1439     EXPECT_STREQ("baz", d["foo"][1].GetString());
1440 }
1441
1442 TEST(Pointer, EraseValueByPointer_Pointer) {
1443     Document d;
1444     d.Parse(kJson);
1445
1446     EXPECT_FALSE(EraseValueByPointer(d, Pointer("")));
1447     EXPECT_FALSE(Pointer("/foo/nonexist").Erase(d));
1448     EXPECT_TRUE(EraseValueByPointer(d, Pointer("/foo/0")));
1449     EXPECT_EQ(1u, d["foo"].Size());
1450     EXPECT_STREQ("baz", d["foo"][0].GetString());
1451     EXPECT_TRUE(EraseValueByPointer(d, Pointer("/foo/0")));
1452     EXPECT_TRUE(d["foo"].Empty());
1453     EXPECT_TRUE(EraseValueByPointer(d, Pointer("/foo")));
1454     EXPECT_TRUE(Pointer("/foo").Get(d) == 0);
1455 }
1456
1457 TEST(Pointer, EraseValueByPointer_String) {
1458     Document d;
1459     d.Parse(kJson);
1460
1461     EXPECT_FALSE(EraseValueByPointer(d, ""));
1462     EXPECT_FALSE(Pointer("/foo/nonexist").Erase(d));
1463     EXPECT_TRUE(EraseValueByPointer(d, "/foo/0"));
1464     EXPECT_EQ(1u, d["foo"].Size());
1465     EXPECT_STREQ("baz", d["foo"][0].GetString());
1466     EXPECT_TRUE(EraseValueByPointer(d, "/foo/0"));
1467     EXPECT_TRUE(d["foo"].Empty());
1468     EXPECT_TRUE(EraseValueByPointer(d, "/foo"));
1469     EXPECT_TRUE(Pointer("/foo").Get(d) == 0);
1470 }
1471
1472 TEST(Pointer, Ambiguity) {
1473     {
1474         Document d;
1475         d.Parse("{\"0\" : [123]}");
1476         EXPECT_EQ(123, Pointer("/0/0").Get(d)->GetInt());
1477         Pointer("/0/a").Set(d, 456);    // Change array [123] to object {456}
1478         EXPECT_EQ(456, Pointer("/0/a").Get(d)->GetInt());
1479     }
1480
1481     {
1482         Document d;
1483         EXPECT_FALSE(d.Parse("[{\"0\": 123}]").HasParseError());
1484         EXPECT_EQ(123, Pointer("/0/0").Get(d)->GetInt());
1485         Pointer("/0/1").Set(d, 456); // 1 is treated as "1" to index object
1486         EXPECT_EQ(123, Pointer("/0/0").Get(d)->GetInt());
1487         EXPECT_EQ(456, Pointer("/0/1").Get(d)->GetInt());
1488     }
1489 }
1490
1491 // https://github.com/miloyip/rapidjson/issues/483
1492 namespace myjson {
1493
1494 class MyAllocator
1495 {
1496 public:
1497     static const bool kNeedFree = true;
1498     void * Malloc(size_t _size) { return malloc(_size); }
1499     void * Realloc(void *_org_p, size_t _org_size, size_t _new_size) { (void)_org_size; return realloc(_org_p, _new_size); }
1500     static void Free(void *_p) { return free(_p); }
1501 };
1502
1503 typedef rapidjson::GenericDocument<
1504             rapidjson::UTF8<>,
1505             rapidjson::MemoryPoolAllocator< MyAllocator >,
1506             MyAllocator
1507         > Document;
1508
1509 typedef rapidjson::GenericPointer<
1510             ::myjson::Document::ValueType,
1511             MyAllocator
1512         > Pointer;
1513
1514 typedef ::myjson::Document::ValueType Value;
1515
1516 }
1517
1518 TEST(Pointer, Issue483) {
1519     std::string mystr, path;
1520     myjson::Document document;
1521     myjson::Value value(rapidjson::kStringType);
1522     value.SetString(mystr.c_str(), static_cast<SizeType>(mystr.length()), document.GetAllocator());
1523     myjson::Pointer(path.c_str()).Set(document, value, document.GetAllocator());
1524 }