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_REVERSE_ITERATOR_HPP
14 #define BOOST_INTRUSIVE_DETAIL_REVERSE_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 <boost/intrusive/detail/config_begin.hpp>
25 #include <boost/intrusive/detail/iterator.hpp>
26 #include <boost/intrusive/detail/mpl.hpp>
27 
28 namespace boost {
29 namespace intrusive {
30 
31 template<class It>
32 class reverse_iterator
33 {
34    public:
35    typedef typename boost::intrusive::iterator_traits<It>::pointer             pointer;
36    typedef typename boost::intrusive::iterator_traits<It>::reference           reference;
37    typedef typename boost::intrusive::iterator_traits<It>::difference_type     difference_type;
38    typedef typename boost::intrusive::iterator_traits<It>::iterator_category   iterator_category;
39    typedef typename boost::intrusive::iterator_traits<It>::value_type          value_type;
40 
41 
42    typedef It iterator_type;
43 
reverse_iterator()44    reverse_iterator()
45       : m_current()  //Value initialization to achieve "null iterators" (N3644)
46    {}
47 
reverse_iterator(It r)48    explicit reverse_iterator(It r)
49       : m_current(r)
50    {}
51 
reverse_iterator(const reverse_iterator & r)52    reverse_iterator(const reverse_iterator& r)
53       : m_current(r.base())
54    {}
55 
56    template<class OtherIt>
reverse_iterator(const reverse_iterator<OtherIt> & r,typename boost::intrusive::detail::enable_if_convertible<OtherIt,It>::type * =0)57    reverse_iterator( const reverse_iterator<OtherIt>& r
58                    , typename boost::intrusive::detail::enable_if_convertible<OtherIt, It>::type* =0
59                    )
60       : m_current(r.base())
61    {}
62 
operator =(const reverse_iterator & r)63    reverse_iterator & operator=( const reverse_iterator& r)
64    {  m_current = r.base();   return *this;  }
65 
66    template<class OtherIt>
67    typename boost::intrusive::detail::enable_if_convertible<OtherIt, It, reverse_iterator &>::type
operator =(const reverse_iterator<OtherIt> & r)68          operator=( const reverse_iterator<OtherIt>& r)
69    {  m_current = r.base();   return *this;  }
70 
base() const71    It base() const
72    {  return m_current;  }
73 
operator *() const74    reference operator*() const
75    {
76       It temp(m_current);
77       --temp;
78       reference r = *temp;
79       return r;
80    }
81 
operator ->() const82    pointer operator->() const
83    {
84       It temp(m_current);
85       --temp;
86       return iterator_arrow_result(temp);
87    }
88 
operator [](difference_type off) const89    reference operator[](difference_type off) const
90    {
91       return this->m_current[-off - 1];
92    }
93 
operator ++()94    reverse_iterator& operator++()
95    {
96       --m_current;
97       return *this;
98    }
99 
operator ++(int)100    reverse_iterator operator++(int)
101    {
102       reverse_iterator temp((*this));
103       --m_current;
104       return temp;
105    }
106 
operator --()107    reverse_iterator& operator--()
108    {
109       ++m_current;
110       return *this;
111    }
112 
operator --(int)113    reverse_iterator operator--(int)
114    {
115       reverse_iterator temp((*this));
116       ++m_current;
117       return temp;
118    }
119 
operator ==(const reverse_iterator & l,const reverse_iterator & r)120    friend bool operator==(const reverse_iterator& l, const reverse_iterator& r)
121    {  return l.m_current == r.m_current;  }
122 
operator !=(const reverse_iterator & l,const reverse_iterator & r)123    friend bool operator!=(const reverse_iterator& l, const reverse_iterator& r)
124    {  return l.m_current != r.m_current;  }
125 
operator <(const reverse_iterator & l,const reverse_iterator & r)126    friend bool operator<(const reverse_iterator& l, const reverse_iterator& r)
127    {  return l.m_current > r.m_current;  }
128 
operator <=(const reverse_iterator & l,const reverse_iterator & r)129    friend bool operator<=(const reverse_iterator& l, const reverse_iterator& r)
130    {  return l.m_current >= r.m_current;  }
131 
operator >(const reverse_iterator & l,const reverse_iterator & r)132    friend bool operator>(const reverse_iterator& l, const reverse_iterator& r)
133    {  return l.m_current < r.m_current;  }
134 
operator >=(const reverse_iterator & l,const reverse_iterator & r)135    friend bool operator>=(const reverse_iterator& l, const reverse_iterator& r)
136    {  return l.m_current <= r.m_current;  }
137 
operator +=(difference_type off)138    reverse_iterator& operator+=(difference_type off)
139    {  m_current -= off; return *this;  }
140 
operator -=(difference_type off)141    reverse_iterator& operator-=(difference_type off)
142    {  m_current += off; return *this;  }
143 
operator +(reverse_iterator l,difference_type off)144    friend reverse_iterator operator+(reverse_iterator l, difference_type off)
145    {  return (l += off);  }
146 
operator +(difference_type off,reverse_iterator r)147    friend reverse_iterator operator+(difference_type off, reverse_iterator r)
148    {  return (r += off);   }
149 
operator -(reverse_iterator l,difference_type off)150    friend reverse_iterator operator-(reverse_iterator l, difference_type off)
151    {  return (l-= off);  }
152 
operator -(const reverse_iterator & l,const reverse_iterator & r)153    friend difference_type operator-(const reverse_iterator& l, const reverse_iterator& r)
154    {  return r.m_current - l.m_current;  }
155 
156    private:
157    It m_current;   // the wrapped iterator
158 };
159 
160 } //namespace intrusive {
161 } //namespace boost {
162 
163 #include <boost/intrusive/detail/config_end.hpp>
164 
165 #endif //BOOST_INTRUSIVE_DETAIL_REVERSE_ITERATOR_HPP
166