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