LCOV - code coverage report
Current view: top level - corosio - endpoint.hpp (source / functions) Coverage Total Hit
Test: coverage_remapped.info Lines: 100.0 % 26 26
Test Date: 2026-10-28 12:45:41 Functions: 100.0 % 11 11

           TLA  Line data    Source code
       1                 : //
       2                 : // Copyright (c) 2026 Vinnie Falco (vinnie.falco@gmail.com)
       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_ENDPOINT_HPP
      12                 : #define BOOST_COROSIO_ENDPOINT_HPP
      13                 : 
      14                 : #include <boost/corosio/detail/config.hpp>
      15                 : #include <boost/corosio/ip_address.hpp>
      16                 : 
      17                 : #include <boost/capy/results.hpp>
      18                 : 
      19                 : #include <compare>
      20                 : #include <cstdint>
      21                 : #include <string_view>
      22                 : #include <system_error>
      23                 : 
      24                 : namespace boost::corosio {
      25                 : 
      26                 : /** Pairs an IP address with a port for either IPv4 or IPv6.
      27                 : 
      28                 :     This class represents an endpoint for IP communication,
      29                 :     consisting of an IP address of either family and a port number.
      30                 :     Use an endpoint to specify a connection target or bind address.
      31                 : 
      32                 :     @par Thread Safety
      33                 :     Distinct objects: Safe.@n
      34                 :     Shared objects: Safe.
      35                 : 
      36                 :     @par Example
      37                 :     @par !example endpoint
      38                 : */
      39                 : class endpoint
      40                 : {
      41                 :     ip_address addr_;
      42                 :     std::uint16_t port_ = 0;
      43                 : 
      44                 : public:
      45                 :     /** Creates an endpoint with the IPv4 any address (0.0.0.0) and port 0.
      46                 :     */
      47 HIT      269298 :     endpoint() noexcept = default;
      48                 : 
      49                 :     /** Construct from an IP address and port.
      50                 : 
      51                 :         `ipv4_address` and `ipv6_address` arguments convert
      52                 :         implicitly, so both families construct directly:
      53                 :         `endpoint(ipv4_address::loopback(), 80)`.
      54                 : 
      55                 :         @param addr The IP address.
      56                 :         @param p The port number in host byte order.
      57                 :     */
      58           35391 :     endpoint(ip_address addr, std::uint16_t p) noexcept : addr_(addr), port_(p)
      59                 :     {
      60           35391 :     }
      61                 : 
      62                 :     /** Construct from port only.
      63                 : 
      64                 :         Uses the IPv4 any address (0.0.0.0), which binds to all
      65                 :         available network interfaces.
      66                 : 
      67                 :         @param p The port number in host byte order.
      68                 :     */
      69              22 :     explicit endpoint(std::uint16_t p) noexcept : port_(p) {}
      70                 : 
      71                 :     /** Construct from an endpoint's address with a different port.
      72                 : 
      73                 :         Creates a new endpoint using the address from an existing
      74                 :         endpoint but with a different port number.
      75                 : 
      76                 :         @param ep The endpoint whose address to use.
      77                 :         @param p The port number in host byte order.
      78                 :     */
      79               2 :     endpoint(endpoint const& ep, std::uint16_t p) noexcept
      80               2 :         : addr_(ep.addr_)
      81               2 :         , port_(p)
      82                 :     {
      83               2 :     }
      84                 : 
      85                 :     /** Check if this endpoint uses an IPv4 address.
      86                 : 
      87                 :         @return `true` if the endpoint uses IPv4, `false` if IPv6.
      88                 :     */
      89           19442 :     bool is_v4() const noexcept
      90                 :     {
      91           19442 :         return addr_.is_v4();
      92                 :     }
      93                 : 
      94                 :     /** Check if this endpoint uses an IPv6 address.
      95                 : 
      96                 :         @return `true` if the endpoint uses IPv6, `false` if IPv4.
      97                 :     */
      98              61 :     bool is_v6() const noexcept
      99                 :     {
     100              61 :         return addr_.is_v6();
     101                 :     }
     102                 : 
     103                 :     /** Return the IP address.
     104                 : 
     105                 :         @return The endpoint's address.
     106                 :     */
     107           11549 :     ip_address address() const noexcept
     108                 :     {
     109           11549 :         return addr_;
     110                 :     }
     111                 : 
     112                 :     /** Return the port number.
     113                 : 
     114                 :         @return The port number in host byte order.
     115                 :     */
     116           12243 :     std::uint16_t port() const noexcept
     117                 :     {
     118           12243 :         return port_;
     119                 :     }
     120                 : 
     121                 :     /** Compare endpoints for equality.
     122                 : 
     123                 :         Two endpoints are equal if they have the same address type,
     124                 :         the same address value, and the same port.
     125                 : 
     126                 :         @return `true` if both endpoints are equal.
     127                 :     */
     128             134 :     friend bool operator==(endpoint const& a, endpoint const& b) noexcept
     129                 :     {
     130             134 :         return a.port_ == b.port_ && a.addr_ == b.addr_;
     131                 :     }
     132                 : 
     133                 :     /** Order two endpoints.
     134                 : 
     135                 :         Establishes a strict total ordering consistent with
     136                 :         @ref operator==: equal endpoints compare equivalent.
     137                 :         `operator<=>` orders endpoints first by address family
     138                 :         (IPv4 before IPv6), then by address value, then by port. This
     139                 :         makes `endpoint` usable as a key in ordered containers
     140                 :         such as `std::map` and `std::set`.
     141                 : 
     142                 :         @return The relative order of @p a and @p b.
     143                 :     */
     144                 :     friend std::strong_ordering
     145              25 :     operator<=>(endpoint const& a, endpoint const& b) noexcept
     146                 :     {
     147              25 :         if (auto c = a.addr_ <=> b.addr_; c != 0)
     148              12 :             return c;
     149              13 :         return a.port_ <=> b.port_;
     150                 :     }
     151                 : };
     152                 : 
     153                 : /** Identifies which of the four supported endpoint string formats a string is in.
     154                 : 
     155                 :     Used internally by `make_endpoint` to determine
     156                 :     the format of an endpoint string.
     157                 : */
     158                 : enum class endpoint_format
     159                 : {
     160                 :     ipv4_no_port,   ///< "192.168.1.1"
     161                 :     ipv4_with_port, ///< "192.168.1.1:8080"
     162                 :     ipv6_no_port,   ///< "::1" or "1:2:3:4:5:6:7:8"
     163                 :     ipv6_bracketed  ///< "[::1]" or "[::1]:8080"
     164                 : };
     165                 : 
     166                 : /** Detect the format of an endpoint string.
     167                 : 
     168                 :     This helper function determines the endpoint format
     169                 :     based on simple rules:
     170                 :     1. Starts with `[` -> `ipv6_bracketed`
     171                 :     2. Else count `:` characters:
     172                 :        - 0 colons -> `ipv4_no_port`
     173                 :        - 1 colon -> `ipv4_with_port`
     174                 :        - 2+ colons -> `ipv6_no_port`
     175                 : 
     176                 :     @param s The string to analyze.
     177                 :     @return The detected endpoint format.
     178                 : */
     179                 : BOOST_COROSIO_DECL
     180                 : endpoint_format detect_endpoint_format(std::string_view s) noexcept;
     181                 : 
     182                 : /** Create an endpoint from a string.
     183                 : 
     184                 :     This function parses an endpoint string in one of
     185                 :     the following formats:
     186                 : 
     187                 :     @li IPv4 without port: `192.168.1.1`
     188                 :     @li IPv4 with port: `192.168.1.1:8080`
     189                 :     @li IPv6 without port: `::1` or `2001:db8::1`
     190                 :     @li IPv6 with port (bracketed): `[::1]:8080`
     191                 : 
     192                 :     @par Example
     193                 :     @par !example make_endpoint
     194                 : 
     195                 :     @param s The string to parse.
     196                 :     @return The error code, empty on success, and the parsed
     197                 :         endpoint — default-constructed on failure.
     198                 : */
     199                 : [[nodiscard]] BOOST_COROSIO_DECL capy::results<endpoint>
     200                 : make_endpoint(std::string_view s) noexcept;
     201                 : 
     202                 : } // namespace boost::corosio
     203                 : 
     204                 : namespace std {
     205                 : 
     206                 : /// Hash support for `boost::corosio::endpoint`.
     207                 : template<>
     208                 : struct hash<boost::corosio::endpoint>
     209                 : {
     210                 :     /// Return the hash of `ep`.
     211              12 :     std::size_t operator()(boost::corosio::endpoint const& ep) const noexcept
     212                 :     {
     213              12 :         std::size_t const h1 = hash<boost::corosio::ip_address>()(ep.address());
     214              12 :         std::size_t const h2 = hash<std::uint16_t>()(ep.port());
     215              12 :         return h1 ^ (h2 + 0x9e3779b9 + (h1 << 6) + (h1 >> 2));
     216                 :     }
     217                 : };
     218                 : 
     219                 : } // namespace std
     220                 : 
     221                 : #endif
        

Generated by: LCOV version 2.3