aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author hop311 <hop3114@gmail.com>2024-03-18 20:58:00 +0100
committer hop311 <hop3114@gmail.com>2024-03-20 23:31:32 +0100
commit60d3b5bdde3f0c4001fa8c4843f999e77568f810 (patch)
tree647acbb45e7943dc48631f5cefe9c3de0cc3e0b6
parent721577e1210c8e9a526b69c77b0bddb098fd5d1e (diff)
Add fixed_point_map_t operators and helper functions
-rw-r--r--src/openvic-simulation/types/fixed_point/FixedPoint.hpp4
-rw-r--r--src/openvic-simulation/types/fixed_point/FixedPointMap.hpp128
2 files changed, 129 insertions, 3 deletions
diff --git a/src/openvic-simulation/types/fixed_point/FixedPoint.hpp b/src/openvic-simulation/types/fixed_point/FixedPoint.hpp
index 95d2759..9ad7966 100644
--- a/src/openvic-simulation/types/fixed_point/FixedPoint.hpp
+++ b/src/openvic-simulation/types/fixed_point/FixedPoint.hpp
@@ -658,6 +658,10 @@ namespace OpenVic {
return static_cast<int64_t>(lhs) << PRECISION != rhs.value;
}
+ constexpr friend std::strong_ordering operator<=>(fixed_point_t const& lhs, fixed_point_t const& rhs) {
+ return lhs.value <=> rhs.value;
+ }
+
private:
static constexpr fixed_point_t parse_integer(char const* str, char const* const end, bool* successful) {
int64_t parsed_value = StringUtils::string_to_int64(str, end, successful, 10);
diff --git a/src/openvic-simulation/types/fixed_point/FixedPointMap.hpp b/src/openvic-simulation/types/fixed_point/FixedPointMap.hpp
index 1904fec..5df537a 100644
--- a/src/openvic-simulation/types/fixed_point/FixedPointMap.hpp
+++ b/src/openvic-simulation/types/fixed_point/FixedPointMap.hpp
@@ -14,20 +14,140 @@ namespace OpenVic {
template<typename T>
using fixed_point_map_const_iterator_t = typename fixed_point_map_t<T>::const_iterator;
+ template<typename T, std::derived_from<T> U>
+ constexpr fixed_point_map_t<T const*>& cast_map(fixed_point_map_t<U const*>& map) {
+ return *reinterpret_cast<fixed_point_map_t<T const*>*>(&map);
+ }
+
+ template<typename T, std::derived_from<T> U>
+ constexpr fixed_point_map_t<T const*> const& cast_map(fixed_point_map_t<U const*> const& map) {
+ return *reinterpret_cast<fixed_point_map_t<T const*> const*>(&map);
+ }
+
+ template<typename T>
+ constexpr fixed_point_map_t<T>& operator+=(fixed_point_map_t<T>& lhs, fixed_point_map_t<T> const& rhs) {
+ for (auto const& [key, value] : rhs) {
+ lhs[key] += value;
+ }
+
+ return lhs;
+ }
+
+ template<typename T>
+ constexpr fixed_point_map_t<T> operator+(fixed_point_map_t<T> const& lhs, fixed_point_map_t<T> const& rhs) {
+ fixed_point_map_t<T> result = lhs;
+
+ result += rhs;
+
+ return result;
+ }
+
+ template<typename T>
+ constexpr fixed_point_map_t<T>& operator*=(fixed_point_map_t<T>& lhs, fixed_point_t rhs) {
+ for (auto [key, value] : mutable_iterator(lhs)) {
+ value *= rhs;
+ }
+
+ return lhs;
+ }
+
+ template<typename T>
+ constexpr fixed_point_map_t<T> operator*(fixed_point_map_t<T> const& lhs, fixed_point_t rhs) {
+ fixed_point_map_t<T> result = lhs;
+
+ result *= rhs;
+
+ return result;
+ }
+
+ template<typename T>
+ constexpr fixed_point_map_t<T> operator*(fixed_point_t lhs, fixed_point_map_t<T> const& rhs) {
+ return rhs * lhs;
+ }
+
+ template<typename T>
+ constexpr fixed_point_map_t<T>& operator/=(fixed_point_map_t<T>& lhs, fixed_point_t rhs) {
+ for (auto [key, value] : mutable_iterator(lhs)) {
+ value /= rhs;
+ }
+
+ return lhs;
+ }
+
+ template<typename T>
+ constexpr fixed_point_map_t<T> operator/(fixed_point_map_t<T> const& lhs, fixed_point_t rhs) {
+ fixed_point_map_t<T> result = lhs;
+
+ result /= rhs;
+
+ return result;
+ }
+
+ /* Assumes arguments are sorted with keys ascending. Result is determined by the
+ * first non-equal keys or values found starting from the back of the maps. */
+ template<typename T>
+ constexpr bool sorted_fixed_map_less_than(fixed_point_map_t<T> const& lhs, fixed_point_map_t<T> const& rhs) {
+
+ typename fixed_point_map_t<T>::const_reverse_iterator lit, rit;
+
+ for (lit = lhs.rcbegin(), rit = rhs.rcbegin(); lit != lhs.rcend() && rit != rhs.rcend(); lit++, rit++) {
+
+ const std::strong_ordering key_cmp = lit->first <=> rit->first;
+
+ if (key_cmp != std::strong_ordering::equal) {
+ return key_cmp == std::strong_ordering::less;
+ }
+
+ const std::strong_ordering value_cmp = lit->second <=> rit->second;
+
+ if (value_cmp != std::strong_ordering::equal) {
+ return value_cmp == std::strong_ordering::less;
+ }
+
+ }
+
+ return rit != rhs.rcend();
+ }
+
template<typename T>
constexpr fixed_point_t get_total(fixed_point_map_t<T> const& map) {
fixed_point_t total = 0;
+
for (auto const& [key, value] : map) {
total += value;
}
+
return total;
}
template<typename T>
+ constexpr void normalise_fixed_point_map(fixed_point_map_t<T>& map) {
+ const fixed_point_t total = get_total(map);
+
+ if (total > 0) {
+ map /= total;
+ }
+ }
+
+ template<typename T>
+ constexpr void rescale_fixed_point_map(fixed_point_map_t<T>& map, fixed_point_t new_total) {
+ const fixed_point_t total = get_total(map);
+
+ if (total > 0) {
+ for (auto [key, value] : mutable_iterator(map)) {
+ value *= new_total;
+ value /= total;
+ }
+ }
+ }
+
+ template<typename T>
constexpr fixed_point_map_const_iterator_t<T> get_largest_item(fixed_point_map_t<T> const& map) {
- constexpr auto pred = [](fixed_point_map_value_t<T> a, fixed_point_map_value_t<T> b) -> bool {
- return a.second < b.second;
- };
+ constexpr auto pred =
+ [](fixed_point_map_value_t<T> const& lhs, fixed_point_map_value_t<T> const& rhs) -> bool {
+ return lhs.second < rhs.second;
+ };
+
return std::max_element(map.begin(), map.end(), pred);
}
@@ -36,6 +156,7 @@ namespace OpenVic {
fixed_point_map_t<T> const& map
) {
fixed_point_map_const_iterator_t<T> largest = map.end(), second_largest = map.end();
+
for (fixed_point_map_const_iterator_t<T> it = map.begin(); it != map.end(); ++it) {
if (largest == map.end() || it->second > largest->second) {
second_largest = largest;
@@ -44,6 +165,7 @@ namespace OpenVic {
second_largest = it;
}
}
+
return std::make_pair(std::move(largest), std::move(second_largest));
}
}