1 // This file is part of the ustl library, an STL implementation.
3 // Copyright (C) 2005 by Mike Sharov <msharov@users.sourceforge.net>
4 // This file is free software, distributed under the MIT License.
7 /// \brief Contains various iterator adapters.
10 #ifndef UITERATOR_H_5BCA176C7214A30F2069E2614D2DC226
11 #define UITERATOR_H_5BCA176C7214A30F2069E2614D2DC226
17 //----------------------------------------------------------------------
19 /// \struct iterator_traits uiterator.h ustl.h
20 /// \brief Contains the type traits of \p Iterator
22 template <typename Iterator
>
23 struct iterator_traits
{
24 typedef typename
Iterator::value_type value_type
;
25 typedef typename
Iterator::difference_type difference_type
;
26 typedef typename
Iterator::pointer pointer
;
27 typedef typename
Iterator::reference reference
;
30 #ifndef DOXYGEN_SHOULD_SKIP_THIS
33 struct iterator_traits
<T
*> {
35 typedef ptrdiff_t difference_type
;
36 typedef const T
* const_pointer
;
38 typedef const T
& const_reference
;
43 struct iterator_traits
<const T
*> {
45 typedef ptrdiff_t difference_type
;
46 typedef const T
* const_pointer
;
47 typedef const T
* pointer
;
48 typedef const T
& const_reference
;
49 typedef const T
& reference
;
53 struct iterator_traits
<void*> {
54 typedef uint8_t value_type
;
55 typedef ptrdiff_t difference_type
;
56 typedef const void* const_pointer
;
57 typedef void* pointer
;
58 typedef const value_type
& const_reference
;
59 typedef value_type
& reference
;
63 struct iterator_traits
<const void*> {
64 typedef uint8_t value_type
;
65 typedef ptrdiff_t difference_type
;
66 typedef const void* const_pointer
;
67 typedef const void* pointer
;
68 typedef const value_type
& const_reference
;
69 typedef const value_type
& reference
;
74 //----------------------------------------------------------------------
76 /// \class reverse_iterator uiterator.h ustl.h
77 /// \ingroup IteratorAdaptors
78 /// \brief Wraps \p Iterator to behave in an exactly opposite manner.
80 template <class Iterator
>
81 class reverse_iterator
{
83 typedef typename iterator_traits
<Iterator
>::value_type value_type
;
84 typedef typename iterator_traits
<Iterator
>::difference_type difference_type
;
85 typedef typename iterator_traits
<Iterator
>::pointer pointer
;
86 typedef typename iterator_traits
<Iterator
>::reference reference
;
88 reverse_iterator (void) : m_i() {}
89 explicit reverse_iterator (Iterator iter
) : m_i (iter
) {}
90 inline bool operator== (const reverse_iterator
& iter
) const { return (m_i
== iter
.m_i
); }
91 inline bool operator< (const reverse_iterator
& iter
) const { return (iter
.m_i
< m_i
); }
92 inline Iterator
base (void) const { return (m_i
); }
93 inline reference
operator* (void) const { Iterator
prev (m_i
); --prev
; return (*prev
); }
94 inline pointer
operator-> (void) const { return (&(operator*())); }
95 inline reverse_iterator
& operator++ (void) { -- m_i
; return (*this); }
96 inline reverse_iterator
& operator-- (void) { ++ m_i
; return (*this); }
97 inline reverse_iterator
operator++ (int) { reverse_iterator
prev (*this); -- m_i
; return (prev
); }
98 inline reverse_iterator
operator-- (int) { reverse_iterator
prev (*this); ++ m_i
; return (prev
); }
99 inline reverse_iterator
& operator+= (size_t n
) { m_i
-= n
; return (*this); }
100 inline reverse_iterator
& operator-= (size_t n
) { m_i
+= n
; return (*this); }
101 inline reverse_iterator
operator+ (size_t n
) const { return (reverse_iterator (m_i
- n
)); }
102 inline reverse_iterator
operator- (size_t n
) const { return (reverse_iterator (m_i
+ n
)); }
103 inline reference
operator[] (uoff_t n
) const { return (*(*this + n
)); }
104 inline difference_type
operator- (const reverse_iterator
& i
) const { return (distance (m_i
, i
.m_i
)); }
109 //----------------------------------------------------------------------
111 /// \class insert_iterator uiterator.h ustl.h
112 /// \ingroup IteratorAdaptors
113 /// \brief Calls insert on bound container for each assignment.
115 template <class Container
>
116 class insert_iterator
{
118 typedef typename
Container::value_type value_type
;
119 typedef typename
Container::difference_type difference_type
;
120 typedef typename
Container::pointer pointer
;
121 typedef typename
Container::reference reference
;
122 typedef typename
Container::iterator iterator
;
124 explicit insert_iterator (Container
& ctr
, iterator ip
) : m_rCtr (ctr
), m_ip (ip
) {}
125 inline insert_iterator
& operator= (typename
Container::const_reference v
)
126 { m_ip
= m_rCtr
.insert (m_ip
, v
); return (*this); }
127 inline insert_iterator
& operator* (void) { return (*this); }
128 inline insert_iterator
& operator++ (void) { ++ m_ip
; return (*this); }
129 inline insert_iterator
operator++ (int) { insert_iterator
prev (*this); ++ m_ip
; return (*this); }
135 /// Returns the insert_iterator for \p ctr.
136 template <class Container
>
137 inline insert_iterator
<Container
> inserter (Container
& ctr
, typename
Container::iterator ip
)
139 return (insert_iterator
<Container
> (ctr
, ip
));
142 //----------------------------------------------------------------------
144 /// \class back_insert_iterator uiterator.h ustl.h
145 /// \ingroup IteratorAdaptors
146 /// \brief Calls push_back on bound container for each assignment.
148 template <class Container
>
149 class back_insert_iterator
{
151 typedef typename
Container::value_type value_type
;
152 typedef typename
Container::difference_type difference_type
;
153 typedef typename
Container::pointer pointer
;
154 typedef typename
Container::reference reference
;
156 explicit back_insert_iterator (Container
& ctr
) : m_rCtr (ctr
) {}
157 inline back_insert_iterator
& operator= (typename
Container::const_reference v
)
158 { m_rCtr
.push_back (v
); return (*this); }
159 inline back_insert_iterator
& operator* (void) { return (*this); }
160 inline back_insert_iterator
& operator++ (void) { return (*this); }
161 inline back_insert_iterator
operator++ (int) { return (*this); }
166 /// Returns the back_insert_iterator for \p ctr.
167 template <class Container
>
168 inline back_insert_iterator
<Container
> back_inserter (Container
& ctr
)
170 return (back_insert_iterator
<Container
> (ctr
));
173 //----------------------------------------------------------------------
175 /// \class index_iterate uiterator.h ustl.h
176 /// \ingroup IteratorAdaptors
178 /// \brief Allows iteration through an index container.
180 /// Converts an iterator into a container of uoff_t indexes to an
181 /// iterator of iterators into another container.
183 template <typename RandomAccessIterator
, typename IndexIterator
>
184 class index_iterate
{
186 typedef RandomAccessIterator value_type
;
187 typedef ptrdiff_t difference_type
;
188 typedef RandomAccessIterator
* pointer
;
189 typedef RandomAccessIterator reference
;
191 index_iterate (void) : m_Base(), m_i() {}
192 index_iterate (RandomAccessIterator ibase
, IndexIterator iindex
) : m_Base (ibase
), m_i (iindex
) {}
193 inline bool operator== (const index_iterate
& i
) const { return (m_i
== i
.m_i
); }
194 inline bool operator< (const index_iterate
& i
) const { return (m_i
< i
.m_i
); }
195 inline bool operator== (const RandomAccessIterator
& i
) const { return (m_Base
== i
); }
196 inline bool operator< (const RandomAccessIterator
& i
) const { return (m_Base
< i
); }
197 inline IndexIterator
base (void) const { return (m_i
); }
198 inline reference
operator* (void) const { return (advance(m_Base
, *m_i
)); }
199 inline pointer
operator-> (void) const { return (&(operator*())); }
200 inline index_iterate
& operator++ (void) { ++ m_i
; return (*this); }
201 inline index_iterate
& operator-- (void) { -- m_i
; return (*this); }
202 inline index_iterate
operator++ (int) { index_iterate
prev (*this); ++ m_i
; return (prev
); }
203 inline index_iterate
operator-- (int) { index_iterate
prev (*this); -- m_i
; return (prev
); }
204 inline index_iterate
& operator+= (size_t n
) { m_i
+= n
; return (*this); }
205 inline index_iterate
& operator-= (size_t n
) { m_i
-= n
; return (*this); }
206 inline index_iterate
operator+ (size_t n
) const { return (index_iterate (m_Base
, m_i
+ n
)); }
207 inline index_iterate
operator- (size_t n
) const { return (index_iterate (m_Base
, m_i
- n
)); }
208 inline reference
operator[] (uoff_t n
) const { return (*(*this + n
)); }
209 inline difference_type
operator- (const index_iterate
& i
) const { return (distance (m_i
, i
.m_i
)); }
211 RandomAccessIterator m_Base
;
215 /// Returns an index_iterate for \p ibase over \p iindex.
216 template <typename RandomAccessIterator
, typename IndexIterator
>
217 inline index_iterate
<RandomAccessIterator
, IndexIterator
> index_iterator (RandomAccessIterator ibase
, IndexIterator iindex
)
219 return (index_iterate
<RandomAccessIterator
, IndexIterator
> (ibase
, iindex
));
222 /// Converts the indexes in \p xc to iterators in \p ic of base \p ibase.
223 template <typename IndexContainer
, typename IteratorContainer
>
224 inline void indexv_to_iteratorv (typename
IteratorContainer::value_type ibase
, const IndexContainer
& xc
, IteratorContainer
& ic
)
226 ic
.resize (xc
.size());
227 copy_n (index_iterator (ibase
, xc
.begin()), xc
.size(), ic
.begin());
230 //----------------------------------------------------------------------
232 /// Converts the given const_iterator into an iterator.
234 template <typename Container
>
235 inline typename
Container::iterator
unconst (typename
Container::const_iterator i
, Container
&)
236 { return (const_cast<typename
Container::iterator
>(i
)); }
238 #ifndef DOXYGEN_SHOULD_SKIP_THIS
240 #define IBYI(Iter1, Iter2, Ctr1, Ctr2) \
241 template <typename Container1, typename Container2> \
242 inline typename Container2::Iter2 ibyi (typename Container1::Iter1 idx, Ctr1& ctr1, Ctr2& ctr2) \
244 assert (ctr1.size() == ctr2.size()); \
245 return (ctr2.begin() + (idx - ctr1.begin())); \
248 IBYI(const_iterator
, const_iterator
, const Container1
, const Container2
)
249 IBYI(iterator
, iterator
, Container1
, Container2
)
250 IBYI(const_iterator
, iterator
, const Container1
, Container2
)
251 IBYI(iterator
, const_iterator
, Container1
, const Container2
)
255 #error This declaration is for doxygen only; it is not compiled.
257 /// Converts a const_iterator in one container into a const_iterator in another container.
258 template <typename Container1
, typename Container2
>
259 inline typename
Container2::iterator
ibyi (typename
Container1::iterator idx
, Container1
& ctr1
, Container2
& ctr2
) {}
263 //----------------------------------------------------------------------