1
0
forked from Alepha/Alepha

The great exception rename.

This commit is contained in:
2023-10-15 02:34:23 -04:00
parent 384eba5797
commit b97ede2b86
2 changed files with 177 additions and 137 deletions

View File

@ -24,25 +24,36 @@ namespace Alepha::Hydrogen
* In Alepha, there are several "grades" of exception types which can be thrown. The grade of * In Alepha, there are several "grades" of exception types which can be thrown. The grade of
* an exception is "branded" into its name as the last word in camel case. * an exception is "branded" into its name as the last word in camel case.
* *
* * `Throwable`: All exceptions inherit from this interface. Catching this will * * `Exception`: All exceptions inherit from this interface. Catching this will
* catch anything which is part of this system. Normally you just ignore this grade. * catch anything which is part of this system. Normally you just ignore this grade.
* Code that needs to catch *everything* should not catch `Throwable`, but `catch( ... )` * Code that needs to catch *everything* should not catch `Exception`, but `catch( ... )`
* instead. * instead. `Exception` is the mechanism by which various situations are reported.
* For comparison, Java calls this class `Throwable`.
* *
* * `Notification`: When a thread is cancelled using interrupts, all exceptions thrown * * `Condition`: An out-of-band message from functions which notify their callers of
* new information that affects the ability to fulfill the common case expected
* result. Note that this kind of `Exception` is not considered a contract `Violation`.
* This exception can be thrown as part of normal program operation -- it is a control
* flow device.
*
* * `Notification`: When a thread is cancelled using interrupts, all `Exception`s thrown
* to do so are derived from this type. Alepha threads are setup to catch and discard * to do so are derived from this type. Alepha threads are setup to catch and discard
* exceptions of this grade in the thread start function. * `Exception`s of this grade in the thread start function. It is legal to catch `Exception`s
* of this type type and silence it; however, `Notification` typically means that the
* target thread needs to change its behaviour. (Note that `ThreadInterrupt` is entirely
* independent from the Alepha exception hierarchy -- this helps ensure that the thread
* termination mechanism works correctly.)
* *
* * `Exception`: This is the exception grade you would typically want to recover from. * * `Error`: This is the exception grade you would typically want to recover from.
* Catch this grade, typically. They should contain sufficient information in their * Catch this grade, in most circumstances. They should contain sufficient information in their
* data pack to facilitate a proper programmatic recovery. All exceptions of this grade * data pack to facilitate a proper programmatic recovery. All exceptions of this grade
* will also have `std::exception` as one of its bases, thus code which is unaware of * will also have `std::exception` as one of its bases, thus code which is unaware of
* Alepha exceptions, but handles basic standard exceptions cleanly, will work just fine. * Alepha exceptions, but handles basic standard exceptions cleanly, will work just fine.
* When an `Exception` models something that the standard library models, such as * When an `Error` models something that the standard library models, such as
* `std::bad_alloc`, then that `Exception` will be eligible for catch by that base as well. * `std::bad_alloc`, then that `Error` will be eligible for catch by that base as well.
* *
* * `Error`: This exception grade represents a form of moderately-unrecoverable condition. * * `CriticalError`: This exception grade represents a form of moderately-unrecoverable condition.
* The `Error` grade typically indicates a condition that prevents the current thread or * The `CriticalError` grade typically indicates a condition that prevents the current thread or
* program state from being easily transitioned to a recovered state. However, a very * program state from being easily transitioned to a recovered state. However, a very
* large state transform, such as an unwind to the top-of-thread-callstack handler, may * large state transform, such as an unwind to the top-of-thread-callstack handler, may
* be able to recover. For example, no more available operating system file handles. * be able to recover. For example, no more available operating system file handles.
@ -97,15 +108,15 @@ namespace Alepha::Hydrogen
template< typename Exc, typename tag > template< typename Exc, typename tag >
using Tagged= typename Exc::template tagged_type< tag >; using Tagged= typename Exc::template tagged_type< tag >;
class Throwable class Exception
{ {
public: public:
using grade_type= Throwable; using grade_type= Exception;
class any_tagged_type; class any_tagged_type;
template< typename Tag > class tagged_type; template< typename Tag > class tagged_type;
virtual ~Throwable()= default; virtual ~Exception()= default;
virtual const char *message() const noexcept= 0; virtual const char *message() const noexcept= 0;
template< typename Target > template< typename Target >
@ -127,14 +138,14 @@ namespace Alepha::Hydrogen
return dynamic_cast< const Target * >( this ); return dynamic_cast< const Target * >( this );
} }
}; };
class Throwable::any_tagged_type class Exception::any_tagged_type
: virtual public grade_type : virtual public grade_type
{ {
public: public:
virtual std::type_index tag() const noexcept= 0; virtual std::type_index tag() const noexcept= 0;
}; };
template< typename Tag > template< typename Tag >
class Throwable::tagged_type class Exception::tagged_type
: virtual public grade_type, virtual public grade_type::any_tagged_type : virtual public grade_type, virtual public grade_type::any_tagged_type
{ {
public: public:
@ -144,16 +155,40 @@ namespace Alepha::Hydrogen
return typeid( std::type_identity< Tag > ); return typeid( std::type_identity< Tag > );
} }
}; };
using AnyTaggedThrowable= AnyTagged< Throwable >; using AnyTaggedException= AnyTagged< Exception >;
template< typename tag > template< typename tag >
using TaggedThrowable= Tagged< Throwable, tag >; using TaggedException= Tagged< Exception, tag >;
// `Condition`s are "events" that indicate a need
// for special control flow changes.
//
// They must be handled, but they do not represent
// an error -- just a "time to change your focus".
class Condition
: public virtual Exception
{
public:
using grade_type= Condition;
class any_tagged_type;
template< typename tag >
class tagged_type;
};
class Condition::any_tagged_type
: public virtual bases< grade_type, Exception::any_tagged_type > {};
template< typename tag >
class Condition::tagged_type
: public virtual bases< grade_type::any_tagged_type, Exception::tagged_type< tag > > {};
using AnyTaggedCondition= Condition::any_tagged_type;
template< typename tag >
using TaggedCondition= Condition::tagged_type< tag >;
// `Notification`s are "events" or "interrupts" that // `Notification`s are "events" or "interrupts" that
// if ignored will gracefully terminate the current // if ignored will gracefully terminate the current
// thread, but not halt the program. // thread, but not halt the program.
class Notification class Notification
: public virtual Throwable : public virtual Exception
{ {
public: public:
using grade_type= Notification; using grade_type= Notification;
@ -163,67 +198,62 @@ namespace Alepha::Hydrogen
class tagged_type; class tagged_type;
}; };
class Notification::any_tagged_type class Notification::any_tagged_type
: public virtual bases< grade_type, Throwable::any_tagged_type > {}; : public virtual bases< grade_type, Exception::any_tagged_type > {};
template< typename tag > template< typename tag >
class Notification::tagged_type class Notification::tagged_type
: public virtual bases< grade_type::any_tagged_type, Throwable::tagged_type< tag > > {}; : public virtual bases< grade_type::any_tagged_type, Exception::tagged_type< tag > > {};
using AnyTaggedNotification= Notification::any_tagged_type; using AnyTaggedNotification= Notification::any_tagged_type;
template< typename tag > template< typename tag >
using TaggedNotification= Notification::tagged_type< tag >; using TaggedNotification= Notification::tagged_type< tag >;
using Interrupt= Notification; // `Error`s are recoverable at any point.
using AnyTaggedInterrupt= AnyTaggedNotification; class ErrorBridgeInterface
template< typename tag >
using TaggedInterrupt= TaggedNotification< tag >;
// `Exception`s are recoverable at any point.
class ExceptionBridgeInterface
{ {
public: public:
virtual const char *what() const noexcept= 0; virtual const char *what() const noexcept= 0;
}; };
class Exception
: virtual public bases< Throwable >, virtual private ExceptionBridgeInterface
{
public:
using grade_type= Exception;
using ExceptionBridgeInterface::what;
class any_tagged_type;
template< typename tag >
class tagged_type;
};
class Exception::any_tagged_type : virtual public bases< grade_type, Throwable::any_tagged_type > {};
template< typename tag >
class Exception::tagged_type
: virtual public bases< grade_type::any_tagged_type, Throwable::tagged_type< tag > > {};
using AnyTaggedException= Exception::any_tagged_type;
template< typename tag >
using TaggedException= Exception::tagged_type< tag >;
// `Error`s are only really recoverable by terminating
// the major procedure underway. Like terminating the
// entire thread or similar. Essentially, arbitrarily
// localized recovery is impossible.
class Error class Error
: virtual public bases< Throwable > : virtual public bases< Exception >, virtual private ErrorBridgeInterface
{ {
public: public:
using grade_type= Error; using grade_type= Error;
using ErrorBridgeInterface::what;
class any_tagged_type; class any_tagged_type;
template< typename tag > template< typename tag >
class tagged_type; class tagged_type;
}; };
class Error::any_tagged_type class Error::any_tagged_type : virtual public bases< grade_type, Exception::any_tagged_type > {};
: virtual public bases< grade_type, Throwable::any_tagged_type > {};
template< typename tag > template< typename tag >
class Error::tagged_type class Error::tagged_type
: virtual bases< grade_type::any_tagged_type, Throwable::tagged_type< tag > > {}; : virtual public bases< grade_type::any_tagged_type, Exception::tagged_type< tag > > {};
using AnyTaggedError= Error::any_tagged_type; using AnyTaggedError= Error::any_tagged_type;
template< typename tag > template< typename tag >
using TaggedError= Error::tagged_type< tag >; using TaggedError= Error::tagged_type< tag >;
// `CriticalError`s are only really recoverable by terminating
// the major procedure underway. Like terminating the
// entire thread or similar. Essentially, arbitrarily
// localized recovery is impossible.
class CriticalError
: virtual public bases< Exception >
{
public:
using grade_type= CriticalError;
class any_tagged_type;
template< typename tag >
class tagged_type;
};
class CriticalError::any_tagged_type
: virtual public bases< grade_type, Exception::any_tagged_type > {};
template< typename tag >
class CriticalError::tagged_type
: public virtual bases< grade_type::any_tagged_type, Exception::tagged_type< tag > > {};
using AnyTaggedCriticalError= CriticalError::any_tagged_type;
template< typename tag >
using TaggedCriticalError= CriticalError::tagged_type< tag >;
// `Violation`s are unrecoverable events which happen to // `Violation`s are unrecoverable events which happen to
// the process. They are impossible to recover from. // the process. They are impossible to recover from.
// Handlers for this should be treated almost like // Handlers for this should be treated almost like
@ -233,7 +263,7 @@ namespace Alepha::Hydrogen
// which is somewhat different to the normal dtors in scope // which is somewhat different to the normal dtors in scope
// and then continue the unwind process // and then continue the unwind process
class Violation class Violation
: virtual public bases< Throwable > : virtual public bases< Exception >
{ {
private: private:
bool active= true; bool active= true;
@ -249,15 +279,15 @@ namespace Alepha::Hydrogen
Violation( const Violation &copy )= delete; Violation( const Violation &copy )= delete;
Violation( Violation &copy ) : active( copy.active ) { copy.active= false; } Violation( Violation &copy ) : active( copy.active ) { copy.active= false; }
}; };
class Violation::any_tagged_type : virtual public bases< grade_type, Throwable::any_tagged_type > {}; class Violation::any_tagged_type : virtual public bases< grade_type, Exception::any_tagged_type > {};
template< typename tag > template< typename tag >
class Violation::tagged_type : virtual public bases< grade_type::any_tagged_type, Throwable::tagged_type< tag > > {}; class Violation::tagged_type : virtual public bases< grade_type::any_tagged_type, Exception::tagged_type< tag > > {};
using AnyTaggedViolation= Violation::any_tagged_type; using AnyTaggedViolation= Violation::any_tagged_type;
template< typename tag > template< typename tag >
using TaggedViolation= Violation::tagged_type< tag >; using TaggedViolation= Violation::tagged_type< tag >;
template< typename T > template< typename T >
concept DerivedFromException= std::is_base_of_v< Exception, T >; concept DerivedFromError= std::is_base_of_v< Error, T >;
class NamedResourceStorage; class NamedResourceStorage;
class NamedResourceInterface class NamedResourceInterface
@ -277,48 +307,48 @@ namespace Alepha::Hydrogen
public: public:
std::string_view resourceName() const noexcept final { return storage; } std::string_view resourceName() const noexcept final { return storage; }
}; };
class NamedResourceThrowable : public virtual synthetic_exception< struct named_resource_throwable, Throwable >, virtual public NamedResourceInterface {}; class NamedResourceException : public virtual synthetic_exception< struct named_resource_throwable, Exception >, virtual public NamedResourceInterface {};
using AnyTaggedNamedResourceThrowable= NamedResourceThrowable::any_tagged_type;
template< typename tag >
using TaggedNamedResourceThrowable= NamedResourceThrowable::tagged_type< tag >;
using NamedResourceNotification= synthetic_exception< struct named_resource_notification, Notification, NamedResourceThrowable >;
using AnyTaggedNamedResourceNotification= NamedResourceNotification::any_tagged_type;
template< typename tag >
using TaggedNamedResourceNotification= NamedResourceNotification::tagged_type< tag >;
using NamedResourceException= synthetic_exception< struct named_resource_exception, Exception, NamedResourceThrowable >;
using AnyTaggedNamedResourceException= NamedResourceException::any_tagged_type; using AnyTaggedNamedResourceException= NamedResourceException::any_tagged_type;
template< typename tag > template< typename tag >
using TaggedNamedResourceException= NamedResourceException::tagged_type< tag >; using TaggedNamedResourceException= NamedResourceException::tagged_type< tag >;
using NamedResourceError= synthetic_exception< struct named_resource_error, Error, NamedResourceThrowable >; using NamedResourceNotification= synthetic_exception< struct named_resource_notification, Notification, NamedResourceException >;
using AnyTaggedNamedResourceNotification= NamedResourceNotification::any_tagged_type;
template< typename tag >
using TaggedNamedResourceNotification= NamedResourceNotification::tagged_type< tag >;
using NamedResourceError= synthetic_exception< struct named_resource_exception, Error, NamedResourceException >;
using AnyTaggedNamedResourceError= NamedResourceError::any_tagged_type; using AnyTaggedNamedResourceError= NamedResourceError::any_tagged_type;
template< typename tag > template< typename tag >
using TaggedNamedResourceError= NamedResourceError::tagged_type< tag >; using TaggedNamedResourceError= NamedResourceError::tagged_type< tag >;
using NamedResourceViolation= synthetic_exception< struct named_resource_violation, Violation, NamedResourceThrowable >; using NamedResourceCriticalError= synthetic_exception< struct named_resource_error, CriticalError, NamedResourceException >;
using AnyTaggedNamedResourceCriticalError= NamedResourceCriticalError::any_tagged_type;
template< typename tag >
using TaggedNamedResourceCriticalError= NamedResourceCriticalError::tagged_type< tag >;
using NamedResourceViolation= synthetic_exception< struct named_resource_violation, Violation, NamedResourceException >;
using AnyTaggedNamedResourceViolation= NamedResourceViolation::any_tagged_type; using AnyTaggedNamedResourceViolation= NamedResourceViolation::any_tagged_type;
template< typename tag > template< typename tag >
using TaggedNamedResourceViolation= NamedResourceViolation::tagged_type< tag >; using TaggedNamedResourceViolation= NamedResourceViolation::tagged_type< tag >;
class OutOfRangeThrowable class OutOfRangeException
: virtual public synthetic_exception< struct out_of_range_throwable, Throwable > {}; : virtual public synthetic_exception< struct out_of_range_throwable, Exception > {};
using AnyTaggedOutOfRangeThrowable= OutOfRangeThrowable::any_tagged_type;
template< typename tag >
using TaggedOutOfRangeThrowable= OutOfRangeThrowable::tagged_type< tag >;
using OutOfRangeException= synthetic_exception< struct out_of_range_throwable, Exception, OutOfRangeThrowable >;
using AnyTaggedOutOfRangeException= OutOfRangeException::any_tagged_type; using AnyTaggedOutOfRangeException= OutOfRangeException::any_tagged_type;
template< typename tag > template< typename tag >
using TaggedOutOfRangeException= OutOfRangeException::tagged_type< tag >; using TaggedOutOfRangeException= OutOfRangeException::tagged_type< tag >;
using OutOfRangeError= synthetic_exception< struct out_of_range_throwable, Error, OutOfRangeThrowable >; using OutOfRangeError= synthetic_exception< struct out_of_range_throwable, Error, OutOfRangeException >;
using AnyTaggedOutOfRangeError= OutOfRangeError::any_tagged_type; using AnyTaggedOutOfRangeError= OutOfRangeError::any_tagged_type;
template< typename tag > template< typename tag >
using TaggedOutOfRangeError= OutOfRangeError::tagged_type< tag >; using TaggedOutOfRangeError= OutOfRangeError::tagged_type< tag >;
using OutOfRangeViolation= synthetic_exception< struct out_of_range_throwable, Violation, OutOfRangeThrowable >; using OutOfRangeCriticalError= synthetic_exception< struct out_of_range_throwable, CriticalError, OutOfRangeException >;
using AnyTaggedOutOfRangeCriticalError= OutOfRangeCriticalError::any_tagged_type;
template< typename tag >
using TaggedOutOfRangeCriticalError= OutOfRangeCriticalError::tagged_type< tag >;
using OutOfRangeViolation= synthetic_exception< struct out_of_range_throwable, Violation, OutOfRangeException >;
using AnyTaggedOutOfRangeViolation= OutOfRangeViolation::any_tagged_type; using AnyTaggedOutOfRangeViolation= OutOfRangeViolation::any_tagged_type;
template< typename tag > template< typename tag >
using TaggedOutOfRangeViolation= OutOfRangeViolation::tagged_type< tag >; using TaggedOutOfRangeViolation= OutOfRangeViolation::tagged_type< tag >;
@ -346,27 +376,27 @@ namespace Alepha::Hydrogen
std::size_t upperBound() const noexcept override { return top; } std::size_t upperBound() const noexcept override { return top; }
std::size_t requested() const noexcept override { return request; } std::size_t requested() const noexcept override { return request; }
}; };
class IndexOutOfRangeThrowable
: virtual public synthetic_exception< struct index_out_of_range_throwable, Throwable, OutOfRangeThrowable > {};
using AnyTaggedIndexOutOfRangeThrowable= IndexOutOfRangeThrowable::any_tagged_type;
template< typename tag >
using TaggedIndexOutOfRangeThrowable= IndexOutOfRangeThrowable::tagged_type< tag >;
class IndexOutOfRangeException class IndexOutOfRangeException
: virtual public synthetic_exception< struct index_out_of_range_throwable, OutOfRangeException, IndexOutOfRangeThrowable > {}; : virtual public synthetic_exception< struct index_out_of_range_throwable, Exception, OutOfRangeException > {};
using AnyTaggedIndexOutOfRangeException= IndexOutOfRangeException::any_tagged_type; using AnyTaggedIndexOutOfRangeException= IndexOutOfRangeException::any_tagged_type;
template< typename tag > template< typename tag >
using TaggedIndexOutOfRangeException= IndexOutOfRangeException::tagged_type< tag >; using TaggedIndexOutOfRangeException= IndexOutOfRangeException::tagged_type< tag >;
class IndexOutOfRangeError class IndexOutOfRangeError
: virtual public synthetic_exception< struct index_out_of_range_throwable, OutOfRangeError, IndexOutOfRangeThrowable > {}; : virtual public synthetic_exception< struct index_out_of_range_throwable, OutOfRangeError, IndexOutOfRangeException > {};
using AnyTaggedIndexOutOfRangeError= IndexOutOfRangeError::any_tagged_type; using AnyTaggedIndexOutOfRangeException= IndexOutOfRangeException::any_tagged_type;
template< typename tag > template< typename tag >
using TaggedIndexOutOfRangeError= IndexOutOfRangeError::tagged_type< tag >; using TaggedIndexOutOfRangeException= IndexOutOfRangeException::tagged_type< tag >;
class IndexOutOfRangeCriticalError
: virtual public synthetic_exception< struct index_out_of_range_throwable, OutOfRangeCriticalError, IndexOutOfRangeException > {};
using AnyTaggedIndexOutOfRangeCriticalError= IndexOutOfRangeCriticalError::any_tagged_type;
template< typename tag >
using TaggedIndexOutOfRangeCriticalError= IndexOutOfRangeCriticalError::tagged_type< tag >;
class IndexOutOfRangeViolation class IndexOutOfRangeViolation
: virtual public synthetic_exception< struct index_out_of_range_throwable, OutOfRangeViolation, IndexOutOfRangeThrowable > {}; : virtual public synthetic_exception< struct index_out_of_range_throwable, OutOfRangeViolation, IndexOutOfRangeException > {};
using AnyTaggedIndexOutOfRangeViolation= IndexOutOfRangeViolation::any_tagged_type; using AnyTaggedIndexOutOfRangeViolation= IndexOutOfRangeViolation::any_tagged_type;
template< typename tag > template< typename tag >
using TaggedIndexOutOfRangeViolation= IndexOutOfRangeViolation::tagged_type< tag >; using TaggedIndexOutOfRangeViolation= IndexOutOfRangeViolation::tagged_type< tag >;
@ -389,29 +419,29 @@ namespace Alepha::Hydrogen
public: public:
std::size_t allocationAmount() const noexcept final { return amount; } std::size_t allocationAmount() const noexcept final { return amount; }
}; };
class AllocationThrowable class AllocationException
: virtual public synthetic_exception< struct allocation_throwable, Throwable >, virtual public AllocationAmountInterface {}; : virtual public synthetic_exception< struct allocation_throwable, Exception >, virtual public AllocationAmountInterface {};
using AnyTaggedAllocationThrowable= AllocationThrowable::any_tagged_type;
template< typename tag >
using TaggedAllocationThrowable= AllocationThrowable::tagged_type< tag >;
using AllocationException= synthetic_exception< struct allocation_exception, Exception, AllocationThrowable >;
using AnyTaggedAllocationException= AllocationException::any_tagged_type; using AnyTaggedAllocationException= AllocationException::any_tagged_type;
template< typename tag > template< typename tag >
using TaggedAllocationException= AllocationException::tagged_type< tag >; using TaggedAllocationException= AllocationException::tagged_type< tag >;
using AllocationError= synthetic_exception< struct allocation_error, Error, AllocationThrowable >; using AllocationError= synthetic_exception< struct allocation_exception, Error, AllocationException >;
using AnyTaggedAllocationError= AllocationError::any_tagged_type; using AnyTaggedAllocationError= AllocationError::any_tagged_type;
template< typename tag > template< typename tag >
using TaggedAllocationError= AllocationError::tagged_type< tag >; using TaggedAllocationError= AllocationError::tagged_type< tag >;
using AllocationViolation= synthetic_exception< struct allocation_violation, Violation, AllocationThrowable >; using AllocationCriticalError= synthetic_exception< struct allocation_error, CriticalError, AllocationException >;
using AnyTaggedAllocationCriticalError= AllocationCriticalError::any_tagged_type;
template< typename tag >
using TaggedAllocationCriticalError= AllocationCriticalError::tagged_type< tag >;
using AllocationViolation= synthetic_exception< struct allocation_violation, Violation, AllocationException >;
using AnyTaggedAllocationViolation= AllocationViolation::any_tagged_type; using AnyTaggedAllocationViolation= AllocationViolation::any_tagged_type;
template< typename tag > template< typename tag >
using TaggedAllocationViolation= AllocationViolation::tagged_type< tag >; using TaggedAllocationViolation= AllocationViolation::tagged_type< tag >;
class MessageStorage class MessageStorage
: virtual public Throwable : virtual public Exception
{ {
protected: protected:
std::string storage; std::string storage;
@ -425,7 +455,7 @@ namespace Alepha::Hydrogen
template< typename std_exception > template< typename std_exception >
class GenericExceptionBridge class GenericExceptionBridge
: virtual public std_exception, public virtual ExceptionBridgeInterface, virtual public Exception : virtual public std_exception, public virtual ErrorBridgeInterface, virtual public Exception
{ {
public: public:
const char *what() const noexcept override { return message(); } const char *what() const noexcept override { return message(); }
@ -436,7 +466,7 @@ namespace Alepha::Hydrogen
build_exception( std::string message ) build_exception( std::string message )
{ {
if constexpr( false ) {} if constexpr( false ) {}
else if constexpr( std::is_base_of_v< AllocationException, Kind > ) else if constexpr( std::is_base_of_v< AllocationError, Kind > )
{ {
class Undergird class Undergird
: virtual public Kind, virtual protected GenericExceptionBridge< std::bad_alloc >, : virtual public Kind, virtual protected GenericExceptionBridge< std::bad_alloc >,
@ -444,16 +474,16 @@ namespace Alepha::Hydrogen
virtual public std::bad_alloc virtual public std::bad_alloc
{}; {};
class Exception class Error
: virtual private Undergird, virtual public Kind, public virtual std::bad_alloc : virtual private Undergird, virtual public Kind, public virtual std::bad_alloc
{ {
public: public:
explicit Exception( std::string message ) : MessageStorage( std::move( message ) ) {} explicit Error( std::string message ) : MessageStorage( std::move( message ) ) {}
}; };
return Exception{ std::move( message ) }; return Error{ std::move( message ) };
} }
else if constexpr( std::is_base_of_v< IndexOutOfRangeException, Kind > ) else if constexpr( std::is_base_of_v< IndexOutOfRangeError, Kind > )
{ {
class Undergird class Undergird
: virtual public Kind, virtual protected GenericExceptionBridge< std::out_of_range >, : virtual public Kind, virtual protected GenericExceptionBridge< std::out_of_range >,
@ -461,32 +491,32 @@ namespace Alepha::Hydrogen
virtual public std::out_of_range virtual public std::out_of_range
{}; {};
class Exception class Error
: virtual private Undergird, virtual public Kind, public virtual std::out_of_range : virtual private Undergird, virtual public Kind, public virtual std::out_of_range
{ {
public: public:
explicit Exception( std::string message ) : MessageStorage( std::move( message ) ) {} explicit Error( std::string message ) : MessageStorage( std::move( message ) ) {}
}; };
return Exception{ std::move( message ) }; return Error{ std::move( message ) };
} }
else if constexpr( std::is_base_of_v< Exception, Kind > ) else if constexpr( std::is_base_of_v< Error, Kind > )
{ {
class Undergird class Undergird
: virtual public Kind, virtual protected GenericExceptionBridge< std::exception >, : virtual public Kind, virtual protected GenericExceptionBridge< std::exception >,
virtual protected MessageStorage, virtual public std::exception virtual protected MessageStorage, virtual public std::exception
{}; {};
class Exception class Error
: virtual private Undergird, : virtual private Undergird,
virtual public Kind, virtual public Kind,
virtual public std::exception virtual public std::exception
{ {
public: public:
explicit Exception( std::string message ) : MessageStorage( std::move( message ) ) {} explicit Error( std::string message ) : MessageStorage( std::move( message ) ) {}
}; };
return Exception{ std::move( message ) }; return Error{ std::move( message ) };
} }
else if constexpr( true ) else if constexpr( true )
{ {
@ -504,6 +534,10 @@ namespace Alepha::Hydrogen
using FinishedException= synthetic_exception< struct finished_exception, Exception >; using FinishedException= synthetic_exception< struct finished_exception, Exception >;
using AnyTaggedFinishedException= AnyTagged< FinishedException >; using AnyTaggedFinishedException= AnyTagged< FinishedException >;
template< typename tag > using TaggedFinishedException= Tagged< FinishedException, tag >; template< typename tag > using TaggedFinishedException= Tagged< FinishedException, tag >;
using FinishedCondition= synthetic_exception< struct finished_exception, Condition, FinishedException >;
using AnyTaggedFinishedCondition= AnyTagged< FinishedCondition >;
template< typename tag > using TaggedFinishedCondition= Tagged< FinishedCondition, tag >;
} }
inline namespace exports {} inline namespace exports {}

View File

@ -33,11 +33,17 @@ namespace
{ {
try try
{ {
auto exc= Alepha::build_exception< Alepha::TaggedAllocationException< struct tag > >( "This is my allocation exception" ); auto exc= Alepha::build_exception< Alepha::TaggedAllocationError< struct tag > >( "This is my allocation exception" );
static_assert( std::is_same_v< decltype( exc )::grade_type, Alepha::Exception > ); static_assert( std::is_same_v< decltype( exc )::grade_type, Alepha::Error > );
static_assert( std::is_same_v< Alepha::AnyTaggedException::grade_type, Alepha::Exception > ); static_assert( std::is_same_v< Alepha::AnyTaggedException::grade_type, Alepha::Exception > );
static_assert( std::is_same_v< typename Alepha::TaggedException< struct bob >::grade_type, Alepha::Exception > ); static_assert( std::is_same_v< typename Alepha::TaggedException< struct bob >::grade_type, Alepha::Exception > );
static_assert( std::is_same_v< typename Alepha::TaggedThrowable< struct bob >::grade_type, Alepha::Throwable > );
static_assert( std::is_same_v< typename Alepha::TaggedCondition< struct bob >::grade_type, Alepha::Condition > );
static_assert( std::is_same_v< typename Alepha::TaggedNotification< struct bob >::grade_type, Alepha::Notification > );
static_assert( std::is_same_v< typename Alepha::TaggedError< struct bob >::grade_type, Alepha::Error > );
static_assert( std::is_same_v< typename Alepha::TaggedCriticalError< struct bob >::grade_type, Alepha::CriticalError > );
static_assert( std::is_same_v< typename Alepha::TaggedViolation< struct bob >::grade_type, Alepha::Violation > ); static_assert( std::is_same_v< typename Alepha::TaggedViolation< struct bob >::grade_type, Alepha::Violation > );
throw exc; throw exc;
} }
@ -48,7 +54,7 @@ namespace
else std::cout << ex.message(); else std::cout << ex.message();
std::cout << std::endl; std::cout << std::endl;
if constexpr( std::is_base_of_v< Alepha::AnyTaggedThrowable, CatchException > ) if constexpr( std::is_base_of_v< Alepha::AnyTaggedException, CatchException > )
{ {
std::cout << "Tag type: `" << boost::core::demangle( ex.tag().name() ) << '`' << std::endl; std::cout << "Tag type: `" << boost::core::demangle( ex.tag().name() ) << '`' << std::endl;
} }
@ -73,33 +79,33 @@ namespace
"smoke"_test <=[] () -> bool "smoke"_test <=[] () -> bool
{ {
testException< std::bad_alloc >(); testException< std::bad_alloc >();
testException< Alepha::TaggedException< tag > >(); testException< Alepha::TaggedError< tag > >();
testException< Alepha::AnyTaggedException >(); testException< Alepha::AnyTaggedError >();
testException< std::exception >(); testException< std::exception >();
testException< Alepha::Exception >(); testException< Alepha::Exception >();
testException< Alepha::Throwable >(); testException< Alepha::Error >();
return true; return true;
}; };
"catch.std::bad_alloc"_test <=catchable< Alepha::TaggedAllocationException< tag >, std::bad_alloc >; "catch.std::bad_alloc"_test <=catchable< Alepha::TaggedAllocationError< tag >, std::bad_alloc >;
"catch.std::exception"_test <=catchable< Alepha::TaggedAllocationException< tag >, std::exception >; "catch.std::exception"_test <=catchable< Alepha::TaggedAllocationError< tag >, std::exception >;
"catch.Alepha::Throwable"_test <=catchable< Alepha::TaggedAllocationException< tag >, Alepha::Throwable >; "catch.Alepha::Exception"_test <=catchable< Alepha::TaggedAllocationError< tag >, Alepha::Exception >;
"catch.Alepha::AnyTaggedThrowable"_test <=catchable< Alepha::TaggedAllocationException< tag >, Alepha::AnyTaggedThrowable >; "catch.Alepha::AnyTaggedException"_test <=catchable< Alepha::TaggedAllocationError< tag >, Alepha::AnyTaggedException >;
"catch.Alepha::TaggedThrowable"_test <=catchable< Alepha::TaggedAllocationException< tag >, Alepha::TaggedThrowable< tag > >; "catch.Alepha::TaggedException"_test <=catchable< Alepha::TaggedAllocationError< tag >, Alepha::TaggedException< tag > >;
"catch.Alepha::Exception"_test <=catchable< Alepha::TaggedAllocationException< tag >, Alepha::Exception >; "catch.Alepha::Error"_test <=catchable< Alepha::TaggedAllocationError< tag >, Alepha::Error >;
"catch.Alepha::AnyTaggedException"_test <=catchable< Alepha::TaggedAllocationException< tag >, Alepha::AnyTaggedException >; "catch.Alepha::AnyTaggedError"_test <=catchable< Alepha::TaggedAllocationError< tag >, Alepha::AnyTaggedError >;
"catch.Alepha::TaggedException"_test <=catchable< Alepha::TaggedAllocationException< tag >, Alepha::TaggedException< tag > >; "catch.Alepha::TaggedError"_test <=catchable< Alepha::TaggedAllocationError< tag >, Alepha::TaggedError< tag > >;
"catch.Alepha::AllocationThrowable"_test <=catchable< Alepha::TaggedAllocationException< tag >, Alepha::AllocationThrowable >; "catch.Alepha::AllocationException"_test <=catchable< Alepha::TaggedAllocationError< tag >, Alepha::AllocationException >;
"catch.Alepha::AnyTaggedAllocationThrowable"_test <=catchable< Alepha::TaggedAllocationException< tag >, Alepha::AnyTaggedAllocationThrowable >; "catch.Alepha::AnyTaggedAllocationException"_test <=catchable< Alepha::TaggedAllocationError< tag >, Alepha::AnyTaggedAllocationException >;
"catch.Alepha::TaggedAllocationThrowable"_test <=catchable< Alepha::TaggedAllocationException< tag >, Alepha::TaggedAllocationThrowable< tag > >; "catch.Alepha::TaggedAllocationException"_test <=catchable< Alepha::TaggedAllocationError< tag >, Alepha::TaggedAllocationException< tag > >;
"catch.Alepha::AllocationException"_test <=catchable< Alepha::TaggedAllocationException< tag >, Alepha::AllocationException >; "catch.Alepha::AllocationError"_test <=catchable< Alepha::TaggedAllocationError< tag >, Alepha::AllocationError >;
"catch.Alepha::AnyTaggedAllocationException"_test <=catchable< Alepha::TaggedAllocationException< tag >, Alepha::AnyTaggedAllocationException >; "catch.Alepha::AnyTaggedAllocationError"_test <=catchable< Alepha::TaggedAllocationError< tag >, Alepha::AnyTaggedAllocationError >;
"catch.Alepha::TaggedAllocationException"_test <=catchable< Alepha::TaggedAllocationException< tag >, Alepha::TaggedAllocationException< tag > >; "catch.Alepha::TaggedAllocationError"_test <=catchable< Alepha::TaggedAllocationError< tag >, Alepha::TaggedAllocationError< tag > >;
"size_probe"_test <=[] "size_probe"_test <=[]
{ {
std::cout << "Size: " << sizeof( Alepha::build_exception< Alepha::TaggedAllocationException< tag > >( "Message" ) ) << std::endl; std::cout << "Size: " << sizeof( Alepha::build_exception< Alepha::TaggedAllocationError< tag > >( "Message" ) ) << std::endl;
}; };
}; };
} }