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