Merge release-4-6 into master
[alexxy/gromacs.git] / src / external / boost / boost / exception / exception.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_274DA366004E11DCB1DDFE2E56D89593\r
7 #define UUID_274DA366004E11DCB1DDFE2E56D89593\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 namespace\r
16 boost\r
17     {\r
18     namespace\r
19     exception_detail\r
20         {\r
21         template <class T>\r
22         class\r
23         refcount_ptr\r
24             {\r
25             public:\r
26 \r
27             refcount_ptr():\r
28                 px_(0)\r
29                 {\r
30                 }\r
31 \r
32             ~refcount_ptr()\r
33                 {\r
34                 release();\r
35                 }\r
36 \r
37             refcount_ptr( refcount_ptr const & x ):\r
38                 px_(x.px_)\r
39                 {\r
40                 add_ref();\r
41                 }\r
42 \r
43             refcount_ptr &\r
44             operator=( refcount_ptr const & x )\r
45                 {\r
46                 adopt(x.px_);\r
47                 return *this;\r
48                 }\r
49 \r
50             void\r
51             adopt( T * px )\r
52                 {\r
53                 release();\r
54                 px_=px;\r
55                 add_ref();\r
56                 }\r
57 \r
58             T *\r
59             get() const\r
60                 {\r
61                 return px_;\r
62                 }\r
63 \r
64             private:\r
65 \r
66             T * px_;\r
67 \r
68             void\r
69             add_ref()\r
70                 {\r
71                 if( px_ )\r
72                     px_->add_ref();\r
73                 }\r
74 \r
75             void\r
76             release()\r
77                 {\r
78                 if( px_ && px_->release() )\r
79                     px_=0;\r
80                 }\r
81             };\r
82         }\r
83 \r
84     ////////////////////////////////////////////////////////////////////////\r
85 \r
86     template <class Tag,class T>\r
87     class error_info;\r
88 \r
89     typedef error_info<struct throw_function_,char const *> throw_function;\r
90     typedef error_info<struct throw_file_,char const *> throw_file;\r
91     typedef error_info<struct throw_line_,int> throw_line;\r
92 \r
93     template <>\r
94     class\r
95     error_info<throw_function_,char const *>\r
96         {\r
97         public:\r
98         typedef char const * value_type;\r
99         value_type v_;\r
100         explicit\r
101         error_info( value_type v ):\r
102             v_(v)\r
103             {\r
104             }\r
105         };\r
106 \r
107     template <>\r
108     class\r
109     error_info<throw_file_,char const *>\r
110         {\r
111         public:\r
112         typedef char const * value_type;\r
113         value_type v_;\r
114         explicit\r
115         error_info( value_type v ):\r
116             v_(v)\r
117             {\r
118             }\r
119         };\r
120 \r
121     template <>\r
122     class\r
123     error_info<throw_line_,int>\r
124         {\r
125         public:\r
126         typedef int value_type;\r
127         value_type v_;\r
128         explicit\r
129         error_info( value_type v ):\r
130             v_(v)\r
131             {\r
132             }\r
133         };\r
134 \r
135 #if defined(__GNUC__)\r
136 # if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)\r
137 #  pragma GCC visibility push (default)\r
138 # endif\r
139 #endif\r
140     class exception;\r
141 #if defined(__GNUC__)\r
142 # if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)\r
143 #  pragma GCC visibility pop\r
144 # endif\r
145 #endif\r
146 \r
147     template <class T>\r
148     class shared_ptr;\r
149 \r
150     namespace\r
151     exception_detail\r
152         {\r
153         class error_info_base;\r
154         struct type_info_;\r
155 \r
156         struct\r
157         error_info_container\r
158             {\r
159             virtual char const * diagnostic_information( char const * ) const = 0;\r
160             virtual shared_ptr<error_info_base> get( type_info_ const & ) const = 0;\r
161             virtual void set( shared_ptr<error_info_base> const &, type_info_ const & ) = 0;\r
162             virtual void add_ref() const = 0;\r
163             virtual bool release() const = 0;\r
164             virtual refcount_ptr<exception_detail::error_info_container> clone() const = 0;\r
165 \r
166             protected:\r
167 \r
168             ~error_info_container() throw()\r
169                 {\r
170                 }\r
171             };\r
172 \r
173         template <class>\r
174         struct get_info;\r
175 \r
176         template <>\r
177         struct get_info<throw_function>;\r
178 \r
179         template <>\r
180         struct get_info<throw_file>;\r
181 \r
182         template <>\r
183         struct get_info<throw_line>;\r
184 \r
185         char const * get_diagnostic_information( exception const &, char const * );\r
186 \r
187         void copy_boost_exception( exception *, exception const * );\r
188 \r
189         template <class E,class Tag,class T>\r
190         E const & set_info( E const &, error_info<Tag,T> const & );\r
191 \r
192         template <class E>\r
193         E const & set_info( E const &, throw_function const & );\r
194 \r
195         template <class E>\r
196         E const & set_info( E const &, throw_file const & );\r
197 \r
198         template <class E>\r
199         E const & set_info( E const &, throw_line const & );\r
200         }\r
201 \r
202 #if defined(__GNUC__)\r
203 # if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)\r
204 #  pragma GCC visibility push (default)\r
205 # endif\r
206 #endif\r
207     class\r
208     exception\r
209         {\r
210         protected:\r
211 \r
212         exception():\r
213             throw_function_(0),\r
214             throw_file_(0),\r
215             throw_line_(-1)\r
216             {\r
217             }\r
218 \r
219 #ifdef __HP_aCC\r
220         //On HP aCC, this protected copy constructor prevents throwing boost::exception.\r
221         //On all other platforms, the same effect is achieved by the pure virtual destructor.\r
222         exception( exception const & x ) throw():\r
223             data_(x.data_),\r
224             throw_function_(x.throw_function_),\r
225             throw_file_(x.throw_file_),\r
226             throw_line_(x.throw_line_)\r
227             {\r
228             }\r
229 #endif\r
230 \r
231         virtual ~exception() throw()\r
232 #ifndef __HP_aCC\r
233             = 0 //Workaround for HP aCC, =0 incorrectly leads to link errors.\r
234 #endif\r
235             ;\r
236 \r
237 #if (defined(__MWERKS__) && __MWERKS__<=0x3207) || (defined(_MSC_VER) && _MSC_VER<=1310)\r
238         public:\r
239 #else\r
240         private:\r
241 \r
242         template <class E>\r
243         friend E const & exception_detail::set_info( E const &, throw_function const & );\r
244 \r
245         template <class E>\r
246         friend E const & exception_detail::set_info( E const &, throw_file const & );\r
247 \r
248         template <class E>\r
249         friend E const & exception_detail::set_info( E const &, throw_line const & );\r
250 \r
251         template <class E,class Tag,class T>\r
252         friend E const & exception_detail::set_info( E const &, error_info<Tag,T> const & );\r
253 \r
254         friend char const * exception_detail::get_diagnostic_information( exception const &, char const * );\r
255 \r
256         template <class>\r
257         friend struct exception_detail::get_info;\r
258         friend struct exception_detail::get_info<throw_function>;\r
259         friend struct exception_detail::get_info<throw_file>;\r
260         friend struct exception_detail::get_info<throw_line>;\r
261         friend void exception_detail::copy_boost_exception( exception *, exception const * );\r
262 #endif\r
263         mutable exception_detail::refcount_ptr<exception_detail::error_info_container> data_;\r
264         mutable char const * throw_function_;\r
265         mutable char const * throw_file_;\r
266         mutable int throw_line_;\r
267         };\r
268 #if defined(__GNUC__)\r
269 # if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)\r
270 #  pragma GCC visibility pop\r
271 # endif\r
272 #endif\r
273 \r
274     inline\r
275     exception::\r
276     ~exception() throw()\r
277         {\r
278         }\r
279 \r
280     namespace\r
281     exception_detail\r
282         {\r
283         template <class E>\r
284         E const &\r
285         set_info( E const & x, throw_function const & y )\r
286             {\r
287             x.throw_function_=y.v_;\r
288             return x;\r
289             }\r
290 \r
291         template <class E>\r
292         E const &\r
293         set_info( E const & x, throw_file const & y )\r
294             {\r
295             x.throw_file_=y.v_;\r
296             return x;\r
297             }\r
298 \r
299         template <class E>\r
300         E const &\r
301         set_info( E const & x, throw_line const & y )\r
302             {\r
303             x.throw_line_=y.v_;\r
304             return x;\r
305             }\r
306         }\r
307 \r
308     ////////////////////////////////////////////////////////////////////////\r
309 \r
310     namespace\r
311     exception_detail\r
312         {\r
313         template <class T>\r
314         struct\r
315         error_info_injector:\r
316             public T,\r
317             public exception\r
318             {\r
319             explicit\r
320             error_info_injector( T const & x ):\r
321                 T(x)\r
322                 {\r
323                 }\r
324 \r
325             ~error_info_injector() throw()\r
326                 {\r
327                 }\r
328             };\r
329 \r
330         struct large_size { char c[256]; };\r
331         large_size dispatch_boost_exception( exception const * );\r
332 \r
333         struct small_size { };\r
334         small_size dispatch_boost_exception( void const * );\r
335 \r
336         template <class,int>\r
337         struct enable_error_info_helper;\r
338 \r
339         template <class T>\r
340         struct\r
341         enable_error_info_helper<T,sizeof(large_size)>\r
342             {\r
343             typedef T type;\r
344             };\r
345 \r
346         template <class T>\r
347         struct\r
348         enable_error_info_helper<T,sizeof(small_size)>\r
349             {\r
350             typedef error_info_injector<T> type;\r
351             };\r
352 \r
353         template <class T>\r
354         struct\r
355         enable_error_info_return_type\r
356             {\r
357             typedef typename enable_error_info_helper<T,sizeof(exception_detail::dispatch_boost_exception(static_cast<T *>(0)))>::type type;\r
358             };\r
359         }\r
360 \r
361     template <class T>\r
362     inline\r
363     typename\r
364     exception_detail::enable_error_info_return_type<T>::type\r
365     enable_error_info( T const & x )\r
366         {\r
367         typedef typename exception_detail::enable_error_info_return_type<T>::type rt;\r
368         return rt(x);\r
369         }\r
370 \r
371     ////////////////////////////////////////////////////////////////////////\r
372 \r
373     namespace\r
374     exception_detail\r
375         {\r
376         class\r
377         clone_base\r
378             {\r
379             public:\r
380 \r
381             virtual clone_base const * clone() const = 0;\r
382             virtual void rethrow() const = 0;\r
383 \r
384             virtual\r
385             ~clone_base() throw()\r
386                 {\r
387                 }\r
388             };\r
389 \r
390         inline\r
391         void\r
392         copy_boost_exception( exception * a, exception const * b )\r
393             {\r
394             refcount_ptr<error_info_container> data;\r
395             if( error_info_container * d=b->data_.get() )\r
396                 data = d->clone();\r
397             a->throw_file_ = b->throw_file_;\r
398             a->throw_line_ = b->throw_line_;\r
399             a->throw_function_ = b->throw_function_;\r
400             a->data_ = data;\r
401             }\r
402 \r
403         inline\r
404         void\r
405         copy_boost_exception( void *, void const * )\r
406             {\r
407             }\r
408 \r
409         template <class T>\r
410         class\r
411         clone_impl:\r
412             public T,\r
413             public clone_base\r
414             {\r
415             public:\r
416 \r
417             explicit\r
418             clone_impl( T const & x ):\r
419                 T(x)\r
420                 {\r
421                 copy_boost_exception(this,&x);\r
422                 }\r
423 \r
424             ~clone_impl() throw()\r
425                 {\r
426                 }\r
427 \r
428             private:\r
429 \r
430             clone_base const *\r
431             clone() const\r
432                 {\r
433                 return new clone_impl(*this);\r
434                 }\r
435 \r
436             void\r
437             rethrow() const\r
438                 {\r
439                 throw*this;\r
440                 }\r
441             };\r
442         }\r
443 \r
444     template <class T>\r
445     inline\r
446     exception_detail::clone_impl<T>\r
447     enable_current_exception( T const & x )\r
448         {\r
449         return exception_detail::clone_impl<T>(x);\r
450         }\r
451     }\r
452 \r
453 #if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)\r
454 #pragma warning(pop)\r
455 #endif\r
456 #endif\r