00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef __TBB_exception_H
00022 #define __TBB_exception_H
00023
00024 #include "tbb_stddef.h"
00025 #include <stdexcept>
00026
00027 namespace tbb {
00028
00030 class bad_last_alloc : public std::bad_alloc {
00031 public:
00032 virtual const char* what() const throw() { return "bad allocation in previous or concurrent attempt"; }
00033 virtual ~bad_last_alloc() throw() {}
00034 };
00035
00036 }
00037
00038 #if __TBB_EXCEPTIONS
00039 #include "tbb_allocator.h"
00040 #include <exception>
00041 #include <typeinfo>
00042 #include <new>
00043
00044 namespace tbb {
00045
00047
00067 class tbb_exception : public std::exception {
00068 public:
00070
00071 virtual tbb_exception* move () throw() = 0;
00072
00074
00076 virtual void destroy () throw() = 0;
00077
00079
00083 virtual void throw_self () = 0;
00084
00086 virtual const char* name() const throw() = 0;
00087
00089 virtual const char* what() const throw() = 0;
00090 };
00091
00093
00097 class captured_exception : public tbb_exception
00098 {
00099 public:
00100 captured_exception ( const captured_exception& src )
00101 : my_dynamic(false)
00102 {
00103 set(src.my_exception_name, src.my_exception_info);
00104 }
00105
00106 captured_exception ( const char* name, const char* info )
00107 : my_dynamic(false)
00108 {
00109 set(name, info);
00110 }
00111
00112 __TBB_EXPORTED_METHOD ~captured_exception () throw() {
00113 clear();
00114 }
00115
00116 captured_exception& operator= ( const captured_exception& src ) {
00117 if ( this != &src ) {
00118 clear();
00119 set(src.my_exception_name, src.my_exception_info);
00120 }
00121 return *this;
00122 }
00123
00124
00125 captured_exception* move () throw();
00126
00127
00128 void destroy () throw();
00129
00130
00131 void throw_self () { throw *this; }
00132
00133
00134 const char* __TBB_EXPORTED_METHOD name() const throw();
00135
00136
00137 const char* __TBB_EXPORTED_METHOD what() const throw();
00138
00139 private:
00141 captured_exception() {}
00142
00144 static captured_exception* allocate ( const char* name, const char* info );
00145
00146 void set ( const char* name, const char* info ) throw();
00147 void clear () throw();
00148
00149 bool my_dynamic;
00150 const char* my_exception_name;
00151 const char* my_exception_info;
00152 };
00153
00155
00159 template<typename ExceptionData>
00160 class movable_exception : public tbb_exception
00161 {
00162 typedef movable_exception<ExceptionData> self_type;
00163
00164 public:
00165 movable_exception ( const ExceptionData& data )
00166 : my_exception_data(data)
00167 , my_dynamic(false)
00168 , my_exception_name(typeid(self_type).name())
00169 {}
00170
00171 movable_exception ( const movable_exception& src ) throw ()
00172 : my_exception_data(src.my_exception_data)
00173 , my_dynamic(false)
00174 , my_exception_name(src.my_exception_name)
00175 {}
00176
00177 ~movable_exception () throw() {}
00178
00179 const movable_exception& operator= ( const movable_exception& src ) {
00180 if ( this != &src ) {
00181 my_exception_data = src.my_exception_data;
00182 my_exception_name = src.my_exception_name;
00183 }
00184 return *this;
00185 }
00186
00187 ExceptionData& data () throw() { return my_exception_data; }
00188
00189 const ExceptionData& data () const throw() { return my_exception_data; }
00190
00191 const char* name () const throw() { return my_exception_name; }
00192
00193 const char* what () const throw() { return "tbb::movable_exception"; }
00194
00195
00196 movable_exception* move () throw() {
00197 void* e = internal::allocate_via_handler_v3(sizeof(movable_exception));
00198 if ( e ) {
00199 new (e) movable_exception(*this);
00200 ((movable_exception*)e)->my_dynamic = true;
00201 }
00202 return (movable_exception*)e;
00203 }
00204
00205 void destroy () throw() {
00206 __TBB_ASSERT ( my_dynamic, "Method destroy can be called only on dynamically allocated movable_exceptions" );
00207 if ( my_dynamic ) {
00208 this->~movable_exception();
00209 internal::deallocate_via_handler_v3(this);
00210 }
00211 }
00212
00213 void throw_self () {
00214 throw *this;
00215 }
00216
00217 protected:
00219 ExceptionData my_exception_data;
00220
00221 private:
00223 bool my_dynamic;
00224
00226
00227 const char* my_exception_name;
00228 };
00229
00230 }
00231
00232 #endif
00233
00234 #endif