Ocean
Base.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_BASE_H
9 #define META_OCEAN_BASE_BASE_H
10 
11 #include <algorithm>
12 #include <array>
13 #include <cassert>
14 #include <cstdint>
15 #include <cstdlib>
16 #include <cstring>
17 #include <map>
18 #include <memory>
19 #include <set>
20 #include <string>
21 #include <unordered_map>
22 #include <unordered_set>
23 #include <vector>
24 
25 #ifdef __APPLE__
26  #include <TargetConditionals.h>
27 #endif
28 
29 namespace Ocean
30 {
31 
32 /**
33  * @defgroup base Ocean Base Library
34  * @{
35  * The Ocean Base Library provides all base functionalities needed in the Ocean framework.
36  * The library is platform independent.
37  *
38  * The DateTime, Timestamp and HighPerformanceTimer classes provide date and time functionalities.<br>
39  *
40  * The Thread, Lock, Signal, Thread, ThreadPool, Worker and WorkerPool classes provide threading, mutex, signal and critical section functionalities.<br>
41  *
42  * Callback and Caller realize callback functions and the Scheduler can be applied to implement regular timer events.<br>
43  *
44  * The StaticBuffer, StaticVector, ShiftVector, KdTree, HashSet, HasMap, RingMap and Triple classes provide possibilities to store and access data elements within individual structures.<br>
45  *
46  * The RandomI and RandomGenerator classes provide capabilities to create random numbers.<br>
47  *
48  * The ObjectRef and SmartObjectRef classes encapsulate individual objects by object references with reference counters.<br>
49  *
50  * Use the Frame class to store arbitrary 2D (image) information.<br>
51  *
52  * Singletons can be realized by application of the Singleton class.<br>
53  *
54  * Several helper classes exist providing template-based solutions to e.g., create data types with specific size or to create data types larger than a specific data type.
55  * Some of this classes are: DataType, SquareValueTyper, DifferenceValueTyper, NextLargerTyper, UnsignedTyper, TypeNamer.
56  * @}
57  */
58 
59 /**
60  * @namespace Ocean The namespace covering the entire Ocean framework.<p>
61  * Ocean is the base namespace for the Ocean framework.<br>
62  * The Namespace Ocean is used in the Base and Math library directly.
63  */
64 
65 // Do not use windows min-max functionality
66 #ifndef NOMINMAX
67  #define NOMINMAX
68 #endif
69 
70 /**
71  * Using min from std.
72  */
73 using std::min;
74 
75 /**
76  * Using max from std.
77  */
78 using std::max;
79 
80 /**
81  * Definition of a 32 bit index value.
82  * @ingroup base
83  */
84 typedef uint32_t Index32;
85 
86 /**
87  * Definition of a 64 bit index value.
88  * @ingroup base
89  */
90 typedef uint64_t Index64;
91 
92 /**
93  * Definition of a vector holding 32 bit index values.
94  * @ingroup base
95  */
96 typedef std::vector<Index32> Indices32;
97 
98 /**
99  * Definition of a vector holding 32 bit indices, so we have groups of indices.
100  * @ingroup base
101  */
102 typedef std::vector<Indices32> IndexGroups32;
103 
104 /**
105  * Definition of a vector holding 64 bit index values.
106  * @ingroup base
107  */
108 typedef std::vector<Index64> Indices64;
109 
110 /**
111  * Definition of a set holding 32 bit indices.
112  * @ingroup base
113  */
114 typedef std::set<Index32> IndexSet32;
115 
116 /**
117  * Definition of a set holding 64 bit indices.
118  * @ingroup base
119  */
120 typedef std::set<Index64> IndexSet64;
121 
122 /**
123  * Definition of an unordered_set holding 32 bit indices.
124  * @ingroup base
125  */
126 typedef std::unordered_set<Index32> UnorderedIndexSet32;
127 
128 /**
129  * Definition of an unordered_set holding 64 bit indices.
130  * @ingroup base
131  */
132 typedef std::unordered_set<Index64> UnorderedIndexSet64;
133 
134 /**
135  * Definition of a pair holding 32 bit indices.
136  * @ingroup base
137  */
138 typedef std::pair<Index32, Index32> IndexPair32;
139 
140 /**
141  * Definition of a vector holding 32 bit index pairs.
142  * @ingroup base
143  */
144 typedef std::vector<IndexPair32> IndexPairs32;
145 
146 /**
147  * Definition of a pair holding 64 bit indices.
148  * @ingroup base
149  */
150 typedef std::pair<Index64, Index64> IndexPair64;
151 
152 /**
153  * Definition of a vector holding 64 bit index pairs.
154  * @ingroup base
155  */
156 typedef std::vector<IndexPair64> IndexPairs64;
157 
158 /**
159  * Definition of a vector holding strings.
160  * @ingroup base
161  */
162 typedef std::vector<std::string> Strings;
163 
164 /**
165  * Definition of a vector holding strings.
166  * @ingroup base
167  */
168 typedef std::vector<std::wstring> WStrings;
169 
170 
171 
172 // Define OCEAN_DEACTIVATED_MESSENGER to disable the messenger capabilities in the entire framework.
173 // Disabling the messenger in the release build also ensures that message strings will not be part of the release binaries.
174 // ENABLE_LOGGING should be enabled in local, rc, and master (but not in profile) builds
175 // PROFILE should be enabled in profile builds
176 // Thus, we use Ocean's messenger in local, profile, rc and master - but not in production
177 // OCEAN_ACTIVATE_MESSENGER can be defined to explicitly avoid deactivating Ocean's messenger
178 #if (!defined(ENABLE_LOGGING) || ENABLE_LOGGING != 1) && (!defined(OCEAN_ACTIVATE_MESSENGER) || OCEAN_ACTIVATE_MESSENGER != 1) && (!defined(PROFILE) || PROFILE != 1)
179  #ifndef OCEAN_DEACTIVATED_MESSENGER
180  #define OCEAN_DEACTIVATED_MESSENGER
181  #endif
182 #else
183  // #define OCEAN_DEACTIVATED_MESSENGER
184 #endif
185 
186 
187 
188 
189 // we ensure that OCEAN_DEBUG is also defined as long as DEBUG is defined or _DEBUG is defined
190 // but do not define OCEAN_DEBUG in fuzzing mode.
191 #if !defined(OCEAN_DEBUG) && (defined(DEBUG) || defined(_DEBUG))
192  #define OCEAN_DEBUG
193 #endif
194 
195 
196 
197 
198 // Define OCEAN_INTENSIVE_DEBUG to activate code blocks intensively checking the correctness/accuracy of some specific function which is disabled by default.
199 #ifdef OCEAN_DEBUG
200  #ifndef OCEAN_INTENSIVE_DEBUG
201  //#define OCEAN_INTENSIVE_DEBUG
202  #endif
203 #endif
204 
205 
206 
207 
208 // we ensure that _ANDROID is also defined as long as __ANDROID__ is defined
209 #if defined(__ANDROID__) && !defined(_ANDROID)
210  #define _ANDROID
211 #endif
212 
213 
214 
215 
216 // Defines OCEAN_RUNTIME_STATIC for static runtimes
217 #ifndef OCEAN_RUNTIME_SHARED
218  #ifndef OCEAN_RUNTIME_STATIC
219  #define OCEAN_RUNTIME_STATIC
220  #endif
221 #endif
222 
223 
224 
225 
226 // Defines OCEAN_HARDWARE_REDUCED_PERFORMANCE to allow the usage of specific code for hardware with reduced computational power.
227 #if defined(_ANDROID) || (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE == 1)
228  #ifndef OCEAN_HARDWARE_REDUCED_PERFORMANCE
229  #define OCEAN_HARDWARE_REDUCED_PERFORMANCE
230  #endif
231 #else
232  //#define OCEAN_HARDWARE_REDUCED_PERFORMANCE
233 #endif
234 
235 
236 
237 
238 
239 // Defines OCEAN_HARDWARE_NEON_VERSION for platforms supporting NEON instructions
240 #ifndef OCEAN_HARDWARE_NEON_VERSION
241  #if defined(__ARM_NEON__) || defined(__ARM_NEON)
242  #define OCEAN_HARDWARE_NEON_VERSION 10
243  #endif
244 #endif
245 
246 #ifndef OCEAN_HARDWARE_NEON_VERSION
247  #define OCEAN_HARDWARE_NEON_VERSION 0
248 #endif
249 
250 
251 
252 
253 // Defines OCEAN_GCC_VERSION according to the given GCC version
254 #ifdef __GNUC__
255  #define OCEAN_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100)
256 #else
257  #define OCEAN_GCC_VERSION 0
258 #endif
259 
260 // Defines OCEAN_CLANG_VERSION according to the given Clang version
261 #ifdef __clang__
262  #define OCEAN_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100)
263 #else
264  #define OCEAN_CLANG_VERSION 0
265 #endif
266 
267 // Defines OCEAN_MSC_VERSION according to the given _MSC_VER version
268 // Beware: _MSC_VER may be defined although the Microsoft compiler is not applied e.g., when using clang for Windows platforms.
269 #ifdef _MSC_VER
270  #define OCEAN_MSC_VERSION (_MSC_VER)
271 #else
272  #define OCEAN_MSC_VERSION 0
273 #endif
274 
275 
276 
277 
278 /**
279  * Ocean supports the following compilers:
280  * GCC, Clang, Microsoft
281  * As macros like `_MSC_VER` can be defined by the Clang compiler (when compiling for Windows platforms),
282  * Ocean defines an own macro `OCEAN_COMPILER_***` to identify the individual compiler.
283  * The macro is defined as follows:
284  * <pre>
285  * Active compiler macro: __GNUC__: __clang__: _MSC_VER:
286  * OCEAN_COMPILER_CLANG do not care defined do not care
287  * OCEAN_COMPILER_GCC defined undefined undefined
288  * OCEAN_COMPILER_MSC undefined undefined defined
289  * </pre>
290  * @ingroup base
291  */
292 
293 // Defines OCEAN_COMPILER_CLANG if the clang compiler is used
294 #if defined(OCEAN_CLANG_VERSION) && OCEAN_CLANG_VERSION > 0
295  /// \cond DOXYGEN_DO_NOT_DOCUMENT
296  #define OCEAN_COMPILER_CLANG 1
297  /// \endcond
298 
299  #if defined(OCEAN_COMPILER_GCC) || defined(OCEAN_COMPILER_MSC)
300  #error Invalid compiler configuration.
301  #endif
302 #endif
303 
304 // Defines OCEAN_COMPILER_GCC if the gcc compiler is used
305 #if defined(OCEAN_GCC_VERSION) && OCEAN_GCC_VERSION > 0
306 
307  #if !defined(OCEAN_CLANG_VERSION) || OCEAN_CLANG_VERSION == 0
308  /// \cond DOXYGEN_DO_NOT_DOCUMENT
309  #define OCEAN_COMPILER_GCC 1
310  /// \endcond
311 
312  #if defined(OCEAN_COMPILER_CLANG) || defined(OCEAN_COMPILER_MSC)
313  #error Invalid compiler configuration.
314  #endif
315  #endif
316 
317  #if defined(OCEAN_MSC_VERSION) && OCEAN_MSC_VERSION > 0
318  #error The GCC compiler is used already, either the usage of gcc or msc is wrong.
319  #endif
320 #endif
321 
322 // Defines OCEAN_COMPILER_MSC if the Microsoft compiler is used
323 #if defined(OCEAN_MSC_VERSION) && OCEAN_MSC_VERSION > 0
324 
325  #if !defined(OCEAN_CLANG_VERSION) || OCEAN_CLANG_VERSION == 0
326  #if !defined(OCEAN_GCC_VERSION) || OCEAN_GCC_VERSION == 0
327  /// \cond DOXYGEN_DO_NOT_DOCUMENT
328  #define OCEAN_COMPILER_MSC 1
329  /// \endcond
330 
331  #if defined(OCEAN_COMPILER_GCC) || defined(OCEAN_COMPILER_CLANG)
332  #error Invalid compiler configuration.
333  #endif
334  #endif
335  #endif
336 #endif
337 
338 #if !defined(OCEAN_COMPILER_GCC) && !defined(OCEAN_COMPILER_CLANG) && !defined(OCEAN_COMPILER_MSC)
339  // we ensure that one of the compilers is defined
340  #error Unknown compiler, either GCC, Clang or the Microsoft compiler must be used.
341 #endif
342 
343 
344 #if !defined(OCEAN_POSIX_AVAILABLE)
345  // Clang on Windows uses standard library from MSVC.
346  #if defined(OCEAN_COMPILER_GCC) || (defined(OCEAN_COMPILER_CLANG) && !defined(_MSC_VER))
347  /// \cond DOXYGEN_DO_NOT_DOCUMENT
348  #define OCEAN_POSIX_AVAILABLE
349  /// \endcond
350  #endif
351 #endif
352 
353 
354 // Defines OCEAN_HARDWARE_SSE_VERSION for platforms supporting SSE instructions
355 #ifndef OCEAN_HARDWARE_SSE_VERSION
356  #if defined(_MSC_VER) && !defined(__clang__)
357 
358  #if defined(_M_IX86_FP) && _M_IX86_FP >= 1
359  #define OCEAN_HARDWARE_SSE_VERSION 41
360  #endif
361 
362  // The 64 bit compiler provides SSE support by default
363  #if defined(_WIN64)
364  #define OCEAN_HARDWARE_SSE_VERSION 41
365  #endif
366 
367  #elif defined(_MSC_VER) && defined(__clang__)
368 
369  #if defined(__SSE4_1__)
370  #define OCEAN_HARDWARE_SSE_VERSION 41
371  #endif
372 
373  #elif defined(__APPLE__)
374 
375  #if defined(__SSE4_1__)
376  #define OCEAN_HARDWARE_SSE_VERSION 41
377  #endif
378 
379  #elif defined(__linux__) && !defined(_ANDROID)
380 
381  #if defined(__SSE4_1__)
382  #define OCEAN_HARDWARE_SSE_VERSION 41
383  #endif
384 
385  #endif
386 #endif
387 
388 #ifndef OCEAN_HARDWARE_SSE_VERSION
389  #define OCEAN_HARDWARE_SSE_VERSION 0
390 #endif
391 
392 
393 
394 
395 // Defines OCEAN_HARDWARE_AVX_VERSION for platforms supporting AVX instructions
396 #if !defined(OCEAN_HARDWARE_AVX_VERSION) && OCEAN_HARDWARE_SSE_VERSION > 0
397  #if defined(_MSC_VER) || defined(__APPLE__) || (defined(__linux__) && !defined(_ANDROID))
398 
399  #if defined(__AVX2__)
400  #define OCEAN_HARDWARE_AVX_VERSION 20
401  #elif defined(__AVX__)
402  #define OCEAN_HARDWARE_AVX_VERSION 10
403  #endif
404 
405  #endif
406 #endif
407 
408 #ifndef OCEAN_HARDWARE_AVX_VERSION
409  #define OCEAN_HARDWARE_AVX_VERSION 0
410 #endif
411 
412 
413 
414 
415 // Defines OCEAN_LITTLE_ENDIAN on platforms with little endian byte order, do not define it on big endian platforms
416 #if defined(_WINDOWS) || defined(_ANDROID) || defined(__APPLE__) || defined(__linux__) || defined(__EMSCRIPTEN__)
417  #ifndef OCEAN_LITTLE_ENDIAN
418  #define OCEAN_LITTLE_ENDIAN
419  #endif
420 #endif
421 
422 
423 
424 
425 // Defines OCEAN_BASE_EXPORT for dll export and import.
426 #if defined(_WINDOWS) && defined(OCEAN_RUNTIME_SHARED)
427  #ifdef USE_OCEAN_BASE_EXPORT
428  #define OCEAN_BASE_EXPORT __declspec(dllexport)
429  #else
430  #define OCEAN_BASE_EXPORT __declspec(dllimport)
431  #endif
432 #else
433  #define OCEAN_BASE_EXPORT
434 #endif
435 
436 
437 
438 
439 // Defines OCEAN_REDIRECT_ASSERT_TO_MESSENGER on platforms not providing useful assert handling
440 #if defined(_ANDROID)
441  //#define OCEAN_REDIRECT_ASSERT_TO_MESSENGER
442 #endif
443 
444 // Defines the ocean_assert() macro
445 //
446 // The 'ocean_assert' or 'ocean_assert_accuracy' macro should be used instead of the standard C assert() directly.
447 //
448 // ocean_assert will be active as long as OCEAN_DEBUG is not defined
449 // In case, OCEAN_DEBUG is not defined, the expression of the assert will disappear, so that compilers may come up with warnings regarding unused variables.
450 //
451 // Use 'ocean_assert' to ensure that a program state is correct e.g., ocean_assert(pointer != nullptr);
452 // Use 'ocean_assert_accuracy' to ensure that the accuracy of a parameter is good enough for the following code
453 #ifndef ocean_assert
454  #ifdef OCEAN_DEBUG
455 
456  // Overwrites the assert for platforms not allowing for senseful debugging
457  #ifdef OCEAN_REDIRECT_ASSERT_TO_MESSENGER
458 
459  /**
460  * Error message function for redirected asserts.
461  * @param file Source file in that the assert occurred
462  * @param line Number of the line in that the assert occurred
463  * @param message The message to be redirected
464  * @ingroup base
465  */
466  extern OCEAN_BASE_EXPORT void assertErrorMessage(const char* file, const int line, const char* message);
467 
468  #define ocean_assert(e) ((bool(e) != true) ? Ocean::assertErrorMessage(__FILE__, __LINE__, #e) : ((void)0))
469 
470  #else
471 
472  #define ocean_assert(e) assert(e)
473 
474  #endif
475  #else
476  #define ocean_assert(e) ((void)0)
477  #endif
478 #endif
479 
480 // Defines the ocean_assert_accuracy() macro
481 //
482 // The 'ocean_assert' or 'ocean_assert_accuracy' macro should be used instead of the standard C assert() directly.
483 //
484 // ocean_assert_accuracy will be active as long as OCEAN_DEBUG is not defined
485 // In case, OCEAN_DEBUG is not defined, the expression of the assert will disappear, so that compilers may come up with warnings regarding unused variables.
486 //
487 // Use 'ocean_assert' to ensure that a program state is correct e.g., ocean_assert(pointer != nullptr);
488 // Use 'ocean_assert_accuracy' to ensure that the accuracy of a parameter is good enough for the following code
489 #ifndef ocean_assert_accuracy
490  #ifdef OCEAN_DEBUG
491  #define ocean_assert_accuracy(e) if (bool(e) != true) std::cout << "ocean_assert_accuracy(" << #e << "): in file " << __FILE__ << ", line " << __LINE__ << std::endl
492  #else
493  #define ocean_assert_accuracy(e) ((void)0)
494  #endif
495 #endif
496 
497 // Defines the ocean_assert_and_suppress_unused() macro
498 //
499 // ocean_assert_and_suppress_unused behaves like ocean_assert.
500 // In addition, in case, OCEAN_DEBUG is not defined, ocean_assert_and_suppress_unused suppressed the warning of an unused variable.
501 // Thus, ocean_assert_and_suppress_unused(expression, variable) does mainly `ocean_assert(expression), OCEAN_SUPPRESS_UNUSED_WARNING(variable)`
502 #ifndef ocean_assert_and_suppress_unused
503  #ifdef OCEAN_DEBUG
504  #define ocean_assert_and_suppress_unused(expression, variable) ocean_assert(expression)
505  #else
506  #define ocean_assert_and_suppress_unused(expression, variable) ((void)(variable))
507  #endif
508 #endif
509 
510 
511 
512 // Defines OCEAN_SUPPORT_RTTI state for compiler configurations supporting e.g., the usage of typeid.
513 #ifndef OCEAN_SUPPORT_RTTI
514  #if defined(OCEAN_COMPILER_MSC)
515  #ifdef _CPPRTTI
516  #define OCEAN_SUPPORT_RTTI
517  #endif
518  #elif defined(OCEAN_COMPILER_GCC) && OCEAN_GCC_VERSION >= 40302
519  #ifdef __GXX_RTTI
520  #define OCEAN_SUPPORT_RTTI
521  #endif
522  #elif defined(OCEAN_COMPILER_CLANG) && OCEAN_CLANG_VERSION >= 20700
523  #if __has_feature(cxx_rtti)
524  #define OCEAN_SUPPORT_RTTI
525  #endif
526  #endif
527 #endif // OCEAN_SUPPORT_RTTI
528 
529 
530 
531 
532 // Defines OCEAN_SUPPORT_EXCEPTIONS state for compiler configurations supporting exceptions.
533 #ifndef OCEAN_SUPPORT_EXCEPTIONS
534  #if defined(OCEAN_COMPILER_MSC)
535  #ifdef _CPPUNWIND
536  #define OCEAN_SUPPORT_EXCEPTIONS
537  #endif
538  #elif defined(OCEAN_COMPILER_GCC) && OCEAN_GCC_VERSION > 0
539  #if defined(__EXCEPTIONS) && __EXCEPTIONS
540  #define OCEAN_SUPPORT_EXCEPTIONS
541  #endif
542  #elif defined(OCEAN_COMPILER_CLANG) && OCEAN_CLANG_VERSION > 0
543  #if defined(__EXCEPTIONS) && __EXCEPTIONS && __has_feature(cxx_exceptions)
544  #define OCEAN_SUPPORT_EXCEPTIONS
545  #endif
546  #endif
547 #endif // OCEAN_SUPPORT_EXCEPTIONS
548 
549 
550 
551 
552 // Define OCEAN_COMPILETIME_WARNING_MISSING_IMPLEMENTATION to create compile time warnings for missing implementations
553 // #define OCEAN_COMPILETIME_WARNING_MISSING_IMPLEMENTATION
554 
555 // Defines the OCEAN_WARNING_MISSING_IMPLEMENTATION state either creating a compile time warning or a runtime warning (an assert).
556 #ifndef OCEAN_WARNING_MISSING_IMPLEMENTATION
557  #ifdef OCEAN_COMPILETIME_WARNING_MISSING_IMPLEMENTATION
558  #ifdef OCEAN_COMPILER_MSC
559  #define OCEAN_WARNING_MISSING_IMPLEMENTATION __pragma(message("Missing implementation!")); assert(false && "Missing implementation!")
560  #else
561  #define OCEAN_WARNING_MISSING_IMPLEMENTATION _Pragma ("message \"Missing implementation\""); assert(false && "Missing implementation!")
562  #endif
563  #else
564  #define OCEAN_WARNING_MISSING_IMPLEMENTATION assert(false && "Missing implementation!")
565  #endif
566 #endif // OCEAN_WARNING_MISSING_IMPLEMENTATION
567 
568 
569 
570 
571 // Defines the OCEAN_SUPPRESS_UNUSED_WARNING state that allows to suppress warnings regarding unused variables.
572 #ifndef OCEAN_SUPPRESS_UNUSED_WARNING
573  #define OCEAN_SUPPRESS_UNUSED_WARNING(e) ((void)e)
574 #endif
575 
576 
577 
578 
579 /**
580  * This function is a helper function returning false any time.
581  * @return False, any the time
582  * @tparam T Template parameter that can be used, however it does not have any impact
583  * @ingroup base
584  */
585 template <typename T>
586 inline constexpr bool oceanFalse()
587 {
588  return false;
589 }
590 
591 
592 
593 
594 // Definition of OCEAN_PLATFORM_BUILD_XXX for individual platforms
595 #if defined(_WINDOWS)
596 
597  #define OCEAN_PLATFORM_BUILD_WINDOWS
598 
599 #elif defined(__APPLE__)
600 
601  #define OCEAN_PLATFORM_BUILD_APPLE
602 
603  #if defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR == 1
604 
605  #define OCEAN_PLATFORM_BUILD_APPLE_IOS_SUMULATOR
606 
607  #elif defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE == 1
608 
609  #define OCEAN_PLATFORM_BUILD_APPLE_IOS
610 
611  #elif defined(TARGET_OS_MAC) && TARGET_OS_MAC == 1
612 
613  #define OCEAN_PLATFORM_BUILD_APPLE_MACOS
614 
615  #else
616 
617  #error Missing implementation
618 
619  #endif
620 
621  #if defined(OCEAN_PLATFORM_BUILD_APPLE_IOS_SUMULATOR) || defined(OCEAN_PLATFORM_BUILD_APPLE_IOS)
622 
623  #define OCEAN_PLATFORM_BUILD_APPLE_IOS_ANY
624 
625  #endif
626 
627 #elif defined(_ANDROID)
628 
629  #define OCEAN_PLATFORM_BUILD_ANDROID
630 
631 #elif defined(__linux__) || defined(__EMSCRIPTEN__)
632 
633  #define OCEAN_PLATFORM_BUILD_LINUX
634 
635 #else
636 
637  #error Missing implementation
638 
639 #endif
640 
641 #if defined(OCEAN_PLATFORM_BUILD_ANDROID) || defined(OCEAN_PLATFORM_BUILD_APPLE_IOS_ANY)
642 
643  #define OCEAN_PLATFORM_BUILD_MOBILE
644 
645 #endif
646 
647 
648 
649 
650 // The OCEAN_APPLY_IF_DEBUG allows to invoke an expression in debug builds.
651 #ifndef OCEAN_APPLY_IF_DEBUG
652  #ifdef OCEAN_DEBUG
653  #define OCEAN_APPLY_IF_DEBUG(e) e
654  #else
655  #define OCEAN_APPLY_IF_DEBUG(e) {}
656  #endif
657 #endif
658 
659 // The OCEAN_APPLY_IF_WINDOWS allows to invoke an expression on windows platforms only.
660 #ifndef OCEAN_APPLY_IF_WINDOWS
661  #ifdef OCEAN_PLATFORM_BUILD_WINDOWS
662  #define OCEAN_APPLY_IF_WINDOWS(e) e
663  #else
664  #define OCEAN_APPLY_IF_WINDOWS(e) {}
665  #endif
666 #endif
667 
668 // The OCEAN_APPLY_IF_APPLE allows to invoke an expression on apple platforms only.
669 #ifndef OCEAN_APPLY_IF_APPLE
670  #ifdef OCEAN_PLATFORM_BUILD_APPLE
671  #define OCEAN_APPLY_IF_APPLE(e) e
672  #else
673  #define OCEAN_APPLY_IF_APPLE(e) {}
674  #endif
675 #endif
676 
677 // The OCEAN_APPLY_IF_LINUX allows to invoke an expression on apple platforms only.
678 #ifndef OCEAN_APPLY_IF_LINUX
679  #ifdef OCEAN_PLATFORM_BUILD_LINUX
680  #define OCEAN_APPLY_IF_LINUX(e) e
681  #else
682  #define OCEAN_APPLY_IF_LINUX(e) {}
683  #endif
684 #endif
685 
686 // The OCEAN_APPLY_IF_ANDROID allows to invoke an expression on android platforms only.
687 #ifndef OCEAN_APPLY_IF_ANDROID
688  #ifdef OCEAN_PLATFORM_BUILD_ANDROID
689  #define OCEAN_APPLY_IF_ANDROID(e) e
690  #else
691  #define OCEAN_APPLY_IF_ANDROID(e) {}
692  #endif
693 #endif
694 
695 // The OCEAN_APPLY_IF_IPHONE allows to invoke an expression on iOS platforms only.
696 #ifndef OCEAN_APPLY_IF_IPHONE
697  #if defined(OCEAN_PLATFORM_BUILD_APPLE_IOS) || defined(TARGET_IPHONE_SIMULATOR)
698  #define OCEAN_APPLY_IF_IPHONE(e) e
699  #else
700  #define OCEAN_APPLY_IF_IPHONE(e) {}
701  #endif
702 #endif
703 
704 // The OCEAN_APPLY_IF_GCC allows to invoke an expression with GCC compilers only.
705 #ifndef OCEAN_APPLY_IF_GCC
706  #if defined(OCEAN_GCC_VERSION) && OCEAN_GCC_VERSION > 0
707  #define OCEAN_APPLY_IF_GCC(e) e
708  #else
709  #define OCEAN_APPLY_IF_GCC(e) {}
710  #endif
711 #endif
712 
713 // The OCEAN_APPLY_IF_SSE allows to invoke an expression if any valid SSE version is defined.
714 #ifndef OCEAN_APPLY_IF_SSE
715  #if defined(OCEAN_HARDWARE_SSE_VERSION) && OCEAN_HARDWARE_SSE_VERSION > 0
716  #define OCEAN_APPLY_IF_SSE(e) e
717  #else
718  #define OCEAN_APPLY_IF_SSE(e) {}
719  #endif
720 #endif
721 
722 // The OCEAN_APPLY_IF_AVX allows to invoke an expression if any valid AVX version is defined.
723 #ifndef OCEAN_APPLY_IF_AVX
724  #if defined(OCEAN_HARDWARE_AVX_VERSION) && OCEAN_HARDWARE_AVX_VERSION > 0
725  #define OCEAN_APPLY_IF_AVX(e) e
726  #else
727  #define OCEAN_APPLY_IF_AVX(e) {}
728  #endif
729 #endif
730 
731 // The OCEAN_APPLY_IF_NEON allows to invoke an expression if any valid NEON version is defined.
732 #ifndef OCEAN_APPLY_IF_NEON
733  #if defined(OCEAN_HARDWARE_NEON_VERSION) && OCEAN_HARDWARE_NEON_VERSION > 0
734  #define OCEAN_APPLY_IF_NEON(e) e
735  #else
736  #define OCEAN_APPLY_IF_NEON(e) {}
737  #endif
738 #endif
739 
740 
741 
742 
743 
744 // The OCEAN_FORCE_INLINE macro allows to overwrite the compiler's inline analysis and forces a function to be inlined in any situation, as long as supported by the compiler
745 #ifndef OCEAN_FORCE_INLINE
746  #if defined(OCEAN_COMPILER_MSC)
747  #define OCEAN_FORCE_INLINE __forceinline
748  #elif defined(OCEAN_COMPILER_CLANG)
749  #if __has_attribute(always_inline)
750  #define OCEAN_FORCE_INLINE inline __attribute__((always_inline))
751  #else
752  #define OCEAN_FORCE_INLINE inline
753  #endif
754  #elif defined(OCEAN_COMPILER_GCC)
755  #define OCEAN_FORCE_INLINE inline __attribute__((always_inline))
756  #else
757  #define OCEAN_FORCE_INLINE inline
758  #endif
759 #endif
760 
761 
762 
763 
764 // The OCEAN_PREVENT_INLINE macro allows to overwrite the compiler's inline analysis and forces a function from being inlined in any situation, as long as supported by the compiler
765 #ifndef OCEAN_PREVENT_INLINE
766  #if defined(OCEAN_COMPILER_MSC)
767  #define OCEAN_PREVENT_INLINE __declspec(noinline)
768  #elif defined(OCEAN_COMPILER_CLANG)
769  #if __has_attribute(noinline)
770  #define OCEAN_PREVENT_INLINE __attribute__((noinline))
771  #else
772  #define OCEAN_PREVENT_INLINE
773  #endif
774  #elif defined(OCEAN_COMPILER_GCC)
775  #define OCEAN_PREVENT_INLINE __attribute__((noinline))
776  #else
777  #define OCEAN_PREVENT_INLINE
778  #endif
779 #endif
780 
781 
782 
783 
784 // The OCEAN_DISABLE_SUBSEQUENT_LOOP_OPTIMIZATION macro allows to disable loop optimizations in the subsequent loop
785 #ifndef OCEAN_DISABLE_SUBSEQUENT_LOOP_OPTIMIZATION
786  #if defined(OCEAN_COMPILER_MSC)
787  #define OCEAN_DISABLE_SUBSEQUENT_LOOP_OPTIMIZATION _Pragma("loop(no_vector)")
788  #elif defined(OCEAN_COMPILER_CLANG)
789  #define OCEAN_DISABLE_SUBSEQUENT_LOOP_OPTIMIZATION _Pragma("clang loop vectorize(disable) interleave(disable)")
790  #elif defined(OCEAN_COMPILER_GCC)
791  #define OCEAN_DISABLE_SUBSEQUENT_LOOP_OPTIMIZATION _Pragma("GCC unroll 1")
792  #else
793  #define OCEAN_DISABLE_SUBSEQUENT_LOOP_OPTIMIZATION
794  #endif
795 #endif
796 
797 // The OCEAN_DISABLE_SUBSEQUENT_LOOP_OPTIMIZATION_IF_NEON macro allows to disable loop optimizations in the subsequent loop in case NEON is supported
798 #ifndef OCEAN_DISABLE_SUBSEQUENT_LOOP_OPTIMIZATION_IF_NEON
799  #if defined(OCEAN_HARDWARE_NEON_VERSION) && OCEAN_HARDWARE_NEON_VERSION > 0
800  #define OCEAN_DISABLE_SUBSEQUENT_LOOP_OPTIMIZATION_IF_NEON OCEAN_DISABLE_SUBSEQUENT_LOOP_OPTIMIZATION
801  #else
802  #define OCEAN_DISABLE_SUBSEQUENT_LOOP_OPTIMIZATION_IF_NEON
803  #endif
804 #endif
805 
806 
807 
808 
809 // The OCEAN_ALIGN_DATA macro allows to force the alignment of data to a specified byte boundary
810 #ifndef OCEAN_ALIGN_DATA
811  #if defined(OCEAN_COMPILER_MSC)
812  #define OCEAN_ALIGN_DATA(x) __declspec(align(x))
813  #else
814  #define OCEAN_ALIGN_DATA(x) __attribute__ ((aligned(x)))
815  #endif
816 #endif
817 
818 
819 
820 
821 
822 #if (defined(DEBUG) || defined(OCEAN_DEBUG)) && defined(NDEBUG)
823  #error You cannot define both flags (DEBUG and NDEBUG) concurrently
824 #endif
825 
826 #if defined(OCEAN_INTENSIVE_DEBUG) && (!defined(DEBUG) || !defined(OCEAN_DEBUG))
827  #error You cannot define OCEAN_INTENSIVE_DEBUG without defining DEBUG/OCEAN_DEBUG
828 #endif
829 
830 
831 
832 
833 #ifndef OCEAN_NDEBUG
834  #if !defined(OCEAN_DEBUG) || defined(NDEBUG)
835  #define OCEAN_NDEBUG
836  #endif
837 #endif
838 
839 
840 
841 
842 // The OCEAN_DISABLE_DOCUMENTATION_DIAGNOSTIC macro allows to disable Clang's code documentation diagnostic, must be balanced with a following usage of `OCEAN_RE_ENABLE_DOCUMENTATION_DIAGNOSTIC`
843 #ifndef OCEAN_DISABLE_DOCUMENTATION_DIAGNOSTIC
844  #if defined(OCEAN_CLANG_VERSION) && OCEAN_CLANG_VERSION > 0
845  #define OCEAN_DISABLE_DOCUMENTATION_DIAGNOSTIC _Pragma("clang diagnostic push") \
846  _Pragma("clang diagnostic ignored \"-Wdocumentation\"")
847  #else
848  #define OCEAN_DISABLE_DOCUMENTATION_DIAGNOSTIC
849  #endif
850 #endif
851 
852 // The OCEAN_RE_ENABLE_DOCUMENTATION_DIAGNOSTIC macro allows to re-enabled Clang's code documentation diagnostic, must be balanced with earlier usage of `OCEAN_DISABLE_DOCUMENTATION_DIAGNOSTIC`
853 #ifndef OCEAN_RE_ENABLE_DOCUMENTATION_DIAGNOSTIC
854  #if defined(OCEAN_CLANG_VERSION) && OCEAN_CLANG_VERSION > 0
855  #define OCEAN_RE_ENABLE_DOCUMENTATION_DIAGNOSTIC _Pragma("clang diagnostic pop")
856  #else
857  #define OCEAN_RE_ENABLE_DOCUMENTATION_DIAGNOSTIC
858  #endif
859 #endif
860 
861 
862 
863 
864 // The OCEAN_PRINT_MACRO_VALUE macro allows to print a macro value at compile time, usage e.g., `OCEAN_PRINT_MACRO_VALUE("This is a version number: ", OCEAN_CLANG_VERSION)`
865 #ifndef OCEAN_PRINT_MACRO_VALUE
866  #define OCEAN_PRINT_MACRO_VALUE_INTERNAL_INTERNAL(value) #value
867  #define OCEAN_PRINT_MACRO_VALUE_INTERNAL(value) OCEAN_PRINT_MACRO_VALUE_INTERNAL_INTERNAL(value)
868 
869  #define OCEAN_PRAGMA_INTERNAL(value) _Pragma(#value)
870  #define OCEAN_PRAGMA(value) OCEAN_PRAGMA_INTERNAL(value)
871 
872  #define OCEAN_PRINT_MACRO_VALUE(text, value) OCEAN_PRAGMA(message text OCEAN_PRINT_MACRO_VALUE_INTERNAL(value))
873 #endif
874 
875 }
876 
877 #endif // META_OCEAN_BASE_BASE_H
std::vector< IndexPair32 > IndexPairs32
Definition of a vector holding 32 bit index pairs.
Definition: Base.h:144
std::set< Index32 > IndexSet32
Definition of a set holding 32 bit indices.
Definition: Base.h:114
uint64_t Index64
Definition of a 64 bit index value.
Definition: Base.h:90
std::vector< std::string > Strings
Definition of a vector holding strings.
Definition: Base.h:162
constexpr bool oceanFalse()
This function is a helper function returning false any time.
Definition: Base.h:586
std::vector< std::wstring > WStrings
Definition of a vector holding strings.
Definition: Base.h:168
std::vector< Indices32 > IndexGroups32
Definition of a vector holding 32 bit indices, so we have groups of indices.
Definition: Base.h:102
std::vector< Index32 > Indices32
Definition of a vector holding 32 bit index values.
Definition: Base.h:96
std::vector< Index64 > Indices64
Definition of a vector holding 64 bit index values.
Definition: Base.h:108
std::unordered_set< Index32 > UnorderedIndexSet32
Definition of an unordered_set holding 32 bit indices.
Definition: Base.h:126
OCEAN_BASE_EXPORT void assertErrorMessage(const char *file, const int line, const char *message)
Error message function for redirected asserts.
std::set< Index64 > IndexSet64
Definition of a set holding 64 bit indices.
Definition: Base.h:120
std::pair< Index64, Index64 > IndexPair64
Definition of a pair holding 64 bit indices.
Definition: Base.h:150
std::unordered_set< Index64 > UnorderedIndexSet64
Definition of an unordered_set holding 64 bit indices.
Definition: Base.h:132
std::vector< IndexPair64 > IndexPairs64
Definition of a vector holding 64 bit index pairs.
Definition: Base.h:156
std::pair< Index32, Index32 > IndexPair32
Definition of a pair holding 32 bit indices.
Definition: Base.h:138
uint32_t Index32
Definition of a 32 bit index value.
Definition: Base.h:84
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15