Chris@102
|
1 /////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
2 //
|
Chris@102
|
3 // (C) Copyright Ion Gaztanaga 2014-2014
|
Chris@102
|
4 //
|
Chris@102
|
5 // Distributed under the Boost Software License, Version 1.0.
|
Chris@102
|
6 // (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@102
|
7 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@102
|
8 //
|
Chris@102
|
9 // See http://www.boost.org/libs/intrusive for documentation.
|
Chris@102
|
10 //
|
Chris@102
|
11 /////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
12
|
Chris@102
|
13 #ifndef BOOST_INTRUSIVE_DETAIL_ITERATOR_HPP
|
Chris@102
|
14 #define BOOST_INTRUSIVE_DETAIL_ITERATOR_HPP
|
Chris@102
|
15
|
Chris@102
|
16 #ifndef BOOST_CONFIG_HPP
|
Chris@102
|
17 # include <boost/config.hpp>
|
Chris@102
|
18 #endif
|
Chris@102
|
19
|
Chris@102
|
20 #if defined(BOOST_HAS_PRAGMA_ONCE)
|
Chris@102
|
21 # pragma once
|
Chris@102
|
22 #endif
|
Chris@102
|
23
|
Chris@102
|
24 #include <cstddef>
|
Chris@102
|
25 #include <boost/intrusive/detail/std_fwd.hpp>
|
Chris@102
|
26 #include <boost/move/detail/iterator_traits.hpp>
|
Chris@102
|
27 #include <boost/move/detail/meta_utils_core.hpp>
|
Chris@102
|
28
|
Chris@102
|
29 namespace boost {
|
Chris@102
|
30 namespace intrusive {
|
Chris@102
|
31
|
Chris@102
|
32 using boost::movelib::iterator_traits;
|
Chris@102
|
33
|
Chris@102
|
34 ////////////////////
|
Chris@102
|
35 // iterator
|
Chris@102
|
36 ////////////////////
|
Chris@102
|
37 template<class Category, class T, class Distance, class Pointer = T*, class Reference = T&>
|
Chris@102
|
38 struct iterator
|
Chris@102
|
39 {
|
Chris@102
|
40 typedef Category iterator_category;
|
Chris@102
|
41 typedef T value_type;
|
Chris@102
|
42 typedef Distance difference_type;
|
Chris@102
|
43 typedef Pointer pointer;
|
Chris@102
|
44 typedef Reference reference;
|
Chris@102
|
45 };
|
Chris@102
|
46
|
Chris@102
|
47 ////////////////////////////////////////
|
Chris@102
|
48 // iterator_[dis|en]able_if_tag
|
Chris@102
|
49 ////////////////////////////////////////
|
Chris@102
|
50 template<class I, class Tag, class R = void>
|
Chris@102
|
51 struct iterator_enable_if_tag
|
Chris@102
|
52 : ::boost::move_detail::enable_if_c
|
Chris@102
|
53 < ::boost::move_detail::is_same
|
Chris@102
|
54 < typename boost::intrusive::iterator_traits<I>::iterator_category
|
Chris@102
|
55 , Tag
|
Chris@102
|
56 >::value
|
Chris@102
|
57 , R>
|
Chris@102
|
58 {};
|
Chris@102
|
59
|
Chris@102
|
60 template<class I, class Tag, class R = void>
|
Chris@102
|
61 struct iterator_disable_if_tag
|
Chris@102
|
62 : ::boost::move_detail::enable_if_c
|
Chris@102
|
63 < !::boost::move_detail::is_same
|
Chris@102
|
64 < typename boost::intrusive::iterator_traits<I>::iterator_category
|
Chris@102
|
65 , Tag
|
Chris@102
|
66 >::value
|
Chris@102
|
67 , R>
|
Chris@102
|
68 {};
|
Chris@102
|
69
|
Chris@102
|
70 ////////////////////////////////////////
|
Chris@102
|
71 // iterator_[dis|en]able_if_tag_difference_type
|
Chris@102
|
72 ////////////////////////////////////////
|
Chris@102
|
73 template<class I, class Tag>
|
Chris@102
|
74 struct iterator_enable_if_tag_difference_type
|
Chris@102
|
75 : iterator_enable_if_tag<I, Tag, typename boost::intrusive::iterator_traits<I>::difference_type>
|
Chris@102
|
76 {};
|
Chris@102
|
77
|
Chris@102
|
78 template<class I, class Tag>
|
Chris@102
|
79 struct iterator_disable_if_tag_difference_type
|
Chris@102
|
80 : iterator_disable_if_tag<I, Tag, typename boost::intrusive::iterator_traits<I>::difference_type>
|
Chris@102
|
81 {};
|
Chris@102
|
82
|
Chris@102
|
83 ////////////////////
|
Chris@102
|
84 // advance
|
Chris@102
|
85 ////////////////////
|
Chris@102
|
86 template<class InputIt, class Distance> inline
|
Chris@102
|
87 typename iterator_enable_if_tag<InputIt, std::input_iterator_tag>::type
|
Chris@102
|
88 iterator_advance(InputIt& it, Distance n)
|
Chris@102
|
89 {
|
Chris@102
|
90 while(n--)
|
Chris@102
|
91 ++it;
|
Chris@102
|
92 }
|
Chris@102
|
93
|
Chris@102
|
94 template<class InputIt, class Distance> inline
|
Chris@102
|
95 typename iterator_enable_if_tag<InputIt, std::forward_iterator_tag>::type
|
Chris@102
|
96 iterator_advance(InputIt& it, Distance n)
|
Chris@102
|
97 {
|
Chris@102
|
98 while(n--)
|
Chris@102
|
99 ++it;
|
Chris@102
|
100 }
|
Chris@102
|
101
|
Chris@102
|
102 template<class InputIt, class Distance> inline
|
Chris@102
|
103 typename iterator_enable_if_tag<InputIt, std::bidirectional_iterator_tag>::type
|
Chris@102
|
104 iterator_advance(InputIt& it, Distance n)
|
Chris@102
|
105 {
|
Chris@102
|
106 for (; 0 < n; --n)
|
Chris@102
|
107 ++it;
|
Chris@102
|
108 for (; n < 0; ++n)
|
Chris@102
|
109 --it;
|
Chris@102
|
110 }
|
Chris@102
|
111
|
Chris@102
|
112 template<class InputIt, class Distance> inline
|
Chris@102
|
113 typename iterator_enable_if_tag<InputIt, std::random_access_iterator_tag>::type
|
Chris@102
|
114 iterator_advance(InputIt& it, Distance n)
|
Chris@102
|
115 {
|
Chris@102
|
116 it += n;
|
Chris@102
|
117 }
|
Chris@102
|
118
|
Chris@102
|
119 ////////////////////
|
Chris@102
|
120 // distance
|
Chris@102
|
121 ////////////////////
|
Chris@102
|
122 template<class InputIt> inline
|
Chris@102
|
123 typename iterator_disable_if_tag_difference_type
|
Chris@102
|
124 <InputIt, std::random_access_iterator_tag>::type
|
Chris@102
|
125 iterator_distance(InputIt first, InputIt last)
|
Chris@102
|
126 {
|
Chris@102
|
127 typename iterator_traits<InputIt>::difference_type off = 0;
|
Chris@102
|
128 while(first != last){
|
Chris@102
|
129 ++off;
|
Chris@102
|
130 ++first;
|
Chris@102
|
131 }
|
Chris@102
|
132 return off;
|
Chris@102
|
133 }
|
Chris@102
|
134
|
Chris@102
|
135 template<class InputIt> inline
|
Chris@102
|
136 typename iterator_enable_if_tag_difference_type
|
Chris@102
|
137 <InputIt, std::random_access_iterator_tag>::type
|
Chris@102
|
138 iterator_distance(InputIt first, InputIt last)
|
Chris@102
|
139 {
|
Chris@102
|
140 typename iterator_traits<InputIt>::difference_type off = last - first;
|
Chris@102
|
141 return off;
|
Chris@102
|
142 }
|
Chris@102
|
143
|
Chris@102
|
144 } //namespace intrusive
|
Chris@102
|
145 } //namespace boost
|
Chris@102
|
146
|
Chris@102
|
147 #endif //BOOST_INTRUSIVE_DETAIL_ITERATOR_HPP
|