exception.h
Go to the documentation of this file.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
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 #ifndef LASS_GUARDIAN_OF_INCLUSION_UTIL_EXCEPTION_H
00053 #define LASS_GUARDIAN_OF_INCLUSION_UTIL_EXCEPTION_H
00054
00055 #include "util_common.h"
00056 #include <exception>
00057 #include <string>
00058 #include <sstream>
00059
00060 #define LASS_UTIL_EXCEPTION_PRIVATE_IMPL(t_exception)\
00061 virtual void doThrowSelf() const { throw *this; }\
00062 virtual ::std::auto_ptr< ::lass::util::experimental::RemoteExceptionBase > doClone() const \
00063 { \
00064 return ::std::auto_ptr< ::lass::util::experimental::RemoteExceptionBase >(new t_exception(*this)); \
00065 }\
00066
00067
00068 namespace lass
00069 {
00070 namespace util
00071 {
00072 namespace experimental
00073 {
00074 class RemoteExceptionBase
00075 {
00076 public:
00077 virtual ~RemoteExceptionBase() {}
00078 void throwSelf() const { doThrowSelf(); }
00079 std::auto_ptr<RemoteExceptionBase> clone() const
00080 {
00081 std::auto_ptr<RemoteExceptionBase> copy = doClone();
00082 if (typeid(*copy) != typeid(*this))
00083 {
00084 std::cerr << "[LASS RUN MSG] UNDEFINED BEHAVIOUR WARNING: Cloned exception has been sliced from '"
00085 << typeid(*this).name() << "' to '" << typeid(*copy).name() << "'." << std::endl;
00086 }
00087 return copy;
00088 }
00089 private:
00090 virtual void doThrowSelf() const = 0;
00091 virtual std::auto_ptr<RemoteExceptionBase> doClone() const = 0;
00092 };
00093
00094 template <typename LocalException>
00095 class RemoteExceptionWrapper:
00096 public LocalException,
00097 public RemoteExceptionBase
00098 {
00099 public:
00100 RemoteExceptionWrapper(const LocalException& e): LocalException(e) {}
00101 ~RemoteExceptionWrapper() throw() {}
00102 private:
00103 void doThrowSelf() const { throw *this; }
00104 std::auto_ptr<RemoteExceptionBase> doClone() const
00105 {
00106 return std::auto_ptr<RemoteExceptionBase>(new RemoteExceptionWrapper<LocalException>(*this));
00107 }
00108 };
00109 }
00110
00111
00112
00113 class Exception:
00114 public std::exception,
00115 public experimental::RemoteExceptionBase
00116 {
00117 public:
00118
00119 Exception(const std::string& message, const std::string& location):
00120 std::exception(),
00121 message_(message),
00122 location_(location)
00123 {
00124 }
00125
00126 explicit Exception(const std::string& message):
00127 std::exception(),
00128 message_(message),
00129 location_("no location")
00130 {
00131 }
00132
00133 Exception():
00134 std::exception(),
00135 message_("no message"),
00136 location_("no location")
00137 {
00138 }
00139
00140 ~Exception() throw() {}
00141
00142
00143
00144 virtual const char* what() const throw()
00145 {
00146 return message_.c_str();
00147 }
00148
00149
00150
00151 const std::string& message() const
00152 {
00153 return message_;
00154 }
00155
00156
00157
00158 const std::string& location() const
00159 {
00160 return location_;
00161 }
00162
00163
00164 private:
00165
00166 std::string message_;
00167 std::string location_;
00168
00169 LASS_UTIL_EXCEPTION_PRIVATE_IMPL(Exception)
00170 };
00171
00172 namespace experimental
00173 {
00174
00175 template <typename ExceptionType, typename ParentType = Exception>
00176 class ExceptionMixin: public ParentType
00177 {
00178 public:
00179 ExceptionMixin(const std::string& msg, const std::string& loc): ParentType(msg, loc) {}
00180 private:
00181 virtual void doThrowSelf() const
00182 {
00183
00184 throw *static_cast<const ExceptionType*>(this);
00185 }
00186 virtual ::std::auto_ptr<RemoteExceptionBase> doClone() const
00187 {
00188
00189 return ::std::auto_ptr<RemoteExceptionBase>(new ExceptionType(*static_cast<const ExceptionType*>(this)));
00190 }
00191 };
00192
00193 }
00194
00195
00196
00197 class KeyError: public experimental::ExceptionMixin<KeyError>
00198 {
00199 public:
00200 KeyError(const std::string& msg, const std::string& loc):
00201 experimental::ExceptionMixin<KeyError>(msg, loc) {}
00202 };
00203
00204
00205 class ValueError: public experimental::ExceptionMixin<ValueError>
00206 {
00207 public:
00208 ValueError(const std::string& msg, const std::string& loc):
00209 experimental::ExceptionMixin<ValueError>(msg, loc) {}
00210 };
00211
00212 }
00213
00214 }
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233 #define LASS_THROW_EX(t_exception, s_message)\
00234 do\
00235 {\
00236 ::std::ostringstream lassUtilExceptionImplBuffer;\
00237 lassUtilExceptionImplBuffer << s_message;\
00238 throw t_exception(lassUtilExceptionImplBuffer.str(), LASS_PRETTY_FUNCTION);\
00239 }\
00240 while (false)
00241
00242
00243
00244
00245
00246
00247
00248
00249 #define LASS_THROW(s_message) LASS_THROW_EX(::lass::util::Exception, s_message)
00250
00251
00252
00253
00254
00255
00256
00257 #define LASS_CATCH_TO_WARNING\
00258 catch (const ::std::exception& error)\
00259 {\
00260 std::cerr << "[LASS RUN MSG] UNDEFINED BEHAVIOUR WARNING: Exception caught in "\
00261 << LASS_PRETTY_FUNCTION << ":\n" << error.what() << std::endl;\
00262 }\
00263 catch (...)\
00264 {\
00265 std::cerr << "[LASS RUN MSG] UNDEFINED BEHAVIOUR WARNING: Unknown exception caught in "\
00266 << LASS_PRETTY_FUNCTION << std::endl;\
00267 }\
00268
00269
00270 #endif
00271
00272