cppcoro/include/cppcoro/net/ip_address.hpp
2017-12-18 22:48:00 +10:30

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