]> AND Private Git Repository - canny.git/blob - stc/exp/ml_stc_linux_make_v1.0/include/boost/exception/detail/exception_ptr.hpp
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
ec148f3d170340abc79f78bf927fd06f69bbec3c
[canny.git] / stc / exp / ml_stc_linux_make_v1.0 / include / boost / exception / detail / exception_ptr.hpp
1 //Copyright (c) 2006-2009 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_618474C2DE1511DEB74A388C56D89593\r
7 #define UUID_618474C2DE1511DEB74A388C56D89593\r
8 #if defined(__GNUC__) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)\r
9 #pragma GCC system_header\r
10 #endif\r
11 #if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)\r
12 #pragma warning(push,1)\r
13 #endif\r
14 \r
15 #include <boost/config.hpp>\r
16 #ifdef BOOST_NO_EXCEPTIONS\r
17 #error This header requires exception handling to be enabled.\r
18 #endif\r
19 #include <boost/exception/exception.hpp>\r
20 #include <boost/exception/info.hpp>\r
21 #include <boost/exception/diagnostic_information.hpp>\r
22 #include <boost/exception/detail/type_info.hpp>\r
23 #include <boost/shared_ptr.hpp>\r
24 #include <stdexcept>\r
25 #include <new>\r
26 #include <ios>\r
27 \r
28 namespace\r
29 boost\r
30     {\r
31 #ifndef BOOST_NO_RTTI\r
32     typedef error_info<struct tag_original_exception_type,std::type_info const *> original_exception_type;\r
33 \r
34     inline\r
35     std::string\r
36     to_string( original_exception_type const & x )\r
37         {\r
38         return x.value()->name();\r
39         }\r
40 #endif\r
41 \r
42     class exception_ptr;\r
43     exception_ptr current_exception();\r
44     void rethrow_exception( exception_ptr const & );\r
45 \r
46     class\r
47     exception_ptr\r
48         {\r
49         typedef bool exception_ptr::*unspecified_bool_type;\r
50         friend exception_ptr current_exception();\r
51         friend void rethrow_exception( exception_ptr const & );\r
52 \r
53         shared_ptr<exception_detail::clone_base const> c_;\r
54         bool bad_alloc_;\r
55 \r
56         struct\r
57         bad_alloc_tag\r
58             {\r
59             };\r
60 \r
61         explicit\r
62         exception_ptr( bad_alloc_tag ):\r
63             bad_alloc_(true)\r
64             {\r
65             }\r
66 \r
67         explicit\r
68         exception_ptr( shared_ptr<exception_detail::clone_base const> const & c ):\r
69             c_(c),\r
70             bad_alloc_(false)\r
71             {\r
72             BOOST_ASSERT(c);\r
73             }\r
74 \r
75         void\r
76         rethrow() const\r
77             {\r
78             BOOST_ASSERT(*this);\r
79             if( bad_alloc_ )\r
80                 throw enable_current_exception(std::bad_alloc());\r
81             else\r
82                 c_->rethrow();\r
83             }\r
84 \r
85         bool\r
86         empty() const\r
87             {\r
88             return !bad_alloc_ && !c_;\r
89             }\r
90 \r
91         public:\r
92 \r
93         exception_ptr():\r
94             bad_alloc_(false)\r
95             {\r
96             }\r
97 \r
98         ~exception_ptr() throw()\r
99             {\r
100             }\r
101 \r
102         operator unspecified_bool_type() const\r
103             {\r
104             return empty() ? 0 : &exception_ptr::bad_alloc_;\r
105             }\r
106 \r
107         friend\r
108         bool\r
109         operator==( exception_ptr const & a, exception_ptr const & b )\r
110             {\r
111             return a.c_==b.c_ && a.bad_alloc_==b.bad_alloc_;\r
112             }\r
113 \r
114         friend\r
115         bool\r
116         operator!=( exception_ptr const & a, exception_ptr const & b )\r
117             {\r
118             return !(a==b);\r
119             }\r
120         };\r
121 \r
122     class\r
123     unknown_exception:\r
124         public exception,\r
125         public std::exception,\r
126         public exception_detail::clone_base\r
127         {\r
128         public:\r
129 \r
130         unknown_exception()\r
131             {\r
132             }\r
133 \r
134         explicit\r
135         unknown_exception( std::exception const & e )\r
136             {\r
137             add_original_type(e);\r
138             }\r
139 \r
140         explicit\r
141         unknown_exception( boost::exception const & e ):\r
142             boost::exception(e)\r
143             {\r
144             add_original_type(e);\r
145             }\r
146 \r
147         ~unknown_exception() throw()\r
148             {\r
149             }\r
150 \r
151         private:\r
152 \r
153         exception_detail::clone_base const *\r
154         clone() const\r
155             {\r
156             return new unknown_exception(*this);\r
157             }\r
158 \r
159         void\r
160         rethrow() const\r
161             {\r
162             throw*this;\r
163             }\r
164 \r
165         template <class E>\r
166         void\r
167         add_original_type( E const & e )\r
168             {\r
169 #ifndef BOOST_NO_RTTI\r
170             (*this) << original_exception_type(&typeid(e));\r
171 #endif\r
172             }\r
173         };\r
174 \r
175     namespace\r
176     exception_detail\r
177         {\r
178         template <class T>\r
179         class\r
180         current_exception_std_exception_wrapper:\r
181             public T,\r
182             public boost::exception,\r
183             public clone_base\r
184             {\r
185             public:\r
186 \r
187             explicit\r
188             current_exception_std_exception_wrapper( T const & e1 ):\r
189                 T(e1)\r
190                 {\r
191                 add_original_type(e1);\r
192                 }\r
193 \r
194             current_exception_std_exception_wrapper( T const & e1, boost::exception const & e2 ):\r
195                 T(e1),\r
196                 boost::exception(e2)\r
197                 {\r
198                 add_original_type(e1);\r
199                 }\r
200 \r
201             ~current_exception_std_exception_wrapper() throw()\r
202                 {\r
203                 }\r
204 \r
205             private:\r
206 \r
207             clone_base const *\r
208             clone() const\r
209                 {\r
210                 return new current_exception_std_exception_wrapper(*this);\r
211                 }\r
212 \r
213             void\r
214             rethrow() const\r
215                 {\r
216                 throw *this;\r
217                 }\r
218 \r
219             template <class E>\r
220             void\r
221             add_original_type( E const & e )\r
222                 {\r
223 #ifndef BOOST_NO_RTTI\r
224                 (*this) << original_exception_type(&typeid(e));\r
225 #endif\r
226                 }\r
227             };\r
228 \r
229 #ifdef BOOST_NO_RTTI\r
230         template <class T>\r
231         exception const *\r
232         get_boost_exception( T const * )\r
233             {\r
234             try\r
235                 {\r
236                 throw;\r
237                 }\r
238             catch(\r
239             exception & x )\r
240                 {\r
241                 return &x;\r
242                 }\r
243             catch(...)\r
244                 {\r
245                 return 0;\r
246                 }\r
247             }\r
248 #else\r
249         template <class T>\r
250         exception const *\r
251         get_boost_exception( T const * x )\r
252             {\r
253             return dynamic_cast<exception const *>(x);\r
254             }\r
255 #endif\r
256 \r
257         template <class T>\r
258         inline\r
259         shared_ptr<clone_base const>\r
260         current_exception_std_exception( T const & e1 )\r
261             {\r
262             if( boost::exception const * e2 = get_boost_exception(&e1) )\r
263                 return shared_ptr<current_exception_std_exception_wrapper<T> const>(new current_exception_std_exception_wrapper<T>(e1,*e2));\r
264             else\r
265                 return shared_ptr<current_exception_std_exception_wrapper<T> const>(new current_exception_std_exception_wrapper<T>(e1));\r
266             }\r
267 \r
268         inline\r
269         shared_ptr<clone_base const>\r
270         current_exception_unknown_exception()\r
271             {\r
272             return shared_ptr<unknown_exception const>(new unknown_exception());\r
273             }\r
274 \r
275         inline\r
276         shared_ptr<clone_base const>\r
277         current_exception_unknown_boost_exception( boost::exception const & e )\r
278             {\r
279             return shared_ptr<unknown_exception const>(new unknown_exception(e));\r
280             }\r
281 \r
282         inline\r
283         shared_ptr<clone_base const>\r
284         current_exception_unknown_std_exception( std::exception const & e )\r
285             {\r
286             if( boost::exception const * be = get_boost_exception(&e) )\r
287                 return current_exception_unknown_boost_exception(*be);\r
288             else\r
289                 return shared_ptr<unknown_exception const>(new unknown_exception(e));\r
290             }\r
291 \r
292         inline\r
293         shared_ptr<clone_base const>\r
294         current_exception_impl()\r
295             {\r
296             try\r
297                 {\r
298                 throw;\r
299                 }\r
300             catch(\r
301             exception_detail::clone_base & e )\r
302                 {\r
303                 return shared_ptr<exception_detail::clone_base const>(e.clone());\r
304                 }\r
305             catch(\r
306             std::domain_error & e )\r
307                 {\r
308                 return exception_detail::current_exception_std_exception(e);\r
309                 }\r
310             catch(\r
311             std::invalid_argument & e )\r
312                 {\r
313                 return exception_detail::current_exception_std_exception(e);\r
314                 }\r
315             catch(\r
316             std::length_error & e )\r
317                 {\r
318                 return exception_detail::current_exception_std_exception(e);\r
319                 }\r
320             catch(\r
321             std::out_of_range & e )\r
322                 {\r
323                 return exception_detail::current_exception_std_exception(e);\r
324                 }\r
325             catch(\r
326             std::logic_error & e )\r
327                 {\r
328                 return exception_detail::current_exception_std_exception(e);\r
329                 }\r
330             catch(\r
331             std::range_error & e )\r
332                 {\r
333                 return exception_detail::current_exception_std_exception(e);\r
334                 }\r
335             catch(\r
336             std::overflow_error & e )\r
337                 {\r
338                 return exception_detail::current_exception_std_exception(e);\r
339                 }\r
340             catch(\r
341             std::underflow_error & e )\r
342                 {\r
343                 return exception_detail::current_exception_std_exception(e);\r
344                 }\r
345             catch(\r
346             std::ios_base::failure & e )\r
347                 {\r
348                 return exception_detail::current_exception_std_exception(e);\r
349                 }\r
350             catch(\r
351             std::runtime_error & e )\r
352                 {\r
353                 return exception_detail::current_exception_std_exception(e);\r
354                 }\r
355             catch(\r
356             std::bad_alloc & e )\r
357                 {\r
358                 return exception_detail::current_exception_std_exception(e);\r
359                 }\r
360 #ifndef BOOST_NO_TYPEID\r
361             catch(\r
362             std::bad_cast & e )\r
363                 {\r
364                 return exception_detail::current_exception_std_exception(e);\r
365                 }\r
366             catch(\r
367             std::bad_typeid & e )\r
368                 {\r
369                 return exception_detail::current_exception_std_exception(e);\r
370                 }\r
371 #endif\r
372             catch(\r
373             std::bad_exception & e )\r
374                 {\r
375                 return exception_detail::current_exception_std_exception(e);\r
376                 }\r
377             catch(\r
378             std::exception & e )\r
379                 {\r
380                 return exception_detail::current_exception_unknown_std_exception(e);\r
381                 }\r
382             catch(\r
383             boost::exception & e )\r
384                 {\r
385                 return exception_detail::current_exception_unknown_boost_exception(e);\r
386                 }\r
387             catch(\r
388             ... )\r
389                 {\r
390                 return exception_detail::current_exception_unknown_exception();\r
391                 }\r
392             }\r
393         }\r
394 \r
395     inline\r
396     exception_ptr\r
397     current_exception()\r
398         {\r
399         try\r
400             {\r
401             return exception_ptr(exception_detail::current_exception_impl());\r
402             }\r
403         catch(\r
404         std::bad_alloc & )\r
405             {\r
406             }\r
407         catch(\r
408         ... )\r
409             {\r
410             try\r
411                 {\r
412                 return exception_ptr(exception_detail::current_exception_std_exception(std::bad_exception()));\r
413                 }\r
414             catch(\r
415             std::bad_alloc & )\r
416                 {\r
417                 }\r
418             catch(\r
419             ... )\r
420                 {\r
421                 BOOST_ASSERT(0);\r
422                 }\r
423             }\r
424         return exception_ptr(exception_ptr::bad_alloc_tag());\r
425         }\r
426 \r
427     template <class T>\r
428     inline\r
429     exception_ptr\r
430     copy_exception( T const & e )\r
431         {\r
432         try\r
433             {\r
434             throw enable_current_exception(e);\r
435             }\r
436         catch(\r
437         ... )\r
438             {\r
439             return current_exception();\r
440             }\r
441         }\r
442 \r
443     inline\r
444     void\r
445     rethrow_exception( exception_ptr const & p )\r
446         {\r
447         p.rethrow();\r
448         }\r
449 \r
450     inline\r
451     std::string\r
452     diagnostic_information( exception_ptr const & p )\r
453         {\r
454         if( p )\r
455             try\r
456                 {\r
457                 rethrow_exception(p);\r
458                 }\r
459             catch(\r
460             ... )\r
461                 {\r
462                 return current_exception_diagnostic_information();\r
463                 }\r
464         return "<empty>";\r
465         }\r
466 \r
467     inline\r
468     std::string\r
469     to_string( exception_ptr const & p )\r
470         {\r
471         std::string s='\n'+diagnostic_information(p);\r
472         std::string padding("  ");\r
473         std::string r;\r
474         bool f=false;\r
475         for( std::string::const_iterator i=s.begin(),e=s.end(); i!=e; ++i )\r
476             {\r
477             if( f )\r
478                 r+=padding;\r
479             char c=*i;\r
480             r+=c;\r
481             f=(c=='\n');\r
482             }\r
483         return r;\r
484         }\r
485     }\r
486 \r
487 #if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)\r
488 #pragma warning(pop)\r
489 #endif\r
490 #endif\r