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 {
00080 void* operator new ( size_t );
00081
00082 public:
00084
00085 virtual tbb_exception* move () throw() = 0;
00086
00088
00090 virtual void destroy () throw() = 0;
00091
00093
00097 virtual void throw_self () = 0;
00098
00100 virtual const char* name() const throw() = 0;
00101
00103 virtual const char* what() const throw() = 0;
00104
00111 void operator delete ( void* p ) {
00112 internal::deallocate_via_handler_v3(p);
00113 }
00114 };
00115
00117
00121 class captured_exception : public tbb_exception
00122 {
00123 public:
00124 captured_exception ( const captured_exception& src )
00125 : tbb_exception(src), my_dynamic(false)
00126 {
00127 set(src.my_exception_name, src.my_exception_info);
00128 }
00129
00130 captured_exception ( const char* name, const char* info )
00131 : my_dynamic(false)
00132 {
00133 set(name, info);
00134 }
00135
00136 __TBB_EXPORTED_METHOD ~captured_exception () throw() {
00137 clear();
00138 }
00139
00140 captured_exception& operator= ( const captured_exception& src ) {
00141 if ( this != &src ) {
00142 clear();
00143 set(src.my_exception_name, src.my_exception_info);
00144 }
00145 return *this;
00146 }
00147
00148
00149 captured_exception* __TBB_EXPORTED_METHOD move () throw();
00150
00151
00152 void __TBB_EXPORTED_METHOD destroy () throw();
00153
00154
00155 void throw_self () { throw *this; }
00156
00157
00158 const char* __TBB_EXPORTED_METHOD name() const throw();
00159
00160
00161 const char* __TBB_EXPORTED_METHOD what() const throw();
00162
00163 void __TBB_EXPORTED_METHOD set ( const char* name, const char* info ) throw();
00164 void __TBB_EXPORTED_METHOD clear () throw();
00165
00166 private:
00168 captured_exception() {}
00169
00171 static captured_exception* allocate ( const char* name, const char* info );
00172
00173 bool my_dynamic;
00174 const char* my_exception_name;
00175 const char* my_exception_info;
00176 };
00177
00179
00183 template<typename ExceptionData>
00184 class movable_exception : public tbb_exception
00185 {
00186 typedef movable_exception<ExceptionData> self_type;
00187
00188 public:
00189 movable_exception ( const ExceptionData& data )
00190 : my_exception_data(data)
00191 , my_dynamic(false)
00192 , my_exception_name(typeid(self_type).name())
00193 {}
00194
00195 movable_exception ( const movable_exception& src ) throw ()
00196 : tbb_exception(src)
00197 , my_exception_data(src.my_exception_data)
00198 , my_dynamic(false)
00199 , my_exception_name(src.my_exception_name)
00200 {}
00201
00202 ~movable_exception () throw() {}
00203
00204 const movable_exception& operator= ( const movable_exception& src ) {
00205 if ( this != &src ) {
00206 my_exception_data = src.my_exception_data;
00207 my_exception_name = src.my_exception_name;
00208 }
00209 return *this;
00210 }
00211
00212 ExceptionData& data () throw() { return my_exception_data; }
00213
00214 const ExceptionData& data () const throw() { return my_exception_data; }
00215
00216 const char* name () const throw() { return my_exception_name; }
00217
00218 const char* what () const throw() { return "tbb::movable_exception"; }
00219
00220
00221 movable_exception* move () throw() {
00222 void* e = internal::allocate_via_handler_v3(sizeof(movable_exception));
00223 if ( e ) {
00224 ::new (e) movable_exception(*this);
00225 ((movable_exception*)e)->my_dynamic = true;
00226 }
00227 return (movable_exception*)e;
00228 }
00229
00230 void destroy () throw() {
00231 __TBB_ASSERT ( my_dynamic, "Method destroy can be called only on dynamically allocated movable_exceptions" );
00232 if ( my_dynamic ) {
00233 this->~movable_exception();
00234 internal::deallocate_via_handler_v3(this);
00235 }
00236 }
00237
00238 void throw_self () {
00239 throw *this;
00240 }
00241
00242 protected:
00244 ExceptionData my_exception_data;
00245
00246 private:
00248 bool my_dynamic;
00249
00251
00252 const char* my_exception_name;
00253 };
00254
00255 #if !TBB_USE_CAPTURED_EXCEPTION
00256 namespace internal {
00257
00259
00261 class tbb_exception_ptr {
00262 std::exception_ptr my_ptr;
00263
00264 public:
00265 static tbb_exception_ptr* allocate ();
00266 static tbb_exception_ptr* allocate ( const tbb_exception& tag );
00268 static tbb_exception_ptr* allocate ( captured_exception& src );
00269
00271
00272 void destroy () throw();
00273
00275 void throw_self () { std::rethrow_exception(my_ptr); }
00276
00277 private:
00278 tbb_exception_ptr ( const std::exception_ptr& src ) : my_ptr(src) {}
00279 tbb_exception_ptr ( const captured_exception& src ) : my_ptr(std::copy_exception(src)) {}
00280 };
00281
00282 }
00283 #endif
00284
00285 }
00286
00287 #endif
00288
00289 #endif