GCC Code Coverage Report


Directory: libs/beast2/
File: include/boost/beast2/server/detail/any_router.hpp
Date: 2025-11-13 15:50:44
Exec Total Coverage
Lines: 9 15 60.0%
Functions: 4 8 50.0%
Branches: 0 0 -%

Line Branch Exec Source
1 //
2 // Copyright (c) 2025 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/cppalliance/beast2
8 //
9
10 #ifndef BOOST_BEAST2_SERVER_DETAIL_ANY_ROUTER_HPP
11 #define BOOST_BEAST2_SERVER_DETAIL_ANY_ROUTER_HPP
12
13 #include <boost/beast2/detail/config.hpp>
14 #include <boost/beast2/detail/call_traits.hpp>
15 #include <boost/beast2/detail/type_traits.hpp>
16 #include <boost/beast2/server/route_handler.hpp>
17 #include <boost/http_proto/method.hpp>
18 #include <boost/url/segments_encoded_view.hpp>
19 #include <boost/core/detail/string_view.hpp>
20 #include <type_traits>
21
22 namespace boost {
23 namespace beast2 {
24
25 struct route_state;
26
27 //------------------------------------------------
28
29 namespace detail {
30
31 class any_router;
32
33 // handler kind constants
34 // 0 = unrecognized
35 // 1 = regular
36 // 2 = router
37 // 3 = error
38
39 template<class T,
40 class Req, class Res, class = void>
41 struct get_handler_kind
42 : std::integral_constant<int, 0>
43 {
44 };
45
46 // route_result( Req&, Res& )
47 template<class T, class Req, class Res>
48 struct get_handler_kind<T, Req, Res,
49 typename std::enable_if<detail::is_invocable<
50 T, route_result, Req&, Res&>::value>::type>
51 : std::integral_constant<int, 1>
52 {
53 };
54
55 // route_result( Req&, Res&, route_state& )
56 template<class T, class Req, class Res>
57 struct get_handler_kind<T, Req, Res,
58 typename std::enable_if<detail::derived_from<
59 T, any_router>::value>::type>
60 : std::integral_constant<int, 2>
61 {
62 };
63
64 // route_result( Req&, Res&, system::error_code&
65 template<class T, class Req, class Res>
66 struct get_handler_kind<T, Req, Res,
67 typename std::enable_if<detail::is_invocable<
68 T, route_result, Req&, Res&,
69 system::error_code&>::value>::type>
70 : std::integral_constant<int, 3>
71 {
72 };
73
74 //------------------------------------------------
75
76 // implementation for all routers
77 class any_router
78 {
79 protected:
80 struct layer;
81 struct impl;
82 struct any_handler;
83
84 struct req_info
85 {
86 core::string_view& base_path;
87 core::string_view& path;
88 };
89
90 using handler_ptr = std::unique_ptr<any_handler>;
91
92 template<class, class, class>
93 struct handler_impl;
94
95 any_router() = default;
96
97 BOOST_BEAST2_DECL ~any_router();
98 BOOST_BEAST2_DECL any_router(any_router&&) noexcept;
99 BOOST_BEAST2_DECL any_router(any_router const&) noexcept;
100 BOOST_BEAST2_DECL any_router& operator=(any_router&&) noexcept;
101 BOOST_BEAST2_DECL any_router& operator=(any_router const&) noexcept;
102 BOOST_BEAST2_DECL any_router(req_info(*)(void*));
103 BOOST_BEAST2_DECL std::size_t count() const noexcept;
104 BOOST_BEAST2_DECL route_result dispatch_impl(http_proto::method,
105 urls::url_view const&, void*, void*, route_state& st) const;
106 BOOST_BEAST2_DECL route_result dispatch_impl(
107 void*, void*, route_state&) const;
108 BOOST_BEAST2_DECL route_result resume(
109 void*, void*, route_state&, route_result const& ec) const;
110 BOOST_BEAST2_DECL void append(bool, http_proto::method,
111 core::string_view, handler_ptr);
112 BOOST_BEAST2_DECL void append(core::string_view, any_router&);
113 void append(bool, http_proto::method, core::string_view) {}
114
115 impl* impl_ = nullptr;
116 };
117
118 //------------------------------------------------
119
120 struct BOOST_SYMBOL_VISIBLE
121 any_router::any_handler
122 {
123 BOOST_BEAST2_DECL virtual ~any_handler();
124 BOOST_BEAST2_DECL virtual
125 std::size_t count() const noexcept = 0 ;
126 virtual route_result invoke(
127 void*, void*, route_state&,
128 system::error_code*) const = 0;
129 };
130
131 // wrapper for route handlers
132 template<class Req, class Res, class H>
133 struct any_router::
134 handler_impl : any_handler
135 {
136 typename std::decay<H>::type h;
137
138 template<class... Args>
139 18 handler_impl(Args&&... args)
140 18 : h(std::forward<Args>(args)...)
141 {
142 18 }
143
144 std::size_t
145 count() const noexcept override
146 {
147 return count(get_handler_kind<
148 decltype(h), Req, Res>{});
149 }
150
151 route_result
152 14 invoke(
153 void* req, void* res,
154 route_state& st,
155 system::error_code* pec) const override
156 {
157 28 return invoke(
158 *reinterpret_cast<Req*>(req),
159 *reinterpret_cast<Res*>(res),
160 st, pec, get_handler_kind<
161 14 decltype(h), Req, Res>{});
162 }
163
164 private:
165 std::size_t count(
166 std::integral_constant<int, 0>) const = delete;
167
168 std::size_t count(
169 std::integral_constant<int, 1>) const noexcept
170 {
171 return 1;
172 }
173
174 std::size_t count(
175 std::integral_constant<int, 2>) const noexcept
176 {
177 return h.count();
178 }
179
180 std::size_t count(
181 std::integral_constant<int, 3>) const noexcept
182 {
183 return 1;
184 }
185
186 route_result
187 invoke(Req&, Res&, route_state&,
188 system::error_code*,
189 std::integral_constant<int, 0>) const = delete;
190
191 route_result
192 7 invoke(Req& req, Res& res, route_state&,
193 system::error_code* pec,
194 std::integral_constant<int, 1>) const
195 {
196 7 if(! pec)
197 7 return h(req, res);
198 return route::next;
199 }
200
201 route_result
202 invoke(Req& req, Res& res, route_state& st,
203 system::error_code* pec,
204 std::integral_constant<int, 2>) const
205 {
206 if(! pec)
207 return h.dispatch(&req, &res, st);
208 return route::next;
209 }
210
211 route_result
212 invoke(Req& req, Res& res, route_state&,
213 system::error_code* pec,
214 std::integral_constant<int, 3>) const
215 {
216 if(pec != nullptr)
217 return h(req, res, *pec);
218 return route::next;
219 }
220 };
221
222 } // detail
223 } // beast2
224 } // boost
225
226 #endif
227