Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. // Nested Exception support header (nested_exception class) for -*- C++ -*-
  2.  
  3. // Copyright (C) 2009-2013 Free Software Foundation, Inc.
  4. //
  5. // This file is part of the GNU ISO C++ Library.  This library is free
  6. // software; you can redistribute it and/or modify it under the
  7. // terms of the GNU General Public License as published by the
  8. // Free Software Foundation; either version 3, or (at your option)
  9. // any later version.
  10.  
  11. // This library is distributed in the hope that it will be useful,
  12. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. // GNU General Public License for more details.
  15.  
  16. // Under Section 7 of GPL version 3, you are granted additional
  17. // permissions described in the GCC Runtime Library Exception, version
  18. // 3.1, as published by the Free Software Foundation.
  19.  
  20. // You should have received a copy of the GNU General Public License and
  21. // a copy of the GCC Runtime Library Exception along with this program;
  22. // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
  23. // <http://www.gnu.org/licenses/>.
  24.  
  25. /** @file bits/nested_exception.h
  26.  *  This is an internal header file, included by other library headers.
  27.  *  Do not attempt to use it directly. @headername{exception}
  28.  */
  29.  
  30. #ifndef _GLIBCXX_NESTED_EXCEPTION_H
  31. #define _GLIBCXX_NESTED_EXCEPTION_H 1
  32.  
  33. #pragma GCC visibility push(default)
  34.  
  35. #if __cplusplus < 201103L
  36. # include <bits/c++0x_warning.h>
  37. #else
  38.  
  39. #include <bits/c++config.h>
  40.  
  41. #if ATOMIC_INT_LOCK_FREE < 2
  42. #  error This platform does not support exception propagation.
  43. #endif
  44.  
  45. extern "C++" {
  46.  
  47. namespace std
  48. {
  49.   /**
  50.    * @addtogroup exceptions
  51.    * @{
  52.    */
  53.  
  54.   /// Exception class with exception_ptr data member.
  55.   class nested_exception
  56.   {
  57.     exception_ptr _M_ptr;
  58.  
  59.   public:
  60.     nested_exception() noexcept : _M_ptr(current_exception()) { }
  61.  
  62.     nested_exception(const nested_exception&) = default;
  63.  
  64.     nested_exception& operator=(const nested_exception&) = default;
  65.  
  66.     virtual ~nested_exception() noexcept;
  67.  
  68.     void
  69.     rethrow_nested() const __attribute__ ((__noreturn__))
  70.     { rethrow_exception(_M_ptr); }
  71.  
  72.     exception_ptr
  73.     nested_ptr() const
  74.     { return _M_ptr; }
  75.   };
  76.  
  77.   template<typename _Except>
  78.     struct _Nested_exception : public _Except, public nested_exception
  79.     {
  80.       explicit _Nested_exception(_Except&& __ex)
  81.       : _Except(static_cast<_Except&&>(__ex))
  82.       { }
  83.     };
  84.  
  85.   template<typename _Ex>
  86.     struct __get_nested_helper
  87.     {
  88.       static const nested_exception*
  89.       _S_get(const _Ex& __ex)
  90.       { return dynamic_cast<const nested_exception*>(&__ex); }
  91.     };
  92.  
  93.   template<typename _Ex>
  94.     struct __get_nested_helper<_Ex*>
  95.     {
  96.       static const nested_exception*
  97.       _S_get(const _Ex* __ex)
  98.       { return dynamic_cast<const nested_exception*>(__ex); }
  99.     };
  100.  
  101.   template<typename _Ex>
  102.     inline const nested_exception*
  103.     __get_nested_exception(const _Ex& __ex)
  104.     { return __get_nested_helper<_Ex>::_S_get(__ex); }
  105.  
  106.   template<typename _Ex>
  107.     void
  108.     __throw_with_nested(_Ex&&, const nested_exception* = 0)
  109.     __attribute__ ((__noreturn__));
  110.  
  111.   template<typename _Ex>
  112.     void
  113.     __throw_with_nested(_Ex&&, ...) __attribute__ ((__noreturn__));
  114.  
  115.   // This function should never be called, but is needed to avoid a warning
  116.   // about ambiguous base classes when instantiating throw_with_nested<_Ex>()
  117.   // with a type that has an accessible nested_exception base.
  118.   template<typename _Ex>
  119.     inline void
  120.     __throw_with_nested(_Ex&& __ex, const nested_exception*)
  121.     { throw __ex; }
  122.  
  123.   template<typename _Ex>
  124.     inline void
  125.     __throw_with_nested(_Ex&& __ex, ...)
  126.     { throw _Nested_exception<_Ex>(static_cast<_Ex&&>(__ex)); }
  127.  
  128.   template<typename _Ex>
  129.     void
  130.     throw_with_nested(_Ex __ex) __attribute__ ((__noreturn__));
  131.  
  132.   /// If @p __ex is derived from nested_exception, @p __ex.
  133.   /// Else, an implementation-defined object derived from both.
  134.   template<typename _Ex>
  135.     inline void
  136.     throw_with_nested(_Ex __ex)
  137.     {
  138.       if (__get_nested_exception(__ex))
  139.         throw __ex;
  140.       __throw_with_nested(static_cast<_Ex&&>(__ex), &__ex);
  141.     }
  142.  
  143.   /// If @p __ex is derived from nested_exception, @p __ex.rethrow_nested().
  144.   template<typename _Ex>
  145.     inline void
  146.     rethrow_if_nested(const _Ex& __ex)
  147.     {
  148.       if (const nested_exception* __nested = __get_nested_exception(__ex))
  149.         __nested->rethrow_nested();
  150.     }
  151.  
  152.   /// Overload, See N2619
  153.   inline void
  154.   rethrow_if_nested(const nested_exception& __ex)
  155.   { __ex.rethrow_nested(); }
  156.  
  157.   // @} group exceptions
  158. } // namespace std
  159.  
  160. } // extern "C++"
  161.  
  162. #endif // C++11
  163.  
  164. #pragma GCC visibility pop
  165.  
  166. #endif // _GLIBCXX_NESTED_EXCEPTION_H
  167.