Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:54:51

0001 ///////////////////////////////////////////////////////////////////////////////
0002 // Copyright (c) Lewis Baker
0003 // Licenced under MIT license. See LICENSE.txt for details.
0004 ///////////////////////////////////////////////////////////////////////////////
0005 #ifndef CPPCORO_NET_IP_ENDPOINT_HPP_INCLUDED
0006 #define CPPCORO_NET_IP_ENDPOINT_HPP_INCLUDED
0007 
0008 #include <cppcoro/net/ip_address.hpp>
0009 #include <cppcoro/net/ipv4_endpoint.hpp>
0010 #include <cppcoro/net/ipv6_endpoint.hpp>
0011 
0012 #include <cassert>
0013 #include <optional>
0014 #include <string>
0015 
0016 namespace cppcoro
0017 {
0018     namespace net
0019     {
0020         class ip_endpoint
0021         {
0022         public:
0023 
0024             // Constructs to IPv4 end-point 0.0.0.0:0
0025             ip_endpoint() noexcept;
0026 
0027             ip_endpoint(ipv4_endpoint endpoint) noexcept;
0028             ip_endpoint(ipv6_endpoint endpoint) noexcept;
0029 
0030             bool is_ipv4() const noexcept { return m_family == family::ipv4; }
0031             bool is_ipv6() const noexcept { return m_family == family::ipv6; }
0032 
0033             const ipv4_endpoint& to_ipv4() const;
0034             const ipv6_endpoint& to_ipv6() const;
0035 
0036             ip_address address() const noexcept;
0037             std::uint16_t port() const noexcept;
0038 
0039             std::string to_string() const;
0040 
0041             static std::optional<ip_endpoint> from_string(std::string_view string) noexcept;
0042 
0043             bool operator==(const ip_endpoint& rhs) const noexcept;
0044             bool operator!=(const ip_endpoint& rhs) const noexcept;
0045 
0046             //  ipv4_endpoint sorts less than ipv6_endpoint
0047             bool operator<(const ip_endpoint& rhs) const noexcept;
0048             bool operator>(const ip_endpoint& rhs) const noexcept;
0049             bool operator<=(const ip_endpoint& rhs) const noexcept;
0050             bool operator>=(const ip_endpoint& rhs) const noexcept;
0051 
0052         private:
0053 
0054             enum class family
0055             {
0056                 ipv4,
0057                 ipv6
0058             };
0059 
0060             family m_family;
0061 
0062             union
0063             {
0064                 ipv4_endpoint m_ipv4;
0065                 ipv6_endpoint m_ipv6;
0066             };
0067 
0068         };
0069 
0070         inline ip_endpoint::ip_endpoint() noexcept
0071             : m_family(family::ipv4)
0072             , m_ipv4()
0073         {}
0074 
0075         inline ip_endpoint::ip_endpoint(ipv4_endpoint endpoint) noexcept
0076             : m_family(family::ipv4)
0077             , m_ipv4(endpoint)
0078         {}
0079 
0080         inline ip_endpoint::ip_endpoint(ipv6_endpoint endpoint) noexcept
0081             : m_family(family::ipv6)
0082             , m_ipv6(endpoint)
0083         {
0084         }
0085 
0086         inline const ipv4_endpoint& ip_endpoint::to_ipv4() const
0087         {
0088             assert(is_ipv4());
0089             return m_ipv4;
0090         }
0091 
0092         inline const ipv6_endpoint& ip_endpoint::to_ipv6() const
0093         {
0094             assert(is_ipv6());
0095             return m_ipv6;
0096         }
0097 
0098         inline ip_address ip_endpoint::address() const noexcept
0099         {
0100             if (is_ipv4())
0101             {
0102                 return m_ipv4.address();
0103             }
0104             else
0105             {
0106                 return m_ipv6.address();
0107             }
0108         }
0109 
0110         inline std::uint16_t ip_endpoint::port() const noexcept
0111         {
0112             return is_ipv4() ? m_ipv4.port() : m_ipv6.port();
0113         }
0114 
0115         inline bool ip_endpoint::operator==(const ip_endpoint& rhs) const noexcept
0116         {
0117             if (is_ipv4())
0118             {
0119                 return rhs.is_ipv4() && m_ipv4 == rhs.m_ipv4;
0120             }
0121             else
0122             {
0123                 return rhs.is_ipv6() && m_ipv6 == rhs.m_ipv6;
0124             }
0125         }
0126 
0127         inline bool ip_endpoint::operator!=(const ip_endpoint& rhs) const noexcept
0128         {
0129             return !(*this == rhs);
0130         }
0131 
0132         inline bool ip_endpoint::operator<(const ip_endpoint& rhs) const noexcept
0133         {
0134             if (is_ipv4())
0135             {
0136                 return !rhs.is_ipv4() || m_ipv4 < rhs.m_ipv4;
0137             }
0138             else
0139             {
0140                 return rhs.is_ipv6() && m_ipv6 < rhs.m_ipv6;
0141             }
0142         }
0143 
0144         inline bool ip_endpoint::operator>(const ip_endpoint& rhs) const noexcept
0145         {
0146             return rhs < *this;
0147         }
0148 
0149         inline bool ip_endpoint::operator<=(const ip_endpoint& rhs) const noexcept
0150         {
0151             return !(rhs < *this);
0152         }
0153 
0154         inline bool ip_endpoint::operator>=(const ip_endpoint& rhs) const noexcept
0155         {
0156             return !(*this < rhs);
0157         }
0158     }
0159 }
0160 
0161 #endif