1 //////////////////////////////////////////////////////////////////////////////
3 // (C) Copyright Ion Gaztanaga 2005-2013.
4 // (C) Copyright Gennaro Prota 2003 - 2004.
6 // Distributed under the Boost Software License, Version 1.0.
7 // (See accompanying file LICENSE_1_0.txt or copy at
8 // http://www.boost.org/LICENSE_1_0.txt)
10 // See http://www.boost.org/libs/container for documentation.
12 //////////////////////////////////////////////////////////////////////////////
14 #ifndef BOOST_CONTAINER_DETAIL_TRANSFORM_ITERATORS_HPP
15 #define BOOST_CONTAINER_DETAIL_TRANSFORM_ITERATORS_HPP
17 #ifndef BOOST_CONFIG_HPP
18 # include <boost/config.hpp>
21 #if defined(BOOST_HAS_PRAGMA_ONCE)
25 #include <boost/container/detail/config_begin.hpp>
26 #include <boost/container/detail/workaround.hpp>
27 #include <boost/container/detail/type_traits.hpp>
28 #include <boost/container/detail/iterator.hpp>
33 template <class PseudoReference>
34 struct operator_arrow_proxy
36 operator_arrow_proxy(const PseudoReference &px)
40 typedef PseudoReference element_type;
42 PseudoReference* operator->() const { return &m_value; }
44 mutable PseudoReference m_value;
48 struct operator_arrow_proxy<T&>
50 operator_arrow_proxy(T &px)
54 typedef T element_type;
56 T* operator->() const { return const_cast<T*>(&m_value); }
61 template <class Iterator, class UnaryFunction>
62 class transform_iterator
63 : public UnaryFunction
64 , public boost::container::iterator
65 < typename Iterator::iterator_category
66 , typename container_detail::remove_reference<typename UnaryFunction::result_type>::type
67 , typename Iterator::difference_type
68 , operator_arrow_proxy<typename UnaryFunction::result_type>
69 , typename UnaryFunction::result_type>
72 explicit transform_iterator(const Iterator &it, const UnaryFunction &f = UnaryFunction())
73 : UnaryFunction(f), m_it(it)
76 explicit transform_iterator()
77 : UnaryFunction(), m_it()
81 transform_iterator& operator++()
82 { increment(); return *this; }
84 transform_iterator operator++(int)
86 transform_iterator result (*this);
91 friend bool operator== (const transform_iterator& i, const transform_iterator& i2)
92 { return i.equal(i2); }
94 friend bool operator!= (const transform_iterator& i, const transform_iterator& i2)
95 { return !(i == i2); }
98 friend bool operator> (const transform_iterator& i, const transform_iterator& i2)
101 friend bool operator<= (const transform_iterator& i, const transform_iterator& i2)
102 { return !(i > i2); }
104 friend bool operator>= (const transform_iterator& i, const transform_iterator& i2)
105 { return !(i < i2); }
107 friend typename Iterator::difference_type operator- (const transform_iterator& i, const transform_iterator& i2)
108 { return i2.distance_to(i); }
111 transform_iterator& operator+=(typename Iterator::difference_type off)
112 { this->advance(off); return *this; }
114 transform_iterator operator+(typename Iterator::difference_type off) const
116 transform_iterator other(*this);
121 friend transform_iterator operator+(typename Iterator::difference_type off, const transform_iterator& right)
122 { return right + off; }
124 transform_iterator& operator-=(typename Iterator::difference_type off)
125 { this->advance(-off); return *this; }
127 transform_iterator operator-(typename Iterator::difference_type off) const
128 { return *this + (-off); }
130 typename UnaryFunction::result_type operator*() const
131 { return dereference(); }
133 operator_arrow_proxy<typename UnaryFunction::result_type>
135 { return operator_arrow_proxy<typename UnaryFunction::result_type>(dereference()); }
140 const Iterator & base() const
152 bool equal(const transform_iterator &other) const
153 { return m_it == other.m_it; }
155 bool less(const transform_iterator &other) const
156 { return other.m_it < m_it; }
158 typename UnaryFunction::result_type dereference() const
159 { return UnaryFunction::operator()(*m_it); }
161 void advance(typename Iterator::difference_type n)
162 { boost::container::iterator_advance(m_it, n); }
164 typename Iterator::difference_type distance_to(const transform_iterator &other)const
165 { return boost::container::iterator_distance(other.m_it, m_it); }
168 template <class Iterator, class UnaryFunc>
169 transform_iterator<Iterator, UnaryFunc>
170 make_transform_iterator(Iterator it, UnaryFunc fun)
172 return transform_iterator<Iterator, UnaryFunc>(it, fun);
175 } //namespace container {
176 } //namespace boost {
178 #include <boost/container/detail/config_end.hpp>
180 #endif //#ifndef BOOST_CONTAINER_DETAIL_TRANSFORM_ITERATORS_HPP