Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
6554 serge 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
// .
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 
37
#else
38
 
39
#include 
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
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
95
	   bool __with_nested = !__is_base_of(nested_exception, _Tp)>
96
    struct _Throw_with_nested_impl
97
    {
98
      template
99
	static void _S_throw(_Up&& __t)
100
	{ throw _Nested_exception<_Tp>{static_cast<_Up&&>(__t)}; }
101
    };
102
 
103
  template
104
    struct _Throw_with_nested_impl<_Tp, false>
105
    {
106
      template
107
	static void _S_throw(_Up&& __t)
108
	{ throw static_cast<_Up&&>(__t); }
109
    };
110
 
111
  template
112
    struct _Throw_with_nested_helper : _Throw_with_nested_impl<_Tp>
113
    { };
114
 
115
  template
116
    struct _Throw_with_nested_helper<_Tp, false>
117
    : _Throw_with_nested_impl<_Tp, false>
118
    { };
119
 
120
  template
121
    struct _Throw_with_nested_helper<_Tp&, false>
122
    : _Throw_with_nested_helper<_Tp>
123
    { };
124
 
125
  template
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
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
141
    struct _Rethrow_if_nested_impl
142
    {
143
      static void _S_rethrow(const _Tp& __t)
144
      {
145
	if (auto __tp = dynamic_cast(&__t))
146
	  __tp->rethrow_nested();
147
      }
148
    };
149
 
150
  template
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
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