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