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