/* * This source code is released into the public domain. */ module; #include #include #include #include #include export module nihil.ucl:real; import :object; import :type; namespace nihil::ucl { export struct real final : object { using contained_type = double; inline static constexpr object_type ucl_type = object_type::real; /* * Create a real holding the value 0. Throws std::system_error * on failure. */ real(); /* * Create a real holding a specific value. Throws std::system_error * on failure. */ explicit real(contained_type value); /* * Create a new real from a UCL object. Throws type_mismatch * on failure. */ real(ref_t, ::ucl_object_t const *uobj); real(noref_t, ::ucl_object_t *uobj); // Return the value of this real. [[nodiscard]] auto value(this real const &self) -> contained_type; }; /* * Real constructors. These return an error instead of throwing. */ export [[nodiscard]] auto make_real(real::contained_type = 0) -> std::expected; /* * Comparison operators. */ export [[nodiscard]] auto operator== (real const &a, real const &b) -> bool; export [[nodiscard]] auto operator== (real const &a, real::contained_type b) -> bool; export [[nodiscard]] auto operator<=> (real const &a, real const &b) -> std::partial_ordering; export [[nodiscard]] auto operator<=> (real const &a, real::contained_type b) -> std::partial_ordering; /* * Literal operator. */ inline namespace literals { export constexpr auto operator""_ucl (long double d) -> real { if (d > static_cast(std::numeric_limits::max()) || d < static_cast(std::numeric_limits::min())) throw std::out_of_range("literal out of range"); return real(static_cast(d)); } } // namespace nihil::ucl::literals } // namespace nihil::ucl namespace nihil { inline namespace literals { export using namespace ::nihil::ucl::literals; }} // namespace nihil::literals /* * std::formatter for a real. This provides the same format operations * as std::formatter; */ export template<> struct std::formatter { std::formatter base_formatter; template constexpr ParseContext::iterator parse(ParseContext& ctx) { return base_formatter.parse(ctx); } template FmtContext::iterator format(nihil::ucl::real const &o, FmtContext& ctx) const { return base_formatter.format(o.value(), ctx); } };