// included by json_value.cpp// everything is within Json namespace// //////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////// class ValueInternalArray// //////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////ValueArrayAllocator::~ValueArrayAllocator(){}// //////////////////////////////////////////////////////////////////// class DefaultValueArrayAllocator// //////////////////////////////////////////////////////////////////#ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATORclass DefaultValueArrayAllocator : public ValueArrayAllocator{public: // overridden from ValueArrayAllocatorvirtual ~DefaultValueArrayAllocator(){}virtual ValueInternalArray *newArray(){return new ValueInternalArray();}virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other ){return new ValueInternalArray( other );}virtual void destructArray( ValueInternalArray *array ){delete array;}virtual void reallocateArrayPageIndex( Value **&indexes,ValueInternalArray::PageIndex &indexCount,ValueInternalArray::PageIndex minNewIndexCount ){ValueInternalArray::PageIndex newIndexCount = (indexCount*3)/2 + 1;if ( minNewIndexCount > newIndexCount )newIndexCount = minNewIndexCount;void *newIndexes = realloc( indexes, sizeof(Value*) * newIndexCount );if ( !newIndexes )throw std::bad_alloc();indexCount = newIndexCount;indexes = static_cast<Value **>( newIndexes );}virtual void releaseArrayPageIndex( Value **indexes,ValueInternalArray::PageIndex indexCount ){if ( indexes )free( indexes );}virtual Value *allocateArrayPage(){return static_cast<Value *>( malloc( sizeof(Value) * ValueInternalArray::itemsPerPage ) );}virtual void releaseArrayPage( Value *value ){if ( value )free( value );}};#else // #ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR/// @todo make this thread-safe (lock when accessign batch allocator)class DefaultValueArrayAllocator : public ValueArrayAllocator{public: // overridden from ValueArrayAllocatorvirtual ~DefaultValueArrayAllocator(){}virtual ValueInternalArray *newArray(){ValueInternalArray *array = arraysAllocator_.allocate();new (array) ValueInternalArray(); // placement newreturn array;}virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other ){ValueInternalArray *array = arraysAllocator_.allocate();new (array) ValueInternalArray( other ); // placement newreturn array;}virtual void destructArray( ValueInternalArray *array ){if ( array ){array->~ValueInternalArray();arraysAllocator_.release( array );}}virtual void reallocateArrayPageIndex( Value **&indexes,ValueInternalArray::PageIndex &indexCount,ValueInternalArray::PageIndex minNewIndexCount ){ValueInternalArray::PageIndex newIndexCount = (indexCount*3)/2 + 1;if ( minNewIndexCount > newIndexCount )newIndexCount = minNewIndexCount;void *newIndexes = realloc( indexes, sizeof(Value*) * newIndexCount );if ( !newIndexes )throw std::bad_alloc();indexCount = newIndexCount;indexes = static_cast<Value **>( newIndexes );}virtual void releaseArrayPageIndex( Value **indexes,ValueInternalArray::PageIndex indexCount ){if ( indexes )free( indexes );}virtual Value *allocateArrayPage(){return static_cast<Value *>( pagesAllocator_.allocate() );}virtual void releaseArrayPage( Value *value ){if ( value )pagesAllocator_.release( value );}private:BatchAllocator<ValueInternalArray,1> arraysAllocator_;BatchAllocator<Value,ValueInternalArray::itemsPerPage> pagesAllocator_;};#endif // #ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATORstatic ValueArrayAllocator *&arrayAllocator(){static DefaultValueArrayAllocator defaultAllocator;static ValueArrayAllocator *arrayAllocator = &defaultAllocator;return arrayAllocator;}static struct DummyArrayAllocatorInitializer {DummyArrayAllocatorInitializer(){arrayAllocator(); // ensure arrayAllocator() statics are initialized before main().}} dummyArrayAllocatorInitializer;// //////////////////////////////////////////////////////////////////// class ValueInternalArray// //////////////////////////////////////////////////////////////////boolValueInternalArray::equals( const IteratorState &x,const IteratorState &other ){return x.array_ == other.array_&& x.currentItemIndex_ == other.currentItemIndex_&& x.currentPageIndex_ == other.currentPageIndex_;}voidValueInternalArray::increment( IteratorState &it ){JSON_ASSERT_MESSAGE( it.array_ &&(it.currentPageIndex_ - it.array_->pages_)*itemsPerPage + it.currentItemIndex_!= it.array_->size_,"ValueInternalArray::increment(): moving iterator beyond end" );++(it.currentItemIndex_);if ( it.currentItemIndex_ == itemsPerPage ){it.currentItemIndex_ = 0;++(it.currentPageIndex_);}}voidValueInternalArray::decrement( IteratorState &it ){JSON_ASSERT_MESSAGE( it.array_ && it.currentPageIndex_ == it.array_->pages_&& it.currentItemIndex_ == 0,"ValueInternalArray::decrement(): moving iterator beyond end" );if ( it.currentItemIndex_ == 0 ){it.currentItemIndex_ = itemsPerPage-1;--(it.currentPageIndex_);}else{--(it.currentItemIndex_);}}Value &ValueInternalArray::unsafeDereference( const IteratorState &it ){return (*(it.currentPageIndex_))[it.currentItemIndex_];}Value &ValueInternalArray::dereference( const IteratorState &it ){JSON_ASSERT_MESSAGE( it.array_ &&(it.currentPageIndex_ - it.array_->pages_)*itemsPerPage + it.currentItemIndex_< it.array_->size_,"ValueInternalArray::dereference(): dereferencing invalid iterator" );return unsafeDereference( it );}voidValueInternalArray::makeBeginIterator( IteratorState &it ) const{it.array_ = const_cast<ValueInternalArray *>( this );it.currentItemIndex_ = 0;it.currentPageIndex_ = pages_;}voidValueInternalArray::makeIterator( IteratorState &it, ArrayIndex index ) const{it.array_ = const_cast<ValueInternalArray *>( this );it.currentItemIndex_ = index % itemsPerPage;it.currentPageIndex_ = pages_ + index / itemsPerPage;}voidValueInternalArray::makeEndIterator( IteratorState &it ) const{makeIterator( it, size_ );}ValueInternalArray::ValueInternalArray(): pages_( 0 ), size_( 0 ), pageCount_( 0 ){}ValueInternalArray::ValueInternalArray( const ValueInternalArray &other ): pages_( 0 ), pageCount_( 0 ), size_( other.size_ ){PageIndex minNewPages = other.size_ / itemsPerPage;arrayAllocator()->reallocateArrayPageIndex( pages_, pageCount_, minNewPages );JSON_ASSERT_MESSAGE( pageCount_ >= minNewPages,"ValueInternalArray::reserve(): bad reallocation" );IteratorState itOther;other.makeBeginIterator( itOther );Value *value;for ( ArrayIndex index = 0; index < size_; ++index, increment(itOther) ){if ( index % itemsPerPage == 0 ){PageIndex pageIndex = index / itemsPerPage;value = arrayAllocator()->allocateArrayPage();pages_[pageIndex] = value;}new (value) Value( dereference( itOther ) );}}ValueInternalArray &ValueInternalArray::operator =( const ValueInternalArray &other ){ValueInternalArray temp( other );swap( temp );return *this;}ValueInternalArray::~ValueInternalArray(){// destroy all constructed itemsIteratorState it;IteratorState itEnd;makeBeginIterator( it);makeEndIterator( itEnd );for ( ; !equals(it,itEnd); increment(it) ){Value *value = &dereference(it);value->~Value();}// release all pagesPageIndex lastPageIndex = size_ / itemsPerPage;for ( PageIndex pageIndex = 0; pageIndex < lastPageIndex; ++pageIndex )arrayAllocator()->releaseArrayPage( pages_[pageIndex] );// release pages indexarrayAllocator()->releaseArrayPageIndex( pages_, pageCount_ );}voidValueInternalArray::swap( ValueInternalArray &other ){Value **tempPages = pages_;pages_ = other.pages_;other.pages_ = tempPages;ArrayIndex tempSize = size_;size_ = other.size_;other.size_ = tempSize;PageIndex tempPageCount = pageCount_;pageCount_ = other.pageCount_;other.pageCount_ = tempPageCount;}voidValueInternalArray::clear(){ValueInternalArray dummy;swap( dummy );}voidValueInternalArray::resize( ArrayIndex newSize ){if ( newSize == 0 )clear();else if ( newSize < size_ ){IteratorState it;IteratorState itEnd;makeIterator( it, newSize );makeIterator( itEnd, size_ );for ( ; !equals(it,itEnd); increment(it) ){Value *value = &dereference(it);value->~Value();}PageIndex pageIndex = (newSize + itemsPerPage - 1) / itemsPerPage;PageIndex lastPageIndex = size_ / itemsPerPage;for ( ; pageIndex < lastPageIndex; ++pageIndex )arrayAllocator()->releaseArrayPage( pages_[pageIndex] );size_ = newSize;}else if ( newSize > size_ )resolveReference( newSize );}voidValueInternalArray::makeIndexValid( ArrayIndex index ){// Need to enlarge page index ?if ( index >= pageCount_ * itemsPerPage ){PageIndex minNewPages = (index + 1) / itemsPerPage;arrayAllocator()->reallocateArrayPageIndex( pages_, pageCount_, minNewPages );JSON_ASSERT_MESSAGE( pageCount_ >= minNewPages, "ValueInternalArray::reserve(): bad reallocation" );}// Need to allocate new pages ?ArrayIndex nextPageIndex =(size_ % itemsPerPage) != 0 ? size_ - (size_%itemsPerPage) + itemsPerPage: size_;if ( nextPageIndex <= index ){PageIndex pageIndex = nextPageIndex / itemsPerPage;PageIndex pageToAllocate = (index - nextPageIndex) / itemsPerPage + 1;for ( ; pageToAllocate-- > 0; ++pageIndex )pages_[pageIndex] = arrayAllocator()->allocateArrayPage();}// Initialize all new entriesIteratorState it;IteratorState itEnd;makeIterator( it, size_ );size_ = index + 1;makeIterator( itEnd, size_ );for ( ; !equals(it,itEnd); increment(it) ){Value *value = &dereference(it);new (value) Value(); // Construct a default value using placement new}}Value &ValueInternalArray::resolveReference( ArrayIndex index ){if ( index >= size_ )makeIndexValid( index );return pages_[index/itemsPerPage][index%itemsPerPage];}Value *ValueInternalArray::find( ArrayIndex index ) const{if ( index >= size_ )return 0;return &(pages_[index/itemsPerPage][index%itemsPerPage]);}ValueInternalArray::ArrayIndexValueInternalArray::size() const{return size_;}intValueInternalArray::distance( const IteratorState &x, const IteratorState &y ){return indexOf(y) - indexOf(x);}ValueInternalArray::ArrayIndexValueInternalArray::indexOf( const IteratorState &iterator ){if ( !iterator.array_ )return ArrayIndex(-1);return ArrayIndex((iterator.currentPageIndex_ - iterator.array_->pages_) * itemsPerPage+ iterator.currentItemIndex_ );}intValueInternalArray::compare( const ValueInternalArray &other ) const{int sizeDiff( size_ - other.size_ );if ( sizeDiff != 0 )return sizeDiff;for ( ArrayIndex index =0; index < size_; ++index ){int diff = pages_[index/itemsPerPage][index%itemsPerPage].compare(other.pages_[index/itemsPerPage][index%itemsPerPage] );if ( diff != 0 )return diff;}return 0;}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。
1. 开源生态
2. 协作、人、软件
3. 评估模型