1 // Tencent is pleased to support the open source community by making RapidJSON available.
3 // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
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
8 // http://opensource.org/licenses/MIT
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.
16 #include "rapidjson/document.h"
21 RAPIDJSON_DIAG_OFF(c++98-compat)
24 using namespace rapidjson;
27 if (sizeof(SizeType) == 4) {
28 #if RAPIDJSON_48BITPOINTER_OPTIMIZATION
29 EXPECT_EQ(16, sizeof(Value));
31 EXPECT_EQ(24, sizeof(Value));
33 EXPECT_EQ(16, sizeof(Value));
38 TEST(Value, DefaultConstructor) {
40 EXPECT_EQ(kNullType, x.GetType());
41 EXPECT_TRUE(x.IsNull());
43 //std::cout << "sizeof(Value): " << sizeof(x) << std::endl;
46 // Should not pass compilation
47 //TEST(Value, copy_constructor) {
52 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
54 #if 0 // Many old compiler does not support these. Turn it off temporaily.
56 #include <type_traits>
59 typedef GenericValue<UTF8<>, CrtAllocator> Value;
60 static_assert(std::is_constructible<Value>::value, "");
61 static_assert(std::is_default_constructible<Value>::value, "");
63 static_assert(!std::is_copy_constructible<Value>::value, "");
65 static_assert(std::is_move_constructible<Value>::value, "");
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, "");
74 static_assert(std::is_assignable<Value,Value>::value, "");
76 static_assert(!std::is_copy_assignable<Value>::value, "");
78 static_assert(std::is_move_assignable<Value>::value, "");
81 static_assert(std::is_nothrow_assignable<Value, Value>::value, "");
83 static_assert(!std::is_nothrow_copy_assignable<Value>::value, "");
85 static_assert(std::is_nothrow_move_assignable<Value>::value, "");
88 static_assert(std::is_destructible<Value>::value, "");
90 static_assert(std::is_nothrow_destructible<Value>::value, "");
96 TEST(Value, MoveConstructor) {
97 typedef GenericValue<UTF8<>, CrtAllocator> V;
98 V::AllocatorType allocator;
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());
106 // Value y(x); // does not compile (!is_copy_constructible)
108 EXPECT_TRUE(x.IsNull());
109 EXPECT_TRUE(y.IsArray());
110 EXPECT_EQ(4u, y.Size());
112 // Value z = y; // does not compile (!is_copy_assignable)
114 EXPECT_TRUE(y.IsNull());
115 EXPECT_TRUE(z.IsArray());
116 EXPECT_EQ(4u, z.Size());
119 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
121 TEST(Value, AssignmentOperator) {
125 EXPECT_TRUE(x.IsNull()); // move semantic
126 EXPECT_EQ(1234, y.GetInt());
129 EXPECT_TRUE(y.IsInt());
130 EXPECT_EQ(5678, y.GetInt());
133 EXPECT_TRUE(x.IsString());
134 EXPECT_STREQ(x.GetString(),"Hello");
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());
141 static char mstr[] = "mutable";
142 // y = mstr; // should not compile
144 EXPECT_TRUE(y.IsString());
145 EXPECT_EQ(y.GetString(),mstr);
147 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
148 // C++11 move assignment
150 EXPECT_TRUE(x.IsString());
151 EXPECT_STREQ("World", x.GetString());
154 EXPECT_TRUE(y.IsNull());
155 EXPECT_TRUE(x.IsString());
156 EXPECT_EQ(x.GetString(), mstr);
158 y = std::move(Value().SetInt(1234));
159 EXPECT_TRUE(y.IsInt());
161 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
164 template <typename A, typename B>
165 void 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);
172 template <typename A, typename B>
173 void 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);
180 TEST(Value, EqualtoOperator) {
181 Value::AllocatorType allocator;
182 Value x(kObjectType);
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);
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);
199 TestEqual(x["t"], true);
200 TestEqual(x["f"], false);
201 TestEqual(x["i"], 123);
202 TestEqual(x["pi"], 3.14);
204 // Test operator==() (including different allocators)
205 CrtAllocator crtAllocator;
206 GenericValue<UTF8<>, CrtAllocator> y;
207 GenericDocument<UTF8<>, CrtAllocator> z(&crtAllocator);
208 y.CopyFrom(x, crtAllocator);
209 z.CopyFrom(y, z.GetAllocator());
214 // Swapping member order should be fine.
215 EXPECT_TRUE(y.RemoveMember("t"));
218 EXPECT_TRUE(z.RemoveMember("t"));
221 y.AddMember("t", false, crtAllocator);
222 z.AddMember("t", false, z.GetAllocator());
231 // Swapping element order is not OK
232 x["a"][0].Swap(x["a"][1]);
234 x["a"][0].Swap(x["a"][1]);
237 // Array of different size
238 x["a"].PushBack(4, allocator);
243 // Issue #129: compare Uint64
244 x.SetUint64(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0xFFFFFFF0));
245 y.SetUint64(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0xFFFFFFFF));
249 template <typename Value>
250 void TestCopyFrom() {
251 typename Value::AllocatorType a;
253 Value v2(v1, a); // deep copy constructor
254 EXPECT_TRUE(v1.GetType() == v2.GetType());
255 EXPECT_EQ(v1.GetInt(), v2.GetInt());
259 EXPECT_TRUE(v1.GetType() == v2.GetType());
260 EXPECT_STREQ(v1.GetString(), v2.GetString());
261 EXPECT_EQ(v1.GetString(), v2.GetString()); // string NOT copied
263 v1.SetString("bar", a); // copy string
265 EXPECT_TRUE(v1.GetType() == v2.GetType());
266 EXPECT_STREQ(v1.GetString(), v2.GetString());
267 EXPECT_NE(v1.GetString(), v2.GetString()); // string copied
270 v1.SetArray().PushBack(1234, a);
272 EXPECT_TRUE(v2.IsArray());
273 EXPECT_EQ(v1.Size(), v2.Size());
275 v1.PushBack(Value().SetString("foo", a), a); // push string copy
276 EXPECT_TRUE(v1.Size() != v2.Size());
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
283 TEST(Value, CopyFrom) {
284 TestCopyFrom<Value>();
285 TestCopyFrom<GenericValue<UTF8<>, CrtAllocator> >();
290 Value v2(kObjectType);
292 EXPECT_EQ(&v1, &v1.Swap(v2));
293 EXPECT_TRUE(v1.IsObject());
294 EXPECT_TRUE(v2.IsInt());
295 EXPECT_EQ(1234, v2.GetInt());
297 // testing std::swap compatibility
300 EXPECT_TRUE(v1.IsInt());
301 EXPECT_TRUE(v2.IsObject());
305 // Default constructor
307 EXPECT_EQ(kNullType, x.GetType());
308 EXPECT_TRUE(x.IsNull());
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());
317 // Constructor with type
319 EXPECT_TRUE(y.IsNull());
324 EXPECT_TRUE(z.IsNull());
328 // Constructor with bool
330 EXPECT_EQ(kTrueType, x.GetType());
331 EXPECT_TRUE(x.GetBool());
332 EXPECT_TRUE(x.IsBool());
333 EXPECT_TRUE(x.IsTrue());
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());
342 // Constructor with type
344 EXPECT_TRUE(y.IsTrue());
349 EXPECT_TRUE(z.IsTrue());
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>());
359 // Constructor with bool
361 EXPECT_EQ(kFalseType, x.GetType());
362 EXPECT_TRUE(x.IsBool());
363 EXPECT_TRUE(x.IsFalse());
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());
374 // Constructor with type
376 EXPECT_TRUE(y.IsFalse());
381 EXPECT_TRUE(z.IsFalse());
385 // Constructor with int
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());
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());
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());
422 // Constructor with type
423 Value y(kNumberType);
424 EXPECT_TRUE(y.IsNumber());
425 EXPECT_TRUE(y.IsInt());
426 EXPECT_EQ(0, y.GetInt());
431 EXPECT_EQ(1234, z.GetInt());
435 EXPECT_EQ(5678, z.GetInt());
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>());
445 // Constructor with int
447 EXPECT_EQ(kNumberType, x.GetType());
448 EXPECT_EQ(1234, x.GetInt());
449 EXPECT_EQ(1234u, x.GetUint());
450 EXPECT_EQ(1234, x.GetInt64());
451 EXPECT_EQ(1234u, x.GetUint64());
452 EXPECT_TRUE(x.IsNumber());
453 EXPECT_TRUE(x.IsInt());
454 EXPECT_TRUE(x.IsUint());
455 EXPECT_TRUE(x.IsInt64());
456 EXPECT_TRUE(x.IsUint64());
457 EXPECT_NEAR(1234.0, x.GetDouble(), 0.0); // Number can always be cast as double but !IsDouble().
459 EXPECT_FALSE(x.IsDouble());
460 EXPECT_FALSE(x.IsFloat());
461 EXPECT_FALSE(x.IsNull());
462 EXPECT_FALSE(x.IsBool());
463 EXPECT_FALSE(x.IsFalse());
464 EXPECT_FALSE(x.IsTrue());
465 EXPECT_FALSE(x.IsString());
466 EXPECT_FALSE(x.IsObject());
467 EXPECT_FALSE(x.IsArray());
472 EXPECT_EQ(1234u, z.GetUint());
474 // operator=(unsigned)
476 EXPECT_EQ(5678u, z.GetUint());
478 z = 2147483648u; // 2^31, cannot cast as int
479 EXPECT_EQ(2147483648u, z.GetUint());
480 EXPECT_FALSE(z.IsInt());
481 EXPECT_TRUE(z.IsInt64()); // Issue 41: Incorrect parsing of unsigned int number types
483 // Templated functions
484 EXPECT_TRUE(z.Is<unsigned>());
485 EXPECT_EQ(2147483648u, z.Get<unsigned>());
486 EXPECT_EQ(2147483649u, z.Set(2147483649u).Get<unsigned>());
487 EXPECT_EQ(2147483650u, z.Set<unsigned>(2147483650u).Get<unsigned>());
491 // Constructor with int
492 Value x(int64_t(1234));
493 EXPECT_EQ(kNumberType, x.GetType());
494 EXPECT_EQ(1234, x.GetInt());
495 EXPECT_EQ(1234u, x.GetUint());
496 EXPECT_EQ(1234, x.GetInt64());
497 EXPECT_EQ(1234u, x.GetUint64());
498 EXPECT_TRUE(x.IsNumber());
499 EXPECT_TRUE(x.IsInt());
500 EXPECT_TRUE(x.IsUint());
501 EXPECT_TRUE(x.IsInt64());
502 EXPECT_TRUE(x.IsUint64());
504 EXPECT_FALSE(x.IsDouble());
505 EXPECT_FALSE(x.IsFloat());
506 EXPECT_FALSE(x.IsNull());
507 EXPECT_FALSE(x.IsBool());
508 EXPECT_FALSE(x.IsFalse());
509 EXPECT_FALSE(x.IsTrue());
510 EXPECT_FALSE(x.IsString());
511 EXPECT_FALSE(x.IsObject());
512 EXPECT_FALSE(x.IsArray());
514 Value nx(int64_t(-1234));
515 EXPECT_EQ(-1234, nx.GetInt());
516 EXPECT_EQ(-1234, nx.GetInt64());
517 EXPECT_TRUE(nx.IsInt());
518 EXPECT_TRUE(nx.IsInt64());
519 EXPECT_FALSE(nx.IsUint());
520 EXPECT_FALSE(nx.IsUint64());
525 EXPECT_EQ(1234, z.GetInt64());
527 z.SetInt64(2147483648u); // 2^31, cannot cast as int
528 EXPECT_FALSE(z.IsInt());
529 EXPECT_TRUE(z.IsUint());
530 EXPECT_NEAR(2147483648.0, z.GetDouble(), 0.0);
532 z.SetInt64(int64_t(4294967295u) + 1); // 2^32, cannot cast as uint
533 EXPECT_FALSE(z.IsInt());
534 EXPECT_FALSE(z.IsUint());
535 EXPECT_NEAR(4294967296.0, z.GetDouble(), 0.0);
537 z.SetInt64(-int64_t(2147483648u) - 1); // -2^31-1, cannot cast as int
538 EXPECT_FALSE(z.IsInt());
539 EXPECT_NEAR(-2147483649.0, z.GetDouble(), 0.0);
541 int64_t i = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 00000000));
543 EXPECT_DOUBLE_EQ(-9223372036854775808.0, z.GetDouble());
545 // Templated functions
546 EXPECT_TRUE(z.Is<int64_t>());
547 EXPECT_EQ(i, z.Get<int64_t>());
548 #if 0 // signed integer underflow is undefined behaviour
549 EXPECT_EQ(i - 1, z.Set(i - 1).Get<int64_t>());
550 EXPECT_EQ(i - 2, z.Set<int64_t>(i - 2).Get<int64_t>());
554 TEST(Value, Uint64) {
555 // Constructor with int
556 Value x(uint64_t(1234));
557 EXPECT_EQ(kNumberType, x.GetType());
558 EXPECT_EQ(1234, x.GetInt());
559 EXPECT_EQ(1234u, x.GetUint());
560 EXPECT_EQ(1234, x.GetInt64());
561 EXPECT_EQ(1234u, x.GetUint64());
562 EXPECT_TRUE(x.IsNumber());
563 EXPECT_TRUE(x.IsInt());
564 EXPECT_TRUE(x.IsUint());
565 EXPECT_TRUE(x.IsInt64());
566 EXPECT_TRUE(x.IsUint64());
568 EXPECT_FALSE(x.IsDouble());
569 EXPECT_FALSE(x.IsFloat());
570 EXPECT_FALSE(x.IsNull());
571 EXPECT_FALSE(x.IsBool());
572 EXPECT_FALSE(x.IsFalse());
573 EXPECT_FALSE(x.IsTrue());
574 EXPECT_FALSE(x.IsString());
575 EXPECT_FALSE(x.IsObject());
576 EXPECT_FALSE(x.IsArray());
581 EXPECT_EQ(1234u, z.GetUint64());
583 z.SetUint64(uint64_t(2147483648u)); // 2^31, cannot cast as int
584 EXPECT_FALSE(z.IsInt());
585 EXPECT_TRUE(z.IsUint());
586 EXPECT_TRUE(z.IsInt64());
588 z.SetUint64(uint64_t(4294967295u) + 1); // 2^32, cannot cast as uint
589 EXPECT_FALSE(z.IsInt());
590 EXPECT_FALSE(z.IsUint());
591 EXPECT_TRUE(z.IsInt64());
593 uint64_t u = RAPIDJSON_UINT64_C2(0x80000000, 0x00000000);
594 z.SetUint64(u); // 2^63 cannot cast as int64
595 EXPECT_FALSE(z.IsInt64());
596 EXPECT_EQ(u, z.GetUint64()); // Issue 48
597 EXPECT_DOUBLE_EQ(9223372036854775808.0, z.GetDouble());
599 // Templated functions
600 EXPECT_TRUE(z.Is<uint64_t>());
601 EXPECT_EQ(u, z.Get<uint64_t>());
602 EXPECT_EQ(u + 1, z.Set(u + 1).Get<uint64_t>());
603 EXPECT_EQ(u + 2, z.Set<uint64_t>(u + 2).Get<uint64_t>());
606 TEST(Value, Double) {
607 // Constructor with double
609 EXPECT_EQ(kNumberType, x.GetType());
610 EXPECT_NEAR(12.34, x.GetDouble(), 0.0);
611 EXPECT_TRUE(x.IsNumber());
612 EXPECT_TRUE(x.IsDouble());
614 EXPECT_FALSE(x.IsInt());
615 EXPECT_FALSE(x.IsNull());
616 EXPECT_FALSE(x.IsBool());
617 EXPECT_FALSE(x.IsFalse());
618 EXPECT_FALSE(x.IsTrue());
619 EXPECT_FALSE(x.IsString());
620 EXPECT_FALSE(x.IsObject());
621 EXPECT_FALSE(x.IsArray());
626 EXPECT_NEAR(12.34, z.GetDouble(), 0.0);
629 EXPECT_NEAR(56.78, z.GetDouble(), 0.0);
631 // Templated functions
632 EXPECT_TRUE(z.Is<double>());
633 EXPECT_EQ(56.78, z.Get<double>());
634 EXPECT_EQ(57.78, z.Set(57.78).Get<double>());
635 EXPECT_EQ(58.78, z.Set<double>(58.78).Get<double>());
639 // Constructor with double
641 EXPECT_EQ(kNumberType, x.GetType());
642 EXPECT_NEAR(12.34f, x.GetFloat(), 0.0);
643 EXPECT_TRUE(x.IsNumber());
644 EXPECT_TRUE(x.IsDouble());
645 EXPECT_TRUE(x.IsFloat());
647 EXPECT_FALSE(x.IsInt());
648 EXPECT_FALSE(x.IsNull());
649 EXPECT_FALSE(x.IsBool());
650 EXPECT_FALSE(x.IsFalse());
651 EXPECT_FALSE(x.IsTrue());
652 EXPECT_FALSE(x.IsString());
653 EXPECT_FALSE(x.IsObject());
654 EXPECT_FALSE(x.IsArray());
659 EXPECT_NEAR(12.34f, z.GetFloat(), 0.0f);
663 EXPECT_EQ(0.0f, z.GetFloat());
666 EXPECT_NEAR(56.78f, z.GetFloat(), 0.0f);
668 // Templated functions
669 EXPECT_TRUE(z.Is<float>());
670 EXPECT_EQ(56.78f, z.Get<float>());
671 EXPECT_EQ(57.78f, z.Set(57.78f).Get<float>());
672 EXPECT_EQ(58.78f, z.Set<float>(58.78f).Get<float>());
675 TEST(Value, IsLosslessDouble) {
676 EXPECT_TRUE(Value(0.0).IsLosslessDouble());
677 EXPECT_TRUE(Value(12.34).IsLosslessDouble());
678 EXPECT_TRUE(Value(-123).IsLosslessDouble());
679 EXPECT_TRUE(Value(2147483648u).IsLosslessDouble());
680 EXPECT_TRUE(Value(-static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x40000000, 0x00000000))).IsLosslessDouble());
681 #if !(defined(_MSC_VER) && _MSC_VER < 1800) // VC2010 has problem
682 EXPECT_TRUE(Value(RAPIDJSON_UINT64_C2(0xA0000000, 0x00000000)).IsLosslessDouble());
685 EXPECT_FALSE(Value(static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x7FFFFFFF, 0xFFFFFFFF))).IsLosslessDouble()); // INT64_MAX
686 EXPECT_FALSE(Value(-static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x7FFFFFFF, 0xFFFFFFFF))).IsLosslessDouble()); // -INT64_MAX
687 EXPECT_TRUE(Value(-static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x7FFFFFFF, 0xFFFFFFFF)) - 1).IsLosslessDouble()); // INT64_MIN
688 EXPECT_FALSE(Value(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0xFFFFFFFF)).IsLosslessDouble()); // UINT64_MAX
690 EXPECT_TRUE(Value(3.4028234e38f).IsLosslessDouble()); // FLT_MAX
691 EXPECT_TRUE(Value(-3.4028234e38f).IsLosslessDouble()); // -FLT_MAX
692 EXPECT_TRUE(Value(1.17549435e-38f).IsLosslessDouble()); // FLT_MIN
693 EXPECT_TRUE(Value(-1.17549435e-38f).IsLosslessDouble()); // -FLT_MIN
694 EXPECT_TRUE(Value(1.7976931348623157e+308).IsLosslessDouble()); // DBL_MAX
695 EXPECT_TRUE(Value(-1.7976931348623157e+308).IsLosslessDouble()); // -DBL_MAX
696 EXPECT_TRUE(Value(2.2250738585072014e-308).IsLosslessDouble()); // DBL_MIN
697 EXPECT_TRUE(Value(-2.2250738585072014e-308).IsLosslessDouble()); // -DBL_MIN
700 TEST(Value, IsLosslessFloat) {
701 EXPECT_TRUE(Value(12.25).IsLosslessFloat());
702 EXPECT_TRUE(Value(-123).IsLosslessFloat());
703 EXPECT_TRUE(Value(2147483648u).IsLosslessFloat());
704 EXPECT_TRUE(Value(3.4028234e38f).IsLosslessFloat());
705 EXPECT_TRUE(Value(-3.4028234e38f).IsLosslessFloat());
706 EXPECT_FALSE(Value(3.4028235e38).IsLosslessFloat());
707 EXPECT_FALSE(Value(0.3).IsLosslessFloat());
710 TEST(Value, String) {
711 // Construction with const string
712 Value x("Hello", 5); // literal
713 EXPECT_EQ(kStringType, x.GetType());
714 EXPECT_TRUE(x.IsString());
715 EXPECT_STREQ("Hello", x.GetString());
716 EXPECT_EQ(5u, x.GetStringLength());
718 EXPECT_FALSE(x.IsNumber());
719 EXPECT_FALSE(x.IsNull());
720 EXPECT_FALSE(x.IsBool());
721 EXPECT_FALSE(x.IsFalse());
722 EXPECT_FALSE(x.IsTrue());
723 EXPECT_FALSE(x.IsObject());
724 EXPECT_FALSE(x.IsArray());
726 static const char cstr[] = "World"; // const array
728 EXPECT_TRUE(x.IsString());
729 EXPECT_EQ(x.GetString(), cstr);
730 EXPECT_EQ(x.GetStringLength(), sizeof(cstr)-1);
732 static char mstr[] = "Howdy"; // non-const array
733 // Value(mstr).Swap(x); // should not compile
734 Value(StringRef(mstr)).Swap(x);
735 EXPECT_TRUE(x.IsString());
736 EXPECT_EQ(x.GetString(), mstr);
737 EXPECT_EQ(x.GetStringLength(), sizeof(mstr)-1);
738 strncpy(mstr,"Hello", sizeof(mstr));
739 EXPECT_STREQ(x.GetString(), "Hello");
741 const char* pstr = cstr;
742 //Value(pstr).Swap(x); // should not compile
743 Value(StringRef(pstr)).Swap(x);
744 EXPECT_TRUE(x.IsString());
745 EXPECT_EQ(x.GetString(), cstr);
746 EXPECT_EQ(x.GetStringLength(), sizeof(cstr)-1);
749 Value(StringRef(mpstr,sizeof(mstr)-1)).Swap(x);
750 EXPECT_TRUE(x.IsString());
751 EXPECT_EQ(x.GetString(), mstr);
752 EXPECT_EQ(x.GetStringLength(), 5u);
753 EXPECT_STREQ(x.GetString(), "Hello");
755 // Constructor with copy string
756 MemoryPoolAllocator<> allocator;
757 Value c(x.GetString(), x.GetStringLength(), allocator);
758 EXPECT_NE(x.GetString(), c.GetString());
759 EXPECT_EQ(x.GetStringLength(), c.GetStringLength());
760 EXPECT_STREQ(x.GetString(), c.GetString());
761 //x.SetString("World");
762 x.SetString("World", 5);
763 EXPECT_STREQ("Hello", c.GetString());
764 EXPECT_EQ(5u, c.GetStringLength());
766 // Constructor with type
767 Value y(kStringType);
768 EXPECT_TRUE(y.IsString());
769 EXPECT_STREQ("", y.GetString()); // Empty string should be "" instead of 0 (issue 226)
770 EXPECT_EQ(0u, y.GetStringLength());
774 z.SetString("Hello");
775 EXPECT_TRUE(x.IsString());
776 z.SetString("Hello", 5);
777 EXPECT_STREQ("Hello", z.GetString());
778 EXPECT_STREQ("Hello", z.GetString());
779 EXPECT_EQ(5u, z.GetStringLength());
781 z.SetString("Hello");
782 EXPECT_TRUE(z.IsString());
783 EXPECT_STREQ("Hello", z.GetString());
785 //z.SetString(mstr); // should not compile
786 //z.SetString(pstr); // should not compile
787 z.SetString(StringRef(mstr));
788 EXPECT_TRUE(z.IsString());
789 EXPECT_STREQ(z.GetString(), mstr);
792 EXPECT_TRUE(z.IsString());
793 EXPECT_EQ(cstr, z.GetString());
796 EXPECT_TRUE(z.IsString());
797 EXPECT_EQ(cstr, z.GetString());
802 w.SetString(s, static_cast<SizeType>(strlen(s)), allocator);
804 EXPECT_STREQ("World", w.GetString());
805 EXPECT_EQ(5u, w.GetStringLength());
807 // templated functions
808 EXPECT_TRUE(z.Is<const char*>());
809 EXPECT_STREQ(cstr, z.Get<const char*>());
810 EXPECT_STREQ("Apple", z.Set<const char*>("Apple").Get<const char*>());
812 #if RAPIDJSON_HAS_STDSTRING
814 std::string str = "Hello World";
816 EXPECT_STREQ(str.data(),"Hello"); // embedded '\0'
817 EXPECT_EQ(str.size(), 11u);
820 Value vs0(StringRef(str));
821 EXPECT_TRUE(vs0.IsString());
822 EXPECT_EQ(vs0.GetString(), str.data());
823 EXPECT_EQ(vs0.GetStringLength(), str.size());
827 Value vs1(str, allocator);
828 EXPECT_TRUE(vs1.IsString());
829 EXPECT_NE(vs1.GetString(), str.data());
830 EXPECT_NE(vs1.GetString(), str); // not equal due to embedded '\0'
831 EXPECT_EQ(vs1.GetStringLength(), str.size());
836 vs0.SetNull().SetString(str, allocator);
837 EXPECT_TRUE(vs0.IsString());
838 EXPECT_STREQ(vs0.GetString(), str.c_str());
839 EXPECT_EQ(vs0.GetStringLength(), str.size());
841 TestUnequal(str, vs1);
843 // vs1 = str; // should not compile
844 vs1 = StringRef(str);
848 // Templated function.
849 EXPECT_TRUE(vs0.Is<std::string>());
850 EXPECT_EQ(str, vs0.Get<std::string>());
851 vs0.Set<std::string>(std::string("Apple"), allocator);
852 EXPECT_EQ(std::string("Apple"), vs0.Get<std::string>());
853 vs0.Set(std::string("Orange"), allocator);
854 EXPECT_EQ(std::string("Orange"), vs0.Get<std::string>());
856 #endif // RAPIDJSON_HAS_STDSTRING
859 // Issue 226: Value of string type should not point to NULL
860 TEST(Value, SetStringNullException) {
862 EXPECT_THROW(v.SetString(0, 0), AssertException);
865 template <typename T, typename Allocator>
866 static void TestArray(T& x, Allocator& allocator) {
871 x.PushBack(v, allocator);
873 x.PushBack(v, allocator);
875 x.PushBack(v, allocator);
877 x.PushBack(v, allocator);
878 //x.PushBack((const char*)"foo", allocator); // should not compile
879 x.PushBack("foo", allocator);
881 EXPECT_FALSE(x.Empty());
882 EXPECT_EQ(5u, x.Size());
883 EXPECT_FALSE(y.Empty());
884 EXPECT_EQ(5u, y.Size());
885 EXPECT_TRUE(x[SizeType(0)].IsNull());
886 EXPECT_TRUE(x[1].IsTrue());
887 EXPECT_TRUE(x[2].IsFalse());
888 EXPECT_TRUE(x[3].IsInt());
889 EXPECT_EQ(123, x[3].GetInt());
890 EXPECT_TRUE(y[SizeType(0)].IsNull());
891 EXPECT_TRUE(y[1].IsTrue());
892 EXPECT_TRUE(y[2].IsFalse());
893 EXPECT_TRUE(y[3].IsInt());
894 EXPECT_EQ(123, y[3].GetInt());
895 EXPECT_TRUE(y[4].IsString());
896 EXPECT_STREQ("foo", y[4].GetString());
898 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
899 // PushBack(GenericValue&&, Allocator&);
901 Value y2(kArrayType);
902 y2.PushBack(Value(true), allocator);
903 y2.PushBack(std::move(Value(kArrayType).PushBack(Value(1), allocator).PushBack("foo", allocator)), allocator);
904 EXPECT_EQ(2u, y2.Size());
905 EXPECT_TRUE(y2[0].IsTrue());
906 EXPECT_TRUE(y2[1].IsArray());
907 EXPECT_EQ(2u, y2[1].Size());
908 EXPECT_TRUE(y2[1][0].IsInt());
909 EXPECT_TRUE(y2[1][1].IsString());
914 typename T::ValueIterator itr = x.Begin();
915 EXPECT_TRUE(itr != x.End());
916 EXPECT_TRUE(itr->IsNull());
918 EXPECT_TRUE(itr != x.End());
919 EXPECT_TRUE(itr->IsTrue());
921 EXPECT_TRUE(itr != x.End());
922 EXPECT_TRUE(itr->IsFalse());
924 EXPECT_TRUE(itr != x.End());
925 EXPECT_TRUE(itr->IsInt());
926 EXPECT_EQ(123, itr->GetInt());
928 EXPECT_TRUE(itr != x.End());
929 EXPECT_TRUE(itr->IsString());
930 EXPECT_STREQ("foo", itr->GetString());
933 typename T::ConstValueIterator citr = y.Begin();
934 EXPECT_TRUE(citr != y.End());
935 EXPECT_TRUE(citr->IsNull());
937 EXPECT_TRUE(citr != y.End());
938 EXPECT_TRUE(citr->IsTrue());
940 EXPECT_TRUE(citr != y.End());
941 EXPECT_TRUE(citr->IsFalse());
943 EXPECT_TRUE(citr != y.End());
944 EXPECT_TRUE(citr->IsInt());
945 EXPECT_EQ(123, citr->GetInt());
947 EXPECT_TRUE(citr != y.End());
948 EXPECT_TRUE(citr->IsString());
949 EXPECT_STREQ("foo", citr->GetString());
953 EXPECT_EQ(4u, x.Size());
954 EXPECT_TRUE(y[SizeType(0)].IsNull());
955 EXPECT_TRUE(y[1].IsTrue());
956 EXPECT_TRUE(y[2].IsFalse());
957 EXPECT_TRUE(y[3].IsInt());
961 EXPECT_TRUE(x.Empty());
962 EXPECT_EQ(0u, x.Size());
963 EXPECT_TRUE(y.Empty());
964 EXPECT_EQ(0u, y.Size());
966 // Erase(ValueIterator)
968 // Use array of array to ensure removed elements' destructor is called.
970 for (int i = 0; i < 10; i++)
971 x.PushBack(Value(kArrayType).PushBack(i, allocator).Move(), allocator);
974 itr = x.Erase(x.Begin());
975 EXPECT_EQ(x.Begin(), itr);
976 EXPECT_EQ(9u, x.Size());
977 for (int i = 0; i < 9; i++)
978 EXPECT_EQ(i + 1, x[static_cast<SizeType>(i)][0].GetInt());
981 itr = x.Erase(x.End() - 1);
982 EXPECT_EQ(x.End(), itr);
983 EXPECT_EQ(8u, x.Size());
984 for (int i = 0; i < 8; i++)
985 EXPECT_EQ(i + 1, x[static_cast<SizeType>(i)][0].GetInt());
988 itr = x.Erase(x.Begin() + 4);
989 EXPECT_EQ(x.Begin() + 4, itr);
990 EXPECT_EQ(7u, x.Size());
991 for (int i = 0; i < 4; i++)
992 EXPECT_EQ(i + 1, x[static_cast<SizeType>(i)][0].GetInt());
993 for (int i = 4; i < 7; i++)
994 EXPECT_EQ(i + 2, x[static_cast<SizeType>(i)][0].GetInt());
996 // Erase(ValueIterator, ValueIterator)
997 // Exhaustive test with all 0 <= first < n, first <= last <= n cases
998 const unsigned n = 10;
999 for (unsigned first = 0; first < n; first++) {
1000 for (unsigned last = first; last <= n; last++) {
1002 for (unsigned i = 0; i < n; i++)
1003 x.PushBack(Value(kArrayType).PushBack(i, allocator).Move(), allocator);
1005 itr = x.Erase(x.Begin() + first, x.Begin() + last);
1007 EXPECT_EQ(x.End(), itr);
1009 EXPECT_EQ(x.Begin() + first, itr);
1011 size_t removeCount = last - first;
1012 EXPECT_EQ(n - removeCount, x.Size());
1013 for (unsigned i = 0; i < first; i++)
1014 EXPECT_EQ(i, x[i][0].GetUint());
1015 for (unsigned i = first; i < n - removeCount; i++)
1016 EXPECT_EQ(i + removeCount, x[static_cast<SizeType>(i)][0].GetUint());
1021 TEST(Value, Array) {
1022 Value x(kArrayType);
1024 Value::AllocatorType allocator;
1026 EXPECT_EQ(kArrayType, x.GetType());
1027 EXPECT_TRUE(x.IsArray());
1028 EXPECT_TRUE(x.Empty());
1029 EXPECT_EQ(0u, x.Size());
1030 EXPECT_TRUE(y.IsArray());
1031 EXPECT_TRUE(y.Empty());
1032 EXPECT_EQ(0u, y.Size());
1034 EXPECT_FALSE(x.IsNull());
1035 EXPECT_FALSE(x.IsBool());
1036 EXPECT_FALSE(x.IsFalse());
1037 EXPECT_FALSE(x.IsTrue());
1038 EXPECT_FALSE(x.IsString());
1039 EXPECT_FALSE(x.IsObject());
1041 TestArray(x, allocator);
1043 // Working in gcc without C++11, but VS2013 cannot compile. To be diagnosed.
1044 // http://en.wikipedia.org/wiki/Erase-remove_idiom
1046 for (int i = 0; i < 10; i++)
1048 x.PushBack(i, allocator);
1050 x.PushBack(Value(kNullType).Move(), allocator);
1052 const Value null(kNullType);
1053 x.Erase(std::remove(x.Begin(), x.End(), null), x.End());
1054 EXPECT_EQ(5u, x.Size());
1055 for (int i = 0; i < 5; i++)
1056 EXPECT_EQ(i * 2, x[static_cast<SizeType>(i)]);
1061 EXPECT_TRUE(z.IsArray());
1062 EXPECT_TRUE(z.Empty());
1065 TEST(Value, ArrayHelper) {
1066 Value::AllocatorType allocator;
1068 Value x(kArrayType);
1069 Value::Array a = x.GetArray();
1070 TestArray(a, allocator);
1074 Value x(kArrayType);
1075 Value::Array a = x.GetArray();
1076 a.PushBack(1, allocator);
1078 Value::Array a2(a); // copy constructor
1079 EXPECT_EQ(1, a2.Size());
1081 Value::Array a3 = a;
1082 EXPECT_EQ(1, a3.Size());
1084 Value::ConstArray y = static_cast<const Value&>(x).GetArray();
1086 // y.PushBack(1, allocator); // should not compile
1088 // Templated functions
1090 EXPECT_TRUE(x.Is<Value::Array>());
1091 EXPECT_TRUE(x.Is<Value::ConstArray>());
1092 a.PushBack(1, allocator);
1093 EXPECT_EQ(1, x.Get<Value::Array>()[0].GetInt());
1094 EXPECT_EQ(1, x.Get<Value::ConstArray>()[0].GetInt());
1097 x2.Set<Value::Array>(a);
1098 EXPECT_TRUE(x.IsArray()); // IsArray() is invariant after moving.
1099 EXPECT_EQ(1, x2.Get<Value::Array>()[0].GetInt());
1103 Value y(kArrayType);
1104 y.PushBack(123, allocator);
1106 Value x(y.GetArray()); // Construct value form array.
1107 EXPECT_TRUE(x.IsArray());
1108 EXPECT_EQ(123, x[0].GetInt());
1109 EXPECT_TRUE(y.IsArray()); // Invariant
1110 EXPECT_TRUE(y.Empty());
1114 Value x(kArrayType);
1115 Value y(kArrayType);
1116 y.PushBack(123, allocator);
1117 x.PushBack(y.GetArray(), allocator); // Implicit constructor to convert Array to GenericValue
1119 EXPECT_EQ(1, x.Size());
1120 EXPECT_EQ(123, x[0][0].GetInt());
1121 EXPECT_TRUE(y.IsArray());
1122 EXPECT_TRUE(y.Empty());
1126 #if RAPIDJSON_HAS_CXX11_RANGE_FOR
1127 TEST(Value, ArrayHelperRangeFor) {
1128 Value::AllocatorType allocator;
1129 Value x(kArrayType);
1131 for (int i = 0; i < 10; i++)
1132 x.PushBack(i, allocator);
1136 for (auto& v : x.GetArray()) {
1137 EXPECT_EQ(i, v.GetInt());
1144 for (const auto& v : const_cast<const Value&>(x).GetArray()) {
1145 EXPECT_EQ(i, v.GetInt());
1151 // Array a = x.GetArray();
1152 // Array ca = const_cast<const Value&>(x).GetArray();
1156 template <typename T, typename Allocator>
1157 static void TestObject(T& x, Allocator& allocator) {
1158 const T& y = x; // const version
1161 x.AddMember("A", "Apple", allocator);
1162 EXPECT_FALSE(x.ObjectEmpty());
1163 EXPECT_EQ(1u, x.MemberCount());
1165 Value value("Banana", 6);
1166 x.AddMember("B", "Banana", allocator);
1167 EXPECT_EQ(2u, x.MemberCount());
1169 // AddMember<T>(StringRefType, T, Allocator)
1171 Value o(kObjectType);
1172 o.AddMember("true", true, allocator);
1173 o.AddMember("false", false, allocator);
1174 o.AddMember("int", -1, allocator);
1175 o.AddMember("uint", 1u, allocator);
1176 o.AddMember("int64", int64_t(-4294967296), allocator);
1177 o.AddMember("uint64", uint64_t(4294967296), allocator);
1178 o.AddMember("double", 3.14, allocator);
1179 o.AddMember("string", "Jelly", allocator);
1181 EXPECT_TRUE(o["true"].GetBool());
1182 EXPECT_FALSE(o["false"].GetBool());
1183 EXPECT_EQ(-1, o["int"].GetInt());
1184 EXPECT_EQ(1u, o["uint"].GetUint());
1185 EXPECT_EQ(int64_t(-4294967296), o["int64"].GetInt64());
1186 EXPECT_EQ(uint64_t(4294967296), o["uint64"].GetUint64());
1187 EXPECT_STREQ("Jelly",o["string"].GetString());
1188 EXPECT_EQ(8u, o.MemberCount());
1191 // AddMember<T>(Value&, T, Allocator)
1193 Value o(kObjectType);
1196 o.AddMember(n, "string", allocator);
1197 EXPECT_EQ(1u, o.MemberCount());
1200 o.AddMember(count, o.MemberCount(), allocator);
1201 EXPECT_EQ(2u, o.MemberCount());
1204 #if RAPIDJSON_HAS_STDSTRING
1206 // AddMember(StringRefType, const std::string&, Allocator)
1207 Value o(kObjectType);
1208 o.AddMember("b", std::string("Banana"), allocator);
1209 EXPECT_STREQ("Banana", o["b"].GetString());
1211 // RemoveMember(const std::string&)
1212 o.RemoveMember(std::string("b"));
1213 EXPECT_TRUE(o.ObjectEmpty());
1217 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1218 // AddMember(GenericValue&&, ...) variants
1220 Value o(kObjectType);
1221 o.AddMember(Value("true"), Value(true), allocator);
1222 o.AddMember(Value("false"), Value(false).Move(), allocator); // value is lvalue ref
1223 o.AddMember(Value("int").Move(), Value(-1), allocator); // name is lvalue ref
1224 o.AddMember("uint", std::move(Value().SetUint(1u)), allocator); // name is literal, value is rvalue
1225 EXPECT_TRUE(o["true"].GetBool());
1226 EXPECT_FALSE(o["false"].GetBool());
1227 EXPECT_EQ(-1, o["int"].GetInt());
1228 EXPECT_EQ(1u, o["uint"].GetUint());
1229 EXPECT_EQ(4u, o.MemberCount());
1233 // Tests a member with null character
1235 const Value C0D("C\0D", 3);
1236 name.SetString(C0D.GetString(), 3);
1237 value.SetString("CherryD", 7);
1238 x.AddMember(name, value, allocator);
1241 EXPECT_TRUE(x.HasMember("A"));
1242 EXPECT_TRUE(x.HasMember("B"));
1243 EXPECT_TRUE(y.HasMember("A"));
1244 EXPECT_TRUE(y.HasMember("B"));
1246 #if RAPIDJSON_HAS_STDSTRING
1247 EXPECT_TRUE(x.HasMember(std::string("A")));
1250 name.SetString("C\0D");
1251 EXPECT_TRUE(x.HasMember(name));
1252 EXPECT_TRUE(y.HasMember(name));
1254 GenericValue<UTF8<>, CrtAllocator> othername("A");
1255 EXPECT_TRUE(x.HasMember(othername));
1256 EXPECT_TRUE(y.HasMember(othername));
1257 othername.SetString("C\0D");
1258 EXPECT_TRUE(x.HasMember(othername));
1259 EXPECT_TRUE(y.HasMember(othername));
1262 EXPECT_STREQ("Apple", x["A"].GetString());
1263 EXPECT_STREQ("Banana", x["B"].GetString());
1264 EXPECT_STREQ("CherryD", x[C0D].GetString());
1265 EXPECT_STREQ("CherryD", x[othername].GetString());
1266 EXPECT_THROW(x["nonexist"], AssertException);
1269 EXPECT_STREQ("Apple", y["A"].GetString());
1270 EXPECT_STREQ("Banana", y["B"].GetString());
1271 EXPECT_STREQ("CherryD", y[C0D].GetString());
1273 #if RAPIDJSON_HAS_STDSTRING
1274 EXPECT_STREQ("Apple", x["A"].GetString());
1275 EXPECT_STREQ("Apple", y[std::string("A")].GetString());
1279 Value::MemberIterator itr = x.MemberBegin();
1280 EXPECT_TRUE(itr != x.MemberEnd());
1281 EXPECT_STREQ("A", itr->name.GetString());
1282 EXPECT_STREQ("Apple", itr->value.GetString());
1284 EXPECT_TRUE(itr != x.MemberEnd());
1285 EXPECT_STREQ("B", itr->name.GetString());
1286 EXPECT_STREQ("Banana", itr->value.GetString());
1288 EXPECT_TRUE(itr != x.MemberEnd());
1289 EXPECT_TRUE(memcmp(itr->name.GetString(), "C\0D", 4) == 0);
1290 EXPECT_STREQ("CherryD", itr->value.GetString());
1292 EXPECT_FALSE(itr != x.MemberEnd());
1294 // const member iterator
1295 Value::ConstMemberIterator citr = y.MemberBegin();
1296 EXPECT_TRUE(citr != y.MemberEnd());
1297 EXPECT_STREQ("A", citr->name.GetString());
1298 EXPECT_STREQ("Apple", citr->value.GetString());
1300 EXPECT_TRUE(citr != y.MemberEnd());
1301 EXPECT_STREQ("B", citr->name.GetString());
1302 EXPECT_STREQ("Banana", citr->value.GetString());
1304 EXPECT_TRUE(citr != y.MemberEnd());
1305 EXPECT_TRUE(memcmp(citr->name.GetString(), "C\0D", 4) == 0);
1306 EXPECT_STREQ("CherryD", citr->value.GetString());
1308 EXPECT_FALSE(citr != y.MemberEnd());
1310 // member iterator conversions/relations
1311 itr = x.MemberBegin();
1312 citr = x.MemberBegin(); // const conversion
1313 TestEqual(itr, citr);
1314 EXPECT_TRUE(itr < x.MemberEnd());
1315 EXPECT_FALSE(itr > y.MemberEnd());
1316 EXPECT_TRUE(citr < x.MemberEnd());
1317 EXPECT_FALSE(citr > y.MemberEnd());
1319 TestUnequal(itr, citr);
1320 EXPECT_FALSE(itr < itr);
1321 EXPECT_TRUE(itr < citr);
1322 EXPECT_FALSE(itr > itr);
1323 EXPECT_TRUE(citr > itr);
1324 EXPECT_EQ(1, citr - x.MemberBegin());
1325 EXPECT_EQ(0, itr - y.MemberBegin());
1326 itr += citr - x.MemberBegin();
1327 EXPECT_EQ(1, itr - y.MemberBegin());
1328 TestEqual(citr, itr);
1329 EXPECT_TRUE(itr <= citr);
1330 EXPECT_TRUE(citr <= itr);
1332 EXPECT_TRUE(itr >= citr);
1333 EXPECT_FALSE(citr >= itr);
1336 EXPECT_TRUE(x.RemoveMember("A"));
1337 EXPECT_FALSE(x.HasMember("A"));
1339 EXPECT_TRUE(x.RemoveMember("B"));
1340 EXPECT_FALSE(x.HasMember("B"));
1342 EXPECT_FALSE(x.RemoveMember("nonexist"));
1344 EXPECT_TRUE(x.RemoveMember(othername));
1345 EXPECT_FALSE(x.HasMember(name));
1347 EXPECT_TRUE(x.MemberBegin() == x.MemberEnd());
1349 // EraseMember(ConstMemberIterator)
1351 // Use array members to ensure removed elements' destructor is called.
1352 // { "a": [0], "b": [1],[2],...]
1353 const char keys[][2] = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j" };
1354 for (int i = 0; i < 10; i++)
1355 x.AddMember(keys[i], Value(kArrayType).PushBack(i, allocator), allocator);
1357 // MemberCount, iterator difference
1358 EXPECT_EQ(x.MemberCount(), SizeType(x.MemberEnd() - x.MemberBegin()));
1361 itr = x.EraseMember(x.MemberBegin());
1362 EXPECT_FALSE(x.HasMember(keys[0]));
1363 EXPECT_EQ(x.MemberBegin(), itr);
1364 EXPECT_EQ(9u, x.MemberCount());
1365 for (; itr != x.MemberEnd(); ++itr) {
1366 size_t i = static_cast<size_t>((itr - x.MemberBegin())) + 1;
1367 EXPECT_STREQ(itr->name.GetString(), keys[i]);
1368 EXPECT_EQ(i, itr->value[0].GetInt());
1372 itr = x.EraseMember(x.MemberEnd() - 1);
1373 EXPECT_FALSE(x.HasMember(keys[9]));
1374 EXPECT_EQ(x.MemberEnd(), itr);
1375 EXPECT_EQ(8u, x.MemberCount());
1376 for (; itr != x.MemberEnd(); ++itr) {
1377 size_t i = static_cast<size_t>(itr - x.MemberBegin()) + 1;
1378 EXPECT_STREQ(itr->name.GetString(), keys[i]);
1379 EXPECT_EQ(i, itr->value[0].GetInt());
1383 itr = x.EraseMember(x.MemberBegin() + 4);
1384 EXPECT_FALSE(x.HasMember(keys[5]));
1385 EXPECT_EQ(x.MemberBegin() + 4, itr);
1386 EXPECT_EQ(7u, x.MemberCount());
1387 for (; itr != x.MemberEnd(); ++itr) {
1388 size_t i = static_cast<size_t>(itr - x.MemberBegin());
1389 i += (i < 4) ? 1 : 2;
1390 EXPECT_STREQ(itr->name.GetString(), keys[i]);
1391 EXPECT_EQ(i, itr->value[0].GetInt());
1394 // EraseMember(ConstMemberIterator, ConstMemberIterator)
1395 // Exhaustive test with all 0 <= first < n, first <= last <= n cases
1396 const unsigned n = 10;
1397 for (unsigned first = 0; first < n; first++) {
1398 for (unsigned last = first; last <= n; last++) {
1399 x.RemoveAllMembers();
1400 for (unsigned i = 0; i < n; i++)
1401 x.AddMember(keys[i], Value(kArrayType).PushBack(i, allocator), allocator);
1403 itr = x.EraseMember(x.MemberBegin() + static_cast<int>(first), x.MemberBegin() + static_cast<int>(last));
1405 EXPECT_EQ(x.MemberEnd(), itr);
1407 EXPECT_EQ(x.MemberBegin() + static_cast<int>(first), itr);
1409 size_t removeCount = last - first;
1410 EXPECT_EQ(n - removeCount, x.MemberCount());
1411 for (unsigned i = 0; i < first; i++)
1412 EXPECT_EQ(i, x[keys[i]][0].GetUint());
1413 for (unsigned i = first; i < n - removeCount; i++)
1414 EXPECT_EQ(i + removeCount, x[keys[i+removeCount]][0].GetUint());
1418 // RemoveAllMembers()
1419 x.RemoveAllMembers();
1420 EXPECT_TRUE(x.ObjectEmpty());
1421 EXPECT_EQ(0u, x.MemberCount());
1424 TEST(Value, Object) {
1425 Value x(kObjectType);
1426 const Value& y = x; // const version
1427 Value::AllocatorType allocator;
1429 EXPECT_EQ(kObjectType, x.GetType());
1430 EXPECT_TRUE(x.IsObject());
1431 EXPECT_TRUE(x.ObjectEmpty());
1432 EXPECT_EQ(0u, x.MemberCount());
1433 EXPECT_EQ(kObjectType, y.GetType());
1434 EXPECT_TRUE(y.IsObject());
1435 EXPECT_TRUE(y.ObjectEmpty());
1436 EXPECT_EQ(0u, y.MemberCount());
1438 TestObject(x, allocator);
1443 EXPECT_TRUE(z.IsObject());
1446 TEST(Value, ObjectHelper) {
1447 Value::AllocatorType allocator;
1449 Value x(kObjectType);
1450 Value::Object o = x.GetObject();
1451 TestObject(o, allocator);
1455 Value x(kObjectType);
1456 Value::Object o = x.GetObject();
1457 o.AddMember("1", 1, allocator);
1459 Value::Object o2(o); // copy constructor
1460 EXPECT_EQ(1, o2.MemberCount());
1462 Value::Object o3 = o;
1463 EXPECT_EQ(1, o3.MemberCount());
1465 Value::ConstObject y = static_cast<const Value&>(x).GetObject();
1467 // y.AddMember("1", 1, allocator); // should not compile
1469 // Templated functions
1470 x.RemoveAllMembers();
1471 EXPECT_TRUE(x.Is<Value::Object>());
1472 EXPECT_TRUE(x.Is<Value::ConstObject>());
1473 o.AddMember("1", 1, allocator);
1474 EXPECT_EQ(1, x.Get<Value::Object>()["1"].GetInt());
1475 EXPECT_EQ(1, x.Get<Value::ConstObject>()["1"].GetInt());
1478 x2.Set<Value::Object>(o);
1479 EXPECT_TRUE(x.IsObject()); // IsObject() is invariant after moving
1480 EXPECT_EQ(1, x2.Get<Value::Object>()["1"].GetInt());
1484 Value x(kObjectType);
1485 x.AddMember("a", "apple", allocator);
1486 Value y(x.GetObject());
1487 EXPECT_STREQ("apple", y["a"].GetString());
1488 EXPECT_TRUE(x.IsObject()); // Invariant
1492 Value x(kObjectType);
1493 x.AddMember("a", "apple", allocator);
1494 Value y(kObjectType);
1495 y.AddMember("fruits", x.GetObject(), allocator);
1496 EXPECT_STREQ("apple", y["fruits"]["a"].GetString());
1497 EXPECT_TRUE(x.IsObject()); // Invariant
1501 #if RAPIDJSON_HAS_CXX11_RANGE_FOR
1502 TEST(Value, ObjectHelperRangeFor) {
1503 Value::AllocatorType allocator;
1504 Value x(kObjectType);
1506 for (int i = 0; i < 10; i++) {
1508 Value n(name, static_cast<SizeType>(sprintf(name, "%d", i)), allocator);
1509 x.AddMember(n, i, allocator);
1514 for (auto& m : x.GetObject()) {
1516 sprintf(name, "%d", i);
1517 EXPECT_STREQ(name, m.name.GetString());
1518 EXPECT_EQ(i, m.value.GetInt());
1525 for (const auto& m : const_cast<const Value&>(x).GetObject()) {
1527 sprintf(name, "%d", i);
1528 EXPECT_STREQ(name, m.name.GetString());
1529 EXPECT_EQ(i, m.value.GetInt());
1535 // Object a = x.GetObject();
1536 // Object ca = const_cast<const Value&>(x).GetObject();
1540 TEST(Value, EraseMember_String) {
1541 Value::AllocatorType allocator;
1542 Value x(kObjectType);
1543 x.AddMember("A", "Apple", allocator);
1544 x.AddMember("B", "Banana", allocator);
1546 EXPECT_TRUE(x.EraseMember("B"));
1547 EXPECT_FALSE(x.HasMember("B"));
1549 EXPECT_FALSE(x.EraseMember("nonexist"));
1551 GenericValue<UTF8<>, CrtAllocator> othername("A");
1552 EXPECT_TRUE(x.EraseMember(othername));
1553 EXPECT_FALSE(x.HasMember("A"));
1555 EXPECT_TRUE(x.MemberBegin() == x.MemberEnd());
1558 TEST(Value, BigNestedArray) {
1559 MemoryPoolAllocator<> allocator;
1560 Value x(kArrayType);
1561 static const SizeType n = 200;
1563 for (SizeType i = 0; i < n; i++) {
1564 Value y(kArrayType);
1565 for (SizeType j = 0; j < n; j++) {
1566 Value number(static_cast<int>(i * n + j));
1567 y.PushBack(number, allocator);
1569 x.PushBack(y, allocator);
1572 for (SizeType i = 0; i < n; i++)
1573 for (SizeType j = 0; j < n; j++) {
1574 EXPECT_TRUE(x[i][j].IsInt());
1575 EXPECT_EQ(static_cast<int>(i * n + j), x[i][j].GetInt());
1579 TEST(Value, BigNestedObject) {
1580 MemoryPoolAllocator<> allocator;
1581 Value x(kObjectType);
1582 static const SizeType n = 200;
1584 for (SizeType i = 0; i < n; i++) {
1586 sprintf(name1, "%d", i);
1588 // Value name(name1); // should not compile
1589 Value name(name1, static_cast<SizeType>(strlen(name1)), allocator);
1590 Value object(kObjectType);
1592 for (SizeType j = 0; j < n; j++) {
1594 sprintf(name2, "%d", j);
1596 Value name3(name2, static_cast<SizeType>(strlen(name2)), allocator);
1597 Value number(static_cast<int>(i * n + j));
1598 object.AddMember(name3, number, allocator);
1601 // x.AddMember(name1, object, allocator); // should not compile
1602 x.AddMember(name, object, allocator);
1605 for (SizeType i = 0; i < n; i++) {
1607 sprintf(name1, "%d", i);
1609 for (SizeType j = 0; j < n; j++) {
1611 sprintf(name2, "%d", j);
1613 EXPECT_EQ(static_cast<int>(i * n + j), x[name1][name2].GetInt());
1618 // Issue 18: Error removing last element of object
1619 // http://code.google.com/p/rapidjson/issues/detail?id=18
1620 TEST(Value, RemoveLastElement) {
1621 rapidjson::Document doc;
1622 rapidjson::Document::AllocatorType& allocator = doc.GetAllocator();
1623 rapidjson::Value objVal(rapidjson::kObjectType);
1624 objVal.AddMember("var1", 123, allocator);
1625 objVal.AddMember("var2", "444", allocator);
1626 objVal.AddMember("var3", 555, allocator);
1627 EXPECT_TRUE(objVal.HasMember("var3"));
1628 objVal.RemoveMember("var3"); // Assertion here in r61
1629 EXPECT_FALSE(objVal.HasMember("var3"));
1632 // Issue 38: Segmentation fault with CrtAllocator
1633 TEST(Document, CrtAllocator) {
1634 typedef GenericValue<UTF8<>, CrtAllocator> V;
1636 V::AllocatorType allocator;
1638 o.AddMember("x", 1, allocator); // Should not call destructor on uninitialized name/value of newly allocated members.
1641 a.PushBack(1, allocator); // Should not call destructor on uninitialized Value of newly allocated elements.
1644 static void TestShortStringOptimization(const char* str) {
1645 const rapidjson::SizeType len = static_cast<rapidjson::SizeType>(strlen(str));
1647 rapidjson::Document doc;
1648 rapidjson::Value val;
1649 val.SetString(str, len, doc.GetAllocator());
1651 EXPECT_EQ(val.GetStringLength(), len);
1652 EXPECT_STREQ(val.GetString(), str);
1655 TEST(Value, AllocateShortString) {
1656 TestShortStringOptimization(""); // edge case: empty string
1657 TestShortStringOptimization("12345678"); // regular case for short strings: 8 chars
1658 TestShortStringOptimization("12345678901"); // edge case: 11 chars in 32-bit mode (=> short string)
1659 TestShortStringOptimization("123456789012"); // edge case: 12 chars in 32-bit mode (=> regular string)
1660 TestShortStringOptimization("123456789012345"); // edge case: 15 chars in 64-bit mode (=> short string)
1661 TestShortStringOptimization("1234567890123456"); // edge case: 16 chars in 64-bit mode (=> regular string)
1665 struct TerminateHandler {
1666 bool Null() { return e != 0; }
1667 bool Bool(bool) { return e != 1; }
1668 bool Int(int) { return e != 2; }
1669 bool Uint(unsigned) { return e != 3; }
1670 bool Int64(int64_t) { return e != 4; }
1671 bool Uint64(uint64_t) { return e != 5; }
1672 bool Double(double) { return e != 6; }
1673 bool RawNumber(const char*, SizeType, bool) { return e != 7; }
1674 bool String(const char*, SizeType, bool) { return e != 8; }
1675 bool StartObject() { return e != 9; }
1676 bool Key(const char*, SizeType, bool) { return e != 10; }
1677 bool EndObject(SizeType) { return e != 11; }
1678 bool StartArray() { return e != 12; }
1679 bool EndArray(SizeType) { return e != 13; }
1682 #define TEST_TERMINATION(e, json)\
1685 EXPECT_FALSE(d.Parse(json).HasParseError()); \
1687 TerminateHandler<e> h;\
1688 EXPECT_FALSE(d.Accept(h));\
1691 TEST(Value, AcceptTerminationByHandler) {
1692 TEST_TERMINATION(0, "[null]");
1693 TEST_TERMINATION(1, "[true]");
1694 TEST_TERMINATION(1, "[false]");
1695 TEST_TERMINATION(2, "[-1]");
1696 TEST_TERMINATION(3, "[2147483648]");
1697 TEST_TERMINATION(4, "[-1234567890123456789]");
1698 TEST_TERMINATION(5, "[9223372036854775808]");
1699 TEST_TERMINATION(6, "[0.5]");
1700 // RawNumber() is never called
1701 TEST_TERMINATION(8, "[\"a\"]");
1702 TEST_TERMINATION(9, "[{}]");
1703 TEST_TERMINATION(10, "[{\"a\":1}]");
1704 TEST_TERMINATION(11, "[{}]");
1705 TEST_TERMINATION(12, "{\"a\":[]}");
1706 TEST_TERMINATION(13, "{\"a\":[]}");
1709 struct ValueIntComparer {
1710 bool operator()(const Value& lhs, const Value& rhs) const {
1711 return lhs.GetInt() < rhs.GetInt();
1715 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1716 TEST(Value, Sorting) {
1717 Value::AllocatorType allocator;
1718 Value a(kArrayType);
1719 a.PushBack(5, allocator);
1720 a.PushBack(1, allocator);
1721 a.PushBack(3, allocator);
1722 std::sort(a.Begin(), a.End(), ValueIntComparer());
1723 EXPECT_EQ(1, a[0].GetInt());
1724 EXPECT_EQ(3, a[1].GetInt());
1725 EXPECT_EQ(5, a[2].GetInt());
1729 // http://stackoverflow.com/questions/35222230/
1731 static void MergeDuplicateKey(Value& v, Value::AllocatorType& a) {
1733 // Convert all key:value into key:[value]
1734 for (Value::MemberIterator itr = v.MemberBegin(); itr != v.MemberEnd(); ++itr)
1735 itr->value = Value(kArrayType).Move().PushBack(itr->value, a);
1737 // Merge arrays if key is duplicated
1738 for (Value::MemberIterator itr = v.MemberBegin(); itr != v.MemberEnd();) {
1739 Value::MemberIterator itr2 = v.FindMember(itr->name);
1741 itr2->value.PushBack(itr->value[0], a);
1742 itr = v.EraseMember(itr);
1748 // Convert key:[values] back to key:value if there is only one value
1749 for (Value::MemberIterator itr = v.MemberBegin(); itr != v.MemberEnd(); ++itr) {
1750 if (itr->value.Size() == 1)
1751 itr->value = itr->value[0];
1752 MergeDuplicateKey(itr->value, a); // Recursion on the value
1755 else if (v.IsArray())
1756 for (Value::ValueIterator itr = v.Begin(); itr != v.End(); ++itr)
1757 MergeDuplicateKey(*itr, a);
1760 TEST(Value, MergeDuplicateKey) {
1786 MergeDuplicateKey(d, d.GetAllocator());