]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/leaf/on_error.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / leaf / on_error.hpp
CommitLineData
20effc67
TL
1#ifndef BOOST_LEAF_ON_ERROR_HPP_INCLUDED
2#define BOOST_LEAF_ON_ERROR_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
TL
10#include <boost/leaf/error.hpp>
11
12namespace boost { namespace leaf {
13
1e59de90
TL
14class error_monitor
15{
20effc67 16#if !defined(BOOST_LEAF_NO_EXCEPTIONS) && BOOST_LEAF_STD_UNCAUGHT_EXCEPTIONS
1e59de90 17 int const uncaught_exceptions_;
20effc67 18#endif
1e59de90 19 int const err_id_;
20effc67 20
1e59de90 21public:
20effc67 22
1e59de90 23 error_monitor() noexcept:
20effc67 24#if !defined(BOOST_LEAF_NO_EXCEPTIONS) && BOOST_LEAF_STD_UNCAUGHT_EXCEPTIONS
1e59de90 25 uncaught_exceptions_(std::uncaught_exceptions()),
20effc67 26#endif
1e59de90
TL
27 err_id_(leaf_detail::current_id())
28 {
29 }
20effc67 30
1e59de90
TL
31 int check_id() const noexcept
32 {
33 int err_id = leaf_detail::current_id();
34 if( err_id != err_id_ )
35 return err_id;
36 else
20effc67 37 {
20effc67
TL
38#ifndef BOOST_LEAF_NO_EXCEPTIONS
39# if BOOST_LEAF_STD_UNCAUGHT_EXCEPTIONS
1e59de90 40 if( std::uncaught_exceptions() > uncaught_exceptions_ )
20effc67 41# else
1e59de90 42 if( std::uncaught_exception() )
20effc67 43# endif
1e59de90 44 return leaf_detail::new_id();
20effc67 45#endif
1e59de90 46 return 0;
20effc67 47 }
1e59de90 48 }
20effc67 49
1e59de90
TL
50 int get_id() const noexcept
51 {
52 int err_id = leaf_detail::current_id();
53 if( err_id != err_id_ )
54 return err_id;
55 else
56 return leaf_detail::new_id();
57 }
20effc67 58
1e59de90
TL
59 error_id check() const noexcept
60 {
61 return leaf_detail::make_error_id(check_id());
62 }
20effc67 63
1e59de90
TL
64 error_id assigned_error_id() const noexcept
65 {
66 return leaf_detail::make_error_id(get_id());
67 }
68};
69
70////////////////////////////////////////////
71
72namespace leaf_detail
73{
74 template <int I, class Tuple>
75 struct tuple_for_each_preload
76 {
77 BOOST_LEAF_CONSTEXPR static void trigger( Tuple & tup, int err_id ) noexcept
20effc67 78 {
1e59de90
TL
79 BOOST_LEAF_ASSERT((err_id&3)==1);
80 tuple_for_each_preload<I-1,Tuple>::trigger(tup,err_id);
81 std::get<I-1>(tup).trigger(err_id);
20effc67
TL
82 }
83 };
84
1e59de90
TL
85 template <class Tuple>
86 struct tuple_for_each_preload<0, Tuple>
87 {
88 BOOST_LEAF_CONSTEXPR static void trigger( Tuple const &, int ) noexcept { }
89 };
20effc67 90
1e59de90
TL
91 template <class E>
92 class preloaded_item
20effc67 93 {
1e59de90
TL
94 using decay_E = typename std::decay<E>::type;
95 slot<decay_E> * s_;
96 decay_E e_;
20effc67 97
1e59de90 98 public:
20effc67 99
1e59de90
TL
100 BOOST_LEAF_CONSTEXPR preloaded_item( E && e ):
101 s_(tls::read_ptr<slot<decay_E>>()),
102 e_(std::forward<E>(e))
20effc67 103 {
1e59de90 104 }
20effc67 105
1e59de90 106 BOOST_LEAF_CONSTEXPR void trigger( int err_id ) noexcept
20effc67 107 {
1e59de90
TL
108 BOOST_LEAF_ASSERT((err_id&3)==1);
109 if( s_ )
20effc67 110 {
1e59de90
TL
111 if( !s_->has_value(err_id) )
112 s_->put(err_id, std::move(e_));
20effc67 113 }
1e59de90
TL
114#if BOOST_LEAF_CFG_DIAGNOSTICS
115 else
20effc67 116 {
1e59de90
TL
117 int c = tls::read_uint32<tls_tag_unexpected_enabled_counter>();
118 BOOST_LEAF_ASSERT(c>=0);
119 if( c )
120 load_unexpected(err_id, std::move(e_));
20effc67 121 }
1e59de90
TL
122#endif
123 }
124 };
20effc67 125
1e59de90
TL
126 template <class F>
127 class deferred_item
128 {
129 using E = decltype(std::declval<F>()());
130 slot<E> * s_;
131 F f_;
20effc67 132
1e59de90 133 public:
20effc67 134
1e59de90
TL
135 BOOST_LEAF_CONSTEXPR deferred_item( F && f ) noexcept:
136 s_(tls::read_ptr<slot<E>>()),
137 f_(std::forward<F>(f))
138 {
139 }
20effc67 140
1e59de90
TL
141 BOOST_LEAF_CONSTEXPR void trigger( int err_id ) noexcept
142 {
143 BOOST_LEAF_ASSERT((err_id&3)==1);
144 if( s_ )
20effc67 145 {
1e59de90
TL
146 if( !s_->has_value(err_id) )
147 s_->put(err_id, f_());
20effc67 148 }
1e59de90
TL
149#if BOOST_LEAF_CFG_DIAGNOSTICS
150 else
20effc67 151 {
1e59de90
TL
152 int c = tls::read_uint32<tls_tag_unexpected_enabled_counter>();
153 BOOST_LEAF_ASSERT(c>=0);
154 if( c )
155 load_unexpected(err_id, std::forward<E>(f_()));
20effc67 156 }
1e59de90
TL
157#endif
158 }
159 };
20effc67 160
1e59de90
TL
161 template <class F, class A0 = fn_arg_type<F,0>, int arity = function_traits<F>::arity>
162 class accumulating_item;
20effc67 163
1e59de90
TL
164 template <class F, class A0>
165 class accumulating_item<F, A0 &, 1>
166 {
167 using E = A0;
168 slot<E> * s_;
169 F f_;
20effc67 170
1e59de90 171 public:
20effc67 172
1e59de90
TL
173 BOOST_LEAF_CONSTEXPR accumulating_item( F && f ) noexcept:
174 s_(tls::read_ptr<slot<E>>()),
175 f_(std::forward<F>(f))
176 {
177 }
20effc67 178
1e59de90
TL
179 BOOST_LEAF_CONSTEXPR void trigger( int err_id ) noexcept
180 {
181 BOOST_LEAF_ASSERT((err_id&3)==1);
182 if( s_ )
183 if( E * e = s_->has_value(err_id) )
184 (void) f_(*e);
185 else
186 (void) f_(s_->put(err_id, E()));
187 }
188 };
20effc67 189
1e59de90
TL
190 template <class... Item>
191 class preloaded
192 {
193 preloaded & operator=( preloaded const & ) = delete;
194
195 std::tuple<Item...> p_;
196 bool moved_;
197 error_monitor id_;
20effc67 198
1e59de90 199 public:
20effc67 200
1e59de90
TL
201 BOOST_LEAF_CONSTEXPR explicit preloaded( Item && ... i ):
202 p_(std::forward<Item>(i)...),
203 moved_(false)
20effc67 204 {
1e59de90 205 }
20effc67 206
1e59de90
TL
207 BOOST_LEAF_CONSTEXPR preloaded( preloaded && x ) noexcept:
208 p_(std::move(x.p_)),
209 moved_(false),
210 id_(std::move(x.id_))
20effc67 211 {
1e59de90
TL
212 x.moved_ = true;
213 }
20effc67 214
1e59de90 215 ~preloaded() noexcept
20effc67 216 {
1e59de90
TL
217 if( moved_ )
218 return;
219 if( auto id = id_.check_id() )
220 tuple_for_each_preload<sizeof...(Item),decltype(p_)>::trigger(p_,id);
221 }
222 };
20effc67 223
1e59de90
TL
224 template <class T, int arity = function_traits<T>::arity>
225 struct deduce_item_type;
226
227 template <class T>
228 struct deduce_item_type<T, -1>
20effc67 229 {
1e59de90
TL
230 using type = preloaded_item<T>;
231 };
232
233 template <class F>
234 struct deduce_item_type<F, 0>
235 {
236 using type = deferred_item<F>;
237 };
238
239 template <class F>
240 struct deduce_item_type<F, 1>
241 {
242 using type = accumulating_item<F>;
243 };
244}
245
246template <class... Item>
247BOOST_LEAF_NODISCARD BOOST_LEAF_CONSTEXPR inline
248leaf_detail::preloaded<typename leaf_detail::deduce_item_type<Item>::type...>
249on_error( Item && ... i )
250{
251 return leaf_detail::preloaded<typename leaf_detail::deduce_item_type<Item>::type...>(std::forward<Item>(i)...);
252}
20effc67
TL
253
254} }
255
256#endif