ipaddress 1.1.0
Loading...
Searching...
No Matches
ip-address-base.hpp
Go to the documentation of this file.
1/**
2 * @file ip-address-base.hpp
3 * @brief Provides basic functionality for IP addresses
4 * @author Vladimir Shaleev
5 * @copyright MIT License
6 *
7 * This header file includes the core functionalities and definitions that are common to
8 * both IPv4 and IPv6 address handling. It serves as a foundational component for building
9 * specialized IP address classes and utilities.
10 */
11
12#ifndef IPADDRESS_IP_ADDRESS_BASE_HPP
13#define IPADDRESS_IP_ADDRESS_BASE_HPP
14
15#include "config.hpp"
16#include "errors.hpp"
17#include "endian.hpp"
18#include "optional.hpp"
19#include "byte-array.hpp"
20#include "fixed-string.hpp"
21
22namespace IPADDRESS_NAMESPACE {
23
24/**
25 * Enumerates the IP address versions.
26 *
27 * Defines constants representing the two versions of Internet Protocol: IPv4 and IPv6.
28 */
30 V4 = 4, /**< IPv4 version identifier. */
31 V6 = 6 /**< IPv6 version identifier. */
32};
33
34/**
35 * Enumerates the formatting options for IP address strings.
36 *
37 * Defines the formatting styles that can be applied when converting IP addresses to strings,
38 * such as full, compact, or compressed representations.
39 */
41 full = 0, /**< Full format with no compression or omission. */
42 compact, /**< Compact format with possible omission of leading zeros. */
43 compressed /**< Compressed format with maximal omission of segments or octets. */
44};
45
46/**
47 * A template base class for IP address representations.
48 *
49 * This class template serves as a base for creating IP address objects. It
50 * inherits from a base class that provides the necessary functionality, and
51 * it is extended by more specific IP address classes.
52 *
53 * @tparam Base The base class providing storage and low-level IP address functionalities.
54 */
55IPADDRESS_EXPORT template <typename Base>
56class ip_address_base : public Base {
57public:
58 using base_type = typename Base::base_type; /**< Type alias for the base storage type. */
59 using uint_type = typename Base::uint_type; /**< Type alias for the underlying unsigned integer type. */
60
61 /**
62 * Default constructor.
63 *
64 * Constructs an empty IP address object.
65 */
67 }
68
69 /**
70 * Constructs an IP address object from a byte array.
71 *
72 * @param[in] bytes The byte array representing an IP address.
73 */
74 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE explicit ip_address_base(const base_type& bytes) IPADDRESS_NOEXCEPT : Base(bytes) {
75 }
76
77 /**
78 * Static factory method to create an IP address object from a byte array.
79 *
80 * @param[in] bytes The byte array representing an IP address.
81 * @return An instance of ip address constructed from the given byte array.
82 */
83 IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE ip_address_base from_bytes(const base_type& bytes) IPADDRESS_NOEXCEPT {
84 return ip_address_base(bytes);
85 }
86
87 /**
88 * Static factory method to create an IP address object from a raw byte buffer.
89 *
90 * @param[in] bytes Pointer to the raw byte buffer representing an IP address.
91 * @param[in] byte_count The number of bytes in the buffer to use.
92 * @return An instance of ip address constructed from the given byte buffer.
93 * @parblock
94 * @remark If the number of bytes \a byte_count is less than the target number .
95 * of bytes to represent the IP address, the missing bytes will be
96 * filled with zeros.
97 * @endparblock
98 * @parblock
99 * @remark If the number of bytes \a byte_count is greater than the target .
100 * number of bytes represented by the IP address, then the extra
101 * bytes will be ignored
102 * @endparblock
103 */
104 IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE ip_address_base from_bytes(const uint8_t* bytes, size_t byte_count) IPADDRESS_NOEXCEPT {
105 base_type data = {};
106 for (size_t i = 0; i < Base::base_size && i < byte_count; ++i) {
107 data[i] = bytes[i];
108 }
109 return ip_address_base(data);
110 }
111
112#ifdef IPADDRESS_NONTYPE_TEMPLATE_PARAMETER
113
114 /**
115 * Static method template to parse an IP address from a fixed string at compile time.
116 *
117 * @tparam FixedString A non-type template parameter that holds the string representation of the IP address.
118 * @return An instance of ip address parsed from the fixed string.
119 * @note This method is only available when non-type template parameters for strings are supported.
120 * @remark If parsing fails, an error will be raised at compile time.
121 */
122 template <fixed_string FixedString>
124 constexpr auto str = FixedString;
125 auto code = error_code::no_error;
126 uint32_t value = 0;
128 if (code != error_code::no_error) {
130 }
131 return ip_address_base(result);
132 }
133
134#endif // IPADDRESS_NONTYPE_TEMPLATE_PARAMETER
135
136#if IPADDRESS_CPP_VERSION >= 17
137
138 /**
139 * Parses an IP address from a string view.
140 *
141 * This method provides a way to parse an IP address from a string view,
142 * which is a non-owning reference to a sequence of characters.
143 *
144 * @param[in] address The string view containing the IP address to parse.
145 * @return An instance of ip address parsed from the string view.
146 * @throw parse_error Exception caused by invalid input string.
147 * @note This method is available for C++17 and later versions.
148 * @remark For C++ versions prior to C++17, member functions with `std::string` and C-strings will be used instead.
149 */
151 return parse_string(address);
152 }
153
154 /**
155 * Parses an IP address from a wide string view.
156 *
157 * This method allows for parsing an IP address from a wide string view,
158 * which is typically used for wide character strings.
159 *
160 * @param[in] address The wide string view containing the IP address to parse.
161 * @return An instance of ip address parsed from the string view.
162 * @throw parse_error Exception caused by invalid input string.
163 * @note This method is available for C++17 and later versions.
164 * @remark For C++ versions prior to C++17, member functions with `std::wstring` and C-strings will be used instead.
165 */
167 return parse_string(address);
168 }
169
170#if __cpp_char8_t >= 201811L
171
172 /**
173 * Parses an IP address from a UTF-8 string view.
174 *
175 * This method parses an IP address from a given UTF-8 string view. It leverages the `char8_t`
176 * type introduced in C++20 to handle UTF-8 strings natively.
177 *
178 * @param[in] address A UTF-8 string view containing the IP address to parse.
179 * @return An instance of ip address parsed from the string view.
180 * @throw parse_error Exception caused by invalid input string.
181 * @note This method is available for C++20 and later versions where `char8_t` is supported.
182 */
184 return parse_string(address);
185 }
186
187#endif // __cpp_char8_t
188
189 /**
190 * Parses an IP address from a UTF-16 string view.
191 *
192 * This method is designed to parse an IP address from a UTF-16 string view,
193 * which is a sequence of 16-bit characters.
194 *
195 * @param[in] address The UTF-16 string view containing the IP address to parse.
196 * @return An instance of ip address parsed from the string view.
197 * @throw parse_error Exception caused by invalid input string.
198 * @note This method is available for C++17 and later versions.
199 * @remark For C++ versions prior to C++17, member functions with `std::u16string` and C-strings will be used instead.
200 */
202 return parse_string(address);
203 }
204
205 /**
206 * Parses an IP address from a UTF-32 string view.
207 *
208 * This method allows for parsing an IP address from a UTF-32 string view,
209 * which is a sequence of 32-bit characters.
210 *
211 * @param[in] address The UTF-32 string view containing the IP address to parse.
212 * @return An instance of ip address parsed from the string view.
213 * @throw parse_error Exception caused by invalid input string.
214 * @note This method is available for C++17 and later versions.
215 * @remark For C++ versions prior to C++17, member functions with `std::u32string` and C-strings will be used instead.
216 */
218 return parse_string(address);
219 }
220
221 /**
222 * Parses an IP address from a string view and reports errors through an error code.
223 *
224 * This method parses an IP address from a string view and provides an error code if the parsing fails.
225 *
226 * @param[in] address The string view containing the IP address to parse.
227 * @param[out] code A reference to an `error_code` object that will be set if an error occurs during parsing.
228 * @return An instance of ip address parsed from the string view. If parsing fails, the returned object will be in an unspecified state.
229 * @note This method is available for C++17 and later versions.
230 * @remark For C++ versions prior to C++17, member functions with `std::string` and C-strings will be used instead.
231 */
233 return parse_string(address, code);
234 }
235
236 /**
237 * Parses an IP address from a wide string view and reports errors through an error code.
238 *
239 * This method parses an IP address from a wide string view and provides an error code if the parsing fails.
240 *
241 * @param[in] address The wide string view containing the IP address to parse.
242 * @param[out] code A reference to an `error_code` object that will be set if an error occurs during parsing.
243 * @return An instance of ip address parsed from the wide string view. If parsing fails, the returned object will be in an unspecified state.
244 * @note This method is available for C++17 and later versions.
245 * @remark For C++ versions prior to C++17, member functions with `std::wstring` and C-strings will be used instead.
246 */
248 return parse_string(address, code);
249 }
250
251#if __cpp_char8_t >= 201811L
252
253 /**
254 * Parses an IP address from a UTF-8 string view and reports errors through an error code.
255 *
256 * This method parses an IP address from a UTF-8 string view and provides an error code if the parsing fails.
257 *
258 * @param[in] address The UTF-8 string view containing the IP address to parse.
259 * @param[out] code A reference to an `error_code` object that will be set if an error occurs during parsing.
260 * @return An instance of ip address parsed from the UTF-8 string view. If parsing fails, the returned object will be in an unspecified state.
261 * @note This method is available for C++20 and later versions where `char8_t` is supported.
262 */
264 return parse_string(address, code);
265 }
266
267#endif // __cpp_char8_t
268
269 /**
270 * Parses an IP address from a UTF-16 string view and reports errors through an error code.
271 *
272 * This method parses an IP address from a UTF-16 string view and provides an error code if the parsing fails.
273 *
274 * @param[in] address The UTF-16 string view containing the IP address to parse.
275 * @param[out] code A reference to an `error_code` object that will be set if an error occurs during parsing.
276 * @return An instance of ip address parsed from the UTF-16 string view. If parsing fails, the returned object will be in an unspecified state.
277 * @note This method is available for C++17 and later versions.
278 * @remark For C++ versions prior to C++17, member functions with `std::u16string` and C-strings will be used instead.
279 */
281 return parse_string(address, code);
282 }
283
284 /**
285 * Parses an IP address from a UTF-32 string view and reports errors through an error code.
286 *
287 * This method parses an IP address from a UTF-32 string view and provides an error code if the parsing fails.
288 *
289 * @param[in] address The UTF-32 string view containing the IP address to parse.
290 * @param[out] code A reference to an `error_code` object that will be set if an error occurs during parsing.
291 * @return An instance of ip address parsed from the UTF-32 string view. If parsing fails, the returned object will be in an unspecified state.
292 * @note This method is available for C++17 and later versions.
293 * @remark For C++ versions prior to C++17, member functions with `std::u32string` and C-strings will be used instead.
294 */
296 return parse_string(address, code);
297 }
298
299#else // IPADDRESS_CPP_VERSION < 17
300
301 /**
302 * Parses an IP address from a `std::string`.
303 *
304 * @param[in] address The `std::string` containing the IP address to parse.
305 * @return An instance of ip address parsed from the string.
306 * @throw parse_error Exception caused by invalid input string.
307 */
309 return parse_string(address);
310 }
311
312 /**
313 * Parses an IP address from a wide `std::wstring`.
314 *
315 * @param[in] address The wide `std::wstring` containing the IP address to parse.
316 * @return An instance of ip address parsed from the string.
317 * @throw parse_error Exception caused by invalid input string.
318 */
320 return parse_string(address);
321 }
322
323 /**
324 * Parses an IP address from a UTF-16 `std::u16string`.
325 *
326 * @param[in] address The UTF-16 `std::u16string` containing the IP address to parse.
327 * @return An instance of ip address parsed from the string.
328 * @throw parse_error Exception caused by invalid input string.
329 */
331 return parse_string(address);
332 }
333
334 /**
335 * Parses an IP address from a UTF-32 `std::u32string`.
336 *
337 * @param[in] address The UTF-32 `std::u32string` containing the IP address to parse.
338 * @return An instance of ip address parsed from the string.
339 * @throw parse_error Exception caused by invalid input string.
340 */
342 return parse_string(address);
343 }
344
345 /**
346 * Parses an IP address from a `std::string` and reports errors through an error code.
347 *
348 * @param[in] address The `std::string` containing the IP address to parse.
349 * @param[out] code A reference to an `error_code` object that will be set if an error occurs during parsing.
350 * @return An instance of ip address parsed from the string. If parsing fails, the returned object will be in an unspecified state.
351 */
352 static IPADDRESS_FORCE_INLINE ip_address_base parse(const std::string& address, error_code& code) IPADDRESS_NOEXCEPT {
353 return parse_string(address, code);
354 }
355
356 /**
357 * Parses an IP address from a wide `std::wstring` and reports errors through an error code.
358 *
359 * @param[in] address The wide `std::wstring` containing the IP address to parse.
360 * @param[out] code A reference to an `error_code` object that will be set if an error occurs during parsing.
361 * @return An instance of ip address parsed from the wide string. If parsing fails, the returned object will be in an unspecified state.
362 */
363 static IPADDRESS_FORCE_INLINE ip_address_base parse(const std::wstring& address, error_code& code) IPADDRESS_NOEXCEPT {
364 return parse_string(address, code);
365 }
366
367 /**
368 * Parses an IP address from a UTF-16 `std::u16string` and reports errors through an error code.
369 *
370 * @param[in] address The UTF-16 `std::u16string` containing the IP address to parse.
371 * @param[out] code A reference to an `error_code` object that will be set if an error occurs during parsing.
372 * @return An instance of ip address parsed from the UTF-16 string. If parsing fails, the returned object will be in an unspecified state.
373 */
374 static IPADDRESS_FORCE_INLINE ip_address_base parse(const std::u16string& address, error_code& code) IPADDRESS_NOEXCEPT {
375 return parse_string(address, code);
376 }
377
378 /**
379 * Parses an IP address from a UTF-32 `std::u32string` and reports errors through an error code.
380 *
381 * @param[in] address The UTF-32 `std::u32string` containing the IP address to parse.
382 * @param[out] code A reference to an `error_code` object that will be set if an error occurs during parsing.
383 * @return An instance of ip address parsed from the UTF-32 string. If parsing fails, the returned object will be in an unspecified state.
384 */
385 static IPADDRESS_FORCE_INLINE ip_address_base parse(const std::u32string& address, error_code& code) IPADDRESS_NOEXCEPT {
386 return parse_string(address, code);
387 }
388
389#endif // IPADDRESS_CPP_VERSION < 17
390
391 /**
392 * Parses an IP address from a character array.
393 *
394 * This method template parses an IP address from a character array of a
395 * specified size. Can check and get the result at compile time.
396 *
397 * @tparam T The character type of the array.
398 * @tparam N The size of the character array.
399 * @param[in] address The character array containing the IP address to parse.
400 * @return An instance of ip address parsed from the character array.
401 */
402 template <typename T, size_t N>
404 #ifdef IPADDRESS_NO_EXCEPTIONS
405 error_code err = error_code::no_error;
406 auto str = make_fixed_string(address, err);
407 if (err != error_code::no_error) {
408 return {};
409 }
410 #else
411 auto str = make_fixed_string(address);
412 #endif
413 return parse_string(str);
414 }
415
416 /**
417 * Parses an IP address from a character array and reports errors through an error code.
418 *
419 * This method template parses an IP address from a character array of a specified size
420 * and provides an error code if the parsing fails.
421 *
422 * @tparam T The character type of the array.
423 * @tparam N The size of the character array.
424 * @param[in] address The character array containing the IP address to parse.
425 * @param[out] code A reference to an `error_code` object that will be set if an error occurs during parsing.
426 * @return An instance of ip address parsed from the character array. If parsing fails, the returned object will be in an unspecified state.
427 */
428 template <typename T, size_t N>
429 static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE ip_address_base parse(const T(&address)[N], error_code& code) IPADDRESS_NOEXCEPT {
430 auto str = make_fixed_string(address, code);
431 return code == error_code::no_error ? parse_string(str, code) : ip_address_base{};
432 }
433
434 /**
435 * Retrieves the raw data representing the IP address in **network byte order** (big-endian).
436 *
437 * This method returns a pointer to the underlying byte array that stores the IP address.
438 *
439 * @return A pointer to the constant byte array containing the raw IP address data.
440 */
441 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const uint8_t* data() const IPADDRESS_NOEXCEPT {
442 return Base::bytes().data();
443 }
444
445 /**
446 * Checks if the IP address is a multicast address.
447 *
448 * @return `true` if the IP address is reserved for multicast use, `false` otherwise.
449 * @see [RFC 3171](https://datatracker.ietf.org/doc/html/rfc3171.html) for IPv4.
450 * @see [RFC 2373](https://datatracker.ietf.org/doc/html/rfc2373.html) for IPv6.
451 */
453
454 /**
455 * Checks if the IP address is a private address.
456 *
457 * @return `true` if the IP address is allocated for private networks, `false` otherwise.
458 * @see [iana-ipv4-special-registry](https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml).
459 * @see [iana-ipv6-special-registry](https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml).
460 */
462
463 /**
464 * Checks if the IP address is a global address.
465 *
466 * @return `true` if the IP address is allocated for public networks, `false` otherwise.
467 * @see [iana-ipv4-special-registry](https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml).
468 * @see [iana-ipv6-special-registry](https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml).
469 */
471
472 /**
473 * Checks if the IP address is a reserved address.
474 *
475 * @return `true` if the IP address is otherwise IETF reserved, `false` otherwise.
476 */
478
479 /**
480 * Checks if the IP address is a loopback address.
481 *
482 * @return `true` if the IP address is a loopback address, `false` otherwise.
483 * @see [RFC 3330](https://datatracker.ietf.org/doc/html/rfc3330.html) for IPv4.
484 * @see [RFC 2373](https://datatracker.ietf.org/doc/html/rfc2373.html) for IPv6.
485 */
487
488 /**
489 * Checks if the IP address is a link-local address.
490 *
491 * @return `true` if the IP address is reserved for link-local usage, `false` otherwise.
492 * @see [RFC 3927](https://datatracker.ietf.org/doc/html/rfc3927.html).
493 */
495
496 /**
497 * Checks if the IP address is unspecified.
498 *
499 * An unspecified IP address is an address with all bits set to zero.
500 * In IPv4, this is represented as 0.0.0.0, and in IPv6, as ::.
501 * This type of address is used to indicate the absence of an address.
502 *
503 * @return `true` if the IP address is unspecified (all bits are zero), `false` otherwise.
504 * @see [RFC 5735](https://datatracker.ietf.org/doc/html/rfc5735.html) for IPv4.
505 * @see [RFC 2373](https://datatracker.ietf.org/doc/html/rfc2373.html) for IPv6.
506 */
508 const auto& b = Base::bytes();
509 for (size_t i = 0; i < Base::base_size; ++i) {
510 if (b[i] != 0) {
511 return false;
512 }
513 }
514 return true;
515 }
516
517 /**
518 * Converts the IP address to a string representation.
519 *
520 * The function converts the binary representation of the IP address to a string.
521 * The format of the output string can be adjusted by passing the desired format as an argument.
522 * The default format is 'compressed'.
523 *
524 * @param[in] fmt The format to use for the string representation. Defaults to `format::compressed`.
525 * @return A `std::string` representing the IP address in the specified format.
526 */
528 char res[Base::base_max_string_len + 1]{};
529 const auto len = Base::ip_to_chars(Base::bytes(), fmt, res);
530 return std::string(res, len);
531 }
532
533 /**
534 * Converts the IP address to a string representation.
535 *
536 * The function converts the binary representation of the IP address to a string.
537 * The format of the output string can be adjusted by passing the desired format as an argument.
538 * The default format is 'compressed'.
539 *
540 * @param[in] fmt The format to use for the string representation. Defaults to `format::compressed`.
541 * @return A `std::wstring` representing the IP address in the specified format.
542 */
544 return internal::string_converter<wchar_t>::convert(to_string(fmt));
545 }
546
547 /**
548 * Converts the IP address to a string representation.
549 *
550 * The function converts the binary representation of the IP address to a string.
551 * The format of the output string can be adjusted by passing the desired format as an argument.
552 * The default format is 'compressed'.
553 *
554 * @param[in] fmt The format to use for the string representation. Defaults to `format::compressed`.
555 * @return A `std::u16string` representing the IP address in the specified format.
556 */
558 return internal::string_converter<char16_t>::convert(to_string(fmt));
559 }
560
561 /**
562 * Converts the IP address to a string representation.
563 *
564 * The function converts the binary representation of the IP address to a string.
565 * The format of the output string can be adjusted by passing the desired format as an argument.
566 * The default format is 'compressed'.
567 *
568 * @param[in] fmt The format to use for the string representation. Defaults to `format::compressed`.
569 * @return A `std::u32string` representing the IP address in the specified format.
570 */
572 return internal::string_converter<char32_t>::convert(to_string(fmt));
573 }
574
575#if __cpp_char8_t >= 201811L
576
577 /**
578 * Converts the IP address to a string representation.
579 *
580 * The function converts the binary representation of the IP address to a string.
581 * The format of the output string can be adjusted by passing the desired format as an argument.
582 * The default format is 'compressed'.
583 *
584 * @param[in] fmt The format to use for the string representation. Defaults to `format::compressed`.
585 * @return A `std::u8string` representing the IP address in the specified format.
586 */
589 }
590
591#endif // __cpp_char8_t
592
593 /**
594 * Swaps the contents of this IP address with another IP address.
595 *
596 * This function swaps the underlying bytes representing the IP address with those of another IP address.
597 *
598 * @param[in] ip The other IP address to swap with.
599 */
601 Base::swap(*this, ip);
602 }
603
604 /**
605 * Computes a hash value for the IP address.
606 *
607 * This function generates a hash value that can be used to uniquely identify the IP address.
608 * It can be useful when IP addresses are used as keys in hash tables.
609 *
610 * @return A `size_t` hash value of the IP address.
611 */
613 return Base::hash(Base::bytes());
614 }
615
616 /**
617 * Generates a reverse DNS lookup pointer for the IP address.
618 *
619 * This function creates a string that is the reverse DNS lookup pointer of the IP address.
620 * It is commonly used in reverse DNS lookups, where the IP address is reversed and appended with `.in-addr.arpa` for IPv4,
621 * or `.ip6.arpa` for IPv6, to form a domain name that can be looked up in the DNS system.
622 *
623 * The name of the reverse DNS PTR record for the IP address, e.g.:
624 * @code{.cpp}
625 * std::cout << ipv4_address::parse("127.0.0.1").reverse_pointer() << std::endl;
626 * std::cout << ipv6_address::parse("2001:db8::1").reverse_pointer() << std::endl;
627 *
628 * // out:
629 * // 1.0.0.127.in-addr.arpa
630 * // 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa
631 * @endcode
632 * @return A `std::string` that is the reverse DNS lookup pointer of the IP address.
633 */
635 return Base::ip_reverse_pointer(Base::bytes());
636 }
637
638 /**
639 * Converts the IP address to an unsigned integer type.
640 *
641 * This operator allows the IP address to be used as an unsigned integer type.
642 * It can be useful when a numerical representation of the IP address is needed.
643 *
644 * @return An unsigned integer representation of the IP address.
645 * @remark Bytes in integer are presented in **host byte order**.
646 */
647 IPADDRESS_NODISCARD explicit IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE operator uint_type() const IPADDRESS_NOEXCEPT {
648 return Base::to_uint();
649 }
650
651 /**
652 * Converts the IP address to a string.
653 *
654 * This operator allows the IP address to be converted to a string.
655 *
656 * @tparam T The character type of the string.
657 * @return A string representation of the IP address.
658 */
659 template <typename T>
660 IPADDRESS_NODISCARD IPADDRESS_FORCE_INLINE explicit operator std::basic_string<T, std::char_traits<T>, std::allocator<T>>() const {
661 return internal::string_converter<T>::convert(to_string());
662 }
663
664 /**
665 * Checks if two IP addresses are equal.
666 *
667 * This operator compares the binary representation of two IP addresses to determine if they are equal.
668 *
669 * @param[in] rhs The right-hand side IP address for comparison.
670 * @return `true` if both IP addresses are equal, `false` otherwise.
671 */
673 return Base::equals(*this, rhs);
674 }
675
676 /**
677 * Checks if two IP addresses are not equal.
678 *
679 * This operator compares the binary representation of two IP addresses to determine if they are not equal.
680 *
681 * @param[in] rhs The right-hand side IP address for comparison.
682 * @return `true` if both IP addresses are not equal, `false` otherwise.
683 */
685 return !(*this == rhs);
686 }
687
688#ifdef IPADDRESS_HAS_SPACESHIP_OPERATOR
689
690 /**
691 * Compares two IP addresses using the three-way comparison operator (spaceship operator).
692 *
693 * This operator provides a total ordering of IP addresses by comparing their binary representations.
694 *
695 * @param[in] rhs The right-hand side IP address for comparison.
696 * @return A value of type `std::strong_ordering` that represents the result of the comparison.
697 */
699 return Base::compare(*this, rhs);
700 }
701
702#else // !IPADDRESS_HAS_SPACESHIP_OPERATOR
703
704 /**
705 * Checks if one IP address is less than another.
706 *
707 * This operator compares the binary representation of two IP addresses to determine if
708 * the left-hand side is less than the right-hand side.
709 *
710 * @param[in] rhs The right-hand side IP address for comparison.
711 * @return `true` if the left-hand side IP address is less than the right-hand side, `false` otherwise.
712 */
714 return Base::less(*this, rhs);
715 }
716
717 /**
718 * Checks if one IP address is greater than another.
719 *
720 * This operator compares the binary representation of two IP addresses to determine if
721 * the left-hand side is greater than the right-hand side.
722 *
723 * @param[in] rhs The right-hand side IP address for comparison.
724 * @return `true` if the left-hand side IP address is greater than the right-hand side, `false` otherwise.
725 */
727 return rhs < *this;
728 }
729
730 /**
731 * Checks if one IP address is less than or equal to another.
732 *
733 * This operator compares the binary representation of two IP addresses to determine if
734 * the left-hand side is less than or equal to the right-hand side.
735 *
736 * @param[in] rhs The right-hand side IP address for comparison.
737 * @return `true` if the left-hand side IP address is less than or equal to the right-hand side, `false` otherwise.
738 */
740 return !(rhs < *this);
741 }
742
743 /**
744 * Checks if one IP address is greater than or equal to another.
745 *
746 * This operator compares the binary representation of two IP addresses to determine if
747 * the left-hand side is greater than or equal to the right-hand side.
748 *
749 * @param[in] rhs The right-hand side IP address for comparison.
750 * @return `true` if the left-hand side IP address is greater than or equal to the right-hand side, `false` otherwise.
751 */
753 return !(*this < rhs);
754 }
755
756#endif // !IPADDRESS_HAS_SPACESHIP_OPERATOR
757
758private:
759 template <typename>
760 friend class ip_network_base;
761
762 template <typename Str>
763 IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE ip_address_base parse_string(const Str& address) IPADDRESS_NOEXCEPT_WHEN_NO_EXCEPTIONS {
764 auto code = error_code::no_error;
765 uint32_t value = 0;
766 auto result = Base::ip_from_string(address.data(), address.data() + address.size(), code, value);
767 if (code != error_code::no_error) {
768 raise_error(code, value, address.data(), address.size());
769 }
770 return result;
771 }
772
773 template <typename Str>
774 static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE ip_address_base parse_string(const Str& address, error_code& code) IPADDRESS_NOEXCEPT {
776 uint32_t value = 0;
777 return Base::ip_from_string(address.data(), address.data() + address.size(), code, value);
778 }
779};
780
781#ifndef IPADDRESS_NONTYPE_TEMPLATE_PARAMETER
782
783namespace internal {
784
785template <typename Base, typename TChar, size_t MaxLen>
786IPADDRESS_NODISCARD_WHEN_NO_EXCEPTIONS IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE ip_address_base<Base> parse_ip_from_literal(const TChar* address, size_t size) IPADDRESS_NOEXCEPT_WHEN_NO_EXCEPTIONS {
787 if (size > MaxLen) {
788 raise_error(error_code::string_is_too_long, 0, address, size);
789 }
790 TChar str[MaxLen + 1] = {};
791 for (size_t i = 0; i < size && i < MaxLen; ++i) {
792 str[i] = address[i];
793 }
794 return ip_address_base<Base>::parse(str);
795}
796
797} // namespace IPADDRESS_NAMESPACE::internal
798
799#endif // IPADDRESS_NONTYPE_TEMPLATE_PARAMETER
800
801#ifndef IPADDRESS_NO_OVERLOAD_STD
802
804 static const int i = std::ios_base::xalloc();
805 return i;
806}
807
808IPADDRESS_EXPORT template <typename T>
809IPADDRESS_FORCE_INLINE std::basic_ostream<T, std::char_traits<T>>& full(std::basic_ostream<T, std::char_traits<T>>& stream) {
810 stream.iword(stream_index()) = long(format::full) + 1;
811 return stream;
812}
813
814IPADDRESS_EXPORT template <typename T>
815IPADDRESS_FORCE_INLINE std::basic_ostream<T, std::char_traits<T>>& compact(std::basic_ostream<T, std::char_traits<T>>& stream) {
816 stream.iword(stream_index()) = long(format::compact) + 1;
817 return stream;
818}
819
820IPADDRESS_EXPORT template <typename T>
821IPADDRESS_FORCE_INLINE std::basic_ostream<T, std::char_traits<T>>& compressed(std::basic_ostream<T, std::char_traits<T>>& stream) {
822 stream.iword(stream_index()) = long(format::compressed) + 1;
823 return stream;
824}
825
826#endif // IPADDRESS_NO_OVERLOAD_STD
827
828} // namespace IPADDRESS_NAMESPACE
829
830#ifndef IPADDRESS_NO_OVERLOAD_STD
831
832namespace std {
833
834IPADDRESS_EXPORT template <typename Base>
835struct hash<IPADDRESS_NAMESPACE::ip_address_base<Base>> {
836 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE size_t operator()(const IPADDRESS_NAMESPACE::ip_address_base<Base>& ip) const IPADDRESS_NOEXCEPT {
837 return ip.hash();
838 }
839};
840
841IPADDRESS_EXPORT template <typename Base>
843 ip1.swap(ip2);
844}
845
846IPADDRESS_EXPORT template <typename Base>
848 return ip.to_string();
849}
850
851IPADDRESS_EXPORT template <typename Base>
852IPADDRESS_NODISCARD IPADDRESS_FORCE_INLINE std::wstring to_wstring(const IPADDRESS_NAMESPACE::ip_address_base<Base>& ip) {
853 return ip.to_wstring();
854}
855
856IPADDRESS_EXPORT template <typename T, typename Base>
857IPADDRESS_FORCE_INLINE std::basic_ostream<T, std::char_traits<T>>& operator<<(std::basic_ostream<T, std::char_traits<T>>& stream, const IPADDRESS_NAMESPACE::ip_address_base<Base>& ip) {
858 auto& iword = stream.iword(IPADDRESS_NAMESPACE::stream_index());
859 auto fmt = iword
860 ? (IPADDRESS_NAMESPACE::format) (iword - 1)
862 iword = 0;
863 auto str = ip.to_string(fmt);
864 if (stream.flags() & ios_base::uppercase) {
865 auto end = std::find(str.cbegin(), str.cend(), '%');
866 std::transform(str.cbegin(), end, str.begin(), [](char c){
867 return std::toupper(c);
868 });
869 }
870 return stream << IPADDRESS_NAMESPACE::internal::string_converter<T>::convert(str);
871}
872
873IPADDRESS_EXPORT template <typename T, typename Base>
874IPADDRESS_FORCE_INLINE std::basic_istream<T, std::char_traits<T>>& operator>>(std::basic_istream<T, std::char_traits<T>>& stream, IPADDRESS_NAMESPACE::ip_address_base<Base>& ip) {
875 std::basic_string<T, std::char_traits<T>, std::allocator<T>> str;
876 stream >> str;
878 ip = IPADDRESS_NAMESPACE::ip_address_base<Base>::parse(str, err);
880 stream.setstate(std::ios_base::failbit);
881 }
882 return stream;
883}
884
885} // namespace std
886
887#endif // IPADDRESS_NO_OVERLOAD_STD
888
889#endif // IPADDRESS_IP_ADDRESS_BASE_HPP
A template base class for IP address representations.
Definition ip-address-base.hpp:56
constexpr inline ip_address_base() noexcept
Default constructor.
Definition ip-address-base.hpp:66
inline std::u16string to_u16string(format fmt=format::compressed) const
Converts the IP address to a string representation.
Definition ip-address-base.hpp:557
constexpr inline const uint8_t * data() const noexcept
Retrieves the raw data representing the IP address in network byte order (big-endian).
Definition ip-address-base.hpp:441
constexpr inline ip_address_base(const base_type &bytes) noexcept
Constructs an IP address object from a byte array.
Definition ip-address-base.hpp:74
static constexpr inline ip_address_base parse(const T(&address)[N])
Parses an IP address from a character array.
Definition ip-address-base.hpp:403
constexpr inline bool operator>=(const ip_address_base &rhs) const noexcept
Checks if one IP address is greater than or equal to another.
Definition ip-address-base.hpp:752
constexpr inline bool operator==(const ip_address_base &rhs) const noexcept
Checks if two IP addresses are equal.
Definition ip-address-base.hpp:672
inline std::string reverse_pointer() const
Generates a reverse DNS lookup pointer for the IP address.
Definition ip-address-base.hpp:634
constexpr inline bool is_multicast() const noexcept
Checks if the IP address is a multicast address.
Definition ip-networks.hpp:378
constexpr inline bool is_private() const noexcept
Checks if the IP address is a private address.
Definition ip-networks.hpp:368
constexpr inline bool is_reserved() const noexcept
Checks if the IP address is a reserved address.
Definition ip-networks.hpp:383
constexpr inline bool is_link_local() const noexcept
Checks if the IP address is a link-local address.
Definition ip-networks.hpp:393
inline operator std::basic_string< T, std::char_traits< T >, std::allocator< T > >() const
Converts the IP address to a string.
Definition ip-address-base.hpp:660
constexpr inline bool operator!=(const ip_address_base &rhs) const noexcept
Checks if two IP addresses are not equal.
Definition ip-address-base.hpp:684
constexpr inline bool is_unspecified() const noexcept
Checks if the IP address is unspecified.
Definition ip-address-base.hpp:507
static constexpr inline ip_address_base parse(const T(&address)[N], error_code &code) noexcept
Parses an IP address from a character array and reports errors through an error code.
Definition ip-address-base.hpp:429
constexpr inline void swap(ip_address_base &ip) noexcept
Swaps the contents of this IP address with another IP address.
Definition ip-address-base.hpp:600
constexpr inline bool operator>(const ip_address_base &rhs) const noexcept
Checks if one IP address is greater than another.
Definition ip-address-base.hpp:726
constexpr inline bool is_global() const noexcept
Checks if the IP address is a global address.
Definition ip-networks.hpp:373
static constexpr inline ip_address_base from_bytes(const base_type &bytes) noexcept
Static factory method to create an IP address object from a byte array.
Definition ip-address-base.hpp:83
constexpr inline size_t hash() const noexcept
Computes a hash value for the IP address.
Definition ip-address-base.hpp:612
inline std::wstring to_wstring(format fmt=format::compressed) const
Converts the IP address to a string representation.
Definition ip-address-base.hpp:543
constexpr inline bool operator<(const ip_address_base &rhs) const noexcept
Checks if one IP address is less than another.
Definition ip-address-base.hpp:713
inline std::u32string to_u32string(format fmt=format::compressed) const
Converts the IP address to a string representation.
Definition ip-address-base.hpp:571
static constexpr inline ip_address_base from_bytes(const uint8_t *bytes, size_t byte_count) noexcept
Static factory method to create an IP address object from a raw byte buffer.
Definition ip-address-base.hpp:104
constexpr inline bool is_loopback() const noexcept
Checks if the IP address is a loopback address.
Definition ip-networks.hpp:388
inline std::string to_string(format fmt=format::compressed) const
Converts the IP address to a string representation.
Definition ip-address-base.hpp:527
constexpr inline operator uint_type() const noexcept
Converts the IP address to an unsigned integer type.
Definition ip-address-base.hpp:647
constexpr inline bool operator<=(const ip_address_base &rhs) const noexcept
Checks if one IP address is less than or equal to another.
Definition ip-address-base.hpp:739
Template base class for representing a network of IP addresses.
Definition ip-network-base.hpp:32
#define IPADDRESS_NOEXCEPT_WHEN_NO_EXCEPTIONS
Definition config.hpp:93
#define IPADDRESS_EXPORT
Definition config.hpp:42
#define IPADDRESS_NODISCARD
Definition config.hpp:98
#define IPADDRESS_FORCE_INLINE
Definition config.hpp:112
#define IPADDRESS_NAMESPACE
Definition config.hpp:38
#define IPADDRESS_NOEXCEPT
Definition config.hpp:89
#define IPADDRESS_NODISCARD_WHEN_NO_EXCEPTIONS
Definition config.hpp:102
ip_version
Enumerates the IP address versions.
Definition ip-address-base.hpp:29
@ V4
IPv4 version identifier.
@ V6
IPv6 version identifier.
format
Enumerates the formatting options for IP address strings.
Definition ip-address-base.hpp:40
@ compressed
Compressed format with maximal omission of segments or octets.
@ compact
Compact format with possible omission of leading zeros.
@ full
Full format with no compression or omission.
error_code
Enumeration of error codes for IP address parsing and validation.
Definition errors.hpp:52
@ no_error
Indicates the absence of any errors.