1  
//
1  
//
2  
// Copyright (c) 2025 Vinnie Falco (vinnie dot falco at gmail dot com)
2  
// Copyright (c) 2025 Vinnie Falco (vinnie dot falco at gmail dot com)
3  
//
3  
//
4  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
4  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
5  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6  
//
6  
//
7  
// Official repository: https://github.com/cppalliance/capy
7  
// Official repository: https://github.com/cppalliance/capy
8  
//
8  
//
9  

9  

10  
#ifndef BOOST_CAPY_DETAIL_RUN_CALLBACKS_HPP
10  
#ifndef BOOST_CAPY_DETAIL_RUN_CALLBACKS_HPP
11  
#define BOOST_CAPY_DETAIL_RUN_CALLBACKS_HPP
11  
#define BOOST_CAPY_DETAIL_RUN_CALLBACKS_HPP
12  

12  

13  
#include <boost/capy/detail/config.hpp>
13  
#include <boost/capy/detail/config.hpp>
14  

14  

15  
#include <concepts>
15  
#include <concepts>
16  
#include <exception>
16  
#include <exception>
17  
#include <type_traits>
17  
#include <type_traits>
18  
#include <utility>
18  
#include <utility>
19  

19  

20  
namespace boost {
20  
namespace boost {
21  
namespace capy {
21  
namespace capy {
22  
namespace detail {
22  
namespace detail {
23  

23  

24  
struct default_handler
24  
struct default_handler
25  
{
25  
{
26  
    template<class T>
26  
    template<class T>
27  
    void operator()(T&&) const noexcept
27  
    void operator()(T&&) const noexcept
28  
    {
28  
    {
29  
    }
29  
    }
30  

30  

31  
    void operator()() const noexcept
31  
    void operator()() const noexcept
32  
    {
32  
    {
33  
    }
33  
    }
34  

34  

35  
    void operator()(std::exception_ptr ep) const
35  
    void operator()(std::exception_ptr ep) const
36  
    {
36  
    {
37  
        if(ep)
37  
        if(ep)
38  
            std::rethrow_exception(ep);
38  
            std::rethrow_exception(ep);
39  
    }
39  
    }
40  
};
40  
};
41  

41  

42  
template<class H1, class H2>
42  
template<class H1, class H2>
43  
struct handler_pair
43  
struct handler_pair
44  
{
44  
{
45  
    static_assert(
45  
    static_assert(
46  
        std::is_nothrow_move_constructible_v<H1> &&
46  
        std::is_nothrow_move_constructible_v<H1> &&
47  
        std::is_nothrow_move_constructible_v<H2>,
47  
        std::is_nothrow_move_constructible_v<H2>,
48  
        "Handlers must be nothrow move constructible");
48  
        "Handlers must be nothrow move constructible");
49  

49  

50  
    H1 h1_;
50  
    H1 h1_;
51  
    H2 h2_;
51  
    H2 h2_;
52  

52  

53  
    template<class T>
53  
    template<class T>
54  
    void operator()(T&& v)
54  
    void operator()(T&& v)
55  
    {
55  
    {
56  
        h1_(std::forward<T>(v));
56  
        h1_(std::forward<T>(v));
57  
    }
57  
    }
58  

58  

59  
    void operator()()
59  
    void operator()()
60  
    {
60  
    {
61  
        h1_();
61  
        h1_();
62  
    }
62  
    }
63  

63  

64  
    void operator()(std::exception_ptr ep)
64  
    void operator()(std::exception_ptr ep)
65  
    {
65  
    {
66  
        h2_(ep);
66  
        h2_(ep);
67  
    }
67  
    }
68  
};
68  
};
69  

69  

70  
template<class H1>
70  
template<class H1>
71  
struct handler_pair<H1, default_handler>
71  
struct handler_pair<H1, default_handler>
72  
{
72  
{
73  
    static_assert(
73  
    static_assert(
74  
        std::is_nothrow_move_constructible_v<H1>,
74  
        std::is_nothrow_move_constructible_v<H1>,
75  
        "Handler must be nothrow move constructible");
75  
        "Handler must be nothrow move constructible");
76  

76  

77  
    H1 h1_;
77  
    H1 h1_;
78  

78  

79  
    template<class T>
79  
    template<class T>
80  
    void operator()(T&& v)
80  
    void operator()(T&& v)
81  
    {
81  
    {
82  
        h1_(std::forward<T>(v));
82  
        h1_(std::forward<T>(v));
83  
    }
83  
    }
84  

84  

85  
    void operator()()
85  
    void operator()()
86  
    {
86  
    {
87  
        h1_();
87  
        h1_();
88  
    }
88  
    }
89  

89  

90  
    void operator()(std::exception_ptr ep)
90  
    void operator()(std::exception_ptr ep)
91  
    {
91  
    {
92  
        if constexpr(std::invocable<H1, std::exception_ptr>)
92  
        if constexpr(std::invocable<H1, std::exception_ptr>)
93  
            h1_(ep);
93  
            h1_(ep);
94  
        else
94  
        else
95  
            std::rethrow_exception(ep);
95  
            std::rethrow_exception(ep);
96  
    }
96  
    }
97  
};
97  
};
98  

98  

99  
} // namespace detail
99  
} // namespace detail
100  
} // namespace capy
100  
} // namespace capy
101  
} // namespace boost
101  
} // namespace boost
102  

102  

103  
#endif
103  
#endif