Mercurial > minori
changeset 211:7cf53145de11
strings: use templates for ToInt, std::to_string -> Strings::ToUtf8String
author | Paper <mrpapersonic@gmail.com> |
---|---|
date | Sun, 07 Jan 2024 09:54:17 -0500 |
parents | da91af31ae73 |
children | 6b08fbd7f206 |
files | include/core/strings.h src/core/anime.cc src/core/strings.cc src/core/time.cc src/gui/pages/anime_list.cc src/services/anilist.cc |
diffstat | 6 files changed, 44 insertions(+), 58 deletions(-) [+] |
line wrap: on
line diff
--- 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 <string> #include <vector> -#include <array> -#include <limits> -#include <stdexcept> -#include <cstdint> +#include <sstream> 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<std::string>& vector, const std::string& delimiter); std::vector<std::string> 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<typename T = int> +/* not really an "int"... but who cares? */ +template<typename T = int, + std::enable_if_t<std::is_integral<T>::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<T>::value) { - return clamp(std::stoll(str), std::numeric_limits<T>::min(), std::numeric_limits<T>::max()); - } else if constexpr (std::is_unsigned<T>::value) { - return clamp(std::stoull(str), std::numeric_limits<T>::max(), std::numeric_limits<T>::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<typename T, + std::enable_if_t<std::is_integral<T>::value && !std::is_same<T, bool>::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
--- 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 <algorithm> #include <string> @@ -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) {
--- 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<std::string, uint64_t> bytes_map = { {"KB", 1ull << 10},
--- 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 <cassert> #include <cmath> #include <cstdint> @@ -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<int64_t*>(&t); } -} // namespace Time \ No newline at end of file +} // namespace Time
--- 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<unsigned int> 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() {
--- 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(