1 |
786 |
skrzyp |
// This file is part of the uSTL library, an STL implementation.
|
2 |
|
|
//
|
3 |
|
|
// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net>
|
4 |
|
|
// This file is free software, distributed under the MIT License.
|
5 |
|
|
//
|
6 |
|
|
/// \file uiterator.h
|
7 |
|
|
/// \brief Contains various iterator adapters.
|
8 |
|
|
|
9 |
|
|
#ifndef UITERATOR_H_5BCA176C7214A30F2069E2614D2DC226
|
10 |
|
|
#define UITERATOR_H_5BCA176C7214A30F2069E2614D2DC226
|
11 |
|
|
|
12 |
|
|
#include "utypes.h"
|
13 |
|
|
|
14 |
|
|
namespace ustl {
|
15 |
|
|
|
16 |
|
|
//----------------------------------------------------------------------
|
17 |
|
|
|
18 |
|
|
/// \struct iterator_traits uiterator.h ustl.h
|
19 |
|
|
/// \brief Contains the type traits of \p Iterator
|
20 |
|
|
///
|
21 |
|
|
template <typename Iterator>
|
22 |
|
|
struct iterator_traits {
|
23 |
|
|
typedef typename Iterator::value_type value_type;
|
24 |
|
|
typedef typename Iterator::difference_type difference_type;
|
25 |
|
|
typedef typename Iterator::pointer pointer;
|
26 |
|
|
typedef typename Iterator::reference reference;
|
27 |
|
|
};
|
28 |
|
|
|
29 |
|
|
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
30 |
|
|
|
31 |
|
|
template <typename T>
|
32 |
|
|
struct iterator_traits<T*> {
|
33 |
|
|
typedef T value_type;
|
34 |
|
|
typedef ptrdiff_t difference_type;
|
35 |
|
|
typedef const T* const_pointer;
|
36 |
|
|
typedef T* pointer;
|
37 |
|
|
typedef const T& const_reference;
|
38 |
|
|
typedef T& reference;
|
39 |
|
|
};
|
40 |
|
|
|
41 |
|
|
template <typename T>
|
42 |
|
|
struct iterator_traits<const T*> {
|
43 |
|
|
typedef T value_type;
|
44 |
|
|
typedef ptrdiff_t difference_type;
|
45 |
|
|
typedef const T* const_pointer;
|
46 |
|
|
typedef const T* pointer;
|
47 |
|
|
typedef const T& const_reference;
|
48 |
|
|
typedef const T& reference;
|
49 |
|
|
};
|
50 |
|
|
|
51 |
|
|
template <>
|
52 |
|
|
struct iterator_traits<void*> {
|
53 |
|
|
typedef uint8_t value_type;
|
54 |
|
|
typedef ptrdiff_t difference_type;
|
55 |
|
|
typedef const void* const_pointer;
|
56 |
|
|
typedef void* pointer;
|
57 |
|
|
typedef const value_type& const_reference;
|
58 |
|
|
typedef value_type& reference;
|
59 |
|
|
};
|
60 |
|
|
|
61 |
|
|
template <>
|
62 |
|
|
struct iterator_traits<const void*> {
|
63 |
|
|
typedef uint8_t value_type;
|
64 |
|
|
typedef ptrdiff_t difference_type;
|
65 |
|
|
typedef const void* const_pointer;
|
66 |
|
|
typedef const void* pointer;
|
67 |
|
|
typedef const value_type& const_reference;
|
68 |
|
|
typedef const value_type& reference;
|
69 |
|
|
};
|
70 |
|
|
|
71 |
|
|
#endif
|
72 |
|
|
|
73 |
|
|
//----------------------------------------------------------------------
|
74 |
|
|
|
75 |
|
|
/// \class reverse_iterator uiterator.h ustl.h
|
76 |
|
|
/// \ingroup IteratorAdaptors
|
77 |
|
|
/// \brief Wraps \p Iterator to behave in an exactly opposite manner.
|
78 |
|
|
///
|
79 |
|
|
template <class Iterator>
|
80 |
|
|
class reverse_iterator {
|
81 |
|
|
public:
|
82 |
|
|
typedef typename iterator_traits<Iterator>::value_type value_type;
|
83 |
|
|
typedef typename iterator_traits<Iterator>::difference_type difference_type;
|
84 |
|
|
typedef typename iterator_traits<Iterator>::pointer pointer;
|
85 |
|
|
typedef typename iterator_traits<Iterator>::reference reference;
|
86 |
|
|
public:
|
87 |
|
|
reverse_iterator (void) : m_i() {}
|
88 |
|
|
explicit reverse_iterator (Iterator iter) : m_i (iter) {}
|
89 |
|
|
inline bool operator== (const reverse_iterator& iter) const { return (m_i == iter.m_i); }
|
90 |
|
|
inline bool operator< (const reverse_iterator& iter) const { return (iter.m_i < m_i); }
|
91 |
|
|
inline Iterator base (void) const { return (m_i); }
|
92 |
|
|
inline reference operator* (void) const { Iterator prev (m_i); --prev; return (*prev); }
|
93 |
|
|
inline pointer operator-> (void) const { return (&(operator*())); }
|
94 |
|
|
inline reverse_iterator& operator++ (void) { -- m_i; return (*this); }
|
95 |
|
|
inline reverse_iterator& operator-- (void) { ++ m_i; return (*this); }
|
96 |
|
|
inline reverse_iterator operator++ (int) { reverse_iterator prev (*this); -- m_i; return (prev); }
|
97 |
|
|
inline reverse_iterator operator-- (int) { reverse_iterator prev (*this); ++ m_i; return (prev); }
|
98 |
|
|
inline reverse_iterator& operator+= (size_t n) { m_i -= n; return (*this); }
|
99 |
|
|
inline reverse_iterator& operator-= (size_t n) { m_i += n; return (*this); }
|
100 |
|
|
inline reverse_iterator operator+ (size_t n) const { return (reverse_iterator (m_i - n)); }
|
101 |
|
|
inline reverse_iterator operator- (size_t n) const { return (reverse_iterator (m_i + n)); }
|
102 |
|
|
inline reference operator[] (uoff_t n) const { return (*(*this + n)); }
|
103 |
|
|
inline difference_type operator- (const reverse_iterator& i) const { return (distance (m_i, i.m_i)); }
|
104 |
|
|
protected:
|
105 |
|
|
Iterator m_i;
|
106 |
|
|
};
|
107 |
|
|
|
108 |
|
|
//----------------------------------------------------------------------
|
109 |
|
|
|
110 |
|
|
/// \class insert_iterator uiterator.h ustl.h
|
111 |
|
|
/// \ingroup IteratorAdaptors
|
112 |
|
|
/// \brief Calls insert on bound container for each assignment.
|
113 |
|
|
///
|
114 |
|
|
template <class Container>
|
115 |
|
|
class insert_iterator {
|
116 |
|
|
public:
|
117 |
|
|
typedef typename Container::value_type value_type;
|
118 |
|
|
typedef typename Container::difference_type difference_type;
|
119 |
|
|
typedef typename Container::pointer pointer;
|
120 |
|
|
typedef typename Container::reference reference;
|
121 |
|
|
typedef typename Container::iterator iterator;
|
122 |
|
|
public:
|
123 |
|
|
explicit insert_iterator (Container& ctr, iterator ip) : m_rCtr (ctr), m_ip (ip) {}
|
124 |
|
|
inline insert_iterator& operator= (typename Container::const_reference v)
|
125 |
|
|
{ m_ip = m_rCtr.insert (m_ip, v); return (*this); }
|
126 |
|
|
inline insert_iterator& operator* (void) { return (*this); }
|
127 |
|
|
inline insert_iterator& operator++ (void) { ++ m_ip; return (*this); }
|
128 |
|
|
inline insert_iterator operator++ (int) { insert_iterator prev (*this); ++ m_ip; return (*this); }
|
129 |
|
|
protected:
|
130 |
|
|
Container& m_rCtr;
|
131 |
|
|
iterator m_ip;
|
132 |
|
|
};
|
133 |
|
|
|
134 |
|
|
/// Returns the insert_iterator for \p ctr.
|
135 |
|
|
template <class Container>
|
136 |
|
|
inline insert_iterator<Container> inserter (Container& ctr, typename Container::iterator ip)
|
137 |
|
|
{
|
138 |
|
|
return (insert_iterator<Container> (ctr, ip));
|
139 |
|
|
}
|
140 |
|
|
|
141 |
|
|
//----------------------------------------------------------------------
|
142 |
|
|
|
143 |
|
|
/// \class back_insert_iterator uiterator.h ustl.h
|
144 |
|
|
/// \ingroup IteratorAdaptors
|
145 |
|
|
/// \brief Calls push_back on bound container for each assignment.
|
146 |
|
|
///
|
147 |
|
|
template <class Container>
|
148 |
|
|
class back_insert_iterator {
|
149 |
|
|
public:
|
150 |
|
|
typedef typename Container::value_type value_type;
|
151 |
|
|
typedef typename Container::difference_type difference_type;
|
152 |
|
|
typedef typename Container::pointer pointer;
|
153 |
|
|
typedef typename Container::reference reference;
|
154 |
|
|
public:
|
155 |
|
|
explicit back_insert_iterator (Container& ctr) : m_rCtr (ctr) {}
|
156 |
|
|
inline back_insert_iterator& operator= (typename Container::const_reference v)
|
157 |
|
|
{ m_rCtr.push_back (v); return (*this); }
|
158 |
|
|
inline back_insert_iterator& operator* (void) { return (*this); }
|
159 |
|
|
inline back_insert_iterator& operator++ (void) { return (*this); }
|
160 |
|
|
inline back_insert_iterator operator++ (int) { return (*this); }
|
161 |
|
|
protected:
|
162 |
|
|
Container& m_rCtr;
|
163 |
|
|
};
|
164 |
|
|
|
165 |
|
|
/// Returns the back_insert_iterator for \p ctr.
|
166 |
|
|
template <class Container>
|
167 |
|
|
inline back_insert_iterator<Container> back_inserter (Container& ctr)
|
168 |
|
|
{
|
169 |
|
|
return (back_insert_iterator<Container> (ctr));
|
170 |
|
|
}
|
171 |
|
|
|
172 |
|
|
//----------------------------------------------------------------------
|
173 |
|
|
|
174 |
|
|
/// \class index_iterate uiterator.h ustl.h
|
175 |
|
|
/// \ingroup IteratorAdaptors
|
176 |
|
|
///
|
177 |
|
|
/// \brief Allows iteration through an index container.
|
178 |
|
|
///
|
179 |
|
|
/// Converts an iterator into a container of uoff_t indexes to an
|
180 |
|
|
/// iterator of iterators into another container.
|
181 |
|
|
///
|
182 |
|
|
template <typename RandomAccessIterator, typename IndexIterator>
|
183 |
|
|
class index_iterate {
|
184 |
|
|
public:
|
185 |
|
|
typedef RandomAccessIterator value_type;
|
186 |
|
|
typedef ptrdiff_t difference_type;
|
187 |
|
|
typedef RandomAccessIterator* pointer;
|
188 |
|
|
typedef RandomAccessIterator reference;
|
189 |
|
|
public:
|
190 |
|
|
index_iterate (void) : m_Base(), m_i() {}
|
191 |
|
|
index_iterate (RandomAccessIterator ibase, IndexIterator iindex) : m_Base (ibase), m_i (iindex) {}
|
192 |
|
|
inline bool operator== (const index_iterate& i) const { return (m_i == i.m_i); }
|
193 |
|
|
inline bool operator< (const index_iterate& i) const { return (m_i < i.m_i); }
|
194 |
|
|
inline bool operator== (const RandomAccessIterator& i) const { return (m_Base == i); }
|
195 |
|
|
inline bool operator< (const RandomAccessIterator& i) const { return (m_Base < i); }
|
196 |
|
|
inline IndexIterator base (void) const { return (m_i); }
|
197 |
|
|
inline reference operator* (void) const { return (advance(m_Base, *m_i)); }
|
198 |
|
|
inline pointer operator-> (void) const { return (&(operator*())); }
|
199 |
|
|
inline index_iterate& operator++ (void) { ++ m_i; return (*this); }
|
200 |
|
|
inline index_iterate& operator-- (void) { -- m_i; return (*this); }
|
201 |
|
|
inline index_iterate operator++ (int) { index_iterate prev (*this); ++ m_i; return (prev); }
|
202 |
|
|
inline index_iterate operator-- (int) { index_iterate prev (*this); -- m_i; return (prev); }
|
203 |
|
|
inline index_iterate& operator+= (size_t n) { m_i += n; return (*this); }
|
204 |
|
|
inline index_iterate& operator-= (size_t n) { m_i -= n; return (*this); }
|
205 |
|
|
inline index_iterate operator+ (size_t n) const { return (index_iterate (m_Base, m_i + n)); }
|
206 |
|
|
inline index_iterate operator- (size_t n) const { return (index_iterate (m_Base, m_i - n)); }
|
207 |
|
|
inline reference operator[] (uoff_t n) const { return (*(*this + n)); }
|
208 |
|
|
inline difference_type operator- (const index_iterate& i) const { return (distance (m_i, i.m_i)); }
|
209 |
|
|
private:
|
210 |
|
|
RandomAccessIterator m_Base;
|
211 |
|
|
IndexIterator m_i;
|
212 |
|
|
};
|
213 |
|
|
|
214 |
|
|
/// Returns an index_iterate for \p ibase over \p iindex.
|
215 |
|
|
template <typename RandomAccessIterator, typename IndexIterator>
|
216 |
|
|
inline index_iterate<RandomAccessIterator, IndexIterator> index_iterator (RandomAccessIterator ibase, IndexIterator iindex)
|
217 |
|
|
{
|
218 |
|
|
return (index_iterate<RandomAccessIterator, IndexIterator> (ibase, iindex));
|
219 |
|
|
}
|
220 |
|
|
|
221 |
|
|
/// Converts the indexes in \p xc to iterators in \p ic of base \p ibase.
|
222 |
|
|
template <typename IndexContainer, typename IteratorContainer>
|
223 |
|
|
inline void indexv_to_iteratorv (typename IteratorContainer::value_type ibase, const IndexContainer& xc, IteratorContainer& ic)
|
224 |
|
|
{
|
225 |
|
|
ic.resize (xc.size());
|
226 |
|
|
copy_n (index_iterator (ibase, xc.begin()), xc.size(), ic.begin());
|
227 |
|
|
}
|
228 |
|
|
|
229 |
|
|
//----------------------------------------------------------------------
|
230 |
|
|
|
231 |
|
|
/// Converts the given const_iterator into an iterator.
|
232 |
|
|
///
|
233 |
|
|
template <typename Container>
|
234 |
|
|
inline typename Container::iterator unconst (typename Container::const_iterator i, Container&)
|
235 |
|
|
{ return (const_cast<typename Container::iterator>(i)); }
|
236 |
|
|
|
237 |
|
|
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
238 |
|
|
|
239 |
|
|
#define IBYI(Iter1, Iter2, Ctr1, Ctr2) \
|
240 |
|
|
template <typename Container1, typename Container2> \
|
241 |
|
|
inline typename Container2::Iter2 ibyi (typename Container1::Iter1 idx, Ctr1& ctr1, Ctr2& ctr2) \
|
242 |
|
|
{ \
|
243 |
|
|
assert (ctr1.size() == ctr2.size()); \
|
244 |
|
|
return (ctr2.begin() + (idx - ctr1.begin())); \
|
245 |
|
|
}
|
246 |
|
|
|
247 |
|
|
IBYI(const_iterator, const_iterator, const Container1, const Container2)
|
248 |
|
|
IBYI(iterator, iterator, Container1, Container2)
|
249 |
|
|
IBYI(const_iterator, iterator, const Container1, Container2)
|
250 |
|
|
IBYI(iterator, const_iterator, Container1, const Container2)
|
251 |
|
|
|
252 |
|
|
#else // DOXYGEN
|
253 |
|
|
|
254 |
|
|
#error This declaration is for doxygen only; it is not compiled.
|
255 |
|
|
|
256 |
|
|
/// Converts a const_iterator in one container into a const_iterator in another container.
|
257 |
|
|
template <typename Container1, typename Container2>
|
258 |
|
|
inline typename Container2::iterator ibyi (typename Container1::iterator idx, Container1& ctr1, Container2& ctr2) {}
|
259 |
|
|
|
260 |
|
|
#endif // DOXYGEN
|
261 |
|
|
|
262 |
|
|
//----------------------------------------------------------------------
|
263 |
|
|
|
264 |
|
|
} // namespace ustl
|
265 |
|
|
|
266 |
|
|
#endif
|