Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. // Nested Exception support header (nested_exception class) for -*- C++ -*-
  2.  
  3. // Copyright (C) 2009-2015 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&) noexcept = default;
  63.  
  64.     nested_exception& operator=(const nested_exception&) noexcept = default;
  65.  
  66.     virtual ~nested_exception() noexcept;
  67.  
  68.     [[noreturn]]
  69.     void
  70.     rethrow_nested() const
  71.     {
  72.       if (_M_ptr)
  73.         rethrow_exception(_M_ptr);
  74.       std::terminate();
  75.     }
  76.  
  77.     exception_ptr
  78.     nested_ptr() const noexcept
  79.     { return _M_ptr; }
  80.   };
  81.  
  82.   template<typename _Except>
  83.     struct _Nested_exception : public _Except, public nested_exception
  84.     {
  85.       explicit _Nested_exception(const _Except& __ex)
  86.       : _Except(__ex)
  87.       { }
  88.  
  89.       explicit _Nested_exception(_Except&& __ex)
  90.       : _Except(static_cast<_Except&&>(__ex))
  91.       { }
  92.     };
  93.  
  94.   template<typename _Tp,
  95.            bool __with_nested = !__is_base_of(nested_exception, _Tp)>
  96.     struct _Throw_with_nested_impl
  97.     {
  98.       template<typename _Up>
  99.         static void _S_throw(_Up&& __t)
  100.         { throw _Nested_exception<_Tp>{static_cast<_Up&&>(__t)}; }
  101.     };
  102.  
  103.   template<typename _Tp>
  104.     struct _Throw_with_nested_impl<_Tp, false>
  105.     {
  106.       template<typename _Up>
  107.         static void _S_throw(_Up&& __t)
  108.         { throw static_cast<_Up&&>(__t); }
  109.     };
  110.  
  111.   template<typename _Tp, bool = __is_class(_Tp) && !__is_final(_Tp)>
  112.     struct _Throw_with_nested_helper : _Throw_with_nested_impl<_Tp>
  113.     { };
  114.  
  115.   template<typename _Tp>
  116.     struct _Throw_with_nested_helper<_Tp, false>
  117.     : _Throw_with_nested_impl<_Tp, false>
  118.     { };
  119.  
  120.   template<typename _Tp>
  121.     struct _Throw_with_nested_helper<_Tp&, false>
  122.     : _Throw_with_nested_helper<_Tp>
  123.     { };
  124.  
  125.   template<typename _Tp>
  126.     struct _Throw_with_nested_helper<_Tp&&, false>
  127.     : _Throw_with_nested_helper<_Tp>
  128.     { };
  129.  
  130.   /// If @p __t is derived from nested_exception, throws @p __t.
  131.   /// Else, throws an implementation-defined object derived from both.
  132.   template<typename _Tp>
  133.     [[noreturn]]
  134.     inline void
  135.     throw_with_nested(_Tp&& __t)
  136.     {
  137.       _Throw_with_nested_helper<_Tp>::_S_throw(static_cast<_Tp&&>(__t));
  138.     }
  139.  
  140.   template<typename _Tp, bool = __is_polymorphic(_Tp)>
  141.     struct _Rethrow_if_nested_impl
  142.     {
  143.       static void _S_rethrow(const _Tp& __t)
  144.       {
  145.         if (auto __tp = dynamic_cast<const nested_exception*>(&__t))
  146.           __tp->rethrow_nested();
  147.       }
  148.     };
  149.  
  150.   template<typename _Tp>
  151.     struct _Rethrow_if_nested_impl<_Tp, false>
  152.     {
  153.       static void _S_rethrow(const _Tp&) { }
  154.     };
  155.  
  156.   /// If @p __ex is derived from nested_exception, @p __ex.rethrow_nested().
  157.   template<typename _Ex>
  158.     inline void
  159.     rethrow_if_nested(const _Ex& __ex)
  160.     {
  161.       _Rethrow_if_nested_impl<_Ex>::_S_rethrow(__ex);
  162.     }
  163.  
  164.   // @} group exceptions
  165. } // namespace std
  166.  
  167. } // extern "C++"
  168.  
  169. #endif // C++11
  170.  
  171. #pragma GCC visibility pop
  172.  
  173. #endif // _GLIBCXX_NESTED_EXCEPTION_H
  174.