diff options
Diffstat (limited to 'boot/result.cc')
| -rw-r--r-- | boot/result.cc | 87 |
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()); +} |
