1 | // |
2 | // ip/basic_resolver_iterator.hpp |
3 | // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
4 | // |
5 | // Copyright (c) 2003-2024 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_BASIC_RESOLVER_ITERATOR_HPP |
12 | #define BOOST_ASIO_IP_BASIC_RESOLVER_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 <cstddef> |
20 | #include <cstring> |
21 | #include <iterator> |
22 | #include <string> |
23 | #include <vector> |
24 | #include <boost/asio/detail/memory.hpp> |
25 | #include <boost/asio/detail/socket_ops.hpp> |
26 | #include <boost/asio/detail/socket_types.hpp> |
27 | #include <boost/asio/ip/basic_resolver_entry.hpp> |
28 | |
29 | #if defined(BOOST_ASIO_WINDOWS_RUNTIME) |
30 | # include <boost/asio/detail/winrt_utils.hpp> |
31 | #endif // defined(BOOST_ASIO_WINDOWS_RUNTIME) |
32 | |
33 | #include <boost/asio/detail/push_options.hpp> |
34 | |
35 | namespace boost { |
36 | namespace asio { |
37 | namespace ip { |
38 | |
39 | /// An iterator over the entries produced by a resolver. |
40 | /** |
41 | * The boost::asio::ip::basic_resolver_iterator class template is used to define |
42 | * iterators over the results returned by a resolver. |
43 | * |
44 | * The iterator's value_type, obtained when the iterator is dereferenced, is: |
45 | * @code const basic_resolver_entry<InternetProtocol> @endcode |
46 | * |
47 | * @par Thread Safety |
48 | * @e Distinct @e objects: Safe.@n |
49 | * @e Shared @e objects: Unsafe. |
50 | */ |
51 | template <typename InternetProtocol> |
52 | class basic_resolver_iterator |
53 | { |
54 | public: |
55 | /// The type used for the distance between two iterators. |
56 | typedef std::ptrdiff_t difference_type; |
57 | |
58 | /// The type of the value pointed to by the iterator. |
59 | typedef basic_resolver_entry<InternetProtocol> value_type; |
60 | |
61 | /// The type of the result of applying operator->() to the iterator. |
62 | typedef const basic_resolver_entry<InternetProtocol>* pointer; |
63 | |
64 | /// The type of the result of applying operator*() to the iterator. |
65 | typedef const basic_resolver_entry<InternetProtocol>& reference; |
66 | |
67 | /// The iterator category. |
68 | typedef std::forward_iterator_tag iterator_category; |
69 | |
70 | /// Default constructor creates an end iterator. |
71 | basic_resolver_iterator() |
72 | : index_(0) |
73 | { |
74 | } |
75 | |
76 | /// Copy constructor. |
77 | basic_resolver_iterator(const basic_resolver_iterator& other) |
78 | : values_(other.values_), |
79 | index_(other.index_) |
80 | { |
81 | } |
82 | |
83 | /// Move constructor. |
84 | basic_resolver_iterator(basic_resolver_iterator&& other) |
85 | : values_(static_cast<values_ptr_type&&>(other.values_)), |
86 | index_(other.index_) |
87 | { |
88 | other.index_ = 0; |
89 | } |
90 | |
91 | /// Assignment operator. |
92 | basic_resolver_iterator& operator=(const basic_resolver_iterator& other) |
93 | { |
94 | values_ = other.values_; |
95 | index_ = other.index_; |
96 | return *this; |
97 | } |
98 | |
99 | /// Move-assignment operator. |
100 | basic_resolver_iterator& operator=(basic_resolver_iterator&& other) |
101 | { |
102 | if (this != &other) |
103 | { |
104 | values_ = static_cast<values_ptr_type&&>(other.values_); |
105 | index_ = other.index_; |
106 | other.index_ = 0; |
107 | } |
108 | |
109 | return *this; |
110 | } |
111 | |
112 | /// Dereference an iterator. |
113 | const basic_resolver_entry<InternetProtocol>& operator*() const |
114 | { |
115 | return dereference(); |
116 | } |
117 | |
118 | /// Dereference an iterator. |
119 | const basic_resolver_entry<InternetProtocol>* operator->() const |
120 | { |
121 | return &dereference(); |
122 | } |
123 | |
124 | /// Increment operator (prefix). |
125 | basic_resolver_iterator& operator++() |
126 | { |
127 | increment(); |
128 | return *this; |
129 | } |
130 | |
131 | /// Increment operator (postfix). |
132 | basic_resolver_iterator operator++(int) |
133 | { |
134 | basic_resolver_iterator tmp(*this); |
135 | ++*this; |
136 | return tmp; |
137 | } |
138 | |
139 | /// Test two iterators for equality. |
140 | friend bool operator==(const basic_resolver_iterator& a, |
141 | const basic_resolver_iterator& b) |
142 | { |
143 | return a.equal(b); |
144 | } |
145 | |
146 | /// Test two iterators for inequality. |
147 | friend bool operator!=(const basic_resolver_iterator& a, |
148 | const basic_resolver_iterator& b) |
149 | { |
150 | return !a.equal(b); |
151 | } |
152 | |
153 | protected: |
154 | void increment() |
155 | { |
156 | if (++index_ == values_->size()) |
157 | { |
158 | // Reset state to match a default constructed end iterator. |
159 | values_.reset(); |
160 | index_ = 0; |
161 | } |
162 | } |
163 | |
164 | bool equal(const basic_resolver_iterator& other) const |
165 | { |
166 | if (!values_ && !other.values_) |
167 | return true; |
168 | if (values_ != other.values_) |
169 | return false; |
170 | return index_ == other.index_; |
171 | } |
172 | |
173 | const basic_resolver_entry<InternetProtocol>& dereference() const |
174 | { |
175 | return (*values_)[index_]; |
176 | } |
177 | |
178 | typedef std::vector<basic_resolver_entry<InternetProtocol>> values_type; |
179 | typedef boost::asio::detail::shared_ptr<values_type> values_ptr_type; |
180 | values_ptr_type values_; |
181 | std::size_t index_; |
182 | }; |
183 | |
184 | } // namespace ip |
185 | } // namespace asio |
186 | } // namespace boost |
187 | |
188 | #include <boost/asio/detail/pop_options.hpp> |
189 | |
190 | #endif // BOOST_ASIO_IP_BASIC_RESOLVER_ITERATOR_HPP |
191 | |