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/move/detail/iterator_traits.hpp>
27 #include <boost/move/detail/meta_utils_core.hpp>
28
29 namespace boost {
30 namespace intrusive {
31
32 using boost::movelib::iterator_traits;
33
34 ////////////////////
35 // iterator
36 ////////////////////
37 template<class Category, class T, class Distance, class Pointer = T*, class Reference = T&>
38 struct iterator
39 {
40 typedef Category iterator_category;
41 typedef T value_type;
42 typedef Distance difference_type;
43 typedef Pointer pointer;
44 typedef Reference reference;
45 };
46
47 ////////////////////////////////////////
48 // iterator_[dis|en]able_if_tag
49 ////////////////////////////////////////
50 template<class I, class Tag, class R = void>
51 struct iterator_enable_if_tag
52 : ::boost::move_detail::enable_if_c
53 < ::boost::move_detail::is_same
54 < typename boost::intrusive::iterator_traits<I>::iterator_category
55 , Tag
56 >::value
57 , R>
58 {};
59
60 template<class I, class Tag, class R = void>
61 struct iterator_disable_if_tag
62 : ::boost::move_detail::enable_if_c
63 < !::boost::move_detail::is_same
64 < typename boost::intrusive::iterator_traits<I>::iterator_category
65 , Tag
66 >::value
67 , R>
68 {};
69
70 ////////////////////////////////////////
71 // iterator_[dis|en]able_if_tag_difference_type
72 ////////////////////////////////////////
73 template<class I, class Tag>
74 struct iterator_enable_if_tag_difference_type
75 : iterator_enable_if_tag<I, Tag, typename boost::intrusive::iterator_traits<I>::difference_type>
76 {};
77
78 template<class I, class Tag>
79 struct iterator_disable_if_tag_difference_type
80 : iterator_disable_if_tag<I, Tag, typename boost::intrusive::iterator_traits<I>::difference_type>
81 {};
82
83 ////////////////////
84 // advance
85 ////////////////////
86 template<class InputIt, class Distance> inline
87 typename iterator_enable_if_tag<InputIt, std::input_iterator_tag>::type
iterator_advance(InputIt & it,Distance n)88 iterator_advance(InputIt& it, Distance n)
89 {
90 while(n--)
91 ++it;
92 }
93
94 template<class InputIt, class Distance> inline
95 typename iterator_enable_if_tag<InputIt, std::forward_iterator_tag>::type
iterator_advance(InputIt & it,Distance n)96 iterator_advance(InputIt& it, Distance n)
97 {
98 while(n--)
99 ++it;
100 }
101
102 template<class InputIt, class Distance> inline
103 typename iterator_enable_if_tag<InputIt, std::bidirectional_iterator_tag>::type
iterator_advance(InputIt & it,Distance n)104 iterator_advance(InputIt& it, Distance n)
105 {
106 for (; 0 < n; --n)
107 ++it;
108 for (; n < 0; ++n)
109 --it;
110 }
111
112 template<class InputIt, class Distance> inline
113 typename iterator_enable_if_tag<InputIt, std::random_access_iterator_tag>::type
iterator_advance(InputIt & it,Distance n)114 iterator_advance(InputIt& it, Distance n)
115 {
116 it += n;
117 }
118
119 ////////////////////
120 // distance
121 ////////////////////
122 template<class InputIt> inline
123 typename iterator_disable_if_tag_difference_type
124 <InputIt, std::random_access_iterator_tag>::type
iterator_distance(InputIt first,InputIt last)125 iterator_distance(InputIt first, InputIt last)
126 {
127 typename iterator_traits<InputIt>::difference_type off = 0;
128 while(first != last){
129 ++off;
130 ++first;
131 }
132 return off;
133 }
134
135 template<class InputIt> inline
136 typename iterator_enable_if_tag_difference_type
137 <InputIt, std::random_access_iterator_tag>::type
iterator_distance(InputIt first,InputIt last)138 iterator_distance(InputIt first, InputIt last)
139 {
140 typename iterator_traits<InputIt>::difference_type off = last - first;
141 return off;
142 }
143
144 template<class I>
iterator_arrow_result(const I & i)145 typename iterator_traits<I>::pointer iterator_arrow_result(const I &i)
146 { return i.operator->(); }
147
148 template<class T>
iterator_arrow_result(T * p)149 T * iterator_arrow_result(T *p)
150 { return p; }
151
152 } //namespace intrusive
153 } //namespace boost
154
155 #endif //BOOST_INTRUSIVE_DETAIL_ITERATOR_HPP
156