148 lines
3.2 KiB
C++
148 lines
3.2 KiB
C++
///////////////////////////////////////////////////////////////////////////////
|
|
// Copyright (c) Lewis Baker
|
|
// Licenced under MIT license. See LICENSE.txt for details.
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
#ifndef CPPCORO_NET_IP_ADDRESS_HPP_INCLUDED
|
|
#define CPPCORO_NET_IP_ADDRESS_HPP_INCLUDED
|
|
|
|
#include <cppcoro/net/ipv4_address.hpp>
|
|
#include <cppcoro/net/ipv6_address.hpp>
|
|
|
|
#include <cassert>
|
|
#include <optional>
|
|
#include <string>
|
|
|
|
namespace cppcoro
|
|
{
|
|
namespace net
|
|
{
|
|
class ip_address
|
|
{
|
|
public:
|
|
|
|
// Constructs to IPv4 address 0.0.0.0
|
|
ip_address() noexcept;
|
|
|
|
ip_address(ipv4_address address) noexcept;
|
|
ip_address(ipv6_address address) noexcept;
|
|
|
|
bool is_ipv4() const noexcept { return m_family == family::ipv4; }
|
|
bool is_ipv6() const noexcept { return m_family == family::ipv6; }
|
|
|
|
const ipv4_address& to_ipv4() const;
|
|
const ipv6_address& to_ipv6() const;
|
|
|
|
const std::uint8_t* bytes() const noexcept;
|
|
|
|
std::string to_string() const;
|
|
|
|
static std::optional<ip_address> from_string(std::string_view string) noexcept;
|
|
|
|
bool operator==(const ip_address& rhs) const noexcept;
|
|
bool operator!=(const ip_address& rhs) const noexcept;
|
|
|
|
// ipv4_address sorts less than ipv6_address
|
|
bool operator<(const ip_address& rhs) const noexcept;
|
|
bool operator>(const ip_address& rhs) const noexcept;
|
|
bool operator<=(const ip_address& rhs) const noexcept;
|
|
bool operator>=(const ip_address& rhs) const noexcept;
|
|
|
|
private:
|
|
|
|
enum class family
|
|
{
|
|
ipv4,
|
|
ipv6
|
|
};
|
|
|
|
family m_family;
|
|
|
|
union
|
|
{
|
|
ipv4_address m_ipv4;
|
|
ipv6_address m_ipv6;
|
|
};
|
|
|
|
};
|
|
|
|
inline ip_address::ip_address() noexcept
|
|
: m_family(family::ipv4)
|
|
, m_ipv4()
|
|
{}
|
|
|
|
inline ip_address::ip_address(ipv4_address address) noexcept
|
|
: m_family(family::ipv4)
|
|
, m_ipv4(address)
|
|
{}
|
|
|
|
inline ip_address::ip_address(ipv6_address address) noexcept
|
|
: m_family(family::ipv6)
|
|
, m_ipv6(address)
|
|
{
|
|
}
|
|
|
|
inline const ipv4_address& ip_address::to_ipv4() const
|
|
{
|
|
assert(is_ipv4());
|
|
return m_ipv4;
|
|
}
|
|
|
|
inline const ipv6_address& ip_address::to_ipv6() const
|
|
{
|
|
assert(is_ipv6());
|
|
return m_ipv6;
|
|
}
|
|
|
|
inline const std::uint8_t* ip_address::bytes() const noexcept
|
|
{
|
|
return is_ipv4() ? m_ipv4.bytes() : m_ipv6.bytes();
|
|
}
|
|
|
|
inline bool ip_address::operator==(const ip_address& rhs) const noexcept
|
|
{
|
|
if (is_ipv4())
|
|
{
|
|
return rhs.is_ipv4() && m_ipv4 == rhs.m_ipv4;
|
|
}
|
|
else
|
|
{
|
|
return rhs.is_ipv6() && m_ipv6 == rhs.m_ipv6;
|
|
}
|
|
}
|
|
|
|
inline bool ip_address::operator!=(const ip_address& rhs) const noexcept
|
|
{
|
|
return !(*this == rhs);
|
|
}
|
|
|
|
inline bool ip_address::operator<(const ip_address& rhs) const noexcept
|
|
{
|
|
if (is_ipv4())
|
|
{
|
|
return !rhs.is_ipv4() || m_ipv4 < rhs.m_ipv4;
|
|
}
|
|
else
|
|
{
|
|
return rhs.is_ipv6() && m_ipv6 < rhs.m_ipv6;
|
|
}
|
|
}
|
|
|
|
inline bool ip_address::operator>(const ip_address& rhs) const noexcept
|
|
{
|
|
return rhs < *this;
|
|
}
|
|
|
|
inline bool ip_address::operator<=(const ip_address& rhs) const noexcept
|
|
{
|
|
return !(rhs < *this);
|
|
}
|
|
|
|
inline bool ip_address::operator>=(const ip_address& rhs) const noexcept
|
|
{
|
|
return !(*this < rhs);
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif
|