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 #if __TBB_EXCEPTIONS && !defined(__EXCEPTIONS) && !defined(_CPPUNWIND) && !defined(__SUNPRO_CC)
00028 #error The current compilation environment does not support exception handling. Please set __TBB_EXCEPTIONS to 0 in tbb_config.h
00029 #endif
00030
00031 namespace tbb {
00032
00034 class bad_last_alloc : public std::bad_alloc {
00035 public:
00036 virtual const char* what() const throw() { return "bad allocation in previous or concurrent attempt"; }
00037 virtual ~bad_last_alloc() throw() {}
00038 };
00039
00040 namespace internal {
00041 void __TBB_EXPORTED_FUNC throw_bad_last_alloc_exception_v4() ;
00042 }
00043
00044 }
00045
00046 #if __TBB_EXCEPTIONS
00047 #include "tbb_allocator.h"
00048 #include <exception>
00049 #include <typeinfo>
00050 #include <new>
00051
00052 namespace tbb {
00053
00055
00075 class tbb_exception : public std::exception {
00076 public:
00078
00079 virtual tbb_exception* move () throw() = 0;
00080
00082
00084 virtual void destroy () throw() = 0;
00085
00087
00091 virtual void throw_self () = 0;
00092
00094 virtual const char* name() const throw() = 0;
00095
00097 virtual const char* what() const throw() = 0;
00098 };
00099
00101
00105 class captured_exception : public tbb_exception
00106 {
00107 public:
00108 captured_exception ( const captured_exception& src )
00109 : my_dynamic(false)
00110 {
00111 set(src.my_exception_name, src.my_exception_info);
00112 }
00113
00114 captured_exception ( const char* name, const char* info )
00115 : my_dynamic(false)
00116 {
00117 set(name, info);
00118 }
00119
00120 __TBB_EXPORTED_METHOD ~captured_exception () throw() {
00121 clear();
00122 }
00123
00124 captured_exception& operator= ( const captured_exception& src ) {
00125 if ( this != &src ) {
00126 clear();
00127 set(src.my_exception_name, src.my_exception_info);
00128 }
00129 return *this;
00130 }
00131
00132
00133 captured_exception* move () throw();
00134
00135
00136 void destroy () throw();
00137
00138
00139 void throw_self () { throw *this; }
00140
00141
00142 const char* __TBB_EXPORTED_METHOD name() const throw();
00143
00144
00145 const char* __TBB_EXPORTED_METHOD what() const throw();
00146
00147 private:
00149 captured_exception() {}
00150
00152 static captured_exception* allocate ( const char* name, const char* info );
00153
00154 void set ( const char* name, const char* info ) throw();
00155 void clear () throw();
00156
00157 bool my_dynamic;
00158 const char* my_exception_name;
00159 const char* my_exception_info;
00160 };
00161
00163
00167 template<typename ExceptionData>
00168 class movable_exception : public tbb_exception
00169 {
00170 typedef movable_exception<ExceptionData> self_type;
00171
00172 public:
00173 movable_exception ( const ExceptionData& data )
00174 : my_exception_data(data)
00175 , my_dynamic(false)
00176 , my_exception_name(typeid(self_type).name())
00177 {}
00178
00179 movable_exception ( const movable_exception& src ) throw ()
00180 : my_exception_data(src.my_exception_data)
00181 , my_dynamic(false)
00182 , my_exception_name(src.my_exception_name)
00183 {}
00184
00185 ~movable_exception () throw() {}
00186
00187 const movable_exception& operator= ( const movable_exception& src ) {
00188 if ( this != &src ) {
00189 my_exception_data = src.my_exception_data;
00190 my_exception_name = src.my_exception_name;
00191 }
00192 return *this;
00193 }
00194
00195 ExceptionData& data () throw() { return my_exception_data; }
00196
00197 const ExceptionData& data () const throw() { return my_exception_data; }
00198
00199 const char* name () const throw() { return my_exception_name; }
00200
00201 const char* what () const throw() { return "tbb::movable_exception"; }
00202
00203
00204 movable_exception* move () throw() {
00205 void* e = internal::allocate_via_handler_v3(sizeof(movable_exception));
00206 if ( e ) {
00207 new (e) movable_exception(*this);
00208 ((movable_exception*)e)->my_dynamic = true;
00209 }
00210 return (movable_exception*)e;
00211 }
00212
00213 void destroy () throw() {
00214 __TBB_ASSERT ( my_dynamic, "Method destroy can be called only on dynamically allocated movable_exceptions" );
00215 if ( my_dynamic ) {
00216 this->~movable_exception();
00217 internal::deallocate_via_handler_v3(this);
00218 }
00219 }
00220
00221 void throw_self () {
00222 throw *this;
00223 }
00224
00225 protected:
00227 ExceptionData my_exception_data;
00228
00229 private:
00231 bool my_dynamic;
00232
00234
00235 const char* my_exception_name;
00236 };
00237
00238 #if !TBB_USE_CAPTURED_EXCEPTION
00239 namespace internal {
00240
00242
00244 class tbb_exception_ptr {
00245 std::exception_ptr my_ptr;
00246
00247 public:
00248 static tbb_exception_ptr* allocate ();
00249 static tbb_exception_ptr* allocate ( const tbb_exception& );
00250 static tbb_exception_ptr* allocate ( const captured_exception& );
00251
00253
00254 void destroy () throw();
00255
00257 void throw_self () { std::rethrow_exception(my_ptr); }
00258
00259 private:
00260 tbb_exception_ptr ( const std::exception_ptr& src ) : my_ptr(src) {}
00261 tbb_exception_ptr ( const captured_exception& src ) : my_ptr(std::copy_exception(src)) {}
00262 };
00263
00264 }
00265 #endif
00266
00267 }
00268
00269 #endif
00270
00271 #endif