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 ) );
74 #else // #ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
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_;
140 #endif // #ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
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_ )
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 )
363 PageIndex minNewPages = (index + 1) / itemsPerPage;
365 JSON_ASSERT_MESSAGE( pageCount_ >= minNewPages,
"ValueInternalArray::reserve(): bad reallocation" );
370 (size_ %
itemsPerPage) != 0 ? size_ - (size_%itemsPerPage) + itemsPerPage
372 if ( nextPageIndex <= index )
375 PageIndex pageToAllocate = (index - nextPageIndex) / itemsPerPage + 1;
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 )
443 other.pages_[index/itemsPerPage][index%itemsPerPage] );