forked from Alepha/Alepha
Flesh out more automatic exception class generation.
Also improved the tests.
This commit is contained in:
266
Exception.h
266
Exception.h
@ -18,7 +18,7 @@ namespace Alepha::Hydrogen
|
|||||||
/*!
|
/*!
|
||||||
* @file
|
* @file
|
||||||
*
|
*
|
||||||
* Exception grades.
|
* Exception grades -- Exceptions have different grades of severity.
|
||||||
*
|
*
|
||||||
* 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.
|
||||||
@ -52,9 +52,54 @@ namespace Alepha::Hydrogen
|
|||||||
* bug. `Violation::~Violation` is setup to call `abort()` when called.
|
* bug. `Violation::~Violation` is setup to call `abort()` when called.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
template< typename ... Bases >
|
||||||
|
struct bases : virtual public Bases... {};
|
||||||
|
|
||||||
|
template< typename unique, typename GradeType, typename Bases >
|
||||||
|
class synthetic_any_tagged_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template< typename unique_handle, typename GradeType, typename ... Bases >
|
||||||
|
class synthetic_exception
|
||||||
|
: virtual public bases< GradeType, Bases... >
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using grade_type= GradeType;
|
||||||
|
|
||||||
|
class any_tagged_type
|
||||||
|
: virtual public bases< synthetic_exception, typename GradeType::any_tagged_type, typename Bases::any_tagged_type... >
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using grade_type= GradeType;
|
||||||
|
};
|
||||||
|
|
||||||
|
template< typename tag >
|
||||||
|
class tagged_type
|
||||||
|
: virtual public bases< synthetic_exception, any_tagged_type, typename GradeType::template tagged_type< tag >, typename Bases::template tagged_type< tag >... >
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using grade_type= GradeType;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template< typename unique_handle, typename GradeType, typename ... Bases >
|
||||||
|
using create_exception= synthetic_exception< unique_handle, GradeType, Bases ... >;
|
||||||
|
|
||||||
|
template< typename Exc >
|
||||||
|
using AnyTagged= typename Exc::any_tagged_type;
|
||||||
|
|
||||||
|
template< typename Exc, typename tag >
|
||||||
|
using Tagged= typename Exc::template tagged_type< tag >;
|
||||||
|
|
||||||
class Throwable
|
class Throwable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
using grade_type= Throwable;
|
||||||
|
|
||||||
|
class any_tagged_type;
|
||||||
|
template< typename Tag > class tagged_type;
|
||||||
|
|
||||||
virtual ~Throwable()= default;
|
virtual ~Throwable()= default;
|
||||||
virtual const char *message() const noexcept= 0;
|
virtual const char *message() const noexcept= 0;
|
||||||
|
|
||||||
@ -77,17 +122,15 @@ namespace Alepha::Hydrogen
|
|||||||
return dynamic_cast< const Target * >( this );
|
return dynamic_cast< const Target * >( this );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
class Throwable::any_tagged_type
|
||||||
class AnyTaggedThrowable
|
: virtual public grade_type
|
||||||
: virtual public Throwable
|
|
||||||
{
|
{
|
||||||
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 TaggedThrowable
|
class Throwable::tagged_type
|
||||||
: virtual public AnyTaggedThrowable
|
: virtual public grade_type, virtual public grade_type::any_tagged_type
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
std::type_index
|
std::type_index
|
||||||
@ -96,19 +139,32 @@ namespace Alepha::Hydrogen
|
|||||||
return typeid( std::type_identity< Tag > );
|
return typeid( std::type_identity< Tag > );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
using AnyTaggedThrowable= AnyTagged< Throwable >;
|
||||||
|
template< typename tag >
|
||||||
|
using TaggedThrowable= Tagged< Throwable, tag >;
|
||||||
|
|
||||||
template< typename ... Bases >
|
|
||||||
struct bases : virtual public Bases... {};
|
|
||||||
|
|
||||||
// `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 : public virtual Throwable {};
|
class Notification
|
||||||
class AnyTaggedNotification
|
: public virtual Throwable
|
||||||
: public virtual bases< Notification, AnyTaggedThrowable > {};
|
{
|
||||||
|
public:
|
||||||
|
using grade_type= Notification;
|
||||||
|
|
||||||
|
class any_tagged_type;
|
||||||
template< typename tag >
|
template< typename tag >
|
||||||
class TaggedNotification
|
class tagged_type;
|
||||||
: public virtual bases< TaggedThrowable< tag >, AnyTaggedNotification > {};
|
};
|
||||||
|
class Notification::any_tagged_type
|
||||||
|
: public virtual bases< grade_type, Throwable::any_tagged_type > {};
|
||||||
|
template< typename tag >
|
||||||
|
class Notification::tagged_type
|
||||||
|
: public virtual bases< grade_type::any_tagged_type, Throwable::tagged_type< tag > > {};
|
||||||
|
using AnyTaggedNotification= Notification::any_tagged_type;
|
||||||
|
template< typename tag >
|
||||||
|
using TaggedNotification= Notification::tagged_type< tag >;
|
||||||
|
|
||||||
using Interrupt= Notification;
|
using Interrupt= Notification;
|
||||||
using AnyTaggedInterrupt= AnyTaggedNotification;
|
using AnyTaggedInterrupt= AnyTaggedNotification;
|
||||||
@ -119,31 +175,58 @@ namespace Alepha::Hydrogen
|
|||||||
class ExceptionBridgeInterface
|
class ExceptionBridgeInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~ExceptionBridgeInterface()= default;
|
|
||||||
|
|
||||||
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 ExceptionBridgeInterface::what; };
|
class Exception
|
||||||
class AnyTaggedException : virtual public bases< Exception, AnyTaggedThrowable > {};
|
: virtual public bases< Throwable >, virtual private ExceptionBridgeInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using grade_type= Exception;
|
||||||
|
using ExceptionBridgeInterface::what;
|
||||||
|
|
||||||
|
class any_tagged_type;
|
||||||
template< typename tag >
|
template< typename tag >
|
||||||
class TaggedException : virtual public bases< TaggedThrowable< tag >, AnyTaggedException > {};
|
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
|
// `Error`s are only really recoverable by terminating
|
||||||
// the major procedure underway. Like terminating the
|
// the major procedure underway. Like terminating the
|
||||||
// entire thread or similar. Essentially, arbitrarily
|
// entire thread or similar. Essentially, arbitrarily
|
||||||
// localized recovery is impossible.
|
// localized recovery is impossible.
|
||||||
class Error: virtual public bases< Throwable > {};
|
class Error
|
||||||
class AnyTaggedError : virtual public bases< Error, AnyTaggedThrowable > {};
|
: virtual public bases< Throwable >
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using grade_type= Error;
|
||||||
|
|
||||||
|
class any_tagged_type;
|
||||||
template< typename tag >
|
template< typename tag >
|
||||||
class TaggedError : virtual bases< AnyTaggedError, TaggedThrowable< tag > > {};
|
class tagged_type;
|
||||||
|
};
|
||||||
|
class Error::any_tagged_type
|
||||||
|
: virtual public bases< grade_type, Throwable::any_tagged_type > {};
|
||||||
|
template< typename tag >
|
||||||
|
class Error::tagged_type
|
||||||
|
: virtual bases< grade_type::any_tagged_type, Throwable::tagged_type< tag > > {};
|
||||||
|
using AnyTaggedError= Error::any_tagged_type;
|
||||||
|
template< typename tag >
|
||||||
|
using TaggedError= Error::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
|
||||||
// `[[noreturn]]` functions. Mostly one would catch
|
// `[[noreturn]]` functions, such as `std::terminate_handler`.
|
||||||
// this class if they intended to perform a bit of local
|
// Mostly one would catch this class if they intended to
|
||||||
// persistent state sanitization and then continue the
|
// perform a bit of local persistent state sanitization
|
||||||
// unwind process
|
// which is somewhat different to the normal dtors in scope
|
||||||
|
// and then continue the unwind process
|
||||||
class Violation
|
class Violation
|
||||||
: virtual public bases< Throwable >
|
: virtual public bases< Throwable >
|
||||||
{
|
{
|
||||||
@ -151,14 +234,22 @@ namespace Alepha::Hydrogen
|
|||||||
bool active= true;
|
bool active= true;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
using grade_type= Violation;
|
||||||
|
class any_tagged_type;
|
||||||
|
template< typename tag >
|
||||||
|
class tagged_type;
|
||||||
|
|
||||||
~Violation() override { if( not active ) abort(); }
|
~Violation() override { if( not active ) abort(); }
|
||||||
|
|
||||||
Violation( const Violation © )= delete;
|
Violation( const Violation © )= delete;
|
||||||
Violation( Violation © ) : active( copy.active ) { copy.active= false; }
|
Violation( Violation © ) : active( copy.active ) { copy.active= false; }
|
||||||
};
|
};
|
||||||
class AnyTaggedViolation : virtual public bases< Violation, AnyTaggedThrowable > {};
|
class Violation::any_tagged_type : virtual public bases< grade_type, Throwable::any_tagged_type > {};
|
||||||
template< typename tag >
|
template< typename tag >
|
||||||
class TaggedViolation : virtual public bases< AnyTaggedViolation, TaggedThrowable< tag > > {};
|
class Violation::tagged_type : virtual public bases< grade_type::any_tagged_type, Throwable::tagged_type< tag > > {};
|
||||||
|
using AnyTaggedViolation= Violation::any_tagged_type;
|
||||||
|
template< typename tag >
|
||||||
|
using TaggedViolation= Violation::tagged_type< tag >;
|
||||||
|
|
||||||
template< typename T >
|
template< typename T >
|
||||||
concept DerivedFromException= std::is_base_of_v< Exception, T >;
|
concept DerivedFromException= std::is_base_of_v< Exception, T >;
|
||||||
@ -181,44 +272,30 @@ 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 : virtual public bases< Throwable, NamedResourceInterface > {};
|
class NamedResourceThrowable : public virtual synthetic_exception< struct named_resource_throwable, Throwable >, virtual public NamedResourceInterface {};
|
||||||
class AnyTaggedNamedResourceThrowable
|
using AnyTaggedNamedResourceThrowable= NamedResourceThrowable::any_tagged_type;
|
||||||
: virtual public bases< NamedResourceThrowable, AnyTaggedThrowable > {};
|
|
||||||
template< typename tag >
|
template< typename tag >
|
||||||
class TaggedNamedResourceThrowable
|
using TaggedNamedResourceThrowable= NamedResourceThrowable::tagged_type< tag >;
|
||||||
: virtual public bases< AnyTaggedNamedResourceThrowable, TaggedThrowable< tag > > {};
|
|
||||||
|
|
||||||
class NamedResourceNotification
|
using NamedResourceNotification= synthetic_exception< struct named_resource_notification, Notification, NamedResourceThrowable >;
|
||||||
: public virtual bases< Notification, NamedResourceThrowable > {};
|
using AnyTaggedNamedResourceNotification= NamedResourceNotification::any_tagged_type;
|
||||||
class AnyTaggedNamedResourceNotification
|
|
||||||
: public virtual bases< NamedResourceNotification, AnyTaggedNotification, AnyTaggedNamedResourceThrowable > {};
|
|
||||||
template< typename tag >
|
template< typename tag >
|
||||||
class TaggedNamedResourceNotification
|
using TaggedNamedResourceNotification= NamedResourceNotification::tagged_type< tag >;
|
||||||
: public virtual bases< AnyTaggedNamedResourceNotification, TaggedNotification< tag >, TaggedNamedResourceThrowable< tag > > {};
|
|
||||||
|
|
||||||
class NamedResourceException
|
using NamedResourceException= synthetic_exception< struct named_resource_exception, Exception, NamedResourceThrowable >;
|
||||||
: public virtual bases< Exception, NamedResourceThrowable > {};
|
using AnyTaggedNamedResourceException= NamedResourceException::any_tagged_type;
|
||||||
class AnyTaggedNamedResourceException
|
|
||||||
: public virtual bases< NamedResourceException, AnyTaggedException, AnyTaggedNamedResourceThrowable > {};
|
|
||||||
template< typename tag >
|
template< typename tag >
|
||||||
class TaggedNamedResourceException
|
using TaggedNamedResourceException= NamedResourceException::tagged_type< tag >;
|
||||||
: public virtual bases< AnyTaggedNamedResourceException, TaggedException< tag >, TaggedNamedResourceThrowable< tag > > {};
|
|
||||||
|
|
||||||
class NamedResourceError
|
using NamedResourceError= synthetic_exception< struct named_resource_error, Error, NamedResourceThrowable >;
|
||||||
: public virtual bases< Error, NamedResourceThrowable > {};
|
using AnyTaggedNamedResourceError= NamedResourceError::any_tagged_type;
|
||||||
class AnyTaggedNamedResourceError
|
|
||||||
: public virtual bases< NamedResourceError, AnyTaggedError, AnyTaggedNamedResourceThrowable > {};
|
|
||||||
template< typename tag >
|
template< typename tag >
|
||||||
class TaggedNamedResourceError
|
using TaggedNamedResourceError= NamedResourceError::tagged_type< tag >;
|
||||||
: public virtual bases< AnyTaggedNamedResourceError, TaggedError< tag >, TaggedNamedResourceThrowable< tag > > {};
|
|
||||||
|
|
||||||
class NamedResourceViolation
|
using NamedResourceViolation= synthetic_exception< struct named_resource_violation, Violation, NamedResourceThrowable >;
|
||||||
: public virtual bases< Violation, NamedResourceThrowable > {};
|
using AnyTaggedNamedResourceViolation= NamedResourceViolation::any_tagged_type;
|
||||||
class AnyTaggedNamedResourceViolation
|
|
||||||
: public virtual bases< NamedResourceViolation, AnyTaggedViolation, AnyTaggedNamedResourceThrowable > {};
|
|
||||||
template< typename tag >
|
template< typename tag >
|
||||||
class TaggedNamedResourceViolation
|
using TaggedNamedResourceViolation= NamedResourceViolation::tagged_type< tag >;
|
||||||
: public virtual bases< AnyTaggedNamedResourceViolation, TaggedViolation< tag >, TaggedNamedResourceThrowable< tag > > {};
|
|
||||||
|
|
||||||
|
|
||||||
class AllocationAmountStorage;
|
class AllocationAmountStorage;
|
||||||
@ -239,58 +316,42 @@ namespace Alepha::Hydrogen
|
|||||||
std::size_t allocationAmount() const noexcept final { return amount; }
|
std::size_t allocationAmount() const noexcept final { return amount; }
|
||||||
};
|
};
|
||||||
class AllocationThrowable
|
class AllocationThrowable
|
||||||
: public virtual bases< Throwable, AllocationAmountInterface > {};
|
: virtual public synthetic_exception< struct allocation_throwable, Throwable >, virtual public AllocationAmountInterface {};
|
||||||
class AnyTaggedAllocationThrowable
|
using AnyTaggedAllocationThrowable= AllocationThrowable::any_tagged_type;
|
||||||
: public virtual bases< AllocationThrowable, AnyTaggedThrowable > {};
|
|
||||||
template< typename tag >
|
template< typename tag >
|
||||||
class TaggedAllocationThrowable
|
using TaggedAllocationThrowable= AllocationThrowable::tagged_type< tag >;
|
||||||
: public virtual bases< AnyTaggedAllocationThrowable, TaggedThrowable< tag > > {};
|
|
||||||
|
|
||||||
class AllocationException
|
using AllocationException= synthetic_exception< struct allocation_exception, Exception, AllocationThrowable >;
|
||||||
: virtual public bases< Exception, AllocationThrowable > {};
|
using AnyTaggedAllocationException= AllocationException::any_tagged_type;
|
||||||
class AnyTaggedAllocationException
|
|
||||||
: virtual public bases< AllocationException, AnyTaggedAllocationThrowable, AnyTaggedException > {};
|
|
||||||
template< typename tag >
|
template< typename tag >
|
||||||
class TaggedAllocationException
|
using TaggedAllocationException= AllocationException::tagged_type< tag >;
|
||||||
: virtual public bases< AnyTaggedAllocationException, TaggedAllocationThrowable< tag >, TaggedException< tag > > {};
|
|
||||||
|
|
||||||
class AllocationError
|
using AllocationError= synthetic_exception< struct allocation_error, Error, AllocationThrowable >;
|
||||||
: virtual public bases< Error, AllocationThrowable > {};
|
using AnyTaggedAllocationError= AllocationError::any_tagged_type;
|
||||||
class AnyTaggedAllocationError
|
|
||||||
: virtual public bases< AllocationError, AnyTaggedAllocationThrowable, AnyTaggedError > {};
|
|
||||||
template< typename tag >
|
template< typename tag >
|
||||||
class TaggedAllocationError
|
using TaggedAllocationError= AllocationError::tagged_type< tag >;
|
||||||
: virtual public bases< AnyTaggedAllocationError, TaggedAllocationThrowable< tag >, TaggedError< tag > > {};
|
|
||||||
|
|
||||||
class AllocationViolation
|
using AllocationViolation= synthetic_exception< struct allocation_violation, Violation, AllocationThrowable >;
|
||||||
: virtual public bases< Violation, AllocationThrowable > {};
|
using AnyTaggedAllocationViolation= AllocationViolation::any_tagged_type;
|
||||||
class AnyTaggedAllocationViolation
|
|
||||||
: virtual public bases< AllocationViolation, AnyTaggedAllocationThrowable, AnyTaggedViolation > {};
|
|
||||||
template< typename tag >
|
template< typename tag >
|
||||||
class TaggedAllocationViolation
|
using TaggedAllocationViolation= AllocationViolation::tagged_type< tag >;
|
||||||
: virtual public bases< AnyTaggedAllocationViolation, TaggedAllocationThrowable< tag >, TaggedViolation< tag > > {};
|
|
||||||
|
|
||||||
class MessageStorage
|
class MessageStorage
|
||||||
: virtual public Throwable
|
: virtual public Throwable
|
||||||
{
|
{
|
||||||
private:
|
protected:
|
||||||
std::string storage;
|
std::string storage;
|
||||||
|
|
||||||
public:
|
MessageStorage()= default;
|
||||||
explicit MessageStorage( std::string storage ) : storage( std::move( storage ) ) {}
|
explicit MessageStorage( std::string storage ) : storage( std::move( storage ) ) {}
|
||||||
|
|
||||||
|
public:
|
||||||
const char *message() const noexcept { return storage.c_str(); }
|
const char *message() const noexcept { return storage.c_str(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class AllocationExceptionBridge
|
template< typename std_exception >
|
||||||
: virtual public std::bad_alloc, public virtual ExceptionBridgeInterface, virtual public Exception
|
class GenericExceptionBridge
|
||||||
{
|
: virtual public std_exception, public virtual ExceptionBridgeInterface, virtual public Exception
|
||||||
public:
|
|
||||||
const char *what() const noexcept override { return message(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
class RegularExceptionBridge
|
|
||||||
: virtual public std::exception, public virtual ExceptionBridgeInterface, virtual public Exception
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
const char *what() const noexcept override { return message(); }
|
const char *what() const noexcept override { return message(); }
|
||||||
@ -303,8 +364,14 @@ namespace Alepha::Hydrogen
|
|||||||
if constexpr( false ) {}
|
if constexpr( false ) {}
|
||||||
else if constexpr( std::is_base_of_v< AllocationException, Kind > )
|
else if constexpr( std::is_base_of_v< AllocationException, Kind > )
|
||||||
{
|
{
|
||||||
|
class Undergird
|
||||||
|
: virtual public Kind, virtual protected GenericExceptionBridge< std::bad_alloc >,
|
||||||
|
virtual protected MessageStorage, virtual protected AllocationAmountStorage,
|
||||||
|
virtual public std::bad_alloc
|
||||||
|
{};
|
||||||
|
|
||||||
class Exception
|
class Exception
|
||||||
: virtual public Kind, virtual private AllocationExceptionBridge, virtual private MessageStorage, virtual private AllocationAmountStorage
|
: virtual private Undergird, virtual public Kind, public virtual std::bad_alloc
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit Exception( std::string message ) : MessageStorage( std::move( message ) ) {}
|
explicit Exception( std::string message ) : MessageStorage( std::move( message ) ) {}
|
||||||
@ -314,8 +381,16 @@ namespace Alepha::Hydrogen
|
|||||||
}
|
}
|
||||||
else if constexpr( std::is_base_of_v< Exception, Kind > )
|
else if constexpr( std::is_base_of_v< Exception, Kind > )
|
||||||
{
|
{
|
||||||
|
class Undergird
|
||||||
|
: virtual public Kind, virtual protected GenericExceptionBridge< std::exception >,
|
||||||
|
virtual protected MessageStorage, virtual protected AllocationAmountStorage,
|
||||||
|
virtual public std::exception
|
||||||
|
{};
|
||||||
|
|
||||||
class Exception
|
class Exception
|
||||||
: virtual public Kind, virtual private RegularExceptionBridge, virtual private MessageStorage
|
: virtual private Undergird,
|
||||||
|
virtual public Kind,
|
||||||
|
virtual public std::exception
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit Exception( std::string message ) : MessageStorage( std::move( message ) ) {}
|
explicit Exception( std::string message ) : MessageStorage( std::move( message ) ) {}
|
||||||
@ -328,12 +403,17 @@ namespace Alepha::Hydrogen
|
|||||||
class Thrown
|
class Thrown
|
||||||
: virtual public Kind, virtual private MessageStorage
|
: virtual public Kind, virtual private MessageStorage
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
explicit Thrown( std::string message ) : MessageStorage( std::move( message ) ) {}
|
explicit Thrown( std::string message ) : MessageStorage( std::move( message ) ) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
return Thrown{ std::move( message ) };
|
return Thrown{ std::move( message ) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using FinishedException= synthetic_exception< struct finished_exception, Exception >;
|
||||||
|
using AnyTaggedFinishedException= AnyTagged< FinishedException >;
|
||||||
|
template< typename tag > using TaggedFinishedException= Tagged< FinishedException, tag >;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline namespace exports {}
|
inline namespace exports {}
|
||||||
|
|||||||
@ -4,5 +4,6 @@ CXX=clang++-12
|
|||||||
|
|
||||||
CXXFLAGS+= -Wno-inline-namespace-reopened-noninline
|
CXXFLAGS+= -Wno-inline-namespace-reopened-noninline
|
||||||
CXXFLAGS+= -Wno-unused-comparison
|
CXXFLAGS+= -Wno-unused-comparison
|
||||||
|
CXXFLAGS+= -DAlepha=MyProject_Alepha
|
||||||
|
|
||||||
all: exception
|
all: exception
|
||||||
|
|||||||
@ -33,7 +33,13 @@ namespace
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
throw Alepha::build_exception< Alepha::TaggedAllocationException< struct tag > >( "This is my allocation exception" );
|
auto exc= Alepha::build_exception< Alepha::TaggedAllocationException< 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< 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::TaggedThrowable< struct bob >::grade_type, Alepha::Throwable > );
|
||||||
|
static_assert( std::is_same_v< typename Alepha::TaggedViolation< struct bob >::grade_type, Alepha::Violation > );
|
||||||
|
throw exc;
|
||||||
}
|
}
|
||||||
catch( const CatchException &ex )
|
catch( const CatchException &ex )
|
||||||
{
|
{
|
||||||
@ -76,19 +82,24 @@ namespace
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
"catch"_test <=catchable< Alepha::TaggedAllocationException< tag >, std::bad_alloc >;
|
"catch.std::bad_alloc"_test <=catchable< Alepha::TaggedAllocationException< tag >, std::bad_alloc >;
|
||||||
"catch"_test <=catchable< Alepha::TaggedAllocationException< tag >, std::exception >;
|
"catch.std::exception"_test <=catchable< Alepha::TaggedAllocationException< tag >, std::exception >;
|
||||||
"catch"_test <=catchable< Alepha::TaggedAllocationException< tag >, Alepha::Throwable >;
|
"catch.Alepha::Throwable"_test <=catchable< Alepha::TaggedAllocationException< tag >, Alepha::Throwable >;
|
||||||
"catch"_test <=catchable< Alepha::TaggedAllocationException< tag >, Alepha::AnyTaggedThrowable >;
|
"catch.Alepha::AnyTaggedThrowable"_test <=catchable< Alepha::TaggedAllocationException< tag >, Alepha::AnyTaggedThrowable >;
|
||||||
"catch"_test <=catchable< Alepha::TaggedAllocationException< tag >, Alepha::TaggedThrowable< tag > >;
|
"catch.Alepha::TaggedThrowable"_test <=catchable< Alepha::TaggedAllocationException< tag >, Alepha::TaggedThrowable< tag > >;
|
||||||
"catch"_test <=catchable< Alepha::TaggedAllocationException< tag >, Alepha::Exception >;
|
"catch.Alepha::Exception"_test <=catchable< Alepha::TaggedAllocationException< tag >, Alepha::Exception >;
|
||||||
"catch"_test <=catchable< Alepha::TaggedAllocationException< tag >, Alepha::AnyTaggedException >;
|
"catch.Alepha::AnyTaggedException"_test <=catchable< Alepha::TaggedAllocationException< tag >, Alepha::AnyTaggedException >;
|
||||||
"catch"_test <=catchable< Alepha::TaggedAllocationException< tag >, Alepha::TaggedException< tag > >;
|
"catch.Alepha::TaggedException"_test <=catchable< Alepha::TaggedAllocationException< tag >, Alepha::TaggedException< tag > >;
|
||||||
"catch"_test <=catchable< Alepha::TaggedAllocationException< tag >, Alepha::AllocationThrowable >;
|
"catch.Alepha::AllocationThrowable"_test <=catchable< Alepha::TaggedAllocationException< tag >, Alepha::AllocationThrowable >;
|
||||||
"catch"_test <=catchable< Alepha::TaggedAllocationException< tag >, Alepha::AnyTaggedAllocationThrowable >;
|
"catch.Alepha::AnyTaggedAllocationThrowable"_test <=catchable< Alepha::TaggedAllocationException< tag >, Alepha::AnyTaggedAllocationThrowable >;
|
||||||
"catch"_test <=catchable< Alepha::TaggedAllocationException< tag >, Alepha::TaggedAllocationThrowable< tag > >;
|
"catch.Alepha::TaggedAllocationThrowable"_test <=catchable< Alepha::TaggedAllocationException< tag >, Alepha::TaggedAllocationThrowable< tag > >;
|
||||||
"catch"_test <=catchable< Alepha::TaggedAllocationException< tag >, Alepha::AllocationException >;
|
"catch.Alepha::AllocationException"_test <=catchable< Alepha::TaggedAllocationException< tag >, Alepha::AllocationException >;
|
||||||
"catch"_test <=catchable< Alepha::TaggedAllocationException< tag >, Alepha::AnyTaggedAllocationException >;
|
"catch.Alepha::AnyTaggedAllocationException"_test <=catchable< Alepha::TaggedAllocationException< tag >, Alepha::AnyTaggedAllocationException >;
|
||||||
"catch"_test <=catchable< Alepha::TaggedAllocationException< tag >, Alepha::TaggedAllocationException< tag > >;
|
"catch.Alepha::TaggedAllocationException"_test <=catchable< Alepha::TaggedAllocationException< tag >, Alepha::TaggedAllocationException< tag > >;
|
||||||
|
|
||||||
|
"size_probe"_test <=[]
|
||||||
|
{
|
||||||
|
std::cout << "Size: " << sizeof( Alepha::build_exception< Alepha::TaggedAllocationException< tag > >( "Message" ) ) << std::endl;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user