From a2d7181700ac64b8e7a4472ec26dfa253b38f188 Mon Sep 17 00:00:00 2001 From: Lexi Winter Date: Sat, 28 Jun 2025 19:25:55 +0100 Subject: split nihil into separate modules --- nihil.error/error.cc | 160 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 nihil.error/error.cc (limited to 'nihil.error/error.cc') diff --git a/nihil.error/error.cc b/nihil.error/error.cc new file mode 100644 index 0000000..15805a3 --- /dev/null +++ b/nihil.error/error.cc @@ -0,0 +1,160 @@ +/* + * This source code is released into the public domain. + */ + +module; + +#include +#include +#include +#include +#include +#include + +module nihil.error; + +import nihil.match; + +namespace nihil { + +auto to_string(error const &self) -> std::string +{ + auto ret = self.str(); + + auto cause = self.cause(); + while (cause) { + ret += ": " + cause->str(); + cause = cause->cause(); + } + + return ret; +} + +error::error() +{ +} + +error::~error() = default; + +error::error(std::string_view what, error cause) + : m_error(std::string(what)) + , m_cause(std::make_shared(std::move(cause))) +{ +} +error::error(std::string_view what) + : m_error(std::string(what)) +{ +} + +error::error(std::error_condition what, error cause) + : m_error(what) + , m_cause(std::make_shared(std::move(cause))) +{ +} + +error::error(std::error_condition what) + : m_error(what) +{ +} + +error::error(std::error_code what, error cause) + : m_error(what) + , m_cause(std::make_shared(std::move(cause))) +{ +} + +error::error(std::error_code what) + : m_error(what) +{ +} + +error::error(error const &) = default; +error::error(error &&) noexcept = default; +auto error::operator=(this error &, error const &) -> error & = default; +auto error::operator=(this error &, error &&) noexcept -> error & = default; + +auto error::cause(this error const &self) -> std::shared_ptr +{ + if (self.m_cause) + return self.m_cause; + return {}; +} + +auto error::root_cause(this error const &self) -> error const & +{ + if (self.m_cause) + return self.m_cause->root_cause(); + + return self; +} + +auto error::str(this error const &self) -> std::string +{ + return self.m_error | match { + [] (std::monostate) -> std::string { + return "No error"; + }, + [] (std::error_code const &m) { + return m.message(); + }, + [] (std::error_condition const &m) { + return m.message(); + }, + [] (std::string const &m) { + return m; + } + }; +} + +auto error::code(this error const &self) -> std::optional +{ + auto const *code = std::get_if(&self.m_error); + if (code) + return {*code}; + return {}; +} + +auto error::condition(this error const &self) + -> std::optional +{ + auto const *condition = std::get_if(&self.m_error); + if (condition) + return {*condition}; + return {}; +} + +auto error::what() const noexcept -> char const * +{ + if (!m_what) + m_what = to_string(*this); + + return m_what->c_str(); +} + +auto operator==(error const &lhs, error const &rhs) -> bool +{ + return lhs.m_error == rhs.m_error; +} + +auto operator<=>(error const &lhs, error const &rhs) -> std::strong_ordering +{ + return lhs.m_error <=> rhs.m_error; +} + +auto operator==(error const &lhs, std::error_code const &rhs) -> bool +{ + return lhs.code() == rhs; +} + +// Compare an error to an std::error_condition. +auto operator==(error const &lhs, std::error_condition const &rhs) -> bool +{ + return lhs.condition() == rhs; +} + +auto operator<<(std::ostream &strm, error const &e) -> std::ostream & +{ + return strm << to_string(e); +} + +} // namespace nihil -- cgit v1.2.3