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 <memory>
00027
00028 namespace qpid {
00029
00030 struct Raisable {
00031 virtual ~Raisable() {};
00032 virtual void raise() const=0;
00033 virtual std::string what() const=0;
00034 };
00035
00040 class ExceptionHolder : public Raisable {
00041 public:
00042 ExceptionHolder() {}
00043 ExceptionHolder(ExceptionHolder& ex) : Raisable(), wrapper(ex.wrapper) {}
00045 template <class Ex> ExceptionHolder(Ex* ex) { wrap(ex); }
00046 template <class Ex> ExceptionHolder(const std::auto_ptr<Ex>& ex) { wrap(ex.release()); }
00047
00048 ExceptionHolder& operator=(ExceptionHolder& ex) { wrapper=ex.wrapper; return *this; }
00049 template <class Ex> ExceptionHolder& operator=(Ex* ex) { wrap(ex); return *this; }
00050 template <class Ex> ExceptionHolder& operator=(std::auto_ptr<Ex> ex) { wrap(ex.release()); return *this; }
00051
00052 void raise() const { if (wrapper.get()) wrapper->raise() ; }
00053 std::string what() const { return wrapper->what(); }
00054 bool empty() const { return !wrapper.get(); }
00055 operator bool() const { return !empty(); }
00056 void reset() { wrapper.reset(); }
00057
00058 private:
00059 template <class Ex> struct Wrapper : public Raisable {
00060 Wrapper(Ex* ptr) : exception(ptr) {}
00061 void raise() const { throw *exception; }
00062 std::string what() const { return exception->what(); }
00063 std::auto_ptr<Ex> exception;
00064 };
00065 template <class Ex> void wrap(Ex* ex) { wrapper.reset(new Wrapper<Ex>(ex)); }
00066 std::auto_ptr<Raisable> wrapper;
00067
00068 };
00069
00070
00071 }
00072
00073 #endif