forked from lewissbaker/cppcoro
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathip_endpoint.hpp
More file actions
161 lines (130 loc) · 3.44 KB
/
Copy pathip_endpoint.hpp
File metadata and controls
161 lines (130 loc) · 3.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
///////////////////////////////////////////////////////////////////////////////
// Copyright (c) Lewis Baker
// Licenced under MIT license. See LICENSE.txt for details.
///////////////////////////////////////////////////////////////////////////////
#ifndef CPPCORO_NET_IP_ENDPOINT_HPP_INCLUDED
#define CPPCORO_NET_IP_ENDPOINT_HPP_INCLUDED
#include <cppcoro/net/ip_address.hpp>
#include <cppcoro/net/ipv4_endpoint.hpp>
#include <cppcoro/net/ipv6_endpoint.hpp>
#include <cassert>
#include <optional>
#include <string>
namespace cppcoro
{
namespace net
{
class ip_endpoint
{
public:
// Constructs to IPv4 end-point 0.0.0.0:0
ip_endpoint() noexcept;
ip_endpoint(ipv4_endpoint endpoint) noexcept;
ip_endpoint(ipv6_endpoint endpoint) noexcept;
bool is_ipv4() const noexcept { return m_family == family::ipv4; }
bool is_ipv6() const noexcept { return m_family == family::ipv6; }
const ipv4_endpoint& to_ipv4() const;
const ipv6_endpoint& to_ipv6() const;
ip_address address() const noexcept;
std::uint16_t port() const noexcept;
std::string to_string() const;
static std::optional<ip_endpoint> from_string(std::string_view string) noexcept;
bool operator==(const ip_endpoint& rhs) const noexcept;
bool operator!=(const ip_endpoint& rhs) const noexcept;
// ipv4_endpoint sorts less than ipv6_endpoint
bool operator<(const ip_endpoint& rhs) const noexcept;
bool operator>(const ip_endpoint& rhs) const noexcept;
bool operator<=(const ip_endpoint& rhs) const noexcept;
bool operator>=(const ip_endpoint& rhs) const noexcept;
private:
enum class family
{
ipv4,
ipv6
};
family m_family;
union
{
ipv4_endpoint m_ipv4;
ipv6_endpoint m_ipv6;
};
};
inline ip_endpoint::ip_endpoint() noexcept
: m_family(family::ipv4)
, m_ipv4()
{}
inline ip_endpoint::ip_endpoint(ipv4_endpoint endpoint) noexcept
: m_family(family::ipv4)
, m_ipv4(endpoint)
{}
inline ip_endpoint::ip_endpoint(ipv6_endpoint endpoint) noexcept
: m_family(family::ipv6)
, m_ipv6(endpoint)
{
}
inline const ipv4_endpoint& ip_endpoint::to_ipv4() const
{
assert(is_ipv4());
return m_ipv4;
}
inline const ipv6_endpoint& ip_endpoint::to_ipv6() const
{
assert(is_ipv6());
return m_ipv6;
}
inline ip_address ip_endpoint::address() const noexcept
{
if (is_ipv4())
{
return m_ipv4.address();
}
else
{
return m_ipv6.address();
}
}
inline std::uint16_t ip_endpoint::port() const noexcept
{
return is_ipv4() ? m_ipv4.port() : m_ipv6.port();
}
inline bool ip_endpoint::operator==(const ip_endpoint& 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_endpoint::operator!=(const ip_endpoint& rhs) const noexcept
{
return !(*this == rhs);
}
inline bool ip_endpoint::operator<(const ip_endpoint& 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_endpoint::operator>(const ip_endpoint& rhs) const noexcept
{
return rhs < *this;
}
inline bool ip_endpoint::operator<=(const ip_endpoint& rhs) const noexcept
{
return !(rhs < *this);
}
inline bool ip_endpoint::operator>=(const ip_endpoint& rhs) const noexcept
{
return !(*this < rhs);
}
}
}
#endif