]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/leaf/exception.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / leaf / exception.hpp
CommitLineData
20effc67
TL
1#ifndef BOOST_LEAF_EXCEPTION_HPP_INCLUDED
2#define BOOST_LEAF_EXCEPTION_HPP_INCLUDED
3
1e59de90 4// Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc.
20effc67
TL
5
6// Distributed under the Boost Software License, Version 1.0. (See accompanying
7// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8
1e59de90 9#include <boost/leaf/config.hpp>
20effc67 10#include <boost/leaf/error.hpp>
1e59de90
TL
11
12#ifndef BOOST_LEAF_NO_EXCEPTIONS
13
20effc67
TL
14#include <exception>
15
16#define BOOST_LEAF_EXCEPTION ::boost::leaf::leaf_detail::inject_loc{__FILE__,__LINE__,__FUNCTION__}+::boost::leaf::exception
17#define BOOST_LEAF_THROW_EXCEPTION ::boost::leaf::leaf_detail::throw_with_loc{__FILE__,__LINE__,__FUNCTION__}+::boost::leaf::exception
18
19////////////////////////////////////////
20
21namespace boost { namespace leaf {
22
1e59de90
TL
23namespace leaf_detail
24{
25 struct throw_with_loc
20effc67 26 {
1e59de90
TL
27 char const * const file;
28 int const line;
29 char const * const fn;
30
31 template <class Ex>
32 [[noreturn]] friend void operator+( throw_with_loc loc, Ex const & ex )
20effc67 33 {
1e59de90
TL
34 ex.load_source_location_(loc.file, loc.line, loc.fn);
35 ::boost::leaf::throw_exception(ex);
36 }
37 };
38}
20effc67
TL
39
40} }
41
42////////////////////////////////////////
43
44namespace boost { namespace leaf {
45
1e59de90
TL
46namespace leaf_detail
47{
48 inline void enforce_std_exception( std::exception const & ) noexcept { }
49
50 class BOOST_LEAF_SYMBOL_VISIBLE exception_base
20effc67 51 {
1e59de90
TL
52 std::shared_ptr<void const> auto_id_bump_;
53 public:
54
55 virtual error_id get_error_id() const noexcept = 0;
20effc67 56
1e59de90
TL
57 protected:
58
59 exception_base():
60 auto_id_bump_(0, [](void const *) { (void) new_id(); })
20effc67 61 {
1e59de90 62 }
20effc67 63
1e59de90
TL
64 ~exception_base() noexcept { }
65 };
20effc67 66
1e59de90
TL
67 template <class Ex>
68 class BOOST_LEAF_SYMBOL_VISIBLE exception:
69 public Ex,
70 public exception_base,
71 public error_id
72 {
73 error_id get_error_id() const noexcept final override
74 {
75 return *this;
76 }
20effc67 77
1e59de90 78 public:
20effc67 79
1e59de90
TL
80 exception( exception const & ) = default;
81 exception( exception && ) = default;
20effc67 82
1e59de90
TL
83 BOOST_LEAF_CONSTEXPR exception( error_id id, Ex const & ex ) noexcept:
84 Ex(ex),
85 error_id(id)
20effc67 86 {
1e59de90
TL
87 enforce_std_exception(*this);
88 }
89
90 BOOST_LEAF_CONSTEXPR exception( error_id id, Ex && ex ) noexcept:
91 Ex(std::move(ex)),
92 error_id(id)
20effc67 93 {
1e59de90
TL
94 enforce_std_exception(*this);
95 }
96
97 explicit BOOST_LEAF_CONSTEXPR exception( error_id id ) noexcept:
98 error_id(id)
99 {
100 enforce_std_exception(*this);
101 }
102 };
103
104 template <class... T>
105 struct at_least_one_derives_from_std_exception;
20effc67 106
1e59de90
TL
107 template <>
108 struct at_least_one_derives_from_std_exception<>: std::false_type { };
109
110 template <class T, class... Rest>
111 struct at_least_one_derives_from_std_exception<T, Rest...>
20effc67 112 {
1e59de90
TL
113 constexpr static const bool value = std::is_base_of<std::exception,typename std::remove_reference<T>::type>::value || at_least_one_derives_from_std_exception<Rest...>::value;
114 };
115}
116
117template <class Ex, class... E>
118inline
119typename std::enable_if<std::is_base_of<std::exception,typename std::remove_reference<Ex>::type>::value, leaf_detail::exception<typename std::remove_reference<Ex>::type>>::type
120exception( error_id err, Ex && ex, E && ... e ) noexcept
121{
122 static_assert(!leaf_detail::at_least_one_derives_from_std_exception<E...>::value, "Error objects passed to leaf::exception may not derive from std::exception");
123 return leaf_detail::exception<typename std::remove_reference<Ex>::type>( err.load(std::forward<E>(e)...), std::forward<Ex>(ex) );
124}
125
126template <class E1, class... E>
127inline
128typename std::enable_if<!std::is_base_of<std::exception,typename std::remove_reference<E1>::type>::value, leaf_detail::exception<std::exception>>::type
129exception( error_id err, E1 && car, E && ... cdr ) noexcept
130{
131 static_assert(!leaf_detail::at_least_one_derives_from_std_exception<E...>::value, "Error objects passed to leaf::exception may not derive from std::exception");
132 return leaf_detail::exception<std::exception>( err.load(std::forward<E1>(car), std::forward<E>(cdr)...) );
133}
134
135inline leaf_detail::exception<std::exception> exception( error_id err ) noexcept
136{
137 return leaf_detail::exception<std::exception>(err);
138}
139
140template <class Ex, class... E>
141inline
142typename std::enable_if<std::is_base_of<std::exception,typename std::remove_reference<Ex>::type>::value, leaf_detail::exception<typename std::remove_reference<Ex>::type>>::type
143exception( Ex && ex, E && ... e ) noexcept
144{
145 static_assert(!leaf_detail::at_least_one_derives_from_std_exception<E...>::value, "Error objects passed to leaf::exception may not derive from std::exception");
146 return leaf_detail::exception<typename std::remove_reference<Ex>::type>( new_error().load(std::forward<E>(e)...), std::forward<Ex>(ex) );
147}
148
149template <class E1, class... E>
150inline
151typename std::enable_if<!std::is_base_of<std::exception,typename std::remove_reference<E1>::type>::value, leaf_detail::exception<std::exception>>::type
152exception( E1 && car, E && ... cdr ) noexcept
153{
154 static_assert(!leaf_detail::at_least_one_derives_from_std_exception<E...>::value, "Error objects passed to leaf::exception may not derive from std::exception");
155 return leaf_detail::exception<std::exception>( new_error().load(std::forward<E1>(car), std::forward<E>(cdr)...) );
156}
157
158inline leaf_detail::exception<std::exception> exception() noexcept
159{
160 return leaf_detail::exception<std::exception>(leaf::new_error());
161}
162
163////////////////////////////////////////
164
165#ifndef BOOST_LEAF_NO_EXCEPTIONS
166
167template <class T>
168class result;
169
170namespace leaf_detail
171{
172 inline error_id catch_exceptions_helper( std::exception const & ex, leaf_detail_mp11::mp_list<> )
173 {
174 return leaf::new_error(std::current_exception());
20effc67
TL
175 }
176
1e59de90
TL
177 template <class Ex1, class... Ex>
178 inline error_id catch_exceptions_helper( std::exception const & ex, leaf_detail_mp11::mp_list<Ex1,Ex...> )
20effc67 179 {
1e59de90
TL
180 if( Ex1 const * p = dynamic_cast<Ex1 const *>(&ex) )
181 return catch_exceptions_helper(ex, leaf_detail_mp11::mp_list<Ex...>{ }).load(*p);
182 else
183 return catch_exceptions_helper(ex, leaf_detail_mp11::mp_list<Ex...>{ });
20effc67
TL
184 }
185
1e59de90
TL
186 template <class T>
187 struct deduce_exception_to_result_return_type_impl
188 {
189 using type = result<T>;
190 };
191
192 template <class T>
193 struct deduce_exception_to_result_return_type_impl<result<T>>
20effc67 194 {
1e59de90
TL
195 using type = result<T>;
196 };
197
198 template <class T>
199 using deduce_exception_to_result_return_type = typename deduce_exception_to_result_return_type_impl<T>::type;
200}
201
202template <class... Ex, class F>
203inline
204leaf_detail::deduce_exception_to_result_return_type<leaf_detail::fn_return_type<F>>
205exception_to_result( F && f ) noexcept
206{
207 try
208 {
209 return std::forward<F>(f)();
210 }
211 catch( std::exception const & ex )
212 {
213 return leaf_detail::catch_exceptions_helper(ex, leaf_detail_mp11::mp_list<Ex...>());
214 }
215 catch(...)
216 {
217 return leaf::new_error(std::current_exception());
20effc67 218 }
1e59de90
TL
219}
220
221#endif
20effc67
TL
222
223} }
224
225#endif
1e59de90
TL
226
227#endif