Imported Upstream version 1.72.0
[platform/upstream/boost.git] / libs / beast / test / beast / core / test_handler.hpp
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_TEST_HANDLER_XXX_HPP
11 #define BOOST_BEAST_TEST_HANDLER_XXX_HPP
12
13 #include <boost/beast/core/detail/config.hpp>
14 #include <boost/beast/_experimental/unit_test/suite.hpp>
15 #include <boost/asio/associated_allocator.hpp>
16 #include <boost/asio/associated_executor.hpp>
17 #include <boost/asio/handler_alloc_hook.hpp>
18 #include <boost/asio/handler_continuation_hook.hpp>
19 #include <boost/asio/handler_invoke_hook.hpp>
20
21 namespace boost {
22 namespace beast {
23
24 class simple_allocator
25 {
26     std::size_t id_;
27
28 public:
29     simple_allocator()
30         : id_([]
31         {
32             static std::size_t n = 0;
33             return ++n;
34         }())
35     {
36     }
37
38     friend
39     bool operator==(
40         simple_allocator const& lhs,
41         simple_allocator const& rhs) noexcept
42     {
43         return lhs.id_ == rhs.id_;
44     }
45
46     friend
47     bool operator!=(
48         simple_allocator const& lhs,
49         simple_allocator const& rhs) noexcept
50     {
51         return lhs.id_ != rhs.id_;
52     }
53 };
54
55 class simple_executor
56 {
57     std::size_t id_;
58
59 public:
60     simple_executor()
61         : id_([]
62         {
63             static std::size_t n = 0;
64             return ++n;
65         }())
66     {
67     }
68
69     void* context() { return nullptr; }
70     void on_work_started() {}
71     void on_work_finished() {}
72     template<class F> void dispatch(F&&) {}
73     template<class F> void post(F&&) {}
74     template<class F> void defer(F&&) {}
75
76     friend
77     bool operator==(
78         simple_executor const& lhs,
79         simple_executor const& rhs) noexcept
80     {
81         return lhs.id_ == rhs.id_;
82     }
83
84     friend
85     bool operator!=(
86         simple_executor const& lhs,
87         simple_executor const& rhs) noexcept
88     {
89         return lhs.id_ != rhs.id_;
90     }
91 };
92
93 // A move-only handler
94 struct move_only_handler
95 {
96     move_only_handler() = default;
97     move_only_handler(move_only_handler&&) = default;
98     move_only_handler(move_only_handler const&) = delete;
99     void operator()() const{};
100 };
101
102 // Used to test the legacy handler hooks
103 struct legacy_handler
104 {
105     bool& hook_invoked;
106
107     simple_executor
108     get_executor() const noexcept
109     {
110         return {};
111     };
112
113     // Signature of `f` is H<legacy_handler> where H is the wrapper to test
114     template<class F>
115     static
116     void
117     test(F const& f)
118     {
119         {
120             bool hook_invoked = false;
121             bool lambda_invoked = false;
122             auto h = f(legacy_handler{hook_invoked});
123             using net::asio_handler_invoke;
124             asio_handler_invoke(
125                 [&lambda_invoked]
126                 {
127                     lambda_invoked =true;
128                 }, &h);
129             BEAST_EXPECT(hook_invoked);
130             BEAST_EXPECT(lambda_invoked);
131         }
132         {
133             bool hook_invoked = false;
134             auto h = f(legacy_handler{hook_invoked});
135             using net::asio_handler_allocate;
136             asio_handler_allocate(0, &h);
137             BEAST_EXPECT(hook_invoked);
138         }
139         {
140             bool hook_invoked = false;
141             auto h = f(legacy_handler{hook_invoked});
142             using net::asio_handler_deallocate;
143             asio_handler_deallocate(nullptr, 0, &h);
144             BEAST_EXPECT(hook_invoked);
145         }
146         {
147             bool hook_invoked = false;
148             auto h = f(legacy_handler{hook_invoked});
149             using net::asio_handler_is_continuation;
150             asio_handler_is_continuation(&h);
151             BEAST_EXPECT(hook_invoked);
152         }
153     }
154 };
155
156 template<class Function>
157 void
158 asio_handler_invoke(
159     Function&& f,
160     legacy_handler* p)
161 {
162     p->hook_invoked = true;
163     f();
164 }
165
166 inline
167 void*
168 asio_handler_allocate(
169     std::size_t,
170     legacy_handler* p)
171 {
172     p->hook_invoked = true;
173     return nullptr;
174 }
175
176 inline
177 void
178 asio_handler_deallocate(
179     void*, std::size_t,
180     legacy_handler* p)
181 {
182     p->hook_invoked = true;
183 }
184
185 inline
186 bool
187 asio_handler_is_continuation(
188     legacy_handler* p)
189 {
190     p->hook_invoked = true;
191     return false;
192 }
193
194 } // beast
195 } // boost
196
197 namespace boost {
198 namespace asio {
199
200 template<class Allocator>
201 struct associated_allocator<
202     boost::beast::legacy_handler, Allocator>
203 {
204     using type = std::allocator<int>;
205
206     static type get(
207         boost::beast::legacy_handler const&,
208         Allocator const& = Allocator()) noexcept
209     {
210         return type{};
211     }
212 };
213
214 template<class Executor>
215 struct associated_executor<
216     boost::beast::legacy_handler, Executor>
217 {
218     using type = boost::beast::simple_executor;
219
220     static type get(
221         boost::beast::legacy_handler const&,
222         Executor const& = Executor()) noexcept
223     {
224         return type{};
225     }
226 };
227
228 } // asio
229 } // boost
230
231 #endif