Chris@16
|
1 /////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
2 //
|
Chris@16
|
3 // (C) Copyright Ion Gaztanaga 2007-2013
|
Chris@16
|
4 //
|
Chris@16
|
5 // Distributed under the Boost Software License, Version 1.0.
|
Chris@16
|
6 // (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
7 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
8 //
|
Chris@16
|
9 // See http://www.boost.org/libs/intrusive for documentation.
|
Chris@16
|
10 //
|
Chris@16
|
11 /////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
12
|
Chris@16
|
13 #ifndef BOOST_INTRUSIVE_DETAIL_TRANSFORM_ITERATOR_HPP
|
Chris@16
|
14 #define BOOST_INTRUSIVE_DETAIL_TRANSFORM_ITERATOR_HPP
|
Chris@16
|
15
|
Chris@101
|
16 #ifndef BOOST_CONFIG_HPP
|
Chris@101
|
17 # include <boost/config.hpp>
|
Chris@101
|
18 #endif
|
Chris@101
|
19
|
Chris@101
|
20 #if defined(BOOST_HAS_PRAGMA_ONCE)
|
Chris@101
|
21 # pragma once
|
Chris@101
|
22 #endif
|
Chris@101
|
23
|
Chris@16
|
24 #include <boost/intrusive/detail/config_begin.hpp>
|
Chris@16
|
25 #include <boost/intrusive/detail/mpl.hpp>
|
Chris@16
|
26
|
Chris@16
|
27 namespace boost {
|
Chris@16
|
28 namespace intrusive {
|
Chris@16
|
29 namespace detail {
|
Chris@16
|
30
|
Chris@16
|
31 template <class PseudoReference>
|
Chris@16
|
32 struct operator_arrow_proxy
|
Chris@16
|
33 {
|
Chris@16
|
34 operator_arrow_proxy(const PseudoReference &px)
|
Chris@16
|
35 : m_value(px)
|
Chris@16
|
36 {}
|
Chris@16
|
37
|
Chris@16
|
38 PseudoReference* operator->() const { return &m_value; }
|
Chris@16
|
39 // This function is needed for MWCW and BCC, which won't call operator->
|
Chris@16
|
40 // again automatically per 13.3.1.2 para 8
|
Chris@16
|
41 // operator T*() const { return &m_value; }
|
Chris@16
|
42 mutable PseudoReference m_value;
|
Chris@16
|
43 };
|
Chris@16
|
44
|
Chris@16
|
45 template <class T>
|
Chris@16
|
46 struct operator_arrow_proxy<T&>
|
Chris@16
|
47 {
|
Chris@16
|
48 operator_arrow_proxy(T &px)
|
Chris@16
|
49 : m_value(px)
|
Chris@16
|
50 {}
|
Chris@16
|
51
|
Chris@16
|
52 T* operator->() const { return &m_value; }
|
Chris@16
|
53 // This function is needed for MWCW and BCC, which won't call operator->
|
Chris@16
|
54 // again automatically per 13.3.1.2 para 8
|
Chris@16
|
55 // operator T*() const { return &m_value; }
|
Chris@16
|
56 T &m_value;
|
Chris@16
|
57 };
|
Chris@16
|
58
|
Chris@16
|
59 template <class Iterator, class UnaryFunction>
|
Chris@16
|
60 class transform_iterator
|
Chris@101
|
61 : public boost::intrusive::iterator
|
Chris@16
|
62 < typename Iterator::iterator_category
|
Chris@16
|
63 , typename detail::remove_reference<typename UnaryFunction::result_type>::type
|
Chris@16
|
64 , typename Iterator::difference_type
|
Chris@16
|
65 , operator_arrow_proxy<typename UnaryFunction::result_type>
|
Chris@16
|
66 , typename UnaryFunction::result_type>
|
Chris@16
|
67 {
|
Chris@16
|
68 public:
|
Chris@16
|
69 explicit transform_iterator(const Iterator &it, const UnaryFunction &f = UnaryFunction())
|
Chris@16
|
70 : members_(it, f)
|
Chris@16
|
71 {}
|
Chris@16
|
72
|
Chris@16
|
73 explicit transform_iterator()
|
Chris@16
|
74 : members_()
|
Chris@16
|
75 {}
|
Chris@16
|
76
|
Chris@16
|
77 Iterator get_it() const
|
Chris@16
|
78 { return members_.m_it; }
|
Chris@16
|
79
|
Chris@16
|
80 //Constructors
|
Chris@16
|
81 transform_iterator& operator++()
|
Chris@16
|
82 { increment(); return *this; }
|
Chris@16
|
83
|
Chris@16
|
84 transform_iterator operator++(int)
|
Chris@16
|
85 {
|
Chris@16
|
86 transform_iterator result (*this);
|
Chris@16
|
87 increment();
|
Chris@16
|
88 return result;
|
Chris@16
|
89 }
|
Chris@16
|
90
|
Chris@16
|
91 friend bool operator== (const transform_iterator& i, const transform_iterator& i2)
|
Chris@16
|
92 { return i.equal(i2); }
|
Chris@16
|
93
|
Chris@16
|
94 friend bool operator!= (const transform_iterator& i, const transform_iterator& i2)
|
Chris@16
|
95 { return !(i == i2); }
|
Chris@16
|
96
|
Chris@16
|
97 friend typename Iterator::difference_type operator- (const transform_iterator& i, const transform_iterator& i2)
|
Chris@16
|
98 { return i2.distance_to(i); }
|
Chris@16
|
99
|
Chris@16
|
100 //Arithmetic
|
Chris@16
|
101 transform_iterator& operator+=(typename Iterator::difference_type off)
|
Chris@16
|
102 { this->advance(off); return *this; }
|
Chris@16
|
103
|
Chris@16
|
104 transform_iterator operator+(typename Iterator::difference_type off) const
|
Chris@16
|
105 {
|
Chris@16
|
106 transform_iterator other(*this);
|
Chris@16
|
107 other.advance(off);
|
Chris@16
|
108 return other;
|
Chris@16
|
109 }
|
Chris@16
|
110
|
Chris@16
|
111 friend transform_iterator operator+(typename Iterator::difference_type off, const transform_iterator& right)
|
Chris@16
|
112 { return right + off; }
|
Chris@16
|
113
|
Chris@16
|
114 transform_iterator& operator-=(typename Iterator::difference_type off)
|
Chris@16
|
115 { this->advance(-off); return *this; }
|
Chris@16
|
116
|
Chris@16
|
117 transform_iterator operator-(typename Iterator::difference_type off) const
|
Chris@16
|
118 { return *this + (-off); }
|
Chris@16
|
119
|
Chris@16
|
120 typename UnaryFunction::result_type operator*() const
|
Chris@16
|
121 { return dereference(); }
|
Chris@16
|
122
|
Chris@16
|
123 operator_arrow_proxy<typename UnaryFunction::result_type>
|
Chris@16
|
124 operator->() const
|
Chris@16
|
125 { return operator_arrow_proxy<typename UnaryFunction::result_type>(dereference()); }
|
Chris@16
|
126
|
Chris@16
|
127 private:
|
Chris@16
|
128 struct members
|
Chris@16
|
129 : UnaryFunction
|
Chris@16
|
130 {
|
Chris@16
|
131 members(const Iterator &it, const UnaryFunction &f)
|
Chris@16
|
132 : UnaryFunction(f), m_it(it)
|
Chris@16
|
133 {}
|
Chris@16
|
134
|
Chris@16
|
135 members()
|
Chris@16
|
136 {}
|
Chris@16
|
137
|
Chris@16
|
138 Iterator m_it;
|
Chris@16
|
139 } members_;
|
Chris@16
|
140
|
Chris@16
|
141
|
Chris@16
|
142 void increment()
|
Chris@16
|
143 { ++members_.m_it; }
|
Chris@16
|
144
|
Chris@16
|
145 void decrement()
|
Chris@16
|
146 { --members_.m_it; }
|
Chris@16
|
147
|
Chris@16
|
148 bool equal(const transform_iterator &other) const
|
Chris@16
|
149 { return members_.m_it == other.members_.m_it; }
|
Chris@16
|
150
|
Chris@16
|
151 bool less(const transform_iterator &other) const
|
Chris@16
|
152 { return other.members_.m_it < members_.m_it; }
|
Chris@16
|
153
|
Chris@16
|
154 typename UnaryFunction::result_type dereference() const
|
Chris@16
|
155 { return members_(*members_.m_it); }
|
Chris@16
|
156
|
Chris@16
|
157 void advance(typename Iterator::difference_type n)
|
Chris@101
|
158 { boost::intrusive::iterator_advance(members_.m_it, n); }
|
Chris@16
|
159
|
Chris@16
|
160 typename Iterator::difference_type distance_to(const transform_iterator &other)const
|
Chris@101
|
161 { return boost::intrusive::iterator_distance(other.members_.m_it, members_.m_it); }
|
Chris@16
|
162 };
|
Chris@16
|
163
|
Chris@16
|
164 } //namespace detail
|
Chris@16
|
165 } //namespace intrusive
|
Chris@16
|
166 } //namespace boost
|
Chris@16
|
167
|
Chris@16
|
168 #include <boost/intrusive/detail/config_end.hpp>
|
Chris@16
|
169
|
Chris@16
|
170 #endif //BOOST_INTRUSIVE_DETAIL_TRANSFORM_ITERATOR_HPP
|