File: Iterator.h

package info (click to toggle)
jazz2-native 3.5.0-1
  • links: PTS, VCS
  • area: contrib
  • in suites:
  • size: 16,836 kB
  • sloc: cpp: 172,557; xml: 113; python: 36; makefile: 5; sh: 2
file content (229 lines) | stat: -rw-r--r-- 5,241 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
#pragma once

#ifndef DOXYGEN_GENERATING_OUTPUT

namespace nCine
{
	/// Dispatching tag for iterators that can only move forward, one element at a time
	struct ForwardIteratorTag
	{
	};
	/// Dispatching tag for iterators that can move both ways, one element at a time
	struct BidirectionalIteratorTag : public ForwardIteratorTag
	{
	};
	/// Dispatching tag for iterators that can jump arbitrary distances in both ways
	struct RandomAccessIteratorTag : public BidirectionalIteratorTag
	{
	};

	/// Base iterator traits structure
	template <class Iterator>
	struct IteratorTraits
	{
	};

	/// Base iterator traits structure
	template<class T>
	struct IteratorTraits<T*>
	{
		/// Type of the values deferenced by the iterator (never const)
		using ValueType = T;
		/// Pointer to the type of the values deferenced by the iterator
		using Pointer = const T*;
		/// Reference to the type of the values deferenced by the iterator
		using Reference = const T&;
		/// Type trait for iterator category
		static inline RandomAccessIteratorTag IteratorCategory() {
			return RandomAccessIteratorTag();
		}
	};

	///////////////////////////////////////////////////////////
	// OPERATIONS
	///////////////////////////////////////////////////////////

	namespace Implementation
	{
		/// Increments an iterator by n elements, for random access iterators
		template<class Iterator>
		inline void advance(Iterator& it, int n, RandomAccessIteratorTag)
		{
			it += n;
		}

		/// Increments an iterator by n elements, for bidirectional iterators
		template<class Iterator>
		inline void advance(Iterator& it, int n, BidirectionalIteratorTag)
		{
			if (n < 0) {
				while (n++)
					--it;
			} else {
				while (n--)
					++it;
			}
		}

		/// Increments an iterator by n elements, for forward iterators
		template<class Iterator>
		inline void advance(Iterator& it, int n, ForwardIteratorTag)
		{
			if (n > 0) {
				while (n--)
					++it;
			}
		}
	}

	/// Increments an iterator by n elements
	template<class Iterator>
	inline void advance(Iterator& it, int n)
	{
		Implementation::advance(it, n, IteratorTraits<Iterator>::IteratorCategory());
	}

	/// Return the nth successor of an iterator
	template<class Iterator>
	inline Iterator next(Iterator it, unsigned int n)
	{
		Implementation::advance(it, n);
		return it;
	}

	/// Return the successor of an iterator
	template<class Iterator>
	inline Iterator next(Iterator it)
	{
		Implementation::advance(it, 1);
		return it;
	}

	/// Return the nth predecessor of an iterator
	template<class Iterator>
	inline Iterator prev(Iterator it, unsigned int n)
	{
		Implementation::advance(it, -n);
		return it;
	}

	/// Return the predecessor of an iterator
	template<class Iterator>
	inline Iterator prev(Iterator it)
	{
		Implementation::advance(it, -1);
		return it;
	}

	namespace Implementation
	{
		/// Returns the distance between two random access iterators with a pointer subtraction
		template<class RandomAccessIterator>
		inline int distance(RandomAccessIterator& first, const RandomAccessIterator& last, RandomAccessIteratorTag)
		{
			return (int)(last - first);
		}

		/// Returns the distance in number of increments between two forward iterators
		template<class ForwardIterator>
		inline int distance(ForwardIterator& first, const ForwardIterator& last, ForwardIteratorTag)
		{
			int counter = 0;

			for (; first != last; ++first)
				counter++;

			return counter;
		}

	}

	/// Returns the distance between two iterators
	template<class Iterator>
	inline int distance(Iterator first, const Iterator last)
	{
		return Implementation::distance(first, last, IteratorTraits<Iterator>::IteratorCategory());
	}

	///////////////////////////////////////////////////////////
	// REVERSE RANGE ADAPTER
	///////////////////////////////////////////////////////////

	template<class T>
	struct ReversionWrapper
	{
		T& iterable;
	};

	template<class T>
	auto begin(ReversionWrapper<T> c) -> decltype(rBegin(c.iterable))
	{
		return rbegin(c.iterable);
	}

	template<class T>
	auto end(ReversionWrapper<T> c) -> decltype(rEnd(c.iterable))
	{
		return rend(c.iterable);
	}

	template<class T>
	ReversionWrapper<T> reverse(T&& iterable)
	{
		return {iterable};
	}

	///////////////////////////////////////////////////////////
	// RANGE
	///////////////////////////////////////////////////////////

	template<class Container>
	typename Container::Iterator begin(Container& c)
	{
		return c.begin();
	}

	template<class Container>
	typename Container::ConstIterator cbegin(const Container& c)
	{
		return c.begin();
	}

	template<class Container>
	typename Container::Iterator end(Container& c)
	{
		return c.end();
	}

	template<class Container>
	typename Container::ConstIterator cend(const Container& c)
	{
		return c.end();
	}

	template<class Container>
	typename Container::ReverseIterator rbegin(Container& c)
	{
		return c.rbegin();
	}

	template<class Container>
	typename Container::ConstReverseIterator crbegin(const Container& c)
	{
		return c.rbegin();
	}

	template<class Container>
	typename Container::ReverseIterator rend(Container& c)
	{
		return c.rend();
	}

	template<class Container>
	typename Container::ConstReverseIterator crend(const Container& c)
	{
		return c.rend();
	}
}

#endif