AK: Avoid implicit conversions in TypeErasedParameter::to_size()
Refactor to a visitor+functor pattern that does an explicit static_cast to size_t after performing suitable range checks for each type.
This commit is contained in:
parent
762b92c650
commit
74e8aa73e5
Notes:
sideshowbarker
2024-07-18 01:07:52 +09:00
Author: https://github.com/ADKaster Commit: https://github.com/SerenityOS/serenity/commit/74e8aa73e5a Pull-request: https://github.com/SerenityOS/serenity/pull/10737 Reviewed-by: https://github.com/BenWiederhake Reviewed-by: https://github.com/PeterBindels-TomTom Reviewed-by: https://github.com/awesomekling Reviewed-by: https://github.com/dascandy Reviewed-by: https://github.com/trflynn89
1 changed files with 32 additions and 24 deletions
56
AK/Format.h
56
AK/Format.h
|
@ -85,32 +85,40 @@ struct TypeErasedParameter {
|
||||||
return Type::Custom;
|
return Type::Custom;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename Visitor>
|
||||||
|
constexpr auto visit(Visitor&& visitor) const
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case TypeErasedParameter::Type::UInt8:
|
||||||
|
return visitor(*static_cast<const u8*>(value));
|
||||||
|
case TypeErasedParameter::Type::UInt16:
|
||||||
|
return visitor(*static_cast<const u16*>(value));
|
||||||
|
case TypeErasedParameter::Type::UInt32:
|
||||||
|
return visitor(*static_cast<const u32*>(value));
|
||||||
|
case TypeErasedParameter::Type::UInt64:
|
||||||
|
return visitor(*static_cast<const u64*>(value));
|
||||||
|
case TypeErasedParameter::Type::Int8:
|
||||||
|
return visitor(*static_cast<const i8*>(value));
|
||||||
|
case TypeErasedParameter::Type::Int16:
|
||||||
|
return visitor(*static_cast<const i16*>(value));
|
||||||
|
case TypeErasedParameter::Type::Int32:
|
||||||
|
return visitor(*static_cast<const i32*>(value));
|
||||||
|
case TypeErasedParameter::Type::Int64:
|
||||||
|
return visitor(*static_cast<const i64*>(value));
|
||||||
|
default:
|
||||||
|
TODO();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
constexpr size_t to_size() const
|
constexpr size_t to_size() const
|
||||||
{
|
{
|
||||||
i64 svalue;
|
return visit([]<typename T>(T value) {
|
||||||
|
if constexpr (sizeof(T) > sizeof(size_t))
|
||||||
if (type == TypeErasedParameter::Type::UInt8)
|
VERIFY(value < NumericLimits<size_t>::max());
|
||||||
svalue = *static_cast<const u8*>(value);
|
if constexpr (IsSigned<T>)
|
||||||
else if (type == TypeErasedParameter::Type::UInt16)
|
VERIFY(value > 0);
|
||||||
svalue = *static_cast<const u16*>(value);
|
return static_cast<size_t>(value);
|
||||||
else if (type == TypeErasedParameter::Type::UInt32)
|
});
|
||||||
svalue = *static_cast<const u32*>(value);
|
|
||||||
else if (type == TypeErasedParameter::Type::UInt64)
|
|
||||||
svalue = *static_cast<const u64*>(value);
|
|
||||||
else if (type == TypeErasedParameter::Type::Int8)
|
|
||||||
svalue = *static_cast<const i8*>(value);
|
|
||||||
else if (type == TypeErasedParameter::Type::Int16)
|
|
||||||
svalue = *static_cast<const i16*>(value);
|
|
||||||
else if (type == TypeErasedParameter::Type::Int32)
|
|
||||||
svalue = *static_cast<const i32*>(value);
|
|
||||||
else if (type == TypeErasedParameter::Type::Int64)
|
|
||||||
svalue = *static_cast<const i64*>(value);
|
|
||||||
else
|
|
||||||
VERIFY_NOT_REACHED();
|
|
||||||
|
|
||||||
VERIFY(svalue >= 0);
|
|
||||||
|
|
||||||
return static_cast<size_t>(svalue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Getters and setters.
|
// FIXME: Getters and setters.
|
||||||
|
|
Loading…
Add table
Reference in a new issue