Ran clang-format again, this time hitting .inl files too.

clang-format -i $(find . -name '*.h' -or -name '*.cpp' -or -name '*.inl')
This commit is contained in:
Aaron Jacobs 2014-09-18 08:55:18 +10:00 committed by Christopher Dunn
parent 57dde78308
commit ba330893d7
4 changed files with 760 additions and 1051 deletions

View File

@ -2,13 +2,15 @@
// and "version.h.in" files. // and "version.h.in" files.
// Run CMake configure step to update it. // Run CMake configure step to update it.
#ifndef JSON_VERSION_H_INCLUDED #ifndef JSON_VERSION_H_INCLUDED
# define JSON_VERSION_H_INCLUDED #define JSON_VERSION_H_INCLUDED
# define JSONCPP_VERSION_STRING "0.7.0" #define JSONCPP_VERSION_STRING "0.7.0"
# define JSONCPP_VERSION_MAJOR 0 #define JSONCPP_VERSION_MAJOR 0
# define JSONCPP_VERSION_MINOR 7 #define JSONCPP_VERSION_MINOR 7
# define JSONCPP_VERSION_PATCH 0 #define JSONCPP_VERSION_PATCH 0
# define JSONCPP_VERSION_QUALIFIER #define JSONCPP_VERSION_QUALIFIER
# define JSONCPP_VERSION_HEXA ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | (JSONCPP_VERSION_PATCH << 8)) #define JSONCPP_VERSION_HEXA \
((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | \
(JSONCPP_VERSION_PATCH << 8))
#endif // JSON_VERSION_H_INCLUDED #endif // JSON_VERSION_H_INCLUDED

View File

@ -15,303 +15,236 @@ namespace Json {
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
ValueArrayAllocator::~ValueArrayAllocator() ValueArrayAllocator::~ValueArrayAllocator() {}
{
}
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
// class DefaultValueArrayAllocator // class DefaultValueArrayAllocator
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
#ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR #ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
class DefaultValueArrayAllocator : public ValueArrayAllocator class DefaultValueArrayAllocator : public ValueArrayAllocator {
{
public: // overridden from ValueArrayAllocator public: // overridden from ValueArrayAllocator
virtual ~DefaultValueArrayAllocator() virtual ~DefaultValueArrayAllocator() {}
{
virtual ValueInternalArray* newArray() { return new ValueInternalArray(); }
virtual ValueInternalArray* newArrayCopy(const ValueInternalArray& other) {
return new ValueInternalArray(other);
} }
virtual ValueInternalArray *newArray() virtual void destructArray(ValueInternalArray* array) { delete array; }
{
return new ValueInternalArray();
}
virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other ) virtual void
{ reallocateArrayPageIndex(Value**& indexes,
return new ValueInternalArray( other ); ValueInternalArray::PageIndex& indexCount,
} ValueInternalArray::PageIndex minNewIndexCount) {
ValueInternalArray::PageIndex newIndexCount = (indexCount * 3) / 2 + 1;
virtual void destructArray( ValueInternalArray *array ) if (minNewIndexCount > newIndexCount)
{
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; newIndexCount = minNewIndexCount;
void *newIndexes = realloc( indexes, sizeof(Value*) * newIndexCount ); void* newIndexes = realloc(indexes, sizeof(Value*) * newIndexCount);
JSON_ASSERT_MESSAGE(newIndexes, "Couldn't realloc."); JSON_ASSERT_MESSAGE(newIndexes, "Couldn't realloc.");
indexCount = newIndexCount; indexCount = newIndexCount;
indexes = static_cast<Value **>( newIndexes ); indexes = static_cast<Value**>(newIndexes);
} }
virtual void releaseArrayPageIndex( Value **indexes, virtual void releaseArrayPageIndex(Value** indexes,
ValueInternalArray::PageIndex indexCount ) ValueInternalArray::PageIndex indexCount) {
{ if (indexes)
if ( indexes ) free(indexes);
free( indexes );
} }
virtual Value *allocateArrayPage() virtual Value* allocateArrayPage() {
{ return static_cast<Value*>(
return static_cast<Value *>( malloc( sizeof(Value) * ValueInternalArray::itemsPerPage ) ); malloc(sizeof(Value) * ValueInternalArray::itemsPerPage));
} }
virtual void releaseArrayPage( Value *value ) virtual void releaseArrayPage(Value* value) {
{ if (value)
if ( value ) free(value);
free( value );
} }
}; };
#else // #ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR #else // #ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
/// @todo make this thread-safe (lock when accessign batch allocator) /// @todo make this thread-safe (lock when accessign batch allocator)
class DefaultValueArrayAllocator : public ValueArrayAllocator class DefaultValueArrayAllocator : public ValueArrayAllocator {
{
public: // overridden from ValueArrayAllocator public: // overridden from ValueArrayAllocator
virtual ~DefaultValueArrayAllocator() virtual ~DefaultValueArrayAllocator() {}
{
}
virtual ValueInternalArray *newArray() virtual ValueInternalArray* newArray() {
{ ValueInternalArray* array = arraysAllocator_.allocate();
ValueInternalArray *array = arraysAllocator_.allocate();
new (array) ValueInternalArray(); // placement new new (array) ValueInternalArray(); // placement new
return array; return array;
} }
virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other ) virtual ValueInternalArray* newArrayCopy(const ValueInternalArray& other) {
{ ValueInternalArray* array = arraysAllocator_.allocate();
ValueInternalArray *array = arraysAllocator_.allocate(); new (array) ValueInternalArray(other); // placement new
new (array) ValueInternalArray( other ); // placement new
return array; return array;
} }
virtual void destructArray( ValueInternalArray *array ) virtual void destructArray(ValueInternalArray* array) {
{ if (array) {
if ( array )
{
array->~ValueInternalArray(); array->~ValueInternalArray();
arraysAllocator_.release( array ); arraysAllocator_.release(array);
} }
} }
virtual void reallocateArrayPageIndex( Value **&indexes, virtual void
ValueInternalArray::PageIndex &indexCount, reallocateArrayPageIndex(Value**& indexes,
ValueInternalArray::PageIndex minNewIndexCount ) ValueInternalArray::PageIndex& indexCount,
{ ValueInternalArray::PageIndex minNewIndexCount) {
ValueInternalArray::PageIndex newIndexCount = (indexCount*3)/2 + 1; ValueInternalArray::PageIndex newIndexCount = (indexCount * 3) / 2 + 1;
if ( minNewIndexCount > newIndexCount ) if (minNewIndexCount > newIndexCount)
newIndexCount = minNewIndexCount; newIndexCount = minNewIndexCount;
void *newIndexes = realloc( indexes, sizeof(Value*) * newIndexCount ); void* newIndexes = realloc(indexes, sizeof(Value*) * newIndexCount);
JSON_ASSERT_MESSAGE(newIndexes, "Couldn't realloc."); JSON_ASSERT_MESSAGE(newIndexes, "Couldn't realloc.");
indexCount = newIndexCount; indexCount = newIndexCount;
indexes = static_cast<Value **>( newIndexes ); indexes = static_cast<Value**>(newIndexes);
} }
virtual void releaseArrayPageIndex( Value **indexes, virtual void releaseArrayPageIndex(Value** indexes,
ValueInternalArray::PageIndex indexCount ) ValueInternalArray::PageIndex indexCount) {
{ if (indexes)
if ( indexes ) free(indexes);
free( indexes );
} }
virtual Value *allocateArrayPage() virtual Value* allocateArrayPage() {
{ return static_cast<Value*>(pagesAllocator_.allocate());
return static_cast<Value *>( pagesAllocator_.allocate() );
} }
virtual void releaseArrayPage( Value *value ) virtual void releaseArrayPage(Value* value) {
{ if (value)
if ( value ) pagesAllocator_.release(value);
pagesAllocator_.release( value );
} }
private: private:
BatchAllocator<ValueInternalArray,1> arraysAllocator_; BatchAllocator<ValueInternalArray, 1> arraysAllocator_;
BatchAllocator<Value,ValueInternalArray::itemsPerPage> pagesAllocator_; BatchAllocator<Value, ValueInternalArray::itemsPerPage> pagesAllocator_;
}; };
#endif // #ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR #endif // #ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
static ValueArrayAllocator *&arrayAllocator() static ValueArrayAllocator*& arrayAllocator() {
{
static DefaultValueArrayAllocator defaultAllocator; static DefaultValueArrayAllocator defaultAllocator;
static ValueArrayAllocator *arrayAllocator = &defaultAllocator; static ValueArrayAllocator* arrayAllocator = &defaultAllocator;
return arrayAllocator; return arrayAllocator;
} }
static struct DummyArrayAllocatorInitializer { static struct DummyArrayAllocatorInitializer {
DummyArrayAllocatorInitializer() DummyArrayAllocatorInitializer() {
{ arrayAllocator(); // ensure arrayAllocator() statics are initialized before
arrayAllocator(); // ensure arrayAllocator() statics are initialized before main(). // main().
} }
} dummyArrayAllocatorInitializer; } dummyArrayAllocatorInitializer;
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
// class ValueInternalArray // class ValueInternalArray
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
bool bool ValueInternalArray::equals(const IteratorState& x,
ValueInternalArray::equals( const IteratorState &x, const IteratorState& other) {
const IteratorState &other ) return x.array_ == other.array_ &&
{ x.currentItemIndex_ == other.currentItemIndex_ &&
return x.array_ == other.array_ x.currentPageIndex_ == other.currentPageIndex_;
&& x.currentItemIndex_ == other.currentItemIndex_
&& x.currentPageIndex_ == other.currentPageIndex_;
} }
void ValueInternalArray::increment(IteratorState& it) {
void JSON_ASSERT_MESSAGE(
ValueInternalArray::increment( IteratorState &it ) it.array_ && (it.currentPageIndex_ - it.array_->pages_) * itemsPerPage +
{ it.currentItemIndex_ !=
JSON_ASSERT_MESSAGE( it.array_ && it.array_->size_,
(it.currentPageIndex_ - it.array_->pages_)*itemsPerPage + it.currentItemIndex_ "ValueInternalArray::increment(): moving iterator beyond end");
!= it.array_->size_,
"ValueInternalArray::increment(): moving iterator beyond end" );
++(it.currentItemIndex_); ++(it.currentItemIndex_);
if ( it.currentItemIndex_ == itemsPerPage ) if (it.currentItemIndex_ == itemsPerPage) {
{
it.currentItemIndex_ = 0; it.currentItemIndex_ = 0;
++(it.currentPageIndex_); ++(it.currentPageIndex_);
} }
} }
void ValueInternalArray::decrement(IteratorState& it) {
void JSON_ASSERT_MESSAGE(
ValueInternalArray::decrement( IteratorState &it ) it.array_ && it.currentPageIndex_ == it.array_->pages_ &&
{ it.currentItemIndex_ == 0,
JSON_ASSERT_MESSAGE( it.array_ && it.currentPageIndex_ == it.array_->pages_ "ValueInternalArray::decrement(): moving iterator beyond end");
&& it.currentItemIndex_ == 0, if (it.currentItemIndex_ == 0) {
"ValueInternalArray::decrement(): moving iterator beyond end" ); it.currentItemIndex_ = itemsPerPage - 1;
if ( it.currentItemIndex_ == 0 )
{
it.currentItemIndex_ = itemsPerPage-1;
--(it.currentPageIndex_); --(it.currentPageIndex_);
} } else {
else
{
--(it.currentItemIndex_); --(it.currentItemIndex_);
} }
} }
Value& ValueInternalArray::unsafeDereference(const IteratorState& it) {
Value &
ValueInternalArray::unsafeDereference( const IteratorState &it )
{
return (*(it.currentPageIndex_))[it.currentItemIndex_]; return (*(it.currentPageIndex_))[it.currentItemIndex_];
} }
Value& ValueInternalArray::dereference(const IteratorState& it) {
Value & JSON_ASSERT_MESSAGE(
ValueInternalArray::dereference( const IteratorState &it ) it.array_ && (it.currentPageIndex_ - it.array_->pages_) * itemsPerPage +
{ it.currentItemIndex_ <
JSON_ASSERT_MESSAGE( it.array_ && it.array_->size_,
(it.currentPageIndex_ - it.array_->pages_)*itemsPerPage + it.currentItemIndex_ "ValueInternalArray::dereference(): dereferencing invalid iterator");
< it.array_->size_, return unsafeDereference(it);
"ValueInternalArray::dereference(): dereferencing invalid iterator" );
return unsafeDereference( it );
} }
void void ValueInternalArray::makeBeginIterator(IteratorState& it) const {
ValueInternalArray::makeBeginIterator( IteratorState &it ) const it.array_ = const_cast<ValueInternalArray*>(this);
{
it.array_ = const_cast<ValueInternalArray *>( this );
it.currentItemIndex_ = 0; it.currentItemIndex_ = 0;
it.currentPageIndex_ = pages_; it.currentPageIndex_ = pages_;
} }
void ValueInternalArray::makeIterator(IteratorState& it,
void ArrayIndex index) const {
ValueInternalArray::makeIterator( IteratorState &it, ArrayIndex index ) const it.array_ = const_cast<ValueInternalArray*>(this);
{
it.array_ = const_cast<ValueInternalArray *>( this );
it.currentItemIndex_ = index % itemsPerPage; it.currentItemIndex_ = index % itemsPerPage;
it.currentPageIndex_ = pages_ + index / itemsPerPage; it.currentPageIndex_ = pages_ + index / itemsPerPage;
} }
void ValueInternalArray::makeEndIterator(IteratorState& it) const {
void makeIterator(it, size_);
ValueInternalArray::makeEndIterator( IteratorState &it ) const
{
makeIterator( it, size_ );
} }
ValueInternalArray::ValueInternalArray() : pages_(0), size_(0), pageCount_(0) {}
ValueInternalArray::ValueInternalArray() ValueInternalArray::ValueInternalArray(const ValueInternalArray& other)
: pages_( 0 ) : pages_(0), size_(other.size_), pageCount_(0) {
, size_( 0 )
, pageCount_( 0 )
{
}
ValueInternalArray::ValueInternalArray( const ValueInternalArray &other )
: pages_( 0 )
, size_( other.size_ )
, pageCount_( 0 )
{
PageIndex minNewPages = other.size_ / itemsPerPage; PageIndex minNewPages = other.size_ / itemsPerPage;
arrayAllocator()->reallocateArrayPageIndex( pages_, pageCount_, minNewPages ); arrayAllocator()->reallocateArrayPageIndex(pages_, pageCount_, minNewPages);
JSON_ASSERT_MESSAGE( pageCount_ >= minNewPages, JSON_ASSERT_MESSAGE(pageCount_ >= minNewPages,
"ValueInternalArray::reserve(): bad reallocation" ); "ValueInternalArray::reserve(): bad reallocation");
IteratorState itOther; IteratorState itOther;
other.makeBeginIterator( itOther ); other.makeBeginIterator(itOther);
Value *value; Value* value;
for ( ArrayIndex index = 0; index < size_; ++index, increment(itOther) ) for (ArrayIndex index = 0; index < size_; ++index, increment(itOther)) {
{ if (index % itemsPerPage == 0) {
if ( index % itemsPerPage == 0 )
{
PageIndex pageIndex = index / itemsPerPage; PageIndex pageIndex = index / itemsPerPage;
value = arrayAllocator()->allocateArrayPage(); value = arrayAllocator()->allocateArrayPage();
pages_[pageIndex] = value; pages_[pageIndex] = value;
} }
new (value) Value( dereference( itOther ) ); new (value) Value(dereference(itOther));
} }
} }
ValueInternalArray& ValueInternalArray::operator=(ValueInternalArray other) {
ValueInternalArray &
ValueInternalArray::operator=(ValueInternalArray other)
{
swap(other); swap(other);
return *this; return *this;
} }
ValueInternalArray::~ValueInternalArray() {
ValueInternalArray::~ValueInternalArray()
{
// destroy all constructed items // destroy all constructed items
IteratorState it; IteratorState it;
IteratorState itEnd; IteratorState itEnd;
makeBeginIterator( it); makeBeginIterator(it);
makeEndIterator( itEnd ); makeEndIterator(itEnd);
for ( ; !equals(it,itEnd); increment(it) ) for (; !equals(it, itEnd); increment(it)) {
{ Value* value = &dereference(it);
Value *value = &dereference(it);
value->~Value(); value->~Value();
} }
// release all pages // release all pages
PageIndex lastPageIndex = size_ / itemsPerPage; PageIndex lastPageIndex = size_ / itemsPerPage;
for ( PageIndex pageIndex = 0; pageIndex < lastPageIndex; ++pageIndex ) for (PageIndex pageIndex = 0; pageIndex < lastPageIndex; ++pageIndex)
arrayAllocator()->releaseArrayPage( pages_[pageIndex] ); arrayAllocator()->releaseArrayPage(pages_[pageIndex]);
// release pages index // release pages index
arrayAllocator()->releaseArrayPageIndex( pages_, pageCount_ ); arrayAllocator()->releaseArrayPageIndex(pages_, pageCount_);
} }
void ValueInternalArray::swap(ValueInternalArray& other) {
void Value** tempPages = pages_;
ValueInternalArray::swap( ValueInternalArray &other )
{
Value **tempPages = pages_;
pages_ = other.pages_; pages_ = other.pages_;
other.pages_ = tempPages; other.pages_ = tempPages;
ArrayIndex tempSize = size_; ArrayIndex tempSize = size_;
@ -322,129 +255,103 @@ ValueInternalArray::swap( ValueInternalArray &other )
other.pageCount_ = tempPageCount; other.pageCount_ = tempPageCount;
} }
void void ValueInternalArray::clear() {
ValueInternalArray::clear()
{
ValueInternalArray dummy; ValueInternalArray dummy;
swap( dummy ); swap(dummy);
} }
void ValueInternalArray::resize(ArrayIndex newSize) {
void if (newSize == 0)
ValueInternalArray::resize( ArrayIndex newSize )
{
if ( newSize == 0 )
clear(); clear();
else if ( newSize < size_ ) else if (newSize < size_) {
{
IteratorState it; IteratorState it;
IteratorState itEnd; IteratorState itEnd;
makeIterator( it, newSize ); makeIterator(it, newSize);
makeIterator( itEnd, size_ ); makeIterator(itEnd, size_);
for ( ; !equals(it,itEnd); increment(it) ) for (; !equals(it, itEnd); increment(it)) {
{ Value* value = &dereference(it);
Value *value = &dereference(it);
value->~Value(); value->~Value();
} }
PageIndex pageIndex = (newSize + itemsPerPage - 1) / itemsPerPage; PageIndex pageIndex = (newSize + itemsPerPage - 1) / itemsPerPage;
PageIndex lastPageIndex = size_ / itemsPerPage; PageIndex lastPageIndex = size_ / itemsPerPage;
for ( ; pageIndex < lastPageIndex; ++pageIndex ) for (; pageIndex < lastPageIndex; ++pageIndex)
arrayAllocator()->releaseArrayPage( pages_[pageIndex] ); arrayAllocator()->releaseArrayPage(pages_[pageIndex]);
size_ = newSize; size_ = newSize;
} } else if (newSize > size_)
else if ( newSize > size_ ) resolveReference(newSize);
resolveReference( newSize );
} }
void ValueInternalArray::makeIndexValid(ArrayIndex index) {
void
ValueInternalArray::makeIndexValid( ArrayIndex index )
{
// Need to enlarge page index ? // Need to enlarge page index ?
if ( index >= pageCount_ * itemsPerPage ) if (index >= pageCount_ * itemsPerPage) {
{
PageIndex minNewPages = (index + 1) / itemsPerPage; PageIndex minNewPages = (index + 1) / itemsPerPage;
arrayAllocator()->reallocateArrayPageIndex( pages_, pageCount_, minNewPages ); arrayAllocator()->reallocateArrayPageIndex(pages_, pageCount_, minNewPages);
JSON_ASSERT_MESSAGE( pageCount_ >= minNewPages, "ValueInternalArray::reserve(): bad reallocation" ); JSON_ASSERT_MESSAGE(pageCount_ >= minNewPages,
"ValueInternalArray::reserve(): bad reallocation");
} }
// Need to allocate new pages ? // Need to allocate new pages ?
ArrayIndex nextPageIndex = ArrayIndex nextPageIndex = (size_ % itemsPerPage) != 0
(size_ % itemsPerPage) != 0 ? size_ - (size_%itemsPerPage) + itemsPerPage ? size_ - (size_ % itemsPerPage) + itemsPerPage
: size_; : size_;
if ( nextPageIndex <= index ) if (nextPageIndex <= index) {
{
PageIndex pageIndex = nextPageIndex / itemsPerPage; PageIndex pageIndex = nextPageIndex / itemsPerPage;
PageIndex pageToAllocate = (index - nextPageIndex) / itemsPerPage + 1; PageIndex pageToAllocate = (index - nextPageIndex) / itemsPerPage + 1;
for ( ; pageToAllocate-- > 0; ++pageIndex ) for (; pageToAllocate-- > 0; ++pageIndex)
pages_[pageIndex] = arrayAllocator()->allocateArrayPage(); pages_[pageIndex] = arrayAllocator()->allocateArrayPage();
} }
// Initialize all new entries // Initialize all new entries
IteratorState it; IteratorState it;
IteratorState itEnd; IteratorState itEnd;
makeIterator( it, size_ ); makeIterator(it, size_);
size_ = index + 1; size_ = index + 1;
makeIterator( itEnd, size_ ); makeIterator(itEnd, size_);
for ( ; !equals(it,itEnd); increment(it) ) for (; !equals(it, itEnd); increment(it)) {
{ Value* value = &dereference(it);
Value *value = &dereference(it);
new (value) Value(); // Construct a default value using placement new new (value) Value(); // Construct a default value using placement new
} }
} }
Value & Value& ValueInternalArray::resolveReference(ArrayIndex index) {
ValueInternalArray::resolveReference( ArrayIndex index ) if (index >= size_)
{ makeIndexValid(index);
if ( index >= size_ ) return pages_[index / itemsPerPage][index % itemsPerPage];
makeIndexValid( index );
return pages_[index/itemsPerPage][index%itemsPerPage];
} }
Value * Value* ValueInternalArray::find(ArrayIndex index) const {
ValueInternalArray::find( ArrayIndex index ) const if (index >= size_)
{
if ( index >= size_ )
return 0; return 0;
return &(pages_[index/itemsPerPage][index%itemsPerPage]); return &(pages_[index / itemsPerPage][index % itemsPerPage]);
} }
ValueInternalArray::ArrayIndex ValueInternalArray::ArrayIndex ValueInternalArray::size() const {
ValueInternalArray::size() const
{
return size_; return size_;
} }
int int ValueInternalArray::distance(const IteratorState& x,
ValueInternalArray::distance( const IteratorState &x, const IteratorState &y ) const IteratorState& y) {
{
return indexOf(y) - indexOf(x); return indexOf(y) - indexOf(x);
} }
ValueInternalArray::ArrayIndex ValueInternalArray::ArrayIndex
ValueInternalArray::indexOf( const IteratorState &iterator ) ValueInternalArray::indexOf(const IteratorState& iterator) {
{ if (!iterator.array_)
if ( !iterator.array_ )
return ArrayIndex(-1); return ArrayIndex(-1);
return ArrayIndex( return ArrayIndex((iterator.currentPageIndex_ - iterator.array_->pages_) *
(iterator.currentPageIndex_ - iterator.array_->pages_) * itemsPerPage itemsPerPage +
+ iterator.currentItemIndex_ ); iterator.currentItemIndex_);
} }
int ValueInternalArray::compare(const ValueInternalArray& other) const {
int int sizeDiff(size_ - other.size_);
ValueInternalArray::compare( const ValueInternalArray &other ) const if (sizeDiff != 0)
{
int sizeDiff( size_ - other.size_ );
if ( sizeDiff != 0 )
return sizeDiff; return sizeDiff;
for ( ArrayIndex index =0; index < size_; ++index ) for (ArrayIndex index = 0; index < size_; ++index) {
{ int diff = pages_[index / itemsPerPage][index % itemsPerPage].compare(
int diff = pages_[index/itemsPerPage][index%itemsPerPage].compare( other.pages_[index / itemsPerPage][index % itemsPerPage]);
other.pages_[index/itemsPerPage][index%itemsPerPage] ); if (diff != 0)
if ( diff != 0 )
return diff; return diff;
} }
return 0; return 0;

View File

@ -15,146 +15,106 @@ namespace Json {
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
/** \internal MUST be safely initialized using memset( this, 0, sizeof(ValueInternalLink) ); /** \internal MUST be safely initialized using memset( this, 0,
* sizeof(ValueInternalLink) );
* This optimization is used by the fast allocator. * This optimization is used by the fast allocator.
*/ */
ValueInternalLink::ValueInternalLink() ValueInternalLink::ValueInternalLink() : previous_(0), next_(0) {}
: previous_( 0 )
, next_( 0 )
{
}
ValueInternalLink::~ValueInternalLink() ValueInternalLink::~ValueInternalLink() {
{ for (int index = 0; index < itemPerLink; ++index) {
for ( int index =0; index < itemPerLink; ++index ) if (!items_[index].isItemAvailable()) {
{ if (!items_[index].isMemberNameStatic())
if ( !items_[index].isItemAvailable() ) free(keys_[index]);
{ } else
if ( !items_[index].isMemberNameStatic() )
free( keys_[index] );
}
else
break; break;
} }
} }
ValueMapAllocator::~ValueMapAllocator() {}
ValueMapAllocator::~ValueMapAllocator()
{
}
#ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR #ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
class DefaultValueMapAllocator : public ValueMapAllocator class DefaultValueMapAllocator : public ValueMapAllocator {
{
public: // overridden from ValueMapAllocator public: // overridden from ValueMapAllocator
virtual ValueInternalMap *newMap() virtual ValueInternalMap* newMap() { return new ValueInternalMap(); }
{
return new ValueInternalMap(); virtual ValueInternalMap* newMapCopy(const ValueInternalMap& other) {
return new ValueInternalMap(other);
} }
virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other ) virtual void destructMap(ValueInternalMap* map) { delete map; }
{
return new ValueInternalMap( other );
}
virtual void destructMap( ValueInternalMap *map ) virtual ValueInternalLink* allocateMapBuckets(unsigned int size) {
{
delete map;
}
virtual ValueInternalLink *allocateMapBuckets( unsigned int size )
{
return new ValueInternalLink[size]; return new ValueInternalLink[size];
} }
virtual void releaseMapBuckets( ValueInternalLink *links ) virtual void releaseMapBuckets(ValueInternalLink* links) { delete[] links; }
{
delete [] links;
}
virtual ValueInternalLink *allocateMapLink() virtual ValueInternalLink* allocateMapLink() {
{
return new ValueInternalLink(); return new ValueInternalLink();
} }
virtual void releaseMapLink( ValueInternalLink *link ) virtual void releaseMapLink(ValueInternalLink* link) { delete link; }
{
delete link;
}
}; };
#else #else
/// @todo make this thread-safe (lock when accessign batch allocator) /// @todo make this thread-safe (lock when accessign batch allocator)
class DefaultValueMapAllocator : public ValueMapAllocator class DefaultValueMapAllocator : public ValueMapAllocator {
{
public: // overridden from ValueMapAllocator public: // overridden from ValueMapAllocator
virtual ValueInternalMap *newMap() virtual ValueInternalMap* newMap() {
{ ValueInternalMap* map = mapsAllocator_.allocate();
ValueInternalMap *map = mapsAllocator_.allocate();
new (map) ValueInternalMap(); // placement new new (map) ValueInternalMap(); // placement new
return map; return map;
} }
virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other ) virtual ValueInternalMap* newMapCopy(const ValueInternalMap& other) {
{ ValueInternalMap* map = mapsAllocator_.allocate();
ValueInternalMap *map = mapsAllocator_.allocate(); new (map) ValueInternalMap(other); // placement new
new (map) ValueInternalMap( other ); // placement new
return map; return map;
} }
virtual void destructMap( ValueInternalMap *map ) virtual void destructMap(ValueInternalMap* map) {
{ if (map) {
if ( map )
{
map->~ValueInternalMap(); map->~ValueInternalMap();
mapsAllocator_.release( map ); mapsAllocator_.release(map);
} }
} }
virtual ValueInternalLink *allocateMapBuckets( unsigned int size ) virtual ValueInternalLink* allocateMapBuckets(unsigned int size) {
{
return new ValueInternalLink[size]; return new ValueInternalLink[size];
} }
virtual void releaseMapBuckets( ValueInternalLink *links ) virtual void releaseMapBuckets(ValueInternalLink* links) { delete[] links; }
{
delete [] links;
}
virtual ValueInternalLink *allocateMapLink() virtual ValueInternalLink* allocateMapLink() {
{ ValueInternalLink* link = linksAllocator_.allocate();
ValueInternalLink *link = linksAllocator_.allocate(); memset(link, 0, sizeof(ValueInternalLink));
memset( link, 0, sizeof(ValueInternalLink) );
return link; return link;
} }
virtual void releaseMapLink( ValueInternalLink *link ) virtual void releaseMapLink(ValueInternalLink* link) {
{
link->~ValueInternalLink(); link->~ValueInternalLink();
linksAllocator_.release( link ); linksAllocator_.release(link);
} }
private: private:
BatchAllocator<ValueInternalMap,1> mapsAllocator_; BatchAllocator<ValueInternalMap, 1> mapsAllocator_;
BatchAllocator<ValueInternalLink,1> linksAllocator_; BatchAllocator<ValueInternalLink, 1> linksAllocator_;
}; };
#endif #endif
static ValueMapAllocator *&mapAllocator() static ValueMapAllocator*& mapAllocator() {
{
static DefaultValueMapAllocator defaultAllocator; static DefaultValueMapAllocator defaultAllocator;
static ValueMapAllocator *mapAllocator = &defaultAllocator; static ValueMapAllocator* mapAllocator = &defaultAllocator;
return mapAllocator; return mapAllocator;
} }
static struct DummyMapAllocatorInitializer { static struct DummyMapAllocatorInitializer {
DummyMapAllocatorInitializer() DummyMapAllocatorInitializer() {
{ mapAllocator(); // ensure mapAllocator() statics are initialized before
mapAllocator(); // ensure mapAllocator() statics are initialized before main(). // main().
} }
} dummyMapAllocatorInitializer; } dummyMapAllocatorInitializer;
// h(K) = value * K >> w ; with w = 32 & K prime w.r.t. 2^32. // h(K) = value * K >> w ; with w = 32 & K prime w.r.t. 2^32.
/* /*
@ -164,71 +124,49 @@ linked list element contains 6 key/values. (memory = (16+4) * 6 + 4 = 124)
value have extra state: valid, available, deleted value have extra state: valid, available, deleted
*/ */
ValueInternalMap::ValueInternalMap() ValueInternalMap::ValueInternalMap()
: buckets_( 0 ) : buckets_(0), tailLink_(0), bucketsSize_(0), itemCount_(0) {}
, tailLink_( 0 )
, bucketsSize_( 0 )
, itemCount_( 0 )
{
}
ValueInternalMap::ValueInternalMap(const ValueInternalMap& other)
ValueInternalMap::ValueInternalMap( const ValueInternalMap &other ) : buckets_(0), tailLink_(0), bucketsSize_(0), itemCount_(0) {
: buckets_( 0 ) reserve(other.itemCount_);
, tailLink_( 0 )
, bucketsSize_( 0 )
, itemCount_( 0 )
{
reserve( other.itemCount_ );
IteratorState it; IteratorState it;
IteratorState itEnd; IteratorState itEnd;
other.makeBeginIterator( it ); other.makeBeginIterator(it);
other.makeEndIterator( itEnd ); other.makeEndIterator(itEnd);
for ( ; !equals(it,itEnd); increment(it) ) for (; !equals(it, itEnd); increment(it)) {
{
bool isStatic; bool isStatic;
const char *memberName = key( it, isStatic ); const char* memberName = key(it, isStatic);
const Value &aValue = value( it ); const Value& aValue = value(it);
resolveReference(memberName, isStatic) = aValue; resolveReference(memberName, isStatic) = aValue;
} }
} }
ValueInternalMap& ValueInternalMap::operator=(ValueInternalMap other) {
ValueInternalMap &
ValueInternalMap::operator=(ValueInternalMap other)
{
swap(other); swap(other);
return *this; return *this;
} }
ValueInternalMap::~ValueInternalMap() {
ValueInternalMap::~ValueInternalMap() if (buckets_) {
{ for (BucketIndex bucketIndex = 0; bucketIndex < bucketsSize_;
if ( buckets_ ) ++bucketIndex) {
{ ValueInternalLink* link = buckets_[bucketIndex].next_;
for ( BucketIndex bucketIndex =0; bucketIndex < bucketsSize_; ++bucketIndex ) while (link) {
{ ValueInternalLink* linkToRelease = link;
ValueInternalLink *link = buckets_[bucketIndex].next_;
while ( link )
{
ValueInternalLink *linkToRelease = link;
link = link->next_; link = link->next_;
mapAllocator()->releaseMapLink( linkToRelease ); mapAllocator()->releaseMapLink(linkToRelease);
} }
} }
mapAllocator()->releaseMapBuckets( buckets_ ); mapAllocator()->releaseMapBuckets(buckets_);
} }
} }
void ValueInternalMap::swap(ValueInternalMap& other) {
void ValueInternalLink* tempBuckets = buckets_;
ValueInternalMap::swap( ValueInternalMap &other )
{
ValueInternalLink *tempBuckets = buckets_;
buckets_ = other.buckets_; buckets_ = other.buckets_;
other.buckets_ = tempBuckets; other.buckets_ = tempBuckets;
ValueInternalLink *tempTailLink = tailLink_; ValueInternalLink* tempTailLink = tailLink_;
tailLink_ = other.tailLink_; tailLink_ = other.tailLink_;
other.tailLink_ = tempTailLink; other.tailLink_ = tempTailLink;
BucketIndex tempBucketsSize = bucketsSize_; BucketIndex tempBucketsSize = bucketsSize_;
@ -239,336 +177,264 @@ ValueInternalMap::swap( ValueInternalMap &other )
other.itemCount_ = tempItemCount; other.itemCount_ = tempItemCount;
} }
void ValueInternalMap::clear() {
void
ValueInternalMap::clear()
{
ValueInternalMap dummy; ValueInternalMap dummy;
swap( dummy ); swap(dummy);
} }
ValueInternalMap::BucketIndex ValueInternalMap::size() const {
ValueInternalMap::BucketIndex
ValueInternalMap::size() const
{
return itemCount_; return itemCount_;
} }
bool bool ValueInternalMap::reserveDelta(BucketIndex growth) {
ValueInternalMap::reserveDelta( BucketIndex growth ) return reserve(itemCount_ + growth);
{
return reserve( itemCount_ + growth );
} }
bool bool ValueInternalMap::reserve(BucketIndex newItemCount) {
ValueInternalMap::reserve( BucketIndex newItemCount ) if (!buckets_ && newItemCount > 0) {
{ buckets_ = mapAllocator()->allocateMapBuckets(1);
if ( !buckets_ && newItemCount > 0 )
{
buckets_ = mapAllocator()->allocateMapBuckets( 1 );
bucketsSize_ = 1; bucketsSize_ = 1;
tailLink_ = &buckets_[0]; tailLink_ = &buckets_[0];
} }
// BucketIndex idealBucketCount = (newItemCount + ValueInternalLink::itemPerLink) / ValueInternalLink::itemPerLink; // BucketIndex idealBucketCount = (newItemCount +
// ValueInternalLink::itemPerLink) / ValueInternalLink::itemPerLink;
return true; return true;
} }
const Value* ValueInternalMap::find(const char* key) const {
const Value * if (!bucketsSize_)
ValueInternalMap::find( const char *key ) const
{
if ( !bucketsSize_ )
return 0; return 0;
HashKey hashedKey = hash( key ); HashKey hashedKey = hash(key);
BucketIndex bucketIndex = hashedKey % bucketsSize_; BucketIndex bucketIndex = hashedKey % bucketsSize_;
for ( const ValueInternalLink *current = &buckets_[bucketIndex]; for (const ValueInternalLink* current = &buckets_[bucketIndex]; current != 0;
current != 0; current = current->next_) {
current = current->next_ ) for (BucketIndex index = 0; index < ValueInternalLink::itemPerLink;
{ ++index) {
for ( BucketIndex index=0; index < ValueInternalLink::itemPerLink; ++index ) if (current->items_[index].isItemAvailable())
{
if ( current->items_[index].isItemAvailable() )
return 0; return 0;
if ( strcmp( key, current->keys_[index] ) == 0 ) if (strcmp(key, current->keys_[index]) == 0)
return &current->items_[index]; return &current->items_[index];
} }
} }
return 0; return 0;
} }
Value* ValueInternalMap::find(const char* key) {
Value * const ValueInternalMap* constThis = this;
ValueInternalMap::find( const char *key ) return const_cast<Value*>(constThis->find(key));
{
const ValueInternalMap *constThis = this;
return const_cast<Value *>( constThis->find( key ) );
} }
Value& ValueInternalMap::resolveReference(const char* key, bool isStatic) {
Value & HashKey hashedKey = hash(key);
ValueInternalMap::resolveReference( const char *key, if (bucketsSize_) {
bool isStatic )
{
HashKey hashedKey = hash( key );
if ( bucketsSize_ )
{
BucketIndex bucketIndex = hashedKey % bucketsSize_; BucketIndex bucketIndex = hashedKey % bucketsSize_;
ValueInternalLink **previous = 0; ValueInternalLink** previous = 0;
BucketIndex index; BucketIndex index;
for ( ValueInternalLink *current = &buckets_[bucketIndex]; for (ValueInternalLink* current = &buckets_[bucketIndex]; current != 0;
current != 0; previous = &current->next_, current = current->next_) {
previous = &current->next_, current = current->next_ ) for (index = 0; index < ValueInternalLink::itemPerLink; ++index) {
{ if (current->items_[index].isItemAvailable())
for ( index=0; index < ValueInternalLink::itemPerLink; ++index ) return setNewItem(key, isStatic, current, index);
{ if (strcmp(key, current->keys_[index]) == 0)
if ( current->items_[index].isItemAvailable() )
return setNewItem( key, isStatic, current, index );
if ( strcmp( key, current->keys_[index] ) == 0 )
return current->items_[index]; return current->items_[index];
} }
} }
} }
reserveDelta( 1 ); reserveDelta(1);
return unsafeAdd( key, isStatic, hashedKey ); return unsafeAdd(key, isStatic, hashedKey);
} }
void ValueInternalMap::remove(const char* key) {
void HashKey hashedKey = hash(key);
ValueInternalMap::remove( const char *key ) if (!bucketsSize_)
{
HashKey hashedKey = hash( key );
if ( !bucketsSize_ )
return; return;
BucketIndex bucketIndex = hashedKey % bucketsSize_; BucketIndex bucketIndex = hashedKey % bucketsSize_;
for ( ValueInternalLink *link = &buckets_[bucketIndex]; for (ValueInternalLink* link = &buckets_[bucketIndex]; link != 0;
link != 0; link = link->next_) {
link = link->next_ )
{
BucketIndex index; BucketIndex index;
for ( index =0; index < ValueInternalLink::itemPerLink; ++index ) for (index = 0; index < ValueInternalLink::itemPerLink; ++index) {
{ if (link->items_[index].isItemAvailable())
if ( link->items_[index].isItemAvailable() )
return; return;
if ( strcmp( key, link->keys_[index] ) == 0 ) if (strcmp(key, link->keys_[index]) == 0) {
{ doActualRemove(link, index, bucketIndex);
doActualRemove( link, index, bucketIndex );
return; return;
} }
} }
} }
} }
void void ValueInternalMap::doActualRemove(ValueInternalLink* link,
ValueInternalMap::doActualRemove( ValueInternalLink *link,
BucketIndex index, BucketIndex index,
BucketIndex bucketIndex ) BucketIndex bucketIndex) {
{
// find last item of the bucket and swap it with the 'removed' one. // find last item of the bucket and swap it with the 'removed' one.
// set removed items flags to 'available'. // set removed items flags to 'available'.
// if last page only contains 'available' items, then desallocate it (it's empty) // if last page only contains 'available' items, then desallocate it (it's
ValueInternalLink *&lastLink = getLastLinkInBucket( index ); // empty)
ValueInternalLink*& lastLink = getLastLinkInBucket(index);
BucketIndex lastItemIndex = 1; // a link can never be empty, so start at 1 BucketIndex lastItemIndex = 1; // a link can never be empty, so start at 1
for ( ; for (; lastItemIndex < ValueInternalLink::itemPerLink;
lastItemIndex < ValueInternalLink::itemPerLink; ++lastItemIndex) // may be optimized with dicotomic search
++lastItemIndex ) // may be optimized with dicotomic search
{ {
if ( lastLink->items_[lastItemIndex].isItemAvailable() ) if (lastLink->items_[lastItemIndex].isItemAvailable())
break; break;
} }
BucketIndex lastUsedIndex = lastItemIndex - 1; BucketIndex lastUsedIndex = lastItemIndex - 1;
Value *valueToDelete = &link->items_[index]; Value* valueToDelete = &link->items_[index];
Value *valueToPreserve = &lastLink->items_[lastUsedIndex]; Value* valueToPreserve = &lastLink->items_[lastUsedIndex];
if ( valueToDelete != valueToPreserve ) if (valueToDelete != valueToPreserve)
valueToDelete->swap( *valueToPreserve ); valueToDelete->swap(*valueToPreserve);
if ( lastUsedIndex == 0 ) // page is now empty if (lastUsedIndex == 0) // page is now empty
{ // remove it from bucket linked list and delete it. { // remove it from bucket linked list and delete it.
ValueInternalLink *linkPreviousToLast = lastLink->previous_; ValueInternalLink* linkPreviousToLast = lastLink->previous_;
if ( linkPreviousToLast != 0 ) // can not deleted bucket link. if (linkPreviousToLast != 0) // can not deleted bucket link.
{ {
mapAllocator()->releaseMapLink( lastLink ); mapAllocator()->releaseMapLink(lastLink);
linkPreviousToLast->next_ = 0; linkPreviousToLast->next_ = 0;
lastLink = linkPreviousToLast; lastLink = linkPreviousToLast;
} }
} } else {
else
{
Value dummy; Value dummy;
valueToPreserve->swap( dummy ); // restore deleted to default Value. valueToPreserve->swap(dummy); // restore deleted to default Value.
valueToPreserve->setItemUsed( false ); valueToPreserve->setItemUsed(false);
} }
--itemCount_; --itemCount_;
} }
ValueInternalLink*&
ValueInternalLink *& ValueInternalMap::getLastLinkInBucket(BucketIndex bucketIndex) {
ValueInternalMap::getLastLinkInBucket( BucketIndex bucketIndex ) if (bucketIndex == bucketsSize_ - 1)
{
if ( bucketIndex == bucketsSize_ - 1 )
return tailLink_; return tailLink_;
ValueInternalLink *&previous = buckets_[bucketIndex+1].previous_; ValueInternalLink*& previous = buckets_[bucketIndex + 1].previous_;
if ( !previous ) if (!previous)
previous = &buckets_[bucketIndex]; previous = &buckets_[bucketIndex];
return previous; return previous;
} }
Value& ValueInternalMap::setNewItem(const char* key,
Value &
ValueInternalMap::setNewItem( const char *key,
bool isStatic, bool isStatic,
ValueInternalLink *link, ValueInternalLink* link,
BucketIndex index ) BucketIndex index) {
{ char* duplicatedKey = makeMemberName(key);
char *duplicatedKey = makeMemberName( key );
++itemCount_; ++itemCount_;
link->keys_[index] = duplicatedKey; link->keys_[index] = duplicatedKey;
link->items_[index].setItemUsed(); link->items_[index].setItemUsed();
link->items_[index].setMemberNameIsStatic( isStatic ); link->items_[index].setMemberNameIsStatic(isStatic);
return link->items_[index]; // items already default constructed. return link->items_[index]; // items already default constructed.
} }
Value&
Value & ValueInternalMap::unsafeAdd(const char* key, bool isStatic, HashKey hashedKey) {
ValueInternalMap::unsafeAdd( const char *key, JSON_ASSERT_MESSAGE(bucketsSize_ > 0,
bool isStatic, "ValueInternalMap::unsafeAdd(): internal logic error.");
HashKey hashedKey )
{
JSON_ASSERT_MESSAGE( bucketsSize_ > 0, "ValueInternalMap::unsafeAdd(): internal logic error." );
BucketIndex bucketIndex = hashedKey % bucketsSize_; BucketIndex bucketIndex = hashedKey % bucketsSize_;
ValueInternalLink *&previousLink = getLastLinkInBucket( bucketIndex ); ValueInternalLink*& previousLink = getLastLinkInBucket(bucketIndex);
ValueInternalLink *link = previousLink; ValueInternalLink* link = previousLink;
BucketIndex index; BucketIndex index;
for ( index =0; index < ValueInternalLink::itemPerLink; ++index ) for (index = 0; index < ValueInternalLink::itemPerLink; ++index) {
{ if (link->items_[index].isItemAvailable())
if ( link->items_[index].isItemAvailable() )
break; break;
} }
if ( index == ValueInternalLink::itemPerLink ) // need to add a new page if (index == ValueInternalLink::itemPerLink) // need to add a new page
{ {
ValueInternalLink *newLink = mapAllocator()->allocateMapLink(); ValueInternalLink* newLink = mapAllocator()->allocateMapLink();
index = 0; index = 0;
link->next_ = newLink; link->next_ = newLink;
previousLink = newLink; previousLink = newLink;
link = newLink; link = newLink;
} }
return setNewItem( key, isStatic, link, index ); return setNewItem(key, isStatic, link, index);
} }
ValueInternalMap::HashKey ValueInternalMap::hash(const char* key) const {
ValueInternalMap::HashKey
ValueInternalMap::hash( const char *key ) const
{
HashKey hash = 0; HashKey hash = 0;
while ( *key ) while (*key)
hash += *key++ * 37; hash += *key++ * 37;
return hash; return hash;
} }
int ValueInternalMap::compare(const ValueInternalMap& other) const {
int int sizeDiff(itemCount_ - other.itemCount_);
ValueInternalMap::compare( const ValueInternalMap &other ) const if (sizeDiff != 0)
{
int sizeDiff( itemCount_ - other.itemCount_ );
if ( sizeDiff != 0 )
return sizeDiff; return sizeDiff;
// Strict order guaranty is required. Compare all keys FIRST, then compare values. // Strict order guaranty is required. Compare all keys FIRST, then compare
// values.
IteratorState it; IteratorState it;
IteratorState itEnd; IteratorState itEnd;
makeBeginIterator( it ); makeBeginIterator(it);
makeEndIterator( itEnd ); makeEndIterator(itEnd);
for ( ; !equals(it,itEnd); increment(it) ) for (; !equals(it, itEnd); increment(it)) {
{ if (!other.find(key(it)))
if ( !other.find( key( it ) ) )
return 1; return 1;
} }
// All keys are equals, let's compare values // All keys are equals, let's compare values
makeBeginIterator( it ); makeBeginIterator(it);
for ( ; !equals(it,itEnd); increment(it) ) for (; !equals(it, itEnd); increment(it)) {
{ const Value* otherValue = other.find(key(it));
const Value *otherValue = other.find( key( it ) ); int valueDiff = value(it).compare(*otherValue);
int valueDiff = value(it).compare( *otherValue ); if (valueDiff != 0)
if ( valueDiff != 0 )
return valueDiff; return valueDiff;
} }
return 0; return 0;
} }
void ValueInternalMap::makeBeginIterator(IteratorState& it) const {
void it.map_ = const_cast<ValueInternalMap*>(this);
ValueInternalMap::makeBeginIterator( IteratorState &it ) const
{
it.map_ = const_cast<ValueInternalMap *>( this );
it.bucketIndex_ = 0; it.bucketIndex_ = 0;
it.itemIndex_ = 0; it.itemIndex_ = 0;
it.link_ = buckets_; it.link_ = buckets_;
} }
void ValueInternalMap::makeEndIterator(IteratorState& it) const {
void it.map_ = const_cast<ValueInternalMap*>(this);
ValueInternalMap::makeEndIterator( IteratorState &it ) const
{
it.map_ = const_cast<ValueInternalMap *>( this );
it.bucketIndex_ = bucketsSize_; it.bucketIndex_ = bucketsSize_;
it.itemIndex_ = 0; it.itemIndex_ = 0;
it.link_ = 0; it.link_ = 0;
} }
bool ValueInternalMap::equals(const IteratorState& x,
bool const IteratorState& other) {
ValueInternalMap::equals( const IteratorState &x, const IteratorState &other ) return x.map_ == other.map_ && x.bucketIndex_ == other.bucketIndex_ &&
{ x.link_ == other.link_ && x.itemIndex_ == other.itemIndex_;
return x.map_ == other.map_
&& x.bucketIndex_ == other.bucketIndex_
&& x.link_ == other.link_
&& x.itemIndex_ == other.itemIndex_;
} }
void ValueInternalMap::incrementBucket(IteratorState& iterator) {
void
ValueInternalMap::incrementBucket( IteratorState &iterator )
{
++iterator.bucketIndex_; ++iterator.bucketIndex_;
JSON_ASSERT_MESSAGE( iterator.bucketIndex_ <= iterator.map_->bucketsSize_, JSON_ASSERT_MESSAGE(
"ValueInternalMap::increment(): attempting to iterate beyond end." ); iterator.bucketIndex_ <= iterator.map_->bucketsSize_,
if ( iterator.bucketIndex_ == iterator.map_->bucketsSize_ ) "ValueInternalMap::increment(): attempting to iterate beyond end.");
if (iterator.bucketIndex_ == iterator.map_->bucketsSize_)
iterator.link_ = 0; iterator.link_ = 0;
else else
iterator.link_ = &(iterator.map_->buckets_[iterator.bucketIndex_]); iterator.link_ = &(iterator.map_->buckets_[iterator.bucketIndex_]);
iterator.itemIndex_ = 0; iterator.itemIndex_ = 0;
} }
void ValueInternalMap::increment(IteratorState& iterator) {
void JSON_ASSERT_MESSAGE(iterator.map_,
ValueInternalMap::increment( IteratorState &iterator ) "Attempting to iterator using invalid iterator.");
{
JSON_ASSERT_MESSAGE( iterator.map_, "Attempting to iterator using invalid iterator." );
++iterator.itemIndex_; ++iterator.itemIndex_;
if ( iterator.itemIndex_ == ValueInternalLink::itemPerLink ) if (iterator.itemIndex_ == ValueInternalLink::itemPerLink) {
{ JSON_ASSERT_MESSAGE(
JSON_ASSERT_MESSAGE( iterator.link_ != 0, iterator.link_ != 0,
"ValueInternalMap::increment(): attempting to iterate beyond end." ); "ValueInternalMap::increment(): attempting to iterate beyond end.");
iterator.link_ = iterator.link_->next_; iterator.link_ = iterator.link_->next_;
if ( iterator.link_ == 0 ) if (iterator.link_ == 0)
incrementBucket( iterator ); incrementBucket(iterator);
} } else if (iterator.link_->items_[iterator.itemIndex_].isItemAvailable()) {
else if ( iterator.link_->items_[iterator.itemIndex_].isItemAvailable() ) incrementBucket(iterator);
{
incrementBucket( iterator );
} }
} }
void ValueInternalMap::decrement(IteratorState& iterator) {
void if (iterator.itemIndex_ == 0) {
ValueInternalMap::decrement( IteratorState &iterator ) JSON_ASSERT_MESSAGE(iterator.map_,
{ "Attempting to iterate using invalid iterator.");
if ( iterator.itemIndex_ == 0 ) if (iterator.link_ == &iterator.map_->buckets_[iterator.bucketIndex_]) {
{ JSON_ASSERT_MESSAGE(iterator.bucketIndex_ > 0,
JSON_ASSERT_MESSAGE( iterator.map_, "Attempting to iterate using invalid iterator." ); "Attempting to iterate beyond beginning.");
if ( iterator.link_ == &iterator.map_->buckets_[iterator.bucketIndex_] )
{
JSON_ASSERT_MESSAGE( iterator.bucketIndex_ > 0, "Attempting to iterate beyond beginning." );
--(iterator.bucketIndex_); --(iterator.bucketIndex_);
} }
iterator.link_ = iterator.link_->previous_; iterator.link_ = iterator.link_->previous_;
@ -576,38 +442,31 @@ ValueInternalMap::decrement( IteratorState &iterator )
} }
} }
const char* ValueInternalMap::key(const IteratorState& iterator) {
const char * JSON_ASSERT_MESSAGE(iterator.link_,
ValueInternalMap::key( const IteratorState &iterator ) "Attempting to iterate using invalid iterator.");
{
JSON_ASSERT_MESSAGE( iterator.link_, "Attempting to iterate using invalid iterator." );
return iterator.link_->keys_[iterator.itemIndex_]; return iterator.link_->keys_[iterator.itemIndex_];
} }
const char * const char* ValueInternalMap::key(const IteratorState& iterator,
ValueInternalMap::key( const IteratorState &iterator, bool &isStatic ) bool& isStatic) {
{ JSON_ASSERT_MESSAGE(iterator.link_,
JSON_ASSERT_MESSAGE( iterator.link_, "Attempting to iterate using invalid iterator." ); "Attempting to iterate using invalid iterator.");
isStatic = iterator.link_->items_[iterator.itemIndex_].isMemberNameStatic(); isStatic = iterator.link_->items_[iterator.itemIndex_].isMemberNameStatic();
return iterator.link_->keys_[iterator.itemIndex_]; return iterator.link_->keys_[iterator.itemIndex_];
} }
Value& ValueInternalMap::value(const IteratorState& iterator) {
Value & JSON_ASSERT_MESSAGE(iterator.link_,
ValueInternalMap::value( const IteratorState &iterator ) "Attempting to iterate using invalid iterator.");
{
JSON_ASSERT_MESSAGE( iterator.link_, "Attempting to iterate using invalid iterator." );
return iterator.link_->items_[iterator.itemIndex_]; return iterator.link_->items_[iterator.itemIndex_];
} }
int ValueInternalMap::distance(const IteratorState& x, const IteratorState& y) {
int
ValueInternalMap::distance( const IteratorState &x, const IteratorState &y )
{
int offset = 0; int offset = 0;
IteratorState it = x; IteratorState it = x;
while ( !equals( it, y ) ) while (!equals(it, y))
increment( it ); increment(it);
return offset; return offset;
} }

View File

@ -17,201 +17,165 @@ namespace Json {
ValueIteratorBase::ValueIteratorBase() ValueIteratorBase::ValueIteratorBase()
#ifndef JSON_VALUE_USE_INTERNAL_MAP #ifndef JSON_VALUE_USE_INTERNAL_MAP
: current_() : current_(), isNull_(true) {
, isNull_( true )
{
} }
#else #else
: isArray_( true ) : isArray_(true), isNull_(true) {
, isNull_( true )
{
iterator_.array_ = ValueInternalArray::IteratorState(); iterator_.array_ = ValueInternalArray::IteratorState();
} }
#endif #endif
#ifndef JSON_VALUE_USE_INTERNAL_MAP #ifndef JSON_VALUE_USE_INTERNAL_MAP
ValueIteratorBase::ValueIteratorBase( const Value::ObjectValues::iterator &current ) ValueIteratorBase::ValueIteratorBase(
: current_( current ) const Value::ObjectValues::iterator& current)
, isNull_( false ) : current_(current), isNull_(false) {}
{
}
#else #else
ValueIteratorBase::ValueIteratorBase( const ValueInternalArray::IteratorState &state ) ValueIteratorBase::ValueIteratorBase(
: isArray_( true ) const ValueInternalArray::IteratorState& state)
{ : isArray_(true) {
iterator_.array_ = state; iterator_.array_ = state;
} }
ValueIteratorBase::ValueIteratorBase(
ValueIteratorBase::ValueIteratorBase( const ValueInternalMap::IteratorState &state ) const ValueInternalMap::IteratorState& state)
: isArray_( false ) : isArray_(false) {
{
iterator_.map_ = state; iterator_.map_ = state;
} }
#endif #endif
Value & Value& ValueIteratorBase::deref() const {
ValueIteratorBase::deref() const
{
#ifndef JSON_VALUE_USE_INTERNAL_MAP #ifndef JSON_VALUE_USE_INTERNAL_MAP
return current_->second; return current_->second;
#else #else
if ( isArray_ ) if (isArray_)
return ValueInternalArray::dereference( iterator_.array_ ); return ValueInternalArray::dereference(iterator_.array_);
return ValueInternalMap::value( iterator_.map_ ); return ValueInternalMap::value(iterator_.map_);
#endif #endif
} }
void ValueIteratorBase::increment() {
void
ValueIteratorBase::increment()
{
#ifndef JSON_VALUE_USE_INTERNAL_MAP #ifndef JSON_VALUE_USE_INTERNAL_MAP
++current_; ++current_;
#else #else
if ( isArray_ ) if (isArray_)
ValueInternalArray::increment( iterator_.array_ ); ValueInternalArray::increment(iterator_.array_);
ValueInternalMap::increment( iterator_.map_ ); ValueInternalMap::increment(iterator_.map_);
#endif #endif
} }
void ValueIteratorBase::decrement() {
void
ValueIteratorBase::decrement()
{
#ifndef JSON_VALUE_USE_INTERNAL_MAP #ifndef JSON_VALUE_USE_INTERNAL_MAP
--current_; --current_;
#else #else
if ( isArray_ ) if (isArray_)
ValueInternalArray::decrement( iterator_.array_ ); ValueInternalArray::decrement(iterator_.array_);
ValueInternalMap::decrement( iterator_.map_ ); ValueInternalMap::decrement(iterator_.map_);
#endif #endif
} }
ValueIteratorBase::difference_type ValueIteratorBase::difference_type
ValueIteratorBase::computeDistance( const SelfType &other ) const ValueIteratorBase::computeDistance(const SelfType& other) const {
{
#ifndef JSON_VALUE_USE_INTERNAL_MAP #ifndef JSON_VALUE_USE_INTERNAL_MAP
# ifdef JSON_USE_CPPTL_SMALLMAP #ifdef JSON_USE_CPPTL_SMALLMAP
return current_ - other.current_; return current_ - other.current_;
# else #else
// Iterator for null value are initialized using the default // Iterator for null value are initialized using the default
// constructor, which initialize current_ to the default // constructor, which initialize current_ to the default
// std::map::iterator. As begin() and end() are two instance // std::map::iterator. As begin() and end() are two instance
// of the default std::map::iterator, they can not be compared. // of the default std::map::iterator, they can not be compared.
// To allow this, we handle this comparison specifically. // To allow this, we handle this comparison specifically.
if ( isNull_ && other.isNull_ ) if (isNull_ && other.isNull_) {
{
return 0; return 0;
} }
// Usage of std::distance is not portable (does not compile with Sun Studio 12
// Usage of std::distance is not portable (does not compile with Sun Studio 12 RogueWave STL, // RogueWave STL,
// which is the one used by default). // which is the one used by default).
// Using a portable hand-made version for non random iterator instead: // Using a portable hand-made version for non random iterator instead:
// return difference_type( std::distance( current_, other.current_ ) ); // return difference_type( std::distance( current_, other.current_ ) );
difference_type myDistance = 0; difference_type myDistance = 0;
for ( Value::ObjectValues::iterator it = current_; it != other.current_; ++it ) for (Value::ObjectValues::iterator it = current_; it != other.current_;
{ ++it) {
++myDistance; ++myDistance;
} }
return myDistance; return myDistance;
# endif #endif
#else #else
if ( isArray_ ) if (isArray_)
return ValueInternalArray::distance( iterator_.array_, other.iterator_.array_ ); return ValueInternalArray::distance(iterator_.array_,
return ValueInternalMap::distance( iterator_.map_, other.iterator_.map_ ); other.iterator_.array_);
return ValueInternalMap::distance(iterator_.map_, other.iterator_.map_);
#endif #endif
} }
bool ValueIteratorBase::isEqual(const SelfType& other) const {
bool
ValueIteratorBase::isEqual( const SelfType &other ) const
{
#ifndef JSON_VALUE_USE_INTERNAL_MAP #ifndef JSON_VALUE_USE_INTERNAL_MAP
if ( isNull_ ) if (isNull_) {
{
return other.isNull_; return other.isNull_;
} }
return current_ == other.current_; return current_ == other.current_;
#else #else
if ( isArray_ ) if (isArray_)
return ValueInternalArray::equals( iterator_.array_, other.iterator_.array_ ); return ValueInternalArray::equals(iterator_.array_, other.iterator_.array_);
return ValueInternalMap::equals( iterator_.map_, other.iterator_.map_ ); return ValueInternalMap::equals(iterator_.map_, other.iterator_.map_);
#endif #endif
} }
void ValueIteratorBase::copy(const SelfType& other) {
void
ValueIteratorBase::copy( const SelfType &other )
{
#ifndef JSON_VALUE_USE_INTERNAL_MAP #ifndef JSON_VALUE_USE_INTERNAL_MAP
current_ = other.current_; current_ = other.current_;
isNull_ = other.isNull_; isNull_ = other.isNull_;
#else #else
if ( isArray_ ) if (isArray_)
iterator_.array_ = other.iterator_.array_; iterator_.array_ = other.iterator_.array_;
iterator_.map_ = other.iterator_.map_; iterator_.map_ = other.iterator_.map_;
#endif #endif
} }
Value ValueIteratorBase::key() const {
Value
ValueIteratorBase::key() const
{
#ifndef JSON_VALUE_USE_INTERNAL_MAP #ifndef JSON_VALUE_USE_INTERNAL_MAP
const Value::CZString czstring = (*current_).first; const Value::CZString czstring = (*current_).first;
if ( czstring.c_str() ) if (czstring.c_str()) {
{ if (czstring.isStaticString())
if ( czstring.isStaticString() ) return Value(StaticString(czstring.c_str()));
return Value( StaticString( czstring.c_str() ) ); return Value(czstring.c_str());
return Value( czstring.c_str() );
} }
return Value( czstring.index() ); return Value(czstring.index());
#else #else
if ( isArray_ ) if (isArray_)
return Value( ValueInternalArray::indexOf( iterator_.array_ ) ); return Value(ValueInternalArray::indexOf(iterator_.array_));
bool isStatic; bool isStatic;
const char *memberName = ValueInternalMap::key( iterator_.map_, isStatic ); const char* memberName = ValueInternalMap::key(iterator_.map_, isStatic);
if ( isStatic ) if (isStatic)
return Value( StaticString( memberName ) ); return Value(StaticString(memberName));
return Value( memberName ); return Value(memberName);
#endif #endif
} }
UInt ValueIteratorBase::index() const {
UInt
ValueIteratorBase::index() const
{
#ifndef JSON_VALUE_USE_INTERNAL_MAP #ifndef JSON_VALUE_USE_INTERNAL_MAP
const Value::CZString czstring = (*current_).first; const Value::CZString czstring = (*current_).first;
if ( !czstring.c_str() ) if (!czstring.c_str())
return czstring.index(); return czstring.index();
return Value::UInt( -1 ); return Value::UInt(-1);
#else #else
if ( isArray_ ) if (isArray_)
return Value::UInt( ValueInternalArray::indexOf( iterator_.array_ ) ); return Value::UInt(ValueInternalArray::indexOf(iterator_.array_));
return Value::UInt( -1 ); return Value::UInt(-1);
#endif #endif
} }
const char* ValueIteratorBase::memberName() const {
const char *
ValueIteratorBase::memberName() const
{
#ifndef JSON_VALUE_USE_INTERNAL_MAP #ifndef JSON_VALUE_USE_INTERNAL_MAP
const char *name = (*current_).first.c_str(); const char* name = (*current_).first.c_str();
return name ? name : ""; return name ? name : "";
#else #else
if ( !isArray_ ) if (!isArray_)
return ValueInternalMap::key( iterator_.map_ ); return ValueInternalMap::key(iterator_.map_);
return ""; return "";
#endif #endif
} }
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
@ -220,36 +184,28 @@ ValueIteratorBase::memberName() const
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
ValueConstIterator::ValueConstIterator() ValueConstIterator::ValueConstIterator() {}
{
}
#ifndef JSON_VALUE_USE_INTERNAL_MAP #ifndef JSON_VALUE_USE_INTERNAL_MAP
ValueConstIterator::ValueConstIterator( const Value::ObjectValues::iterator &current ) ValueConstIterator::ValueConstIterator(
: ValueIteratorBase( current ) const Value::ObjectValues::iterator& current)
{ : ValueIteratorBase(current) {}
}
#else #else
ValueConstIterator::ValueConstIterator( const ValueInternalArray::IteratorState &state ) ValueConstIterator::ValueConstIterator(
: ValueIteratorBase( state ) const ValueInternalArray::IteratorState& state)
{ : ValueIteratorBase(state) {}
}
ValueConstIterator::ValueConstIterator( const ValueInternalMap::IteratorState &state ) ValueConstIterator::ValueConstIterator(
: ValueIteratorBase( state ) const ValueInternalMap::IteratorState& state)
{ : ValueIteratorBase(state) {}
}
#endif #endif
ValueConstIterator & ValueConstIterator& ValueConstIterator::
ValueConstIterator::operator =( const ValueIteratorBase &other ) operator=(const ValueIteratorBase& other) {
{ copy(other);
copy( other );
return *this; return *this;
} }
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
@ -258,42 +214,27 @@ ValueConstIterator::operator =( const ValueIteratorBase &other )
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
ValueIterator::ValueIterator() ValueIterator::ValueIterator() {}
{
}
#ifndef JSON_VALUE_USE_INTERNAL_MAP #ifndef JSON_VALUE_USE_INTERNAL_MAP
ValueIterator::ValueIterator( const Value::ObjectValues::iterator &current ) ValueIterator::ValueIterator(const Value::ObjectValues::iterator& current)
: ValueIteratorBase( current ) : ValueIteratorBase(current) {}
{
}
#else #else
ValueIterator::ValueIterator( const ValueInternalArray::IteratorState &state ) ValueIterator::ValueIterator(const ValueInternalArray::IteratorState& state)
: ValueIteratorBase( state ) : ValueIteratorBase(state) {}
{
}
ValueIterator::ValueIterator( const ValueInternalMap::IteratorState &state ) ValueIterator::ValueIterator(const ValueInternalMap::IteratorState& state)
: ValueIteratorBase( state ) : ValueIteratorBase(state) {}
{
}
#endif #endif
ValueIterator::ValueIterator( const ValueConstIterator &other ) ValueIterator::ValueIterator(const ValueConstIterator& other)
: ValueIteratorBase( other ) : ValueIteratorBase(other) {}
{
}
ValueIterator::ValueIterator( const ValueIterator &other ) ValueIterator::ValueIterator(const ValueIterator& other)
: ValueIteratorBase( other ) : ValueIteratorBase(other) {}
{
}
ValueIterator & ValueIterator& ValueIterator::operator=(const SelfType& other) {
ValueIterator::operator =( const SelfType &other ) copy(other);
{
copy( other );
return *this; return *this;
} }