1 #ifndef BOOST_LEAF_HPP_INCLUDED
2 #define BOOST_LEAF_HPP_INCLUDED
3 
4 // Copyright (c) 2018-2020 Emil Dotchevski and Reverge Studios, Inc.
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 
9 // >>> #include <boost/leaf/capture.hpp>
10 #line 1 "boost/leaf/capture.hpp"
11 #ifndef BOOST_LEAF_CAPTURE_HPP_INCLUDED
12 #define BOOST_LEAF_CAPTURE_HPP_INCLUDED
13 
14 // Copyright (c) 2018-2020 Emil Dotchevski and Reverge Studios, Inc.
15 
16 // Distributed under the Boost Software License, Version 1.0. (See accompanying
17 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
18 
19 #ifndef BOOST_LEAF_ENABLE_WARNINGS
20 #   if defined(__clang__)
21 #       pragma clang system_header
22 #   elif (__GNUC__*100+__GNUC_MINOR__>301)
23 #       pragma GCC system_header
24 #   elif defined(_MSC_VER)
25 #       pragma warning(push,1)
26 #   endif
27 #endif
28 
29 // >>> #include <boost/leaf/exception.hpp>
30 #line 1 "boost/leaf/exception.hpp"
31 #ifndef BOOST_LEAF_EXCEPTION_HPP_INCLUDED
32 #define BOOST_LEAF_EXCEPTION_HPP_INCLUDED
33 
34 // Copyright (c) 2018-2020 Emil Dotchevski and Reverge Studios, Inc.
35 
36 // Distributed under the Boost Software License, Version 1.0. (See accompanying
37 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
38 
39 #ifndef BOOST_LEAF_ENABLE_WARNINGS
40 #   if defined(__clang__)
41 #       pragma clang system_header
42 #   elif (__GNUC__*100+__GNUC_MINOR__>301)
43 #       pragma GCC system_header
44 #   elif defined(_MSC_VER)
45 #       pragma warning(push,1)
46 #   endif
47 #endif
48 
49 // >>> #include <boost/leaf/error.hpp>
50 #line 1 "boost/leaf/error.hpp"
51 #ifndef BOOST_LEAF_ERROR_HPP_INCLUDED
52 #define BOOST_LEAF_ERROR_HPP_INCLUDED
53 
54 // Copyright (c) 2018-2020 Emil Dotchevski and Reverge Studios, Inc.
55 
56 // Distributed under the Boost Software License, Version 1.0. (See accompanying
57 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
58 
59 #ifndef BOOST_LEAF_ENABLE_WARNINGS
60 #   if defined(__clang__)
61 #       pragma clang system_header
62 #   elif (__GNUC__*100+__GNUC_MINOR__>301)
63 #       pragma GCC system_header
64 #   elif defined(_MSC_VER)
65 #       pragma warning(push,1)
66 #   endif
67 #endif
68 
69 // >>> #include <boost/leaf/detail/function_traits.hpp>
70 #line 1 "boost/leaf/detail/function_traits.hpp"
71 #ifndef BOOST_LEAF_DETAIL_FUNCTION_TRAITS_HPP_INCLUDED
72 #define BOOST_LEAF_DETAIL_FUNCTION_TRAITS_HPP_INCLUDED
73 
74 // Copyright (c) 2018-2020 Emil Dotchevski and Reverge Studios, Inc.
75 
76 // Distributed under the Boost Software License, Version 1.0. (See accompanying
77 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
78 
79 #ifndef BOOST_LEAF_ENABLE_WARNINGS
80 #   if defined(__clang__)
81 #       pragma clang system_header
82 #   elif (__GNUC__*100+__GNUC_MINOR__>301)
83 #       pragma GCC system_header
84 #   elif defined(_MSC_VER)
85 #       pragma warning(push,1)
86 #   endif
87 #endif
88 
89 // >>> #include <boost/leaf/detail/mp11.hpp>
90 #line 1 "boost/leaf/detail/mp11.hpp"
91 #ifndef BOOST_LEAF_DETAIL_MP11_HPP_INCLUDED
92 #define BOOST_LEAF_DETAIL_MP11_HPP_INCLUDED
93 
94 //  Copyright 2015-2017 Peter Dimov.
95 //  Copyright 2019 Emil Dotchevski.
96 //
97 //  Distributed under the Boost Software License, Version 1.0.
98 //
99 //  See accompanying file LICENSE_1_0.txt or copy at
100 //  http://www.boost.org/LICENSE_1_0.txt
101 
102 #include <type_traits>
103 #include <cstddef>
104 
105 namespace boost { namespace leaf { namespace leaf_detail_mp11 {
106 
107 // mp_list<T...>
108 template<class... T> struct mp_list
109 {
110 };
111 
112 // mp_identity
113 template<class T> struct mp_identity
114 {
115     using type = T;
116 };
117 
118 // mp_inherit
119 template<class... T> struct mp_inherit: T... {};
120 
121 // mp_if, mp_if_c
122 namespace detail
123 {
124 
125 template<bool C, class T, class... E> struct mp_if_c_impl
126 {
127 };
128 
129 template<class T, class... E> struct mp_if_c_impl<true, T, E...>
130 {
131     using type = T;
132 };
133 
134 template<class T, class E> struct mp_if_c_impl<false, T, E>
135 {
136     using type = E;
137 };
138 
139 } // namespace detail
140 
141 template<bool C, class T, class... E> using mp_if_c = typename detail::mp_if_c_impl<C, T, E...>::type;
142 template<class C, class T, class... E> using mp_if = typename detail::mp_if_c_impl<static_cast<bool>(C::value), T, E...>::type;
143 
144 // mp_bool
145 template<bool B> using mp_bool = std::integral_constant<bool, B>;
146 
147 using mp_true = mp_bool<true>;
148 using mp_false = mp_bool<false>;
149 
150 // mp_to_bool
151 template<class T> using mp_to_bool = mp_bool<static_cast<bool>( T::value )>;
152 
153 // mp_not<T>
154 template<class T> using mp_not = mp_bool< !T::value >;
155 
156 // mp_int
157 template<int I> using mp_int = std::integral_constant<int, I>;
158 
159 // mp_size_t
160 template<std::size_t N> using mp_size_t = std::integral_constant<std::size_t, N>;
161 
162 // mp_set_contains<S, V>
163 namespace detail
164 {
165 
166 template<class S, class V> struct mp_set_contains_impl;
167 
168 template<template<class...> class L, class... T, class V> struct mp_set_contains_impl<L<T...>, V>
169 {
170     using type = mp_to_bool<std::is_base_of<mp_identity<V>, mp_inherit<mp_identity<T>...> > >;
171 };
172 
173 } // namespace detail
174 
175 template<class S, class V> using mp_set_contains = typename detail::mp_set_contains_impl<S, V>::type;
176 
177 // mp_set_push_back<S, T...>
178 namespace detail
179 {
180 
181 template<class S, class... T> struct mp_set_push_back_impl;
182 
183 template<template<class...> class L, class... U> struct mp_set_push_back_impl<L<U...>>
184 {
185     using type = L<U...>;
186 };
187 
188 template<template<class...> class L, class... U, class T1, class... T> struct mp_set_push_back_impl<L<U...>, T1, T...>
189 {
190     using S = mp_if<mp_set_contains<L<U...>, T1>, L<U...>, L<U..., T1>>;
191     using type = typename mp_set_push_back_impl<S, T...>::type;
192 };
193 
194 } // namespace detail
195 
196 template<class S, class... T> using mp_set_push_back = typename detail::mp_set_push_back_impl<S, T...>::type;
197 
198 // mp_unique<L>
199 namespace detail
200 {
201 
202 template<class L> struct mp_unique_impl;
203 
204 template<template<class...> class L, class... T> struct mp_unique_impl<L<T...>>
205 {
206     using type = mp_set_push_back<L<>, T...>;
207 };
208 
209 } // namespace detail
210 
211 template<class L> using mp_unique = typename detail::mp_unique_impl<L>::type;
212 
213 // mp_append<L...>
214 
215 namespace detail
216 {
217 
218 template<class... L> struct mp_append_impl;
219 
220 template<> struct mp_append_impl<>
221 {
222     using type = mp_list<>;
223 };
224 
225 template<template<class...> class L, class... T> struct mp_append_impl<L<T...>>
226 {
227     using type = L<T...>;
228 };
229 
230 template<template<class...> class L1, class... T1, template<class...> class L2, class... T2, class... Lr> struct mp_append_impl<L1<T1...>, L2<T2...>, Lr...>
231 {
232     using type = typename mp_append_impl<L1<T1..., T2...>, Lr...>::type;
233 };
234 
235 }
236 
237 template<class... L> using mp_append = typename detail::mp_append_impl<L...>::type;
238 
239 // mp_front<L>
240 namespace detail
241 {
242 
243 template<class L> struct mp_front_impl
244 {
245 // An error "no type named 'type'" here means that the argument to mp_front
246 // is either not a list, or is an empty list
247 };
248 
249 template<template<class...> class L, class T1, class... T> struct mp_front_impl<L<T1, T...>>
250 {
251     using type = T1;
252 };
253 
254 } // namespace detail
255 
256 template<class L> using mp_front = typename detail::mp_front_impl<L>::type;
257 
258 // mp_pop_front<L>
259 namespace detail
260 {
261 
262 template<class L> struct mp_pop_front_impl
263 {
264 // An error "no type named 'type'" here means that the argument to mp_pop_front
265 // is either not a list, or is an empty list
266 };
267 
268 template<template<class...> class L, class T1, class... T> struct mp_pop_front_impl<L<T1, T...>>
269 {
270     using type = L<T...>;
271 };
272 
273 } // namespace detail
274 
275 template<class L> using mp_pop_front = typename detail::mp_pop_front_impl<L>::type;
276 
277 // mp_first<L>
278 template<class L> using mp_first = mp_front<L>;
279 
280 // mp_rest<L>
281 template<class L> using mp_rest = mp_pop_front<L>;
282 
283 // mp_remove_if<L, P>
284 namespace detail
285 {
286 
287 template<class L, template<class...> class P> struct mp_remove_if_impl;
288 
289 template<template<class...> class L, class... T, template<class...> class P> struct mp_remove_if_impl<L<T...>, P>
290 {
291     template<class U> using _f = mp_if<P<U>, mp_list<>, mp_list<U>>;
292     using type = mp_append<L<>, _f<T>...>;
293 };
294 
295 } // namespace detail
296 
297 template<class L, template<class...> class P> using mp_remove_if = typename detail::mp_remove_if_impl<L, P>::type;
298 
299 // integer_sequence
300 template<class T, T... I> struct integer_sequence
301 {
302 };
303 
304 // detail::make_integer_sequence_impl
305 namespace detail
306 {
307 
308 // iseq_if_c
309 template<bool C, class T, class E> struct iseq_if_c_impl;
310 
311 template<class T, class E> struct iseq_if_c_impl<true, T, E>
312 {
313     using type = T;
314 };
315 
316 template<class T, class E> struct iseq_if_c_impl<false, T, E>
317 {
318     using type = E;
319 };
320 
321 template<bool C, class T, class E> using iseq_if_c = typename iseq_if_c_impl<C, T, E>::type;
322 
323 // iseq_identity
324 template<class T> struct iseq_identity
325 {
326     using type = T;
327 };
328 
329 template<class S1, class S2> struct append_integer_sequence;
330 
331 template<class T, T... I, T... J> struct append_integer_sequence<integer_sequence<T, I...>, integer_sequence<T, J...>>
332 {
333     using type = integer_sequence< T, I..., ( J + sizeof...(I) )... >;
334 };
335 
336 template<class T, T N> struct make_integer_sequence_impl;
337 
338 template<class T, T N> struct make_integer_sequence_impl_
339 {
340 private:
341 
342     static_assert( N >= 0, "make_integer_sequence<T, N>: N must not be negative" );
343 
344     static T const M = N / 2;
345     static T const R = N % 2;
346 
347     using S1 = typename make_integer_sequence_impl<T, M>::type;
348     using S2 = typename append_integer_sequence<S1, S1>::type;
349     using S3 = typename make_integer_sequence_impl<T, R>::type;
350     using S4 = typename append_integer_sequence<S2, S3>::type;
351 
352 public:
353 
354     using type = S4;
355 };
356 
357 template<class T, T N> struct make_integer_sequence_impl: iseq_if_c<N == 0, iseq_identity<integer_sequence<T>>, iseq_if_c<N == 1, iseq_identity<integer_sequence<T, 0>>, make_integer_sequence_impl_<T, N> > >
358 {
359 };
360 
361 } // namespace detail
362 
363 // make_integer_sequence
364 template<class T, T N> using make_integer_sequence = typename detail::make_integer_sequence_impl<T, N>::type;
365 
366 // index_sequence
367 template<std::size_t... I> using index_sequence = integer_sequence<std::size_t, I...>;
368 
369 // make_index_sequence
370 template<std::size_t N> using make_index_sequence = make_integer_sequence<std::size_t, N>;
371 
372 // index_sequence_for
373 template<class... T> using index_sequence_for = make_integer_sequence<std::size_t, sizeof...(T)>;
374 
375 // implementation by Bruno Dutra (by the name is_evaluable)
376 namespace detail
377 {
378 
379 template<template<class...> class F, class... T> struct mp_valid_impl
380 {
381     template<template<class...> class G, class = G<T...>> static mp_true check(int);
382     template<template<class...> class> static mp_false check(...);
383 
384     using type = decltype(check<F>(0));
385 };
386 
387 } // namespace detail
388 
389 template<template<class...> class F, class... T> using mp_valid = typename detail::mp_valid_impl<F, T...>::type;
390 
391 } } }
392 
393 #endif
394 // <<< #include <boost/leaf/detail/mp11.hpp>
395 #line 20 "boost/leaf/detail/function_traits.hpp"
396 #include <tuple>
397 
398 namespace boost { namespace leaf {
399 
400     namespace leaf_detail
401     {
402         template<class...>
403         struct gcc49_workaround //Thanks Glen Fernandes
404         {
405             using type = void;
406         };
407 
408         template<class... T>
409         using void_t = typename gcc49_workaround<T...>::type;
410 
411         template<class F,class V=void>
412         struct function_traits
413         {
414             constexpr static int arity = -1;
415         };
416 
417         template<class F>
418         struct function_traits<F, void_t<decltype(&F::operator())>>
419         {
420         private:
421 
422             using tr = function_traits<decltype(&F::operator())>;
423 
424         public:
425 
426             using return_type = typename tr::return_type;
427             static constexpr int arity = tr::arity - 1;
428 
429             using mp_args = typename leaf_detail_mp11::mp_rest<typename tr::mp_args>;
430 
431             template <int I>
432             struct arg:
433                 tr::template arg<I+1>
434             {
435             };
436         };
437 
438         template<class R, class... A>
439         struct function_traits<R(A...)>
440         {
441             using return_type = R;
442             static constexpr int arity = sizeof...(A);
443 
444             using mp_args = leaf_detail_mp11::mp_list<A...>;
445 
446             template <int I>
447             struct arg
448             {
449                 static_assert(I < arity, "I out of range");
450                 using type = typename std::tuple_element<I,std::tuple<A...>>::type;
451             };
452         };
453 
454         template<class F> struct function_traits<F&> : function_traits<F> { };
455         template<class F> struct function_traits<F&&> : function_traits<F> { };
456         template<class R, class... A> struct function_traits<R(*)(A...)> : function_traits<R(A...)> { };
457         template<class R, class... A> struct function_traits<R(* &)(A...)> : function_traits<R(A...)> { };
458         template<class R, class... A> struct function_traits<R(* const &)(A...)> : function_traits<R(A...)> { };
459         template<class C, class R, class... A> struct function_traits<R(C::*)(A...)> : function_traits<R(C&,A...)> { };
460         template<class C, class R, class... A> struct function_traits<R(C::*)(A...) const> : function_traits<R(C const &,A...)> { };
461         template<class C, class R> struct function_traits<R(C::*)> : function_traits<R(C&)> { };
462 
463         template <class F>
464         using fn_return_type = typename function_traits<F>::return_type;
465 
466         template <class F, int I>
467         using fn_arg_type = typename function_traits<F>::template arg<I>::type;
468 
469         template <class F>
470         using fn_mp_args = typename function_traits<F>::mp_args;
471 
472     }
473 
474 } }
475 
476 #endif
477 // <<< #include <boost/leaf/detail/function_traits.hpp>
478 #line 20 "boost/leaf/error.hpp"
479 // >>> #include <boost/leaf/detail/print.hpp>
480 #line 1 "boost/leaf/detail/print.hpp"
481 #ifndef BOOST_LEAF_DETAIL_PRINT_HPP_INCLUDED
482 #define BOOST_LEAF_DETAIL_PRINT_HPP_INCLUDED
483 
484 // Copyright (c) 2018-2020 Emil Dotchevski and Reverge Studios, Inc.
485 
486 // Distributed under the Boost Software License, Version 1.0. (See accompanying
487 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
488 
489 #ifndef BOOST_LEAF_ENABLE_WARNINGS
490 #   if defined(__clang__)
491 #       pragma clang system_header
492 #   elif (__GNUC__*100+__GNUC_MINOR__>301)
493 #       pragma GCC system_header
494 #   elif defined(_MSC_VER)
495 #       pragma warning(push,1)
496 #   endif
497 #endif
498 
499 // >>> #include <boost/leaf/detail/optional.hpp>
500 #line 1 "boost/leaf/detail/optional.hpp"
501 #ifndef BOOST_LEAF_DETAIL_OPTIONAL_HPP_INCLUDED
502 #define BOOST_LEAF_DETAIL_OPTIONAL_HPP_INCLUDED
503 
504 // Copyright (c) 2018-2020 Emil Dotchevski and Reverge Studios, Inc.
505 
506 // Distributed under the Boost Software License, Version 1.0. (See accompanying
507 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
508 
509 #ifndef BOOST_LEAF_ENABLE_WARNINGS
510 #   if defined(__clang__)
511 #       pragma clang system_header
512 #   elif (__GNUC__*100+__GNUC_MINOR__>301)
513 #       pragma GCC system_header
514 #   elif defined(_MSC_VER)
515 #       pragma warning(push,1)
516 #   endif
517 #endif
518 
519 // >>> #include <boost/leaf/detail/config.hpp>
520 #line 1 "boost/leaf/detail/config.hpp"
521 #ifndef BOOST_LEAF_CONFIG_HPP_INCLUDED
522 #define BOOST_LEAF_CONFIG_HPP_INCLUDED
523 
524 // Copyright (c) 2018-2020 Emil Dotchevski and Reverge Studios, Inc.
525 
526 // Distributed under the Boost Software License, Version 1.0. (See accompanying
527 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
528 
529 // The following is based on Boost Config.
530 
531 // (C) Copyright John Maddock 2001 - 2003.
532 // (C) Copyright Martin Wille 2003.
533 // (C) Copyright Guillaume Melquiond 2003.
534 
535 #ifndef BOOST_LEAF_ENABLE_WARNINGS
536 #   if defined(__clang__)
537 #       pragma clang system_header
538 #   elif (__GNUC__*100+__GNUC_MINOR__>301)
539 #       pragma GCC system_header
540 #   elif defined(_MSC_VER)
541 #       pragma warning(push,1)
542 #   endif
543 #endif
544 
545 ////////////////////////////////////////
546 
547 // Configure BOOST_LEAF_NO_EXCEPTIONS, unless already #defined
548 #ifndef BOOST_LEAF_NO_EXCEPTIONS
549 
550 #   if defined(__clang__) && !defined(__ibmxl__)
551 //  Clang C++ emulates GCC, so it has to appear early.
552 
553 #       if !__has_feature(cxx_exceptions)
554 #           define BOOST_LEAF_NO_EXCEPTIONS
555 #       endif
556 
557 #   elif defined(__DMC__)
558 //  Digital Mars C++
559 
560 #       if !defined(_CPPUNWIND)
561 #           define BOOST_LEAF_NO_EXCEPTIONS
562 #       endif
563 
564 #   elif defined(__GNUC__) && !defined(__ibmxl__)
565 //  GNU C++:
566 
567 #       if !defined(__EXCEPTIONS)
568 #           define BOOST_LEAF_NO_EXCEPTIONS
569 #       endif
570 
571 #   elif defined(__KCC)
572 //  Kai C++
573 
574 #       if !defined(_EXCEPTIONS)
575 #           define BOOST_LEAF_NO_EXCEPTIONS
576 #       endif
577 
578 #   elif defined(__CODEGEARC__)
579 //  CodeGear - must be checked for before Borland
580 
581 #       if !defined(_CPPUNWIND) && !defined(__EXCEPTIONS)
582 #           define BOOST_LEAF_NO_EXCEPTIONS
583 #       endif
584 
585 #   elif defined(__BORLANDC__)
586 //  Borland
587 
588 #       if !defined(_CPPUNWIND) && !defined(__EXCEPTIONS)
589 #           define BOOST_LEAF_NO_EXCEPTIONS
590 #       endif
591 
592 #   elif defined(__MWERKS__)
593 //  Metrowerks CodeWarrior
594 
595 #       if !__option(exceptions)
596 #           define BOOST_LEAF_NO_EXCEPTIONS
597 #       endif
598 
599 #   elif defined(__IBMCPP__) && defined(__COMPILER_VER__) && defined(__MVS__)
600 //  IBM z/OS XL C/C++
601 
602 #       if !defined(_CPPUNWIND) && !defined(__EXCEPTIONS)
603 #           define BOOST_LEAF_NO_EXCEPTIONS
604 #       endif
605 
606 #   elif defined(__ibmxl__)
607 //  IBM XL C/C++ for Linux (Little Endian)
608 
609 #       if !__has_feature(cxx_exceptions)
610 #           define BOOST_LEAF_NO_EXCEPTIONS
611 #       endif
612 
613 #   elif defined(_MSC_VER)
614 //  Microsoft Visual C++
615 //
616 //  Must remain the last #elif since some other vendors (Metrowerks, for
617 //  example) also #define _MSC_VER
618 
619 #       if !defined(_CPPUNWIND)
620 #           define BOOST_LEAF_NO_EXCEPTIONS
621 #       endif
622 #   endif
623 
624 #endif
625 
626 #ifdef BOOST_NORETURN
627 #   define BOOST_LEAF_NORETURN BOOST_NORETURN
628 #else
629 #   if defined(_MSC_VER)
630 #       define BOOST_LEAF_NORETURN __declspec(noreturn)
631 #   elif defined(__GNUC__)
632 #       define BOOST_LEAF_NORETURN __attribute__ ((__noreturn__))
633 #   elif defined(__has_attribute) && defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x5130)
634 #       if __has_attribute(noreturn)
635 #           define BOOST_LEAF_NORETURN [[noreturn]]
636 #       endif
637 #   elif defined(__has_cpp_attribute)
638 #       if __has_cpp_attribute(noreturn)
639 #           define BOOST_LEAF_NORETURN [[noreturn]]
640 #       endif
641 #   endif
642 #endif
643 #if !defined(BOOST_LEAF_NORETURN)
644 #  define BOOST_LEAF_NORETURN
645 #endif
646 
647 ////////////////////////////////////////
648 
649 #ifndef BOOST_LEAF_DIAGNOSTICS
650 #   define BOOST_LEAF_DIAGNOSTICS 1
651 #endif
652 
653 #if BOOST_LEAF_DIAGNOSTICS!=0 && BOOST_LEAF_DIAGNOSTICS!=1
654 #   error BOOST_LEAF_DIAGNOSTICS must be 0 or 1.
655 #endif
656 
657 ////////////////////////////////////////
658 
659 #ifdef _MSC_VER
660 #   define BOOST_LEAF_ALWAYS_INLINE __forceinline
661 #else
662 #   define BOOST_LEAF_ALWAYS_INLINE __attribute__((always_inline)) inline
663 #endif
664 
665 ////////////////////////////////////////
666 
667 #ifndef BOOST_LEAF_NODISCARD
668 #   if __cplusplus >= 201703L
669 #       define BOOST_LEAF_NODISCARD [[nodiscard]]
670 #   else
671 #       define BOOST_LEAF_NODISCARD
672 #   endif
673 #endif
674 
675 ////////////////////////////////////////
676 
677 #ifndef BOOST_LEAF_CONSTEXPR
678 #   if __cplusplus > 201402L
679 #       define BOOST_LEAF_CONSTEXPR constexpr
680 #   else
681 #       define BOOST_LEAF_CONSTEXPR
682 #   endif
683 #endif
684 
685 ////////////////////////////////////////
686 
687 #ifndef BOOST_LEAF_ASSERT
688 #   ifdef BOOST_ASSERT
689 #       define BOOST_LEAF_ASSERT BOOST_ASSERT
690 #   else
691 #       include <cassert>
692 #       define BOOST_LEAF_ASSERT assert
693 #   endif
694 #endif
695 
696 ////////////////////////////////////////
697 
698 #ifndef BOOST_LEAF_NO_EXCEPTIONS
699 #   include <exception>
700 #   if (defined(__cpp_lib_uncaught_exceptions) && __cpp_lib_uncaught_exceptions >= 201411L) || (defined(_MSC_VER) && _MSC_VER >= 1900)
701 #       define BOOST_LEAF_STD_UNCAUGHT_EXCEPTIONS 1
702 #   else
703 #       define BOOST_LEAF_STD_UNCAUGHT_EXCEPTIONS 0
704 #   endif
705 #endif
706 
707 #endif
708 // <<< #include <boost/leaf/detail/config.hpp>
709 #line 20 "boost/leaf/detail/optional.hpp"
710 #include <utility>
711 #include <new>
712 
713 namespace boost { namespace leaf {
714 
715     namespace leaf_detail
716     {
717         template <class T>
718         class optional
719         {
720             int key_;
721             union { T value_; };
722 
723         public:
724 
725             typedef T value_type;
726 
optional()727             BOOST_LEAF_CONSTEXPR optional() noexcept:
728                 key_(0)
729             {
730             }
731 
optional(optional const & x)732             BOOST_LEAF_CONSTEXPR optional( optional const & x ):
733                 key_(x.key_)
734             {
735                 if( x.key_ )
736                     (void) new (&value_) T( x.value_ );
737             }
738 
optional(optional && x)739             BOOST_LEAF_CONSTEXPR optional( optional && x ) noexcept:
740                 key_(x.key_)
741             {
742                 if( x.key_ )
743                 {
744                     (void) new (&value_) T( std::move(x.value_) );
745                     x.reset();
746                 }
747             }
748 
optional(int key,T const & v)749             BOOST_LEAF_CONSTEXPR optional( int key, T const & v ):
750                 key_(key),
751                 value_(v)
752             {
753                 BOOST_LEAF_ASSERT(!empty());
754             }
755 
optional(int key,T && v)756             BOOST_LEAF_CONSTEXPR optional( int key, T && v ) noexcept:
757                 key_(key),
758                 value_(std::move(v))
759             {
760                 BOOST_LEAF_ASSERT(!empty());
761             }
762 
operator =(optional const & x)763             BOOST_LEAF_CONSTEXPR optional & operator=( optional const & x )
764             {
765                 reset();
766                 if( int key = x.key() )
767                 {
768                     put(key, x.value_);
769                     key_ = key;
770                 }
771                 return *this;
772             }
773 
operator =(optional && x)774             BOOST_LEAF_CONSTEXPR optional & operator=( optional && x ) noexcept
775             {
776                 reset();
777                 if( int key = x.key() )
778                 {
779                     put(key, std::move(x.value_));
780                     x.reset();
781                 }
782                 return *this;
783             }
784 
~optional()785             ~optional() noexcept
786             {
787                 reset();
788             }
789 
empty() const790             BOOST_LEAF_CONSTEXPR bool empty() const noexcept
791             {
792                 return key_==0;
793             }
794 
key() const795             BOOST_LEAF_CONSTEXPR int key() const noexcept
796             {
797                 return key_;
798             }
799 
reset()800             BOOST_LEAF_CONSTEXPR void reset() noexcept
801             {
802                 if( key_ )
803                 {
804                     value_.~T();
805                     key_=0;
806                 }
807             }
808 
put(int key,T const & v)809             BOOST_LEAF_CONSTEXPR T & put( int key, T const & v )
810             {
811                 BOOST_LEAF_ASSERT(key);
812                 reset();
813                 (void) new(&value_) T(v);
814                 key_=key;
815                 return value_;
816             }
817 
put(int key,T && v)818             BOOST_LEAF_CONSTEXPR T & put( int key, T && v ) noexcept
819             {
820                 BOOST_LEAF_ASSERT(key);
821                 reset();
822                 (void) new(&value_) T(std::move(v));
823                 key_=key;
824                 return value_;
825             }
826 
has_value(int key) const827             BOOST_LEAF_CONSTEXPR T const * has_value(int key) const noexcept
828             {
829                 BOOST_LEAF_ASSERT(key);
830                 return key_==key ? &value_ : 0;
831             }
832 
has_value(int key)833             BOOST_LEAF_CONSTEXPR T * has_value(int key) noexcept
834             {
835                 BOOST_LEAF_ASSERT(key);
836                 return key_==key ? &value_ : 0;
837             }
838 
value(int key) const839             BOOST_LEAF_CONSTEXPR T const & value(int key) const & noexcept
840             {
841                 BOOST_LEAF_ASSERT(has_value(key) != 0);
842                 return value_;
843             }
844 
value(int key)845             BOOST_LEAF_CONSTEXPR T & value(int key) & noexcept
846             {
847                 BOOST_LEAF_ASSERT(has_value(key) != 0);
848                 return value_;
849             }
850 
value(int key) const851             BOOST_LEAF_CONSTEXPR T const && value(int key) const && noexcept
852             {
853                 BOOST_LEAF_ASSERT(has_value(key) != 0);
854                 return value_;
855             }
856 
value(int key)857             BOOST_LEAF_CONSTEXPR T value(int key) && noexcept
858             {
859                 BOOST_LEAF_ASSERT(has_value(key) != 0);
860                 T tmp(std::move(value_));
861                 reset();
862                 return tmp;
863             }
864         };
865 
866     }
867 
868 } }
869 
870 #endif
871 // <<< #include <boost/leaf/detail/optional.hpp>
872 #line 20 "boost/leaf/detail/print.hpp"
873 #include <iosfwd>
874 #include <cstring>
875 
876 namespace boost { namespace leaf {
877 
878     namespace leaf_detail
879     {
880         template <int N>
check_prefix(char const * t,char const (& prefix)[N])881         BOOST_LEAF_CONSTEXPR inline char const * check_prefix( char const * t, char const (&prefix)[N] )
882         {
883             return std::strncmp(t,prefix,sizeof(prefix)-1)==0 ? t+sizeof(prefix)-1 : t;
884         }
885     }
886 
887     template <class Name>
type()888     inline char const * type()
889     {
890         using leaf_detail::check_prefix;
891     char const * t =
892 #ifdef __FUNCSIG__
893         __FUNCSIG__;
894 #else
895         __PRETTY_FUNCTION__;
896 #endif
897 #if defined(__clang__)
898         BOOST_LEAF_ASSERT(check_prefix(t,"const char *boost::leaf::type() ")==t+32);
899         return t+32;
900 #elif defined(__GNUC__)
901         BOOST_LEAF_ASSERT(check_prefix(t,"const char* boost::leaf::type() ")==t+32);
902         return t+32;
903 #else
904         char const * clang_style = check_prefix(t,"const char *boost::leaf::type() ");
905         if( clang_style!=t )
906             return clang_style;
907         char const * gcc_style = check_prefix(t,"const char* boost::leaf::type() ");
908         if( gcc_style!=t )
909             return gcc_style;
910 #endif
911         return t;
912     }
913 
914     namespace leaf_detail
915     {
916         template <class T, class E = void>
917         struct is_printable: std::false_type
918         {
919         };
920 
921         template <class T>
922         struct is_printable<T, decltype(std::declval<std::ostream&>()<<std::declval<T const &>(), void())>: std::true_type
923         {
924         };
925 
926         ////////////////////////////////////////
927 
928         template <class T, class E = void>
929         struct has_printable_member_value: std::false_type
930         {
931         };
932 
933         template <class T>
934         struct has_printable_member_value<T, decltype(std::declval<std::ostream&>()<<std::declval<T const &>().value, void())>: std::true_type
935         {
936         };
937 
938         ////////////////////////////////////////
939 
940         template <class Wrapper, bool WrapperPrintable=is_printable<Wrapper>::value, bool ValuePrintable=has_printable_member_value<Wrapper>::value>
941         struct diagnostic;
942 
943         template <class Wrapper, bool ValuePrintable>
944         struct diagnostic<Wrapper, true, ValuePrintable>
945         {
946             static constexpr bool is_invisible = false;
printboost::leaf::leaf_detail::diagnostic947             static void print( std::ostream & os, Wrapper const & x )
948             {
949                 os << x;
950             }
951         };
952 
953         template <class Wrapper>
954         struct diagnostic<Wrapper, false, true>
955         {
956             static constexpr bool is_invisible = false;
printboost::leaf::leaf_detail::diagnostic957             static void print( std::ostream & os, Wrapper const & x )
958             {
959                 os << type<Wrapper>() << ": " << x.value;
960             }
961         };
962 
963         template <class Wrapper>
964         struct diagnostic<Wrapper, false, false>
965         {
966             static constexpr bool is_invisible = false;
printboost::leaf::leaf_detail::diagnostic967             static void print( std::ostream & os, Wrapper const & )
968             {
969                 os << type<Wrapper>() << ": {Non-Printable}";
970             }
971         };
972 
973 #ifndef BOOST_LEAF_NO_EXCEPTIONS
974         template <>
975         struct diagnostic<std::exception_ptr, false, false>
976         {
977             static constexpr bool is_invisible = true;
printboost::leaf::leaf_detail::diagnostic978             BOOST_LEAF_CONSTEXPR static void print( std::ostream &, std::exception_ptr const & )
979             {
980             }
981         };
982 #endif
983     }
984 
985 } }
986 
987 #endif
988 // <<< #include <boost/leaf/detail/print.hpp>
989 #line 21 "boost/leaf/error.hpp"
990 #include <system_error>
991 #include <type_traits>
992 #include <memory>
993 #include <string>
994 
995 #if BOOST_LEAF_DIAGNOSTICS
996 #   include <sstream>
997 #   include <set>
998 #endif
999 
1000 #define BOOST_LEAF_TOKEN_PASTE(x, y) x ## y
1001 #define BOOST_LEAF_TOKEN_PASTE2(x, y) BOOST_LEAF_TOKEN_PASTE(x, y)
1002 #define BOOST_LEAF_TMP BOOST_LEAF_TOKEN_PASTE2(boost_leaf_tmp_, __LINE__)
1003 
1004 #define BOOST_LEAF_ASSIGN(v,r)\
1005     static_assert(::boost::leaf::is_result_type<typename std::decay<decltype(r)>::type>::value, "The BOOST_LEAF_ASSIGN macro requires a result type as the second argument");\
1006     auto && BOOST_LEAF_TMP = r;\
1007     if( !BOOST_LEAF_TMP )\
1008         return BOOST_LEAF_TMP.error();\
1009     v = std::forward<decltype(BOOST_LEAF_TMP)>(BOOST_LEAF_TMP).value()
1010 
1011 #define BOOST_LEAF_AUTO(v, r)\
1012     BOOST_LEAF_ASSIGN(auto v, r)
1013 
1014 #define BOOST_LEAF_CHECK(r)\
1015     {\
1016         static_assert(::boost::leaf::is_result_type<typename std::decay<decltype(r)>::type>::value, "BOOST_LEAF_CHECK requires a result type");\
1017         auto && BOOST_LEAF_TMP = r;\
1018         if( !BOOST_LEAF_TMP )\
1019             return BOOST_LEAF_TMP.error();\
1020     }
1021 
1022 #define BOOST_LEAF_NEW_ERROR ::leaf::leaf_detail::inject_loc{__FILE__,__LINE__,__FUNCTION__}+::boost::leaf::new_error
1023 
1024 namespace boost { namespace leaf {
1025 
1026     namespace leaf_detail
1027     {
1028         struct inject_loc
1029         {
1030             char const * const file;
1031             int const line;
1032             char const * const fn;
1033 
1034             template <class T>
operator +(inject_loc loc,T && x)1035             friend T operator+( inject_loc loc, T && x ) noexcept
1036             {
1037                 x.load_source_location_(loc.file, loc.line, loc.fn);
1038                 return std::move(x);
1039             }
1040         };
1041     }
1042 
1043 } }
1044 
1045 ////////////////////////////////////////
1046 
1047 #ifdef BOOST_LEAF_NO_EXCEPTIONS
1048 
1049 namespace boost
1050 {
1051     BOOST_LEAF_NORETURN void throw_exception( std::exception const & ); // user defined
1052 }
1053 
1054 namespace boost { namespace leaf {
1055 
1056     template <class T>
throw_exception(T const & e)1057     BOOST_LEAF_NORETURN void throw_exception( T const & e )
1058     {
1059         ::boost::throw_exception(e);
1060     }
1061 
1062 } }
1063 
1064 #else
1065 
1066 namespace boost { namespace leaf {
1067 
1068     template <class T>
throw_exception(T const & e)1069     BOOST_LEAF_NORETURN void throw_exception( T const & e )
1070     {
1071         throw e;
1072     }
1073 
1074 } }
1075 
1076 #endif
1077 
1078 ////////////////////////////////////////
1079 
1080 #ifdef BOOST_LEAF_NO_THREADS
1081 
1082 #   define BOOST_LEAF_THREAD_LOCAL
1083     namespace boost { namespace leaf {
1084         namespace leaf_detail
1085         {
1086             using atomic_unsigned_int = unsigned int;
1087         }
1088     } }
1089 
1090 #else
1091 
1092 #   include <atomic>
1093 #   include <thread>
1094 #   define BOOST_LEAF_THREAD_LOCAL thread_local
1095     namespace boost { namespace leaf {
1096         namespace leaf_detail
1097         {
1098             using atomic_unsigned_int = std::atomic<unsigned int>;
1099         }
1100     } }
1101 
1102 #endif
1103 
1104 ////////////////////////////////////////
1105 
1106 namespace boost { namespace leaf {
1107 
1108 #if BOOST_LEAF_DIAGNOSTICS
1109 
1110     namespace leaf_detail
1111     {
1112         class e_unexpected_count
1113         {
1114         public:
1115 
1116             char const * (*first_type)();
1117             int count;
1118 
e_unexpected_count(char const * (* first_type)())1119             BOOST_LEAF_CONSTEXPR explicit e_unexpected_count(char const * (*first_type)()) noexcept:
1120                 first_type(first_type),
1121                 count(1)
1122             {
1123             }
1124 
1125             template <class CharT, class Traits>
print(std::basic_ostream<CharT,Traits> & os) const1126             void print( std::basic_ostream<CharT, Traits> & os ) const
1127             {
1128                 BOOST_LEAF_ASSERT(first_type != 0);
1129                 BOOST_LEAF_ASSERT(count>0);
1130                 os << "Detected ";
1131                 if( count==1 )
1132                     os << "1 attempt to communicate an unexpected error object";
1133                 else
1134                     os << count << " attempts to communicate unexpected error objects, the first one";
1135                 (os << " of type " << first_type() << '\n').flush();
1136             }
1137         };
1138 
1139         template <>
1140         struct diagnostic<e_unexpected_count, false, false>
1141         {
1142             static constexpr bool is_invisible = true;
printboost::leaf::leaf_detail::diagnostic1143             BOOST_LEAF_CONSTEXPR static void print(std::ostream &, e_unexpected_count const &) noexcept { }
1144         };
1145 
1146         class e_unexpected_info
1147         {
1148             std::string s_;
1149             std::set<char const *(*)()> already_;
1150 
1151         public:
1152 
e_unexpected_info()1153             e_unexpected_info() noexcept
1154             {
1155             }
1156 
1157             template <class E>
add(E && e)1158             void add(E && e)
1159             {
1160                 if( !diagnostic<E>::is_invisible && already_.insert(&type<E>).second  )
1161                 {
1162                     std::stringstream s;
1163                     diagnostic<E>::print(s,e);
1164                     (s << '\n').flush();
1165                     s_ += s.str();
1166                 }
1167             }
1168 
1169             template <class CharT, class Traits>
print(std::basic_ostream<CharT,Traits> & os) const1170             void print( std::basic_ostream<CharT, Traits> & os ) const
1171             {
1172                 os << "Unhandled error objects:\n" << s_;
1173             }
1174         };
1175 
1176         template <>
1177         struct diagnostic<e_unexpected_info, false, false>
1178         {
1179             static constexpr bool is_invisible = true;
printboost::leaf::leaf_detail::diagnostic1180             BOOST_LEAF_CONSTEXPR static void print(std::ostream &, e_unexpected_info const &) noexcept { }
1181         };
1182 
1183         template <class=void>
1184         struct tl_unexpected_enabled
1185         {
1186             static BOOST_LEAF_THREAD_LOCAL int counter;
1187         };
1188 
1189         template <class T>
1190         BOOST_LEAF_THREAD_LOCAL int tl_unexpected_enabled<T>::counter;
1191     }
1192 
1193 #endif
1194 
1195 } }
1196 
1197 ////////////////////////////////////////
1198 
1199 namespace boost { namespace leaf {
1200 
1201     struct e_source_location
1202     {
1203         char const * const file;
1204         int const line;
1205         char const * const function;
1206 
1207         template <class CharT, class Traits>
operator <<(std::basic_ostream<CharT,Traits> & os,e_source_location const & x)1208         friend std::basic_ostream<CharT, Traits> & operator<<( std::basic_ostream<CharT, Traits> & os, e_source_location const & x )
1209         {
1210             return os << leaf::type<e_source_location>() << ": " << x.file << '(' << x.line << ") in function " << x.function;
1211         }
1212     };
1213 
1214     ////////////////////////////////////////
1215 
1216     namespace leaf_detail
1217     {
1218         template <class E>
1219         class slot;
1220 
1221         template <class E>
1222         struct tl_slot_ptr
1223         {
1224             static BOOST_LEAF_THREAD_LOCAL slot<E> * p;
1225         };
1226 
1227         template <class E>
1228         BOOST_LEAF_THREAD_LOCAL slot<E> * tl_slot_ptr<E>::p;
1229 
1230         template <class E>
1231         class slot:
1232             optional<E>
1233         {
1234             slot( slot const & ) = delete;
1235             slot & operator=( slot const & ) = delete;
1236 
1237             using impl = optional<E>;
1238             slot<E> * * top_;
1239             slot<E> * prev_;
1240 
1241         public:
1242 
slot()1243             BOOST_LEAF_CONSTEXPR slot() noexcept:
1244                 top_(0)
1245             {
1246             }
1247 
slot(slot && x)1248             BOOST_LEAF_CONSTEXPR slot( slot && x ) noexcept:
1249                 optional<E>(std::move(x)),
1250                 top_(0)
1251             {
1252                 BOOST_LEAF_ASSERT(x.top_==0);
1253             }
1254 
activate()1255             BOOST_LEAF_CONSTEXPR void activate() noexcept
1256             {
1257                 BOOST_LEAF_ASSERT(top_==0 || *top_!=this);
1258                 top_ = &tl_slot_ptr<E>::p;
1259                 prev_ = *top_;
1260                 *top_ = this;
1261             }
1262 
deactivate()1263             BOOST_LEAF_CONSTEXPR void deactivate() noexcept
1264             {
1265                 BOOST_LEAF_ASSERT(top_!=0 && *top_==this);
1266                 *top_ = prev_;
1267             }
1268 
1269             BOOST_LEAF_CONSTEXPR void propagate() noexcept;
1270 
1271             template <class CharT, class Traits>
print(std::basic_ostream<CharT,Traits> & os,int key_to_print) const1272             void print( std::basic_ostream<CharT, Traits> & os, int key_to_print ) const
1273             {
1274                 if( !diagnostic<E>::is_invisible )
1275                     if( int k = this->key() )
1276                     {
1277                         if( key_to_print )
1278                         {
1279                             if( key_to_print!=k )
1280                                 return;
1281                         }
1282                         else
1283                             os << '[' << k << ']';
1284                         diagnostic<E>::print(os, value(k));
1285                         (os << '\n').flush();
1286                     }
1287             }
1288 
1289             using impl::put;
1290             using impl::has_value;
1291             using impl::value;
1292         };
1293 
1294 #if BOOST_LEAF_DIAGNOSTICS
1295 
1296         template <class E>
load_unexpected_count(int err_id)1297         BOOST_LEAF_CONSTEXPR inline void load_unexpected_count( int err_id ) noexcept
1298         {
1299             if( slot<e_unexpected_count> * sl = tl_slot_ptr<e_unexpected_count>::p )
1300                 if( e_unexpected_count * unx = sl->has_value(err_id) )
1301                     ++unx->count;
1302                 else
1303                     sl->put(err_id, e_unexpected_count(&type<E>));
1304         }
1305 
1306         template <class E>
load_unexpected_info(int err_id,E && e)1307         BOOST_LEAF_CONSTEXPR inline void load_unexpected_info( int err_id, E && e ) noexcept
1308         {
1309             if( slot<e_unexpected_info> * sl = tl_slot_ptr<e_unexpected_info>::p )
1310                 if( e_unexpected_info * unx = sl->has_value(err_id) )
1311                     unx->add(std::forward<E>(e));
1312                 else
1313                     sl->put(err_id, e_unexpected_info()).add(std::forward<E>(e));
1314         }
1315 
1316         template <class E>
load_unexpected(int err_id,E && e)1317         BOOST_LEAF_CONSTEXPR inline void load_unexpected( int err_id, E && e  ) noexcept
1318         {
1319             load_unexpected_count<E>(err_id);
1320             load_unexpected_info(err_id, std::forward<E>(e));
1321         }
1322 
1323 #endif
1324 
1325         template <class E>
propagate()1326         BOOST_LEAF_CONSTEXPR inline void slot<E>::propagate() noexcept
1327         {
1328             BOOST_LEAF_ASSERT(top_!=0 && (*top_==prev_ || *top_==this));
1329             if( prev_ )
1330             {
1331                 impl & that_ = *prev_;
1332                 if( that_.empty() )
1333                 {
1334                     impl & this_ = *this;
1335                     that_ = std::move(this_);
1336                 }
1337             }
1338 #if BOOST_LEAF_DIAGNOSTICS
1339             else
1340             {
1341                 int c = tl_unexpected_enabled<>::counter;
1342                 BOOST_LEAF_ASSERT(c>=0);
1343                 if( c )
1344                     if( int err_id = impl::key() )
1345                         load_unexpected(err_id, std::move(*this).value(err_id));
1346             }
1347 #endif
1348         }
1349 
1350         template <class E>
load_slot(int err_id,E && e)1351         BOOST_LEAF_CONSTEXPR inline int load_slot( int err_id, E && e ) noexcept
1352         {
1353             static_assert(!std::is_pointer<E>::value, "Error objects of pointer types are not allowed");
1354             using T = typename std::decay<E>::type;
1355             BOOST_LEAF_ASSERT((err_id&3)==1);
1356             if( slot<T> * p = tl_slot_ptr<T>::p )
1357                 (void) p->put(err_id, std::forward<E>(e));
1358 #if BOOST_LEAF_DIAGNOSTICS
1359             else
1360             {
1361                 int c = tl_unexpected_enabled<>::counter;
1362                 BOOST_LEAF_ASSERT(c>=0);
1363                 if( c )
1364                     load_unexpected(err_id, std::forward<E>(e));
1365             }
1366 #endif
1367             return 0;
1368         }
1369 
1370         template <class F>
accumulate_slot(int err_id,F && f)1371         BOOST_LEAF_CONSTEXPR inline int accumulate_slot( int err_id, F && f ) noexcept
1372         {
1373             static_assert(function_traits<F>::arity==1, "Lambdas passed to accumulate must take a single e-type argument by reference");
1374             using E = typename std::decay<fn_arg_type<F,0>>::type;
1375             static_assert(!std::is_pointer<E>::value, "Error objects of pointer types are not allowed");
1376             BOOST_LEAF_ASSERT((err_id&3)==1);
1377             if( auto sl = tl_slot_ptr<E>::p )
1378                 if( auto v = sl->has_value(err_id) )
1379                     (void) std::forward<F>(f)(*v);
1380                 else
1381                     (void) std::forward<F>(f)(sl->put(err_id,E()));
1382             return 0;
1383         }
1384     }
1385 
1386     ////////////////////////////////////////
1387 
1388     namespace leaf_detail
1389     {
1390         template <class=void>
1391         struct id_factory
1392         {
1393             static atomic_unsigned_int counter;
1394             static BOOST_LEAF_THREAD_LOCAL unsigned current_id;
1395 
generate_next_idboost::leaf::leaf_detail::id_factory1396             BOOST_LEAF_CONSTEXPR static unsigned generate_next_id() noexcept
1397             {
1398                 auto id = (counter+=4);
1399                 BOOST_LEAF_ASSERT((id&3)==1);
1400                 return id;
1401             }
1402         };
1403 
1404         template <class T>
1405         atomic_unsigned_int id_factory<T>::counter(-3);
1406 
1407         template <class T>
1408         BOOST_LEAF_THREAD_LOCAL unsigned id_factory<T>::current_id(0);
1409 
current_id()1410         inline int current_id() noexcept
1411         {
1412             auto id = id_factory<>::current_id;
1413             BOOST_LEAF_ASSERT(id==0 || (id&3)==1);
1414             return id;
1415         }
1416 
new_id()1417         inline int new_id() noexcept
1418         {
1419             auto id = id_factory<>::generate_next_id();
1420             return id_factory<>::current_id = id;
1421         }
1422     }
1423 
1424     ////////////////////////////////////////
1425 
1426     namespace leaf_detail
1427     {
1428         template <class T, int Arity = function_traits<T>::arity>
1429         struct load_item
1430         {
1431             static_assert(Arity==0 || Arity==1, "If a functions is passed to new_error or load, it must take zero or one argument");
1432         };
1433 
1434         template <class E>
1435         struct load_item<E, -1>
1436         {
loadboost::leaf::leaf_detail::load_item1437             BOOST_LEAF_CONSTEXPR static int load( int err_id, E && e ) noexcept
1438             {
1439                 return load_slot(err_id, std::forward<E>(e));
1440             }
1441         };
1442 
1443         template <class F>
1444         struct load_item<F, 0>
1445         {
loadboost::leaf::leaf_detail::load_item1446             BOOST_LEAF_CONSTEXPR static int load( int err_id, F && f ) noexcept
1447             {
1448                 return load_slot(err_id, std::forward<F>(f)());
1449             }
1450         };
1451 
1452         template <class F>
1453         struct load_item<F, 1>
1454         {
loadboost::leaf::leaf_detail::load_item1455             BOOST_LEAF_CONSTEXPR static int load( int err_id, F && f ) noexcept
1456             {
1457                 return accumulate_slot(err_id, std::forward<F>(f));
1458             }
1459         };
1460     }
1461 
1462     ////////////////////////////////////////
1463 
1464     namespace leaf_detail
1465     {
1466         class leaf_category final: public std::error_category
1467         {
equivalent(int,std::error_condition const &) const1468             bool equivalent( int,  std::error_condition const & ) const noexcept final override { return false; }
equivalent(std::error_code const &,int) const1469             bool equivalent( std::error_code const &, int ) const noexcept final override { return false; }
name() const1470             char const * name() const noexcept final override { return "LEAF error"; }
message(int condition) const1471             std::string message( int condition ) const final override { return name(); }
1472         public:
~leaf_category()1473             ~leaf_category() noexcept final override { }
1474         };
1475 
1476         template <class=void>
1477         struct get_error_category
1478         {
1479             static leaf_category cat;
1480         };
1481 
1482         template <class T>
1483         leaf_category get_error_category<T>::cat;
1484 
import_error_code(std::error_code const & ec)1485         inline int import_error_code( std::error_code const & ec ) noexcept
1486         {
1487             if( int err_id = ec.value() )
1488             {
1489                 std::error_category const & cat = get_error_category<>::cat;
1490                 if( &ec.category()==&cat )
1491                 {
1492                     BOOST_LEAF_ASSERT((err_id&3)==1);
1493                     return (err_id&~3)|1;
1494                 }
1495                 else
1496                 {
1497                     err_id = new_id();
1498                     (void) load_slot(err_id, ec);
1499                     return (err_id&~3)|1;
1500                 }
1501             }
1502             else
1503                 return 0;
1504         }
1505     }
1506 
is_error_id(std::error_code const & ec)1507     inline bool is_error_id( std::error_code const & ec ) noexcept
1508     {
1509         bool res = (&ec.category() == &leaf_detail::get_error_category<>::cat);
1510         BOOST_LEAF_ASSERT(!res || !ec.value() || ((ec.value()&3)==1));
1511         return res;
1512     }
1513 
1514     ////////////////////////////////////////
1515 
1516     class error_id;
1517 
1518     namespace leaf_detail
1519     {
1520         BOOST_LEAF_CONSTEXPR error_id make_error_id(int) noexcept;
1521     }
1522 
1523     class error_id
1524     {
1525         friend error_id BOOST_LEAF_CONSTEXPR leaf_detail::make_error_id(int) noexcept;
1526 
1527         int value_;
1528 
error_id(int value)1529         BOOST_LEAF_CONSTEXPR explicit error_id( int value ) noexcept:
1530             value_(value)
1531         {
1532             BOOST_LEAF_ASSERT(value_==0 || ((value_&3)==1));
1533         }
1534 
1535     public:
1536 
error_id()1537         BOOST_LEAF_CONSTEXPR error_id() noexcept:
1538             value_(0)
1539         {
1540         }
1541 
error_id(std::error_code const & ec)1542         error_id( std::error_code const & ec ) noexcept:
1543             value_(leaf_detail::import_error_code(ec))
1544         {
1545             BOOST_LEAF_ASSERT(!value_ || ((value_&3)==1));
1546         }
1547 
1548         template <class Enum>
error_id(Enum e,typename std::enable_if<std::is_error_code_enum<Enum>::value,Enum>::type * =0)1549         error_id( Enum e, typename std::enable_if<std::is_error_code_enum<Enum>::value, Enum>::type * = 0 ) noexcept:
1550             value_(leaf_detail::import_error_code(e))
1551         {
1552         }
1553 
load() const1554         BOOST_LEAF_CONSTEXPR error_id load() const noexcept
1555         {
1556             return *this;
1557         }
1558 
1559         template <class... Item>
load(Item &&...item) const1560         BOOST_LEAF_CONSTEXPR error_id load( Item && ... item ) const noexcept
1561         {
1562             if( int err_id = value() )
1563             {
1564                 int const unused[ ] = { 42, leaf_detail::load_item<Item>::load(err_id, std::forward<Item>(item))... };
1565                 (void) unused;
1566             }
1567             return *this;
1568         }
1569 
to_error_code() const1570         std::error_code to_error_code() const noexcept
1571         {
1572             return std::error_code(value_, leaf_detail::get_error_category<>::cat);
1573         }
1574 
value() const1575         BOOST_LEAF_CONSTEXPR int value() const noexcept
1576         {
1577             if( int v = value_ )
1578             {
1579                 BOOST_LEAF_ASSERT((v&3)==1);
1580                 return (v&~3)|1;
1581             }
1582             else
1583                 return 0;
1584         }
1585 
operator bool() const1586         BOOST_LEAF_CONSTEXPR explicit operator bool() const noexcept
1587         {
1588             return value_ != 0;
1589         }
1590 
operator ==(error_id a,error_id b)1591         BOOST_LEAF_CONSTEXPR friend bool operator==( error_id a, error_id b ) noexcept
1592         {
1593             return a.value_ == b.value_;
1594         }
1595 
operator !=(error_id a,error_id b)1596         BOOST_LEAF_CONSTEXPR friend bool operator!=( error_id a, error_id b ) noexcept
1597         {
1598             return !(a == b);
1599         }
1600 
operator <(error_id a,error_id b)1601         BOOST_LEAF_CONSTEXPR friend bool operator<( error_id a, error_id b ) noexcept
1602         {
1603             return a.value_ < b.value_;
1604         }
1605 
1606         template <class CharT, class Traits>
operator <<(std::basic_ostream<CharT,Traits> & os,error_id x)1607         friend std::basic_ostream<CharT, Traits> & operator<<( std::basic_ostream<CharT, Traits> & os, error_id x )
1608         {
1609             return os << x.value_;
1610         }
1611 
load_source_location_(char const * file,int line,char const * function) const1612         BOOST_LEAF_CONSTEXPR void load_source_location_( char const * file, int line, char const * function ) const noexcept
1613         {
1614             BOOST_LEAF_ASSERT(file&&*file);
1615             BOOST_LEAF_ASSERT(line>0);
1616             BOOST_LEAF_ASSERT(function&&*function);
1617             BOOST_LEAF_ASSERT(value_);
1618             (void) load(e_source_location {file,line,function});
1619         }
1620     };
1621 
1622     namespace leaf_detail
1623     {
make_error_id(int err_id)1624         BOOST_LEAF_CONSTEXPR inline error_id make_error_id( int err_id ) noexcept
1625         {
1626             BOOST_LEAF_ASSERT(err_id==0 || (err_id&3)==1);
1627             return error_id((err_id&~3)|1);
1628         }
1629     }
1630 
new_error()1631     inline error_id new_error() noexcept
1632     {
1633         return leaf_detail::make_error_id(leaf_detail::new_id());
1634     }
1635 
1636     template <class... Item>
new_error(Item &&...item)1637     inline error_id new_error( Item && ... item ) noexcept
1638     {
1639         return leaf_detail::make_error_id(leaf_detail::new_id()).load(std::forward<Item>(item)...);
1640     }
1641 
current_error()1642     inline error_id current_error() noexcept
1643     {
1644         return leaf_detail::make_error_id(leaf_detail::current_id());
1645     }
1646 
1647     ////////////////////////////////////////////
1648 
1649     class polymorphic_context
1650     {
1651     protected:
1652 
1653         polymorphic_context() noexcept = default;
1654         ~polymorphic_context() noexcept = default;
1655 
1656     public:
1657 
1658         virtual error_id propagate_captured_errors() noexcept = 0;
1659         virtual void activate() noexcept = 0;
1660         virtual void deactivate() noexcept = 0;
1661         virtual void propagate() noexcept = 0;
1662         virtual bool is_active() const noexcept = 0;
1663         virtual void print( std::ostream & ) const = 0;
1664         error_id captured_id_;
1665     };
1666 
1667     using context_ptr = std::shared_ptr<polymorphic_context>;
1668 
1669     ////////////////////////////////////////////
1670 
1671     template <class Ctx>
1672     class context_activator
1673     {
1674         context_activator( context_activator const & ) = delete;
1675         context_activator & operator=( context_activator const & ) = delete;
1676 
1677 #if !defined(BOOST_LEAF_NO_EXCEPTIONS) && BOOST_LEAF_STD_UNCAUGHT_EXCEPTIONS
1678         int const uncaught_exceptions_;
1679 #endif
1680         Ctx * ctx_;
1681 
1682     public:
1683 
context_activator(Ctx & ctx)1684         explicit BOOST_LEAF_CONSTEXPR BOOST_LEAF_ALWAYS_INLINE context_activator(Ctx & ctx) noexcept:
1685 #if !defined(BOOST_LEAF_NO_EXCEPTIONS) && BOOST_LEAF_STD_UNCAUGHT_EXCEPTIONS
1686             uncaught_exceptions_(std::uncaught_exceptions()),
1687 #endif
1688             ctx_(ctx.is_active() ? 0 : &ctx)
1689         {
1690             if( ctx_ )
1691                 ctx_->activate();
1692         }
1693 
context_activator(context_activator && x)1694         BOOST_LEAF_CONSTEXPR BOOST_LEAF_ALWAYS_INLINE context_activator( context_activator && x ) noexcept:
1695 #if !defined(BOOST_LEAF_NO_EXCEPTIONS) && BOOST_LEAF_STD_UNCAUGHT_EXCEPTIONS
1696             uncaught_exceptions_(x.uncaught_exceptions_),
1697 #endif
1698             ctx_(x.ctx_)
1699         {
1700             x.ctx_ = 0;
1701         }
1702 
~context_activator()1703         BOOST_LEAF_ALWAYS_INLINE ~context_activator() noexcept
1704         {
1705             if( !ctx_ )
1706                 return;
1707             if( ctx_->is_active() )
1708                 ctx_->deactivate();
1709 #ifndef BOOST_LEAF_NO_EXCEPTIONS
1710 #   if BOOST_LEAF_STD_UNCAUGHT_EXCEPTIONS
1711             if( std::uncaught_exceptions() > uncaught_exceptions_ )
1712 #   else
1713             if( std::uncaught_exception() )
1714 #   endif
1715                 ctx_->propagate();
1716 #endif
1717         }
1718     };
1719 
1720     template <class Ctx>
activate_context(Ctx & ctx)1721     BOOST_LEAF_CONSTEXPR BOOST_LEAF_ALWAYS_INLINE context_activator<Ctx> activate_context(Ctx & ctx) noexcept
1722     {
1723         return context_activator<Ctx>(ctx);
1724     }
1725 
1726     ////////////////////////////////////////////
1727 
1728     template <class R>
1729     struct is_result_type: std::false_type
1730     {
1731     };
1732 
1733     template <class R>
1734     struct is_result_type<R const>: is_result_type<R>
1735     {
1736     };
1737 
1738 } }
1739 
1740 #undef BOOST_LEAF_THREAD_LOCAL
1741 
1742 #endif
1743 // <<< #include <boost/leaf/error.hpp>
1744 #line 20 "boost/leaf/exception.hpp"
1745 #include <exception>
1746 
1747 #define BOOST_LEAF_EXCEPTION ::boost::leaf::leaf_detail::inject_loc{__FILE__,__LINE__,__FUNCTION__}+::boost::leaf::exception
1748 #define BOOST_LEAF_THROW_EXCEPTION ::boost::leaf::leaf_detail::throw_with_loc{__FILE__,__LINE__,__FUNCTION__}+::boost::leaf::exception
1749 
1750 ////////////////////////////////////////
1751 
1752 namespace boost { namespace leaf {
1753 
1754     namespace leaf_detail
1755     {
1756         struct throw_with_loc
1757         {
1758             char const * const file;
1759             int const line;
1760             char const * const fn;
1761 
1762             template <class Ex>
operator +(throw_with_loc loc,Ex const & ex)1763             [[noreturn]] friend void operator+( throw_with_loc loc, Ex const & ex )
1764             {
1765                 ex.load_source_location_(loc.file, loc.line, loc.fn);
1766                 ::boost::leaf::throw_exception(ex);
1767             }
1768         };
1769     }
1770 
1771 } }
1772 
1773 ////////////////////////////////////////
1774 
1775 namespace boost { namespace leaf {
1776 
1777     namespace leaf_detail
1778     {
enforce_std_exception(std::exception const &)1779         inline void enforce_std_exception( std::exception const & ) noexcept { }
1780 
1781         class exception_base
1782         {
1783             std::shared_ptr<void const> auto_id_bump_;
1784         public:
1785 
1786             virtual error_id get_error_id() const noexcept = 0;
1787 
1788         protected:
1789 
exception_base()1790             exception_base():
1791                 auto_id_bump_(0, [](void const *) { (void) new_id(); })
1792             {
1793             }
1794 
~exception_base()1795             ~exception_base() noexcept { }
1796         };
1797 
1798         template <class Ex>
1799         class exception:
1800             public Ex,
1801             public exception_base,
1802             public error_id
1803         {
get_error_id() const1804             error_id get_error_id() const noexcept final override
1805             {
1806                 return *this;
1807             }
1808 
1809         public:
1810 
1811             exception( exception const & ) = default;
1812             exception( exception && ) = default;
1813 
exception(error_id id,Ex && ex)1814             BOOST_LEAF_CONSTEXPR exception( error_id id, Ex && ex ) noexcept:
1815                 Ex(std::move(ex)),
1816                 error_id(id)
1817             {
1818                 enforce_std_exception(*this);
1819             }
1820 
exception(error_id id)1821             explicit BOOST_LEAF_CONSTEXPR exception( error_id id ) noexcept:
1822                 error_id(id)
1823             {
1824                 enforce_std_exception(*this);
1825             }
1826         };
1827 
1828         template <class... T>
1829         struct at_least_one_derives_from_std_exception;
1830 
1831         template <>
1832         struct at_least_one_derives_from_std_exception<>: std::false_type { };
1833 
1834         template <class T, class... Rest>
1835         struct at_least_one_derives_from_std_exception<T, Rest...>
1836         {
1837             constexpr static const bool value = std::is_base_of<std::exception,T>::value || at_least_one_derives_from_std_exception<Rest...>::value;
1838         };
1839     }
1840 
1841     template <class Ex, class... E>
1842     inline
1843     typename std::enable_if<std::is_base_of<std::exception,Ex>::value, leaf_detail::exception<Ex>>::type
exception(Ex && ex,E &&...e)1844     exception( Ex && ex, E && ... e ) noexcept
1845     {
1846         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");
1847         auto id = leaf::new_error(std::forward<E>(e)...);
1848         return leaf_detail::exception<Ex>(id, std::forward<Ex>(ex));
1849     }
1850 
1851     template <class E1, class... E>
1852     inline
1853     typename std::enable_if<!std::is_base_of<std::exception,E1>::value, leaf_detail::exception<std::exception>>::type
exception(E1 && car,E &&...cdr)1854     exception( E1 && car, E && ... cdr ) noexcept
1855     {
1856         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");
1857         auto id = leaf::new_error(std::forward<E1>(car), std::forward<E>(cdr)...);
1858         return leaf_detail::exception<std::exception>(id);
1859     }
1860 
exception()1861     inline leaf_detail::exception<std::exception> exception() noexcept
1862     {
1863         return leaf_detail::exception<std::exception>(leaf::new_error());
1864     }
1865 
1866 } }
1867 
1868 #endif
1869 // <<< #include <boost/leaf/exception.hpp>
1870 #line 20 "boost/leaf/capture.hpp"
1871 // >>> #include <boost/leaf/on_error.hpp>
1872 #line 1 "boost/leaf/on_error.hpp"
1873 #ifndef BOOST_LEAF_ON_ERROR_HPP_INCLUDED
1874 #define BOOST_LEAF_ON_ERROR_HPP_INCLUDED
1875 
1876 // Copyright (c) 2018-2020 Emil Dotchevski and Reverge Studios, Inc.
1877 
1878 // Distributed under the Boost Software License, Version 1.0. (See accompanying
1879 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
1880 
1881 #ifndef BOOST_LEAF_ENABLE_WARNINGS
1882 #   if defined(__clang__)
1883 #       pragma clang system_header
1884 #   elif (__GNUC__*100+__GNUC_MINOR__>301)
1885 #       pragma GCC system_header
1886 #   elif defined(_MSC_VER)
1887 #       pragma warning(push,1)
1888 #   endif
1889 #endif
1890 
1891 
1892 namespace boost { namespace leaf {
1893 
1894     class error_monitor
1895     {
1896 #if !defined(BOOST_LEAF_NO_EXCEPTIONS) && BOOST_LEAF_STD_UNCAUGHT_EXCEPTIONS
1897         int const uncaught_exceptions_;
1898 #endif
1899         int const err_id_;
1900 
1901     public:
1902 
error_monitor()1903         error_monitor() noexcept:
1904 #if !defined(BOOST_LEAF_NO_EXCEPTIONS) && BOOST_LEAF_STD_UNCAUGHT_EXCEPTIONS
1905             uncaught_exceptions_(std::uncaught_exceptions()),
1906 #endif
1907             err_id_(leaf_detail::current_id())
1908         {
1909         }
1910 
check_id() const1911         int check_id() const noexcept
1912         {
1913             int err_id = leaf_detail::current_id();
1914             if( err_id != err_id_ )
1915                 return err_id;
1916             else
1917             {
1918 #ifndef BOOST_LEAF_NO_EXCEPTIONS
1919 #   if BOOST_LEAF_STD_UNCAUGHT_EXCEPTIONS
1920                 if( std::uncaught_exceptions() > uncaught_exceptions_ )
1921 #   else
1922                 if( std::uncaught_exception() )
1923 #   endif
1924                     return leaf_detail::new_id();
1925 #endif
1926                 return 0;
1927             }
1928         }
1929 
get_id() const1930         int get_id() const noexcept
1931         {
1932             int err_id = leaf_detail::current_id();
1933             if( err_id != err_id_ )
1934                 return err_id;
1935             else
1936                 return leaf_detail::new_id();
1937         }
1938 
check() const1939         error_id check() const noexcept
1940         {
1941             return leaf_detail::make_error_id(check_id());
1942         }
1943 
assigned_error_id() const1944         error_id assigned_error_id() const noexcept
1945         {
1946             return leaf_detail::make_error_id(get_id());
1947         }
1948     };
1949 
1950     ////////////////////////////////////////////
1951 
1952     namespace leaf_detail
1953     {
1954         template <int I, class Tuple>
1955         struct tuple_for_each_preload
1956         {
triggerboost::leaf::leaf_detail::tuple_for_each_preload1957             BOOST_LEAF_CONSTEXPR static void trigger( Tuple & tup, int err_id ) noexcept
1958             {
1959                 BOOST_LEAF_ASSERT((err_id&3)==1);
1960                 tuple_for_each_preload<I-1,Tuple>::trigger(tup,err_id);
1961                 std::get<I-1>(tup).trigger(err_id);
1962             }
1963         };
1964 
1965         template <class Tuple>
1966         struct tuple_for_each_preload<0, Tuple>
1967         {
triggerboost::leaf::leaf_detail::tuple_for_each_preload1968             BOOST_LEAF_CONSTEXPR static void trigger( Tuple const &, int ) noexcept { }
1969         };
1970 
1971         template <class E>
1972         class preloaded_item
1973         {
1974             using decay_E = typename std::decay<E>::type;
1975             slot<decay_E> * s_;
1976             decay_E e_;
1977 
1978         public:
1979 
preloaded_item(E && e)1980             BOOST_LEAF_CONSTEXPR preloaded_item( E && e ):
1981                 s_(tl_slot_ptr<decay_E>::p),
1982                 e_(std::forward<E>(e))
1983             {
1984             }
1985 
trigger(int err_id)1986             BOOST_LEAF_CONSTEXPR void trigger( int err_id ) noexcept
1987             {
1988                 BOOST_LEAF_ASSERT((err_id&3)==1);
1989                 if( s_ )
1990                 {
1991                     if( !s_->has_value(err_id) )
1992                         s_->put(err_id, std::move(e_));
1993                 }
1994 #if BOOST_LEAF_DIAGNOSTICS
1995                 else
1996                 {
1997                     int c = tl_unexpected_enabled<>::counter;
1998                     BOOST_LEAF_ASSERT(c>=0);
1999                     if( c )
2000                         load_unexpected(err_id, std::move(e_));
2001                 }
2002 #endif
2003             }
2004         };
2005 
2006         template <class F>
2007         class deferred_item
2008         {
2009             using E = decltype(std::declval<F>()());
2010             slot<E> * s_;
2011             F f_;
2012 
2013         public:
2014 
deferred_item(F && f)2015             BOOST_LEAF_CONSTEXPR deferred_item( F && f ) noexcept:
2016                 s_(tl_slot_ptr<E>::p),
2017                 f_(std::forward<F>(f))
2018             {
2019             }
2020 
trigger(int err_id)2021             BOOST_LEAF_CONSTEXPR void trigger( int err_id ) noexcept
2022             {
2023                 BOOST_LEAF_ASSERT((err_id&3)==1);
2024                 if( s_ )
2025                 {
2026                     if( !s_->has_value(err_id) )
2027                         s_->put(err_id, f_());
2028                 }
2029 #if BOOST_LEAF_DIAGNOSTICS
2030                 else
2031                 {
2032                     int c = tl_unexpected_enabled<>::counter;
2033                     BOOST_LEAF_ASSERT(c>=0);
2034                     if( c )
2035                         load_unexpected(err_id, std::forward<E>(f_()));
2036                 }
2037 #endif
2038             }
2039         };
2040 
2041         template <class F, class A0 = fn_arg_type<F,0>, int arity = function_traits<F>::arity>
2042         class accumulating_item;
2043 
2044         template <class F, class A0>
2045         class accumulating_item<F, A0 &, 1>
2046         {
2047             using E = A0;
2048             slot<E> * s_;
2049             F f_;
2050 
2051         public:
2052 
accumulating_item(F && f)2053             BOOST_LEAF_CONSTEXPR accumulating_item( F && f ) noexcept:
2054                 s_(tl_slot_ptr<E>::p),
2055                 f_(std::forward<F>(f))
2056             {
2057             }
2058 
trigger(int err_id)2059             BOOST_LEAF_CONSTEXPR void trigger( int err_id ) noexcept
2060             {
2061                 BOOST_LEAF_ASSERT((err_id&3)==1);
2062                 if( s_ )
2063                     if( E * e = s_->has_value(err_id) )
2064                         (void) f_(*e);
2065                     else
2066                         (void) f_(s_->put(err_id, E()));
2067             }
2068         };
2069 
2070         template <class... Item>
2071         class preloaded
2072         {
2073             preloaded & operator=( preloaded const & ) = delete;
2074 
2075             std::tuple<Item...> p_;
2076             bool moved_;
2077             error_monitor id_;
2078 
2079         public:
2080 
preloaded(Item &&...i)2081             BOOST_LEAF_CONSTEXPR explicit preloaded( Item && ... i ):
2082                 p_(std::forward<Item>(i)...),
2083                 moved_(false)
2084             {
2085             }
2086 
preloaded(preloaded && x)2087             BOOST_LEAF_CONSTEXPR preloaded( preloaded && x ) noexcept:
2088                 p_(std::move(x.p_)),
2089                 moved_(false),
2090                 id_(std::move(x.id_))
2091             {
2092                 x.moved_ = true;
2093             }
2094 
~preloaded()2095             ~preloaded() noexcept
2096             {
2097                 if( moved_ )
2098                     return;
2099                 if( auto id = id_.check_id() )
2100                     tuple_for_each_preload<sizeof...(Item),decltype(p_)>::trigger(p_,id);
2101             }
2102         };
2103 
2104         template <class T, int arity = function_traits<T>::arity>
2105         struct deduce_item_type;
2106 
2107         template <class T>
2108         struct deduce_item_type<T, -1>
2109         {
2110             using type = preloaded_item<T>;
2111         };
2112 
2113         template <class F>
2114         struct deduce_item_type<F, 0>
2115         {
2116             using type = deferred_item<F>;
2117         };
2118 
2119         template <class F>
2120         struct deduce_item_type<F, 1>
2121         {
2122             using type = accumulating_item<F>;
2123         };
2124     }
2125 
2126     template <class... Item>
2127     BOOST_LEAF_NODISCARD BOOST_LEAF_CONSTEXPR inline
2128     leaf_detail::preloaded<typename leaf_detail::deduce_item_type<Item>::type...>
on_error(Item &&...i)2129     on_error( Item && ... i )
2130     {
2131         return leaf_detail::preloaded<typename leaf_detail::deduce_item_type<Item>::type...>(std::forward<Item>(i)...);
2132     }
2133 
2134 } }
2135 
2136 #endif
2137 // <<< #include <boost/leaf/on_error.hpp>
2138 #line 21 "boost/leaf/capture.hpp"
2139 
2140 namespace boost { namespace leaf {
2141 
2142     namespace leaf_detail
2143     {
2144         template <class R, bool IsResult = is_result_type<R>::value>
2145         struct is_result_tag;
2146 
2147         template <class R>
2148         struct is_result_tag<R, false>
2149         {
2150         };
2151 
2152         template <class R>
2153         struct is_result_tag<R, true>
2154         {
2155         };
2156     }
2157 
2158 #ifdef BOOST_LEAF_NO_EXCEPTIONS
2159 
2160     namespace leaf_detail
2161     {
2162         template <class R, class F, class... A>
2163         inline
2164         decltype(std::declval<F>()(std::forward<A>(std::declval<A>())...))
capture_impl(is_result_tag<R,false>,context_ptr && ctx,F && f,A...a)2165         capture_impl(is_result_tag<R, false>, context_ptr && ctx, F && f, A... a) noexcept
2166         {
2167             auto active_context = activate_context(*ctx);
2168             return std::forward<F>(f)(std::forward<A>(a)...);
2169         }
2170 
2171         template <class R, class F, class... A>
2172         inline
2173         decltype(std::declval<F>()(std::forward<A>(std::declval<A>())...))
capture_impl(is_result_tag<R,true>,context_ptr && ctx,F && f,A...a)2174         capture_impl(is_result_tag<R, true>, context_ptr && ctx, F && f, A... a) noexcept
2175         {
2176             auto active_context = activate_context(*ctx);
2177             if( auto r = std::forward<F>(f)(std::forward<A>(a)...) )
2178                 return r;
2179             else
2180             {
2181                 ctx->captured_id_ = r.error();
2182                 return std::move(ctx);
2183             }
2184         }
2185 
2186         template <class R, class Future>
2187         inline
2188         decltype(std::declval<Future>().get())
future_get_impl(is_result_tag<R,false>,Future & fut)2189         future_get_impl(is_result_tag<R, false>, Future & fut) noexcept
2190         {
2191             return fut.get();
2192         }
2193 
2194         template <class R, class Future>
2195         inline
2196         decltype(std::declval<Future>().get())
future_get_impl(is_result_tag<R,true>,Future & fut)2197         future_get_impl(is_result_tag<R, true>, Future & fut) noexcept
2198         {
2199             if( auto r = fut.get() )
2200                 return r;
2201             else
2202                 return error_id(r.error()); // unloads
2203         }
2204     }
2205 
2206 #else
2207 
2208     namespace leaf_detail
2209     {
2210         class capturing_exception:
2211             public std::exception
2212         {
2213             std::exception_ptr ex_;
2214             context_ptr ctx_;
2215 
2216         public:
2217 
capturing_exception(std::exception_ptr && ex,context_ptr && ctx)2218             capturing_exception(std::exception_ptr && ex, context_ptr && ctx) noexcept:
2219                 ex_(std::move(ex)),
2220                 ctx_(std::move(ctx))
2221             {
2222                 BOOST_LEAF_ASSERT(ex_);
2223                 BOOST_LEAF_ASSERT(ctx_);
2224                 BOOST_LEAF_ASSERT(ctx_->captured_id_);
2225             }
2226 
unload_and_rethrow_original_exception() const2227             [[noreturn]] void unload_and_rethrow_original_exception() const
2228             {
2229                 BOOST_LEAF_ASSERT(ctx_->captured_id_);
2230                 auto active_context = activate_context(*ctx_);
2231                 id_factory<>::current_id = ctx_->captured_id_.value();
2232                 std::rethrow_exception(ex_);
2233             }
2234 
2235             template <class CharT, class Traits>
print(std::basic_ostream<CharT,Traits> & os) const2236             void print( std::basic_ostream<CharT, Traits> & os ) const
2237             {
2238                 ctx_->print(os);
2239             }
2240         };
2241 
2242         template <class R, class F, class... A>
2243         inline
2244         decltype(std::declval<F>()(std::forward<A>(std::declval<A>())...))
capture_impl(is_result_tag<R,false>,context_ptr && ctx,F && f,A...a)2245         capture_impl(is_result_tag<R, false>, context_ptr && ctx, F && f, A... a)
2246         {
2247             auto active_context = activate_context(*ctx);
2248             error_monitor cur_err;
2249             try
2250             {
2251                 return std::forward<F>(f)(std::forward<A>(a)...);
2252             }
2253             catch( capturing_exception const & )
2254             {
2255                 throw;
2256             }
2257             catch( exception_base const & e )
2258             {
2259                 ctx->captured_id_ = e.get_error_id();
2260                 throw_exception( capturing_exception(std::current_exception(), std::move(ctx)) );
2261             }
2262             catch(...)
2263             {
2264                 ctx->captured_id_ = cur_err.assigned_error_id();
2265                 throw_exception( capturing_exception(std::current_exception(), std::move(ctx)) );
2266             }
2267         }
2268 
2269         template <class R, class F, class... A>
2270         inline
2271         decltype(std::declval<F>()(std::forward<A>(std::declval<A>())...))
capture_impl(is_result_tag<R,true>,context_ptr && ctx,F && f,A...a)2272         capture_impl(is_result_tag<R, true>, context_ptr && ctx, F && f, A... a)
2273         {
2274             auto active_context = activate_context(*ctx);
2275             error_monitor cur_err;
2276             try
2277             {
2278                 if( auto && r = std::forward<F>(f)(std::forward<A>(a)...) )
2279                     return std::move(r);
2280                 else
2281                 {
2282                     ctx->captured_id_ = r.error();
2283                     return std::move(ctx);
2284                 }
2285             }
2286             catch( capturing_exception const & )
2287             {
2288                 throw;
2289             }
2290             catch( exception_base const & e )
2291             {
2292                 ctx->captured_id_ = e.get_error_id();
2293                 throw_exception( capturing_exception(std::current_exception(), std::move(ctx)) );
2294             }
2295             catch(...)
2296             {
2297                 ctx->captured_id_ = cur_err.assigned_error_id();
2298                 throw_exception( capturing_exception(std::current_exception(), std::move(ctx)) );
2299             }
2300         }
2301 
2302         template <class R, class Future>
2303         inline
2304         decltype(std::declval<Future>().get())
future_get_impl(is_result_tag<R,false>,Future & fut)2305         future_get_impl(is_result_tag<R, false>, Future & fut )
2306         {
2307             try
2308             {
2309                 return fut.get();
2310             }
2311             catch( capturing_exception const & cap )
2312             {
2313                 cap.unload_and_rethrow_original_exception();
2314             }
2315         }
2316 
2317         template <class R, class Future>
2318         inline
2319         decltype(std::declval<Future>().get())
future_get_impl(is_result_tag<R,true>,Future & fut)2320         future_get_impl(is_result_tag<R, true>, Future & fut )
2321         {
2322             try
2323             {
2324                 if( auto r = fut.get() )
2325                     return r;
2326                 else
2327                     return error_id(r.error()); // unloads
2328             }
2329             catch( capturing_exception const & cap )
2330             {
2331                 cap.unload_and_rethrow_original_exception();
2332             }
2333         }
2334     }
2335 
2336 #endif
2337 
2338     template <class F, class... A>
2339     inline
2340     decltype(std::declval<F>()(std::forward<A>(std::declval<A>())...))
capture(context_ptr && ctx,F && f,A...a)2341     capture(context_ptr && ctx, F && f, A... a)
2342     {
2343         using namespace leaf_detail;
2344         return capture_impl(is_result_tag<decltype(std::declval<F>()(std::forward<A>(std::declval<A>())...))>(), std::move(ctx), std::forward<F>(f), std::forward<A>(a)...);
2345     }
2346 
2347     template <class Future>
2348     inline
2349     decltype(std::declval<Future>().get())
future_get(Future & fut)2350     future_get( Future & fut )
2351     {
2352         using namespace leaf_detail;
2353         return future_get_impl(is_result_tag<decltype(std::declval<Future>().get())>(), fut);
2354     }
2355 
2356     ////////////////////////////////////////
2357 
2358 #ifndef BOOST_LEAF_NO_EXCEPTIONS
2359 
2360     template <class T>
2361     class result;
2362 
2363     namespace leaf_detail
2364     {
catch_exceptions_helper(std::exception const & ex,leaf_detail_mp11::mp_list<>)2365         inline error_id catch_exceptions_helper( std::exception const & ex, leaf_detail_mp11::mp_list<> )
2366         {
2367             return leaf::new_error(std::current_exception());
2368         }
2369 
2370         template <class Ex1, class... Ex>
catch_exceptions_helper(std::exception const & ex,leaf_detail_mp11::mp_list<Ex1,Ex...>)2371         inline error_id catch_exceptions_helper( std::exception const & ex, leaf_detail_mp11::mp_list<Ex1,Ex...> )
2372         {
2373             if( Ex1 const * p = dynamic_cast<Ex1 const *>(&ex) )
2374                 return catch_exceptions_helper(ex, leaf_detail_mp11::mp_list<Ex...>{ }).load(*p);
2375             else
2376                 return catch_exceptions_helper(ex, leaf_detail_mp11::mp_list<Ex...>{ });
2377         }
2378 
2379         template <class T>
2380         struct deduce_exception_to_result_return_type_impl
2381         {
2382             using type = result<T>;
2383         };
2384 
2385         template <class T>
2386         struct deduce_exception_to_result_return_type_impl<result<T>>
2387         {
2388             using type = result<T>;
2389         };
2390 
2391         template <class T>
2392         using deduce_exception_to_result_return_type = typename deduce_exception_to_result_return_type_impl<T>::type;
2393     }
2394 
2395     template <class... Ex, class F>
2396     inline
2397     leaf_detail::deduce_exception_to_result_return_type<leaf_detail::fn_return_type<F>>
exception_to_result(F && f)2398     exception_to_result( F && f ) noexcept
2399     {
2400         try
2401         {
2402             return std::forward<F>(f)();
2403         }
2404         catch( std::exception const & ex )
2405         {
2406             return leaf_detail::catch_exceptions_helper(ex, leaf_detail_mp11::mp_list<Ex...>());
2407         }
2408         catch(...)
2409         {
2410             return leaf::new_error(std::current_exception());
2411         }
2412     }
2413 
2414 #endif
2415 
2416 } }
2417 
2418 #endif
2419 // <<< #include <boost/leaf/capture.hpp>
2420 #line 10 "../../include/boost/leaf/detail/all.hpp"
2421 // >>> #include <boost/leaf/common.hpp>
2422 #line 1 "boost/leaf/common.hpp"
2423 #ifndef BOOST_LEAF_COMMON_HPP_INCLUDED
2424 #define BOOST_LEAF_COMMON_HPP_INCLUDED
2425 
2426 // Copyright (c) 2018-2020 Emil Dotchevski and Reverge Studios, Inc.
2427 
2428 // Distributed under the Boost Software License, Version 1.0. (See accompanying
2429 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
2430 
2431 #ifndef BOOST_LEAF_ENABLE_WARNINGS
2432 #   if defined(__clang__)
2433 #       pragma clang system_header
2434 #   elif (__GNUC__*100+__GNUC_MINOR__>301)
2435 #       pragma GCC system_header
2436 #   elif defined(_MSC_VER)
2437 #       pragma warning(push,1)
2438 #   endif
2439 #endif
2440 
2441 #include <string>
2442 #include <cerrno>
2443 #ifdef _WIN32
2444 #   include <Windows.h>
2445 #   include <cstring>
2446 #ifdef min
2447 #   undef min
2448 #endif
2449 #ifdef max
2450 #   undef max
2451 #endif
2452 #endif
2453 
2454 namespace boost { namespace leaf {
2455 
2456     struct e_api_function { char const * value; };
2457 
2458     struct e_file_name { std::string value; };
2459 
2460     struct e_errno
2461     {
2462         int value;
2463 
2464         template <class CharT, class Traits>
operator <<(std::basic_ostream<CharT,Traits> & os,e_errno const & err)2465         friend std::basic_ostream<CharT, Traits> & operator<<( std::basic_ostream<CharT, Traits> & os, e_errno const & err )
2466         {
2467             return os << type<e_errno>() << ": " << err.value << ", \"" << std::strerror(err.value) << '"';
2468         }
2469     };
2470 
2471     struct e_type_info_name { char const * value; };
2472 
2473     struct e_at_line { int value; };
2474 
2475     namespace windows
2476     {
2477         struct e_LastError
2478         {
2479             unsigned value;
2480 
2481 #ifdef _WIN32
2482             template <class CharT, class Traits>
operator <<(std::basic_ostream<CharT,Traits> os,e_LastError const & err)2483             friend std::basic_ostream<CharT, Traits> & operator<<( std::basic_ostream<CharT, Traits> os, e_LastError const & err )
2484             {
2485                 struct msg_buf
2486                 {
2487                     LPVOID * p;
2488                     msg_buf(): p(0) { }
2489                     ~msg_buf() noexcept { if(p) LocalFree(p); }
2490                 };
2491                 msg_buf mb;
2492                 if( FormatMessageA(
2493                     FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
2494                     0,
2495                     err.value,
2496                     MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
2497                     (LPSTR)&mb.p,
2498                     0,
2499                     0) )
2500                 {
2501                     BOOST_LEAF_ASSERT(mb.p != 0);
2502                     char * z = std::strchr((LPSTR)mb.p,0);
2503                     if( z[-1] == '\n' )
2504                         *--z = 0;
2505                     if( z[-1] == '\r' )
2506                         *--z = 0;
2507                     return os << type<e_LastError>() << ": " << err.value << ", \"" << (LPCSTR)mb.p << '"';
2508                 }
2509                 return os;
2510             }
2511 #else
2512             // TODO : Other platforms
2513 #endif
2514         };
2515     }
2516 
2517 } }
2518 
2519 #endif
2520 // <<< #include <boost/leaf/common.hpp>
2521 #line 11 "../../include/boost/leaf/detail/all.hpp"
2522 // >>> #include <boost/leaf/context.hpp>
2523 #line 1 "boost/leaf/context.hpp"
2524 #ifndef BOOST_LEAF_CONTEXT_HPP_INCLUDED
2525 #define BOOST_LEAF_CONTEXT_HPP_INCLUDED
2526 
2527 // Copyright (c) 2018-2020 Emil Dotchevski and Reverge Studios, Inc.
2528 
2529 // Distributed under the Boost Software License, Version 1.0. (See accompanying
2530 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
2531 
2532 #ifndef BOOST_LEAF_ENABLE_WARNINGS
2533 #   if defined(__clang__)
2534 #       pragma clang system_header
2535 #   elif (__GNUC__*100+__GNUC_MINOR__>301)
2536 #       pragma GCC system_header
2537 #   elif defined(_MSC_VER)
2538 #       pragma warning(push,1)
2539 #   endif
2540 #endif
2541 
2542 
2543 namespace boost { namespace leaf {
2544 
2545     class error_info;
2546     class diagnostic_info;
2547     class verbose_diagnostic_info;
2548 
2549     template <class>
2550     struct is_predicate: std::false_type
2551     {
2552     };
2553 
2554     namespace leaf_detail
2555     {
2556         template <class T>
2557         struct is_exception: std::is_base_of<std::exception, typename std::decay<T>::type>
2558         {
2559         };
2560 
2561         template <class E>
2562         struct handler_argument_traits;
2563 
2564         template <class E, bool IsPredicate = is_predicate<E>::value>
2565         struct handler_argument_traits_defaults;
2566 
2567         template <class E>
2568         struct handler_argument_traits_defaults<E, false>
2569         {
2570             using error_type = typename std::decay<E>::type;
2571             constexpr static bool always_available = false;
2572 
2573             template <class Tup>
2574             BOOST_LEAF_CONSTEXPR static error_type const * check( Tup const &, error_info const & ) noexcept;
2575 
2576             template <class Tup>
2577             BOOST_LEAF_CONSTEXPR static error_type * check( Tup &, error_info const & ) noexcept;
2578 
2579             template <class Tup>
getboost::leaf::leaf_detail::handler_argument_traits_defaults2580             BOOST_LEAF_CONSTEXPR static E get( Tup & tup, error_info const & ei ) noexcept
2581             {
2582                 return *check(tup, ei);
2583             }
2584 
2585             static_assert(!is_predicate<error_type>::value, "Handlers must take predicate arguments by value");
2586             static_assert(!std::is_same<E, error_info>::value, "Handlers must take leaf::error_info arguments by const &");
2587             static_assert(!std::is_same<E, diagnostic_info>::value, "Handlers must take leaf::diagnostic_info arguments by const &");
2588             static_assert(!std::is_same<E, verbose_diagnostic_info>::value, "Handlers must take leaf::verbose_diagnostic_info arguments by const &");
2589         };
2590 
2591         template <class Pred>
2592         struct handler_argument_traits_defaults<Pred, true>: handler_argument_traits<typename Pred::error_type>
2593         {
2594             using base = handler_argument_traits<typename Pred::error_type>;
2595             static_assert(!base::always_available, "Predicates can't use types that are always_available");
2596 
2597             template <class Tup>
checkboost::leaf::leaf_detail::handler_argument_traits_defaults2598             BOOST_LEAF_CONSTEXPR static bool check( Tup const & tup, error_info const & ei ) noexcept
2599             {
2600                 auto e = base::check(tup, ei);
2601                 return e && Pred::evaluate(*e);
2602             };
2603 
2604             template <class Tup>
getboost::leaf::leaf_detail::handler_argument_traits_defaults2605             BOOST_LEAF_CONSTEXPR static Pred get( Tup const & tup, error_info const & ei ) noexcept
2606             {
2607                 return Pred{*base::check(tup, ei)};
2608             }
2609         };
2610 
2611         template <class E>
2612         struct handler_argument_always_available
2613         {
2614             using error_type = E;
2615             constexpr static bool always_available = true;
2616 
2617             template <class Tup>
checkboost::leaf::leaf_detail::handler_argument_always_available2618             BOOST_LEAF_CONSTEXPR static bool check( Tup &, error_info const & ) noexcept
2619             {
2620                 return true;
2621             };
2622         };
2623 
2624         template <class E>
2625         struct handler_argument_traits: handler_argument_traits_defaults<E>
2626         {
2627         };
2628 
2629         template <>
2630         struct handler_argument_traits<void>
2631         {
2632             using error_type = void;
2633             constexpr static bool always_available = false;
2634 
2635             template <class Tup>
2636             BOOST_LEAF_CONSTEXPR static std::exception const * check( Tup const &, error_info const & ) noexcept;
2637         };
2638 
2639         template <class E>
2640         struct handler_argument_traits<E &&>
2641         {
2642             static_assert(sizeof(E) == 0, "Error handlers may not take rvalue ref arguments");
2643         };
2644 
2645         template <class E>
2646         struct handler_argument_traits<E *>: handler_argument_always_available<typename std::remove_const<E>::type>
2647         {
2648             template <class Tup>
getboost::leaf::leaf_detail::handler_argument_traits2649             BOOST_LEAF_CONSTEXPR static E * get( Tup & tup, error_info const & ei) noexcept
2650             {
2651                 return handler_argument_traits_defaults<E>::check(tup, ei);
2652             }
2653         };
2654 
2655         template <>
2656         struct handler_argument_traits<error_info const &>: handler_argument_always_available<void>
2657         {
2658             template <class Tup>
getboost::leaf::leaf_detail::handler_argument_traits2659             BOOST_LEAF_CONSTEXPR static error_info const & get( Tup const &, error_info const & ei ) noexcept
2660             {
2661                 return ei;
2662             }
2663         };
2664 
2665         template <class E>
2666         struct handler_argument_traits_require_by_value
2667         {
2668             static_assert(sizeof(E) == 0, "Error handlers must take this type by value");
2669         };
2670     }
2671 
2672     ////////////////////////////////////////
2673 
2674     namespace leaf_detail
2675     {
2676         template <int I, class Tuple>
2677         struct tuple_for_each
2678         {
activateboost::leaf::leaf_detail::tuple_for_each2679             BOOST_LEAF_CONSTEXPR static void activate( Tuple & tup ) noexcept
2680             {
2681                 static_assert(!std::is_same<error_info, typename std::decay<decltype(std::get<I-1>(tup))>::type>::value, "Bug in LEAF: context type deduction");
2682                 tuple_for_each<I-1,Tuple>::activate(tup);
2683                 std::get<I-1>(tup).activate();
2684             }
2685 
deactivateboost::leaf::leaf_detail::tuple_for_each2686             BOOST_LEAF_CONSTEXPR static void deactivate( Tuple & tup ) noexcept
2687             {
2688                 static_assert(!std::is_same<error_info, typename std::decay<decltype(std::get<I-1>(tup))>::type>::value, "Bug in LEAF: context type deduction");
2689                 std::get<I-1>(tup).deactivate();
2690                 tuple_for_each<I-1,Tuple>::deactivate(tup);
2691             }
2692 
propagateboost::leaf::leaf_detail::tuple_for_each2693             BOOST_LEAF_CONSTEXPR static void propagate( Tuple & tup ) noexcept
2694             {
2695                 static_assert(!std::is_same<error_info, typename std::decay<decltype(std::get<I-1>(tup))>::type>::value, "Bug in LEAF: context type deduction");
2696                 auto & sl = std::get<I-1>(tup);
2697                 sl.propagate();
2698                 tuple_for_each<I-1,Tuple>::propagate(tup);
2699             }
2700 
propagate_capturedboost::leaf::leaf_detail::tuple_for_each2701             BOOST_LEAF_CONSTEXPR static void propagate_captured( Tuple & tup, int err_id ) noexcept
2702             {
2703                 static_assert(!std::is_same<error_info, typename std::decay<decltype(std::get<I-1>(tup))>::type>::value, "Bug in LEAF: context type deduction");
2704                 auto & sl = std::get<I-1>(tup);
2705                 if( sl.has_value(err_id) )
2706                     load_slot(err_id, std::move(sl).value(err_id));
2707                 tuple_for_each<I-1,Tuple>::propagate_captured(tup, err_id);
2708             }
2709 
printboost::leaf::leaf_detail::tuple_for_each2710             static void print( std::ostream & os, void const * tup, int key_to_print )
2711             {
2712                 BOOST_LEAF_ASSERT(tup != 0);
2713                 tuple_for_each<I-1,Tuple>::print(os, tup, key_to_print);
2714                 std::get<I-1>(*static_cast<Tuple const *>(tup)).print(os, key_to_print);
2715             }
2716         };
2717 
2718         template <class Tuple>
2719         struct tuple_for_each<0, Tuple>
2720         {
activateboost::leaf::leaf_detail::tuple_for_each2721             BOOST_LEAF_CONSTEXPR static void activate( Tuple & ) noexcept { }
deactivateboost::leaf::leaf_detail::tuple_for_each2722             BOOST_LEAF_CONSTEXPR static void deactivate( Tuple & ) noexcept { }
propagateboost::leaf::leaf_detail::tuple_for_each2723             BOOST_LEAF_CONSTEXPR static void propagate( Tuple & tup ) noexcept { }
propagate_capturedboost::leaf::leaf_detail::tuple_for_each2724             BOOST_LEAF_CONSTEXPR static void propagate_captured( Tuple & tup, int ) noexcept { }
printboost::leaf::leaf_detail::tuple_for_each2725             static void print( std::ostream &, void const *, int ) { }
2726         };
2727     }
2728 
2729     ////////////////////////////////////////////
2730 
2731 #if BOOST_LEAF_DIAGNOSTICS
2732 
2733     namespace leaf_detail
2734     {
2735         template <class T> struct requires_unexpected { constexpr static bool value = false; };
2736         template <class T> struct requires_unexpected<T const> { constexpr static bool value = requires_unexpected<T>::value; };
2737         template <class T> struct requires_unexpected<T const &> { constexpr static bool value = requires_unexpected<T>::value; };
2738         template <class T> struct requires_unexpected<T const *> { constexpr static bool value = requires_unexpected<T>::value; };
2739         template <> struct requires_unexpected<e_unexpected_count> { constexpr static bool value = true; };
2740         template <> struct requires_unexpected<e_unexpected_info> { constexpr static bool value = true; };
2741 
2742         template <class L>
2743         struct unexpected_requested;
2744 
2745         template <template <class ...> class L>
2746         struct unexpected_requested<L<>>
2747         {
2748             constexpr static bool value = false;
2749         };
2750 
2751         template <template <class...> class L, template <class> class S, class Car, class... Cdr>
2752         struct unexpected_requested<L<S<Car>, S<Cdr>...>>
2753         {
2754             constexpr static bool value = requires_unexpected<Car>::value || unexpected_requested<L<S<Cdr>...>>::value;
2755         };
2756     }
2757 
2758 #endif
2759 
2760     ////////////////////////////////////////////
2761 
2762     namespace leaf_detail
2763     {
2764         template <class T> struct does_not_participate_in_context_deduction: std::false_type { };
2765         template <> struct does_not_participate_in_context_deduction<void>: std::true_type { };
2766 
2767         template <class L>
2768         struct deduce_e_type_list;
2769 
2770         template <template<class...> class L, class... T>
2771         struct deduce_e_type_list<L<T...>>
2772         {
2773             using type =
2774                 leaf_detail_mp11::mp_remove_if<
2775                     leaf_detail_mp11::mp_unique<
2776                         leaf_detail_mp11::mp_list<typename handler_argument_traits<T>::error_type...>
2777                     >,
2778                     does_not_participate_in_context_deduction
2779                 >;
2780         };
2781 
2782         template <class L>
2783         struct deduce_e_tuple_impl;
2784 
2785         template <template <class...> class L, class... E>
2786         struct deduce_e_tuple_impl<L<E...>>
2787         {
2788             using type = std::tuple<slot<E>...>;
2789         };
2790 
2791         template <class... E>
2792         using deduce_e_tuple = typename deduce_e_tuple_impl<typename deduce_e_type_list<leaf_detail_mp11::mp_list<E...>>::type>::type;
2793     }
2794 
2795     ////////////////////////////////////////////
2796 
2797     template <class... E>
2798     class context
2799     {
2800         context( context const & ) = delete;
2801         context & operator=( context const & ) = delete;
2802 
2803         using Tup = leaf_detail::deduce_e_tuple<E...>;
2804         Tup tup_;
2805 
2806 #if !defined(BOOST_LEAF_NO_THREADS) && !defined(NDEBUG)
2807         std::thread::id thread_id_;
2808 #endif
2809         bool is_active_;
2810 
2811     protected:
2812 
propagate_captured_errors(error_id err_id)2813         BOOST_LEAF_CONSTEXPR error_id propagate_captured_errors( error_id err_id ) noexcept
2814         {
2815             leaf_detail::tuple_for_each<std::tuple_size<Tup>::value,Tup>::propagate_captured(tup_, err_id.value());
2816             return err_id;
2817         }
2818 
2819     public:
2820 
context(context && x)2821         BOOST_LEAF_CONSTEXPR context( context && x ) noexcept:
2822             tup_(std::move(x.tup_)),
2823             is_active_(false)
2824         {
2825             BOOST_LEAF_ASSERT(!x.is_active());
2826         }
2827 
context()2828         BOOST_LEAF_CONSTEXPR context() noexcept:
2829             is_active_(false)
2830         {
2831         }
2832 
~context()2833         ~context() noexcept
2834         {
2835             BOOST_LEAF_ASSERT(!is_active());
2836         }
2837 
tup() const2838         BOOST_LEAF_CONSTEXPR Tup const & tup() const noexcept
2839         {
2840             return tup_;
2841         }
2842 
tup()2843         BOOST_LEAF_CONSTEXPR Tup & tup() noexcept
2844         {
2845             return tup_;
2846         }
2847 
activate()2848         BOOST_LEAF_CONSTEXPR void activate() noexcept
2849         {
2850             using namespace leaf_detail;
2851             BOOST_LEAF_ASSERT(!is_active());
2852             tuple_for_each<std::tuple_size<Tup>::value,Tup>::activate(tup_);
2853 #if BOOST_LEAF_DIAGNOSTICS
2854             if( unexpected_requested<Tup>::value )
2855                 ++tl_unexpected_enabled<>::counter;
2856 #endif
2857 #if !defined(BOOST_LEAF_NO_THREADS) && !defined(NDEBUG)
2858             thread_id_ = std::this_thread::get_id();
2859 #endif
2860             is_active_ = true;
2861         }
2862 
deactivate()2863         BOOST_LEAF_CONSTEXPR void deactivate() noexcept
2864         {
2865             using namespace leaf_detail;
2866             BOOST_LEAF_ASSERT(is_active());
2867             is_active_ = false;
2868 #if !defined(BOOST_LEAF_NO_THREADS) && !defined(NDEBUG)
2869             BOOST_LEAF_ASSERT(std::this_thread::get_id() == thread_id_);
2870             thread_id_ = std::thread::id();
2871 #endif
2872 #if BOOST_LEAF_DIAGNOSTICS
2873             if( unexpected_requested<Tup>::value )
2874                 --tl_unexpected_enabled<>::counter;
2875 #endif
2876             tuple_for_each<std::tuple_size<Tup>::value,Tup>::deactivate(tup_);
2877         }
2878 
propagate()2879         BOOST_LEAF_CONSTEXPR void propagate() noexcept
2880         {
2881             leaf_detail::tuple_for_each<std::tuple_size<Tup>::value,Tup>::propagate(tup_);
2882         }
2883 
is_active() const2884         BOOST_LEAF_CONSTEXPR bool is_active() const noexcept
2885         {
2886             return is_active_;
2887         }
2888 
print(std::ostream & os) const2889         void print( std::ostream & os ) const
2890         {
2891             leaf_detail::tuple_for_each<std::tuple_size<Tup>::value,Tup>::print(os, &tup_, 0);
2892         }
2893 
2894         template <class R, class... H>
2895         BOOST_LEAF_CONSTEXPR R handle_error( error_id, H && ... ) const;
2896 
2897         template <class R, class... H>
2898         BOOST_LEAF_CONSTEXPR R handle_error( error_id, H && ... );
2899     };
2900 
2901     ////////////////////////////////////////
2902 
2903     namespace leaf_detail
2904     {
2905         template <class TypeList>
2906         struct deduce_context_impl;
2907 
2908         template <template <class...> class L, class... E>
2909         struct deduce_context_impl<L<E...>>
2910         {
2911             using type = context<E...>;
2912         };
2913 
2914         template <class TypeList>
2915         using deduce_context = typename deduce_context_impl<TypeList>::type;
2916 
2917         template <class H>
2918         struct fn_mp_args_fwd
2919         {
2920             using type = fn_mp_args<H>;
2921         };
2922 
2923         template <class... H>
2924         struct fn_mp_args_fwd<std::tuple<H...> &>: fn_mp_args_fwd<std::tuple<H...>> { };
2925 
2926         template <class... H>
2927         struct fn_mp_args_fwd<std::tuple<H...>>
2928         {
2929             using type = leaf_detail_mp11::mp_append<typename fn_mp_args_fwd<H>::type...>;
2930         };
2931 
2932         template <class... H>
2933         struct context_type_from_handlers_impl
2934         {
2935             using type = deduce_context<leaf_detail_mp11::mp_append<typename fn_mp_args_fwd<H>::type...>>;
2936         };
2937 
2938         template <class Ctx>
2939         struct polymorphic_context_impl: polymorphic_context, Ctx
2940         {
propagate_captured_errorsboost::leaf::leaf_detail::polymorphic_context_impl2941             error_id propagate_captured_errors() noexcept final override { return Ctx::propagate_captured_errors(captured_id_); }
activateboost::leaf::leaf_detail::polymorphic_context_impl2942             void activate() noexcept final override { Ctx::activate(); }
deactivateboost::leaf::leaf_detail::polymorphic_context_impl2943             void deactivate() noexcept final override { Ctx::deactivate(); }
propagateboost::leaf::leaf_detail::polymorphic_context_impl2944             void propagate() noexcept final override { Ctx::propagate(); }
is_activeboost::leaf::leaf_detail::polymorphic_context_impl2945             bool is_active() const noexcept final override { return Ctx::is_active(); }
printboost::leaf::leaf_detail::polymorphic_context_impl2946             void print( std::ostream & os ) const final override { return Ctx::print(os); }
2947         };
2948     }
2949 
2950     template <class... H>
2951     using context_type_from_handlers = typename leaf_detail::context_type_from_handlers_impl<H...>::type;
2952 
2953     ////////////////////////////////////////////
2954 
2955     template <class...  H>
make_context()2956     BOOST_LEAF_CONSTEXPR inline context_type_from_handlers<H...> make_context() noexcept
2957     {
2958         return { };
2959     }
2960 
2961     template <class...  H>
make_context(H &&...)2962     BOOST_LEAF_CONSTEXPR inline context_type_from_handlers<H...> make_context( H && ... ) noexcept
2963     {
2964         return { };
2965     }
2966 
2967     ////////////////////////////////////////////
2968 
2969     template <class...  H>
make_shared_context()2970     inline context_ptr make_shared_context() noexcept
2971     {
2972         return std::make_shared<leaf_detail::polymorphic_context_impl<context_type_from_handlers<H...>>>();
2973     }
2974 
2975     template <class...  H>
make_shared_context(H &&...)2976     inline context_ptr make_shared_context( H && ... ) noexcept
2977     {
2978         return std::make_shared<leaf_detail::polymorphic_context_impl<context_type_from_handlers<H...>>>();
2979     }
2980 
2981 } }
2982 
2983 #endif
2984 // <<< #include <boost/leaf/context.hpp>
2985 #line 12 "../../include/boost/leaf/detail/all.hpp"
2986 // >>> #include <boost/leaf/handle_errors.hpp>
2987 #line 1 "boost/leaf/handle_errors.hpp"
2988 #ifndef BOOST_LEAF_HANDLE_ERRORS_HPP_INCLUDED
2989 #define BOOST_LEAF_HANDLE_ERRORS_HPP_INCLUDED
2990 
2991 // Copyright (c) 2018-2020 Emil Dotchevski and Reverge Studios, Inc.
2992 
2993 // Distributed under the Boost Software License, Version 1.0. (See accompanying
2994 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
2995 
2996 #ifndef BOOST_LEAF_ENABLE_WARNINGS
2997 #   if defined(__clang__)
2998 #       pragma clang system_header
2999 #   elif (__GNUC__*100+__GNUC_MINOR__>301)
3000 #       pragma GCC system_header
3001 #   elif defined(_MSC_VER)
3002 #       pragma warning(push,1)
3003 #   endif
3004 #endif
3005 
3006 // >>> #include <boost/leaf/detail/demangle.hpp>
3007 #line 1 "boost/leaf/detail/demangle.hpp"
3008 #ifndef BOOST_LEAF_DETAIL_DEMANGLE_HPP_INCLUDED
3009 #define BOOST_LEAF_DETAIL_DEMANGLE_HPP_INCLUDED
3010 
3011 // Copyright (c) 2018-2020 Emil Dotchevski and Reverge Studios, Inc.
3012 
3013 // Distributed under the Boost Software License, Version 1.0. (See accompanying
3014 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
3015 
3016 // core::demangle
3017 //
3018 // Copyright 2014 Peter Dimov
3019 // Copyright 2014 Andrey Semashev
3020 //
3021 // Distributed under the Boost Software License, Version 1.0.
3022 // See accompanying file LICENSE_1_0.txt or copy at
3023 // http://www.boost.org/LICENSE_1_0.txt
3024 
3025 #ifndef BOOST_LEAF_ENABLE_WARNINGS
3026 #   if defined(__clang__)
3027 #       pragma clang system_header
3028 #   elif (__GNUC__*100+__GNUC_MINOR__>301)
3029 #       pragma GCC system_header
3030 #   elif defined(_MSC_VER)
3031 #       pragma warning(push,1)
3032 #   endif
3033 #endif
3034 
3035 #if !defined(_MSC_VER)
3036 #   if defined(__has_include) && __has_include(<cxxabi.h>)
3037 #       define BOOST_LEAF_HAS_CXXABI_H
3038 #   endif
3039 #endif
3040 
3041 #if defined( BOOST_LEAF_HAS_CXXABI_H )
3042 #   include <cxxabi.h>
3043 // For some architectures (mips, mips64, x86, x86_64) cxxabi.h in Android NDK is implemented by gabi++ library
3044 // (https://android.googlesource.com/platform/ndk/+/master/sources/cxx-stl/gabi++/), which does not implement
3045 // abi::__cxa_demangle(). We detect this implementation by checking the include guard here.
3046 #   if defined( __GABIXX_CXXABI_H__ )
3047 #       undef BOOST_LEAF_HAS_CXXABI_H
3048 #   else
3049 #       include <cstddef>
3050 #   endif
3051 #endif
3052 
3053 namespace boost { namespace leaf {
3054 
3055     namespace leaf_detail
3056     {
3057         inline char const * demangle_alloc( char const * name ) noexcept;
3058         inline void demangle_free( char const * name ) noexcept;
3059 
3060         class scoped_demangled_name
3061         {
3062         private:
3063 
3064             char const * m_p;
3065 
3066         public:
3067 
scoped_demangled_name(char const * name)3068             explicit scoped_demangled_name( char const * name ) noexcept :
3069                 m_p( demangle_alloc( name ) )
3070             {
3071             }
3072 
~scoped_demangled_name()3073             ~scoped_demangled_name() noexcept
3074             {
3075                 demangle_free( m_p );
3076             }
3077 
get() const3078             char const * get() const noexcept
3079             {
3080                 return m_p;
3081             }
3082 
3083             scoped_demangled_name( scoped_demangled_name const& ) = delete;
3084             scoped_demangled_name& operator= ( scoped_demangled_name const& ) = delete;
3085         };
3086 
3087 #if defined( BOOST_LEAF_HAS_CXXABI_H )
3088 
demangle_alloc(char const * name)3089         inline char const * demangle_alloc( char const * name ) noexcept
3090         {
3091             int status = 0;
3092             std::size_t size = 0;
3093             return abi::__cxa_demangle( name, NULL, &size, &status );
3094         }
3095 
demangle_free(char const * name)3096         inline void demangle_free( char const * name ) noexcept
3097         {
3098             std::free( const_cast< char* >( name ) );
3099         }
3100 
demangle(char const * name)3101         inline char const * demangle( char const * name )
3102         {
3103             scoped_demangled_name demangled_name( name );
3104             char const * p = demangled_name.get();
3105             if( !p )
3106                 p = name;
3107             return p;
3108         }
3109 
3110 #else
3111 
demangle_alloc(char const * name)3112         inline char const * demangle_alloc( char const * name ) noexcept
3113         {
3114             return name;
3115         }
3116 
demangle_free(char const *)3117         inline void demangle_free( char const * ) noexcept
3118         {
3119         }
3120 
demangle(char const * name)3121         inline char const * demangle( char const * name )
3122         {
3123             return name;
3124         }
3125 
3126 #endif
3127     }
3128 
3129 } }
3130 
3131 #ifdef BOOST_LEAF_HAS_CXXABI_H
3132 #   undef BOOST_LEAF_HAS_CXXABI_H
3133 #endif
3134 
3135 #endif
3136 // <<< #include <boost/leaf/detail/demangle.hpp>
3137 #line 21 "boost/leaf/handle_errors.hpp"
3138 
3139 #ifndef BOOST_LEAF_NO_EXCEPTIONS
3140 #endif
3141 
3142 namespace boost { namespace leaf {
3143 
3144     class error_info
3145     {
3146         error_info & operator=( error_info const & ) = delete;
3147 
3148 #ifndef BOOST_LEAF_NO_EXCEPTIONS
unpack_error_id(std::exception const * ex)3149         static error_id unpack_error_id( std::exception const * ex ) noexcept
3150         {
3151             if( std::system_error const * se = dynamic_cast<std::system_error const *>(ex) )
3152                 if( is_error_id(se->code()) )
3153                     return leaf_detail::make_error_id(se->code().value());
3154             if( std::error_code const * ec = dynamic_cast<std::error_code const *>(ex) )
3155                 if( is_error_id(*ec) )
3156                     return leaf_detail::make_error_id(ec->value());
3157             if( error_id const * err_id = dynamic_cast<error_id const *>(ex) )
3158                 return *err_id;
3159             return current_error();
3160         }
3161 
3162         std::exception * const ex_;
3163 #endif
3164 
3165         error_id const err_id_;
3166 
3167     protected:
3168 
3169         error_info( error_info const & ) noexcept = default;
3170 
3171         template <class CharT, class Traits>
print(std::basic_ostream<CharT,Traits> & os) const3172         void print( std::basic_ostream<CharT, Traits> & os ) const
3173         {
3174             os << "Error ID = " << err_id_.value();
3175 #ifndef BOOST_LEAF_NO_EXCEPTIONS
3176             if( ex_ )
3177             {
3178                 os <<
3179                     "\nException dynamic type: " << leaf_detail::demangle(typeid(*ex_).name()) <<
3180                     "\nstd::exception::what(): " << ex_->what();
3181             }
3182 #endif
3183         }
3184 
3185     public:
3186 
error_info(error_id id)3187         BOOST_LEAF_CONSTEXPR explicit error_info( error_id id ) noexcept:
3188 #ifndef BOOST_LEAF_NO_EXCEPTIONS
3189             ex_(0),
3190 #endif
3191             err_id_(id)
3192         {
3193         }
3194 
3195 #ifndef BOOST_LEAF_NO_EXCEPTIONS
error_info(std::exception * ex)3196         explicit error_info( std::exception * ex ) noexcept:
3197             ex_(ex),
3198             err_id_(unpack_error_id(ex_))
3199         {
3200         }
3201 #endif
3202 
error() const3203         BOOST_LEAF_CONSTEXPR error_id error() const noexcept
3204         {
3205             return err_id_;
3206         }
3207 
exception() const3208         BOOST_LEAF_CONSTEXPR std::exception * exception() const noexcept
3209         {
3210 #ifdef BOOST_LEAF_NO_EXCEPTIONS
3211             return nullptr;
3212 #else
3213             return ex_;
3214 #endif
3215         }
3216 
3217         template <class CharT, class Traits>
operator <<(std::basic_ostream<CharT,Traits> & os,error_info const & x)3218         friend std::basic_ostream<CharT, Traits> & operator<<( std::basic_ostream<CharT, Traits> & os, error_info const & x )
3219         {
3220             os << "leaf::error_info: ";
3221             x.print(os);
3222             return os << '\n';
3223         }
3224     };
3225 
3226     ////////////////////////////////////////
3227 
3228 #if BOOST_LEAF_DIAGNOSTICS
3229 
3230     class diagnostic_info: public error_info
3231     {
3232         leaf_detail::e_unexpected_count const * e_uc_;
3233         void const * tup_;
3234         void (*print_)( std::ostream &, void const * tup, int key_to_print );
3235 
3236     protected:
3237 
3238         diagnostic_info( diagnostic_info const & ) noexcept = default;
3239 
3240         template <class Tup>
diagnostic_info(error_info const & ei,leaf_detail::e_unexpected_count const * e_uc,Tup const & tup)3241         BOOST_LEAF_CONSTEXPR diagnostic_info( error_info const & ei, leaf_detail::e_unexpected_count const * e_uc, Tup const & tup ) noexcept:
3242             error_info(ei),
3243             e_uc_(e_uc),
3244             tup_(&tup),
3245             print_(&leaf_detail::tuple_for_each<std::tuple_size<Tup>::value, Tup>::print)
3246         {
3247         }
3248 
3249     public:
3250 
3251         template <class CharT, class Traits>
operator <<(std::basic_ostream<CharT,Traits> & os,diagnostic_info const & x)3252         friend std::basic_ostream<CharT, Traits> & operator<<( std::basic_ostream<CharT, Traits> & os, diagnostic_info const & x )
3253         {
3254             os << "leaf::diagnostic_info for ";
3255             x.print(os);
3256             os << ":\n";
3257             x.print_(os, x.tup_, x.error().value());
3258             if( x.e_uc_  )
3259                 x.e_uc_->print(os);
3260             return os;
3261         }
3262     };
3263 
3264     namespace leaf_detail
3265     {
3266         struct diagnostic_info_: diagnostic_info
3267         {
3268             template <class Tup>
diagnostic_info_boost::leaf::leaf_detail::diagnostic_info_3269             BOOST_LEAF_CONSTEXPR diagnostic_info_( error_info const & ei, leaf_detail::e_unexpected_count const * e_uc, Tup const & tup ) noexcept:
3270                 diagnostic_info(ei, e_uc, tup)
3271             {
3272             }
3273         };
3274 
3275         template <>
3276         struct handler_argument_traits<diagnostic_info const &>: handler_argument_always_available<e_unexpected_count>
3277         {
3278             template <class Tup>
getboost::leaf::leaf_detail::handler_argument_traits3279             BOOST_LEAF_CONSTEXPR static diagnostic_info_ get( Tup const & tup, error_info const & ei ) noexcept
3280             {
3281                 return diagnostic_info_(ei, handler_argument_traits_defaults<e_unexpected_count>::check(tup, ei), tup);
3282             }
3283         };
3284     }
3285 
3286 #else
3287 
3288     class diagnostic_info: public error_info
3289     {
3290     protected:
3291 
3292         diagnostic_info( diagnostic_info const & ) noexcept = default;
3293 
diagnostic_info(error_info const & ei)3294         BOOST_LEAF_CONSTEXPR diagnostic_info( error_info const & ei ) noexcept:
3295             error_info(ei)
3296         {
3297         }
3298 
3299     public:
3300 
3301         template <class CharT, class Traits>
operator <<(std::basic_ostream<CharT,Traits> & os,diagnostic_info const & x)3302         friend std::basic_ostream<CharT, Traits> & operator<<( std::basic_ostream<CharT, Traits> & os, diagnostic_info const & x )
3303         {
3304             os <<
3305                 "leaf::diagnostic_info requires #define BOOST_LEAF_DIAGNOSTICS 1\n"
3306                 "leaf::error_info: ";
3307             x.print(os);
3308             return os << '\n';
3309         }
3310     };
3311 
3312     namespace leaf_detail
3313     {
3314         struct diagnostic_info_: diagnostic_info
3315         {
diagnostic_info_boost::leaf::leaf_detail::diagnostic_info_3316             BOOST_LEAF_CONSTEXPR diagnostic_info_( error_info const & ei ) noexcept:
3317                 diagnostic_info(ei)
3318             {
3319             }
3320         };
3321 
3322         template <>
3323         struct handler_argument_traits<diagnostic_info const &>: handler_argument_always_available<void>
3324         {
3325             template <class Tup>
getboost::leaf::leaf_detail::handler_argument_traits3326             BOOST_LEAF_CONSTEXPR static diagnostic_info_ get( Tup const & tup, error_info const & ei ) noexcept
3327             {
3328                 return diagnostic_info_(ei);
3329             }
3330         };
3331     }
3332 
3333 #endif
3334 
3335     ////////////////////////////////////////
3336 
3337 #if BOOST_LEAF_DIAGNOSTICS
3338 
3339     class verbose_diagnostic_info: public error_info
3340     {
3341         leaf_detail::e_unexpected_info const * e_ui_;
3342         void const * tup_;
3343         void (*print_)( std::ostream &, void const * tup, int key_to_print );
3344 
3345     protected:
3346 
3347         verbose_diagnostic_info( verbose_diagnostic_info const & ) noexcept = default;
3348 
3349         template <class Tup>
verbose_diagnostic_info(error_info const & ei,leaf_detail::e_unexpected_info const * e_ui,Tup const & tup)3350         BOOST_LEAF_CONSTEXPR verbose_diagnostic_info( error_info const & ei, leaf_detail::e_unexpected_info const * e_ui, Tup const & tup ) noexcept:
3351             error_info(ei),
3352             e_ui_(e_ui),
3353             tup_(&tup),
3354             print_(&leaf_detail::tuple_for_each<std::tuple_size<Tup>::value, Tup>::print)
3355         {
3356         }
3357 
3358     public:
3359 
3360         template <class CharT, class Traits>
operator <<(std::basic_ostream<CharT,Traits> & os,verbose_diagnostic_info const & x)3361         friend std::basic_ostream<CharT, Traits> & operator<<( std::basic_ostream<CharT, Traits> & os, verbose_diagnostic_info const & x )
3362         {
3363             os << "leaf::verbose_diagnostic_info for ";
3364             x.print(os);
3365             os << ":\n";
3366             x.print_(os, x.tup_, x.error().value());
3367             if( x.e_ui_ )
3368                 x.e_ui_->print(os);
3369             return os;
3370         }
3371     };
3372 
3373     namespace leaf_detail
3374     {
3375         struct verbose_diagnostic_info_: verbose_diagnostic_info
3376         {
3377             template <class Tup>
verbose_diagnostic_info_boost::leaf::leaf_detail::verbose_diagnostic_info_3378             BOOST_LEAF_CONSTEXPR verbose_diagnostic_info_( error_info const & ei, leaf_detail::e_unexpected_info const * e_ui, Tup const & tup ) noexcept:
3379                 verbose_diagnostic_info(ei, e_ui, tup)
3380             {
3381             }
3382         };
3383 
3384         template <>
3385         struct handler_argument_traits<verbose_diagnostic_info const &>: handler_argument_always_available<e_unexpected_info>
3386         {
3387             template <class Tup>
getboost::leaf::leaf_detail::handler_argument_traits3388             BOOST_LEAF_CONSTEXPR static verbose_diagnostic_info_ get( Tup const & tup, error_info const & ei ) noexcept
3389             {
3390                 return verbose_diagnostic_info_(ei, handler_argument_traits_defaults<e_unexpected_info>::check(tup, ei), tup);
3391             }
3392         };
3393     }
3394 
3395 #else
3396 
3397     class verbose_diagnostic_info: public error_info
3398     {
3399     protected:
3400 
3401         verbose_diagnostic_info( verbose_diagnostic_info const & ) noexcept = default;
3402 
verbose_diagnostic_info(error_info const & ei)3403         BOOST_LEAF_CONSTEXPR verbose_diagnostic_info( error_info const & ei ) noexcept:
3404             error_info(ei)
3405         {
3406         }
3407 
3408     public:
3409 
3410         template <class CharT, class Traits>
operator <<(std::basic_ostream<CharT,Traits> & os,verbose_diagnostic_info const & x)3411         friend std::basic_ostream<CharT, Traits> & operator<<( std::basic_ostream<CharT, Traits> & os, verbose_diagnostic_info const & x )
3412         {
3413             os <<
3414                 "leaf::verbose_diagnostic_info requires #define BOOST_LEAF_DIAGNOSTICS 1\n"
3415                 "leaf::error_info: ";
3416             x.print(os);
3417             return os << '\n';
3418         }
3419     };
3420 
3421     namespace leaf_detail
3422     {
3423         struct verbose_diagnostic_info_: verbose_diagnostic_info
3424         {
verbose_diagnostic_info_boost::leaf::leaf_detail::verbose_diagnostic_info_3425             BOOST_LEAF_CONSTEXPR verbose_diagnostic_info_( error_info const & ei ) noexcept:
3426                 verbose_diagnostic_info(ei)
3427             {
3428             }
3429         };
3430 
3431 
3432         template <>
3433         struct handler_argument_traits<verbose_diagnostic_info const &>: handler_argument_always_available<void>
3434         {
3435             template <class Tup>
getboost::leaf::leaf_detail::handler_argument_traits3436             BOOST_LEAF_CONSTEXPR static verbose_diagnostic_info_ get( Tup const & tup, error_info const & ei ) noexcept
3437             {
3438                 return verbose_diagnostic_info_(ei);
3439             }
3440         };
3441     }
3442 
3443 #endif
3444 
3445     ////////////////////////////////////////
3446 
3447     namespace leaf_detail
3448     {
3449         template <class T, class... List>
3450         struct type_index;
3451 
3452         template <class T, class... Cdr>
3453         struct type_index<T, T, Cdr...>
3454         {
3455             constexpr static int value = 0;
3456         };
3457 
3458         template <class T, class Car, class... Cdr>
3459         struct type_index<T, Car, Cdr...>
3460         {
3461             constexpr static int value = 1 + type_index<T,Cdr...>::value;
3462         };
3463 
3464         template <class T, class Tuple>
3465         struct tuple_type_index;
3466 
3467         template <class T, class... TupleTypes>
3468         struct tuple_type_index<T,std::tuple<TupleTypes...>>
3469         {
3470             constexpr static int value = type_index<T,TupleTypes...>::value;
3471         };
3472 
3473 #ifndef BOOST_LEAF_NO_EXCEPTIONS
3474 
3475         template <class E, bool = std::is_class<E>::value>
3476         struct peek_exception;
3477 
3478         template <>
3479         struct peek_exception<std::exception const, true>
3480         {
peekboost::leaf::leaf_detail::peek_exception3481             BOOST_LEAF_CONSTEXPR static std::exception const * peek( error_info const & ei ) noexcept
3482             {
3483                 return ei.exception();
3484             }
3485         };
3486 
3487         template <>
3488         struct peek_exception<std::exception, true>
3489         {
peekboost::leaf::leaf_detail::peek_exception3490             BOOST_LEAF_CONSTEXPR static std::exception * peek( error_info const & ei ) noexcept
3491             {
3492                 return ei.exception();
3493             }
3494         };
3495 
3496         template <>
3497         struct peek_exception<std::error_code const, true>
3498         {
peekboost::leaf::leaf_detail::peek_exception3499             static std::error_code const * peek( error_info const & ei ) noexcept
3500             {
3501                 auto const ex = ei.exception();
3502                 if( std::system_error * se = dynamic_cast<std::system_error *>(ex) )
3503                     return &se->code();
3504                 else if( std::error_code * ec = dynamic_cast<std::error_code *>(ex) )
3505                     return ec;
3506                 else
3507                     return 0;
3508             }
3509         };
3510 
3511         template <>
3512         struct peek_exception<std::error_code, true>
3513         {
peekboost::leaf::leaf_detail::peek_exception3514             static std::error_code * peek( error_info const & ei ) noexcept
3515             {
3516                 auto const ex = ei.exception();
3517                 if( std::system_error * se = dynamic_cast<std::system_error *>(ex) )
3518                     return const_cast<std::error_code *>(&se->code());
3519                 else if( std::error_code * ec = dynamic_cast<std::error_code *>(ex) )
3520                     return ec;
3521                 else
3522                     return 0;
3523             }
3524         };
3525 
3526         template <class E>
3527         struct peek_exception<E, true>
3528         {
peekboost::leaf::leaf_detail::peek_exception3529             static E * peek( error_info const & ei ) noexcept
3530             {
3531                 return dynamic_cast<E *>(ei.exception());
3532             }
3533         };
3534 
3535         template <class E>
3536         struct peek_exception<E, false>
3537         {
peekboost::leaf::leaf_detail::peek_exception3538             BOOST_LEAF_CONSTEXPR static E * peek( error_info const & ) noexcept
3539             {
3540                 return 0;
3541             }
3542         };
3543 
3544 #endif
3545 
3546         template <class E, class SlotsTuple>
3547         BOOST_LEAF_CONSTEXPR inline
3548         E const *
peek(SlotsTuple const & tup,error_info const & ei)3549         peek( SlotsTuple const & tup, error_info const & ei ) noexcept
3550         {
3551             if( error_id err = ei.error() )
3552                 if( E const * e = std::get<tuple_type_index<slot<E>,SlotsTuple>::value>(tup).has_value(err.value()) )
3553                     return e;
3554 #ifndef BOOST_LEAF_NO_EXCEPTIONS
3555                 else
3556                     return peek_exception<E const>::peek(ei);
3557 #endif
3558             return 0;
3559         }
3560 
3561         template <class E, class SlotsTuple>
3562         BOOST_LEAF_CONSTEXPR inline
3563         E *
peek(SlotsTuple & tup,error_info const & ei)3564         peek( SlotsTuple & tup, error_info const & ei ) noexcept
3565         {
3566             if( error_id err = ei.error() )
3567                 if( E * e = std::get<tuple_type_index<slot<E>,SlotsTuple>::value>(tup).has_value(err.value()) )
3568                     return e;
3569 #ifndef BOOST_LEAF_NO_EXCEPTIONS
3570                 else
3571                     return peek_exception<E>::peek(ei);
3572 #endif
3573             return 0;
3574         }
3575     }
3576 
3577     ////////////////////////////////////////
3578 
3579     namespace leaf_detail
3580     {
3581         template <class A>
3582         template <class Tup>
3583         BOOST_LEAF_CONSTEXPR inline
3584         typename handler_argument_traits_defaults<A, false>::error_type const *
3585         handler_argument_traits_defaults<A, false>::
check(Tup const & tup,error_info const & ei)3586         check( Tup const & tup, error_info const & ei ) noexcept
3587         {
3588             return peek<typename std::decay<A>::type>(tup, ei);
3589         }
3590 
3591         template <class A>
3592         template <class Tup>
3593         BOOST_LEAF_CONSTEXPR inline
3594         typename handler_argument_traits_defaults<A, false>::error_type *
3595         handler_argument_traits_defaults<A, false>::
check(Tup & tup,error_info const & ei)3596         check( Tup & tup, error_info const & ei ) noexcept
3597         {
3598             return peek<typename std::decay<A>::type>(tup, ei);
3599         }
3600 
3601         template <class Tup>
3602         BOOST_LEAF_CONSTEXPR inline
3603         std::exception const *
3604         handler_argument_traits<void>::
check(Tup const &,error_info const & ei)3605         check( Tup const &, error_info const & ei ) noexcept
3606         {
3607             return ei.exception();
3608         }
3609 
3610         template <class Tup, class... List>
3611         struct check_arguments;
3612 
3613         template <class Tup>
3614         struct check_arguments<Tup>
3615         {
checkboost::leaf::leaf_detail::check_arguments3616             BOOST_LEAF_CONSTEXPR static bool check( Tup const &, error_info const & )
3617             {
3618                 return true;
3619             }
3620         };
3621 
3622         template <class Tup, class Car, class... Cdr>
3623         struct check_arguments<Tup, Car, Cdr...>
3624         {
checkboost::leaf::leaf_detail::check_arguments3625             BOOST_LEAF_CONSTEXPR static bool check( Tup & tup, error_info const & ei ) noexcept
3626             {
3627                 return handler_argument_traits<Car>::check(tup, ei) && check_arguments<Tup, Cdr...>::check(tup, ei);
3628             }
3629         };
3630     }
3631 
3632     ////////////////////////////////////////
3633 
3634     namespace leaf_detail
3635     {
3636         template <class>
3637         struct handler_matches_any_error: std::false_type
3638         {
3639         };
3640 
3641         template <template<class...> class L>
3642         struct handler_matches_any_error<L<>>: std::true_type
3643         {
3644         };
3645 
3646         template <template<class...> class L, class Car, class... Cdr>
3647         struct handler_matches_any_error<L<Car, Cdr...>>
3648         {
3649             constexpr static bool value = handler_argument_traits<Car>::always_available && handler_matches_any_error<L<Cdr...>>::value;
3650         };
3651     }
3652 
3653     ////////////////////////////////////////
3654 
3655     namespace leaf_detail
3656     {
3657         template <class Tup, class... A>
check_handler_(Tup & tup,error_info const & ei,leaf_detail_mp11::mp_list<A...>)3658         BOOST_LEAF_CONSTEXPR inline bool check_handler_( Tup & tup, error_info const & ei, leaf_detail_mp11::mp_list<A...> ) noexcept
3659         {
3660             return check_arguments<Tup, A...>::check(tup, ei);
3661         }
3662 
3663         template <class R, class F, bool IsResult = is_result_type<R>::value, class FReturnType = fn_return_type<F>>
3664         struct handler_caller
3665         {
3666             template <class Tup, class... A>
callboost::leaf::leaf_detail::handler_caller3667             BOOST_LEAF_CONSTEXPR static R call( Tup & tup, error_info const & ei, F && f, leaf_detail_mp11::mp_list<A...> )
3668             {
3669                 return std::forward<F>(f)( handler_argument_traits<A>::get(tup, ei)... );
3670             }
3671         };
3672 
3673         template <template <class...> class Result, class... E, class F>
3674         struct handler_caller<Result<void, E...>, F, true, void>
3675         {
3676             using R = Result<void, E...>;
3677 
3678             template <class Tup, class... A>
callboost::leaf::leaf_detail::handler_caller3679             BOOST_LEAF_CONSTEXPR static R call( Tup & tup, error_info const & ei, F && f, leaf_detail_mp11::mp_list<A...> )
3680             {
3681                 std::forward<F>(f)( handler_argument_traits<A>::get(tup, ei)... );
3682                 return { };
3683             }
3684         };
3685 
3686         template <class T>
3687         struct is_tuple: std::false_type { };
3688 
3689         template <class... T>
3690         struct is_tuple<std::tuple<T...>>: std::true_type { };
3691 
3692         template <class... T>
3693         struct is_tuple<std::tuple<T...> &>: std::true_type { };
3694 
3695         template <class R, class Tup, class H>
3696         BOOST_LEAF_CONSTEXPR
3697         inline
3698         typename std::enable_if<!is_tuple<H>::value, R>::type
handle_error_(Tup & tup,error_info const & ei,H && h)3699         handle_error_( Tup & tup, error_info const & ei, H && h )
3700         {
3701             static_assert( handler_matches_any_error<fn_mp_args<H>>::value, "The last handler passed to handle_all must match any error." );
3702             return handler_caller<R, H>::call( tup, ei, std::forward<H>(h), fn_mp_args<H>{ } );
3703         }
3704 
3705         template <class R, class Tup, class Car, class... Cdr>
3706         BOOST_LEAF_CONSTEXPR inline
3707         typename std::enable_if<!is_tuple<Car>::value, R>::type
handle_error_(Tup & tup,error_info const & ei,Car && car,Cdr &&...cdr)3708         handle_error_( Tup & tup, error_info const & ei, Car && car, Cdr && ... cdr )
3709         {
3710             if( handler_matches_any_error<fn_mp_args<Car>>::value || check_handler_( tup, ei, fn_mp_args<Car>{ } ) )
3711                 return handler_caller<R, Car>::call( tup, ei, std::forward<Car>(car), fn_mp_args<Car>{ } );
3712             else
3713                 return handle_error_<R>( tup, ei, std::forward<Cdr>(cdr)...);
3714         }
3715 
3716         template <class R, class Tup, class HTup, size_t ... I>
3717         BOOST_LEAF_CONSTEXPR inline
3718         R
handle_error_tuple_(Tup & tup,error_info const & ei,leaf_detail_mp11::index_sequence<I...>,HTup && htup)3719         handle_error_tuple_( Tup & tup, error_info const & ei, leaf_detail_mp11::index_sequence<I...>, HTup && htup )
3720         {
3721             return handle_error_<R>(tup, ei, std::get<I>(std::forward<HTup>(htup))...);
3722         }
3723 
3724         template <class R, class Tup, class HTup, class... Cdr, size_t ... I>
3725         BOOST_LEAF_CONSTEXPR inline
3726         R
handle_error_tuple_(Tup & tup,error_info const & ei,leaf_detail_mp11::index_sequence<I...>,HTup && htup,Cdr &&...cdr)3727         handle_error_tuple_( Tup & tup, error_info const & ei, leaf_detail_mp11::index_sequence<I...>, HTup && htup, Cdr && ... cdr )
3728         {
3729             return handle_error_<R>(tup, ei, std::get<I>(std::forward<HTup>(htup))..., std::forward<Cdr>(cdr)...);
3730         }
3731 
3732         template <class R, class Tup, class H>
3733         BOOST_LEAF_CONSTEXPR inline
3734         typename std::enable_if<is_tuple<H>::value, R>::type
handle_error_(Tup & tup,error_info const & ei,H && h)3735         handle_error_( Tup & tup, error_info const & ei, H && h )
3736         {
3737             return handle_error_tuple_<R>(
3738                 tup,
3739                 ei,
3740                 leaf_detail_mp11::make_index_sequence<std::tuple_size<typename std::decay<H>::type>::value>(),
3741                 std::forward<H>(h));
3742         }
3743 
3744         template <class R, class Tup, class Car, class... Cdr>
3745         BOOST_LEAF_CONSTEXPR inline
3746         typename std::enable_if<is_tuple<Car>::value, R>::type
handle_error_(Tup & tup,error_info const & ei,Car && car,Cdr &&...cdr)3747         handle_error_( Tup & tup, error_info const & ei, Car && car, Cdr && ... cdr )
3748         {
3749             return handle_error_tuple_<R>(
3750                 tup,
3751                 ei,
3752                 leaf_detail_mp11::make_index_sequence<std::tuple_size<typename std::decay<Car>::type>::value>(),
3753                 std::forward<Car>(car),
3754                 std::forward<Cdr>(cdr)...);
3755         }
3756     }
3757 
3758     ////////////////////////////////////////
3759 
3760     template <class... E>
3761     template <class R, class... H>
3762     BOOST_LEAF_CONSTEXPR BOOST_LEAF_ALWAYS_INLINE
3763     R
3764     context<E...>::
handle_error(error_id id,H &&...h) const3765     handle_error( error_id id, H && ... h ) const
3766     {
3767         BOOST_LEAF_ASSERT(!is_active());
3768         return leaf_detail::handle_error_<R>(tup(), error_info(id), std::forward<H>(h)...);
3769     }
3770 
3771     template <class... E>
3772     template <class R, class... H>
3773     BOOST_LEAF_CONSTEXPR BOOST_LEAF_ALWAYS_INLINE
3774     R
3775     context<E...>::
handle_error(error_id id,H &&...h)3776     handle_error( error_id id, H && ... h )
3777     {
3778         BOOST_LEAF_ASSERT(!is_active());
3779         return leaf_detail::handle_error_<R>(tup(), error_info(id), std::forward<H>(h)...);
3780     }
3781 
3782     ////////////////////////////////////////
3783 
3784 #ifdef BOOST_LEAF_NO_EXCEPTIONS
3785 
3786     template <class TryBlock, class... H>
3787     BOOST_LEAF_CONSTEXPR inline
3788     typename std::decay<decltype(std::declval<TryBlock>()().value())>::type
try_handle_all(TryBlock && try_block,H &&...h)3789     try_handle_all( TryBlock && try_block, H && ... h ) noexcept
3790     {
3791         static_assert(is_result_type<decltype(std::declval<TryBlock>()())>::value, "The return type of the try_block passed to a try_handle_all function must be registered with leaf::is_result_type");
3792         context_type_from_handlers<H...> ctx;
3793         auto active_context = activate_context(ctx);
3794         if( auto r = std::forward<TryBlock>(try_block)() )
3795             return r.value();
3796         else
3797         {
3798             error_id id = r.error();
3799             ctx.deactivate();
3800             using R = typename std::decay<decltype(std::declval<TryBlock>()().value())>::type;
3801             return ctx.template handle_error<R>(std::move(id), std::forward<H>(h)...);
3802         }
3803     }
3804 
3805     template <class TryBlock, class... H>
3806     BOOST_LEAF_NODISCARD BOOST_LEAF_CONSTEXPR inline
3807     typename std::decay<decltype(std::declval<TryBlock>()())>::type
try_handle_some(TryBlock && try_block,H &&...h)3808     try_handle_some( TryBlock && try_block, H && ... h ) noexcept
3809     {
3810         static_assert(is_result_type<decltype(std::declval<TryBlock>()())>::value, "The return type of the try_block passed to a try_handle_some function must be registered with leaf::is_result_type");
3811         context_type_from_handlers<H...> ctx;
3812         auto active_context = activate_context(ctx);
3813         if( auto r = std::forward<TryBlock>(try_block)() )
3814             return r;
3815         else
3816         {
3817             error_id id = r.error();
3818             ctx.deactivate();
3819             using R = typename std::decay<decltype(std::declval<TryBlock>()())>::type;
3820             auto rr = ctx.template handle_error<R>(std::move(id), std::forward<H>(h)..., [&r]()->R { return std::move(r); });
3821             if( !rr )
3822                 ctx.propagate();
3823             return rr;
3824         }
3825     }
3826 
3827     template <class TryBlock, class... H>
3828     BOOST_LEAF_CONSTEXPR inline
3829     decltype(std::declval<TryBlock>()())
try_catch(TryBlock && try_block,H &&...)3830     try_catch( TryBlock && try_block, H && ... ) noexcept
3831     {
3832         static_assert(sizeof(context_type_from_handlers<H...>) > 0,
3833             "When exceptions are disabled, try_catch can't fail and has no use for the handlers, but this ensures that the supplied H... types are compatible.");
3834         return std::forward<TryBlock>(try_block)();
3835     }
3836 
3837 #else
3838 
3839     namespace leaf_detail
3840     {
3841         template <class Ctx, class TryBlock, class... H>
3842         decltype(std::declval<TryBlock>()())
try_catch_(Ctx & ctx,TryBlock && try_block,H &&...h)3843         try_catch_( Ctx & ctx, TryBlock && try_block, H && ... h )
3844         {
3845             using namespace leaf_detail;
3846             BOOST_LEAF_ASSERT(ctx.is_active());
3847             using R = decltype(std::declval<TryBlock>()());
3848             try
3849             {
3850                 return std::forward<TryBlock>(try_block)();
3851             }
3852             catch( capturing_exception const & cap )
3853             {
3854                 try
3855                 {
3856                     cap.unload_and_rethrow_original_exception();
3857                 }
3858                 catch( std::exception & ex )
3859                 {
3860                     ctx.deactivate();
3861                     return handle_error_<R>(ctx.tup(), error_info(&ex), std::forward<H>(h)...,
3862                         []() -> R { throw; } );
3863                 }
3864                 catch(...)
3865                 {
3866                     ctx.deactivate();
3867                     return handle_error_<R>(ctx.tup(), error_info(nullptr), std::forward<H>(h)...,
3868                         []() -> R { throw; } );
3869                 }
3870             }
3871             catch( std::exception & ex )
3872             {
3873                 ctx.deactivate();
3874                 return handle_error_<R>(ctx.tup(), error_info(&ex), std::forward<H>(h)...,
3875                     []() -> R { throw; } );
3876             }
3877             catch(...)
3878             {
3879                 ctx.deactivate();
3880                 return handle_error_<R>(ctx.tup(), error_info(nullptr), std::forward<H>(h)...,
3881                     []() -> R { throw; } );
3882             }
3883         }
3884     }
3885 
3886     template <class TryBlock, class... H>
3887     BOOST_LEAF_CONSTEXPR inline
3888     typename std::decay<decltype(std::declval<TryBlock>()().value())>::type
try_handle_all(TryBlock && try_block,H &&...h)3889     try_handle_all( TryBlock && try_block, H && ... h )
3890     {
3891         static_assert(is_result_type<decltype(std::declval<TryBlock>()())>::value, "The return type of the try_block passed to a try_handle_all function must be registered with leaf::is_result_type");
3892         context_type_from_handlers<H...> ctx;
3893         auto active_context = activate_context(ctx);
3894         if( auto r = leaf_detail::try_catch_(
3895                 ctx,
3896                 [&]
3897                 {
3898                     return std::forward<TryBlock>(try_block)();
3899                 },
3900                 std::forward<H>(h)...) )
3901             return r.value();
3902         else
3903         {
3904             error_id id = r.error();
3905             if( ctx.is_active() )
3906                 ctx.deactivate();
3907             using R = typename std::decay<decltype(std::declval<TryBlock>()().value())>::type;
3908             return ctx.template handle_error<R>(std::move(id), std::forward<H>(h)...);
3909         }
3910     }
3911 
3912     template <class TryBlock, class... H>
3913     BOOST_LEAF_NODISCARD BOOST_LEAF_CONSTEXPR inline
3914     typename std::decay<decltype(std::declval<TryBlock>()())>::type
try_handle_some(TryBlock && try_block,H &&...h)3915     try_handle_some( TryBlock && try_block, H && ... h )
3916     {
3917         static_assert(is_result_type<decltype(std::declval<TryBlock>()())>::value, "The return type of the try_block passed to a try_handle_some function must be registered with leaf::is_result_type");
3918         context_type_from_handlers<H...> ctx;
3919         auto active_context = activate_context(ctx);
3920         if( auto r = leaf_detail::try_catch_(
3921                 ctx,
3922                 [&]
3923                 {
3924                     return std::forward<TryBlock>(try_block)();
3925                 },
3926                 std::forward<H>(h)...) )
3927             return r;
3928         else
3929         {
3930             error_id id = r.error();
3931             if( ctx.is_active() )
3932                 ctx.deactivate();
3933             using R = typename std::decay<decltype(std::declval<TryBlock>()())>::type;
3934             auto rr = ctx.template handle_error<R>(std::move(id), std::forward<H>(h)..., [&r]()->R { return std::move(r); });
3935             if( !rr )
3936                 ctx.propagate();
3937             return rr;
3938         }
3939     }
3940 
3941     template <class TryBlock, class... H>
3942     BOOST_LEAF_CONSTEXPR inline
3943     decltype(std::declval<TryBlock>()())
try_catch(TryBlock && try_block,H &&...h)3944     try_catch( TryBlock && try_block, H && ... h )
3945     {
3946         context_type_from_handlers<H...> ctx;
3947         auto active_context = activate_context(ctx);
3948         return leaf_detail::try_catch_(
3949             ctx,
3950             [&]
3951             {
3952                 return std::forward<TryBlock>(try_block)();
3953             },
3954             std::forward<H>(h)...);
3955     }
3956 
3957 #endif
3958 
3959 } }
3960 
3961 // Boost Exception Integration
3962 
3963 namespace boost { class exception; }
3964 namespace boost { template <class Tag,class T> class error_info; }
3965 namespace boost { namespace exception_detail { template <class ErrorInfo> struct get_info; } }
3966 
3967 namespace boost { namespace leaf {
3968 
3969     namespace leaf_detail
3970     {
3971         template <class T>
3972         struct match_enum_type;
3973 
3974         template <class Tag, class T>
3975         struct match_enum_type<boost::error_info<Tag, T>>
3976         {
3977             using type = T;
3978         };
3979 
3980         template <class Ex>
get_exception(error_info const & ei)3981         BOOST_LEAF_CONSTEXPR inline Ex * get_exception( error_info const & ei )
3982         {
3983             return dynamic_cast<Ex *>(ei.exception());
3984         }
3985 
3986         template <class, class T>
3987         struct dependent_type { using type = T; };
3988 
3989         template <class Dep, class T>
3990         using dependent_type_t = typename dependent_type<Dep, T>::type;
3991 
3992         template <class Tag, class T>
3993         struct handler_argument_traits<boost::error_info<Tag, T>>
3994         {
3995             using error_type = void;
3996             constexpr static bool always_available = false;
3997 
3998             template <class Tup>
checkboost::leaf::leaf_detail::handler_argument_traits3999             BOOST_LEAF_CONSTEXPR static T * check( Tup & tup, error_info const & ei ) noexcept
4000             {
4001                 using boost_exception = dependent_type_t<T, boost::exception>;
4002                 if( auto * be = get_exception<boost_exception>(ei) )
4003                     return exception_detail::get_info<boost::error_info<Tag, T>>::get(*be);
4004                 else
4005                     return 0;
4006             }
4007 
4008             template <class Tup>
getboost::leaf::leaf_detail::handler_argument_traits4009             BOOST_LEAF_CONSTEXPR static boost::error_info<Tag, T> get( Tup const & tup, error_info const & ei ) noexcept
4010             {
4011                 return boost::error_info<Tag, T>(*check(tup, ei));
4012             }
4013         };
4014 
4015         template <class Tag, class T> struct handler_argument_traits<boost::error_info<Tag, T> const &>: handler_argument_traits_require_by_value<boost::error_info<Tag, T>> { };
4016         template <class Tag, class T> struct handler_argument_traits<boost::error_info<Tag, T> const *>: handler_argument_traits_require_by_value<boost::error_info<Tag, T>> { };
4017         template <class Tag, class T> struct handler_argument_traits<boost::error_info<Tag, T> &>: handler_argument_traits_require_by_value<boost::error_info<Tag, T>> { };
4018         template <class Tag, class T> struct handler_argument_traits<boost::error_info<Tag, T> *>: handler_argument_traits_require_by_value<boost::error_info<Tag, T>> { };
4019     }
4020 
4021 } }
4022 
4023 #endif
4024 // <<< #include <boost/leaf/handle_errors.hpp>
4025 #line 15 "../../include/boost/leaf/detail/all.hpp"
4026 // >>> #include <boost/leaf/pred.hpp>
4027 #line 1 "boost/leaf/pred.hpp"
4028 #ifndef BOOST_LEAF_PRED_HPP_INCLUDED
4029 #define BOOST_LEAF_PRED_HPP_INCLUDED
4030 
4031 // Copyright (c) 2018-2020 Emil Dotchevski and Reverge Studios, Inc.
4032 
4033 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4034 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
4035 
4036 #ifndef BOOST_LEAF_ENABLE_WARNINGS
4037 #   if defined(__clang__)
4038 #       pragma clang system_header
4039 #   elif (__GNUC__*100+__GNUC_MINOR__>301)
4040 #       pragma GCC system_header
4041 #   elif defined(_MSC_VER)
4042 #       pragma warning(push,1)
4043 #   endif
4044 #endif
4045 
4046 
4047 #if __cplusplus >= 201703L
4048 #   define BOOST_LEAF_MATCH_ARGS(et,v1,v) auto v1, auto... v
4049 #else
4050 #   define BOOST_LEAF_MATCH_ARGS(et,v1,v) typename leaf_detail::et::type v1, typename leaf_detail::et::type... v
4051 #endif
4052 #define BOOST_LEAF_ESC(...) __VA_ARGS__
4053 
4054 namespace boost { namespace leaf {
4055 
4056     namespace leaf_detail
4057     {
4058 #if __cplusplus >= 201703L
4059         template <class MatchType, class T>
cmp_value_pack(MatchType const & e,bool (* P)(T)noexcept)4060         BOOST_LEAF_CONSTEXPR BOOST_LEAF_ALWAYS_INLINE bool cmp_value_pack( MatchType const & e, bool (*P)(T) noexcept ) noexcept
4061         {
4062             BOOST_LEAF_ASSERT(P != 0);
4063             return P(e);
4064         }
4065 
4066         template <class MatchType, class T>
cmp_value_pack(MatchType const & e,bool (* P)(T))4067         BOOST_LEAF_CONSTEXPR BOOST_LEAF_ALWAYS_INLINE bool cmp_value_pack( MatchType const & e, bool (*P)(T) )
4068         {
4069             BOOST_LEAF_ASSERT(P != 0);
4070             return P(e);
4071         }
4072 #endif
4073 
4074         template <class MatchType, class V>
cmp_value_pack(MatchType const & e,V v)4075         BOOST_LEAF_CONSTEXPR BOOST_LEAF_ALWAYS_INLINE bool cmp_value_pack( MatchType const & e, V v )
4076         {
4077             return e == v;
4078         }
4079 
4080         template <class MatchType, class VCar, class... VCdr>
cmp_value_pack(MatchType const & e,VCar car,VCdr...cdr)4081         BOOST_LEAF_CONSTEXPR BOOST_LEAF_ALWAYS_INLINE bool cmp_value_pack( MatchType const & e, VCar car, VCdr ... cdr )
4082         {
4083             return cmp_value_pack(e, car) || cmp_value_pack(e, cdr...);
4084         }
4085     }
4086 
4087     ////////////////////////////////////////
4088 
4089     template <class E, class Enum = E>
4090     struct condition
4091     {
4092         static_assert(std::is_error_condition_enum<Enum>::value || std::is_error_code_enum<Enum>::value, "leaf::condition<E, Enum> requires Enum to be registered either with std::is_error_condition_enum or std::is_error_code_enum.");
4093     };
4094 
4095     template <class Enum>
4096     struct condition<Enum, Enum>
4097     {
4098         static_assert(std::is_error_condition_enum<Enum>::value || std::is_error_code_enum<Enum>::value, "leaf::condition<Enum> requires Enum to be registered either with std::is_error_condition_enum or std::is_error_code_enum.");
4099     };
4100 
4101 #if __cplusplus >= 201703L
4102     template <class ErrorCodeEnum>
category(std::error_code const & ec)4103     BOOST_LEAF_CONSTEXPR inline bool category( std::error_code const & ec )
4104     {
4105         static_assert(std::is_error_code_enum<ErrorCodeEnum>::value, "leaf::category requires an error code enum");
4106         return &ec.category() == &std::error_code(ErrorCodeEnum{}).category();
4107     }
4108 #endif
4109 
4110     ////////////////////////////////////////
4111 
4112     namespace leaf_detail
4113     {
4114         template <class T>
4115         struct match_enum_type
4116         {
4117             using type = T;
4118         };
4119 
4120         template <class Enum>
4121         struct match_enum_type<condition<Enum, Enum>>
4122         {
4123             using type = Enum;
4124         };
4125 
4126         template <class E, class Enum>
4127         struct match_enum_type<condition<E, Enum>>
4128         {
4129             static_assert(sizeof(Enum) == 0, "leaf::condition<E, Enum> should be used with leaf::match_value<>, not with leaf::match<>");
4130         };
4131     }
4132 
4133     template <class E, BOOST_LEAF_MATCH_ARGS(match_enum_type<E>, V1, V)>
4134     struct match
4135     {
4136         using error_type = E;
4137         E matched;
4138 
4139         template <class T>
evaluateboost::leaf::match4140         BOOST_LEAF_CONSTEXPR static bool evaluate(T && x)
4141         {
4142             return leaf_detail::cmp_value_pack(std::forward<T>(x), V1, V...);
4143         }
4144     };
4145 
4146     template <class Enum, BOOST_LEAF_MATCH_ARGS(BOOST_LEAF_ESC(match_enum_type<condition<Enum, Enum>>), V1, V)>
4147     struct match<condition<Enum, Enum>, V1, V...>
4148     {
4149         using error_type = std::error_code;
4150         std::error_code const & matched;
4151 
evaluateboost::leaf::match4152         BOOST_LEAF_CONSTEXPR static bool evaluate(std::error_code const & e) noexcept
4153         {
4154             return leaf_detail::cmp_value_pack(e, V1, V...);
4155         }
4156     };
4157 
4158     template <class E, BOOST_LEAF_MATCH_ARGS(match_enum_type<E>, V1, V)>
4159     struct is_predicate<match<E, V1, V...>>: std::true_type
4160     {
4161     };
4162 
4163     ////////////////////////////////////////
4164 
4165     namespace leaf_detail
4166     {
4167         template <class E>
4168         struct match_value_enum_type
4169         {
4170             using type = typename std::remove_reference<decltype(std::declval<E>().value)>::type;
4171         };
4172 
4173         template <class E, class Enum>
4174         struct match_value_enum_type<condition<E, Enum>>
4175         {
4176             using type = Enum;
4177         };
4178 
4179         template <class Enum>
4180         struct match_value_enum_type<condition<Enum, Enum>>
4181         {
4182             static_assert(sizeof(Enum)==0, "leaf::condition<Enum> should be used with leaf::match<>, not with leaf::match_value<>");
4183         };
4184     }
4185 
4186     template <class E, BOOST_LEAF_MATCH_ARGS(match_value_enum_type<E>, V1, V)>
4187     struct match_value
4188     {
4189         using error_type = E;
4190         E const & matched;
4191 
evaluateboost::leaf::match_value4192         BOOST_LEAF_CONSTEXPR static bool evaluate(E const & e) noexcept
4193         {
4194             return leaf_detail::cmp_value_pack(e.value, V1, V...);
4195         }
4196     };
4197 
4198     template <class E, class Enum, BOOST_LEAF_MATCH_ARGS(BOOST_LEAF_ESC(match_value_enum_type<condition<E, Enum>>), V1, V)>
4199     struct match_value<condition<E, Enum>, V1, V...>
4200     {
4201         using error_type = E;
4202         E const & matched;
4203 
evaluateboost::leaf::match_value4204         BOOST_LEAF_CONSTEXPR static bool evaluate(E const & e)
4205         {
4206             return leaf_detail::cmp_value_pack(e.value, V1, V...);
4207         }
4208     };
4209 
4210     template <class E, BOOST_LEAF_MATCH_ARGS(match_value_enum_type<E>, V1, V)>
4211     struct is_predicate<match_value<E, V1, V...>>: std::true_type
4212     {
4213     };
4214 
4215     ////////////////////////////////////////
4216 
4217 #if __cplusplus >= 201703L
4218     template <auto, auto, auto...>
4219     struct match_member;
4220 
4221     template <class T, class E, T E::* P, auto V1, auto... V>
4222     struct match_member<P, V1, V...>
4223     {
4224         using error_type = E;
4225         E const & matched;
4226 
evaluateboost::leaf::match_member4227         BOOST_LEAF_CONSTEXPR static bool evaluate(E const & e) noexcept
4228         {
4229             return leaf_detail::cmp_value_pack(e.*P, V1, V...);
4230         }
4231     };
4232 
4233     template <auto P, auto V1, auto... V>
4234     struct is_predicate<match_member<P, V1, V...>>: std::true_type
4235     {
4236     };
4237 #endif
4238 
4239     ////////////////////////////////////////
4240 
4241     template <class P>
4242     struct if_not
4243     {
4244         using error_type = typename P::error_type;;
4245         decltype(std::declval<P>().matched) matched;
4246 
4247         template <class E>
evaluateboost::leaf::if_not4248         BOOST_LEAF_CONSTEXPR static bool evaluate(E && e) noexcept
4249         {
4250             return !P::evaluate(std::forward<E>(e));
4251         }
4252     };
4253 
4254     template <class P>
4255     struct is_predicate<if_not<P>>: std::true_type
4256     {
4257     };
4258 
4259     ////////////////////////////////////////
4260 
4261 
4262 #ifndef BOOST_LEAF_NO_EXCEPTIONS
4263 
4264     namespace leaf_detail
4265     {
4266         template <class Ex>
check_exception_pack(std::exception const & ex,Ex const *)4267         BOOST_LEAF_CONSTEXPR inline bool check_exception_pack( std::exception const & ex, Ex const * ) noexcept
4268         {
4269             return dynamic_cast<Ex const *>(&ex)!=0;
4270         }
4271 
4272         template <class Ex, class... ExRest>
check_exception_pack(std::exception const & ex,Ex const *,ExRest const * ...ex_rest)4273         BOOST_LEAF_CONSTEXPR inline bool check_exception_pack( std::exception const & ex, Ex const *, ExRest const * ... ex_rest ) noexcept
4274         {
4275             return dynamic_cast<Ex const *>(&ex)!=0 || check_exception_pack(ex, ex_rest...);
4276         }
4277 
check_exception_pack(std::exception const &)4278         BOOST_LEAF_CONSTEXPR inline bool check_exception_pack( std::exception const & ) noexcept
4279         {
4280             return true;
4281         }
4282     }
4283 
4284     template <class... Ex>
4285     struct catch_
4286     {
4287         using error_type = void;
4288         std::exception const & matched;
4289 
evaluateboost::leaf::catch_4290         BOOST_LEAF_CONSTEXPR static bool evaluate(std::exception const & ex) noexcept
4291         {
4292             return leaf_detail::check_exception_pack(ex, static_cast<Ex const *>(0)...);
4293         }
4294     };
4295 
4296     template <class Ex>
4297     struct catch_<Ex>
4298     {
4299         using error_type = void;
4300         Ex const & matched;
4301 
evaluateboost::leaf::catch_4302         BOOST_LEAF_CONSTEXPR static Ex const * evaluate(std::exception const & ex) noexcept
4303         {
4304             return dynamic_cast<Ex const *>(&ex);
4305         }
4306 
catch_boost::leaf::catch_4307         explicit catch_( std::exception const & ex ):
4308             matched(*dynamic_cast<Ex const *>(&ex))
4309         {
4310         }
4311     };
4312 
4313     template <class... Ex>
4314     struct is_predicate<catch_<Ex...>>: std::true_type
4315     {
4316     };
4317 
4318 #endif
4319 
4320 } }
4321 
4322 #endif
4323 // <<< #include <boost/leaf/pred.hpp>
4324 #line 17 "../../include/boost/leaf/detail/all.hpp"
4325 // >>> #include <boost/leaf/result.hpp>
4326 #line 1 "boost/leaf/result.hpp"
4327 #ifndef BOOST_LEAF_RESULT_HPP_INCLUDED
4328 #define BOOST_LEAF_RESULT_HPP_INCLUDED
4329 
4330 // Copyright (c) 2018-2020 Emil Dotchevski and Reverge Studios, Inc.
4331 
4332 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4333 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
4334 
4335 #ifndef BOOST_LEAF_ENABLE_WARNINGS
4336 #   if defined(__clang__)
4337 #       pragma clang system_header
4338 #   elif (__GNUC__*100+__GNUC_MINOR__>301)
4339 #       pragma GCC system_header
4340 #   elif defined(_MSC_VER)
4341 #       pragma warning(push,1)
4342 #   endif
4343 #endif
4344 
4345 #include <climits>
4346 
4347 namespace boost { namespace leaf {
4348 
4349     class bad_result:
4350         public std::exception,
4351         public error_id
4352     {
what() const4353         char const * what() const noexcept final override
4354         {
4355             return "boost::leaf::bad_result";
4356         }
4357 
4358     public:
4359 
bad_result(error_id id)4360         explicit bad_result( error_id id ) noexcept:
4361             error_id(id)
4362         {
4363             BOOST_LEAF_ASSERT(value());
4364         }
4365     };
4366 
4367     ////////////////////////////////////////
4368 
4369     namespace leaf_detail
4370     {
4371         template <class T>
4372         struct stored
4373         {
4374             using type = T;
4375             using value_type = T;
4376             using value_type_const = T const;
4377             using value_cref = T const &;
4378             using value_ref = T &;
4379             using value_rv_cref = T const &&;
4380             using value_rv_ref = T &&;
4381         };
4382 
4383         template <class T>
4384         struct stored<T &>
4385         {
4386             using type = std::reference_wrapper<T>;
4387             using value_type_const = T;
4388             using value_type = T;
4389             using value_ref = T &;
4390             using value_cref = T &;
4391             using value_rv_ref = T &;
4392             using value_rv_cref = T &;
4393         };
4394 
4395         class result_discriminant
4396         {
4397             unsigned state_;
4398 
4399         public:
4400 
4401             enum kind_t
4402             {
4403                 no_error = 0,
4404                 err_id = 1,
4405                 ctx_ptr = 2,
4406                 val = 3
4407             };
4408 
result_discriminant(error_id id)4409             explicit result_discriminant( error_id id ) noexcept:
4410                 state_(id.value())
4411             {
4412                 BOOST_LEAF_ASSERT(state_==0 || (state_&3)==1);
4413             }
4414 
4415             struct kind_val { };
result_discriminant(kind_val)4416             explicit result_discriminant( kind_val ) noexcept:
4417                 state_(val)
4418             {
4419             }
4420 
4421             struct kind_ctx_ptr { };
result_discriminant(kind_ctx_ptr)4422             explicit result_discriminant( kind_ctx_ptr ) noexcept:
4423                 state_(ctx_ptr)
4424             {
4425             }
4426 
kind() const4427             kind_t kind() const noexcept
4428             {
4429                 return kind_t(state_&3);
4430             }
4431 
get_error_id() const4432             error_id get_error_id() const noexcept
4433             {
4434                 BOOST_LEAF_ASSERT(kind()==no_error || kind()==err_id);
4435                 return make_error_id(state_);
4436             }
4437         };
4438     }
4439 
4440     ////////////////////////////////////////
4441 
4442     template <class T>
4443     class result
4444     {
4445         template <class U>
4446         friend class result;
4447 
4448         using result_discriminant = leaf_detail::result_discriminant;
4449 
4450         struct error_result
4451         {
4452             error_result( error_result && ) = default;
4453             error_result( error_result const & ) = delete;
4454             error_result & operator=( error_result const & ) = delete;
4455 
4456             result & r_;
4457 
error_resultboost::leaf::result::error_result4458             error_result( result & r ) noexcept:
4459                 r_(r)
4460             {
4461             }
4462 
4463             template <class U>
operator result<U>boost::leaf::result::error_result4464             operator result<U>() noexcept
4465             {
4466                 switch(r_.what_.kind())
4467                 {
4468                 case result_discriminant::val:
4469                     return result<U>(error_id());
4470                 case result_discriminant::ctx_ptr:
4471                     return result<U>(std::move(r_.ctx_));
4472                 default:
4473                     return result<U>(std::move(r_.what_));
4474                 }
4475             }
4476 
operator error_idboost::leaf::result::error_result4477             operator error_id() noexcept
4478             {
4479                 switch(r_.what_.kind())
4480                 {
4481                 case result_discriminant::val:
4482                     return error_id();
4483                 case result_discriminant::ctx_ptr:
4484                 {
4485                     error_id captured_id = r_.ctx_->propagate_captured_errors();
4486                     leaf_detail::id_factory<>::current_id = captured_id.value();
4487                     return captured_id;
4488                 }
4489                 default:
4490                     return r_.what_.get_error_id();
4491                 }
4492             }
4493         };
4494 
4495         using stored_type = typename leaf_detail::stored<T>::type;
4496         using value_type = typename leaf_detail::stored<T>::value_type;
4497         using value_type_const = typename leaf_detail::stored<T>::value_type_const;
4498         using value_ref = typename leaf_detail::stored<T>::value_ref;
4499         using value_cref = typename leaf_detail::stored<T>::value_cref;
4500         using value_rv_ref = typename leaf_detail::stored<T>::value_rv_ref;
4501         using value_rv_cref = typename leaf_detail::stored<T>::value_rv_cref;
4502 
4503         union
4504         {
4505             stored_type stored_;
4506             context_ptr ctx_;
4507         };
4508 
4509         result_discriminant what_;
4510 
destroy() const4511         void destroy() const noexcept
4512         {
4513             switch(this->what_.kind())
4514             {
4515             case result_discriminant::val:
4516                 stored_.~stored_type();
4517                 break;
4518             case result_discriminant::ctx_ptr:
4519                 BOOST_LEAF_ASSERT(!ctx_ || ctx_->captured_id_);
4520                 ctx_.~context_ptr();
4521             default:
4522                 break;
4523             }
4524         }
4525 
4526         template <class U>
move_from(result<U> && x)4527         result_discriminant move_from( result<U> && x ) noexcept
4528         {
4529             auto x_what = x.what_;
4530             switch(x_what.kind())
4531             {
4532             case result_discriminant::val:
4533                 (void) new(&stored_) stored_type(std::move(x.stored_));
4534                 break;
4535             case result_discriminant::ctx_ptr:
4536                 BOOST_LEAF_ASSERT(!x.ctx_ || x.ctx_->captured_id_);
4537                 (void) new(&ctx_) context_ptr(std::move(x.ctx_));
4538             default:
4539                 break;
4540             }
4541             return x_what;
4542         }
4543 
result(result_discriminant && what)4544         result( result_discriminant && what ) noexcept:
4545             what_(std::move(what))
4546         {
4547             BOOST_LEAF_ASSERT(what_.kind()==result_discriminant::err_id || what_.kind()==result_discriminant::no_error);
4548         }
4549 
get_error_id() const4550         error_id get_error_id() const noexcept
4551         {
4552             BOOST_LEAF_ASSERT(what_.kind()!=result_discriminant::val);
4553             return what_.kind()==result_discriminant::ctx_ptr ? ctx_->captured_id_ : what_.get_error_id();
4554         }
4555 
4556         static int init_T_with_U( T && );
4557 
4558     protected:
4559 
enforce_value_state() const4560         void enforce_value_state() const
4561         {
4562             if( what_.kind() != result_discriminant::val )
4563                 ::boost::leaf::throw_exception(bad_result(get_error_id()));
4564         }
4565 
4566     public:
4567 
result(result && x)4568         result( result && x ) noexcept:
4569             what_(move_from(std::move(x)))
4570         {
4571         }
4572 
4573         template <class U>
result(result<U> && x)4574         result( result<U> && x ) noexcept:
4575             what_(move_from(std::move(x)))
4576 
4577         {
4578         }
4579 
result()4580         result():
4581             stored_(stored_type()),
4582             what_(result_discriminant::kind_val{})
4583         {
4584         }
4585 
result(value_type && v)4586         result( value_type && v ) noexcept:
4587             stored_(std::forward<value_type>(v)),
4588             what_(result_discriminant::kind_val{})
4589         {
4590         }
4591 
result(value_type const & v)4592         result( value_type const & v ):
4593             stored_(v),
4594             what_(result_discriminant::kind_val{})
4595         {
4596         }
4597 
result(error_id err)4598         result( error_id err ) noexcept:
4599             what_(err)
4600         {
4601         }
4602 
4603         // SFINAE: T can be initialized with a U, e.g. result<std::string>("literal").
4604         // Not using is_constructible on purpose, bug with COMPILER=/usr/bin/clang++ CXXSTD=11 clang 3.3.
4605         template <class U>
result(U && u,decltype(init_T_with_U (std::forward<U> (u)))* =0)4606         result( U && u, decltype(init_T_with_U(std::forward<U>(u))) * = 0 ):
4607             stored_(std::forward<U>(u)),
4608             what_(result_discriminant::kind_val{})
4609         {
4610         }
4611 
result(std::error_code const & ec)4612         result( std::error_code const & ec ) noexcept:
4613             what_(error_id(ec))
4614         {
4615         }
4616 
4617         template <class Enum>
result(Enum e,typename std::enable_if<std::is_error_code_enum<Enum>::value,int>::type * =0)4618         result( Enum e, typename std::enable_if<std::is_error_code_enum<Enum>::value, int>::type * = 0 ) noexcept:
4619             what_(error_id(e))
4620         {
4621         }
4622 
result(context_ptr && ctx)4623         result( context_ptr && ctx ) noexcept:
4624             ctx_(std::move(ctx)),
4625             what_(result_discriminant::kind_ctx_ptr{})
4626         {
4627         }
4628 
~result()4629         ~result() noexcept
4630         {
4631             destroy();
4632         }
4633 
operator =(result && x)4634         result & operator=( result && x ) noexcept
4635         {
4636             destroy();
4637             what_ = move_from(std::move(x));
4638             return *this;
4639         }
4640 
4641         template <class U>
operator =(result<U> && x)4642         result & operator=( result<U> && x ) noexcept
4643         {
4644             destroy();
4645             what_ = move_from(std::move(x));
4646             return *this;
4647         }
4648 
operator bool() const4649         explicit operator bool() const noexcept
4650         {
4651             return what_.kind() == result_discriminant::val;
4652         }
4653 
value() const4654         value_cref value() const &
4655         {
4656             enforce_value_state();
4657             return stored_;
4658         }
4659 
value()4660         value_ref value() &
4661         {
4662             enforce_value_state();
4663             return stored_;
4664         }
4665 
value() const4666         value_rv_cref value() const &&
4667         {
4668             enforce_value_state();
4669             return std::move(stored_);
4670         }
4671 
value()4672         value_rv_ref value() &&
4673         {
4674             enforce_value_state();
4675             return std::move(stored_);
4676         }
4677 
operator *() const4678         value_cref operator*() const &
4679         {
4680             return value();
4681         }
4682 
operator *()4683         value_ref operator*() &
4684         {
4685             return value();
4686         }
4687 
operator *() const4688         value_rv_cref operator*() const &&
4689         {
4690             return value();
4691         }
4692 
operator *()4693         value_rv_ref operator*() &&
4694         {
4695             return value();
4696         }
4697 
operator ->() const4698         value_type_const * operator->() const
4699         {
4700             return &value();
4701         }
4702 
operator ->()4703         value_type * operator->()
4704         {
4705             return &value();
4706         }
4707 
error()4708         error_result error() noexcept
4709         {
4710             return error_result{*this};
4711         }
4712 
4713         template <class... Item>
load(Item &&...item)4714         error_id load( Item && ... item ) noexcept
4715         {
4716             return error_id(error()).load(std::forward<Item>(item)...);
4717         }
4718     };
4719 
4720     ////////////////////////////////////////
4721 
4722     namespace leaf_detail
4723     {
4724         struct void_ { };
4725     }
4726 
4727     template <>
4728     class result<void>:
4729         result<leaf_detail::void_>
4730     {
4731         using result_discriminant = leaf_detail::result_discriminant;
4732         using void_ = leaf_detail::void_;
4733         using base = result<void_>;
4734 
4735         template <class U>
4736         friend class result;
4737 
result(result_discriminant && what)4738         result( result_discriminant && what ) noexcept:
4739             base(std::move(what))
4740         {
4741         }
4742 
4743     public:
4744 
4745         using value_type = void;
4746 
result(result && x)4747         result( result && x ) noexcept:
4748             base(std::move(x))
4749         {
4750         }
4751 
result()4752         result() noexcept
4753         {
4754         }
4755 
result(error_id err)4756         result( error_id err ) noexcept:
4757             base(err)
4758         {
4759         }
4760 
result(std::error_code const & ec)4761         result( std::error_code const & ec ) noexcept:
4762             base(ec)
4763         {
4764         }
4765 
4766         template <class Enum>
result(Enum e,typename std::enable_if<std::is_error_code_enum<Enum>::value,Enum>::type * =0)4767         result( Enum e, typename std::enable_if<std::is_error_code_enum<Enum>::value, Enum>::type * = 0 ) noexcept:
4768             base(e)
4769         {
4770         }
4771 
result(context_ptr && ctx)4772         result( context_ptr && ctx ) noexcept:
4773             base(std::move(ctx))
4774         {
4775         }
4776 
~result()4777         ~result() noexcept
4778         {
4779         }
4780 
value() const4781         void value() const
4782         {
4783             base::enforce_value_state();
4784         }
4785 
4786         using base::operator=;
4787         using base::operator bool;
4788         using base::get_error_id;
4789         using base::error;
4790         using base::load;
4791     };
4792 
4793     ////////////////////////////////////////
4794 
4795     template <class R>
4796     struct is_result_type;
4797 
4798     template <class T>
4799     struct is_result_type<result<T>>: std::true_type
4800     {
4801     };
4802 
4803 } }
4804 
4805 #endif
4806 // <<< #include <boost/leaf/result.hpp>
4807 #line 18 "../../include/boost/leaf/detail/all.hpp"
4808 
4809 #endif
4810