From 99b98bb555967d6ea13293addffdd2a110acfbf0 Mon Sep 17 00:00:00 2001 From: Kp Date: Sat, 14 Jan 2023 19:05:37 +0000 Subject: [PATCH] Rework convert_integer to return result in some cases Prefer returning the result in a std::optional over returning a flag value and taking a non-const reference to the result. --- common/main/nvparse.h | 40 ++++++++++++++++++++++++++------------- similar/main/config.cpp | 11 +++++------ similar/main/playsave.cpp | 33 +++++++++++++++----------------- 3 files changed, 47 insertions(+), 37 deletions(-) diff --git a/common/main/nvparse.h b/common/main/nvparse.h index 095d83459..9f0a3f25e 100644 --- a/common/main/nvparse.h +++ b/common/main/nvparse.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include "dxxsconf.h" #include "ntstring.h" @@ -22,32 +23,45 @@ static inline bool cmp(const char *token, const char *equal, const char (&name)[ return &token[N - 1] == equal && !strncmp(token, name, N - 1); } -template -static inline bool convert_integer(F *f, T &t, const char *value, int base) +template +static inline std::optional convert_integer(const char *value, int base, auto libc_str_to_integer) { char *e; - auto r = (*f)(value, &e, base); + const auto r = libc_str_to_integer(value, &e, base); if (*e) /* Trailing garbage found */ - return false; - T tr = static_cast(r); - if (r != tr) + return std::nullopt; + if constexpr (std::is_same::value) + { + if (r != 0 && r != 1) + return std::nullopt; + } + else if (!std::in_range(r)) /* Result truncated */ - return false; - t = tr; - return true; + return std::nullopt; + return static_cast(r); } template -static inline typename std::enable_if::value, bool>::type convert_integer(T &t, const char *value, int base = 10) +requires(std::is_signed::value) +static inline auto convert_integer(const char *value, int base = 10) { - return convert_integer(strtol, t, value, base); + return convert_integer(value, base, std::strtol); } template -static inline typename std::enable_if::value, bool>::type convert_integer(T &t, const char *value, int base = 10) +requires(std::is_unsigned::value) +static inline auto convert_integer(const char *value, int base = 10) { - return convert_integer(strtoul, t, value, base); + return convert_integer(value, base, std::strtoul); +} + +template +requires(std::is_integral::value) +static inline void convert_integer(T &t, const char *value, int base = 10) +{ + if (auto r = convert_integer(value, base)) + t = *r; } template diff --git a/similar/main/config.cpp b/similar/main/config.cpp index d5e9c673b..c7a3c9eb9 100644 --- a/similar/main/config.cpp +++ b/similar/main/config.cpp @@ -171,9 +171,9 @@ int ReadConfigFile() convert_integer(GameCfg.MusicType, value); else if (cmp(lb, eq, CMLevelMusicPlayOrderStr)) { - unsigned CMLevelMusicPlayOrder; - if (convert_integer(CMLevelMusicPlayOrder, value) && CMLevelMusicPlayOrder <= static_cast(LevelMusicPlayOrder::Random)) - CGameCfg.CMLevelMusicPlayOrder = static_cast(CMLevelMusicPlayOrder); + if (auto r = convert_integer(value)) + if (auto CMLevelMusicPlayOrder = *r; CMLevelMusicPlayOrder <= static_cast(LevelMusicPlayOrder::Random)) + CGameCfg.CMLevelMusicPlayOrder = LevelMusicPlayOrder{CMLevelMusicPlayOrder}; } else if (cmp(lb, eq, CMLevelMusicTrack0Str)) convert_integer(CGameCfg.CMLevelMusicTrack[0], value); @@ -212,10 +212,9 @@ int ReadConfigFile() convert_integer(CGameCfg.WindowMode, value); else if (cmp(lb, eq, TexFiltStr)) { - uint8_t TexFilt; - if (convert_integer(TexFilt, value)) + if (auto r = convert_integer(value)) { - switch (TexFilt) + switch (const auto TexFilt = *r) { case static_cast(opengl_texture_filter::classic): case static_cast(opengl_texture_filter::upscale): diff --git a/similar/main/playsave.cpp b/similar/main/playsave.cpp index c29040ca7..c6f68633a 100644 --- a/similar/main/playsave.cpp +++ b/similar/main/playsave.cpp @@ -1622,10 +1622,9 @@ static int get_lifetime_checksum (int a,int b) template static void convert_duplicate_powerup_integer(packed_netduplicate_items &d, const char *value) { - /* Initialize 'i' to avoid bogus -Wmaybe-uninitialized at -Og on - * gcc-4.9 */ - unsigned i = 0; - if (convert_integer(i, value) && !(i & ~((1 << width) - 1))) + if (auto r = convert_integer(value); !r) + return; + else if (const auto i = *r; !(i & ~((1 << width) - 1))) d.set_sub_field(i); } } @@ -1658,23 +1657,23 @@ void read_netgame_profile(netgame_info *ng) convert_string(ng->game_name, value, eol); else if (cmp(lb, eq, GameModeStr)) { - uint8_t gamemode; - if (convert_integer(gamemode, value)) - ng->gamemode = network_game_type{gamemode}; + if (auto gamemode = convert_integer(value)) + ng->gamemode = network_game_type{*gamemode}; } else if (cmp(lb, eq, RefusePlayersStr)) convert_integer(ng->RefusePlayers, value); else if (cmp(lb, eq, DifficultyStr)) { - uint8_t difficulty; - if (convert_integer(difficulty, value)) - ng->difficulty = cast_clamp_difficulty(difficulty); + if (auto difficulty = convert_integer(value)) + ng->difficulty = cast_clamp_difficulty(*difficulty); } else if (cmp(lb, eq, GameFlagsStr)) { - packed_game_flags p; - if (convert_integer(p.value, value)) + if (auto r = convert_integer(value)) + { + const packed_game_flags p{*r}; ng->game_flag = unpack_game_flags(&p); + } } else if (cmp(lb, eq, AllowedItemsStr)) convert_integer(ng->AllowedItems, value); @@ -1716,9 +1715,8 @@ void read_netgame_profile(netgame_info *ng) convert_integer(ng->KillGoal, value); else if (cmp(lb, eq, PlayTimeAllowedStr)) { - int PlayTimeAllowed; - if (convert_integer(PlayTimeAllowed, value)) - ng->PlayTimeAllowed = std::chrono::duration(PlayTimeAllowed); + if (const auto r = convert_integer(value)) + ng->PlayTimeAllowed = std::chrono::duration(*r); } else if (cmp(lb, eq, ControlInvulTimeStr)) convert_integer(ng->control_invul_time, value); @@ -1732,9 +1730,8 @@ void read_netgame_profile(netgame_info *ng) convert_integer(ng->PitchLockFlags, value); else if (cmp(lb, eq, AutosaveIntervalStr)) { - uint16_t AutosaveInterval; - if (convert_integer(AutosaveInterval, value)) - ng->MPGameplayOptions.AutosaveInterval = std::chrono::seconds(AutosaveInterval); + if (const auto r = convert_integer(value)) + ng->MPGameplayOptions.AutosaveInterval = std::chrono::seconds(*r); } #if DXX_USE_TRACKER else if (cmp(lb, eq, TrackerStr))