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