Reworked the type conversion system again, so that:A

*  isFoo methods determine exact representability.
 *  asFoo methods cause casting when safe.
 *  isConvertibleTo indicates whether casting is safe.

See NEWS.txt for details.
This commit is contained in:
Aaron Jacobs
2011-05-26 02:46:28 +00:00
parent b0ec41c3e3
commit c025697ea5
4 changed files with 518 additions and 91 deletions

View File

@@ -13,6 +13,7 @@
#endif // if !defined(JSON_IS_AMALGAMATION)
#include <math.h>
#include <iostream>
#include <sstream>
#include <utility>
#include <stdexcept>
#include <cstring>
@@ -43,6 +44,11 @@ const LargestUInt Value::maxLargestUInt = LargestUInt(-1);
/// Unknown size marker
static const unsigned int unknown = (unsigned)-1;
template <typename T, typename U>
static inline bool InRange(double d, T min, U max) {
return d >= min && d <= max;
}
/** Duplicates the specified string value.
* @param value Pointer to the string to duplicate. Must be zero-terminated if
@@ -663,6 +669,9 @@ Value::asCString() const
std::string
Value::asString() const
{
// Let the STL sort it out for numeric types.
std::ostringstream oss;
switch ( type_ )
{
case nullValue:
@@ -672,15 +681,18 @@ Value::asString() const
case booleanValue:
return value_.bool_ ? "true" : "false";
case intValue:
oss << value_.int_;
break;
case uintValue:
oss << value_.uint_;
break;
case realValue:
case arrayValue:
case objectValue:
JSON_FAIL_MESSAGE( "Type is not convertible to string" );
oss << value_.real_;
break;
default:
JSON_ASSERT_UNREACHABLE;
JSON_FAIL_MESSAGE( "Type is not convertible to string" );
}
return ""; // unreachable
return oss.str();
}
# ifdef JSON_USE_CPPTL
@@ -695,17 +707,23 @@ Value::asConstString() const
Value::Int
Value::asInt() const
{
JSON_ASSERT_MESSAGE(isInt(), "Value is not convertible to Int");
switch ( type_ )
{
case intValue:
JSON_ASSERT_MESSAGE(isInt(), "LargestInt out of Int range");
return Int(value_.int_);
case uintValue:
JSON_ASSERT_MESSAGE(isInt(), "LargestUInt out of Int range");
return Int(value_.uint_);
case realValue:
return Int( value_.real_ );
JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt, maxInt), "double out of Int range");
return Int(value_.real_);
case nullValue:
return 0;
case booleanValue:
return value_.bool_ ? 1 : 0;
default:
break;
JSON_FAIL_MESSAGE("Value is not convertible to Int.");
}
JSON_ASSERT_UNREACHABLE;
return 0;
@@ -715,17 +733,23 @@ Value::asInt() const
Value::UInt
Value::asUInt() const
{
JSON_ASSERT_MESSAGE(isUInt(), "Value is not convertible to UInt");
switch ( type_ )
{
case intValue:
JSON_ASSERT_MESSAGE(isUInt(), "LargestInt out of UInt range");
return UInt(value_.int_);
case uintValue:
JSON_ASSERT_MESSAGE(isUInt(), "LargestUInt out of UInt range");
return UInt(value_.uint_);
case realValue:
JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt), "double out of UInt range");
return UInt( value_.real_ );
case nullValue:
return 0;
case booleanValue:
return value_.bool_ ? 1 : 0;
default:
break;
JSON_FAIL_MESSAGE("Value is not convertible to UInt.");
}
JSON_ASSERT_UNREACHABLE;
return 0;
@@ -737,17 +761,22 @@ Value::asUInt() const
Value::Int64
Value::asInt64() const
{
JSON_ASSERT_MESSAGE(isInt64(), "Value is not convertible to Int64");
switch ( type_ )
{
case intValue:
return Int64(value_.int_);
case uintValue:
JSON_ASSERT_MESSAGE(isInt64(), "LargestUInt out of Int64 range");
return Int64(value_.uint_);
case realValue:
return Int64( value_.real_ );
JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt64, maxInt64), "double out of Int64 range");
return Int64(value_.real_);
case nullValue:
return 0;
case booleanValue:
return value_.bool_ ? 1 : 0;
default:
break;
JSON_FAIL_MESSAGE("Value is not convertible to Int64.");
}
JSON_ASSERT_UNREACHABLE;
return 0;
@@ -757,15 +786,20 @@ Value::asInt64() const
Value::UInt64
Value::asUInt64() const
{
JSON_ASSERT_MESSAGE(isUInt64(), "Value is not convertible to UInt64");
switch ( type_ )
{
case intValue:
JSON_ASSERT_MESSAGE(isUInt64(), "LargestInt out of UInt64 range");
return UInt64(value_.int_);
case uintValue:
return UInt64(value_.uint_);
case realValue:
JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt64), "double out of UInt64 range");
return UInt64( value_.real_ );
case nullValue:
return 0;
case booleanValue:
return value_.bool_ ? 1 : 0;
default:
break;
}
@@ -814,13 +848,11 @@ Value::asDouble() const
case realValue:
return value_.real_;
case nullValue:
return 0.0;
case booleanValue:
case stringValue:
case arrayValue:
case objectValue:
JSON_FAIL_MESSAGE( "Value is not a double" );
return value_.bool_ ? 1.0 : 0.0;
default:
JSON_ASSERT_UNREACHABLE;
JSON_FAIL_MESSAGE("Value is not convertible to double.");
}
return 0; // unreachable;
}
@@ -841,15 +873,14 @@ Value::asFloat() const
case realValue:
return static_cast<float>( value_.real_ );
case nullValue:
return 0.0;
case booleanValue:
case stringValue:
case arrayValue:
case objectValue:
JSON_FAIL_MESSAGE( "Value is not a float" );
return value_.bool_ ? 1.0 : 0.0;
default:
JSON_ASSERT_UNREACHABLE;
JSON_FAIL_MESSAGE("Value is not convertible to float.");
}
return 0.0f; // unreachable;
JSON_ASSERT_UNREACHABLE;
return 0.0f;
}
bool
@@ -860,68 +891,67 @@ Value::asBool() const
case booleanValue:
return value_.bool_;
case nullValue:
return false;
case intValue:
return value_.int_ ? true : false;
case uintValue:
return value_.uint_ ? true : false;
case realValue:
case stringValue:
case arrayValue:
case objectValue:
JSON_FAIL_MESSAGE( "Value is not a bool" );
return value_.real_ ? true : false;
default:
JSON_ASSERT_UNREACHABLE;
JSON_FAIL_MESSAGE("Value is not convertible to bool.");
}
return false; // unreachable;
JSON_ASSERT_UNREACHABLE;
return false;
}
bool
Value::isConvertibleTo( ValueType other ) const
{
switch ( type_ )
switch ( other )
{
case nullValue:
return true;
return ( isNumeric() && asDouble() == 0.0 )
|| ( type_ == booleanValue && value_.bool_ == false )
|| ( type_ == stringValue && asString() == "" )
|| ( type_ == arrayValue && value_.map_->size() == 0 )
|| ( type_ == objectValue && value_.map_->size() == 0 )
|| type_ == nullValue;
case intValue:
return ( other == nullValue && value_.int_ == 0 )
|| other == intValue
|| ( other == uintValue && value_.int_ >= 0 )
|| other == realValue
|| other == stringValue
|| other == booleanValue;
return isInt()
|| (type_ == realValue && InRange(value_.real_, minInt, maxInt))
|| type_ == booleanValue
|| type_ == nullValue;
case uintValue:
return ( other == nullValue && value_.uint_ == 0 )
|| ( other == intValue && value_.uint_ <= (LargestUInt)maxInt )
|| other == uintValue
|| other == realValue
|| other == stringValue
|| other == booleanValue;
return isUInt()
|| (type_ == realValue && InRange(value_.real_, 0, maxUInt))
|| type_ == booleanValue
|| type_ == nullValue;
case realValue:
return ( other == nullValue && value_.real_ == 0.0 )
|| ( other == intValue && value_.real_ >= minInt && value_.real_ <= maxInt )
|| ( other == uintValue && value_.real_ >= 0 && value_.real_ <= maxUInt )
|| other == realValue
|| other == stringValue
|| other == booleanValue;
return isNumeric()
|| type_ == booleanValue
|| type_ == nullValue;
case booleanValue:
return ( other == nullValue && value_.bool_ == false )
|| other == intValue
|| other == uintValue
|| other == realValue
|| other == stringValue
|| other == booleanValue;
return isNumeric()
|| type_ == booleanValue
|| type_ == nullValue;
case stringValue:
return other == stringValue
|| ( other == nullValue && (!value_.string_ || value_.string_[0] == 0) );
return isNumeric()
|| type_ == booleanValue
|| type_ == stringValue
|| type_ == nullValue;
case arrayValue:
return other == arrayValue
|| ( other == nullValue && value_.map_->size() == 0 );
return type_ == arrayValue
|| type_ == nullValue;
case objectValue:
return other == objectValue
|| ( other == nullValue && value_.map_->size() == 0 );
return type_ == objectValue
|| type_ == nullValue;
default:
JSON_ASSERT_UNREACHABLE;
break;
}
return false; // unreachable;
JSON_ASSERT_UNREACHABLE;
return false;
}

View File

@@ -250,7 +250,6 @@ TestResult::addToLastFailure( const std::string &message )
}
// class TestCase
// //////////////////////////////////////////////////////////////////
@@ -324,7 +323,7 @@ Runner::runTestAt( unsigned int index, TestResult &result ) const
catch ( const std::exception &e )
{
result.addFailure( __FILE__, __LINE__,
"Unexpected exception caugth:" ) << e.what();
"Unexpected exception caught:" ) << e.what();
}
#endif // if JSON_USE_EXCEPTION
delete test;

View File

@@ -121,6 +121,23 @@ JSONTEST_FIXTURE( ValueTest, objects )
JSONTEST_ASSERT_EQUAL(Json::objectValue, emptyObject_.type());
// Empty object okay
JSONTEST_ASSERT(emptyObject_.isConvertibleTo(Json::nullValue));
// Non-empty object not okay
JSONTEST_ASSERT(!object1_.isConvertibleTo(Json::nullValue));
// Always okay
JSONTEST_ASSERT(emptyObject_.isConvertibleTo(Json::objectValue));
// Never okay
JSONTEST_ASSERT(!emptyObject_.isConvertibleTo(Json::arrayValue));
JSONTEST_ASSERT(!emptyObject_.isConvertibleTo(Json::intValue));
JSONTEST_ASSERT(!emptyObject_.isConvertibleTo(Json::uintValue));
JSONTEST_ASSERT(!emptyObject_.isConvertibleTo(Json::realValue));
JSONTEST_ASSERT(!emptyObject_.isConvertibleTo(Json::booleanValue));
JSONTEST_ASSERT(!emptyObject_.isConvertibleTo(Json::stringValue));
// Access through const reference
const Json::Value &constObject = object1_;
@@ -148,6 +165,23 @@ JSONTEST_FIXTURE( ValueTest, arrays )
JSONTEST_ASSERT_EQUAL(Json::arrayValue, array1_.type());
// Empty array okay
JSONTEST_ASSERT(emptyArray_.isConvertibleTo(Json::nullValue));
// Non-empty array not okay
JSONTEST_ASSERT(!array1_.isConvertibleTo(Json::nullValue));
// Always okay
JSONTEST_ASSERT(emptyArray_.isConvertibleTo(Json::arrayValue));
// Never okay
JSONTEST_ASSERT(!emptyArray_.isConvertibleTo(Json::objectValue));
JSONTEST_ASSERT(!emptyArray_.isConvertibleTo(Json::intValue));
JSONTEST_ASSERT(!emptyArray_.isConvertibleTo(Json::uintValue));
JSONTEST_ASSERT(!emptyArray_.isConvertibleTo(Json::realValue));
JSONTEST_ASSERT(!emptyArray_.isConvertibleTo(Json::booleanValue));
JSONTEST_ASSERT(!emptyArray_.isConvertibleTo(Json::stringValue));
// Access through const reference
const Json::Value &constArray = array1_;
JSONTEST_ASSERT_EQUAL(Json::Value(1234), constArray[index0]);
@@ -170,6 +204,23 @@ JSONTEST_FIXTURE( ValueTest, null )
IsCheck checks;
checks.isNull_ = true;
JSONTEST_ASSERT_PRED( checkIs( null_, checks ) );
JSONTEST_ASSERT(null_.isConvertibleTo(Json::nullValue));
JSONTEST_ASSERT(null_.isConvertibleTo(Json::intValue));
JSONTEST_ASSERT(null_.isConvertibleTo(Json::uintValue));
JSONTEST_ASSERT(null_.isConvertibleTo(Json::realValue));
JSONTEST_ASSERT(null_.isConvertibleTo(Json::booleanValue));
JSONTEST_ASSERT(null_.isConvertibleTo(Json::stringValue));
JSONTEST_ASSERT(null_.isConvertibleTo(Json::arrayValue));
JSONTEST_ASSERT(null_.isConvertibleTo(Json::objectValue));
JSONTEST_ASSERT_EQUAL(Json::Int(0), null_.asInt());
JSONTEST_ASSERT_EQUAL(Json::LargestInt(0), null_.asLargestInt());
JSONTEST_ASSERT_EQUAL(Json::UInt(0), null_.asUInt());
JSONTEST_ASSERT_EQUAL(Json::LargestUInt(0), null_.asLargestUInt());
JSONTEST_ASSERT_EQUAL(0.0, null_.asDouble());
JSONTEST_ASSERT_EQUAL(0.0, null_.asFloat());
JSONTEST_ASSERT_STRING_EQUAL("", null_.asString());
}
@@ -183,6 +234,22 @@ JSONTEST_FIXTURE( ValueTest, strings )
JSONTEST_ASSERT_PRED( checkIs( string_, checks ) );
JSONTEST_ASSERT_PRED( checkIs( string1_, checks ) );
// Empty string okay
JSONTEST_ASSERT(emptyString_.isConvertibleTo(Json::nullValue));
// Non-empty string not okay
JSONTEST_ASSERT(!string1_.isConvertibleTo(Json::nullValue));
// Always okay
JSONTEST_ASSERT(string1_.isConvertibleTo(Json::stringValue));
// Never okay
JSONTEST_ASSERT(!string1_.isConvertibleTo(Json::objectValue));
JSONTEST_ASSERT(!string1_.isConvertibleTo(Json::arrayValue));
JSONTEST_ASSERT(!string1_.isConvertibleTo(Json::intValue));
JSONTEST_ASSERT(!string1_.isConvertibleTo(Json::uintValue));
JSONTEST_ASSERT(!string1_.isConvertibleTo(Json::realValue));
JSONTEST_ASSERT_STRING_EQUAL("a", string1_.asString());
JSONTEST_ASSERT_STRING_EQUAL("a", string1_.asCString());
}
@@ -197,8 +264,38 @@ JSONTEST_FIXTURE( ValueTest, bools )
JSONTEST_ASSERT_PRED( checkIs( false_, checks ) );
JSONTEST_ASSERT_PRED( checkIs( true_, checks ) );
// False okay
JSONTEST_ASSERT(false_.isConvertibleTo(Json::nullValue));
// True not okay
JSONTEST_ASSERT(!true_.isConvertibleTo(Json::nullValue));
// Always okay
JSONTEST_ASSERT(true_.isConvertibleTo(Json::intValue));
JSONTEST_ASSERT(true_.isConvertibleTo(Json::uintValue));
JSONTEST_ASSERT(true_.isConvertibleTo(Json::realValue));
JSONTEST_ASSERT(true_.isConvertibleTo(Json::booleanValue));
JSONTEST_ASSERT(true_.isConvertibleTo(Json::stringValue));
// Never okay
JSONTEST_ASSERT(!true_.isConvertibleTo(Json::arrayValue));
JSONTEST_ASSERT(!true_.isConvertibleTo(Json::objectValue));
JSONTEST_ASSERT_EQUAL(true, true_.asBool());
JSONTEST_ASSERT_EQUAL(1, true_.asInt());
JSONTEST_ASSERT_EQUAL(1, true_.asLargestInt());
JSONTEST_ASSERT_EQUAL(1, true_.asUInt());
JSONTEST_ASSERT_EQUAL(1, true_.asLargestUInt());
JSONTEST_ASSERT_EQUAL(1.0, true_.asDouble());
JSONTEST_ASSERT_EQUAL(1.0, true_.asFloat());
JSONTEST_ASSERT_EQUAL(false, false_.asBool());
JSONTEST_ASSERT_EQUAL(0, false_.asInt());
JSONTEST_ASSERT_EQUAL(0, false_.asLargestInt());
JSONTEST_ASSERT_EQUAL(0, false_.asUInt());
JSONTEST_ASSERT_EQUAL(0, false_.asLargestUInt());
JSONTEST_ASSERT_EQUAL(0.0, false_.asDouble());
JSONTEST_ASSERT_EQUAL(0.0, false_.asFloat());
}
@@ -207,6 +304,25 @@ JSONTEST_FIXTURE( ValueTest, integers )
IsCheck checks;
Json::Value val;
// Conversions that don't depend on the value.
JSONTEST_ASSERT(Json::Value(17).isConvertibleTo(Json::realValue));
JSONTEST_ASSERT(Json::Value(17).isConvertibleTo(Json::stringValue));
JSONTEST_ASSERT(Json::Value(17).isConvertibleTo(Json::booleanValue));
JSONTEST_ASSERT(!Json::Value(17).isConvertibleTo(Json::arrayValue));
JSONTEST_ASSERT(!Json::Value(17).isConvertibleTo(Json::objectValue));
JSONTEST_ASSERT(Json::Value(17U).isConvertibleTo(Json::realValue));
JSONTEST_ASSERT(Json::Value(17U).isConvertibleTo(Json::stringValue));
JSONTEST_ASSERT(Json::Value(17U).isConvertibleTo(Json::booleanValue));
JSONTEST_ASSERT(!Json::Value(17U).isConvertibleTo(Json::arrayValue));
JSONTEST_ASSERT(!Json::Value(17U).isConvertibleTo(Json::objectValue));
JSONTEST_ASSERT(Json::Value(17.0).isConvertibleTo(Json::realValue));
JSONTEST_ASSERT(Json::Value(17.0).isConvertibleTo(Json::stringValue));
JSONTEST_ASSERT(Json::Value(17.0).isConvertibleTo(Json::booleanValue));
JSONTEST_ASSERT(!Json::Value(17.0).isConvertibleTo(Json::arrayValue));
JSONTEST_ASSERT(!Json::Value(17.0).isConvertibleTo(Json::objectValue));
// Default int
val = Json::Value(Json::intValue);
@@ -222,12 +338,18 @@ JSONTEST_FIXTURE( ValueTest, integers )
checks.isNumeric_ = true;
JSONTEST_ASSERT_PRED( checkIs( val, checks ) );
JSONTEST_ASSERT(val.isConvertibleTo(Json::nullValue));
JSONTEST_ASSERT(val.isConvertibleTo(Json::intValue));
JSONTEST_ASSERT(val.isConvertibleTo(Json::uintValue));
JSONTEST_ASSERT_EQUAL(0, val.asInt());
JSONTEST_ASSERT_EQUAL(0, val.asLargestInt());
JSONTEST_ASSERT_EQUAL(0, val.asUInt());
JSONTEST_ASSERT_EQUAL(0, val.asLargestUInt());
JSONTEST_ASSERT_EQUAL(0.0, val.asDouble());
JSONTEST_ASSERT_EQUAL(0.0, val.asFloat());
JSONTEST_ASSERT_EQUAL(false, val.asBool());
JSONTEST_ASSERT_STRING_EQUAL("0", val.asString());
// Default uint
val = Json::Value(Json::uintValue);
@@ -244,18 +366,28 @@ JSONTEST_FIXTURE( ValueTest, integers )
checks.isNumeric_ = true;
JSONTEST_ASSERT_PRED( checkIs( val, checks ) );
JSONTEST_ASSERT(val.isConvertibleTo(Json::nullValue));
JSONTEST_ASSERT(val.isConvertibleTo(Json::intValue));
JSONTEST_ASSERT(val.isConvertibleTo(Json::uintValue));
JSONTEST_ASSERT_EQUAL(0, val.asInt());
JSONTEST_ASSERT_EQUAL(0, val.asLargestInt());
JSONTEST_ASSERT_EQUAL(0, val.asUInt());
JSONTEST_ASSERT_EQUAL(0, val.asLargestUInt());
JSONTEST_ASSERT_EQUAL(0.0, val.asDouble());
JSONTEST_ASSERT_EQUAL(0.0, val.asFloat());
JSONTEST_ASSERT_EQUAL(false, val.asBool());
JSONTEST_ASSERT_STRING_EQUAL("0", val.asString());
// Default real
val = Json::Value(Json::realValue);
JSONTEST_ASSERT_EQUAL(Json::realValue, val.type());
JSONTEST_ASSERT(val.isConvertibleTo(Json::nullValue));
JSONTEST_ASSERT(val.isConvertibleTo(Json::intValue));
JSONTEST_ASSERT(val.isConvertibleTo(Json::uintValue));
checks = IsCheck();
checks.isInt_ = true;
checks.isInt64_ = true;
@@ -272,6 +404,8 @@ JSONTEST_FIXTURE( ValueTest, integers )
JSONTEST_ASSERT_EQUAL(0, val.asLargestUInt());
JSONTEST_ASSERT_EQUAL(0.0, val.asDouble());
JSONTEST_ASSERT_EQUAL(0.0, val.asFloat());
JSONTEST_ASSERT_EQUAL(false, val.asBool());
JSONTEST_ASSERT_STRING_EQUAL("0", val.asString());
// Zero (signed constructor arg)
val = Json::Value(0);
@@ -288,12 +422,18 @@ JSONTEST_FIXTURE( ValueTest, integers )
checks.isNumeric_ = true;
JSONTEST_ASSERT_PRED( checkIs( val, checks ) );
JSONTEST_ASSERT(val.isConvertibleTo(Json::nullValue));
JSONTEST_ASSERT(val.isConvertibleTo(Json::intValue));
JSONTEST_ASSERT(val.isConvertibleTo(Json::uintValue));
JSONTEST_ASSERT_EQUAL(0, val.asInt());
JSONTEST_ASSERT_EQUAL(0, val.asLargestInt());
JSONTEST_ASSERT_EQUAL(0, val.asUInt());
JSONTEST_ASSERT_EQUAL(0, val.asLargestUInt());
JSONTEST_ASSERT_EQUAL(0.0, val.asDouble());
JSONTEST_ASSERT_EQUAL(0.0, val.asFloat());
JSONTEST_ASSERT_EQUAL(false, val.asBool());
JSONTEST_ASSERT_STRING_EQUAL("0", val.asString());
// Zero (unsigned constructor arg)
val = Json::Value(0u);
@@ -310,12 +450,18 @@ JSONTEST_FIXTURE( ValueTest, integers )
checks.isNumeric_ = true;
JSONTEST_ASSERT_PRED( checkIs( val, checks ) );
JSONTEST_ASSERT(val.isConvertibleTo(Json::nullValue));
JSONTEST_ASSERT(val.isConvertibleTo(Json::intValue));
JSONTEST_ASSERT(val.isConvertibleTo(Json::uintValue));
JSONTEST_ASSERT_EQUAL(0, val.asInt());
JSONTEST_ASSERT_EQUAL(0, val.asLargestInt());
JSONTEST_ASSERT_EQUAL(0, val.asUInt());
JSONTEST_ASSERT_EQUAL(0, val.asLargestUInt());
JSONTEST_ASSERT_EQUAL(0.0, val.asDouble());
JSONTEST_ASSERT_EQUAL(0.0, val.asFloat());
JSONTEST_ASSERT_EQUAL(false, val.asBool());
JSONTEST_ASSERT_STRING_EQUAL("0", val.asString());
// Zero (floating-point constructor arg)
val = Json::Value(0.0);
@@ -332,12 +478,18 @@ JSONTEST_FIXTURE( ValueTest, integers )
checks.isNumeric_ = true;
JSONTEST_ASSERT_PRED( checkIs( val, checks ) );
JSONTEST_ASSERT(val.isConvertibleTo(Json::nullValue));
JSONTEST_ASSERT(val.isConvertibleTo(Json::intValue));
JSONTEST_ASSERT(val.isConvertibleTo(Json::uintValue));
JSONTEST_ASSERT_EQUAL(0, val.asInt());
JSONTEST_ASSERT_EQUAL(0, val.asLargestInt());
JSONTEST_ASSERT_EQUAL(0, val.asUInt());
JSONTEST_ASSERT_EQUAL(0, val.asLargestUInt());
JSONTEST_ASSERT_EQUAL(0.0, val.asDouble());
JSONTEST_ASSERT_EQUAL(0.0, val.asFloat());
JSONTEST_ASSERT_EQUAL(false, val.asBool());
JSONTEST_ASSERT_STRING_EQUAL("0", val.asString());
// 2^20 (signed constructor arg)
val = Json::Value(1 << 20);
@@ -354,12 +506,18 @@ JSONTEST_FIXTURE( ValueTest, integers )
checks.isNumeric_ = true;
JSONTEST_ASSERT_PRED( checkIs( val, checks ) );
JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue));
JSONTEST_ASSERT(val.isConvertibleTo(Json::intValue));
JSONTEST_ASSERT(val.isConvertibleTo(Json::uintValue));
JSONTEST_ASSERT_EQUAL((1 << 20), val.asInt());
JSONTEST_ASSERT_EQUAL((1 << 20), val.asLargestInt());
JSONTEST_ASSERT_EQUAL((1 << 20), val.asUInt());
JSONTEST_ASSERT_EQUAL((1 << 20), val.asLargestUInt());
JSONTEST_ASSERT_EQUAL((1 << 20), val.asDouble());
JSONTEST_ASSERT_EQUAL((1 << 20), val.asFloat());
JSONTEST_ASSERT_EQUAL(true, val.asBool());
JSONTEST_ASSERT_STRING_EQUAL("1048576", val.asString());
// 2^20 (unsigned constructor arg)
val = Json::Value(1u << 20);
@@ -376,12 +534,18 @@ JSONTEST_FIXTURE( ValueTest, integers )
checks.isNumeric_ = true;
JSONTEST_ASSERT_PRED( checkIs( val, checks ) );
JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue));
JSONTEST_ASSERT(val.isConvertibleTo(Json::intValue));
JSONTEST_ASSERT(val.isConvertibleTo(Json::uintValue));
JSONTEST_ASSERT_EQUAL((1 << 20), val.asInt());
JSONTEST_ASSERT_EQUAL((1 << 20), val.asLargestInt());
JSONTEST_ASSERT_EQUAL((1 << 20), val.asUInt());
JSONTEST_ASSERT_EQUAL((1 << 20), val.asLargestUInt());
JSONTEST_ASSERT_EQUAL((1 << 20), val.asDouble());
JSONTEST_ASSERT_EQUAL((1 << 20), val.asFloat());
JSONTEST_ASSERT_EQUAL(true, val.asBool());
JSONTEST_ASSERT_STRING_EQUAL("1048576", val.asString());
// 2^20 (floating-point constructor arg)
val = Json::Value((1 << 20) / 1.0);
@@ -398,12 +562,18 @@ JSONTEST_FIXTURE( ValueTest, integers )
checks.isNumeric_ = true;
JSONTEST_ASSERT_PRED( checkIs( val, checks ) );
JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue));
JSONTEST_ASSERT(val.isConvertibleTo(Json::intValue));
JSONTEST_ASSERT(val.isConvertibleTo(Json::uintValue));
JSONTEST_ASSERT_EQUAL((1 << 20), val.asInt());
JSONTEST_ASSERT_EQUAL((1 << 20), val.asLargestInt());
JSONTEST_ASSERT_EQUAL((1 << 20), val.asUInt());
JSONTEST_ASSERT_EQUAL((1 << 20), val.asLargestUInt());
JSONTEST_ASSERT_EQUAL((1 << 20), val.asDouble());
JSONTEST_ASSERT_EQUAL((1 << 20), val.asFloat());
JSONTEST_ASSERT_EQUAL(true, val.asBool());
JSONTEST_ASSERT_STRING_EQUAL("1.04858e+06", val.asString());
// -2^20
val = Json::Value(-(1 << 20));
@@ -418,10 +588,16 @@ JSONTEST_FIXTURE( ValueTest, integers )
checks.isNumeric_ = true;
JSONTEST_ASSERT_PRED( checkIs( val, checks ) );
JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue));
JSONTEST_ASSERT(val.isConvertibleTo(Json::intValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::uintValue));
JSONTEST_ASSERT_EQUAL(-(1 << 20), val.asInt());
JSONTEST_ASSERT_EQUAL(-(1 << 20), val.asLargestInt());
JSONTEST_ASSERT_EQUAL(-(1 << 20), val.asDouble());
JSONTEST_ASSERT_EQUAL(-(1 << 20), val.asFloat());
JSONTEST_ASSERT_EQUAL(true, val.asBool());
JSONTEST_ASSERT_STRING_EQUAL("-1048576", val.asString());
// int32 max
val = Json::Value(kint32max);
@@ -438,12 +614,18 @@ JSONTEST_FIXTURE( ValueTest, integers )
checks.isNumeric_ = true;
JSONTEST_ASSERT_PRED( checkIs( val, checks ) );
JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue));
JSONTEST_ASSERT(val.isConvertibleTo(Json::intValue));
JSONTEST_ASSERT(val.isConvertibleTo(Json::uintValue));
JSONTEST_ASSERT_EQUAL(kint32max, val.asInt());
JSONTEST_ASSERT_EQUAL(kint32max, val.asLargestInt());
JSONTEST_ASSERT_EQUAL(kint32max, val.asUInt());
JSONTEST_ASSERT_EQUAL(kint32max, val.asLargestUInt());
JSONTEST_ASSERT_EQUAL(kint32max, val.asDouble());
JSONTEST_ASSERT_EQUAL(kint32max, val.asFloat());
JSONTEST_ASSERT_EQUAL(true, val.asBool());
JSONTEST_ASSERT_STRING_EQUAL("2147483647", val.asString());
// int32 min
val = Json::Value(kint32min);
@@ -458,10 +640,16 @@ JSONTEST_FIXTURE( ValueTest, integers )
checks.isNumeric_ = true;
JSONTEST_ASSERT_PRED( checkIs( val, checks ) );
JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue));
JSONTEST_ASSERT(val.isConvertibleTo(Json::intValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::uintValue));
JSONTEST_ASSERT_EQUAL(kint32min, val.asInt());
JSONTEST_ASSERT_EQUAL(kint32min, val.asLargestInt());
JSONTEST_ASSERT_EQUAL(kint32min, val.asDouble());
JSONTEST_ASSERT_EQUAL(kint32min, val.asFloat());
JSONTEST_ASSERT_EQUAL(true, val.asBool());
JSONTEST_ASSERT_STRING_EQUAL("-2147483648", val.asString());
// uint32 max
val = Json::Value(kuint32max);
@@ -477,6 +665,10 @@ JSONTEST_FIXTURE( ValueTest, integers )
checks.isNumeric_ = true;
JSONTEST_ASSERT_PRED( checkIs( val, checks ) );
JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::intValue));
JSONTEST_ASSERT(val.isConvertibleTo(Json::uintValue));
#ifndef JSON_NO_INT64
JSONTEST_ASSERT_EQUAL(kuint32max, val.asLargestInt());
#endif
@@ -484,6 +676,8 @@ JSONTEST_FIXTURE( ValueTest, integers )
JSONTEST_ASSERT_EQUAL(kuint32max, val.asLargestUInt());
JSONTEST_ASSERT_EQUAL(kuint32max, val.asDouble());
JSONTEST_ASSERT_EQUAL(kuint32max, val.asFloat());
JSONTEST_ASSERT_EQUAL(true, val.asBool());
JSONTEST_ASSERT_STRING_EQUAL("4294967295", val.asString());
#ifdef JSON_NO_INT64
// int64 max
@@ -496,8 +690,14 @@ JSONTEST_FIXTURE( ValueTest, integers )
checks.isNumeric_ = true;
JSONTEST_ASSERT_PRED( checkIs( val, checks ) );
JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::intValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::uintValue));
JSONTEST_ASSERT_EQUAL(double(kint64max), val.asDouble());
JSONTEST_ASSERT_EQUAL(float(kint64max), val.asFloat());
JSONTEST_ASSERT_EQUAL(true, val.asBool());
JSONTEST_ASSERT_STRING_EQUAL("9.22337204e18", val.asString());
// int64 min
val = Json::Value(double(kint64min));
@@ -509,8 +709,14 @@ JSONTEST_FIXTURE( ValueTest, integers )
checks.isNumeric_ = true;
JSONTEST_ASSERT_PRED( checkIs( val, checks ) );
JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::intValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::uintValue));
JSONTEST_ASSERT_EQUAL(double(kint64min), val.asDouble());
JSONTEST_ASSERT_EQUAL(float(kint64min), val.asFloat());
JSONTEST_ASSERT_EQUAL(true, val.asBool());
JSONTEST_ASSERT_STRING_EQUAL("-9.22337204e18", val.asString());
// uint64 max
val = Json::Value(double(kuint64max));
@@ -522,8 +728,14 @@ JSONTEST_FIXTURE( ValueTest, integers )
checks.isNumeric_ = true;
JSONTEST_ASSERT_PRED( checkIs( val, checks ) );
JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::intValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::uintValue));
JSONTEST_ASSERT_EQUAL(double(kuint64max), val.asDouble());
JSONTEST_ASSERT_EQUAL(float(kuint64max), val.asFloat());
JSONTEST_ASSERT_EQUAL(true, val.asBool());
JSONTEST_ASSERT_STRING_EQUAL("1.84467441e19", val.asString());
#else // ifdef JSON_NO_INT64
// 2^40 (signed constructor arg)
val = Json::Value(1LL << 40);
@@ -538,12 +750,18 @@ JSONTEST_FIXTURE( ValueTest, integers )
checks.isNumeric_ = true;
JSONTEST_ASSERT_PRED( checkIs( val, checks ) );
JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::intValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::uintValue));
JSONTEST_ASSERT_EQUAL((1LL << 40), val.asInt64());
JSONTEST_ASSERT_EQUAL((1LL << 40), val.asLargestInt());
JSONTEST_ASSERT_EQUAL((1LL << 40), val.asUInt64());
JSONTEST_ASSERT_EQUAL((1LL << 40), val.asLargestUInt());
JSONTEST_ASSERT_EQUAL((1LL << 40), val.asDouble());
JSONTEST_ASSERT_EQUAL((1LL << 40), val.asFloat());
JSONTEST_ASSERT_EQUAL(true, val.asBool());
JSONTEST_ASSERT_STRING_EQUAL("1099511627776", val.asString());
// 2^40 (unsigned constructor arg)
val = Json::Value(1ULL << 40);
@@ -558,12 +776,18 @@ JSONTEST_FIXTURE( ValueTest, integers )
checks.isNumeric_ = true;
JSONTEST_ASSERT_PRED( checkIs( val, checks ) );
JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::intValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::uintValue));
JSONTEST_ASSERT_EQUAL((1LL << 40), val.asInt64());
JSONTEST_ASSERT_EQUAL((1LL << 40), val.asLargestInt());
JSONTEST_ASSERT_EQUAL((1LL << 40), val.asUInt64());
JSONTEST_ASSERT_EQUAL((1LL << 40), val.asLargestUInt());
JSONTEST_ASSERT_EQUAL((1LL << 40), val.asDouble());
JSONTEST_ASSERT_EQUAL((1LL << 40), val.asFloat());
JSONTEST_ASSERT_EQUAL(true, val.asBool());
JSONTEST_ASSERT_STRING_EQUAL("1099511627776", val.asString());
// 2^40 (floating-point constructor arg)
val = Json::Value((1LL << 40) / 1.0);
@@ -578,12 +802,18 @@ JSONTEST_FIXTURE( ValueTest, integers )
checks.isNumeric_ = true;
JSONTEST_ASSERT_PRED( checkIs( val, checks ) );
JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::intValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::uintValue));
JSONTEST_ASSERT_EQUAL((1LL << 40), val.asInt64());
JSONTEST_ASSERT_EQUAL((1LL << 40), val.asLargestInt());
JSONTEST_ASSERT_EQUAL((1LL << 40), val.asUInt64());
JSONTEST_ASSERT_EQUAL((1LL << 40), val.asLargestUInt());
JSONTEST_ASSERT_EQUAL((1LL << 40), val.asDouble());
JSONTEST_ASSERT_EQUAL((1LL << 40), val.asFloat());
JSONTEST_ASSERT_EQUAL(true, val.asBool());
JSONTEST_ASSERT_STRING_EQUAL("1.09951e+12", val.asString());
// -2^40
val = Json::Value(-(1LL << 40));
@@ -597,10 +827,16 @@ JSONTEST_FIXTURE( ValueTest, integers )
checks.isNumeric_ = true;
JSONTEST_ASSERT_PRED( checkIs( val, checks ) );
JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::intValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::uintValue));
JSONTEST_ASSERT_EQUAL(-(1LL << 40), val.asInt64());
JSONTEST_ASSERT_EQUAL(-(1LL << 40), val.asLargestInt());
JSONTEST_ASSERT_EQUAL(-(1LL << 40), val.asDouble());
JSONTEST_ASSERT_EQUAL(-(1LL << 40), val.asFloat());
JSONTEST_ASSERT_EQUAL(true, val.asBool());
JSONTEST_ASSERT_STRING_EQUAL("-1099511627776", val.asString());
// int64 max
val = Json::Value(Json::Int64(kint64max));
@@ -615,12 +851,18 @@ JSONTEST_FIXTURE( ValueTest, integers )
checks.isNumeric_ = true;
JSONTEST_ASSERT_PRED( checkIs( val, checks ) );
JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::intValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::uintValue));
JSONTEST_ASSERT_EQUAL(kint64max, val.asInt64());
JSONTEST_ASSERT_EQUAL(kint64max, val.asLargestInt());
JSONTEST_ASSERT_EQUAL(kint64max, val.asUInt64());
JSONTEST_ASSERT_EQUAL(kint64max, val.asLargestUInt());
JSONTEST_ASSERT_EQUAL(double(kint64max), val.asDouble());
JSONTEST_ASSERT_EQUAL(float(kint64max), val.asFloat());
JSONTEST_ASSERT_EQUAL(true, val.asBool());
JSONTEST_ASSERT_STRING_EQUAL("9223372036854775807", val.asString());
// int64 max (floating point constructor). Note that kint64max is not exactly
// representable as a double, and will be rounded up to be higher.
@@ -635,10 +877,16 @@ JSONTEST_FIXTURE( ValueTest, integers )
checks.isNumeric_ = true;
JSONTEST_ASSERT_PRED( checkIs( val, checks ) );
JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::intValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::uintValue));
JSONTEST_ASSERT_EQUAL(9223372036854775808ULL, val.asUInt64());
JSONTEST_ASSERT_EQUAL(9223372036854775808ULL, val.asLargestUInt());
JSONTEST_ASSERT_EQUAL(9223372036854775808ULL, val.asDouble());
JSONTEST_ASSERT_EQUAL(9223372036854775808ULL, val.asFloat());
JSONTEST_ASSERT_EQUAL(true, val.asBool());
JSONTEST_ASSERT_STRING_EQUAL("9.22337e+18", val.asString());
// int64 min
val = Json::Value(Json::Int64(kint64min));
@@ -652,10 +900,16 @@ JSONTEST_FIXTURE( ValueTest, integers )
checks.isNumeric_ = true;
JSONTEST_ASSERT_PRED( checkIs( val, checks ) );
JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::intValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::uintValue));
JSONTEST_ASSERT_EQUAL(kint64min, val.asInt64());
JSONTEST_ASSERT_EQUAL(kint64min, val.asLargestInt());
JSONTEST_ASSERT_EQUAL(double(kint64min), val.asDouble());
JSONTEST_ASSERT_EQUAL(float(kint64min), val.asFloat());
JSONTEST_ASSERT_EQUAL(true, val.asBool());
JSONTEST_ASSERT_STRING_EQUAL("-9223372036854775808", val.asString());
// int64 min (floating point constructor). Note that kint64min *is* exactly
// representable as a double.
@@ -670,10 +924,16 @@ JSONTEST_FIXTURE( ValueTest, integers )
checks.isNumeric_ = true;
JSONTEST_ASSERT_PRED( checkIs( val, checks ) );
JSONTEST_ASSERT_EQUAL(-9223372036854775808LL, val.asInt64());
JSONTEST_ASSERT_EQUAL(-9223372036854775808LL, val.asLargestInt());
JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::intValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::uintValue));
JSONTEST_ASSERT_EQUAL(kint64min, val.asInt64());
JSONTEST_ASSERT_EQUAL(kint64min, val.asLargestInt());
JSONTEST_ASSERT_EQUAL(-9223372036854775808.0, val.asDouble());
JSONTEST_ASSERT_EQUAL(-9223372036854775808.0, val.asFloat());
JSONTEST_ASSERT_EQUAL(true, val.asBool());
JSONTEST_ASSERT_STRING_EQUAL("-9.22337e+18", val.asString());
// uint64 max
val = Json::Value(Json::UInt64(kuint64max));
@@ -687,10 +947,16 @@ JSONTEST_FIXTURE( ValueTest, integers )
checks.isNumeric_ = true;
JSONTEST_ASSERT_PRED( checkIs( val, checks ) );
JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::intValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::uintValue));
JSONTEST_ASSERT_EQUAL(kuint64max, val.asUInt64());
JSONTEST_ASSERT_EQUAL(kuint64max, val.asLargestUInt());
JSONTEST_ASSERT_EQUAL(double(kuint64max), val.asDouble());
JSONTEST_ASSERT_EQUAL(float(kuint64max), val.asFloat());
JSONTEST_ASSERT_EQUAL(true, val.asBool());
JSONTEST_ASSERT_STRING_EQUAL("18446744073709551615", val.asString());
// uint64 max (floating point constructor). Note that kuint64max is not
// exactly representable as a double, and will be rounded up to be higher.
@@ -703,8 +969,14 @@ JSONTEST_FIXTURE( ValueTest, integers )
checks.isNumeric_ = true;
JSONTEST_ASSERT_PRED( checkIs( val, checks ) );
JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::intValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::uintValue));
JSONTEST_ASSERT_EQUAL(18446744073709551616.0, val.asDouble());
JSONTEST_ASSERT_EQUAL(18446744073709551616.0, val.asFloat());
JSONTEST_ASSERT_EQUAL(true, val.asBool());
JSONTEST_ASSERT_STRING_EQUAL("1.84467e+19", val.asString());
#endif
}
@@ -714,8 +986,8 @@ JSONTEST_FIXTURE( ValueTest, nonIntegers )
IsCheck checks;
Json::Value val;
// Positive number
val = Json::Value(0.25);
// Small positive number
val = Json::Value(1.5);
JSONTEST_ASSERT_EQUAL(Json::realValue, val.type());
@@ -724,11 +996,26 @@ JSONTEST_FIXTURE( ValueTest, nonIntegers )
checks.isNumeric_ = true;
JSONTEST_ASSERT_PRED( checkIs( val, checks ) );
JSONTEST_ASSERT_EQUAL(0.25, val.asDouble());
JSONTEST_ASSERT_EQUAL(0.25, val.asFloat());
JSONTEST_ASSERT(val.isConvertibleTo(Json::intValue));
JSONTEST_ASSERT(val.isConvertibleTo(Json::uintValue));
JSONTEST_ASSERT(val.isConvertibleTo(Json::realValue));
JSONTEST_ASSERT(val.isConvertibleTo(Json::booleanValue));
JSONTEST_ASSERT(val.isConvertibleTo(Json::stringValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::arrayValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::objectValue));
// Negative number
val = Json::Value(-0.25);
JSONTEST_ASSERT_EQUAL(1.5, val.asDouble());
JSONTEST_ASSERT_EQUAL(1.5, val.asFloat());
JSONTEST_ASSERT_EQUAL(1, val.asInt());
JSONTEST_ASSERT_EQUAL(1, val.asLargestInt());
JSONTEST_ASSERT_EQUAL(1, val.asUInt());
JSONTEST_ASSERT_EQUAL(1, val.asLargestUInt());
JSONTEST_ASSERT_EQUAL(true, val.asBool());
JSONTEST_ASSERT_EQUAL("1.5", val.asString());
// Small negative number
val = Json::Value(-1.5);
JSONTEST_ASSERT_EQUAL(Json::realValue, val.type());
@@ -737,8 +1024,105 @@ JSONTEST_FIXTURE( ValueTest, nonIntegers )
checks.isNumeric_ = true;
JSONTEST_ASSERT_PRED( checkIs( val, checks ) );
JSONTEST_ASSERT_EQUAL(-0.25, val.asDouble());
JSONTEST_ASSERT_EQUAL(-0.25, val.asFloat());
JSONTEST_ASSERT(val.isConvertibleTo(Json::intValue));
JSONTEST_ASSERT(val.isConvertibleTo(Json::realValue));
JSONTEST_ASSERT(val.isConvertibleTo(Json::booleanValue));
JSONTEST_ASSERT(val.isConvertibleTo(Json::stringValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::uintValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::arrayValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::objectValue));
JSONTEST_ASSERT_EQUAL(-1.5, val.asDouble());
JSONTEST_ASSERT_EQUAL(-1.5, val.asFloat());
JSONTEST_ASSERT_EQUAL(-1, val.asInt());
JSONTEST_ASSERT_EQUAL(-1, val.asLargestInt());
JSONTEST_ASSERT_EQUAL(true, val.asBool());
JSONTEST_ASSERT_EQUAL("-1.5", val.asString());
// A bit over int32 max
val = Json::Value(kint32max + 0.5);
JSONTEST_ASSERT_EQUAL(Json::realValue, val.type());
checks = IsCheck();
checks.isDouble_ = true;
checks.isNumeric_ = true;
JSONTEST_ASSERT_PRED( checkIs( val, checks ) );
JSONTEST_ASSERT(val.isConvertibleTo(Json::uintValue));
JSONTEST_ASSERT(val.isConvertibleTo(Json::realValue));
JSONTEST_ASSERT(val.isConvertibleTo(Json::booleanValue));
JSONTEST_ASSERT(val.isConvertibleTo(Json::stringValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::intValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::arrayValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::objectValue));
JSONTEST_ASSERT_EQUAL(2147483647.5, val.asDouble());
JSONTEST_ASSERT_EQUAL(float(2147483647.5), val.asFloat());
JSONTEST_ASSERT_EQUAL(2147483647U, val.asUInt());
#ifdef JSON_HAS_INT64
JSONTEST_ASSERT_EQUAL(2147483647L, val.asLargestInt());
JSONTEST_ASSERT_EQUAL(2147483647U, val.asLargestUInt());
#endif
JSONTEST_ASSERT_EQUAL(true, val.asBool());
JSONTEST_ASSERT_EQUAL("2.14748e+09", val.asString());
// A bit under int32 min
val = Json::Value(kint32min - 0.5);
JSONTEST_ASSERT_EQUAL(Json::realValue, val.type());
checks = IsCheck();
checks.isDouble_ = true;
checks.isNumeric_ = true;
JSONTEST_ASSERT_PRED( checkIs( val, checks ) );
JSONTEST_ASSERT(val.isConvertibleTo(Json::realValue));
JSONTEST_ASSERT(val.isConvertibleTo(Json::booleanValue));
JSONTEST_ASSERT(val.isConvertibleTo(Json::stringValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::intValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::uintValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::arrayValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::objectValue));
JSONTEST_ASSERT_EQUAL(-2147483648.5, val.asDouble());
JSONTEST_ASSERT_EQUAL(float(-2147483648.5), val.asFloat());
#ifdef JSON_HAS_INT64
JSONTEST_ASSERT_EQUAL(-2147483648LL, val.asLargestInt());
#endif
JSONTEST_ASSERT_EQUAL(true, val.asBool());
JSONTEST_ASSERT_EQUAL("-2.14748e+09", val.asString());
// A bit over uint32 max
val = Json::Value(kuint32max + 0.5);
JSONTEST_ASSERT_EQUAL(Json::realValue, val.type());
checks = IsCheck();
checks.isDouble_ = true;
checks.isNumeric_ = true;
JSONTEST_ASSERT_PRED( checkIs( val, checks ) );
JSONTEST_ASSERT(val.isConvertibleTo(Json::realValue));
JSONTEST_ASSERT(val.isConvertibleTo(Json::booleanValue));
JSONTEST_ASSERT(val.isConvertibleTo(Json::stringValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::nullValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::intValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::uintValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::arrayValue));
JSONTEST_ASSERT(!val.isConvertibleTo(Json::objectValue));
JSONTEST_ASSERT_EQUAL(4294967295.5, val.asDouble());
JSONTEST_ASSERT_EQUAL(float(4294967295.5), val.asFloat());
#ifdef JSON_HAS_INT64
JSONTEST_ASSERT_EQUAL(4294967295LL, val.asLargestInt());
JSONTEST_ASSERT_EQUAL(4294967295ULL, val.asLargestUInt());
#endif
JSONTEST_ASSERT_EQUAL(true, val.asBool());
JSONTEST_ASSERT_EQUAL("4.29497e+09", val.asString());
}