LCOV - code coverage report
Current view: top level - corosio/native - native_resolver.hpp (source / functions) Coverage Total Hit
Test: coverage_remapped.info Lines: 100.0 % 15 15
Test Date: 2026-09-25 21:36:35 Functions: 100.0 % 10 10

           TLA  Line data    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 HIT           2 :     impl_type& get_impl() noexcept
      58                 :     {
      59               2 :         return *static_cast<impl_type*>(h_.get());
      60                 :     }
      61                 : 
      62                 :     struct native_resolve_awaitable
      63                 :         : detail::value_op_base<native_resolve_awaitable, std::vector<endpoint>>
      64                 :     {
      65                 :         native_resolver& self_;
      66                 :         std::string host_;
      67                 :         std::string service_;
      68                 :         resolve_flags flags_;
      69                 : 
      70               4 :         native_resolve_awaitable(
      71                 :             native_resolver& self,
      72                 :             std::string_view host,
      73                 :             std::string_view service,
      74                 :             resolve_flags flags) noexcept
      75               4 :             : self_(self)
      76               8 :             , host_(host)
      77               8 :             , service_(service)
      78               4 :             , flags_(flags)
      79                 :         {
      80               4 :         }
      81                 : 
      82                 :         std::coroutine_handle<>
      83               2 :         dispatch(std::coroutine_handle<> h, capy::executor_ref ex) const
      84                 :         {
      85               6 :             return self_.get_impl().resolve(
      86               2 :                 h, ex, host_, service_, flags_, this->token_, &this->ec_,
      87               4 :                 &this->value_);
      88                 :         }
      89                 :     };
      90                 : 
      91                 :     struct native_reverse_awaitable
      92                 :         : detail::value_op_base<native_reverse_awaitable, endpoint_name>
      93                 :     {
      94                 :         native_resolver& self_;
      95                 :         endpoint ep_;
      96                 :         reverse_flags flags_;
      97                 : 
      98                 :         native_reverse_awaitable(
      99                 :             native_resolver& self,
     100                 :             endpoint const& ep,
     101                 :             reverse_flags flags) noexcept
     102                 :             : self_(self)
     103                 :             , ep_(ep)
     104                 :             , flags_(flags)
     105                 :         {
     106                 :         }
     107                 : 
     108                 :         std::coroutine_handle<>
     109                 :         dispatch(std::coroutine_handle<> h, capy::executor_ref ex) const
     110                 :         {
     111                 :             return self_.get_impl().reverse_resolve(
     112                 :                 h, ex, ep_, flags_, this->token_, &this->ec_, &this->value_);
     113                 :         }
     114                 :     };
     115                 : 
     116                 : public:
     117                 :     /** Construct a native resolver from an execution context.
     118                 : 
     119                 :         @param ctx The execution context that will own this resolver.
     120                 :     */
     121               8 :     explicit native_resolver(capy::execution_context& ctx) : resolver(ctx) {}
     122                 : 
     123                 :     /** Construct a native resolver from an executor.
     124                 : 
     125                 :         @param ex The executor whose context will own the resolver.
     126                 :     */
     127                 :     template<class Ex>
     128                 :         requires(!std::same_as<std::remove_cvref_t<Ex>, native_resolver>) &&
     129                 :         capy::Executor<Ex>
     130                 :     explicit native_resolver(Ex const& ex) : native_resolver(ex.context())
     131                 :     {
     132                 :     }
     133                 : 
     134                 :     /** Move construct.
     135                 : 
     136                 :         @pre No awaitables returned by @p other's `resolve` methods
     137                 :             exist.
     138                 :         @pre The execution context associated with @p other must
     139                 :             outlive this resolver.
     140                 :     */
     141                 :     native_resolver(native_resolver&&) noexcept = default;
     142                 : 
     143                 :     /** Move assign.
     144                 : 
     145                 :         @pre No awaitables returned by either `*this` or the source's
     146                 :             `resolve` methods exist.
     147                 :         @pre The execution context associated with the source must
     148                 :             outlive this resolver.
     149                 :     */
     150                 :     native_resolver& operator=(native_resolver&&) noexcept = default;
     151                 : 
     152                 :     native_resolver(native_resolver const&)            = delete;
     153                 :     native_resolver& operator=(native_resolver const&) = delete;
     154                 : 
     155                 :     /** Asynchronously resolve a host and service to endpoints.
     156                 : 
     157                 :         Calls the backend implementation directly, bypassing virtual
     158                 :         dispatch. Otherwise identical to @ref resolver::resolve.
     159                 : 
     160                 :         This resolver must outlive the returned awaitable.
     161                 : 
     162                 :         @param host The host name or address string.
     163                 :         @param service The service name or port string.
     164                 : 
     165                 :         @return An awaitable yielding `io_result<std::vector<endpoint>>`.
     166                 :     */
     167               4 :     [[nodiscard]] auto resolve(std::string_view host, std::string_view service)
     168                 :     {
     169                 :         return native_resolve_awaitable(
     170               4 :             *this, host, service, resolve_flags::none);
     171                 :     }
     172                 : 
     173                 :     /** Asynchronously resolve a host and service with flags.
     174                 : 
     175                 :         This resolver must outlive the returned awaitable.
     176                 : 
     177                 :         @param host The host name or address string.
     178                 :         @param service The service name or port string.
     179                 :         @param flags Flags controlling resolution behavior.
     180                 : 
     181                 :         @return An awaitable yielding
     182                 :             `io_result<std::vector<endpoint>>`.
     183                 :     */
     184                 :     [[nodiscard]] auto resolve(
     185                 :         std::string_view host, std::string_view service, resolve_flags flags)
     186                 :     {
     187                 :         return native_resolve_awaitable(*this, host, service, flags);
     188                 :     }
     189                 : 
     190                 :     /** Asynchronously reverse-resolve an endpoint.
     191                 : 
     192                 :         Calls the backend implementation directly, bypassing virtual
     193                 :         dispatch. Otherwise identical to the endpoint overload of
     194                 :         @ref resolver::resolve.
     195                 : 
     196                 :         This resolver must outlive the returned awaitable.
     197                 : 
     198                 :         @param ep The endpoint to resolve.
     199                 : 
     200                 :         @return An awaitable yielding
     201                 :             `io_result<endpoint_name>`.
     202                 :     */
     203                 :     [[nodiscard]] auto resolve(endpoint const& ep)
     204                 :     {
     205                 :         return native_reverse_awaitable(*this, ep, reverse_flags::none);
     206                 :     }
     207                 : 
     208                 :     /** Asynchronously reverse-resolve an endpoint with flags.
     209                 : 
     210                 :         This resolver must outlive the returned awaitable.
     211                 : 
     212                 :         @param ep The endpoint to resolve.
     213                 :         @param flags Flags controlling resolution behavior.
     214                 : 
     215                 :         @return An awaitable yielding
     216                 :             `io_result<endpoint_name>`.
     217                 :     */
     218                 :     [[nodiscard]] auto resolve(endpoint const& ep, reverse_flags flags)
     219                 :     {
     220                 :         return native_reverse_awaitable(*this, ep, flags);
     221                 :     }
     222                 : };
     223                 : 
     224                 : } // namespace boost::corosio
     225                 : 
     226                 : #endif
        

Generated by: LCOV version 2.3