1 //
2 // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
3 //
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)
6 //
7 // Official repository: https://github.com/boostorg/beast
8 //
9 
10 #ifndef BOOST_BEAST_CORE_SAVED_HANDLER_HPP
11 #define BOOST_BEAST_CORE_SAVED_HANDLER_HPP
12 
13 #include <boost/beast/core/detail/config.hpp>
14 
15 namespace boost {
16 namespace beast {
17 
18 /** An invocable, nullary function object which holds a completion handler.
19 
20     This container can hold a type-erased instance of any completion
21     handler, or it can be empty. When the container holds a value,
22     the implementation maintains an instance of `net::executor_work_guard`
23     for the handler's associated executor. Memory is dynamically allocated
24     to store the completion handler, and the allocator may optionally
25     be specified. Otherwise, the implementation uses the handler's
26     associated allocator.
27 */
28 class saved_handler
29 {
30     class base;
31 
32     template<class, class>
33     class impl;
34 
35     base* p_ = nullptr;
36 
37 public:
38     /// Default Constructor
39     saved_handler() = default;
40 
41     /// Copy Constructor (deleted)
42     saved_handler(saved_handler const&) = delete;
43 
44     /// Copy Assignment (deleted)
45     saved_handler& operator=(saved_handler const&) = delete;
46 
47     /// Destructor
48     BOOST_BEAST_DECL
49     ~saved_handler();
50 
51     /// Move Constructor
52     BOOST_BEAST_DECL
53     saved_handler(saved_handler&& other) noexcept;
54 
55     /// Move Assignment
56     BOOST_BEAST_DECL
57     saved_handler&
58     operator=(saved_handler&& other) noexcept;
59 
60     /// Returns `true` if `*this` contains a completion handler.
61     bool
has_value() const62     has_value() const noexcept
63     {
64         return p_ != nullptr;
65     }
66 
67     /** Store a completion handler in the container.
68 
69         Requires `this->has_value() == false`.
70 
71         @param handler The completion handler to store.
72         The implementation takes ownership of the handler by performing a decay-copy.
73 
74         @param alloc The allocator to use.
75     */
76     template<class Handler, class Allocator>
77     void
78     emplace(Handler&& handler, Allocator const& alloc);
79 
80     /** Store a completion handler in the container.
81 
82         Requires `this->has_value() == false`. The
83         implementation will use the handler's associated
84         allocator to obtian storage.
85 
86         @param handler The completion handler to store.
87         The implementation takes ownership of the handler by performing a decay-copy.
88     */
89     template<class Handler>
90     void
91     emplace(Handler&& handler);
92 
93     /** Discard the saved handler, if one exists.
94 
95         If `*this` contains an object, it is destroyed.
96 
97         @returns `true` if an object was destroyed.
98     */
99     BOOST_BEAST_DECL
100     bool
101     reset() noexcept;
102 
103     /** Unconditionally invoke the stored completion handler.
104 
105         Requires `this->has_value() == true`. Any dynamic memory
106         used is deallocated before the stored completion handler
107         is invoked. The executor work guard is also reset before
108         the invocation.
109     */
110     BOOST_BEAST_DECL
111     void
112     invoke();
113 
114     /** Conditionally invoke the stored completion handler.
115 
116         Invokes the stored completion handler if
117         `this->has_value() == true`, otherwise does nothing. Any
118         dynamic memory used is deallocated before the stored completion
119         handler is invoked. The executor work guard is also reset before
120         the invocation.
121 
122         @return `true` if the invocation took place.
123     */
124     BOOST_BEAST_DECL
125     bool
126     maybe_invoke();
127 };
128 
129 } // beast
130 } // boost
131 
132 #include <boost/beast/core/impl/saved_handler.hpp>
133 #ifdef BOOST_BEAST_HEADER_ONLY
134 #include <boost/beast/core/impl/saved_handler.ipp>
135 #endif
136 
137 #endif
138