00001 #ifndef Exc_Ruby__detail__Exception_Handler__hpp_
00002 #define Exc_Ruby__detail__Exception_Handler__hpp_
00003
00004 #include "ruby.h"
00005
00006 namespace Exc_Ruby
00007 {
00008
00009 namespace detail
00010 {
00011
00012 class Exception_Handler
00013 {
00014 public:
00015 Exception_Handler(Exception_Handler const * next_exception_handler)
00016 : next_exception_handler_(next_exception_handler)
00017 {
00018 }
00019
00020 virtual ~Exception_Handler()
00021 {
00022 }
00023
00024 virtual VALUE handle_exception() const = 0;
00025
00026 VALUE call_next_exception_handler() const
00027 {
00028 return next_exception_handler_->handle_exception();
00029 }
00030
00031 private:
00032 Exception_Handler const * next_exception_handler_;
00033 };
00034
00035 class Default_Exception_Handler
00036 : public Exception_Handler
00037 {
00038 public:
00039 Default_Exception_Handler()
00040 : Exception_Handler(0)
00041 {
00042 }
00043
00044 virtual VALUE handle_exception() const
00045 {
00046 throw;
00047 }
00048 };
00049
00050 template <typename Exception_T, typename Functor_T>
00051 class Functor_Exception_Handler
00052 : public Exception_Handler
00053 {
00054 public:
00055 Functor_Exception_Handler(
00056 Functor_T handler,
00057 Exception_Handler const * next_exception_handler)
00058 : Exception_Handler(next_exception_handler)
00059 , handler_(handler)
00060 {
00061 }
00062
00063 private:
00064 virtual VALUE handle_exception() const
00065 {
00066 try
00067 {
00068 return call_next_exception_handler();
00069 }
00070 catch(Exception_T const & ex)
00071 {
00072 handler_(ex);
00073 throw;
00074 }
00075 }
00076
00077 private:
00078 Functor_T handler_;
00079 };
00080
00081 }
00082
00083 }
00084
00085 #endif // Exc_Ruby__detail__Exception_Handler__hpp_
00086