aboutsummaryrefslogtreecommitdiff
path: root/src/openvic/types
diff options
context:
space:
mode:
author Hop311 <hop3114@gmail.com>2023-08-26 00:25:12 +0200
committer Hop311 <hop3114@gmail.com>2023-09-03 12:53:52 +0200
commit366f1b3941315641bdcb0ee98465b4d2134eee86 (patch)
treeebb1e95b5e874c6eab09f19a323d721fd1fdac1b /src/openvic/types
parentefa88c722fcb6c8fea7a86e1b3b8a83f1f59eb31 (diff)
Followup big dataloader commit
Diffstat (limited to 'src/openvic/types')
-rw-r--r--src/openvic/types/Date.cpp122
-rw-r--r--src/openvic/types/Date.hpp8
-rw-r--r--src/openvic/types/IdentifierRegistry.cpp8
-rw-r--r--src/openvic/types/IdentifierRegistry.hpp18
-rw-r--r--src/openvic/types/fixed_point/FP.hpp192
5 files changed, 207 insertions, 141 deletions
diff --git a/src/openvic/types/Date.cpp b/src/openvic/types/Date.cpp
index b6e1367..1f13808 100644
--- a/src/openvic/types/Date.cpp
+++ b/src/openvic/types/Date.cpp
@@ -6,6 +6,7 @@
#include <charconv>
#include "openvic/utility/Logger.hpp"
+#include "openvic/utility/StringUtils.hpp"
using namespace OpenVic;
@@ -55,12 +56,16 @@ Timespan::operator double() const {
return days;
}
-Timespan::operator std::string() const {
+std::string Timespan::to_string() const {
return std::to_string(days);
}
+Timespan::operator std::string() const {
+ return to_string();
+}
+
std::ostream& OpenVic::operator<<(std::ostream& out, Timespan const& timespan) {
- return out << static_cast<std::string>(timespan);
+ return out << timespan.to_string();
}
Timespan Date::_dateToTimespan(year_t year, month_t month, day_t day) {
@@ -146,95 +151,112 @@ Date Date::operator++(int) {
return old;
}
-Date::operator std::string() const {
+std::string Date::to_string() const {
std::stringstream ss;
ss << *this;
return ss.str();
}
+Date::operator std::string() const {
+ return to_string();
+}
+
std::ostream& OpenVic::operator<<(std::ostream& out, Date const& date) {
- return out << static_cast<int>(date.getYear()) << '.' << static_cast<int>(date.getMonth()) << '.' << static_cast<int>(date.getDay());
+ return out << static_cast<int>(date.getYear()) << Date::SEPARATOR_CHARACTER << static_cast<int>(date.getMonth()) << Date::SEPARATOR_CHARACTER << static_cast<int>(date.getDay());
}
// Parsed from string of the form YYYY.MM.DD
-Date Date::from_string(const std::string_view date, bool* successful) {
+Date Date::from_string(char const* const str, char const* const end, bool* successful) {
if (successful != nullptr) *successful = true;
- size_t first_pos = 0;
- while (first_pos < date.length() && std::isdigit(date[first_pos])) {
- first_pos++;
+
+ year_t year = 0;
+ month_t month = 1;
+ day_t day = 1;
+
+ if (str == nullptr || end <= str) {
+ Logger::error("Invalid string start/end pointers: ", static_cast<void const*>(str), " - ", static_cast<void const*>(end));
+ if (successful != nullptr) *successful = false;
+ return { year, month, day };
}
- if (first_pos == 0) {
- Logger::error("Failed to find year digits in date: ", date);
+ char const* year_end = str;
+ while (std::isdigit(*year_end) && ++year_end < end);
+
+ if (year_end <= str) {
+ Logger::error("Failed to find year digits in date: ", std::string_view { str, static_cast<size_t>(end - str) });
if (successful != nullptr) *successful = false;
- return {};
+ return { year, month, day };
}
- int val = 0;
- char const* start = date.data();
- char const* end = start + first_pos;
- std::from_chars_result result = std::from_chars(start, end, val);
- if (result.ec != std::errc{} || result.ptr != end || val < 0 || val >= 1 << (8 * sizeof(year_t))) {
- Logger::error("Failed to read year: ", date);
+ bool sub_successful = false;
+ uint64_t val = StringUtils::string_to_uint64(str, year_end, &sub_successful, 10);
+ if (!sub_successful || val >= 1 << (8 * sizeof(year_t))) {
+ Logger::error("Failed to read year: ", std::string_view { str, static_cast<size_t>(end - str) });
if (successful != nullptr) *successful = false;
- return {};
+ return { year, month, day };
}
- year_t year = val;
- month_t month = 1;
- day_t day = 1;
- if (first_pos < date.length()) {
- if (date[first_pos] == '.') {
- size_t second_pos = ++first_pos;
- while (second_pos < date.length() && std::isdigit(date[second_pos])) {
- second_pos++;
+ year = val;
+ if (year_end < end) {
+ if (*year_end == SEPARATOR_CHARACTER) {
+ char const* const month_start = year_end + 1;
+ char const* month_end = month_start;
+ if (month_start < end) {
+ while (std::isdigit(*month_end) && ++month_end < end);
}
- if (first_pos == second_pos) {
- Logger::error("Failed to find month digits in date: ", date);
+ if (month_start >= month_end) {
+ Logger::error("Failed to find month digits in date: ", std::string_view { str, static_cast<size_t>(end - str) });
if (successful != nullptr) *successful = false;
} else {
- start = date.data() + first_pos;
- end = date.data() + second_pos;
- result = std::from_chars(start, end, val);
- if (result.ec != std::errc{} || result.ptr != end || val < 1 || val > MONTHS_IN_YEAR) {
- Logger::error("Failed to read month: ", date);
+ sub_successful = false;
+ val = StringUtils::string_to_uint64(month_start, month_end, &sub_successful, 10);
+ if (!sub_successful || val < 1 || val > MONTHS_IN_YEAR) {
+ Logger::error("Failed to read month: ", std::string_view { str, static_cast<size_t>(end - str) });
if (successful != nullptr) *successful = false;
} else {
month = val;
- if (second_pos < date.length()) {
- if (date[second_pos] == '.') {
- size_t third_pos = ++second_pos;
- while (third_pos < date.length() && std::isdigit(date[third_pos])) {
- third_pos++;
+ if (month_end < end) {
+ if (*month_end == SEPARATOR_CHARACTER) {
+ char const* const day_start = month_end + 1;
+ char const* day_end = day_start;
+ if (day_start < end) {
+ while (std::isdigit(*day_end) && ++day_end < end);
}
- if (second_pos == third_pos) {
- Logger::error("Failed to find day digits in date: ", date);
+ if (day_start >= day_end) {
+ Logger::error("Failed to find day digits in date: ", std::string_view { str, static_cast<size_t>(end - str) });
if (successful != nullptr) *successful = false;
} else {
- start = date.data() + second_pos;
- end = date.data() + third_pos;
- result = std::from_chars(start, end, val);
- if (result.ec != std::errc{} || result.ptr != end || val < 1 || val > DAYS_IN_MONTH[month - 1]) {
- Logger::error("Failed to read day: ", date);
+ sub_successful = false;
+ val = StringUtils::string_to_uint64(day_start, day_end, &sub_successful);
+ if (!sub_successful || val < 1 || val > DAYS_IN_MONTH[month - 1]) {
+ Logger::error("Failed to read day: ", std::string_view { str, static_cast<size_t>(end - str) });
if (successful != nullptr) *successful = false;
} else {
day = val;
- if (third_pos < date.length()) {
- Logger::error("Unexpected string \"", date.substr(third_pos), "\" at the end of date ", date);
+ if (day_end < end) {
+ Logger::error("Unexpected string \"", std::string_view { day_end, static_cast<size_t>(end - day_end) }, "\" at the end of date ", std::string_view { str, static_cast<size_t>(end - str) });
if (successful != nullptr) *successful = false;
}
}
}
} else {
- Logger::error("Unexpected character \"", date[second_pos], "\" in month of date ", date);
+ Logger::error("Unexpected character \"", *month_end, "\" in month of date ", std::string_view { str, static_cast<size_t>(end - str) });
if (successful != nullptr) *successful = false;
}
}
}
}
} else {
- Logger::error("Unexpected character \"", date[first_pos], "\" in year of date ", date);
+ Logger::error("Unexpected character \"", *year_end, "\" in year of date ", std::string_view { str, static_cast<size_t>(end - str) });
if (successful != nullptr) *successful = false;
}
}
- return _dateToTimespan(year, month, day);
+ return { year, month, day };
};
+
+Date Date::from_string(char const* str, size_t length, bool* successful) {
+ return from_string(str, str + length, successful);
+}
+
+Date Date::from_string(const std::string_view str, bool* successful) {
+ return from_string(str.data(), str.length(), successful);
+}
diff --git a/src/openvic/types/Date.hpp b/src/openvic/types/Date.hpp
index ca5645c..601f9dc 100644
--- a/src/openvic/types/Date.hpp
+++ b/src/openvic/types/Date.hpp
@@ -33,6 +33,7 @@ namespace OpenVic {
explicit operator day_t() const;
explicit operator double() const;
+ std::string to_string() const;
explicit operator std::string() const;
};
std::ostream& operator<<(std::ostream& out, Timespan const& timespan);
@@ -50,6 +51,8 @@ namespace OpenVic {
static Timespan::day_t const* DAYS_UP_TO_MONTH;
static month_t const* MONTH_FROM_DAY_IN_YEAR;
+ static constexpr char SEPARATOR_CHARACTER = '.';
+
private:
// Number of days since Jan 1st, Year 0
Timespan timespan;
@@ -82,9 +85,12 @@ namespace OpenVic {
Date& operator++();
Date operator++(int);
+ std::string to_string() const;
explicit operator std::string() const;
// Parsed from string of the form YYYY.MM.DD
- static Date from_string(const std::string_view date, bool* successful = nullptr);
+ static Date from_string(char const* str, char const* end, bool* successful = nullptr);
+ static Date from_string(char const* str, size_t length, bool* successful = nullptr);
+ static Date from_string(const std::string_view str, bool* successful = nullptr);
};
std::ostream& operator<<(std::ostream& out, Date const& date);
}
diff --git a/src/openvic/types/IdentifierRegistry.cpp b/src/openvic/types/IdentifierRegistry.cpp
index 97a1ff5..3710387 100644
--- a/src/openvic/types/IdentifierRegistry.cpp
+++ b/src/openvic/types/IdentifierRegistry.cpp
@@ -35,3 +35,11 @@ HasIdentifierAndColour::HasIdentifierAndColour(const std::string_view new_identi
const colour_t new_colour, bool can_be_null)
: HasIdentifier { new_identifier },
HasColour { new_colour, can_be_null } {}
+
+distribution_t::value_type OpenVic::get_largest_item(distribution_t const& dist) {
+ const distribution_t::const_iterator result = std::max_element(dist.begin(), dist.end(),
+ [](distribution_t::value_type a, distribution_t::value_type b) -> bool {
+ return a.second < b.second;
+ });
+ return result != dist.end() ? *result : distribution_t::value_type { nullptr, -1.0f };
+}
diff --git a/src/openvic/types/IdentifierRegistry.hpp b/src/openvic/types/IdentifierRegistry.hpp
index e5ac94b..989db01 100644
--- a/src/openvic/types/IdentifierRegistry.hpp
+++ b/src/openvic/types/IdentifierRegistry.hpp
@@ -64,7 +64,9 @@ namespace OpenVic {
HasIdentifierAndColour& operator=(HasIdentifierAndColour&&) = delete;
};
- using distribution_t = std::unordered_map<HasIdentifierAndColour const*, float>;
+ using distribution_t = std::map<HasIdentifierAndColour const*, float>;
+
+ distribution_t::value_type get_largest_item(distribution_t const& dist);
/*
* Template for a list of objects with unique string identifiers that can
@@ -102,7 +104,7 @@ namespace OpenVic {
Logger::error("Failed to lock ", name, " registry - already locked!");
} else {
locked = true;
- if (log) Logger::info("Locked ", name, " registry after registering ", get_item_count(), " items");
+ if (log) Logger::info("Locked ", name, " registry after registering ", size(), " items");
}
}
bool is_locked() const {
@@ -113,9 +115,19 @@ namespace OpenVic {
items.clear();
locked = false;
}
- size_t get_item_count() const {
+ size_t size() const {
return items.size();
}
+ bool empty() const {
+ return items.empty();
+ }
+ void reserve(size_t size) {
+ if (locked) {
+ Logger::error("Failed to reserve space for ", size, " items in ", name, " registry - already locked!");
+ } else {
+ items.reserve(size);
+ }
+ }
T* get_item_by_identifier(const std::string_view identifier) {
const identifier_index_map_t::const_iterator it = identifier_index_map.find(identifier);
if (it != identifier_index_map.end()) return &items[it->second];
diff --git a/src/openvic/types/fixed_point/FP.hpp b/src/openvic/types/fixed_point/FP.hpp
index 8b32906..42ddf79 100644
--- a/src/openvic/types/fixed_point/FP.hpp
+++ b/src/openvic/types/fixed_point/FP.hpp
@@ -1,16 +1,17 @@
#pragma once
-#include <cstdint>
-#include <cstdlib>
#include <cerrno>
#include <cmath>
+#include <cstdint>
+#include <cstdlib>
#include <limits>
-#include <cstring>
+#include <string_view>
-#include "FPLUT.hpp"
-#include "openvic/utility/FloatUtils.hpp"
-#include "openvic/utility/StringUtils.hpp"
#include "openvic/utility/Logger.hpp"
+#include "openvic/utility/NumberUtils.hpp"
+#include "openvic/utility/StringUtils.hpp"
+
+#include "FPLUT.hpp"
namespace OpenVic {
struct FP {
@@ -41,7 +42,7 @@ namespace OpenVic {
static constexpr FP _0() {
return 0;
- }
+ }
static constexpr FP _1() {
return 1;
@@ -195,13 +196,17 @@ namespace OpenVic {
return static_cast<int64_t>(178145LL);
}
+ constexpr bool is_negative() const {
+ return value < 0;
+ }
+
constexpr FP abs() const {
- return value >= 0 ? value : -value;
+ return !is_negative() ? value : -value;
}
- // Not including sign, so -1.1 -> 0.1
+ // Doesn't account for sign, so -n.abc -> 1 - 0.abc
constexpr FP get_frac() const {
- return abs().value & ((1 << FPLUT::PRECISION) - 1);
+ return value & (FPLUT::ONE - 1);
}
constexpr int64_t to_int64_t() const {
@@ -217,33 +222,35 @@ namespace OpenVic {
}
constexpr int32_t to_int32_t() const {
- return static_cast<int32_t>(value >> FPLUT::PRECISION);
+ return static_cast<int32_t>(to_int64_t());
}
constexpr float to_float() const {
- return value / 65536.0F;
+ return value / static_cast<float>(FPLUT::ONE);
}
constexpr float to_float_rounded() const {
- return static_cast<float>(FloatUtils::round_to_int64((value / 65536.0F) * 100000.0F)) / 100000.0F;
+ return static_cast<float>(NumberUtils::round_to_int64((value / static_cast<float>(FPLUT::ONE)) * 100000.0f)) / 100000.0f;
}
- constexpr float to_double() const {
- return value / 65536.0;
+ constexpr double to_double() const {
+ return value / static_cast<double>(FPLUT::ONE);
}
constexpr float to_double_rounded() const {
- return FloatUtils::round_to_int64((value / 65536.0) * 100000.0) / 100000.0;
+ return NumberUtils::round_to_int64((value / static_cast<double>(FPLUT::ONE)) * 100000.0) / 100000.0;
}
std::string to_string() const {
- std::string str = std::to_string(to_int64_t()) + ".";
- FP frac_part = get_frac();
+ FP val = abs();
+ std::string str = std::to_string(val.to_int64_t()) + ".";
+ if (is_negative()) str = "-" + str;
+ val = val.get_frac();
do {
- frac_part.value *= 10;
- str += std::to_string(frac_part.to_int64_t());
- frac_part = frac_part.get_frac();
- } while (frac_part > 0);
+ val *= 10;
+ str.push_back('0' + static_cast<char>(val.to_int64_t()));
+ val = val.get_frac();
+ } while (val > 0);
return str;
}
@@ -258,7 +265,7 @@ namespace OpenVic {
}
// Deterministic
- static constexpr FP parse(const char* str, const char* end, bool *successful = nullptr) {
+ static constexpr FP parse(char const* str, char const* const end, bool* successful = nullptr) {
if (successful != nullptr) *successful = false;
if (str == nullptr || str >= end) {
@@ -273,7 +280,7 @@ namespace OpenVic {
if (str == end) return _0();
}
- const char* dot_pointer = str;
+ char const* dot_pointer = str;
while (*dot_pointer != '.' && ++dot_pointer != end);
if (dot_pointer == str && dot_pointer + 1 == end) {
@@ -287,31 +294,35 @@ namespace OpenVic {
if (dot_pointer != str) {
// Non-empty integer part
bool int_successful = false;
- result += parse_integer(str, dot_pointer, &int_successful);
+ result += parse_integer(str, dot_pointer, &int_successful);
if (!int_successful && successful != nullptr) *successful = false;
}
if (dot_pointer + 1 < end) {
// Non-empty fractional part
bool frac_successful = false;
- result += parse_fraction(dot_pointer + 1, end, &frac_successful);
+ result += parse_fraction(dot_pointer + 1, end, &frac_successful);
if (!frac_successful && successful != nullptr) *successful = false;
}
return negative ? -result : result;
}
- static constexpr FP parse(const char* str, size_t length, bool *successful = nullptr) {
+ static constexpr FP parse(char const* str, size_t length, bool* successful = nullptr) {
return parse(str, str + length, successful);
}
+ static FP parse(const std::string_view str, bool* successful = nullptr) {
+ return parse(str.data(), str.length(), successful);
+ }
+
// Not Deterministic
static constexpr FP parse_unsafe(float value) {
return static_cast<int64_t>(value * FPLUT::ONE + 0.5f * (value < 0 ? -1 : 1));
}
// Not Deterministic
- static FP parse_unsafe(const char* value) {
+ static FP parse_unsafe(char const* value) {
char* endpointer;
double double_value = std::strtod(value, &endpointer);
@@ -325,7 +336,7 @@ namespace OpenVic {
}
constexpr operator int32_t() const {
- return to_int32_t();
+ return to_int32_t();
}
constexpr operator int64_t() const {
@@ -344,218 +355,225 @@ namespace OpenVic {
return to_string();
}
- friend std::ostream& operator<<(std::ostream& stream, const FP& obj) {
+ friend std::ostream& operator<<(std::ostream& stream, FP const& obj) {
return stream << obj.to_string();
}
- constexpr friend FP operator-(const FP& obj) {
+ constexpr friend FP operator-(FP const& obj) {
return -obj.value;
}
- constexpr friend FP operator+(const FP& obj) {
+ constexpr friend FP operator+(FP const& obj) {
return +obj.value;
}
- constexpr friend FP operator+(const FP& lhs, const FP& rhs) {
+ constexpr friend FP operator+(FP const& lhs, FP const& rhs) {
return lhs.value + rhs.value;
}
- constexpr friend FP operator+(const FP& lhs, const int32_t& rhs) {
+ constexpr friend FP operator+(FP const& lhs, int32_t const& rhs) {
return lhs.value + (static_cast<int64_t>(rhs) << FPLUT::PRECISION);
}
- constexpr friend FP operator+(const int32_t& lhs, const FP& rhs) {
+ constexpr friend FP operator+(int32_t const& lhs, FP const& rhs) {
return (static_cast<int64_t>(lhs) << FPLUT::PRECISION) + rhs.value;
}
- constexpr FP operator+=(const FP& obj) {
+ constexpr FP operator+=(FP const& obj) {
value += obj.value;
return *this;
}
- constexpr FP operator+=(const int32_t& obj) {
+ constexpr FP operator+=(int32_t const& obj) {
value += (static_cast<int64_t>(obj) << FPLUT::PRECISION);
return *this;
}
- constexpr friend FP operator-(const FP& lhs, const FP& rhs) {
+ constexpr friend FP operator-(FP const& lhs, FP const& rhs) {
return lhs.value - rhs.value;
}
- constexpr friend FP operator-(const FP& lhs, const int32_t& rhs) {
+ constexpr friend FP operator-(FP const& lhs, int32_t const& rhs) {
return lhs.value - (static_cast<int64_t>(rhs) << FPLUT::PRECISION);
}
- constexpr friend FP operator-(const int32_t& lhs, const FP& rhs) {
+ constexpr friend FP operator-(int32_t const& lhs, FP const& rhs) {
return (static_cast<int64_t>(lhs) << FPLUT::PRECISION) - rhs.value;
}
- constexpr FP operator-=(const FP& obj) {
+ constexpr FP operator-=(FP const& obj) {
value -= obj.value;
return *this;
}
- constexpr FP operator-=(const int32_t& obj) {
+ constexpr FP operator-=(int32_t const& obj) {
value -= (static_cast<int64_t>(obj) << FPLUT::PRECISION);
return *this;
}
- constexpr friend FP operator*(const FP& lhs, const FP& rhs) {
+ constexpr friend FP operator*(FP const& lhs, FP const& rhs) {
return lhs.value * rhs.value >> FPLUT::PRECISION;
}
- constexpr friend FP operator*(const FP& lhs, const int32_t& rhs) {
+ constexpr friend FP operator*(FP const& lhs, int32_t const& rhs) {
return lhs.value * rhs;
}
- constexpr friend FP operator*(const int32_t& lhs, const FP& rhs) {
+ constexpr friend FP operator*(int32_t const& lhs, FP const& rhs) {
return lhs * rhs.value;
}
- constexpr FP operator*=(const FP& obj) {
+ constexpr FP operator*=(FP const& obj) {
value *= obj.value >> FPLUT::PRECISION;
return *this;
}
- constexpr FP operator*=(const int32_t& obj) {
+ constexpr FP operator*=(int32_t const& obj) {
value *= obj;
return *this;
}
- constexpr friend FP operator/(const FP& lhs, const FP& rhs) {
- return (lhs.value << FPLUT::PRECISION) / rhs.value;
+ constexpr friend FP operator/(FP const& lhs, FP const& rhs) {
+ return (lhs.value << FPLUT::PRECISION) / rhs.value;
}
- constexpr friend FP operator/(const FP& lhs, const int32_t& rhs) {
+ constexpr friend FP operator/(FP const& lhs, int32_t const& rhs) {
return lhs.value / rhs;
}
- constexpr friend FP operator/(const int32_t& lhs, const FP& rhs) {
- return (static_cast<int64_t>(lhs) << (2 / FPLUT::PRECISION)) / rhs.value;
+ constexpr friend FP operator/(int32_t const& lhs, FP const& rhs) {
+ return (static_cast<int64_t>(lhs) << (2 * FPLUT::PRECISION)) / rhs.value;
}
- constexpr FP operator/=(const FP& obj) {
+ constexpr FP operator/=(FP const& obj) {
value = (value << FPLUT::PRECISION) / obj.value;
return *this;
}
- constexpr FP operator/=(const int32_t& obj) {
+ constexpr FP operator/=(int32_t const& obj) {
value /= obj;
return *this;
}
- constexpr friend FP operator%(const FP& lhs, const FP& rhs) {
+ constexpr friend FP operator%(FP const& lhs, FP const& rhs) {
return lhs.value % rhs.value;
}
- constexpr friend FP operator%(const FP& lhs, const int32_t& rhs) {
+ constexpr friend FP operator%(FP const& lhs, int32_t const& rhs) {
return lhs.value % (static_cast<int64_t>(rhs) << FPLUT::PRECISION);
}
- constexpr friend FP operator%(const int32_t& lhs, const FP& rhs) {
+ constexpr friend FP operator%(int32_t const& lhs, FP const& rhs) {
return (static_cast<int64_t>(lhs) << FPLUT::PRECISION) % rhs.value;
}
- constexpr FP operator%=(const FP& obj) {
+ constexpr FP operator%=(FP const& obj) {
value %= obj.value;
return *this;
}
- constexpr FP operator%=(const int32_t& obj) {
+ constexpr FP operator%=(int32_t const& obj) {
value %= (static_cast<int64_t>(obj) << FPLUT::PRECISION);
return *this;
}
- constexpr friend bool operator<(const FP& lhs, const FP& rhs) {
+ constexpr friend bool operator<(FP const& lhs, FP const& rhs) {
return lhs.value < rhs.value;
}
- constexpr friend bool operator<(const FP& lhs, const int32_t& rhs) {
+ constexpr friend bool operator<(FP const& lhs, int32_t const& rhs) {
return lhs.value < static_cast<int64_t>(rhs) << FPLUT::PRECISION;
}
- constexpr friend bool operator<(const int32_t& lhs, const FP& rhs) {
+ constexpr friend bool operator<(int32_t const& lhs, FP const& rhs) {
return static_cast<int64_t>(lhs) << FPLUT::PRECISION < rhs.value;
}
- constexpr friend bool operator<=(const FP& lhs, const FP& rhs) {
+ constexpr friend bool operator<=(FP const& lhs, FP const& rhs) {
return lhs.value <= rhs.value;
}
- constexpr friend bool operator<=(const FP& lhs, const int32_t& rhs) {
+ constexpr friend bool operator<=(FP const& lhs, int32_t const& rhs) {
return lhs.value <= static_cast<int64_t>(rhs) << FPLUT::PRECISION;
}
- constexpr friend bool operator<=(const int32_t& lhs, const FP& rhs) {
+ constexpr friend bool operator<=(int32_t const& lhs, FP const& rhs) {
return static_cast<int64_t>(lhs) << FPLUT::PRECISION <= rhs.value;
}
- constexpr friend bool operator>(const FP& lhs, const FP& rhs) {
+ constexpr friend bool operator>(FP const& lhs, FP const& rhs) {
return lhs.value > rhs.value;
}
- constexpr friend bool operator>(const FP& lhs, const int32_t& rhs) {
+ constexpr friend bool operator>(FP const& lhs, int32_t const& rhs) {
return lhs.value > static_cast<int64_t>(rhs) << FPLUT::PRECISION;
}
- constexpr friend bool operator>(const int32_t& lhs, const FP& rhs) {
+ constexpr friend bool operator>(int32_t const& lhs, FP const& rhs) {
return static_cast<int64_t>(lhs) << FPLUT::PRECISION > rhs.value;
}
- constexpr friend bool operator>=(const FP& lhs, const FP& rhs) {
+ constexpr friend bool operator>=(FP const& lhs, FP const& rhs) {
return lhs.value >= rhs.value;
}
- constexpr friend bool operator>=(const FP& lhs, const int32_t& rhs) {
+ constexpr friend bool operator>=(FP const& lhs, int32_t const& rhs) {
return lhs.value >= static_cast<int64_t>(rhs) << FPLUT::PRECISION;
}
- constexpr friend bool operator>=(const int32_t& lhs, const FP& rhs) {
+ constexpr friend bool operator>=(int32_t const& lhs, FP const& rhs) {
return static_cast<int64_t>(lhs) << FPLUT::PRECISION >= rhs.value;
}
- constexpr friend bool operator==(const FP& lhs, const FP& rhs) {
+ constexpr friend bool operator==(FP const& lhs, FP const& rhs) {
return lhs.value == rhs.value;
}
- constexpr friend bool operator==(const FP& lhs, const int32_t& rhs) {
+ constexpr friend bool operator==(FP const& lhs, int32_t const& rhs) {
return lhs.value == static_cast<int64_t>(rhs) << FPLUT::PRECISION;
}
- constexpr friend bool operator==(const int32_t& lhs, const FP& rhs) {
+ constexpr friend bool operator==(int32_t const& lhs, FP const& rhs) {
return static_cast<int64_t>(lhs) << FPLUT::PRECISION == rhs.value;
}
- constexpr friend bool operator!=(const FP& lhs, const FP& rhs) {
+ constexpr friend bool operator!=(FP const& lhs, FP const& rhs) {
return lhs.value != rhs.value;
}
- constexpr friend bool operator!=(const FP& lhs, const int32_t& rhs) {
+ constexpr friend bool operator!=(FP const& lhs, int32_t const& rhs) {
return lhs.value != static_cast<int64_t>(rhs) << FPLUT::PRECISION;
}
- constexpr friend bool operator!=(const int32_t& lhs, const FP& rhs) {
+ constexpr friend bool operator!=(int32_t const& lhs, FP const& rhs) {
return static_cast<int64_t>(lhs) << FPLUT::PRECISION != rhs.value;
}
-
private:
int64_t value;
- static constexpr FP parse_integer(const char* str, const char* end, bool* successful) {
+ static constexpr FP parse_integer(char const* str, char const* const end, bool* successful) {
int64_t parsed_value = StringUtils::string_to_int64(str, end, successful, 10);
return parse(parsed_value);
}
- static constexpr FP parse_fraction(const char* str, const char* end, bool* successful) {
- constexpr size_t READ_SIZE = 5;
- if (str + READ_SIZE < end) {
- Logger::error("Fixed point fraction parse will only use the first ", READ_SIZE,
- " characters of ", std::string_view { str, static_cast<size_t>(end - str) });
- end = str + READ_SIZE;
+ static constexpr FP parse_fraction(char const* str, char const* end, bool* successful) {
+ char const* const read_end = str + FPLUT::PRECISION;
+ if (read_end < end) end = read_end;
+ uint64_t parsed_value = StringUtils::string_to_uint64(str, end, successful, 10);
+ while (end++ < read_end) {
+ parsed_value *= 10;
}
- int64_t parsed_value = StringUtils::string_to_int64(str, end, successful, 10);
- return parse_raw(parsed_value * 65536 / 100000);
+ uint64_t decimal = NumberUtils::pow(static_cast<uint64_t>(10), FPLUT::PRECISION);
+ int64_t ret = 0;
+ for (int i = FPLUT::PRECISION - 1; i >= 0; --i) {
+ decimal >>= 1;
+ if (parsed_value > decimal) {
+ parsed_value -= decimal;
+ ret |= 1 << i;
+ }
+ }
+ return ret;
}
};