address_v4.hpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  1. //
  2. // ip/address_v4.hpp
  3. // ~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2023 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. #ifndef ASIO_IP_ADDRESS_V4_HPP
  11. #define ASIO_IP_ADDRESS_V4_HPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include "asio/detail/config.hpp"
  16. #include <functional>
  17. #include <string>
  18. #include "asio/detail/array.hpp"
  19. #include "asio/detail/cstdint.hpp"
  20. #include "asio/detail/socket_types.hpp"
  21. #include "asio/detail/string_view.hpp"
  22. #include "asio/detail/winsock_init.hpp"
  23. #include "asio/error_code.hpp"
  24. #if !defined(ASIO_NO_IOSTREAM)
  25. # include <iosfwd>
  26. #endif // !defined(ASIO_NO_IOSTREAM)
  27. #include "asio/detail/push_options.hpp"
  28. namespace asio {
  29. namespace ip {
  30. /// Implements IP version 4 style addresses.
  31. /**
  32. * The asio::ip::address_v4 class provides the ability to use and
  33. * manipulate IP version 4 addresses.
  34. *
  35. * @par Thread Safety
  36. * @e Distinct @e objects: Safe.@n
  37. * @e Shared @e objects: Unsafe.
  38. */
  39. class address_v4
  40. {
  41. public:
  42. /// The type used to represent an address as an unsigned integer.
  43. typedef uint_least32_t uint_type;
  44. /// The type used to represent an address as an array of bytes.
  45. /**
  46. * @note This type is defined in terms of the C++0x template @c std::array
  47. * when it is available. Otherwise, it uses @c boost:array.
  48. */
  49. #if defined(GENERATING_DOCUMENTATION)
  50. typedef array<unsigned char, 4> bytes_type;
  51. #else
  52. typedef asio::detail::array<unsigned char, 4> bytes_type;
  53. #endif
  54. /// Default constructor.
  55. /**
  56. * Initialises the @c address_v4 object such that:
  57. * @li <tt>to_bytes()</tt> yields <tt>{0, 0, 0, 0}</tt>; and
  58. * @li <tt>to_uint() == 0</tt>.
  59. */
  60. address_v4() noexcept
  61. {
  62. addr_.s_addr = 0;
  63. }
  64. /// Construct an address from raw bytes.
  65. /**
  66. * Initialises the @c address_v4 object such that <tt>to_bytes() ==
  67. * bytes</tt>.
  68. *
  69. * @throws out_of_range Thrown if any element in @c bytes is not in the range
  70. * <tt>0 - 0xFF</tt>. Note that no range checking is required for platforms
  71. * where <tt>std::numeric_limits<unsigned char>::max()</tt> is <tt>0xFF</tt>.
  72. */
  73. ASIO_DECL explicit address_v4(const bytes_type& bytes);
  74. /// Construct an address from an unsigned integer in host byte order.
  75. /**
  76. * Initialises the @c address_v4 object such that <tt>to_uint() == addr</tt>.
  77. */
  78. ASIO_DECL explicit address_v4(uint_type addr);
  79. /// Copy constructor.
  80. address_v4(const address_v4& other) noexcept
  81. : addr_(other.addr_)
  82. {
  83. }
  84. /// Move constructor.
  85. address_v4(address_v4&& other) noexcept
  86. : addr_(other.addr_)
  87. {
  88. }
  89. /// Assign from another address.
  90. address_v4& operator=(const address_v4& other) noexcept
  91. {
  92. addr_ = other.addr_;
  93. return *this;
  94. }
  95. /// Move-assign from another address.
  96. address_v4& operator=(address_v4&& other) noexcept
  97. {
  98. addr_ = other.addr_;
  99. return *this;
  100. }
  101. /// Get the address in bytes, in network byte order.
  102. ASIO_DECL bytes_type to_bytes() const noexcept;
  103. /// Get the address as an unsigned integer in host byte order.
  104. ASIO_DECL uint_type to_uint() const noexcept;
  105. #if !defined(ASIO_NO_DEPRECATED)
  106. /// (Deprecated: Use to_uint().) Get the address as an unsigned long in host
  107. /// byte order.
  108. ASIO_DECL unsigned long to_ulong() const;
  109. #endif // !defined(ASIO_NO_DEPRECATED)
  110. /// Get the address as a string in dotted decimal format.
  111. ASIO_DECL std::string to_string() const;
  112. #if !defined(ASIO_NO_DEPRECATED)
  113. /// (Deprecated: Use other overload.) Get the address as a string in dotted
  114. /// decimal format.
  115. ASIO_DECL std::string to_string(asio::error_code& ec) const;
  116. /// (Deprecated: Use make_address_v4().) Create an address from an IP address
  117. /// string in dotted decimal form.
  118. static address_v4 from_string(const char* str);
  119. /// (Deprecated: Use make_address_v4().) Create an address from an IP address
  120. /// string in dotted decimal form.
  121. static address_v4 from_string(
  122. const char* str, asio::error_code& ec);
  123. /// (Deprecated: Use make_address_v4().) Create an address from an IP address
  124. /// string in dotted decimal form.
  125. static address_v4 from_string(const std::string& str);
  126. /// (Deprecated: Use make_address_v4().) Create an address from an IP address
  127. /// string in dotted decimal form.
  128. static address_v4 from_string(
  129. const std::string& str, asio::error_code& ec);
  130. #endif // !defined(ASIO_NO_DEPRECATED)
  131. /// Determine whether the address is a loopback address.
  132. /**
  133. * This function tests whether the address is in the address block
  134. * <tt>127.0.0.0/8</tt>, which corresponds to the address range
  135. * <tt>127.0.0.0 - 127.255.255.255</tt>.
  136. *
  137. * @returns <tt>(to_uint() & 0xFF000000) == 0x7F000000</tt>.
  138. */
  139. ASIO_DECL bool is_loopback() const noexcept;
  140. /// Determine whether the address is unspecified.
  141. /**
  142. * This function tests whether the address is the unspecified address
  143. * <tt>0.0.0.0</tt>.
  144. *
  145. * @returns <tt>to_uint() == 0</tt>.
  146. */
  147. ASIO_DECL bool is_unspecified() const noexcept;
  148. #if !defined(ASIO_NO_DEPRECATED)
  149. /// (Deprecated: Use network_v4 class.) Determine whether the address is a
  150. /// class A address.
  151. ASIO_DECL bool is_class_a() const;
  152. /// (Deprecated: Use network_v4 class.) Determine whether the address is a
  153. /// class B address.
  154. ASIO_DECL bool is_class_b() const;
  155. /// (Deprecated: Use network_v4 class.) Determine whether the address is a
  156. /// class C address.
  157. ASIO_DECL bool is_class_c() const;
  158. #endif // !defined(ASIO_NO_DEPRECATED)
  159. /// Determine whether the address is a multicast address.
  160. /**
  161. * This function tests whether the address is in the multicast address block
  162. * <tt>224.0.0.0/4</tt>, which corresponds to the address range
  163. * <tt>224.0.0.0 - 239.255.255.255</tt>.
  164. *
  165. * @returns <tt>(to_uint() & 0xF0000000) == 0xE0000000</tt>.
  166. */
  167. ASIO_DECL bool is_multicast() const noexcept;
  168. /// Compare two addresses for equality.
  169. friend bool operator==(const address_v4& a1,
  170. const address_v4& a2) noexcept
  171. {
  172. return a1.addr_.s_addr == a2.addr_.s_addr;
  173. }
  174. /// Compare two addresses for inequality.
  175. friend bool operator!=(const address_v4& a1,
  176. const address_v4& a2) noexcept
  177. {
  178. return a1.addr_.s_addr != a2.addr_.s_addr;
  179. }
  180. /// Compare addresses for ordering.
  181. /**
  182. * Compares two addresses in host byte order.
  183. *
  184. * @returns <tt>a1.to_uint() < a2.to_uint()</tt>.
  185. */
  186. friend bool operator<(const address_v4& a1,
  187. const address_v4& a2) noexcept
  188. {
  189. return a1.to_uint() < a2.to_uint();
  190. }
  191. /// Compare addresses for ordering.
  192. /**
  193. * Compares two addresses in host byte order.
  194. *
  195. * @returns <tt>a1.to_uint() > a2.to_uint()</tt>.
  196. */
  197. friend bool operator>(const address_v4& a1,
  198. const address_v4& a2) noexcept
  199. {
  200. return a1.to_uint() > a2.to_uint();
  201. }
  202. /// Compare addresses for ordering.
  203. /**
  204. * Compares two addresses in host byte order.
  205. *
  206. * @returns <tt>a1.to_uint() <= a2.to_uint()</tt>.
  207. */
  208. friend bool operator<=(const address_v4& a1,
  209. const address_v4& a2) noexcept
  210. {
  211. return a1.to_uint() <= a2.to_uint();
  212. }
  213. /// Compare addresses for ordering.
  214. /**
  215. * Compares two addresses in host byte order.
  216. *
  217. * @returns <tt>a1.to_uint() >= a2.to_uint()</tt>.
  218. */
  219. friend bool operator>=(const address_v4& a1,
  220. const address_v4& a2) noexcept
  221. {
  222. return a1.to_uint() >= a2.to_uint();
  223. }
  224. /// Obtain an address object that represents any address.
  225. /**
  226. * This functions returns an address that represents the "any" address
  227. * <tt>0.0.0.0</tt>.
  228. *
  229. * @returns A default-constructed @c address_v4 object.
  230. */
  231. static address_v4 any() noexcept
  232. {
  233. return address_v4();
  234. }
  235. /// Obtain an address object that represents the loopback address.
  236. /**
  237. * This function returns an address that represents the well-known loopback
  238. * address <tt>127.0.0.1</tt>.
  239. *
  240. * @returns <tt>address_v4(0x7F000001)</tt>.
  241. */
  242. static address_v4 loopback() noexcept
  243. {
  244. return address_v4(0x7F000001);
  245. }
  246. /// Obtain an address object that represents the broadcast address.
  247. /**
  248. * This function returns an address that represents the broadcast address
  249. * <tt>255.255.255.255</tt>.
  250. *
  251. * @returns <tt>address_v4(0xFFFFFFFF)</tt>.
  252. */
  253. static address_v4 broadcast() noexcept
  254. {
  255. return address_v4(0xFFFFFFFF);
  256. }
  257. #if !defined(ASIO_NO_DEPRECATED)
  258. /// (Deprecated: Use network_v4 class.) Obtain an address object that
  259. /// represents the broadcast address that corresponds to the specified
  260. /// address and netmask.
  261. ASIO_DECL static address_v4 broadcast(
  262. const address_v4& addr, const address_v4& mask);
  263. /// (Deprecated: Use network_v4 class.) Obtain the netmask that corresponds
  264. /// to the address, based on its address class.
  265. ASIO_DECL static address_v4 netmask(const address_v4& addr);
  266. #endif // !defined(ASIO_NO_DEPRECATED)
  267. private:
  268. // The underlying IPv4 address.
  269. asio::detail::in4_addr_type addr_;
  270. };
  271. /// Create an IPv4 address from raw bytes in network order.
  272. /**
  273. * @relates address_v4
  274. */
  275. inline address_v4 make_address_v4(const address_v4::bytes_type& bytes)
  276. {
  277. return address_v4(bytes);
  278. }
  279. /// Create an IPv4 address from an unsigned integer in host byte order.
  280. /**
  281. * @relates address_v4
  282. */
  283. inline address_v4 make_address_v4(address_v4::uint_type addr)
  284. {
  285. return address_v4(addr);
  286. }
  287. /// Create an IPv4 address from an IP address string in dotted decimal form.
  288. /**
  289. * @relates address_v4
  290. */
  291. ASIO_DECL address_v4 make_address_v4(const char* str);
  292. /// Create an IPv4 address from an IP address string in dotted decimal form.
  293. /**
  294. * @relates address_v4
  295. */
  296. ASIO_DECL address_v4 make_address_v4(const char* str,
  297. asio::error_code& ec) noexcept;
  298. /// Create an IPv4 address from an IP address string in dotted decimal form.
  299. /**
  300. * @relates address_v4
  301. */
  302. ASIO_DECL address_v4 make_address_v4(const std::string& str);
  303. /// Create an IPv4 address from an IP address string in dotted decimal form.
  304. /**
  305. * @relates address_v4
  306. */
  307. ASIO_DECL address_v4 make_address_v4(const std::string& str,
  308. asio::error_code& ec) noexcept;
  309. #if defined(ASIO_HAS_STRING_VIEW) \
  310. || defined(GENERATING_DOCUMENTATION)
  311. /// Create an IPv4 address from an IP address string in dotted decimal form.
  312. /**
  313. * @relates address_v4
  314. */
  315. ASIO_DECL address_v4 make_address_v4(string_view str);
  316. /// Create an IPv4 address from an IP address string in dotted decimal form.
  317. /**
  318. * @relates address_v4
  319. */
  320. ASIO_DECL address_v4 make_address_v4(string_view str,
  321. asio::error_code& ec) noexcept;
  322. #endif // defined(ASIO_HAS_STRING_VIEW)
  323. // || defined(GENERATING_DOCUMENTATION)
  324. #if !defined(ASIO_NO_IOSTREAM)
  325. /// Output an address as a string.
  326. /**
  327. * Used to output a human-readable string for a specified address.
  328. *
  329. * @param os The output stream to which the string will be written.
  330. *
  331. * @param addr The address to be written.
  332. *
  333. * @return The output stream.
  334. *
  335. * @relates asio::ip::address_v4
  336. */
  337. template <typename Elem, typename Traits>
  338. std::basic_ostream<Elem, Traits>& operator<<(
  339. std::basic_ostream<Elem, Traits>& os, const address_v4& addr);
  340. #endif // !defined(ASIO_NO_IOSTREAM)
  341. } // namespace ip
  342. } // namespace asio
  343. namespace std {
  344. template <>
  345. struct hash<asio::ip::address_v4>
  346. {
  347. std::size_t operator()(const asio::ip::address_v4& addr)
  348. const noexcept
  349. {
  350. return std::hash<unsigned int>()(addr.to_uint());
  351. }
  352. };
  353. } // namespace std
  354. #include "asio/detail/pop_options.hpp"
  355. #include "asio/ip/impl/address_v4.hpp"
  356. #if defined(ASIO_HEADER_ONLY)
  357. # include "asio/ip/impl/address_v4.ipp"
  358. #endif // defined(ASIO_HEADER_ONLY)
  359. #endif // ASIO_IP_ADDRESS_V4_HPP