yat  0.12.3pre
boost_exception_ptr.h
1 #ifndef theplu_yat_utility_boost_exception_ptr_h
2 #define theplu_yat_utility_boost_exception_ptr_h
3 // $Id: boost_exception_ptr.h 3047 2013-06-09 05:10:24Z peter $
4 
5 /*
6  Copyright (C) 2013 Peter Johansson
7 
8  This file is part of the yat library, http://dev.thep.lu.se/yat
9 
10  The yat library is free software; you can redistribute it and/or
11  modify it under the terms of the GNU General Public License as
12  published by the Free Software Foundation; either version 3 of the
13  License, or (at your option) any later version.
14 
15  The yat library is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with yat. If not, see <http://www.gnu.org/licenses/>.
22 */
23 
24 //Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc.
25 
26 //Distributed under the Boost Software License, Version 1.0. (See accompanying
27 //file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
28 
29 // This file is patched version of the one distributed in Boost 1.41
30 // See ticket #762 http://dev.thep.lu.se/yat/ticket/762 for motivation.
31 // If compiler works with <boost/exception_ptr.hpp> that file is
32 // included; otherwise this patched version is included
33 //
34 // Users can include this file before any boost header to avoid the
35 // problem reported in: http://dev.thep.lu.se/yat/ticket/762
36 
38 
39 #include "config_public.h"
40 #ifdef YAT_HAVE_WORKING_BOOST_EXCEPTION_PTR
41 #include <boost/exception_ptr.hpp>
42 #else
43 
44 #ifndef UUID_FA5836A2CADA11DC8CD47C8555D89593
45 #define UUID_FA5836A2CADA11DC8CD47C8555D89593
46 
47 #include <boost/config.hpp>
48 #ifdef BOOST_NO_EXCEPTIONS
49 #error This header requires exception handling to be enabled.
50 #endif
51 #include <boost/exception/exception.hpp>
52 #include <boost/exception/info.hpp>
53 #include <boost/exception/diagnostic_information.hpp>
54 #include <boost/exception/detail/type_info.hpp>
55 #include <boost/shared_ptr.hpp>
56 #include <stdexcept>
57 #include <new>
58 #include <ios>
59 
60 namespace
61 boost
62  {
63 #ifndef BOOST_NO_RTTI
64  typedef error_info<struct tag_original_exception_type,std::type_info const *> original_exception_type;
65 
66  inline
67  std::string
68  to_string( original_exception_type const & x )
69  {
70  return x.value()->name();
71  }
72 #endif
73 
74  class exception_ptr;
75  exception_ptr current_exception();
76  void rethrow_exception( exception_ptr const & );
77 
78  class
79  exception_ptr:
80  public exception_detail::exception_ptr_base
81  {
82  typedef bool exception_ptr::*unspecified_bool_type;
83  friend exception_ptr current_exception();
84  friend void rethrow_exception( exception_ptr const & );
85 
86  shared_ptr<exception_detail::clone_base const> c_;
87  bool bad_alloc_;
88 
89  struct
90  bad_alloc_tag
91  {
92  };
93 
94  explicit
95  exception_ptr( bad_alloc_tag ):
96  bad_alloc_(true)
97  {
98  }
99 
100  explicit
101  exception_ptr( shared_ptr<exception_detail::clone_base const> const & c ):
102  c_(c),
103  bad_alloc_(false)
104  {
105  BOOST_ASSERT(c);
106  }
107 
108  void
109  _rethrow() const
110  {
111  BOOST_ASSERT(*this);
112  if( bad_alloc_ )
113  throw enable_current_exception(std::bad_alloc());
114  else
115  c_->rethrow();
116  }
117 
118  bool
119  _empty() const
120  {
121  return !bad_alloc_ && !c_;
122  }
123 
124  public:
125 
126  exception_ptr():
127  bad_alloc_(false)
128  {
129  }
130 
131  ~exception_ptr() throw() { }
132 
133  operator unspecified_bool_type() const
134  {
135  return _empty() ? 0 : &exception_ptr::bad_alloc_;
136  }
137 
138  friend
139  bool
140  operator==( exception_ptr const & a, exception_ptr const & b )
141  {
142  return a.c_==b.c_ && a.bad_alloc_==b.bad_alloc_;
143  }
144 
145  friend
146  bool
147  operator!=( exception_ptr const & a, exception_ptr const & b )
148  {
149  return !(a==b);
150  }
151  };
152 
153  class
154  unknown_exception:
155  public exception,
156  public std::exception,
157  public exception_detail::clone_base
158  {
159  public:
160 
161  unknown_exception()
162  {
163  }
164 
165  explicit
166  unknown_exception( std::exception const & e )
167  {
168  add_original_type(e);
169  }
170 
171  explicit
172  unknown_exception( boost::exception const & e ):
173  boost::exception(e)
174  {
175  add_original_type(e);
176  }
177 
178  ~unknown_exception() throw()
179  {
180  }
181 
182  private:
183 
184  exception_detail::clone_base const *
185  clone() const
186  {
187  return new unknown_exception(*this);
188  }
189 
190  void
191  rethrow() const
192  {
193  throw*this;
194  }
195 
196  template <class E>
197  void
198  add_original_type( E const & e )
199  {
200 #ifndef BOOST_NO_RTTI
201  (*this) << original_exception_type(&typeid(e));
202 #endif
203  }
204  };
205 
206  namespace
207  exception_detail
208  {
209  template <class T>
210  class
211  current_exception_std_exception_wrapper:
212  public T,
213  public boost::exception,
214  public clone_base
215  {
216  public:
217 
218  explicit
219  current_exception_std_exception_wrapper( T const & e1 ):
220  T(e1)
221  {
222  add_original_type(e1);
223  }
224 
225  current_exception_std_exception_wrapper( T const & e1, boost::exception const & e2 ):
226  T(e1),
227  boost::exception(e2)
228  {
229  add_original_type(e1);
230  }
231 
232  ~current_exception_std_exception_wrapper() throw()
233  {
234  }
235 
236  private:
237 
238  clone_base const *
239  clone() const
240  {
241  return new current_exception_std_exception_wrapper(*this);
242  }
243 
244  void
245  rethrow() const
246  {
247  throw *this;
248  }
249 
250  template <class E>
251  void
252  add_original_type( E const & e )
253  {
254 #ifndef BOOST_NO_RTTI
255  (*this) << original_exception_type(&typeid(e));
256 #endif
257  }
258  };
259 
260 #ifdef BOOST_NO_RTTI
261  template <class T>
262  exception const *
263  get_boost_exception( T const * )
264  {
265  try
266  {
267  throw;
268  }
269  catch(
270  exception & x )
271  {
272  return &x;
273  }
274  catch(...)
275  {
276  return 0;
277  }
278  }
279 #else
280  template <class T>
281  exception const *
282  get_boost_exception( T const * x )
283  {
284  return dynamic_cast<exception const *>(x);
285  }
286 #endif
287 
288  template <class T>
289  inline
290  shared_ptr<clone_base const>
291  current_exception_std_exception( T const & e1 )
292  {
293  if( boost::exception const * e2 = get_boost_exception(&e1) )
294  return shared_ptr<current_exception_std_exception_wrapper<T> const>(new current_exception_std_exception_wrapper<T>(e1,*e2));
295  else
296  return shared_ptr<current_exception_std_exception_wrapper<T> const>(new current_exception_std_exception_wrapper<T>(e1));
297  }
298 
299  inline
300  shared_ptr<clone_base const>
301  current_exception_unknown_exception()
302  {
303  return shared_ptr<unknown_exception const>(new unknown_exception());
304  }
305 
306  inline
307  shared_ptr<clone_base const>
308  current_exception_unknown_boost_exception( boost::exception const & e )
309  {
310  return shared_ptr<unknown_exception const>(new unknown_exception(e));
311  }
312 
313  inline
314  shared_ptr<clone_base const>
315  current_exception_unknown_std_exception( std::exception const & e )
316  {
317  if( boost::exception const * be = get_boost_exception(&e) )
318  return current_exception_unknown_boost_exception(*be);
319  else
320  return shared_ptr<unknown_exception const>(new unknown_exception(e));
321  }
322 
323  inline
324  shared_ptr<clone_base const>
325  current_exception_impl()
326  {
327  try
328  {
329  throw;
330  }
331  catch(
332  exception_detail::clone_base & e )
333  {
334  return shared_ptr<exception_detail::clone_base const>(e.clone());
335  }
336  catch(
337  std::domain_error & e )
338  {
339  return exception_detail::current_exception_std_exception(e);
340  }
341  catch(
342  std::invalid_argument & e )
343  {
344  return exception_detail::current_exception_std_exception(e);
345  }
346  catch(
347  std::length_error & e )
348  {
349  return exception_detail::current_exception_std_exception(e);
350  }
351  catch(
352  std::out_of_range & e )
353  {
354  return exception_detail::current_exception_std_exception(e);
355  }
356  catch(
357  std::logic_error & e )
358  {
359  return exception_detail::current_exception_std_exception(e);
360  }
361  catch(
362  std::range_error & e )
363  {
364  return exception_detail::current_exception_std_exception(e);
365  }
366  catch(
367  std::overflow_error & e )
368  {
369  return exception_detail::current_exception_std_exception(e);
370  }
371  catch(
372  std::underflow_error & e )
373  {
374  return exception_detail::current_exception_std_exception(e);
375  }
376  catch(
377  std::ios_base::failure & e )
378  {
379  return exception_detail::current_exception_std_exception(e);
380  }
381  catch(
382  std::runtime_error & e )
383  {
384  return exception_detail::current_exception_std_exception(e);
385  }
386  catch(
387  std::bad_alloc & e )
388  {
389  return exception_detail::current_exception_std_exception(e);
390  }
391 #ifndef BOOST_NO_TYPEID
392  catch(
393  std::bad_cast & e )
394  {
395  return exception_detail::current_exception_std_exception(e);
396  }
397  catch(
398  std::bad_typeid & e )
399  {
400  return exception_detail::current_exception_std_exception(e);
401  }
402 #endif
403  catch(
404  std::bad_exception & e )
405  {
406  return exception_detail::current_exception_std_exception(e);
407  }
408  catch(
409  std::exception & e )
410  {
411  return exception_detail::current_exception_unknown_std_exception(e);
412  }
413  catch(
414  boost::exception & e )
415  {
416  return exception_detail::current_exception_unknown_boost_exception(e);
417  }
418  catch(
419  ... )
420  {
421  return exception_detail::current_exception_unknown_exception();
422  }
423  }
424  }
425 
426  inline
427  exception_ptr
428  current_exception()
429  {
430  try
431  {
432  return exception_ptr(exception_detail::current_exception_impl());
433  }
434  catch(
435  std::bad_alloc & )
436  {
437  }
438  catch(
439  ... )
440  {
441  try
442  {
443  return exception_ptr(exception_detail::current_exception_std_exception(std::bad_exception()));
444  }
445  catch(
446  std::bad_alloc & )
447  {
448  }
449  catch(
450  ... )
451  {
452  BOOST_ASSERT(0);
453  }
454  }
455  return exception_ptr(exception_ptr::bad_alloc_tag());
456  }
457 
458  template <class T>
459  inline
460  exception_ptr
461  copy_exception( T const & e )
462  {
463  try
464  {
465  throw enable_current_exception(e);
466  }
467  catch(
468  ... )
469  {
470  return current_exception();
471  }
472  }
473 
474  inline
475  void
476  rethrow_exception( exception_ptr const & p )
477  {
478  p._rethrow();
479  }
480 
481  inline
482  std::string
483  to_string( exception_ptr const & p )
484  {
485  std::string s='\n'+diagnostic_information(p);
486  std::string padding(" ");
487  std::string r;
488  bool f=false;
489  for( std::string::const_iterator i=s.begin(),e=s.end(); i!=e; ++i )
490  {
491  if( f )
492  r+=padding;
493  char c=*i;
494  r+=c;
495  f=(c=='\n');
496  }
497  return r;
498  }
499  }
500 
501 #endif
502 #endif
503 #endif
bool operator!=(const DataWeight &, const DataWeight &)
inequality operator
bool operator==(const DNA &lhs, const DNA &rhs)

Generated on Mon Jun 1 2015 12:29:52 for yat by  doxygen 1.8.5