23 #ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
26 virtual ~DefaultValueArrayAllocator() {}
28 virtual ValueInternalArray* newArray() {
return new ValueInternalArray(); }
30 virtual ValueInternalArray* newArrayCopy(
const ValueInternalArray& other) {
31 return new ValueInternalArray(other);
34 virtual void destructArray(ValueInternalArray* array) {
delete array; }
37 reallocateArrayPageIndex(Value**& indexes,
41 if (minNewIndexCount > newIndexCount)
42 newIndexCount = minNewIndexCount;
43 void* newIndexes = realloc(indexes,
sizeof(Value*) * newIndexCount);
45 indexCount = newIndexCount;
46 indexes =
static_cast<Value**
>(newIndexes);
48 virtual void releaseArrayPageIndex(Value** indexes,
54 virtual Value* allocateArrayPage() {
55 return static_cast<Value*
>(
59 virtual void releaseArrayPage(Value* value) {
65 #else // #ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
66 class DefaultValueArrayAllocator :
public ValueArrayAllocator {
69 virtual ~DefaultValueArrayAllocator() {}
71 virtual ValueInternalArray* newArray() {
72 ValueInternalArray* array = arraysAllocator_.allocate();
73 new (array) ValueInternalArray();
77 virtual ValueInternalArray* newArrayCopy(
const ValueInternalArray& other) {
78 ValueInternalArray* array = arraysAllocator_.allocate();
79 new (array) ValueInternalArray(other);
83 virtual void destructArray(ValueInternalArray* array) {
85 array->~ValueInternalArray();
86 arraysAllocator_.release(array);
91 reallocateArrayPageIndex(Value**& indexes,
95 if (minNewIndexCount > newIndexCount)
96 newIndexCount = minNewIndexCount;
97 void* newIndexes = realloc(indexes,
sizeof(Value*) * newIndexCount);
99 indexCount = newIndexCount;
100 indexes =
static_cast<Value**
>(newIndexes);
102 virtual void releaseArrayPageIndex(Value** indexes,
108 virtual Value* allocateArrayPage() {
109 return static_cast<Value*
>(pagesAllocator_.allocate());
112 virtual void releaseArrayPage(Value* value) {
114 pagesAllocator_.release(value);
118 BatchAllocator<ValueInternalArray, 1> arraysAllocator_;
119 BatchAllocator<Value, ValueInternalArray::itemsPerPage> pagesAllocator_;
121 #endif // #ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
124 static DefaultValueArrayAllocator defaultAllocator;
129 static struct DummyArrayAllocatorInitializer {
130 DummyArrayAllocatorInitializer() {
139 bool ValueInternalArray::equals(
const IteratorState& x,
140 const IteratorState& other) {
141 return x.array_ == other.array_ &&
142 x.currentItemIndex_ == other.currentItemIndex_ &&
143 x.currentPageIndex_ == other.currentPageIndex_;
146 void ValueInternalArray::increment(IteratorState& it) {
148 it.array_ && (it.currentPageIndex_ - it.array_->pages_) *
itemsPerPage +
149 it.currentItemIndex_ !=
151 "ValueInternalArray::increment(): moving iterator beyond end");
152 ++(it.currentItemIndex_);
154 it.currentItemIndex_ = 0;
155 ++(it.currentPageIndex_);
159 void ValueInternalArray::decrement(IteratorState& it) {
161 it.array_ && it.currentPageIndex_ == it.array_->pages_ &&
162 it.currentItemIndex_ == 0,
163 "ValueInternalArray::decrement(): moving iterator beyond end");
164 if (it.currentItemIndex_ == 0) {
166 --(it.currentPageIndex_);
168 --(it.currentItemIndex_);
172 Value& ValueInternalArray::unsafeDereference(
const IteratorState& it) {
173 return (*(it.currentPageIndex_))[it.currentItemIndex_];
176 Value& ValueInternalArray::dereference(
const IteratorState& it) {
178 it.array_ && (it.currentPageIndex_ - it.array_->pages_) *
itemsPerPage +
179 it.currentItemIndex_ <
181 "ValueInternalArray::dereference(): dereferencing invalid iterator");
182 return unsafeDereference(it);
185 void ValueInternalArray::makeBeginIterator(IteratorState& it)
const {
187 it.currentItemIndex_ = 0;
188 it.currentPageIndex_ = pages_;
191 void ValueInternalArray::makeIterator(IteratorState& it,
198 void ValueInternalArray::makeEndIterator(IteratorState& it)
const {
199 makeIterator(it, size_);
205 : pages_(0), size_(other.size_), pageCount_(0) {
209 "ValueInternalArray::reserve(): bad reallocation");
210 IteratorState itOther;
211 other.makeBeginIterator(itOther);
213 for (
ArrayIndex index = 0; index < size_; ++index, increment(itOther)) {
217 pages_[pageIndex] = value;
219 new (value)
Value(dereference(itOther));
232 makeBeginIterator(it);
233 makeEndIterator(itEnd);
234 for (; !equals(it, itEnd); increment(it)) {
235 Value* value = &dereference(it);
240 for (
PageIndex pageIndex = 0; pageIndex < lastPageIndex; ++pageIndex)
247 Value** tempPages = pages_;
248 pages_ = other.pages_;
249 other.pages_ = tempPages;
252 other.size_ = tempSize;
254 pageCount_ = other.pageCount_;
255 other.pageCount_ = tempPageCount;
266 else if (newSize < size_) {
269 makeIterator(it, newSize);
270 makeIterator(itEnd, size_);
271 for (; !equals(it, itEnd); increment(it)) {
272 Value* value = &dereference(it);
277 for (; pageIndex < lastPageIndex; ++pageIndex)
280 }
else if (newSize > size_)
284 void ValueInternalArray::makeIndexValid(
ArrayIndex index) {
287 PageIndex minNewPages = (index + 1) / itemsPerPage;
290 "ValueInternalArray::reserve(): bad reallocation");
295 ? size_ - (size_ % itemsPerPage) + itemsPerPage
297 if (nextPageIndex <= index) {
299 PageIndex pageToAllocate = (index - nextPageIndex) / itemsPerPage + 1;
300 for (; pageToAllocate-- > 0; ++pageIndex)
307 makeIterator(it, size_);
309 makeIterator(itEnd, size_);
310 for (; !equals(it, itEnd); increment(it)) {
311 Value* value = &dereference(it);
318 makeIndexValid(index);
332 int ValueInternalArray::distance(
const IteratorState& x,
333 const IteratorState& y) {
334 return indexOf(y) - indexOf(x);
338 ValueInternalArray::indexOf(
const IteratorState& iterator) {
339 if (!iterator.array_)
341 return ArrayIndex((iterator.currentPageIndex_ - iterator.array_->pages_) *
343 iterator.currentItemIndex_);
347 int sizeDiff(size_ - other.size_);
351 for (
ArrayIndex index = 0; index < size_; ++index) {
353 other.pages_[index / itemsPerPage][index % itemsPerPage]);
Experimental: do not use.
int compare(const ValueInternalArray &other) const
Value & resolveReference(ArrayIndex index)
#define JSON_ASSERT_MESSAGE(condition, message)
virtual void reallocateArrayPageIndex(Value **&indexes, ValueInternalArray::PageIndex &indexCount, ValueInternalArray::PageIndex minNewIndexCount)=0
Reallocate array page index.
int compare(const Value &other) const
static struct Json::DummyArrayAllocatorInitializer dummyArrayAllocatorInitializer
Value::ArrayIndex ArrayIndex
static ValueArrayAllocator *& arrayAllocator()
void swap(ValueInternalArray &other)
virtual ~ValueArrayAllocator()
void resize(ArrayIndex newSize)
Value * find(ArrayIndex index) const
A simplified deque implementation used internally by Value.
ValueInternalArray & operator=(ValueInternalArray other)
virtual Value * allocateArrayPage()=0
virtual void releaseArrayPage(Value *value)=0
virtual void releaseArrayPageIndex(Value **indexes, ValueInternalArray::PageIndex indexCount)=0