00001 #ifndef QPID_EXCEPTIONHOLDER_H
00002 #define QPID_EXCEPTIONHOLDER_H
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "qpid/memory.h"
00026 #include <boost/shared_ptr.hpp>
00027
00028
00029 namespace qpid {
00030 namespace sys {
00031
00032 struct Raisable {
00033 virtual ~Raisable() {};
00034 virtual void raise() const=0;
00035 virtual std::string what() const=0;
00036 };
00037
00042 class ExceptionHolder : public Raisable {
00043 public:
00044 ExceptionHolder() {}
00045
00046
00048 template <class Ex> ExceptionHolder(Ex* ex) { wrap(ex); }
00049 template <class Ex> ExceptionHolder(const boost::shared_ptr<Ex>& ex) { wrap(ex.release()); }
00050
00051 template <class Ex> ExceptionHolder& operator=(Ex* ex) { wrap(ex); return *this; }
00052 template <class Ex> ExceptionHolder& operator=(boost::shared_ptr<Ex> ex) { wrap(ex.release()); return *this; }
00053
00054 void raise() const { if (wrapper.get()) wrapper->raise() ; }
00055 std::string what() const { return wrapper.get() ? wrapper->what() : std::string(); }
00056 bool empty() const { return !wrapper.get(); }
00057 operator bool() const { return !empty(); }
00058 void reset() { wrapper.reset(); }
00059
00060 private:
00061 template <class Ex> struct Wrapper : public Raisable {
00062 Wrapper(Ex* ptr) : exception(ptr) {}
00063 void raise() const { throw *exception; }
00064 std::string what() const { return exception->what(); }
00065 boost::shared_ptr<Ex> exception;
00066 };
00067 template <class Ex> void wrap(Ex* ex) { wrapper.reset(new Wrapper<Ex>(ex)); }
00068 boost::shared_ptr<Raisable> wrapper;
00069 };
00070
00071
00072 }}
00073
00074
00075 #endif