/* * This source code is released into the public domain. */ module; #include #include #include #include #include #include #include export module nihil.ucl:integer; import nihil; import :object; import :type; namespace nihil::ucl { export struct integer final : object { using contained_type = std::int64_t; inline static constexpr object_type ucl_type = object_type::integer; /* * Create an integer holding the value 0. Throws std::system_error * on failure. */ integer(); /* * Create an integer holding a specific value. Throws std::system_error * on failure. */ explicit integer(contained_type value); /* * Create a new integer from a UCL object. Throws type_mismatch * on failure. */ integer(ref_t, ::ucl_object_t const *uobj); integer(noref_t, ::ucl_object_t *uobj); // Return the value of this object. [[nodiscard]] auto value(this integer const &self) -> contained_type; }; /* * Integer constructors. These return an error instead of throwing. */ export [[nodiscard]] auto make_integer(integer::contained_type = 0) -> std::expected; /* * Comparison operators. */ export [[nodiscard]] auto operator== (integer const &a, integer const &b) -> bool; export [[nodiscard]] auto operator== (integer const &a, integer::contained_type b) -> bool; export [[nodiscard]] auto operator<=> (integer const &a, integer const &b) -> std::strong_ordering; export [[nodiscard]] auto operator<=> (integer const &a, integer::contained_type b) -> std::strong_ordering; /* * Literal operator. */ inline namespace literals { export constexpr auto operator""_ucl (unsigned long long i) -> integer { if (std::cmp_greater(i, std::numeric_limits::max())) throw std::out_of_range("literal out of range"); return integer(i); } } // namespace nihil::ucl::literals } // namespace nihil::ucl namespace nihil { inline namespace literals { export using namespace ::nihil::ucl::literals; }} // namespace nihil::literals /* * std::formatter for an integer. 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::integer const &o, FmtContext& ctx) const { return base_formatter.format(o.value(), ctx); } };