# HG changeset patch # User Paper # Date 1704639257 18000 # Node ID 7cf53145de11475f2d8db078e0c24841519c8387 # Parent da91af31ae73ab0137909b47314df96686ddde6c strings: use templates for ToInt, std::to_string -> Strings::ToUtf8String diff -r da91af31ae73 -r 7cf53145de11 include/core/strings.h --- a/include/core/strings.h Tue Jan 02 02:37:03 2024 -0500 +++ b/include/core/strings.h Sun Jan 07 09:54:17 2024 -0500 @@ -3,10 +3,7 @@ #include #include -#include -#include -#include -#include +#include class QString; class QByteArray; @@ -14,7 +11,8 @@ namespace Strings { /* Implode function: takes a vector of strings and turns it - into a string, separated by delimiters. */ + * into a string, separated by delimiters. +*/ std::string Implode(const std::vector& vector, const std::string& delimiter); std::vector Split(const std::string &text, const std::string& delimiter); @@ -31,7 +29,10 @@ std::string ToLower(const std::string& string); /* functions that make the way we convert from and to - different string formats universal */ + * different string formats universal (and these functions + * typically do things the right way so we avoid retarded + * code) +*/ std::wstring ToWstring(const std::string& string); std::wstring ToWstring(const QString& string); std::string ToUtf8String(const std::wstring& wstring); @@ -40,28 +41,26 @@ QString ToQString(const std::string& string); QString ToQString(const std::wstring& wstring); -/* arithmetic :) */ -template +/* not really an "int"... but who cares? */ +template::value, bool> = true> T ToInt(const std::string& str, T def = 0) { - auto clamp = [](const T& val, const T& min, const T& max){ - return std::max(min, std::min(val, max)); - }; - - try { - if constexpr (std::is_signed::value) { - return clamp(std::stoll(str), std::numeric_limits::min(), std::numeric_limits::max()); - } else if constexpr (std::is_unsigned::value) { - return clamp(std::stoull(str), std::numeric_limits::max(), std::numeric_limits::max()); - } else { - throw std::invalid_argument("Invalid input to Strings::ToInt()!"); - } - } catch (std::invalid_argument const& ex) { - return def; - } + std::istringstream s(str); + s >> std::noboolalpha >> def; + return def; } -bool ToBool(const std::string& s, const bool def = false); -std::string ToUtf8String(const bool b); +template::value && !std::is_same::value, bool> = true> +std::string ToUtf8String(T i) { + std::ostringstream s; + s << i; + return s.str(); +} + +bool ToBool(const std::string& s, bool def); + +std::string ToUtf8String(bool b); uint64_t HumanReadableSizeToBytes(const std::string& str); @@ -72,4 +71,4 @@ }; // namespace Strings -#endif // __core__strings_h \ No newline at end of file +#endif // __core__strings_h diff -r da91af31ae73 -r 7cf53145de11 src/core/anime.cc --- a/src/core/anime.cc Tue Jan 02 02:37:03 2024 -0500 +++ b/src/core/anime.cc Sun Jan 07 09:54:17 2024 -0500 @@ -5,6 +5,7 @@ #include "core/anime.h" #include "core/date.h" #include "core/session.h" +#include "core/strings.h" #include #include @@ -50,9 +51,9 @@ switch (session.config.anime_list.score_format) { case ScoreFormat::POINT_10_DECIMAL: - return std::to_string(score / 10) + "." + std::to_string(score % 10); + return Strings::ToUtf8String(score / 10) + "." + Strings::ToUtf8String(score % 10); case ScoreFormat::POINT_10: - return std::to_string(score / 10); + return Strings::ToUtf8String(score / 10); case ScoreFormat::POINT_5: { std::string stars = ""; @@ -73,7 +74,7 @@ } default: case ScoreFormat::POINT_100: - return std::to_string(score); + return Strings::ToUtf8String(score); } } @@ -243,7 +244,7 @@ std::string Anime::GetServiceUrl() const { /* todo: add support for other services... */ - return "https://anilist.co/anime/" + std::to_string(GetId()); + return "https://anilist.co/anime/" + Strings::ToUtf8String(GetId()); } void Anime::SetId(int id) { diff -r da91af31ae73 -r 7cf53145de11 src/core/strings.cc --- a/src/core/strings.cc Tue Jan 02 02:37:03 2024 -0500 +++ b/src/core/strings.cc Sun Jan 07 09:54:17 2024 -0500 @@ -159,33 +159,17 @@ return QString::fromWCharArray(wstring.c_str(), wstring.length()); } -/* not really an "int"... but who cares? */ -int ToInt(const std::string& str, int def) { - int tmp = 0; - try { - tmp = std::stoi(str); - } catch (std::invalid_argument const& ex) { - qDebug() << "Failed to parse int from std::string: no number found in " << ToQString(str) << " defaulting to " << def; - tmp = def; - } - return tmp; +std::string ToUtf8String(const bool b) { + return b ? "true" : "false"; // lol } -bool ToBool(const std::string& s, const bool def) { - if (s.length() < 4) - return def; - const std::string l = Strings::ToLower(s); - if (Strings::BeginningMatchesSubstring(l, "true")) - return true; - else if (Strings::BeginningMatchesSubstring(l, "false")) - return false; +bool ToBool(const std::string& str, bool def) { + std::istringstream s(Strings::ToLower(str)); + s >> std::boolalpha >> def; return def; } -std::string ToUtf8String(const bool b) { - return b ? "true" : "false"; -} - +/* util funcs */ uint64_t HumanReadableSizeToBytes(const std::string& str) { static const std::unordered_map bytes_map = { {"KB", 1ull << 10}, diff -r da91af31ae73 -r 7cf53145de11 src/core/time.cc --- a/src/core/time.cc Tue Jan 02 02:37:03 2024 -0500 +++ b/src/core/time.cc Sun Jan 07 09:54:17 2024 -0500 @@ -1,4 +1,6 @@ #include "core/time.h" +#include "core/strings.h" + #include #include #include @@ -15,7 +17,7 @@ std::string result; auto get = [](int64_t val, const std::string& s, const std::string& p) { - return std::to_string(val) + " " + (val == 1 ? s : p); + return Strings::ToUtf8String(val) + " " + (val == 1 ? s : p); }; if (InSeconds() < 60) @@ -61,4 +63,4 @@ return *reinterpret_cast(&t); } -} // namespace Time \ No newline at end of file +} // namespace Time diff -r da91af31ae73 -r 7cf53145de11 src/gui/pages/anime_list.cc --- a/src/gui/pages/anime_list.cc Tue Jan 02 02:37:03 2024 -0500 +++ b/src/gui/pages/anime_list.cc Sun Jan 07 09:54:17 2024 -0500 @@ -119,7 +119,7 @@ std::optional year = list[index.row()].GetAirDate().GetYear(); if (!year) return "Unknown Unknown"; - return Strings::ToQString(Translate::ToLocalString(list[index.row()].GetSeason()) + " " + std::to_string(year.value())); + return Strings::ToQString(Translate::ToLocalString(list[index.row()].GetSeason()) + " " + Strings::ToUtf8String(year.value())); } case AL_AVG_SCORE: return QString::number(list[index.row()].GetAudienceScore()) + "%"; case AL_STARTED: return list[index.row()].GetUserDateStarted().GetAsQDate(); @@ -349,8 +349,8 @@ void AnimeListPage::RefreshTabs() { for (unsigned int i = 0; i < sort_models.size(); i++) - tab_bar->setTabText(i, Strings::ToQString(Translate::ToString(Anime::ListStatuses[i]) + " (" + - std::to_string(Anime::db.GetListsAnimeAmount(Anime::ListStatuses[i])) + ")")); + tab_bar->setTabText(i, Strings::ToQString(Translate::ToString(Anime::ListStatuses[i])) + " (" + + QString::number(Anime::db.GetListsAnimeAmount(Anime::ListStatuses[i])) + ")"); } void AnimeListPage::Refresh() { diff -r da91af31ae73 -r 7cf53145de11 src/services/anilist.cc --- a/src/services/anilist.cc Tue Jan 02 02:37:03 2024 -0500 +++ b/src/services/anilist.cc Sun Jan 07 09:54:17 2024 -0500 @@ -308,7 +308,7 @@ bool AuthorizeUser() { /* Prompt for PIN */ QDesktopServices::openUrl( - QUrl(Strings::ToQString("https://anilist.co/api/v2/oauth/authorize?client_id=" + std::to_string(CLIENT_ID) + "&response_type=token"))); + QUrl(Strings::ToQString("https://anilist.co/api/v2/oauth/authorize?client_id=" + Strings::ToUtf8String(CLIENT_ID) + "&response_type=token"))); bool ok; QString token = QInputDialog::getText(