diff options
author | Andrew Kaster <akaster@serenityos.org> | 2021-10-31 17:11:58 -0600 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-11-14 22:52:35 +0100 |
commit | 74e8aa73e5a5c3156299c581c02aae563edb2388 (patch) | |
tree | b90760c1bfd53833b3c9a8787ae25b61ca83d415 /AK | |
parent | 762b92c650295b4855028fbd5124adb2669a5b93 (diff) | |
download | serenity-74e8aa73e5a5c3156299c581c02aae563edb2388.zip |
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.
Diffstat (limited to 'AK')
-rw-r--r-- | AK/Format.h | 56 |
1 files changed, 32 insertions, 24 deletions
diff --git a/AK/Format.h b/AK/Format.h index cd23a6e577..092088284d 100644 --- a/AK/Format.h +++ b/AK/Format.h @@ -85,32 +85,40 @@ struct TypeErasedParameter { return Type::Custom; } - constexpr size_t to_size() const + template<typename Visitor> + constexpr auto visit(Visitor&& visitor) const { - i64 svalue; - - if (type == TypeErasedParameter::Type::UInt8) - svalue = *static_cast<const u8*>(value); - else if (type == TypeErasedParameter::Type::UInt16) - svalue = *static_cast<const u16*>(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); + 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(); + } + } - return static_cast<size_t>(svalue); + constexpr size_t to_size() const + { + return visit([]<typename T>(T value) { + if constexpr (sizeof(T) > sizeof(size_t)) + VERIFY(value < NumericLimits<size_t>::max()); + if constexpr (IsSigned<T>) + VERIFY(value > 0); + return static_cast<size_t>(value); + }); } // FIXME: Getters and setters. |