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