ES-DE/external/rapidjson/test/unittest/valuetest.cpp

1862 lines
56 KiB
C++
Raw Permalink Normal View History

// Tencent is pleased to support the open source community by making RapidJSON available.
//
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
//
// Licensed under the MIT License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// http://opensource.org/licenses/MIT
//
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
#include "unittest.h"
#include "rapidjson/document.h"
#include <algorithm>
#ifdef __clang__
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(c++98-compat)
#endif
using namespace rapidjson;
TEST(Value, Size) {
if (sizeof(SizeType) == 4) {
#if RAPIDJSON_48BITPOINTER_OPTIMIZATION
EXPECT_EQ(16u, sizeof(Value));
#elif RAPIDJSON_64BIT
EXPECT_EQ(24u, sizeof(Value));
#else
EXPECT_EQ(16u, sizeof(Value));
#endif
}
}
TEST(Value, DefaultConstructor) {
Value x;
EXPECT_EQ(kNullType, x.GetType());
EXPECT_TRUE(x.IsNull());
//std::cout << "sizeof(Value): " << sizeof(x) << std::endl;
}
// Should not pass compilation
//TEST(Value, copy_constructor) {
// Value x(1234);
// Value y = x;
//}
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
#if 0 // Many old compiler does not support these. Turn it off temporaily.
#include <type_traits>
TEST(Value, Traits) {
typedef GenericValue<UTF8<>, CrtAllocator> Value;
static_assert(std::is_constructible<Value>::value, "");
static_assert(std::is_default_constructible<Value>::value, "");
#ifndef _MSC_VER
static_assert(!std::is_copy_constructible<Value>::value, "");
#endif
static_assert(std::is_move_constructible<Value>::value, "");
#ifndef _MSC_VER
static_assert(std::is_nothrow_constructible<Value>::value, "");
static_assert(std::is_nothrow_default_constructible<Value>::value, "");
static_assert(!std::is_nothrow_copy_constructible<Value>::value, "");
static_assert(std::is_nothrow_move_constructible<Value>::value, "");
#endif
static_assert(std::is_assignable<Value,Value>::value, "");
#ifndef _MSC_VER
static_assert(!std::is_copy_assignable<Value>::value, "");
#endif
static_assert(std::is_move_assignable<Value>::value, "");
#ifndef _MSC_VER
static_assert(std::is_nothrow_assignable<Value, Value>::value, "");
#endif
static_assert(!std::is_nothrow_copy_assignable<Value>::value, "");
#ifndef _MSC_VER
static_assert(std::is_nothrow_move_assignable<Value>::value, "");
#endif
static_assert(std::is_destructible<Value>::value, "");
#ifndef _MSC_VER
static_assert(std::is_nothrow_destructible<Value>::value, "");
#endif
}
#endif
TEST(Value, MoveConstructor) {
typedef GenericValue<UTF8<>, CrtAllocator> V;
V::AllocatorType allocator;
V x((V(kArrayType)));
x.Reserve(4u, allocator);
x.PushBack(1, allocator).PushBack(2, allocator).PushBack(3, allocator).PushBack(4, allocator);
EXPECT_TRUE(x.IsArray());
EXPECT_EQ(4u, x.Size());
// Value y(x); // does not compile (!is_copy_constructible)
V y(std::move(x));
EXPECT_TRUE(x.IsNull());
EXPECT_TRUE(y.IsArray());
EXPECT_EQ(4u, y.Size());
// Value z = y; // does not compile (!is_copy_assignable)
V z = std::move(y);
EXPECT_TRUE(y.IsNull());
EXPECT_TRUE(z.IsArray());
EXPECT_EQ(4u, z.Size());
}
#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
TEST(Value, AssignmentOperator) {
Value x(1234);
Value y;
y = x;
EXPECT_TRUE(x.IsNull()); // move semantic
EXPECT_EQ(1234, y.GetInt());
y = 5678;
EXPECT_TRUE(y.IsInt());
EXPECT_EQ(5678, y.GetInt());
x = "Hello";
EXPECT_TRUE(x.IsString());
EXPECT_STREQ(x.GetString(),"Hello");
y = StringRef(x.GetString(),x.GetStringLength());
EXPECT_TRUE(y.IsString());
EXPECT_EQ(y.GetString(),x.GetString());
EXPECT_EQ(y.GetStringLength(),x.GetStringLength());
static char mstr[] = "mutable";
// y = mstr; // should not compile
y = StringRef(mstr);
EXPECT_TRUE(y.IsString());
EXPECT_EQ(y.GetString(),mstr);
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
// C++11 move assignment
x = Value("World");
EXPECT_TRUE(x.IsString());
EXPECT_STREQ("World", x.GetString());
x = std::move(y);
EXPECT_TRUE(y.IsNull());
EXPECT_TRUE(x.IsString());
EXPECT_EQ(x.GetString(), mstr);
y = std::move(Value().SetInt(1234));
EXPECT_TRUE(y.IsInt());
EXPECT_EQ(1234, y);
#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
}
template <typename A, typename B>
void TestEqual(const A& a, const B& b) {
EXPECT_TRUE (a == b);
EXPECT_FALSE(a != b);
EXPECT_TRUE (b == a);
EXPECT_FALSE(b != a);
}
template <typename A, typename B>
void TestUnequal(const A& a, const B& b) {
EXPECT_FALSE(a == b);
EXPECT_TRUE (a != b);
EXPECT_FALSE(b == a);
EXPECT_TRUE (b != a);
}
TEST(Value, EqualtoOperator) {
Value::AllocatorType allocator;
Value x(kObjectType);
x.AddMember("hello", "world", allocator)
.AddMember("t", Value(true).Move(), allocator)
.AddMember("f", Value(false).Move(), allocator)
.AddMember("n", Value(kNullType).Move(), allocator)
.AddMember("i", 123, allocator)
.AddMember("pi", 3.14, allocator)
.AddMember("a", Value(kArrayType).Move().PushBack(1, allocator).PushBack(2, allocator).PushBack(3, allocator), allocator);
// Test templated operator==() and operator!=()
TestEqual(x["hello"], "world");
const char* cc = "world";
TestEqual(x["hello"], cc);
char* c = strdup("world");
TestEqual(x["hello"], c);
free(c);
TestEqual(x["t"], true);
TestEqual(x["f"], false);
TestEqual(x["i"], 123);
TestEqual(x["pi"], 3.14);
// Test operator==() (including different allocators)
CrtAllocator crtAllocator;
GenericValue<UTF8<>, CrtAllocator> y;
GenericDocument<UTF8<>, CrtAllocator> z(&crtAllocator);
y.CopyFrom(x, crtAllocator);
z.CopyFrom(y, z.GetAllocator());
TestEqual(x, y);
TestEqual(y, z);
TestEqual(z, x);
// Swapping member order should be fine.
EXPECT_TRUE(y.RemoveMember("t"));
TestUnequal(x, y);
TestUnequal(z, y);
EXPECT_TRUE(z.RemoveMember("t"));
TestUnequal(x, z);
TestEqual(y, z);
y.AddMember("t", false, crtAllocator);
z.AddMember("t", false, z.GetAllocator());
TestUnequal(x, y);
TestUnequal(z, x);
y["t"] = true;
z["t"] = true;
TestEqual(x, y);
TestEqual(y, z);
TestEqual(z, x);
// Swapping element order is not OK
x["a"][0].Swap(x["a"][1]);
TestUnequal(x, y);
x["a"][0].Swap(x["a"][1]);
TestEqual(x, y);
// Array of different size
x["a"].PushBack(4, allocator);
TestUnequal(x, y);
x["a"].PopBack();
TestEqual(x, y);
// Issue #129: compare Uint64
x.SetUint64(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0xFFFFFFF0));
y.SetUint64(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0xFFFFFFFF));
TestUnequal(x, y);
}
template <typename Value>
void TestCopyFrom() {
typename Value::AllocatorType a;
Value v1(1234);
Value v2(v1, a); // deep copy constructor
EXPECT_TRUE(v1.GetType() == v2.GetType());
EXPECT_EQ(v1.GetInt(), v2.GetInt());
v1.SetString("foo");
v2.CopyFrom(v1, a);
EXPECT_TRUE(v1.GetType() == v2.GetType());
EXPECT_STREQ(v1.GetString(), v2.GetString());
EXPECT_EQ(v1.GetString(), v2.GetString()); // string NOT copied
v1.SetString("bar", a); // copy string
v2.CopyFrom(v1, a);
EXPECT_TRUE(v1.GetType() == v2.GetType());
EXPECT_STREQ(v1.GetString(), v2.GetString());
EXPECT_NE(v1.GetString(), v2.GetString()); // string copied
v1.SetArray().PushBack(1234, a);
v2.CopyFrom(v1, a);
EXPECT_TRUE(v2.IsArray());
EXPECT_EQ(v1.Size(), v2.Size());
v1.PushBack(Value().SetString("foo", a), a); // push string copy
EXPECT_TRUE(v1.Size() != v2.Size());
v2.CopyFrom(v1, a);
EXPECT_TRUE(v1.Size() == v2.Size());
EXPECT_STREQ(v1[1].GetString(), v2[1].GetString());
EXPECT_NE(v1[1].GetString(), v2[1].GetString()); // string got copied
}
TEST(Value, CopyFrom) {
TestCopyFrom<Value>();
TestCopyFrom<GenericValue<UTF8<>, CrtAllocator> >();
}
TEST(Value, Swap) {
Value v1(1234);
Value v2(kObjectType);
EXPECT_EQ(&v1, &v1.Swap(v2));
EXPECT_TRUE(v1.IsObject());
EXPECT_TRUE(v2.IsInt());
EXPECT_EQ(1234, v2.GetInt());
// testing std::swap compatibility
using std::swap;
swap(v1, v2);
EXPECT_TRUE(v1.IsInt());
EXPECT_TRUE(v2.IsObject());
}
TEST(Value, Null) {
// Default constructor
Value x;
EXPECT_EQ(kNullType, x.GetType());
EXPECT_TRUE(x.IsNull());
EXPECT_FALSE(x.IsTrue());
EXPECT_FALSE(x.IsFalse());
EXPECT_FALSE(x.IsNumber());
EXPECT_FALSE(x.IsString());
EXPECT_FALSE(x.IsObject());
EXPECT_FALSE(x.IsArray());
// Constructor with type
Value y(kNullType);
EXPECT_TRUE(y.IsNull());
// SetNull();
Value z(true);
z.SetNull();
EXPECT_TRUE(z.IsNull());
}
TEST(Value, True) {
// Constructor with bool
Value x(true);
EXPECT_EQ(kTrueType, x.GetType());
EXPECT_TRUE(x.GetBool());
EXPECT_TRUE(x.IsBool());
EXPECT_TRUE(x.IsTrue());
EXPECT_FALSE(x.IsNull());
EXPECT_FALSE(x.IsFalse());
EXPECT_FALSE(x.IsNumber());
EXPECT_FALSE(x.IsString());
EXPECT_FALSE(x.IsObject());
EXPECT_FALSE(x.IsArray());
// Constructor with type
Value y(kTrueType);
EXPECT_TRUE(y.IsTrue());
// SetBool()
Value z;
z.SetBool(true);
EXPECT_TRUE(z.IsTrue());
// Templated functions
EXPECT_TRUE(z.Is<bool>());
EXPECT_TRUE(z.Get<bool>());
EXPECT_FALSE(z.Set<bool>(false).Get<bool>());
EXPECT_TRUE(z.Set(true).Get<bool>());
}
TEST(Value, False) {
// Constructor with bool
Value x(false);
EXPECT_EQ(kFalseType, x.GetType());
EXPECT_TRUE(x.IsBool());
EXPECT_TRUE(x.IsFalse());
EXPECT_FALSE(x.IsNull());
EXPECT_FALSE(x.IsTrue());
EXPECT_FALSE(x.GetBool());
//EXPECT_FALSE((bool)x);
EXPECT_FALSE(x.IsNumber());
EXPECT_FALSE(x.IsString());
EXPECT_FALSE(x.IsObject());
EXPECT_FALSE(x.IsArray());
// Constructor with type
Value y(kFalseType);
EXPECT_TRUE(y.IsFalse());
// SetBool()
Value z;
z.SetBool(false);
EXPECT_TRUE(z.IsFalse());
}
TEST(Value, Int) {
// Constructor with int
Value x(1234);
EXPECT_EQ(kNumberType, x.GetType());
EXPECT_EQ(1234, x.GetInt());
EXPECT_EQ(1234u, x.GetUint());
EXPECT_EQ(1234, x.GetInt64());
EXPECT_EQ(1234u, x.GetUint64());
EXPECT_NEAR(1234.0, x.GetDouble(), 0.0);
//EXPECT_EQ(1234, (int)x);
//EXPECT_EQ(1234, (unsigned)x);
//EXPECT_EQ(1234, (int64_t)x);
//EXPECT_EQ(1234, (uint64_t)x);
//EXPECT_EQ(1234, (double)x);
EXPECT_TRUE(x.IsNumber());
EXPECT_TRUE(x.IsInt());
EXPECT_TRUE(x.IsUint());
EXPECT_TRUE(x.IsInt64());
EXPECT_TRUE(x.IsUint64());
EXPECT_FALSE(x.IsDouble());
EXPECT_FALSE(x.IsFloat());
EXPECT_FALSE(x.IsNull());
EXPECT_FALSE(x.IsBool());
EXPECT_FALSE(x.IsFalse());
EXPECT_FALSE(x.IsTrue());
EXPECT_FALSE(x.IsString());
EXPECT_FALSE(x.IsObject());
EXPECT_FALSE(x.IsArray());
Value nx(-1234);
EXPECT_EQ(-1234, nx.GetInt());
EXPECT_EQ(-1234, nx.GetInt64());
EXPECT_TRUE(nx.IsInt());
EXPECT_TRUE(nx.IsInt64());
EXPECT_FALSE(nx.IsUint());
EXPECT_FALSE(nx.IsUint64());
// Constructor with type
Value y(kNumberType);
EXPECT_TRUE(y.IsNumber());
EXPECT_TRUE(y.IsInt());
EXPECT_EQ(0, y.GetInt());
// SetInt()
Value z;
z.SetInt(1234);
EXPECT_EQ(1234, z.GetInt());
// operator=(int)
z = 5678;
EXPECT_EQ(5678, z.GetInt());
// Templated functions
EXPECT_TRUE(z.Is<int>());
EXPECT_EQ(5678, z.Get<int>());
EXPECT_EQ(5679, z.Set(5679).Get<int>());
EXPECT_EQ(5680, z.Set<int>(5680).Get<int>());
#ifdef _MSC_VER
// long as int on MSC platforms
RAPIDJSON_STATIC_ASSERT(sizeof(long) == sizeof(int));
z.SetInt(2222);
EXPECT_TRUE(z.Is<long>());
EXPECT_EQ(2222l, z.Get<long>());
EXPECT_EQ(3333l, z.Set(3333l).Get<long>());
EXPECT_EQ(4444l, z.Set<long>(4444l).Get<long>());
EXPECT_TRUE(z.IsInt());
#endif
}
TEST(Value, Uint) {
// Constructor with int
Value x(1234u);
EXPECT_EQ(kNumberType, x.GetType());
EXPECT_EQ(1234, x.GetInt());
EXPECT_EQ(1234u, x.GetUint());
EXPECT_EQ(1234, x.GetInt64());
EXPECT_EQ(1234u, x.GetUint64());
EXPECT_TRUE(x.IsNumber());
EXPECT_TRUE(x.IsInt());
EXPECT_TRUE(x.IsUint());
EXPECT_TRUE(x.IsInt64());
EXPECT_TRUE(x.IsUint64());
EXPECT_NEAR(1234.0, x.GetDouble(), 0.0); // Number can always be cast as double but !IsDouble().
EXPECT_FALSE(x.IsDouble());
EXPECT_FALSE(x.IsFloat());
EXPECT_FALSE(x.IsNull());
EXPECT_FALSE(x.IsBool());
EXPECT_FALSE(x.IsFalse());
EXPECT_FALSE(x.IsTrue());
EXPECT_FALSE(x.IsString());
EXPECT_FALSE(x.IsObject());
EXPECT_FALSE(x.IsArray());
// SetUint()
Value z;
z.SetUint(1234);
EXPECT_EQ(1234u, z.GetUint());
// operator=(unsigned)
z = 5678u;
EXPECT_EQ(5678u, z.GetUint());
z = 2147483648u; // 2^31, cannot cast as int
EXPECT_EQ(2147483648u, z.GetUint());
EXPECT_FALSE(z.IsInt());
EXPECT_TRUE(z.IsInt64()); // Issue 41: Incorrect parsing of unsigned int number types
// Templated functions
EXPECT_TRUE(z.Is<unsigned>());
EXPECT_EQ(2147483648u, z.Get<unsigned>());
EXPECT_EQ(2147483649u, z.Set(2147483649u).Get<unsigned>());
EXPECT_EQ(2147483650u, z.Set<unsigned>(2147483650u).Get<unsigned>());
#ifdef _MSC_VER
// unsigned long as unsigned on MSC platforms
RAPIDJSON_STATIC_ASSERT(sizeof(unsigned long) == sizeof(unsigned));
z.SetUint(2222);
EXPECT_TRUE(z.Is<unsigned long>());
EXPECT_EQ(2222ul, z.Get<unsigned long>());
EXPECT_EQ(3333ul, z.Set(3333ul).Get<unsigned long>());
EXPECT_EQ(4444ul, z.Set<unsigned long>(4444ul).Get<unsigned long>());
EXPECT_TRUE(x.IsUint());
#endif
}
TEST(Value, Int64) {
// Constructor with int
Value x(int64_t(1234));
EXPECT_EQ(kNumberType, x.GetType());
EXPECT_EQ(1234, x.GetInt());
EXPECT_EQ(1234u, x.GetUint());
EXPECT_EQ(1234, x.GetInt64());
EXPECT_EQ(1234u, x.GetUint64());
EXPECT_TRUE(x.IsNumber());
EXPECT_TRUE(x.IsInt());
EXPECT_TRUE(x.IsUint());
EXPECT_TRUE(x.IsInt64());
EXPECT_TRUE(x.IsUint64());
EXPECT_FALSE(x.IsDouble());
EXPECT_FALSE(x.IsFloat());
EXPECT_FALSE(x.IsNull());
EXPECT_FALSE(x.IsBool());
EXPECT_FALSE(x.IsFalse());
EXPECT_FALSE(x.IsTrue());
EXPECT_FALSE(x.IsString());
EXPECT_FALSE(x.IsObject());
EXPECT_FALSE(x.IsArray());
Value nx(int64_t(-1234));
EXPECT_EQ(-1234, nx.GetInt());
EXPECT_EQ(-1234, nx.GetInt64());
EXPECT_TRUE(nx.IsInt());
EXPECT_TRUE(nx.IsInt64());
EXPECT_FALSE(nx.IsUint());
EXPECT_FALSE(nx.IsUint64());
// SetInt64()
Value z;
z.SetInt64(1234);
EXPECT_EQ(1234, z.GetInt64());
z.SetInt64(2147483648u); // 2^31, cannot cast as int
EXPECT_FALSE(z.IsInt());
EXPECT_TRUE(z.IsUint());
EXPECT_NEAR(2147483648.0, z.GetDouble(), 0.0);
z.SetInt64(int64_t(4294967295u) + 1); // 2^32, cannot cast as uint
EXPECT_FALSE(z.IsInt());
EXPECT_FALSE(z.IsUint());
EXPECT_NEAR(4294967296.0, z.GetDouble(), 0.0);
z.SetInt64(-int64_t(2147483648u) - 1); // -2^31-1, cannot cast as int
EXPECT_FALSE(z.IsInt());
EXPECT_NEAR(-2147483649.0, z.GetDouble(), 0.0);
int64_t i = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 00000000));
z.SetInt64(i);
EXPECT_DOUBLE_EQ(-9223372036854775808.0, z.GetDouble());
// Templated functions
EXPECT_TRUE(z.Is<int64_t>());
EXPECT_EQ(i, z.Get<int64_t>());
#if 0 // signed integer underflow is undefined behaviour
EXPECT_EQ(i - 1, z.Set(i - 1).Get<int64_t>());
EXPECT_EQ(i - 2, z.Set<int64_t>(i - 2).Get<int64_t>());
#endif
}
TEST(Value, Uint64) {
// Constructor with int
Value x(uint64_t(1234));
EXPECT_EQ(kNumberType, x.GetType());
EXPECT_EQ(1234, x.GetInt());
EXPECT_EQ(1234u, x.GetUint());
EXPECT_EQ(1234, x.GetInt64());
EXPECT_EQ(1234u, x.GetUint64());
EXPECT_TRUE(x.IsNumber());
EXPECT_TRUE(x.IsInt());
EXPECT_TRUE(x.IsUint());
EXPECT_TRUE(x.IsInt64());
EXPECT_TRUE(x.IsUint64());
EXPECT_FALSE(x.IsDouble());
EXPECT_FALSE(x.IsFloat());
EXPECT_FALSE(x.IsNull());
EXPECT_FALSE(x.IsBool());
EXPECT_FALSE(x.IsFalse());
EXPECT_FALSE(x.IsTrue());
EXPECT_FALSE(x.IsString());
EXPECT_FALSE(x.IsObject());
EXPECT_FALSE(x.IsArray());
// SetUint64()
Value z;
z.SetUint64(1234);
EXPECT_EQ(1234u, z.GetUint64());
z.SetUint64(uint64_t(2147483648u)); // 2^31, cannot cast as int
EXPECT_FALSE(z.IsInt());
EXPECT_TRUE(z.IsUint());
EXPECT_TRUE(z.IsInt64());
z.SetUint64(uint64_t(4294967295u) + 1); // 2^32, cannot cast as uint
EXPECT_FALSE(z.IsInt());
EXPECT_FALSE(z.IsUint());
EXPECT_TRUE(z.IsInt64());
uint64_t u = RAPIDJSON_UINT64_C2(0x80000000, 0x00000000);
z.SetUint64(u); // 2^63 cannot cast as int64
EXPECT_FALSE(z.IsInt64());
EXPECT_EQ(u, z.GetUint64()); // Issue 48
EXPECT_DOUBLE_EQ(9223372036854775808.0, z.GetDouble());
// Templated functions
EXPECT_TRUE(z.Is<uint64_t>());
EXPECT_EQ(u, z.Get<uint64_t>());
EXPECT_EQ(u + 1, z.Set(u + 1).Get<uint64_t>());
EXPECT_EQ(u + 2, z.Set<uint64_t>(u + 2).Get<uint64_t>());
}
TEST(Value, Double) {
// Constructor with double
Value x(12.34);
EXPECT_EQ(kNumberType, x.GetType());
EXPECT_NEAR(12.34, x.GetDouble(), 0.0);
EXPECT_TRUE(x.IsNumber());
EXPECT_TRUE(x.IsDouble());
EXPECT_FALSE(x.IsInt());
EXPECT_FALSE(x.IsNull());
EXPECT_FALSE(x.IsBool());
EXPECT_FALSE(x.IsFalse());
EXPECT_FALSE(x.IsTrue());
EXPECT_FALSE(x.IsString());
EXPECT_FALSE(x.IsObject());
EXPECT_FALSE(x.IsArray());
// SetDouble()
Value z;
z.SetDouble(12.34);
EXPECT_NEAR(12.34, z.GetDouble(), 0.0);
z = 56.78;
EXPECT_NEAR(56.78, z.GetDouble(), 0.0);
// Templated functions
EXPECT_TRUE(z.Is<double>());
EXPECT_EQ(56.78, z.Get<double>());
EXPECT_EQ(57.78, z.Set(57.78).Get<double>());
EXPECT_EQ(58.78, z.Set<double>(58.78).Get<double>());
}
TEST(Value, Float) {
// Constructor with double
Value x(12.34f);
EXPECT_EQ(kNumberType, x.GetType());
EXPECT_NEAR(12.34f, x.GetFloat(), 0.0);
EXPECT_TRUE(x.IsNumber());
EXPECT_TRUE(x.IsDouble());
EXPECT_TRUE(x.IsFloat());
EXPECT_FALSE(x.IsInt());
EXPECT_FALSE(x.IsNull());
EXPECT_FALSE(x.IsBool());
EXPECT_FALSE(x.IsFalse());
EXPECT_FALSE(x.IsTrue());
EXPECT_FALSE(x.IsString());
EXPECT_FALSE(x.IsObject());
EXPECT_FALSE(x.IsArray());
// SetFloat()
Value z;
z.SetFloat(12.34f);
EXPECT_NEAR(12.34f, z.GetFloat(), 0.0f);
// Issue 573
z.SetInt(0);
EXPECT_EQ(0.0f, z.GetFloat());
z = 56.78f;
EXPECT_NEAR(56.78f, z.GetFloat(), 0.0f);
// Templated functions
EXPECT_TRUE(z.Is<float>());
EXPECT_EQ(56.78f, z.Get<float>());
EXPECT_EQ(57.78f, z.Set(57.78f).Get<float>());
EXPECT_EQ(58.78f, z.Set<float>(58.78f).Get<float>());
}
TEST(Value, IsLosslessDouble) {
EXPECT_TRUE(Value(0.0).IsLosslessDouble());
EXPECT_TRUE(Value(12.34).IsLosslessDouble());
EXPECT_TRUE(Value(-123).IsLosslessDouble());
EXPECT_TRUE(Value(2147483648u).IsLosslessDouble());
EXPECT_TRUE(Value(-static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x40000000, 0x00000000))).IsLosslessDouble());
#if !(defined(_MSC_VER) && _MSC_VER < 1800) // VC2010 has problem
EXPECT_TRUE(Value(RAPIDJSON_UINT64_C2(0xA0000000, 0x00000000)).IsLosslessDouble());
#endif
EXPECT_FALSE(Value(static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x7FFFFFFF, 0xFFFFFFFF))).IsLosslessDouble()); // INT64_MAX
EXPECT_FALSE(Value(-static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x7FFFFFFF, 0xFFFFFFFF))).IsLosslessDouble()); // -INT64_MAX
EXPECT_TRUE(Value(-static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x7FFFFFFF, 0xFFFFFFFF)) - 1).IsLosslessDouble()); // INT64_MIN
EXPECT_FALSE(Value(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0xFFFFFFFF)).IsLosslessDouble()); // UINT64_MAX
EXPECT_TRUE(Value(3.4028234e38f).IsLosslessDouble()); // FLT_MAX
EXPECT_TRUE(Value(-3.4028234e38f).IsLosslessDouble()); // -FLT_MAX
EXPECT_TRUE(Value(1.17549435e-38f).IsLosslessDouble()); // FLT_MIN
EXPECT_TRUE(Value(-1.17549435e-38f).IsLosslessDouble()); // -FLT_MIN
EXPECT_TRUE(Value(1.7976931348623157e+308).IsLosslessDouble()); // DBL_MAX
EXPECT_TRUE(Value(-1.7976931348623157e+308).IsLosslessDouble()); // -DBL_MAX
EXPECT_TRUE(Value(2.2250738585072014e-308).IsLosslessDouble()); // DBL_MIN
EXPECT_TRUE(Value(-2.2250738585072014e-308).IsLosslessDouble()); // -DBL_MIN
}
TEST(Value, IsLosslessFloat) {
EXPECT_TRUE(Value(12.25).IsLosslessFloat());
EXPECT_TRUE(Value(-123).IsLosslessFloat());
EXPECT_TRUE(Value(2147483648u).IsLosslessFloat());
EXPECT_TRUE(Value(3.4028234e38f).IsLosslessFloat());
EXPECT_TRUE(Value(-3.4028234e38f).IsLosslessFloat());
EXPECT_FALSE(Value(3.4028235e38).IsLosslessFloat());
EXPECT_FALSE(Value(0.3).IsLosslessFloat());
}
TEST(Value, String) {
// Construction with const string
Value x("Hello", 5); // literal
EXPECT_EQ(kStringType, x.GetType());
EXPECT_TRUE(x.IsString());
EXPECT_STREQ("Hello", x.GetString());
EXPECT_EQ(5u, x.GetStringLength());
EXPECT_FALSE(x.IsNumber());
EXPECT_FALSE(x.IsNull());
EXPECT_FALSE(x.IsBool());
EXPECT_FALSE(x.IsFalse());
EXPECT_FALSE(x.IsTrue());
EXPECT_FALSE(x.IsObject());
EXPECT_FALSE(x.IsArray());
static const char cstr[] = "World"; // const array
Value(cstr).Swap(x);
EXPECT_TRUE(x.IsString());
EXPECT_EQ(x.GetString(), cstr);
EXPECT_EQ(x.GetStringLength(), sizeof(cstr)-1);
static char mstr[] = "Howdy"; // non-const array
// Value(mstr).Swap(x); // should not compile
Value(StringRef(mstr)).Swap(x);
EXPECT_TRUE(x.IsString());
EXPECT_EQ(x.GetString(), mstr);
EXPECT_EQ(x.GetStringLength(), sizeof(mstr)-1);
strncpy(mstr,"Hello", sizeof(mstr));
EXPECT_STREQ(x.GetString(), "Hello");
const char* pstr = cstr;
//Value(pstr).Swap(x); // should not compile
Value(StringRef(pstr)).Swap(x);
EXPECT_TRUE(x.IsString());
EXPECT_EQ(x.GetString(), cstr);
EXPECT_EQ(x.GetStringLength(), sizeof(cstr)-1);
char* mpstr = mstr;
Value(StringRef(mpstr,sizeof(mstr)-1)).Swap(x);
EXPECT_TRUE(x.IsString());
EXPECT_EQ(x.GetString(), mstr);
EXPECT_EQ(x.GetStringLength(), 5u);
EXPECT_STREQ(x.GetString(), "Hello");
// Constructor with copy string
MemoryPoolAllocator<> allocator;
Value c(x.GetString(), x.GetStringLength(), allocator);
EXPECT_NE(x.GetString(), c.GetString());
EXPECT_EQ(x.GetStringLength(), c.GetStringLength());
EXPECT_STREQ(x.GetString(), c.GetString());
//x.SetString("World");
x.SetString("World", 5);
EXPECT_STREQ("Hello", c.GetString());
EXPECT_EQ(5u, c.GetStringLength());
// Constructor with type
Value y(kStringType);
EXPECT_TRUE(y.IsString());
EXPECT_STREQ("", y.GetString()); // Empty string should be "" instead of 0 (issue 226)
EXPECT_EQ(0u, y.GetStringLength());
// SetConsttring()
Value z;
z.SetString("Hello");
EXPECT_TRUE(x.IsString());
z.SetString("Hello", 5);
EXPECT_STREQ("Hello", z.GetString());
EXPECT_STREQ("Hello", z.GetString());
EXPECT_EQ(5u, z.GetStringLength());
z.SetString("Hello");
EXPECT_TRUE(z.IsString());
EXPECT_STREQ("Hello", z.GetString());
//z.SetString(mstr); // should not compile
//z.SetString(pstr); // should not compile
z.SetString(StringRef(mstr));
EXPECT_TRUE(z.IsString());
EXPECT_STREQ(z.GetString(), mstr);
z.SetString(cstr);
EXPECT_TRUE(z.IsString());
EXPECT_EQ(cstr, z.GetString());
z = cstr;
EXPECT_TRUE(z.IsString());
EXPECT_EQ(cstr, z.GetString());
// SetString()
char s[] = "World";
Value w;
w.SetString(s, static_cast<SizeType>(strlen(s)), allocator);
s[0] = '\0';
EXPECT_STREQ("World", w.GetString());
EXPECT_EQ(5u, w.GetStringLength());
// templated functions
EXPECT_TRUE(z.Is<const char*>());
EXPECT_STREQ(cstr, z.Get<const char*>());
EXPECT_STREQ("Apple", z.Set<const char*>("Apple").Get<const char*>());
#if RAPIDJSON_HAS_STDSTRING
{
std::string str = "Hello World";
str[5] = '\0';
EXPECT_STREQ(str.data(),"Hello"); // embedded '\0'
EXPECT_EQ(str.size(), 11u);
// no copy
Value vs0(StringRef(str));
EXPECT_TRUE(vs0.IsString());
EXPECT_EQ(vs0.GetString(), str.data());
EXPECT_EQ(vs0.GetStringLength(), str.size());
TestEqual(vs0, str);
// do copy
Value vs1(str, allocator);
EXPECT_TRUE(vs1.IsString());
EXPECT_NE(vs1.GetString(), str.data());
EXPECT_NE(vs1.GetString(), str); // not equal due to embedded '\0'
EXPECT_EQ(vs1.GetStringLength(), str.size());
TestEqual(vs1, str);
// SetString
str = "World";
vs0.SetNull().SetString(str, allocator);
EXPECT_TRUE(vs0.IsString());
EXPECT_STREQ(vs0.GetString(), str.c_str());
EXPECT_EQ(vs0.GetStringLength(), str.size());
TestEqual(str, vs0);
TestUnequal(str, vs1);
// vs1 = str; // should not compile
vs1 = StringRef(str);
TestEqual(str, vs1);
TestEqual(vs0, vs1);
// Templated function.
EXPECT_TRUE(vs0.Is<std::string>());
EXPECT_EQ(str, vs0.Get<std::string>());
vs0.Set<std::string>(std::string("Apple"), allocator);
EXPECT_EQ(std::string("Apple"), vs0.Get<std::string>());
vs0.Set(std::string("Orange"), allocator);
EXPECT_EQ(std::string("Orange"), vs0.Get<std::string>());
}
#endif // RAPIDJSON_HAS_STDSTRING
}
// Issue 226: Value of string type should not point to NULL
TEST(Value, SetStringNull) {
MemoryPoolAllocator<> allocator;
const char* nullPtr = 0;
{
// Construction with string type creates empty string
Value v(kStringType);
EXPECT_NE(v.GetString(), nullPtr); // non-null string returned
EXPECT_EQ(v.GetStringLength(), 0u);
// Construction from/setting to null without length not allowed
EXPECT_THROW(Value(StringRef(nullPtr)), AssertException);
EXPECT_THROW(Value(StringRef(nullPtr), allocator), AssertException);
EXPECT_THROW(v.SetString(nullPtr, allocator), AssertException);
// Non-empty length with null string is not allowed
EXPECT_THROW(v.SetString(nullPtr, 17u), AssertException);
EXPECT_THROW(v.SetString(nullPtr, 42u, allocator), AssertException);
// Setting to null string with empty length is allowed
v.SetString(nullPtr, 0u);
EXPECT_NE(v.GetString(), nullPtr); // non-null string returned
EXPECT_EQ(v.GetStringLength(), 0u);
v.SetNull();
v.SetString(nullPtr, 0u, allocator);
EXPECT_NE(v.GetString(), nullPtr); // non-null string returned
EXPECT_EQ(v.GetStringLength(), 0u);
}
// Construction with null string and empty length is allowed
{
Value v(nullPtr,0u);
EXPECT_NE(v.GetString(), nullPtr); // non-null string returned
EXPECT_EQ(v.GetStringLength(), 0u);
}
{
Value v(nullPtr, 0u, allocator);
EXPECT_NE(v.GetString(), nullPtr); // non-null string returned
EXPECT_EQ(v.GetStringLength(), 0u);
}
}
template <typename T, typename Allocator>
static void TestArray(T& x, Allocator& allocator) {
const T& y = x;
// PushBack()
Value v;
x.PushBack(v, allocator);
v.SetBool(true);
x.PushBack(v, allocator);
v.SetBool(false);
x.PushBack(v, allocator);
v.SetInt(123);
x.PushBack(v, allocator);
//x.PushBack((const char*)"foo", allocator); // should not compile
x.PushBack("foo", allocator);
EXPECT_FALSE(x.Empty());
EXPECT_EQ(5u, x.Size());
EXPECT_FALSE(y.Empty());
EXPECT_EQ(5u, y.Size());
EXPECT_TRUE(x[SizeType(0)].IsNull());
EXPECT_TRUE(x[1].IsTrue());
EXPECT_TRUE(x[2].IsFalse());
EXPECT_TRUE(x[3].IsInt());
EXPECT_EQ(123, x[3].GetInt());
EXPECT_TRUE(y[SizeType(0)].IsNull());
EXPECT_TRUE(y[1].IsTrue());
EXPECT_TRUE(y[2].IsFalse());
EXPECT_TRUE(y[3].IsInt());
EXPECT_EQ(123, y[3].GetInt());
EXPECT_TRUE(y[4].IsString());
EXPECT_STREQ("foo", y[4].GetString());
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
// PushBack(GenericValue&&, Allocator&);
{
Value y2(kArrayType);
y2.PushBack(Value(true), allocator);
y2.PushBack(std::move(Value(kArrayType).PushBack(Value(1), allocator).PushBack("foo", allocator)), allocator);
EXPECT_EQ(2u, y2.Size());
EXPECT_TRUE(y2[0].IsTrue());
EXPECT_TRUE(y2[1].IsArray());
EXPECT_EQ(2u, y2[1].Size());
EXPECT_TRUE(y2[1][0].IsInt());
EXPECT_TRUE(y2[1][1].IsString());
}
#endif
// iterator
typename T::ValueIterator itr = x.Begin();
EXPECT_TRUE(itr != x.End());
EXPECT_TRUE(itr->IsNull());
++itr;
EXPECT_TRUE(itr != x.End());
EXPECT_TRUE(itr->IsTrue());
++itr;
EXPECT_TRUE(itr != x.End());
EXPECT_TRUE(itr->IsFalse());
++itr;
EXPECT_TRUE(itr != x.End());
EXPECT_TRUE(itr->IsInt());
EXPECT_EQ(123, itr->GetInt());
++itr;
EXPECT_TRUE(itr != x.End());
EXPECT_TRUE(itr->IsString());
EXPECT_STREQ("foo", itr->GetString());
// const iterator
typename T::ConstValueIterator citr = y.Begin();
EXPECT_TRUE(citr != y.End());
EXPECT_TRUE(citr->IsNull());
++citr;
EXPECT_TRUE(citr != y.End());
EXPECT_TRUE(citr->IsTrue());
++citr;
EXPECT_TRUE(citr != y.End());
EXPECT_TRUE(citr->IsFalse());
++citr;
EXPECT_TRUE(citr != y.End());
EXPECT_TRUE(citr->IsInt());
EXPECT_EQ(123, citr->GetInt());
++citr;
EXPECT_TRUE(citr != y.End());
EXPECT_TRUE(citr->IsString());
EXPECT_STREQ("foo", citr->GetString());
// PopBack()
x.PopBack();
EXPECT_EQ(4u, x.Size());
EXPECT_TRUE(y[SizeType(0)].IsNull());
EXPECT_TRUE(y[1].IsTrue());
EXPECT_TRUE(y[2].IsFalse());
EXPECT_TRUE(y[3].IsInt());
// Clear()
x.Clear();
EXPECT_TRUE(x.Empty());
EXPECT_EQ(0u, x.Size());
EXPECT_TRUE(y.Empty());
EXPECT_EQ(0u, y.Size());
// Erase(ValueIterator)
// Use array of array to ensure removed elements' destructor is called.
// [[0],[1],[2],...]
for (int i = 0; i < 10; i++)
x.PushBack(Value(kArrayType).PushBack(i, allocator).Move(), allocator);
// Erase the first
itr = x.Erase(x.Begin());
EXPECT_EQ(x.Begin(), itr);
EXPECT_EQ(9u, x.Size());
for (int i = 0; i < 9; i++)
EXPECT_EQ(i + 1, x[static_cast<SizeType>(i)][0].GetInt());
// Ease the last
itr = x.Erase(x.End() - 1);
EXPECT_EQ(x.End(), itr);
EXPECT_EQ(8u, x.Size());
for (int i = 0; i < 8; i++)
EXPECT_EQ(i + 1, x[static_cast<SizeType>(i)][0].GetInt());
// Erase the middle
itr = x.Erase(x.Begin() + 4);
EXPECT_EQ(x.Begin() + 4, itr);
EXPECT_EQ(7u, x.Size());
for (int i = 0; i < 4; i++)
EXPECT_EQ(i + 1, x[static_cast<SizeType>(i)][0].GetInt());
for (int i = 4; i < 7; i++)
EXPECT_EQ(i + 2, x[static_cast<SizeType>(i)][0].GetInt());
// Erase(ValueIterator, ValueIterator)
// Exhaustive test with all 0 <= first < n, first <= last <= n cases
const unsigned n = 10;
for (unsigned first = 0; first < n; first++) {
for (unsigned last = first; last <= n; last++) {
x.Clear();
for (unsigned i = 0; i < n; i++)
x.PushBack(Value(kArrayType).PushBack(i, allocator).Move(), allocator);
Squashed 'external/rapidjson/' changes from 2e8f5d897..a95e013b9 a95e013b9 Stringify NaN, Inf as null if needs 973dc9c06 Avoid ptrdiff between pointers to different allocations 2a1f586ba Check for __GNUC__ definition 0e88d5e40 Eliminate missing prototypes warning 949c771b0 Resolve conflict with Windows header about max macro 083f359f5 CMakeLists: fix optflags for ppc 012be8528 Use passed in allocator. 1ce516e50 Suppress uritest 778dc8b03 fix #1 76281ff38 fix a typo in error.h: literial -> literal a98e99992 do not define operator!= in C++20 b08672d46 review comment updates 55eca66f3 code & tests for openapi 2.0 & 3.0 suppprt 80b6d1c83 small corrections for schema.h 97fd83017 attempt to fix SEH 7cad78e23 tidy up after merge from master 794248ee6 fix build break 2d87923e9 remove unnecessary templating from schema tests aa1f22251 correct address.json so tests pass ecb8d9e3a add dump of unexpected schema errors in schematest.cpp 89f6717f0 corrections 338d8defd initial 06d58b9e8 Update dtoa.h 22a62fcc2 Update allocators.h 27c3a8dc0 docs: fix simple typo, perecent -> percent 232389d4f delete unused variable 64faab2e9 gate definition of symmetric equality operators on impl, not lib 719304b11 fixes for natvis dd3f730d7 Make schema dtor robust against exceptions 781a4e667 Try to fix MSVC build. 88f8ddd70 Include conceptual change from PR 2001. 469595356 Avoid exit-time destructors. 0390b1ad5 Avoid exit-time destructors. 2b2c80450 encdedstreamtest: fix use-after-free compile error with gcc-12 1f59c69cd valuetest: fix potential write of terminating nul past the end of the destination fcb23c2db Merge pull request #2008 from agate-pris/access-to-allocator-types bdc49ad80 Merge pull request #2014 from lazydroid/dev/lenik/fix_shadowed_variables 6b500986c fix shadowed variable, take 2 3988c5e25 fix shadowed variable 386d31ab6 Allow access to the template parameter StackAllocator in the GenericDocument 79d7a448e Allow the macro RAPIDJSON_DEFAULT_STACK_ALLOCATOR to be used in any namespace 9965ab37f Allow the macro RAPIDJSON_DEFAULT_ALLOCATOR to be used in any namespace 8261c1ddf Merge pull request #1969 from MalcolmTyrrell/MalcolmTyrrell/sanitizeSchemaCode 0d78b1ce9 Merge pull request #1989 from adamcalhoon/really-fix-placement-new-alignment 1dff2abff Fix the alignment of placement new buffer for GenericValue. e4bde9774 Merge pull request #1988 from Tencent/revert-1987-fix-placement-new-alignment 88bbd87dd Revert "Fix the alignment of placement new buffer for GenericValue." bf8ca5da8 Merge pull request #1987 from adamcalhoon/fix-placement-new-alignment 5b242b6b2 Fix the alignment of placement new buffer for GenericValue. fd3dc29a5 Merge pull request #1944 from ilelann/patch-1 53602ec6b Sanitize the code in schema.h 0d4517f15 Merge pull request #1961 from jedwardsol/issue1960_arm64ec_intrinsic 060c348ea use softintrin on arm64ec 4d6cb0818 Merge pull request #1949 from ardb-uk/master 033bef3c6 Merge pull request #1 from ardb-uk/ardb-uk-patch-1 befba39af Merge pull request #2 from ardb-uk/ardb-uk-patch-1-1 4bbaf28ff Add files via upload 14f1e37f8 Resolve issue 1948 e6736d1ba Support CMake none targets git-subtree-dir: external/rapidjson git-subtree-split: a95e013b97ca6523f32da23f5095fcc9dd6067e5
2023-08-05 09:13:29 +00:00
itr = x.Erase(x.Begin() + first, x.Begin() + last);
if (last == n)
EXPECT_EQ(x.End(), itr);
else
EXPECT_EQ(x.Begin() + first, itr);
size_t removeCount = last - first;
EXPECT_EQ(n - removeCount, x.Size());
for (unsigned i = 0; i < first; i++)
EXPECT_EQ(i, x[i][0].GetUint());
for (unsigned i = first; i < n - removeCount; i++)
EXPECT_EQ(i + removeCount, x[static_cast<SizeType>(i)][0].GetUint());
}
}
}
TEST(Value, Array) {
Value::AllocatorType allocator;
Value x(kArrayType);
const Value& y = x;
EXPECT_EQ(kArrayType, x.GetType());
EXPECT_TRUE(x.IsArray());
EXPECT_TRUE(x.Empty());
EXPECT_EQ(0u, x.Size());
EXPECT_TRUE(y.IsArray());
EXPECT_TRUE(y.Empty());
EXPECT_EQ(0u, y.Size());
EXPECT_FALSE(x.IsNull());
EXPECT_FALSE(x.IsBool());
EXPECT_FALSE(x.IsFalse());
EXPECT_FALSE(x.IsTrue());
EXPECT_FALSE(x.IsString());
EXPECT_FALSE(x.IsObject());
TestArray(x, allocator);
// Working in gcc without C++11, but VS2013 cannot compile. To be diagnosed.
// http://en.wikipedia.org/wiki/Erase-remove_idiom
x.Clear();
for (int i = 0; i < 10; i++)
if (i % 2 == 0)
x.PushBack(i, allocator);
else
x.PushBack(Value(kNullType).Move(), allocator);
const Value null(kNullType);
x.Erase(std::remove(x.Begin(), x.End(), null), x.End());
EXPECT_EQ(5u, x.Size());
for (int i = 0; i < 5; i++)
EXPECT_EQ(i * 2, x[static_cast<SizeType>(i)]);
// SetArray()
Value z;
z.SetArray();
EXPECT_TRUE(z.IsArray());
EXPECT_TRUE(z.Empty());
// PR #1503: assign from inner Value
{
CrtAllocator a; // Free() is not a noop
GenericValue<UTF8<>, CrtAllocator> nullValue;
GenericValue<UTF8<>, CrtAllocator> arrayValue(kArrayType);
arrayValue.PushBack(nullValue, a);
arrayValue = arrayValue[0]; // shouldn't crash (use after free)
EXPECT_TRUE(arrayValue.IsNull());
}
}
TEST(Value, ArrayHelper) {
Value::AllocatorType allocator;
{
Value x(kArrayType);
Value::Array a = x.GetArray();
TestArray(a, allocator);
}
{
Value x(kArrayType);
Value::Array a = x.GetArray();
a.PushBack(1, allocator);
Value::Array a2(a); // copy constructor
EXPECT_EQ(1u, a2.Size());
Value::Array a3 = a;
EXPECT_EQ(1u, a3.Size());
Value::ConstArray y = static_cast<const Value&>(x).GetArray();
(void)y;
// y.PushBack(1, allocator); // should not compile
// Templated functions
x.Clear();
EXPECT_TRUE(x.Is<Value::Array>());
EXPECT_TRUE(x.Is<Value::ConstArray>());
a.PushBack(1, allocator);
EXPECT_EQ(1, x.Get<Value::Array>()[0].GetInt());
EXPECT_EQ(1, x.Get<Value::ConstArray>()[0].GetInt());
Value x2;
x2.Set<Value::Array>(a);
EXPECT_TRUE(x.IsArray()); // IsArray() is invariant after moving.
EXPECT_EQ(1, x2.Get<Value::Array>()[0].GetInt());
}
{
Value y(kArrayType);
y.PushBack(123, allocator);
Value x(y.GetArray()); // Construct value form array.
EXPECT_TRUE(x.IsArray());
EXPECT_EQ(123, x[0].GetInt());
EXPECT_TRUE(y.IsArray()); // Invariant
EXPECT_TRUE(y.Empty());
}
{
Value x(kArrayType);
Value y(kArrayType);
y.PushBack(123, allocator);
x.PushBack(y.GetArray(), allocator); // Implicit constructor to convert Array to GenericValue
EXPECT_EQ(1u, x.Size());
EXPECT_EQ(123, x[0][0].GetInt());
EXPECT_TRUE(y.IsArray());
EXPECT_TRUE(y.Empty());
}
}
#if RAPIDJSON_HAS_CXX11_RANGE_FOR
TEST(Value, ArrayHelperRangeFor) {
Value::AllocatorType allocator;
Value x(kArrayType);
for (int i = 0; i < 10; i++)
x.PushBack(i, allocator);
{
int i = 0;
for (auto& v : x.GetArray()) {
EXPECT_EQ(i, v.GetInt());
i++;
}
EXPECT_EQ(i, 10);
}
{
int i = 0;
for (const auto& v : const_cast<const Value&>(x).GetArray()) {
EXPECT_EQ(i, v.GetInt());
i++;
}
EXPECT_EQ(i, 10);
}
// Array a = x.GetArray();
// Array ca = const_cast<const Value&>(x).GetArray();
}
#endif
template <typename T, typename Allocator>
static void TestObject(T& x, Allocator& allocator) {
const T& y = x; // const version
// AddMember()
x.AddMember("A", "Apple", allocator);
EXPECT_FALSE(x.ObjectEmpty());
EXPECT_EQ(1u, x.MemberCount());
Value value("Banana", 6);
x.AddMember("B", "Banana", allocator);
EXPECT_EQ(2u, x.MemberCount());
// AddMember<T>(StringRefType, T, Allocator)
{
Value o(kObjectType);
o.AddMember("true", true, allocator);
o.AddMember("false", false, allocator);
o.AddMember("int", -1, allocator);
o.AddMember("uint", 1u, allocator);
o.AddMember("int64", int64_t(-4294967296), allocator);
o.AddMember("uint64", uint64_t(4294967296), allocator);
o.AddMember("double", 3.14, allocator);
o.AddMember("string", "Jelly", allocator);
EXPECT_TRUE(o["true"].GetBool());
EXPECT_FALSE(o["false"].GetBool());
EXPECT_EQ(-1, o["int"].GetInt());
EXPECT_EQ(1u, o["uint"].GetUint());
EXPECT_EQ(int64_t(-4294967296), o["int64"].GetInt64());
EXPECT_EQ(uint64_t(4294967296), o["uint64"].GetUint64());
EXPECT_STREQ("Jelly",o["string"].GetString());
EXPECT_EQ(8u, o.MemberCount());
}
// AddMember<T>(Value&, T, Allocator)
{
Value o(kObjectType);
Value n("s");
o.AddMember(n, "string", allocator);
EXPECT_EQ(1u, o.MemberCount());
Value count("#");
o.AddMember(count, o.MemberCount(), allocator);
EXPECT_EQ(2u, o.MemberCount());
}
#if RAPIDJSON_HAS_STDSTRING
{
// AddMember(StringRefType, const std::string&, Allocator)
Value o(kObjectType);
o.AddMember("b", std::string("Banana"), allocator);
EXPECT_STREQ("Banana", o["b"].GetString());
// RemoveMember(const std::string&)
o.RemoveMember(std::string("b"));
EXPECT_TRUE(o.ObjectEmpty());
}
#endif
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
// AddMember(GenericValue&&, ...) variants
{
Value o(kObjectType);
o.AddMember(Value("true"), Value(true), allocator);
o.AddMember(Value("false"), Value(false).Move(), allocator); // value is lvalue ref
o.AddMember(Value("int").Move(), Value(-1), allocator); // name is lvalue ref
o.AddMember("uint", std::move(Value().SetUint(1u)), allocator); // name is literal, value is rvalue
EXPECT_TRUE(o["true"].GetBool());
EXPECT_FALSE(o["false"].GetBool());
EXPECT_EQ(-1, o["int"].GetInt());
EXPECT_EQ(1u, o["uint"].GetUint());
EXPECT_EQ(4u, o.MemberCount());
}
#endif
// Tests a member with null character
Value name;
const Value C0D("C\0D", 3);
name.SetString(C0D.GetString(), 3);
value.SetString("CherryD", 7);
x.AddMember(name, value, allocator);
// HasMember()
EXPECT_TRUE(x.HasMember("A"));
EXPECT_TRUE(x.HasMember("B"));
EXPECT_TRUE(y.HasMember("A"));
EXPECT_TRUE(y.HasMember("B"));
#if RAPIDJSON_HAS_STDSTRING
EXPECT_TRUE(x.HasMember(std::string("A")));
#endif
name.SetString("C\0D");
EXPECT_TRUE(x.HasMember(name));
EXPECT_TRUE(y.HasMember(name));
GenericValue<UTF8<>, CrtAllocator> othername("A");
EXPECT_TRUE(x.HasMember(othername));
EXPECT_TRUE(y.HasMember(othername));
othername.SetString("C\0D");
EXPECT_TRUE(x.HasMember(othername));
EXPECT_TRUE(y.HasMember(othername));
// operator[]
EXPECT_STREQ("Apple", x["A"].GetString());
EXPECT_STREQ("Banana", x["B"].GetString());
EXPECT_STREQ("CherryD", x[C0D].GetString());
EXPECT_STREQ("CherryD", x[othername].GetString());
EXPECT_THROW(x["nonexist"], AssertException);
// const operator[]
EXPECT_STREQ("Apple", y["A"].GetString());
EXPECT_STREQ("Banana", y["B"].GetString());
EXPECT_STREQ("CherryD", y[C0D].GetString());
#if RAPIDJSON_HAS_STDSTRING
EXPECT_STREQ("Apple", x["A"].GetString());
EXPECT_STREQ("Apple", y[std::string("A")].GetString());
#endif
// member iterator
Value::MemberIterator itr = x.MemberBegin();
EXPECT_TRUE(itr != x.MemberEnd());
EXPECT_STREQ("A", itr->name.GetString());
EXPECT_STREQ("Apple", itr->value.GetString());
++itr;
EXPECT_TRUE(itr != x.MemberEnd());
EXPECT_STREQ("B", itr->name.GetString());
EXPECT_STREQ("Banana", itr->value.GetString());
++itr;
EXPECT_TRUE(itr != x.MemberEnd());
EXPECT_TRUE(memcmp(itr->name.GetString(), "C\0D", 4) == 0);
EXPECT_STREQ("CherryD", itr->value.GetString());
++itr;
EXPECT_FALSE(itr != x.MemberEnd());
// const member iterator
Value::ConstMemberIterator citr = y.MemberBegin();
EXPECT_TRUE(citr != y.MemberEnd());
EXPECT_STREQ("A", citr->name.GetString());
EXPECT_STREQ("Apple", citr->value.GetString());
++citr;
EXPECT_TRUE(citr != y.MemberEnd());
EXPECT_STREQ("B", citr->name.GetString());
EXPECT_STREQ("Banana", citr->value.GetString());
++citr;
EXPECT_TRUE(citr != y.MemberEnd());
EXPECT_TRUE(memcmp(citr->name.GetString(), "C\0D", 4) == 0);
EXPECT_STREQ("CherryD", citr->value.GetString());
++citr;
EXPECT_FALSE(citr != y.MemberEnd());
// member iterator conversions/relations
itr = x.MemberBegin();
citr = x.MemberBegin(); // const conversion
TestEqual(itr, citr);
EXPECT_TRUE(itr < x.MemberEnd());
EXPECT_FALSE(itr > y.MemberEnd());
EXPECT_TRUE(citr < x.MemberEnd());
EXPECT_FALSE(citr > y.MemberEnd());
++citr;
TestUnequal(itr, citr);
EXPECT_FALSE(itr < itr);
EXPECT_TRUE(itr < citr);
EXPECT_FALSE(itr > itr);
EXPECT_TRUE(citr > itr);
EXPECT_EQ(1, citr - x.MemberBegin());
EXPECT_EQ(0, itr - y.MemberBegin());
itr += citr - x.MemberBegin();
EXPECT_EQ(1, itr - y.MemberBegin());
TestEqual(citr, itr);
EXPECT_TRUE(itr <= citr);
EXPECT_TRUE(citr <= itr);
itr++;
EXPECT_TRUE(itr >= citr);
EXPECT_FALSE(citr >= itr);
// RemoveMember()
EXPECT_TRUE(x.RemoveMember("A"));
EXPECT_FALSE(x.HasMember("A"));
EXPECT_TRUE(x.RemoveMember("B"));
EXPECT_FALSE(x.HasMember("B"));
EXPECT_FALSE(x.RemoveMember("nonexist"));
EXPECT_TRUE(x.RemoveMember(othername));
EXPECT_FALSE(x.HasMember(name));
EXPECT_TRUE(x.MemberBegin() == x.MemberEnd());
// EraseMember(ConstMemberIterator)
// Use array members to ensure removed elements' destructor is called.
// { "a": [0], "b": [1],[2],...]
const char keys[][2] = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j" };
for (int i = 0; i < 10; i++)
x.AddMember(keys[i], Value(kArrayType).PushBack(i, allocator), allocator);
// MemberCount, iterator difference
EXPECT_EQ(x.MemberCount(), SizeType(x.MemberEnd() - x.MemberBegin()));
// Erase the first
itr = x.EraseMember(x.MemberBegin());
EXPECT_FALSE(x.HasMember(keys[0]));
EXPECT_EQ(x.MemberBegin(), itr);
EXPECT_EQ(9u, x.MemberCount());
for (; itr != x.MemberEnd(); ++itr) {
size_t i = static_cast<size_t>((itr - x.MemberBegin())) + 1;
EXPECT_STREQ(itr->name.GetString(), keys[i]);
EXPECT_EQ(static_cast<int>(i), itr->value[0].GetInt());
}
// Erase the last
itr = x.EraseMember(x.MemberEnd() - 1);
EXPECT_FALSE(x.HasMember(keys[9]));
EXPECT_EQ(x.MemberEnd(), itr);
EXPECT_EQ(8u, x.MemberCount());
for (; itr != x.MemberEnd(); ++itr) {
size_t i = static_cast<size_t>(itr - x.MemberBegin()) + 1;
EXPECT_STREQ(itr->name.GetString(), keys[i]);
EXPECT_EQ(static_cast<int>(i), itr->value[0].GetInt());
}
// Erase the middle
itr = x.EraseMember(x.MemberBegin() + 4);
EXPECT_FALSE(x.HasMember(keys[5]));
EXPECT_EQ(x.MemberBegin() + 4, itr);
EXPECT_EQ(7u, x.MemberCount());
for (; itr != x.MemberEnd(); ++itr) {
size_t i = static_cast<size_t>(itr - x.MemberBegin());
i += (i < 4) ? 1 : 2;
EXPECT_STREQ(itr->name.GetString(), keys[i]);
EXPECT_EQ(static_cast<int>(i), itr->value[0].GetInt());
}
// EraseMember(ConstMemberIterator, ConstMemberIterator)
// Exhaustive test with all 0 <= first < n, first <= last <= n cases
const unsigned n = 10;
for (unsigned first = 0; first < n; first++) {
for (unsigned last = first; last <= n; last++) {
x.RemoveAllMembers();
for (unsigned i = 0; i < n; i++)
x.AddMember(keys[i], Value(kArrayType).PushBack(i, allocator), allocator);
itr = x.EraseMember(x.MemberBegin() + static_cast<int>(first), x.MemberBegin() + static_cast<int>(last));
if (last == n)
EXPECT_EQ(x.MemberEnd(), itr);
else
EXPECT_EQ(x.MemberBegin() + static_cast<int>(first), itr);
size_t removeCount = last - first;
EXPECT_EQ(n - removeCount, x.MemberCount());
for (unsigned i = 0; i < first; i++)
EXPECT_EQ(i, x[keys[i]][0].GetUint());
for (unsigned i = first; i < n - removeCount; i++)
EXPECT_EQ(i + removeCount, x[keys[i+removeCount]][0].GetUint());
}
}
// RemoveAllMembers()
x.RemoveAllMembers();
EXPECT_TRUE(x.ObjectEmpty());
EXPECT_EQ(0u, x.MemberCount());
}
TEST(Value, Object) {
Value::AllocatorType allocator;
Value x(kObjectType);
const Value& y = x; // const version
EXPECT_EQ(kObjectType, x.GetType());
EXPECT_TRUE(x.IsObject());
EXPECT_TRUE(x.ObjectEmpty());
EXPECT_EQ(0u, x.MemberCount());
EXPECT_EQ(kObjectType, y.GetType());
EXPECT_TRUE(y.IsObject());
EXPECT_TRUE(y.ObjectEmpty());
EXPECT_EQ(0u, y.MemberCount());
TestObject(x, allocator);
// SetObject()
Value z;
z.SetObject();
EXPECT_TRUE(z.IsObject());
}
TEST(Value, ObjectHelper) {
Value::AllocatorType allocator;
{
Value x(kObjectType);
Value::Object o = x.GetObject();
TestObject(o, allocator);
}
{
Value x(kObjectType);
Value::Object o = x.GetObject();
o.AddMember("1", 1, allocator);
Value::Object o2(o); // copy constructor
EXPECT_EQ(1u, o2.MemberCount());
Value::Object o3 = o;
EXPECT_EQ(1u, o3.MemberCount());
Value::ConstObject y = static_cast<const Value&>(x).GetObject();
(void)y;
// y.AddMember("1", 1, allocator); // should not compile
// Templated functions
x.RemoveAllMembers();
EXPECT_TRUE(x.Is<Value::Object>());
EXPECT_TRUE(x.Is<Value::ConstObject>());
o.AddMember("1", 1, allocator);
EXPECT_EQ(1, x.Get<Value::Object>()["1"].GetInt());
EXPECT_EQ(1, x.Get<Value::ConstObject>()["1"].GetInt());
Value x2;
x2.Set<Value::Object>(o);
EXPECT_TRUE(x.IsObject()); // IsObject() is invariant after moving
EXPECT_EQ(1, x2.Get<Value::Object>()["1"].GetInt());
}
{
Value x(kObjectType);
x.AddMember("a", "apple", allocator);
Value y(x.GetObject());
EXPECT_STREQ("apple", y["a"].GetString());
EXPECT_TRUE(x.IsObject()); // Invariant
}
Squashed 'external/rapidjson/' changes from 2e8f5d897..a95e013b9 a95e013b9 Stringify NaN, Inf as null if needs 973dc9c06 Avoid ptrdiff between pointers to different allocations 2a1f586ba Check for __GNUC__ definition 0e88d5e40 Eliminate missing prototypes warning 949c771b0 Resolve conflict with Windows header about max macro 083f359f5 CMakeLists: fix optflags for ppc 012be8528 Use passed in allocator. 1ce516e50 Suppress uritest 778dc8b03 fix #1 76281ff38 fix a typo in error.h: literial -> literal a98e99992 do not define operator!= in C++20 b08672d46 review comment updates 55eca66f3 code & tests for openapi 2.0 & 3.0 suppprt 80b6d1c83 small corrections for schema.h 97fd83017 attempt to fix SEH 7cad78e23 tidy up after merge from master 794248ee6 fix build break 2d87923e9 remove unnecessary templating from schema tests aa1f22251 correct address.json so tests pass ecb8d9e3a add dump of unexpected schema errors in schematest.cpp 89f6717f0 corrections 338d8defd initial 06d58b9e8 Update dtoa.h 22a62fcc2 Update allocators.h 27c3a8dc0 docs: fix simple typo, perecent -> percent 232389d4f delete unused variable 64faab2e9 gate definition of symmetric equality operators on impl, not lib 719304b11 fixes for natvis dd3f730d7 Make schema dtor robust against exceptions 781a4e667 Try to fix MSVC build. 88f8ddd70 Include conceptual change from PR 2001. 469595356 Avoid exit-time destructors. 0390b1ad5 Avoid exit-time destructors. 2b2c80450 encdedstreamtest: fix use-after-free compile error with gcc-12 1f59c69cd valuetest: fix potential write of terminating nul past the end of the destination fcb23c2db Merge pull request #2008 from agate-pris/access-to-allocator-types bdc49ad80 Merge pull request #2014 from lazydroid/dev/lenik/fix_shadowed_variables 6b500986c fix shadowed variable, take 2 3988c5e25 fix shadowed variable 386d31ab6 Allow access to the template parameter StackAllocator in the GenericDocument 79d7a448e Allow the macro RAPIDJSON_DEFAULT_STACK_ALLOCATOR to be used in any namespace 9965ab37f Allow the macro RAPIDJSON_DEFAULT_ALLOCATOR to be used in any namespace 8261c1ddf Merge pull request #1969 from MalcolmTyrrell/MalcolmTyrrell/sanitizeSchemaCode 0d78b1ce9 Merge pull request #1989 from adamcalhoon/really-fix-placement-new-alignment 1dff2abff Fix the alignment of placement new buffer for GenericValue. e4bde9774 Merge pull request #1988 from Tencent/revert-1987-fix-placement-new-alignment 88bbd87dd Revert "Fix the alignment of placement new buffer for GenericValue." bf8ca5da8 Merge pull request #1987 from adamcalhoon/fix-placement-new-alignment 5b242b6b2 Fix the alignment of placement new buffer for GenericValue. fd3dc29a5 Merge pull request #1944 from ilelann/patch-1 53602ec6b Sanitize the code in schema.h 0d4517f15 Merge pull request #1961 from jedwardsol/issue1960_arm64ec_intrinsic 060c348ea use softintrin on arm64ec 4d6cb0818 Merge pull request #1949 from ardb-uk/master 033bef3c6 Merge pull request #1 from ardb-uk/ardb-uk-patch-1 befba39af Merge pull request #2 from ardb-uk/ardb-uk-patch-1-1 4bbaf28ff Add files via upload 14f1e37f8 Resolve issue 1948 e6736d1ba Support CMake none targets git-subtree-dir: external/rapidjson git-subtree-split: a95e013b97ca6523f32da23f5095fcc9dd6067e5
2023-08-05 09:13:29 +00:00
{
Value x(kObjectType);
x.AddMember("a", "apple", allocator);
Value y(kObjectType);
y.AddMember("fruits", x.GetObject(), allocator);
EXPECT_STREQ("apple", y["fruits"]["a"].GetString());
EXPECT_TRUE(x.IsObject()); // Invariant
}
}
#if RAPIDJSON_HAS_CXX11_RANGE_FOR
TEST(Value, ObjectHelperRangeFor) {
Value::AllocatorType allocator;
Value x(kObjectType);
for (int i = 0; i < 10; i++) {
char name[10];
Value n(name, static_cast<SizeType>(sprintf(name, "%d", i)), allocator);
x.AddMember(n, i, allocator);
}
{
int i = 0;
for (auto& m : x.GetObject()) {
Squashed 'external/rapidjson/' changes from 2e8f5d897..a95e013b9 a95e013b9 Stringify NaN, Inf as null if needs 973dc9c06 Avoid ptrdiff between pointers to different allocations 2a1f586ba Check for __GNUC__ definition 0e88d5e40 Eliminate missing prototypes warning 949c771b0 Resolve conflict with Windows header about max macro 083f359f5 CMakeLists: fix optflags for ppc 012be8528 Use passed in allocator. 1ce516e50 Suppress uritest 778dc8b03 fix #1 76281ff38 fix a typo in error.h: literial -> literal a98e99992 do not define operator!= in C++20 b08672d46 review comment updates 55eca66f3 code & tests for openapi 2.0 & 3.0 suppprt 80b6d1c83 small corrections for schema.h 97fd83017 attempt to fix SEH 7cad78e23 tidy up after merge from master 794248ee6 fix build break 2d87923e9 remove unnecessary templating from schema tests aa1f22251 correct address.json so tests pass ecb8d9e3a add dump of unexpected schema errors in schematest.cpp 89f6717f0 corrections 338d8defd initial 06d58b9e8 Update dtoa.h 22a62fcc2 Update allocators.h 27c3a8dc0 docs: fix simple typo, perecent -> percent 232389d4f delete unused variable 64faab2e9 gate definition of symmetric equality operators on impl, not lib 719304b11 fixes for natvis dd3f730d7 Make schema dtor robust against exceptions 781a4e667 Try to fix MSVC build. 88f8ddd70 Include conceptual change from PR 2001. 469595356 Avoid exit-time destructors. 0390b1ad5 Avoid exit-time destructors. 2b2c80450 encdedstreamtest: fix use-after-free compile error with gcc-12 1f59c69cd valuetest: fix potential write of terminating nul past the end of the destination fcb23c2db Merge pull request #2008 from agate-pris/access-to-allocator-types bdc49ad80 Merge pull request #2014 from lazydroid/dev/lenik/fix_shadowed_variables 6b500986c fix shadowed variable, take 2 3988c5e25 fix shadowed variable 386d31ab6 Allow access to the template parameter StackAllocator in the GenericDocument 79d7a448e Allow the macro RAPIDJSON_DEFAULT_STACK_ALLOCATOR to be used in any namespace 9965ab37f Allow the macro RAPIDJSON_DEFAULT_ALLOCATOR to be used in any namespace 8261c1ddf Merge pull request #1969 from MalcolmTyrrell/MalcolmTyrrell/sanitizeSchemaCode 0d78b1ce9 Merge pull request #1989 from adamcalhoon/really-fix-placement-new-alignment 1dff2abff Fix the alignment of placement new buffer for GenericValue. e4bde9774 Merge pull request #1988 from Tencent/revert-1987-fix-placement-new-alignment 88bbd87dd Revert "Fix the alignment of placement new buffer for GenericValue." bf8ca5da8 Merge pull request #1987 from adamcalhoon/fix-placement-new-alignment 5b242b6b2 Fix the alignment of placement new buffer for GenericValue. fd3dc29a5 Merge pull request #1944 from ilelann/patch-1 53602ec6b Sanitize the code in schema.h 0d4517f15 Merge pull request #1961 from jedwardsol/issue1960_arm64ec_intrinsic 060c348ea use softintrin on arm64ec 4d6cb0818 Merge pull request #1949 from ardb-uk/master 033bef3c6 Merge pull request #1 from ardb-uk/ardb-uk-patch-1 befba39af Merge pull request #2 from ardb-uk/ardb-uk-patch-1-1 4bbaf28ff Add files via upload 14f1e37f8 Resolve issue 1948 e6736d1ba Support CMake none targets git-subtree-dir: external/rapidjson git-subtree-split: a95e013b97ca6523f32da23f5095fcc9dd6067e5
2023-08-05 09:13:29 +00:00
char name[11];
sprintf(name, "%d", i);
EXPECT_STREQ(name, m.name.GetString());
EXPECT_EQ(i, m.value.GetInt());
i++;
}
EXPECT_EQ(i, 10);
}
{
int i = 0;
for (const auto& m : const_cast<const Value&>(x).GetObject()) {
Squashed 'external/rapidjson/' changes from 2e8f5d897..a95e013b9 a95e013b9 Stringify NaN, Inf as null if needs 973dc9c06 Avoid ptrdiff between pointers to different allocations 2a1f586ba Check for __GNUC__ definition 0e88d5e40 Eliminate missing prototypes warning 949c771b0 Resolve conflict with Windows header about max macro 083f359f5 CMakeLists: fix optflags for ppc 012be8528 Use passed in allocator. 1ce516e50 Suppress uritest 778dc8b03 fix #1 76281ff38 fix a typo in error.h: literial -> literal a98e99992 do not define operator!= in C++20 b08672d46 review comment updates 55eca66f3 code & tests for openapi 2.0 & 3.0 suppprt 80b6d1c83 small corrections for schema.h 97fd83017 attempt to fix SEH 7cad78e23 tidy up after merge from master 794248ee6 fix build break 2d87923e9 remove unnecessary templating from schema tests aa1f22251 correct address.json so tests pass ecb8d9e3a add dump of unexpected schema errors in schematest.cpp 89f6717f0 corrections 338d8defd initial 06d58b9e8 Update dtoa.h 22a62fcc2 Update allocators.h 27c3a8dc0 docs: fix simple typo, perecent -> percent 232389d4f delete unused variable 64faab2e9 gate definition of symmetric equality operators on impl, not lib 719304b11 fixes for natvis dd3f730d7 Make schema dtor robust against exceptions 781a4e667 Try to fix MSVC build. 88f8ddd70 Include conceptual change from PR 2001. 469595356 Avoid exit-time destructors. 0390b1ad5 Avoid exit-time destructors. 2b2c80450 encdedstreamtest: fix use-after-free compile error with gcc-12 1f59c69cd valuetest: fix potential write of terminating nul past the end of the destination fcb23c2db Merge pull request #2008 from agate-pris/access-to-allocator-types bdc49ad80 Merge pull request #2014 from lazydroid/dev/lenik/fix_shadowed_variables 6b500986c fix shadowed variable, take 2 3988c5e25 fix shadowed variable 386d31ab6 Allow access to the template parameter StackAllocator in the GenericDocument 79d7a448e Allow the macro RAPIDJSON_DEFAULT_STACK_ALLOCATOR to be used in any namespace 9965ab37f Allow the macro RAPIDJSON_DEFAULT_ALLOCATOR to be used in any namespace 8261c1ddf Merge pull request #1969 from MalcolmTyrrell/MalcolmTyrrell/sanitizeSchemaCode 0d78b1ce9 Merge pull request #1989 from adamcalhoon/really-fix-placement-new-alignment 1dff2abff Fix the alignment of placement new buffer for GenericValue. e4bde9774 Merge pull request #1988 from Tencent/revert-1987-fix-placement-new-alignment 88bbd87dd Revert "Fix the alignment of placement new buffer for GenericValue." bf8ca5da8 Merge pull request #1987 from adamcalhoon/fix-placement-new-alignment 5b242b6b2 Fix the alignment of placement new buffer for GenericValue. fd3dc29a5 Merge pull request #1944 from ilelann/patch-1 53602ec6b Sanitize the code in schema.h 0d4517f15 Merge pull request #1961 from jedwardsol/issue1960_arm64ec_intrinsic 060c348ea use softintrin on arm64ec 4d6cb0818 Merge pull request #1949 from ardb-uk/master 033bef3c6 Merge pull request #1 from ardb-uk/ardb-uk-patch-1 befba39af Merge pull request #2 from ardb-uk/ardb-uk-patch-1-1 4bbaf28ff Add files via upload 14f1e37f8 Resolve issue 1948 e6736d1ba Support CMake none targets git-subtree-dir: external/rapidjson git-subtree-split: a95e013b97ca6523f32da23f5095fcc9dd6067e5
2023-08-05 09:13:29 +00:00
char name[11];
sprintf(name, "%d", i);
EXPECT_STREQ(name, m.name.GetString());
EXPECT_EQ(i, m.value.GetInt());
i++;
}
EXPECT_EQ(i, 10);
}
// Object a = x.GetObject();
// Object ca = const_cast<const Value&>(x).GetObject();
}
#endif
TEST(Value, EraseMember_String) {
Value::AllocatorType allocator;
Value x(kObjectType);
x.AddMember("A", "Apple", allocator);
x.AddMember("B", "Banana", allocator);
EXPECT_TRUE(x.EraseMember("B"));
EXPECT_FALSE(x.HasMember("B"));
EXPECT_FALSE(x.EraseMember("nonexist"));
GenericValue<UTF8<>, CrtAllocator> othername("A");
EXPECT_TRUE(x.EraseMember(othername));
EXPECT_FALSE(x.HasMember("A"));
EXPECT_TRUE(x.MemberBegin() == x.MemberEnd());
}
TEST(Value, BigNestedArray) {
MemoryPoolAllocator<> allocator;
Value x(kArrayType);
static const SizeType n = 200;
for (SizeType i = 0; i < n; i++) {
Value y(kArrayType);
for (SizeType j = 0; j < n; j++) {
Value number(static_cast<int>(i * n + j));
y.PushBack(number, allocator);
}
x.PushBack(y, allocator);
}
for (SizeType i = 0; i < n; i++)
for (SizeType j = 0; j < n; j++) {
EXPECT_TRUE(x[i][j].IsInt());
EXPECT_EQ(static_cast<int>(i * n + j), x[i][j].GetInt());
}
}
TEST(Value, BigNestedObject) {
MemoryPoolAllocator<> allocator;
Value x(kObjectType);
static const SizeType n = 200;
for (SizeType i = 0; i < n; i++) {
char name1[10];
sprintf(name1, "%d", i);
// Value name(name1); // should not compile
Value name(name1, static_cast<SizeType>(strlen(name1)), allocator);
Value object(kObjectType);
for (SizeType j = 0; j < n; j++) {
char name2[10];
sprintf(name2, "%d", j);
Value name3(name2, static_cast<SizeType>(strlen(name2)), allocator);
Value number(static_cast<int>(i * n + j));
object.AddMember(name3, number, allocator);
}
// x.AddMember(name1, object, allocator); // should not compile
x.AddMember(name, object, allocator);
}
for (SizeType i = 0; i < n; i++) {
char name1[10];
sprintf(name1, "%d", i);
Squashed 'external/rapidjson/' changes from 2e8f5d897..a95e013b9 a95e013b9 Stringify NaN, Inf as null if needs 973dc9c06 Avoid ptrdiff between pointers to different allocations 2a1f586ba Check for __GNUC__ definition 0e88d5e40 Eliminate missing prototypes warning 949c771b0 Resolve conflict with Windows header about max macro 083f359f5 CMakeLists: fix optflags for ppc 012be8528 Use passed in allocator. 1ce516e50 Suppress uritest 778dc8b03 fix #1 76281ff38 fix a typo in error.h: literial -> literal a98e99992 do not define operator!= in C++20 b08672d46 review comment updates 55eca66f3 code & tests for openapi 2.0 & 3.0 suppprt 80b6d1c83 small corrections for schema.h 97fd83017 attempt to fix SEH 7cad78e23 tidy up after merge from master 794248ee6 fix build break 2d87923e9 remove unnecessary templating from schema tests aa1f22251 correct address.json so tests pass ecb8d9e3a add dump of unexpected schema errors in schematest.cpp 89f6717f0 corrections 338d8defd initial 06d58b9e8 Update dtoa.h 22a62fcc2 Update allocators.h 27c3a8dc0 docs: fix simple typo, perecent -> percent 232389d4f delete unused variable 64faab2e9 gate definition of symmetric equality operators on impl, not lib 719304b11 fixes for natvis dd3f730d7 Make schema dtor robust against exceptions 781a4e667 Try to fix MSVC build. 88f8ddd70 Include conceptual change from PR 2001. 469595356 Avoid exit-time destructors. 0390b1ad5 Avoid exit-time destructors. 2b2c80450 encdedstreamtest: fix use-after-free compile error with gcc-12 1f59c69cd valuetest: fix potential write of terminating nul past the end of the destination fcb23c2db Merge pull request #2008 from agate-pris/access-to-allocator-types bdc49ad80 Merge pull request #2014 from lazydroid/dev/lenik/fix_shadowed_variables 6b500986c fix shadowed variable, take 2 3988c5e25 fix shadowed variable 386d31ab6 Allow access to the template parameter StackAllocator in the GenericDocument 79d7a448e Allow the macro RAPIDJSON_DEFAULT_STACK_ALLOCATOR to be used in any namespace 9965ab37f Allow the macro RAPIDJSON_DEFAULT_ALLOCATOR to be used in any namespace 8261c1ddf Merge pull request #1969 from MalcolmTyrrell/MalcolmTyrrell/sanitizeSchemaCode 0d78b1ce9 Merge pull request #1989 from adamcalhoon/really-fix-placement-new-alignment 1dff2abff Fix the alignment of placement new buffer for GenericValue. e4bde9774 Merge pull request #1988 from Tencent/revert-1987-fix-placement-new-alignment 88bbd87dd Revert "Fix the alignment of placement new buffer for GenericValue." bf8ca5da8 Merge pull request #1987 from adamcalhoon/fix-placement-new-alignment 5b242b6b2 Fix the alignment of placement new buffer for GenericValue. fd3dc29a5 Merge pull request #1944 from ilelann/patch-1 53602ec6b Sanitize the code in schema.h 0d4517f15 Merge pull request #1961 from jedwardsol/issue1960_arm64ec_intrinsic 060c348ea use softintrin on arm64ec 4d6cb0818 Merge pull request #1949 from ardb-uk/master 033bef3c6 Merge pull request #1 from ardb-uk/ardb-uk-patch-1 befba39af Merge pull request #2 from ardb-uk/ardb-uk-patch-1-1 4bbaf28ff Add files via upload 14f1e37f8 Resolve issue 1948 e6736d1ba Support CMake none targets git-subtree-dir: external/rapidjson git-subtree-split: a95e013b97ca6523f32da23f5095fcc9dd6067e5
2023-08-05 09:13:29 +00:00
for (SizeType j = 0; j < n; j++) {
char name2[10];
sprintf(name2, "%d", j);
x[name1];
EXPECT_EQ(static_cast<int>(i * n + j), x[name1][name2].GetInt());
}
}
}
// Issue 18: Error removing last element of object
// http://code.google.com/p/rapidjson/issues/detail?id=18
TEST(Value, RemoveLastElement) {
rapidjson::Document doc;
rapidjson::Document::AllocatorType& allocator = doc.GetAllocator();
Squashed 'external/rapidjson/' changes from 2e8f5d897..a95e013b9 a95e013b9 Stringify NaN, Inf as null if needs 973dc9c06 Avoid ptrdiff between pointers to different allocations 2a1f586ba Check for __GNUC__ definition 0e88d5e40 Eliminate missing prototypes warning 949c771b0 Resolve conflict with Windows header about max macro 083f359f5 CMakeLists: fix optflags for ppc 012be8528 Use passed in allocator. 1ce516e50 Suppress uritest 778dc8b03 fix #1 76281ff38 fix a typo in error.h: literial -> literal a98e99992 do not define operator!= in C++20 b08672d46 review comment updates 55eca66f3 code & tests for openapi 2.0 & 3.0 suppprt 80b6d1c83 small corrections for schema.h 97fd83017 attempt to fix SEH 7cad78e23 tidy up after merge from master 794248ee6 fix build break 2d87923e9 remove unnecessary templating from schema tests aa1f22251 correct address.json so tests pass ecb8d9e3a add dump of unexpected schema errors in schematest.cpp 89f6717f0 corrections 338d8defd initial 06d58b9e8 Update dtoa.h 22a62fcc2 Update allocators.h 27c3a8dc0 docs: fix simple typo, perecent -> percent 232389d4f delete unused variable 64faab2e9 gate definition of symmetric equality operators on impl, not lib 719304b11 fixes for natvis dd3f730d7 Make schema dtor robust against exceptions 781a4e667 Try to fix MSVC build. 88f8ddd70 Include conceptual change from PR 2001. 469595356 Avoid exit-time destructors. 0390b1ad5 Avoid exit-time destructors. 2b2c80450 encdedstreamtest: fix use-after-free compile error with gcc-12 1f59c69cd valuetest: fix potential write of terminating nul past the end of the destination fcb23c2db Merge pull request #2008 from agate-pris/access-to-allocator-types bdc49ad80 Merge pull request #2014 from lazydroid/dev/lenik/fix_shadowed_variables 6b500986c fix shadowed variable, take 2 3988c5e25 fix shadowed variable 386d31ab6 Allow access to the template parameter StackAllocator in the GenericDocument 79d7a448e Allow the macro RAPIDJSON_DEFAULT_STACK_ALLOCATOR to be used in any namespace 9965ab37f Allow the macro RAPIDJSON_DEFAULT_ALLOCATOR to be used in any namespace 8261c1ddf Merge pull request #1969 from MalcolmTyrrell/MalcolmTyrrell/sanitizeSchemaCode 0d78b1ce9 Merge pull request #1989 from adamcalhoon/really-fix-placement-new-alignment 1dff2abff Fix the alignment of placement new buffer for GenericValue. e4bde9774 Merge pull request #1988 from Tencent/revert-1987-fix-placement-new-alignment 88bbd87dd Revert "Fix the alignment of placement new buffer for GenericValue." bf8ca5da8 Merge pull request #1987 from adamcalhoon/fix-placement-new-alignment 5b242b6b2 Fix the alignment of placement new buffer for GenericValue. fd3dc29a5 Merge pull request #1944 from ilelann/patch-1 53602ec6b Sanitize the code in schema.h 0d4517f15 Merge pull request #1961 from jedwardsol/issue1960_arm64ec_intrinsic 060c348ea use softintrin on arm64ec 4d6cb0818 Merge pull request #1949 from ardb-uk/master 033bef3c6 Merge pull request #1 from ardb-uk/ardb-uk-patch-1 befba39af Merge pull request #2 from ardb-uk/ardb-uk-patch-1-1 4bbaf28ff Add files via upload 14f1e37f8 Resolve issue 1948 e6736d1ba Support CMake none targets git-subtree-dir: external/rapidjson git-subtree-split: a95e013b97ca6523f32da23f5095fcc9dd6067e5
2023-08-05 09:13:29 +00:00
rapidjson::Value objVal(rapidjson::kObjectType);
objVal.AddMember("var1", 123, allocator);
objVal.AddMember("var2", "444", allocator);
objVal.AddMember("var3", 555, allocator);
EXPECT_TRUE(objVal.HasMember("var3"));
objVal.RemoveMember("var3"); // Assertion here in r61
EXPECT_FALSE(objVal.HasMember("var3"));
}
// Issue 38: Segmentation fault with CrtAllocator
TEST(Document, CrtAllocator) {
typedef GenericValue<UTF8<>, CrtAllocator> V;
V::AllocatorType allocator;
V o(kObjectType);
o.AddMember("x", 1, allocator); // Should not call destructor on uninitialized name/value of newly allocated members.
V a(kArrayType);
a.PushBack(1, allocator); // Should not call destructor on uninitialized Value of newly allocated elements.
}
static void TestShortStringOptimization(const char* str) {
const rapidjson::SizeType len = static_cast<rapidjson::SizeType>(strlen(str));
Squashed 'external/rapidjson/' changes from 2e8f5d897..a95e013b9 a95e013b9 Stringify NaN, Inf as null if needs 973dc9c06 Avoid ptrdiff between pointers to different allocations 2a1f586ba Check for __GNUC__ definition 0e88d5e40 Eliminate missing prototypes warning 949c771b0 Resolve conflict with Windows header about max macro 083f359f5 CMakeLists: fix optflags for ppc 012be8528 Use passed in allocator. 1ce516e50 Suppress uritest 778dc8b03 fix #1 76281ff38 fix a typo in error.h: literial -> literal a98e99992 do not define operator!= in C++20 b08672d46 review comment updates 55eca66f3 code & tests for openapi 2.0 & 3.0 suppprt 80b6d1c83 small corrections for schema.h 97fd83017 attempt to fix SEH 7cad78e23 tidy up after merge from master 794248ee6 fix build break 2d87923e9 remove unnecessary templating from schema tests aa1f22251 correct address.json so tests pass ecb8d9e3a add dump of unexpected schema errors in schematest.cpp 89f6717f0 corrections 338d8defd initial 06d58b9e8 Update dtoa.h 22a62fcc2 Update allocators.h 27c3a8dc0 docs: fix simple typo, perecent -> percent 232389d4f delete unused variable 64faab2e9 gate definition of symmetric equality operators on impl, not lib 719304b11 fixes for natvis dd3f730d7 Make schema dtor robust against exceptions 781a4e667 Try to fix MSVC build. 88f8ddd70 Include conceptual change from PR 2001. 469595356 Avoid exit-time destructors. 0390b1ad5 Avoid exit-time destructors. 2b2c80450 encdedstreamtest: fix use-after-free compile error with gcc-12 1f59c69cd valuetest: fix potential write of terminating nul past the end of the destination fcb23c2db Merge pull request #2008 from agate-pris/access-to-allocator-types bdc49ad80 Merge pull request #2014 from lazydroid/dev/lenik/fix_shadowed_variables 6b500986c fix shadowed variable, take 2 3988c5e25 fix shadowed variable 386d31ab6 Allow access to the template parameter StackAllocator in the GenericDocument 79d7a448e Allow the macro RAPIDJSON_DEFAULT_STACK_ALLOCATOR to be used in any namespace 9965ab37f Allow the macro RAPIDJSON_DEFAULT_ALLOCATOR to be used in any namespace 8261c1ddf Merge pull request #1969 from MalcolmTyrrell/MalcolmTyrrell/sanitizeSchemaCode 0d78b1ce9 Merge pull request #1989 from adamcalhoon/really-fix-placement-new-alignment 1dff2abff Fix the alignment of placement new buffer for GenericValue. e4bde9774 Merge pull request #1988 from Tencent/revert-1987-fix-placement-new-alignment 88bbd87dd Revert "Fix the alignment of placement new buffer for GenericValue." bf8ca5da8 Merge pull request #1987 from adamcalhoon/fix-placement-new-alignment 5b242b6b2 Fix the alignment of placement new buffer for GenericValue. fd3dc29a5 Merge pull request #1944 from ilelann/patch-1 53602ec6b Sanitize the code in schema.h 0d4517f15 Merge pull request #1961 from jedwardsol/issue1960_arm64ec_intrinsic 060c348ea use softintrin on arm64ec 4d6cb0818 Merge pull request #1949 from ardb-uk/master 033bef3c6 Merge pull request #1 from ardb-uk/ardb-uk-patch-1 befba39af Merge pull request #2 from ardb-uk/ardb-uk-patch-1-1 4bbaf28ff Add files via upload 14f1e37f8 Resolve issue 1948 e6736d1ba Support CMake none targets git-subtree-dir: external/rapidjson git-subtree-split: a95e013b97ca6523f32da23f5095fcc9dd6067e5
2023-08-05 09:13:29 +00:00
rapidjson::Document doc;
rapidjson::Value val;
val.SetString(str, len, doc.GetAllocator());
Squashed 'external/rapidjson/' changes from 2e8f5d897..a95e013b9 a95e013b9 Stringify NaN, Inf as null if needs 973dc9c06 Avoid ptrdiff between pointers to different allocations 2a1f586ba Check for __GNUC__ definition 0e88d5e40 Eliminate missing prototypes warning 949c771b0 Resolve conflict with Windows header about max macro 083f359f5 CMakeLists: fix optflags for ppc 012be8528 Use passed in allocator. 1ce516e50 Suppress uritest 778dc8b03 fix #1 76281ff38 fix a typo in error.h: literial -> literal a98e99992 do not define operator!= in C++20 b08672d46 review comment updates 55eca66f3 code & tests for openapi 2.0 & 3.0 suppprt 80b6d1c83 small corrections for schema.h 97fd83017 attempt to fix SEH 7cad78e23 tidy up after merge from master 794248ee6 fix build break 2d87923e9 remove unnecessary templating from schema tests aa1f22251 correct address.json so tests pass ecb8d9e3a add dump of unexpected schema errors in schematest.cpp 89f6717f0 corrections 338d8defd initial 06d58b9e8 Update dtoa.h 22a62fcc2 Update allocators.h 27c3a8dc0 docs: fix simple typo, perecent -> percent 232389d4f delete unused variable 64faab2e9 gate definition of symmetric equality operators on impl, not lib 719304b11 fixes for natvis dd3f730d7 Make schema dtor robust against exceptions 781a4e667 Try to fix MSVC build. 88f8ddd70 Include conceptual change from PR 2001. 469595356 Avoid exit-time destructors. 0390b1ad5 Avoid exit-time destructors. 2b2c80450 encdedstreamtest: fix use-after-free compile error with gcc-12 1f59c69cd valuetest: fix potential write of terminating nul past the end of the destination fcb23c2db Merge pull request #2008 from agate-pris/access-to-allocator-types bdc49ad80 Merge pull request #2014 from lazydroid/dev/lenik/fix_shadowed_variables 6b500986c fix shadowed variable, take 2 3988c5e25 fix shadowed variable 386d31ab6 Allow access to the template parameter StackAllocator in the GenericDocument 79d7a448e Allow the macro RAPIDJSON_DEFAULT_STACK_ALLOCATOR to be used in any namespace 9965ab37f Allow the macro RAPIDJSON_DEFAULT_ALLOCATOR to be used in any namespace 8261c1ddf Merge pull request #1969 from MalcolmTyrrell/MalcolmTyrrell/sanitizeSchemaCode 0d78b1ce9 Merge pull request #1989 from adamcalhoon/really-fix-placement-new-alignment 1dff2abff Fix the alignment of placement new buffer for GenericValue. e4bde9774 Merge pull request #1988 from Tencent/revert-1987-fix-placement-new-alignment 88bbd87dd Revert "Fix the alignment of placement new buffer for GenericValue." bf8ca5da8 Merge pull request #1987 from adamcalhoon/fix-placement-new-alignment 5b242b6b2 Fix the alignment of placement new buffer for GenericValue. fd3dc29a5 Merge pull request #1944 from ilelann/patch-1 53602ec6b Sanitize the code in schema.h 0d4517f15 Merge pull request #1961 from jedwardsol/issue1960_arm64ec_intrinsic 060c348ea use softintrin on arm64ec 4d6cb0818 Merge pull request #1949 from ardb-uk/master 033bef3c6 Merge pull request #1 from ardb-uk/ardb-uk-patch-1 befba39af Merge pull request #2 from ardb-uk/ardb-uk-patch-1-1 4bbaf28ff Add files via upload 14f1e37f8 Resolve issue 1948 e6736d1ba Support CMake none targets git-subtree-dir: external/rapidjson git-subtree-split: a95e013b97ca6523f32da23f5095fcc9dd6067e5
2023-08-05 09:13:29 +00:00
EXPECT_EQ(val.GetStringLength(), len);
EXPECT_STREQ(val.GetString(), str);
}
TEST(Value, AllocateShortString) {
Squashed 'external/rapidjson/' changes from 2e8f5d897..a95e013b9 a95e013b9 Stringify NaN, Inf as null if needs 973dc9c06 Avoid ptrdiff between pointers to different allocations 2a1f586ba Check for __GNUC__ definition 0e88d5e40 Eliminate missing prototypes warning 949c771b0 Resolve conflict with Windows header about max macro 083f359f5 CMakeLists: fix optflags for ppc 012be8528 Use passed in allocator. 1ce516e50 Suppress uritest 778dc8b03 fix #1 76281ff38 fix a typo in error.h: literial -> literal a98e99992 do not define operator!= in C++20 b08672d46 review comment updates 55eca66f3 code & tests for openapi 2.0 & 3.0 suppprt 80b6d1c83 small corrections for schema.h 97fd83017 attempt to fix SEH 7cad78e23 tidy up after merge from master 794248ee6 fix build break 2d87923e9 remove unnecessary templating from schema tests aa1f22251 correct address.json so tests pass ecb8d9e3a add dump of unexpected schema errors in schematest.cpp 89f6717f0 corrections 338d8defd initial 06d58b9e8 Update dtoa.h 22a62fcc2 Update allocators.h 27c3a8dc0 docs: fix simple typo, perecent -> percent 232389d4f delete unused variable 64faab2e9 gate definition of symmetric equality operators on impl, not lib 719304b11 fixes for natvis dd3f730d7 Make schema dtor robust against exceptions 781a4e667 Try to fix MSVC build. 88f8ddd70 Include conceptual change from PR 2001. 469595356 Avoid exit-time destructors. 0390b1ad5 Avoid exit-time destructors. 2b2c80450 encdedstreamtest: fix use-after-free compile error with gcc-12 1f59c69cd valuetest: fix potential write of terminating nul past the end of the destination fcb23c2db Merge pull request #2008 from agate-pris/access-to-allocator-types bdc49ad80 Merge pull request #2014 from lazydroid/dev/lenik/fix_shadowed_variables 6b500986c fix shadowed variable, take 2 3988c5e25 fix shadowed variable 386d31ab6 Allow access to the template parameter StackAllocator in the GenericDocument 79d7a448e Allow the macro RAPIDJSON_DEFAULT_STACK_ALLOCATOR to be used in any namespace 9965ab37f Allow the macro RAPIDJSON_DEFAULT_ALLOCATOR to be used in any namespace 8261c1ddf Merge pull request #1969 from MalcolmTyrrell/MalcolmTyrrell/sanitizeSchemaCode 0d78b1ce9 Merge pull request #1989 from adamcalhoon/really-fix-placement-new-alignment 1dff2abff Fix the alignment of placement new buffer for GenericValue. e4bde9774 Merge pull request #1988 from Tencent/revert-1987-fix-placement-new-alignment 88bbd87dd Revert "Fix the alignment of placement new buffer for GenericValue." bf8ca5da8 Merge pull request #1987 from adamcalhoon/fix-placement-new-alignment 5b242b6b2 Fix the alignment of placement new buffer for GenericValue. fd3dc29a5 Merge pull request #1944 from ilelann/patch-1 53602ec6b Sanitize the code in schema.h 0d4517f15 Merge pull request #1961 from jedwardsol/issue1960_arm64ec_intrinsic 060c348ea use softintrin on arm64ec 4d6cb0818 Merge pull request #1949 from ardb-uk/master 033bef3c6 Merge pull request #1 from ardb-uk/ardb-uk-patch-1 befba39af Merge pull request #2 from ardb-uk/ardb-uk-patch-1-1 4bbaf28ff Add files via upload 14f1e37f8 Resolve issue 1948 e6736d1ba Support CMake none targets git-subtree-dir: external/rapidjson git-subtree-split: a95e013b97ca6523f32da23f5095fcc9dd6067e5
2023-08-05 09:13:29 +00:00
TestShortStringOptimization(""); // edge case: empty string
TestShortStringOptimization("12345678"); // regular case for short strings: 8 chars
TestShortStringOptimization("12345678901"); // edge case: 11 chars in 32-bit mode (=> short string)
TestShortStringOptimization("123456789012"); // edge case: 12 chars in 32-bit mode (=> regular string)
TestShortStringOptimization("123456789012345"); // edge case: 15 chars in 64-bit mode (=> short string)
TestShortStringOptimization("1234567890123456"); // edge case: 16 chars in 64-bit mode (=> regular string)
}
template <int e>
struct TerminateHandler {
bool Null() { return e != 0; }
bool Bool(bool) { return e != 1; }
bool Int(int) { return e != 2; }
bool Uint(unsigned) { return e != 3; }
bool Int64(int64_t) { return e != 4; }
bool Uint64(uint64_t) { return e != 5; }
bool Double(double) { return e != 6; }
bool RawNumber(const char*, SizeType, bool) { return e != 7; }
bool String(const char*, SizeType, bool) { return e != 8; }
bool StartObject() { return e != 9; }
bool Key(const char*, SizeType, bool) { return e != 10; }
bool EndObject(SizeType) { return e != 11; }
bool StartArray() { return e != 12; }
bool EndArray(SizeType) { return e != 13; }
};
#define TEST_TERMINATION(e, json)\
{\
Document d; \
EXPECT_FALSE(d.Parse(json).HasParseError()); \
Reader reader; \
TerminateHandler<e> h;\
EXPECT_FALSE(d.Accept(h));\
}
TEST(Value, AcceptTerminationByHandler) {
TEST_TERMINATION(0, "[null]");
TEST_TERMINATION(1, "[true]");
TEST_TERMINATION(1, "[false]");
TEST_TERMINATION(2, "[-1]");
TEST_TERMINATION(3, "[2147483648]");
TEST_TERMINATION(4, "[-1234567890123456789]");
TEST_TERMINATION(5, "[9223372036854775808]");
TEST_TERMINATION(6, "[0.5]");
// RawNumber() is never called
TEST_TERMINATION(8, "[\"a\"]");
TEST_TERMINATION(9, "[{}]");
TEST_TERMINATION(10, "[{\"a\":1}]");
TEST_TERMINATION(11, "[{}]");
TEST_TERMINATION(12, "{\"a\":[]}");
TEST_TERMINATION(13, "{\"a\":[]}");
}
struct ValueIntComparer {
bool operator()(const Value& lhs, const Value& rhs) const {
return lhs.GetInt() < rhs.GetInt();
}
};
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
TEST(Value, Sorting) {
Value::AllocatorType allocator;
Value a(kArrayType);
a.PushBack(5, allocator);
a.PushBack(1, allocator);
a.PushBack(3, allocator);
std::sort(a.Begin(), a.End(), ValueIntComparer());
EXPECT_EQ(1, a[0].GetInt());
EXPECT_EQ(3, a[1].GetInt());
EXPECT_EQ(5, a[2].GetInt());
}
#endif
// http://stackoverflow.com/questions/35222230/
static void MergeDuplicateKey(Value& v, Value::AllocatorType& a) {
if (v.IsObject()) {
// Convert all key:value into key:[value]
for (Value::MemberIterator itr = v.MemberBegin(); itr != v.MemberEnd(); ++itr)
itr->value = Value(kArrayType).Move().PushBack(itr->value, a);
Squashed 'external/rapidjson/' changes from 2e8f5d897..a95e013b9 a95e013b9 Stringify NaN, Inf as null if needs 973dc9c06 Avoid ptrdiff between pointers to different allocations 2a1f586ba Check for __GNUC__ definition 0e88d5e40 Eliminate missing prototypes warning 949c771b0 Resolve conflict with Windows header about max macro 083f359f5 CMakeLists: fix optflags for ppc 012be8528 Use passed in allocator. 1ce516e50 Suppress uritest 778dc8b03 fix #1 76281ff38 fix a typo in error.h: literial -> literal a98e99992 do not define operator!= in C++20 b08672d46 review comment updates 55eca66f3 code & tests for openapi 2.0 & 3.0 suppprt 80b6d1c83 small corrections for schema.h 97fd83017 attempt to fix SEH 7cad78e23 tidy up after merge from master 794248ee6 fix build break 2d87923e9 remove unnecessary templating from schema tests aa1f22251 correct address.json so tests pass ecb8d9e3a add dump of unexpected schema errors in schematest.cpp 89f6717f0 corrections 338d8defd initial 06d58b9e8 Update dtoa.h 22a62fcc2 Update allocators.h 27c3a8dc0 docs: fix simple typo, perecent -> percent 232389d4f delete unused variable 64faab2e9 gate definition of symmetric equality operators on impl, not lib 719304b11 fixes for natvis dd3f730d7 Make schema dtor robust against exceptions 781a4e667 Try to fix MSVC build. 88f8ddd70 Include conceptual change from PR 2001. 469595356 Avoid exit-time destructors. 0390b1ad5 Avoid exit-time destructors. 2b2c80450 encdedstreamtest: fix use-after-free compile error with gcc-12 1f59c69cd valuetest: fix potential write of terminating nul past the end of the destination fcb23c2db Merge pull request #2008 from agate-pris/access-to-allocator-types bdc49ad80 Merge pull request #2014 from lazydroid/dev/lenik/fix_shadowed_variables 6b500986c fix shadowed variable, take 2 3988c5e25 fix shadowed variable 386d31ab6 Allow access to the template parameter StackAllocator in the GenericDocument 79d7a448e Allow the macro RAPIDJSON_DEFAULT_STACK_ALLOCATOR to be used in any namespace 9965ab37f Allow the macro RAPIDJSON_DEFAULT_ALLOCATOR to be used in any namespace 8261c1ddf Merge pull request #1969 from MalcolmTyrrell/MalcolmTyrrell/sanitizeSchemaCode 0d78b1ce9 Merge pull request #1989 from adamcalhoon/really-fix-placement-new-alignment 1dff2abff Fix the alignment of placement new buffer for GenericValue. e4bde9774 Merge pull request #1988 from Tencent/revert-1987-fix-placement-new-alignment 88bbd87dd Revert "Fix the alignment of placement new buffer for GenericValue." bf8ca5da8 Merge pull request #1987 from adamcalhoon/fix-placement-new-alignment 5b242b6b2 Fix the alignment of placement new buffer for GenericValue. fd3dc29a5 Merge pull request #1944 from ilelann/patch-1 53602ec6b Sanitize the code in schema.h 0d4517f15 Merge pull request #1961 from jedwardsol/issue1960_arm64ec_intrinsic 060c348ea use softintrin on arm64ec 4d6cb0818 Merge pull request #1949 from ardb-uk/master 033bef3c6 Merge pull request #1 from ardb-uk/ardb-uk-patch-1 befba39af Merge pull request #2 from ardb-uk/ardb-uk-patch-1-1 4bbaf28ff Add files via upload 14f1e37f8 Resolve issue 1948 e6736d1ba Support CMake none targets git-subtree-dir: external/rapidjson git-subtree-split: a95e013b97ca6523f32da23f5095fcc9dd6067e5
2023-08-05 09:13:29 +00:00
// Merge arrays if key is duplicated
for (Value::MemberIterator itr = v.MemberBegin(); itr != v.MemberEnd();) {
Value::MemberIterator itr2 = v.FindMember(itr->name);
if (itr != itr2) {
itr2->value.PushBack(itr->value[0], a);
itr = v.EraseMember(itr);
}
else
++itr;
}
// Convert key:[values] back to key:value if there is only one value
for (Value::MemberIterator itr = v.MemberBegin(); itr != v.MemberEnd(); ++itr) {
if (itr->value.Size() == 1)
itr->value = itr->value[0];
MergeDuplicateKey(itr->value, a); // Recursion on the value
}
}
else if (v.IsArray())
for (Value::ValueIterator itr = v.Begin(); itr != v.End(); ++itr)
MergeDuplicateKey(*itr, a);
}
TEST(Value, MergeDuplicateKey) {
Document d;
d.Parse(
"{"
" \"key1\": {"
" \"a\": \"asdf\","
" \"b\": \"foo\","
" \"b\": \"bar\","
" \"c\": \"fdas\""
" }"
"}");
Document d2;
d2.Parse(
"{"
" \"key1\": {"
" \"a\": \"asdf\","
" \"b\": ["
" \"foo\","
" \"bar\""
" ],"
" \"c\": \"fdas\""
" }"
"}");
EXPECT_NE(d2, d);
MergeDuplicateKey(d, d.GetAllocator());
EXPECT_EQ(d2, d);
}
#ifdef __clang__
RAPIDJSON_DIAG_POP
#endif