Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
valuetest.cpp
Go to the documentation of this file.
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/document.h"
17#include <algorithm>
18
19#ifdef __clang__
20RAPIDJSON_DIAG_PUSH
21RAPIDJSON_DIAG_OFF(c++98-compat)
22#endif
23
24using namespace rapidjson;
25
26TEST(Value, Size) {
27 if (sizeof(SizeType) == 4) {
28#if RAPIDJSON_48BITPOINTER_OPTIMIZATION
29 EXPECT_EQ(16u, sizeof(Value));
30#elif RAPIDJSON_64BIT
31 EXPECT_EQ(24u, sizeof(Value));
32#else
33 EXPECT_EQ(16u, sizeof(Value));
34#endif
35 }
36}
37
38TEST(Value, DefaultConstructor) {
39 Value x;
40 EXPECT_EQ(kNullType, x.GetType());
41 EXPECT_TRUE(x.IsNull());
42
43 //std::cout << "sizeof(Value): " << sizeof(x) << std::endl;
44}
45
46// Should not pass compilation
47//TEST(Value, copy_constructor) {
48// Value x(1234);
49// Value y = x;
50//}
51
52#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
53
54#if 0 // Many old compiler does not support these. Turn it off temporaily.
55
56#include <type_traits>
57
60 static_assert(std::is_constructible<Value>::value, "");
61 static_assert(std::is_default_constructible<Value>::value, "");
62#ifndef _MSC_VER
63 static_assert(!std::is_copy_constructible<Value>::value, "");
64#endif
65 static_assert(std::is_move_constructible<Value>::value, "");
66
67#ifndef _MSC_VER
68 static_assert(std::is_nothrow_constructible<Value>::value, "");
69 static_assert(std::is_nothrow_default_constructible<Value>::value, "");
70 static_assert(!std::is_nothrow_copy_constructible<Value>::value, "");
71 static_assert(std::is_nothrow_move_constructible<Value>::value, "");
72#endif
73
74 static_assert(std::is_assignable<Value,Value>::value, "");
75#ifndef _MSC_VER
76 static_assert(!std::is_copy_assignable<Value>::value, "");
77#endif
78 static_assert(std::is_move_assignable<Value>::value, "");
79
80#ifndef _MSC_VER
81 static_assert(std::is_nothrow_assignable<Value, Value>::value, "");
82#endif
83 static_assert(!std::is_nothrow_copy_assignable<Value>::value, "");
84#ifndef _MSC_VER
85 static_assert(std::is_nothrow_move_assignable<Value>::value, "");
86#endif
87
88 static_assert(std::is_destructible<Value>::value, "");
89#ifndef _MSC_VER
90 static_assert(std::is_nothrow_destructible<Value>::value, "");
91#endif
92}
93
94#endif
95
96TEST(Value, MoveConstructor) {
98 V::AllocatorType allocator;
99
100 V x((V(kArrayType)));
101 x.Reserve(4u, allocator);
102 x.PushBack(1, allocator).PushBack(2, allocator).PushBack(3, allocator).PushBack(4, allocator);
103 EXPECT_TRUE(x.IsArray());
104 EXPECT_EQ(4u, x.Size());
105
106 // Value y(x); // does not compile (!is_copy_constructible)
107 V y(std::move(x));
108 EXPECT_TRUE(x.IsNull());
109 EXPECT_TRUE(y.IsArray());
110 EXPECT_EQ(4u, y.Size());
111
112 // Value z = y; // does not compile (!is_copy_assignable)
113 V z = std::move(y);
114 EXPECT_TRUE(y.IsNull());
115 EXPECT_TRUE(z.IsArray());
116 EXPECT_EQ(4u, z.Size());
117}
118
119#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
120
121TEST(Value, AssignmentOperator) {
122 Value x(1234);
123 Value y;
124 y = x;
125 EXPECT_TRUE(x.IsNull()); // move semantic
126 EXPECT_EQ(1234, y.GetInt());
127
128 y = 5678;
129 EXPECT_TRUE(y.IsInt());
130 EXPECT_EQ(5678, y.GetInt());
131
132 x = "Hello";
133 EXPECT_TRUE(x.IsString());
134 EXPECT_STREQ(x.GetString(),"Hello");
135
136 y = StringRef(x.GetString(),x.GetStringLength());
137 EXPECT_TRUE(y.IsString());
138 EXPECT_EQ(y.GetString(),x.GetString());
139 EXPECT_EQ(y.GetStringLength(),x.GetStringLength());
140
141 static char mstr[] = "mutable";
142 // y = mstr; // should not compile
143 y = StringRef(mstr);
144 EXPECT_TRUE(y.IsString());
145 EXPECT_EQ(y.GetString(),mstr);
146
147#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
148 // C++11 move assignment
149 x = Value("World");
150 EXPECT_TRUE(x.IsString());
151 EXPECT_STREQ("World", x.GetString());
152
153 x = std::move(y);
154 EXPECT_TRUE(y.IsNull());
155 EXPECT_TRUE(x.IsString());
156 EXPECT_EQ(x.GetString(), mstr);
157
158 y = std::move(Value().SetInt(1234));
159 EXPECT_TRUE(y.IsInt());
160 EXPECT_EQ(1234, y);
161#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
162}
163
164template <typename A, typename B>
165void TestEqual(const A& a, const B& b) {
166 EXPECT_TRUE (a == b);
167 EXPECT_FALSE(a != b);
168 EXPECT_TRUE (b == a);
169 EXPECT_FALSE(b != a);
170}
171
172template <typename A, typename B>
173void TestUnequal(const A& a, const B& b) {
174 EXPECT_FALSE(a == b);
175 EXPECT_TRUE (a != b);
176 EXPECT_FALSE(b == a);
177 EXPECT_TRUE (b != a);
178}
179
180TEST(Value, EqualtoOperator) {
181 Value::AllocatorType allocator;
183 x.AddMember("hello", "world", allocator)
184 .AddMember("t", Value(true).Move(), allocator)
185 .AddMember("f", Value(false).Move(), allocator)
186 .AddMember("n", Value(kNullType).Move(), allocator)
187 .AddMember("i", 123, allocator)
188 .AddMember("pi", 3.14, allocator)
189 .AddMember("a", Value(kArrayType).Move().PushBack(1, allocator).PushBack(2, allocator).PushBack(3, allocator), allocator);
190
191 // Test templated operator==() and operator!=()
192 TestEqual(x["hello"], "world");
193 const char* cc = "world";
194 TestEqual(x["hello"], cc);
195 char* c = strdup("world");
196 TestEqual(x["hello"], c);
197 free(c);
198
199 TestEqual(x["t"], true);
200 TestEqual(x["f"], false);
201 TestEqual(x["i"], 123);
202 TestEqual(x["pi"], 3.14);
203
204 // Test operator==() (including different allocators)
205 CrtAllocator crtAllocator;
207 GenericDocument<UTF8<>, CrtAllocator> z(&crtAllocator);
208 y.CopyFrom(x, crtAllocator);
209 z.CopyFrom(y, z.GetAllocator());
210 TestEqual(x, y);
211 TestEqual(y, z);
212 TestEqual(z, x);
213
214 // Swapping member order should be fine.
215 EXPECT_TRUE(y.RemoveMember("t"));
216 TestUnequal(x, y);
217 TestUnequal(z, y);
218 EXPECT_TRUE(z.RemoveMember("t"));
219 TestUnequal(x, z);
220 TestEqual(y, z);
221 y.AddMember("t", false, crtAllocator);
222 z.AddMember("t", false, z.GetAllocator());
223 TestUnequal(x, y);
224 TestUnequal(z, x);
225 y["t"] = true;
226 z["t"] = true;
227 TestEqual(x, y);
228 TestEqual(y, z);
229 TestEqual(z, x);
230
231 // Swapping element order is not OK
232 x["a"][0].Swap(x["a"][1]);
233 TestUnequal(x, y);
234 x["a"][0].Swap(x["a"][1]);
235 TestEqual(x, y);
236
237 // Array of different size
238 x["a"].PushBack(4, allocator);
239 TestUnequal(x, y);
240 x["a"].PopBack();
241 TestEqual(x, y);
242
243 // Issue #129: compare Uint64
244 x.SetUint64(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0xFFFFFFF0));
245 y.SetUint64(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0xFFFFFFFF));
246 TestUnequal(x, y);
247}
248
249template <typename Value>
251 typename Value::AllocatorType a;
252 Value v1(1234);
253 Value v2(v1, a); // deep copy constructor
254 EXPECT_TRUE(v1.GetType() == v2.GetType());
255 EXPECT_EQ(v1.GetInt(), v2.GetInt());
256
257 v1.SetString("foo");
258 v2.CopyFrom(v1, a);
259 EXPECT_TRUE(v1.GetType() == v2.GetType());
260 EXPECT_STREQ(v1.GetString(), v2.GetString());
261 EXPECT_EQ(v1.GetString(), v2.GetString()); // string NOT copied
262
263 v1.SetString("bar", a); // copy string
264 v2.CopyFrom(v1, a);
265 EXPECT_TRUE(v1.GetType() == v2.GetType());
266 EXPECT_STREQ(v1.GetString(), v2.GetString());
267 EXPECT_NE(v1.GetString(), v2.GetString()); // string copied
268
269
270 v1.SetArray().PushBack(1234, a);
271 v2.CopyFrom(v1, a);
272 EXPECT_TRUE(v2.IsArray());
273 EXPECT_EQ(v1.Size(), v2.Size());
274
275 v1.PushBack(Value().SetString("foo", a), a); // push string copy
276 EXPECT_TRUE(v1.Size() != v2.Size());
277 v2.CopyFrom(v1, a);
278 EXPECT_TRUE(v1.Size() == v2.Size());
279 EXPECT_STREQ(v1[1].GetString(), v2[1].GetString());
280 EXPECT_NE(v1[1].GetString(), v2[1].GetString()); // string got copied
281}
282
287
288TEST(Value, Swap) {
289 Value v1(1234);
290 Value v2(kObjectType);
291
292 EXPECT_EQ(&v1, &v1.Swap(v2));
293 EXPECT_TRUE(v1.IsObject());
294 EXPECT_TRUE(v2.IsInt());
295 EXPECT_EQ(1234, v2.GetInt());
296
297 // testing std::swap compatibility
298 using std::swap;
299 swap(v1, v2);
300 EXPECT_TRUE(v1.IsInt());
301 EXPECT_TRUE(v2.IsObject());
302}
303
304TEST(Value, Null) {
305 // Default constructor
306 Value x;
307 EXPECT_EQ(kNullType, x.GetType());
308 EXPECT_TRUE(x.IsNull());
309
310 EXPECT_FALSE(x.IsTrue());
311 EXPECT_FALSE(x.IsFalse());
312 EXPECT_FALSE(x.IsNumber());
313 EXPECT_FALSE(x.IsString());
314 EXPECT_FALSE(x.IsObject());
315 EXPECT_FALSE(x.IsArray());
316
317 // Constructor with type
318 Value y(kNullType);
319 EXPECT_TRUE(y.IsNull());
320
321 // SetNull();
322 Value z(true);
323 z.SetNull();
324 EXPECT_TRUE(z.IsNull());
325}
326
327TEST(Value, True) {
328 // Constructor with bool
329 Value x(true);
330 EXPECT_EQ(kTrueType, x.GetType());
331 EXPECT_TRUE(x.GetBool());
332 EXPECT_TRUE(x.IsBool());
333 EXPECT_TRUE(x.IsTrue());
334
335 EXPECT_FALSE(x.IsNull());
336 EXPECT_FALSE(x.IsFalse());
337 EXPECT_FALSE(x.IsNumber());
338 EXPECT_FALSE(x.IsString());
339 EXPECT_FALSE(x.IsObject());
340 EXPECT_FALSE(x.IsArray());
341
342 // Constructor with type
343 Value y(kTrueType);
344 EXPECT_TRUE(y.IsTrue());
345
346 // SetBool()
347 Value z;
348 z.SetBool(true);
349 EXPECT_TRUE(z.IsTrue());
350
351 // Templated functions
352 EXPECT_TRUE(z.Is<bool>());
353 EXPECT_TRUE(z.Get<bool>());
354 EXPECT_FALSE(z.Set<bool>(false).Get<bool>());
355 EXPECT_TRUE(z.Set(true).Get<bool>());
356}
357
358TEST(Value, False) {
359 // Constructor with bool
360 Value x(false);
361 EXPECT_EQ(kFalseType, x.GetType());
362 EXPECT_TRUE(x.IsBool());
363 EXPECT_TRUE(x.IsFalse());
364
365 EXPECT_FALSE(x.IsNull());
366 EXPECT_FALSE(x.IsTrue());
367 EXPECT_FALSE(x.GetBool());
368 //EXPECT_FALSE((bool)x);
369 EXPECT_FALSE(x.IsNumber());
370 EXPECT_FALSE(x.IsString());
371 EXPECT_FALSE(x.IsObject());
372 EXPECT_FALSE(x.IsArray());
373
374 // Constructor with type
375 Value y(kFalseType);
376 EXPECT_TRUE(y.IsFalse());
377
378 // SetBool()
379 Value z;
380 z.SetBool(false);
381 EXPECT_TRUE(z.IsFalse());
382}
383
384TEST(Value, Int) {
385 // Constructor with int
386 Value x(1234);
387 EXPECT_EQ(kNumberType, x.GetType());
388 EXPECT_EQ(1234, x.GetInt());
389 EXPECT_EQ(1234u, x.GetUint());
390 EXPECT_EQ(1234, x.GetInt64());
391 EXPECT_EQ(1234u, x.GetUint64());
392 EXPECT_NEAR(1234.0, x.GetDouble(), 0.0);
393 //EXPECT_EQ(1234, (int)x);
394 //EXPECT_EQ(1234, (unsigned)x);
395 //EXPECT_EQ(1234, (int64_t)x);
396 //EXPECT_EQ(1234, (uint64_t)x);
397 //EXPECT_EQ(1234, (double)x);
398 EXPECT_TRUE(x.IsNumber());
399 EXPECT_TRUE(x.IsInt());
400 EXPECT_TRUE(x.IsUint());
401 EXPECT_TRUE(x.IsInt64());
402 EXPECT_TRUE(x.IsUint64());
403
404 EXPECT_FALSE(x.IsDouble());
405 EXPECT_FALSE(x.IsFloat());
406 EXPECT_FALSE(x.IsNull());
407 EXPECT_FALSE(x.IsBool());
408 EXPECT_FALSE(x.IsFalse());
409 EXPECT_FALSE(x.IsTrue());
410 EXPECT_FALSE(x.IsString());
411 EXPECT_FALSE(x.IsObject());
412 EXPECT_FALSE(x.IsArray());
413
414 Value nx(-1234);
415 EXPECT_EQ(-1234, nx.GetInt());
416 EXPECT_EQ(-1234, nx.GetInt64());
417 EXPECT_TRUE(nx.IsInt());
418 EXPECT_TRUE(nx.IsInt64());
419 EXPECT_FALSE(nx.IsUint());
420 EXPECT_FALSE(nx.IsUint64());
421
422 // Constructor with type
424 EXPECT_TRUE(y.IsNumber());
425 EXPECT_TRUE(y.IsInt());
426 EXPECT_EQ(0, y.GetInt());
427
428 // SetInt()
429 Value z;
430 z.SetInt(1234);
431 EXPECT_EQ(1234, z.GetInt());
432
433 // operator=(int)
434 z = 5678;
435 EXPECT_EQ(5678, z.GetInt());
436
437 // Templated functions
438 EXPECT_TRUE(z.Is<int>());
439 EXPECT_EQ(5678, z.Get<int>());
440 EXPECT_EQ(5679, z.Set(5679).Get<int>());
441 EXPECT_EQ(5680, z.Set<int>(5680).Get<int>());
442
443#ifdef _MSC_VER
444 // long as int on MSC platforms
445 RAPIDJSON_STATIC_ASSERT(sizeof(long) == sizeof(int));
446 z.SetInt(2222);
447 EXPECT_TRUE(z.Is<long>());
448 EXPECT_EQ(2222l, z.Get<long>());
449 EXPECT_EQ(3333l, z.Set(3333l).Get<long>());
450 EXPECT_EQ(4444l, z.Set<long>(4444l).Get<long>());
451 EXPECT_TRUE(z.IsInt());
452#endif
453}
454
455TEST(Value, Uint) {
456 // Constructor with int
457 Value x(1234u);
458 EXPECT_EQ(kNumberType, x.GetType());
459 EXPECT_EQ(1234, x.GetInt());
460 EXPECT_EQ(1234u, x.GetUint());
461 EXPECT_EQ(1234, x.GetInt64());
462 EXPECT_EQ(1234u, x.GetUint64());
463 EXPECT_TRUE(x.IsNumber());
464 EXPECT_TRUE(x.IsInt());
465 EXPECT_TRUE(x.IsUint());
466 EXPECT_TRUE(x.IsInt64());
467 EXPECT_TRUE(x.IsUint64());
468 EXPECT_NEAR(1234.0, x.GetDouble(), 0.0); // Number can always be cast as double but !IsDouble().
469
470 EXPECT_FALSE(x.IsDouble());
471 EXPECT_FALSE(x.IsFloat());
472 EXPECT_FALSE(x.IsNull());
473 EXPECT_FALSE(x.IsBool());
474 EXPECT_FALSE(x.IsFalse());
475 EXPECT_FALSE(x.IsTrue());
476 EXPECT_FALSE(x.IsString());
477 EXPECT_FALSE(x.IsObject());
478 EXPECT_FALSE(x.IsArray());
479
480 // SetUint()
481 Value z;
482 z.SetUint(1234);
483 EXPECT_EQ(1234u, z.GetUint());
484
485 // operator=(unsigned)
486 z = 5678u;
487 EXPECT_EQ(5678u, z.GetUint());
488
489 z = 2147483648u; // 2^31, cannot cast as int
490 EXPECT_EQ(2147483648u, z.GetUint());
491 EXPECT_FALSE(z.IsInt());
492 EXPECT_TRUE(z.IsInt64()); // Issue 41: Incorrect parsing of unsigned int number types
493
494 // Templated functions
495 EXPECT_TRUE(z.Is<unsigned>());
496 EXPECT_EQ(2147483648u, z.Get<unsigned>());
497 EXPECT_EQ(2147483649u, z.Set(2147483649u).Get<unsigned>());
498 EXPECT_EQ(2147483650u, z.Set<unsigned>(2147483650u).Get<unsigned>());
499
500#ifdef _MSC_VER
501 // unsigned long as unsigned on MSC platforms
502 RAPIDJSON_STATIC_ASSERT(sizeof(unsigned long) == sizeof(unsigned));
503 z.SetUint(2222);
504 EXPECT_TRUE(z.Is<unsigned long>());
505 EXPECT_EQ(2222ul, z.Get<unsigned long>());
506 EXPECT_EQ(3333ul, z.Set(3333ul).Get<unsigned long>());
507 EXPECT_EQ(4444ul, z.Set<unsigned long>(4444ul).Get<unsigned long>());
508 EXPECT_TRUE(x.IsUint());
509#endif
510}
511
512TEST(Value, Int64) {
513 // Constructor with int
514 Value x(int64_t(1234));
515 EXPECT_EQ(kNumberType, x.GetType());
516 EXPECT_EQ(1234, x.GetInt());
517 EXPECT_EQ(1234u, x.GetUint());
518 EXPECT_EQ(1234, x.GetInt64());
519 EXPECT_EQ(1234u, x.GetUint64());
520 EXPECT_TRUE(x.IsNumber());
521 EXPECT_TRUE(x.IsInt());
522 EXPECT_TRUE(x.IsUint());
523 EXPECT_TRUE(x.IsInt64());
524 EXPECT_TRUE(x.IsUint64());
525
526 EXPECT_FALSE(x.IsDouble());
527 EXPECT_FALSE(x.IsFloat());
528 EXPECT_FALSE(x.IsNull());
529 EXPECT_FALSE(x.IsBool());
530 EXPECT_FALSE(x.IsFalse());
531 EXPECT_FALSE(x.IsTrue());
532 EXPECT_FALSE(x.IsString());
533 EXPECT_FALSE(x.IsObject());
534 EXPECT_FALSE(x.IsArray());
535
536 Value nx(int64_t(-1234));
537 EXPECT_EQ(-1234, nx.GetInt());
538 EXPECT_EQ(-1234, nx.GetInt64());
539 EXPECT_TRUE(nx.IsInt());
540 EXPECT_TRUE(nx.IsInt64());
541 EXPECT_FALSE(nx.IsUint());
542 EXPECT_FALSE(nx.IsUint64());
543
544 // SetInt64()
545 Value z;
546 z.SetInt64(1234);
547 EXPECT_EQ(1234, z.GetInt64());
548
549 z.SetInt64(2147483648u); // 2^31, cannot cast as int
550 EXPECT_FALSE(z.IsInt());
551 EXPECT_TRUE(z.IsUint());
552 EXPECT_NEAR(2147483648.0, z.GetDouble(), 0.0);
553
554 z.SetInt64(int64_t(4294967295u) + 1); // 2^32, cannot cast as uint
555 EXPECT_FALSE(z.IsInt());
556 EXPECT_FALSE(z.IsUint());
557 EXPECT_NEAR(4294967296.0, z.GetDouble(), 0.0);
558
559 z.SetInt64(-int64_t(2147483648u) - 1); // -2^31-1, cannot cast as int
560 EXPECT_FALSE(z.IsInt());
561 EXPECT_NEAR(-2147483649.0, z.GetDouble(), 0.0);
562
563 int64_t i = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 00000000));
564 z.SetInt64(i);
565 EXPECT_DOUBLE_EQ(-9223372036854775808.0, z.GetDouble());
566
567 // Templated functions
568 EXPECT_TRUE(z.Is<int64_t>());
569 EXPECT_EQ(i, z.Get<int64_t>());
570#if 0 // signed integer underflow is undefined behaviour
571 EXPECT_EQ(i - 1, z.Set(i - 1).Get<int64_t>());
572 EXPECT_EQ(i - 2, z.Set<int64_t>(i - 2).Get<int64_t>());
573#endif
574}
575
576TEST(Value, Uint64) {
577 // Constructor with int
578 Value x(uint64_t(1234));
579 EXPECT_EQ(kNumberType, x.GetType());
580 EXPECT_EQ(1234, x.GetInt());
581 EXPECT_EQ(1234u, x.GetUint());
582 EXPECT_EQ(1234, x.GetInt64());
583 EXPECT_EQ(1234u, x.GetUint64());
584 EXPECT_TRUE(x.IsNumber());
585 EXPECT_TRUE(x.IsInt());
586 EXPECT_TRUE(x.IsUint());
587 EXPECT_TRUE(x.IsInt64());
588 EXPECT_TRUE(x.IsUint64());
589
590 EXPECT_FALSE(x.IsDouble());
591 EXPECT_FALSE(x.IsFloat());
592 EXPECT_FALSE(x.IsNull());
593 EXPECT_FALSE(x.IsBool());
594 EXPECT_FALSE(x.IsFalse());
595 EXPECT_FALSE(x.IsTrue());
596 EXPECT_FALSE(x.IsString());
597 EXPECT_FALSE(x.IsObject());
598 EXPECT_FALSE(x.IsArray());
599
600 // SetUint64()
601 Value z;
602 z.SetUint64(1234);
603 EXPECT_EQ(1234u, z.GetUint64());
604
605 z.SetUint64(uint64_t(2147483648u)); // 2^31, cannot cast as int
606 EXPECT_FALSE(z.IsInt());
607 EXPECT_TRUE(z.IsUint());
608 EXPECT_TRUE(z.IsInt64());
609
610 z.SetUint64(uint64_t(4294967295u) + 1); // 2^32, cannot cast as uint
611 EXPECT_FALSE(z.IsInt());
612 EXPECT_FALSE(z.IsUint());
613 EXPECT_TRUE(z.IsInt64());
614
615 uint64_t u = RAPIDJSON_UINT64_C2(0x80000000, 0x00000000);
616 z.SetUint64(u); // 2^63 cannot cast as int64
617 EXPECT_FALSE(z.IsInt64());
618 EXPECT_EQ(u, z.GetUint64()); // Issue 48
619 EXPECT_DOUBLE_EQ(9223372036854775808.0, z.GetDouble());
620
621 // Templated functions
622 EXPECT_TRUE(z.Is<uint64_t>());
623 EXPECT_EQ(u, z.Get<uint64_t>());
624 EXPECT_EQ(u + 1, z.Set(u + 1).Get<uint64_t>());
625 EXPECT_EQ(u + 2, z.Set<uint64_t>(u + 2).Get<uint64_t>());
626}
627
628TEST(Value, Double) {
629 // Constructor with double
630 Value x(12.34);
631 EXPECT_EQ(kNumberType, x.GetType());
632 EXPECT_NEAR(12.34, x.GetDouble(), 0.0);
633 EXPECT_TRUE(x.IsNumber());
634 EXPECT_TRUE(x.IsDouble());
635
636 EXPECT_FALSE(x.IsInt());
637 EXPECT_FALSE(x.IsNull());
638 EXPECT_FALSE(x.IsBool());
639 EXPECT_FALSE(x.IsFalse());
640 EXPECT_FALSE(x.IsTrue());
641 EXPECT_FALSE(x.IsString());
642 EXPECT_FALSE(x.IsObject());
643 EXPECT_FALSE(x.IsArray());
644
645 // SetDouble()
646 Value z;
647 z.SetDouble(12.34);
648 EXPECT_NEAR(12.34, z.GetDouble(), 0.0);
649
650 z = 56.78;
651 EXPECT_NEAR(56.78, z.GetDouble(), 0.0);
652
653 // Templated functions
654 EXPECT_TRUE(z.Is<double>());
655 EXPECT_EQ(56.78, z.Get<double>());
656 EXPECT_EQ(57.78, z.Set(57.78).Get<double>());
657 EXPECT_EQ(58.78, z.Set<double>(58.78).Get<double>());
658}
659
660TEST(Value, Float) {
661 // Constructor with double
662 Value x(12.34f);
663 EXPECT_EQ(kNumberType, x.GetType());
664 EXPECT_NEAR(12.34f, x.GetFloat(), 0.0);
665 EXPECT_TRUE(x.IsNumber());
666 EXPECT_TRUE(x.IsDouble());
667 EXPECT_TRUE(x.IsFloat());
668
669 EXPECT_FALSE(x.IsInt());
670 EXPECT_FALSE(x.IsNull());
671 EXPECT_FALSE(x.IsBool());
672 EXPECT_FALSE(x.IsFalse());
673 EXPECT_FALSE(x.IsTrue());
674 EXPECT_FALSE(x.IsString());
675 EXPECT_FALSE(x.IsObject());
676 EXPECT_FALSE(x.IsArray());
677
678 // SetFloat()
679 Value z;
680 z.SetFloat(12.34f);
681 EXPECT_NEAR(12.34f, z.GetFloat(), 0.0f);
682
683 // Issue 573
684 z.SetInt(0);
685 EXPECT_EQ(0.0f, z.GetFloat());
686
687 z = 56.78f;
688 EXPECT_NEAR(56.78f, z.GetFloat(), 0.0f);
689
690 // Templated functions
691 EXPECT_TRUE(z.Is<float>());
692 EXPECT_EQ(56.78f, z.Get<float>());
693 EXPECT_EQ(57.78f, z.Set(57.78f).Get<float>());
694 EXPECT_EQ(58.78f, z.Set<float>(58.78f).Get<float>());
695}
696
697TEST(Value, IsLosslessDouble) {
698 EXPECT_TRUE(Value(0.0).IsLosslessDouble());
699 EXPECT_TRUE(Value(12.34).IsLosslessDouble());
700 EXPECT_TRUE(Value(-123).IsLosslessDouble());
701 EXPECT_TRUE(Value(2147483648u).IsLosslessDouble());
702 EXPECT_TRUE(Value(-static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x40000000, 0x00000000))).IsLosslessDouble());
703#if !(defined(_MSC_VER) && _MSC_VER < 1800) // VC2010 has problem
704 EXPECT_TRUE(Value(RAPIDJSON_UINT64_C2(0xA0000000, 0x00000000)).IsLosslessDouble());
705#endif
706
707 EXPECT_FALSE(Value(static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x7FFFFFFF, 0xFFFFFFFF))).IsLosslessDouble()); // INT64_MAX
708 EXPECT_FALSE(Value(-static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x7FFFFFFF, 0xFFFFFFFF))).IsLosslessDouble()); // -INT64_MAX
709 EXPECT_TRUE(Value(-static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x7FFFFFFF, 0xFFFFFFFF)) - 1).IsLosslessDouble()); // INT64_MIN
710 EXPECT_FALSE(Value(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0xFFFFFFFF)).IsLosslessDouble()); // UINT64_MAX
711
712 EXPECT_TRUE(Value(3.4028234e38f).IsLosslessDouble()); // FLT_MAX
713 EXPECT_TRUE(Value(-3.4028234e38f).IsLosslessDouble()); // -FLT_MAX
714 EXPECT_TRUE(Value(1.17549435e-38f).IsLosslessDouble()); // FLT_MIN
715 EXPECT_TRUE(Value(-1.17549435e-38f).IsLosslessDouble()); // -FLT_MIN
716 EXPECT_TRUE(Value(1.7976931348623157e+308).IsLosslessDouble()); // DBL_MAX
717 EXPECT_TRUE(Value(-1.7976931348623157e+308).IsLosslessDouble()); // -DBL_MAX
718 EXPECT_TRUE(Value(2.2250738585072014e-308).IsLosslessDouble()); // DBL_MIN
719 EXPECT_TRUE(Value(-2.2250738585072014e-308).IsLosslessDouble()); // -DBL_MIN
720}
721
722TEST(Value, IsLosslessFloat) {
723 EXPECT_TRUE(Value(12.25).IsLosslessFloat());
724 EXPECT_TRUE(Value(-123).IsLosslessFloat());
725 EXPECT_TRUE(Value(2147483648u).IsLosslessFloat());
726 EXPECT_TRUE(Value(3.4028234e38f).IsLosslessFloat());
727 EXPECT_TRUE(Value(-3.4028234e38f).IsLosslessFloat());
728 EXPECT_FALSE(Value(3.4028235e38).IsLosslessFloat());
729 EXPECT_FALSE(Value(0.3).IsLosslessFloat());
730}
731
732TEST(Value, String) {
733 // Construction with const string
734 Value x("Hello", 5); // literal
735 EXPECT_EQ(kStringType, x.GetType());
736 EXPECT_TRUE(x.IsString());
737 EXPECT_STREQ("Hello", x.GetString());
738 EXPECT_EQ(5u, x.GetStringLength());
739
740 EXPECT_FALSE(x.IsNumber());
741 EXPECT_FALSE(x.IsNull());
742 EXPECT_FALSE(x.IsBool());
743 EXPECT_FALSE(x.IsFalse());
744 EXPECT_FALSE(x.IsTrue());
745 EXPECT_FALSE(x.IsObject());
746 EXPECT_FALSE(x.IsArray());
747
748 static const char cstr[] = "World"; // const array
749 Value(cstr).Swap(x);
750 EXPECT_TRUE(x.IsString());
751 EXPECT_EQ(x.GetString(), cstr);
752 EXPECT_EQ(x.GetStringLength(), sizeof(cstr)-1);
753
754 static char mstr[] = "Howdy"; // non-const array
755 // Value(mstr).Swap(x); // should not compile
756 Value(StringRef(mstr)).Swap(x);
757 EXPECT_TRUE(x.IsString());
758 EXPECT_EQ(x.GetString(), mstr);
759 EXPECT_EQ(x.GetStringLength(), sizeof(mstr)-1);
760 strncpy(mstr,"Hello", sizeof(mstr));
761 EXPECT_STREQ(x.GetString(), "Hello");
762
763 const char* pstr = cstr;
764 //Value(pstr).Swap(x); // should not compile
765 Value(StringRef(pstr)).Swap(x);
766 EXPECT_TRUE(x.IsString());
767 EXPECT_EQ(x.GetString(), cstr);
768 EXPECT_EQ(x.GetStringLength(), sizeof(cstr)-1);
769
770 char* mpstr = mstr;
771 Value(StringRef(mpstr,sizeof(mstr)-1)).Swap(x);
772 EXPECT_TRUE(x.IsString());
773 EXPECT_EQ(x.GetString(), mstr);
774 EXPECT_EQ(x.GetStringLength(), 5u);
775 EXPECT_STREQ(x.GetString(), "Hello");
776
777 // Constructor with copy string
778 MemoryPoolAllocator<> allocator;
779 Value c(x.GetString(), x.GetStringLength(), allocator);
780 EXPECT_NE(x.GetString(), c.GetString());
781 EXPECT_EQ(x.GetStringLength(), c.GetStringLength());
782 EXPECT_STREQ(x.GetString(), c.GetString());
783 //x.SetString("World");
784 x.SetString("World", 5);
785 EXPECT_STREQ("Hello", c.GetString());
786 EXPECT_EQ(5u, c.GetStringLength());
787
788 // Constructor with type
790 EXPECT_TRUE(y.IsString());
791 EXPECT_STREQ("", y.GetString()); // Empty string should be "" instead of 0 (issue 226)
792 EXPECT_EQ(0u, y.GetStringLength());
793
794 // SetConsttring()
795 Value z;
796 z.SetString("Hello");
797 EXPECT_TRUE(x.IsString());
798 z.SetString("Hello", 5);
799 EXPECT_STREQ("Hello", z.GetString());
800 EXPECT_STREQ("Hello", z.GetString());
801 EXPECT_EQ(5u, z.GetStringLength());
802
803 z.SetString("Hello");
804 EXPECT_TRUE(z.IsString());
805 EXPECT_STREQ("Hello", z.GetString());
806
807 //z.SetString(mstr); // should not compile
808 //z.SetString(pstr); // should not compile
809 z.SetString(StringRef(mstr));
810 EXPECT_TRUE(z.IsString());
811 EXPECT_STREQ(z.GetString(), mstr);
812
813 z.SetString(cstr);
814 EXPECT_TRUE(z.IsString());
815 EXPECT_EQ(cstr, z.GetString());
816
817 z = cstr;
818 EXPECT_TRUE(z.IsString());
819 EXPECT_EQ(cstr, z.GetString());
820
821 // SetString()
822 char s[] = "World";
823 Value w;
824 w.SetString(s, static_cast<SizeType>(strlen(s)), allocator);
825 s[0] = '\0';
826 EXPECT_STREQ("World", w.GetString());
827 EXPECT_EQ(5u, w.GetStringLength());
828
829 // templated functions
830 EXPECT_TRUE(z.Is<const char*>());
831 EXPECT_STREQ(cstr, z.Get<const char*>());
832 EXPECT_STREQ("Apple", z.Set<const char*>("Apple").Get<const char*>());
833
834#if RAPIDJSON_HAS_STDSTRING
835 {
836 std::string str = "Hello World";
837 str[5] = '\0';
838 EXPECT_STREQ(str.data(),"Hello"); // embedded '\0'
839 EXPECT_EQ(str.size(), 11u);
840
841 // no copy
842 Value vs0(StringRef(str));
843 EXPECT_TRUE(vs0.IsString());
844 EXPECT_EQ(vs0.GetString(), str.data());
845 EXPECT_EQ(vs0.GetStringLength(), str.size());
846 TestEqual(vs0, str);
847
848 // do copy
849 Value vs1(str, allocator);
850 EXPECT_TRUE(vs1.IsString());
851 EXPECT_NE(vs1.GetString(), str.data());
852 EXPECT_NE(vs1.GetString(), str); // not equal due to embedded '\0'
853 EXPECT_EQ(vs1.GetStringLength(), str.size());
854 TestEqual(vs1, str);
855
856 // SetString
857 str = "World";
858 vs0.SetNull().SetString(str, allocator);
859 EXPECT_TRUE(vs0.IsString());
860 EXPECT_STREQ(vs0.GetString(), str.c_str());
861 EXPECT_EQ(vs0.GetStringLength(), str.size());
862 TestEqual(str, vs0);
863 TestUnequal(str, vs1);
864
865 // vs1 = str; // should not compile
866 vs1 = StringRef(str);
867 TestEqual(str, vs1);
868 TestEqual(vs0, vs1);
869
870 // Templated function.
871 EXPECT_TRUE(vs0.Is<std::string>());
872 EXPECT_EQ(str, vs0.Get<std::string>());
873 vs0.Set<std::string>(std::string("Apple"), allocator);
874 EXPECT_EQ(std::string("Apple"), vs0.Get<std::string>());
875 vs0.Set(std::string("Orange"), allocator);
876 EXPECT_EQ(std::string("Orange"), vs0.Get<std::string>());
877 }
878#endif // RAPIDJSON_HAS_STDSTRING
879}
880
881// Issue 226: Value of string type should not point to NULL
882TEST(Value, SetStringNull) {
883
884 MemoryPoolAllocator<> allocator;
885 const char* nullPtr = 0;
886 {
887 // Construction with string type creates empty string
889 EXPECT_NE(v.GetString(), nullPtr); // non-null string returned
890 EXPECT_EQ(v.GetStringLength(), 0u);
891
892 // Construction from/setting to null without length not allowed
894 EXPECT_THROW(Value(StringRef(nullPtr), allocator), AssertException);
895 EXPECT_THROW(v.SetString(nullPtr, allocator), AssertException);
896
897 // Non-empty length with null string is not allowed
898 EXPECT_THROW(v.SetString(nullPtr, 17u), AssertException);
899 EXPECT_THROW(v.SetString(nullPtr, 42u, allocator), AssertException);
900
901 // Setting to null string with empty length is allowed
902 v.SetString(nullPtr, 0u);
903 EXPECT_NE(v.GetString(), nullPtr); // non-null string returned
904 EXPECT_EQ(v.GetStringLength(), 0u);
905
906 v.SetNull();
907 v.SetString(nullPtr, 0u, allocator);
908 EXPECT_NE(v.GetString(), nullPtr); // non-null string returned
909 EXPECT_EQ(v.GetStringLength(), 0u);
910 }
911 // Construction with null string and empty length is allowed
912 {
913 Value v(nullPtr,0u);
914 EXPECT_NE(v.GetString(), nullPtr); // non-null string returned
915 EXPECT_EQ(v.GetStringLength(), 0u);
916 }
917 {
918 Value v(nullPtr, 0u, allocator);
919 EXPECT_NE(v.GetString(), nullPtr); // non-null string returned
920 EXPECT_EQ(v.GetStringLength(), 0u);
921 }
922}
923
924template <typename T, typename Allocator>
925static void TestArray(T& x, Allocator& allocator) {
926 const T& y = x;
927
928 // PushBack()
929 Value v;
930 x.PushBack(v, allocator);
931 v.SetBool(true);
932 x.PushBack(v, allocator);
933 v.SetBool(false);
934 x.PushBack(v, allocator);
935 v.SetInt(123);
936 x.PushBack(v, allocator);
937 //x.PushBack((const char*)"foo", allocator); // should not compile
938 x.PushBack("foo", allocator);
939
940 EXPECT_FALSE(x.Empty());
941 EXPECT_EQ(5u, x.Size());
942 EXPECT_FALSE(y.Empty());
943 EXPECT_EQ(5u, y.Size());
944 EXPECT_TRUE(x[SizeType(0)].IsNull());
945 EXPECT_TRUE(x[1].IsTrue());
946 EXPECT_TRUE(x[2].IsFalse());
947 EXPECT_TRUE(x[3].IsInt());
948 EXPECT_EQ(123, x[3].GetInt());
949 EXPECT_TRUE(y[SizeType(0)].IsNull());
950 EXPECT_TRUE(y[1].IsTrue());
951 EXPECT_TRUE(y[2].IsFalse());
952 EXPECT_TRUE(y[3].IsInt());
953 EXPECT_EQ(123, y[3].GetInt());
954 EXPECT_TRUE(y[4].IsString());
955 EXPECT_STREQ("foo", y[4].GetString());
956
957#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
958 // PushBack(GenericValue&&, Allocator&);
959 {
960 Value y2(kArrayType);
961 y2.PushBack(Value(true), allocator);
962 y2.PushBack(std::move(Value(kArrayType).PushBack(Value(1), allocator).PushBack("foo", allocator)), allocator);
963 EXPECT_EQ(2u, y2.Size());
964 EXPECT_TRUE(y2[0].IsTrue());
965 EXPECT_TRUE(y2[1].IsArray());
966 EXPECT_EQ(2u, y2[1].Size());
967 EXPECT_TRUE(y2[1][0].IsInt());
968 EXPECT_TRUE(y2[1][1].IsString());
969 }
970#endif
971
972 // iterator
973 typename T::ValueIterator itr = x.Begin();
974 EXPECT_TRUE(itr != x.End());
975 EXPECT_TRUE(itr->IsNull());
976 ++itr;
977 EXPECT_TRUE(itr != x.End());
978 EXPECT_TRUE(itr->IsTrue());
979 ++itr;
980 EXPECT_TRUE(itr != x.End());
981 EXPECT_TRUE(itr->IsFalse());
982 ++itr;
983 EXPECT_TRUE(itr != x.End());
984 EXPECT_TRUE(itr->IsInt());
985 EXPECT_EQ(123, itr->GetInt());
986 ++itr;
987 EXPECT_TRUE(itr != x.End());
988 EXPECT_TRUE(itr->IsString());
989 EXPECT_STREQ("foo", itr->GetString());
990
991 // const iterator
992 typename T::ConstValueIterator citr = y.Begin();
993 EXPECT_TRUE(citr != y.End());
994 EXPECT_TRUE(citr->IsNull());
995 ++citr;
996 EXPECT_TRUE(citr != y.End());
997 EXPECT_TRUE(citr->IsTrue());
998 ++citr;
999 EXPECT_TRUE(citr != y.End());
1000 EXPECT_TRUE(citr->IsFalse());
1001 ++citr;
1002 EXPECT_TRUE(citr != y.End());
1003 EXPECT_TRUE(citr->IsInt());
1004 EXPECT_EQ(123, citr->GetInt());
1005 ++citr;
1006 EXPECT_TRUE(citr != y.End());
1007 EXPECT_TRUE(citr->IsString());
1008 EXPECT_STREQ("foo", citr->GetString());
1009
1010 // PopBack()
1011 x.PopBack();
1012 EXPECT_EQ(4u, x.Size());
1013 EXPECT_TRUE(y[SizeType(0)].IsNull());
1014 EXPECT_TRUE(y[1].IsTrue());
1015 EXPECT_TRUE(y[2].IsFalse());
1016 EXPECT_TRUE(y[3].IsInt());
1017
1018 // Clear()
1019 x.Clear();
1020 EXPECT_TRUE(x.Empty());
1021 EXPECT_EQ(0u, x.Size());
1022 EXPECT_TRUE(y.Empty());
1023 EXPECT_EQ(0u, y.Size());
1024
1025 // Erase(ValueIterator)
1026
1027 // Use array of array to ensure removed elements' destructor is called.
1028 // [[0],[1],[2],...]
1029 for (int i = 0; i < 10; i++)
1030 x.PushBack(Value(kArrayType).PushBack(i, allocator).Move(), allocator);
1031
1032 // Erase the first
1033 itr = x.Erase(x.Begin());
1034 EXPECT_EQ(x.Begin(), itr);
1035 EXPECT_EQ(9u, x.Size());
1036 for (int i = 0; i < 9; i++)
1037 EXPECT_EQ(i + 1, x[static_cast<SizeType>(i)][0].GetInt());
1038
1039 // Ease the last
1040 itr = x.Erase(x.End() - 1);
1041 EXPECT_EQ(x.End(), itr);
1042 EXPECT_EQ(8u, x.Size());
1043 for (int i = 0; i < 8; i++)
1044 EXPECT_EQ(i + 1, x[static_cast<SizeType>(i)][0].GetInt());
1045
1046 // Erase the middle
1047 itr = x.Erase(x.Begin() + 4);
1048 EXPECT_EQ(x.Begin() + 4, itr);
1049 EXPECT_EQ(7u, x.Size());
1050 for (int i = 0; i < 4; i++)
1051 EXPECT_EQ(i + 1, x[static_cast<SizeType>(i)][0].GetInt());
1052 for (int i = 4; i < 7; i++)
1053 EXPECT_EQ(i + 2, x[static_cast<SizeType>(i)][0].GetInt());
1054
1055 // Erase(ValueIterator, ValueIterator)
1056 // Exhaustive test with all 0 <= first < n, first <= last <= n cases
1057 const unsigned n = 10;
1058 for (unsigned first = 0; first < n; first++) {
1059 for (unsigned last = first; last <= n; last++) {
1060 x.Clear();
1061 for (unsigned i = 0; i < n; i++)
1062 x.PushBack(Value(kArrayType).PushBack(i, allocator).Move(), allocator);
1063
1064 itr = x.Erase(x.Begin() + first, x.Begin() + last);
1065 if (last == n)
1066 EXPECT_EQ(x.End(), itr);
1067 else
1068 EXPECT_EQ(x.Begin() + first, itr);
1069
1070 size_t removeCount = last - first;
1071 EXPECT_EQ(n - removeCount, x.Size());
1072 for (unsigned i = 0; i < first; i++)
1073 EXPECT_EQ(i, x[i][0].GetUint());
1074 for (unsigned i = first; i < n - removeCount; i++)
1075 EXPECT_EQ(i + removeCount, x[static_cast<SizeType>(i)][0].GetUint());
1076 }
1077 }
1078}
1079
1080TEST(Value, Array) {
1081 Value x(kArrayType);
1082 const Value& y = x;
1083 Value::AllocatorType allocator;
1084
1085 EXPECT_EQ(kArrayType, x.GetType());
1086 EXPECT_TRUE(x.IsArray());
1087 EXPECT_TRUE(x.Empty());
1088 EXPECT_EQ(0u, x.Size());
1089 EXPECT_TRUE(y.IsArray());
1090 EXPECT_TRUE(y.Empty());
1091 EXPECT_EQ(0u, y.Size());
1092
1093 EXPECT_FALSE(x.IsNull());
1094 EXPECT_FALSE(x.IsBool());
1095 EXPECT_FALSE(x.IsFalse());
1096 EXPECT_FALSE(x.IsTrue());
1097 EXPECT_FALSE(x.IsString());
1098 EXPECT_FALSE(x.IsObject());
1099
1100 TestArray(x, allocator);
1101
1102 // Working in gcc without C++11, but VS2013 cannot compile. To be diagnosed.
1103 // http://en.wikipedia.org/wiki/Erase-remove_idiom
1104 x.Clear();
1105 for (int i = 0; i < 10; i++)
1106 if (i % 2 == 0)
1107 x.PushBack(i, allocator);
1108 else
1109 x.PushBack(Value(kNullType).Move(), allocator);
1110
1111 const Value null(kNullType);
1112 x.Erase(std::remove(x.Begin(), x.End(), null), x.End());
1113 EXPECT_EQ(5u, x.Size());
1114 for (int i = 0; i < 5; i++)
1115 EXPECT_EQ(i * 2, x[static_cast<SizeType>(i)]);
1116
1117 // SetArray()
1118 Value z;
1119 z.SetArray();
1120 EXPECT_TRUE(z.IsArray());
1121 EXPECT_TRUE(z.Empty());
1122}
1123
1124TEST(Value, ArrayHelper) {
1125 Value::AllocatorType allocator;
1126 {
1127 Value x(kArrayType);
1128 Value::Array a = x.GetArray();
1129 TestArray(a, allocator);
1130 }
1131
1132 {
1133 Value x(kArrayType);
1134 Value::Array a = x.GetArray();
1135 a.PushBack(1, allocator);
1136
1137 Value::Array a2(a); // copy constructor
1138 EXPECT_EQ(1u, a2.Size());
1139
1140 Value::Array a3 = a;
1141 EXPECT_EQ(1u, a3.Size());
1142
1143 Value::ConstArray y = static_cast<const Value&>(x).GetArray();
1144 (void)y;
1145 // y.PushBack(1, allocator); // should not compile
1146
1147 // Templated functions
1148 x.Clear();
1149 EXPECT_TRUE(x.Is<Value::Array>());
1151 a.PushBack(1, allocator);
1152 EXPECT_EQ(1, x.Get<Value::Array>()[0].GetInt());
1153 EXPECT_EQ(1, x.Get<Value::ConstArray>()[0].GetInt());
1154
1155 Value x2;
1156 x2.Set<Value::Array>(a);
1157 EXPECT_TRUE(x.IsArray()); // IsArray() is invariant after moving.
1158 EXPECT_EQ(1, x2.Get<Value::Array>()[0].GetInt());
1159 }
1160
1161 {
1162 Value y(kArrayType);
1163 y.PushBack(123, allocator);
1164
1165 Value x(y.GetArray()); // Construct value form array.
1166 EXPECT_TRUE(x.IsArray());
1167 EXPECT_EQ(123, x[0].GetInt());
1168 EXPECT_TRUE(y.IsArray()); // Invariant
1169 EXPECT_TRUE(y.Empty());
1170 }
1171
1172 {
1173 Value x(kArrayType);
1174 Value y(kArrayType);
1175 y.PushBack(123, allocator);
1176 x.PushBack(y.GetArray(), allocator); // Implicit constructor to convert Array to GenericValue
1177
1178 EXPECT_EQ(1u, x.Size());
1179 EXPECT_EQ(123, x[0][0].GetInt());
1180 EXPECT_TRUE(y.IsArray());
1181 EXPECT_TRUE(y.Empty());
1182 }
1183}
1184
1185#if RAPIDJSON_HAS_CXX11_RANGE_FOR
1186TEST(Value, ArrayHelperRangeFor) {
1188 Value x(kArrayType);
1189
1190 for (int i = 0; i < 10; i++)
1191 x.PushBack(i, allocator);
1192
1193 {
1194 int i = 0;
1195 for (auto& v : x.GetArray()) {
1196 EXPECT_EQ(i, v.GetInt());
1197 i++;
1198 }
1199 EXPECT_EQ(i, 10);
1200 }
1201 {
1202 int i = 0;
1203 for (const auto& v : const_cast<const Value&>(x).GetArray()) {
1204 EXPECT_EQ(i, v.GetInt());
1205 i++;
1206 }
1207 EXPECT_EQ(i, 10);
1208 }
1209
1210 // Array a = x.GetArray();
1211 // Array ca = const_cast<const Value&>(x).GetArray();
1212}
1213#endif
1214
1215template <typename T, typename Allocator>
1216static void TestObject(T& x, Allocator& allocator) {
1217 const T& y = x; // const version
1218
1219 // AddMember()
1220 x.AddMember("A", "Apple", allocator);
1221 EXPECT_FALSE(x.ObjectEmpty());
1222 EXPECT_EQ(1u, x.MemberCount());
1223
1224 Value value("Banana", 6);
1225 x.AddMember("B", "Banana", allocator);
1226 EXPECT_EQ(2u, x.MemberCount());
1227
1228 // AddMember<T>(StringRefType, T, Allocator)
1229 {
1230 Value o(kObjectType);
1231 o.AddMember("true", true, allocator);
1232 o.AddMember("false", false, allocator);
1233 o.AddMember("int", -1, allocator);
1234 o.AddMember("uint", 1u, allocator);
1235 o.AddMember("int64", int64_t(-4294967296), allocator);
1236 o.AddMember("uint64", uint64_t(4294967296), allocator);
1237 o.AddMember("double", 3.14, allocator);
1238 o.AddMember("string", "Jelly", allocator);
1239
1240 EXPECT_TRUE(o["true"].GetBool());
1241 EXPECT_FALSE(o["false"].GetBool());
1242 EXPECT_EQ(-1, o["int"].GetInt());
1243 EXPECT_EQ(1u, o["uint"].GetUint());
1244 EXPECT_EQ(int64_t(-4294967296), o["int64"].GetInt64());
1245 EXPECT_EQ(uint64_t(4294967296), o["uint64"].GetUint64());
1246 EXPECT_STREQ("Jelly",o["string"].GetString());
1247 EXPECT_EQ(8u, o.MemberCount());
1248 }
1249
1250 // AddMember<T>(Value&, T, Allocator)
1251 {
1252 Value o(kObjectType);
1253
1254 Value n("s");
1255 o.AddMember(n, "string", allocator);
1256 EXPECT_EQ(1u, o.MemberCount());
1257
1258 Value count("#");
1259 o.AddMember(count, o.MemberCount(), allocator);
1260 EXPECT_EQ(2u, o.MemberCount());
1261 }
1262
1263#if RAPIDJSON_HAS_STDSTRING
1264 {
1265 // AddMember(StringRefType, const std::string&, Allocator)
1266 Value o(kObjectType);
1267 o.AddMember("b", std::string("Banana"), allocator);
1268 EXPECT_STREQ("Banana", o["b"].GetString());
1269
1270 // RemoveMember(const std::string&)
1271 o.RemoveMember(std::string("b"));
1272 EXPECT_TRUE(o.ObjectEmpty());
1273 }
1274#endif
1275
1276#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1277 // AddMember(GenericValue&&, ...) variants
1278 {
1279 Value o(kObjectType);
1280 o.AddMember(Value("true"), Value(true), allocator);
1281 o.AddMember(Value("false"), Value(false).Move(), allocator); // value is lvalue ref
1282 o.AddMember(Value("int").Move(), Value(-1), allocator); // name is lvalue ref
1283 o.AddMember("uint", std::move(Value().SetUint(1u)), allocator); // name is literal, value is rvalue
1284 EXPECT_TRUE(o["true"].GetBool());
1285 EXPECT_FALSE(o["false"].GetBool());
1286 EXPECT_EQ(-1, o["int"].GetInt());
1287 EXPECT_EQ(1u, o["uint"].GetUint());
1288 EXPECT_EQ(4u, o.MemberCount());
1289 }
1290#endif
1291
1292 // Tests a member with null character
1293 Value name;
1294 const Value C0D("C\0D", 3);
1295 name.SetString(C0D.GetString(), 3);
1296 value.SetString("CherryD", 7);
1297 x.AddMember(name, value, allocator);
1298
1299 // HasMember()
1300 EXPECT_TRUE(x.HasMember("A"));
1301 EXPECT_TRUE(x.HasMember("B"));
1302 EXPECT_TRUE(y.HasMember("A"));
1303 EXPECT_TRUE(y.HasMember("B"));
1304
1305#if RAPIDJSON_HAS_STDSTRING
1306 EXPECT_TRUE(x.HasMember(std::string("A")));
1307#endif
1308
1309 name.SetString("C\0D");
1310 EXPECT_TRUE(x.HasMember(name));
1311 EXPECT_TRUE(y.HasMember(name));
1312
1313 GenericValue<UTF8<>, CrtAllocator> othername("A");
1314 EXPECT_TRUE(x.HasMember(othername));
1315 EXPECT_TRUE(y.HasMember(othername));
1316 othername.SetString("C\0D");
1317 EXPECT_TRUE(x.HasMember(othername));
1318 EXPECT_TRUE(y.HasMember(othername));
1319
1320 // operator[]
1321 EXPECT_STREQ("Apple", x["A"].GetString());
1322 EXPECT_STREQ("Banana", x["B"].GetString());
1323 EXPECT_STREQ("CherryD", x[C0D].GetString());
1324 EXPECT_STREQ("CherryD", x[othername].GetString());
1325 EXPECT_THROW(x["nonexist"], AssertException);
1326
1327 // const operator[]
1328 EXPECT_STREQ("Apple", y["A"].GetString());
1329 EXPECT_STREQ("Banana", y["B"].GetString());
1330 EXPECT_STREQ("CherryD", y[C0D].GetString());
1331
1332#if RAPIDJSON_HAS_STDSTRING
1333 EXPECT_STREQ("Apple", x["A"].GetString());
1334 EXPECT_STREQ("Apple", y[std::string("A")].GetString());
1335#endif
1336
1337 // member iterator
1338 Value::MemberIterator itr = x.MemberBegin();
1339 EXPECT_TRUE(itr != x.MemberEnd());
1340 EXPECT_STREQ("A", itr->name.GetString());
1341 EXPECT_STREQ("Apple", itr->value.GetString());
1342 ++itr;
1343 EXPECT_TRUE(itr != x.MemberEnd());
1344 EXPECT_STREQ("B", itr->name.GetString());
1345 EXPECT_STREQ("Banana", itr->value.GetString());
1346 ++itr;
1347 EXPECT_TRUE(itr != x.MemberEnd());
1348 EXPECT_TRUE(memcmp(itr->name.GetString(), "C\0D", 4) == 0);
1349 EXPECT_STREQ("CherryD", itr->value.GetString());
1350 ++itr;
1351 EXPECT_FALSE(itr != x.MemberEnd());
1352
1353 // const member iterator
1354 Value::ConstMemberIterator citr = y.MemberBegin();
1355 EXPECT_TRUE(citr != y.MemberEnd());
1356 EXPECT_STREQ("A", citr->name.GetString());
1357 EXPECT_STREQ("Apple", citr->value.GetString());
1358 ++citr;
1359 EXPECT_TRUE(citr != y.MemberEnd());
1360 EXPECT_STREQ("B", citr->name.GetString());
1361 EXPECT_STREQ("Banana", citr->value.GetString());
1362 ++citr;
1363 EXPECT_TRUE(citr != y.MemberEnd());
1364 EXPECT_TRUE(memcmp(citr->name.GetString(), "C\0D", 4) == 0);
1365 EXPECT_STREQ("CherryD", citr->value.GetString());
1366 ++citr;
1367 EXPECT_FALSE(citr != y.MemberEnd());
1368
1369 // member iterator conversions/relations
1370 itr = x.MemberBegin();
1371 citr = x.MemberBegin(); // const conversion
1372 TestEqual(itr, citr);
1373 EXPECT_TRUE(itr < x.MemberEnd());
1374 EXPECT_FALSE(itr > y.MemberEnd());
1375 EXPECT_TRUE(citr < x.MemberEnd());
1376 EXPECT_FALSE(citr > y.MemberEnd());
1377 ++citr;
1378 TestUnequal(itr, citr);
1379 EXPECT_FALSE(itr < itr);
1380 EXPECT_TRUE(itr < citr);
1381 EXPECT_FALSE(itr > itr);
1382 EXPECT_TRUE(citr > itr);
1383 EXPECT_EQ(1, citr - x.MemberBegin());
1384 EXPECT_EQ(0, itr - y.MemberBegin());
1385 itr += citr - x.MemberBegin();
1386 EXPECT_EQ(1, itr - y.MemberBegin());
1387 TestEqual(citr, itr);
1388 EXPECT_TRUE(itr <= citr);
1389 EXPECT_TRUE(citr <= itr);
1390 itr++;
1391 EXPECT_TRUE(itr >= citr);
1392 EXPECT_FALSE(citr >= itr);
1393
1394 // RemoveMember()
1395 EXPECT_TRUE(x.RemoveMember("A"));
1396 EXPECT_FALSE(x.HasMember("A"));
1397
1398 EXPECT_TRUE(x.RemoveMember("B"));
1399 EXPECT_FALSE(x.HasMember("B"));
1400
1401 EXPECT_FALSE(x.RemoveMember("nonexist"));
1402
1403 EXPECT_TRUE(x.RemoveMember(othername));
1404 EXPECT_FALSE(x.HasMember(name));
1405
1406 EXPECT_TRUE(x.MemberBegin() == x.MemberEnd());
1407
1408 // EraseMember(ConstMemberIterator)
1409
1410 // Use array members to ensure removed elements' destructor is called.
1411 // { "a": [0], "b": [1],[2],...]
1412 const char keys[][2] = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j" };
1413 for (int i = 0; i < 10; i++)
1414 x.AddMember(keys[i], Value(kArrayType).PushBack(i, allocator), allocator);
1415
1416 // MemberCount, iterator difference
1417 EXPECT_EQ(x.MemberCount(), SizeType(x.MemberEnd() - x.MemberBegin()));
1418
1419 // Erase the first
1420 itr = x.EraseMember(x.MemberBegin());
1421 EXPECT_FALSE(x.HasMember(keys[0]));
1422 EXPECT_EQ(x.MemberBegin(), itr);
1423 EXPECT_EQ(9u, x.MemberCount());
1424 for (; itr != x.MemberEnd(); ++itr) {
1425 size_t i = static_cast<size_t>((itr - x.MemberBegin())) + 1;
1426 EXPECT_STREQ(itr->name.GetString(), keys[i]);
1427 EXPECT_EQ(static_cast<int>(i), itr->value[0].GetInt());
1428 }
1429
1430 // Erase the last
1431 itr = x.EraseMember(x.MemberEnd() - 1);
1432 EXPECT_FALSE(x.HasMember(keys[9]));
1433 EXPECT_EQ(x.MemberEnd(), itr);
1434 EXPECT_EQ(8u, x.MemberCount());
1435 for (; itr != x.MemberEnd(); ++itr) {
1436 size_t i = static_cast<size_t>(itr - x.MemberBegin()) + 1;
1437 EXPECT_STREQ(itr->name.GetString(), keys[i]);
1438 EXPECT_EQ(static_cast<int>(i), itr->value[0].GetInt());
1439 }
1440
1441 // Erase the middle
1442 itr = x.EraseMember(x.MemberBegin() + 4);
1443 EXPECT_FALSE(x.HasMember(keys[5]));
1444 EXPECT_EQ(x.MemberBegin() + 4, itr);
1445 EXPECT_EQ(7u, x.MemberCount());
1446 for (; itr != x.MemberEnd(); ++itr) {
1447 size_t i = static_cast<size_t>(itr - x.MemberBegin());
1448 i += (i < 4) ? 1 : 2;
1449 EXPECT_STREQ(itr->name.GetString(), keys[i]);
1450 EXPECT_EQ(static_cast<int>(i), itr->value[0].GetInt());
1451 }
1452
1453 // EraseMember(ConstMemberIterator, ConstMemberIterator)
1454 // Exhaustive test with all 0 <= first < n, first <= last <= n cases
1455 const unsigned n = 10;
1456 for (unsigned first = 0; first < n; first++) {
1457 for (unsigned last = first; last <= n; last++) {
1458 x.RemoveAllMembers();
1459 for (unsigned i = 0; i < n; i++)
1460 x.AddMember(keys[i], Value(kArrayType).PushBack(i, allocator), allocator);
1461
1462 itr = x.EraseMember(x.MemberBegin() + static_cast<int>(first), x.MemberBegin() + static_cast<int>(last));
1463 if (last == n)
1464 EXPECT_EQ(x.MemberEnd(), itr);
1465 else
1466 EXPECT_EQ(x.MemberBegin() + static_cast<int>(first), itr);
1467
1468 size_t removeCount = last - first;
1469 EXPECT_EQ(n - removeCount, x.MemberCount());
1470 for (unsigned i = 0; i < first; i++)
1471 EXPECT_EQ(i, x[keys[i]][0].GetUint());
1472 for (unsigned i = first; i < n - removeCount; i++)
1473 EXPECT_EQ(i + removeCount, x[keys[i+removeCount]][0].GetUint());
1474 }
1475 }
1476
1477 // RemoveAllMembers()
1478 x.RemoveAllMembers();
1479 EXPECT_TRUE(x.ObjectEmpty());
1480 EXPECT_EQ(0u, x.MemberCount());
1481}
1482
1483TEST(Value, Object) {
1484 Value x(kObjectType);
1485 const Value& y = x; // const version
1486 Value::AllocatorType allocator;
1487
1488 EXPECT_EQ(kObjectType, x.GetType());
1489 EXPECT_TRUE(x.IsObject());
1490 EXPECT_TRUE(x.ObjectEmpty());
1491 EXPECT_EQ(0u, x.MemberCount());
1492 EXPECT_EQ(kObjectType, y.GetType());
1493 EXPECT_TRUE(y.IsObject());
1494 EXPECT_TRUE(y.ObjectEmpty());
1495 EXPECT_EQ(0u, y.MemberCount());
1496
1497 TestObject(x, allocator);
1498
1499 // SetObject()
1500 Value z;
1501 z.SetObject();
1502 EXPECT_TRUE(z.IsObject());
1503}
1504
1505TEST(Value, ObjectHelper) {
1506 Value::AllocatorType allocator;
1507 {
1508 Value x(kObjectType);
1509 Value::Object o = x.GetObject();
1510 TestObject(o, allocator);
1511 }
1512
1513 {
1514 Value x(kObjectType);
1515 Value::Object o = x.GetObject();
1516 o.AddMember("1", 1, allocator);
1517
1518 Value::Object o2(o); // copy constructor
1519 EXPECT_EQ(1u, o2.MemberCount());
1520
1521 Value::Object o3 = o;
1522 EXPECT_EQ(1u, o3.MemberCount());
1523
1524 Value::ConstObject y = static_cast<const Value&>(x).GetObject();
1525 (void)y;
1526 // y.AddMember("1", 1, allocator); // should not compile
1527
1528 // Templated functions
1529 x.RemoveAllMembers();
1530 EXPECT_TRUE(x.Is<Value::Object>());
1532 o.AddMember("1", 1, allocator);
1533 EXPECT_EQ(1, x.Get<Value::Object>()["1"].GetInt());
1534 EXPECT_EQ(1, x.Get<Value::ConstObject>()["1"].GetInt());
1535
1536 Value x2;
1537 x2.Set<Value::Object>(o);
1538 EXPECT_TRUE(x.IsObject()); // IsObject() is invariant after moving
1539 EXPECT_EQ(1, x2.Get<Value::Object>()["1"].GetInt());
1540 }
1541
1542 {
1543 Value x(kObjectType);
1544 x.AddMember("a", "apple", allocator);
1545 Value y(x.GetObject());
1546 EXPECT_STREQ("apple", y["a"].GetString());
1547 EXPECT_TRUE(x.IsObject()); // Invariant
1548 }
1549
1550 {
1551 Value x(kObjectType);
1552 x.AddMember("a", "apple", allocator);
1553 Value y(kObjectType);
1554 y.AddMember("fruits", x.GetObject(), allocator);
1555 EXPECT_STREQ("apple", y["fruits"]["a"].GetString());
1556 EXPECT_TRUE(x.IsObject()); // Invariant
1557 }
1558}
1559
1560#if RAPIDJSON_HAS_CXX11_RANGE_FOR
1561TEST(Value, ObjectHelperRangeFor) {
1563 Value x(kObjectType);
1564
1565 for (int i = 0; i < 10; i++) {
1566 char name[10];
1567 Value n(name, static_cast<SizeType>(sprintf(name, "%d", i)), allocator);
1568 x.AddMember(n, i, allocator);
1569 }
1570
1571 {
1572 int i = 0;
1573 for (auto& m : x.GetObject()) {
1574 char name[10];
1575 sprintf(name, "%d", i);
1576 EXPECT_STREQ(name, m.name.GetString());
1577 EXPECT_EQ(i, m.value.GetInt());
1578 i++;
1579 }
1580 EXPECT_EQ(i, 10);
1581 }
1582 {
1583 int i = 0;
1584 for (const auto& m : const_cast<const Value&>(x).GetObject()) {
1585 char name[10];
1586 sprintf(name, "%d", i);
1587 EXPECT_STREQ(name, m.name.GetString());
1588 EXPECT_EQ(i, m.value.GetInt());
1589 i++;
1590 }
1591 EXPECT_EQ(i, 10);
1592 }
1593
1594 // Object a = x.GetObject();
1595 // Object ca = const_cast<const Value&>(x).GetObject();
1596}
1597#endif
1598
1599TEST(Value, EraseMember_String) {
1600 Value::AllocatorType allocator;
1601 Value x(kObjectType);
1602 x.AddMember("A", "Apple", allocator);
1603 x.AddMember("B", "Banana", allocator);
1604
1605 EXPECT_TRUE(x.EraseMember("B"));
1606 EXPECT_FALSE(x.HasMember("B"));
1607
1608 EXPECT_FALSE(x.EraseMember("nonexist"));
1609
1610 GenericValue<UTF8<>, CrtAllocator> othername("A");
1611 EXPECT_TRUE(x.EraseMember(othername));
1612 EXPECT_FALSE(x.HasMember("A"));
1613
1614 EXPECT_TRUE(x.MemberBegin() == x.MemberEnd());
1615}
1616
1617TEST(Value, BigNestedArray) {
1618 MemoryPoolAllocator<> allocator;
1619 Value x(kArrayType);
1620 static const SizeType n = 200;
1621
1622 for (SizeType i = 0; i < n; i++) {
1623 Value y(kArrayType);
1624 for (SizeType j = 0; j < n; j++) {
1625 Value number(static_cast<int>(i * n + j));
1626 y.PushBack(number, allocator);
1627 }
1628 x.PushBack(y, allocator);
1629 }
1630
1631 for (SizeType i = 0; i < n; i++)
1632 for (SizeType j = 0; j < n; j++) {
1633 EXPECT_TRUE(x[i][j].IsInt());
1634 EXPECT_EQ(static_cast<int>(i * n + j), x[i][j].GetInt());
1635 }
1636}
1637
1638TEST(Value, BigNestedObject) {
1639 MemoryPoolAllocator<> allocator;
1640 Value x(kObjectType);
1641 static const SizeType n = 200;
1642
1643 for (SizeType i = 0; i < n; i++) {
1644 char name1[10];
1645 sprintf(name1, "%d", i);
1646
1647 // Value name(name1); // should not compile
1648 Value name(name1, static_cast<SizeType>(strlen(name1)), allocator);
1650
1651 for (SizeType j = 0; j < n; j++) {
1652 char name2[10];
1653 sprintf(name2, "%d", j);
1654
1655 Value name3(name2, static_cast<SizeType>(strlen(name2)), allocator);
1656 Value number(static_cast<int>(i * n + j));
1657 object.AddMember(name3, number, allocator);
1658 }
1659
1660 // x.AddMember(name1, object, allocator); // should not compile
1661 x.AddMember(name, object, allocator);
1662 }
1663
1664 for (SizeType i = 0; i < n; i++) {
1665 char name1[10];
1666 sprintf(name1, "%d", i);
1667
1668 for (SizeType j = 0; j < n; j++) {
1669 char name2[10];
1670 sprintf(name2, "%d", j);
1671 x[name1];
1672 EXPECT_EQ(static_cast<int>(i * n + j), x[name1][name2].GetInt());
1673 }
1674 }
1675}
1676
1677// Issue 18: Error removing last element of object
1678// http://code.google.com/p/rapidjson/issues/detail?id=18
1679TEST(Value, RemoveLastElement) {
1680 rapidjson::Document doc;
1681 rapidjson::Document::AllocatorType& allocator = doc.GetAllocator();
1682 rapidjson::Value objVal(rapidjson::kObjectType);
1683 objVal.AddMember("var1", 123, allocator);
1684 objVal.AddMember("var2", "444", allocator);
1685 objVal.AddMember("var3", 555, allocator);
1686 EXPECT_TRUE(objVal.HasMember("var3"));
1687 objVal.RemoveMember("var3"); // Assertion here in r61
1688 EXPECT_FALSE(objVal.HasMember("var3"));
1689}
1690
1691// Issue 38: Segmentation fault with CrtAllocator
1694
1695 V::AllocatorType allocator;
1696 V o(kObjectType);
1697 o.AddMember("x", 1, allocator); // Should not call destructor on uninitialized name/value of newly allocated members.
1698
1699 V a(kArrayType);
1700 a.PushBack(1, allocator); // Should not call destructor on uninitialized Value of newly allocated elements.
1701}
1702
1703static void TestShortStringOptimization(const char* str) {
1704 const rapidjson::SizeType len = static_cast<rapidjson::SizeType>(strlen(str));
1705
1706 rapidjson::Document doc;
1707 rapidjson::Value val;
1708 val.SetString(str, len, doc.GetAllocator());
1709
1710 EXPECT_EQ(val.GetStringLength(), len);
1711 EXPECT_STREQ(val.GetString(), str);
1712}
1713
1714TEST(Value, AllocateShortString) {
1715 TestShortStringOptimization(""); // edge case: empty string
1716 TestShortStringOptimization("12345678"); // regular case for short strings: 8 chars
1717 TestShortStringOptimization("12345678901"); // edge case: 11 chars in 32-bit mode (=> short string)
1718 TestShortStringOptimization("123456789012"); // edge case: 12 chars in 32-bit mode (=> regular string)
1719 TestShortStringOptimization("123456789012345"); // edge case: 15 chars in 64-bit mode (=> short string)
1720 TestShortStringOptimization("1234567890123456"); // edge case: 16 chars in 64-bit mode (=> regular string)
1721}
1722
1723template <int e>
1724struct TerminateHandler {
1725 bool Null() { return e != 0; }
1726 bool Bool(bool) { return e != 1; }
1727 bool Int(int) { return e != 2; }
1728 bool Uint(unsigned) { return e != 3; }
1729 bool Int64(int64_t) { return e != 4; }
1730 bool Uint64(uint64_t) { return e != 5; }
1731 bool Double(double) { return e != 6; }
1732 bool RawNumber(const char*, SizeType, bool) { return e != 7; }
1733 bool String(const char*, SizeType, bool) { return e != 8; }
1734 bool StartObject() { return e != 9; }
1735 bool Key(const char*, SizeType, bool) { return e != 10; }
1736 bool EndObject(SizeType) { return e != 11; }
1737 bool StartArray() { return e != 12; }
1738 bool EndArray(SizeType) { return e != 13; }
1739};
1740
1741#define TEST_TERMINATION(e, json)\
1742{\
1743 Document d; \
1744 EXPECT_FALSE(d.Parse(json).HasParseError()); \
1745 Reader reader; \
1746 TerminateHandler<e> h;\
1747 EXPECT_FALSE(d.Accept(h));\
1748}
1749
1750TEST(Value, AcceptTerminationByHandler) {
1751 TEST_TERMINATION(0, "[null]");
1752 TEST_TERMINATION(1, "[true]");
1753 TEST_TERMINATION(1, "[false]");
1754 TEST_TERMINATION(2, "[-1]");
1755 TEST_TERMINATION(3, "[2147483648]");
1756 TEST_TERMINATION(4, "[-1234567890123456789]");
1757 TEST_TERMINATION(5, "[9223372036854775808]");
1758 TEST_TERMINATION(6, "[0.5]");
1759 // RawNumber() is never called
1760 TEST_TERMINATION(8, "[\"a\"]");
1761 TEST_TERMINATION(9, "[{}]");
1762 TEST_TERMINATION(10, "[{\"a\":1}]");
1763 TEST_TERMINATION(11, "[{}]");
1764 TEST_TERMINATION(12, "{\"a\":[]}");
1765 TEST_TERMINATION(13, "{\"a\":[]}");
1766}
1767
1769 bool operator()(const Value& lhs, const Value& rhs) const {
1770 return lhs.GetInt() < rhs.GetInt();
1771 }
1772};
1773
1774#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1775TEST(Value, Sorting) {
1778 a.PushBack(5, allocator);
1779 a.PushBack(1, allocator);
1780 a.PushBack(3, allocator);
1781 std::sort(a.Begin(), a.End(), ValueIntComparer());
1782 EXPECT_EQ(1, a[0].GetInt());
1783 EXPECT_EQ(3, a[1].GetInt());
1784 EXPECT_EQ(5, a[2].GetInt());
1785}
1786#endif
1787
1788// http://stackoverflow.com/questions/35222230/
1789
1790static void MergeDuplicateKey(Value& v, Value::AllocatorType& a) {
1791 if (v.IsObject()) {
1792 // Convert all key:value into key:[value]
1793 for (Value::MemberIterator itr = v.MemberBegin(); itr != v.MemberEnd(); ++itr)
1794 itr->value = Value(kArrayType).Move().PushBack(itr->value, a);
1795
1796 // Merge arrays if key is duplicated
1797 for (Value::MemberIterator itr = v.MemberBegin(); itr != v.MemberEnd();) {
1798 Value::MemberIterator itr2 = v.FindMember(itr->name);
1799 if (itr != itr2) {
1800 itr2->value.PushBack(itr->value[0], a);
1801 itr = v.EraseMember(itr);
1802 }
1803 else
1804 ++itr;
1805 }
1806
1807 // Convert key:[values] back to key:value if there is only one value
1808 for (Value::MemberIterator itr = v.MemberBegin(); itr != v.MemberEnd(); ++itr) {
1809 if (itr->value.Size() == 1)
1810 itr->value = itr->value[0];
1811 MergeDuplicateKey(itr->value, a); // Recursion on the value
1812 }
1813 }
1814 else if (v.IsArray())
1815 for (Value::ValueIterator itr = v.Begin(); itr != v.End(); ++itr)
1816 MergeDuplicateKey(*itr, a);
1817}
1818
1819TEST(Value, MergeDuplicateKey) {
1820 Document d;
1821 d.Parse(
1822 "{"
1823 " \"key1\": {"
1824 " \"a\": \"asdf\","
1825 " \"b\": \"foo\","
1826 " \"b\": \"bar\","
1827 " \"c\": \"fdas\""
1828 " }"
1829 "}");
1830
1831 Document d2;
1832 d2.Parse(
1833 "{"
1834 " \"key1\": {"
1835 " \"a\": \"asdf\","
1836 " \"b\": ["
1837 " \"foo\","
1838 " \"bar\""
1839 " ],"
1840 " \"c\": \"fdas\""
1841 " }"
1842 "}");
1843
1844 EXPECT_NE(d2, d);
1845 MergeDuplicateKey(d, d.GetAllocator());
1846 EXPECT_EQ(d2, d);
1847}
1848
1849#ifdef __clang__
1850RAPIDJSON_DIAG_POP
1851#endif
std::string name
C-runtime library allocator.
Definition allocators.h:75
Helper class for accessing Value of array type.
Definition document.h:2514
SizeType Size() const
Definition document.h:2532
A document for parsing JSON text as DOM.
Definition document.h:2124
Allocator & GetAllocator()
Get the allocator of this document.
Definition document.h:2412
GenericDocument & Parse(const typename SourceEncoding::Ch *str)
Parse JSON text from a read-only string (with Encoding conversion)
Definition document.h:2325
(Constant) member iterator for a JSON object value
Definition document.h:102
Helper class for accessing Value of object type.
Definition document.h:2567
SizeType MemberCount() const
Definition document.h:2587
GenericObject AddMember(ValueType &name, ValueType &value, AllocatorType &allocator) const
Definition document.h:2608
Default memory allocator used by the parser and DOM.
Definition allocators.h:115
Concept for allocating, resizing and freeing memory block.
GenericValue< UTF8<> > Value
GenericValue with UTF8 encoding.
Definition document.h:2110
GenericStringRef< CharType > StringRef(const CharType *str)
Mark a character pointer as constant string.
Definition document.h:364
int * count
#define EXPECT_EQ(val1, val2)
Definition gtest.h:1954
#define EXPECT_NE(val1, val2)
Definition gtest.h:1958
#define EXPECT_THROW(statement, expected_exception)
Definition gtest.h:1879
#define EXPECT_NEAR(val1, val2, abs_error)
Definition gtest.h:2075
#define EXPECT_DOUBLE_EQ(val1, val2)
Definition gtest.h:2063
#define EXPECT_TRUE(condition)
Definition gtest.h:1895
#define EXPECT_STREQ(s1, s2)
Definition gtest.h:2027
#define TEST(test_case_name, test_name)
Definition gtest.h:2275
#define EXPECT_FALSE(condition)
Definition gtest.h:1898
bip::allocator< T, pinnable_mapped_file::segment_manager > allocator
Definition chainbase.hpp:56
uint64_t y
Definition sha3.cpp:34
main RapidJSON namespace
void swap(picojson::value &x, picojson::value &y)
GTEST_API_ bool IsTrue(bool condition)
Definition gtest.cc:5404
#define value
Definition pkcs11.h:157
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition pointer.h:1181
#define T(meth, val, expected)
@ kFalseType
false
Definition rapidjson.h:646
@ kObjectType
object
Definition rapidjson.h:648
@ kTrueType
true
Definition rapidjson.h:647
@ kStringType
string
Definition rapidjson.h:650
@ kNullType
null
Definition rapidjson.h:645
@ kArrayType
array
Definition rapidjson.h:649
@ kNumberType
number
Definition rapidjson.h:651
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition rapidjson.h:384
#define RAPIDJSON_UINT64_C2(high32, low32)
Construct a 64-bit literal by a pair of 32-bit integer.
Definition rapidjson.h:289
#define RAPIDJSON_STATIC_ASSERT(x)
(Internal) macro to check for conditions at compile-time
Definition rapidjson.h:445
signed __int64 int64_t
Definition stdint.h:135
unsigned __int64 uint64_t
Definition stdint.h:136
bool Uint64(uint64_t)
bool Int64(int64_t)
bool Double(double)
bool Key(const char *, SizeType, bool)
bool Uint(unsigned)
bool EndArray(SizeType)
bool EndObject(SizeType)
bool String(const char *, SizeType, bool)
bool RawNumber(const char *, SizeType, bool)
Definition test_zm.cpp:19
bool operator()(const Value &lhs, const Value &rhs) const
#define TEST_TERMINATION(e, json)
void TestEqual(const A &a, const B &b)
void TestUnequal(const A &a, const B &b)
void TestCopyFrom()
CK_ULONG d
char * s
uint16_t j
size_t len
yh_object_descriptor object