1 | // |
2 | // ip/basic_endpoint.hpp |
3 | // ~~~~~~~~~~~~~~~~~~~~~ |
4 | // |
5 | // Copyright (c) 2003-2024 Christopher M. Kohlhoff (chris at kohlhoff dot com) |
6 | // |
7 | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
8 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
9 | // |
10 | |
11 | #ifndef BOOST_ASIO_IP_BASIC_ENDPOINT_HPP |
12 | #define BOOST_ASIO_IP_BASIC_ENDPOINT_HPP |
13 | |
14 | #if defined(_MSC_VER) && (_MSC_VER >= 1200) |
15 | # pragma once |
16 | #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) |
17 | |
18 | #include <boost/asio/detail/config.hpp> |
19 | #include <functional> |
20 | #include <boost/asio/detail/cstdint.hpp> |
21 | #include <boost/asio/ip/address.hpp> |
22 | #include <boost/asio/ip/detail/endpoint.hpp> |
23 | |
24 | #if !defined(BOOST_ASIO_NO_IOSTREAM) |
25 | # include <iosfwd> |
26 | #endif // !defined(BOOST_ASIO_NO_IOSTREAM) |
27 | |
28 | #include <boost/asio/detail/push_options.hpp> |
29 | |
30 | namespace boost { |
31 | namespace asio { |
32 | namespace ip { |
33 | |
34 | /// Type used for storing port numbers. |
35 | typedef uint_least16_t port_type; |
36 | |
37 | /// Describes an endpoint for a version-independent IP socket. |
38 | /** |
39 | * The boost::asio::ip::basic_endpoint class template describes an endpoint that |
40 | * may be associated with a particular socket. |
41 | * |
42 | * @par Thread Safety |
43 | * @e Distinct @e objects: Safe.@n |
44 | * @e Shared @e objects: Unsafe. |
45 | * |
46 | * @par Concepts: |
47 | * Endpoint. |
48 | */ |
49 | template <typename InternetProtocol> |
50 | class basic_endpoint |
51 | { |
52 | public: |
53 | /// The protocol type associated with the endpoint. |
54 | typedef InternetProtocol protocol_type; |
55 | |
56 | /// The type of the endpoint structure. This type is dependent on the |
57 | /// underlying implementation of the socket layer. |
58 | #if defined(GENERATING_DOCUMENTATION) |
59 | typedef implementation_defined data_type; |
60 | #else |
61 | typedef boost::asio::detail::socket_addr_type data_type; |
62 | #endif |
63 | |
64 | /// Default constructor. |
65 | basic_endpoint() noexcept |
66 | : impl_() |
67 | { |
68 | } |
69 | |
70 | /// Construct an endpoint using a port number, specified in the host's byte |
71 | /// order. The IP address will be the any address (i.e. INADDR_ANY or |
72 | /// in6addr_any). This constructor would typically be used for accepting new |
73 | /// connections. |
74 | /** |
75 | * @par Examples |
76 | * To initialise an IPv4 TCP endpoint for port 1234, use: |
77 | * @code |
78 | * boost::asio::ip::tcp::endpoint ep(boost::asio::ip::tcp::v4(), 1234); |
79 | * @endcode |
80 | * |
81 | * To specify an IPv6 UDP endpoint for port 9876, use: |
82 | * @code |
83 | * boost::asio::ip::udp::endpoint ep(boost::asio::ip::udp::v6(), 9876); |
84 | * @endcode |
85 | */ |
86 | basic_endpoint(const InternetProtocol& internet_protocol, |
87 | port_type port_num) noexcept |
88 | : impl_(internet_protocol.family(), port_num) |
89 | { |
90 | } |
91 | |
92 | /// Construct an endpoint using a port number and an IP address. This |
93 | /// constructor may be used for accepting connections on a specific interface |
94 | /// or for making a connection to a remote endpoint. |
95 | basic_endpoint(const boost::asio::ip::address& addr, |
96 | port_type port_num) noexcept |
97 | : impl_(addr, port_num) |
98 | { |
99 | } |
100 | |
101 | /// Copy constructor. |
102 | basic_endpoint(const basic_endpoint& other) noexcept |
103 | : impl_(other.impl_) |
104 | { |
105 | } |
106 | |
107 | /// Move constructor. |
108 | basic_endpoint(basic_endpoint&& other) noexcept |
109 | : impl_(other.impl_) |
110 | { |
111 | } |
112 | |
113 | /// Assign from another endpoint. |
114 | basic_endpoint& operator=(const basic_endpoint& other) noexcept |
115 | { |
116 | impl_ = other.impl_; |
117 | return *this; |
118 | } |
119 | |
120 | /// Move-assign from another endpoint. |
121 | basic_endpoint& operator=(basic_endpoint&& other) noexcept |
122 | { |
123 | impl_ = other.impl_; |
124 | return *this; |
125 | } |
126 | |
127 | /// The protocol associated with the endpoint. |
128 | protocol_type protocol() const noexcept |
129 | { |
130 | if (impl_.is_v4()) |
131 | return InternetProtocol::v4(); |
132 | return InternetProtocol::v6(); |
133 | } |
134 | |
135 | /// Get the underlying endpoint in the native type. |
136 | data_type* data() noexcept |
137 | { |
138 | return impl_.data(); |
139 | } |
140 | |
141 | /// Get the underlying endpoint in the native type. |
142 | const data_type* data() const noexcept |
143 | { |
144 | return impl_.data(); |
145 | } |
146 | |
147 | /// Get the underlying size of the endpoint in the native type. |
148 | std::size_t size() const noexcept |
149 | { |
150 | return impl_.size(); |
151 | } |
152 | |
153 | /// Set the underlying size of the endpoint in the native type. |
154 | void resize(std::size_t new_size) |
155 | { |
156 | impl_.resize(new_size); |
157 | } |
158 | |
159 | /// Get the capacity of the endpoint in the native type. |
160 | std::size_t capacity() const noexcept |
161 | { |
162 | return impl_.capacity(); |
163 | } |
164 | |
165 | /// Get the port associated with the endpoint. The port number is always in |
166 | /// the host's byte order. |
167 | port_type port() const noexcept |
168 | { |
169 | return impl_.port(); |
170 | } |
171 | |
172 | /// Set the port associated with the endpoint. The port number is always in |
173 | /// the host's byte order. |
174 | void port(port_type port_num) noexcept |
175 | { |
176 | impl_.port(port_num); |
177 | } |
178 | |
179 | /// Get the IP address associated with the endpoint. |
180 | boost::asio::ip::address address() const noexcept |
181 | { |
182 | return impl_.address(); |
183 | } |
184 | |
185 | /// Set the IP address associated with the endpoint. |
186 | void address(const boost::asio::ip::address& addr) noexcept |
187 | { |
188 | impl_.address(addr); |
189 | } |
190 | |
191 | /// Compare two endpoints for equality. |
192 | friend bool operator==(const basic_endpoint<InternetProtocol>& e1, |
193 | const basic_endpoint<InternetProtocol>& e2) noexcept |
194 | { |
195 | return e1.impl_ == e2.impl_; |
196 | } |
197 | |
198 | /// Compare two endpoints for inequality. |
199 | friend bool operator!=(const basic_endpoint<InternetProtocol>& e1, |
200 | const basic_endpoint<InternetProtocol>& e2) noexcept |
201 | { |
202 | return !(e1 == e2); |
203 | } |
204 | |
205 | /// Compare endpoints for ordering. |
206 | friend bool operator<(const basic_endpoint<InternetProtocol>& e1, |
207 | const basic_endpoint<InternetProtocol>& e2) noexcept |
208 | { |
209 | return e1.impl_ < e2.impl_; |
210 | } |
211 | |
212 | /// Compare endpoints for ordering. |
213 | friend bool operator>(const basic_endpoint<InternetProtocol>& e1, |
214 | const basic_endpoint<InternetProtocol>& e2) noexcept |
215 | { |
216 | return e2.impl_ < e1.impl_; |
217 | } |
218 | |
219 | /// Compare endpoints for ordering. |
220 | friend bool operator<=(const basic_endpoint<InternetProtocol>& e1, |
221 | const basic_endpoint<InternetProtocol>& e2) noexcept |
222 | { |
223 | return !(e2 < e1); |
224 | } |
225 | |
226 | /// Compare endpoints for ordering. |
227 | friend bool operator>=(const basic_endpoint<InternetProtocol>& e1, |
228 | const basic_endpoint<InternetProtocol>& e2) noexcept |
229 | { |
230 | return !(e1 < e2); |
231 | } |
232 | |
233 | private: |
234 | // The underlying IP endpoint. |
235 | boost::asio::ip::detail::endpoint impl_; |
236 | }; |
237 | |
238 | #if !defined(BOOST_ASIO_NO_IOSTREAM) |
239 | |
240 | /// Output an endpoint as a string. |
241 | /** |
242 | * Used to output a human-readable string for a specified endpoint. |
243 | * |
244 | * @param os The output stream to which the string will be written. |
245 | * |
246 | * @param endpoint The endpoint to be written. |
247 | * |
248 | * @return The output stream. |
249 | * |
250 | * @relates boost::asio::ip::basic_endpoint |
251 | */ |
252 | template <typename Elem, typename Traits, typename InternetProtocol> |
253 | std::basic_ostream<Elem, Traits>& operator<<( |
254 | std::basic_ostream<Elem, Traits>& os, |
255 | const basic_endpoint<InternetProtocol>& endpoint); |
256 | |
257 | #endif // !defined(BOOST_ASIO_NO_IOSTREAM) |
258 | |
259 | } // namespace ip |
260 | } // namespace asio |
261 | } // namespace boost |
262 | |
263 | namespace std { |
264 | |
265 | template <typename InternetProtocol> |
266 | struct hash<boost::asio::ip::basic_endpoint<InternetProtocol>> |
267 | { |
268 | std::size_t operator()( |
269 | const boost::asio::ip::basic_endpoint<InternetProtocol>& ep) |
270 | const noexcept |
271 | { |
272 | std::size_t hash1 = std::hash<boost::asio::ip::address>()(ep.address()); |
273 | std::size_t hash2 = std::hash<unsigned short>()(ep.port()); |
274 | return hash1 ^ (hash2 + 0x9e3779b9 + (hash1 << 6) + (hash1 >> 2)); |
275 | } |
276 | }; |
277 | |
278 | } // namespace std |
279 | |
280 | #include <boost/asio/detail/pop_options.hpp> |
281 | |
282 | #include <boost/asio/ip/impl/basic_endpoint.hpp> |
283 | |
284 | #endif // BOOST_ASIO_IP_BASIC_ENDPOINT_HPP |
285 | |