Mercurial > minori
comparison src/core/date.cc @ 187:9613d72b097e
*: multiple performance improvements
like marking `static const` when it makes sense...
date: change old stupid heap-based method to a structure which should
make copying the thing actually make a copy.
also many performance-based changes, like removing the std::tie
dependency and forward-declaring nlohmann json
*: replace every instance of QString::fromUtf8 to Strings::ToQString.
the main difference is that our function will always convert exactly
what is in the string, while some other times it would only convert
up to the nearest NUL byte
author | Paper <mrpapersonic@gmail.com> |
---|---|
date | Wed, 06 Dec 2023 13:43:54 -0500 |
parents | 9b10175be389 |
children | f0ff06a45c42 |
comparison
equal
deleted
inserted
replaced
186:6ef31dbb90ca | 187:9613d72b097e |
---|---|
1 #include "core/date.h" | 1 #include "core/date.h" |
2 #include "core/json.h" | 2 #include "core/json.h" |
3 | |
3 #include <QDate> | 4 #include <QDate> |
4 #include <QDebug> | 5 #include <QDebug> |
6 | |
5 #include <algorithm> | 7 #include <algorithm> |
6 #include <cstdint> | |
7 #include <tuple> | |
8 | 8 |
9 /* An implementation of AniList's "fuzzy date" */ | 9 /* An implementation of AniList's "fuzzy date" */ |
10 | 10 |
11 #define CLAMP(x, low, high) (std::max(low, std::min(high, x))) | 11 template<typename T> |
12 bool CLAMP(T x, T low, T high) { | |
13 return std::max(low, std::min(high, x)); | |
14 } | |
12 | 15 |
13 Date::Date() { | 16 Date::Date() { |
14 } | 17 } |
15 | 18 |
16 Date::Date(unsigned int y) { | 19 Date::Date(unsigned int y) { |
29 SetDay(date.day()); | 32 SetDay(date.day()); |
30 } | 33 } |
31 | 34 |
32 Date::Date(const nlohmann::json& json) { | 35 Date::Date(const nlohmann::json& json) { |
33 /* NOTE: this constructor is made for use with | 36 /* NOTE: this constructor is made for use with |
34 AniList FussyDate-style JSON. In the future, some other | 37 AniList FuzzyDate-style JSON. In the future, some other |
35 methods may be parsed and whatnot if necessary. */ | 38 methods may be parsed and whatnot if necessary. */ |
36 if (json.contains("year") && json.at("year").is_number()) | 39 if (json.contains("year") && json.at("year").is_number()) |
37 SetYear(json.at("year").get<unsigned int>()); | 40 SetYear(json.at("year").get<unsigned int>()); |
38 if (json.contains("month") && json.at("month").is_number()) | 41 if (json.contains("month") && json.at("month").is_number()) |
39 SetMonth(json.at("month").get<unsigned int>()); | 42 SetMonth(json.at("month").get<unsigned int>()); |
40 if (json.contains("day") && json.at("day").is_number()) | 43 if (json.contains("day") && json.at("day").is_number()) |
41 SetDay(json.at("day").get<unsigned int>()); | 44 SetDay(json.at("day").get<unsigned int>()); |
42 } | 45 } |
43 | 46 |
44 void Date::VoidYear() { | 47 void Date::VoidYear() { |
45 year.reset(); | 48 year.Void(); |
46 } | 49 } |
47 | 50 |
48 void Date::VoidMonth() { | 51 void Date::VoidMonth() { |
49 month.reset(); | 52 month.Void(); |
50 } | 53 } |
51 | 54 |
52 void Date::VoidDay() { | 55 void Date::VoidDay() { |
53 day.reset(); | 56 day.Void(); |
54 } | 57 } |
55 | 58 |
56 void Date::SetYear(unsigned int y) { | 59 void Date::SetYear(unsigned int y) { |
57 year.reset(new unsigned int(y)); | 60 year.Set(y); |
58 } | 61 } |
59 | 62 |
60 void Date::SetMonth(unsigned int m) { | 63 void Date::SetMonth(unsigned int m) { |
61 month.reset(new unsigned int(CLAMP(m, 1U, 12U))); | 64 month.Set(CLAMP(m, 1U, 12U)); |
62 } | 65 } |
63 | 66 |
64 void Date::SetDay(unsigned int d) { | 67 void Date::SetDay(unsigned int d) { |
65 day.reset(new unsigned int(CLAMP(d, 1U, 31U))); | 68 day.Set(CLAMP(d, 1U, 31U)); |
66 } | 69 } |
67 | 70 |
68 unsigned int Date::GetYear() const { | 71 unsigned int Date::GetYear() const { |
69 unsigned int* ptr = year.get(); | 72 return year.Get(); |
70 if (ptr != nullptr) | |
71 return *year; | |
72 return -1; | |
73 } | 73 } |
74 | 74 |
75 unsigned int Date::GetMonth() const { | 75 unsigned int Date::GetMonth() const { |
76 unsigned int* ptr = month.get(); | 76 return month.Get(); |
77 if (ptr != nullptr) | |
78 return *month; | |
79 return -1; | |
80 } | 77 } |
81 | 78 |
82 unsigned int Date::GetDay() const { | 79 unsigned int Date::GetDay() const { |
83 unsigned int* ptr = day.get(); | 80 return day.Get(); |
84 if (ptr != nullptr) | |
85 return *day; | |
86 return -1; | |
87 } | 81 } |
88 | 82 |
89 bool Date::IsValid() const { | 83 bool Date::IsValid() const { |
90 return year.get() && month.get() && day.get(); | 84 return year.Enabled() && month.Enabled() && day.Enabled(); |
91 } | 85 } |
92 | 86 |
93 bool Date::operator<(const Date& other) const { | 87 bool Date::operator<(const Date& other) const { |
94 unsigned int y = GetYear(), m = GetMonth(), d = GetDay(); | 88 const unsigned int y = GetYear(), m = GetMonth(), d = GetDay(); |
95 unsigned int o_y = other.GetYear(), o_m = other.GetMonth(), o_d = other.GetDay(); | 89 const unsigned int o_y = other.GetYear(), o_m = other.GetMonth(), o_d = other.GetDay(); |
96 return std::tie(y, m, d) < std::tie(o_y, o_m, o_d); | 90 |
91 return (y < o_y && m < o_m && d < o_d); | |
97 } | 92 } |
98 | 93 |
99 bool Date::operator>(const Date& other) const { | 94 bool Date::operator>(const Date& other) const { |
100 return other < (*this); | 95 return other < (*this); |
101 } | 96 } |
107 bool Date::operator>=(const Date& other) const { | 102 bool Date::operator>=(const Date& other) const { |
108 return !((*this) < other); | 103 return !((*this) < other); |
109 } | 104 } |
110 | 105 |
111 QDate Date::GetAsQDate() const { | 106 QDate Date::GetAsQDate() const { |
112 /* QDates don't support "missing" values, for good reason. */ | 107 /* QDate doesn't support "missing" values (for good reason), |
113 if (IsValid()) | 108 * so we do our best and return what we can. |
114 return QDate(*year, *month, *day); | 109 */ |
115 else | 110 |
116 return QDate(); | 111 return QDate(year.Enabled() ? year.Get() : 2000, month.Enabled() ? month.Get() : 1, day.Enabled() ? day.Get() : 1); |
117 } | 112 } |
118 | 113 |
119 nlohmann::json Date::GetAsAniListJson() const { | 114 nlohmann::json Date::GetAsAniListJson() const { |
120 nlohmann::json result = {}; | 115 nlohmann::json result = {}; |
121 if (year.get()) | 116 |
122 result["year"] = *year; | 117 if (year.Enabled()) |
118 result["year"] = year.Get(); | |
123 else | 119 else |
124 result["year"] = nullptr; | 120 result["year"] = nullptr; |
125 if (month.get()) | 121 |
126 result["month"] = *month; | 122 if (month.Enabled()) |
123 result["month"] = month.Get(); | |
127 else | 124 else |
128 result["month"] = nullptr; | 125 result["month"] = nullptr; |
129 if (day.get()) | 126 |
130 result["day"] = *day; | 127 if (day.Enabled()) |
128 result["day"] = day.Get(); | |
131 else | 129 else |
132 result["day"] = nullptr; | 130 result["day"] = nullptr; |
131 | |
133 return result; | 132 return result; |
134 } | 133 } |