Ocean
Loading...
Searching...
No Matches
base/Utilities.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_UTILITIES_H
9#define META_OCEAN_BASE_UTILITIES_H
10
11#include "ocean/base/Base.h"
12
13#include <climits>
14#include <cmath>
15#include <limits>
16
17namespace Ocean
18{
19
20/**
21 * This class implements basic utility functions.
22 * @ingroup base
23 */
24class OCEAN_BASE_EXPORT Utilities
25{
26 public:
27
28 /**
29 * Separates a set of given values.
30 * @param values Set of values to be separated
31 * @param delimiter The delimiter separating the individual values
32 * @param removeQuotes State determining whether the beginning and ending quotes are removed for each value
33 * @param trim State determining whether prefix and postfix blanks are removed for each value
34 * @return Resulting separated values
35 */
36 static std::vector<std::string> separateValues(const std::string& values, const char delimiter = ',', const bool removeQuotes = true, const bool trim = true);
37
38 /**
39 * Sorts two values so that the lowest value will finally be the first value.
40 * The sorting is not stable.<br>
41 * @param value0 First value
42 * @param value1 Second value
43 * @tparam T Data type of the values to be sorted
44 */
45 template <typename T>
46 static void sortLowestToFront2(T& value0, T& value1);
47
48 /**
49 * Sorts three values so that the lowest value will finally be the first value.
50 * The sorting is not stable.<br>
51 * @param value0 First value
52 * @param value1 Second value
53 * @param value2 Third value
54 * @tparam T Data type of the values to be sorted
55 */
56 template <typename T>
57 static void sortLowestToFront3(T& value0, T& value1, T& value2);
58
59 /**
60 * Sorts two values so that the lowest value will finally be the first value.
61 * Each value has a connected data value that will be sorted accordingly.<br>
62 * The sorting is not stable.<br>
63 * @param value0 First value
64 * @param value1 Second value
65 * @param data0 First data value
66 * @param data1 Second data value
67 * @tparam T Data type of the values to be sorted
68 */
69 template <typename T, typename TData>
70 static void sortLowestToFront2(T& value0, T& value1, TData& data0, TData& data1);
71
72 /**
73 * Sorts three values so that the lowest value will finally be the first value.
74 * Each value has a connected data value that will be sorted accordingly.<br>
75 * The sorting is not stable.<br>
76 * @param value0 First value
77 * @param value1 Second value
78 * @param value2 Third value
79 * @param data0 First data value
80 * @param data1 Second data value
81 * @param data2 Third data value
82 * @tparam T Data type of the values to be sorted
83 */
84 template <typename T, typename TData>
85 static void sortLowestToFront3(T& value0, T& value1, T& value2, TData& data0, TData& data1, TData& data2);
86
87 /**
88 * Sorts two values so that the highest value will finally be the first value.
89 * The sorting is not stable.<br>
90 * @param value0 First value
91 * @param value1 Second value
92 * @tparam T Data type of the values to be sorted
93 */
94 template <typename T>
95 static void sortHighestToFront2(T& value0, T& value1);
96
97 /**
98 * Sorts three values so that the highest value will finally be the first value.
99 * The sorting is not stable.<br>
100 * @param value0 First value
101 * @param value1 Second value
102 * @param value2 Third value
103 * @tparam T Data type of the values to be sorted
104 */
105 template <typename T>
106 static void sortHighestToFront3(T& value0, T& value1, T& value2);
107
108 /**
109 * Sorts two values so that the highest value will finally be the first value.
110 * Each value has a connected payload data value that will be sorted accordingly.<br>
111 * The sorting is not stable.<br>
112 * @param value0 First value
113 * @param value1 Second value
114 * @param data0 First data value
115 * @param data1 Second data value
116 * @tparam T Data type of the values to be sorted
117 * @tparam TData Data type of the payload data value
118 */
119 template <typename T, typename TData>
120 static void sortHighestToFront2(T& value0, T& value1, TData& data0, TData& data1);
121
122 /**
123 * Sorts three values so that the highest value will finally be the first value.
124 * Each value has a connected payload data value that will be sorted accordingly.<br>
125 * The sorting is not stable.<br>
126 * @param value0 First value
127 * @param value1 Second value
128 * @param value2 Third value
129 * @param data0 First data value
130 * @param data1 Second data value
131 * @param data2 Third data value
132 * @tparam T Data type of the values to be sorted
133 * @tparam TData Data type of the payload data value
134 */
135 template <typename T, typename TData>
136 static void sortHighestToFront3(T& value0, T& value1, T& value2, TData& data0, TData& data1, TData& data2);
137
138 /**
139 * Returns the index of the lowest value, if two or more values have the lowest value the smallest index of the values will be returned.
140 * @param value0 The first value
141 * @param value1 The second value
142 * @param value2 The third value
143 * @return The resulting index with range [0, 2]
144 */
145 template <typename T>
146 static unsigned int lowestValue(const T& value0, const T& value1, const T& value2);
147
148 /**
149 * Returns the index of the highest value, if two or more values have the highest value the smallest index of the values will be returned.
150 * @param value0 The first value
151 * @param value1 The second value
152 * @param value2 The third value
153 * @return The resulting index with range [0, 2]
154 */
155 template <typename T>
156 static unsigned int highestValue(const T& value0, const T& value1, const T& value2);
157
158 /**
159 * Compares two pair objects and returns whether the first value of the first pair is lesser than the first value of the second pair.
160 * @param firstPair First pair object
161 * @param secondPair Second pair object
162 * @return True, if so
163 * @tparam T1 The data type of the first value of the pair objects
164 * @tparam T2 The data type of the second value of the pair objects
165 */
166 template <typename T1, typename T2>
167 static inline bool sortPairFirst(const std::pair<T1, T2>& firstPair, const std::pair<T1, T2>& secondPair);
168
169 /**
170 * Compares two pair objects and returns whether the first value of the first pair is lesser than the first value of the second pair.
171 * @param firstPair First pair object
172 * @param secondPair Second pair object
173 * @return True, if so
174 * @tparam T The data type of the std::pair object
175 */
176 template <typename T>
177 static inline bool sortPairFirst(const T& firstPair, const T& secondPair);
178
179 /**
180 * Compares two pair objects and returns whether the second value of the first pair is lesser than the second value of the second pair.
181 * @param firstPair First pair object
182 * @param secondPair Second pair object
183 * @return True, if so
184 * @tparam T1 The data type of the first value of the pair objects
185 * @tparam T2 The data type of the second value of the pair objects
186 */
187 template <typename T1, typename T2>
188 static inline bool sortPairSecond(const std::pair<T1, T2>& firstPair, const std::pair<T1, T2>& secondPair);
189
190 /**
191 * Compares two pair objects and returns whether the second value of the first pair is lesser than the second value of the second pair.
192 * @param firstPair First pair object
193 * @param secondPair Second pair object
194 * @return True, if so
195 * @tparam T The data type of the std::pair object
196 */
197 template <typename T>
198 static inline bool sortPairSecond(const T& firstPair, const T& secondPair);
199
200 /**
201 * This function divides a given value by two.
202 * Integer values are divided by two (bit shifting is no applied), floating point values are multiplied by 0.5.
203 * @param value The value to be divided
204 * @tparam T The data type of the value
205 * @return The resulting value
206 */
207 template <typename T>
208 static inline T divideBy2(const T& value);
209
210 /**
211 * This function applies a fast division by 255 for unsigned integer values.
212 * @param value The value that will be divided by 255, with range [0, 65534]
213 * @return Divided unsigned integer value
214 */
215 static inline unsigned char divideBy255(const unsigned int value);
216
217 /**
218 * Returns whether a given value is a power of two.
219 * Zero is not a power of two value.
220 * @param value The value to be checked, with range [0, infinity)
221 * @return True, if so
222 */
223 static inline bool isPowerOfTwo(const unsigned int value);
224
225 /**
226 * Returns the smallest power of two value that is equal or larger than a given value.
227 * @param value The value for that the smallest power of two value is determined, with range [0, 0x80000000]
228 * @return Smallest power of two value that is equal or larger
229 */
230 static inline unsigned int smallestPowerOfTwo(const unsigned int value);
231
232 /**
233 * Multiplies the specified 64 bit integers and stores the 128 bit integer result in resultHigh (64 most significant bits) and resultLow (64 least significant bits).
234 * @param left The left operand
235 * @param right The right operand
236 * @param resultHigh Receives the 64 most significant bits of the 128 bit result
237 * @param resultLow Receives the 64 least significant bits of the 128 bit result
238 */
239 static void multiply64(const uint64_t left, const uint64_t right, uint64_t& resultHigh, uint64_t& resultLow);
240
241 /**
242 * Compares the product specified by the first two factors with the product specified by the last two factors.
243 * @param leftFactor1 First factor of left operand
244 * @param leftFactor2 Second factor of left operand
245 * @param rightFactor1 First factor of right operand
246 * @param rightFactor2 Second factor of right operand
247 * @return 1 if the left product is greater than the right product, -1 if it is less and 0 if both are equal.
248 */
249 static inline int compareProducts(const uint64_t leftFactor1, const uint64_t leftFactor2, const uint64_t rightFactor1, const uint64_t rightFactor2);
250};
251
252/**
253 * This function fits a given parameter into a specified value range.
254 * If the given parameter is lesser the lower boundary, the lower boundary value is returned.
255 * If the given parameter is higher the upper boundary, the upper boundary value is returned.
256 * @param lowerBoundary Lower boundary value, with range (-infinity, upperBoundary]
257 * @param value The value to be fitted
258 * @param upperBoundary Upper boundary value, with range [lowerBoundary, infinity)
259 * @return Value fitting into the given range
260 * @tparam T Data type of the values
261 * @ingroup base
262 */
263template <typename T>
264inline T minmax(const T& lowerBoundary, const T& value, const T& upperBoundary);
265
266/**
267 * Returns the modulo value of a given parameter within a ring allowing positive and negative parameters.
268 * The function provides a modulo result for a ring size of 5 as below:<br>
269 * <pre>
270 * Original: -7 -6 | -5 -4 -3 -2 -1 | 0 1 2 3 4 | 5 6 7 9 ...
271 * Result: 3 4 | 0 1 2 3 4 | 0 1 2 3 4 | 0 1 2 3 ...
272 * </pre>
273 * @param value Parameter to return the module value for
274 * @param ring The ring size, must be positive with range [1, infinity)
275 * @return Resulting modulo value
276 * @tparam T Data type of the values
277 * @ingroup base
278 */
279template <typename T>
280inline T modulo(const T& value, const T& ring);
281
282/**
283 * Returns the distance between two values inside defined ring.
284 * @param value0 First value inside the ring, with range [0, ring)
285 * @param value1 Second value inside the ring, with range [0, ring)
286 * @param ring The ring size, must be positive
287 * @return Resulting distance
288 * @tparam T Data type of the values
289 * @ingroup base
290 */
291template <typename T>
292inline T ringDistance(const T& value0, const T& value1, const T& ring);
293
294/**
295 * Returns the square value of a given value.
296 * @param value The value to be squared
297 * @return Squared value
298 * @ingroup base
299 */
300inline unsigned int sqr(const char value);
301
302/**
303 * Returns the square value of a given value.
304 * @param value The value to be squared
305 * @return Squared value
306 * @ingroup base
307 */
308inline unsigned int sqr(const unsigned char value);
309
310/**
311 * Returns the square value of a given value.
312 * @param value The value to be squared
313 * @return Squared value
314 * @ingroup base
315 */
316inline unsigned int sqr(const short value);
317
318/**
319 * Returns the square value of a given value.
320 * @param value The value to be squared
321 * @return Squared value
322 * @ingroup base
323 */
324inline unsigned int sqr(const unsigned short value);
325
326/**
327 * Returns the square value of a given value.
328 * @param value The value to be squared
329 * @return Squared value
330 * @ingroup base
331 */
332inline unsigned int sqr(const int value);
333
334/**
335 * Returns the square value of a given value.
336 * @param value The value to be squared
337 * @return Squared value
338 * @ingroup base
339 */
340inline unsigned int sqr(const unsigned int value);
341
342/**
343 * Returns the square value of a given value.
344 * @param value The value to be squared
345 * @return Squared value
346 * @ingroup base
347 */
348inline unsigned long sqr(const long value);
349
350/**
351 * Returns the square value of a given value.
352 * @param value The value to be squared
353 * @return Squared value
354 * @ingroup base
355 */
356inline unsigned long sqr(const unsigned long value);
357
358/**
359 * Returns the square value of a given value.
360 * @param value The value to be squared
361 * @return Squared value
362 * @ingroup base
363 */
364inline unsigned long long sqr(const long long value);
365
366/**
367 * Returns the square value of a given value.
368 * @param value The value to be squared
369 * @return Squared value
370 * @ingroup base
371 */
372inline unsigned long long sqr(const unsigned long long value);
373
374/**
375 * Returns the square value of a given value.
376 * @param value The value to be squared
377 * @return Squared value
378 * @ingroup base
379 */
380inline float sqr(const float value);
381
382/**
383 * Returns the square value of a given value.
384 * @param value The value to be squared
385 * @return Squared value
386 * @ingroup base
387 */
388inline double sqr(const double value);
389
390/**
391 * Returns the square distance between two values.
392 * @param first The first value
393 * @param second The second value
394 * @return Square distance
395 * @ingroup base
396 */
397inline unsigned int sqrDistance(const char first, const char second);
398
399/**
400 * Returns the square distance between two values.
401 * @param first The first value
402 * @param second The second value
403 * @return Square distance
404 * @ingroup base
405 */
406inline unsigned int sqrDistance(const unsigned char first, const unsigned char second);
407
408/**
409 * Returns the square distance between two values.
410 * @param first The first value
411 * @param second The second value
412 * @return Square distance
413 * @ingroup base
414 */
415inline unsigned int sqrDistance(const short first, const short second);
416
417/**
418 * Returns the square distance between two values.
419 * @param first The first value
420 * @param second The second value
421 * @return Square distance
422 * @ingroup base
423 */
424inline unsigned int sqrDistance(const unsigned short first, const unsigned short second);
425
426/**
427 * Returns the square distance between two values.
428 * @param first The first value
429 * @param second The second value
430 * @return Square distance
431 * @ingroup base
432 */
433inline unsigned int sqrDistance(const int first, const int second);
434
435/**
436 * Returns the square distance between two values.
437 * @param first The first value
438 * @param second The second value
439 * @return Square distance
440 * @ingroup base
441 */
442inline unsigned int sqrDistance(const unsigned int first, const unsigned int second);
443
444/**
445 * Returns the square distance between two values.
446 * @param first The first value
447 * @param second The second value
448 * @return Square distance
449 * @ingroup base
450 */
451inline unsigned long long sqrDistance(const long long first, const long long second);
452
453/**
454 * Returns the square distance between two values.
455 * @param first The first value
456 * @param second The second value
457 * @return Square distance
458 * @ingroup base
459 */
460inline unsigned long long sqrDistance(const unsigned long long first, const unsigned long long second);
461
462/**
463 * Returns the square distance between two values.
464 * @param first The first value
465 * @param second The second value
466 * @return Square distance
467 * @ingroup base
468 */
469inline float sqrDistance(const float first, const float second);
470
471/**
472 * Returns the square distance between two values.
473 * @param first The first value
474 * @param second The second value
475 * @return Square distance
476 * @ingroup base
477 */
478inline double sqrDistance(const double first, const double second);
479
480/**
481 * Returns the absolute distance between two values.
482 * @param first The first value
483 * @param second The second value
484 * @return Square distance
485 * @ingroup base
486 */
487inline unsigned char absDistance(const char first, const char second);
488
489/**
490 * Returns the absolute distance between two values.
491 * @param first The first value
492 * @param second The second value
493 * @return Square distance
494 * @ingroup base
495 */
496inline unsigned char absDistance(const unsigned char first, const unsigned char second);
497
498/**
499 * Returns the absolute distance between two values.
500 * @param first The first value
501 * @param second The second value
502 * @return Square distance
503 * @ingroup base
504 */
505inline unsigned short absDistance(const short first, const short second);
506
507/**
508 * Returns the absolute distance between two values.
509 * @param first The first value
510 * @param second The second value
511 * @return Square distance
512 * @ingroup base
513 */
514inline unsigned short absDistance(const unsigned short first, const unsigned short second);
515
516/**
517 * Returns the absolute distance between two values.
518 * @param first The first value
519 * @param second The second value
520 * @return Square distance
521 * @ingroup base
522 */
523inline unsigned int absDistance(const int first, const int second);
524
525/**
526 * Returns the absolute distance between two values.
527 * @param first The first value
528 * @param second The second value
529 * @return Square distance
530 * @ingroup base
531 */
532inline unsigned int absDistance(const unsigned int first, const unsigned int second);
533
534/**
535 * Returns the absolute distance between two values.
536 * @param first The first value
537 * @param second The second value
538 * @return Square distance
539 * @ingroup base
540 */
541inline unsigned long long absDistance(const long long first, const long long second);
542
543/**
544 * Returns the absolute distance between two values.
545 * @param first The first value
546 * @param second The second value
547 * @return Square distance
548 * @ingroup base
549 */
550inline unsigned long long absDistance(const unsigned long long first, const unsigned long long second);
551
552/**
553 * Mirrors a given value if necessary.
554 * The values is mirrored according to a given size parameter.<br>
555 * The function provides a result as below:<br>
556 * <pre>
557 * Original: -3 -2 -1 | 0 1 2 3 4 5 6 ... s-2 s-1 | s s+1 s+2
558 * Result: 2 1 0 | 0 1 2 3 4 5 6 ... s-2 s-1 | s-1 s-2 s-3
559 * </pre>
560 * @param value The value to be mirrored, with range [-size, 2*size]
561 * @param size Specified size defining the upper mirror border, with range [1, 2147483647]
562 * @return Mirrored value
563 * @ingroup base
564 */
565static inline unsigned int mirrorValue(const int value, const unsigned int size);
566
567/**
568 * Determines the entire number of elements that are stored in a vector holding a vector of elements.
569 * @param vectors Set of given vector
570 * @return Resulting entire number of elements
571 * @tparam T Data type of the vector elements
572 * @ingroup base
573 */
574template <typename T>
575static inline size_t countElements(const std::vector<std::vector<T>>& vectors);
576
577/**
578 * Returns whether a vector holds a specified element.
579 * @param elements Vector to be checked
580 * @param element The element that has to be found
581 * @return True, if so
582 */
583template <typename T>
584static inline bool hasElement(const std::vector<T>& elements, const T& element);
585
586/**
587 * Concatenates a given set of vectors to one vector.
588 * @param vectors Set of given vectors
589 * @return Resulting unique vector
590 * @tparam T Data type of the vector elements
591 * @ingroup base
592 */
593template <typename T>
594static inline std::vector<T> concatenate(const std::vector<std::vector<T>>& vectors);
595
596/**
597 * Fills a vector with increasing index values.
598 * @param numberIndices Number of indices that will be created, with range [1, infinity)
599 * @param startIndex Start index value, successive indices will be incremented, with range [0, infinity)
600 * @param indices The vector receiving the indices
601 * @tparam T Data type of the index elements
602 * @ingroup base
603 */
604template <typename T>
605static inline void createIndices(const size_t numberIndices, const T& startIndex, std::vector<T>& indices);
606
607/**
608 * Returns a vector with increasing index values.
609 * @param numberIndices Number of indices that will be created, with range [1, infinity)
610 * @param startIndex Start index value, successive indices will be incremented, with range [0, infinity)
611 * @return The resulting index vector
612 * @tparam T Data type of the index elements
613 * @ingroup base
614 */
615template <typename T>
616[[nodiscard]] static inline std::vector<T> createIndices(const size_t numberIndices, const T& startIndex);
617
618template <typename T>
619void Utilities::sortLowestToFront2(T& value0, T& value1)
620{
621 if (!(value0 < value1))
622 {
623 std::swap(value0, value1);
624 }
625
626 ocean_assert(value0 <= value1);
627}
628
629template <typename T>
630void Utilities::sortLowestToFront3(T& value0, T& value1, T& value2)
631{
632 if (!(value0 < value1))
633 {
634 std::swap(value0, value1);
635 }
636
637 if (!(value0 < value2))
638 {
639 std::swap(value0, value2);
640 }
641
642 if (!(value1 < value2))
643 {
644 std::swap(value1, value2);
645 }
646
647 ocean_assert(value0 <= value1);
648 ocean_assert(value1 <= value2);
649}
650
651template <typename T, typename TData>
652void Utilities::sortLowestToFront2(T& value0, T& value1, TData& data0, TData& data1)
653{
654 if (!(value0 < value1))
655 {
656 std::swap(value0, value1);
657 std::swap(data0, data1);
658 }
659
660 ocean_assert(value0 <= value1);
661}
662
663template <typename T, typename TData>
664void Utilities::sortLowestToFront3(T& value0, T& value1, T& value2, TData& data0, TData& data1, TData& data2)
665{
666 if (!(value0 < value1))
667 {
668 std::swap(value0, value1);
669 std::swap(data0, data1);
670 }
671
672 if (!(value0 < value2))
673 {
674 std::swap(value0, value2);
675 std::swap(data0, data2);
676 }
677
678 if (!(value1 < value2))
679 {
680 std::swap(value1, value2);
681 std::swap(data1, data2);
682 }
683
684 ocean_assert(value0 <= value1);
685 ocean_assert(value1 <= value2);
686}
687
688template <typename T>
689void Utilities::sortHighestToFront2(T& value0, T& value1)
690{
691 if (value0 < value1)
692 {
693 std::swap(value0, value1);
694 }
695
696 ocean_assert(value0 >= value1);
697}
698
699template <typename T>
700void Utilities::sortHighestToFront3(T& value0, T& value1, T& value2)
701{
702 if (value0 < value1)
703 {
704 std::swap(value0, value1);
705 }
706
707 if (value0 < value2)
708 {
709 std::swap(value0, value2);
710 }
711
712 if (value1 < value2)
713 {
714 std::swap(value1, value2);
715 }
716
717 ocean_assert(value0 >= value1);
718 ocean_assert(value1 >= value2);
719}
720
721template <typename T, typename TData>
722void Utilities::sortHighestToFront2(T& value0, T& value1, TData& data0, TData& data1)
723{
724 if (value0 < value1)
725 {
726 std::swap(value0, value1);
727 std::swap(data0, data1);
728 }
729
730 ocean_assert(value0 >= value1);
731}
732
733template <typename T, typename TData>
734void Utilities::sortHighestToFront3(T& value0, T& value1, T& value2, TData& data0, TData& data1, TData& data2)
735{
736 if (value0 < value1)
737 {
738 std::swap(value0, value1);
739 std::swap(data0, data1);
740 }
741
742 if (value0 < value2)
743 {
744 std::swap(value0, value2);
745 std::swap(data0, data2);
746 }
747
748 if (value1 < value2)
749 {
750 std::swap(value1, value2);
751 std::swap(data1, data2);
752 }
753
754 ocean_assert(value0 >= value1);
755 ocean_assert(value1 >= value2);
756}
757
758template <typename T>
759unsigned int Utilities::lowestValue(const T& value0, const T& value1, const T& value2)
760{
761 if (value0 <= value1)
762 {
763 if (value0 <= value2)
764 {
765 return 0u;
766 }
767 else
768 {
769 return 2u;
770 }
771 }
772 else
773 {
774 if (value1 <= value2)
775 {
776 return 1u;
777 }
778 else
779 {
780 return 2u;
781 }
782 }
783}
784
785template <typename T>
786unsigned int Utilities::highestValue(const T& value0, const T& value1, const T& value2)
787{
788 if (value0 >= value1)
789 {
790 if (value0 >= value2)
791 {
792 return 0u;
793 }
794 else
795 {
796 return 2u;
797 }
798 }
799 else
800 {
801 if (value1 >= value2)
802 {
803 return 1u;
804 }
805 else
806 {
807 return 2u;
808 }
809 }
810}
811
812template <typename T1, typename T2>
813inline bool Utilities::sortPairFirst(const std::pair<T1, T2>& firstPair, const std::pair<T1, T2>& secondPair)
814{
815 return firstPair.first < secondPair.first;
816}
817
818template <typename T>
819inline bool Utilities::sortPairFirst(const T& firstPair, const T& secondPair)
820{
821 return firstPair.first < secondPair.first;
822}
823
824template <typename T1, typename T2>
825inline bool Utilities::sortPairSecond(const std::pair<T1, T2>& firstPair, const std::pair<T1, T2>& secondPair)
826{
827 return firstPair.second < secondPair.second;
828}
829
830template <typename T>
831inline bool Utilities::sortPairSecond(const T& firstPair, const T& secondPair)
832{
833 return firstPair.second < secondPair.second;
834}
835
836template <typename T>
837inline T Utilities::divideBy2(const T& value)
838{
839 return value / T(2);
840}
841
842template <>
843inline float Utilities::divideBy2(const float& value)
844{
845 return value * 0.5f;
846}
847
848template <>
849inline double Utilities::divideBy2(const double& value)
850{
851 return value * 0.5;
852}
853
854inline unsigned char Utilities::divideBy255(const unsigned int value)
855{
856 ocean_assert(value < 65535u);
857 ocean_assert(value / 255u == (value + 1u + (value >> 8u)) >> 8u);
858
859 return (unsigned char)((value + 1u + (value >> 8u)) >> 8u);
860}
861
862inline bool Utilities::isPowerOfTwo(const unsigned int value)
863{
864 // we determine/extract the least significant bit and check whether the value is still equal:
865 // value: 11010011000
866 // value-1: 11010010111
867 // ~(value-1): 00101101000
868 // value & ~(value-1): 00000001000
869
870 // return value != 0u && (value == (value & ~(value - 1u)));
871
872 // an even faster way is to check (for all values larger than zero):
873 // (value & (value - 1u)) == 0
874
875 ocean_assert((value == 1u || value == 2u || value == 4u || value == 8u || value == 16u || value == 32u || value == 64u
876 || value == 128u || value == 256u || value == 512u || value == 1024u || value == 2048u
877 || value == 4096u || value == 8192 || value == 16384u || value == 32768u || value == 65536u
878 || value == 131072 || value == 262144u || value == 524288u || value == 1048576u || value == 2097152u
879 || value == 4194304u || value == 8388608u || value == 16777216u || value == 33554432u || value == 67108864u
880 || value == 134217728u || value == 268435456u || value == 536870912u || value == 1073741824u || value == 2147483648u) == (value != 0u && (value & (value - 1u)) == 0u));
881
882 return value != 0u && (value & (value - 1u)) == 0u;
883}
884
885inline unsigned int Utilities::smallestPowerOfTwo(const unsigned int value)
886{
887 ocean_assert(value <= 0x80000000u);
888
889 unsigned int powerOfTwoValue = 0x80000000u;
890
891 while (powerOfTwoValue != 0u && (powerOfTwoValue >> 1) >= value)
892 {
893 powerOfTwoValue >>= 1u;
894 }
895
896 return powerOfTwoValue;
897}
898
899#ifdef __GNUC__
900
901// The GCC compiler provides faster code with this minmax determination
902template <typename T>
903inline T minmax(const T& lowerBoundary, const T& value, const T& upperBoundary)
904{
905 ocean_assert(lowerBoundary <= upperBoundary);
906
907 ocean_assert((value < lowerBoundary ? lowerBoundary : (value > upperBoundary ? upperBoundary : value)) == (max(lowerBoundary, min(value, upperBoundary))));
908 return value < lowerBoundary ? lowerBoundary : (value > upperBoundary ? upperBoundary : value);
909}
910
911#else
912
913// The Microsoft VC compiler provides faster code with this minmax determination
914template <typename T>
915inline T minmax(const T& lowerBoundary, const T& value, const T& upperBoundary)
916{
917 ocean_assert(lowerBoundary <= upperBoundary);
918 return max(lowerBoundary, min(upperBoundary, value));
919}
920
921#endif // __GNUC__
922
923template <typename T>
924inline T modulo(const T& value, const T& ring)
925{
926 ocean_assert(ring > 0);
927
928 if (value >= 0)
929 {
930 if (value < ring)
931 {
932 return value;
933 }
934
935 ocean_assert(value % ring < ring);
936 return value % ring;
937 }
938 else
939 {
940 const T result = (ring - 1) - (-(value + 1) % ring);
941 ocean_assert(result >= 0 && result < ring);
942
943 return result;
944 }
945}
946
947template <>
948inline unsigned char modulo(const unsigned char& value, const unsigned char& ring)
949{
950 return value % ring;
951}
952
953template <>
954inline unsigned short modulo(const unsigned short& value, const unsigned short& ring)
955{
956 return value % ring;
957}
958
959template <>
960inline unsigned int modulo(const unsigned int& value, const unsigned int& ring)
961{
962 return value % ring;
963}
964
965template <>
966inline unsigned long long modulo(const unsigned long long& value, const unsigned long long& ring)
967{
968 return value % ring;
969}
970
971template <>
972inline double modulo(const double& value, const double& ring)
973{
974 ocean_assert(ring > 0);
975
976 if (value >= 0)
977 {
978 if (value < ring)
979 {
980 return value;
981 }
982
983 return fmod(value, ring);
984 }
985 else
986 {
987 const double intermediate = ring - (fmod(-value, ring));
988 ocean_assert(intermediate >= 0.0 && intermediate <= ring);
989
990 return intermediate == ring ? 0.0 : intermediate;
991 }
992}
993
994template <>
995inline float modulo(const float& value, const float& ring)
996{
997 ocean_assert(ring > 0);
998
999 if (value >= 0)
1000 {
1001 if (value < ring)
1002 {
1003 return value;
1004 }
1005
1006 return fmod(value, ring);
1007 }
1008 else
1009 {
1010 const float intermediate = ring - (fmod(-value, ring));
1011 ocean_assert(intermediate >= 0.0f && intermediate <= ring);
1012
1013 return intermediate == ring ? 0.0f : intermediate;
1014 }
1015}
1016
1017template <typename T>
1018inline T ringDistance(const T& value0, const T& value1, const T& ring)
1019{
1020 ocean_assert(value0 >= 0 && value0 < ring);
1021 ocean_assert(value1 >= 0 && value1 < ring);
1022
1023 const T low = min(value0, value1);
1024 const T high = max(value0, value1);
1025
1026 return min(high - low, low + ring - high);
1027}
1028
1029inline unsigned int sqr(const char value)
1030{
1031 return value * value;
1032}
1033
1034inline unsigned int sqr(const unsigned char value)
1035{
1036 return value * value;
1037}
1038
1039inline unsigned int sqr(const short value)
1040{
1041 return value * value;
1042}
1043
1044inline unsigned int sqr(const unsigned short value)
1045{
1046 return value * value;
1047}
1048
1049inline unsigned int sqr(const int value)
1050{
1051 return value * value;
1052}
1053
1054inline unsigned int sqr(const unsigned int value)
1055{
1056 return value * value;
1057}
1058
1059inline unsigned long sqr(const long value)
1060{
1061 return value * value;
1062}
1063
1064inline unsigned long sqr(const unsigned long value)
1065{
1066 return value * value;
1067}
1068
1069inline unsigned long long sqr(const long long value)
1070{
1071 return value * value;
1072}
1073
1074inline unsigned long long sqr(const unsigned long long value)
1075{
1076 return value * value;
1077}
1078
1079inline float sqr(const float value)
1080{
1081 return value * value;
1082}
1083
1084inline double sqr(const double value)
1085{
1086 return value * value;
1087}
1088
1089inline unsigned int sqrDistance(const char first, const char second)
1090{
1091 const int distance = int(first) - int(second);
1092 return distance * distance;
1093}
1094
1095inline unsigned int sqrDistance(const unsigned char first, const unsigned char second)
1096{
1097 const int distance = int(first) - int(second);
1098 return distance * distance;
1099}
1100
1101inline unsigned int sqrDistance(const short first, const short second)
1102{
1103 const int distance = int(first) - int(second);
1104 return distance * distance;
1105}
1106
1107inline unsigned int sqrDistance(const unsigned short first, const unsigned short second)
1108{
1109 const int distance = int(first) - int(second);
1110 return distance * distance;
1111}
1112
1113inline unsigned int sqrDistance(const int first, const int second)
1114{
1115 const int distance = first - second;
1116 return distance * distance;
1117}
1118
1119inline unsigned int sqrDistance(const unsigned int first, const unsigned int second)
1120{
1121 ocean_assert(first <= (unsigned int)INT_MAX);
1122 ocean_assert(second <= (unsigned int)INT_MAX);
1123
1124 const int distance = int(first) - int(second);
1125 return distance * distance;
1126}
1127
1128inline unsigned long long sqrDistance(const long long first, const long long second)
1129{
1130 const long long distance = first - second;
1131 return distance * distance;
1132}
1133
1134inline unsigned long long sqrDistance(const unsigned long long first, const unsigned long long second)
1135{
1136 ocean_assert(first <= (unsigned long long)LLONG_MAX);
1137 ocean_assert(second <= (unsigned long long)LLONG_MAX);
1138
1139 const long long distance = (long long)first - (long long)second;
1140 return distance * distance;
1141}
1142
1143inline float sqrDistance(const float first, const float second)
1144{
1145 const float distance = first - second;
1146 return distance * distance;
1147}
1148
1149inline double sqrDistance(const double first, const double second)
1150{
1151 const double distance = first - second;
1152 return distance * distance;
1153}
1154
1155inline unsigned char absDistance(const char first, const char second)
1156{
1157 return (unsigned char)(::abs(int(first) - int(second)));
1158}
1159
1160inline unsigned char absDistance(const unsigned char first, const unsigned char second)
1161{
1162 return (unsigned char)(::abs(int(first - second)));
1163}
1164
1165inline unsigned short absDistance(const short first, const short second)
1166{
1167 return (unsigned short)(::abs(int(first) - int(second)));
1168}
1169
1170inline unsigned short absDistance(const unsigned short first, const unsigned short second)
1171{
1172 return (unsigned short)(::abs(int(first - second)));
1173}
1174
1175inline unsigned int absDistance(const int first, const int second)
1176{
1177 return (unsigned int)(::abs(first - second));
1178}
1179
1180inline unsigned int absDistance(const unsigned int first, const unsigned int second)
1181{
1182 return (unsigned int)(::abs(int(first - second)));
1183}
1184
1185inline unsigned long long absDistance(const long long first, const long long second)
1186{
1187#if defined(__clang__)
1188 return (first > second) ? (first - second) : (second - first);
1189#elif (defined(OCEAN_COMPILER_MSC) && OCEAN_MSC_VERSION <= 1500)
1190 return (first > second) ? (first - second) : (second - first);
1191#else
1192 return ::abs(first - second);
1193#endif
1194}
1195
1196inline unsigned long long absDistance(const unsigned long long first, const unsigned long long second)
1197{
1198#if defined(__clang__)
1199 return (first > second) ? (first - second) : (second - first);
1200#elif (defined(OCEAN_COMPILER_MSC) && OCEAN_MSC_VERSION <= 1500)
1201 return (first > second) ? (first - second) : (second - first);
1202#else
1203 return ::abs((long long)(first - second));
1204#endif
1205}
1206
1207inline unsigned int mirrorValue(const int value, const unsigned int size)
1208{
1209 ocean_assert(size != 0u);
1210 ocean_assert(size <= 2147483647);
1211 ocean_assert(value >= -int(size) && value <= int(size * 2));
1212
1213#ifdef OCEAN_DEBUG
1214 const int result = (value < 0) ? (-value - 1) : (value >= int(size) ? (int(size + size) - value - 1) : value);
1215 ocean_assert(result >= 0 && result < int(size));
1216#endif // OCEAN_DEBUG
1217
1218 return (value < 0) ? (-value - 1) : (value >= int(size) ? (int(size + size) - value - 1) : value);
1219}
1220
1221template <typename T>
1222inline size_t countElements(const std::vector<std::vector<T>>& vectors)
1223{
1224 size_t size = 0;
1225
1226 for (size_t n = 0; n < vectors.size(); ++n)
1227 {
1228 size += vectors[n].size();
1229 }
1230
1231 return size;
1232}
1233
1234template <typename T>
1235inline bool hasElement(const std::vector<T>& elements, const T& element)
1236{
1237 for (const T& value : elements)
1238 {
1239 if (value == element)
1240 {
1241 return true;
1242 }
1243 }
1244
1245 return false;
1246}
1247
1248template <typename T>
1249inline std::vector<T> concatenate(const std::vector<std::vector<T>>& vectors)
1250{
1251 const size_t size = countElements(vectors);
1252
1253 std::vector<T> result;
1254 result.reserve(size);
1255
1256 for (size_t n = 0; n < vectors.size(); ++n)
1257 {
1258 result.insert(result.end(), vectors[n].begin(), vectors[n].end());
1259 }
1260
1261 return result;
1262}
1263
1264template <typename T>
1265inline void createIndices(const size_t numberIndices, const T& startIndex, std::vector<T>& indices)
1266{
1267 ocean_assert(numberIndices > 0);
1268
1269 indices.reserve(numberIndices);
1270 indices.clear();
1271
1272 T index = startIndex;
1273
1274 for (size_t n = 0; n < numberIndices; ++n)
1275 {
1276 indices.emplace_back(index++);
1277 }
1278}
1279
1280template <typename T>
1281inline std::vector<T> createIndices(const size_t numberIndices, const T& startIndex)
1282{
1283 std::vector<T> result;
1284 createIndices(numberIndices, startIndex, result);
1285
1286 return result;
1287}
1288
1289int Utilities::compareProducts(const uint64_t leftFactor1, const uint64_t leftFactor2, const uint64_t rightFactor1, const uint64_t rightFactor2)
1290{
1291 uint64_t leftProductHigh, leftProductLow;
1292 multiply64(leftFactor1, leftFactor2, leftProductHigh, leftProductLow);
1293
1294 uint64_t rightProductHigh, rightProductLow;
1295 multiply64(rightFactor1, rightFactor2, rightProductHigh, rightProductLow);
1296
1297 return leftProductHigh == rightProductHigh ? (leftProductLow > rightProductLow) - (leftProductLow < rightProductLow) : (leftProductHigh > rightProductHigh) - (leftProductHigh < rightProductHigh);
1298}
1299
1300
1301}
1302
1303#endif // META_OCEAN_BASE_UTILITIES_H
This class implements basic utility functions.
Definition base/Utilities.h:25
static bool sortPairSecond(const std::pair< T1, T2 > &firstPair, const std::pair< T1, T2 > &secondPair)
Compares two pair objects and returns whether the second value of the first pair is lesser than the s...
Definition base/Utilities.h:825
static void sortLowestToFront2(T &value0, T &value1)
Sorts two values so that the lowest value will finally be the first value.
Definition base/Utilities.h:619
static unsigned int smallestPowerOfTwo(const unsigned int value)
Returns the smallest power of two value that is equal or larger than a given value.
Definition base/Utilities.h:885
static std::vector< std::string > separateValues(const std::string &values, const char delimiter=',', const bool removeQuotes=true, const bool trim=true)
Separates a set of given values.
static bool isPowerOfTwo(const unsigned int value)
Returns whether a given value is a power of two.
Definition base/Utilities.h:862
static unsigned int highestValue(const T &value0, const T &value1, const T &value2)
Returns the index of the highest value, if two or more values have the highest value the smallest ind...
Definition base/Utilities.h:786
static T divideBy2(const T &value)
This function divides a given value by two.
Definition base/Utilities.h:837
static int compareProducts(const uint64_t leftFactor1, const uint64_t leftFactor2, const uint64_t rightFactor1, const uint64_t rightFactor2)
Compares the product specified by the first two factors with the product specified by the last two fa...
Definition base/Utilities.h:1289
static unsigned char divideBy255(const unsigned int value)
This function applies a fast division by 255 for unsigned integer values.
Definition base/Utilities.h:854
static unsigned int lowestValue(const T &value0, const T &value1, const T &value2)
Returns the index of the lowest value, if two or more values have the lowest value the smallest index...
Definition base/Utilities.h:759
static void sortLowestToFront3(T &value0, T &value1, T &value2)
Sorts three values so that the lowest value will finally be the first value.
Definition base/Utilities.h:630
static void sortHighestToFront3(T &value0, T &value1, T &value2)
Sorts three values so that the highest value will finally be the first value.
Definition base/Utilities.h:700
static bool sortPairFirst(const std::pair< T1, T2 > &firstPair, const std::pair< T1, T2 > &secondPair)
Compares two pair objects and returns whether the first value of the first pair is lesser than the fi...
Definition base/Utilities.h:813
static void sortHighestToFront2(T &value0, T &value1)
Sorts two values so that the highest value will finally be the first value.
Definition base/Utilities.h:689
static void multiply64(const uint64_t left, const uint64_t right, uint64_t &resultHigh, uint64_t &resultLow)
Multiplies the specified 64 bit integers and stores the 128 bit integer result in resultHigh (64 most...
T minmax(const T &lowerBoundary, const T &value, const T &upperBoundary)
This function fits a given parameter into a specified value range.
Definition base/Utilities.h:903
unsigned int sqrDistance(const char first, const char second)
Returns the square distance between two values.
Definition base/Utilities.h:1089
static std::vector< T > concatenate(const std::vector< std::vector< T > > &vectors)
Concatenates a given set of vectors to one vector.
Definition base/Utilities.h:1249
unsigned char absDistance(const char first, const char second)
Returns the absolute distance between two values.
Definition base/Utilities.h:1155
static void createIndices(const size_t numberIndices, const T &startIndex, std::vector< T > &indices)
Fills a vector with increasing index values.
Definition base/Utilities.h:1265
T modulo(const T &value, const T &ring)
Returns the modulo value of a given parameter within a ring allowing positive and negative parameters...
Definition base/Utilities.h:924
static size_t countElements(const std::vector< std::vector< T > > &vectors)
Determines the entire number of elements that are stored in a vector holding a vector of elements.
Definition base/Utilities.h:1222
T ringDistance(const T &value0, const T &value1, const T &ring)
Returns the distance between two values inside defined ring.
Definition base/Utilities.h:1018
unsigned int sqr(const char value)
Returns the square value of a given value.
Definition base/Utilities.h:1029
static unsigned int mirrorValue(const int value, const unsigned int size)
Mirrors a given value if necessary.
Definition base/Utilities.h:1207
The namespace covering the entire Ocean framework.
Definition Accessor.h:15
static bool hasElement(const std::vector< T > &elements, const T &element)
Returns whether a vector holds a specified element.
Definition base/Utilities.h:1235