The whole thing

This commit is contained in:
Johann Dreo 2014-03-14 21:06:56 +01:00
commit 58afecfa27
3 changed files with 116 additions and 3 deletions

13
README
View file

@ -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. some informations about _where_ the exceptions are thrown.
To do so, it uses compilers macros that indicates the current function, file and 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. with the given description returned by the _what_ standard method.
Example: Example:
@ -16,8 +16,15 @@ Additionaly, it permits a one-line declaration of new exceptions, derived from
existing ones. existing ones.
Example: Example:
`EXCEPTION(Exception, Existential_Observation ); `EXCEPTION( Exception, Existential_Observation );
EXCEPTION(Existential_Observation, Pastafarism_Observation );` EXCEPTION( Existential_Observation, Pastafarism_Observation );`
Note that the base "Exception" class derivate from std::exception. 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" );`

27
example.cpp Normal file
View file

@ -0,0 +1,27 @@
#include <iostream>
#include <iomanip>
#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;
}
}

79
exceptions.h Normal file
View file

@ -0,0 +1,79 @@
#ifndef __EXCEPTIONS_H__
#define __EXCEPTIONS_H__
#include <string>
#include <sstream>
#include <exception>
//! 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__