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