Extract ArrayData from CollectionData

This commit is contained in:
Benoit Blanchon
2023-06-26 10:48:56 +02:00
parent 67bbb4c90d
commit 7bc73d7849
17 changed files with 194 additions and 161 deletions

View File

@ -32,6 +32,7 @@
#include "ArduinoJson/Document/JsonDocument.hpp" #include "ArduinoJson/Document/JsonDocument.hpp"
#include "ArduinoJson/Array/ArrayImpl.hpp"
#include "ArduinoJson/Array/ElementProxy.hpp" #include "ArduinoJson/Array/ElementProxy.hpp"
#include "ArduinoJson/Array/JsonArrayImpl.hpp" #include "ArduinoJson/Array/JsonArrayImpl.hpp"
#include "ArduinoJson/Array/Utilities.hpp" #include "ArduinoJson/Array/Utilities.hpp"

View File

@ -0,0 +1,65 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2023, Benoit BLANCHON
// MIT License
#pragma once
#include <ArduinoJson/Collection/CollectionData.hpp>
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
class ArrayData : public CollectionData {
public:
VariantData* addElement(ResourceManager* resources);
static VariantData* addElement(ArrayData* array, ResourceManager* resources) {
if (!array)
return nullptr;
return array->addElement(resources);
}
VariantData* getOrAddElement(size_t index, ResourceManager* resources);
VariantData* getElement(size_t index) const;
static VariantData* getElement(const ArrayData* array, size_t index) {
if (!array)
return nullptr;
return array->getElement(index);
}
void removeElement(size_t index, ResourceManager* resources);
static void removeElement(ArrayData* array, size_t index,
ResourceManager* resources) {
if (!array)
return;
array->removeElement(index, resources);
}
bool equals(const ArrayData&) const;
static bool equals(const ArrayData* lhs, const ArrayData* rhs) {
if (lhs == rhs)
return true;
if (!lhs || !rhs)
return false;
return lhs->equals(*rhs);
}
bool copyFrom(const ArrayData& src, ResourceManager* resources);
static bool copy(ArrayData* dst, const ArrayData* src,
ResourceManager* resources) {
if (!dst || !src)
return false;
return dst->copyFrom(*src, resources);
}
private:
VariantSlot* getSlot(size_t index) const;
};
ARDUINOJSON_END_PRIVATE_NAMESPACE

View File

@ -0,0 +1,81 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2023, Benoit BLANCHON
// MIT License
#pragma once
#include <ArduinoJson/Array/ArrayData.hpp>
#include <ArduinoJson/Variant/VariantCompare.hpp>
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
inline VariantData* ArrayData::addElement(ResourceManager* resources) {
auto slot = resources->allocVariant();
if (!slot)
return nullptr;
addSlot(slot);
return slot->data();
}
inline bool ArrayData::copyFrom(const ArrayData& src,
ResourceManager* resources) {
clear(resources);
for (VariantSlot* s = src.head(); s; s = s->next()) {
auto var = addElement(resources);
if (!variantCopyFrom(var, s->data(), resources))
return false;
}
return true;
}
inline bool ArrayData::equals(const ArrayData& other) const {
auto a = head();
auto b = other.head();
for (;;) {
if (!a && !b) // both ended
return true;
if (!a || !b) // one ended
return false;
if (compare(a->data(), b->data()) != COMPARE_RESULT_EQUAL)
return false;
a = a->next();
b = b->next();
}
}
inline VariantData* ArrayData::getOrAddElement(size_t index,
ResourceManager* resources) {
VariantSlot* slot = head();
while (slot && index > 0) {
slot = slot->next();
index--;
}
if (!slot)
index++;
while (index > 0) {
slot = resources->allocVariant();
if (!slot)
return nullptr;
addSlot(slot);
index--;
}
return slot->data();
}
inline VariantData* ArrayData::getElement(size_t index) const {
return slotData(getSlot(index));
}
inline VariantSlot* ArrayData::getSlot(size_t index) const {
if (!head())
return 0;
return head()->next(index);
}
inline void ArrayData::removeElement(size_t index, ResourceManager* resources) {
removeSlot(getSlot(index), resources);
}
ARDUINOJSON_END_PRIVATE_NAMESPACE

View File

@ -24,7 +24,7 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
FORCE_INLINE JsonArray() : data_(0), resources_(0) {} FORCE_INLINE JsonArray() : data_(0), resources_(0) {}
// INTERNAL USE ONLY // INTERNAL USE ONLY
FORCE_INLINE JsonArray(detail::CollectionData* data, FORCE_INLINE JsonArray(detail::ArrayData* data,
detail::ResourceManager* resources) detail::ResourceManager* resources)
: data_(data), resources_(resources) {} : data_(data), resources_(resources) {}
@ -46,7 +46,8 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
// Returns a reference to the new element. // Returns a reference to the new element.
// https://arduinojson.org/v6/api/jsonarray/add/ // https://arduinojson.org/v6/api/jsonarray/add/
JsonVariant add() const { JsonVariant add() const {
return JsonVariant(collectionAddElement(data_, resources_), resources_); return JsonVariant(detail::ArrayData::addElement(data_, resources_),
resources_);
} }
// Appends a value to the array. // Appends a value to the array.
@ -80,12 +81,12 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
// Copies an array. // Copies an array.
// https://arduinojson.org/v6/api/jsonarray/set/ // https://arduinojson.org/v6/api/jsonarray/set/
FORCE_INLINE bool set(JsonArrayConst src) const { FORCE_INLINE bool set(JsonArrayConst src) const {
return collectionCopy(data_, src.data_, resources_); return detail::ArrayData::copy(data_, src.data_, resources_);
} }
// Compares the content of two arrays. // Compares the content of two arrays.
FORCE_INLINE bool operator==(JsonArray rhs) const { FORCE_INLINE bool operator==(JsonArray rhs) const {
return arrayEquals(data_, rhs.data_); return detail::ArrayData::equals(data_, rhs.data_);
} }
// Removes the element at the specified iterator. // Removes the element at the specified iterator.
@ -99,7 +100,7 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
// ⚠️ Doesn't release the memory associated with the removed element. // ⚠️ Doesn't release the memory associated with the removed element.
// https://arduinojson.org/v6/api/jsonarray/remove/ // https://arduinojson.org/v6/api/jsonarray/remove/
FORCE_INLINE void remove(size_t index) const { FORCE_INLINE void remove(size_t index) const {
collectionRemoveElement(data_, index, resources_); detail::ArrayData::removeElement(data_, index, resources_);
} }
// Removes all the elements of the array. // Removes all the elements of the array.
@ -172,7 +173,7 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
return collectionToVariant(data_); return collectionToVariant(data_);
} }
detail::CollectionData* data_; detail::ArrayData* data_;
detail::ResourceManager* resources_; detail::ResourceManager* resources_;
}; };

View File

@ -40,19 +40,18 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
FORCE_INLINE JsonArrayConst() : data_(0) {} FORCE_INLINE JsonArrayConst() : data_(0) {}
// INTERNAL USE ONLY // INTERNAL USE ONLY
FORCE_INLINE JsonArrayConst(const detail::CollectionData* data) FORCE_INLINE JsonArrayConst(const detail::ArrayData* data) : data_(data) {}
: data_(data) {}
// Compares the content of two arrays. // Compares the content of two arrays.
// Returns true if the two arrays are equal. // Returns true if the two arrays are equal.
FORCE_INLINE bool operator==(JsonArrayConst rhs) const { FORCE_INLINE bool operator==(JsonArrayConst rhs) const {
return arrayEquals(data_, rhs.data_); return detail::ArrayData::equals(data_, rhs.data_);
} }
// Returns the element at the specified index. // Returns the element at the specified index.
// https://arduinojson.org/v6/api/jsonarrayconst/subscript/ // https://arduinojson.org/v6/api/jsonarrayconst/subscript/
FORCE_INLINE JsonVariantConst operator[](size_t index) const { FORCE_INLINE JsonVariantConst operator[](size_t index) const {
return JsonVariantConst(collectionGetElement(data_, index)); return JsonVariantConst(detail::ArrayData::getElement(data_, index));
} }
operator JsonVariantConst() const { operator JsonVariantConst() const {
@ -94,7 +93,7 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
return collectionToVariant(data_); return collectionToVariant(data_);
} }
const detail::CollectionData* data_; const detail::ArrayData* data_;
}; };
template <> template <>

View File

@ -29,8 +29,6 @@ class CollectionData {
size_t memoryUsage() const; size_t memoryUsage() const;
size_t size() const; size_t size() const;
VariantData* addElement(ResourceManager* resources);
VariantData* addMember(StringNode* key, ResourceManager* resources); VariantData* addMember(StringNode* key, ResourceManager* resources);
template <typename TAdaptedString> template <typename TAdaptedString>
@ -39,10 +37,6 @@ class CollectionData {
void clear(ResourceManager* resources); void clear(ResourceManager* resources);
bool copyFrom(const CollectionData& src, ResourceManager* resources); bool copyFrom(const CollectionData& src, ResourceManager* resources);
VariantData* getOrAddElement(size_t index, ResourceManager* resources);
VariantData* getElement(size_t index) const;
template <typename TAdaptedString> template <typename TAdaptedString>
VariantData* getOrAddMember(TAdaptedString key, ResourceManager* resources); VariantData* getOrAddMember(TAdaptedString key, ResourceManager* resources);
@ -51,8 +45,6 @@ class CollectionData {
void removeSlot(VariantSlot* slot, ResourceManager* resources); void removeSlot(VariantSlot* slot, ResourceManager* resources);
void removeElement(size_t index, ResourceManager* resources);
template <typename TAdaptedString> template <typename TAdaptedString>
void removeMember(TAdaptedString key, ResourceManager* resources); void removeMember(TAdaptedString key, ResourceManager* resources);
@ -62,15 +54,14 @@ class CollectionData {
void movePointers(ptrdiff_t variantDistance); void movePointers(ptrdiff_t variantDistance);
private: protected:
void addSlot(VariantSlot*); void addSlot(VariantSlot*);
VariantSlot* getPreviousSlot(VariantSlot*) const;
VariantSlot* getSlot(size_t index) const;
template <typename TAdaptedString> template <typename TAdaptedString>
VariantSlot* getSlot(TAdaptedString key) const; VariantSlot* getSlot(TAdaptedString key) const;
private:
VariantSlot* getPreviousSlot(VariantSlot*) const;
}; };
inline const VariantData* collectionToVariant( inline const VariantData* collectionToVariant(
@ -84,10 +75,6 @@ inline VariantData* collectionToVariant(CollectionData* collection) {
return reinterpret_cast<VariantData*>(data); return reinterpret_cast<VariantData*>(data);
} }
bool arrayEquals(const detail::CollectionData& lhs,
const detail::CollectionData& rhs);
bool arrayEquals(const detail::CollectionData* lhs,
const detail::CollectionData* rhs);
bool objectEquals(const detail::CollectionData& lhs, bool objectEquals(const detail::CollectionData& lhs,
const detail::CollectionData& rhs); const detail::CollectionData& rhs);
bool objectEquals(const detail::CollectionData* lhs, bool objectEquals(const detail::CollectionData* lhs,

View File

@ -8,20 +8,6 @@
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
inline VariantData* collectionAddElement(CollectionData* array,
ResourceManager* resources) {
if (!array)
return nullptr;
return array->addElement(resources);
}
template <typename TAdaptedString>
inline VariantData* collectionAddMember(CollectionData* obj, TAdaptedString key,
ResourceManager* resources) {
ARDUINOJSON_ASSERT(obj != nullptr);
return obj->addMember(key, resources);
}
inline void collectionClear(CollectionData* c, ResourceManager* resources) { inline void collectionClear(CollectionData* c, ResourceManager* resources) {
if (!c) if (!c)
return; return;
@ -36,13 +22,6 @@ inline bool collectionCopy(CollectionData* dst, const CollectionData* src,
return dst->copyFrom(*src, resources); return dst->copyFrom(*src, resources);
} }
inline VariantData* collectionGetElement(const CollectionData* obj,
size_t index) {
if (!obj)
return nullptr;
return obj->getElement(index);
}
template <typename TAdaptedString> template <typename TAdaptedString>
inline VariantData* collectionGetMember(const CollectionData* obj, inline VariantData* collectionGetMember(const CollectionData* obj,
TAdaptedString key) { TAdaptedString key) {
@ -58,13 +37,6 @@ inline void collectionRemove(CollectionData* data, VariantSlot* slot,
data->removeSlot(slot, resources); data->removeSlot(slot, resources);
} }
inline void collectionRemoveElement(CollectionData* array, size_t index,
ResourceManager* resources) {
if (!array)
return;
array->removeElement(index, resources);
}
template <typename TAdaptedString> template <typename TAdaptedString>
inline void collectionRemoveMember(CollectionData* obj, TAdaptedString key, inline void collectionRemoveMember(CollectionData* obj, TAdaptedString key,
ResourceManager* resources) { ResourceManager* resources) {

View File

@ -23,14 +23,6 @@ inline void CollectionData::addSlot(VariantSlot* slot) {
} }
} }
inline VariantData* CollectionData::addElement(ResourceManager* resources) {
auto slot = resources->allocVariant();
if (!slot)
return nullptr;
addSlot(slot);
return slot->data();
}
inline VariantData* CollectionData::addMember(StringNode* key, inline VariantData* CollectionData::addMember(StringNode* key,
ResourceManager* resources) { ResourceManager* resources) {
ARDUINOJSON_ASSERT(key != nullptr); ARDUINOJSON_ASSERT(key != nullptr);
@ -67,25 +59,6 @@ inline VariantData* CollectionData::getMember(TAdaptedString key) const {
return slotData(getSlot(key)); return slotData(getSlot(key));
} }
inline VariantData* CollectionData::getOrAddElement(
size_t index, ResourceManager* resources) {
VariantSlot* slot = head_;
while (slot && index > 0) {
slot = slot->next();
index--;
}
if (!slot)
index++;
while (index > 0) {
slot = resources->allocVariant();
if (!slot)
return nullptr;
addSlot(slot);
index--;
}
return slot->data();
}
template <typename TAdaptedString> template <typename TAdaptedString>
VariantData* CollectionData::getOrAddMember(TAdaptedString key, VariantData* CollectionData::getOrAddMember(TAdaptedString key,
ResourceManager* resources) { ResourceManager* resources) {
@ -95,10 +68,6 @@ VariantData* CollectionData::getOrAddMember(TAdaptedString key,
return addMember(key, resources); return addMember(key, resources);
} }
inline VariantData* CollectionData::getElement(size_t index) const {
return slotData(getSlot(index));
}
inline void CollectionData::clear(ResourceManager* resources) { inline void CollectionData::clear(ResourceManager* resources) {
for (auto slot = head_; slot; slot = slot->next()) for (auto slot = head_; slot; slot = slot->next())
slotRelease(slot, resources); slotRelease(slot, resources);
@ -111,14 +80,10 @@ inline bool CollectionData::copyFrom(const CollectionData& src,
clear(resources); clear(resources);
for (VariantSlot* s = src.head(); s; s = s->next()) { for (VariantSlot* s = src.head(); s; s = s->next()) {
VariantData* var; ARDUINOJSON_ASSERT(s->key() != 0);
if (s->key() != 0) { JsonString key(s->key(),
JsonString key(s->key(), s->ownsKey() ? JsonString::Copied : JsonString::Linked);
s->ownsKey() ? JsonString::Copied : JsonString::Linked); auto var = addMember(adaptString(key), resources);
var = addMember(adaptString(key), resources);
} else {
var = addElement(resources);
}
if (!variantCopyFrom(var, s->data(), resources)) if (!variantCopyFrom(var, s->data(), resources))
return false; return false;
} }
@ -138,12 +103,6 @@ inline VariantSlot* CollectionData::getSlot(TAdaptedString key) const {
return slot; return slot;
} }
inline VariantSlot* CollectionData::getSlot(size_t index) const {
if (!head_)
return 0;
return head_->next(index);
}
inline VariantSlot* CollectionData::getPreviousSlot(VariantSlot* target) const { inline VariantSlot* CollectionData::getPreviousSlot(VariantSlot* target) const {
VariantSlot* current = head_; VariantSlot* current = head_;
while (current) { while (current) {
@ -170,11 +129,6 @@ inline void CollectionData::removeSlot(VariantSlot* slot,
slotRelease(slot, resources); slotRelease(slot, resources);
} }
inline void CollectionData::removeElement(size_t index,
ResourceManager* resources) {
removeSlot(getSlot(index), resources);
}
template <typename TAdaptedString> template <typename TAdaptedString>
inline void CollectionData::removeMember(TAdaptedString key, inline void CollectionData::removeMember(TAdaptedString key,
ResourceManager* resources) { ResourceManager* resources) {
@ -211,31 +165,6 @@ inline void CollectionData::movePointers(ptrdiff_t variantDistance) {
slot->data()->movePointers(variantDistance); slot->data()->movePointers(variantDistance);
} }
inline bool arrayEquals(const CollectionData& lhs, const CollectionData& rhs) {
auto a = lhs.head();
auto b = rhs.head();
for (;;) {
if (!a && !b) // both ended
return true;
if (!a || !b) // one ended
return false;
if (compare(a->data(), b->data()) != COMPARE_RESULT_EQUAL)
return false;
a = a->next();
b = b->next();
}
}
inline bool arrayEquals(const CollectionData* lhs, const CollectionData* rhs) {
if (lhs == rhs)
return true;
if (!lhs || !rhs)
return false;
return arrayEquals(*lhs, *rhs);
}
inline bool objectEquals(const CollectionData& lhs, const CollectionData& rhs) { inline bool objectEquals(const CollectionData& lhs, const CollectionData& rhs) {
size_t count = 0; size_t count = 0;
for (auto a = lhs.head(); a; a = a->next()) { for (auto a = lhs.head(); a; a = a->next()) {

View File

@ -146,7 +146,7 @@ class JsonDeserializer {
template <typename TFilter> template <typename TFilter>
DeserializationError::Code parseArray( DeserializationError::Code parseArray(
CollectionData& array, TFilter filter, ArrayData& array, TFilter filter,
DeserializationOption::NestingLimit nestingLimit) { DeserializationOption::NestingLimit nestingLimit) {
DeserializationError::Code err; DeserializationError::Code err;
@ -172,7 +172,7 @@ class JsonDeserializer {
for (;;) { for (;;) {
if (elementFilter.allow()) { if (elementFilter.allow()) {
// Allocate slot in array // Allocate slot in array
VariantData* value = collectionAddElement(&array, resources_); VariantData* value = array.addElement(resources_);
if (!value) if (!value)
return DeserializationError::NoMemory; return DeserializationError::NoMemory;

View File

@ -18,7 +18,7 @@ class JsonSerializer : public Visitor<size_t> {
JsonSerializer(TWriter writer) : formatter_(writer) {} JsonSerializer(TWriter writer) : formatter_(writer) {}
FORCE_INLINE size_t visitArray(const CollectionData& array) { FORCE_INLINE size_t visitArray(const ArrayData& array) {
write('['); write('[');
const VariantSlot* slot = array.head(); const VariantSlot* slot = array.head();

View File

@ -18,7 +18,7 @@ class PrettyJsonSerializer : public JsonSerializer<TWriter> {
public: public:
PrettyJsonSerializer(TWriter writer) : base(writer), nesting_(0) {} PrettyJsonSerializer(TWriter writer) : base(writer), nesting_(0) {}
size_t visitArray(const CollectionData& array) { size_t visitArray(const ArrayData& array) {
const VariantSlot* slot = array.head(); const VariantSlot* slot = array.head();
if (slot) { if (slot) {
base::write("[\r\n"); base::write("[\r\n");

View File

@ -419,7 +419,7 @@ class MsgPackDeserializer {
bool allowArray = filter.allowArray(); bool allowArray = filter.allowArray();
CollectionData* array; ArrayData* array;
if (allowArray) { if (allowArray) {
ARDUINOJSON_ASSERT(variant != 0); ARDUINOJSON_ASSERT(variant != 0);
array = &variant->toArray(); array = &variant->toArray();
@ -434,7 +434,7 @@ class MsgPackDeserializer {
if (elementFilter.allow()) { if (elementFilter.allow()) {
ARDUINOJSON_ASSERT(array != 0); ARDUINOJSON_ASSERT(array != 0);
value = collectionAddElement(array, resources_); value = array->addElement(resources_);
if (!value) if (!value)
return DeserializationError::NoMemory; return DeserializationError::NoMemory;
} else { } else {

View File

@ -44,7 +44,7 @@ class MsgPackSerializer : public Visitor<size_t> {
return bytesWritten(); return bytesWritten();
} }
size_t visitArray(const CollectionData& array) { size_t visitArray(const ArrayData& array) {
size_t n = array.size(); size_t n = array.size();
if (n < 0x10) { if (n < 0x10) {
writeByte(uint8_t(0x90 + array.size())); writeByte(uint8_t(0x90 + array.size()));

View File

@ -79,12 +79,12 @@ struct Comparer<decltype(nullptr), void> : NullComparer {
}; };
struct ArrayComparer : ComparerBase { struct ArrayComparer : ComparerBase {
const CollectionData* rhs_; const ArrayData* rhs_;
explicit ArrayComparer(const CollectionData& rhs) : rhs_(&rhs) {} explicit ArrayComparer(const ArrayData& rhs) : rhs_(&rhs) {}
CompareResult visitArray(const CollectionData& lhs) { CompareResult visitArray(const ArrayData& lhs) {
if (arrayEquals(lhs, *rhs_)) if (rhs_->equals(lhs))
return COMPARE_RESULT_EQUAL; return COMPARE_RESULT_EQUAL;
else else
return COMPARE_RESULT_DIFFER; return COMPARE_RESULT_DIFFER;
@ -128,7 +128,7 @@ struct VariantComparer : ComparerBase {
explicit VariantComparer(const VariantData* value) : rhs(value) {} explicit VariantComparer(const VariantData* value) : rhs(value) {}
CompareResult visitArray(const CollectionData& lhs) { CompareResult visitArray(const ArrayData& lhs) {
ArrayComparer comparer(lhs); ArrayComparer comparer(lhs);
return accept(comparer); return accept(comparer);
} }

View File

@ -6,10 +6,12 @@
#include <stddef.h> // size_t #include <stddef.h> // size_t
#include <ArduinoJson/Array/ArrayData.hpp>
#include <ArduinoJson/Collection/CollectionData.hpp> #include <ArduinoJson/Collection/CollectionData.hpp>
#include <ArduinoJson/Numbers/JsonFloat.hpp> #include <ArduinoJson/Numbers/JsonFloat.hpp>
#include <ArduinoJson/Numbers/JsonInteger.hpp> #include <ArduinoJson/Numbers/JsonInteger.hpp>
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
enum { enum {
@ -45,6 +47,7 @@ union VariantContent {
JsonUInt asUnsignedInteger; JsonUInt asUnsignedInteger;
JsonInteger asSignedInteger; JsonInteger asSignedInteger;
CollectionData asCollection; CollectionData asCollection;
ArrayData asArray;
const char* asLinkedString; const char* asLinkedString;
struct StringNode* asOwnedString; struct StringNode* asOwnedString;
}; };

View File

@ -14,12 +14,8 @@
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
VariantData* collectionAddElement(CollectionData* array,
ResourceManager* resources);
bool collectionCopy(CollectionData* dst, const CollectionData* src, bool collectionCopy(CollectionData* dst, const CollectionData* src,
ResourceManager* resources); ResourceManager* resources);
void collectionRemoveElement(CollectionData* data, size_t index,
ResourceManager* resources);
template <typename T> template <typename T>
T parseNumber(const char* s); T parseNumber(const char* s);
void slotRelease(VariantSlot* slot, ResourceManager* resources); void slotRelease(VariantSlot* slot, ResourceManager* resources);
@ -38,7 +34,7 @@ class VariantData {
return visitor.visitFloat(content_.asFloat); return visitor.visitFloat(content_.asFloat);
case VALUE_IS_ARRAY: case VALUE_IS_ARRAY:
return visitor.visitArray(content_.asCollection); return visitor.visitArray(content_.asArray);
case VALUE_IS_OBJECT: case VALUE_IS_OBJECT:
return visitor.visitObject(content_.asCollection); return visitor.visitObject(content_.asCollection);
@ -71,7 +67,7 @@ class VariantData {
VariantData* addElement(ResourceManager* resources) { VariantData* addElement(ResourceManager* resources) {
auto array = isNull() ? &toArray() : asArray(); auto array = isNull() ? &toArray() : asArray();
return collectionAddElement(array, resources); return detail::ArrayData::addElement(array, resources);
} }
bool asBoolean() const { bool asBoolean() const {
@ -90,11 +86,11 @@ class VariantData {
} }
} }
CollectionData* asArray() { ArrayData* asArray() {
return isArray() ? &content_.asCollection : 0; return isArray() ? &content_.asArray : 0;
} }
const CollectionData* asArray() const { const ArrayData* asArray() const {
return const_cast<VariantData*>(this)->asArray(); return const_cast<VariantData*>(this)->asArray();
} }
@ -181,7 +177,7 @@ class VariantData {
} }
switch (src->type()) { switch (src->type()) {
case VALUE_IS_ARRAY: case VALUE_IS_ARRAY:
return collectionCopy(&toArray(), src->asArray(), resources); return toArray().copyFrom(*src->asArray(), resources);
case VALUE_IS_OBJECT: case VALUE_IS_OBJECT:
return collectionCopy(&toObject(), src->asObject(), resources); return collectionCopy(&toObject(), src->asObject(), resources);
case VALUE_IS_OWNED_STRING: { case VALUE_IS_OWNED_STRING: {
@ -319,7 +315,7 @@ class VariantData {
} }
void removeElement(size_t index, ResourceManager* resources) { void removeElement(size_t index, ResourceManager* resources) {
collectionRemoveElement(asArray(), index, resources); ArrayData::removeElement(asArray(), index, resources);
} }
template <typename TAdaptedString> template <typename TAdaptedString>
@ -427,13 +423,13 @@ class VariantData {
return isCollection() ? content_.asCollection.size() : 0; return isCollection() ? content_.asCollection.size() : 0;
} }
CollectionData& toArray() { ArrayData& toArray() {
setType(VALUE_IS_ARRAY); setType(VALUE_IS_ARRAY);
new (&content_.asCollection) CollectionData(); new (&content_.asArray) ArrayData();
return content_.asCollection; return content_.asArray;
} }
CollectionData& toArray(ResourceManager* resources) { ArrayData& toArray(ResourceManager* resources) {
release(resources); release(resources);
return toArray(); return toArray();
} }
@ -594,8 +590,7 @@ inline size_t variantSize(const VariantData* var) {
return var != 0 ? var->size() : 0; return var != 0 ? var->size() : 0;
} }
inline CollectionData* variantToArray(VariantData* var, inline ArrayData* variantToArray(VariantData* var, ResourceManager* resources) {
ResourceManager* resources) {
if (!var) if (!var)
return 0; return 0;
return &var->toArray(resources); return &var->toArray(resources);

View File

@ -14,7 +14,7 @@ template <typename TResult>
struct Visitor { struct Visitor {
typedef TResult result_type; typedef TResult result_type;
TResult visitArray(const CollectionData&) { TResult visitArray(const ArrayData&) {
return TResult(); return TResult();
} }