blob: 69b76cc780c9545577b0d8776ad7f2d550f883f1 [file] [log] [blame]
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001// -*- C++ -*-
2//===-------------------------- exception ---------------------------------===//
3//
Howard Hinnantf5256e12010-05-11 21:36:01 +00004// The LLVM Compiler Infrastructure
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005//
6// This file is distributed under the University of Illinois Open Source
7// License. See LICENSE.TXT for details.
8//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP_EXCEPTION
12#define _LIBCPP_EXCEPTION
13
14/*
15 exception synopsis
16
17namespace std
18{
19
20class exception
21{
22public:
23 exception() throw();
24 exception(const exception&) throw();
25 exception& operator=(const exception&) throw();
26 virtual ~exception() throw();
27 virtual const char* what() const throw();
28};
29
30class bad_exception
31 : public exception
32{
33public:
34 bad_exception() throw();
35 bad_exception(const bad_exception&) throw();
36 bad_exception& operator=(const bad_exception&) throw();
37 virtual ~bad_exception() throw();
38 virtual const char* what() const throw();
39};
40
41typedef void (*unexpected_handler)();
42unexpected_handler set_unexpected(unexpected_handler f ) throw();
43void unexpected [[noreturn]] ();
44
45typedef void (*terminate_handler)();
46terminate_handler set_terminate(terminate_handler f ) throw();
47void terminate [[noreturn]] ();
48
49bool uncaught_exception() throw();
50
51typedef unspecified exception_ptr;
52
53exception_ptr current_exception();
54void rethrow_exception [[noreturn]] (exception_ptr p);
55template<class E> exception_ptr make_exception_ptr(E e);
56
57class nested_exception
58{
59public:
60 nested_exception() throw();
61 nested_exception(const nested_exception&) throw() = default;
62 nested_exception& operator=(const nested_exception&) throw() = default;
63 virtual ~nested_exception() = default;
64
65 // access functions
66 void rethrow_nested [[noreturn]] () const;
67 exception_ptr nested_ptr() const;
68};
69
70template <class T> void throw_with_nested [[noreturn]] (T&& t);
71template <class E> void rethrow_if_nested(const E& e);
72
73} // std
74
75*/
76
77#include <__config>
78#include <cstddef>
Howard Hinnanted2c2912010-05-27 17:06:52 +000079#include <type_traits>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000080
81#pragma GCC system_header
82
83namespace std // purposefully not using versioning namespace
84{
85
86class _LIBCPP_EXCEPTION_ABI exception
87{
88public:
89 _LIBCPP_INLINE_VISIBILITY exception() throw() {}
90 virtual ~exception() throw();
91 virtual const char* what() const throw();
92};
93
94class _LIBCPP_EXCEPTION_ABI bad_exception
95 : public exception
96{
97public:
98 _LIBCPP_INLINE_VISIBILITY bad_exception() throw() {}
99 virtual ~bad_exception() throw();
100 virtual const char* what() const throw();
101};
102
103typedef void (*unexpected_handler)();
104_LIBCPP_VISIBLE unexpected_handler set_unexpected(unexpected_handler) throw();
105_LIBCPP_VISIBLE void unexpected();
106
107typedef void (*terminate_handler)();
108_LIBCPP_VISIBLE terminate_handler set_terminate(terminate_handler) throw();
109_LIBCPP_VISIBLE void terminate() __attribute__((__noreturn__));
110
111_LIBCPP_VISIBLE bool uncaught_exception() throw();
112
113class exception_ptr;
114
115exception_ptr current_exception();
116void rethrow_exception(exception_ptr); // noreturn
117
118class exception_ptr
119{
120 void* __ptr_;
121public:
122 exception_ptr() : __ptr_() {}
123 exception_ptr(nullptr_t) : __ptr_() {}
124 exception_ptr(const exception_ptr&);
125 exception_ptr& operator=(const exception_ptr&);
126 ~exception_ptr();
127
128 // explicit
129 operator bool() const {return __ptr_ != nullptr;}
130
131 friend bool operator==(const exception_ptr& __x, const exception_ptr& __y)
132 {return __x.__ptr_ == __y.__ptr_;}
133 friend bool operator!=(const exception_ptr& __x, const exception_ptr& __y)
134 {return !(__x == __y);}
135
136 friend exception_ptr current_exception();
137 friend void rethrow_exception(exception_ptr); // noreturn
138};
139
140template<class _E>
141exception_ptr
142make_exception_ptr(_E __e)
143{
Howard Hinnantd4444702010-08-11 17:04:31 +0000144#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000145 try
146 {
147 throw __e;
148 }
149 catch (...)
150 {
151 return current_exception();
152 }
Howard Hinnant324bb032010-08-22 00:02:43 +0000153#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000154}
155
Howard Hinnanted2c2912010-05-27 17:06:52 +0000156// nested_exception
157
158class _LIBCPP_EXCEPTION_ABI nested_exception
159{
160 exception_ptr __ptr_;
161public:
162 nested_exception();
163// nested_exception(const nested_exception&) throw() = default;
164// nested_exception& operator=(const nested_exception&) throw() = default;
165 virtual ~nested_exception();
166
167 // access functions
168 void rethrow_nested /*[[noreturn]]*/ () const;
169 exception_ptr nested_ptr() const {return __ptr_;}
170};
171
172template <class _Tp>
173struct __nested
174 : public _Tp,
175 public nested_exception
176{
177 explicit __nested(const _Tp& __t) : _Tp(__t) {}
178};
179
180template <class _Tp>
Howard Hinnant324bb032010-08-22 00:02:43 +0000181void
Howard Hinnant73d21a42010-09-04 23:28:19 +0000182#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnanted2c2912010-05-27 17:06:52 +0000183throw_with_nested /*[[noreturn]]*/ (_Tp&& __t, typename enable_if<
184 is_class<typename remove_reference<_Tp>::type>::value &&
185 !is_base_of<nested_exception, typename remove_reference<_Tp>::type>::value
186 >::type* = 0)
Howard Hinnant73d21a42010-09-04 23:28:19 +0000187#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnanted2c2912010-05-27 17:06:52 +0000188throw_with_nested (_Tp& __t, typename enable_if<
189 is_class<_Tp>::value && !is_base_of<nested_exception, _Tp>::value
190 >::type* = 0)
Howard Hinnant73d21a42010-09-04 23:28:19 +0000191#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnanted2c2912010-05-27 17:06:52 +0000192{
Howard Hinnantd4444702010-08-11 17:04:31 +0000193#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnanted2c2912010-05-27 17:06:52 +0000194 throw __nested<typename remove_reference<_Tp>::type>(_STD::forward<_Tp>(__t));
Howard Hinnantd4444702010-08-11 17:04:31 +0000195#endif
Howard Hinnanted2c2912010-05-27 17:06:52 +0000196}
197
198template <class _Tp>
Howard Hinnant324bb032010-08-22 00:02:43 +0000199void
Howard Hinnant73d21a42010-09-04 23:28:19 +0000200#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnanted2c2912010-05-27 17:06:52 +0000201throw_with_nested /*[[noreturn]]*/ (_Tp&& __t, typename enable_if<
202 !is_class<typename remove_reference<_Tp>::type>::value ||
203 is_base_of<nested_exception, typename remove_reference<_Tp>::type>::value
204 >::type* = 0)
Howard Hinnant73d21a42010-09-04 23:28:19 +0000205#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnanted2c2912010-05-27 17:06:52 +0000206throw_with_nested (_Tp& __t, typename enable_if<
207 !is_class<_Tp>::value || is_base_of<nested_exception, _Tp>::value
208 >::type* = 0)
Howard Hinnant73d21a42010-09-04 23:28:19 +0000209#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
Howard Hinnanted2c2912010-05-27 17:06:52 +0000210{
Howard Hinnantd4444702010-08-11 17:04:31 +0000211#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnanted2c2912010-05-27 17:06:52 +0000212 throw _STD::forward<_Tp>(__t);
Howard Hinnantd4444702010-08-11 17:04:31 +0000213#endif
Howard Hinnanted2c2912010-05-27 17:06:52 +0000214}
215
216template <class _E>
217inline
218void
219rethrow_if_nested(const _E& __e, typename enable_if<
Howard Hinnant6bb9f582010-05-28 13:35:41 +0000220 is_polymorphic<_E>::value
Howard Hinnanted2c2912010-05-27 17:06:52 +0000221 >::type* = 0)
222{
Howard Hinnant6bb9f582010-05-28 13:35:41 +0000223 const nested_exception* __nep = dynamic_cast<const nested_exception*>(&__e);
224 if (__nep)
225 __nep->rethrow_nested();
Howard Hinnanted2c2912010-05-27 17:06:52 +0000226}
227
228template <class _E>
229inline
230void
231rethrow_if_nested(const _E& __e, typename enable_if<
Howard Hinnant6bb9f582010-05-28 13:35:41 +0000232 !is_polymorphic<_E>::value
Howard Hinnanted2c2912010-05-27 17:06:52 +0000233 >::type* = 0)
234{
235}
236
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000237} // std
238
239#endif // _LIBCPP_EXCEPTION