# pragma once
# include <stdexcept>
# include <stacktrace>
# include <source_location>
# include "exopt.h"
# include "optional.h"
# include "either.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 types : : Option < Error & > inner ( ) noexcept { return { std : : nullopt } ; }
constexpr virtual types : : MaybeOwned < Report > into_report ( ) noexcept { /* TODO */ } //TODO: Maybe just use `std::optional<std::reference_wrapper<Error>>`? Or Box<Report&>?
constexpr virtual types : : 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
}