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/move for documentation.
10 //
11 /////////////////////////////////////////////////////////////////////////////
12
13 #ifndef BOOST_MOVE_DETAIL_REVERSE_ITERATOR_HPP
14 #define BOOST_MOVE_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/move/detail/config_begin.hpp>
25 #include <boost/move/detail/iterator_traits.hpp>
26 #include <boost/move/detail/meta_utils.hpp>
27
28 namespace boost {
29 namespace movelib {
30
31 template<class It>
32 class reverse_iterator
33 {
34 public:
35 typedef typename boost::movelib::iterator_traits<It>::pointer pointer;
36 typedef typename boost::movelib::iterator_traits<It>::reference reference;
37 typedef typename boost::movelib::iterator_traits<It>::difference_type difference_type;
38 typedef typename boost::movelib::iterator_traits<It>::iterator_category iterator_category;
39 typedef typename boost::movelib::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::move_detail::enable_if_convertible<OtherIt,It>::type * =0)57 reverse_iterator( const reverse_iterator<OtherIt>& r
58 , typename boost::move_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::move_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 template< class Iterator >
make_reverse_iterator(Iterator i)161 reverse_iterator<Iterator> make_reverse_iterator( Iterator i )
162 {
163 return reverse_iterator<Iterator>(i);
164 }
165
166 } //namespace movelib {
167 } //namespace boost {
168
169 #include <boost/move/detail/config_end.hpp>
170
171 #endif //BOOST_MOVE_DETAIL_REVERSE_ITERATOR_HPP
172