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 }