25 #ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR 29 virtual ~DefaultValueArrayAllocator()
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 );
80 #else // #ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR 85 virtual ~DefaultValueArrayAllocator()
108 arraysAllocator_.release( array );
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 );
134 return static_cast<Value *
>( pagesAllocator_.allocate() );
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_);
183 if ( it.currentItemIndex_ == itemsPerPage )
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 )
199 it.currentItemIndex_ = itemsPerPage-1;
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 239 it.currentItemIndex_ = index % itemsPerPage;
240 it.currentPageIndex_ = pages_ + index / itemsPerPage;
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" );
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 )
Experimental: do not use.
int compare(const Value &other) const
Value & resolveReference(ArrayIndex index)
virtual void reallocateArrayPageIndex(Value **&indexes, ValueInternalArray::PageIndex &indexCount, ValueInternalArray::PageIndex minNewIndexCount)=0
Reallocate array page index.
static struct Json::DummyArrayAllocatorInitializer dummyArrayAllocatorInitializer
Value::ArrayIndex ArrayIndex
Value * find(ArrayIndex index) const
static ValueArrayAllocator *& arrayAllocator()
void swap(ValueInternalArray &other)
virtual void destructArray(ValueInternalArray *array)=0
virtual ~ValueArrayAllocator()
ValueInternalArray & operator=(const ValueInternalArray &other)
virtual ValueInternalArray * newArray()=0
int compare(const ValueInternalArray &other) const
#define JSON_ASSERT_MESSAGE(condition, message)
virtual ValueInternalArray * newArrayCopy(const ValueInternalArray &other)=0
void resize(ArrayIndex newSize)
JSON (JavaScript Object Notation).
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