export struct error_msg {
string m_message;
error_msg() = default;
error_msg(cstr msg) : m_message(msg) {}
error_msg(string_view msg) : m_message(msg) {}
bool failed() const { return !m_message.empty(); }
operator string_view() const { return m_message; }
};
export enum class error_code : i32 {
ok = 0, fail = 1000,
invalid_argument, out_of_range, not_implemented,
file_not_found, permission_denied, read_error, write_error, end_of_file,
connection_failed, timeout, host_unreachable, protocol_error,
out_of_memory, resource_busy, resource_unavailable,
parse_error, format_error, validation_failed,
deadlock_detected, lock_failed, thread_error
};
template<typename T, typename E>
struct base_result {
base_result() = default;
base_result(const T& value) : m_value(value), m_error() {}
base_result(T&& value) : m_value(move(value)), m_error() {}
base_result(const E& error) : m_value(), m_error(error) {}
base_result(E&& error) : m_value(), m_error(move(error)) {}
operator tuple<T&, E&>()& { return { m_value, m_error }; }
operator tuple<T, E>()&& { return { move(m_value), move(m_error) }; }
operator tuple<const T&, const E&>() const& { return { m_value, m_error }; }
operator T&&()&& { return move(m_value); }
operator bool() const { return m_error == E(); }
const T& value() const& { return m_value; }
T&& value()&& { return move(m_value); }
const E& error() const& { return m_error; }
E&& error()&& { return move(m_error); }
T m_value = {};
E m_error = {};
};
export template<typename T> using result = base_result<T, error_code>;
export template<typename T> using report = base_result<T, error_msg>;
export error_code error(error_code code) { return error_code(code); }
export error_msg error(cstr msg) { return error_msg(msg); }
export error_msg error(string_view msg) { return error_msg(msg); }