1/////////////////////////////////////////////////////////////////////////////
2//
3// (C) Copyright Ion Gaztanaga 2014-2014
4//
5// Distributed under the Boost Software License, Version 1.0.
6// (See accompanying file LICENSE_1_0.txt or copy at
7// http://www.boost.org/LICENSE_1_0.txt)
8//
9// See http://www.boost.org/libs/intrusive for documentation.
10//
11/////////////////////////////////////////////////////////////////////////////
12
13#ifndef BOOST_INTRUSIVE_DETAIL_ITERATOR_HPP
14#define BOOST_INTRUSIVE_DETAIL_ITERATOR_HPP
15
16#ifndef BOOST_CONFIG_HPP
17# include <boost/config.hpp>
18#endif
19
20#if defined(BOOST_HAS_PRAGMA_ONCE)
21# pragma once
22#endif
23
24#include <cstddef>
25#include <boost/intrusive/detail/std_fwd.hpp>
26#include <boost/intrusive/detail/workaround.hpp>
27#include <boost/move/detail/iterator_traits.hpp>
28#include <boost/move/detail/meta_utils_core.hpp>
29
30namespace boost{
31namespace iterators{
32
33struct incrementable_traversal_tag;
34struct single_pass_traversal_tag;
35struct forward_traversal_tag;
36struct bidirectional_traversal_tag;
37struct random_access_traversal_tag;
38
39namespace detail{
40
41template <class Category, class Traversal>
42struct iterator_category_with_traversal;
43
44} //namespace boost{
45} //namespace iterators{
46} //namespace detail{
47
48namespace boost {
49namespace intrusive {
50
51using boost::movelib::iterator_traits;
52using boost::movelib::iter_difference;
53using boost::movelib::iter_value;
54using boost::movelib::iter_category;
55using boost::movelib::iter_size;
56
57
58////////////////////
59// iterator
60////////////////////
61template<class Category, class T, class Difference, class Pointer, class Reference>
62struct iterator
63{
64 typedef Category iterator_category;
65 typedef T value_type;
66 typedef Difference difference_type;
67 typedef Pointer pointer;
68 typedef Reference reference;
69};
70
71////////////////////////////////////////////////////////////////////////////////
72// Conversion from boost::iterator traversals to std tags
73////////////////////////////////////////////////////////////////////////////////
74
75template<class Tag>
76struct get_std_category_from_tag
77{
78 typedef Tag type;
79};
80
81template <class Category>
82struct get_std_category_from_tag
83 <boost::iterators::detail::iterator_category_with_traversal
84 <Category, boost::iterators::incrementable_traversal_tag> >
85{
86 typedef std::input_iterator_tag type;
87};
88
89template <class Category>
90struct get_std_category_from_tag
91 <boost::iterators::detail::iterator_category_with_traversal
92 <Category, boost::iterators::single_pass_traversal_tag> >
93{
94 typedef std::input_iterator_tag type;
95};
96
97template <class Category>
98struct get_std_category_from_tag
99 <boost::iterators::detail::iterator_category_with_traversal
100 <Category, boost::iterators::forward_traversal_tag> >
101{
102 typedef std::input_iterator_tag type;
103};
104
105template <class Category>
106struct get_std_category_from_tag
107 <boost::iterators::detail::iterator_category_with_traversal
108 <Category, boost::iterators::bidirectional_traversal_tag> >
109{
110 typedef std::bidirectional_iterator_tag type;
111};
112
113template <class Category>
114struct get_std_category_from_tag
115 <boost::iterators::detail::iterator_category_with_traversal
116 <Category, boost::iterators::random_access_traversal_tag> >
117{
118 typedef std::random_access_iterator_tag type;
119};
120
121template<class It>
122struct get_std_category_from_it
123 : get_std_category_from_tag< typename boost::intrusive::iter_category<It>::type >
124{};
125
126////////////////////////////////////////
127// iterator_[dis|en]able_if_tag
128////////////////////////////////////////
129template<class I, class Tag, class R = void>
130struct iterator_enable_if_tag
131 : ::boost::move_detail::enable_if_c
132 < ::boost::move_detail::is_same
133 < typename get_std_category_from_it<I>::type
134 , Tag
135 >::value
136 , R>
137{};
138
139template<class I, class Tag, class R = void>
140struct iterator_disable_if_tag
141 : ::boost::move_detail::enable_if_c
142 < !::boost::move_detail::is_same
143 < typename get_std_category_from_it<I>::type
144 , Tag
145 >::value
146 , R>
147{};
148
149////////////////////////////////////////
150// iterator_[dis|en]able_if_tag
151////////////////////////////////////////
152template<class I, class Tag, class Tag2, class R = void>
153struct iterator_enable_if_convertible_tag
154 : ::boost::move_detail::enable_if_c
155 < ::boost::move_detail::is_same_or_convertible
156 < typename get_std_category_from_it<I>::type
157 , Tag
158 >::value &&
159 !::boost::move_detail::is_same_or_convertible
160 < typename get_std_category_from_it<I>::type
161 , Tag2
162 >::value
163 , R>
164{};
165
166////////////////////////////////////////
167// iterator_[dis|en]able_if_tag_difference_type
168////////////////////////////////////////
169template<class I, class Tag>
170struct iterator_enable_if_tag_difference_type
171 : iterator_enable_if_tag<I, Tag, typename boost::intrusive::iter_difference<I>::type>
172{};
173
174template<class I, class Tag>
175struct iterator_disable_if_tag_difference_type
176 : iterator_disable_if_tag<I, Tag, typename boost::intrusive::iter_difference<I>::type>
177{};
178
179////////////////////
180// advance
181////////////////////
182
183template<class InputIt>
184inline typename iterator_enable_if_tag<InputIt, std::input_iterator_tag>::type
185 iterator_advance(InputIt& it, typename iter_difference<InputIt>::type n)
186{
187 while(n--)
188 ++it;
189}
190
191template<class InputIt>
192typename iterator_enable_if_tag<InputIt, std::forward_iterator_tag>::type
193 iterator_advance(InputIt& it, typename iter_difference<InputIt>::type n)
194{
195 while(n--)
196 ++it;
197}
198
199template<class InputIt>
200inline typename iterator_enable_if_tag<InputIt, std::bidirectional_iterator_tag>::type
201 iterator_advance(InputIt& it, typename iter_difference<InputIt>::type n)
202{
203 for (; 0 < n; --n)
204 ++it;
205 for (; n < 0; ++n)
206 --it;
207}
208
209template<class InputIt, class Distance>
210inline typename iterator_enable_if_tag<InputIt, std::random_access_iterator_tag>::type
211 iterator_advance(InputIt& it, Distance n)
212{
213 it += n;
214}
215
216template<class InputIt, class Distance>
217inline typename iterator_enable_if_tag<InputIt, std::random_access_iterator_tag, InputIt>::type
218 make_iterator_advance(InputIt it, Distance n)
219{
220 (iterator_advance)(it, n);
221 return it;
222}
223
224template<class It>
225inline
226 void iterator_uadvance(It& it, typename iter_size<It>::type n)
227{
228 (iterator_advance)(it, (typename iterator_traits<It>::difference_type)n);
229}
230
231template<class It>
232inline
233It make_iterator_uadvance(It it, typename iter_size<It>::type n)
234{
235 (iterator_uadvance)(it, n);
236 return it;
237}
238
239////////////////////////////////////////
240// iterator_distance
241////////////////////////////////////////
242template<class InputIt> inline
243typename iterator_disable_if_tag_difference_type
244 <InputIt, std::random_access_iterator_tag>::type
245 iterator_distance(InputIt first, InputIt last)
246{
247 typename iter_difference<InputIt>::type off = 0;
248 while(first != last){
249 ++off;
250 ++first;
251 }
252 return off;
253}
254
255template<class InputIt>
256inline typename iterator_enable_if_tag_difference_type
257 <InputIt, std::random_access_iterator_tag>::type
258 iterator_distance(InputIt first, InputIt last)
259{
260 typename iter_difference<InputIt>::type off = last - first;
261 return off;
262}
263
264////////////////////////////////////////
265// iterator_udistance
266////////////////////////////////////////
267
268template<class It>
269inline typename iter_size<It>::type
270 iterator_udistance(It first, It last)
271{
272 return (typename iter_size<It>::type)(iterator_distance)(first, last);
273}
274
275////////////////////////////////////////
276// iterator_next
277////////////////////////////////////////
278
279template<class InputIt>
280inline InputIt iterator_next(InputIt it, typename iter_difference<InputIt>::type n)
281{
282 (iterator_advance)(it, n);
283 return it;
284}
285
286template<class InputIt>
287inline InputIt iterator_unext(InputIt it, typename iterator_traits<InputIt>::size_type n)
288{
289 (iterator_uadvance)(it, n);
290 return it;
291}
292
293////////////////////////////////////////
294// iterator_arrow_result
295////////////////////////////////////////
296
297template<class I>
298inline typename iterator_traits<I>::pointer iterator_arrow_result(const I &i)
299{ return i.operator->(); }
300
301template<class T>
302inline T * iterator_arrow_result(T *p)
303{ return p; }
304
305} //namespace intrusive
306} //namespace boost
307
308#endif //BOOST_INTRUSIVE_DETAIL_ITERATOR_HPP
309

source code of boost/libs/intrusive/include/boost/intrusive/detail/iterator.hpp