Electroneum
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 #ifdef _MSC_VER
444  // long as int on MSC platforms
445  RAPIDJSON_STATIC_ASSERT(sizeof(long) == sizeof(int));
446  z.SetInt(2222);
447  EXPECT_TRUE(z.Is<long>());
448  EXPECT_EQ(2222l, z.Get<long>());
449  EXPECT_EQ(3333l, z.Set(3333l).Get<long>());
450  EXPECT_EQ(4444l, z.Set<long>(4444l).Get<long>());
451  EXPECT_TRUE(z.IsInt());
452 #endif
453 }
454 
455 TEST(Value, Uint) {
456  // Constructor with int
457  Value x(1234u);
458  EXPECT_EQ(kNumberType, x.GetType());
459  EXPECT_EQ(1234, x.GetInt());
460  EXPECT_EQ(1234u, x.GetUint());
461  EXPECT_EQ(1234, x.GetInt64());
462  EXPECT_EQ(1234u, x.GetUint64());
463  EXPECT_TRUE(x.IsNumber());
464  EXPECT_TRUE(x.IsInt());
465  EXPECT_TRUE(x.IsUint());
466  EXPECT_TRUE(x.IsInt64());
467  EXPECT_TRUE(x.IsUint64());
468  EXPECT_NEAR(1234.0, x.GetDouble(), 0.0); // Number can always be cast as double but !IsDouble().
469 
470  EXPECT_FALSE(x.IsDouble());
471  EXPECT_FALSE(x.IsFloat());
472  EXPECT_FALSE(x.IsNull());
473  EXPECT_FALSE(x.IsBool());
474  EXPECT_FALSE(x.IsFalse());
475  EXPECT_FALSE(x.IsTrue());
476  EXPECT_FALSE(x.IsString());
477  EXPECT_FALSE(x.IsObject());
478  EXPECT_FALSE(x.IsArray());
479 
480  // SetUint()
481  Value z;
482  z.SetUint(1234);
483  EXPECT_EQ(1234u, z.GetUint());
484 
485  // operator=(unsigned)
486  z = 5678u;
487  EXPECT_EQ(5678u, z.GetUint());
488 
489  z = 2147483648u; // 2^31, cannot cast as int
490  EXPECT_EQ(2147483648u, z.GetUint());
491  EXPECT_FALSE(z.IsInt());
492  EXPECT_TRUE(z.IsInt64()); // Issue 41: Incorrect parsing of unsigned int number types
493 
494  // Templated functions
495  EXPECT_TRUE(z.Is<unsigned>());
496  EXPECT_EQ(2147483648u, z.Get<unsigned>());
497  EXPECT_EQ(2147483649u, z.Set(2147483649u).Get<unsigned>());
498  EXPECT_EQ(2147483650u, z.Set<unsigned>(2147483650u).Get<unsigned>());
499 
500 #ifdef _MSC_VER
501  // unsigned long as unsigned on MSC platforms
502  RAPIDJSON_STATIC_ASSERT(sizeof(unsigned long) == sizeof(unsigned));
503  z.SetUint(2222);
504  EXPECT_TRUE(z.Is<unsigned long>());
505  EXPECT_EQ(2222ul, z.Get<unsigned long>());
506  EXPECT_EQ(3333ul, z.Set(3333ul).Get<unsigned long>());
507  EXPECT_EQ(4444ul, z.Set<unsigned long>(4444ul).Get<unsigned long>());
508  EXPECT_TRUE(x.IsUint());
509 #endif
510 }
511 
513  // Constructor with int
514  Value x(int64_t(1234));
515  EXPECT_EQ(kNumberType, x.GetType());
516  EXPECT_EQ(1234, x.GetInt());
517  EXPECT_EQ(1234u, x.GetUint());
518  EXPECT_EQ(1234, x.GetInt64());
519  EXPECT_EQ(1234u, x.GetUint64());
520  EXPECT_TRUE(x.IsNumber());
521  EXPECT_TRUE(x.IsInt());
522  EXPECT_TRUE(x.IsUint());
523  EXPECT_TRUE(x.IsInt64());
524  EXPECT_TRUE(x.IsUint64());
525 
526  EXPECT_FALSE(x.IsDouble());
527  EXPECT_FALSE(x.IsFloat());
528  EXPECT_FALSE(x.IsNull());
529  EXPECT_FALSE(x.IsBool());
530  EXPECT_FALSE(x.IsFalse());
531  EXPECT_FALSE(x.IsTrue());
532  EXPECT_FALSE(x.IsString());
533  EXPECT_FALSE(x.IsObject());
534  EXPECT_FALSE(x.IsArray());
535 
536  Value nx(int64_t(-1234));
537  EXPECT_EQ(-1234, nx.GetInt());
538  EXPECT_EQ(-1234, nx.GetInt64());
539  EXPECT_TRUE(nx.IsInt());
540  EXPECT_TRUE(nx.IsInt64());
541  EXPECT_FALSE(nx.IsUint());
542  EXPECT_FALSE(nx.IsUint64());
543 
544  // SetInt64()
545  Value z;
546  z.SetInt64(1234);
547  EXPECT_EQ(1234, z.GetInt64());
548 
549  z.SetInt64(2147483648u); // 2^31, cannot cast as int
550  EXPECT_FALSE(z.IsInt());
551  EXPECT_TRUE(z.IsUint());
552  EXPECT_NEAR(2147483648.0, z.GetDouble(), 0.0);
553 
554  z.SetInt64(int64_t(4294967295u) + 1); // 2^32, cannot cast as uint
555  EXPECT_FALSE(z.IsInt());
556  EXPECT_FALSE(z.IsUint());
557  EXPECT_NEAR(4294967296.0, z.GetDouble(), 0.0);
558 
559  z.SetInt64(-int64_t(2147483648u) - 1); // -2^31-1, cannot cast as int
560  EXPECT_FALSE(z.IsInt());
561  EXPECT_NEAR(-2147483649.0, z.GetDouble(), 0.0);
562 
563  int64_t i = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 00000000));
564  z.SetInt64(i);
565  EXPECT_DOUBLE_EQ(-9223372036854775808.0, z.GetDouble());
566 
567  // Templated functions
568  EXPECT_TRUE(z.Is<int64_t>());
569  EXPECT_EQ(i, z.Get<int64_t>());
570 #if 0 // signed integer underflow is undefined behaviour
571  EXPECT_EQ(i - 1, z.Set(i - 1).Get<int64_t>());
572  EXPECT_EQ(i - 2, z.Set<int64_t>(i - 2).Get<int64_t>());
573 #endif
574 }
575 
576 TEST(Value, Uint64) {
577  // Constructor with int
578  Value x(uint64_t(1234));
579  EXPECT_EQ(kNumberType, x.GetType());
580  EXPECT_EQ(1234, x.GetInt());
581  EXPECT_EQ(1234u, x.GetUint());
582  EXPECT_EQ(1234, x.GetInt64());
583  EXPECT_EQ(1234u, x.GetUint64());
584  EXPECT_TRUE(x.IsNumber());
585  EXPECT_TRUE(x.IsInt());
586  EXPECT_TRUE(x.IsUint());
587  EXPECT_TRUE(x.IsInt64());
588  EXPECT_TRUE(x.IsUint64());
589 
590  EXPECT_FALSE(x.IsDouble());
591  EXPECT_FALSE(x.IsFloat());
592  EXPECT_FALSE(x.IsNull());
593  EXPECT_FALSE(x.IsBool());
594  EXPECT_FALSE(x.IsFalse());
595  EXPECT_FALSE(x.IsTrue());
596  EXPECT_FALSE(x.IsString());
597  EXPECT_FALSE(x.IsObject());
598  EXPECT_FALSE(x.IsArray());
599 
600  // SetUint64()
601  Value z;
602  z.SetUint64(1234);
603  EXPECT_EQ(1234u, z.GetUint64());
604 
605  z.SetUint64(uint64_t(2147483648u)); // 2^31, cannot cast as int
606  EXPECT_FALSE(z.IsInt());
607  EXPECT_TRUE(z.IsUint());
608  EXPECT_TRUE(z.IsInt64());
609 
610  z.SetUint64(uint64_t(4294967295u) + 1); // 2^32, cannot cast as uint
611  EXPECT_FALSE(z.IsInt());
612  EXPECT_FALSE(z.IsUint());
613  EXPECT_TRUE(z.IsInt64());
614 
615  uint64_t u = RAPIDJSON_UINT64_C2(0x80000000, 0x00000000);
616  z.SetUint64(u); // 2^63 cannot cast as int64
617  EXPECT_FALSE(z.IsInt64());
618  EXPECT_EQ(u, z.GetUint64()); // Issue 48
619  EXPECT_DOUBLE_EQ(9223372036854775808.0, z.GetDouble());
620 
621  // Templated functions
622  EXPECT_TRUE(z.Is<uint64_t>());
623  EXPECT_EQ(u, z.Get<uint64_t>());
624  EXPECT_EQ(u + 1, z.Set(u + 1).Get<uint64_t>());
625  EXPECT_EQ(u + 2, z.Set<uint64_t>(u + 2).Get<uint64_t>());
626 }
627 
629  // Constructor with double
630  Value x(12.34);
631  EXPECT_EQ(kNumberType, x.GetType());
632  EXPECT_NEAR(12.34, x.GetDouble(), 0.0);
633  EXPECT_TRUE(x.IsNumber());
634  EXPECT_TRUE(x.IsDouble());
635 
636  EXPECT_FALSE(x.IsInt());
637  EXPECT_FALSE(x.IsNull());
638  EXPECT_FALSE(x.IsBool());
639  EXPECT_FALSE(x.IsFalse());
640  EXPECT_FALSE(x.IsTrue());
641  EXPECT_FALSE(x.IsString());
642  EXPECT_FALSE(x.IsObject());
643  EXPECT_FALSE(x.IsArray());
644 
645  // SetDouble()
646  Value z;
647  z.SetDouble(12.34);
648  EXPECT_NEAR(12.34, z.GetDouble(), 0.0);
649 
650  z = 56.78;
651  EXPECT_NEAR(56.78, z.GetDouble(), 0.0);
652 
653  // Templated functions
654  EXPECT_TRUE(z.Is<double>());
655  EXPECT_EQ(56.78, z.Get<double>());
656  EXPECT_EQ(57.78, z.Set(57.78).Get<double>());
657  EXPECT_EQ(58.78, z.Set<double>(58.78).Get<double>());
658 }
659 
661  // Constructor with double
662  Value x(12.34f);
663  EXPECT_EQ(kNumberType, x.GetType());
664  EXPECT_NEAR(12.34f, x.GetFloat(), 0.0);
665  EXPECT_TRUE(x.IsNumber());
666  EXPECT_TRUE(x.IsDouble());
667  EXPECT_TRUE(x.IsFloat());
668 
669  EXPECT_FALSE(x.IsInt());
670  EXPECT_FALSE(x.IsNull());
671  EXPECT_FALSE(x.IsBool());
672  EXPECT_FALSE(x.IsFalse());
673  EXPECT_FALSE(x.IsTrue());
674  EXPECT_FALSE(x.IsString());
675  EXPECT_FALSE(x.IsObject());
676  EXPECT_FALSE(x.IsArray());
677 
678  // SetFloat()
679  Value z;
680  z.SetFloat(12.34f);
681  EXPECT_NEAR(12.34f, z.GetFloat(), 0.0f);
682 
683  // Issue 573
684  z.SetInt(0);
685  EXPECT_EQ(0.0f, z.GetFloat());
686 
687  z = 56.78f;
688  EXPECT_NEAR(56.78f, z.GetFloat(), 0.0f);
689 
690  // Templated functions
691  EXPECT_TRUE(z.Is<float>());
692  EXPECT_EQ(56.78f, z.Get<float>());
693  EXPECT_EQ(57.78f, z.Set(57.78f).Get<float>());
694  EXPECT_EQ(58.78f, z.Set<float>(58.78f).Get<float>());
695 }
696 
697 TEST(Value, IsLosslessDouble) {
698  EXPECT_TRUE(Value(0.0).IsLosslessDouble());
699  EXPECT_TRUE(Value(12.34).IsLosslessDouble());
700  EXPECT_TRUE(Value(-123).IsLosslessDouble());
701  EXPECT_TRUE(Value(2147483648u).IsLosslessDouble());
702  EXPECT_TRUE(Value(-static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x40000000, 0x00000000))).IsLosslessDouble());
703 #if !(defined(_MSC_VER) && _MSC_VER < 1800) // VC2010 has problem
704  EXPECT_TRUE(Value(RAPIDJSON_UINT64_C2(0xA0000000, 0x00000000)).IsLosslessDouble());
705 #endif
706 
707  EXPECT_FALSE(Value(static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x7FFFFFFF, 0xFFFFFFFF))).IsLosslessDouble()); // INT64_MAX
708  EXPECT_FALSE(Value(-static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x7FFFFFFF, 0xFFFFFFFF))).IsLosslessDouble()); // -INT64_MAX
709  EXPECT_TRUE(Value(-static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x7FFFFFFF, 0xFFFFFFFF)) - 1).IsLosslessDouble()); // INT64_MIN
710  EXPECT_FALSE(Value(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0xFFFFFFFF)).IsLosslessDouble()); // UINT64_MAX
711 
712  EXPECT_TRUE(Value(3.4028234e38f).IsLosslessDouble()); // FLT_MAX
713  EXPECT_TRUE(Value(-3.4028234e38f).IsLosslessDouble()); // -FLT_MAX
714  EXPECT_TRUE(Value(1.17549435e-38f).IsLosslessDouble()); // FLT_MIN
715  EXPECT_TRUE(Value(-1.17549435e-38f).IsLosslessDouble()); // -FLT_MIN
716  EXPECT_TRUE(Value(1.7976931348623157e+308).IsLosslessDouble()); // DBL_MAX
717  EXPECT_TRUE(Value(-1.7976931348623157e+308).IsLosslessDouble()); // -DBL_MAX
718  EXPECT_TRUE(Value(2.2250738585072014e-308).IsLosslessDouble()); // DBL_MIN
719  EXPECT_TRUE(Value(-2.2250738585072014e-308).IsLosslessDouble()); // -DBL_MIN
720 }
721 
722 TEST(Value, IsLosslessFloat) {
723  EXPECT_TRUE(Value(12.25).IsLosslessFloat());
724  EXPECT_TRUE(Value(-123).IsLosslessFloat());
725  EXPECT_TRUE(Value(2147483648u).IsLosslessFloat());
726  EXPECT_TRUE(Value(3.4028234e38f).IsLosslessFloat());
727  EXPECT_TRUE(Value(-3.4028234e38f).IsLosslessFloat());
728  EXPECT_FALSE(Value(3.4028235e38).IsLosslessFloat());
729  EXPECT_FALSE(Value(0.3).IsLosslessFloat());
730 }
731 
732 TEST(Value, String) {
733  // Construction with const string
734  Value x("Hello", 5); // literal
735  EXPECT_EQ(kStringType, x.GetType());
736  EXPECT_TRUE(x.IsString());
737  EXPECT_STREQ("Hello", x.GetString());
738  EXPECT_EQ(5u, x.GetStringLength());
739 
740  EXPECT_FALSE(x.IsNumber());
741  EXPECT_FALSE(x.IsNull());
742  EXPECT_FALSE(x.IsBool());
743  EXPECT_FALSE(x.IsFalse());
744  EXPECT_FALSE(x.IsTrue());
745  EXPECT_FALSE(x.IsObject());
746  EXPECT_FALSE(x.IsArray());
747 
748  static const char cstr[] = "World"; // const array
749  Value(cstr).Swap(x);
750  EXPECT_TRUE(x.IsString());
751  EXPECT_EQ(x.GetString(), cstr);
752  EXPECT_EQ(x.GetStringLength(), sizeof(cstr)-1);
753 
754  static char mstr[] = "Howdy"; // non-const array
755  // Value(mstr).Swap(x); // should not compile
756  Value(StringRef(mstr)).Swap(x);
757  EXPECT_TRUE(x.IsString());
758  EXPECT_EQ(x.GetString(), mstr);
759  EXPECT_EQ(x.GetStringLength(), sizeof(mstr)-1);
760  strncpy(mstr,"Hello", sizeof(mstr));
761  EXPECT_STREQ(x.GetString(), "Hello");
762 
763  const char* pstr = cstr;
764  //Value(pstr).Swap(x); // should not compile
765  Value(StringRef(pstr)).Swap(x);
766  EXPECT_TRUE(x.IsString());
767  EXPECT_EQ(x.GetString(), cstr);
768  EXPECT_EQ(x.GetStringLength(), sizeof(cstr)-1);
769 
770  char* mpstr = mstr;
771  Value(StringRef(mpstr,sizeof(mstr)-1)).Swap(x);
772  EXPECT_TRUE(x.IsString());
773  EXPECT_EQ(x.GetString(), mstr);
774  EXPECT_EQ(x.GetStringLength(), 5u);
775  EXPECT_STREQ(x.GetString(), "Hello");
776 
777  // Constructor with copy string
778  MemoryPoolAllocator<> allocator;
779  Value c(x.GetString(), x.GetStringLength(), allocator);
780  EXPECT_NE(x.GetString(), c.GetString());
781  EXPECT_EQ(x.GetStringLength(), c.GetStringLength());
782  EXPECT_STREQ(x.GetString(), c.GetString());
783  //x.SetString("World");
784  x.SetString("World", 5);
785  EXPECT_STREQ("Hello", c.GetString());
786  EXPECT_EQ(5u, c.GetStringLength());
787 
788  // Constructor with type
789  Value y(kStringType);
790  EXPECT_TRUE(y.IsString());
791  EXPECT_STREQ("", y.GetString()); // Empty string should be "" instead of 0 (issue 226)
792  EXPECT_EQ(0u, y.GetStringLength());
793 
794  // SetConsttring()
795  Value z;
796  z.SetString("Hello");
797  EXPECT_TRUE(x.IsString());
798  z.SetString("Hello", 5);
799  EXPECT_STREQ("Hello", z.GetString());
800  EXPECT_STREQ("Hello", z.GetString());
801  EXPECT_EQ(5u, z.GetStringLength());
802 
803  z.SetString("Hello");
804  EXPECT_TRUE(z.IsString());
805  EXPECT_STREQ("Hello", z.GetString());
806 
807  //z.SetString(mstr); // should not compile
808  //z.SetString(pstr); // should not compile
809  z.SetString(StringRef(mstr));
810  EXPECT_TRUE(z.IsString());
811  EXPECT_STREQ(z.GetString(), mstr);
812 
813  z.SetString(cstr);
814  EXPECT_TRUE(z.IsString());
815  EXPECT_EQ(cstr, z.GetString());
816 
817  z = cstr;
818  EXPECT_TRUE(z.IsString());
819  EXPECT_EQ(cstr, z.GetString());
820 
821  // SetString()
822  char s[] = "World";
823  Value w;
824  w.SetString(s, static_cast<SizeType>(strlen(s)), allocator);
825  s[0] = '\0';
826  EXPECT_STREQ("World", w.GetString());
827  EXPECT_EQ(5u, w.GetStringLength());
828 
829  // templated functions
830  EXPECT_TRUE(z.Is<const char*>());
831  EXPECT_STREQ(cstr, z.Get<const char*>());
832  EXPECT_STREQ("Apple", z.Set<const char*>("Apple").Get<const char*>());
833 
834 #if RAPIDJSON_HAS_STDSTRING
835  {
836  std::string str = "Hello World";
837  str[5] = '\0';
838  EXPECT_STREQ(str.data(),"Hello"); // embedded '\0'
839  EXPECT_EQ(str.size(), 11u);
840 
841  // no copy
842  Value vs0(StringRef(str));
843  EXPECT_TRUE(vs0.IsString());
844  EXPECT_EQ(vs0.GetString(), str.data());
845  EXPECT_EQ(vs0.GetStringLength(), str.size());
846  TestEqual(vs0, str);
847 
848  // do copy
849  Value vs1(str, allocator);
850  EXPECT_TRUE(vs1.IsString());
851  EXPECT_NE(vs1.GetString(), str.data());
852  EXPECT_NE(vs1.GetString(), str); // not equal due to embedded '\0'
853  EXPECT_EQ(vs1.GetStringLength(), str.size());
854  TestEqual(vs1, str);
855 
856  // SetString
857  str = "World";
858  vs0.SetNull().SetString(str, allocator);
859  EXPECT_TRUE(vs0.IsString());
860  EXPECT_STREQ(vs0.GetString(), str.c_str());
861  EXPECT_EQ(vs0.GetStringLength(), str.size());
862  TestEqual(str, vs0);
863  TestUnequal(str, vs1);
864 
865  // vs1 = str; // should not compile
866  vs1 = StringRef(str);
867  TestEqual(str, vs1);
868  TestEqual(vs0, vs1);
869 
870  // Templated function.
871  EXPECT_TRUE(vs0.Is<std::string>());
872  EXPECT_EQ(str, vs0.Get<std::string>());
873  vs0.Set<std::string>(std::string("Apple"), allocator);
874  EXPECT_EQ(std::string("Apple"), vs0.Get<std::string>());
875  vs0.Set(std::string("Orange"), allocator);
876  EXPECT_EQ(std::string("Orange"), vs0.Get<std::string>());
877  }
878 #endif // RAPIDJSON_HAS_STDSTRING
879 }
880 
881 // Issue 226: Value of string type should not point to NULL
882 TEST(Value, SetStringNull) {
883 
884  MemoryPoolAllocator<> allocator;
885  const char* nullPtr = 0;
886  {
887  // Construction with string type creates empty string
888  Value v(kStringType);
889  EXPECT_NE(v.GetString(), nullPtr); // non-null string returned
890  EXPECT_EQ(v.GetStringLength(), 0u);
891 
892  // Construction from/setting to null without length not allowed
894  EXPECT_THROW(Value(StringRef(nullPtr), allocator), AssertException);
895  EXPECT_THROW(v.SetString(nullPtr, allocator), AssertException);
896 
897  // Non-empty length with null string is not allowed
898  EXPECT_THROW(v.SetString(nullPtr, 17u), AssertException);
899  EXPECT_THROW(v.SetString(nullPtr, 42u, allocator), AssertException);
900 
901  // Setting to null string with empty length is allowed
902  v.SetString(nullPtr, 0u);
903  EXPECT_NE(v.GetString(), nullPtr); // non-null string returned
904  EXPECT_EQ(v.GetStringLength(), 0u);
905 
906  v.SetNull();
907  v.SetString(nullPtr, 0u, allocator);
908  EXPECT_NE(v.GetString(), nullPtr); // non-null string returned
909  EXPECT_EQ(v.GetStringLength(), 0u);
910  }
911  // Construction with null string and empty length is allowed
912  {
913  Value v(nullPtr,0u);
914  EXPECT_NE(v.GetString(), nullPtr); // non-null string returned
915  EXPECT_EQ(v.GetStringLength(), 0u);
916  }
917  {
918  Value v(nullPtr, 0u, allocator);
919  EXPECT_NE(v.GetString(), nullPtr); // non-null string returned
920  EXPECT_EQ(v.GetStringLength(), 0u);
921  }
922 }
923 
924 template <typename T, typename Allocator>
925 static void TestArray(T& x, Allocator& allocator) {
926  const T& y = x;
927 
928  // PushBack()
929  Value v;
930  x.PushBack(v, allocator);
931  v.SetBool(true);
932  x.PushBack(v, allocator);
933  v.SetBool(false);
934  x.PushBack(v, allocator);
935  v.SetInt(123);
936  x.PushBack(v, allocator);
937  //x.PushBack((const char*)"foo", allocator); // should not compile
938  x.PushBack("foo", allocator);
939 
940  EXPECT_FALSE(x.Empty());
941  EXPECT_EQ(5u, x.Size());
942  EXPECT_FALSE(y.Empty());
943  EXPECT_EQ(5u, y.Size());
944  EXPECT_TRUE(x[SizeType(0)].IsNull());
945  EXPECT_TRUE(x[1].IsTrue());
946  EXPECT_TRUE(x[2].IsFalse());
947  EXPECT_TRUE(x[3].IsInt());
948  EXPECT_EQ(123, x[3].GetInt());
949  EXPECT_TRUE(y[SizeType(0)].IsNull());
950  EXPECT_TRUE(y[1].IsTrue());
951  EXPECT_TRUE(y[2].IsFalse());
952  EXPECT_TRUE(y[3].IsInt());
953  EXPECT_EQ(123, y[3].GetInt());
954  EXPECT_TRUE(y[4].IsString());
955  EXPECT_STREQ("foo", y[4].GetString());
956 
957 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
958  // PushBack(GenericValue&&, Allocator&);
959  {
960  Value y2(kArrayType);
961  y2.PushBack(Value(true), allocator);
962  y2.PushBack(std::move(Value(kArrayType).PushBack(Value(1), allocator).PushBack("foo", allocator)), allocator);
963  EXPECT_EQ(2u, y2.Size());
964  EXPECT_TRUE(y2[0].IsTrue());
965  EXPECT_TRUE(y2[1].IsArray());
966  EXPECT_EQ(2u, y2[1].Size());
967  EXPECT_TRUE(y2[1][0].IsInt());
968  EXPECT_TRUE(y2[1][1].IsString());
969  }
970 #endif
971 
972  // iterator
973  typename T::ValueIterator itr = x.Begin();
974  EXPECT_TRUE(itr != x.End());
975  EXPECT_TRUE(itr->IsNull());
976  ++itr;
977  EXPECT_TRUE(itr != x.End());
978  EXPECT_TRUE(itr->IsTrue());
979  ++itr;
980  EXPECT_TRUE(itr != x.End());
981  EXPECT_TRUE(itr->IsFalse());
982  ++itr;
983  EXPECT_TRUE(itr != x.End());
984  EXPECT_TRUE(itr->IsInt());
985  EXPECT_EQ(123, itr->GetInt());
986  ++itr;
987  EXPECT_TRUE(itr != x.End());
988  EXPECT_TRUE(itr->IsString());
989  EXPECT_STREQ("foo", itr->GetString());
990 
991  // const iterator
992  typename T::ConstValueIterator citr = y.Begin();
993  EXPECT_TRUE(citr != y.End());
994  EXPECT_TRUE(citr->IsNull());
995  ++citr;
996  EXPECT_TRUE(citr != y.End());
997  EXPECT_TRUE(citr->IsTrue());
998  ++citr;
999  EXPECT_TRUE(citr != y.End());
1000  EXPECT_TRUE(citr->IsFalse());
1001  ++citr;
1002  EXPECT_TRUE(citr != y.End());
1003  EXPECT_TRUE(citr->IsInt());
1004  EXPECT_EQ(123, citr->GetInt());
1005  ++citr;
1006  EXPECT_TRUE(citr != y.End());
1007  EXPECT_TRUE(citr->IsString());
1008  EXPECT_STREQ("foo", citr->GetString());
1009 
1010  // PopBack()
1011  x.PopBack();
1012  EXPECT_EQ(4u, x.Size());
1013  EXPECT_TRUE(y[SizeType(0)].IsNull());
1014  EXPECT_TRUE(y[1].IsTrue());
1015  EXPECT_TRUE(y[2].IsFalse());
1016  EXPECT_TRUE(y[3].IsInt());
1017 
1018  // Clear()
1019  x.Clear();
1020  EXPECT_TRUE(x.Empty());
1021  EXPECT_EQ(0u, x.Size());
1022  EXPECT_TRUE(y.Empty());
1023  EXPECT_EQ(0u, y.Size());
1024 
1025  // Erase(ValueIterator)
1026 
1027  // Use array of array to ensure removed elements' destructor is called.
1028  // [[0],[1],[2],...]
1029  for (int i = 0; i < 10; i++)
1030  x.PushBack(Value(kArrayType).PushBack(i, allocator).Move(), allocator);
1031 
1032  // Erase the first
1033  itr = x.Erase(x.Begin());
1034  EXPECT_EQ(x.Begin(), itr);
1035  EXPECT_EQ(9u, x.Size());
1036  for (int i = 0; i < 9; i++)
1037  EXPECT_EQ(i + 1, x[static_cast<SizeType>(i)][0].GetInt());
1038 
1039  // Ease the last
1040  itr = x.Erase(x.End() - 1);
1041  EXPECT_EQ(x.End(), itr);
1042  EXPECT_EQ(8u, x.Size());
1043  for (int i = 0; i < 8; i++)
1044  EXPECT_EQ(i + 1, x[static_cast<SizeType>(i)][0].GetInt());
1045 
1046  // Erase the middle
1047  itr = x.Erase(x.Begin() + 4);
1048  EXPECT_EQ(x.Begin() + 4, itr);
1049  EXPECT_EQ(7u, x.Size());
1050  for (int i = 0; i < 4; i++)
1051  EXPECT_EQ(i + 1, x[static_cast<SizeType>(i)][0].GetInt());
1052  for (int i = 4; i < 7; i++)
1053  EXPECT_EQ(i + 2, x[static_cast<SizeType>(i)][0].GetInt());
1054 
1055  // Erase(ValueIterator, ValueIterator)
1056  // Exhaustive test with all 0 <= first < n, first <= last <= n cases
1057  const unsigned n = 10;
1058  for (unsigned first = 0; first < n; first++) {
1059  for (unsigned last = first; last <= n; last++) {
1060  x.Clear();
1061  for (unsigned i = 0; i < n; i++)
1062  x.PushBack(Value(kArrayType).PushBack(i, allocator).Move(), allocator);
1063 
1064  itr = x.Erase(x.Begin() + first, x.Begin() + last);
1065  if (last == n)
1066  EXPECT_EQ(x.End(), itr);
1067  else
1068  EXPECT_EQ(x.Begin() + first, itr);
1069 
1070  size_t removeCount = last - first;
1071  EXPECT_EQ(n - removeCount, x.Size());
1072  for (unsigned i = 0; i < first; i++)
1073  EXPECT_EQ(i, x[i][0].GetUint());
1074  for (unsigned i = first; i < n - removeCount; i++)
1075  EXPECT_EQ(i + removeCount, x[static_cast<SizeType>(i)][0].GetUint());
1076  }
1077  }
1078 }
1079 
1080 TEST(Value, Array) {
1081  Value x(kArrayType);
1082  const Value& y = x;
1083  Value::AllocatorType allocator;
1084 
1085  EXPECT_EQ(kArrayType, x.GetType());
1086  EXPECT_TRUE(x.IsArray());
1087  EXPECT_TRUE(x.Empty());
1088  EXPECT_EQ(0u, x.Size());
1089  EXPECT_TRUE(y.IsArray());
1090  EXPECT_TRUE(y.Empty());
1091  EXPECT_EQ(0u, y.Size());
1092 
1093  EXPECT_FALSE(x.IsNull());
1094  EXPECT_FALSE(x.IsBool());
1095  EXPECT_FALSE(x.IsFalse());
1096  EXPECT_FALSE(x.IsTrue());
1097  EXPECT_FALSE(x.IsString());
1098  EXPECT_FALSE(x.IsObject());
1099 
1100  TestArray(x, allocator);
1101 
1102  // Working in gcc without C++11, but VS2013 cannot compile. To be diagnosed.
1103  // http://en.wikipedia.org/wiki/Erase-remove_idiom
1104  x.Clear();
1105  for (int i = 0; i < 10; i++)
1106  if (i % 2 == 0)
1107  x.PushBack(i, allocator);
1108  else
1109  x.PushBack(Value(kNullType).Move(), allocator);
1110 
1111  const Value null(kNullType);
1112  x.Erase(std::remove(x.Begin(), x.End(), null), x.End());
1113  EXPECT_EQ(5u, x.Size());
1114  for (int i = 0; i < 5; i++)
1115  EXPECT_EQ(i * 2, x[static_cast<SizeType>(i)]);
1116 
1117  // SetArray()
1118  Value z;
1119  z.SetArray();
1120  EXPECT_TRUE(z.IsArray());
1121  EXPECT_TRUE(z.Empty());
1122 }
1123 
1124 TEST(Value, ArrayHelper) {
1125  Value::AllocatorType allocator;
1126  {
1127  Value x(kArrayType);
1128  Value::Array a = x.GetArray();
1129  TestArray(a, allocator);
1130  }
1131 
1132  {
1133  Value x(kArrayType);
1134  Value::Array a = x.GetArray();
1135  a.PushBack(1, allocator);
1136 
1137  Value::Array a2(a); // copy constructor
1138  EXPECT_EQ(1, a2.Size());
1139 
1140  Value::Array a3 = a;
1141  EXPECT_EQ(1, a3.Size());
1142 
1143  Value::ConstArray y = static_cast<const Value&>(x).GetArray();
1144  (void)y;
1145  // y.PushBack(1, allocator); // should not compile
1146 
1147  // Templated functions
1148  x.Clear();
1149  EXPECT_TRUE(x.Is<Value::Array>());
1150  EXPECT_TRUE(x.Is<Value::ConstArray>());
1151  a.PushBack(1, allocator);
1152  EXPECT_EQ(1, x.Get<Value::Array>()[0].GetInt());
1153  EXPECT_EQ(1, x.Get<Value::ConstArray>()[0].GetInt());
1154 
1155  Value x2;
1156  x2.Set<Value::Array>(a);
1157  EXPECT_TRUE(x.IsArray()); // IsArray() is invariant after moving.
1158  EXPECT_EQ(1, x2.Get<Value::Array>()[0].GetInt());
1159  }
1160 
1161  {
1162  Value y(kArrayType);
1163  y.PushBack(123, allocator);
1164 
1165  Value x(y.GetArray()); // Construct value form array.
1166  EXPECT_TRUE(x.IsArray());
1167  EXPECT_EQ(123, x[0].GetInt());
1168  EXPECT_TRUE(y.IsArray()); // Invariant
1169  EXPECT_TRUE(y.Empty());
1170  }
1171 
1172  {
1173  Value x(kArrayType);
1174  Value y(kArrayType);
1175  y.PushBack(123, allocator);
1176  x.PushBack(y.GetArray(), allocator); // Implicit constructor to convert Array to GenericValue
1177 
1178  EXPECT_EQ(1, x.Size());
1179  EXPECT_EQ(123, x[0][0].GetInt());
1180  EXPECT_TRUE(y.IsArray());
1181  EXPECT_TRUE(y.Empty());
1182  }
1183 }
1184 
1185 #if RAPIDJSON_HAS_CXX11_RANGE_FOR
1186 TEST(Value, ArrayHelperRangeFor) {
1187  Value::AllocatorType allocator;
1188  Value x(kArrayType);
1189 
1190  for (int i = 0; i < 10; i++)
1191  x.PushBack(i, allocator);
1192 
1193  {
1194  int i = 0;
1195  for (auto& v : x.GetArray()) {
1196  EXPECT_EQ(i, v.GetInt());
1197  i++;
1198  }
1199  EXPECT_EQ(i, 10);
1200  }
1201  {
1202  int i = 0;
1203  for (const auto& v : const_cast<const Value&>(x).GetArray()) {
1204  EXPECT_EQ(i, v.GetInt());
1205  i++;
1206  }
1207  EXPECT_EQ(i, 10);
1208  }
1209 
1210  // Array a = x.GetArray();
1211  // Array ca = const_cast<const Value&>(x).GetArray();
1212 }
1213 #endif
1214 
1215 template <typename T, typename Allocator>
1216 static void TestObject(T& x, Allocator& allocator) {
1217  const T& y = x; // const version
1218 
1219  // AddMember()
1220  x.AddMember("A", "Apple", allocator);
1221  EXPECT_FALSE(x.ObjectEmpty());
1222  EXPECT_EQ(1u, x.MemberCount());
1223 
1224  Value value("Banana", 6);
1225  x.AddMember("B", "Banana", allocator);
1226  EXPECT_EQ(2u, x.MemberCount());
1227 
1228  // AddMember<T>(StringRefType, T, Allocator)
1229  {
1230  Value o(kObjectType);
1231  o.AddMember("true", true, allocator);
1232  o.AddMember("false", false, allocator);
1233  o.AddMember("int", -1, allocator);
1234  o.AddMember("uint", 1u, allocator);
1235  o.AddMember("int64", int64_t(-4294967296), allocator);
1236  o.AddMember("uint64", uint64_t(4294967296), allocator);
1237  o.AddMember("double", 3.14, allocator);
1238  o.AddMember("string", "Jelly", allocator);
1239 
1240  EXPECT_TRUE(o["true"].GetBool());
1241  EXPECT_FALSE(o["false"].GetBool());
1242  EXPECT_EQ(-1, o["int"].GetInt());
1243  EXPECT_EQ(1u, o["uint"].GetUint());
1244  EXPECT_EQ(int64_t(-4294967296), o["int64"].GetInt64());
1245  EXPECT_EQ(uint64_t(4294967296), o["uint64"].GetUint64());
1246  EXPECT_STREQ("Jelly",o["string"].GetString());
1247  EXPECT_EQ(8u, o.MemberCount());
1248  }
1249 
1250  // AddMember<T>(Value&, T, Allocator)
1251  {
1252  Value o(kObjectType);
1253 
1254  Value n("s");
1255  o.AddMember(n, "string", allocator);
1256  EXPECT_EQ(1u, o.MemberCount());
1257 
1258  Value count("#");
1259  o.AddMember(count, o.MemberCount(), allocator);
1260  EXPECT_EQ(2u, o.MemberCount());
1261  }
1262 
1263 #if RAPIDJSON_HAS_STDSTRING
1264  {
1265  // AddMember(StringRefType, const std::string&, Allocator)
1266  Value o(kObjectType);
1267  o.AddMember("b", std::string("Banana"), allocator);
1268  EXPECT_STREQ("Banana", o["b"].GetString());
1269 
1270  // RemoveMember(const std::string&)
1271  o.RemoveMember(std::string("b"));
1272  EXPECT_TRUE(o.ObjectEmpty());
1273  }
1274 #endif
1275 
1276 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1277  // AddMember(GenericValue&&, ...) variants
1278  {
1279  Value o(kObjectType);
1280  o.AddMember(Value("true"), Value(true), allocator);
1281  o.AddMember(Value("false"), Value(false).Move(), allocator); // value is lvalue ref
1282  o.AddMember(Value("int").Move(), Value(-1), allocator); // name is lvalue ref
1283  o.AddMember("uint", std::move(Value().SetUint(1u)), allocator); // name is literal, value is rvalue
1284  EXPECT_TRUE(o["true"].GetBool());
1285  EXPECT_FALSE(o["false"].GetBool());
1286  EXPECT_EQ(-1, o["int"].GetInt());
1287  EXPECT_EQ(1u, o["uint"].GetUint());
1288  EXPECT_EQ(4u, o.MemberCount());
1289  }
1290 #endif
1291 
1292  // Tests a member with null character
1293  Value name;
1294  const Value C0D("C\0D", 3);
1295  name.SetString(C0D.GetString(), 3);
1296  value.SetString("CherryD", 7);
1297  x.AddMember(name, value, allocator);
1298 
1299  // HasMember()
1300  EXPECT_TRUE(x.HasMember("A"));
1301  EXPECT_TRUE(x.HasMember("B"));
1302  EXPECT_TRUE(y.HasMember("A"));
1303  EXPECT_TRUE(y.HasMember("B"));
1304 
1305 #if RAPIDJSON_HAS_STDSTRING
1306  EXPECT_TRUE(x.HasMember(std::string("A")));
1307 #endif
1308 
1309  name.SetString("C\0D");
1310  EXPECT_TRUE(x.HasMember(name));
1311  EXPECT_TRUE(y.HasMember(name));
1312 
1313  GenericValue<UTF8<>, CrtAllocator> othername("A");
1314  EXPECT_TRUE(x.HasMember(othername));
1315  EXPECT_TRUE(y.HasMember(othername));
1316  othername.SetString("C\0D");
1317  EXPECT_TRUE(x.HasMember(othername));
1318  EXPECT_TRUE(y.HasMember(othername));
1319 
1320  // operator[]
1321  EXPECT_STREQ("Apple", x["A"].GetString());
1322  EXPECT_STREQ("Banana", x["B"].GetString());
1323  EXPECT_STREQ("CherryD", x[C0D].GetString());
1324  EXPECT_STREQ("CherryD", x[othername].GetString());
1325  EXPECT_THROW(x["nonexist"], AssertException);
1326 
1327  // const operator[]
1328  EXPECT_STREQ("Apple", y["A"].GetString());
1329  EXPECT_STREQ("Banana", y["B"].GetString());
1330  EXPECT_STREQ("CherryD", y[C0D].GetString());
1331 
1332 #if RAPIDJSON_HAS_STDSTRING
1333  EXPECT_STREQ("Apple", x["A"].GetString());
1334  EXPECT_STREQ("Apple", y[std::string("A")].GetString());
1335 #endif
1336 
1337  // member iterator
1338  Value::MemberIterator itr = x.MemberBegin();
1339  EXPECT_TRUE(itr != x.MemberEnd());
1340  EXPECT_STREQ("A", itr->name.GetString());
1341  EXPECT_STREQ("Apple", itr->value.GetString());
1342  ++itr;
1343  EXPECT_TRUE(itr != x.MemberEnd());
1344  EXPECT_STREQ("B", itr->name.GetString());
1345  EXPECT_STREQ("Banana", itr->value.GetString());
1346  ++itr;
1347  EXPECT_TRUE(itr != x.MemberEnd());
1348  EXPECT_TRUE(memcmp(itr->name.GetString(), "C\0D", 4) == 0);
1349  EXPECT_STREQ("CherryD", itr->value.GetString());
1350  ++itr;
1351  EXPECT_FALSE(itr != x.MemberEnd());
1352 
1353  // const member iterator
1354  Value::ConstMemberIterator citr = y.MemberBegin();
1355  EXPECT_TRUE(citr != y.MemberEnd());
1356  EXPECT_STREQ("A", citr->name.GetString());
1357  EXPECT_STREQ("Apple", citr->value.GetString());
1358  ++citr;
1359  EXPECT_TRUE(citr != y.MemberEnd());
1360  EXPECT_STREQ("B", citr->name.GetString());
1361  EXPECT_STREQ("Banana", citr->value.GetString());
1362  ++citr;
1363  EXPECT_TRUE(citr != y.MemberEnd());
1364  EXPECT_TRUE(memcmp(citr->name.GetString(), "C\0D", 4) == 0);
1365  EXPECT_STREQ("CherryD", citr->value.GetString());
1366  ++citr;
1367  EXPECT_FALSE(citr != y.MemberEnd());
1368 
1369  // member iterator conversions/relations
1370  itr = x.MemberBegin();
1371  citr = x.MemberBegin(); // const conversion
1372  TestEqual(itr, citr);
1373  EXPECT_TRUE(itr < x.MemberEnd());
1374  EXPECT_FALSE(itr > y.MemberEnd());
1375  EXPECT_TRUE(citr < x.MemberEnd());
1376  EXPECT_FALSE(citr > y.MemberEnd());
1377  ++citr;
1378  TestUnequal(itr, citr);
1379  EXPECT_FALSE(itr < itr);
1380  EXPECT_TRUE(itr < citr);
1381  EXPECT_FALSE(itr > itr);
1382  EXPECT_TRUE(citr > itr);
1383  EXPECT_EQ(1, citr - x.MemberBegin());
1384  EXPECT_EQ(0, itr - y.MemberBegin());
1385  itr += citr - x.MemberBegin();
1386  EXPECT_EQ(1, itr - y.MemberBegin());
1387  TestEqual(citr, itr);
1388  EXPECT_TRUE(itr <= citr);
1389  EXPECT_TRUE(citr <= itr);
1390  itr++;
1391  EXPECT_TRUE(itr >= citr);
1392  EXPECT_FALSE(citr >= itr);
1393 
1394  // RemoveMember()
1395  EXPECT_TRUE(x.RemoveMember("A"));
1396  EXPECT_FALSE(x.HasMember("A"));
1397 
1398  EXPECT_TRUE(x.RemoveMember("B"));
1399  EXPECT_FALSE(x.HasMember("B"));
1400 
1401  EXPECT_FALSE(x.RemoveMember("nonexist"));
1402 
1403  EXPECT_TRUE(x.RemoveMember(othername));
1404  EXPECT_FALSE(x.HasMember(name));
1405 
1406  EXPECT_TRUE(x.MemberBegin() == x.MemberEnd());
1407 
1408  // EraseMember(ConstMemberIterator)
1409 
1410  // Use array members to ensure removed elements' destructor is called.
1411  // { "a": [0], "b": [1],[2],...]
1412  const char keys[][2] = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j" };
1413  for (int i = 0; i < 10; i++)
1414  x.AddMember(keys[i], Value(kArrayType).PushBack(i, allocator), allocator);
1415 
1416  // MemberCount, iterator difference
1417  EXPECT_EQ(x.MemberCount(), SizeType(x.MemberEnd() - x.MemberBegin()));
1418 
1419  // Erase the first
1420  itr = x.EraseMember(x.MemberBegin());
1421  EXPECT_FALSE(x.HasMember(keys[0]));
1422  EXPECT_EQ(x.MemberBegin(), itr);
1423  EXPECT_EQ(9u, x.MemberCount());
1424  for (; itr != x.MemberEnd(); ++itr) {
1425  size_t i = static_cast<size_t>((itr - x.MemberBegin())) + 1;
1426  EXPECT_STREQ(itr->name.GetString(), keys[i]);
1427  EXPECT_EQ(i, itr->value[0].GetInt());
1428  }
1429 
1430  // Erase the last
1431  itr = x.EraseMember(x.MemberEnd() - 1);
1432  EXPECT_FALSE(x.HasMember(keys[9]));
1433  EXPECT_EQ(x.MemberEnd(), itr);
1434  EXPECT_EQ(8u, x.MemberCount());
1435  for (; itr != x.MemberEnd(); ++itr) {
1436  size_t i = static_cast<size_t>(itr - x.MemberBegin()) + 1;
1437  EXPECT_STREQ(itr->name.GetString(), keys[i]);
1438  EXPECT_EQ(i, itr->value[0].GetInt());
1439  }
1440 
1441  // Erase the middle
1442  itr = x.EraseMember(x.MemberBegin() + 4);
1443  EXPECT_FALSE(x.HasMember(keys[5]));
1444  EXPECT_EQ(x.MemberBegin() + 4, itr);
1445  EXPECT_EQ(7u, x.MemberCount());
1446  for (; itr != x.MemberEnd(); ++itr) {
1447  size_t i = static_cast<size_t>(itr - x.MemberBegin());
1448  i += (i < 4) ? 1 : 2;
1449  EXPECT_STREQ(itr->name.GetString(), keys[i]);
1450  EXPECT_EQ(i, itr->value[0].GetInt());
1451  }
1452 
1453  // EraseMember(ConstMemberIterator, ConstMemberIterator)
1454  // Exhaustive test with all 0 <= first < n, first <= last <= n cases
1455  const unsigned n = 10;
1456  for (unsigned first = 0; first < n; first++) {
1457  for (unsigned last = first; last <= n; last++) {
1458  x.RemoveAllMembers();
1459  for (unsigned i = 0; i < n; i++)
1460  x.AddMember(keys[i], Value(kArrayType).PushBack(i, allocator), allocator);
1461 
1462  itr = x.EraseMember(x.MemberBegin() + static_cast<int>(first), x.MemberBegin() + static_cast<int>(last));
1463  if (last == n)
1464  EXPECT_EQ(x.MemberEnd(), itr);
1465  else
1466  EXPECT_EQ(x.MemberBegin() + static_cast<int>(first), itr);
1467 
1468  size_t removeCount = last - first;
1469  EXPECT_EQ(n - removeCount, x.MemberCount());
1470  for (unsigned i = 0; i < first; i++)
1471  EXPECT_EQ(i, x[keys[i]][0].GetUint());
1472  for (unsigned i = first; i < n - removeCount; i++)
1473  EXPECT_EQ(i + removeCount, x[keys[i+removeCount]][0].GetUint());
1474  }
1475  }
1476 
1477  // RemoveAllMembers()
1478  x.RemoveAllMembers();
1479  EXPECT_TRUE(x.ObjectEmpty());
1480  EXPECT_EQ(0u, x.MemberCount());
1481 }
1482 
1483 TEST(Value, Object) {
1484  Value x(kObjectType);
1485  const Value& y = x; // const version
1486  Value::AllocatorType allocator;
1487 
1488  EXPECT_EQ(kObjectType, x.GetType());
1489  EXPECT_TRUE(x.IsObject());
1490  EXPECT_TRUE(x.ObjectEmpty());
1491  EXPECT_EQ(0u, x.MemberCount());
1492  EXPECT_EQ(kObjectType, y.GetType());
1493  EXPECT_TRUE(y.IsObject());
1494  EXPECT_TRUE(y.ObjectEmpty());
1495  EXPECT_EQ(0u, y.MemberCount());
1496 
1497  TestObject(x, allocator);
1498 
1499  // SetObject()
1500  Value z;
1501  z.SetObject();
1502  EXPECT_TRUE(z.IsObject());
1503 }
1504 
1505 TEST(Value, ObjectHelper) {
1506  Value::AllocatorType allocator;
1507  {
1508  Value x(kObjectType);
1509  Value::Object o = x.GetObject();
1510  TestObject(o, allocator);
1511  }
1512 
1513  {
1514  Value x(kObjectType);
1515  Value::Object o = x.GetObject();
1516  o.AddMember("1", 1, allocator);
1517 
1518  Value::Object o2(o); // copy constructor
1519  EXPECT_EQ(1, o2.MemberCount());
1520 
1521  Value::Object o3 = o;
1522  EXPECT_EQ(1, o3.MemberCount());
1523 
1524  Value::ConstObject y = static_cast<const Value&>(x).GetObject();
1525  (void)y;
1526  // y.AddMember("1", 1, allocator); // should not compile
1527 
1528  // Templated functions
1529  x.RemoveAllMembers();
1530  EXPECT_TRUE(x.Is<Value::Object>());
1532  o.AddMember("1", 1, allocator);
1533  EXPECT_EQ(1, x.Get<Value::Object>()["1"].GetInt());
1534  EXPECT_EQ(1, x.Get<Value::ConstObject>()["1"].GetInt());
1535 
1536  Value x2;
1537  x2.Set<Value::Object>(o);
1538  EXPECT_TRUE(x.IsObject()); // IsObject() is invariant after moving
1539  EXPECT_EQ(1, x2.Get<Value::Object>()["1"].GetInt());
1540  }
1541 
1542  {
1543  Value x(kObjectType);
1544  x.AddMember("a", "apple", allocator);
1545  Value y(x.GetObject());
1546  EXPECT_STREQ("apple", y["a"].GetString());
1547  EXPECT_TRUE(x.IsObject()); // Invariant
1548  }
1549 
1550  {
1551  Value x(kObjectType);
1552  x.AddMember("a", "apple", allocator);
1553  Value y(kObjectType);
1554  y.AddMember("fruits", x.GetObject(), allocator);
1555  EXPECT_STREQ("apple", y["fruits"]["a"].GetString());
1556  EXPECT_TRUE(x.IsObject()); // Invariant
1557  }
1558 }
1559 
1560 #if RAPIDJSON_HAS_CXX11_RANGE_FOR
1561 TEST(Value, ObjectHelperRangeFor) {
1562  Value::AllocatorType allocator;
1563  Value x(kObjectType);
1564 
1565  for (int i = 0; i < 10; i++) {
1566  char name[10];
1567  Value n(name, static_cast<SizeType>(sprintf(name, "%d", i)), allocator);
1568  x.AddMember(n, i, allocator);
1569  }
1570 
1571  {
1572  int i = 0;
1573  for (auto& m : x.GetObject()) {
1574  char name[10];
1575  sprintf(name, "%d", i);
1576  EXPECT_STREQ(name, m.name.GetString());
1577  EXPECT_EQ(i, m.value.GetInt());
1578  i++;
1579  }
1580  EXPECT_EQ(i, 10);
1581  }
1582  {
1583  int i = 0;
1584  for (const auto& m : const_cast<const Value&>(x).GetObject()) {
1585  char name[10];
1586  sprintf(name, "%d", i);
1587  EXPECT_STREQ(name, m.name.GetString());
1588  EXPECT_EQ(i, m.value.GetInt());
1589  i++;
1590  }
1591  EXPECT_EQ(i, 10);
1592  }
1593 
1594  // Object a = x.GetObject();
1595  // Object ca = const_cast<const Value&>(x).GetObject();
1596 }
1597 #endif
1598 
1599 TEST(Value, EraseMember_String) {
1600  Value::AllocatorType allocator;
1601  Value x(kObjectType);
1602  x.AddMember("A", "Apple", allocator);
1603  x.AddMember("B", "Banana", allocator);
1604 
1605  EXPECT_TRUE(x.EraseMember("B"));
1606  EXPECT_FALSE(x.HasMember("B"));
1607 
1608  EXPECT_FALSE(x.EraseMember("nonexist"));
1609 
1610  GenericValue<UTF8<>, CrtAllocator> othername("A");
1611  EXPECT_TRUE(x.EraseMember(othername));
1612  EXPECT_FALSE(x.HasMember("A"));
1613 
1614  EXPECT_TRUE(x.MemberBegin() == x.MemberEnd());
1615 }
1616 
1617 TEST(Value, BigNestedArray) {
1618  MemoryPoolAllocator<> allocator;
1619  Value x(kArrayType);
1620  static const SizeType n = 200;
1621 
1622  for (SizeType i = 0; i < n; i++) {
1623  Value y(kArrayType);
1624  for (SizeType j = 0; j < n; j++) {
1625  Value number(static_cast<int>(i * n + j));
1626  y.PushBack(number, allocator);
1627  }
1628  x.PushBack(y, allocator);
1629  }
1630 
1631  for (SizeType i = 0; i < n; i++)
1632  for (SizeType j = 0; j < n; j++) {
1633  EXPECT_TRUE(x[i][j].IsInt());
1634  EXPECT_EQ(static_cast<int>(i * n + j), x[i][j].GetInt());
1635  }
1636 }
1637 
1638 TEST(Value, BigNestedObject) {
1639  MemoryPoolAllocator<> allocator;
1640  Value x(kObjectType);
1641  static const SizeType n = 200;
1642 
1643  for (SizeType i = 0; i < n; i++) {
1644  char name1[10];
1645  sprintf(name1, "%d", i);
1646 
1647  // Value name(name1); // should not compile
1648  Value name(name1, static_cast<SizeType>(strlen(name1)), allocator);
1649  Value object(kObjectType);
1650 
1651  for (SizeType j = 0; j < n; j++) {
1652  char name2[10];
1653  sprintf(name2, "%d", j);
1654 
1655  Value name3(name2, static_cast<SizeType>(strlen(name2)), allocator);
1656  Value number(static_cast<int>(i * n + j));
1657  object.AddMember(name3, number, allocator);
1658  }
1659 
1660  // x.AddMember(name1, object, allocator); // should not compile
1661  x.AddMember(name, object, allocator);
1662  }
1663 
1664  for (SizeType i = 0; i < n; i++) {
1665  char name1[10];
1666  sprintf(name1, "%d", i);
1667 
1668  for (SizeType j = 0; j < n; j++) {
1669  char name2[10];
1670  sprintf(name2, "%d", j);
1671  x[name1];
1672  EXPECT_EQ(static_cast<int>(i * n + j), x[name1][name2].GetInt());
1673  }
1674  }
1675 }
1676 
1677 // Issue 18: Error removing last element of object
1678 // http://code.google.com/p/rapidjson/issues/detail?id=18
1679 TEST(Value, RemoveLastElement) {
1680  rapidjson::Document doc;
1681  rapidjson::Document::AllocatorType& allocator = doc.GetAllocator();
1683  objVal.AddMember("var1", 123, allocator);
1684  objVal.AddMember("var2", "444", allocator);
1685  objVal.AddMember("var3", 555, allocator);
1686  EXPECT_TRUE(objVal.HasMember("var3"));
1687  objVal.RemoveMember("var3"); // Assertion here in r61
1688  EXPECT_FALSE(objVal.HasMember("var3"));
1689 }
1690 
1691 // Issue 38: Segmentation fault with CrtAllocator
1693  typedef GenericValue<UTF8<>, CrtAllocator> V;
1694 
1695  V::AllocatorType allocator;
1696  V o(kObjectType);
1697  o.AddMember("x", 1, allocator); // Should not call destructor on uninitialized name/value of newly allocated members.
1698 
1699  V a(kArrayType);
1700  a.PushBack(1, allocator); // Should not call destructor on uninitialized Value of newly allocated elements.
1701 }
1702 
1703 static void TestShortStringOptimization(const char* str) {
1704  const rapidjson::SizeType len = static_cast<rapidjson::SizeType>(strlen(str));
1705 
1706  rapidjson::Document doc;
1707  rapidjson::Value val;
1708  val.SetString(str, len, doc.GetAllocator());
1709 
1710  EXPECT_EQ(val.GetStringLength(), len);
1711  EXPECT_STREQ(val.GetString(), str);
1712 }
1713 
1714 TEST(Value, AllocateShortString) {
1715  TestShortStringOptimization(""); // edge case: empty string
1716  TestShortStringOptimization("12345678"); // regular case for short strings: 8 chars
1717  TestShortStringOptimization("12345678901"); // edge case: 11 chars in 32-bit mode (=> short string)
1718  TestShortStringOptimization("123456789012"); // edge case: 12 chars in 32-bit mode (=> regular string)
1719  TestShortStringOptimization("123456789012345"); // edge case: 15 chars in 64-bit mode (=> short string)
1720  TestShortStringOptimization("1234567890123456"); // edge case: 16 chars in 64-bit mode (=> regular string)
1721 }
1722 
1723 template <int e>
1724 struct TerminateHandler {
1725  bool Null() { return e != 0; }
1726  bool Bool(bool) { return e != 1; }
1727  bool Int(int) { return e != 2; }
1728  bool Uint(unsigned) { return e != 3; }
1729  bool Int64(int64_t) { return e != 4; }
1730  bool Uint64(uint64_t) { return e != 5; }
1731  bool Double(double) { return e != 6; }
1732  bool RawNumber(const char*, SizeType, bool) { return e != 7; }
1733  bool String(const char*, SizeType, bool) { return e != 8; }
1734  bool StartObject() { return e != 9; }
1735  bool Key(const char*, SizeType, bool) { return e != 10; }
1736  bool EndObject(SizeType) { return e != 11; }
1737  bool StartArray() { return e != 12; }
1738  bool EndArray(SizeType) { return e != 13; }
1739 };
1740 
1741 #define TEST_TERMINATION(e, json)\
1742 {\
1743  Document d; \
1744  EXPECT_FALSE(d.Parse(json).HasParseError()); \
1745  Reader reader; \
1746  TerminateHandler<e> h;\
1747  EXPECT_FALSE(d.Accept(h));\
1748 }
1749 
1750 TEST(Value, AcceptTerminationByHandler) {
1751  TEST_TERMINATION(0, "[null]");
1752  TEST_TERMINATION(1, "[true]");
1753  TEST_TERMINATION(1, "[false]");
1754  TEST_TERMINATION(2, "[-1]");
1755  TEST_TERMINATION(3, "[2147483648]");
1756  TEST_TERMINATION(4, "[-1234567890123456789]");
1757  TEST_TERMINATION(5, "[9223372036854775808]");
1758  TEST_TERMINATION(6, "[0.5]");
1759  // RawNumber() is never called
1760  TEST_TERMINATION(8, "[\"a\"]");
1761  TEST_TERMINATION(9, "[{}]");
1762  TEST_TERMINATION(10, "[{\"a\":1}]");
1763  TEST_TERMINATION(11, "[{}]");
1764  TEST_TERMINATION(12, "{\"a\":[]}");
1765  TEST_TERMINATION(13, "{\"a\":[]}");
1766 }
1767 
1769  bool operator()(const Value& lhs, const Value& rhs) const {
1770  return lhs.GetInt() < rhs.GetInt();
1771  }
1772 };
1773 
1774 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1775 TEST(Value, Sorting) {
1776  Value::AllocatorType allocator;
1777  Value a(kArrayType);
1778  a.PushBack(5, allocator);
1779  a.PushBack(1, allocator);
1780  a.PushBack(3, allocator);
1781  std::sort(a.Begin(), a.End(), ValueIntComparer());
1782  EXPECT_EQ(1, a[0].GetInt());
1783  EXPECT_EQ(3, a[1].GetInt());
1784  EXPECT_EQ(5, a[2].GetInt());
1785 }
1786 #endif
1787 
1788 // http://stackoverflow.com/questions/35222230/
1789 
1790 static void MergeDuplicateKey(Value& v, Value::AllocatorType& a) {
1791  if (v.IsObject()) {
1792  // Convert all key:value into key:[value]
1793  for (Value::MemberIterator itr = v.MemberBegin(); itr != v.MemberEnd(); ++itr)
1794  itr->value = Value(kArrayType).Move().PushBack(itr->value, a);
1795 
1796  // Merge arrays if key is duplicated
1797  for (Value::MemberIterator itr = v.MemberBegin(); itr != v.MemberEnd();) {
1798  Value::MemberIterator itr2 = v.FindMember(itr->name);
1799  if (itr != itr2) {
1800  itr2->value.PushBack(itr->value[0], a);
1801  itr = v.EraseMember(itr);
1802  }
1803  else
1804  ++itr;
1805  }
1806 
1807  // Convert key:[values] back to key:value if there is only one value
1808  for (Value::MemberIterator itr = v.MemberBegin(); itr != v.MemberEnd(); ++itr) {
1809  if (itr->value.Size() == 1)
1810  itr->value = itr->value[0];
1811  MergeDuplicateKey(itr->value, a); // Recursion on the value
1812  }
1813  }
1814  else if (v.IsArray())
1815  for (Value::ValueIterator itr = v.Begin(); itr != v.End(); ++itr)
1816  MergeDuplicateKey(*itr, a);
1817 }
1818 
1819 TEST(Value, MergeDuplicateKey) {
1820  Document d;
1821  d.Parse(
1822  "{"
1823  " \"key1\": {"
1824  " \"a\": \"asdf\","
1825  " \"b\": \"foo\","
1826  " \"b\": \"bar\","
1827  " \"c\": \"fdas\""
1828  " }"
1829  "}");
1830 
1831  Document d2;
1832  d2.Parse(
1833  "{"
1834  " \"key1\": {"
1835  " \"a\": \"asdf\","
1836  " \"b\": ["
1837  " \"foo\","
1838  " \"bar\""
1839  " ],"
1840  " \"c\": \"fdas\""
1841  " }"
1842  "}");
1843 
1844  EXPECT_NE(d2, d);
1845  MergeDuplicateKey(d, d.GetAllocator());
1846  EXPECT_EQ(d2, d);
1847 }
1848 
1849 #ifdef __clang__
1850 RAPIDJSON_DIAG_POP
1851 #endif
void TestUnequal(const A &a, const B &b)
Definition: valuetest.cpp:173
TypeWithSize< 8 >::Int Int64
Definition: gtest-port.h:2496
void TestEqual(const A &a, const B &b)
Definition: valuetest.cpp:165
bool EndArray(SizeType)
Definition: valuetest.cpp:1738
SizeType Size() const
Definition: document.h:2538
const uint32_t T[512]
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:389
bool String(const char *, SizeType, bool)
Definition: valuetest.cpp:1733
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
#define EXPECT_STREQ(s1, s2)
Definition: gtest.h:1995
#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:624
::std::string string
Definition: gtest-port.h:1097
GTEST_API_ bool IsTrue(bool condition)
C-runtime library allocator.
Definition: allocators.h:75
#define EXPECT_THROW(statement, expected_exception)
Definition: gtest.h:1843
array
Definition: rapidjson.h:625
#define RAPIDJSON_STATIC_ASSERT(x)
(Internal) macro to check for conditions at compile-time
Definition: rapidjson.h:450
bool Double(double)
Definition: valuetest.cpp:1731
false
Definition: rapidjson.h:622
const char * name
bool operator()(const Value &lhs, const Value &rhs) const
Definition: valuetest.cpp:1769
#define EXPECT_NEAR(val1, val2, abs_error)
Definition: gtest.h:2043
Allocator & GetAllocator()
Get the allocator of this document.
Definition: document.h:2418
void TestCopyFrom()
Definition: valuetest.cpp:250
bool Key(const char *, SizeType, bool)
Definition: valuetest.cpp:1735
bool RawNumber(const char *, SizeType, bool)
Definition: valuetest.cpp:1732
mdb_size_t count(MDB_cursor *cur)
string
Definition: rapidjson.h:626
GenericValue< UTF8<> > Value
GenericValue with UTF8 encoding.
Definition: document.h:2116
FloatingPoint< float > Float
unsigned __int64 uint64_t
Definition: stdint.h:136
GenericObject AddMember(ValueType &name, ValueType &value, AllocatorType &allocator) const
Definition: document.h:2614
#define TEST_TERMINATION(e, json)
Definition: valuetest.cpp:1741
GenericDocument< UTF8<> > Document
GenericDocument with UTF8 encoding.
Definition: document.h:2512
number
Definition: rapidjson.h:627
void Swap(T &a, T &b) RAPIDJSON_NOEXCEPT
Custom swap() to avoid dependency on C++ <algorithm> header.
Definition: swap.h:33
#define EXPECT_NE(val1, val2)
Definition: gtest.h:1926
main RapidJSON namespace
PolymorphicMatcher< internal::IsNullMatcher > IsNull()
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition: pointer.h:1124
bool Uint(unsigned)
Definition: valuetest.cpp:1728
Helper class for accessing Value of array type.
Definition: document.h:558
SizeType MemberCount() const
Definition: document.h:2593
GenericDocument & Parse(const typename SourceEncoding::Ch *str)
Parse JSON text from a read-only string (with Encoding conversion)
Definition: document.h:2331
GenericStringRef< CharType > StringRef(const CharType *str)
Mark a character pointer as constant string.
Definition: document.h:361
const T & move(const T &t)
Definition: gtest-port.h:1317
FloatingPoint< double > Double
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1225
Matcher< T > A()
signed __int64 int64_t
Definition: stdint.h:135
Helper class for accessing Value of object type.
Definition: document.h:559
bool Uint64(uint64_t)
Definition: valuetest.cpp:1730
#define EXPECT_DOUBLE_EQ(val1, val2)
Definition: gtest.h:2031
true
Definition: rapidjson.h:623
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
Concept for allocating, resizing and freeing memory block.
(Constant) member iterator for a JSON object value
Definition: document.h:99
bool Int64(int64_t)
Definition: valuetest.cpp:1729
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
bool Bool(bool)
Definition: valuetest.cpp:1726
TEST(Value, Size)
Definition: valuetest.cpp:26
A document for parsing JSON text as DOM.
Definition: document.h:60
null
Definition: rapidjson.h:621
bool EndObject(SizeType)
Definition: valuetest.cpp:1736