mirror of https://github.com/aseprite/aseprite.git
Replace INT/UINT_COMPATIBLE/IS_REDUCIBLE_INT macros w/templates
This commit is contained in:
parent
70a388177d
commit
8f5e8256cf
|
|
@ -1566,20 +1566,26 @@ static void ase_file_write_property_value(FILE* f,
|
|||
case USER_DATA_PROPERTY_TYPE_VECTOR: {
|
||||
auto& vector = *std::get_if<UserData::Vector>(&value);
|
||||
fputl(vector.size(), f);
|
||||
|
||||
const uint16_t type = doc::all_elements_of_same_type(vector);
|
||||
fputw(type, f);
|
||||
|
||||
for (const auto& elem : vector) {
|
||||
UserData::Variant v = elem;
|
||||
|
||||
// Reduce each element if possible, because each element has
|
||||
// its own type.
|
||||
if (type == 0) {
|
||||
if (IS_REDUCIBLE_INT(v.type())) {
|
||||
if (is_reducible_int(v)) {
|
||||
v = reduce_int_type_size(v);
|
||||
}
|
||||
fputw(v.type(), f);
|
||||
}
|
||||
else if (IS_REDUCIBLE_INT(v.type()) && type < v.type()) {
|
||||
// We need to cast each value to the common type.
|
||||
// Reduce to the smaller/common int type.
|
||||
else if (is_reducible_int(v) && type < v.type()) {
|
||||
v = cast_to_smaller_int_type(v, type);
|
||||
}
|
||||
|
||||
ase_file_write_property_value(f, v);
|
||||
}
|
||||
break;
|
||||
|
|
@ -1587,13 +1593,14 @@ static void ase_file_write_property_value(FILE* f,
|
|||
case USER_DATA_PROPERTY_TYPE_PROPERTIES: {
|
||||
auto& properties = *std::get_if<UserData::Properties>(&value);
|
||||
ASSERT(properties.size() > 0);
|
||||
|
||||
fputl(properties.size(), f);
|
||||
for (auto property : properties) {
|
||||
|
||||
for (const auto& property : properties) {
|
||||
const std::string& name = property.first;
|
||||
ase_file_write_string(f, name);
|
||||
|
||||
UserData::Variant v = property.second;
|
||||
if (IS_REDUCIBLE_INT(v.type())) {
|
||||
if (is_reducible_int(v)) {
|
||||
v = reduce_int_type_size(v);
|
||||
}
|
||||
fputw(v.type(), f);
|
||||
|
|
@ -1619,7 +1626,7 @@ static void ase_file_write_properties_maps(FILE* f, FileOp* fop,
|
|||
fputl(0, f);
|
||||
|
||||
fputl(nmaps, f);
|
||||
for (auto propertiesMap : propertiesMaps) {
|
||||
for (const auto& propertiesMap : propertiesMaps) {
|
||||
const UserData::Properties& properties = propertiesMap.second;
|
||||
// Skip properties map if it doesn't have any property
|
||||
if (properties.empty())
|
||||
|
|
|
|||
|
|
@ -49,14 +49,15 @@ uint16_t all_elements_of_same_type(const UserData::Vector& vector)
|
|||
uint16_t type = vector.empty() ? 0 : vector.front().type();
|
||||
uint16_t commonReducedType = 0;
|
||||
bool hasNegativeNumbers = false;
|
||||
for (auto value : vector) {
|
||||
|
||||
for (const auto& value : vector) {
|
||||
if (type != value.type()) {
|
||||
return 0;
|
||||
}
|
||||
else if (IS_REDUCIBLE_INT(value.type())) {
|
||||
else if (is_reducible_int(value)) {
|
||||
auto t = reduce_int_type_size(value).type();
|
||||
hasNegativeNumbers |= is_negative(value);
|
||||
if (t > commonReducedType) {
|
||||
if (commonReducedType < t) {
|
||||
commonReducedType = t;
|
||||
}
|
||||
}
|
||||
|
|
@ -69,14 +70,16 @@ uint16_t all_elements_of_same_type(const UserData::Vector& vector)
|
|||
// If our common reduced type is unsigned and we have negative numbers
|
||||
// in our vector we should select the next signed type that includes it.
|
||||
if (commonReducedType != 0 &&
|
||||
(commonReducedType & 1) &&
|
||||
(commonReducedType & 1) && // TODO fix this assumption about USER_DATA_PROPERTY_TYPE_* values
|
||||
hasNegativeNumbers) {
|
||||
commonReducedType++;
|
||||
// We couldn't find one type that satisfies all the integers. This shouldn't ever happen.
|
||||
if (commonReducedType >= USER_DATA_PROPERTY_TYPE_UINT64) commonReducedType = 0;
|
||||
// We couldn't find one type that satisfies all the integers. This
|
||||
// shouldn't ever happen.
|
||||
if (commonReducedType >= USER_DATA_PROPERTY_TYPE_UINT64)
|
||||
commonReducedType = 0;
|
||||
}
|
||||
|
||||
return commonReducedType ? commonReducedType : type;
|
||||
return (commonReducedType ? commonReducedType : type);
|
||||
}
|
||||
|
||||
UserData::Variant cast_to_smaller_int_type(const UserData::Variant& value, uint16_t type)
|
||||
|
|
@ -164,50 +167,50 @@ UserData::Variant reduce_int_type_size(const UserData::Variant& value)
|
|||
switch (value.type()) {
|
||||
case USER_DATA_PROPERTY_TYPE_INT16: {
|
||||
auto v = get_value<int16_t>(value);
|
||||
if (INT8_COMPATIBLE(v)) return static_cast<int8_t>(v);
|
||||
else if (UINT8_COMPATIBLE(v)) return static_cast<uint8_t>(v);
|
||||
if (is_compatible_int<int8_t>(v)) return static_cast<int8_t>(v);
|
||||
else if (is_compatible_int<uint8_t>(v)) return static_cast<uint8_t>(v);
|
||||
return v;
|
||||
}
|
||||
case USER_DATA_PROPERTY_TYPE_UINT16: {
|
||||
auto v = get_value<uint16_t>(value);
|
||||
if (INT8_COMPATIBLE(v)) return static_cast<int8_t>(v);
|
||||
else if (UINT8_COMPATIBLE(v)) return static_cast<uint8_t>(v);
|
||||
if (is_compatible_int<int8_t>(v)) return static_cast<int8_t>(v);
|
||||
else if (is_compatible_int<uint8_t>(v)) return static_cast<uint8_t>(v);
|
||||
return v;
|
||||
}
|
||||
case USER_DATA_PROPERTY_TYPE_INT32: {
|
||||
auto v = get_value<int32_t>(value);
|
||||
if (INT8_COMPATIBLE(v)) return static_cast<int8_t>(v);
|
||||
else if (UINT8_COMPATIBLE(v)) return static_cast<uint8_t>(v);
|
||||
else if (INT16_COMPATIBLE(v)) return static_cast<int16_t>(v);
|
||||
else if (UINT16_COMPATIBLE(v)) return static_cast<uint16_t>(v);
|
||||
if (is_compatible_int<int8_t>(v)) return static_cast<int8_t>(v);
|
||||
else if (is_compatible_int<uint8_t>(v)) return static_cast<uint8_t>(v);
|
||||
else if (is_compatible_int<int16_t>(v)) return static_cast<int16_t>(v);
|
||||
else if (is_compatible_int<uint16_t>(v)) return static_cast<uint16_t>(v);
|
||||
return v;
|
||||
}
|
||||
case USER_DATA_PROPERTY_TYPE_UINT32: {
|
||||
auto v = get_value<uint32_t>(value);
|
||||
if (INT8_COMPATIBLE(v)) return static_cast<int8_t>(v);
|
||||
else if (UINT8_COMPATIBLE(v)) return static_cast<uint8_t>(v);
|
||||
else if (INT16_COMPATIBLE(v)) return static_cast<int16_t>(v);
|
||||
else if (UINT16_COMPATIBLE(v)) return static_cast<uint16_t>(v);
|
||||
if (is_compatible_int<int8_t>(v)) return static_cast<int8_t>(v);
|
||||
else if (is_compatible_int<uint8_t>(v)) return static_cast<uint8_t>(v);
|
||||
else if (is_compatible_int<int16_t>(v)) return static_cast<int16_t>(v);
|
||||
else if (is_compatible_int<uint16_t>(v)) return static_cast<uint16_t>(v);
|
||||
return v;
|
||||
}
|
||||
case USER_DATA_PROPERTY_TYPE_INT64: {
|
||||
auto v = get_value<int64_t>(value);
|
||||
if (INT8_COMPATIBLE(v)) return static_cast<int8_t>(v);
|
||||
else if (UINT8_COMPATIBLE(v)) return static_cast<uint8_t>(v);
|
||||
else if (INT16_COMPATIBLE(v)) return static_cast<int16_t>(v);
|
||||
else if (UINT16_COMPATIBLE(v)) return static_cast<uint16_t>(v);
|
||||
else if (INT32_COMPATIBLE(v)) return static_cast<int32_t>(v);
|
||||
else if (UINT32_COMPATIBLE(v)) return static_cast<uint32_t>(v);
|
||||
if (is_compatible_int<int8_t>(v)) return static_cast<int8_t>(v);
|
||||
else if (is_compatible_int<uint8_t>(v)) return static_cast<uint8_t>(v);
|
||||
else if (is_compatible_int<int16_t>(v)) return static_cast<int16_t>(v);
|
||||
else if (is_compatible_int<uint16_t>(v)) return static_cast<uint16_t>(v);
|
||||
else if (is_compatible_int<int32_t>(v)) return static_cast<int32_t>(v);
|
||||
else if (is_compatible_int<uint32_t>(v)) return static_cast<uint32_t>(v);
|
||||
return v;
|
||||
}
|
||||
case USER_DATA_PROPERTY_TYPE_UINT64: {
|
||||
auto v = get_value<uint64_t>(value);
|
||||
if (INT8_COMPATIBLE(v)) return static_cast<int8_t>(v);
|
||||
else if (UINT8_COMPATIBLE(v)) return static_cast<uint8_t>(v);
|
||||
else if (INT16_COMPATIBLE(v)) return static_cast<int16_t>(v);
|
||||
else if (UINT16_COMPATIBLE(v)) return static_cast<uint16_t>(v);
|
||||
else if (INT32_COMPATIBLE(v)) return static_cast<int32_t>(v);
|
||||
else if (UINT32_COMPATIBLE(v)) return static_cast<uint32_t>(v);
|
||||
if (is_compatible_int<int8_t>(v)) return static_cast<int8_t>(v);
|
||||
else if (is_compatible_int<uint8_t>(v)) return static_cast<uint8_t>(v);
|
||||
else if (is_compatible_int<int16_t>(v)) return static_cast<int16_t>(v);
|
||||
else if (is_compatible_int<uint16_t>(v)) return static_cast<uint16_t>(v);
|
||||
else if (is_compatible_int<int32_t>(v)) return static_cast<int32_t>(v);
|
||||
else if (is_compatible_int<uint32_t>(v)) return static_cast<uint32_t>(v);
|
||||
return v;
|
||||
}
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
#include "gfx/rect.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <limits>
|
||||
#include <map>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
|
@ -42,17 +43,6 @@
|
|||
#define USER_DATA_PROPERTY_TYPE_VECTOR 0x0011
|
||||
#define USER_DATA_PROPERTY_TYPE_PROPERTIES 0x0012
|
||||
|
||||
#define INT8_COMPATIBLE(i) i >= -128 && i <= 127
|
||||
#define UINT8_COMPATIBLE(i) i >= 128 && i <= 255
|
||||
#define INT16_COMPATIBLE(i) i >= -32768 && i <= 32767
|
||||
#define UINT16_COMPATIBLE(i) i >= 32768 && i <= 65535
|
||||
// The (int) cast is to make MSVC happy. If we remove it, the condition could
|
||||
// be jumped.
|
||||
#define INT32_COMPATIBLE(i) i >= ((int)-2147483648) && i <= 2147483647
|
||||
#define UINT32_COMPATIBLE(i) i >= 2147483648 && i <= 4294967295
|
||||
|
||||
#define IS_REDUCIBLE_INT(variantType) variantType >= USER_DATA_PROPERTY_TYPE_INT16 && variantType <= USER_DATA_PROPERTY_TYPE_UINT64
|
||||
|
||||
namespace doc {
|
||||
|
||||
class UserData {
|
||||
|
|
@ -158,6 +148,18 @@ namespace doc {
|
|||
return *value;
|
||||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
inline bool is_compatible_int(const U u) {
|
||||
static_assert(sizeof(U) > sizeof(T), "T type must be smaller than U type");
|
||||
return (u >= std::numeric_limits<T>::min() &&
|
||||
u <= std::numeric_limits<T>::max());
|
||||
}
|
||||
|
||||
inline bool is_reducible_int(const UserData::Variant& variant) {
|
||||
return (variant.type() >= USER_DATA_PROPERTY_TYPE_INT16 &&
|
||||
variant.type() <= USER_DATA_PROPERTY_TYPE_UINT64);
|
||||
}
|
||||
|
||||
size_t count_nonempty_properties_maps(const UserData::PropertiesMaps& propertiesMaps);
|
||||
|
||||
// If all the elements of vector have the same type, returns that type, also
|
||||
|
|
|
|||
Loading…
Reference in New Issue