You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
libexopt/include/error.hh

74 lines
2.5 KiB

#pragma once
#include <stdexcept>
#include <stacktrace>
#include <source_location>
#include "exopt.h"
#include "optional.h"
#include "util.hh"
namespace exopt {
// Report generated from an error. (virtual base, not abstract.)
class Report {
public:
virtual ~Report();
};
// This is propagated returned (base, abstract)
class Error {
public:
constexpr Error(Error const&) = default;
constexpr Error(Error &&) = default;
constexpr Error& operator=(Error &&) = default;
constexpr Error& operator=(Error const&) = default;
constexpr virtual std::source_location const& location() const noexcept { return m_location; }
constexpr operator std::string_view() const noexcept { return message(); }
constexpr virtual std::string_view message() const noexcept =0;
constexpr virtual MaybeOwnedRef<Error> inner() noexcept { return {}; } //TODO: Maybe just use `std::optional<std::reference_wrapper<Error>>`
constexpr virtual MaybeOwned<Report> into_report() noexcept { /* TODO */ } // XXX: ^^
constexpr virtual MaybeOwned<Report> into_report() && noexcept { /* TODO: auto{*this}.into_report() */ }
constexpr virtual ~Error() = default;
protected:
constexpr Error(std::source_location loc = std::source_location::current()) noexcept
: m_location(std::move(loc)) {}
private:
std::source_location m_location;
//Moved this to non-constexpr subclass `TracedError` \
std::unique_ptr<std::stacktrace> m_trace{nullptr}; //TODO: Change to exopt::types::Box<> to make copy ctor/assign work
};
// This is propagated returned, along with a stack trace. (base, abstract)
class TracedError : Error {
public:
TracedError(TracedError const &) = default;
TracedError(TracedError &&) = default;
TracedError& operator=(TracedError &&) = default;
TracedError& operator=(TracedError const&) = default;
virtual ~TracedError() = default;
inline virtual std::stacktrace const& stacktrace() const noexcept { return m_trace; }
protected:
inline TracedError(
std::source_location loc = std::source_location::current()
, std::stacktrace trace = std::stacktrace::current()) noexcept
: Error(std::move(loc)), m_trace(std::move(trace)) {}
private:
std::stacktrace m_trace; //TODO: Maybe box this? idk how big it is...
};
// This is thrown. (virtual base, abstract)
class Panic : /*virtual?? I think it should be XXX*/ Error {
//TODO: How to make a `constexpr` deduced panic that has stack-trace at runtime only? Is it needed? Hnm...
};
//TODO: Fatal(string) : public virtual Panic
}