25 #ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
29 virtual ~DefaultValueArrayAllocator()
33 virtual ValueInternalArray *newArray()
35 return new ValueInternalArray();
38 virtual ValueInternalArray *newArrayCopy(
const ValueInternalArray &other )
40 return new ValueInternalArray( other );
43 virtual void destructArray( ValueInternalArray *array )
48 virtual void reallocateArrayPageIndex( Value **&indexes,
53 if ( minNewIndexCount > newIndexCount )
54 newIndexCount = minNewIndexCount;
55 void *newIndexes = realloc( indexes,
sizeof(Value*) * newIndexCount );
57 throw std::bad_alloc();
58 indexCount = newIndexCount;
59 indexes =
static_cast<Value **
>( newIndexes );
61 virtual void releaseArrayPageIndex( Value **indexes,
68 virtual Value *allocateArrayPage()
73 virtual void releaseArrayPage( Value *value )
80 #else // #ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
81 class DefaultValueArrayAllocator :
public ValueArrayAllocator
85 virtual ~DefaultValueArrayAllocator()
89 virtual ValueInternalArray *newArray()
91 ValueInternalArray *array = arraysAllocator_.allocate();
92 new (array) ValueInternalArray();
96 virtual ValueInternalArray *newArrayCopy(
const ValueInternalArray &other )
98 ValueInternalArray *array = arraysAllocator_.allocate();
99 new (array) ValueInternalArray( other );
103 virtual void destructArray( ValueInternalArray *array )
107 array->~ValueInternalArray();
108 arraysAllocator_.release( array );
112 virtual void reallocateArrayPageIndex( Value **&indexes,
117 if ( minNewIndexCount > newIndexCount )
118 newIndexCount = minNewIndexCount;
119 void *newIndexes = realloc( indexes,
sizeof(Value*) * newIndexCount );
121 throw std::bad_alloc();
122 indexCount = newIndexCount;
123 indexes =
static_cast<Value **
>( newIndexes );
125 virtual void releaseArrayPageIndex( Value **indexes,
132 virtual Value *allocateArrayPage()
134 return static_cast<Value *
>( pagesAllocator_.allocate() );
137 virtual void releaseArrayPage( Value *value )
140 pagesAllocator_.release( value );
143 BatchAllocator<ValueInternalArray,1> arraysAllocator_;
144 BatchAllocator<Value,ValueInternalArray::itemsPerPage> pagesAllocator_;
146 #endif // #ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
150 static DefaultValueArrayAllocator defaultAllocator;
155 static struct DummyArrayAllocatorInitializer {
156 DummyArrayAllocatorInitializer()
166 ValueInternalArray::equals(
const IteratorState &x,
167 const IteratorState &other )
169 return x.array_ == other.array_
170 && x.currentItemIndex_ == other.currentItemIndex_
171 && x.currentPageIndex_ == other.currentPageIndex_;
176 ValueInternalArray::increment( IteratorState &it )
179 (it.currentPageIndex_ - it.array_->pages_)*
itemsPerPage + it.currentItemIndex_
181 "ValueInternalArray::increment(): moving iterator beyond end" );
182 ++(it.currentItemIndex_);
185 it.currentItemIndex_ = 0;
186 ++(it.currentPageIndex_);
192 ValueInternalArray::decrement( IteratorState &it )
195 && it.currentItemIndex_ == 0,
196 "ValueInternalArray::decrement(): moving iterator beyond end" );
197 if ( it.currentItemIndex_ == 0 )
200 --(it.currentPageIndex_);
204 --(it.currentItemIndex_);
210 ValueInternalArray::unsafeDereference(
const IteratorState &it )
212 return (*(it.currentPageIndex_))[it.currentItemIndex_];
217 ValueInternalArray::dereference(
const IteratorState &it )
220 (it.currentPageIndex_ - it.array_->pages_)*
itemsPerPage + it.currentItemIndex_
222 "ValueInternalArray::dereference(): dereferencing invalid iterator" );
223 return unsafeDereference( it );
227 ValueInternalArray::makeBeginIterator( IteratorState &it )
const
230 it.currentItemIndex_ = 0;
231 it.currentPageIndex_ = pages_;
236 ValueInternalArray::makeIterator( IteratorState &it,
ArrayIndex index )
const
245 ValueInternalArray::makeEndIterator( IteratorState &it )
const
247 makeIterator( it, size_ );
262 , size_( other.size_ )
267 "ValueInternalArray::reserve(): bad reallocation" );
268 IteratorState itOther;
269 other.makeBeginIterator( itOther );
271 for (
ArrayIndex index = 0; index < size_; ++index, increment(itOther) )
277 pages_[pageIndex] = value;
279 new (value)
Value( dereference( itOther ) );
298 makeBeginIterator( it);
299 makeEndIterator( itEnd );
300 for ( ; !equals(it,itEnd); increment(it) )
302 Value *value = &dereference(it);
307 for (
PageIndex pageIndex = 0; pageIndex < lastPageIndex; ++pageIndex )
317 Value **tempPages = pages_;
318 pages_ = other.pages_;
319 other.pages_ = tempPages;
322 other.size_ = tempSize;
324 pageCount_ = other.pageCount_;
325 other.pageCount_ = tempPageCount;
341 else if ( newSize < size_ )
345 makeIterator( it, newSize );
346 makeIterator( itEnd, size_ );
347 for ( ; !equals(it,itEnd); increment(it) )
349 Value *value = &dereference(it);
354 for ( ; pageIndex < lastPageIndex; ++pageIndex )
358 else if ( newSize > size_ )
364 ValueInternalArray::makeIndexValid(
ArrayIndex index )
369 PageIndex minNewPages = (index + 1) / itemsPerPage;
371 JSON_ASSERT_MESSAGE( pageCount_ >= minNewPages,
"ValueInternalArray::reserve(): bad reallocation" );
376 (size_ %
itemsPerPage) != 0 ? size_ - (size_%itemsPerPage) + itemsPerPage
378 if ( nextPageIndex <= index )
381 PageIndex pageToAllocate = (index - nextPageIndex) / itemsPerPage + 1;
382 for ( ; pageToAllocate-- > 0; ++pageIndex )
389 makeIterator( it, size_ );
391 makeIterator( itEnd, size_ );
392 for ( ; !equals(it,itEnd); increment(it) )
394 Value *value = &dereference(it);
402 if ( index >= size_ )
403 makeIndexValid( index );
410 if ( index >= size_ )
422 ValueInternalArray::distance(
const IteratorState &x,
const IteratorState &y )
424 return indexOf(y) - indexOf(x);
429 ValueInternalArray::indexOf(
const IteratorState &iterator )
431 if ( !iterator.array_ )
434 (iterator.currentPageIndex_ - iterator.array_->pages_) * itemsPerPage
435 + iterator.currentItemIndex_ );
442 int sizeDiff( size_ - other.size_ );
446 for (
ArrayIndex index =0; index < size_; ++index )
449 other.pages_[index/itemsPerPage][index%itemsPerPage] );
Experimental: do not use.
int compare(const ValueInternalArray &other) const
Value & resolveReference(ArrayIndex index)
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()
ValueInternalArray & operator=(const ValueInternalArray &other)
#define JSON_ASSERT_MESSAGE(condition, message)
void resize(ArrayIndex newSize)
JSON (JavaScript Object Notation).
Value * find(ArrayIndex index) const
A simplified deque implementation used internally by Value.
virtual Value * allocateArrayPage()=0
virtual void releaseArrayPage(Value *value)=0
virtual void releaseArrayPageIndex(Value **indexes, ValueInternalArray::PageIndex indexCount)=0