00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
#ifndef BASICEXCEPTION_H
00027
#define BASICEXCEPTION_H
00028
00029
#include "BasicFileLocation.h"
00030
#include "BasicSmartPointer.h"
00031
#include "BasicDebugger.h"
00032
#include "Zap.h"
00033
00034
#include <string>
00035
#include <iostream>
00036
00037
00038
template <
class T, sp_alloc_t alloc_t>
00039
class BasicSmartPointer;
00040
00061 class BasicException {
00062 std::string
message;
00063 BasicFileLocation location;
00064 BasicSmartPointer<BasicException>
cause;
00065 BasicSmartPointer<std::list<std::string> >
trace;
00066
00067
public:
00068
static unsigned int causePrintLevel;
00069
static bool enableStackTraces;
00070
00071 BasicException() {
init();}
00072
00073 BasicException(
const std::string message) : message(message) {
00074
init();
00075 }
00076
00077 BasicException(
const std::string message,
const BasicFileLocation &location)
00078 : message(message), location(location) {
00079
init();
00080 }
00081
00082 BasicException(
const std::string message,
BasicException &cause) :
00083 message(message) {
00084 this->cause =
new BasicException(cause);
00085
init();
00086 }
00087
00088 BasicException(
const std::string message,
const BasicFileLocation &location,
00089
BasicException &cause) :
00090 message(message), location(location) {
00091 this->cause =
new BasicException(cause);
00092
init();
00093 }
00094
00096 BasicException(
const BasicException &e) :
00097
message(e.
message),
location(e.
location),
cause(e.
cause),
trace(e.
trace) {}
00098
00099 virtual ~BasicException() {}
00100
00101 const std::string
getMessage()
const {
return message;}
00102 BasicFileLocation getLocation()
const {
return location;}
00103
00108 BasicSmartPointer<BasicException>
getCause()
const {
return cause;}
00109
00110 BasicSmartPointer<std::list<std::string> >
getTrace()
const {
return trace;}
00111
00124 std::ostream &
print(std::ostream &stream,
00125
bool printLocations =
true,
00126
unsigned int printLevel = 0)
const {
00127
00128
if (printLocations && !
location.
isEmpty())
00129 stream <<
"@ " <<
location <<
" ";
00130
00131 stream <<
message;
00132
00133
if (
enableStackTraces && !
trace.isNull()) {
00134 std::list<std::string>::iterator it;
00135
for (it =
trace->begin(); it !=
trace->end(); it++)
00136 stream << std::endl <<
" " << *it;
00137 }
00138
00139
if (!
cause.isNull()) {
00140 stream << std::endl <<
" ";
00141
00142
if (printLevel >
causePrintLevel) {
00143 stream <<
"Aborting exception dump due to causePrintLevel limit! "
00144 <<
"Increase BasicException::causePrintLevel to see more.";
00145
00146 }
else {
00147 stream <<
"caused by: ";
00148
cause->print(stream, printLocations, printLevel);
00149 }
00150 }
00151
00152
return stream;
00153 }
00154
00155
protected:
00156 void init() {
00157
if (
enableStackTraces) {
00158
trace =
new std::list<std::string>;
00159
00160
00161
00162
00163
00164
00165
# ifdef __OPTIMIZE__
00166
BasicDebugger::getStackTrace(*
trace, 0);
00167
trace->push_front(
"Warning: Optimization can cause incomplete traces.");
00168
# else
00169
BasicDebugger::getStackTrace(*
trace, 2);
00170
# endif
00171
}
00172 }
00173
00174
friend std::ostream &
operator<<(std::ostream &,
const BasicException &);
00175 };
00176
00187 inline std::ostream &
operator<<(std::ostream &stream,
00188
const BasicException &e) {
00189 e.
print(stream);
00190
return stream;
00191 }
00192
00193 #define THROW(msg) throw BasicException((msg), FILE_LOCATION)
00194 #define THROWC(msg, cause) throw BasicException((msg), FILE_LOCATION, (cause))
00195 #define ASSERT_OR_THROW(msg, condition) {if (!(condition)) THROW(msg);}
00196
00197
#endif