Rectify constness of Array
This commit is contained in:
parent
59309b5dd2
commit
0b098eb38d
@ -481,9 +481,25 @@ struct TypeHelper<ValueType, std::basic_string<typename ValueType::Ch> > {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // namespace internal
|
template<typename ValueType>
|
||||||
|
struct TypeHelper<ValueType, typename ValueType::Array> {
|
||||||
|
typedef typename ValueType::Array ArratType;
|
||||||
|
static bool Is(const ValueType& v) { return v.IsArray(); }
|
||||||
|
static ArratType Get(ValueType& v) { return v.GetArray(); }
|
||||||
|
static ValueType& Set(ValueType& v, ArratType data) { return v.SetArray(data); }
|
||||||
|
static ValueType& Set(ValueType& v, ArratType data, typename ValueType::AllocatorType&) { return v.SetArray(data); }
|
||||||
|
};
|
||||||
|
|
||||||
template<typename ValueType>
|
template<typename ValueType>
|
||||||
|
struct TypeHelper<ValueType, typename ValueType::ConstArray> {
|
||||||
|
typedef typename ValueType::ConstArray ArratType;
|
||||||
|
static bool Is(const ValueType& v) { return v.IsArray(); }
|
||||||
|
static ArratType Get(const ValueType& v) { return v.GetArray(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
template <bool, typename>
|
||||||
class GenericArray;
|
class GenericArray;
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
@ -513,7 +529,8 @@ public:
|
|||||||
typedef GenericValue* ValueIterator; //!< Value iterator for iterating in array.
|
typedef GenericValue* ValueIterator; //!< Value iterator for iterating in array.
|
||||||
typedef const GenericValue* ConstValueIterator; //!< Constant value iterator for iterating in array.
|
typedef const GenericValue* ConstValueIterator; //!< Constant value iterator for iterating in array.
|
||||||
typedef GenericValue<Encoding, Allocator> ValueType; //!< Value type of itself.
|
typedef GenericValue<Encoding, Allocator> ValueType; //!< Value type of itself.
|
||||||
typedef GenericArray<ValueType> ArrayType;
|
typedef GenericArray<false, ValueType> Array;
|
||||||
|
typedef GenericArray<true, ValueType> ConstArray;
|
||||||
|
|
||||||
//!@name Constructors and destructor.
|
//!@name Constructors and destructor.
|
||||||
//@{
|
//@{
|
||||||
@ -1114,7 +1131,7 @@ public:
|
|||||||
RAPIDJSON_ASSERT(IsObject());
|
RAPIDJSON_ASSERT(IsObject());
|
||||||
RAPIDJSON_ASSERT(name.IsString());
|
RAPIDJSON_ASSERT(name.IsString());
|
||||||
|
|
||||||
Object& o = data_.o;
|
ObjectData& o = data_.o;
|
||||||
if (o.size >= o.capacity) {
|
if (o.size >= o.capacity) {
|
||||||
if (o.capacity == 0) {
|
if (o.capacity == 0) {
|
||||||
o.capacity = kDefaultObjectCapacity;
|
o.capacity = kDefaultObjectCapacity;
|
||||||
@ -1394,6 +1411,9 @@ public:
|
|||||||
/*! \post IsArray == true */
|
/*! \post IsArray == true */
|
||||||
GenericValue& SetArray() { this->~GenericValue(); new (this) GenericValue(kArrayType); return *this; }
|
GenericValue& SetArray() { this->~GenericValue(); new (this) GenericValue(kArrayType); return *this; }
|
||||||
|
|
||||||
|
//! Set this value with an array.
|
||||||
|
GenericValue& SetArray(Array& a) { return *this = *a.ptr_; }
|
||||||
|
|
||||||
//! Get the number of elements in array.
|
//! Get the number of elements in array.
|
||||||
SizeType Size() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size; }
|
SizeType Size() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size; }
|
||||||
|
|
||||||
@ -1560,8 +1580,8 @@ public:
|
|||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayType GetArray() { RAPIDJSON_ASSERT(IsArray()); return ArrayType(*this); }
|
Array GetArray() { RAPIDJSON_ASSERT(IsArray()); return Array(*this); }
|
||||||
const ArrayType GetArray() const { RAPIDJSON_ASSERT(IsArray()); return ArrayType(*this); }
|
ConstArray GetArray() const { RAPIDJSON_ASSERT(IsArray()); return ConstArray(*this); }
|
||||||
|
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
@ -1673,6 +1693,9 @@ public:
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
T Get() const { return internal::TypeHelper<ValueType, T>::Get(*this); }
|
T Get() const { return internal::TypeHelper<ValueType, T>::Get(*this); }
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T Get() { return internal::TypeHelper<ValueType, T>::Get(*this); }
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ValueType& Set(const T& data) { return internal::TypeHelper<ValueType, T>::Set(*this, data); }
|
ValueType& Set(const T& data) { return internal::TypeHelper<ValueType, T>::Set(*this, data); }
|
||||||
|
|
||||||
@ -1815,13 +1838,13 @@ private:
|
|||||||
double d;
|
double d;
|
||||||
}; // 8 bytes
|
}; // 8 bytes
|
||||||
|
|
||||||
struct Object {
|
struct ObjectData {
|
||||||
Member* members;
|
Member* members;
|
||||||
SizeType size;
|
SizeType size;
|
||||||
SizeType capacity;
|
SizeType capacity;
|
||||||
}; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
|
}; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
|
||||||
|
|
||||||
struct Array {
|
struct ArrayData {
|
||||||
GenericValue* elements;
|
GenericValue* elements;
|
||||||
SizeType size;
|
SizeType size;
|
||||||
SizeType capacity;
|
SizeType capacity;
|
||||||
@ -1831,8 +1854,8 @@ private:
|
|||||||
String s;
|
String s;
|
||||||
ShortString ss;
|
ShortString ss;
|
||||||
Number n;
|
Number n;
|
||||||
Object o;
|
ObjectData o;
|
||||||
Array a;
|
ArrayData a;
|
||||||
}; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
|
}; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
|
||||||
|
|
||||||
// Initialize this value as array with initial data, without calling destructor.
|
// Initialize this value as array with initial data, without calling destructor.
|
||||||
@ -2295,9 +2318,13 @@ GenericValue<Encoding,Allocator>::GenericValue(const GenericValue<Encoding,Sourc
|
|||||||
Instance of this helper class is obtained by \c GenericValue::GetArray().
|
Instance of this helper class is obtained by \c GenericValue::GetArray().
|
||||||
In addition to all APIs for array type, it provides range-based for loop if \c RAPIDJSON_HAS_CXX11_RANGE_FOR=1.
|
In addition to all APIs for array type, it provides range-based for loop if \c RAPIDJSON_HAS_CXX11_RANGE_FOR=1.
|
||||||
*/
|
*/
|
||||||
template <typename ValueType>
|
template <bool Const, typename ValueT>
|
||||||
class GenericArray {
|
class GenericArray {
|
||||||
public:
|
public:
|
||||||
|
typedef GenericArray<true, ValueT> ConstArray;
|
||||||
|
typedef GenericArray<false, ValueT> Array;
|
||||||
|
typedef ValueT PlainType;
|
||||||
|
typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
|
||||||
typedef typename ValueType::ValueIterator ValueIterator;
|
typedef typename ValueType::ValueIterator ValueIterator;
|
||||||
typedef typename ValueType::ConstValueIterator ConstValueIterator;
|
typedef typename ValueType::ConstValueIterator ConstValueIterator;
|
||||||
typedef typename ValueType::AllocatorType AllocatorType;
|
typedef typename ValueType::AllocatorType AllocatorType;
|
||||||
@ -2308,7 +2335,7 @@ public:
|
|||||||
|
|
||||||
GenericArray() : ptr_() {}
|
GenericArray() : ptr_() {}
|
||||||
GenericArray(const GenericArray& rhs) : ptr_(rhs.ptr_) {}
|
GenericArray(const GenericArray& rhs) : ptr_(rhs.ptr_) {}
|
||||||
GenericArray& operator=(GenericArray& rhs) { ptr_ = rhs.ptr_; return *this; }
|
GenericArray& operator=(const GenericArray& rhs) { ptr_ = rhs.ptr_; return *this; }
|
||||||
~GenericArray() {}
|
~GenericArray() {}
|
||||||
|
|
||||||
SizeType Size() const { return ptr_->Size(); }
|
SizeType Size() const { return ptr_->Size(); }
|
||||||
@ -2343,12 +2370,9 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
GenericArray(ValueType& value) : ptr_(&value) {}
|
GenericArray(ValueType& value) : ptr_(&value) {}
|
||||||
GenericArray(const ValueType& value) : ptr_(const_cast<ValueType*>(&value)) {}
|
|
||||||
ValueType* ptr_;
|
ValueType* ptr_;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef GenericArray<Value> Array;
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
RAPIDJSON_NAMESPACE_END
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
@ -1028,20 +1028,40 @@ TEST(Value, ArrayHelper) {
|
|||||||
Value::AllocatorType allocator;
|
Value::AllocatorType allocator;
|
||||||
{
|
{
|
||||||
Value x(kArrayType);
|
Value x(kArrayType);
|
||||||
Array a = x.GetArray();
|
Value::Array a = x.GetArray();
|
||||||
TestArray(a, allocator);
|
TestArray(a, allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
Value x(kArrayType);
|
Value x(kArrayType);
|
||||||
Array a = x.GetArray();
|
Value::Array a = x.GetArray();
|
||||||
a.PushBack(1, allocator);
|
a.PushBack(1, allocator);
|
||||||
|
|
||||||
Array a2(a); // copy constructor
|
Value::Array a2(a); // copy constructor
|
||||||
EXPECT_EQ(1, a2.Size());
|
EXPECT_EQ(1, a2.Size());
|
||||||
|
|
||||||
Array a3; // default constructor
|
Value::Array a3; // default constructor
|
||||||
a3 = a; // assignment operator
|
a3 = a; // assignment operator
|
||||||
EXPECT_EQ(1, a3.Size());
|
EXPECT_EQ(1, 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);
|
||||||
|
a = x.Get<Value::Array>();
|
||||||
|
EXPECT_EQ(1, a[0].GetInt());
|
||||||
|
EXPECT_EQ(1, x.Get<Value::ConstArray>()[0].GetInt());
|
||||||
|
|
||||||
|
Value x2;
|
||||||
|
x2.Set<Value::Array>(a);
|
||||||
|
EXPECT_TRUE(x.IsNull());
|
||||||
|
EXPECT_EQ(1, x2.Get<Value::Array>()[0].GetInt());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if RAPIDJSON_HAS_CXX11_RANGE_FOR
|
#if RAPIDJSON_HAS_CXX11_RANGE_FOR
|
||||||
|
Loading…
x
Reference in New Issue
Block a user