1 // 2 // ip/address_v6_iterator.hpp 3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~ 4 // 5 // Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com) 6 // Oliver Kowalke (oliver dot kowalke at gmail dot com) 7 // 8 // Distributed under the Boost Software License, Version 1.0. (See accompanying 9 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 10 // 11 12 #ifndef BOOST_ASIO_IP_ADDRESS_V6_ITERATOR_HPP 13 #define BOOST_ASIO_IP_ADDRESS_V6_ITERATOR_HPP 14 15 #if defined(_MSC_VER) && (_MSC_VER >= 1200) 16 # pragma once 17 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 18 19 #include <boost/asio/detail/config.hpp> 20 #include <boost/asio/ip/address_v6.hpp> 21 22 #include <boost/asio/detail/push_options.hpp> 23 24 namespace boost { 25 namespace asio { 26 namespace ip { 27 28 template <typename> class basic_address_iterator; 29 30 /// An input iterator that can be used for traversing IPv6 addresses. 31 /** 32 * In addition to satisfying the input iterator requirements, this iterator 33 * also supports decrement. 34 * 35 * @par Thread Safety 36 * @e Distinct @e objects: Safe.@n 37 * @e Shared @e objects: Unsafe. 38 */ 39 template <> class basic_address_iterator<address_v6> 40 { 41 public: 42 /// The type of the elements pointed to by the iterator. 43 typedef address_v6 value_type; 44 45 /// Distance between two iterators. 46 typedef std::ptrdiff_t difference_type; 47 48 /// The type of a pointer to an element pointed to by the iterator. 49 typedef const address_v6* pointer; 50 51 /// The type of a reference to an element pointed to by the iterator. 52 typedef const address_v6& reference; 53 54 /// Denotes that the iterator satisfies the input iterator requirements. 55 typedef std::input_iterator_tag iterator_category; 56 57 /// Construct an iterator that points to the specified address. basic_address_iterator(const address_v6 & addr)58 basic_address_iterator(const address_v6& addr) BOOST_ASIO_NOEXCEPT 59 : address_(addr) 60 { 61 } 62 63 /// Copy constructor. basic_address_iterator(const basic_address_iterator & other)64 basic_address_iterator( 65 const basic_address_iterator& other) BOOST_ASIO_NOEXCEPT 66 : address_(other.address_) 67 { 68 } 69 70 #if defined(BOOST_ASIO_HAS_MOVE) 71 /// Move constructor. basic_address_iterator(basic_address_iterator && other)72 basic_address_iterator(basic_address_iterator&& other) BOOST_ASIO_NOEXCEPT 73 : address_(BOOST_ASIO_MOVE_CAST(address_v6)(other.address_)) 74 { 75 } 76 #endif // defined(BOOST_ASIO_HAS_MOVE) 77 78 /// Assignment operator. operator =(const basic_address_iterator & other)79 basic_address_iterator& operator=( 80 const basic_address_iterator& other) BOOST_ASIO_NOEXCEPT 81 { 82 address_ = other.address_; 83 return *this; 84 } 85 86 #if defined(BOOST_ASIO_HAS_MOVE) 87 /// Move assignment operator. operator =(basic_address_iterator && other)88 basic_address_iterator& operator=( 89 basic_address_iterator&& other) BOOST_ASIO_NOEXCEPT 90 { 91 address_ = BOOST_ASIO_MOVE_CAST(address_v6)(other.address_); 92 return *this; 93 } 94 #endif // defined(BOOST_ASIO_HAS_MOVE) 95 96 /// Dereference the iterator. operator *() const97 const address_v6& operator*() const BOOST_ASIO_NOEXCEPT 98 { 99 return address_; 100 } 101 102 /// Dereference the iterator. operator ->() const103 const address_v6* operator->() const BOOST_ASIO_NOEXCEPT 104 { 105 return &address_; 106 } 107 108 /// Pre-increment operator. operator ++()109 basic_address_iterator& operator++() BOOST_ASIO_NOEXCEPT 110 { 111 for (int i = 15; i >= 0; --i) 112 { 113 if (address_.addr_.s6_addr[i] < 0xFF) 114 { 115 ++address_.addr_.s6_addr[i]; 116 break; 117 } 118 119 address_.addr_.s6_addr[i] = 0; 120 } 121 122 return *this; 123 } 124 125 /// Post-increment operator. operator ++(int)126 basic_address_iterator operator++(int) BOOST_ASIO_NOEXCEPT 127 { 128 basic_address_iterator tmp(*this); 129 ++*this; 130 return tmp; 131 } 132 133 /// Pre-decrement operator. operator --()134 basic_address_iterator& operator--() BOOST_ASIO_NOEXCEPT 135 { 136 for (int i = 15; i >= 0; --i) 137 { 138 if (address_.addr_.s6_addr[i] > 0) 139 { 140 --address_.addr_.s6_addr[i]; 141 break; 142 } 143 144 address_.addr_.s6_addr[i] = 0xFF; 145 } 146 147 return *this; 148 } 149 150 /// Post-decrement operator. operator --(int)151 basic_address_iterator operator--(int) 152 { 153 basic_address_iterator tmp(*this); 154 --*this; 155 return tmp; 156 } 157 158 /// Compare two addresses for equality. operator ==(const basic_address_iterator & a,const basic_address_iterator & b)159 friend bool operator==(const basic_address_iterator& a, 160 const basic_address_iterator& b) 161 { 162 return a.address_ == b.address_; 163 } 164 165 /// Compare two addresses for inequality. operator !=(const basic_address_iterator & a,const basic_address_iterator & b)166 friend bool operator!=(const basic_address_iterator& a, 167 const basic_address_iterator& b) 168 { 169 return a.address_ != b.address_; 170 } 171 172 private: 173 address_v6 address_; 174 }; 175 176 /// An input iterator that can be used for traversing IPv6 addresses. 177 typedef basic_address_iterator<address_v6> address_v6_iterator; 178 179 } // namespace ip 180 } // namespace asio 181 } // namespace boost 182 183 #include <boost/asio/detail/pop_options.hpp> 184 185 #endif // BOOST_ASIO_IP_ADDRESS_V6_ITERATOR_HPP 186