Fixed iteration bug over null values.

This commit is contained in:
Baptiste Lepilleur 2009-11-23 22:33:30 +00:00
parent 2814f6e95b
commit a1d6c9e66a
3 changed files with 46 additions and 29 deletions

View File

@ -917,6 +917,8 @@ public: // overridden from ValueArrayAllocator
private:
#ifndef JSON_VALUE_USE_INTERNAL_MAP
Value::ObjectValues::iterator current_;
// Indicates that iterator is for a null value.
bool isNull_;
#else
union
{

View File

@ -13,6 +13,7 @@
ValueIteratorBase::ValueIteratorBase()
#ifndef JSON_VALUE_USE_INTERNAL_MAP
: current_()
, isNull_( true )
#else
# error fix me // Need to handle uninitialized iterator comparison for experimental maps
#endif
@ -23,6 +24,7 @@ ValueIteratorBase::ValueIteratorBase()
#ifndef JSON_VALUE_USE_INTERNAL_MAP
ValueIteratorBase::ValueIteratorBase( const Value::ObjectValues::iterator &current )
: current_( current )
, isNull_( false )
{
}
#else
@ -86,6 +88,15 @@ ValueIteratorBase::computeDistance( const SelfType &other ) const
# ifdef JSON_USE_CPPTL_SMALLMAP
return current_ - other.current_;
# else
// Iterator for null value are initialized using the default
// constructor, which initialize current_ to the default
// std::map::iterator. As begin() and end() are two instance
// of the default std::map::iterator, they can not be compared.
// To allow this, we handle this comparison specifically.
if ( isNull_ && other.isNull_ )
{
return 0;
}
return difference_type( std::distance( current_, other.current_ ) );
# endif
#else
@ -100,6 +111,10 @@ bool
ValueIteratorBase::isEqual( const SelfType &other ) const
{
#ifndef JSON_VALUE_USE_INTERNAL_MAP
if ( isNull_ )
{
return other.isNull_;
}
return current_ == other.current_;
#else
if ( isArray_ )

View File

@ -505,35 +505,35 @@ Runner::runCommandLine( int argc, const char *argv[] ) const
#if defined(_MSC_VER)
// Hook MSVCRT assertions to prevent dialog from appearing
static int
msvcrtSilentReportHook( int reportType, char *message, int *returnValue )
{
// The default CRT handling of error and assertion is to display
// an error dialog to the user.
// Instead, when an error or an assertion occurs, we force the
// application to terminate using abort() after display
// the message on stderr.
if ( reportType == _CRT_ERROR ||
reportType == _CRT_ASSERT )
{
// calling abort() cause the ReportHook to be called
// The following is used to detect this case and let's the
// error handler fallback on its default behaviour (
// display a warning message)
static volatile bool isAborting = false;
if ( isAborting )
{
return TRUE;
}
isAborting = true;
fprintf( stderr, "CRT Error/Assert:\n%s\n", message );
fflush( stderr );
abort();
}
// Let's other reportType (_CRT_WARNING) be handled as they would by default
return FALSE;
}
static int
msvcrtSilentReportHook( int reportType, char *message, int *returnValue )
{
// The default CRT handling of error and assertion is to display
// an error dialog to the user.
// Instead, when an error or an assertion occurs, we force the
// application to terminate using abort() after display
// the message on stderr.
if ( reportType == _CRT_ERROR ||
reportType == _CRT_ASSERT )
{
// calling abort() cause the ReportHook to be called
// The following is used to detect this case and let's the
// error handler fallback on its default behaviour (
// display a warning message)
static volatile bool isAborting = false;
if ( isAborting )
{
return TRUE;
}
isAborting = true;
fprintf( stderr, "CRT Error/Assert:\n%s\n", message );
fflush( stderr );
abort();
}
// Let's other reportType (_CRT_WARNING) be handled as they would by default
return FALSE;
}
#endif // if defined(_MSC_VER)