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__
20 RAPIDJSON_DIAG_PUSH
21 RAPIDJSON_DIAG_OFF(c++98-compat)
22 #endif
23 
24 using namespace rapidjson;
25 
26 TEST(Value, Size) {
27  if (sizeof(SizeType) == 4) {
28 #if RAPIDJSON_48BITPOINTER_OPTIMIZATION
29  EXPECT_EQ(16, sizeof(Value));
30 #elif RAPIDJSON_64BIT
31  EXPECT_EQ(24, sizeof(Value));
32 #else
33  EXPECT_EQ(16, sizeof(Value));
34 #endif
35  }
36 }
37 
38 TEST(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 
58 TEST(Value, Traits) {
60  static_assert(std::is_constructible<Value>::value, "");
62 #ifndef _MSC_VER
63  static_assert(!std::is_copy_constructible<Value>::value, "");
64 #endif
66 
67 #ifndef _MSC_VER
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
82 #endif
84 #ifndef _MSC_VER
86 #endif
87 
88  static_assert(std::is_destructible<Value>::value, "");
89 #ifndef _MSC_VER
91 #endif
92 }
93 
94 #endif
95 
96 TEST(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 
121 TEST(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 
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);
170 }
171 
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);
178 }
179 
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);
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 
249 template <typename Value>
250 void TestCopyFrom() {
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 
283 TEST(Value, CopyFrom) {
284  TestCopyFrom<Value>();
285  TestCopyFrom<GenericValue<UTF8<>, CrtAllocator> >();
286 }
287 
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 
304 TEST(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 
327 TEST(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 
358 TEST(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 
384 TEST(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
423  Value y(kNumberType);
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 
444 TEST(Value, Uint) {
445  // Constructor with int
446  Value x(1234u);
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().
458 
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());
468 
469  // SetUint()
470  Value z;
471  z.SetUint(1234);
472  EXPECT_EQ(1234u, z.GetUint());
473 
474  // operator=(unsigned)
475  z = 5678u;
476  EXPECT_EQ(5678u, z.GetUint());
477 
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
482 
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>());
488 }
489 
490 TEST(Value, Int64) {
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());
503 
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());
513 
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());
521 
522  // SetInt64()
523  Value z;
524  z.SetInt64(1234);
525  EXPECT_EQ(1234, z.GetInt64());
526 
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);
531 
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);
536 
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);
540 
541  int64_t i = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 00000000));
542  z.SetInt64(i);
543  EXPECT_DOUBLE_EQ(-9223372036854775808.0, z.GetDouble());
544 
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>());
551 #endif
552 }
553 
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());
567 
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());
577 
578  // SetUint64()
579  Value z;
580  z.SetUint64(1234);
581  EXPECT_EQ(1234u, z.GetUint64());
582 
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());
587 
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());
592 
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());
598 
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>());
604 }
605 
606 TEST(Value, Double) {
607  // Constructor with double
608  Value x(12.34);
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());
613 
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());
622 
623  // SetDouble()
624  Value z;
625  z.SetDouble(12.34);
626  EXPECT_NEAR(12.34, z.GetDouble(), 0.0);
627 
628  z = 56.78;
629  EXPECT_NEAR(56.78, z.GetDouble(), 0.0);
630 
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>());
636 }
637 
638 TEST(Value, Float) {
639  // Constructor with double
640  Value x(12.34f);
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());
646 
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());
655 
656  // SetFloat()
657  Value z;
658  z.SetFloat(12.34f);
659  EXPECT_NEAR(12.34f, z.GetFloat(), 0.0f);
660 
661  // Issue 573
662  z.SetInt(0);
663  EXPECT_EQ(0.0f, z.GetFloat());
664 
665  z = 56.78f;
666  EXPECT_NEAR(56.78f, z.GetFloat(), 0.0f);
667 
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>());
673 }
674 
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());
683 #endif
684 
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
689 
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
698 }
699 
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());
708 }
709 
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());
717 
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());
725 
726  static const char cstr[] = "World"; // const array
727  Value(cstr).Swap(x);
728  EXPECT_TRUE(x.IsString());
729  EXPECT_EQ(x.GetString(), cstr);
730  EXPECT_EQ(x.GetStringLength(), sizeof(cstr)-1);
731 
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");
740 
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);
747 
748  char* mpstr = mstr;
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");
754 
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());
765 
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());
771 
772  // SetConsttring()
773  Value z;
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());
780 
781  z.SetString("Hello");
782  EXPECT_TRUE(z.IsString());
783  EXPECT_STREQ("Hello", z.GetString());
784 
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);
790 
791  z.SetString(cstr);
792  EXPECT_TRUE(z.IsString());
793  EXPECT_EQ(cstr, z.GetString());
794 
795  z = cstr;
796  EXPECT_TRUE(z.IsString());
797  EXPECT_EQ(cstr, z.GetString());
798 
799  // SetString()
800  char s[] = "World";
801  Value w;
802  w.SetString(s, static_cast<SizeType>(strlen(s)), allocator);
803  s[0] = '\0';
804  EXPECT_STREQ("World", w.GetString());
805  EXPECT_EQ(5u, w.GetStringLength());
806 
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*>());
811 
812 #if RAPIDJSON_HAS_STDSTRING
813  {
814  std::string str = "Hello World";
815  str[5] = '\0';
816  EXPECT_STREQ(str.data(),"Hello"); // embedded '\0'
817  EXPECT_EQ(str.size(), 11u);
818 
819  // no copy
820  Value vs0(StringRef(str));
821  EXPECT_TRUE(vs0.IsString());
822  EXPECT_EQ(vs0.GetString(), str.data());
823  EXPECT_EQ(vs0.GetStringLength(), str.size());
824  TestEqual(vs0, str);
825 
826  // do copy
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());
832  TestEqual(vs1, str);
833 
834  // SetString
835  str = "World";
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());
840  TestEqual(str, vs0);
841  TestUnequal(str, vs1);
842 
843  // vs1 = str; // should not compile
844  vs1 = StringRef(str);
845  TestEqual(str, vs1);
846  TestEqual(vs0, vs1);
847 
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>());
855  }
856 #endif // RAPIDJSON_HAS_STDSTRING
857 }
858 
859 // Issue 226: Value of string type should not point to NULL
860 TEST(Value, SetStringNull) {
861 
862  MemoryPoolAllocator<> allocator;
863  const char* nullPtr = 0;
864  {
865  // Construction with string type creates empty string
866  Value v(kStringType);
867  EXPECT_NE(v.GetString(), nullPtr); // non-null string returned
868  EXPECT_EQ(v.GetStringLength(), 0u);
869 
870  // Construction from/setting to null without length not allowed
871  EXPECT_THROW(Value(StringRef(nullPtr)), AssertException);
872  EXPECT_THROW(Value(StringRef(nullPtr), allocator), AssertException);
873  EXPECT_THROW(v.SetString(nullPtr, allocator), AssertException);
874 
875  // Non-empty length with null string is not allowed
876  EXPECT_THROW(v.SetString(nullPtr, 17u), AssertException);
877  EXPECT_THROW(v.SetString(nullPtr, 42u, allocator), AssertException);
878 
879  // Setting to null string with empty length is allowed
880  v.SetString(nullPtr, 0u);
881  EXPECT_NE(v.GetString(), nullPtr); // non-null string returned
882  EXPECT_EQ(v.GetStringLength(), 0u);
883 
884  v.SetNull();
885  v.SetString(nullPtr, 0u, allocator);
886  EXPECT_NE(v.GetString(), nullPtr); // non-null string returned
887  EXPECT_EQ(v.GetStringLength(), 0u);
888  }
889  // Construction with null string and empty length is allowed
890  {
891  Value v(nullPtr,0u);
892  EXPECT_NE(v.GetString(), nullPtr); // non-null string returned
893  EXPECT_EQ(v.GetStringLength(), 0u);
894  }
895  {
896  Value v(nullPtr, 0u, allocator);
897  EXPECT_NE(v.GetString(), nullPtr); // non-null string returned
898  EXPECT_EQ(v.GetStringLength(), 0u);
899  }
900 }
901 
902 template <typename T, typename Allocator>
903 static void TestArray(T& x, Allocator& allocator) {
904  const T& y = x;
905 
906  // PushBack()
907  Value v;
908  x.PushBack(v, allocator);
909  v.SetBool(true);
910  x.PushBack(v, allocator);
911  v.SetBool(false);
912  x.PushBack(v, allocator);
913  v.SetInt(123);
914  x.PushBack(v, allocator);
915  //x.PushBack((const char*)"foo", allocator); // should not compile
916  x.PushBack("foo", allocator);
917 
918  EXPECT_FALSE(x.Empty());
919  EXPECT_EQ(5u, x.Size());
920  EXPECT_FALSE(y.Empty());
921  EXPECT_EQ(5u, y.Size());
922  EXPECT_TRUE(x[SizeType(0)].IsNull());
923  EXPECT_TRUE(x[1].IsTrue());
924  EXPECT_TRUE(x[2].IsFalse());
925  EXPECT_TRUE(x[3].IsInt());
926  EXPECT_EQ(123, x[3].GetInt());
927  EXPECT_TRUE(y[SizeType(0)].IsNull());
928  EXPECT_TRUE(y[1].IsTrue());
929  EXPECT_TRUE(y[2].IsFalse());
930  EXPECT_TRUE(y[3].IsInt());
931  EXPECT_EQ(123, y[3].GetInt());
932  EXPECT_TRUE(y[4].IsString());
933  EXPECT_STREQ("foo", y[4].GetString());
934 
935 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
936  // PushBack(GenericValue&&, Allocator&);
937  {
938  Value y2(kArrayType);
939  y2.PushBack(Value(true), allocator);
940  y2.PushBack(std::move(Value(kArrayType).PushBack(Value(1), allocator).PushBack("foo", allocator)), allocator);
941  EXPECT_EQ(2u, y2.Size());
942  EXPECT_TRUE(y2[0].IsTrue());
943  EXPECT_TRUE(y2[1].IsArray());
944  EXPECT_EQ(2u, y2[1].Size());
945  EXPECT_TRUE(y2[1][0].IsInt());
946  EXPECT_TRUE(y2[1][1].IsString());
947  }
948 #endif
949 
950  // iterator
951  typename T::ValueIterator itr = x.Begin();
952  EXPECT_TRUE(itr != x.End());
953  EXPECT_TRUE(itr->IsNull());
954  ++itr;
955  EXPECT_TRUE(itr != x.End());
956  EXPECT_TRUE(itr->IsTrue());
957  ++itr;
958  EXPECT_TRUE(itr != x.End());
959  EXPECT_TRUE(itr->IsFalse());
960  ++itr;
961  EXPECT_TRUE(itr != x.End());
962  EXPECT_TRUE(itr->IsInt());
963  EXPECT_EQ(123, itr->GetInt());
964  ++itr;
965  EXPECT_TRUE(itr != x.End());
966  EXPECT_TRUE(itr->IsString());
967  EXPECT_STREQ("foo", itr->GetString());
968 
969  // const iterator
970  typename T::ConstValueIterator citr = y.Begin();
971  EXPECT_TRUE(citr != y.End());
972  EXPECT_TRUE(citr->IsNull());
973  ++citr;
974  EXPECT_TRUE(citr != y.End());
975  EXPECT_TRUE(citr->IsTrue());
976  ++citr;
977  EXPECT_TRUE(citr != y.End());
978  EXPECT_TRUE(citr->IsFalse());
979  ++citr;
980  EXPECT_TRUE(citr != y.End());
981  EXPECT_TRUE(citr->IsInt());
982  EXPECT_EQ(123, citr->GetInt());
983  ++citr;
984  EXPECT_TRUE(citr != y.End());
985  EXPECT_TRUE(citr->IsString());
986  EXPECT_STREQ("foo", citr->GetString());
987 
988  // PopBack()
989  x.PopBack();
990  EXPECT_EQ(4u, x.Size());
991  EXPECT_TRUE(y[SizeType(0)].IsNull());
992  EXPECT_TRUE(y[1].IsTrue());
993  EXPECT_TRUE(y[2].IsFalse());
994  EXPECT_TRUE(y[3].IsInt());
995 
996  // Clear()
997  x.Clear();
998  EXPECT_TRUE(x.Empty());
999  EXPECT_EQ(0u, x.Size());
1000  EXPECT_TRUE(y.Empty());
1001  EXPECT_EQ(0u, y.Size());
1002 
1003  // Erase(ValueIterator)
1004 
1005  // Use array of array to ensure removed elements' destructor is called.
1006  // [[0],[1],[2],...]
1007  for (int i = 0; i < 10; i++)
1008  x.PushBack(Value(kArrayType).PushBack(i, allocator).Move(), allocator);
1009 
1010  // Erase the first
1011  itr = x.Erase(x.Begin());
1012  EXPECT_EQ(x.Begin(), itr);
1013  EXPECT_EQ(9u, x.Size());
1014  for (int i = 0; i < 9; i++)
1015  EXPECT_EQ(i + 1, x[static_cast<SizeType>(i)][0].GetInt());
1016 
1017  // Ease the last
1018  itr = x.Erase(x.End() - 1);
1019  EXPECT_EQ(x.End(), itr);
1020  EXPECT_EQ(8u, x.Size());
1021  for (int i = 0; i < 8; i++)
1022  EXPECT_EQ(i + 1, x[static_cast<SizeType>(i)][0].GetInt());
1023 
1024  // Erase the middle
1025  itr = x.Erase(x.Begin() + 4);
1026  EXPECT_EQ(x.Begin() + 4, itr);
1027  EXPECT_EQ(7u, x.Size());
1028  for (int i = 0; i < 4; i++)
1029  EXPECT_EQ(i + 1, x[static_cast<SizeType>(i)][0].GetInt());
1030  for (int i = 4; i < 7; i++)
1031  EXPECT_EQ(i + 2, x[static_cast<SizeType>(i)][0].GetInt());
1032 
1033  // Erase(ValueIterator, ValueIterator)
1034  // Exhaustive test with all 0 <= first < n, first <= last <= n cases
1035  const unsigned n = 10;
1036  for (unsigned first = 0; first < n; first++) {
1037  for (unsigned last = first; last <= n; last++) {
1038  x.Clear();
1039  for (unsigned i = 0; i < n; i++)
1040  x.PushBack(Value(kArrayType).PushBack(i, allocator).Move(), allocator);
1041 
1042  itr = x.Erase(x.Begin() + first, x.Begin() + last);
1043  if (last == n)
1044  EXPECT_EQ(x.End(), itr);
1045  else
1046  EXPECT_EQ(x.Begin() + first, itr);
1047 
1048  size_t removeCount = last - first;
1049  EXPECT_EQ(n - removeCount, x.Size());
1050  for (unsigned i = 0; i < first; i++)
1051  EXPECT_EQ(i, x[i][0].GetUint());
1052  for (unsigned i = first; i < n - removeCount; i++)
1053  EXPECT_EQ(i + removeCount, x[static_cast<SizeType>(i)][0].GetUint());
1054  }
1055  }
1056 }
1057 
1058 TEST(Value, Array) {
1059  Value x(kArrayType);
1060  const Value& y = x;
1061  Value::AllocatorType allocator;
1062 
1063  EXPECT_EQ(kArrayType, x.GetType());
1064  EXPECT_TRUE(x.IsArray());
1065  EXPECT_TRUE(x.Empty());
1066  EXPECT_EQ(0u, x.Size());
1067  EXPECT_TRUE(y.IsArray());
1068  EXPECT_TRUE(y.Empty());
1069  EXPECT_EQ(0u, y.Size());
1070 
1071  EXPECT_FALSE(x.IsNull());
1072  EXPECT_FALSE(x.IsBool());
1073  EXPECT_FALSE(x.IsFalse());
1074  EXPECT_FALSE(x.IsTrue());
1075  EXPECT_FALSE(x.IsString());
1076  EXPECT_FALSE(x.IsObject());
1077 
1078  TestArray(x, allocator);
1079 
1080  // Working in gcc without C++11, but VS2013 cannot compile. To be diagnosed.
1081  // http://en.wikipedia.org/wiki/Erase-remove_idiom
1082  x.Clear();
1083  for (int i = 0; i < 10; i++)
1084  if (i % 2 == 0)
1085  x.PushBack(i, allocator);
1086  else
1087  x.PushBack(Value(kNullType).Move(), allocator);
1088 
1089  const Value null(kNullType);
1090  x.Erase(std::remove(x.Begin(), x.End(), null), x.End());
1091  EXPECT_EQ(5u, x.Size());
1092  for (int i = 0; i < 5; i++)
1093  EXPECT_EQ(i * 2, x[static_cast<SizeType>(i)]);
1094 
1095  // SetArray()
1096  Value z;
1097  z.SetArray();
1098  EXPECT_TRUE(z.IsArray());
1099  EXPECT_TRUE(z.Empty());
1100 }
1101 
1102 TEST(Value, ArrayHelper) {
1103  Value::AllocatorType allocator;
1104  {
1105  Value x(kArrayType);
1106  Value::Array a = x.GetArray();
1107  TestArray(a, allocator);
1108  }
1109 
1110  {
1111  Value x(kArrayType);
1112  Value::Array a = x.GetArray();
1113  a.PushBack(1, allocator);
1114 
1115  Value::Array a2(a); // copy constructor
1116  EXPECT_EQ(1, a2.Size());
1117 
1118  Value::Array a3 = a;
1119  EXPECT_EQ(1, a3.Size());
1120 
1121  Value::ConstArray y = static_cast<const Value&>(x).GetArray();
1122  (void)y;
1123  // y.PushBack(1, allocator); // should not compile
1124 
1125  // Templated functions
1126  x.Clear();
1127  EXPECT_TRUE(x.Is<Value::Array>());
1128  EXPECT_TRUE(x.Is<Value::ConstArray>());
1129  a.PushBack(1, allocator);
1130  EXPECT_EQ(1, x.Get<Value::Array>()[0].GetInt());
1131  EXPECT_EQ(1, x.Get<Value::ConstArray>()[0].GetInt());
1132 
1133  Value x2;
1134  x2.Set<Value::Array>(a);
1135  EXPECT_TRUE(x.IsArray()); // IsArray() is invariant after moving.
1136  EXPECT_EQ(1, x2.Get<Value::Array>()[0].GetInt());
1137  }
1138 
1139  {
1140  Value y(kArrayType);
1141  y.PushBack(123, allocator);
1142 
1143  Value x(y.GetArray()); // Construct value form array.
1144  EXPECT_TRUE(x.IsArray());
1145  EXPECT_EQ(123, x[0].GetInt());
1146  EXPECT_TRUE(y.IsArray()); // Invariant
1147  EXPECT_TRUE(y.Empty());
1148  }
1149 
1150  {
1151  Value x(kArrayType);
1152  Value y(kArrayType);
1153  y.PushBack(123, allocator);
1154  x.PushBack(y.GetArray(), allocator); // Implicit constructor to convert Array to GenericValue
1155 
1156  EXPECT_EQ(1, x.Size());
1157  EXPECT_EQ(123, x[0][0].GetInt());
1158  EXPECT_TRUE(y.IsArray());
1159  EXPECT_TRUE(y.Empty());
1160  }
1161 }
1162 
1163 #if RAPIDJSON_HAS_CXX11_RANGE_FOR
1164 TEST(Value, ArrayHelperRangeFor) {
1165  Value::AllocatorType allocator;
1166  Value x(kArrayType);
1167 
1168  for (int i = 0; i < 10; i++)
1169  x.PushBack(i, allocator);
1170 
1171  {
1172  int i = 0;
1173  for (auto& v : x.GetArray()) {
1174  EXPECT_EQ(i, v.GetInt());
1175  i++;
1176  }
1177  EXPECT_EQ(i, 10);
1178  }
1179  {
1180  int i = 0;
1181  for (const auto& v : const_cast<const Value&>(x).GetArray()) {
1182  EXPECT_EQ(i, v.GetInt());
1183  i++;
1184  }
1185  EXPECT_EQ(i, 10);
1186  }
1187 
1188  // Array a = x.GetArray();
1189  // Array ca = const_cast<const Value&>(x).GetArray();
1190 }
1191 #endif
1192 
1193 template <typename T, typename Allocator>
1194 static void TestObject(T& x, Allocator& allocator) {
1195  const T& y = x; // const version
1196 
1197  // AddMember()
1198  x.AddMember("A", "Apple", allocator);
1199  EXPECT_FALSE(x.ObjectEmpty());
1200  EXPECT_EQ(1u, x.MemberCount());
1201 
1202  Value value("Banana", 6);
1203  x.AddMember("B", "Banana", allocator);
1204  EXPECT_EQ(2u, x.MemberCount());
1205 
1206  // AddMember<T>(StringRefType, T, Allocator)
1207  {
1208  Value o(kObjectType);
1209  o.AddMember("true", true, allocator);
1210  o.AddMember("false", false, allocator);
1211  o.AddMember("int", -1, allocator);
1212  o.AddMember("uint", 1u, allocator);
1213  o.AddMember("int64", int64_t(-4294967296), allocator);
1214  o.AddMember("uint64", uint64_t(4294967296), allocator);
1215  o.AddMember("double", 3.14, allocator);
1216  o.AddMember("string", "Jelly", allocator);
1217 
1218  EXPECT_TRUE(o["true"].GetBool());
1219  EXPECT_FALSE(o["false"].GetBool());
1220  EXPECT_EQ(-1, o["int"].GetInt());
1221  EXPECT_EQ(1u, o["uint"].GetUint());
1222  EXPECT_EQ(int64_t(-4294967296), o["int64"].GetInt64());
1223  EXPECT_EQ(uint64_t(4294967296), o["uint64"].GetUint64());
1224  EXPECT_STREQ("Jelly",o["string"].GetString());
1225  EXPECT_EQ(8u, o.MemberCount());
1226  }
1227 
1228  // AddMember<T>(Value&, T, Allocator)
1229  {
1230  Value o(kObjectType);
1231 
1232  Value n("s");
1233  o.AddMember(n, "string", allocator);
1234  EXPECT_EQ(1u, o.MemberCount());
1235 
1236  Value count("#");
1237  o.AddMember(count, o.MemberCount(), allocator);
1238  EXPECT_EQ(2u, o.MemberCount());
1239  }
1240 
1241 #if RAPIDJSON_HAS_STDSTRING
1242  {
1243  // AddMember(StringRefType, const std::string&, Allocator)
1244  Value o(kObjectType);
1245  o.AddMember("b", std::string("Banana"), allocator);
1246  EXPECT_STREQ("Banana", o["b"].GetString());
1247 
1248  // RemoveMember(const std::string&)
1249  o.RemoveMember(std::string("b"));
1250  EXPECT_TRUE(o.ObjectEmpty());
1251  }
1252 #endif
1253 
1254 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1255  // AddMember(GenericValue&&, ...) variants
1256  {
1257  Value o(kObjectType);
1258  o.AddMember(Value("true"), Value(true), allocator);
1259  o.AddMember(Value("false"), Value(false).Move(), allocator); // value is lvalue ref
1260  o.AddMember(Value("int").Move(), Value(-1), allocator); // name is lvalue ref
1261  o.AddMember("uint", std::move(Value().SetUint(1u)), allocator); // name is literal, value is rvalue
1262  EXPECT_TRUE(o["true"].GetBool());
1263  EXPECT_FALSE(o["false"].GetBool());
1264  EXPECT_EQ(-1, o["int"].GetInt());
1265  EXPECT_EQ(1u, o["uint"].GetUint());
1266  EXPECT_EQ(4u, o.MemberCount());
1267  }
1268 #endif
1269 
1270  // Tests a member with null character
1271  Value name;
1272  const Value C0D("C\0D", 3);
1273  name.SetString(C0D.GetString(), 3);
1274  value.SetString("CherryD", 7);
1275  x.AddMember(name, value, allocator);
1276 
1277  // HasMember()
1278  EXPECT_TRUE(x.HasMember("A"));
1279  EXPECT_TRUE(x.HasMember("B"));
1280  EXPECT_TRUE(y.HasMember("A"));
1281  EXPECT_TRUE(y.HasMember("B"));
1282 
1283 #if RAPIDJSON_HAS_STDSTRING
1284  EXPECT_TRUE(x.HasMember(std::string("A")));
1285 #endif
1286 
1287  name.SetString("C\0D");
1288  EXPECT_TRUE(x.HasMember(name));
1289  EXPECT_TRUE(y.HasMember(name));
1290 
1291  GenericValue<UTF8<>, CrtAllocator> othername("A");
1292  EXPECT_TRUE(x.HasMember(othername));
1293  EXPECT_TRUE(y.HasMember(othername));
1294  othername.SetString("C\0D");
1295  EXPECT_TRUE(x.HasMember(othername));
1296  EXPECT_TRUE(y.HasMember(othername));
1297 
1298  // operator[]
1299  EXPECT_STREQ("Apple", x["A"].GetString());
1300  EXPECT_STREQ("Banana", x["B"].GetString());
1301  EXPECT_STREQ("CherryD", x[C0D].GetString());
1302  EXPECT_STREQ("CherryD", x[othername].GetString());
1303  EXPECT_THROW(x["nonexist"], AssertException);
1304 
1305  // const operator[]
1306  EXPECT_STREQ("Apple", y["A"].GetString());
1307  EXPECT_STREQ("Banana", y["B"].GetString());
1308  EXPECT_STREQ("CherryD", y[C0D].GetString());
1309 
1310 #if RAPIDJSON_HAS_STDSTRING
1311  EXPECT_STREQ("Apple", x["A"].GetString());
1312  EXPECT_STREQ("Apple", y[std::string("A")].GetString());
1313 #endif
1314 
1315  // member iterator
1316  Value::MemberIterator itr = x.MemberBegin();
1317  EXPECT_TRUE(itr != x.MemberEnd());
1318  EXPECT_STREQ("A", itr->name.GetString());
1319  EXPECT_STREQ("Apple", itr->value.GetString());
1320  ++itr;
1321  EXPECT_TRUE(itr != x.MemberEnd());
1322  EXPECT_STREQ("B", itr->name.GetString());
1323  EXPECT_STREQ("Banana", itr->value.GetString());
1324  ++itr;
1325  EXPECT_TRUE(itr != x.MemberEnd());
1326  EXPECT_TRUE(memcmp(itr->name.GetString(), "C\0D", 4) == 0);
1327  EXPECT_STREQ("CherryD", itr->value.GetString());
1328  ++itr;
1329  EXPECT_FALSE(itr != x.MemberEnd());
1330 
1331  // const member iterator
1332  Value::ConstMemberIterator citr = y.MemberBegin();
1333  EXPECT_TRUE(citr != y.MemberEnd());
1334  EXPECT_STREQ("A", citr->name.GetString());
1335  EXPECT_STREQ("Apple", citr->value.GetString());
1336  ++citr;
1337  EXPECT_TRUE(citr != y.MemberEnd());
1338  EXPECT_STREQ("B", citr->name.GetString());
1339  EXPECT_STREQ("Banana", citr->value.GetString());
1340  ++citr;
1341  EXPECT_TRUE(citr != y.MemberEnd());
1342  EXPECT_TRUE(memcmp(citr->name.GetString(), "C\0D", 4) == 0);
1343  EXPECT_STREQ("CherryD", citr->value.GetString());
1344  ++citr;
1345  EXPECT_FALSE(citr != y.MemberEnd());
1346 
1347  // member iterator conversions/relations
1348  itr = x.MemberBegin();
1349  citr = x.MemberBegin(); // const conversion
1350  TestEqual(itr, citr);
1351  EXPECT_TRUE(itr < x.MemberEnd());
1352  EXPECT_FALSE(itr > y.MemberEnd());
1353  EXPECT_TRUE(citr < x.MemberEnd());
1354  EXPECT_FALSE(citr > y.MemberEnd());
1355  ++citr;
1356  TestUnequal(itr, citr);
1357  EXPECT_FALSE(itr < itr);
1358  EXPECT_TRUE(itr < citr);
1359  EXPECT_FALSE(itr > itr);
1360  EXPECT_TRUE(citr > itr);
1361  EXPECT_EQ(1, citr - x.MemberBegin());
1362  EXPECT_EQ(0, itr - y.MemberBegin());
1363  itr += citr - x.MemberBegin();
1364  EXPECT_EQ(1, itr - y.MemberBegin());
1365  TestEqual(citr, itr);
1366  EXPECT_TRUE(itr <= citr);
1367  EXPECT_TRUE(citr <= itr);
1368  itr++;
1369  EXPECT_TRUE(itr >= citr);
1370  EXPECT_FALSE(citr >= itr);
1371 
1372  // RemoveMember()
1373  EXPECT_TRUE(x.RemoveMember("A"));
1374  EXPECT_FALSE(x.HasMember("A"));
1375 
1376  EXPECT_TRUE(x.RemoveMember("B"));
1377  EXPECT_FALSE(x.HasMember("B"));
1378 
1379  EXPECT_FALSE(x.RemoveMember("nonexist"));
1380 
1381  EXPECT_TRUE(x.RemoveMember(othername));
1382  EXPECT_FALSE(x.HasMember(name));
1383 
1384  EXPECT_TRUE(x.MemberBegin() == x.MemberEnd());
1385 
1386  // EraseMember(ConstMemberIterator)
1387 
1388  // Use array members to ensure removed elements' destructor is called.
1389  // { "a": [0], "b": [1],[2],...]
1390  const char keys[][2] = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j" };
1391  for (int i = 0; i < 10; i++)
1392  x.AddMember(keys[i], Value(kArrayType).PushBack(i, allocator), allocator);
1393 
1394  // MemberCount, iterator difference
1395  EXPECT_EQ(x.MemberCount(), SizeType(x.MemberEnd() - x.MemberBegin()));
1396 
1397  // Erase the first
1398  itr = x.EraseMember(x.MemberBegin());
1399  EXPECT_FALSE(x.HasMember(keys[0]));
1400  EXPECT_EQ(x.MemberBegin(), itr);
1401  EXPECT_EQ(9u, x.MemberCount());
1402  for (; itr != x.MemberEnd(); ++itr) {
1403  size_t i = static_cast<size_t>((itr - x.MemberBegin())) + 1;
1404  EXPECT_STREQ(itr->name.GetString(), keys[i]);
1405  EXPECT_EQ(i, itr->value[0].GetInt());
1406  }
1407 
1408  // Erase the last
1409  itr = x.EraseMember(x.MemberEnd() - 1);
1410  EXPECT_FALSE(x.HasMember(keys[9]));
1411  EXPECT_EQ(x.MemberEnd(), itr);
1412  EXPECT_EQ(8u, x.MemberCount());
1413  for (; itr != x.MemberEnd(); ++itr) {
1414  size_t i = static_cast<size_t>(itr - x.MemberBegin()) + 1;
1415  EXPECT_STREQ(itr->name.GetString(), keys[i]);
1416  EXPECT_EQ(i, itr->value[0].GetInt());
1417  }
1418 
1419  // Erase the middle
1420  itr = x.EraseMember(x.MemberBegin() + 4);
1421  EXPECT_FALSE(x.HasMember(keys[5]));
1422  EXPECT_EQ(x.MemberBegin() + 4, itr);
1423  EXPECT_EQ(7u, x.MemberCount());
1424  for (; itr != x.MemberEnd(); ++itr) {
1425  size_t i = static_cast<size_t>(itr - x.MemberBegin());
1426  i += (i < 4) ? 1 : 2;
1427  EXPECT_STREQ(itr->name.GetString(), keys[i]);
1428  EXPECT_EQ(i, itr->value[0].GetInt());
1429  }
1430 
1431  // EraseMember(ConstMemberIterator, ConstMemberIterator)
1432  // Exhaustive test with all 0 <= first < n, first <= last <= n cases
1433  const unsigned n = 10;
1434  for (unsigned first = 0; first < n; first++) {
1435  for (unsigned last = first; last <= n; last++) {
1436  x.RemoveAllMembers();
1437  for (unsigned i = 0; i < n; i++)
1438  x.AddMember(keys[i], Value(kArrayType).PushBack(i, allocator), allocator);
1439 
1440  itr = x.EraseMember(x.MemberBegin() + static_cast<int>(first), x.MemberBegin() + static_cast<int>(last));
1441  if (last == n)
1442  EXPECT_EQ(x.MemberEnd(), itr);
1443  else
1444  EXPECT_EQ(x.MemberBegin() + static_cast<int>(first), itr);
1445 
1446  size_t removeCount = last - first;
1447  EXPECT_EQ(n - removeCount, x.MemberCount());
1448  for (unsigned i = 0; i < first; i++)
1449  EXPECT_EQ(i, x[keys[i]][0].GetUint());
1450  for (unsigned i = first; i < n - removeCount; i++)
1451  EXPECT_EQ(i + removeCount, x[keys[i+removeCount]][0].GetUint());
1452  }
1453  }
1454 
1455  // RemoveAllMembers()
1456  x.RemoveAllMembers();
1457  EXPECT_TRUE(x.ObjectEmpty());
1458  EXPECT_EQ(0u, x.MemberCount());
1459 }
1460 
1461 TEST(Value, Object) {
1462  Value x(kObjectType);
1463  const Value& y = x; // const version
1464  Value::AllocatorType allocator;
1465 
1466  EXPECT_EQ(kObjectType, x.GetType());
1467  EXPECT_TRUE(x.IsObject());
1468  EXPECT_TRUE(x.ObjectEmpty());
1469  EXPECT_EQ(0u, x.MemberCount());
1470  EXPECT_EQ(kObjectType, y.GetType());
1471  EXPECT_TRUE(y.IsObject());
1472  EXPECT_TRUE(y.ObjectEmpty());
1473  EXPECT_EQ(0u, y.MemberCount());
1474 
1475  TestObject(x, allocator);
1476 
1477  // SetObject()
1478  Value z;
1479  z.SetObject();
1480  EXPECT_TRUE(z.IsObject());
1481 }
1482 
1483 TEST(Value, ObjectHelper) {
1484  Value::AllocatorType allocator;
1485  {
1486  Value x(kObjectType);
1487  Value::Object o = x.GetObject();
1488  TestObject(o, allocator);
1489  }
1490 
1491  {
1492  Value x(kObjectType);
1493  Value::Object o = x.GetObject();
1494  o.AddMember("1", 1, allocator);
1495 
1496  Value::Object o2(o); // copy constructor
1497  EXPECT_EQ(1, o2.MemberCount());
1498 
1499  Value::Object o3 = o;
1500  EXPECT_EQ(1, o3.MemberCount());
1501 
1502  Value::ConstObject y = static_cast<const Value&>(x).GetObject();
1503  (void)y;
1504  // y.AddMember("1", 1, allocator); // should not compile
1505 
1506  // Templated functions
1507  x.RemoveAllMembers();
1508  EXPECT_TRUE(x.Is<Value::Object>());
1509  EXPECT_TRUE(x.Is<Value::ConstObject>());
1510  o.AddMember("1", 1, allocator);
1511  EXPECT_EQ(1, x.Get<Value::Object>()["1"].GetInt());
1512  EXPECT_EQ(1, x.Get<Value::ConstObject>()["1"].GetInt());
1513 
1514  Value x2;
1515  x2.Set<Value::Object>(o);
1516  EXPECT_TRUE(x.IsObject()); // IsObject() is invariant after moving
1517  EXPECT_EQ(1, x2.Get<Value::Object>()["1"].GetInt());
1518  }
1519 
1520  {
1521  Value x(kObjectType);
1522  x.AddMember("a", "apple", allocator);
1523  Value y(x.GetObject());
1524  EXPECT_STREQ("apple", y["a"].GetString());
1525  EXPECT_TRUE(x.IsObject()); // Invariant
1526  }
1527 
1528  {
1529  Value x(kObjectType);
1530  x.AddMember("a", "apple", allocator);
1531  Value y(kObjectType);
1532  y.AddMember("fruits", x.GetObject(), allocator);
1533  EXPECT_STREQ("apple", y["fruits"]["a"].GetString());
1534  EXPECT_TRUE(x.IsObject()); // Invariant
1535  }
1536 }
1537 
1538 #if RAPIDJSON_HAS_CXX11_RANGE_FOR
1539 TEST(Value, ObjectHelperRangeFor) {
1540  Value::AllocatorType allocator;
1541  Value x(kObjectType);
1542 
1543  for (int i = 0; i < 10; i++) {
1544  char name[10];
1545  Value n(name, static_cast<SizeType>(sprintf(name, "%d", i)), allocator);
1546  x.AddMember(n, i, allocator);
1547  }
1548 
1549  {
1550  int i = 0;
1551  for (auto& m : x.GetObject()) {
1552  char name[10];
1553  sprintf(name, "%d", i);
1554  EXPECT_STREQ(name, m.name.GetString());
1555  EXPECT_EQ(i, m.value.GetInt());
1556  i++;
1557  }
1558  EXPECT_EQ(i, 10);
1559  }
1560  {
1561  int i = 0;
1562  for (const auto& m : const_cast<const Value&>(x).GetObject()) {
1563  char name[10];
1564  sprintf(name, "%d", i);
1565  EXPECT_STREQ(name, m.name.GetString());
1566  EXPECT_EQ(i, m.value.GetInt());
1567  i++;
1568  }
1569  EXPECT_EQ(i, 10);
1570  }
1571 
1572  // Object a = x.GetObject();
1573  // Object ca = const_cast<const Value&>(x).GetObject();
1574 }
1575 #endif
1576 
1577 TEST(Value, EraseMember_String) {
1578  Value::AllocatorType allocator;
1579  Value x(kObjectType);
1580  x.AddMember("A", "Apple", allocator);
1581  x.AddMember("B", "Banana", allocator);
1582 
1583  EXPECT_TRUE(x.EraseMember("B"));
1584  EXPECT_FALSE(x.HasMember("B"));
1585 
1586  EXPECT_FALSE(x.EraseMember("nonexist"));
1587 
1588  GenericValue<UTF8<>, CrtAllocator> othername("A");
1589  EXPECT_TRUE(x.EraseMember(othername));
1590  EXPECT_FALSE(x.HasMember("A"));
1591 
1592  EXPECT_TRUE(x.MemberBegin() == x.MemberEnd());
1593 }
1594 
1595 TEST(Value, BigNestedArray) {
1596  MemoryPoolAllocator<> allocator;
1597  Value x(kArrayType);
1598  static const SizeType n = 200;
1599 
1600  for (SizeType i = 0; i < n; i++) {
1601  Value y(kArrayType);
1602  for (SizeType j = 0; j < n; j++) {
1603  Value number(static_cast<int>(i * n + j));
1604  y.PushBack(number, allocator);
1605  }
1606  x.PushBack(y, allocator);
1607  }
1608 
1609  for (SizeType i = 0; i < n; i++)
1610  for (SizeType j = 0; j < n; j++) {
1611  EXPECT_TRUE(x[i][j].IsInt());
1612  EXPECT_EQ(static_cast<int>(i * n + j), x[i][j].GetInt());
1613  }
1614 }
1615 
1616 TEST(Value, BigNestedObject) {
1617  MemoryPoolAllocator<> allocator;
1618  Value x(kObjectType);
1619  static const SizeType n = 200;
1620 
1621  for (SizeType i = 0; i < n; i++) {
1622  char name1[10];
1623  sprintf(name1, "%d", i);
1624 
1625  // Value name(name1); // should not compile
1626  Value name(name1, static_cast<SizeType>(strlen(name1)), allocator);
1627  Value object(kObjectType);
1628 
1629  for (SizeType j = 0; j < n; j++) {
1630  char name2[10];
1631  sprintf(name2, "%d", j);
1632 
1633  Value name3(name2, static_cast<SizeType>(strlen(name2)), allocator);
1634  Value number(static_cast<int>(i * n + j));
1635  object.AddMember(name3, number, allocator);
1636  }
1637 
1638  // x.AddMember(name1, object, allocator); // should not compile
1639  x.AddMember(name, object, allocator);
1640  }
1641 
1642  for (SizeType i = 0; i < n; i++) {
1643  char name1[10];
1644  sprintf(name1, "%d", i);
1645 
1646  for (SizeType j = 0; j < n; j++) {
1647  char name2[10];
1648  sprintf(name2, "%d", j);
1649  x[name1];
1650  EXPECT_EQ(static_cast<int>(i * n + j), x[name1][name2].GetInt());
1651  }
1652  }
1653 }
1654 
1655 // Issue 18: Error removing last element of object
1656 // http://code.google.com/p/rapidjson/issues/detail?id=18
1657 TEST(Value, RemoveLastElement) {
1658  rapidjson::Document doc;
1659  rapidjson::Document::AllocatorType& allocator = doc.GetAllocator();
1661  objVal.AddMember("var1", 123, allocator);
1662  objVal.AddMember("var2", "444", allocator);
1663  objVal.AddMember("var3", 555, allocator);
1664  EXPECT_TRUE(objVal.HasMember("var3"));
1665  objVal.RemoveMember("var3"); // Assertion here in r61
1666  EXPECT_FALSE(objVal.HasMember("var3"));
1667 }
1668 
1669 // Issue 38: Segmentation fault with CrtAllocator
1671  typedef GenericValue<UTF8<>, CrtAllocator> V;
1672 
1673  V::AllocatorType allocator;
1674  V o(kObjectType);
1675  o.AddMember("x", 1, allocator); // Should not call destructor on uninitialized name/value of newly allocated members.
1676 
1677  V a(kArrayType);
1678  a.PushBack(1, allocator); // Should not call destructor on uninitialized Value of newly allocated elements.
1679 }
1680 
1681 static void TestShortStringOptimization(const char* str) {
1682  const rapidjson::SizeType len = static_cast<rapidjson::SizeType>(strlen(str));
1683 
1684  rapidjson::Document doc;
1685  rapidjson::Value val;
1686  val.SetString(str, len, doc.GetAllocator());
1687 
1688  EXPECT_EQ(val.GetStringLength(), len);
1689  EXPECT_STREQ(val.GetString(), str);
1690 }
1691 
1692 TEST(Value, AllocateShortString) {
1693  TestShortStringOptimization(""); // edge case: empty string
1694  TestShortStringOptimization("12345678"); // regular case for short strings: 8 chars
1695  TestShortStringOptimization("12345678901"); // edge case: 11 chars in 32-bit mode (=> short string)
1696  TestShortStringOptimization("123456789012"); // edge case: 12 chars in 32-bit mode (=> regular string)
1697  TestShortStringOptimization("123456789012345"); // edge case: 15 chars in 64-bit mode (=> short string)
1698  TestShortStringOptimization("1234567890123456"); // edge case: 16 chars in 64-bit mode (=> regular string)
1699 }
1700 
1701 template <int e>
1702 struct TerminateHandler {
1703  bool Null() { return e != 0; }
1704  bool Bool(bool) { return e != 1; }
1705  bool Int(int) { return e != 2; }
1706  bool Uint(unsigned) { return e != 3; }
1707  bool Int64(int64_t) { return e != 4; }
1708  bool Uint64(uint64_t) { return e != 5; }
1709  bool Double(double) { return e != 6; }
1710  bool RawNumber(const char*, SizeType, bool) { return e != 7; }
1711  bool String(const char*, SizeType, bool) { return e != 8; }
1712  bool StartObject() { return e != 9; }
1713  bool Key(const char*, SizeType, bool) { return e != 10; }
1714  bool EndObject(SizeType) { return e != 11; }
1715  bool StartArray() { return e != 12; }
1716  bool EndArray(SizeType) { return e != 13; }
1717 };
1718 
1719 #define TEST_TERMINATION(e, json)\
1720 {\
1721  Document d; \
1722  EXPECT_FALSE(d.Parse(json).HasParseError()); \
1723  Reader reader; \
1724  TerminateHandler<e> h;\
1725  EXPECT_FALSE(d.Accept(h));\
1726 }
1727 
1728 TEST(Value, AcceptTerminationByHandler) {
1729  TEST_TERMINATION(0, "[null]");
1730  TEST_TERMINATION(1, "[true]");
1731  TEST_TERMINATION(1, "[false]");
1732  TEST_TERMINATION(2, "[-1]");
1733  TEST_TERMINATION(3, "[2147483648]");
1734  TEST_TERMINATION(4, "[-1234567890123456789]");
1735  TEST_TERMINATION(5, "[9223372036854775808]");
1736  TEST_TERMINATION(6, "[0.5]");
1737  // RawNumber() is never called
1738  TEST_TERMINATION(8, "[\"a\"]");
1739  TEST_TERMINATION(9, "[{}]");
1740  TEST_TERMINATION(10, "[{\"a\":1}]");
1741  TEST_TERMINATION(11, "[{}]");
1742  TEST_TERMINATION(12, "{\"a\":[]}");
1743  TEST_TERMINATION(13, "{\"a\":[]}");
1744 }
1745 
1747  bool operator()(const Value& lhs, const Value& rhs) const {
1748  return lhs.GetInt() < rhs.GetInt();
1749  }
1750 };
1751 
1752 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1753 TEST(Value, Sorting) {
1754  Value::AllocatorType allocator;
1755  Value a(kArrayType);
1756  a.PushBack(5, allocator);
1757  a.PushBack(1, allocator);
1758  a.PushBack(3, allocator);
1759  std::sort(a.Begin(), a.End(), ValueIntComparer());
1760  EXPECT_EQ(1, a[0].GetInt());
1761  EXPECT_EQ(3, a[1].GetInt());
1762  EXPECT_EQ(5, a[2].GetInt());
1763 }
1764 #endif
1765 
1766 // http://stackoverflow.com/questions/35222230/
1767 
1769  if (v.IsObject()) {
1770  // Convert all key:value into key:[value]
1771  for (Value::MemberIterator itr = v.MemberBegin(); itr != v.MemberEnd(); ++itr)
1772  itr->value = Value(kArrayType).Move().PushBack(itr->value, a);
1773 
1774  // Merge arrays if key is duplicated
1775  for (Value::MemberIterator itr = v.MemberBegin(); itr != v.MemberEnd();) {
1776  Value::MemberIterator itr2 = v.FindMember(itr->name);
1777  if (itr != itr2) {
1778  itr2->value.PushBack(itr->value[0], a);
1779  itr = v.EraseMember(itr);
1780  }
1781  else
1782  ++itr;
1783  }
1784 
1785  // Convert key:[values] back to key:value if there is only one value
1786  for (Value::MemberIterator itr = v.MemberBegin(); itr != v.MemberEnd(); ++itr) {
1787  if (itr->value.Size() == 1)
1788  itr->value = itr->value[0];
1789  MergeDuplicateKey(itr->value, a); // Recursion on the value
1790  }
1791  }
1792  else if (v.IsArray())
1793  for (Value::ValueIterator itr = v.Begin(); itr != v.End(); ++itr)
1794  MergeDuplicateKey(*itr, a);
1795 }
1796 
1798  Document d;
1799  d.Parse(
1800  "{"
1801  " \"key1\": {"
1802  " \"a\": \"asdf\","
1803  " \"b\": \"foo\","
1804  " \"b\": \"bar\","
1805  " \"c\": \"fdas\""
1806  " }"
1807  "}");
1808 
1809  Document d2;
1810  d2.Parse(
1811  "{"
1812  " \"key1\": {"
1813  " \"a\": \"asdf\","
1814  " \"b\": ["
1815  " \"foo\","
1816  " \"bar\""
1817  " ],"
1818  " \"c\": \"fdas\""
1819  " }"
1820  "}");
1821 
1822  EXPECT_NE(d2, d);
1824  EXPECT_EQ(d2, d);
1825 }
1826 
1827 #ifdef __clang__
1828 RAPIDJSON_DIAG_POP
1829 #endif
d
void TestUnequal(const A &a, const B &b)
Definition: valuetest.cpp:173
void TestEqual(const A &a, const B &b)
Definition: valuetest.cpp:165
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:389
GenericObject AddMember(ValueType &name, ValueType &value, AllocatorType &allocator) const
Definition: document.h:2577
#define RAPIDJSON_UINT64_C2(high32, low32)
Construct a 64-bit literal by a pair of 32-bit integer.
Definition: rapidjson.h:294
object
Definition: rapidjson.h:620
f
Helper class for accessing Value of array type.
Definition: document.h:542
static void TestShortStringOptimization(const char *str)
Definition: valuetest.cpp:1681
(Constant) member iterator for a JSON object value
Definition: document.h:109
array
Definition: rapidjson.h:621
bool Bool(bool)
Definition: valuetest.cpp:1704
XmlRpcServer s
GenericArray PushBack(ValueType &value, AllocatorType &allocator) const
Definition: document.h:2511
false
Definition: rapidjson.h:618
bool Double(double)
Definition: valuetest.cpp:1709
bool Uint(unsigned)
Definition: valuetest.cpp:1706
bool EndObject(SizeType)
Definition: valuetest.cpp:1714
A document for parsing JSON text as DOM.
Definition: document.h:70
void TestCopyFrom()
Definition: valuetest.cpp:250
bool operator()(const Value &lhs, const Value &rhs) const
Definition: valuetest.cpp:1747
bool Key(const char *, SizeType, bool)
Definition: valuetest.cpp:1713
string
Definition: rapidjson.h:622
GenericValue< UTF8<> > Value
GenericValue with UTF8 encoding.
Definition: document.h:2081
bool Uint64(uint64_t)
Definition: valuetest.cpp:1708
Helper class for accessing Value of object type.
Definition: document.h:543
unsigned __int64 uint64_t
Definition: stdint.h:136
#define TEST_TERMINATION(e, json)
Definition: valuetest.cpp:1719
Concept for allocating, resizing and freeing memory block.
Allocator & GetAllocator()
Get the allocator of this document.
Definition: document.h:2383
GenericDocument< UTF8<> > Document
GenericDocument with UTF8 encoding.
Definition: document.h:2477
number
Definition: rapidjson.h:623
void Swap(T &a, T &b) RAPIDJSON_NOEXCEPT
Custom swap() to avoid dependency on C++ <algorithm> header.
Definition: swap.h:33
GenericDocument & Parse(const typename SourceEncoding::Ch *str)
Parse JSON text from a read-only string (with Encoding conversion)
Definition: document.h:2296
main RapidJSON namespace
SizeType MemberCount() const
Definition: document.h:2558
bool RawNumber(const char *, SizeType, bool)
Definition: valuetest.cpp:1710
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition: pointer.h:1121
C-runtime library allocator.
Definition: allocators.h:62
bool String(const char *, SizeType, bool)
Definition: valuetest.cpp:1711
GenericStringRef< CharType > StringRef(const CharType *str)
Mark a character pointer as constant string.
Definition: document.h:365
static void TestArray(T &x, Allocator &allocator)
Definition: valuetest.cpp:903
#define T(x)
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1222
signed __int64 int64_t
Definition: stdint.h:135
true
Definition: rapidjson.h:619
SizeType Size() const
Definition: document.h:2503
static void TestObject(T &x, Allocator &allocator)
Definition: valuetest.cpp:1194
bool Int64(int64_t)
Definition: valuetest.cpp:1707
TEST(Value, Size)
Definition: valuetest.cpp:26
bool EndArray(SizeType)
Definition: valuetest.cpp:1716
null
Definition: rapidjson.h:617
static void MergeDuplicateKey(Value &v, Value::AllocatorType &a)
Definition: valuetest.cpp:1768


choreo_rapidjson
Author(s):
autogenerated on Thu Jul 18 2019 03:59:09