ipaddress 1.1.0
Loading...
Searching...
No Matches
ip-address-iterator.hpp
Go to the documentation of this file.
1/**
2 * @file ip-address-iterator.hpp
3 * @brief Provides iterator classes for sequential IP address traversal
4 * @author Vladimir Shaleev
5 * @copyright MIT License
6 *
7 * This file defines iterator classes that enable sequential traversal over IP addresses within a network range.
8 * It includes the ip_reverse_iterator for reverse iteration, ip_address_iterator for forward iteration,
9 * and hosts_sequence for iterating over all host addresses in a network. These classes are essential for
10 * applications that perform operations on multiple IP addresses, such as network scanners, IP address management
11 * systems, and other network utilities. The iterators are designed to be flexible and work with both IPv4 and IPv6
12 */
13
14#ifndef IPADDRESS_IP_ADDRESS_ITERATOR_HPP
15#define IPADDRESS_IP_ADDRESS_ITERATOR_HPP
16
17#include "config.hpp"
18#include "ipv4-address.hpp"
19#include "ipv6-address.hpp"
20
21namespace IPADDRESS_NAMESPACE {
22
23/**
24 * A reverse iterator template class for IP addresses.
25 *
26 * The ip_reverse_iterator class template provides reverse iteration capabilities over a range of IP addresses.
27 * It is designed to work with both IPv4 and IPv6 addresses, allowing for backward traversal of IP address sequences.
28 * This class template is particularly useful in scenarios where IP addresses need to be processed in reverse order,
29 * such as deallocating IP addresses in a network. The ip_reverse_iterator leverages underlying iterator functionality
30 * to provide a robust and flexible mechanism for reverse IP address iteration.
31 *
32 * @tparam Iterator The underlying iterator type over which this reverse iterator operates.
33 */
34IPADDRESS_EXPORT template <typename Iterator>
36public:
37 using iterator_category = typename std::iterator_traits<Iterator>::iterator_category; /**< The category of the iterator. */
38 using iterator_type = Iterator; /**< The underlying iterator type. */
39 using value_type = typename std::iterator_traits<Iterator>::value_type; /**< The type of the values iterated over. */
40 using difference_type = typename std::iterator_traits<Iterator>::difference_type; /**< The type representing the difference between two iterators. */
41 using pointer = typename std::iterator_traits<Iterator>::pointer; /**< The pointer type of the iterated values. */
42 using reference = typename std::iterator_traits<Iterator>::reference; /**< The reference type of the iterated values. */
43
44 using uint_type = typename Iterator::uint_type; /**< The unsigned integer type used by the iterator. */
45
46 /**
47 * Default constructor.
48 *
49 * Constructs an ip_reverse_iterator that points to no object.
50 */
52
53 /**
54 * Constructs an ip_reverse_iterator from an underlying iterator.
55 *
56 * Creates an ip_reverse_iterator that is the reverse of the given iterator.
57 *
58 * @param[in] it The underlying iterator to reverse.
59 */
60 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE explicit ip_reverse_iterator(Iterator it) IPADDRESS_NOEXCEPT
61 : _it(it.reverse()) {
62 }
63
64 /**
65 * Calculates the difference in the number of elements between this and another ip_reverse_iterator.
66 *
67 * @param[in] other The ip_reverse_iterator to compare with.
68 * @return The number of elements between this and the other iterator.
69 * @remark This is a special function for calculate the difference between iterators,
70 * which can correctly represent all addresses using the integer number uint128_t
71 */
73 return other._it.uint_diff(_it);
74 }
75
76 /**
77 * Returns the underlying base iterator.
78 *
79 * @return The base iterator.
80 */
81 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE iterator_type base() const IPADDRESS_NOEXCEPT {
82 return _it.base();
83 }
84
85 /**
86 * Returns a reference to the current element.
87 *
88 * @return A reference to the element pointed to by the iterator.
89 */
91 return *_it;
92 }
93
94 /**
95 * Returns a pointer to the current element.
96 *
97 * @return A pointer to the element pointed to by the iterator.
98 */
100 return &*_it;
101 }
102
103 /**
104 * Accesses an element by index.
105 *
106 * @param[in] n The index of the element.
107 * @return The element at the specified index.
108 */
109 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE value_type operator[](difference_type n) const IPADDRESS_NOEXCEPT {
110 return *(_it - n);
111 }
112
113 /**
114 * Accesses an element by index.
115 *
116 * @param[in] n The index of the element.
117 * @return The element at the specified index.
118 */
119 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE value_type operator[](const uint_type& n) const IPADDRESS_NOEXCEPT {
120 return *(_it - n);
121 }
122
123 /**
124 * Pre-increment operator.
125 *
126 * @return A reference to the incremented iterator.
127 */
129 --_it;
130 return *this;
131 }
132
133 /**
134 * Post-increment operator.
135 *
136 * @return The iterator before incrementing.
137 */
139 auto tmp = *this;
140 ++(*this);
141 return tmp;
142 }
143
144 /**
145 * Pre-decrement operator.
146 *
147 * @return A reference to the decremented iterator.
148 */
150 ++_it;
151 return *this;
152 }
153
154 /**
155 * Post-decrement operator.
156 *
157 * @return The iterator before decrementing.
158 */
160 auto tmp = *this;
161 --(*this);
162 return tmp;
163 }
164
165 /**
166 * Addition assignment operator.
167 *
168 * Moves the iterator forward by \a n positions.
169 *
170 * @param[in] n The number of positions to move the iterator forward.
171 * @return A reference to the updated iterator.
172 */
173 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE ip_reverse_iterator& operator+=(difference_type n) IPADDRESS_NOEXCEPT {
174 _it -= n;
175 return *this;
176 }
177
178 /**
179 * Addition assignment operator.
180 *
181 * Moves the iterator forward by \a n positions.
182 *
183 * @param[in] n The number of positions to move the iterator forward.
184 * @return A reference to the updated iterator.
185 */
186 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE ip_reverse_iterator& operator+=(const uint_type& n) IPADDRESS_NOEXCEPT {
187 _it -= n;
188 return *this;
189 }
190
191 /**
192 * Subtraction assignment operator.
193 *
194 * Moves the iterator backward by \a n positions.
195 *
196 * @param[in] n The number of positions to move the iterator backward.
197 * @return A reference to the updated iterator.
198 */
199 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE ip_reverse_iterator& operator-=(difference_type n) IPADDRESS_NOEXCEPT {
200 _it += n;
201 return *this;
202 }
203
204 /**
205 * Subtraction assignment operator.
206 *
207 * Moves the iterator backward by \a n positions.
208 *
209 * @param[in] n The number of positions to move the iterator backward.
210 * @return A reference to the updated iterator.
211 */
212 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE ip_reverse_iterator& operator-=(const uint_type& n) IPADDRESS_NOEXCEPT {
213 _it += n;
214 return *this;
215 }
216
217 /**
218 * Addition operator.
219 *
220 * Creates a new iterator that is \a n positions ahead of the current one.
221 *
222 * @param[in] n The number of positions to move ahead.
223 * @return A new iterator that is \a n positions ahead.
224 */
226 auto tmp = *this;
227 tmp += n;
228 return tmp;
229 }
230
231 /**
232 * Addition operator.
233 *
234 * Creates a new iterator that is \a n positions ahead of the current one.
235 *
236 * @param[in] n The number of positions to move ahead.
237 * @return A new iterator that is \a n positions ahead.
238 */
240 auto tmp = *this;
241 tmp += n;
242 return tmp;
243 }
244
245 /**
246 * Addition operator.
247 *
248 * Creates a new iterator that is \a n positions ahead of the specified iterator.
249 *
250 * @param[in] n The number of positions to move ahead.
251 * @param[in] it The iterator to move ahead from.
252 * @return A new iterator that is \a n positions ahead of it.
253 */
255 return it + n;
256 }
257
258 /**
259 * Addition operator.
260 *
261 * Creates a new iterator that is \a n positions ahead of the specified iterator.
262 *
263 * @param[in] n The number of positions to move ahead.
264 * @param[in] it The iterator to move ahead from.
265 * @return A new iterator that is \a n positions ahead of it.
266 */
268 return it + n;
269 }
270
271 /**
272 * Subtraction operator.
273 *
274 * Creates a new iterator that is \a n positions behind the current one.
275 *
276 * @param[in] n The number of positions to move behind.
277 * @return A new iterator that is \a n positions behind.
278 */
280 auto tmp = *this;
281 tmp -= n;
282 return tmp;
283 }
284
285 /**
286 * Subtraction operator.
287 *
288 * Creates a new iterator that is \a n positions behind the current one.
289 *
290 * @param[in] n The number of positions to move behind.
291 * @return A new iterator that is \a n positions behind.
292 */
294 auto tmp = *this;
295 tmp -= n;
296 return tmp;
297 }
298
299 /**
300 * Subtraction operator.
301 *
302 * Calculates the difference in the number of elements between this and another ip_reverse_iterator.
303 *
304 * @param[in] other The ip_reverse_iterator to compare with.
305 * @return The number of elements between this and the other iterator.
306 */
307 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE difference_type operator-(const ip_reverse_iterator& other) const IPADDRESS_NOEXCEPT {
308 return difference_type(other._it - _it);
309 }
310
311 /**
312 * Equality operator.
313 *
314 * Compares two ip_reverse_iterators for equality.
315 *
316 * @param[in] other The ip_reverse_iterator to compare with.
317 * @return `true` if the iterators are equal, `false` otherwise.
318 */
320 return other._it == _it;
321 }
322
323 /**
324 * Inequality operator.
325 *
326 * Compares two ip_reverse_iterators for inequality.
327 *
328 * @param[in] other The ip_reverse_iterator to compare with.
329 * @return `true` if the iterators are not equal, `false` otherwise.
330 */
332 return !(*this == other);
333 }
334
335#ifdef IPADDRESS_HAS_SPACESHIP_OPERATOR
336
337 /**
338 * Three-way comparison operator (spaceship operator).
339 *
340 * Compares two ip_reverse_iterators for ordering.
341 *
342 * @param[in] other The ip_reverse_iterator to compare with.
343 * @return The result of the comparison as a std::strong_ordering value.
344 */
346 return other._it <=> _it;
347 }
348
349#else // !IPADDRESS_HAS_SPACESHIP_OPERATOR
350
351 /**
352 * Less-than operator.
353 *
354 * Compares two ip_reverse_iterators to determine if the left one is less than the right one.
355 *
356 * @param[in] other The ip_reverse_iterator to compare with.
357 * @return `true` if the left iterator is less than the right iterator, `false` otherwise.
358 */
360 return other._it < _it;
361 }
362
363 /**
364 * Less-than-or-equal-to operator.
365 *
366 * Compares two ip_reverse_iterators to determine if the left one is less than or equal to the right one.
367 *
368 * @param[in] other The ip_reverse_iterator to compare with.
369 * @return `true` if the left iterator is less than or equal to the right iterator, `false` otherwise.
370 */
372 return !(other < *this);
373 }
374
375 /**
376 * Greater-than operator.
377 *
378 * Compares two ip_reverse_iterators to determine if the left one is greater than the right one.
379 *
380 * @param[in] other The ip_reverse_iterator to compare with.
381 * @return `true` if the left iterator is greater than the right iterator, `false` otherwise.
382 */
384 return other < *this;
385 }
386
387 /**
388 * Greater-than-or-equal-to operator.
389 *
390 * Compares two ip_reverse_iterators to determine if the left one is greater than or equal to the right one.
391 *
392 * @param[in] other The ip_reverse_iterator to compare with.
393 * @return `true` if the left iterator is greater than or equal to the right iterator, `false` otherwise.
394 */
396 return !(*this < other);
397 }
398
399#endif // !IPADDRESS_HAS_SPACESHIP_OPERATOR
400
401private:
402 Iterator _it;
403};
404
405IPADDRESS_EXPORT template <typename>
406class ip_address_iterator;
407
408/**
409 * An iterator for traversing IP addresses.
410 *
411 * The `ip_address_iterator` class template is specialized for `ip_address_base<Base>` to provide iteration functionality over IP addresses.
412 * It supports all operations typical for a random access iterator, allowing both forward and backward traversal with constant time complexity
413 * for increment, decrement, and arithmetic operations. This specialization is crucial for enabling seamless iteration over IP addresses,
414 * abstracting away the underlying IP version specifics.
415 *
416 * @tparam Base The base type from which the ip_address_base is derived, representing the underlying IP address type.
417 */
418IPADDRESS_EXPORT template <typename Base>
419class ip_address_iterator<ip_address_base<Base>> {
420public:
421 using iterator_category = std::random_access_iterator_tag; /**< The category of the iterator. */
422 using value_type = ip_address_base<Base>; /**< The type of the values iterated over. */
423 using difference_type = int64_t; /**< The type representing the difference between two iterators. */
424 using pointer = const value_type*; /**< The pointer type of the iterated values. */
425 using reference = const value_type&; /**< The reference type of the iterated values. */
426
427 using uint_type = typename value_type::uint_type; /**< The unsigned integer type used by the */
428
429 /**
430 * Default constructor.
431 *
432 * Constructs an ip_address_iterator that points to no object.
433 */
435
436 /**
437 * Constructs an ip_address_iterator with a specific range and reference point.
438 *
439 * Initializes the iterator to point to a specific IP address within a range, with an optional carry for overflow handling.
440 *
441 * @param[in] ref The reference IP address to which the iterator initially points.
442 * @param[in] carry An optional carry value for overflow handling (default is 0).
443 */
444 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE explicit ip_address_iterator(reference ref, int carry = 0) IPADDRESS_NOEXCEPT
445 : _current(ref), _offset(ref.to_uint()), _carry(carry) {
446 }
447
448 /**
449 * Calculates the difference in the number of elements between this and another ip_address_iterator.
450 *
451 * @param[in] other The ip_address_iterator to compare with.
452 * @return The number of elements between this and the other iterator.
453 * @remark This is a special function for calculate the difference between iterators,
454 * which can correctly represent all addresses using the integer number uint128_t
455 */
456 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE uint_type uint_diff(const ip_address_iterator& other) const IPADDRESS_NOEXCEPT {
457 return _offset - other._offset;
458 }
459
460 /**
461 * Returns a reference to the current element.
462 *
463 * @return A reference to the element pointed to by the iterator.
464 */
466 return _current;
467 }
468
469 /**
470 * Returns a pointer to the current element.
471 *
472 * @return A pointer to the element pointed to by the iterator.
473 */
475 return &_current;
476 }
477
478 /**
479 * Accesses an element by index.
480 *
481 * @param[in] n The index of the element.
482 * @return The element at the specified index.
483 */
484 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE value_type operator[](difference_type n) const IPADDRESS_NOEXCEPT {
485 const auto& it = *this;
486 return it[uint_type(n)];
487 }
488
489 /**
490 * Accesses an element by index.
491 *
492 * @param[in] n The index of the element.
493 * @return The element at the specified index.
494 */
495 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE value_type operator[](const uint_type& n) const IPADDRESS_NOEXCEPT {
496 return value_type::from_uint(_offset + n);
497 }
498
499 /**
500 * Pre-increment operator.
501 *
502 * Increments the iterator to the next element.
503 *
504 * @return A reference to the incremented iterator.
505 */
506 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE ip_address_iterator& operator++() IPADDRESS_NOEXCEPT {
507 add(1);
508 return *this;
509 }
510
511 /**
512 * Post-increment operator.
513 *
514 * Increments the iterator to the next element and returns the iterator before the increment.
515 *
516 * @return The iterator before the increment.
517 */
518 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE ip_address_iterator operator++(int) IPADDRESS_NOEXCEPT {
519 auto tmp = *this;
520 ++(*this);
521 return tmp;
522 }
523
524 /**
525 * Pre-decrement operator.
526 *
527 * Decrements the iterator to the previous element.
528 *
529 * @return A reference to the decremented iterator.
530 */
531 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE ip_address_iterator& operator--() IPADDRESS_NOEXCEPT {
532 sub(1);
533 return *this;
534 }
535
536 /**
537 * Post-decrement operator.
538 *
539 * Decrements the iterator to the previous element and returns the iterator before the decrement.
540 *
541 * @return The iterator before the decrement.
542 */
543 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE ip_address_iterator operator--(int) IPADDRESS_NOEXCEPT {
544 auto tmp = *this;
545 --(*this);
546 return tmp;
547 }
548
549 /**
550 * Addition assignment operator.
551 *
552 * Adds a difference_type value to the iterator.
553 *
554 * @param[in] n The number to add.
555 * @return A reference to the updated iterator.
556 */
557 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE ip_address_iterator& operator+=(difference_type n) IPADDRESS_NOEXCEPT {
558 add(n);
559 return *this;
560 }
561
562 /**
563 * Addition assignment operator.
564 *
565 * Adds a uint_type value to the iterator.
566 *
567 * @param[in] n The number to add.
568 * @return A reference to the updated iterator.
569 */
570 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE ip_address_iterator& operator+=(const uint_type& n) IPADDRESS_NOEXCEPT {
571 add(n);
572 return *this;
573 }
574
575 /**
576 * Subtraction assignment operator.
577 *
578 * Subtracts a difference_type value from the iterator.
579 *
580 * @param[in] n The number to subtract.
581 * @return A reference to the updated iterator.
582 */
583 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE ip_address_iterator& operator-=(difference_type n) IPADDRESS_NOEXCEPT {
584 sub(n);
585 return *this;
586 }
587
588 /**
589 * Subtraction assignment operator.
590 *
591 * Subtracts a uint_type value from the iterator.
592 *
593 * @param[in] n The number to subtract.
594 * @return A reference to the updated iterator.
595 */
596 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE ip_address_iterator& operator-=(const uint_type& n) IPADDRESS_NOEXCEPT {
597 sub(n);
598 return *this;
599 }
600
601 /**
602 * Addition operator.
603 *
604 * Creates a new iterator that is the sum of the iterator and a difference_type value.
605 *
606 * @param[in] n The number to add.
607 * @return A new iterator that is the sum of the iterator and the number.
608 */
609 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE ip_address_iterator operator+(difference_type n) const IPADDRESS_NOEXCEPT {
610 auto tmp = *this;
611 tmp += n;
612 return tmp;
613 }
614
615 /**
616 * Addition operator.
617 *
618 * Creates a new iterator that is the sum of the iterator and a uint_type value.
619 *
620 * @param[in] n The number to add.
621 * @return A new iterator that is the sum of the iterator and the number.
622 */
623 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE ip_address_iterator operator+(const uint_type& n) const IPADDRESS_NOEXCEPT {
624 auto tmp = *this;
625 tmp += n;
626 return tmp;
627 }
628
629 /**
630 * Addition operator.
631 *
632 * Creates a new iterator that is the sum of a difference_type value and the iterator.
633 *
634 * @param[in] n The number to add.
635 * @param[in] it The iterator to add the number to.
636 * @return A new iterator that is the sum of the number and the iterator.
637 */
638 IPADDRESS_NODISCARD friend IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE ip_address_iterator operator+(difference_type n, const ip_address_iterator& it) IPADDRESS_NOEXCEPT {
639 return it + n;
640 }
641
642 /**
643 * Addition operator.
644 *
645 * Creates a new iterator that is the sum of a uint_type value and the iterator.
646 *
647 * @param[in] n The number to add.
648 * @param[in] it The iterator to add the number to.
649 * @return A new iterator that is the sum of the number and the iterator.
650 */
651 IPADDRESS_NODISCARD friend IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE ip_address_iterator operator+(const uint_type& n, const ip_address_iterator& it) IPADDRESS_NOEXCEPT {
652 return it + n;
653 }
654
655 /**
656 * Subtraction operator.
657 *
658 * Creates a new iterator that is the difference of the iterator and a difference_type value.
659 *
660 * @param[in] n The number to subtract.
661 * @return A new iterator that is the difference of the iterator and the number.
662 */
663 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE ip_address_iterator operator-(difference_type n) const IPADDRESS_NOEXCEPT {
664 auto tmp = *this;
665 tmp -= n;
666 return tmp;
667 }
668
669 /**
670 * Subtraction operator.
671 *
672 * Creates a new iterator that is the difference of the iterator and a uint_type value.
673 *
674 * @param[in] n The number to subtract.
675 * @return A new iterator that is the difference of the iterator and the number.
676 */
677 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE ip_address_iterator operator-(const uint_type& n) const IPADDRESS_NOEXCEPT {
678 auto tmp = *this;
679 tmp -= n;
680 return tmp;
681 }
682
683 /**
684 * Subtraction operator.
685 *
686 * Calculates the difference in the number of elements between this and another ip_address_iterator.
687 *
688 * @param[in] other The ip_address_iterator to compare with.
689 * @return The number of elements between this and the other iterator.
690 */
691 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE difference_type operator-(const ip_address_iterator& other) const IPADDRESS_NOEXCEPT {
692 return difference_type(_offset - other._offset);
693 }
694
695 /**
696 * Equality operator.
697 *
698 * Compares two ip_address_iterators for equality.
699 *
700 * @param[in] other The ip_address_iterator to compare with.
701 * @return `true` if the iterators are equal, `false` otherwise.
702 */
703 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool operator==(const ip_address_iterator& other) const IPADDRESS_NOEXCEPT {
704 return _carry == other._carry && _current == other._current;
705 }
706
707 /**
708 * Inequality operator.
709 *
710 * Compares two ip_address_iterators for inequality.
711 *
712 * @param[in] other The ip_address_iterator to compare with.
713 * @return `true` if the iterators are not equal, `false` otherwise.
714 */
715 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool operator!=(const ip_address_iterator& other) const IPADDRESS_NOEXCEPT {
716 return !(*this == other);
717 }
718
719#ifdef IPADDRESS_HAS_SPACESHIP_OPERATOR
720
721 /**
722 * Three-way comparison operator (spaceship operator).
723 *
724 * Compares two ip_address_iterators for ordering using the spaceship operator.
725 *
726 * @param[in] other The ip_address_iterator to compare with.
727 * @return The result of the comparison as a std::strong_ordering value.
728 */
729 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE std::strong_ordering operator<=>(const ip_address_iterator& other) const IPADDRESS_NOEXCEPT {
730 if (const auto result = _carry <=> other._carry; result == std::strong_ordering::equivalent) {
731 return _current <=> other._current;
732 } else {
733 return result;
734 }
735 }
736
737#else // !IPADDRESS_HAS_SPACESHIP_OPERATOR
738
739 /**
740 * Less-than operator.
741 *
742 * Compares two ip_address_iterators to determine if the left one is less than the right one.
743 *
744 * @param[in] other The ip_address_iterator to compare with.
745 * @return `true` if the left iterator is less than the right iterator, `false` otherwise.
746 */
747 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool operator<(const ip_address_iterator& other) const IPADDRESS_NOEXCEPT {
748 return _carry < other._carry || (_carry == other._carry && _current < other._current);
749 }
750
751 /**
752 * Less-than-or-equal-to operator.
753 *
754 * Compares two ip_address_iterators to determine if the left one is less than or equal to the right one.
755 *
756 * @param[in] other The ip_address_iterator to compare with.
757 * @return `true` if the left iterator is less than or equal to the right iterator, `false` otherwise.
758 */
759 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool operator<=(const ip_address_iterator& other) const IPADDRESS_NOEXCEPT {
760 return !(other < *this);
761 }
762
763 /**
764 * Greater-than operator.
765 *
766 * Compares two ip_address_iterators to determine if the left one is greater than the right one.
767 *
768 * @param[in] other The ip_address_iterator to compare with.
769 * @return `true` if the left iterator is greater than the right iterator, `false` otherwise.
770 */
771 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool operator>(const ip_address_iterator& other) const IPADDRESS_NOEXCEPT {
772 return other < *this;
773 }
774
775 /**
776 * Greater-than-or-equal-to operator.
777 *
778 * Compares two ip_address_iterators to determine if the left one is greater than or equal to the right one.
779 *
780 * @param[in] other The ip_address_iterator to compare with.
781 * @return `true` if the left iterator is greater than or equal to the right iterator, `false` otherwise.
782 */
783 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool operator>=(const ip_address_iterator& other) const IPADDRESS_NOEXCEPT {
784 return !(*this < other);
785 }
786
787#endif // !IPADDRESS_HAS_SPACESHIP_OPERATOR
788
789private:
790 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE ip_address_iterator base() const IPADDRESS_NOEXCEPT {
791 auto result = *this;
792 const auto old = result._offset;
793 ++result._offset;
794 if (result._offset < old) {
795 result._carry = 1 - result._carry;
796 }
797 result._current = value_type::from_uint(result._offset);
798 return result;
799 }
800
801 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE ip_address_iterator reverse() const IPADDRESS_NOEXCEPT {
802 auto result = *this;
803 const auto old = result._offset;
804 --result._offset;
805 if (result._offset > old) {
806 result._carry = 1 - result._carry;
807 }
808 result._current = value_type::from_uint(result._offset);
809 return result;
810 }
811
812 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE void add(const uint_type& n) IPADDRESS_NOEXCEPT {
813 if (n != 0) {
814 const auto old = _offset;
815 _offset += n;
816 if (_offset < old) {
817 _carry = 1 - _carry;
818 }
819 _current = value_type::from_uint(_offset);
820 }
821 }
822
823 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE void sub(const uint_type& n) IPADDRESS_NOEXCEPT {
824 if (n != 0) {
825 const auto old = _offset;
826 _offset -= n;
827 if (_offset > old) {
828 _carry = 1 - _carry;
829 }
830 _current = value_type::from_uint(_offset);
831 }
832 }
833
834 template <typename>
835 friend class ip_reverse_iterator;
836
837 template <typename>
838 friend class ip_network_iterator;
839
840 template <typename, typename, typename>
841 friend class ip_any_iterator;
842
843 value_type _current{};
844 uint_type _offset{};
845 int _carry{};
846};
847
848IPADDRESS_EXPORT template <typename>
849class hosts_sequence;
850
851/**
852 * A sequence of host IP addresses.
853 *
854 * The hosts_sequence class template is specialized for `ip_address_base<Base>` to provide a container-like interface for IP address sequences.
855 * It allows for iteration over the host addresses in a network or subnet, excluding the network and broadcast addresses when appropriate.
856 * This specialization is essential for network-related operations that require processing of individual host addresses within a given range.
857 *
858 * @tparam Base The base type from which the ip_address_base is derived, representing the underlying IP address type.
859 * @remark When iterating, obtaining addresses occurs through lazy calculations.
860 */
861IPADDRESS_EXPORT template <typename Base>
862class hosts_sequence<ip_address_base<Base>> {
863public:
864 using value_type = ip_address_base<Base>; /**< The type of the IP addresses in the sequence. */
865 using size_type = size_t; /**< The type used for representing the size of the sequence. */
866 using difference_type = typename value_type::uint_type; /**< The type used for representing differences between iterators. */
867 using pointer = value_type*; /**< The pointer type for the value_type. */
868 using const_pointer = const value_type*; /**< The const pointer type for the value_type. */
869 using reference = value_type&; /**< The reference type for the value_type. */
870 using const_reference = const value_type&; /**< The const reference type for the value_type. */
871
872 using iterator = ip_address_iterator<value_type>; /**< The iterator type for iterating over the sequence. */
873 using const_iterator = ip_address_iterator<value_type>; /**< The const iterator type for iterating over the sequence. */
874
875 using reverse_iterator = ip_reverse_iterator<iterator>; /**< The reverse iterator type for iterating over the sequence in reverse. */
876 using const_reverse_iterator = ip_reverse_iterator<const_iterator>; /**< The const reverse iterator type for iterating over the sequence in reverse. */
877
878 /**
879 * Constructs a hosts_sequence with specified network parameters.
880 *
881 * Initializes the sequence based on the provided network address, broadcast address, and prefix lengths.
882 * The sequence excludes the network and broadcast addresses when appropriate, according to the prefix length.
883 *
884 * @param[in] network_address The network address of the subnet.
885 * @param[in] broadcast_address The broadcast address of the subnet.
886 * @param[in] prefixlen The prefix length of the subnet.
887 * @param[in] max_prefixlen The maximum prefix length possible for the IP version.
888 */
889 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE hosts_sequence(const_reference network_address, const_reference broadcast_address, size_t prefixlen, size_t max_prefixlen) IPADDRESS_NOEXCEPT {
890 if (prefixlen == max_prefixlen - 1) {
891 const auto begin = value_type::from_uint(network_address.to_uint());
892 const auto end = value_type::from_uint(broadcast_address.to_uint() + 1);
893 _begin = const_iterator(begin);
894 _end = const_iterator(end);
895 } else if (prefixlen == max_prefixlen) {
896 const auto begin = value_type::from_uint(network_address.to_uint());
897 const auto end = value_type::from_uint(network_address.to_uint() + 1);
898 _begin = const_iterator(begin);
899 _end = const_iterator(end, end < begin ? 1 : 0);
900 } else {
901 const auto begin = value_type::from_uint(network_address.to_uint() + 1);
902 const auto end = value_type::from_uint(broadcast_address.to_uint() + (std::is_same<value_type, ipv6_address>::value ? 1 : 0));
903 _begin = const_iterator(begin);
904 _end = const_iterator(end);
905 }
906 }
907
908 /**
909 * Gets the beginning iterator of the sequence.
910 *
911 * @return A const_iterator to the first element in the sequence.
912 */
913 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_iterator begin() const IPADDRESS_NOEXCEPT {
914 return _begin;
915 }
916
917 /**
918 * Gets the end iterator of the sequence.
919 *
920 * @return A const_iterator to the element following the last element in the sequence.
921 */
922 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_iterator end() const IPADDRESS_NOEXCEPT {
923 return _end;
924 }
925
926 /**
927 * Gets the beginning reverse iterator of the sequence.
928 *
929 * @return A const_reverse_iterator to the first element of the reversed sequence.
930 */
931 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_reverse_iterator rbegin() const IPADDRESS_NOEXCEPT {
932 return const_reverse_iterator(end());
933 }
934
935 /**
936 * Gets the end reverse iterator of the sequence.
937 *
938 * @return A const_reverse_iterator to the element following the last element of the reversed sequence.
939 */
940 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_reverse_iterator rend() const IPADDRESS_NOEXCEPT {
941 return const_reverse_iterator(begin());
942 }
943
944 /**
945 * Gets the beginning const iterator of the sequence.
946 *
947 * @return A const_iterator to the first element in the sequence.
948 */
949 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_iterator cbegin() const IPADDRESS_NOEXCEPT {
950 return begin();
951 }
952
953 /**
954 * Gets the end const iterator of the sequence.
955 *
956 * @return A const_iterator to the element following the last element in the sequence.
957 */
958 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_iterator cend() const IPADDRESS_NOEXCEPT {
959 return end();
960 }
961
962 /**
963 * Gets the beginning const reverse iterator of the sequence.
964 *
965 * @return A const_reverse_iterator to the first element of the reversed sequence.
966 */
967 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_reverse_iterator crbegin() const IPADDRESS_NOEXCEPT {
968 return const_reverse_iterator(cend());
969 }
970
971 /**
972 * Gets the end const reverse iterator of the sequence.
973 *
974 * @return A const_reverse_iterator to the element following the last element of the reversed sequence.
975 */
976 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE const_reverse_iterator crend() const IPADDRESS_NOEXCEPT {
977 return const_reverse_iterator(cbegin());
978 }
979
980 /**
981 * Checks if the sequence is empty.
982 *
983 * @return `true` if the sequence is empty, `false` otherwise.
984 */
986 return _begin == _end;
987 }
988
989 /**
990 * Gets the size of the sequence.
991 *
992 * @return The number of elements in the sequence.
993 */
994 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE difference_type size() const IPADDRESS_NOEXCEPT {
995 return _end.uint_diff(_begin);
996 }
997
998 /**
999 * Accesses an element by index.
1000 *
1001 * @param[in] n The index of the element.
1002 * @return The element at the specified index.
1003 */
1004 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE value_type operator[](difference_type n) const IPADDRESS_NOEXCEPT {
1005 return at(n);
1006 }
1007
1008 /**
1009 * Accesses an element by index with bounds checking.
1010 *
1011 * @param[in] n The index of the element.
1012 * @return The element at the specified index.
1013 */
1014 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE value_type at(difference_type n) const IPADDRESS_NOEXCEPT {
1015 return *(_begin + n);
1016 }
1017
1018 /**
1019 * Accesses the first element in the sequence.
1020 *
1021 * @return A reference to the first element in the sequence.
1022 */
1024 return *_begin;
1025 }
1026
1027 /**
1028 * Accesses the last element in the sequence.
1029 *
1030 * @return A reference to the last element in the sequence.
1031 */
1033 return *(_end - 1U);
1034 }
1035
1036private:
1037 const_iterator _begin{};
1038 const_iterator _end{};
1039};
1040
1041} // namespace IPADDRESS_NAMESPACE
1042
1043#endif // IPADDRESS_HOSTS_HPP
constexpr inline const_reverse_iterator crbegin() const noexcept
Gets the beginning const reverse iterator of the sequence.
Definition ip-address-iterator.hpp:967
constexpr inline value_type operator[](difference_type n) const noexcept
Accesses an element by index.
Definition ip-address-iterator.hpp:1004
constexpr inline const_iterator begin() const noexcept
Gets the beginning iterator of the sequence.
Definition ip-address-iterator.hpp:913
constexpr inline bool empty() const noexcept
Checks if the sequence is empty.
Definition ip-address-iterator.hpp:985
constexpr inline value_type back() const noexcept
Accesses the last element in the sequence.
Definition ip-address-iterator.hpp:1032
constexpr inline const_reverse_iterator crend() const noexcept
Gets the end const reverse iterator of the sequence.
Definition ip-address-iterator.hpp:976
constexpr inline value_type front() const noexcept
Accesses the first element in the sequence.
Definition ip-address-iterator.hpp:1023
constexpr inline difference_type size() const noexcept
Gets the size of the sequence.
Definition ip-address-iterator.hpp:994
constexpr inline const_reverse_iterator rend() const noexcept
Gets the end reverse iterator of the sequence.
Definition ip-address-iterator.hpp:940
constexpr inline const_iterator cend() const noexcept
Gets the end const iterator of the sequence.
Definition ip-address-iterator.hpp:958
constexpr inline hosts_sequence(const_reference network_address, const_reference broadcast_address, size_t prefixlen, size_t max_prefixlen) noexcept
Constructs a hosts_sequence with specified network parameters.
Definition ip-address-iterator.hpp:889
constexpr inline const_iterator cbegin() const noexcept
Gets the beginning const iterator of the sequence.
Definition ip-address-iterator.hpp:949
constexpr inline const_iterator end() const noexcept
Gets the end iterator of the sequence.
Definition ip-address-iterator.hpp:922
constexpr inline value_type at(difference_type n) const noexcept
Accesses an element by index with bounds checking.
Definition ip-address-iterator.hpp:1014
constexpr inline const_reverse_iterator rbegin() const noexcept
Gets the beginning reverse iterator of the sequence.
Definition ip-address-iterator.hpp:931
A template base class for IP address representations.
Definition ip-address-base.hpp:56
constexpr inline bool operator>=(const ip_address_iterator &other) const noexcept
Greater-than-or-equal-to operator.
Definition ip-address-iterator.hpp:783
constexpr inline bool operator<=(const ip_address_iterator &other) const noexcept
Less-than-or-equal-to operator.
Definition ip-address-iterator.hpp:759
constexpr inline ip_address_iterator & operator+=(const uint_type &n) noexcept
Addition assignment operator.
Definition ip-address-iterator.hpp:570
constexpr inline value_type operator[](difference_type n) const noexcept
Accesses an element by index.
Definition ip-address-iterator.hpp:484
constexpr inline value_type operator[](const uint_type &n) const noexcept
Accesses an element by index.
Definition ip-address-iterator.hpp:495
constexpr inline difference_type operator-(const ip_address_iterator &other) const noexcept
Subtraction operator.
Definition ip-address-iterator.hpp:691
constexpr inline ip_address_iterator(reference ref, int carry=0) noexcept
Constructs an ip_address_iterator with a specific range and reference point.
Definition ip-address-iterator.hpp:444
constexpr inline ip_address_iterator operator++(int) noexcept
Post-increment operator.
Definition ip-address-iterator.hpp:518
constexpr inline ip_address_iterator operator+(const uint_type &n) const noexcept
Addition operator.
Definition ip-address-iterator.hpp:623
constexpr inline ip_address_iterator & operator++() noexcept
Pre-increment operator.
Definition ip-address-iterator.hpp:506
constexpr inline uint_type uint_diff(const ip_address_iterator &other) const noexcept
Calculates the difference in the number of elements between this and another ip_address_iterator.
Definition ip-address-iterator.hpp:456
constexpr inline ip_address_iterator & operator-=(const uint_type &n) noexcept
Subtraction assignment operator.
Definition ip-address-iterator.hpp:596
constexpr inline bool operator<(const ip_address_iterator &other) const noexcept
Less-than operator.
Definition ip-address-iterator.hpp:747
friend constexpr inline ip_address_iterator operator+(const uint_type &n, const ip_address_iterator &it) noexcept
Addition operator.
Definition ip-address-iterator.hpp:651
constexpr inline ip_address_iterator operator+(difference_type n) const noexcept
Addition operator.
Definition ip-address-iterator.hpp:609
constexpr inline ip_address_iterator & operator-=(difference_type n) noexcept
Subtraction assignment operator.
Definition ip-address-iterator.hpp:583
constexpr inline ip_address_iterator() noexcept=default
Default constructor.
constexpr inline pointer operator->() const noexcept
Returns a pointer to the current element.
Definition ip-address-iterator.hpp:474
constexpr inline bool operator==(const ip_address_iterator &other) const noexcept
Equality operator.
Definition ip-address-iterator.hpp:703
constexpr inline bool operator!=(const ip_address_iterator &other) const noexcept
Inequality operator.
Definition ip-address-iterator.hpp:715
constexpr inline ip_address_iterator operator--(int) noexcept
Post-decrement operator.
Definition ip-address-iterator.hpp:543
constexpr inline reference operator*() const noexcept
Returns a reference to the current element.
Definition ip-address-iterator.hpp:465
constexpr inline bool operator>(const ip_address_iterator &other) const noexcept
Greater-than operator.
Definition ip-address-iterator.hpp:771
constexpr inline ip_address_iterator operator-(difference_type n) const noexcept
Subtraction operator.
Definition ip-address-iterator.hpp:663
friend constexpr inline ip_address_iterator operator+(difference_type n, const ip_address_iterator &it) noexcept
Addition operator.
Definition ip-address-iterator.hpp:638
constexpr inline ip_address_iterator operator-(const uint_type &n) const noexcept
Subtraction operator.
Definition ip-address-iterator.hpp:677
constexpr inline ip_address_iterator & operator--() noexcept
Pre-decrement operator.
Definition ip-address-iterator.hpp:531
constexpr inline ip_address_iterator & operator+=(difference_type n) noexcept
Addition assignment operator.
Definition ip-address-iterator.hpp:557
An iterator for unified traversal over IPv4 and IPv6 address spaces.
Definition ip-any-iterator.hpp:44
An iterator for traversing IP addresses within a network range.
Definition ip-network-iterator.hpp:33
A reverse iterator template class for IP addresses.
Definition ip-address-iterator.hpp:35
constexpr inline bool operator>(const ip_reverse_iterator &other) const noexcept
Greater-than operator.
Definition ip-address-iterator.hpp:383
constexpr inline difference_type operator-(const ip_reverse_iterator &other) const noexcept
Subtraction operator.
Definition ip-address-iterator.hpp:307
constexpr inline value_type operator[](difference_type n) const noexcept
Accesses an element by index.
Definition ip-address-iterator.hpp:109
constexpr inline uint_type uint_diff(const ip_reverse_iterator &other) const noexcept
Calculates the difference in the number of elements between this and another ip_reverse_iterator.
Definition ip-address-iterator.hpp:72
constexpr inline bool operator<(const ip_reverse_iterator &other) const noexcept
Less-than operator.
Definition ip-address-iterator.hpp:359
constexpr inline value_type operator[](const uint_type &n) const noexcept
Accesses an element by index.
Definition ip-address-iterator.hpp:119
constexpr inline ip_reverse_iterator & operator-=(difference_type n) noexcept
Subtraction assignment operator.
Definition ip-address-iterator.hpp:199
constexpr inline ip_reverse_iterator & operator--() noexcept
Pre-decrement operator.
Definition ip-address-iterator.hpp:149
constexpr inline ip_reverse_iterator & operator++() noexcept
Pre-increment operator.
Definition ip-address-iterator.hpp:128
constexpr inline bool operator<=(const ip_reverse_iterator &other) const noexcept
Less-than-or-equal-to operator.
Definition ip-address-iterator.hpp:371
friend constexpr inline ip_reverse_iterator operator+(difference_type n, const ip_reverse_iterator &it) noexcept
Addition operator.
Definition ip-address-iterator.hpp:254
constexpr inline iterator_type base() const noexcept
Returns the underlying base iterator.
Definition ip-address-iterator.hpp:81
friend constexpr inline ip_reverse_iterator operator+(const uint_type &n, const ip_reverse_iterator &it) noexcept
Addition operator.
Definition ip-address-iterator.hpp:267
constexpr inline ip_reverse_iterator operator--(int) noexcept
Post-decrement operator.
Definition ip-address-iterator.hpp:159
constexpr inline ip_reverse_iterator operator-(difference_type n) const noexcept
Subtraction operator.
Definition ip-address-iterator.hpp:279
constexpr inline bool operator==(const ip_reverse_iterator &other) const noexcept
Equality operator.
Definition ip-address-iterator.hpp:319
constexpr inline bool operator>=(const ip_reverse_iterator &other) const noexcept
Greater-than-or-equal-to operator.
Definition ip-address-iterator.hpp:395
constexpr inline ip_reverse_iterator operator+(const uint_type &n) const noexcept
Addition operator.
Definition ip-address-iterator.hpp:239
constexpr inline ip_reverse_iterator operator++(int) noexcept
Post-increment operator.
Definition ip-address-iterator.hpp:138
constexpr inline bool operator!=(const ip_reverse_iterator &other) const noexcept
Inequality operator.
Definition ip-address-iterator.hpp:331
constexpr inline ip_reverse_iterator operator+(difference_type n) const noexcept
Addition operator.
Definition ip-address-iterator.hpp:225
constexpr inline pointer operator->() const noexcept
Returns a pointer to the current element.
Definition ip-address-iterator.hpp:99
constexpr inline ip_reverse_iterator & operator-=(const uint_type &n) noexcept
Subtraction assignment operator.
Definition ip-address-iterator.hpp:212
constexpr inline ip_reverse_iterator & operator+=(const uint_type &n) noexcept
Addition assignment operator.
Definition ip-address-iterator.hpp:186
constexpr inline ip_reverse_iterator() noexcept=default
Default constructor.
constexpr inline ip_reverse_iterator(Iterator it) noexcept
Constructs an ip_reverse_iterator from an underlying iterator.
Definition ip-address-iterator.hpp:60
constexpr inline reference operator*() const noexcept
Returns a reference to the current element.
Definition ip-address-iterator.hpp:90
constexpr inline ip_reverse_iterator & operator+=(difference_type n) noexcept
Addition assignment operator.
Definition ip-address-iterator.hpp:173
constexpr inline ip_reverse_iterator operator-(const uint_type &n) const noexcept
Subtraction operator.
Definition ip-address-iterator.hpp:293
#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