Changed integer storage from positive/negative to signed/unsigned

This commit is contained in:
Benoit Blanchon
2021-04-14 11:42:53 +02:00
parent a002393716
commit fc4f5fd05f
16 changed files with 251 additions and 171 deletions

View File

@@ -57,16 +57,16 @@ struct Comparer<T, typename enable_if<is_integral<T>::value ||
return arithmeticCompare(lhs, rhs);
}
CompareResult visitNegativeInteger(UInt lhs) {
return arithmeticCompareNegateLeft(lhs, rhs);
CompareResult visitSignedInteger(Integer lhs) {
return arithmeticCompare(lhs, rhs);
}
CompareResult visitPositiveInteger(UInt lhs) {
CompareResult visitUnsignedInteger(UInt lhs) {
return arithmeticCompare(lhs, rhs);
}
CompareResult visitBoolean(bool lhs) {
return visitPositiveInteger(static_cast<UInt>(lhs));
return visitUnsignedInteger(static_cast<UInt>(lhs));
}
};
@@ -96,28 +96,6 @@ struct ArrayComparer : ComparerBase {
}
};
struct NegativeIntegerComparer : ComparerBase {
UInt _rhs;
explicit NegativeIntegerComparer(UInt rhs) : _rhs(rhs) {}
CompareResult visitFloat(Float lhs) {
return arithmeticCompareNegateRight(lhs, _rhs);
}
CompareResult visitNegativeInteger(UInt lhs) {
return arithmeticCompare(_rhs, lhs);
}
CompareResult visitPositiveInteger(UInt) {
return COMPARE_RESULT_GREATER;
}
CompareResult visitBoolean(bool) {
return COMPARE_RESULT_GREATER;
}
};
struct ObjectComparer : ComparerBase {
const CollectionData *_rhs;
@@ -182,12 +160,12 @@ struct Comparer<T, typename enable_if<IsVisitable<T>::value>::type>
return accept(comparer);
}
CompareResult visitNegativeInteger(UInt lhs) {
NegativeIntegerComparer comparer(lhs);
CompareResult visitSignedInteger(Integer lhs) {
Comparer<Integer> comparer(lhs);
return accept(comparer);
}
CompareResult visitPositiveInteger(UInt lhs) {
CompareResult visitUnsignedInteger(UInt lhs) {
Comparer<UInt> comparer(lhs);
return accept(comparer);
}

View File

@@ -25,8 +25,8 @@ enum {
// CAUTION: no VALUE_IS_OWNED below
VALUE_IS_BOOLEAN = 0x06,
VALUE_IS_POSITIVE_INTEGER = 0x08,
VALUE_IS_NEGATIVE_INTEGER = 0x0A,
VALUE_IS_UNSIGNED_INTEGER = 0x08,
VALUE_IS_SIGNED_INTEGER = 0x0A,
VALUE_IS_FLOAT = 0x0C,
COLLECTION_MASK = 0x60,
@@ -43,7 +43,9 @@ struct RawData {
union VariantContent {
Float asFloat;
UInt asInteger;
bool asBoolean;
UInt asUnsignedInteger;
Integer asSignedInteger;
CollectionData asCollection;
const char *asString;
struct {

View File

@@ -56,14 +56,14 @@ class VariantData {
case VALUE_IS_LINKED_RAW:
return visitor.visitRawJson(_content.asRaw.data, _content.asRaw.size);
case VALUE_IS_NEGATIVE_INTEGER:
return visitor.visitNegativeInteger(_content.asInteger);
case VALUE_IS_SIGNED_INTEGER:
return visitor.visitSignedInteger(_content.asSignedInteger);
case VALUE_IS_POSITIVE_INTEGER:
return visitor.visitPositiveInteger(_content.asInteger);
case VALUE_IS_UNSIGNED_INTEGER:
return visitor.visitUnsignedInteger(_content.asUnsignedInteger);
case VALUE_IS_BOOLEAN:
return visitor.visitBoolean(_content.asInteger != 0);
return visitor.visitBoolean(_content.asBoolean != 0);
default:
return visitor.visitNull();
@@ -129,11 +129,11 @@ class VariantData {
template <typename T>
bool isInteger() const {
switch (type()) {
case VALUE_IS_POSITIVE_INTEGER:
return canStorePositiveInteger<T>(_content.asInteger);
case VALUE_IS_UNSIGNED_INTEGER:
return canConvertNumber<T>(_content.asUnsignedInteger);
case VALUE_IS_NEGATIVE_INTEGER:
return canStoreNegativeInteger<T>(_content.asInteger);
case VALUE_IS_SIGNED_INTEGER:
return canConvertNumber<T>(_content.asSignedInteger);
default:
return false;
@@ -141,8 +141,8 @@ class VariantData {
}
bool isFloat() const {
return type() == VALUE_IS_FLOAT || type() == VALUE_IS_POSITIVE_INTEGER ||
type() == VALUE_IS_NEGATIVE_INTEGER;
return type() == VALUE_IS_FLOAT || type() == VALUE_IS_UNSIGNED_INTEGER ||
type() == VALUE_IS_SIGNED_INTEGER;
}
bool isString() const {
@@ -174,7 +174,7 @@ class VariantData {
void setBoolean(bool value) {
setType(VALUE_IS_BOOLEAN);
_content.asInteger = static_cast<UInt>(value);
_content.asBoolean = value;
}
void setFloat(Float value) {
@@ -208,36 +208,14 @@ class VariantData {
template <typename T>
typename enable_if<is_unsigned<T>::value>::type setInteger(T value) {
setUnsignedInteger(value);
setType(VALUE_IS_UNSIGNED_INTEGER);
_content.asUnsignedInteger = static_cast<UInt>(value);
}
template <typename T>
typename enable_if<is_signed<T>::value>::type setInteger(T value) {
setSignedInteger(value);
}
template <typename T>
void setSignedInteger(T value) {
if (value >= 0) {
setPositiveInteger(static_cast<UInt>(value));
} else {
setNegativeInteger(~static_cast<UInt>(value) + 1);
}
}
void setUnsignedInteger(UInt value) {
setType(VALUE_IS_POSITIVE_INTEGER);
_content.asInteger = static_cast<UInt>(value);
}
void setPositiveInteger(UInt value) {
setType(VALUE_IS_POSITIVE_INTEGER);
_content.asInteger = value;
}
void setNegativeInteger(UInt value) {
setType(VALUE_IS_NEGATIVE_INTEGER);
_content.asInteger = value;
setType(VALUE_IS_SIGNED_INTEGER);
_content.asSignedInteger = value;
}
void setNull() {

View File

@@ -18,16 +18,17 @@ namespace ARDUINOJSON_NAMESPACE {
template <typename T>
inline T VariantData::asIntegral() const {
switch (type()) {
case VALUE_IS_POSITIVE_INTEGER:
case VALUE_IS_BOOLEAN:
return convertPositiveInteger<T>(_content.asInteger);
case VALUE_IS_NEGATIVE_INTEGER:
return convertNegativeInteger<T>(_content.asInteger);
return _content.asBoolean;
case VALUE_IS_UNSIGNED_INTEGER:
return convertNumber<T>(_content.asUnsignedInteger);
case VALUE_IS_SIGNED_INTEGER:
return convertNumber<T>(_content.asSignedInteger);
case VALUE_IS_LINKED_STRING:
case VALUE_IS_OWNED_STRING:
return parseNumber<T>(_content.asString);
case VALUE_IS_FLOAT:
return convertFloat<T>(_content.asFloat);
return convertNumber<T>(_content.asFloat);
default:
return 0;
}
@@ -35,10 +36,11 @@ inline T VariantData::asIntegral() const {
inline bool VariantData::asBoolean() const {
switch (type()) {
case VALUE_IS_POSITIVE_INTEGER:
case VALUE_IS_BOOLEAN:
case VALUE_IS_NEGATIVE_INTEGER:
return _content.asInteger != 0;
return _content.asBoolean;
case VALUE_IS_SIGNED_INTEGER:
case VALUE_IS_UNSIGNED_INTEGER:
return _content.asUnsignedInteger != 0;
case VALUE_IS_FLOAT:
return _content.asFloat != 0;
case VALUE_IS_NULL:
@@ -52,11 +54,12 @@ inline bool VariantData::asBoolean() const {
template <typename T>
inline T VariantData::asFloat() const {
switch (type()) {
case VALUE_IS_POSITIVE_INTEGER:
case VALUE_IS_BOOLEAN:
return static_cast<T>(_content.asInteger);
case VALUE_IS_NEGATIVE_INTEGER:
return -static_cast<T>(_content.asInteger);
return static_cast<T>(_content.asBoolean);
case VALUE_IS_UNSIGNED_INTEGER:
return static_cast<T>(_content.asUnsignedInteger);
case VALUE_IS_SIGNED_INTEGER:
return static_cast<T>(_content.asSignedInteger);
case VALUE_IS_LINKED_STRING:
case VALUE_IS_OWNED_STRING:
return parseNumber<T>(_content.asString);

View File

@@ -26,7 +26,7 @@ struct Visitor {
return TResult();
}
TResult visitNegativeInteger(UInt) {
TResult visitSignedInteger(Integer) {
return TResult();
}
@@ -38,7 +38,7 @@ struct Visitor {
return TResult();
}
TResult visitPositiveInteger(UInt) {
TResult visitUnsignedInteger(UInt) {
return TResult();
}