File indexing completed on 2025-03-13 09:06:31
0001
0002
0003
0004
0005 #ifndef CPPCORO_NET_IP_ADDRESS_HPP_INCLUDED
0006 #define CPPCORO_NET_IP_ADDRESS_HPP_INCLUDED
0007
0008 #include <cppcoro/net/ipv4_address.hpp>
0009 #include <cppcoro/net/ipv6_address.hpp>
0010
0011 #include <cassert>
0012 #include <optional>
0013 #include <string>
0014
0015 namespace cppcoro
0016 {
0017 namespace net
0018 {
0019 class ip_address
0020 {
0021 public:
0022
0023
0024 ip_address() noexcept;
0025
0026 ip_address(ipv4_address address) noexcept;
0027 ip_address(ipv6_address address) noexcept;
0028
0029 bool is_ipv4() const noexcept { return m_family == family::ipv4; }
0030 bool is_ipv6() const noexcept { return m_family == family::ipv6; }
0031
0032 const ipv4_address& to_ipv4() const;
0033 const ipv6_address& to_ipv6() const;
0034
0035 const std::uint8_t* bytes() const noexcept;
0036
0037 std::string to_string() const;
0038
0039 static std::optional<ip_address> from_string(std::string_view string) noexcept;
0040
0041 bool operator==(const ip_address& rhs) const noexcept;
0042 bool operator!=(const ip_address& rhs) const noexcept;
0043
0044
0045 bool operator<(const ip_address& rhs) const noexcept;
0046 bool operator>(const ip_address& rhs) const noexcept;
0047 bool operator<=(const ip_address& rhs) const noexcept;
0048 bool operator>=(const ip_address& rhs) const noexcept;
0049
0050 private:
0051
0052 enum class family
0053 {
0054 ipv4,
0055 ipv6
0056 };
0057
0058 family m_family;
0059
0060 union
0061 {
0062 ipv4_address m_ipv4;
0063 ipv6_address m_ipv6;
0064 };
0065
0066 };
0067
0068 inline ip_address::ip_address() noexcept
0069 : m_family(family::ipv4)
0070 , m_ipv4()
0071 {}
0072
0073 inline ip_address::ip_address(ipv4_address address) noexcept
0074 : m_family(family::ipv4)
0075 , m_ipv4(address)
0076 {}
0077
0078 inline ip_address::ip_address(ipv6_address address) noexcept
0079 : m_family(family::ipv6)
0080 , m_ipv6(address)
0081 {
0082 }
0083
0084 inline const ipv4_address& ip_address::to_ipv4() const
0085 {
0086 assert(is_ipv4());
0087 return m_ipv4;
0088 }
0089
0090 inline const ipv6_address& ip_address::to_ipv6() const
0091 {
0092 assert(is_ipv6());
0093 return m_ipv6;
0094 }
0095
0096 inline const std::uint8_t* ip_address::bytes() const noexcept
0097 {
0098 return is_ipv4() ? m_ipv4.bytes() : m_ipv6.bytes();
0099 }
0100
0101 inline bool ip_address::operator==(const ip_address& rhs) const noexcept
0102 {
0103 if (is_ipv4())
0104 {
0105 return rhs.is_ipv4() && m_ipv4 == rhs.m_ipv4;
0106 }
0107 else
0108 {
0109 return rhs.is_ipv6() && m_ipv6 == rhs.m_ipv6;
0110 }
0111 }
0112
0113 inline bool ip_address::operator!=(const ip_address& rhs) const noexcept
0114 {
0115 return !(*this == rhs);
0116 }
0117
0118 inline bool ip_address::operator<(const ip_address& rhs) const noexcept
0119 {
0120 if (is_ipv4())
0121 {
0122 return !rhs.is_ipv4() || m_ipv4 < rhs.m_ipv4;
0123 }
0124 else
0125 {
0126 return rhs.is_ipv6() && m_ipv6 < rhs.m_ipv6;
0127 }
0128 }
0129
0130 inline bool ip_address::operator>(const ip_address& rhs) const noexcept
0131 {
0132 return rhs < *this;
0133 }
0134
0135 inline bool ip_address::operator<=(const ip_address& rhs) const noexcept
0136 {
0137 return !(rhs < *this);
0138 }
0139
0140 inline bool ip_address::operator>=(const ip_address& rhs) const noexcept
0141 {
0142 return !(*this < rhs);
0143 }
0144 }
0145 }
0146
0147 #endif