include/boost/corosio/native/native_resolver.hpp

100.0% Lines (15 / 15) 100.0% Functions (8 / 8)
native_resolver.hpp
f(x) Functions (8)
Function Calls Lines Blocks
boost::corosio::native_resolver<boost::corosio::epoll_t{}>::get_impl() :57 1x 100.0% 100.0% boost::corosio::native_resolver<boost::corosio::select_t{}>::get_impl() :57 1x 100.0% 100.0% boost::corosio::native_resolver<boost::corosio::epoll_t{}>::native_resolve_awaitable::native_resolve_awaitable(boost::corosio::native_resolver<boost::corosio::epoll_t{}>&, std::basic_string_view<char, std::char_traits<char> >, std::basic_string_view<char, std::char_traits<char> >, boost::corosio::resolve_flags) :70 2x 100.0% 100.0% boost::corosio::native_resolver<boost::corosio::select_t{}>::native_resolve_awaitable::native_resolve_awaitable(boost::corosio::native_resolver<boost::corosio::select_t{}>&, std::basic_string_view<char, std::char_traits<char> >, std::basic_string_view<char, std::char_traits<char> >, boost::corosio::resolve_flags) :70 2x 100.0% 100.0% boost::corosio::native_resolver<boost::corosio::epoll_t{}>::native_resolve_awaitable::dispatch(std::__n4861::coroutine_handle<void>, boost::capy::executor_ref) const :83 1x 100.0% 83.0% boost::corosio::native_resolver<boost::corosio::select_t{}>::native_resolve_awaitable::dispatch(std::__n4861::coroutine_handle<void>, boost::capy::executor_ref) const :83 1x 100.0% 83.0% boost::corosio::native_resolver<boost::corosio::epoll_t{}>::native_resolver(boost::capy::execution_context&) :122 4x 100.0% 100.0% boost::corosio::native_resolver<boost::corosio::select_t{}>::native_resolver(boost::capy::execution_context&) :122 4x 100.0% 100.0%
Line TLA Hits Source Code
1 //
2 // Copyright (c) 2026 Steve Gerbino
3 // Copyright (c) 2026 Michael Vandeberg
4 //
5 // Distributed under the Boost Software License, Version 1.0. (See accompanying
6 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 //
8 // Official repository: https://github.com/cppalliance/corosio
9 //
10
11 #ifndef BOOST_COROSIO_NATIVE_NATIVE_RESOLVER_HPP
12 #define BOOST_COROSIO_NATIVE_NATIVE_RESOLVER_HPP
13
14 #include <boost/corosio/resolver.hpp>
15 #include <boost/corosio/backend.hpp>
16 #include <boost/corosio/detail/op_base.hpp>
17
18 #ifndef BOOST_COROSIO_MRDOCS
19 #if BOOST_COROSIO_HAS_EPOLL || BOOST_COROSIO_HAS_SELECT || \
20 BOOST_COROSIO_HAS_KQUEUE
21 #include <boost/corosio/native/detail/posix/posix_resolver_service.hpp>
22 #endif
23
24 #if BOOST_COROSIO_HAS_IOCP
25 #include <boost/corosio/native/detail/iocp/win_resolver_service.hpp>
26 #endif
27 #endif // !BOOST_COROSIO_MRDOCS
28
29 namespace boost::corosio {
30
31 /** An asynchronous DNS resolver with devirtualized operations.
32
33 This class template inherits from @ref resolver and shadows
34 the `resolve` operations with versions that call the backend
35 implementation directly, allowing the compiler to inline
36 through the entire call chain.
37
38 Non-async operations (`cancel`) remain unchanged and dispatch
39 through the compiled library.
40
41 A `native_resolver` IS-A `resolver` and can be passed to any
42 function expecting `resolver&`.
43
44 @tparam Backend A backend tag value (e.g., `epoll`).
45
46 @par Thread Safety
47 Same as @ref resolver.
48
49 @see resolver, epoll_t, iocp_t
50 */
51 template<auto Backend>
52 class native_resolver : public resolver
53 {
54 using backend_type = decltype(Backend);
55 using impl_type = typename backend_type::resolver_type;
56
57 2x impl_type& get_impl() noexcept
58 {
59 2x return *static_cast<impl_type*>(h_.get());
60 }
61
62 struct native_resolve_awaitable
63 : detail::value_op_base<native_resolve_awaitable, resolver_results>
64 {
65 native_resolver& self_;
66 std::string host_;
67 std::string service_;
68 resolve_flags flags_;
69
70 4x native_resolve_awaitable(
71 native_resolver& self,
72 std::string_view host,
73 std::string_view service,
74 resolve_flags flags) noexcept
75 4x : self_(self)
76 8x , host_(host)
77 8x , service_(service)
78 4x , flags_(flags)
79 {
80 4x }
81
82 std::coroutine_handle<>
83 2x dispatch(std::coroutine_handle<> h, capy::executor_ref ex) const
84 {
85 6x return self_.get_impl().resolve(
86 2x h, ex, host_, service_, flags_, this->token_, &this->ec_,
87 4x &this->value_);
88 }
89 };
90
91 struct native_reverse_awaitable
92 : detail::
93 value_op_base<native_reverse_awaitable, reverse_resolver_result>
94 {
95 native_resolver& self_;
96 endpoint ep_;
97 reverse_flags flags_;
98
99 native_reverse_awaitable(
100 native_resolver& self,
101 endpoint const& ep,
102 reverse_flags flags) noexcept
103 : self_(self)
104 , ep_(ep)
105 , flags_(flags)
106 {
107 }
108
109 std::coroutine_handle<>
110 dispatch(std::coroutine_handle<> h, capy::executor_ref ex) const
111 {
112 return self_.get_impl().reverse_resolve(
113 h, ex, ep_, flags_, this->token_, &this->ec_, &this->value_);
114 }
115 };
116
117 public:
118 /** Construct a native resolver from an execution context.
119
120 @param ctx The execution context that will own this resolver.
121 */
122 8x explicit native_resolver(capy::execution_context& ctx) : resolver(ctx) {}
123
124 /** Construct a native resolver from an executor.
125
126 @param ex The executor whose context will own the resolver.
127 */
128 template<class Ex>
129 requires(!std::same_as<std::remove_cvref_t<Ex>, native_resolver>) &&
130 capy::Executor<Ex>
131 explicit native_resolver(Ex const& ex) : native_resolver(ex.context())
132 {
133 }
134
135 /** Move construct.
136
137 @pre No awaitables returned by @p other's `resolve` methods
138 exist.
139 @pre The execution context associated with @p other must
140 outlive this resolver.
141 */
142 native_resolver(native_resolver&&) noexcept = default;
143
144 /** Move assign.
145
146 @pre No awaitables returned by either `*this` or the source's
147 `resolve` methods exist.
148 @pre The execution context associated with the source must
149 outlive this resolver.
150 */
151 native_resolver& operator=(native_resolver&&) noexcept = default;
152
153 native_resolver(native_resolver const&) = delete;
154 native_resolver& operator=(native_resolver const&) = delete;
155
156 /** Asynchronously resolve a host and service to endpoints.
157
158 Calls the backend implementation directly, bypassing virtual
159 dispatch. Otherwise identical to @ref resolver::resolve.
160
161 This resolver must outlive the returned awaitable.
162
163 @param host The host name or address string.
164 @param service The service name or port string.
165
166 @return An awaitable yielding `io_result<resolver_results>`.
167
168 @note `resolver_results` is an alias for `std::vector<resolver_entry>`;
169 copying it deep-copies every entry. See @ref resolver::resolve.
170 */
171 4x [[nodiscard]] auto resolve(std::string_view host, std::string_view service)
172 {
173 return native_resolve_awaitable(
174 4x *this, host, service, resolve_flags::none);
175 }
176
177 /** Asynchronously resolve a host and service with flags.
178
179 This resolver must outlive the returned awaitable.
180
181 @param host The host name or address string.
182 @param service The service name or port string.
183 @param flags Flags controlling resolution behavior.
184
185 @return An awaitable yielding `io_result<resolver_results>`.
186 */
187 [[nodiscard]] auto resolve(
188 std::string_view host, std::string_view service, resolve_flags flags)
189 {
190 return native_resolve_awaitable(*this, host, service, flags);
191 }
192
193 /** Asynchronously reverse-resolve an endpoint.
194
195 Calls the backend implementation directly, bypassing virtual
196 dispatch. Otherwise identical to the endpoint overload of
197 @ref resolver::resolve.
198
199 This resolver must outlive the returned awaitable.
200
201 @param ep The endpoint to resolve.
202
203 @return An awaitable yielding
204 `io_result<reverse_resolver_result>`.
205 */
206 [[nodiscard]] auto resolve(endpoint const& ep)
207 {
208 return native_reverse_awaitable(*this, ep, reverse_flags::none);
209 }
210
211 /** Asynchronously reverse-resolve an endpoint with flags.
212
213 This resolver must outlive the returned awaitable.
214
215 @param ep The endpoint to resolve.
216 @param flags Flags controlling resolution behavior.
217
218 @return An awaitable yielding
219 `io_result<reverse_resolver_result>`.
220 */
221 [[nodiscard]] auto resolve(endpoint const& ep, reverse_flags flags)
222 {
223 return native_reverse_awaitable(*this, ep, flags);
224 }
225 };
226
227 } // namespace boost::corosio
228
229 #endif
230