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