-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy patharray_view.h
More file actions
324 lines (253 loc) · 8.98 KB
/
Copy patharray_view.h
File metadata and controls
324 lines (253 loc) · 8.98 KB
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
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
#ifndef ARRAY_VIEW_H_
#define ARRAY_VIEW_H_
#include <type_traits>
namespace detail {
template<typename A, typename C> static auto test_index_operator(int32_t) ->
decltype(C(std::declval<A>()[0]), std::true_type{});
template<typename A, typename C> static auto test_index_operator(int64_t) -> std::false_type;
}
template<typename T, typename ReturnType> struct has_index_operator : decltype(::detail::test_index_operator<T, ReturnType>(0))::type {};
template<bool Unique, typename T>
inline void add_sorted(array<T>& list, const T& element) {
unsigned int index = linear_search(list.data, element, 0, list.length);
if (Unique && index < list.length && list[index] == element) return;
shift_right(list.data, list.length, index);
list[index] = element;
list.length++;
}
template<typename T>
struct array_view {
T* array;
unsigned int length;
array_view(T* array, unsigned int length) : array(array), length(length) { }
inline T& operator[] (size_t index) {
return array[index];
}
inline const T& operator[] (size_t index) const {
return array[index];
}
inline const T* begin() const {
return array;
}
inline const T* end() const {
return array + length;
}
inline unsigned int size() const {
return length;
}
};
template<typename T>
array_view<T> make_array_view(T* array, unsigned int length) {
return array_view<T>(array, length);
}
template<typename T>
struct indexed_array_view {
T* array;
const unsigned int* indices;
unsigned int length;
indexed_array_view(T* array, const unsigned int* indices, unsigned int length) : array(array), indices(indices), length(length) { }
inline T& operator[] (size_t index) {
return array[indices[index]];
}
inline const T& operator[] (size_t index) const {
return array[indices[index]];
}
inline unsigned int size() const {
return length;
}
};
template<typename T>
indexed_array_view<T> make_indexed_array_view(T* array, unsigned int* indices, unsigned int length) {
return indexed_array_view<T>(array, indices, length);
}
template<typename Array, typename T>
struct lookup_table_array_view {
static_assert(has_index_operator<Array, T>::value, "`Array` does not have an index operator that returns type `T`");
Array* arrays;
const unsigned int* indices;
unsigned int length;
lookup_table_array_view(Array* arrays, const unsigned int* indices, unsigned int length) : arrays(arrays), indices(indices), length(length) { }
inline T& operator[] (size_t index) {
return arrays[index][indices[index]];
}
inline const T& operator[] (size_t index) const {
return arrays[index][indices[index]];
}
inline unsigned int size() const {
return length;
}
};
template<typename T, typename Array>
struct prepended_array_view {
static_assert(has_index_operator<Array, T>::value, "`Array` does not have an index operator that returns type `T`");
T first;
const Array& second;
prepended_array_view(T first, const Array& second) : first(first), second(second) { }
inline T& operator[] (size_t index) {
if (index == 0) return first;
else return second[index - 1];
}
inline const T& operator[] (size_t index) const {
if (index == 0) return first;
else return second[index - 1];
}
inline unsigned int size() const {
return 1 + second.size();
}
};
template<typename T, typename Array>
prepended_array_view<T, Array> make_prepended_array_view(T first, const Array& second) {
return prepended_array_view<T, Array>(first, second);
}
template<typename T, typename Array>
struct appended_array_view {
static_assert(has_index_operator<Array, T>::value, "`Array` does not have an index operator that returns type `T`");
const Array& first;
T second;
appended_array_view(const Array& first, T second) : first(first), second(second) { }
inline T& operator[] (size_t index) {
if (index == first.size()) return second;
else return first[index];
}
inline const T& operator[] (size_t index) const {
if (index == first.size()) return second;
else return first[index];
}
inline unsigned int size() const {
return first.size() + 1;
}
};
template<typename T, typename Array>
appended_array_view<T, Array> make_appended_array_view(const Array& first, T second) {
return appended_array_view<T, Array>(first, second);
}
template<typename T>
struct excluded_array_view {
T* elements;
unsigned int length;
unsigned int excluded_index;
excluded_array_view(T* elements, unsigned int original_length, unsigned int excluded_index) :
elements(elements), length(original_length - 1), excluded_index(excluded_index) { }
inline T& operator[] (size_t index) {
if (index < excluded_index)
return elements[index];
else return elements[index + 1];
}
inline const T& operator[] (size_t index) const {
if (index < excluded_index)
return elements[index];
else return elements[index + 1];
}
inline unsigned int size() const {
return length;
}
};
template<typename T>
inline excluded_array_view<T> make_excluded_array_view(T* elements, unsigned int original_length, unsigned int excluded_index) {
return excluded_array_view<T>(elements, original_length, excluded_index);
}
template<typename T>
struct included_array_view {
T* elements;
unsigned int length;
T& included;
unsigned int included_index;
included_array_view(T* elements, unsigned int original_length, T& included, unsigned int included_index) :
elements(elements), length(original_length + 1), included(included), included_index(included_index) { }
inline T& operator[] (size_t index) {
if (index < included_index)
return elements[index];
else if (index == included_index)
return included;
else return elements[index - 1];
}
inline const T& operator[] (size_t index) const {
if (index < included_index)
return elements[index];
else if (index == included_index)
return included;
else return elements[index - 1];
}
inline unsigned int size() const {
return length;
}
};
template<typename T>
inline included_array_view<T> make_included_array_view(T* elements, unsigned int original_length, T& included, unsigned int included_index) {
return included_array_view<T>(elements, original_length, included, included_index);
}
template<typename T>
struct repeated_array_view {
T repeated_element;
unsigned int length;
repeated_array_view(T repeated_element, unsigned int length) :
repeated_element(repeated_element), length(length) { }
inline T& operator[] (size_t index) {
return repeated_element;
}
inline const T& operator[] (size_t index) const {
return repeated_element;
}
inline unsigned int size() const {
return length;
}
};
template<typename T>
inline repeated_array_view<T> make_repeated_array_view(T repeated_element, unsigned int length) {
return repeated_array_view<T>(repeated_element, length);
}
template<typename T, typename Array>
struct replaced_array_view {
static_assert(has_index_operator<Array, T>::value, "`Array` does not have an index operator that returns type `T`");
const Array& array;
T replaced_element;
unsigned int replaced_index;
replaced_array_view(const Array& array, T replaced_element, unsigned int replaced_index) :
array(array), replaced_element(replaced_element), replaced_index(replaced_index) { }
inline T& operator[] (size_t index) {
if (index == replaced_index)
return replaced_element;
else return array[index];
}
inline const T& operator[] (size_t index) const {
if (index == replaced_index)
return replaced_element;
else return array[index];
}
inline unsigned int size() const {
return array.size();
}
};
template<typename T, typename Array>
inline replaced_array_view<T, Array> make_replaced_array_view(const Array& array, T replaced_element, unsigned int replaced_index) {
return replaced_array_view<T, Array>(array, replaced_element, replaced_index);
}
template<typename T, typename FirstArray, typename SecondArray>
struct concat_array_view {
static_assert(has_index_operator<FirstArray, T>::value, "`FirstArray` does not have an index operator that returns type `T`");
static_assert(has_index_operator<SecondArray, T>::value, "`SecondArray` does not have an index operator that returns type `T`");
const FirstArray& first;
const SecondArray& second;
concat_array_view(const FirstArray& first, const SecondArray& second) : first(first), second(second) { }
inline T& operator[] (size_t index) {
unsigned int first_size = first.size();
if (index < first_size)
return first[index];
else return second[index - first_size];
}
inline const T& operator[] (size_t index) const {
unsigned int first_size = first.size();
if (index < first_size)
return first[index];
else return second[index - first_size];
}
inline unsigned int size() const {
return first.size() + second.size();
}
};
template<typename FirstArray, typename SecondArray>
inline concat_array_view<typename std::decay<decltype(std::declval<FirstArray>()[0])>::type, FirstArray, SecondArray>
make_concat_array_view(const FirstArray& first, const SecondArray& second) {
return concat_array_view<typename std::decay<decltype(std::declval<FirstArray>()[0])>::type, FirstArray, SecondArray>(first, second);
}
#endif /* ARRAY_VIEW_H_ */