CodeMover prototype
[dyninst.git] / external / boost / exception_ptr.hpp
1 //Copyright (c) 2006-2008 Emil Dotchevski and Reverge Studios, Inc.\r
2 \r
3 //Distributed under the Boost Software License, Version 1.0. (See accompanying\r
4 //file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\r
5 \r
6 #ifndef UUID_FA5836A2CADA11DC8CD47C8555D89593\r
7 #define UUID_FA5836A2CADA11DC8CD47C8555D89593\r
8 \r
9 #include <boost/exception/exception.hpp>\r
10 #include <boost/exception/detail/type_info.hpp>\r
11 #include <boost/shared_ptr.hpp>\r
12 #include <stdexcept>\r
13 #include <new>\r
14 \r
15 namespace\r
16 boost\r
17     {\r
18     class exception_ptr;\r
19     exception_ptr current_exception();\r
20     void rethrow_exception( exception_ptr const & );\r
21 \r
22     class\r
23     exception_ptr\r
24         {\r
25         typedef bool exception_ptr::*unspecified_bool_type;\r
26         friend exception_ptr current_exception();\r
27         friend void rethrow_exception( exception_ptr const & );\r
28 \r
29         shared_ptr<exception_detail::clone_base const> c_;\r
30         bool bad_alloc_;\r
31 \r
32         struct\r
33         bad_alloc_tag\r
34             {\r
35             };\r
36 \r
37         explicit\r
38         exception_ptr( bad_alloc_tag ):\r
39             bad_alloc_(true)\r
40             {\r
41             }\r
42 \r
43         explicit\r
44         exception_ptr( shared_ptr<exception_detail::clone_base const> const & c ):\r
45             c_(c),\r
46             bad_alloc_(false)\r
47             {\r
48             BOOST_ASSERT(c);\r
49             }\r
50 \r
51         public:\r
52 \r
53         exception_ptr():\r
54             bad_alloc_(false)\r
55             {\r
56             }\r
57 \r
58         operator unspecified_bool_type() const\r
59             {\r
60             return (bad_alloc_ || c_) ? &exception_ptr::bad_alloc_ : 0;\r
61             }\r
62 \r
63         friend\r
64         bool\r
65         operator==( exception_ptr const & a, exception_ptr const & b )\r
66             {\r
67             return a.c_==b.c_ && a.bad_alloc_==b.bad_alloc_;\r
68             }\r
69 \r
70         friend\r
71         bool\r
72         operator!=( exception_ptr const & a, exception_ptr const & b )\r
73             {\r
74             return !(a==b);\r
75             }\r
76         };\r
77 \r
78     class\r
79     unknown_exception:\r
80         public exception,\r
81         public std::exception,\r
82         public exception_detail::clone_base\r
83         {\r
84         public:\r
85 \r
86         unknown_exception()\r
87             {\r
88             }\r
89 \r
90         explicit\r
91         unknown_exception( boost::exception const & e ):\r
92             boost::exception(e)\r
93             {\r
94             }\r
95 \r
96         ~unknown_exception() throw()\r
97             {\r
98             }\r
99 \r
100         private:\r
101 \r
102                 exception_detail::clone_base const *\r
103         clone() const\r
104             {\r
105             return new unknown_exception(*this);\r
106             }\r
107 \r
108         void\r
109         rethrow() const\r
110             {\r
111             throw*this;\r
112             }\r
113         };\r
114 \r
115     namespace\r
116     exception_detail\r
117         {\r
118         template <class T>\r
119         class\r
120         current_exception_std_exception_wrapper:\r
121             public T,\r
122             public boost::exception,\r
123             public clone_base\r
124             {\r
125             public:\r
126 \r
127             explicit\r
128             current_exception_std_exception_wrapper( T const & e1 ):\r
129                 T(e1)\r
130                 {\r
131                 }\r
132 \r
133             current_exception_std_exception_wrapper( T const & e1, boost::exception const & e2 ):\r
134                 T(e1),\r
135                 boost::exception(e2)\r
136                 {\r
137                 }\r
138 \r
139             ~current_exception_std_exception_wrapper() throw()\r
140                 {\r
141                 }\r
142 \r
143             private:\r
144 \r
145             clone_base const *\r
146             clone() const\r
147                 {\r
148                 return new current_exception_std_exception_wrapper(*this);\r
149                 }\r
150 \r
151             void\r
152             rethrow() const\r
153                 {\r
154                 throw *this;\r
155                 }\r
156             };\r
157 \r
158 #ifdef BOOST_NO_RTTI\r
159         template <class T>\r
160         exception const *\r
161         get_boost_exception( T const * )\r
162             {\r
163             try\r
164                 {\r
165                 throw;\r
166                 }\r
167             catch(\r
168             exception & x )\r
169                 {\r
170                 return &x;\r
171                 }\r
172             catch(...)\r
173                 {\r
174                 return 0;\r
175                 }\r
176             }\r
177 #else\r
178         template <class T>\r
179         exception const *\r
180         get_boost_exception( T const * x )\r
181             {\r
182             return dynamic_cast<exception const *>(x);\r
183             }\r
184 #endif\r
185 \r
186         template <class T>\r
187         inline\r
188         shared_ptr<clone_base const>\r
189         current_exception_std_exception( T const & e1 )\r
190             {\r
191             if( boost::exception const * e2 = get_boost_exception(&e1) )\r
192                 return shared_ptr<clone_base const>(new current_exception_std_exception_wrapper<T>(e1,*e2));\r
193             else\r
194                 return shared_ptr<clone_base const>(new current_exception_std_exception_wrapper<T>(e1));\r
195             }\r
196 \r
197         inline\r
198         shared_ptr<clone_base const>\r
199         current_exception_unknown_exception()\r
200             {\r
201             return shared_ptr<clone_base const>(new unknown_exception());\r
202             }\r
203 \r
204         inline\r
205         shared_ptr<clone_base const>\r
206         current_exception_unknown_boost_exception( boost::exception const & e )\r
207             {\r
208             return shared_ptr<clone_base const>(new unknown_exception(e));\r
209             }\r
210 \r
211         inline\r
212         shared_ptr<clone_base const>\r
213         current_exception_unknown_std_exception( std::exception const & e )\r
214             {\r
215             if( boost::exception const * be = get_boost_exception(&e) )\r
216                 return current_exception_unknown_boost_exception(*be);\r
217             else\r
218                 return current_exception_unknown_exception();\r
219             }\r
220 \r
221         inline\r
222         shared_ptr<clone_base const>\r
223         current_exception_impl()\r
224             {\r
225             try\r
226                 {\r
227                 throw;\r
228                 }\r
229             catch(\r
230             exception_detail::clone_base & e )\r
231                 {\r
232                 return shared_ptr<exception_detail::clone_base const>(e.clone());\r
233                 }\r
234             catch(\r
235             std::invalid_argument & e )\r
236                 {\r
237                 return exception_detail::current_exception_std_exception(e);\r
238                 }\r
239             catch(\r
240             std::out_of_range & e )\r
241                 {\r
242                 return exception_detail::current_exception_std_exception(e);\r
243                 }\r
244             catch(\r
245             std::logic_error & e )\r
246                 {\r
247                 return exception_detail::current_exception_std_exception(e);\r
248                 }\r
249             catch(\r
250             std::bad_alloc & e )\r
251                 {\r
252                 return exception_detail::current_exception_std_exception(e);\r
253                 }\r
254 #ifndef BOOST_NO_TYPEID\r
255             catch(\r
256             std::bad_cast & e )\r
257                 {\r
258                 return exception_detail::current_exception_std_exception(e);\r
259                 }\r
260             catch(\r
261             std::bad_typeid & e )\r
262                 {\r
263                 return exception_detail::current_exception_std_exception(e);\r
264                 }\r
265 #endif\r
266             catch(\r
267             std::bad_exception & e )\r
268                 {\r
269                 return exception_detail::current_exception_std_exception(e);\r
270                 }\r
271             catch(\r
272             std::exception & e )\r
273                 {\r
274                 return exception_detail::current_exception_unknown_std_exception(e);\r
275                 }\r
276             catch(\r
277             boost::exception & e )\r
278                 {\r
279                 return exception_detail::current_exception_unknown_boost_exception(e);\r
280                 }\r
281             catch(\r
282             ... )\r
283                 {\r
284                 return exception_detail::current_exception_unknown_exception();\r
285                 }\r
286             }\r
287         }\r
288 \r
289     inline\r
290     exception_ptr\r
291     current_exception()\r
292         {\r
293         try\r
294             {\r
295             return exception_ptr(exception_detail::current_exception_impl());\r
296             }\r
297         catch(\r
298         std::bad_alloc & )\r
299             {\r
300             }\r
301         catch(\r
302         ... )\r
303             {\r
304             try\r
305                 {\r
306                 return exception_ptr(exception_detail::current_exception_std_exception(std::bad_exception()));\r
307                 }\r
308             catch(\r
309             std::bad_alloc & )\r
310                 {\r
311                 }\r
312             catch(\r
313             ... )\r
314                 {\r
315                 BOOST_ASSERT(0);\r
316                 }\r
317             }\r
318         return exception_ptr(exception_ptr::bad_alloc_tag());\r
319         }\r
320 \r
321     template <class T>\r
322     inline\r
323     exception_ptr\r
324     copy_exception( T const & e )\r
325         {\r
326         try\r
327             {\r
328             throw enable_current_exception(e);\r
329             }\r
330         catch(\r
331         ... )\r
332             {\r
333             return current_exception();\r
334             }\r
335         }\r
336 \r
337     inline\r
338     void\r
339     rethrow_exception( exception_ptr const & p )\r
340         {\r
341         BOOST_ASSERT(p);\r
342         if( p.bad_alloc_ )\r
343             throw enable_current_exception(std::bad_alloc());\r
344         else\r
345             p.c_->rethrow();\r
346         }\r
347     }\r
348 \r
349 #endif\r