1 // 2 // ip/basic_resolver_iterator.hpp 3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 4 // 5 // Copyright (c) 2003-2019 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. basic_resolver_iterator()71 basic_resolver_iterator() 72 : index_(0) 73 { 74 } 75 76 /// Copy constructor. basic_resolver_iterator(const basic_resolver_iterator & other)77 basic_resolver_iterator(const basic_resolver_iterator& other) 78 : values_(other.values_), 79 index_(other.index_) 80 { 81 } 82 83 #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) 84 /// Move constructor. basic_resolver_iterator(basic_resolver_iterator && other)85 basic_resolver_iterator(basic_resolver_iterator&& other) 86 : values_(BOOST_ASIO_MOVE_CAST(values_ptr_type)(other.values_)), 87 index_(other.index_) 88 { 89 other.index_ = 0; 90 } 91 #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) 92 93 /// Assignment operator. operator =(const basic_resolver_iterator & other)94 basic_resolver_iterator& operator=(const basic_resolver_iterator& other) 95 { 96 values_ = other.values_; 97 index_ = other.index_; 98 return *this; 99 } 100 101 #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) 102 /// Move-assignment operator. operator =(basic_resolver_iterator && other)103 basic_resolver_iterator& operator=(basic_resolver_iterator&& other) 104 { 105 if (this != &other) 106 { 107 values_ = BOOST_ASIO_MOVE_CAST(values_ptr_type)(other.values_); 108 index_ = other.index_; 109 other.index_ = 0; 110 } 111 112 return *this; 113 } 114 #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) 115 116 /// Dereference an iterator. operator *() const117 const basic_resolver_entry<InternetProtocol>& operator*() const 118 { 119 return dereference(); 120 } 121 122 /// Dereference an iterator. operator ->() const123 const basic_resolver_entry<InternetProtocol>* operator->() const 124 { 125 return &dereference(); 126 } 127 128 /// Increment operator (prefix). operator ++()129 basic_resolver_iterator& operator++() 130 { 131 increment(); 132 return *this; 133 } 134 135 /// Increment operator (postfix). operator ++(int)136 basic_resolver_iterator operator++(int) 137 { 138 basic_resolver_iterator tmp(*this); 139 ++*this; 140 return tmp; 141 } 142 143 /// Test two iterators for equality. operator ==(const basic_resolver_iterator & a,const basic_resolver_iterator & b)144 friend bool operator==(const basic_resolver_iterator& a, 145 const basic_resolver_iterator& b) 146 { 147 return a.equal(b); 148 } 149 150 /// Test two iterators for inequality. operator !=(const basic_resolver_iterator & a,const basic_resolver_iterator & b)151 friend bool operator!=(const basic_resolver_iterator& a, 152 const basic_resolver_iterator& b) 153 { 154 return !a.equal(b); 155 } 156 157 protected: increment()158 void increment() 159 { 160 if (++index_ == values_->size()) 161 { 162 // Reset state to match a default constructed end iterator. 163 values_.reset(); 164 index_ = 0; 165 } 166 } 167 equal(const basic_resolver_iterator & other) const168 bool equal(const basic_resolver_iterator& other) const 169 { 170 if (!values_ && !other.values_) 171 return true; 172 if (values_ != other.values_) 173 return false; 174 return index_ == other.index_; 175 } 176 dereference() const177 const basic_resolver_entry<InternetProtocol>& dereference() const 178 { 179 return (*values_)[index_]; 180 } 181 182 typedef std::vector<basic_resolver_entry<InternetProtocol> > values_type; 183 typedef boost::asio::detail::shared_ptr<values_type> values_ptr_type; 184 values_ptr_type values_; 185 std::size_t index_; 186 }; 187 188 } // namespace ip 189 } // namespace asio 190 } // namespace boost 191 192 #include <boost/asio/detail/pop_options.hpp> 193 194 #endif // BOOST_ASIO_IP_BASIC_RESOLVER_ITERATOR_HPP 195