Ocean
Loading...
Searching...
No Matches
Subset.h
Go to the documentation of this file.
1/*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8#ifndef META_OCEAN_BASE_SUBSET_H
9#define META_OCEAN_BASE_SUBSET_H
10
11#include "ocean/base/Base.h"
12
13namespace Ocean
14{
15
16/**
17 * This class implements subset functions.
18 * @ingroup base
19 */
20class Subset
21{
22 private:
23
24 /**
25 * This helper class implements a subset functions.
26 * @tparam TIndex Data type of the index elements
27 */
28 template <typename TIndex>
30 {
31 public:
32
33 /**
34 * Extracts a subset of a given set of objects by usage of an index vector holding the indices of all objects to be used.
35 * If the index data type is an uint8_t, than the (boolean != 0u) statement is used to use the corresponding object or not.<br>
36 * Beware: No range check is done! Thus, each index must not exceed the number of given objects.<br>
37 * @param objects Entire set of objects from that a subset will be extracted
38 * @param indices Indices defining the subset to be extracted
39 * @return Resulting subset of the given objects
40 * @tparam T Data type of the objects
41 */
42 template <typename T>
43 static inline std::vector<T> subset(const std::vector<T>& objects, const std::vector<TIndex>& indices);
44
45 /**
46 * Extracts a subset of a given set of objects by usage of a set of indices of all objects to be used.
47 * Beware: No range check is done! Thus, each index must not exceed the number of given objects.<br>
48 * @param objects Entire set of objects from that a subset will be extracted
49 * @param indices Indices defining the subset to be extracted
50 * @return Resulting subset of the given objects
51 * @tparam T Data type of the objects
52 */
53 template <typename T>
54 static inline std::vector<T> subset(const std::vector<T>& objects, const std::set<TIndex>& indices);
55
56 /**
57 * Extracts a subset of a given set of objects by usage of a set of indices of all objects to be not used.
58 * Beware: No range check is done! Thus, each index must not exceed the number of given objects.<br>
59 * @param objects Entire set of objects from that a subset will be extracted
60 * @param indices Indices defining the inverted subset to be extracted
61 * @return Resulting subset of the given objects
62 * @tparam T Data type of the objects
63 */
64 template <typename T>
65 static inline std::vector<T> invertedSubset(const std::vector<T>& objects, const std::unordered_set<TIndex>& indices);
66
67 /**
68 * Extracts a subset of a given set of objects by usage of a set of indices of all objects to be not used.
69 * Beware: No range check is done! Thus, each index must not exceed the number of given objects.<br>
70 * @param objects Entire set of objects from that a subset will be extracted
71 * @param indices Indices defining the inverted subset to be extracted
72 * @return Resulting subset of the given objects
73 * @tparam T Data type of the objects
74 */
75 template <typename T>
76 static inline std::vector<T> invertedSubset(const std::vector<T>& objects, const std::set<TIndex>& indices);
77
78 /**
79 * Extracts a subset of a given set of objects by usage of a set of indices of all objects to be used.
80 * If the index data type is an uint8_t, than the (boolean != 0u) statement is used to use the corresponding object or not.<br>
81 * Beware: No range check is done! Thus, each index must not exceed the number of given objects.<br>
82 * @param objects Entire set of objects from that a subset will be extracted
83 * @param numberObjects Number of given objects
84 * @param indices Indices defining the subset to be extracted
85 * @param numberIndices Number of given indices
86 * @return Resulting subset of the given objects
87 * @tparam T Data type of the objects
88 */
89 template <typename T>
90 static inline std::vector<T> subset(const T* objects, const size_t numberObjects, const TIndex* indices, const size_t numberIndices);
91
92 /**
93 * Extracts a subset of a given set of objects by usage of a set of indices of all objects to be used.
94 * If the index data type is an uint8_t, than the (boolean != 0u) statement is used to use the corresponding object or not.<br>
95 * Beware: No range check is done! Thus, each index must not exceed the number of given objects.<br>
96 * @param objects Entire set of objects from that a subset will be extracted
97 * @param numberObjects Number of given objects
98 * @param indices Indices defining the subset to be extracted
99 * @return Resulting subset of the given objects
100 * @tparam T Data type of the objects
101 */
102 template <typename T>
103 static inline std::vector<T> subset(const T* objects, const size_t numberObjects, const std::vector<TIndex>& indices);
104
105 /**
106 * Extracts a subset of a given set of objects by usage of a set of indices of all objects to be used.
107 * Beware: No range check is done! Thus, each index must not exceed the number of given objects.<br>
108 * @param objects Entire set of objects from that a subset will be extracted
109 * @param numberObjects Number of given objects
110 * @param indices Indices defining the subset to be extracted
111 * @return Resulting subset of the given objects
112 * @tparam T Data type of the objects
113 */
114 template <typename T>
115 static inline std::vector<T> subset(const T* objects, const size_t numberObjects, const std::set<TIndex>& indices);
116
117 /**
118 * Extracts a subset of a given set of objects by usage of a set of indices of all objects to be not used.
119 * Beware: No range check is done! Thus, each index must not exceed the number of given objects.<br>
120 * @param objects Entire set of objects from that a subset will be extracted
121 * @param numberObjects Number of given objects
122 * @param indices Indices defining the inverted subset to be extracted
123 * @return Resulting subset of the given objects
124 * @tparam T Data type of the objects
125 */
126 template <typename T>
127 static inline std::vector<T> invertedSubset(const T* objects, const size_t numberObjects, const std::unordered_set<TIndex>& indices);
128
129 /**
130 * Extracts a subset of a given set of objects by usage of a set of indices of all objects to be not used.
131 * Beware: No range check is done! Thus, each index must not exceed the number of given objects.<br>
132 * @param objects Entire set of objects from that a subset will be extracted
133 * @param numberObjects Number of given objects
134 * @param indices Indices defining the inverted subset to be extracted
135 * @return Resulting subset of the given objects
136 * @tparam T Data type of the objects
137 */
138 template <typename T>
139 static inline std::vector<T> invertedSubset(const T* objects, const size_t numberObjects, const std::set<TIndex>& indices);
140
141 /**
142 * Converts object indices to an uint8_t vector holding statements for each object.
143 * @param indices Indices defining the subset of the objects, with range [0, numberObjects)
144 * @param numberObjects Number of objects that can be addressed by the indices
145 * @return Resulting (boolean != 0u) statements
146 * @tparam TContainer The container to be used, e.g., std::vector, std::set, std::unordred_set
147 * @tparam tValue Value for objects that are defined in the indices, the inverse value is applied otherwise
148 */
149 template <typename TContainer, uint8_t tValue>
150 static inline std::vector<uint8_t> indices2statements(const TContainer& indices, const size_t numberObjects);
151
152 /**
153 * Converts object indices to an uint8_t vector holding statements for each object.
154 * @param indices Indices defining the subset of the objects, with range [0, numberObjects)
155 * @param numberIndices Number of provided indices
156 * @param numberObjects Number of objects that can be addressed by the indices
157 * @return Resulting boolean statements
158 * @tparam tValue Value for objects that are defined in the indices, the inverse value is applied otherwise
159 */
160 template <uint8_t tValue>
161 static inline std::vector<uint8_t> indices2statements(const TIndex* indices, const size_t numberIndices, const size_t numberObjects);
162
163 /**
164 * Converts an uint8_t vector holding statements for each object into object indices.
165 * @param statements Boolean statement for each object
166 * @return Resulting object indices
167 * @tparam tValue Value for objects that will be defined in the indices
168 */
169 template <uint8_t tValue>
170 static inline std::vector<TIndex> statements2indices(const std::vector<uint8_t>& statements);
171
172 /**
173 * Converts an uint8_t vector holding statements for each object into object indices.
174 * @param statements Boolean statement for each object
175 * @param numberStatements Number of statements
176 * @return Resulting object indices
177 * @tparam tValue Value for objects that will be defined in the indices
178 */
179 template <uint8_t tValue>
180 static inline std::vector<TIndex> statements2indices(const uint8_t* statements, const size_t numberStatements);
181 };
182
183 public:
184
185 /**
186 * Extracts a subset of a given set of objects by usage of an index vector holding the indices of all objects to be used.
187 * If the index data type is an uint8_t, than the (boolean != 0u) statement is used to use the corresponding object or not.<br>
188 * Beware: No range check is done! Thus, each index must not exceed the number of given objects.<br>
189 * @param objects Entire set of objects from that a subset will be extracted
190 * @param indices Indices defining the subset to be extracted
191 * @return Resulting subset of the given objects
192 * @tparam TIndex Data type of the index elements
193 * @tparam T Data type of the objects
194 */
195 template <typename TIndex, typename T>
196 static inline std::vector<T> subset(const std::vector<T>& objects, const std::vector<TIndex>& indices);
197
198 /**
199 * Extracts a subset of a given set of objects by usage of a set of indices of all objects to be used.
200 * Beware: No range check is done! Thus, each index must not exceed the number of given objects.<br>
201 * @param objects Entire set of objects from that a subset will be extracted
202 * @param indices Indices defining the subset to be extracted
203 * @return Resulting subset of the given objects
204 * @tparam TIndex Data type of the index elements
205 * @tparam T Data type of the objects
206 */
207 template <typename TIndex, typename T>
208 static inline std::vector<T> subset(const std::vector<T>& objects, const std::set<TIndex>& indices);
209
210 /**
211 * Extracts a subset of a given set of objects by usage of a set of indices of all objects to be not used.
212 * Beware: No range check is done! Thus, each index must not exceed the number of given objects.<br>
213 * @param objects Entire set of objects from that a subset will be extracted
214 * @param indices Indices defining the inverted subset to be extracted
215 * @return Resulting subset of the given objects
216 * @tparam TIndex Data type of the index elements
217 * @tparam T Data type of the objects
218 */
219 template <typename TIndex, typename T>
220 static inline std::vector<T> invertedSubset(const std::vector<T>& objects, const std::unordered_set<TIndex>& indices);
221
222 /**
223 * Extracts a subset of a given set of objects by usage of a set of indices of all objects to be not used.
224 * Beware: No range check is done! Thus, each index must not exceed the number of given objects.<br>
225 * @param objects Entire set of objects from that a subset will be extracted
226 * @param indices Indices defining the inverted subset to be extracted
227 * @return Resulting subset of the given objects
228 * @tparam TIndex Data type of the index elements
229 * @tparam T Data type of the objects
230 */
231 template <typename TIndex, typename T>
232 static inline std::vector<T> invertedSubset(const std::vector<T>& objects, const std::set<TIndex>& indices);
233
234 /**
235 * Extracts a subset of a given set of objects by usage of a set of indices of all objects to be used.
236 * If the index data type is an uint8_t, than the (boolean != 0u) statement is used to use the corresponding object or not.<br>
237 * Beware: No range check is done! Thus, each index must not exceed the number of given objects.<br>
238 * @param objects Entire set of objects from that a subset will be extracted
239 * @param numberObjects Number of given objects
240 * @param indices Indices defining the subset to be extracted
241 * @param numberIndices Number of given indices
242 * @return Resulting subset of the given objects
243 * @tparam TIndex Data type of the index elements
244 * @tparam T Data type of the objects
245 */
246 template <typename TIndex, typename T>
247 static inline std::vector<T> subset(const T* objects, const size_t numberObjects, const TIndex* indices, const size_t numberIndices);
248
249 /**
250 * Extracts a subset of a given set of objects by usage of a set of indices of all objects to be used.
251 * If the index data type is an uint8_t, than the (boolean != 0u) statement is used to use the corresponding object or not.<br>
252 * Beware: No range check is done! Thus, each index must not exceed the number of given objects.<br>
253 * @param objects Entire set of objects from that a subset will be extracted
254 * @param numberObjects Number of given objects
255 * @param indices Indices defining the subset to be extracted
256 * @return Resulting subset of the given objects
257 * @tparam TIndex Data type of the index elements
258 * @tparam T Data type of the objects
259 */
260 template <typename TIndex, typename T>
261 static inline std::vector<T> subset(const T* objects, const size_t numberObjects, const std::vector<TIndex>& indices);
262
263 /**
264 * Extracts a subset of a given set of objects by usage of a set of indices of all objects to be used.
265 * Beware: No range check is done! Thus, each index must not exceed the number of given objects.<br>
266 * @param objects Entire set of objects from that a subset will be extracted
267 * @param numberObjects Number of given objects
268 * @param indices Indices defining the subset to be extracted
269 * @return Resulting subset of the given objects
270 * @tparam TIndex Data type of the index elements
271 * @tparam T Data type of the objects
272 */
273 template <typename TIndex, typename T>
274 static inline std::vector<T> subset(const T* objects, const size_t numberObjects, const std::set<TIndex>& indices);
275
276 /**
277 * Extracts the indices that are not given within a set indices.
278 * @param indices The set of given indices, the resulting indices will not contain any of these indices, can contain indices with range [0, maximalIndex]
279 * @param numberElements The number of possible elements defining the entire range of possible indices: [0, numberElements)
280 * @tparam TIndex Data type of the index elements
281 */
282 template <typename TIndex>
283 static std::vector<TIndex> invertedIndices(const std::vector<TIndex>& indices, const size_t numberElements);
284
285 /**
286 * Extracts the indices that are not given within a set indices.
287 * @param indices The set of given indices, the resulting indices will not contain any of these indices, can contain indices with range [0, maximalIndex]
288 * @param numberElements The number of possible elements defining the entire range of possible indices: [0, numberElements)
289 * @tparam TIndex Data type of the index elements
290 */
291 template <typename TIndex>
292 static std::unordered_set<TIndex> invertedIndices(const std::unordered_set<TIndex>& indices, const size_t numberElements);
293
294 /**
295 * Extracts the indices that are not given within a set indices.
296 * @param indices The set of given indices, the resulting indices will not contain any of these indices, can contain indices with range [0, maximalIndex]
297 * @param numberElements The number of possible elements defining the entire range of possible indices: [0, numberElements)
298 * @tparam TIndex Data type of the index elements
299 */
300 template <typename TIndex>
301 static std::set<TIndex> invertedIndices(const std::set<TIndex>& indices, const size_t numberElements);
302
303 /**
304 * Extracts a subset of a given set of objects by usage of a set of indices of all objects to be not used.
305 * Beware: No range check is done! Thus, each index must not exceed the number of given objects.<br>
306 * @param objects Entire set of objects from that a subset will be extracted
307 * @param numberObjects Number of given objects
308 * @param indices Indices defining the inverted subset to be extracted
309 * @return Resulting subset of the given objects
310 * @tparam TIndex Data type of the index elements
311 * @tparam T Data type of the objects
312 */
313 template <typename TIndex, typename T>
314 static inline std::vector<T> invertedSubset(const T* objects, const size_t numberObjects, const std::unordered_set<TIndex>& indices);
315
316 /**
317 * Extracts a subset of a given set of objects by usage of a set of indices of all objects to be not used.
318 * Beware: No range check is done! Thus, each index must not exceed the number of given objects.<br>
319 * @param objects Entire set of objects from that a subset will be extracted
320 * @param numberObjects Number of given objects
321 * @param indices Indices defining the inverted subset to be extracted
322 * @return Resulting subset of the given objects
323 * @tparam TIndex Data type of the index elements
324 * @tparam T Data type of the objects
325 */
326 template <typename TIndex, typename T>
327 static inline std::vector<T> invertedSubset(const T* objects, const size_t numberObjects, const std::set<TIndex>& indices);
328
329 /**
330 * Converts object indices to an uint8_t vector holding statements for each object.
331 * @param indices Indices defining the subset of the objects, with range [0, numberObjects)
332 * @param numberObjects Number of objects that can be addressed by the indices
333 * @return Resulting boolean statements
334 * @tparam TIndex Data type of the index elements
335 * @tparam tValue Value for objects that are defined in the indices, the inverse value is applied otherwise
336 */
337 template <typename TIndex, uint8_t tValue>
338 static inline std::vector<uint8_t> indices2statements(const std::vector<TIndex>& indices, const size_t numberObjects);
339
340 /**
341 * Converts object indices to an uint8_t vector holding statements for each object.
342 * @param indices Indices defining the subset of the objects, with range [0, numberObjects)
343 * @param numberObjects Number of objects that can be addressed by the indices
344 * @return Resulting boolean statements
345 * @tparam TIndex Data type of the index elements
346 * @tparam tValue Value for objects that are defined in the indices, the inverse value is applied otherwise
347 */
348 template <typename TIndex, uint8_t tValue>
349 static inline std::vector<uint8_t> indices2statements(const std::set<TIndex>& indices, const size_t numberObjects);
350
351 /**
352 * Converts object indices to an uint8_t vector holding statements for each object.
353 * @param indices Indices defining the subset of the objects, with range [0, numberObjects)
354 * @param numberObjects Number of objects that can be addressed by the indices
355 * @return Resulting boolean statements
356 * @tparam TIndex Data type of the index elements
357 * @tparam tValue Value for objects that are defined in the indices, the inverse value is applied otherwise
358 */
359 template <typename TIndex, uint8_t tValue>
360 static inline std::vector<uint8_t> indices2statements(const std::unordered_set<TIndex>& indices, const size_t numberObjects);
361
362 /**
363 * Converts object indices to an uint8_t vector holding statements for each object.
364 * @param indices Indices defining the subset of the objects, with range [0, numberObjects)
365 * @param numberIndices Number of provided indices
366 * @param numberObjects Number of objects that can be addressed by the indices
367 * @return Resulting boolean statements
368 * @tparam TIndex Data type of the index elements
369 * @tparam tValue Value for objects that are defined in the indices, the inverse value is applied otherwise
370 */
371 template <typename TIndex, uint8_t tValue>
372 static inline std::vector<uint8_t> indices2statements(const TIndex* indices, const size_t numberIndices, const size_t numberObjects);
373
374 /**
375 * Converts an uint8_t vector holding statements for each object into object indices.
376 * @param statements Boolean statement for each object
377 * @return Resulting object indices
378 * @tparam TIndex Data type of the index elements
379 * @tparam tValue Value for objects that will be defined in the indices
380 */
381 template <typename TIndex, uint8_t tValue>
382 static inline std::vector<TIndex> statements2indices(const std::vector<uint8_t>& statements);
383
384 /**
385 * Converts an uint8_t vector holding statements for each object into object indices.
386 * @param statements Boolean statement for each object
387 * @param numberStatements Number of statements
388 * @return Resulting object indices
389 * @tparam TIndex Data type of the index elements
390 * @tparam tValue Value for objects that will be defined in the indices
391 */
392 template <typename TIndex, uint8_t tValue>
393 static inline std::vector<TIndex> statements2indices(const uint8_t* statements, const size_t numberStatements);
394
395 /**
396 * Determines corresponding element pairs from two sets of element maps.
397 * Two elements correspond with each other if they have the same key.
398 * @param elementMapA The first map of elements
399 * @param elementMapB The second map of elements
400 * @param elementsA The resulting elements from the first map which have a corresponding element in the second map
401 * @param elementsB The resulting elements from the second map which have a corresponding element in the first map
402 * @tparam TKey The data type of each key
403 * @tparam TElement The data type of each element
404 */
405 template <typename TKey, typename TElement>
406 static void correspondingElements(const std::map<TKey, TElement>& elementMapA, const std::map<TKey, TElement>& elementMapB, std::vector<TElement>& elementsA, std::vector<TElement>& elementsB);
407
408 /**
409 * Determines whether two (ordered) sets have at least one intersecting element.
410 * Both input sets must be in ascending order.
411 * @param firstA The iterator to the first element in the first set
412 * @param endA The iterator to the (exclusive) element after the last element in the first set
413 * @param firstB The iterator to the first element in the second set
414 * @param endB The iterator to the (exclusive) element after the last element in the second set
415 * @return True, if so
416 */
417 template <typename TIterator>
418 static bool hasIntersectingElement(const TIterator& firstA, const TIterator& endA, const TIterator& firstB, const TIterator& endB);
419
420 /**
421 * Determines whether two (ordered) sets have at least one intersecting element.
422 * @param setA The first set to check, can be empty
423 * @param setB The second set to check, can be empty
424 * @return True, if so
425 */
426 template <typename T>
427 static inline bool hasIntersectingElement(const std::set<T>& setA, const std::set<T>& setB);
428
429 /**
430 * Determines whether two ordered vectors have at least one intersecting element.
431 * @param sortedA The first vector to check, can be empty
432 * @param sortedB The second vector to check, can be empty
433 * @return True, if so
434 */
435 template <typename T>
436 static inline bool hasIntersectingElement(const std::vector<T>& sortedA, const std::vector<T>& sortedB);
437};
438
439template <typename TIndex>
440template <typename T>
441inline std::vector<T> Subset::InternalSubset<TIndex>::subset(const std::vector<T>& objects, const std::vector<TIndex>& indices)
442{
443 std::vector<T> result;
444 result.reserve(indices.size());
445
446 for (const TIndex& index : indices)
447 {
448 ocean_assert(size_t(index) < objects.size());
449 result.push_back(objects[size_t(index)]);
450 }
451
452 return result;
453}
454
455template <>
456template <typename T>
457inline std::vector<T> Subset::InternalSubset<uint8_t>::subset(const std::vector<T>& objects, const std::vector<uint8_t>& indices)
458{
459 std::vector<T> result;
460 result.reserve(indices.size());
461
462 typename std::vector<T>::const_iterator iObject = objects.begin();
463
464 for (const uint8_t index : indices)
465 {
466 if (index != 0u)
467 {
468 result.push_back(*iObject);
469 }
470
471 ++iObject;
472 }
473
474 return result;
475}
476
477template <typename TIndex>
478template <typename T>
479inline std::vector<T> Subset::InternalSubset<TIndex>::subset(const std::vector<T>& objects, const std::set<TIndex>& indices)
480{
481 std::vector<T> result;
482 result.reserve(indices.size());
483
484 for (typename std::set<TIndex>::const_iterator i = indices.begin(); i != indices.end(); ++i)
485 {
486 ocean_assert(*i < objects.size());
487 result.push_back(objects[size_t(*i)]);
488 }
489
490 return result;
491}
492
493template <typename TIndex>
494template <typename T>
495inline std::vector<T> Subset::InternalSubset<TIndex>::invertedSubset(const std::vector<T>& objects, const std::unordered_set<TIndex>& indices)
496{
497 ocean_assert(objects.size() >= indices.size());
498 ocean_assert((unsigned long long)(objects.size()) < (unsigned long long)(std::numeric_limits<TIndex>::max()));
499
500 if (objects.size() == indices.size())
501 {
502#ifdef OCEAN_DEBUG
503 for (const TIndex& index : indices)
504 {
505 ocean_assert(index < objects.size());
506 }
507#endif
508
509 return std::vector<T>();
510 }
511
512 std::vector<T> result;
513 result.reserve(objects.size() - indices.size());
514
515 for (size_t n = 0u; n < objects.size(); ++n)
516 {
517 if (indices.find(TIndex(n)) == indices.cend())
518 {
519 result.push_back(objects[n]);
520 }
521 }
522
523 return result;
524}
525
526template <typename TIndex>
527template <typename T>
528inline std::vector<T> Subset::InternalSubset<TIndex>::invertedSubset(const std::vector<T>& objects, const std::set<TIndex>& indices)
529{
530 ocean_assert(objects.size() >= indices.size());
531 ocean_assert((unsigned long long)(objects.size()) < (unsigned long long)(std::numeric_limits<TIndex>::max()));
532
533 if (objects.size() == indices.size())
534 {
535#ifdef OCEAN_DEBUG
536 for (const TIndex& index : indices)
537 {
538 ocean_assert(index < objects.size());
539 }
540#endif
541
542 return std::vector<T>();
543 }
544
545 std::vector<T> result;
546 result.reserve(objects.size() - indices.size());
547
548 for (size_t n = 0u; n < objects.size(); ++n)
549 {
550 if (indices.find(TIndex(n)) == indices.cend())
551 {
552 result.push_back(objects[n]);
553 }
554 }
555
556 return result;
557}
558
559template <typename TIndex>
560template <typename T>
561inline std::vector<T> Subset::InternalSubset<TIndex>::subset(const T* objects, const size_t numberObjects, const TIndex* indices, const size_t numberIndices)
562{
563 std::vector<T> result;
564 result.reserve(numberIndices);
565
566 for (size_t n = 0; n < numberIndices; ++n)
567 {
568 ocean_assert_and_suppress_unused(indices[n] < numberObjects, numberObjects);
569
570 result.push_back(objects[indices[n]]);
571 }
572
573 return result;
574}
575
576template <>
577template <typename T>
578inline std::vector<T> Subset::InternalSubset<uint8_t>::subset(const T* objects, const size_t numberObjects, const uint8_t* indices, const size_t numberIndices)
579{
580 ocean_assert_and_suppress_unused(numberIndices <= numberObjects, numberObjects);
581
582 std::vector<T> result;
583 result.reserve(numberIndices);
584
585 for (size_t n = 0; n < numberIndices; ++n)
586 {
587 if (indices[n] != 0u)
588 {
589 result.push_back(objects[n]);
590 }
591 }
592
593 return result;
594}
595
596template <typename TIndex>
597template <typename T>
598inline std::vector<T> Subset::InternalSubset<TIndex>::subset(const T* objects, const size_t numberObjects, const std::vector<TIndex>& indices)
599{
600 return subset(objects, numberObjects, indices.data(), indices.size());
601}
602
603template <typename TIndex>
604template <typename T>
605inline std::vector<T> Subset::InternalSubset<TIndex>::subset(const T* objects, const size_t numberObjects, const std::set<TIndex>& indices)
606{
607 std::vector<T> result;
608 result.reserve(indices.size());
609
610 for (const TIndex& index : indices)
611 {
612 ocean_assert_and_suppress_unused(index < numberObjects, numberObjects);
613
614 result.push_back(objects[index]);
615 }
616
617 return result;
618}
619
620template <typename TIndex>
621template <typename T>
622inline std::vector<T> Subset::InternalSubset<TIndex>::invertedSubset(const T* objects, const size_t numberObjects, const std::unordered_set<TIndex>& indices)
623{
624 ocean_assert(numberObjects >= indices.size());
625 ocean_assert((unsigned long long)(numberObjects) < (unsigned long long)(std::numeric_limits<TIndex>::max()));
626
627 if (numberObjects == indices.size())
628 {
629#ifdef OCEAN_DEBUG
630 for (const TIndex& index : indices)
631 {
632 ocean_assert(indices < numberObjects);
633 }
634#endif
635
636 return std::vector<T>();
637 }
638
639 std::vector<T> result;
640 result.reserve(numberObjects - indices.size());
641
642 for (size_t n = 0; n < numberObjects; ++n)
643 {
644 if (indices.find(TIndex(n)) == indices.cend())
645 {
646 result.push_back(objects[n]);
647 }
648 }
649
650 return result;
651}
652
653template <typename TIndex>
654template <typename T>
655inline std::vector<T> Subset::InternalSubset<TIndex>::invertedSubset(const T* objects, const size_t numberObjects, const std::set<TIndex>& indices)
656{
657 ocean_assert(numberObjects >= indices.size());
658 ocean_assert((unsigned long long)(numberObjects) < (unsigned long long)(std::numeric_limits<TIndex>::max()));
659
660 if (numberObjects == indices.size())
661 {
662#ifdef OCEAN_DEBUG
663 for (const TIndex& index : indices)
664 {
665 ocean_assert(index < numberObjects);
666 }
667#endif
668
669 return std::vector<T>();
670 }
671
672 std::vector<T> result;
673 result.reserve(numberObjects - indices.size());
674
675 for (size_t n = 0; n < numberObjects; ++n)
676 {
677 if (indices.find(TIndex(n)) == indices.cend())
678 {
679 result.push_back(objects[n]);
680 }
681 }
682
683 return result;
684}
685
686template <typename TIndex>
687template <typename TContainer, uint8_t tValue>
688inline std::vector<uint8_t> Subset::InternalSubset<TIndex>::indices2statements(const TContainer& indices, const size_t numberObjects)
689{
690 std::vector<uint8_t> result(numberObjects, !tValue);
691
692 for (const TIndex& index : indices)
693 {
694 ocean_assert(index < result.size());
695 result[index] = tValue;
696 }
697
698 return result;
699}
700
701template <typename TIndex>
702template <uint8_t tValue>
703inline std::vector<uint8_t> Subset::InternalSubset<TIndex>::indices2statements(const TIndex* indices, const size_t numberIndices, const size_t numberObjects)
704{
705 std::vector<uint8_t> result(numberObjects, !tValue);
706
707 for (size_t n = 0; n < numberIndices; ++n)
708 {
709 ocean_assert(indices[n] < result.size());
710 result[indices[n]] = tValue;
711 }
712
713 return result;
714}
715
716template <typename TIndex>
717template <uint8_t tValue>
718inline std::vector<TIndex> Subset::InternalSubset<TIndex>::statements2indices(const std::vector<uint8_t>& statements)
719{
720 std::vector<TIndex> result;
721
722 for (size_t n = 0; n < statements.size(); ++n)
723 {
724 if (statements[n] == tValue)
725 {
726 result.push_back(TIndex(n));
727 }
728 }
729
730 return result;
731}
732
733template <typename TIndex>
734template <uint8_t tValue>
735inline std::vector<TIndex> Subset::InternalSubset<TIndex>::statements2indices(const uint8_t* statements, const size_t numberStatements)
736{
737 std::vector<TIndex> result;
738
739 for (size_t n = 0; n < numberStatements; ++n)
740 {
741 if (statements[n] == tValue)
742 {
743 result.push_back(TIndex(n));
744 }
745 }
746
747 return result;
748}
749
750template <typename TIndex, typename T>
751inline std::vector<T> Subset::subset(const std::vector<T>& objects, const std::vector<TIndex>& indices)
752{
753 return InternalSubset<TIndex>::template subset<T>(objects, indices);
754}
755
756template <typename TIndex, typename T>
757inline std::vector<T> Subset::subset(const std::vector<T>& objects, const std::set<TIndex>& indices)
758{
759 return InternalSubset<TIndex>::template subset<T>(objects, indices);
760}
761
762template <typename TIndex>
763std::vector<TIndex> Subset::invertedIndices(const std::vector<TIndex>& indices, const size_t numberElements)
764{
765 ocean_assert(indices.size() <= TIndex(numberElements));
766
767 if (indices.size() == numberElements)
768 {
769#ifdef OCEAN_DEBUG
770 const std::unordered_set<TIndex> indexSet(indices.begin(), indices.end());
771 ocean_assert(indexSet.size() == indices.size());
772
773 for (size_t n = 0; n < numberElements; ++n)
774 {
775 ocean_assert(indexSet.find(TIndex(n)) != indexSet.cend());
776 }
777#endif
778
779 return std::vector<TIndex>();
780 }
781
782 const std::unordered_set<TIndex> indexSet(indices.begin(), indices.end());
783 ocean_assert(indexSet.size() == indices.size());
784
785 std::vector<TIndex> result;
786 result.reserve(numberElements - indices.size());
787
788 for (TIndex i = TIndex(0); i < TIndex(numberElements); ++i)
789 {
790 if (indexSet.find(i) == indexSet.cend())
791 {
792 result.push_back(i);
793 }
794 }
795
796 return result;
797}
798
799template <typename TIndex>
800std::unordered_set<TIndex> Subset::invertedIndices(const std::unordered_set<TIndex>& indices, const size_t numberElements)
801{
802 ocean_assert(indices.size() <= TIndex(numberElements));
803
804 if (indices.size() == numberElements)
805 {
806#ifdef OCEAN_DEBUG
807 for (size_t n = 0; n < numberElements; ++n)
808 {
809 ocean_assert(indices.find(TIndex(n)) != indices.end());
810 }
811#endif
812
813 return std::unordered_set<TIndex>();
814 }
815
816 std::unordered_set<TIndex> result;
817 result.reserve(numberElements - indices.size());
818
819 for (TIndex i = TIndex(0); i < TIndex(numberElements); ++i)
820 {
821 if (indices.find(i) == indices.cend())
822 {
823 result.emplace(i);
824 }
825 }
826
827 return result;
828}
829
830template <typename TIndex>
831std::set<TIndex> Subset::invertedIndices(const std::set<TIndex>& indices, const size_t numberElements)
832{
833 ocean_assert(indices.size() <= TIndex(numberElements));
834
835 if (indices.size() == numberElements)
836 {
837#ifdef OCEAN_DEBUG
838 for (size_t n = 0; n < numberElements; ++n)
839 {
840 ocean_assert(indices.find(TIndex(n)) != indices.end());
841 }
842#endif
843
844 return std::set<TIndex>();
845 }
846
847 std::set<TIndex> result;
848
849 for (TIndex i = TIndex(0); i < TIndex(numberElements); ++i)
850 {
851 if (indices.find(i) == indices.cend())
852 {
853 result.insert(i);
854 }
855 }
856
857 return result;
858}
859
860template <typename TIndex, typename T>
861inline std::vector<T> Subset::invertedSubset(const std::vector<T>& objects, const std::unordered_set<TIndex>& indices)
862{
863 return InternalSubset<TIndex>::template invertedSubset<T>(objects, indices);
864}
865
866template <typename TIndex, typename T>
867inline std::vector<T> Subset::invertedSubset(const std::vector<T>& objects, const std::set<TIndex>& indices)
868{
869 return InternalSubset<TIndex>::template invertedSubset<T>(objects, indices);
870}
871
872template <typename TIndex, typename T>
873inline std::vector<T> Subset::subset(const T* objects, const size_t numberObjects, const TIndex* indices, const size_t numberIndices)
874{
875 return InternalSubset<TIndex>::template subset<T>(objects, numberObjects, indices, numberIndices);
876}
877
878template <typename TIndex, typename T>
879inline std::vector<T> Subset::subset(const T* objects, const size_t numberObjects, const std::vector<TIndex>& indices)
880{
881 return InternalSubset<TIndex>::template subset<T>(objects, numberObjects, indices);
882}
883
884template <typename TIndex, typename T>
885inline std::vector<T> Subset::subset(const T* objects, const size_t numberObjects, const std::set<TIndex>& indices)
886{
887 return InternalSubset<TIndex>::template subset<T>(objects, numberObjects, indices);
888}
889
890template <typename TIndex, typename T>
891inline std::vector<T> Subset::invertedSubset(const T* objects, const size_t numberObjects, const std::unordered_set<TIndex>& indices)
892{
893 return InternalSubset<TIndex>::template invertedSubset<T>(objects, numberObjects, indices);
894}
895
896template <typename TIndex, typename T>
897inline std::vector<T> Subset::invertedSubset(const T* objects, const size_t numberObjects, const std::set<TIndex>& indices)
898{
899 return InternalSubset<TIndex>::template invertedSubset<T>(objects, numberObjects, indices);
900}
901
902template <typename TIndex, uint8_t tValue>
903inline std::vector<uint8_t> Subset::indices2statements(const std::vector<TIndex>& indices, const size_t numberObjects)
904{
905 return InternalSubset<TIndex>::template indices2statements<std::vector<TIndex>, tValue>(indices, numberObjects);
906}
907
908template <typename TIndex, uint8_t tValue>
909inline std::vector<uint8_t> Subset::indices2statements(const std::unordered_set<TIndex>& indices, const size_t numberObjects)
910{
911 return InternalSubset<TIndex>::template indices2statements<std::unordered_set<TIndex>, tValue>(indices, numberObjects);
912}
913
914template <typename TIndex, uint8_t tValue>
915inline std::vector<uint8_t> Subset::indices2statements(const std::set<TIndex>& indices, const size_t numberObjects)
916{
917 return InternalSubset<TIndex>::template indices2statements<std::set<TIndex>, tValue>(indices, numberObjects);
918}
919
920template <typename TIndex, uint8_t tValue>
921inline std::vector<uint8_t> Subset::indices2statements(const TIndex* indices, const size_t numberIndices, const size_t numberObjects)
922{
923 return InternalSubset<TIndex>::template indices2statements<tValue>(indices, numberIndices, numberObjects);
924}
925
926template <typename TIndex, uint8_t tValue>
927inline std::vector<TIndex> Subset::statements2indices(const std::vector<uint8_t>& statements)
928{
929 return InternalSubset<TIndex>::template statements2indices<tValue>(statements);
930}
931
932template <typename TIndex, uint8_t tValue>
933inline std::vector<TIndex> Subset::statements2indices(const uint8_t* statements, const size_t numberStatements)
934{
935 return InternalSubset<TIndex>::template statements2indices<tValue>(statements, numberStatements);
936}
937
938template <typename TKey, typename TElement>
939void Subset::correspondingElements(const std::map<TKey, TElement>& elementMapA, const std::map<TKey, TElement>& elementMapB, std::vector<TElement>& elementsA, std::vector<TElement>& elementsB)
940{
941 elementsA.clear();
942 elementsB.clear();
943
944 // we expect that the map entries are sorted based on their keys
945 ocean_assert(elementMapA.size() < 2 || elementMapA.cbegin()->first < elementMapA.crbegin()->first);
946 ocean_assert(elementMapB.size() < 2 || elementMapB.cbegin()->first < elementMapB.crbegin()->first);
947
948 typename std::map<TKey, TElement>::const_iterator iA = elementMapA.cbegin();
949 typename std::map<TKey, TElement>::const_iterator iB = elementMapB.cbegin();
950
951 while (iA != elementMapA.cend() && iB != elementMapB.cend())
952 {
953 // let's find elements with identical keys
954
955 if (iA->first > iB->first)
956 {
957 ++iB;
958 }
959 else if (iA->first < iB->first)
960 {
961 ++iA;
962 }
963 else
964 {
965 ocean_assert(iA->first == iB->first);
966
967 elementsA.emplace_back(iA->second);
968 elementsB.emplace_back(iB->second);
969
970 ++iA;
971 ++iB;
972 }
973 }
974}
975
976template <typename TIterator>
977bool Subset::hasIntersectingElement(const TIterator& firstA, const TIterator& endA, const TIterator& firstB, const TIterator& endB)
978{
979 if (firstA == endA || firstB == endB)
980 {
981 return false;
982 }
983
984#ifdef OCEAN_DEBUG
985 TIterator debugLeftA = firstA;
986 TIterator debugRightA = firstA;
987 ++debugRightA;
988
989 TIterator debugLeftB = firstB;
990 TIterator debugRightB = firstB;
991 ++debugRightB;
992
993 while (debugRightA != endA && debugRightB != endB)
994 {
995 ocean_assert(*debugLeftA++ <= *debugRightA++);
996 ocean_assert(*debugLeftB++ <= *debugRightB++);
997 }
998#endif
999
1000 TIterator lastA = endA;
1001 TIterator lastB = endB;
1002
1003 if (*(--lastA) < *firstB || *(--lastB) < *firstA)
1004 {
1005 return false;
1006 }
1007
1008 TIterator iA = firstA;
1009 TIterator iB = firstB;
1010
1011 while (iA != endA && iB != endB)
1012 {
1013 if (*iA == *iB)
1014 {
1015 return true;
1016 }
1017
1018 if (*iA < *iB)
1019 {
1020 ++iA;
1021 }
1022 else
1023 {
1024 ocean_assert(*iA > *iB);
1025 ++iB;
1026 }
1027 }
1028
1029 return false;
1030}
1031
1032template <typename T>
1033bool Subset::hasIntersectingElement(const std::set<T>& setA, const std::set<T>& setB)
1034{
1035 return hasIntersectingElement(setA.cbegin(), setA.cend(), setB.cbegin(), setB.cend());
1036}
1037
1038template <typename T>
1039bool Subset::hasIntersectingElement(const std::vector<T>& sortedA, const std::vector<T>& sortedB)
1040{
1041 return hasIntersectingElement(sortedA.cbegin(), sortedA.cend(), sortedB.cbegin(), sortedB.cend());
1042}
1043
1044}
1045
1046#endif // META_OCEAN_BASE_SUBSET_H
This helper class implements a subset functions.
Definition Subset.h:30
static std::vector< T > invertedSubset(const std::vector< T > &objects, const std::unordered_set< TIndex > &indices)
Extracts a subset of a given set of objects by usage of a set of indices of all objects to be not use...
Definition Subset.h:495
static std::vector< uint8_t > indices2statements(const TContainer &indices, const size_t numberObjects)
Converts object indices to an uint8_t vector holding statements for each object.
Definition Subset.h:688
static std::vector< TIndex > statements2indices(const std::vector< uint8_t > &statements)
Converts an uint8_t vector holding statements for each object into object indices.
Definition Subset.h:718
static std::vector< T > subset(const std::vector< T > &objects, const std::vector< TIndex > &indices)
Extracts a subset of a given set of objects by usage of an index vector holding the indices of all ob...
Definition Subset.h:441
This class implements subset functions.
Definition Subset.h:21
static std::vector< uint8_t > indices2statements(const std::vector< TIndex > &indices, const size_t numberObjects)
Converts object indices to an uint8_t vector holding statements for each object.
Definition Subset.h:903
static bool hasIntersectingElement(const TIterator &firstA, const TIterator &endA, const TIterator &firstB, const TIterator &endB)
Determines whether two (ordered) sets have at least one intersecting element.
Definition Subset.h:977
static std::vector< T > subset(const std::vector< T > &objects, const std::vector< TIndex > &indices)
Extracts a subset of a given set of objects by usage of an index vector holding the indices of all ob...
Definition Subset.h:751
static std::vector< TIndex > invertedIndices(const std::vector< TIndex > &indices, const size_t numberElements)
Extracts the indices that are not given within a set indices.
Definition Subset.h:763
static void correspondingElements(const std::map< TKey, TElement > &elementMapA, const std::map< TKey, TElement > &elementMapB, std::vector< TElement > &elementsA, std::vector< TElement > &elementsB)
Determines corresponding element pairs from two sets of element maps.
Definition Subset.h:939
static std::vector< TIndex > statements2indices(const std::vector< uint8_t > &statements)
Converts an uint8_t vector holding statements for each object into object indices.
Definition Subset.h:927
static std::vector< T > invertedSubset(const std::vector< T > &objects, const std::unordered_set< TIndex > &indices)
Extracts a subset of a given set of objects by usage of a set of indices of all objects to be not use...
Definition Subset.h:861
The namespace covering the entire Ocean framework.
Definition Accessor.h:15