12 ValueArrayAllocator::~ValueArrayAllocator()
19 #ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
23 virtual ~DefaultValueArrayAllocator()
27 virtual ValueInternalArray *
newArray()
29 return new ValueInternalArray();
32 virtual ValueInternalArray *
newArrayCopy(
const ValueInternalArray &other )
34 return new ValueInternalArray( other );
43 ValueInternalArray::PageIndex &indexCount,
44 ValueInternalArray::PageIndex minNewIndexCount )
46 ValueInternalArray::PageIndex newIndexCount = (indexCount*3)/2 + 1;
47 if ( minNewIndexCount > newIndexCount )
48 newIndexCount = minNewIndexCount;
49 void *newIndexes = realloc( indexes,
sizeof(Value*) * newIndexCount );
51 throw std::bad_alloc();
52 indexCount = newIndexCount;
53 indexes =
static_cast<Value **
>( newIndexes );
56 ValueInternalArray::PageIndex indexCount )
64 return static_cast<Value *
>( malloc(
sizeof(Value) * ValueInternalArray::itemsPerPage ) );
76 class DefaultValueArrayAllocator : public ValueArrayAllocator
79 virtual ~DefaultValueArrayAllocator()
83 virtual ValueInternalArray *newArray()
85 ValueInternalArray *array = arraysAllocator_.allocate();
86 new (array) ValueInternalArray();
90 virtual ValueInternalArray *newArrayCopy(
const ValueInternalArray &other )
92 ValueInternalArray *array = arraysAllocator_.allocate();
93 new (array) ValueInternalArray( other );
97 virtual void destructArray( ValueInternalArray *array )
101 array->~ValueInternalArray();
102 arraysAllocator_.release( array );
106 virtual void reallocateArrayPageIndex( Value **&indexes,
107 ValueInternalArray::PageIndex &indexCount,
108 ValueInternalArray::PageIndex minNewIndexCount )
110 ValueInternalArray::PageIndex newIndexCount = (indexCount*3)/2 + 1;
111 if ( minNewIndexCount > newIndexCount )
112 newIndexCount = minNewIndexCount;
113 void *newIndexes = realloc( indexes,
sizeof(Value*) * newIndexCount );
115 throw std::bad_alloc();
116 indexCount = newIndexCount;
117 indexes =
static_cast<Value **
>( newIndexes );
119 virtual void releaseArrayPageIndex( Value **indexes,
120 ValueInternalArray::PageIndex indexCount )
126 virtual Value *allocateArrayPage()
128 return static_cast<Value *
>( pagesAllocator_.allocate() );
131 virtual void releaseArrayPage( Value *value )
134 pagesAllocator_.release( value );
137 BatchAllocator<ValueInternalArray,1> arraysAllocator_;
138 BatchAllocator<Value,ValueInternalArray::itemsPerPage> pagesAllocator_;
144 static DefaultValueArrayAllocator defaultAllocator;
149 static struct DummyArrayAllocatorInitializer {
150 DummyArrayAllocatorInitializer()
160 ValueInternalArray::equals(
const IteratorState &x,
161 const IteratorState &other )
163 return x.array_ == other.array_
164 && x.currentItemIndex_ == other.currentItemIndex_
165 && x.currentPageIndex_ == other.currentPageIndex_;
170 ValueInternalArray::increment( IteratorState &it )
173 (it.currentPageIndex_ - it.array_->pages_)*itemsPerPage + it.currentItemIndex_
175 "ValueInternalArray::increment(): moving iterator beyond end" );
176 ++(it.currentItemIndex_);
177 if ( it.currentItemIndex_ == itemsPerPage )
179 it.currentItemIndex_ = 0;
180 ++(it.currentPageIndex_);
186 ValueInternalArray::decrement( IteratorState &it )
189 && it.currentItemIndex_ == 0,
190 "ValueInternalArray::decrement(): moving iterator beyond end" );
191 if ( it.currentItemIndex_ == 0 )
193 it.currentItemIndex_ = itemsPerPage-1;
194 --(it.currentPageIndex_);
198 --(it.currentItemIndex_);
204 ValueInternalArray::unsafeDereference(
const IteratorState &it )
206 return (*(it.currentPageIndex_))[it.currentItemIndex_];
211 ValueInternalArray::dereference(
const IteratorState &it )
214 (it.currentPageIndex_ - it.array_->pages_)*itemsPerPage + it.currentItemIndex_
216 "ValueInternalArray::dereference(): dereferencing invalid iterator" );
217 return unsafeDereference( it );
221 ValueInternalArray::makeBeginIterator( IteratorState &it )
const
223 it.array_ =
const_cast<ValueInternalArray *
>( this );
224 it.currentItemIndex_ = 0;
225 it.currentPageIndex_ = pages_;
230 ValueInternalArray::makeIterator( IteratorState &it, ArrayIndex index )
const
232 it.array_ =
const_cast<ValueInternalArray *
>( this );
233 it.currentItemIndex_ = index % itemsPerPage;
234 it.currentPageIndex_ = pages_ + index / itemsPerPage;
239 ValueInternalArray::makeEndIterator( IteratorState &it )
const
241 makeIterator( it, size_ );
245 ValueInternalArray::ValueInternalArray()
256 , size_( other.size_ )
259 arrayAllocator()->reallocateArrayPageIndex( pages_, pageCount_, minNewPages );
261 "ValueInternalArray::reserve(): bad reallocation" );
262 IteratorState itOther;
263 other.makeBeginIterator( itOther );
265 for (
ArrayIndex index = 0; index < size_; ++index, increment(itOther) )
271 pages_[pageIndex] = value;
273 new (value)
Value( dereference( itOther ) );
292 makeBeginIterator( it);
293 makeEndIterator( itEnd );
294 for ( ; !equals(it,itEnd); increment(it) )
296 Value *value = &dereference(it);
301 for (
PageIndex pageIndex = 0; pageIndex < lastPageIndex; ++pageIndex )
311 Value **tempPages = pages_;
312 pages_ = other.pages_;
313 other.pages_ = tempPages;
316 other.size_ = tempSize;
318 pageCount_ = other.pageCount_;
319 other.pageCount_ = tempPageCount;
335 else if ( newSize < size_ )
339 makeIterator( it, newSize );
340 makeIterator( itEnd, size_ );
341 for ( ; !equals(it,itEnd); increment(it) )
343 Value *value = &dereference(it);
348 for ( ; pageIndex < lastPageIndex; ++pageIndex )
352 else if ( newSize > size_ )
358 ValueInternalArray::makeIndexValid( ArrayIndex index )
364 arrayAllocator()->reallocateArrayPageIndex( pages_, pageCount_, minNewPages );
365 JSON_ASSERT_MESSAGE( pageCount_ >= minNewPages,
"ValueInternalArray::reserve(): bad reallocation" );
372 if ( nextPageIndex <= index )
376 for ( ; pageToAllocate-- > 0; ++pageIndex )
383 makeIterator( it, size_ );
385 makeIterator( itEnd, size_ );
386 for ( ; !equals(it,itEnd); increment(it) )
388 Value *value = &dereference(it);
396 if ( index >= size_ )
397 makeIndexValid( index );
404 if ( index >= size_ )
416 ValueInternalArray::distance(
const IteratorState &x,
const IteratorState &y )
418 return indexOf(y) - indexOf(x);
423 ValueInternalArray::indexOf(
const IteratorState &iterator )
425 if ( !iterator.array_ )
428 (iterator.currentPageIndex_ - iterator.array_->pages_) *
itemsPerPage
429 + iterator.currentItemIndex_ );
436 int sizeDiff( size_ - other.size_ );
440 for (
ArrayIndex index =0; index < size_; ++index )
Experimental: do not use.
virtual Value * allocateArrayPage()=0
virtual void destructArray(ValueInternalArray *array)=0
virtual void releaseArrayPageIndex(Value **indexes, ValueInternalArray::PageIndex indexCount)=0
virtual ValueInternalArray * newArray()=0
virtual ValueInternalArray * newArrayCopy(const ValueInternalArray &other)=0
virtual void releaseArrayPage(Value *value)=0
virtual void reallocateArrayPageIndex(Value **&indexes, ValueInternalArray::PageIndex &indexCount, ValueInternalArray::PageIndex minNewIndexCount)=0
Reallocate array page index.
int compare(const Value &other)
A simplified deque implementation used internally by Value.
Value::ArrayIndex ArrayIndex
void swap(ValueInternalArray &other)
Value * find(ArrayIndex index) const
Value & resolveReference(ArrayIndex index)
int compare(const ValueInternalArray &other) const
ValueInternalArray & operator=(const ValueInternalArray &other)
void resize(ArrayIndex newSize)
static struct DummyArrayAllocatorInitializer dummyArrayAllocatorInitializer
static ValueArrayAllocator *& arrayAllocator()
#define JSON_ASSERT_MESSAGE(condition, message)