exception revision 261272
1227825Stheraven// -*- C++ -*-
2227825Stheraven//===-------------------------- exception ---------------------------------===//
3227825Stheraven//
4227825Stheraven//                     The LLVM Compiler Infrastructure
5227825Stheraven//
6227825Stheraven// This file is dual licensed under the MIT and the University of Illinois Open
7227825Stheraven// Source Licenses. See LICENSE.TXT for details.
8227825Stheraven//
9227825Stheraven//===----------------------------------------------------------------------===//
10227825Stheraven
11227825Stheraven#ifndef _LIBCPP_EXCEPTION
12227825Stheraven#define _LIBCPP_EXCEPTION
13227825Stheraven
14227825Stheraven/*
15227825Stheraven    exception synopsis
16227825Stheraven
17227825Stheravennamespace std
18227825Stheraven{
19227825Stheraven
20227825Stheravenclass exception
21227825Stheraven{
22227825Stheravenpublic:
23227825Stheraven    exception() noexcept;
24227825Stheraven    exception(const exception&) noexcept;
25227825Stheraven    exception& operator=(const exception&) noexcept;
26227825Stheraven    virtual ~exception() noexcept;
27227825Stheraven    virtual const char* what() const noexcept;
28227825Stheraven};
29227825Stheraven
30227825Stheravenclass bad_exception
31227825Stheraven    : public exception
32227825Stheraven{
33227825Stheravenpublic:
34227825Stheraven    bad_exception() noexcept;
35227825Stheraven    bad_exception(const bad_exception&) noexcept;
36227825Stheraven    bad_exception& operator=(const bad_exception&) noexcept;
37227825Stheraven    virtual ~bad_exception() noexcept;
38227825Stheraven    virtual const char* what() const noexcept;
39227825Stheraven};
40227825Stheraven
41227825Stheraventypedef void (*unexpected_handler)();
42227825Stheravenunexpected_handler set_unexpected(unexpected_handler  f ) noexcept;
43227825Stheravenunexpected_handler get_unexpected() noexcept;
44227825Stheraven[[noreturn]] void unexpected();
45227825Stheraven
46227825Stheraventypedef void (*terminate_handler)();
47227825Stheraventerminate_handler set_terminate(terminate_handler  f ) noexcept;
48227825Stheraventerminate_handler get_terminate() noexcept;
49227825Stheraven[[noreturn]] void terminate() noexcept;
50227825Stheraven
51227825Stheravenbool uncaught_exception() noexcept;
52227825Stheraven
53227825Stheraventypedef unspecified exception_ptr;
54227825Stheraven
55227825Stheravenexception_ptr current_exception() noexcept;
56227825Stheravenvoid rethrow_exception [[noreturn]] (exception_ptr p);
57227825Stheraventemplate<class E> exception_ptr make_exception_ptr(E e) noexcept;
58227825Stheraven
59227825Stheravenclass nested_exception
60227825Stheraven{
61227825Stheravenpublic:
62227825Stheraven    nested_exception() noexcept;
63227825Stheraven    nested_exception(const nested_exception&) noexcept = default;
64227825Stheraven    nested_exception& operator=(const nested_exception&) noexcept = default;
65227825Stheraven    virtual ~nested_exception() = default;
66227825Stheraven
67227825Stheraven    // access functions
68227825Stheraven    [[noreturn]] void rethrow_nested() const;
69227825Stheraven    exception_ptr nested_ptr() const noexcept;
70227825Stheraven};
71227825Stheraven
72227825Stheraventemplate <class T> [[noreturn]] void throw_with_nested(T&& t);
73227825Stheraventemplate <class E> void rethrow_if_nested(const E& e);
74227825Stheraven
75227825Stheraven}  // std
76227825Stheraven
77227825Stheraven*/
78227825Stheraven
79227825Stheraven#include <__config>
80227825Stheraven#include <cstddef>
81227825Stheraven#include <type_traits>
82227825Stheraven
83227825Stheraven#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
84227825Stheraven#pragma GCC system_header
85227825Stheraven#endif
86227825Stheraven
87227825Stheravennamespace std  // purposefully not using versioning namespace
88227825Stheraven{
89227825Stheraven
90227825Stheravenclass _LIBCPP_EXCEPTION_ABI exception
91227825Stheraven{
92227825Stheravenpublic:
93227825Stheraven    _LIBCPP_INLINE_VISIBILITY exception() _NOEXCEPT {}
94227825Stheraven    virtual ~exception() _NOEXCEPT;
95227825Stheraven    virtual const char* what() const _NOEXCEPT;
96227825Stheraven};
97227825Stheraven
98227825Stheravenclass _LIBCPP_EXCEPTION_ABI bad_exception
99227825Stheraven    : public exception
100227825Stheraven{
101227825Stheravenpublic:
102227825Stheraven    _LIBCPP_INLINE_VISIBILITY bad_exception() _NOEXCEPT {}
103227825Stheraven    virtual ~bad_exception() _NOEXCEPT;
104227825Stheraven    virtual const char* what() const _NOEXCEPT;
105227825Stheraven};
106227825Stheraven
107227825Stheraventypedef void (*unexpected_handler)();
108249989Sdim_LIBCPP_FUNC_VIS unexpected_handler set_unexpected(unexpected_handler) _NOEXCEPT;
109249989Sdim_LIBCPP_FUNC_VIS unexpected_handler get_unexpected() _NOEXCEPT;
110249989Sdim_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void unexpected();
111227825Stheraven
112227825Stheraventypedef void (*terminate_handler)();
113249989Sdim_LIBCPP_FUNC_VIS terminate_handler set_terminate(terminate_handler) _NOEXCEPT;
114249989Sdim_LIBCPP_FUNC_VIS terminate_handler get_terminate() _NOEXCEPT;
115249989Sdim_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void terminate() _NOEXCEPT;
116227825Stheraven
117249989Sdim_LIBCPP_FUNC_VIS bool uncaught_exception() _NOEXCEPT;
118227825Stheraven
119249989Sdimclass _LIBCPP_TYPE_VIS exception_ptr;
120227825Stheraven
121261272Sdim_LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT;
122261272Sdim_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr);
123227825Stheraven
124249989Sdimclass _LIBCPP_TYPE_VIS exception_ptr
125227825Stheraven{
126227825Stheraven    void* __ptr_;
127227825Stheravenpublic:
128227825Stheraven    _LIBCPP_INLINE_VISIBILITY exception_ptr() _NOEXCEPT : __ptr_() {}
129227825Stheraven    _LIBCPP_INLINE_VISIBILITY exception_ptr(nullptr_t) _NOEXCEPT : __ptr_() {}
130227825Stheraven    exception_ptr(const exception_ptr&) _NOEXCEPT;
131227825Stheraven    exception_ptr& operator=(const exception_ptr&) _NOEXCEPT;
132227825Stheraven    ~exception_ptr() _NOEXCEPT;
133227825Stheraven
134227825Stheraven    _LIBCPP_INLINE_VISIBILITY
135232924Stheraven    _LIBCPP_EXPLICIT
136227825Stheraven        operator bool() const _NOEXCEPT {return __ptr_ != nullptr;}
137227825Stheraven
138227825Stheraven    friend _LIBCPP_INLINE_VISIBILITY
139227825Stheraven    bool operator==(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT
140227825Stheraven        {return __x.__ptr_ == __y.__ptr_;}
141227825Stheraven    friend _LIBCPP_INLINE_VISIBILITY
142227825Stheraven    bool operator!=(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT
143227825Stheraven        {return !(__x == __y);}
144227825Stheraven
145261272Sdim    friend _LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT;
146261272Sdim    friend _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr);
147227825Stheraven};
148227825Stheraven
149232924Stheraventemplate<class _Ep>
150227825Stheravenexception_ptr
151232924Stheravenmake_exception_ptr(_Ep __e) _NOEXCEPT
152227825Stheraven{
153227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
154227825Stheraven    try
155227825Stheraven    {
156227825Stheraven        throw __e;
157227825Stheraven    }
158227825Stheraven    catch (...)
159227825Stheraven    {
160227825Stheraven        return current_exception();
161227825Stheraven    }
162227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
163227825Stheraven}
164227825Stheraven
165227825Stheraven// nested_exception
166227825Stheraven
167227825Stheravenclass _LIBCPP_EXCEPTION_ABI nested_exception
168227825Stheraven{
169227825Stheraven    exception_ptr __ptr_;
170227825Stheravenpublic:
171227825Stheraven    nested_exception() _NOEXCEPT;
172227825Stheraven//     nested_exception(const nested_exception&) noexcept = default;
173227825Stheraven//     nested_exception& operator=(const nested_exception&) noexcept = default;
174227825Stheraven    virtual ~nested_exception() _NOEXCEPT;
175227825Stheraven
176227825Stheraven    // access functions
177241900Sdim    _LIBCPP_NORETURN void rethrow_nested() const;
178227825Stheraven    _LIBCPP_INLINE_VISIBILITY exception_ptr nested_ptr() const _NOEXCEPT {return __ptr_;}
179227825Stheraven};
180227825Stheraven
181227825Stheraventemplate <class _Tp>
182227825Stheravenstruct __nested
183227825Stheraven    : public _Tp,
184227825Stheraven      public nested_exception
185227825Stheraven{
186227825Stheraven    _LIBCPP_INLINE_VISIBILITY explicit __nested(const _Tp& __t) : _Tp(__t) {}
187227825Stheraven};
188227825Stheraven
189227825Stheraventemplate <class _Tp>
190241900Sdim_LIBCPP_NORETURN
191227825Stheravenvoid
192227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
193227825Stheraventhrow_with_nested(_Tp&& __t, typename enable_if<
194227825Stheraven                  is_class<typename remove_reference<_Tp>::type>::value &&
195227825Stheraven                  !is_base_of<nested_exception, typename remove_reference<_Tp>::type>::value
196227825Stheraven                                    >::type* = 0)
197227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
198227825Stheraventhrow_with_nested (_Tp& __t, typename enable_if<
199227825Stheraven                  is_class<_Tp>::value && !is_base_of<nested_exception, _Tp>::value
200227825Stheraven                                    >::type* = 0)
201227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
202227825Stheraven{
203227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
204227825Stheraven    throw __nested<typename remove_reference<_Tp>::type>(_VSTD::forward<_Tp>(__t));
205227825Stheraven#endif
206227825Stheraven}
207227825Stheraven
208227825Stheraventemplate <class _Tp>
209241900Sdim_LIBCPP_NORETURN
210227825Stheravenvoid
211227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
212227825Stheraventhrow_with_nested(_Tp&& __t, typename enable_if<
213227825Stheraven                  !is_class<typename remove_reference<_Tp>::type>::value ||
214227825Stheraven                  is_base_of<nested_exception, typename remove_reference<_Tp>::type>::value
215227825Stheraven                                    >::type* = 0)
216227825Stheraven#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
217227825Stheraventhrow_with_nested (_Tp& __t, typename enable_if<
218227825Stheraven                  !is_class<_Tp>::value || is_base_of<nested_exception, _Tp>::value
219227825Stheraven                                    >::type* = 0)
220227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
221227825Stheraven{
222227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
223227825Stheraven    throw _VSTD::forward<_Tp>(__t);
224227825Stheraven#endif
225227825Stheraven}
226227825Stheraven
227232924Stheraventemplate <class _Ep>
228227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
229227825Stheravenvoid
230232924Stheravenrethrow_if_nested(const _Ep& __e, typename enable_if<
231232924Stheraven                                   is_polymorphic<_Ep>::value
232227825Stheraven                                                   >::type* = 0)
233227825Stheraven{
234227825Stheraven    const nested_exception* __nep = dynamic_cast<const nested_exception*>(&__e);
235227825Stheraven    if (__nep)
236227825Stheraven        __nep->rethrow_nested();
237227825Stheraven}
238227825Stheraven
239232924Stheraventemplate <class _Ep>
240227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
241227825Stheravenvoid
242232924Stheravenrethrow_if_nested(const _Ep&, typename enable_if<
243232924Stheraven                                   !is_polymorphic<_Ep>::value
244227825Stheraven                                                   >::type* = 0)
245227825Stheraven{
246227825Stheraven}
247227825Stheraven
248227825Stheraven}  // std
249227825Stheraven
250227825Stheraven#endif  // _LIBCPP_EXCEPTION
251