diff options
| author | Lexi Winter <lexi@le-fay.org> | 2025-07-01 17:07:04 +0100 |
|---|---|---|
| committer | Lexi Winter <lexi@le-fay.org> | 2025-07-01 17:07:04 +0100 |
| commit | 2e2d1bd3b6c7776b77c33b94f30ead89367a71e6 (patch) | |
| tree | 54d37ffadf8e677938d9b7a28e4e9b71be1e75c1 /nihil.ucl/boolean.ccm | |
| parent | 36427c0966faa7aecd586b397ed9b845f18172f5 (diff) | |
| download | nihil-2e2d1bd3b6c7776b77c33b94f30ead89367a71e6.tar.gz nihil-2e2d1bd3b6c7776b77c33b94f30ead89367a71e6.tar.bz2 | |
add nihil.std
Diffstat (limited to 'nihil.ucl/boolean.ccm')
| -rw-r--r-- | nihil.ucl/boolean.ccm | 138 |
1 files changed, 83 insertions, 55 deletions
diff --git a/nihil.ucl/boolean.ccm b/nihil.ucl/boolean.ccm index 068dfdd..4cacdc4 100644 --- a/nihil.ucl/boolean.ccm +++ b/nihil.ucl/boolean.ccm @@ -1,90 +1,118 @@ -/* - * This source code is released into the public domain. - */ - +// This source code is released into the public domain. module; -#include <cassert> -#include <cstdint> -#include <cstdlib> -#include <expected> -#include <format> -#include <string> - #include <ucl.h> export module nihil.ucl:boolean; +import nihil.std; +import nihil.core; import :object; namespace nihil::ucl { -export struct boolean final : object { +export struct boolean final : object +{ using contained_type = bool; - inline static constexpr object_type ucl_type = object_type::boolean; + static constexpr object_type ucl_type = object_type::boolean; + + // Create a boolean holding the value false. Throws std::system_error + // on failure. + boolean() + : boolean(false) + { + } + + // Create a boolean holding a specific value. Throws std::system_error + // on failure. + explicit boolean(bool const value) + : object(noref, [&] { + auto *uobj = ::ucl_object_frombool(value); + if (uobj == nullptr) + throw std::system_error(std::make_error_code(sys_error())); + return uobj; + }()) + { + } - /* - * Create a boolean holding the value false. Throws std::system_error - * on failure. - */ - boolean(); + // Create a new boolean from a UCL object. Throws type_mismatch + // on failure. - /* - * Create a boolean holding a specific value. Throws std::system_error - * on failure. - */ - explicit boolean(bool); + boolean(ref_t, ::ucl_object_t const *uobj) + : object(nihil::ucl::ref, ensure_ucl_type(uobj, boolean::ucl_type)) + { + } - /* - * Create a new boolean from a UCL object. Throws type_mismatch - * on failure. - */ - boolean(ref_t, ::ucl_object_t const *uobj); - boolean(noref_t, ::ucl_object_t *uobj); + boolean(noref_t, ::ucl_object_t *uobj) + : object(nihil::ucl::noref, ensure_ucl_type(uobj, boolean::ucl_type)) + { + } // Return this object's value. - auto value(this boolean const &self) -> contained_type; -}; + auto value(this boolean const &self) -> contained_type + { + auto v = contained_type{}; + auto const *uobj = self.get_ucl_object(); -/* - * Boolean constructors. These return an error instead of throwing. - */ + if (::ucl_object_toboolean_safe(uobj, &v)) + return v; -export [[nodiscard]] auto -make_boolean(boolean::contained_type = false) -> std::expected<boolean, error>; + throw std::runtime_error("ucl_object_toboolean_safe failed"); + } + +private: + // Comparison operators. + [[nodiscard]] friend auto operator==(boolean const &a, boolean const &b) -> bool + { + return a.value() == b.value(); + } -/* - * Comparison operators. - */ + [[nodiscard]] friend auto + operator<=>(boolean const &a, boolean const &b) -> std::strong_ordering + { + return static_cast<int>(a.value()) <=> static_cast<int>(b.value()); + } -export auto operator== (boolean const &a, boolean const &b) -> bool; -export auto operator== (boolean const &a, boolean::contained_type b) -> bool; -export auto operator<=> (boolean const &a, boolean const &b) - -> std::strong_ordering; -export auto operator<=> (boolean const &a, boolean::contained_type b) - -> std::strong_ordering; + [[nodiscard]] friend auto operator==(boolean const &a, contained_type const b) -> bool + { + return a.value() == b; + } + + [[nodiscard]] friend auto + operator<=>(boolean const &a, contained_type const b) -> std::strong_ordering + { + return static_cast<int>(a.value()) <=> static_cast<int>(b); + } +}; + +// Boolean constructors. This returns an error instead of throwing. +export [[nodiscard]] auto +make_boolean(boolean::contained_type const value = false) -> std::expected<boolean, error> +{ + if (auto *uobj = ::ucl_object_frombool(value); uobj == nullptr) + return error(errc::failed_to_create_object, error(sys_error())); + else + return boolean(noref, uobj); +} } // namespace nihil::ucl -/* - * std::formatter for a boolean. This provides the same format operations - * as std::formatter<bool>. - */ -export template<> +// std::formatter for a boolean. This provides the same format operations +// as std::formatter<bool>. +export template <> struct std::formatter<nihil::ucl::boolean, char> { std::formatter<bool> base_formatter; - template<class ParseContext> - constexpr ParseContext::iterator parse(ParseContext& ctx) + template <class ParseContext> + constexpr auto parse(ParseContext &ctx) -> ParseContext::iterator { return base_formatter.parse(ctx); } - template<class FmtContext> - FmtContext::iterator format(nihil::ucl::boolean const &o, - FmtContext& ctx) const + template <class FmtContext> + auto format(nihil::ucl::boolean const &o, FmtContext &ctx) const -> FmtContext::iterator { return base_formatter.format(o.value(), ctx); } |
