From 58afecfa27bb12e23e79bbb2fa168dc829badfb3 Mon Sep 17 00:00:00 2001 From: Johann Dreo Date: Fri, 14 Mar 2014 21:06:56 +0100 Subject: [PATCH] The whole thing --- README | 13 +++++++-- example.cpp | 27 ++++++++++++++++++ exceptions.h | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 116 insertions(+), 3 deletions(-) create mode 100644 example.cpp create mode 100644 exceptions.h diff --git a/README b/README index b471b44..f3a35fb 100644 --- a/README +++ b/README @@ -6,7 +6,7 @@ The point of this system is to permits to easily add to exceptions instances some informations about _where_ the exceptions are thrown. To do so, it uses compilers macros that indicates the current function, file and -line (__FUNCTION__, __FILE__ and __LINE__ for g++) and merge those information +line (`__FUNCTION__`, `__FILE__` and `__LINE__` for g++) and merge those information with the given description returned by the _what_ standard method. Example: @@ -16,8 +16,15 @@ Additionaly, it permits a one-line declaration of new exceptions, derived from existing ones. Example: -`EXCEPTION(Exception, Existential_Observation ); - EXCEPTION(Existential_Observation, Pastafarism_Observation );` +`EXCEPTION( Exception, Existential_Observation ); + EXCEPTION( Existential_Observation, Pastafarism_Observation );` Note that the base "Exception" class derivate from std::exception. +It also provides a macro to easily throw an exception +that permits to use dynamic streamed messages inline and +without having to specify E_INFOS. + +Example: + `RAISE( Pastafarism_Observation, "Shit happens with " << 42 << " noodly appendages" );` + diff --git a/example.cpp b/example.cpp new file mode 100644 index 0000000..2e41e2c --- /dev/null +++ b/example.cpp @@ -0,0 +1,27 @@ + +#include +#include + +#include "exceptions.h" + +// Use this macro to build up your hierarchy of exceptions +EXCEPTION( Exception, Existential_Observation ); + EXCEPTION( Existential_Observation, Buddhist_Observation ); + EXCEPTION( Buddhist_Observation, Zen_Observation ); + EXCEPTION( Existential_Observation, Pastafarism_Observation ); + +int main() +{ + try { + double pi = 3.1415926535; + // Use this macro to easily throw an exception with a dynamic message + RAISE( Pastafarism_Observation, std::setprecision(3) << "Shit happens with " << pi << " noodly appendages" ); + + // Or, if you prefer, use the standard way, but you'll have to indicate E_INFOS yourself + throw( Zen_Observation( "What is the sound of shit happening?", E_INFOS) ); + + } catch( Existential_Observation & e ) { + std::cerr << e.what() << std::endl; + } +} + diff --git a/exceptions.h b/exceptions.h new file mode 100644 index 0000000..e634df7 --- /dev/null +++ b/exceptions.h @@ -0,0 +1,79 @@ +#ifndef __EXCEPTIONS_H__ +#define __EXCEPTIONS_H__ + +#include +#include +#include + +//! This macro should be used when calling an exception +/*! for example : + throw( Exception( "Shit happens", E_INFOS ); +*/ +#define E_INFOS __FUNCTION__,__FILE__,__LINE__ + + +//! This macro should be used to declare an exception +/*! The second argument is the name of the exception class + The first argument is the name of the base class + for example : + EXCEPTION(Exception,Buddhist_Observation); + creates an new exception class "Buddhist_Observation", derived from the base "Exception" +*/ +#define EXCEPTION(Super,Current) class Current : public Super {public: Current ( const std::string & desc, const std::string & func="?", const std::string & f="?", const int l=-1 ) : Super (desc,func,f,l) {name = #Current;} } + + +/** A shortcut to throw an exception without having to type ",E_INFOS" + * and that could take streamed-formatted input instead of plain strings. + * + * Example: + * RAISE( Buddhist_Observation, "There is " << 0 << " shit that happens" ); + */ +#define RAISE( Err, msg ) {std::ostringstream oss; oss << msg; throw( Err(oss.str(), E_INFOS) );} + + +//! This is the base class for all exceptions in oMetah +class Exception : public std::exception +{ +protected: + //! Name of the current exception class + std::string name; + + //! Description of the exception + std::string description; + + //! Function where the exception has been raised + std::string function; + + //! File where the exception has been raised + std::string file; + + //! Line where the exception has been raised + int line; + +public: + //! Constructor of the exception + /*! + This constructor is not supposed to be used with hand-made location arguments + but with metadata provided by the compiler. + + Use the E_INFOS macro to raise the exception, for example : + throw( Exception( "Shit evolves", E_INFOS ); + */ + Exception( const std::string & desc, const std::string & func, const std::string & f, const int l ) + : description(desc), function(func), file(f), line(l) {} + + //! The destructor is not allowed to throw exceptions + virtual ~Exception() throw () {} + + //! The method to use for printing the complete description of the exception + std::string what() + { + std::ostringstream msg; + msg << description << " (<" << name << "> in " << function << " at " << file << ":" << line << ")"; + + return msg.str(); + } +}; + +#endif // __EXCEPTIONS_H__ +