Ocean
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 
17 namespace Ocean
18 {
19 
20 /**
21  * This class implements basic utility functions.
22  * @ingroup base
23  */
24 class 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  */
263 template <typename T>
264 inline 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  */
279 template <typename T>
280 inline 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  */
291 template <typename T>
292 inline 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  */
300 inline 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  */
308 inline 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  */
316 inline 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  */
324 inline 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  */
332 inline 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  */
340 inline 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  */
348 inline 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  */
356 inline 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  */
364 inline 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  */
372 inline 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  */
380 inline 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  */
388 inline 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  */
397 inline 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  */
406 inline 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  */
415 inline 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  */
424 inline 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  */
433 inline 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  */
442 inline 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  */
451 inline 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  */
460 inline 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  */
469 inline 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  */
478 inline 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  */
487 inline 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  */
496 inline 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  */
505 inline 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  */
514 inline 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  */
523 inline 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  */
532 inline 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  */
541 inline 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  */
550 inline 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  */
565 static 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  */
574 template <typename T>
575 static 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  */
583 template <typename T>
584 static 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  */
593 template <typename T>
594 static 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  */
604 template <typename T>
605 static 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  */
615 template <typename T>
616 [[nodiscard]] static inline std::vector<T> createIndices(const size_t numberIndices, const T& startIndex);
617 
618 template <typename T>
619 void 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 
629 template <typename T>
630 void 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 
651 template <typename T, typename TData>
652 void 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 
663 template <typename T, typename TData>
664 void 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 
688 template <typename T>
689 void 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 
699 template <typename T>
700 void 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 
721 template <typename T, typename TData>
722 void 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 
733 template <typename T, typename TData>
734 void 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 
758 template <typename T>
759 unsigned 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 
785 template <typename T>
786 unsigned 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 
812 template <typename T1, typename T2>
813 inline bool Utilities::sortPairFirst(const std::pair<T1, T2>& firstPair, const std::pair<T1, T2>& secondPair)
814 {
815  return firstPair.first < secondPair.first;
816 }
817 
818 template <typename T>
819 inline bool Utilities::sortPairFirst(const T& firstPair, const T& secondPair)
820 {
821  return firstPair.first < secondPair.first;
822 }
823 
824 template <typename T1, typename T2>
825 inline bool Utilities::sortPairSecond(const std::pair<T1, T2>& firstPair, const std::pair<T1, T2>& secondPair)
826 {
827  return firstPair.second < secondPair.second;
828 }
829 
830 template <typename T>
831 inline bool Utilities::sortPairSecond(const T& firstPair, const T& secondPair)
832 {
833  return firstPair.second < secondPair.second;
834 }
835 
836 template <typename T>
837 inline T Utilities::divideBy2(const T& value)
838 {
839  return value / T(2);
840 }
841 
842 template <>
843 inline float Utilities::divideBy2(const float& value)
844 {
845  return value * 0.5f;
846 }
847 
848 template <>
849 inline double Utilities::divideBy2(const double& value)
850 {
851  return value * 0.5;
852 }
853 
854 inline 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 
862 inline 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 
885 inline 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
902 template <typename T>
903 inline 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
914 template <typename T>
915 inline 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 
923 template <typename T>
924 inline 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 
947 template <>
948 inline unsigned char modulo(const unsigned char& value, const unsigned char& ring)
949 {
950  return value % ring;
951 }
952 
953 template <>
954 inline unsigned short modulo(const unsigned short& value, const unsigned short& ring)
955 {
956  return value % ring;
957 }
958 
959 template <>
960 inline unsigned int modulo(const unsigned int& value, const unsigned int& ring)
961 {
962  return value % ring;
963 }
964 
965 template <>
966 inline unsigned long long modulo(const unsigned long long& value, const unsigned long long& ring)
967 {
968  return value % ring;
969 }
970 
971 template <>
972 inline 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 
994 template <>
995 inline 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 
1017 template <typename T>
1018 inline 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 
1029 inline unsigned int sqr(const char value)
1030 {
1031  return value * value;
1032 }
1033 
1034 inline unsigned int sqr(const unsigned char value)
1035 {
1036  return value * value;
1037 }
1038 
1039 inline unsigned int sqr(const short value)
1040 {
1041  return value * value;
1042 }
1043 
1044 inline unsigned int sqr(const unsigned short value)
1045 {
1046  return value * value;
1047 }
1048 
1049 inline unsigned int sqr(const int value)
1050 {
1051  return value * value;
1052 }
1053 
1054 inline unsigned int sqr(const unsigned int value)
1055 {
1056  return value * value;
1057 }
1058 
1059 inline unsigned long sqr(const long value)
1060 {
1061  return value * value;
1062 }
1063 
1064 inline unsigned long sqr(const unsigned long value)
1065 {
1066  return value * value;
1067 }
1068 
1069 inline unsigned long long sqr(const long long value)
1070 {
1071  return value * value;
1072 }
1073 
1074 inline unsigned long long sqr(const unsigned long long value)
1075 {
1076  return value * value;
1077 }
1078 
1079 inline float sqr(const float value)
1080 {
1081  return value * value;
1082 }
1083 
1084 inline double sqr(const double value)
1085 {
1086  return value * value;
1087 }
1088 
1089 inline unsigned int sqrDistance(const char first, const char second)
1090 {
1091  const int distance = int(first) - int(second);
1092  return distance * distance;
1093 }
1094 
1095 inline 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 
1101 inline unsigned int sqrDistance(const short first, const short second)
1102 {
1103  const int distance = int(first) - int(second);
1104  return distance * distance;
1105 }
1106 
1107 inline 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 
1113 inline unsigned int sqrDistance(const int first, const int second)
1114 {
1115  const int distance = first - second;
1116  return distance * distance;
1117 }
1118 
1119 inline 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 
1128 inline 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 
1134 inline 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 
1143 inline float sqrDistance(const float first, const float second)
1144 {
1145  const float distance = first - second;
1146  return distance * distance;
1147 }
1148 
1149 inline double sqrDistance(const double first, const double second)
1150 {
1151  const double distance = first - second;
1152  return distance * distance;
1153 }
1154 
1155 inline unsigned char absDistance(const char first, const char second)
1156 {
1157  return (unsigned char)(::abs(int(first) - int(second)));
1158 }
1159 
1160 inline unsigned char absDistance(const unsigned char first, const unsigned char second)
1161 {
1162  return (unsigned char)(::abs(int(first - second)));
1163 }
1164 
1165 inline unsigned short absDistance(const short first, const short second)
1166 {
1167  return (unsigned short)(::abs(int(first) - int(second)));
1168 }
1169 
1170 inline unsigned short absDistance(const unsigned short first, const unsigned short second)
1171 {
1172  return (unsigned short)(::abs(int(first - second)));
1173 }
1174 
1175 inline unsigned int absDistance(const int first, const int second)
1176 {
1177  return (unsigned int)(::abs(first - second));
1178 }
1179 
1180 inline unsigned int absDistance(const unsigned int first, const unsigned int second)
1181 {
1182  return (unsigned int)(::abs(int(first - second)));
1183 }
1184 
1185 inline 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 
1196 inline 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 
1207 inline 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 
1221 template <typename T>
1222 inline 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 
1234 template <typename T>
1235 inline 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 
1248 template <typename T>
1249 inline 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 
1264 template <typename T>
1265 inline 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 
1280 template <typename T>
1281 inline 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 
1289 int 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 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 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 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
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
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
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
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
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