Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-03-13 09:06:31

0001 ///////////////////////////////////////////////////////////////////////////////
0002 // Copyright (c) Lewis Baker
0003 // Licenced under MIT license. See LICENSE.txt for details.
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             // Constructs to IPv4 address 0.0.0.0
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             //  ipv4_address sorts less than ipv6_address
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