File indexing completed on 2025-01-18 09:54:51
0001
0002
0003
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
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
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