Blame view

3rdparty/boost_1_81_0/boost/leaf/exception.hpp 8.12 KB
63e88f80   Hu Chunming   提交三方库
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
  #ifndef BOOST_LEAF_EXCEPTION_HPP_INCLUDED
  #define BOOST_LEAF_EXCEPTION_HPP_INCLUDED
  
  // Copyright 2018-2022 Emil Dotchevski and Reverge Studios, Inc.
  
  // Distributed under the Boost Software License, Version 1.0. (See accompanying
  // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  
  #include <boost/leaf/config.hpp>
  #include <boost/leaf/error.hpp>
  #include <exception>
  
  #ifdef BOOST_LEAF_NO_EXCEPTIONS
  
  namespace boost
  {
      [[noreturn]] void throw_exception( std::exception const & ); // user defined
  }
  
  namespace boost { namespace leaf {
  
  namespace leaf_detail
  {
      template <class T>
      [[noreturn]] void throw_exception_impl( T && e )
      {
          ::boost::throw_exception(std::move(e));
      }
  
      class BOOST_LEAF_SYMBOL_VISIBLE exception_base
      {
      public:
  
          virtual error_id get_error_id() const noexcept = 0;
  
      protected:
  
          exception_base() noexcept { }
          ~exception_base() noexcept { }
      };
  }
  
  } }
  
  #else
  
  #include <memory>
  
  namespace boost { namespace leaf {
  
  namespace leaf_detail
  {
      template <class T>
      [[noreturn]] void throw_exception_impl( T && e )
      {
          throw std::move(e);
      }
  
      class BOOST_LEAF_SYMBOL_VISIBLE exception_base
      {
          std::shared_ptr<void const> auto_id_bump_;
  
      public:
  
          virtual error_id get_error_id() const noexcept = 0;
  
      protected:
  
          exception_base():
              auto_id_bump_(nullptr, [](void const *) { (void) new_id(); })
          {
          }
  
          ~exception_base() noexcept { }
      };
  }
  
  } }
  
  #endif
  
  ////////////////////////////////////////
  
  #define BOOST_LEAF_THROW_EXCEPTION ::boost::leaf::leaf_detail::throw_with_loc{__FILE__,__LINE__,__FUNCTION__}+::boost::leaf::leaf_detail::make_exception
  
  namespace boost { namespace leaf {
  
  namespace leaf_detail
  {
      struct throw_with_loc
      {
          char const * const file;
          int const line;
          char const * const fn;
  
          template <class Ex>
          [[noreturn]] friend void operator+( throw_with_loc loc, Ex && ex )
          {
              ex.load_source_location_(loc.file, loc.line, loc.fn);
              ::boost::leaf::leaf_detail::throw_exception_impl(std::move(ex));
          }
      };
  }
  
  } }
  
  ////////////////////////////////////////
  
  namespace boost { namespace leaf {
  
  namespace leaf_detail
  {
      inline void enforce_std_exception( std::exception const & ) noexcept { }
  
      template <class Ex>
      class BOOST_LEAF_SYMBOL_VISIBLE exception:
          public Ex,
          public exception_base,
          public error_id
      {
          error_id get_error_id() const noexcept final override
          {
              return *this;
          }
  
      public:
  
          exception( exception const & ) = default;
          exception( exception && ) = default;
  
          BOOST_LEAF_CONSTEXPR exception( error_id id, Ex const & ex ) noexcept:
              Ex(ex),
              error_id(id)
          {
              enforce_std_exception(*this);
          }
  
          BOOST_LEAF_CONSTEXPR exception( error_id id, Ex && ex ) noexcept:
              Ex(std::move(ex)),
              error_id(id)
          {
              enforce_std_exception(*this);
          }
  
          explicit BOOST_LEAF_CONSTEXPR exception( error_id id ) noexcept:
              error_id(id)
          {
              enforce_std_exception(*this);
          }
      };
  
      template <class... T>
      struct at_least_one_derives_from_std_exception;
  
      template <>
      struct at_least_one_derives_from_std_exception<>: std::false_type { };
  
      template <class T, class... Rest>
      struct at_least_one_derives_from_std_exception<T, Rest...>
      {
          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;
      };
  
      template <class Ex, class... E>
      inline
      typename std::enable_if<std::is_base_of<std::exception,typename std::remove_reference<Ex>::type>::value, exception<typename std::remove_reference<Ex>::type>>::type
      make_exception( error_id err, Ex && ex, E && ... e ) noexcept
      {
          static_assert(!at_least_one_derives_from_std_exception<E...>::value, "Error objects passed to leaf::exception may not derive from std::exception");
          return exception<typename std::remove_reference<Ex>::type>( err.load(std::forward<E>(e)...), std::forward<Ex>(ex) );
      }
  
      template <class E1, class... E>
      inline
      typename std::enable_if<!std::is_base_of<std::exception,typename std::remove_reference<E1>::type>::value, exception<std::exception>>::type
      make_exception( error_id err, E1 && car, E && ... cdr ) noexcept
      {
          static_assert(!at_least_one_derives_from_std_exception<E...>::value, "Error objects passed to leaf::exception may not derive from std::exception");
          return exception<std::exception>( err.load(std::forward<E1>(car), std::forward<E>(cdr)...) );
      }
  
      inline exception<std::exception> make_exception( error_id err ) noexcept
      {
          return exception<std::exception>(err);
      }
  
      template <class Ex, class... E>
      inline
      typename std::enable_if<std::is_base_of<std::exception,typename std::remove_reference<Ex>::type>::value, exception<typename std::remove_reference<Ex>::type>>::type
      make_exception( Ex && ex, E && ... e ) noexcept
      {
          static_assert(!at_least_one_derives_from_std_exception<E...>::value, "Error objects passed to leaf::exception may not derive from std::exception");
          return exception<typename std::remove_reference<Ex>::type>( new_error().load(std::forward<E>(e)...), std::forward<Ex>(ex) );
      }
  
      template <class E1, class... E>
      inline
      typename std::enable_if<!std::is_base_of<std::exception,typename std::remove_reference<E1>::type>::value, exception<std::exception>>::type
      make_exception( E1 && car, E && ... cdr ) noexcept
      {
          static_assert(!at_least_one_derives_from_std_exception<E...>::value, "Error objects passed to leaf::exception may not derive from std::exception");
          return exception<std::exception>( new_error().load(std::forward<E1>(car), std::forward<E>(cdr)...) );
      }
  
      inline exception<std::exception> make_exception() noexcept
      {
          return exception<std::exception>(leaf::new_error());
      }
  }
  
  template <class... E>
  [[noreturn]] void throw_exception( E && ... e )
  {
      // Warning: setting a breakpoint here will not intercept exceptions thrown
      // via BOOST_LEAF_THROW_EXCEPTION or originating in the few other throw
      // points elsewhere in LEAF. To intercept all of those exceptions as well,
      // set a breakpoint inside boost::leaf::leaf_detail::throw_exception_impl.
      leaf_detail::throw_exception_impl(leaf_detail::make_exception(std::forward<E>(e)...));
  }
  
  ////////////////////////////////////////
  
  #ifndef BOOST_LEAF_NO_EXCEPTIONS
  
  template <class T>
  class result;
  
  namespace leaf_detail
  {
      inline error_id catch_exceptions_helper( std::exception const &, leaf_detail_mp11::mp_list<> )
      {
          return leaf::new_error(std::current_exception());
      }
  
      template <class Ex1, class... Ex>
      inline error_id catch_exceptions_helper( std::exception const & ex, leaf_detail_mp11::mp_list<Ex1,Ex...> )
      {
          if( Ex1 const * p = dynamic_cast<Ex1 const *>(&ex) )
              return catch_exceptions_helper(ex, leaf_detail_mp11::mp_list<Ex...>{ }).load(*p);
          else
              return catch_exceptions_helper(ex, leaf_detail_mp11::mp_list<Ex...>{ });
      }
  
      template <class T>
      struct deduce_exception_to_result_return_type_impl
      {
          using type = result<T>;
      };
  
      template <class T>
      struct deduce_exception_to_result_return_type_impl<result<T>>
      {
          using type = result<T>;
      };
  
      template <class T>
      using deduce_exception_to_result_return_type = typename deduce_exception_to_result_return_type_impl<T>::type;
  }
  
  template <class... Ex, class F>
  inline
  leaf_detail::deduce_exception_to_result_return_type<leaf_detail::fn_return_type<F>>
  exception_to_result( F && f ) noexcept
  {
      try
      {
          return std::forward<F>(f)();
      }
      catch( std::exception const & ex )
      {
          return leaf_detail::catch_exceptions_helper(ex, leaf_detail_mp11::mp_list<Ex...>());
      }
      catch(...)
      {
          return leaf::new_error(std::current_exception());
      }
  }
  
  #endif
  
  } }
  
  #endif