aboutsummaryrefslogtreecommitdiff
path: root/boot/result.cc
diff options
context:
space:
mode:
Diffstat (limited to 'boot/result.cc')
-rw-r--r--boot/result.cc87
1 files changed, 87 insertions, 0 deletions
diff --git a/boot/result.cc b/boot/result.cc
index 3970b1f..d25b85b 100644
--- a/boot/result.cc
+++ b/boot/result.cc
@@ -18,6 +18,8 @@ along with GCC; see the file COPYING3. If not see
#include "elna/boot/result.h"
#include <algorithm>
+#include <charconv>
+#include <cmath>
#include <cstring>
#include <numeric>
@@ -467,6 +469,85 @@ namespace elna::boot
return mpz_sgn(this->raw) < 0;
}
+ float_literal::float_literal(format_kind binary_format, double value)
+ : m_format(binary_format), raw(value)
+ {
+ }
+
+ float_literal float_literal::rounded(format_kind binary_format, double value)
+ {
+ if (binary_format == format_kind::binary32)
+ {
+ return float_literal(format_kind::binary32, static_cast<float>(value));
+ }
+ return float_literal(binary_format, value);
+ }
+
+ float_literal float_literal::operator+(const float_literal& that) const
+ {
+ return rounded(this->m_format, this->raw + that.raw);
+ }
+
+ float_literal float_literal::operator-(const float_literal& that) const
+ {
+ return rounded(this->m_format, this->raw - that.raw);
+ }
+
+ float_literal float_literal::operator*(const float_literal& that) const
+ {
+ return rounded(this->m_format, this->raw * that.raw);
+ }
+
+ float_literal float_literal::operator/(const float_literal& that) const
+ {
+ return rounded(this->m_format, this->raw / that.raw);
+ }
+
+ float_literal float_literal::operator-() const
+ {
+ return rounded(this->m_format, -this->raw);
+ }
+
+ bool float_literal::operator==(const float_literal& that) const
+ {
+ return this->raw == that.raw;
+ }
+
+ std::partial_ordering float_literal::operator<=>(const float_literal& that) const
+ {
+ return this->raw <=> that.raw;
+ }
+
+ float_literal::format_kind float_literal::format() const
+ {
+ return this->m_format;
+ }
+
+ std::string float_literal::to_string() const
+ {
+ constexpr std::size_t shortest_round_trip = 24;
+ std::array<char, shortest_round_trip + 4> buffer;
+
+ auto float_chars = std::to_chars(buffer.begin(), buffer.end(), this->raw);
+
+ return std::string(buffer.begin(), float_chars.ptr);
+ }
+
+ float_literal float_literal::cast_to(format_kind binary_format) const
+ {
+ return rounded(binary_format, this->raw);
+ }
+
+ double float_literal::value() const
+ {
+ return this->raw;
+ }
+
+ bool float_literal::is_finite() const
+ {
+ return std::isfinite(this->raw);
+ }
+
std::size_t constant_value_hash::operator()(const elna::boot::constant_value& value) const noexcept
{
return std::visit([](auto&& alternative) -> std::size_t {
@@ -541,3 +622,9 @@ std::size_t std::hash<elna::boot::integer_literal>::operator()(const elna::boot:
}
return 0;
}
+
+std::size_t std::hash<elna::boot::float_literal>::operator()(const elna::boot::float_literal& key) const noexcept
+{
+ // -0.0 and 0.0 compare equal, so their hashes must agree.
+ return std::hash<double>{}(key == 0.0 ? 0.0 : key.value());
+}