summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--3rdparty/bx/.appveyor.yml3
-rw-r--r--3rdparty/bx/.travis.yml2
-rw-r--r--3rdparty/bx/3rdparty/catch/catch.hpp2887
-rw-r--r--3rdparty/bx/LICENSE2
-rw-r--r--3rdparty/bx/README.md6
-rw-r--r--3rdparty/bx/include/bx/allocator.h3
-rw-r--r--3rdparty/bx/include/bx/bx.h18
-rw-r--r--3rdparty/bx/include/bx/commandline.h2
-rw-r--r--3rdparty/bx/include/bx/config.h2
-rw-r--r--3rdparty/bx/include/bx/cpu.h2
-rw-r--r--3rdparty/bx/include/bx/debug.h2
-rw-r--r--3rdparty/bx/include/bx/easing.h2
-rw-r--r--3rdparty/bx/include/bx/endian.h2
-rw-r--r--3rdparty/bx/include/bx/error.h34
-rw-r--r--3rdparty/bx/include/bx/file.h2
-rw-r--r--3rdparty/bx/include/bx/filepath.h8
-rw-r--r--3rdparty/bx/include/bx/float4x4_t.h24
-rw-r--r--3rdparty/bx/include/bx/handlealloc.h4
-rw-r--r--3rdparty/bx/include/bx/hash.h2
-rw-r--r--3rdparty/bx/include/bx/inline/allocator.inl12
-rw-r--r--3rdparty/bx/include/bx/inline/bx.inl29
-rw-r--r--3rdparty/bx/include/bx/inline/cpu.inl53
-rw-r--r--3rdparty/bx/include/bx/inline/easing.inl2
-rw-r--r--3rdparty/bx/include/bx/inline/endian.inl2
-rw-r--r--3rdparty/bx/include/bx/inline/error.inl33
-rw-r--r--3rdparty/bx/include/bx/inline/float4x4_t.inl91
-rw-r--r--3rdparty/bx/include/bx/inline/handlealloc.inl12
-rw-r--r--3rdparty/bx/include/bx/inline/hash.inl2
-rw-r--r--3rdparty/bx/include/bx/inline/math.inl33
-rw-r--r--3rdparty/bx/include/bx/inline/mpscqueue.inl2
-rw-r--r--3rdparty/bx/include/bx/inline/mutex.inl2
-rw-r--r--3rdparty/bx/include/bx/inline/os.inl18
-rw-r--r--3rdparty/bx/include/bx/inline/pixelformat.inl2
-rw-r--r--3rdparty/bx/include/bx/inline/readerwriter.inl18
-rw-r--r--3rdparty/bx/include/bx/inline/ringbuffer.inl6
-rw-r--r--3rdparty/bx/include/bx/inline/rng.inl4
-rw-r--r--3rdparty/bx/include/bx/inline/simd128_langext.inl10
-rw-r--r--3rdparty/bx/include/bx/inline/simd128_neon.inl62
-rw-r--r--3rdparty/bx/include/bx/inline/simd128_ref.inl43
-rw-r--r--3rdparty/bx/include/bx/inline/simd128_sse.inl38
-rw-r--r--3rdparty/bx/include/bx/inline/simd256_avx.inl2
-rw-r--r--3rdparty/bx/include/bx/inline/simd256_ref.inl2
-rw-r--r--3rdparty/bx/include/bx/inline/simd_ni.inl11
-rw-r--r--3rdparty/bx/include/bx/inline/sort.inl64
-rw-r--r--3rdparty/bx/include/bx/inline/spscqueue.inl2
-rw-r--r--3rdparty/bx/include/bx/inline/string.inl16
-rw-r--r--3rdparty/bx/include/bx/inline/uint32_t.inl68
-rw-r--r--3rdparty/bx/include/bx/macros.h30
-rw-r--r--3rdparty/bx/include/bx/maputil.h2
-rw-r--r--3rdparty/bx/include/bx/math.h20
-rw-r--r--3rdparty/bx/include/bx/mpscqueue.h2
-rw-r--r--3rdparty/bx/include/bx/mutex.h2
-rw-r--r--3rdparty/bx/include/bx/os.h8
-rw-r--r--3rdparty/bx/include/bx/pixelformat.h2
-rw-r--r--3rdparty/bx/include/bx/platform.h24
-rw-r--r--3rdparty/bx/include/bx/process.h2
-rw-r--r--3rdparty/bx/include/bx/readerwriter.h24
-rw-r--r--3rdparty/bx/include/bx/ringbuffer.h2
-rw-r--r--3rdparty/bx/include/bx/rng.h2
-rw-r--r--3rdparty/bx/include/bx/semaphore.h2
-rw-r--r--3rdparty/bx/include/bx/settings.h2
-rw-r--r--3rdparty/bx/include/bx/simd_t.h10
-rw-r--r--3rdparty/bx/include/bx/sort.h2
-rw-r--r--3rdparty/bx/include/bx/spscqueue.h2
-rw-r--r--3rdparty/bx/include/bx/string.h15
-rw-r--r--3rdparty/bx/include/bx/thread.h16
-rw-r--r--3rdparty/bx/include/bx/timer.h2
-rw-r--r--3rdparty/bx/include/bx/uint32_t.h38
-rw-r--r--3rdparty/bx/include/bx/url.h2
-rw-r--r--3rdparty/bx/makefile67
-rw-r--r--3rdparty/bx/scripts/bin2c.lua2
-rw-r--r--3rdparty/bx/scripts/bx.lua16
-rw-r--r--3rdparty/bx/scripts/genie.lua6
-rw-r--r--3rdparty/bx/scripts/lemon.lua2
-rw-r--r--3rdparty/bx/scripts/toolchain.lua169
-rw-r--r--3rdparty/bx/src/allocator.cpp2
-rw-r--r--3rdparty/bx/src/amalgamated.cpp2
-rw-r--r--3rdparty/bx/src/bx.cpp2
-rw-r--r--3rdparty/bx/src/bx_p.h6
-rw-r--r--3rdparty/bx/src/commandline.cpp2
-rw-r--r--3rdparty/bx/src/crtnone.cpp4
-rw-r--r--3rdparty/bx/src/debug.cpp4
-rw-r--r--3rdparty/bx/src/dtoa.cpp8
-rw-r--r--3rdparty/bx/src/easing.cpp2
-rw-r--r--3rdparty/bx/src/file.cpp88
-rw-r--r--3rdparty/bx/src/filepath.cpp2
-rw-r--r--3rdparty/bx/src/hash.cpp2
-rw-r--r--3rdparty/bx/src/math.cpp2
-rw-r--r--3rdparty/bx/src/mutex.cpp26
-rw-r--r--3rdparty/bx/src/os.cpp14
-rw-r--r--3rdparty/bx/src/process.cpp32
-rw-r--r--3rdparty/bx/src/semaphore.cpp24
-rw-r--r--3rdparty/bx/src/settings.cpp2
-rw-r--r--3rdparty/bx/src/sort.cpp2
-rw-r--r--3rdparty/bx/src/string.cpp116
-rw-r--r--3rdparty/bx/src/thread.cpp78
-rw-r--r--3rdparty/bx/src/timer.cpp4
-rw-r--r--3rdparty/bx/src/url.cpp2
-rw-r--r--3rdparty/bx/tests/atomic_test.cpp2
-rw-r--r--3rdparty/bx/tests/crt_test.cpp2
-rw-r--r--3rdparty/bx/tests/dbg.h2
-rw-r--r--3rdparty/bx/tests/easing_test.cpp2
-rw-r--r--3rdparty/bx/tests/filepath_test.cpp2
-rw-r--r--3rdparty/bx/tests/handle_bench.cpp2
-rw-r--r--3rdparty/bx/tests/handle_test.cpp2
-rw-r--r--3rdparty/bx/tests/hash_test.cpp2
-rw-r--r--3rdparty/bx/tests/macros_test.cpp16
-rw-r--r--3rdparty/bx/tests/main_test.cpp2
-rw-r--r--3rdparty/bx/tests/math_bench.cpp2
-rw-r--r--3rdparty/bx/tests/math_test.cpp9
-rw-r--r--3rdparty/bx/tests/nlalloc_test.cpp6
-rw-r--r--3rdparty/bx/tests/os_test.cpp2
-rw-r--r--3rdparty/bx/tests/queue_test.cpp2
-rw-r--r--3rdparty/bx/tests/readerwriter_test.cpp2
-rw-r--r--3rdparty/bx/tests/ringbuffer_test.cpp2
-rw-r--r--3rdparty/bx/tests/rng_test.cpp2
-rw-r--r--3rdparty/bx/tests/run_test.cpp2
-rw-r--r--3rdparty/bx/tests/settings_test.cpp2
-rw-r--r--3rdparty/bx/tests/simd_bench.cpp2
-rw-r--r--3rdparty/bx/tests/simd_test.cpp2
-rw-r--r--3rdparty/bx/tests/sort_test.cpp2
-rw-r--r--3rdparty/bx/tests/string_test.cpp41
-rw-r--r--3rdparty/bx/tests/test.h2
-rw-r--r--3rdparty/bx/tests/thread_test.cpp6
-rw-r--r--3rdparty/bx/tests/tokenizecmd_test.cpp2
-rw-r--r--3rdparty/bx/tests/uint32_test.cpp34
-rw-r--r--3rdparty/bx/tests/url_test.cpp2
-rw-r--r--3rdparty/bx/tests/vsnprintf_test.cpp51
-rwxr-xr-x[-rw-r--r--]3rdparty/bx/tools/bin/darwin/bin2cbin127496 -> 127496 bytes
-rwxr-xr-x3rdparty/bx/tools/bin/darwin/geniebin561360 -> 549136 bytes
-rwxr-xr-x[-rw-r--r--]3rdparty/bx/tools/bin/darwin/lemonbin95148 -> 95148 bytes
-rwxr-xr-x[-rw-r--r--]3rdparty/bx/tools/bin/darwin/ninjabin176588 -> 176588 bytes
-rwxr-xr-x[-rw-r--r--]3rdparty/bx/tools/bin/linux/bin2cbin84448 -> 88112 bytes
-rwxr-xr-x3rdparty/bx/tools/bin/linux/geniebin547592 -> 543624 bytes
-rwxr-xr-x[-rw-r--r--]3rdparty/bx/tools/bin/linux/lemonbin80864 -> 84576 bytes
-rwxr-xr-x[-rw-r--r--]3rdparty/bx/tools/bin/linux/ninjabin175240 -> 175240 bytes
-rwxr-xr-x[-rw-r--r--]3rdparty/bx/tools/bin/windows/bin2c.exebin163328 -> 163328 bytes
-rw-r--r--3rdparty/bx/tools/bin/windows/genie.exebin559616 -> 547328 bytes
-rwxr-xr-x[-rw-r--r--]3rdparty/bx/tools/bin/windows/ninja.exebin396800 -> 396800 bytes
-rw-r--r--3rdparty/bx/tools/bin2c/bin2c.cpp52
140 files changed, 3184 insertions, 1622 deletions
diff --git a/3rdparty/bx/.appveyor.yml b/3rdparty/bx/.appveyor.yml
index 001d04317b3..b0b107726f8 100644
--- a/3rdparty/bx/.appveyor.yml
+++ b/3rdparty/bx/.appveyor.yml
@@ -1,11 +1,12 @@
shallow_clone: true
os:
- - Visual Studio 2017
+ - Visual Studio 2019
environment:
matrix:
- TOOLSET: vs2017
+# - TOOLSET: vs2019
configuration:
- Debug
diff --git a/3rdparty/bx/.travis.yml b/3rdparty/bx/.travis.yml
index 54bf844abf2..82e0ac2e024 100644
--- a/3rdparty/bx/.travis.yml
+++ b/3rdparty/bx/.travis.yml
@@ -26,4 +26,4 @@ branches:
notifications:
email: false
-osx_image: xcode9.3
+osx_image: xcode11
diff --git a/3rdparty/bx/3rdparty/catch/catch.hpp b/3rdparty/bx/3rdparty/catch/catch.hpp
index 9b14505916c..0384171ae4a 100644
--- a/3rdparty/bx/3rdparty/catch/catch.hpp
+++ b/3rdparty/bx/3rdparty/catch/catch.hpp
@@ -1,9 +1,9 @@
/*
- * Catch v2.9.0
- * Generated: 2019-06-16 10:41:32.122746
+ * Catch v2.13.4
+ * Generated: 2020-12-29 14:48:00.116107
* ----------------------------------------------------------
* This file has been merged from multiple headers. Please don't edit it directly
- * Copyright (c) 2019 Two Blue Cubes Ltd. All rights reserved.
+ * Copyright (c) 2020 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -14,8 +14,8 @@
#define CATCH_VERSION_MAJOR 2
-#define CATCH_VERSION_MINOR 9
-#define CATCH_VERSION_PATCH 0
+#define CATCH_VERSION_MINOR 13
+#define CATCH_VERSION_PATCH 4
#ifdef __clang__
# pragma clang system_header
@@ -132,36 +132,51 @@ namespace Catch {
#endif
-#if defined(CATCH_CPP17_OR_GREATER)
-# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
+// We have to avoid both ICC and Clang, because they try to mask themselves
+// as gcc, and we want only GCC in this block
+#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && !defined(__CUDACC__)
+# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic push" )
+# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic pop" )
+
+# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__)
+
#endif
-#ifdef __clang__
+#if defined(__clang__)
+
+# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic push" )
+# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic pop" )
+
+// As of this writing, IBM XL's implementation of __builtin_constant_p has a bug
+// which results in calls to destructors being emitted for each temporary,
+// without a matching initialization. In practice, this can result in something
+// like `std::string::~string` being called on an uninitialized value.
+//
+// For example, this code will likely segfault under IBM XL:
+// ```
+// REQUIRE(std::string("12") + "34" == "1234")
+// ```
+//
+// Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented.
+# if !defined(__ibmxl__) && !defined(__CUDACC__)
+# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg, hicpp-vararg) */
+# endif
+
+# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
+ _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \
+ _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"")
+
+# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
+ _Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
-# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
- _Pragma( "clang diagnostic push" ) \
- _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \
- _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"")
-# define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
- _Pragma( "clang diagnostic pop" )
-
-# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
- _Pragma( "clang diagnostic push" ) \
- _Pragma( "clang diagnostic ignored \"-Wparentheses\"" )
-# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
- _Pragma( "clang diagnostic pop" )
-
-# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
- _Pragma( "clang diagnostic push" ) \
- _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" )
-# define CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS \
- _Pragma( "clang diagnostic pop" )
-
-# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
- _Pragma( "clang diagnostic push" ) \
- _Pragma( "clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"" )
-# define CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS \
- _Pragma( "clang diagnostic pop" )
+# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
+ _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" )
+
+# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
+ _Pragma( "clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"" )
+
+# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
+ _Pragma( "clang diagnostic ignored \"-Wunused-template\"" )
#endif // __clang__
@@ -186,6 +201,7 @@ namespace Catch {
// Android somehow still does not support std::to_string
#if defined(__ANDROID__)
# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING
+# define CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE
#endif
////////////////////////////////////////////////////////////////////////////////
@@ -219,11 +235,10 @@ namespace Catch {
////////////////////////////////////////////////////////////////////////////////
// Visual C++
-#ifdef _MSC_VER
+#if defined(_MSC_VER)
-# if _MSC_VER >= 1900 // Visual Studio 2015 or newer
-# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
-# endif
+# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) )
+# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) )
// Universal Windows platform does not support SEH
// Or console colours (or console at all...)
@@ -236,9 +251,12 @@ namespace Catch {
// MSVC traditional preprocessor needs some workaround for __VA_ARGS__
// _MSVC_TRADITIONAL == 0 means new conformant preprocessor
// _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor
-# if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL)
-# define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
-# endif
+# if !defined(__clang__) // Handle Clang masquerading for msvc
+# if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL)
+# define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
+# endif // MSVC_TRADITIONAL
+# endif // __clang__
+
#endif // _MSC_VER
#if defined(_REENTRANT) || defined(_MSC_VER)
@@ -276,40 +294,56 @@ namespace Catch {
#endif
////////////////////////////////////////////////////////////////////////////////
-// Check if string_view is available and usable
-// The check is split apart to work around v140 (VS2015) preprocessor issue...
-#if defined(__has_include)
-#if __has_include(<string_view>) && defined(CATCH_CPP17_OR_GREATER)
-# define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW
-#endif
+
+// RTX is a special version of Windows that is real time.
+// This means that it is detected as Windows, but does not provide
+// the same set of capabilities as real Windows does.
+#if defined(UNDER_RTSS) || defined(RTX64_BUILD)
+ #define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH
+ #define CATCH_INTERNAL_CONFIG_NO_ASYNC
+ #define CATCH_CONFIG_COLOUR_NONE
#endif
-////////////////////////////////////////////////////////////////////////////////
-// Check if optional is available and usable
-#if defined(__has_include)
-# if __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
-# define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL
-# endif // __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
-#endif // __has_include
+#if !defined(_GLIBCXX_USE_C99_MATH_TR1)
+#define CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER
+#endif
-////////////////////////////////////////////////////////////////////////////////
-// Check if variant is available and usable
+// Various stdlib support checks that require __has_include
#if defined(__has_include)
-# if __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
-# if defined(__clang__) && (__clang_major__ < 8)
- // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852
- // fix should be in clang 8, workaround in libstdc++ 8.2
-# include <ciso646>
-# if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
-# define CATCH_CONFIG_NO_CPP17_VARIANT
-# else
-# define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
-# endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
-# else
-# define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
-# endif // defined(__clang__) && (__clang_major__ < 8)
-# endif // __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
-#endif // __has_include
+ // Check if string_view is available and usable
+ #if __has_include(<string_view>) && defined(CATCH_CPP17_OR_GREATER)
+ # define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW
+ #endif
+
+ // Check if optional is available and usable
+ # if __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
+ # define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL
+ # endif // __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)
+
+ // Check if byte is available and usable
+ # if __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
+ # include <cstddef>
+ # if __cpp_lib_byte > 0
+ # define CATCH_INTERNAL_CONFIG_CPP17_BYTE
+ # endif
+ # endif // __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)
+
+ // Check if variant is available and usable
+ # if __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
+ # if defined(__clang__) && (__clang_major__ < 8)
+ // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852
+ // fix should be in clang 8, workaround in libstdc++ 8.2
+ # include <ciso646>
+ # if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
+ # define CATCH_CONFIG_NO_CPP17_VARIANT
+ # else
+ # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
+ # endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)
+ # else
+ # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT
+ # endif // defined(__clang__) && (__clang_major__ < 8)
+ # endif // __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)
+#endif // defined(__has_include)
#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
# define CATCH_CONFIG_COUNTER
@@ -334,10 +368,6 @@ namespace Catch {
# define CATCH_CONFIG_CPP17_OPTIONAL
#endif
-#if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
-# define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
-#endif
-
#if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW)
# define CATCH_CONFIG_CPP17_STRING_VIEW
#endif
@@ -346,6 +376,10 @@ namespace Catch {
# define CATCH_CONFIG_CPP17_VARIANT
#endif
+#if defined(CATCH_INTERNAL_CONFIG_CPP17_BYTE) && !defined(CATCH_CONFIG_NO_CPP17_BYTE) && !defined(CATCH_CONFIG_CPP17_BYTE)
+# define CATCH_CONFIG_CPP17_BYTE
+#endif
+
#if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
# define CATCH_INTERNAL_CONFIG_NEW_CAPTURE
#endif
@@ -362,25 +396,53 @@ namespace Catch {
# define CATCH_CONFIG_POLYFILL_ISNAN
#endif
-#if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC) && !defined(CATCH_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC)
+#if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC) && !defined(CATCH_INTERNAL_CONFIG_NO_ASYNC) && !defined(CATCH_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC)
# define CATCH_CONFIG_USE_ASYNC
#endif
+#if defined(CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_NO_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_ANDROID_LOGWRITE)
+# define CATCH_CONFIG_ANDROID_LOGWRITE
+#endif
+
+#if defined(CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_NO_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
+# define CATCH_CONFIG_GLOBAL_NEXTAFTER
+#endif
+
+// Even if we do not think the compiler has that warning, we still have
+// to provide a macro that can be used by the code.
+#if !defined(CATCH_INTERNAL_START_WARNINGS_SUPPRESSION)
+# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION
+#endif
+#if !defined(CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION)
+# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
+#endif
#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)
# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS
-# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS
#endif
#if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS)
# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
-# define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
#endif
#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS)
# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS
-# define CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS
#endif
#if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS)
# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS
-# define CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS
+#endif
+
+// The goal of this macro is to avoid evaluation of the arguments, but
+// still have the compiler warn on problems inside...
+#if !defined(CATCH_INTERNAL_IGNORE_BUT_WARN)
+# define CATCH_INTERNAL_IGNORE_BUT_WARN(...)
+#endif
+
+#if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10)
+# undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
+#elif defined(__clang__) && (__clang_major__ < 5)
+# undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
+#endif
+
+#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS)
+# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS
#endif
#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
@@ -445,7 +507,7 @@ namespace Catch {
SourceLineInfo( SourceLineInfo&& ) noexcept = default;
SourceLineInfo& operator = ( SourceLineInfo&& ) noexcept = default;
- bool empty() const noexcept;
+ bool empty() const noexcept { return file[0] == '\0'; }
bool operator == ( SourceLineInfo const& other ) const noexcept;
bool operator < ( SourceLineInfo const& other ) const noexcept;
@@ -486,9 +548,10 @@ namespace Catch {
} // end namespace Catch
#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \
+ CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \
- CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
+ CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
// end catch_tag_alias_autoregistrar.h
// start catch_test_registry.h
@@ -515,6 +578,7 @@ namespace Catch {
virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const = 0;
};
+ bool isThrowSafe( TestCase const& testCase, IConfig const& config );
bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
@@ -527,53 +591,30 @@ namespace Catch {
#include <cstddef>
#include <string>
#include <iosfwd>
+#include <cassert>
namespace Catch {
/// A non-owning string class (similar to the forthcoming std::string_view)
/// Note that, because a StringRef may be a substring of another string,
- /// it may not be null terminated. c_str() must return a null terminated
- /// string, however, and so the StringRef will internally take ownership
- /// (taking a copy), if necessary. In theory this ownership is not externally
- /// visible - but it does mean (substring) StringRefs should not be shared between
- /// threads.
+ /// it may not be null terminated.
class StringRef {
public:
using size_type = std::size_t;
+ using const_iterator = const char*;
private:
- friend struct StringRefTestAccess;
-
- char const* m_start;
- size_type m_size;
-
- char* m_data = nullptr;
-
- void takeOwnership();
-
static constexpr char const* const s_empty = "";
- public: // construction/ assignment
- StringRef() noexcept
- : StringRef( s_empty, 0 )
- {}
-
- StringRef( StringRef const& other ) noexcept
- : m_start( other.m_start ),
- m_size( other.m_size )
- {}
+ char const* m_start = s_empty;
+ size_type m_size = 0;
- StringRef( StringRef&& other ) noexcept
- : m_start( other.m_start ),
- m_size( other.m_size ),
- m_data( other.m_data )
- {
- other.m_data = nullptr;
- }
+ public: // construction
+ constexpr StringRef() noexcept = default;
StringRef( char const* rawChars ) noexcept;
- StringRef( char const* rawChars, size_type size ) noexcept
+ constexpr StringRef( char const* rawChars, size_type size ) noexcept
: m_start( rawChars ),
m_size( size )
{}
@@ -583,101 +624,64 @@ namespace Catch {
m_size( stdString.size() )
{}
- ~StringRef() noexcept {
- delete[] m_data;
- }
-
- auto operator = ( StringRef const &other ) noexcept -> StringRef& {
- delete[] m_data;
- m_data = nullptr;
- m_start = other.m_start;
- m_size = other.m_size;
- return *this;
+ explicit operator std::string() const {
+ return std::string(m_start, m_size);
}
- operator std::string() const;
-
- void swap( StringRef& other ) noexcept;
-
public: // operators
auto operator == ( StringRef const& other ) const noexcept -> bool;
- auto operator != ( StringRef const& other ) const noexcept -> bool;
+ auto operator != (StringRef const& other) const noexcept -> bool {
+ return !(*this == other);
+ }
- auto operator[] ( size_type index ) const noexcept -> char;
+ auto operator[] ( size_type index ) const noexcept -> char {
+ assert(index < m_size);
+ return m_start[index];
+ }
public: // named queries
- auto empty() const noexcept -> bool {
+ constexpr auto empty() const noexcept -> bool {
return m_size == 0;
}
- auto size() const noexcept -> size_type {
+ constexpr auto size() const noexcept -> size_type {
return m_size;
}
- auto numberOfCharacters() const noexcept -> size_type;
+ // Returns the current start pointer. If the StringRef is not
+ // null-terminated, throws std::domain_exception
auto c_str() const -> char const*;
public: // substrings and searches
- auto substr( size_type start, size_type size ) const noexcept -> StringRef;
+ // Returns a substring of [start, start + length).
+ // If start + length > size(), then the substring is [start, size()).
+ // If start > size(), then the substring is empty.
+ auto substr( size_type start, size_type length ) const noexcept -> StringRef;
- // Returns the current start pointer.
- // Note that the pointer can change when if the StringRef is a substring
- auto currentData() const noexcept -> char const*;
+ // Returns the current start pointer. May not be null-terminated.
+ auto data() const noexcept -> char const*;
- private: // ownership queries - may not be consistent between calls
- auto isOwned() const noexcept -> bool;
- auto isSubstring() const noexcept -> bool;
- };
+ constexpr auto isNullTerminated() const noexcept -> bool {
+ return m_start[m_size] == '\0';
+ }
- auto operator + ( StringRef const& lhs, StringRef const& rhs ) -> std::string;
- auto operator + ( StringRef const& lhs, char const* rhs ) -> std::string;
- auto operator + ( char const* lhs, StringRef const& rhs ) -> std::string;
+ public: // iterators
+ constexpr const_iterator begin() const { return m_start; }
+ constexpr const_iterator end() const { return m_start + m_size; }
+ };
auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&;
auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&;
- inline auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef {
+ constexpr auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef {
return StringRef( rawChars, size );
}
-
} // namespace Catch
-inline auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef {
+constexpr auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef {
return Catch::StringRef( rawChars, size );
}
// end catch_stringref.h
-// start catch_type_traits.hpp
-
-
-#include <type_traits>
-
-namespace Catch{
-
-#ifdef CATCH_CPP17_OR_GREATER
- template <typename...>
- inline constexpr auto is_unique = std::true_type{};
-
- template <typename T, typename... Rest>
- inline constexpr auto is_unique<T, Rest...> = std::bool_constant<
- (!std::is_same_v<T, Rest> && ...) && is_unique<Rest...>
- >{};
-#else
-
-template <typename...>
-struct is_unique : std::true_type{};
-
-template <typename T0, typename T1, typename... Rest>
-struct is_unique<T0, T1, Rest...> : std::integral_constant
-<bool,
- !std::is_same<T0, T1>::value
- && is_unique<T0, Rest...>::value
- && is_unique<T1, Rest...>::value
->{};
-
-#endif
-}
-
-// end catch_type_traits.hpp
// start catch_preprocessor.hpp
@@ -762,7 +766,7 @@ struct is_unique<T0, T1, Rest...> : std::integral_constant
#define INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_0, _1, _2, _3) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_1, _2, _3)
#define INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_0, _1, _2, _3, _4) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_1, _2, _3, _4)
#define INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_0, _1, _2, _3, _4, _5) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_1, _2, _3, _4, _5)
-#define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _4, _5, _6)
+#define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _3, _4, _5, _6)
#define INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_0, _1, _2, _3, _4, _5, _6, _7) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_1, _2, _3, _4, _5, _6, _7)
#define INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_1, _2, _3, _4, _5, _6, _7, _8)
#define INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9)
@@ -774,35 +778,49 @@ struct is_unique<T0, T1, Rest...> : std::integral_constant
template<typename...> struct TypeList {};\
template<typename...Ts>\
constexpr auto get_wrapper() noexcept -> TypeList<Ts...> { return {}; }\
+ template<template<typename...> class...> struct TemplateTypeList{};\
+ template<template<typename...> class...Cs>\
+ constexpr auto get_wrapper() noexcept -> TemplateTypeList<Cs...> { return {}; }\
+ template<typename...>\
+ struct append;\
+ template<typename...>\
+ struct rewrap;\
+ template<template<typename...> class, typename...>\
+ struct create;\
+ template<template<typename...> class, typename>\
+ struct convert;\
\
- template<template<typename...> class L1, typename...E1, template<typename...> class L2, typename...E2> \
- constexpr auto append(L1<E1...>, L2<E2...>) noexcept -> L1<E1...,E2...> { return {}; }\
+ template<typename T> \
+ struct append<T> { using type = T; };\
template< template<typename...> class L1, typename...E1, template<typename...> class L2, typename...E2, typename...Rest>\
- constexpr auto append(L1<E1...>, L2<E2...>, Rest...) noexcept -> decltype(append(L1<E1...,E2...>{}, Rest{}...)) { return {}; }\
+ struct append<L1<E1...>, L2<E2...>, Rest...> { using type = typename append<L1<E1...,E2...>, Rest...>::type; };\
template< template<typename...> class L1, typename...E1, typename...Rest>\
- constexpr auto append(L1<E1...>, TypeList<mpl_::na>, Rest...) noexcept -> L1<E1...> { return {}; }\
+ struct append<L1<E1...>, TypeList<mpl_::na>, Rest...> { using type = L1<E1...>; };\
\
template< template<typename...> class Container, template<typename...> class List, typename...elems>\
- constexpr auto rewrap(List<elems...>) noexcept -> TypeList<Container<elems...>> { return {}; }\
+ struct rewrap<TemplateTypeList<Container>, List<elems...>> { using type = TypeList<Container<elems...>>; };\
template< template<typename...> class Container, template<typename...> class List, class...Elems, typename...Elements>\
- constexpr auto rewrap(List<Elems...>,Elements...) noexcept -> decltype(append(TypeList<Container<Elems...>>{}, rewrap<Container>(Elements{}...))) { return {}; }\
+ struct rewrap<TemplateTypeList<Container>, List<Elems...>, Elements...> { using type = typename append<TypeList<Container<Elems...>>, typename rewrap<TemplateTypeList<Container>, Elements...>::type>::type; };\
\
template<template <typename...> class Final, template< typename...> class...Containers, typename...Types>\
- constexpr auto create(TypeList<Types...>) noexcept -> decltype(append(Final<>{}, rewrap<Containers>(Types{}...)...)) { return {}; }\
+ struct create<Final, TemplateTypeList<Containers...>, TypeList<Types...>> { using type = typename append<Final<>, typename rewrap<TemplateTypeList<Containers>, Types...>::type...>::type; };\
template<template <typename...> class Final, template <typename...> class List, typename...Ts>\
- constexpr auto convert(List<Ts...>) noexcept -> decltype(append(Final<>{},TypeList<Ts>{}...)) { return {}; }
+ struct convert<Final, List<Ts...>> { using type = typename append<Final<>,TypeList<Ts>...>::type; };
#define INTERNAL_CATCH_NTTP_1(signature, ...)\
template<INTERNAL_CATCH_REMOVE_PARENS(signature)> struct Nttp{};\
template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\
constexpr auto get_wrapper() noexcept -> Nttp<__VA_ARGS__> { return {}; } \
+ template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...> struct NttpTemplateTypeList{};\
+ template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...Cs>\
+ constexpr auto get_wrapper() noexcept -> NttpTemplateTypeList<Cs...> { return {}; } \
\
template< template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature)>\
- constexpr auto rewrap(List<__VA_ARGS__>) noexcept -> TypeList<Container<__VA_ARGS__>> { return {}; }\
+ struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>> { using type = TypeList<Container<__VA_ARGS__>>; };\
template< template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature), typename...Elements>\
- constexpr auto rewrap(List<__VA_ARGS__>,Elements...elems) noexcept -> decltype(append(TypeList<Container<__VA_ARGS__>>{}, rewrap<Container>(elems...))) { return {}; }\
+ struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>, Elements...> { using type = typename append<TypeList<Container<__VA_ARGS__>>, typename rewrap<NttpTemplateTypeList<Container>, Elements...>::type>::type; };\
template<template <typename...> class Final, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...Containers, typename...Types>\
- constexpr auto create(TypeList<Types...>) noexcept -> decltype(append(Final<>{}, rewrap<Containers>(Types{}...)...)) { return {}; }
+ struct create<Final, NttpTemplateTypeList<Containers...>, TypeList<Types...>> { using type = typename append<Final<>, typename rewrap<NttpTemplateTypeList<Containers>, Types...>::type...>::type; };
#define INTERNAL_CATCH_DECLARE_SIG_TEST0(TestName)
#define INTERNAL_CATCH_DECLARE_SIG_TEST1(TestName, signature)\
@@ -898,22 +916,33 @@ struct is_unique<T0, T1, Rest...> : std::integral_constant
#include <type_traits>
namespace Catch {
-template<typename T>
-struct always_false : std::false_type {};
+ template<typename T>
+ struct always_false : std::false_type {};
+
+ template <typename> struct true_given : std::true_type {};
+ struct is_callable_tester {
+ template <typename Fun, typename... Args>
+ true_given<decltype(std::declval<Fun>()(std::declval<Args>()...))> static test(int);
+ template <typename...>
+ std::false_type static test(...);
+ };
-template <typename> struct true_given : std::true_type {};
-struct is_callable_tester {
- template <typename Fun, typename... Args>
- true_given<decltype(std::declval<Fun>()(std::declval<Args>()...))> static test(int);
- template <typename...>
- std::false_type static test(...);
-};
+ template <typename T>
+ struct is_callable;
-template <typename T>
-struct is_callable;
+ template <typename Fun, typename... Args>
+ struct is_callable<Fun(Args...)> : decltype(is_callable_tester::test<Fun, Args...>(0)) {};
-template <typename Fun, typename... Args>
-struct is_callable<Fun(Args...)> : decltype(is_callable_tester::test<Fun, Args...>(0)) {};
+#if defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703
+ // std::result_of is deprecated in C++17 and removed in C++20. Hence, it is
+ // replaced with std::invoke_result here.
+ template <typename Func, typename... U>
+ using FunctionReturnType = std::remove_reference_t<std::remove_cv_t<std::invoke_result_t<Func, U...>>>;
+#else
+ // Keep ::type here because we still support C++11
+ template <typename Func, typename... U>
+ using FunctionReturnType = typename std::remove_reference<typename std::remove_cv<typename std::result_of<Func(U...)>::type>::type>::type;
+#endif
} // namespace Catch
@@ -1012,21 +1041,24 @@ struct AutoReg : NonCopyable {
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
static void TestName(); \
+ CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
- CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
+ CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
static void TestName()
#define INTERNAL_CATCH_TESTCASE( ... ) \
INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ )
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
+ CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
- CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
+ CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
+ CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
namespace{ \
struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
@@ -1034,21 +1066,24 @@ struct AutoReg : NonCopyable {
}; \
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
} \
- CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
+ CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
void TestName::test()
#define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ )
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
+ CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
- CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
+ CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(TestName, TestFunc, Name, Tags, Signature, ... )\
+ CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
+ CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
INTERNAL_CATCH_DECLARE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature));\
namespace {\
namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\
@@ -1061,7 +1096,7 @@ struct AutoReg : NonCopyable {
int index = 0; \
constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\
using expander = int[];\
- (void)expander{(reg_test(Types{}, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++, 0)... };/* NOLINT */ \
+ (void)expander{(reg_test(Types{}, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++)... };/* NOLINT */ \
}\
};\
static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
@@ -1070,8 +1105,7 @@ struct AutoReg : NonCopyable {
}();\
}\
}\
- CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
- CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS \
+ CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc,INTERNAL_CATCH_REMOVE_PARENS(Signature))
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
@@ -1091,8 +1125,10 @@ struct AutoReg : NonCopyable {
#endif
#define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(TestName, TestFuncName, Name, Tags, Signature, TmplTypes, TypesList) \
+ CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
+ CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
template<typename TestType> static void TestFuncName(); \
namespace {\
namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) { \
@@ -1106,19 +1142,18 @@ struct AutoReg : NonCopyable {
constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
- (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFuncName<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + "<" + std::string(types_list[index % num_types]) + ">", Tags } ), index++, 0)... };/* NOLINT */\
+ (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFuncName<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + "<" + std::string(types_list[index % num_types]) + ">", Tags } ), index++)... };/* NOLINT */\
} \
}; \
static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
- using TestInit = decltype(create<TestName, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>(TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>{})); \
+ using TestInit = typename create<TestName, decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>()), TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>>::type; \
TestInit t; \
t.reg_tests(); \
return 0; \
}(); \
} \
} \
- CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
- CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS \
+ CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
template<typename TestType> \
static void TestFuncName()
@@ -1139,7 +1174,9 @@ struct AutoReg : NonCopyable {
#endif
#define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2(TestName, TestFunc, Name, Tags, TmplList)\
+ CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
+ CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
template<typename TestType> static void TestFunc(); \
namespace {\
namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\
@@ -1149,17 +1186,17 @@ struct AutoReg : NonCopyable {
void reg_tests() { \
int index = 0; \
using expander = int[]; \
- (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFunc<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++, 0)... };/* NOLINT */\
+ (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFunc<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++)... };/* NOLINT */\
} \
};\
static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
- using TestInit = decltype(convert<TestName>(TmplList {})); \
+ using TestInit = typename convert<TestName, TmplList>::type; \
TestInit t; \
t.reg_tests(); \
return 0; \
- }(); \
+ }(); \
}}\
- CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
+ CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
template<typename TestType> \
static void TestFunc()
@@ -1167,8 +1204,10 @@ struct AutoReg : NonCopyable {
INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, TmplList )
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... ) \
+ CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
+ CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
namespace {\
namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){ \
INTERNAL_CATCH_TYPE_GEN\
@@ -1181,7 +1220,7 @@ struct AutoReg : NonCopyable {
int index = 0; \
constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\
using expander = int[];\
- (void)expander{(reg_test(Types{}, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++, 0)... };/* NOLINT */ \
+ (void)expander{(reg_test(Types{}, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++)... };/* NOLINT */ \
}\
};\
static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
@@ -1190,8 +1229,7 @@ struct AutoReg : NonCopyable {
}();\
}\
}\
- CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS\
- CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS\
+ CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
@@ -1211,8 +1249,10 @@ struct AutoReg : NonCopyable {
#endif
#define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, Signature, TmplTypes, TypesList)\
+ CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \
+ CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
template<typename TestType> \
struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
void test();\
@@ -1229,19 +1269,18 @@ struct AutoReg : NonCopyable {
constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
- (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + "<" + std::string(types_list[index % num_types]) + ">", Tags } ), index++, 0)... };/* NOLINT */ \
+ (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + "<" + std::string(types_list[index % num_types]) + ">", Tags } ), index++)... };/* NOLINT */ \
}\
};\
static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
- using TestInit = decltype(create<TestNameClass, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>(TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>{}));\
+ using TestInit = typename create<TestNameClass, decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>()), TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>>::type;\
TestInit t;\
t.reg_tests();\
return 0;\
}(); \
}\
}\
- CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
- CATCH_INTERNAL_UNSUPPRESS_ZERO_VARIADIC_WARNINGS \
+ CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
template<typename TestType> \
void TestName<TestType>::test()
@@ -1262,7 +1301,9 @@ struct AutoReg : NonCopyable {
#endif
#define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, TmplList) \
+ CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
+ CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \
template<typename TestType> \
struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
void test();\
@@ -1275,17 +1316,17 @@ struct AutoReg : NonCopyable {
void reg_tests(){\
int index = 0;\
using expander = int[];\
- (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++, 0)... };/* NOLINT */ \
+ (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++)... };/* NOLINT */ \
}\
};\
static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
- using TestInit = decltype(convert<TestNameClass>(TmplList {}));\
+ using TestInit = typename convert<TestNameClass, TmplList>::type;\
TestInit t;\
t.reg_tests();\
return 0;\
}(); \
}}\
- CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
+ CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
template<typename TestType> \
void TestName<TestType>::test()
@@ -1391,7 +1432,7 @@ namespace Catch {
auto makeStream( StringRef const &filename ) -> IStream const*;
- class ReusableStringStream {
+ class ReusableStringStream : NonCopyable {
std::size_t m_index;
std::ostream* m_oss;
public:
@@ -1419,7 +1460,7 @@ namespace Catch {
namespace Detail {
struct EnumInfo {
StringRef m_name;
- std::vector<std::pair<int, std::string>> m_values;
+ std::vector<std::pair<int, StringRef>> m_values;
~EnumInfo();
@@ -1434,6 +1475,7 @@ namespace Catch {
template<typename E>
Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::initializer_list<E> values ) {
+ static_assert(sizeof(int) >= sizeof(E), "Cannot serialize enum to int");
std::vector<int> intValues;
intValues.reserve( values.size() );
for( auto enumValue : values )
@@ -1515,9 +1557,9 @@ namespace Catch {
template<typename T>
class IsStreamInsertable {
- template<typename SS, typename TT>
+ template<typename Stream, typename U>
static auto test(int)
- -> decltype(std::declval<SS&>() << std::declval<TT>(), std::true_type());
+ -> decltype(std::declval<Stream&>() << std::declval<U>(), std::true_type());
template<typename, typename>
static auto test(...)->std::false_type;
@@ -1679,6 +1721,12 @@ namespace Catch {
}
};
+#if defined(CATCH_CONFIG_CPP17_BYTE)
+ template<>
+ struct StringMaker<std::byte> {
+ static std::string convert(std::byte value);
+ };
+#endif // defined(CATCH_CONFIG_CPP17_BYTE)
template<>
struct StringMaker<int> {
static std::string convert(int value);
@@ -1772,8 +1820,8 @@ namespace Catch {
#endif
namespace Detail {
- template<typename InputIterator>
- std::string rangeToString(InputIterator first, InputIterator last) {
+ template<typename InputIterator, typename Sentinel = InputIterator>
+ std::string rangeToString(InputIterator first, Sentinel last) {
ReusableStringStream rss;
rss << "{ ";
if (first != last) {
@@ -1931,20 +1979,27 @@ namespace Catch {
#endif // CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER
namespace Catch {
- struct not_this_one {}; // Tag type for detecting which begin/ end are being selected
-
- // Import begin/ end from std here so they are considered alongside the fallback (...) overloads in this namespace
+ // Import begin/ end from std here
using std::begin;
using std::end;
- not_this_one begin( ... );
- not_this_one end( ... );
+ namespace detail {
+ template <typename...>
+ struct void_type {
+ using type = void;
+ };
+
+ template <typename T, typename = void>
+ struct is_range_impl : std::false_type {
+ };
+
+ template <typename T>
+ struct is_range_impl<T, typename void_type<decltype(begin(std::declval<T>()))>::type> : std::true_type {
+ };
+ } // namespace detail
template <typename T>
- struct is_range {
- static const bool value =
- !std::is_same<decltype(begin(std::declval<T>())), not_this_one>::value &&
- !std::is_same<decltype(end(std::declval<T>())), not_this_one>::value;
+ struct is_range : detail::is_range_impl<T> {
};
#if defined(_MANAGED) // Managed types are never ranges
@@ -2114,7 +2169,7 @@ namespace Catch { \
template<> struct StringMaker<enumName> { \
static std::string convert( enumName value ) { \
static const auto& enumInfo = ::Catch::getMutableRegistryHub().getMutableEnumValuesRegistry().registerEnum( #enumName, #__VA_ARGS__, { __VA_ARGS__ } ); \
- return enumInfo.lookup( static_cast<int>( value ) ); \
+ return static_cast<std::string>(enumInfo.lookup( static_cast<int>( value ) )); \
} \
}; \
}
@@ -2312,6 +2367,18 @@ namespace Catch {
auto operator <= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {
return { static_cast<bool>(m_lhs <= rhs), m_lhs, "<=", rhs };
}
+ template <typename RhsT>
+ auto operator | (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const {
+ return { static_cast<bool>(m_lhs | rhs), m_lhs, "|", rhs };
+ }
+ template <typename RhsT>
+ auto operator & (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const {
+ return { static_cast<bool>(m_lhs & rhs), m_lhs, "&", rhs };
+ }
+ template <typename RhsT>
+ auto operator ^ (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const {
+ return { static_cast<bool>(m_lhs ^ rhs), m_lhs, "^", rhs };
+ }
template<typename RhsT>
auto operator && ( RhsT const& ) -> BinaryExpr<LhsT, RhsT const&> const {
@@ -2392,7 +2459,7 @@ namespace Catch {
virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;
virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;
- virtual auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& = 0;
+ virtual auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& = 0;
#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
virtual void benchmarkPreparing( std::string const& name ) = 0;
@@ -2630,15 +2697,16 @@ namespace Catch {
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \
do { \
+ CATCH_INTERNAL_IGNORE_BUT_WARN(__VA_ARGS__); \
Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \
INTERNAL_CATCH_TRY { \
+ CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
catchAssertionHandler.handleExpr( Catch::Decomposer() <= __VA_ARGS__ ); \
- CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
+ CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
} INTERNAL_CATCH_CATCH( catchAssertionHandler ) \
INTERNAL_CATCH_REACT( catchAssertionHandler ) \
- } while( (void)0, (false) && static_cast<bool>( !!(__VA_ARGS__) ) ) // the expression here is never evaluated at runtime but it forces the compiler to give it a look
- // The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&.
+ } while( (void)0, (false) && static_cast<bool>( !!(__VA_ARGS__) ) )
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_IF( macroName, resultDisposition, ... ) \
@@ -2855,14 +2923,16 @@ namespace Catch {
} // end namespace Catch
#define INTERNAL_CATCH_SECTION( ... ) \
+ CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) \
- CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS
+ CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
#define INTERNAL_CATCH_DYNAMIC_SECTION( ... ) \
+ CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \
if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, (Catch::ReusableStringStream() << __VA_ARGS__).str() ) ) \
- CATCH_INTERNAL_UNSUPPRESS_UNUSED_WARNINGS
+ CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
// end catch_section.h
// start catch_interfaces_exception.h
@@ -2953,6 +3023,9 @@ namespace Catch {
{}
std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const override {
+#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
+ return "";
+#else
try {
if( it == itEnd )
std::rethrow_exception(std::current_exception());
@@ -2962,6 +3035,7 @@ namespace Catch {
catch( T& ex ) {
return m_translateFunction( ex );
}
+#endif
}
protected:
@@ -2980,9 +3054,10 @@ namespace Catch {
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \
static std::string translatorName( signature ); \
+ CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); } \
- CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
+ CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
static std::string translatorName( signature )
#define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
@@ -3124,7 +3199,10 @@ namespace Catch {
bool contains( std::string const& s, std::string const& infix );
void toLowerInPlace( std::string& s );
std::string toLower( std::string const& s );
+ //! Returns a new string without whitespace at the start/end
std::string trim( std::string const& str );
+ //! Returns a substring of the original ref without whitespace. Beware lifetimes!
+ StringRef trim(StringRef ref);
// !!! Be aware, returns refs into original string - make sure original string outlives them
std::vector<StringRef> splitStringRef( StringRef str, char delimiter );
@@ -3180,6 +3258,15 @@ namespace Matchers {
virtual bool match( ObjectT const& arg ) const = 0;
};
+#if defined(__OBJC__)
+ // Hack to fix Catch GH issue #1661. Could use id for generic Object support.
+ // use of const for Object pointers is very uncommon and under ARC it causes some kind of signature mismatch that breaks compilation
+ template<>
+ struct MatcherMethod<NSString*> {
+ virtual bool match( NSString* arg ) const = 0;
+ };
+#endif
+
#ifdef __clang__
# pragma clang diagnostic pop
#endif
@@ -3217,9 +3304,10 @@ namespace Matchers {
return description;
}
- MatchAllOf<ArgT>& operator && ( MatcherBase<ArgT> const& other ) {
- m_matchers.push_back( &other );
- return *this;
+ MatchAllOf<ArgT> operator && ( MatcherBase<ArgT> const& other ) {
+ auto copy(*this);
+ copy.m_matchers.push_back( &other );
+ return copy;
}
std::vector<MatcherBase<ArgT> const*> m_matchers;
@@ -3250,9 +3338,10 @@ namespace Matchers {
return description;
}
- MatchAnyOf<ArgT>& operator || ( MatcherBase<ArgT> const& other ) {
- m_matchers.push_back( &other );
- return *this;
+ MatchAnyOf<ArgT> operator || ( MatcherBase<ArgT> const& other ) {
+ auto copy(*this);
+ copy.m_matchers.push_back( &other );
+ return copy;
}
std::vector<MatcherBase<ArgT> const*> m_matchers;
@@ -3296,10 +3385,34 @@ using Matchers::Impl::MatcherBase;
} // namespace Catch
// end catch_matchers.h
-// start catch_matchers_floating.h
+// start catch_matchers_exception.hpp
-#include <type_traits>
-#include <cmath>
+namespace Catch {
+namespace Matchers {
+namespace Exception {
+
+class ExceptionMessageMatcher : public MatcherBase<std::exception> {
+ std::string m_message;
+public:
+
+ ExceptionMessageMatcher(std::string const& message):
+ m_message(message)
+ {}
+
+ bool match(std::exception const& ex) const override;
+
+ std::string describe() const override;
+};
+
+} // namespace Exception
+
+Exception::ExceptionMessageMatcher Message(std::string const& message);
+
+} // namespace Matchers
+} // namespace Catch
+
+// end catch_matchers_exception.hpp
+// start catch_matchers_floating.h
namespace Catch {
namespace Matchers {
@@ -3318,22 +3431,43 @@ namespace Matchers {
};
struct WithinUlpsMatcher : MatcherBase<double> {
- WithinUlpsMatcher(double target, int ulps, FloatingPointKind baseType);
+ WithinUlpsMatcher(double target, uint64_t ulps, FloatingPointKind baseType);
bool match(double const& matchee) const override;
std::string describe() const override;
private:
double m_target;
- int m_ulps;
+ uint64_t m_ulps;
FloatingPointKind m_type;
};
+ // Given IEEE-754 format for floats and doubles, we can assume
+ // that float -> double promotion is lossless. Given this, we can
+ // assume that if we do the standard relative comparison of
+ // |lhs - rhs| <= epsilon * max(fabs(lhs), fabs(rhs)), then we get
+ // the same result if we do this for floats, as if we do this for
+ // doubles that were promoted from floats.
+ struct WithinRelMatcher : MatcherBase<double> {
+ WithinRelMatcher(double target, double epsilon);
+ bool match(double const& matchee) const override;
+ std::string describe() const override;
+ private:
+ double m_target;
+ double m_epsilon;
+ };
+
} // namespace Floating
// The following functions create the actual matcher objects.
// This allows the types to be inferred
- Floating::WithinUlpsMatcher WithinULP(double target, int maxUlpDiff);
- Floating::WithinUlpsMatcher WithinULP(float target, int maxUlpDiff);
+ Floating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff);
+ Floating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff);
Floating::WithinAbsMatcher WithinAbs(double target, double margin);
+ Floating::WithinRelMatcher WithinRel(double target, double eps);
+ // defaults epsilon to 100*numeric_limits<double>::epsilon()
+ Floating::WithinRelMatcher WithinRel(double target);
+ Floating::WithinRelMatcher WithinRel(float target, float eps);
+ // defaults epsilon to 100*numeric_limits<float>::epsilon()
+ Floating::WithinRelMatcher WithinRel(float target);
} // namespace Matchers
} // namespace Catch
@@ -3464,12 +3598,12 @@ namespace Catch {
namespace Matchers {
namespace Vector {
- template<typename T>
- struct ContainsElementMatcher : MatcherBase<std::vector<T>> {
+ template<typename T, typename Alloc>
+ struct ContainsElementMatcher : MatcherBase<std::vector<T, Alloc>> {
ContainsElementMatcher(T const &comparator) : m_comparator( comparator) {}
- bool match(std::vector<T> const &v) const override {
+ bool match(std::vector<T, Alloc> const &v) const override {
for (auto const& el : v) {
if (el == m_comparator) {
return true;
@@ -3485,12 +3619,12 @@ namespace Matchers {
T const& m_comparator;
};
- template<typename T>
- struct ContainsMatcher : MatcherBase<std::vector<T>> {
+ template<typename T, typename AllocComp, typename AllocMatch>
+ struct ContainsMatcher : MatcherBase<std::vector<T, AllocMatch>> {
- ContainsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {}
+ ContainsMatcher(std::vector<T, AllocComp> const &comparator) : m_comparator( comparator ) {}
- bool match(std::vector<T> const &v) const override {
+ bool match(std::vector<T, AllocMatch> const &v) const override {
// !TBD: see note in EqualsMatcher
if (m_comparator.size() > v.size())
return false;
@@ -3512,18 +3646,18 @@ namespace Matchers {
return "Contains: " + ::Catch::Detail::stringify( m_comparator );
}
- std::vector<T> const& m_comparator;
+ std::vector<T, AllocComp> const& m_comparator;
};
- template<typename T>
- struct EqualsMatcher : MatcherBase<std::vector<T>> {
+ template<typename T, typename AllocComp, typename AllocMatch>
+ struct EqualsMatcher : MatcherBase<std::vector<T, AllocMatch>> {
- EqualsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {}
+ EqualsMatcher(std::vector<T, AllocComp> const &comparator) : m_comparator( comparator ) {}
- bool match(std::vector<T> const &v) const override {
+ bool match(std::vector<T, AllocMatch> const &v) const override {
// !TBD: This currently works if all elements can be compared using !=
// - a more general approach would be via a compare template that defaults
- // to using !=. but could be specialised for, e.g. std::vector<T> etc
+ // to using !=. but could be specialised for, e.g. std::vector<T, Alloc> etc
// - then just call that directly
if (m_comparator.size() != v.size())
return false;
@@ -3535,15 +3669,15 @@ namespace Matchers {
std::string describe() const override {
return "Equals: " + ::Catch::Detail::stringify( m_comparator );
}
- std::vector<T> const& m_comparator;
+ std::vector<T, AllocComp> const& m_comparator;
};
- template<typename T>
- struct ApproxMatcher : MatcherBase<std::vector<T>> {
+ template<typename T, typename AllocComp, typename AllocMatch>
+ struct ApproxMatcher : MatcherBase<std::vector<T, AllocMatch>> {
- ApproxMatcher(std::vector<T> const& comparator) : m_comparator( comparator ) {}
+ ApproxMatcher(std::vector<T, AllocComp> const& comparator) : m_comparator( comparator ) {}
- bool match(std::vector<T> const &v) const override {
+ bool match(std::vector<T, AllocMatch> const &v) const override {
if (m_comparator.size() != v.size())
return false;
for (std::size_t i = 0; i < v.size(); ++i)
@@ -3570,16 +3704,14 @@ namespace Matchers {
return *this;
}
- std::vector<T> const& m_comparator;
+ std::vector<T, AllocComp> const& m_comparator;
mutable Catch::Detail::Approx approx = Catch::Detail::Approx::custom();
};
- template<typename T>
- struct UnorderedEqualsMatcher : MatcherBase<std::vector<T>> {
- UnorderedEqualsMatcher(std::vector<T> const& target) : m_target(target) {}
- bool match(std::vector<T> const& vec) const override {
- // Note: This is a reimplementation of std::is_permutation,
- // because I don't want to include <algorithm> inside the common path
+ template<typename T, typename AllocComp, typename AllocMatch>
+ struct UnorderedEqualsMatcher : MatcherBase<std::vector<T, AllocMatch>> {
+ UnorderedEqualsMatcher(std::vector<T, AllocComp> const& target) : m_target(target) {}
+ bool match(std::vector<T, AllocMatch> const& vec) const override {
if (m_target.size() != vec.size()) {
return false;
}
@@ -3590,7 +3722,7 @@ namespace Matchers {
return "UnorderedEquals: " + ::Catch::Detail::stringify(m_target);
}
private:
- std::vector<T> const& m_target;
+ std::vector<T, AllocComp> const& m_target;
};
} // namespace Vector
@@ -3598,29 +3730,29 @@ namespace Matchers {
// The following functions create the actual matcher objects.
// This allows the types to be inferred
- template<typename T>
- Vector::ContainsMatcher<T> Contains( std::vector<T> const& comparator ) {
- return Vector::ContainsMatcher<T>( comparator );
+ template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
+ Vector::ContainsMatcher<T, AllocComp, AllocMatch> Contains( std::vector<T, AllocComp> const& comparator ) {
+ return Vector::ContainsMatcher<T, AllocComp, AllocMatch>( comparator );
}
- template<typename T>
- Vector::ContainsElementMatcher<T> VectorContains( T const& comparator ) {
- return Vector::ContainsElementMatcher<T>( comparator );
+ template<typename T, typename Alloc = std::allocator<T>>
+ Vector::ContainsElementMatcher<T, Alloc> VectorContains( T const& comparator ) {
+ return Vector::ContainsElementMatcher<T, Alloc>( comparator );
}
- template<typename T>
- Vector::EqualsMatcher<T> Equals( std::vector<T> const& comparator ) {
- return Vector::EqualsMatcher<T>( comparator );
+ template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
+ Vector::EqualsMatcher<T, AllocComp, AllocMatch> Equals( std::vector<T, AllocComp> const& comparator ) {
+ return Vector::EqualsMatcher<T, AllocComp, AllocMatch>( comparator );
}
- template<typename T>
- Vector::ApproxMatcher<T> Approx( std::vector<T> const& comparator ) {
- return Vector::ApproxMatcher<T>( comparator );
+ template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
+ Vector::ApproxMatcher<T, AllocComp, AllocMatch> Approx( std::vector<T, AllocComp> const& comparator ) {
+ return Vector::ApproxMatcher<T, AllocComp, AllocMatch>( comparator );
}
- template<typename T>
- Vector::UnorderedEqualsMatcher<T> UnorderedEquals(std::vector<T> const& target) {
- return Vector::UnorderedEqualsMatcher<T>(target);
+ template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>
+ Vector::UnorderedEqualsMatcher<T, AllocComp, AllocMatch> UnorderedEquals(std::vector<T, AllocComp> const& target) {
+ return Vector::UnorderedEqualsMatcher<T, AllocComp, AllocMatch>( target );
}
} // namespace Matchers
@@ -3758,13 +3890,13 @@ namespace Catch {
(Catch::ReusableStringStream() << __VA_ARGS__).str()
#define CATCH_INTERNAL_ERROR(...) \
- Catch::throw_logic_error(CATCH_MAKE_MSG( CATCH_INTERNAL_LINEINFO << ": Internal Catch2 error: " << __VA_ARGS__));
+ Catch::throw_logic_error(CATCH_MAKE_MSG( CATCH_INTERNAL_LINEINFO << ": Internal Catch2 error: " << __VA_ARGS__))
#define CATCH_ERROR(...) \
- Catch::throw_domain_error(CATCH_MAKE_MSG( __VA_ARGS__ ));
+ Catch::throw_domain_error(CATCH_MAKE_MSG( __VA_ARGS__ ))
#define CATCH_RUNTIME_ERROR(...) \
- Catch::throw_runtime_error(CATCH_MAKE_MSG( __VA_ARGS__ ));
+ Catch::throw_runtime_error(CATCH_MAKE_MSG( __VA_ARGS__ ))
#define CATCH_ENFORCE( condition, ... ) \
do{ if( !(condition) ) CATCH_ERROR( __VA_ARGS__ ); } while(false)
@@ -3816,7 +3948,6 @@ namespace Generators {
class SingleValueGenerator final : public IGenerator<T> {
T m_value;
public:
- SingleValueGenerator(T const& value) : m_value( value ) {}
SingleValueGenerator(T&& value) : m_value(std::move(value)) {}
T const& get() const override {
@@ -3829,6 +3960,9 @@ namespace Generators {
template<typename T>
class FixedValuesGenerator final : public IGenerator<T> {
+ static_assert(!std::is_same<T, bool>::value,
+ "FixedValuesGenerator does not support bools because of std::vector<bool>"
+ "specialization, use SingleValue Generator instead.");
std::vector<T> m_values;
size_t m_idx = 0;
public:
@@ -3876,21 +4010,21 @@ namespace Generators {
m_generators.emplace_back(std::move(generator));
}
void populate(T&& val) {
- m_generators.emplace_back(value(std::move(val)));
+ m_generators.emplace_back(value(std::forward<T>(val)));
}
template<typename U>
void populate(U&& val) {
- populate(T(std::move(val)));
+ populate(T(std::forward<U>(val)));
}
template<typename U, typename... Gs>
- void populate(U&& valueOrGenerator, Gs... moreGenerators) {
+ void populate(U&& valueOrGenerator, Gs &&... moreGenerators) {
populate(std::forward<U>(valueOrGenerator));
populate(std::forward<Gs>(moreGenerators)...);
}
public:
template <typename... Gs>
- Generators(Gs... moreGenerators) {
+ Generators(Gs &&... moreGenerators) {
m_generators.reserve(sizeof...(Gs));
populate(std::forward<Gs>(moreGenerators)...);
}
@@ -3921,7 +4055,7 @@ namespace Generators {
struct as {};
template<typename T, typename... Gs>
- auto makeGenerators( GeneratorWrapper<T>&& generator, Gs... moreGenerators ) -> Generators<T> {
+ auto makeGenerators( GeneratorWrapper<T>&& generator, Gs &&... moreGenerators ) -> Generators<T> {
return Generators<T>(std::move(generator), std::forward<Gs>(moreGenerators)...);
}
template<typename T>
@@ -3929,24 +4063,24 @@ namespace Generators {
return Generators<T>(std::move(generator));
}
template<typename T, typename... Gs>
- auto makeGenerators( T&& val, Gs... moreGenerators ) -> Generators<T> {
+ auto makeGenerators( T&& val, Gs &&... moreGenerators ) -> Generators<T> {
return makeGenerators( value( std::forward<T>( val ) ), std::forward<Gs>( moreGenerators )... );
}
template<typename T, typename U, typename... Gs>
- auto makeGenerators( as<T>, U&& val, Gs... moreGenerators ) -> Generators<T> {
+ auto makeGenerators( as<T>, U&& val, Gs &&... moreGenerators ) -> Generators<T> {
return makeGenerators( value( T( std::forward<U>( val ) ) ), std::forward<Gs>( moreGenerators )... );
}
- auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker&;
+ auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker&;
template<typename L>
// Note: The type after -> is weird, because VS2015 cannot parse
// the expression used in the typedef inside, when it is in
// return type. Yeah.
- auto generate( SourceLineInfo const& lineInfo, L const& generatorExpression ) -> decltype(std::declval<decltype(generatorExpression())>().get()) {
+ auto generate( StringRef generatorName, SourceLineInfo const& lineInfo, L const& generatorExpression ) -> decltype(std::declval<decltype(generatorExpression())>().get()) {
using UnderlyingType = typename decltype(generatorExpression())::type;
- IGeneratorTracker& tracker = acquireGeneratorTracker( lineInfo );
+ IGeneratorTracker& tracker = acquireGeneratorTracker( generatorName, lineInfo );
if (!tracker.hasGenerator()) {
tracker.setGenerator(pf::make_unique<Generators<UnderlyingType>>(generatorExpression()));
}
@@ -3959,11 +4093,17 @@ namespace Generators {
} // namespace Catch
#define GENERATE( ... ) \
- Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [ ]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } )
+ Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \
+ CATCH_INTERNAL_LINEINFO, \
+ [ ]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
#define GENERATE_COPY( ... ) \
- Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [=]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } )
+ Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \
+ CATCH_INTERNAL_LINEINFO, \
+ [=]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
#define GENERATE_REF( ... ) \
- Catch::Generators::generate( CATCH_INTERNAL_LINEINFO, [&]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } )
+ Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \
+ CATCH_INTERNAL_LINEINFO, \
+ [&]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)
// end catch_generators.hpp
// start catch_generators_generic.hpp
@@ -4048,6 +4188,9 @@ namespace Generators {
template <typename T>
class RepeatGenerator : public IGenerator<T> {
+ static_assert(!std::is_same<T, bool>::value,
+ "RepeatGenerator currently does not support bools"
+ "because of std::vector<bool> specialization");
GeneratorWrapper<T> m_generator;
mutable std::vector<T> m_returned;
size_t m_target_repeats;
@@ -4126,18 +4269,7 @@ namespace Generators {
}
};
-#if defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703
- // std::result_of is deprecated in C++17 and removed in C++20. Hence, it is
- // replaced with std::invoke_result here. Also *_t format is preferred over
- // typename *::type format.
- template <typename Func, typename U>
- using MapFunctionReturnType = std::remove_reference_t<std::remove_cv_t<std::invoke_result_t<Func, U>>>;
-#else
- template <typename Func, typename U>
- using MapFunctionReturnType = typename std::remove_reference<typename std::remove_cv<typename std::result_of<Func(U)>::type>::type>::type;
-#endif
-
- template <typename Func, typename U, typename T = MapFunctionReturnType<Func, U>>
+ template <typename Func, typename U, typename T = FunctionReturnType<Func, U>>
GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) {
return GeneratorWrapper<T>(
pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator))
@@ -4162,12 +4294,14 @@ namespace Generators {
m_chunk_size(size), m_generator(std::move(generator))
{
m_chunk.reserve(m_chunk_size);
- m_chunk.push_back(m_generator.get());
- for (size_t i = 1; i < m_chunk_size; ++i) {
- if (!m_generator.next()) {
- Catch::throw_exception(GeneratorException("Not enough values to initialize the first chunk"));
- }
+ if (m_chunk_size != 0) {
m_chunk.push_back(m_generator.get());
+ for (size_t i = 1; i < m_chunk_size; ++i) {
+ if (!m_generator.next()) {
+ Catch::throw_exception(GeneratorException("Not enough values to initialize the first chunk"));
+ }
+ m_chunk.push_back(m_generator.get());
+ }
}
}
std::vector<T> const& get() const override {
@@ -4238,6 +4372,7 @@ namespace Catch {
{
if( !IMutableContext::currentContext )
IMutableContext::createContext();
+ // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn)
return *IMutableContext::currentContext;
}
@@ -4247,6 +4382,9 @@ namespace Catch {
}
void cleanUpContext();
+
+ class SimplePcg32;
+ SimplePcg32& rng();
}
// end catch_context.h
@@ -4317,6 +4455,7 @@ namespace Catch {
} // end namespace Catch
// end catch_option.hpp
+#include <chrono>
#include <iosfwd>
#include <string>
#include <vector>
@@ -4374,6 +4513,7 @@ namespace Catch {
virtual int abortAfter() const = 0;
virtual bool showInvisibles() const = 0;
virtual ShowDurations::OrNot showDurations() const = 0;
+ virtual double minDuration() const = 0;
virtual TestSpec const& testSpec() const = 0;
virtual bool hasTestFilters() const = 0;
virtual std::vector<std::string> const& getTestsOrTags() const = 0;
@@ -4387,12 +4527,63 @@ namespace Catch {
virtual int benchmarkSamples() const = 0;
virtual double benchmarkConfidenceInterval() const = 0;
virtual unsigned int benchmarkResamples() const = 0;
+ virtual std::chrono::milliseconds benchmarkWarmupTime() const = 0;
};
using IConfigPtr = std::shared_ptr<IConfig const>;
}
// end catch_interfaces_config.h
+// start catch_random_number_generator.h
+
+#include <cstdint>
+
+namespace Catch {
+
+ // This is a simple implementation of C++11 Uniform Random Number
+ // Generator. It does not provide all operators, because Catch2
+ // does not use it, but it should behave as expected inside stdlib's
+ // distributions.
+ // The implementation is based on the PCG family (http://pcg-random.org)
+ class SimplePcg32 {
+ using state_type = std::uint64_t;
+ public:
+ using result_type = std::uint32_t;
+ static constexpr result_type (min)() {
+ return 0;
+ }
+ static constexpr result_type (max)() {
+ return static_cast<result_type>(-1);
+ }
+
+ // Provide some default initial state for the default constructor
+ SimplePcg32():SimplePcg32(0xed743cc4U) {}
+
+ explicit SimplePcg32(result_type seed_);
+
+ void seed(result_type seed_);
+ void discard(uint64_t skip);
+
+ result_type operator()();
+
+ private:
+ friend bool operator==(SimplePcg32 const& lhs, SimplePcg32 const& rhs);
+ friend bool operator!=(SimplePcg32 const& lhs, SimplePcg32 const& rhs);
+
+ // In theory we also need operator<< and operator>>
+ // In practice we do not use them, so we will skip them for now
+
+ std::uint64_t m_state;
+ // This part of the state determines which "stream" of the numbers
+ // is chosen -- we take it as a constant for Catch2, so we only
+ // need to deal with seeding the main state.
+ // Picked by reading 8 bytes from `/dev/random` :-)
+ static const std::uint64_t s_inc = (0x13ed0cc53f939476ULL << 1ULL) | 1ULL;
+ };
+
+} // end namespace Catch
+
+// end catch_random_number_generator.h
#include <random>
namespace Catch {
@@ -4400,14 +4591,13 @@ namespace Generators {
template <typename Float>
class RandomFloatingGenerator final : public IGenerator<Float> {
- // FIXME: What is the right seed?
- std::minstd_rand m_rand;
+ Catch::SimplePcg32& m_rng;
std::uniform_real_distribution<Float> m_dist;
Float m_current_number;
public:
RandomFloatingGenerator(Float a, Float b):
- m_rand(getCurrentContext().getConfig()->rngSeed()),
+ m_rng(rng()),
m_dist(a, b) {
static_cast<void>(next());
}
@@ -4416,20 +4606,20 @@ public:
return m_current_number;
}
bool next() override {
- m_current_number = m_dist(m_rand);
+ m_current_number = m_dist(m_rng);
return true;
}
};
template <typename Integer>
class RandomIntegerGenerator final : public IGenerator<Integer> {
- std::minstd_rand m_rand;
+ Catch::SimplePcg32& m_rng;
std::uniform_int_distribution<Integer> m_dist;
Integer m_current_number;
public:
RandomIntegerGenerator(Integer a, Integer b):
- m_rand(getCurrentContext().getConfig()->rngSeed()),
+ m_rng(rng()),
m_dist(a, b) {
static_cast<void>(next());
}
@@ -4438,7 +4628,7 @@ public:
return m_current_number;
}
bool next() override {
- m_current_number = m_dist(m_rand);
+ m_current_number = m_dist(m_rng);
return true;
}
};
@@ -4498,7 +4688,7 @@ public:
template <typename T>
GeneratorWrapper<T> range(T const& start, T const& end, T const& step) {
- static_assert(std::is_integral<T>::value && !std::is_same<T, bool>::value, "Type must be an integer");
+ static_assert(std::is_arithmetic<T>::value && !std::is_same<T, bool>::value, "Type must be numeric");
return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end, step));
}
@@ -4508,6 +4698,45 @@ GeneratorWrapper<T> range(T const& start, T const& end) {
return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end));
}
+template <typename T>
+class IteratorGenerator final : public IGenerator<T> {
+ static_assert(!std::is_same<T, bool>::value,
+ "IteratorGenerator currently does not support bools"
+ "because of std::vector<bool> specialization");
+
+ std::vector<T> m_elems;
+ size_t m_current = 0;
+public:
+ template <typename InputIterator, typename InputSentinel>
+ IteratorGenerator(InputIterator first, InputSentinel last):m_elems(first, last) {
+ if (m_elems.empty()) {
+ Catch::throw_exception(GeneratorException("IteratorGenerator received no valid values"));
+ }
+ }
+
+ T const& get() const override {
+ return m_elems[m_current];
+ }
+
+ bool next() override {
+ ++m_current;
+ return m_current != m_elems.size();
+ }
+};
+
+template <typename InputIterator,
+ typename InputSentinel,
+ typename ResultType = typename std::iterator_traits<InputIterator>::value_type>
+GeneratorWrapper<ResultType> from_range(InputIterator from, InputSentinel to) {
+ return GeneratorWrapper<ResultType>(pf::make_unique<IteratorGenerator<ResultType>>(from, to));
+}
+
+template <typename Container,
+ typename ResultType = typename Container::value_type>
+GeneratorWrapper<ResultType> from_range(Container const& cnt) {
+ return GeneratorWrapper<ResultType>(pf::make_unique<IteratorGenerator<ResultType>>(cnt.begin(), cnt.end()));
+}
+
} // namespace Generators
} // namespace Catch
@@ -4711,7 +4940,7 @@ namespace Catch {
arcSafeRelease( m_substr );
}
- bool match( NSString* const& str ) const override {
+ bool match( NSString* str ) const override {
return false;
}
@@ -4721,7 +4950,7 @@ namespace Catch {
struct Equals : StringHolder {
Equals( NSString* substr ) : StringHolder( substr ){}
- bool match( NSString* const& str ) const override {
+ bool match( NSString* str ) const override {
return (str != nil || m_substr == nil ) &&
[str isEqualToString:m_substr];
}
@@ -4734,7 +4963,7 @@ namespace Catch {
struct Contains : StringHolder {
Contains( NSString* substr ) : StringHolder( substr ){}
- bool match( NSString* const& str ) const override {
+ bool match( NSString* str ) const override {
return (str != nil || m_substr == nil ) &&
[str rangeOfString:m_substr].location != NSNotFound;
}
@@ -4747,7 +4976,7 @@ namespace Catch {
struct StartsWith : StringHolder {
StartsWith( NSString* substr ) : StringHolder( substr ){}
- bool match( NSString* const& str ) const override {
+ bool match( NSString* str ) const override {
return (str != nil || m_substr == nil ) &&
[str rangeOfString:m_substr].location == 0;
}
@@ -4759,7 +4988,7 @@ namespace Catch {
struct EndsWith : StringHolder {
EndsWith( NSString* substr ) : StringHolder( substr ){}
- bool match( NSString* const& str ) const override {
+ bool match( NSString* str ) const override {
return (str != nil || m_substr == nil ) &&
[str rangeOfString:m_substr].location == [str length] - [m_substr length];
}
@@ -4810,7 +5039,8 @@ return @ desc; \
// end catch_objc.hpp
#endif
-#ifdef CATCH_CONFIG_EXTERNAL_INTERFACES
+// Benchmarking needs the externally-facing parts of reporters to work
+#if defined(CATCH_CONFIG_EXTERNAL_INTERFACES) || defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
// start catch_external_interfaces.h
// start catch_reporter_bases.hpp
@@ -4852,7 +5082,7 @@ namespace Catch
virtual bool matches( std::string const& str ) const;
private:
- std::string adjustCase( std::string const& str ) const;
+ std::string normaliseString( std::string const& str ) const;
CaseSensitive::Choice m_caseSensitivity;
WildcardPosition m_wildcard = NoWildcard;
std::string m_pattern;
@@ -4866,17 +5096,23 @@ namespace Catch
namespace Catch {
+ struct IConfig;
+
class TestSpec {
- struct Pattern {
+ class Pattern {
+ public:
+ explicit Pattern( std::string const& name );
virtual ~Pattern();
virtual bool matches( TestCaseInfo const& testCase ) const = 0;
+ std::string const& name() const;
+ private:
+ std::string const m_name;
};
using PatternPtr = std::shared_ptr<Pattern>;
class NamePattern : public Pattern {
public:
- NamePattern( std::string const& name );
- virtual ~NamePattern();
+ explicit NamePattern( std::string const& name, std::string const& filterString );
bool matches( TestCaseInfo const& testCase ) const override;
private:
WildcardPattern m_wildcardPattern;
@@ -4884,8 +5120,7 @@ namespace Catch {
class TagPattern : public Pattern {
public:
- TagPattern( std::string const& tag );
- virtual ~TagPattern();
+ explicit TagPattern( std::string const& tag, std::string const& filterString );
bool matches( TestCaseInfo const& testCase ) const override;
private:
std::string m_tag;
@@ -4893,8 +5128,7 @@ namespace Catch {
class ExcludedPattern : public Pattern {
public:
- ExcludedPattern( PatternPtr const& underlyingPattern );
- virtual ~ExcludedPattern();
+ explicit ExcludedPattern( PatternPtr const& underlyingPattern );
bool matches( TestCaseInfo const& testCase ) const override;
private:
PatternPtr m_underlyingPattern;
@@ -4904,15 +5138,25 @@ namespace Catch {
std::vector<PatternPtr> m_patterns;
bool matches( TestCaseInfo const& testCase ) const;
+ std::string name() const;
};
public:
+ struct FilterMatch {
+ std::string name;
+ std::vector<TestCase const*> tests;
+ };
+ using Matches = std::vector<FilterMatch>;
+ using vectorStrings = std::vector<std::string>;
+
bool hasFilters() const;
bool matches( TestCaseInfo const& testCase ) const;
+ Matches matchesByFilter( std::vector<TestCase> const& testCases, IConfig const& config ) const;
+ const vectorStrings & getInvalidArgs() const;
private:
std::vector<Filter> m_filters;
-
+ std::vector<std::string> m_invalidArgs;
friend class TestSpecParser;
};
}
@@ -4947,9 +5191,13 @@ namespace Catch {
class TestSpecParser {
enum Mode{ None, Name, QuotedName, Tag, EscapedName };
Mode m_mode = None;
+ Mode lastMode = None;
bool m_exclusion = false;
- std::size_t m_start = std::string::npos, m_pos = 0;
+ std::size_t m_pos = 0;
+ std::size_t m_realPatternPos = 0;
std::string m_arg;
+ std::string m_substring;
+ std::string m_patternName;
std::vector<std::size_t> m_escapeChars;
TestSpec::Filter m_currentFilter;
TestSpec m_testSpec;
@@ -4962,32 +5210,32 @@ namespace Catch {
TestSpec testSpec();
private:
- void visitChar( char c );
- void startNewMode( Mode mode, std::size_t start );
+ bool visitChar( char c );
+ void startNewMode( Mode mode );
+ bool processNoneChar( char c );
+ void processNameChar( char c );
+ bool processOtherChar( char c );
+ void endMode();
void escape();
- std::string subString() const;
+ bool isControlChar( char c ) const;
+ void saveLastMode();
+ void revertBackToLastMode();
+ void addFilter();
+ bool separate();
- template<typename T>
- void addPattern() {
- std::string token = subString();
- for( std::size_t i = 0; i < m_escapeChars.size(); ++i )
- token = token.substr( 0, m_escapeChars[i]-m_start-i ) + token.substr( m_escapeChars[i]-m_start-i+1 );
- m_escapeChars.clear();
- if( startsWith( token, "exclude:" ) ) {
- m_exclusion = true;
- token = token.substr( 8 );
- }
- if( !token.empty() ) {
- TestSpec::PatternPtr pattern = std::make_shared<T>( token );
- if( m_exclusion )
- pattern = std::make_shared<TestSpec::ExcludedPattern>( pattern );
- m_currentFilter.m_patterns.push_back( pattern );
- }
- m_exclusion = false;
- m_mode = None;
+ // Handles common preprocessing of the pattern for name/tag patterns
+ std::string preprocessPattern();
+ // Adds the current pattern as a test name
+ void addNamePattern();
+ // Adds the current pattern as a tag
+ void addTagPattern();
+
+ inline void addCharToPattern(char c) {
+ m_substring += c;
+ m_patternName += c;
+ m_realPatternPos++;
}
- void addFilter();
};
TestSpec parseTestSpec( std::string const& arg );
@@ -5033,10 +5281,12 @@ namespace Catch {
unsigned int benchmarkSamples = 100;
double benchmarkConfidenceInterval = 0.95;
unsigned int benchmarkResamples = 100000;
+ std::chrono::milliseconds::rep benchmarkWarmupTime = 100;
Verbosity verbosity = Verbosity::Normal;
WarnAbout::What warnings = WarnAbout::Nothing;
ShowDurations::OrNot showDurations = ShowDurations::DefaultForReporter;
+ double minDuration = -1;
RunTests::InWhatOrder runOrder = RunTests::InDeclarationOrder;
UseColour::YesOrNo useColour = UseColour::Auto;
WaitForKeypress::When waitForKeypress = WaitForKeypress::Never;
@@ -5087,6 +5337,7 @@ namespace Catch {
bool warnAboutMissingAssertions() const override;
bool warnAboutNoTests() const override;
ShowDurations::OrNot showDurations() const override;
+ double minDuration() const override;
RunTests::InWhatOrder runOrder() const override;
unsigned int rngSeed() const override;
UseColour::YesOrNo useColour() const override;
@@ -5098,6 +5349,7 @@ namespace Catch {
int benchmarkSamples() const override;
double benchmarkConfidenceInterval() const override;
unsigned int benchmarkResamples() const override;
+ std::chrono::milliseconds benchmarkWarmupTime() const override;
private:
@@ -5395,6 +5647,8 @@ namespace Catch {
virtual void noMatchingTestCases( std::string const& spec ) = 0;
+ virtual void reportInvalidArguments(std::string const&) {}
+
virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;
virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0;
@@ -5461,6 +5715,9 @@ namespace Catch {
// Returns double formatted as %.3f (format expected on output)
std::string getFormattedDuration( double duration );
+ //! Should the reporter show
+ bool shouldShowDuration( IConfig const& config, double duration );
+
std::string serializeFilters( std::vector<std::string> const& container );
template<typename DerivedT>
@@ -5487,6 +5744,8 @@ namespace Catch {
void noMatchingTestCases(std::string const&) override {}
+ void reportInvalidArguments(std::string const&) override {}
+
void testRunStarting(TestRunInfo const& _testRunInfo) override {
currentTestRunInfo = _testRunInfo;
}
@@ -5821,14 +6080,16 @@ namespace Catch {
#if !defined(CATCH_CONFIG_DISABLE)
#define CATCH_REGISTER_REPORTER( name, reporterType ) \
+ CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); } \
- CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
+ CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
#define CATCH_REGISTER_LISTENER( listenerType ) \
- CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
- namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; } \
- CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
+ CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
+ CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
+ namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; } \
+ CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
#else // CATCH_CONFIG_DISABLE
#define CATCH_REGISTER_REPORTER(name, reporterType)
@@ -5850,8 +6111,6 @@ namespace Catch {
static std::string getDescription();
- ReporterPreferences getPreferences() const override;
-
void noMatchingTestCases(std::string const& spec) override;
void assertionStarting(AssertionInfo const&) override;
@@ -5890,6 +6149,8 @@ namespace Catch {
void noMatchingTestCases(std::string const& spec) override;
+ void reportInvalidArguments(std::string const&arg) override;
+
void assertionStarting(AssertionInfo const&) override;
bool assertionEnded(AssertionStats const& _assertionStats) override;
@@ -5949,6 +6210,14 @@ namespace Catch {
#include <vector>
namespace Catch {
+ enum class XmlFormatting {
+ None = 0x00,
+ Indent = 0x01,
+ Newline = 0x02,
+ };
+
+ XmlFormatting operator | (XmlFormatting lhs, XmlFormatting rhs);
+ XmlFormatting operator & (XmlFormatting lhs, XmlFormatting rhs);
class XmlEncode {
public:
@@ -5970,14 +6239,14 @@ namespace Catch {
class ScopedElement {
public:
- ScopedElement( XmlWriter* writer );
+ ScopedElement( XmlWriter* writer, XmlFormatting fmt );
ScopedElement( ScopedElement&& other ) noexcept;
ScopedElement& operator=( ScopedElement&& other ) noexcept;
~ScopedElement();
- ScopedElement& writeText( std::string const& text, bool indent = true );
+ ScopedElement& writeText( std::string const& text, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent );
template<typename T>
ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {
@@ -5987,6 +6256,7 @@ namespace Catch {
private:
mutable XmlWriter* m_writer = nullptr;
+ XmlFormatting m_fmt;
};
XmlWriter( std::ostream& os = Catch::cout() );
@@ -5995,11 +6265,11 @@ namespace Catch {
XmlWriter( XmlWriter const& ) = delete;
XmlWriter& operator=( XmlWriter const& ) = delete;
- XmlWriter& startElement( std::string const& name );
+ XmlWriter& startElement( std::string const& name, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
- ScopedElement scopedElement( std::string const& name );
+ ScopedElement scopedElement( std::string const& name, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
- XmlWriter& endElement();
+ XmlWriter& endElement(XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
XmlWriter& writeAttribute( std::string const& name, std::string const& attribute );
@@ -6012,9 +6282,9 @@ namespace Catch {
return writeAttribute( name, rss.str() );
}
- XmlWriter& writeText( std::string const& text, bool indent = true );
+ XmlWriter& writeText( std::string const& text, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
- XmlWriter& writeComment( std::string const& text );
+ XmlWriter& writeComment(std::string const& text, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);
void writeStylesheetRef( std::string const& url );
@@ -6024,6 +6294,8 @@ namespace Catch {
private:
+ void applyFormatting(XmlFormatting fmt);
+
void writeDeclaration();
void newlineIfNecessary();
@@ -6125,6 +6397,7 @@ namespace Catch {
void testRunEnded(TestRunStats const& testRunStats) override;
#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+ void benchmarkPreparing(std::string const& name) override;
void benchmarkStarting(BenchmarkInfo const&) override;
void benchmarkEnded(BenchmarkStats<> const&) override;
void benchmarkFailed(std::string const&) override;
@@ -6144,6 +6417,12 @@ namespace Catch {
#endif
#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
+// start catch_benchmarking_all.hpp
+
+// A proxy header that includes all of the benchmarking headers to allow
+// concise include of the benchmarking features. You should prefer the
+// individual includes in standard use.
+
// start catch_benchmark.hpp
// Benchmark
@@ -6279,20 +6558,18 @@ namespace Catch {
return {};
}
};
- template <typename Sig>
- using ResultOf_t = typename std::result_of<Sig>::type;
// invoke and not return void :(
template <typename Fun, typename... Args>
- CompleteType_t<ResultOf_t<Fun(Args...)>> complete_invoke(Fun&& fun, Args&&... args) {
- return CompleteInvoker<ResultOf_t<Fun(Args...)>>::invoke(std::forward<Fun>(fun), std::forward<Args>(args)...);
+ CompleteType_t<FunctionReturnType<Fun, Args...>> complete_invoke(Fun&& fun, Args&&... args) {
+ return CompleteInvoker<FunctionReturnType<Fun, Args...>>::invoke(std::forward<Fun>(fun), std::forward<Args>(args)...);
}
const std::string benchmarkErrorMsg = "a benchmark failed to run successfully";
} // namespace Detail
template <typename Fun>
- Detail::CompleteType_t<Detail::ResultOf_t<Fun()>> user_code(Fun&& fun) {
+ Detail::CompleteType_t<FunctionReturnType<Fun>> user_code(Fun&& fun) {
CATCH_TRY{
return Detail::complete_invoke(std::forward<Fun>(fun));
} CATCH_CATCH_ALL{
@@ -6537,8 +6814,8 @@ namespace Catch {
Result result;
int iterations;
};
- template <typename Clock, typename Sig>
- using TimingOf = Timing<ClockDuration<Clock>, Detail::CompleteType_t<Detail::ResultOf_t<Sig>>>;
+ template <typename Clock, typename Func, typename... Args>
+ using TimingOf = Timing<ClockDuration<Clock>, Detail::CompleteType_t<FunctionReturnType<Func, Args...>>>;
} // namespace Benchmark
} // namespace Catch
@@ -6549,7 +6826,7 @@ namespace Catch {
namespace Benchmark {
namespace Detail {
template <typename Clock, typename Fun, typename... Args>
- TimingOf<Clock, Fun(Args...)> measure(Fun&& fun, Args&&... args) {
+ TimingOf<Clock, Fun, Args...> measure(Fun&& fun, Args&&... args) {
auto start = Clock::now();
auto&& r = Detail::complete_invoke(fun, std::forward<Args>(args)...);
auto end = Clock::now();
@@ -6568,11 +6845,11 @@ namespace Catch {
namespace Benchmark {
namespace Detail {
template <typename Clock, typename Fun>
- TimingOf<Clock, Fun(int)> measure_one(Fun&& fun, int iters, std::false_type) {
+ TimingOf<Clock, Fun, int> measure_one(Fun&& fun, int iters, std::false_type) {
return Detail::measure<Clock>(fun, iters);
}
template <typename Clock, typename Fun>
- TimingOf<Clock, Fun(Chronometer)> measure_one(Fun&& fun, int iters, std::true_type) {
+ TimingOf<Clock, Fun, Chronometer> measure_one(Fun&& fun, int iters, std::true_type) {
Detail::ChronometerModel<Clock> meter;
auto&& result = Detail::complete_invoke(fun, Chronometer(meter, iters));
@@ -6589,7 +6866,7 @@ namespace Catch {
};
template <typename Clock, typename Fun>
- TimingOf<Clock, Fun(run_for_at_least_argument_t<Clock, Fun>)> run_for_at_least(ClockDuration<Clock> how_long, int seed, Fun&& fun) {
+ TimingOf<Clock, Fun, run_for_at_least_argument_t<Clock, Fun>> run_for_at_least(ClockDuration<Clock> how_long, int seed, Fun&& fun) {
auto iters = seed;
while (iters < (1 << 30)) {
auto&& Timing = measure_one<Clock>(fun, iters, is_callable<Fun(Chronometer)>());
@@ -6657,11 +6934,13 @@ namespace Catch {
#include <algorithm>
#include <functional>
#include <vector>
+#include <iterator>
#include <numeric>
#include <tuple>
#include <cmath>
#include <utility>
#include <cstddef>
+#include <random>
namespace Catch {
namespace Benchmark {
@@ -7011,10 +7290,10 @@ namespace Catch {
template <typename Clock>
ExecutionPlan<FloatDuration<Clock>> prepare(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const {
auto min_time = env.clock_resolution.mean * Detail::minimum_ticks;
- auto run_time = std::max(min_time, std::chrono::duration_cast<decltype(min_time)>(Detail::warmup_time));
+ auto run_time = std::max(min_time, std::chrono::duration_cast<decltype(min_time)>(cfg.benchmarkWarmupTime()));
auto&& test = Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(run_time), 1, fun);
int new_iters = static_cast<int>(std::ceil(min_time * test.iterations / test.elapsed));
- return { new_iters, test.elapsed / test.iterations * new_iters * cfg.benchmarkSamples(), fun, std::chrono::duration_cast<FloatDuration<Clock>>(Detail::warmup_time), Detail::warmup_iterations };
+ return { new_iters, test.elapsed / test.iterations * new_iters * cfg.benchmarkSamples(), fun, std::chrono::duration_cast<FloatDuration<Clock>>(cfg.benchmarkWarmupTime()), Detail::warmup_iterations };
}
template <typename Clock = default_clock>
@@ -7046,7 +7325,7 @@ namespace Catch {
});
auto analysis = Detail::analyse(*cfg, env, samples.begin(), samples.end());
- BenchmarkStats<std::chrono::duration<double, std::nano>> stats{ info, analysis.samples, analysis.mean, analysis.standard_deviation, analysis.outliers, analysis.outlier_variance };
+ BenchmarkStats<FloatDuration<Clock>> stats{ info, analysis.samples, analysis.mean, analysis.standard_deviation, analysis.outliers, analysis.outlier_variance };
getResultCapture().benchmarkEnded(stats);
} CATCH_CATCH_ALL{
@@ -7087,6 +7366,77 @@ namespace Catch {
BenchmarkName = [&]
// end catch_benchmark.hpp
+// start catch_constructor.hpp
+
+// Constructor and destructor helpers
+
+
+#include <type_traits>
+
+namespace Catch {
+ namespace Benchmark {
+ namespace Detail {
+ template <typename T, bool Destruct>
+ struct ObjectStorage
+ {
+ using TStorage = typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type;
+
+ ObjectStorage() : data() {}
+
+ ObjectStorage(const ObjectStorage& other)
+ {
+ new(&data) T(other.stored_object());
+ }
+
+ ObjectStorage(ObjectStorage&& other)
+ {
+ new(&data) T(std::move(other.stored_object()));
+ }
+
+ ~ObjectStorage() { destruct_on_exit<T>(); }
+
+ template <typename... Args>
+ void construct(Args&&... args)
+ {
+ new (&data) T(std::forward<Args>(args)...);
+ }
+
+ template <bool AllowManualDestruction = !Destruct>
+ typename std::enable_if<AllowManualDestruction>::type destruct()
+ {
+ stored_object().~T();
+ }
+
+ private:
+ // If this is a constructor benchmark, destruct the underlying object
+ template <typename U>
+ void destruct_on_exit(typename std::enable_if<Destruct, U>::type* = 0) { destruct<true>(); }
+ // Otherwise, don't
+ template <typename U>
+ void destruct_on_exit(typename std::enable_if<!Destruct, U>::type* = 0) { }
+
+ T& stored_object() {
+ return *static_cast<T*>(static_cast<void*>(&data));
+ }
+
+ T const& stored_object() const {
+ return *static_cast<T*>(static_cast<void*>(&data));
+ }
+
+ TStorage data;
+ };
+ }
+
+ template <typename T>
+ using storage_for = Detail::ObjectStorage<T, true>;
+
+ template <typename T>
+ using destructable_object = Detail::ObjectStorage<T, false>;
+ }
+}
+
+// end catch_constructor.hpp
+// end catch_benchmarking_all.hpp
#endif
#endif // ! CATCH_CONFIG_IMPL_ONLY
@@ -7114,23 +7464,37 @@ namespace TestCaseTracking {
SourceLineInfo location;
NameAndLocation( std::string const& _name, SourceLineInfo const& _location );
+ friend bool operator==(NameAndLocation const& lhs, NameAndLocation const& rhs) {
+ return lhs.name == rhs.name
+ && lhs.location == rhs.location;
+ }
};
- struct ITracker;
+ class ITracker;
using ITrackerPtr = std::shared_ptr<ITracker>;
- struct ITracker {
- virtual ~ITracker();
+ class ITracker {
+ NameAndLocation m_nameAndLocation;
+
+ public:
+ ITracker(NameAndLocation const& nameAndLoc) :
+ m_nameAndLocation(nameAndLoc)
+ {}
// static queries
- virtual NameAndLocation const& nameAndLocation() const = 0;
+ NameAndLocation const& nameAndLocation() const {
+ return m_nameAndLocation;
+ }
+
+ virtual ~ITracker();
// dynamic queries
virtual bool isComplete() const = 0; // Successfully completed or failed
virtual bool isSuccessfullyCompleted() const = 0;
virtual bool isOpen() const = 0; // Started but not complete
virtual bool hasChildren() const = 0;
+ virtual bool hasStarted() const = 0;
virtual ITracker& parent() = 0;
@@ -7185,7 +7549,6 @@ namespace TestCaseTracking {
};
using Children = std::vector<ITrackerPtr>;
- NameAndLocation m_nameAndLocation;
TrackerContext& m_ctx;
ITracker* m_parent;
Children m_children;
@@ -7194,11 +7557,13 @@ namespace TestCaseTracking {
public:
TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
- NameAndLocation const& nameAndLocation() const override;
bool isComplete() const override;
bool isSuccessfullyCompleted() const override;
bool isOpen() const override;
bool hasChildren() const override;
+ bool hasStarted() const override {
+ return m_runState != NotStarted;
+ }
void addChild( ITrackerPtr const& child ) override;
@@ -7223,6 +7588,7 @@ namespace TestCaseTracking {
class SectionTracker : public TrackerBase {
std::vector<std::string> m_filters;
+ std::string m_trimmed_name;
public:
SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );
@@ -7236,6 +7602,10 @@ namespace TestCaseTracking {
void addInitialFilters( std::vector<std::string> const& filters );
void addNextFilters( std::vector<std::string> const& filters );
+ //! Returns filters active in this tracker
+ std::vector<std::string> const& getFilters() const;
+ //! Returns whitespace-trimmed name of the tracked section
+ std::string const& trimmedName() const;
};
} // namespace TestCaseTracking
@@ -7424,9 +7794,10 @@ namespace Catch {
}
bootstrap_analysis analyse_samples(double confidence_level, int n_resamples, std::vector<double>::iterator first, std::vector<double>::iterator last) {
+ CATCH_INTERNAL_START_WARNINGS_SUPPRESSION
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS
static std::random_device entropy;
- CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
+ CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
auto n = static_cast<int>(last - first); // seriously, one can't use integral types without hell in C++
@@ -7514,7 +7885,8 @@ namespace Detail {
bool Approx::equalityComparisonImpl(const double other) const {
// First try with fixed margin, then compute margin based on epsilon, scale and Approx's value
// Thanks to Richard Harris for his help refining the scaled margin value
- return marginComparison(m_value, other, m_margin) || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(m_value)));
+ return marginComparison(m_value, other, m_margin)
+ || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(std::isinf(m_value)? 0 : m_value)));
}
void Approx::setMargin(double newMargin) {
@@ -7558,7 +7930,24 @@ namespace Catch {
#ifdef CATCH_PLATFORM_MAC
- #define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */
+ #if defined(__i386__) || defined(__x86_64__)
+ #define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */
+ #elif defined(__aarch64__)
+ #define CATCH_TRAP() __asm__(".inst 0xd4200000")
+ #endif
+
+#elif defined(CATCH_PLATFORM_IPHONE)
+
+ // use inline assembler
+ #if defined(__i386__) || defined(__x86_64__)
+ #define CATCH_TRAP() __asm__("int $3")
+ #elif defined(__aarch64__)
+ #define CATCH_TRAP() __asm__(".inst 0xd4200000")
+ #elif defined(__arm__) && !defined(__thumb__)
+ #define CATCH_TRAP() __asm__(".inst 0xe7f001f0")
+ #elif defined(__arm__) && defined(__thumb__)
+ #define CATCH_TRAP() __asm__(".inst 0xde01")
+ #endif
#elif defined(CATCH_PLATFORM_LINUX)
// If we can use inline assembler, do it because this allows us to break
@@ -7578,10 +7967,12 @@ namespace Catch {
#define CATCH_TRAP() DebugBreak()
#endif
-#ifdef CATCH_TRAP
- #define CATCH_BREAK_INTO_DEBUGGER() []{ if( Catch::isDebuggerActive() ) { CATCH_TRAP(); } }()
-#else
- #define CATCH_BREAK_INTO_DEBUGGER() []{}()
+#ifndef CATCH_BREAK_INTO_DEBUGGER
+ #ifdef CATCH_TRAP
+ #define CATCH_BREAK_INTO_DEBUGGER() []{ if( Catch::isDebuggerActive() ) { CATCH_TRAP(); } }()
+ #else
+ #define CATCH_BREAK_INTO_DEBUGGER() []{}()
+ #endif
#endif
// end catch_debugger.h
@@ -7728,7 +8119,7 @@ namespace Catch {
void sectionEnded( SectionEndInfo const& endInfo ) override;
void sectionEndedEarly( SectionEndInfo const& endInfo ) override;
- auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& override;
+ auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& override;
#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
void benchmarkPreparing( std::string const& name ) override;
@@ -7799,6 +8190,8 @@ namespace Catch {
bool m_includeSuccessfulResults;
};
+ void seedRng(IConfig const& config);
+ unsigned int rngSeed();
} // end namespace Catch
// end catch_run_context.h
@@ -7945,7 +8338,7 @@ namespace Catch {
}
bool AssertionResult::hasExpression() const {
- return m_info.capturedExpression[0] != 0;
+ return !m_info.capturedExpression.empty();
}
bool AssertionResult::hasMessage() const {
@@ -7953,16 +8346,22 @@ namespace Catch {
}
std::string AssertionResult::getExpression() const {
- if( isFalseTest( m_info.resultDisposition ) )
- return "!(" + m_info.capturedExpression + ")";
- else
- return m_info.capturedExpression;
+ // Possibly overallocating by 3 characters should be basically free
+ std::string expr; expr.reserve(m_info.capturedExpression.size() + 3);
+ if (isFalseTest(m_info.resultDisposition)) {
+ expr += "!(";
+ }
+ expr += m_info.capturedExpression;
+ if (isFalseTest(m_info.resultDisposition)) {
+ expr += ')';
+ }
+ return expr;
}
std::string AssertionResult::getExpressionInMacro() const {
std::string expr;
- if( m_info.macroName[0] == 0 )
- expr = m_info.capturedExpression;
+ if( m_info.macroName.empty() )
+ expr = static_cast<std::string>(m_info.capturedExpression);
else {
expr.reserve( m_info.macroName.size() + m_info.capturedExpression.size() + 4 );
expr += m_info.macroName;
@@ -8696,7 +9095,7 @@ namespace detail {
}
inline auto convertInto( std::string const &source, bool &target ) -> ParserResult {
std::string srcLC = source;
- std::transform( srcLC.begin(), srcLC.end(), srcLC.begin(), []( char c ) { return static_cast<char>( std::tolower(c) ); } );
+ std::transform( srcLC.begin(), srcLC.end(), srcLC.begin(), []( unsigned char c ) { return static_cast<char>( std::tolower(c) ); } );
if (srcLC == "y" || srcLC == "1" || srcLC == "true" || srcLC == "yes" || srcLC == "on")
target = true;
else if (srcLC == "n" || srcLC == "0" || srcLC == "false" || srcLC == "no" || srcLC == "off")
@@ -9344,9 +9743,14 @@ namespace Catch {
if( !line.empty() && !startsWith( line, '#' ) ) {
if( !startsWith( line, '"' ) )
line = '"' + line + '"';
- config.testsOrTags.push_back( line + ',' );
+ config.testsOrTags.push_back( line );
+ config.testsOrTags.emplace_back( "," );
}
}
+ //Remove comma in the end
+ if(!config.testsOrTags.empty())
+ config.testsOrTags.erase( config.testsOrTags.end()-1 );
+
return ParserResult::ok( ParseResultType::Matched );
};
auto const setTestOrder = [&]( std::string const& order ) {
@@ -9381,14 +9785,16 @@ namespace Catch {
};
auto const setWaitForKeypress = [&]( std::string const& keypress ) {
auto keypressLc = toLower( keypress );
- if( keypressLc == "start" )
+ if (keypressLc == "never")
+ config.waitForKeypress = WaitForKeypress::Never;
+ else if( keypressLc == "start" )
config.waitForKeypress = WaitForKeypress::BeforeStart;
else if( keypressLc == "exit" )
config.waitForKeypress = WaitForKeypress::BeforeExit;
else if( keypressLc == "both" )
config.waitForKeypress = WaitForKeypress::BeforeStartAndExit;
else
- return ParserResult::runtimeError( "keypress argument must be one of: start, exit or both. '" + keypress + "' not recognised" );
+ return ParserResult::runtimeError( "keypress argument must be one of: never, start, exit or both. '" + keypress + "' not recognised" );
return ParserResult::ok( ParseResultType::Matched );
};
auto const setVerbosity = [&]( std::string const& verbosity ) {
@@ -9458,6 +9864,9 @@ namespace Catch {
| Opt( [&]( bool flag ) { config.showDurations = flag ? ShowDurations::Always : ShowDurations::Never; }, "yes|no" )
["-d"]["--durations"]
( "show test durations" )
+ | Opt( config.minDuration, "seconds" )
+ ["-D"]["--min-duration"]
+ ( "show test durations for tests taking at least the given number of seconds" )
| Opt( loadTestNamesFromFile, "filename" )
["-f"]["--input-file"]
( "load test names to run from a file" )
@@ -9488,7 +9897,7 @@ namespace Catch {
| Opt( config.libIdentify )
["--libidentify"]
( "report name and version according to libidentify standard" )
- | Opt( setWaitForKeypress, "start|exit|both" )
+ | Opt( setWaitForKeypress, "never|start|exit|both" )
["--wait-for-keypress"]
( "waits for a keypress before exiting" )
| Opt( config.benchmarkSamples, "samples" )
@@ -9503,7 +9912,10 @@ namespace Catch {
| Opt( config.benchmarkNoAnalysis )
["--benchmark-no-analysis"]
( "perform only measurements; do not perform any analysis" )
- | Arg( config.testsOrTags, "test name|pattern|tags" )
+ | Opt( config.benchmarkWarmupTime, "benchmarkWarmupTime" )
+ ["--benchmark-warmup-time"]
+ ( "amount of time in milliseconds spent on warming up each test (default: 100)" )
+ | Arg( config.testsOrTags, "test name|pattern|tags" )
( "which test or tests to use" );
return cli;
@@ -9518,9 +9930,6 @@ namespace Catch {
namespace Catch {
- bool SourceLineInfo::empty() const noexcept {
- return file[0] == '\0';
- }
bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const noexcept {
return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0);
}
@@ -9556,11 +9965,23 @@ namespace Catch {
: m_data( data ),
m_stream( openStream() )
{
+ // We need to trim filter specs to avoid trouble with superfluous
+ // whitespace (esp. important for bdd macros, as those are manually
+ // aligned with whitespace).
+
+ for (auto& elem : m_data.testsOrTags) {
+ elem = trim(elem);
+ }
+ for (auto& elem : m_data.sectionsToRun) {
+ elem = trim(elem);
+ }
+
TestSpecParser parser(ITagAliasRegistry::get());
- if (!data.testsOrTags.empty()) {
+ if (!m_data.testsOrTags.empty()) {
m_hasTestFilters = true;
- for( auto const& testOrTags : data.testsOrTags )
- parser.parse( testOrTags );
+ for (auto const& testOrTags : m_data.testsOrTags) {
+ parser.parse(testOrTags);
+ }
}
m_testSpec = parser.testSpec();
}
@@ -9593,6 +10014,7 @@ namespace Catch {
bool Config::warnAboutMissingAssertions() const { return !!(m_data.warnings & WarnAbout::NoAssertions); }
bool Config::warnAboutNoTests() const { return !!(m_data.warnings & WarnAbout::NoTests); }
ShowDurations::OrNot Config::showDurations() const { return m_data.showDurations; }
+ double Config::minDuration() const { return m_data.minDuration; }
RunTests::InWhatOrder Config::runOrder() const { return m_data.runOrder; }
unsigned int Config::rngSeed() const { return m_data.rngSeed; }
UseColour::YesOrNo Config::useColour() const { return m_data.useColour; }
@@ -9601,10 +10023,11 @@ namespace Catch {
bool Config::showInvisibles() const { return m_data.showInvisibles; }
Verbosity Config::verbosity() const { return m_data.verbosity; }
- bool Config::benchmarkNoAnalysis() const { return m_data.benchmarkNoAnalysis; }
- int Config::benchmarkSamples() const { return m_data.benchmarkSamples; }
- double Config::benchmarkConfidenceInterval() const { return m_data.benchmarkConfidenceInterval; }
- unsigned int Config::benchmarkResamples() const { return m_data.benchmarkResamples; }
+ bool Config::benchmarkNoAnalysis() const { return m_data.benchmarkNoAnalysis; }
+ int Config::benchmarkSamples() const { return m_data.benchmarkSamples; }
+ double Config::benchmarkConfidenceInterval() const { return m_data.benchmarkConfidenceInterval; }
+ unsigned int Config::benchmarkResamples() const { return m_data.benchmarkResamples; }
+ std::chrono::milliseconds Config::benchmarkWarmupTime() const { return std::chrono::milliseconds(m_data.benchmarkWarmupTime); }
IStream const* Config::openStream() {
return Catch::makeStream(m_data.outputFilename);
@@ -9645,7 +10068,7 @@ namespace Catch {
};
struct NoColourImpl : IColourImpl {
- void use( Colour::Code ) {}
+ void use( Colour::Code ) override {}
static IColourImpl* instance() {
static NoColourImpl s_instance;
@@ -9777,7 +10200,7 @@ namespace {
bool useColourOnPlatform() {
return
-#ifdef CATCH_PLATFORM_MAC
+#if defined(CATCH_PLATFORM_MAC) || defined(CATCH_PLATFORM_IPHONE)
!isDebuggerActive() &&
#endif
#if !(defined(__DJGPP__) && defined(__STRICT_ANSI__))
@@ -9818,13 +10241,13 @@ namespace Catch {
namespace Catch {
Colour::Colour( Code _colourCode ) { use( _colourCode ); }
- Colour::Colour( Colour&& rhs ) noexcept {
- m_moved = rhs.m_moved;
- rhs.m_moved = true;
+ Colour::Colour( Colour&& other ) noexcept {
+ m_moved = other.m_moved;
+ other.m_moved = true;
}
- Colour& Colour::operator=( Colour&& rhs ) noexcept {
- m_moved = rhs.m_moved;
- rhs.m_moved = true;
+ Colour& Colour::operator=( Colour&& other ) noexcept {
+ m_moved = other.m_moved;
+ other.m_moved = true;
return *this;
}
@@ -9836,7 +10259,7 @@ namespace Catch {
// However, under some conditions it does happen (see #1626),
// and this change is small enough that we can let practicality
// triumph over purity in this case.
- if (impl != NULL) {
+ if (impl != nullptr) {
impl->use( _colourCode );
}
}
@@ -9905,6 +10328,12 @@ namespace Catch {
IContext::~IContext() = default;
IMutableContext::~IMutableContext() = default;
Context::~Context() = default;
+
+ SimplePcg32& rng() {
+ static SimplePcg32 s_rng;
+ return s_rng;
+ }
+
}
// end catch_context.cpp
// start catch_debug_console.cpp
@@ -9918,7 +10347,16 @@ namespace Catch {
}
// end catch_debug_console.h
-#ifdef CATCH_PLATFORM_WINDOWS
+#if defined(CATCH_CONFIG_ANDROID_LOGWRITE)
+#include <android/log.h>
+
+ namespace Catch {
+ void writeToDebugConsole( std::string const& text ) {
+ __android_log_write( ANDROID_LOG_DEBUG, "Catch", text.c_str() );
+ }
+ }
+
+#elif defined(CATCH_PLATFORM_WINDOWS)
namespace Catch {
void writeToDebugConsole( std::string const& text ) {
@@ -9939,10 +10377,9 @@ namespace Catch {
// end catch_debug_console.cpp
// start catch_debugger.cpp
-#ifdef CATCH_PLATFORM_MAC
+#if defined(CATCH_PLATFORM_MAC) || defined(CATCH_PLATFORM_IPHONE)
-# include <assert.h>
-# include <stdbool.h>
+# include <cassert>
# include <sys/types.h>
# include <unistd.h>
# include <cstddef>
@@ -10115,7 +10552,7 @@ namespace Catch {
EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector<int> const& values) override;
};
- std::vector<std::string> parseEnums( StringRef enums );
+ std::vector<StringRef> parseEnums( StringRef enums );
} // Detail
@@ -10132,13 +10569,25 @@ namespace Catch {
namespace Detail {
- std::vector<std::string> parseEnums( StringRef enums ) {
+ namespace {
+ // Extracts the actual name part of an enum instance
+ // In other words, it returns the Blue part of Bikeshed::Colour::Blue
+ StringRef extractInstanceName(StringRef enumInstance) {
+ // Find last occurence of ":"
+ size_t name_start = enumInstance.size();
+ while (name_start > 0 && enumInstance[name_start - 1] != ':') {
+ --name_start;
+ }
+ return enumInstance.substr(name_start, enumInstance.size() - name_start);
+ }
+ }
+
+ std::vector<StringRef> parseEnums( StringRef enums ) {
auto enumValues = splitStringRef( enums, ',' );
- std::vector<std::string> parsed;
+ std::vector<StringRef> parsed;
parsed.reserve( enumValues.size() );
for( auto const& enumValue : enumValues ) {
- auto identifiers = splitStringRef( enumValue, ':' );
- parsed.push_back( Catch::trim( identifiers.back() ) );
+ parsed.push_back(trim(extractInstanceName(enumValue)));
}
return parsed;
}
@@ -10150,7 +10599,7 @@ namespace Catch {
if( valueToName.first == value )
return valueToName.second;
}
- return "{** unexpected enum value **}";
+ return "{** unexpected enum value **}"_sr;
}
std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) {
@@ -10162,16 +10611,14 @@ namespace Catch {
assert( valueNames.size() == values.size() );
std::size_t i = 0;
for( auto value : values )
- enumInfo->m_values.push_back({ value, valueNames[i++] });
+ enumInfo->m_values.emplace_back(value, valueNames[i++]);
return enumInfo;
}
EnumInfo const& EnumValuesRegistry::registerEnum( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) {
- auto enumInfo = makeEnumInfo( enumName, allValueNames, values );
- EnumInfo* raw = enumInfo.get();
- m_enumInfos.push_back( std::move( enumInfo ) );
- return *raw;
+ m_enumInfos.push_back(makeEnumInfo(enumName, allValueNames, values));
+ return *m_enumInfos.back();
}
} // Detail
@@ -10372,7 +10819,7 @@ namespace Catch {
// 32kb for the alternate stack seems to be sufficient. However, this value
// is experimentally determined, so that's not guaranteed.
- constexpr static std::size_t sigStackSize = 32768 >= MINSIGSTKSZ ? 32768 : MINSIGSTKSZ;
+ static constexpr std::size_t sigStackSize = 32768 >= MINSIGSTKSZ ? 32768 : MINSIGSTKSZ;
static SignalDefs signalDefs[] = {
{ SIGINT, "SIGINT - Terminal interrupt signal" },
@@ -10449,22 +10896,6 @@ namespace Catch {
// end catch_fatal_condition.cpp
// start catch_generators.cpp
-// start catch_random_number_generator.h
-
-#include <algorithm>
-#include <random>
-
-namespace Catch {
-
- struct IConfig;
-
- std::mt19937& rng();
- void seedRng( IConfig const& config );
- unsigned int rngSeed();
-
-}
-
-// end catch_random_number_generator.h
#include <limits>
#include <set>
@@ -10480,8 +10911,8 @@ namespace Generators {
GeneratorUntypedBase::~GeneratorUntypedBase() {}
- auto acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
- return getResultCapture().acquireGeneratorTracker( lineInfo );
+ auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
+ return getResultCapture().acquireGeneratorTracker( generatorName, lineInfo );
}
} // namespace Generators
@@ -10537,6 +10968,8 @@ namespace Catch {
void noMatchingTestCases( std::string const& spec ) override;
+ void reportInvalidArguments(std::string const&arg) override;
+
static std::set<Verbosity> getSupportedVerbosities();
#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
@@ -10754,7 +11187,7 @@ namespace Catch {
namespace Catch {
std::size_t listTests( Config const& config ) {
- TestSpec testSpec = config.testSpec();
+ TestSpec const& testSpec = config.testSpec();
if( config.hasTestFilters() )
Catch::cout() << "Matching test cases:\n";
else {
@@ -10788,7 +11221,7 @@ namespace Catch {
}
std::size_t listTestsNamesOnly( Config const& config ) {
- TestSpec testSpec = config.testSpec();
+ TestSpec const& testSpec = config.testSpec();
std::size_t matchedTests = 0;
std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
for( auto const& testCaseInfo : matchedTestCases ) {
@@ -10810,14 +11243,23 @@ namespace Catch {
}
std::string TagInfo::all() const {
- std::string out;
- for( auto const& spelling : spellings )
- out += "[" + spelling + "]";
+ size_t size = 0;
+ for (auto const& spelling : spellings) {
+ // Add 2 for the brackes
+ size += spelling.size() + 2;
+ }
+
+ std::string out; out.reserve(size);
+ for (auto const& spelling : spellings) {
+ out += '[';
+ out += spelling;
+ out += ']';
+ }
return out;
}
std::size_t listTags( Config const& config ) {
- TestSpec testSpec = config.testSpec();
+ TestSpec const& testSpec = config.testSpec();
if( config.hasTestFilters() )
Catch::cout() << "Tags for matching test cases:\n";
else {
@@ -10911,6 +11353,29 @@ using Matchers::Impl::MatcherBase;
} // namespace Catch
// end catch_matchers.cpp
+// start catch_matchers_exception.cpp
+
+namespace Catch {
+namespace Matchers {
+namespace Exception {
+
+bool ExceptionMessageMatcher::match(std::exception const& ex) const {
+ return ex.what() == m_message;
+}
+
+std::string ExceptionMessageMatcher::describe() const {
+ return "exception message matches \"" + m_message + "\"";
+}
+
+}
+Exception::ExceptionMessageMatcher Message(std::string const& message) {
+ return Exception::ExceptionMessageMatcher(message);
+}
+
+// namespace Exception
+} // namespace Matchers
+} // namespace Catch
+// end catch_matchers_exception.cpp
// start catch_matchers_floating.cpp
// start catch_polyfills.hpp
@@ -10939,85 +11404,100 @@ namespace Catch {
} // end namespace Catch
// end catch_to_string.hpp
+#include <algorithm>
+#include <cmath>
#include <cstdlib>
#include <cstdint>
#include <cstring>
#include <sstream>
+#include <type_traits>
#include <iomanip>
#include <limits>
namespace Catch {
-namespace Matchers {
-namespace Floating {
-enum class FloatingPointKind : uint8_t {
- Float,
- Double
-};
-}
-}
-}
-
namespace {
-template <typename T>
-struct Converter;
-
-template <>
-struct Converter<float> {
- static_assert(sizeof(float) == sizeof(int32_t), "Important ULP matcher assumption violated");
- Converter(float f) {
+ int32_t convert(float f) {
+ static_assert(sizeof(float) == sizeof(int32_t), "Important ULP matcher assumption violated");
+ int32_t i;
std::memcpy(&i, &f, sizeof(f));
+ return i;
}
- int32_t i;
-};
-template <>
-struct Converter<double> {
- static_assert(sizeof(double) == sizeof(int64_t), "Important ULP matcher assumption violated");
- Converter(double d) {
+ int64_t convert(double d) {
+ static_assert(sizeof(double) == sizeof(int64_t), "Important ULP matcher assumption violated");
+ int64_t i;
std::memcpy(&i, &d, sizeof(d));
+ return i;
}
- int64_t i;
-};
-template <typename T>
-auto convert(T t) -> Converter<T> {
- return Converter<T>(t);
-}
+ template <typename FP>
+ bool almostEqualUlps(FP lhs, FP rhs, uint64_t maxUlpDiff) {
+ // Comparison with NaN should always be false.
+ // This way we can rule it out before getting into the ugly details
+ if (Catch::isnan(lhs) || Catch::isnan(rhs)) {
+ return false;
+ }
-template <typename FP>
-bool almostEqualUlps(FP lhs, FP rhs, int maxUlpDiff) {
- // Comparison with NaN should always be false.
- // This way we can rule it out before getting into the ugly details
- if (Catch::isnan(lhs) || Catch::isnan(rhs)) {
- return false;
+ auto lc = convert(lhs);
+ auto rc = convert(rhs);
+
+ if ((lc < 0) != (rc < 0)) {
+ // Potentially we can have +0 and -0
+ return lhs == rhs;
+ }
+
+ auto ulpDiff = std::abs(lc - rc);
+ return static_cast<uint64_t>(ulpDiff) <= maxUlpDiff;
}
- auto lc = convert(lhs);
- auto rc = convert(rhs);
+#if defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
- if ((lc.i < 0) != (rc.i < 0)) {
- // Potentially we can have +0 and -0
- return lhs == rhs;
+ float nextafter(float x, float y) {
+ return ::nextafterf(x, y);
}
- auto ulpDiff = std::abs(lc.i - rc.i);
- return ulpDiff <= maxUlpDiff;
-}
+ double nextafter(double x, double y) {
+ return ::nextafter(x, y);
+ }
+
+#endif // ^^^ CATCH_CONFIG_GLOBAL_NEXTAFTER ^^^
template <typename FP>
-FP step(FP start, FP direction, int steps) {
- for (int i = 0; i < steps; ++i) {
+FP step(FP start, FP direction, uint64_t steps) {
+ for (uint64_t i = 0; i < steps; ++i) {
+#if defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)
+ start = Catch::nextafter(start, direction);
+#else
start = std::nextafter(start, direction);
+#endif
}
return start;
}
+// Performs equivalent check of std::fabs(lhs - rhs) <= margin
+// But without the subtraction to allow for INFINITY in comparison
+bool marginComparison(double lhs, double rhs, double margin) {
+ return (lhs + margin >= rhs) && (rhs + margin >= lhs);
+}
+
+template <typename FloatingPoint>
+void write(std::ostream& out, FloatingPoint num) {
+ out << std::scientific
+ << std::setprecision(std::numeric_limits<FloatingPoint>::max_digits10 - 1)
+ << num;
+}
+
} // end anonymous namespace
-namespace Catch {
namespace Matchers {
namespace Floating {
+
+ enum class FloatingPointKind : uint8_t {
+ Float,
+ Double
+ };
+
WithinAbsMatcher::WithinAbsMatcher(double target, double margin)
:m_target{ target }, m_margin{ margin } {
CATCH_ENFORCE(margin >= 0, "Invalid margin: " << margin << '.'
@@ -11034,10 +11514,11 @@ namespace Floating {
return "is within " + ::Catch::Detail::stringify(m_margin) + " of " + ::Catch::Detail::stringify(m_target);
}
- WithinUlpsMatcher::WithinUlpsMatcher(double target, int ulps, FloatingPointKind baseType)
+ WithinUlpsMatcher::WithinUlpsMatcher(double target, uint64_t ulps, FloatingPointKind baseType)
:m_target{ target }, m_ulps{ ulps }, m_type{ baseType } {
- CATCH_ENFORCE(ulps >= 0, "Invalid ULP setting: " << ulps << '.'
- << " ULPs have to be non-negative.");
+ CATCH_ENFORCE(m_type == FloatingPointKind::Double
+ || m_ulps < (std::numeric_limits<uint32_t>::max)(),
+ "Provided ULP is impossibly large for a float comparison.");
}
#if defined(__clang__)
@@ -11064,36 +11545,57 @@ namespace Floating {
std::string WithinUlpsMatcher::describe() const {
std::stringstream ret;
- ret << "is within " << m_ulps << " ULPs of " << ::Catch::Detail::stringify(m_target);
+ ret << "is within " << m_ulps << " ULPs of ";
if (m_type == FloatingPointKind::Float) {
+ write(ret, static_cast<float>(m_target));
ret << 'f';
+ } else {
+ write(ret, m_target);
}
ret << " ([";
- ret << std::fixed << std::setprecision(std::numeric_limits<double>::max_digits10);
if (m_type == FloatingPointKind::Double) {
- ret << step(m_target, static_cast<double>(-INFINITY), m_ulps)
- << ", "
- << step(m_target, static_cast<double>(INFINITY), m_ulps);
+ write(ret, step(m_target, static_cast<double>(-INFINITY), m_ulps));
+ ret << ", ";
+ write(ret, step(m_target, static_cast<double>( INFINITY), m_ulps));
} else {
- ret << step<float>(static_cast<float>(m_target), -INFINITY, m_ulps)
- << ", "
- << step<float>(static_cast<float>(m_target), INFINITY, m_ulps);
+ // We have to cast INFINITY to float because of MinGW, see #1782
+ write(ret, step(static_cast<float>(m_target), static_cast<float>(-INFINITY), m_ulps));
+ ret << ", ";
+ write(ret, step(static_cast<float>(m_target), static_cast<float>( INFINITY), m_ulps));
}
ret << "])";
return ret.str();
- //return "is within " + Catch::to_string(m_ulps) + " ULPs of " + ::Catch::Detail::stringify(m_target) + ((m_type == FloatingPointKind::Float)? "f" : "");
+ }
+
+ WithinRelMatcher::WithinRelMatcher(double target, double epsilon):
+ m_target(target),
+ m_epsilon(epsilon){
+ CATCH_ENFORCE(m_epsilon >= 0., "Relative comparison with epsilon < 0 does not make sense.");
+ CATCH_ENFORCE(m_epsilon < 1., "Relative comparison with epsilon >= 1 does not make sense.");
+ }
+
+ bool WithinRelMatcher::match(double const& matchee) const {
+ const auto relMargin = m_epsilon * (std::max)(std::fabs(matchee), std::fabs(m_target));
+ return marginComparison(matchee, m_target,
+ std::isinf(relMargin)? 0 : relMargin);
+ }
+
+ std::string WithinRelMatcher::describe() const {
+ Catch::ReusableStringStream sstr;
+ sstr << "and " << m_target << " are within " << m_epsilon * 100. << "% of each other";
+ return sstr.str();
}
}// namespace Floating
-Floating::WithinUlpsMatcher WithinULP(double target, int maxUlpDiff) {
+Floating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff) {
return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Double);
}
-Floating::WithinUlpsMatcher WithinULP(float target, int maxUlpDiff) {
+Floating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff) {
return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Float);
}
@@ -11101,6 +11603,22 @@ Floating::WithinAbsMatcher WithinAbs(double target, double margin) {
return Floating::WithinAbsMatcher(target, margin);
}
+Floating::WithinRelMatcher WithinRel(double target, double eps) {
+ return Floating::WithinRelMatcher(target, eps);
+}
+
+Floating::WithinRelMatcher WithinRel(double target) {
+ return Floating::WithinRelMatcher(target, std::numeric_limits<double>::epsilon() * 100);
+}
+
+Floating::WithinRelMatcher WithinRel(float target, float eps) {
+ return Floating::WithinRelMatcher(target, eps);
+}
+
+Floating::WithinRelMatcher WithinRel(float target) {
+ return Floating::WithinRelMatcher(target, std::numeric_limits<float>::epsilon() * 100);
+}
+
} // namespace Matchers
} // namespace Catch
@@ -11281,10 +11799,10 @@ namespace Catch {
Capturer::Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names ) {
auto trimmed = [&] (size_t start, size_t end) {
- while (names[start] == ',' || isspace(names[start])) {
+ while (names[start] == ',' || isspace(static_cast<unsigned char>(names[start]))) {
++start;
}
- while (names[end] == ',' || isspace(names[end])) {
+ while (names[end] == ',' || isspace(static_cast<unsigned char>(names[end]))) {
--end;
}
return names.substr(start, end - start + 1);
@@ -11323,17 +11841,17 @@ namespace Catch {
pos = skipq(pos, c);
break;
case ',':
- if (start != pos && openings.size() == 0) {
+ if (start != pos && openings.empty()) {
m_messages.emplace_back(macroName, lineInfo, resultType);
- m_messages.back().message = trimmed(start, pos);
+ m_messages.back().message = static_cast<std::string>(trimmed(start, pos));
m_messages.back().message += " := ";
start = pos;
}
}
}
- assert(openings.size() == 0 && "Mismatched openings");
+ assert(openings.empty() && "Mismatched openings");
m_messages.emplace_back(macroName, lineInfo, resultType);
- m_messages.back().message = trimmed(start, names.size() - 1);
+ m_messages.back().message = static_cast<std::string>(trimmed(start, names.size() - 1));
m_messages.back().message += " := ";
}
Capturer::~Capturer() {
@@ -11519,7 +12037,7 @@ namespace Catch {
if (tmpnam_s(m_buffer)) {
CATCH_RUNTIME_ERROR("Could not get a temp filename");
}
- if (fopen_s(&m_file, m_buffer, "w")) {
+ if (fopen_s(&m_file, m_buffer, "w+")) {
char buffer[100];
if (strerror_s(buffer, errno)) {
CATCH_RUNTIME_ERROR("Could not translate errno to a string");
@@ -11627,20 +12145,61 @@ namespace Catch {
namespace Catch {
- std::mt19937& rng() {
- static std::mt19937 s_rng;
- return s_rng;
+namespace {
+
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable:4146) // we negate uint32 during the rotate
+#endif
+ // Safe rotr implementation thanks to John Regehr
+ uint32_t rotate_right(uint32_t val, uint32_t count) {
+ const uint32_t mask = 31;
+ count &= mask;
+ return (val >> count) | (val << (-count & mask));
+ }
+
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+
+}
+
+ SimplePcg32::SimplePcg32(result_type seed_) {
+ seed(seed_);
}
- void seedRng( IConfig const& config ) {
- if( config.rngSeed() != 0 ) {
- std::srand( config.rngSeed() );
- rng().seed( config.rngSeed() );
+ void SimplePcg32::seed(result_type seed_) {
+ m_state = 0;
+ (*this)();
+ m_state += seed_;
+ (*this)();
+ }
+
+ void SimplePcg32::discard(uint64_t skip) {
+ // We could implement this to run in O(log n) steps, but this
+ // should suffice for our use case.
+ for (uint64_t s = 0; s < skip; ++s) {
+ static_cast<void>((*this)());
}
}
- unsigned int rngSeed() {
- return getCurrentContext().getConfig()->rngSeed();
+ SimplePcg32::result_type SimplePcg32::operator()() {
+ // prepare the output value
+ const uint32_t xorshifted = static_cast<uint32_t>(((m_state >> 18u) ^ m_state) >> 27u);
+ const auto output = rotate_right(xorshifted, m_state >> 59u);
+
+ // advance state
+ m_state = m_state * 6364136223846793005ULL + s_inc;
+
+ return output;
+ }
+
+ bool operator==(SimplePcg32 const& lhs, SimplePcg32 const& rhs) {
+ return lhs.m_state == rhs.m_state;
+ }
+
+ bool operator!=(SimplePcg32 const& lhs, SimplePcg32 const& rhs) {
+ return lhs.m_state != rhs.m_state;
}
}
// end catch_random_number_generator.cpp
@@ -11659,6 +12218,8 @@ namespace Catch {
struct IConfig;
std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases );
+
+ bool isThrowSafe( TestCase const& testCase, IConfig const& config );
bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions );
@@ -11771,11 +12332,13 @@ namespace Catch {
namespace Catch {
class StartupExceptionRegistry {
+#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
public:
void add(std::exception_ptr const& exception) noexcept;
std::vector<std::exception_ptr> const& getExceptions() const noexcept;
private:
std::vector<std::exception_ptr> m_exceptions;
+#endif
};
} // end namespace Catch
@@ -11858,7 +12421,11 @@ namespace Catch {
m_tagAliasRegistry.add( alias, tag, lineInfo );
}
void registerStartupException() noexcept override {
+#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
m_exceptionRegistry.add(std::current_exception());
+#else
+ CATCH_INTERNAL_ERROR("Attempted to register active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!");
+#endif
}
IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() override {
return m_enumValuesRegistry;
@@ -11962,17 +12529,32 @@ namespace Catch {
std::shared_ptr<GeneratorTracker> tracker;
ITracker& currentTracker = ctx.currentTracker();
- if( TestCaseTracking::ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
+ // Under specific circumstances, the generator we want
+ // to acquire is also the current tracker. If this is
+ // the case, we have to avoid looking through current
+ // tracker's children, and instead return the current
+ // tracker.
+ // A case where this check is important is e.g.
+ // for (int i = 0; i < 5; ++i) {
+ // int n = GENERATE(1, 2);
+ // }
+ //
+ // without it, the code above creates 5 nested generators.
+ if (currentTracker.nameAndLocation() == nameAndLocation) {
+ auto thisTracker = currentTracker.parent().findChild(nameAndLocation);
+ assert(thisTracker);
+ assert(thisTracker->isGeneratorTracker());
+ tracker = std::static_pointer_cast<GeneratorTracker>(thisTracker);
+ } else if ( TestCaseTracking::ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {
assert( childTracker );
assert( childTracker->isGeneratorTracker() );
tracker = std::static_pointer_cast<GeneratorTracker>( childTracker );
- }
- else {
+ } else {
tracker = std::make_shared<GeneratorTracker>( nameAndLocation, ctx, &currentTracker );
currentTracker.addChild( tracker );
}
- if( !ctx.completedCycle() && !tracker->isComplete() ) {
+ if( !tracker->isComplete() ) {
tracker->open();
}
@@ -11986,8 +12568,68 @@ namespace Catch {
}
void close() override {
TrackerBase::close();
- // Generator interface only finds out if it has another item on atual move
- if (m_runState == CompletedSuccessfully && m_generator->next()) {
+ // If a generator has a child (it is followed by a section)
+ // and none of its children have started, then we must wait
+ // until later to start consuming its values.
+ // This catches cases where `GENERATE` is placed between two
+ // `SECTION`s.
+ // **The check for m_children.empty cannot be removed**.
+ // doing so would break `GENERATE` _not_ followed by `SECTION`s.
+ const bool should_wait_for_child = [&]() {
+ // No children -> nobody to wait for
+ if ( m_children.empty() ) {
+ return false;
+ }
+ // If at least one child started executing, don't wait
+ if ( std::find_if(
+ m_children.begin(),
+ m_children.end(),
+ []( TestCaseTracking::ITrackerPtr tracker ) {
+ return tracker->hasStarted();
+ } ) != m_children.end() ) {
+ return false;
+ }
+
+ // No children have started. We need to check if they _can_
+ // start, and thus we should wait for them, or they cannot
+ // start (due to filters), and we shouldn't wait for them
+ auto* parent = m_parent;
+ // This is safe: there is always at least one section
+ // tracker in a test case tracking tree
+ while ( !parent->isSectionTracker() ) {
+ parent = &( parent->parent() );
+ }
+ assert( parent &&
+ "Missing root (test case) level section" );
+
+ auto const& parentSection =
+ static_cast<SectionTracker&>( *parent );
+ auto const& filters = parentSection.getFilters();
+ // No filters -> no restrictions on running sections
+ if ( filters.empty() ) {
+ return true;
+ }
+
+ for ( auto const& child : m_children ) {
+ if ( child->isSectionTracker() &&
+ std::find( filters.begin(),
+ filters.end(),
+ static_cast<SectionTracker&>( *child )
+ .trimmedName() ) !=
+ filters.end() ) {
+ return true;
+ }
+ }
+ return false;
+ }();
+
+ // This check is a bit tricky, because m_generator->next()
+ // has a side-effect, where it consumes generator's current
+ // value, but we do not want to invoke the side-effect if
+ // this generator is still waiting for any child to start.
+ if ( should_wait_for_child ||
+ ( m_runState == CompletedSuccessfully &&
+ m_generator->next() ) ) {
m_children.clear();
m_runState = Executing;
}
@@ -12123,10 +12765,10 @@ namespace Catch {
return true;
}
- auto RunContext::acquireGeneratorTracker( SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
+ auto RunContext::acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {
using namespace Generators;
- GeneratorTracker& tracker = GeneratorTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( "generator", lineInfo ) );
- assert( tracker.isOpen() );
+ GeneratorTracker& tracker = GeneratorTracker::acquire(m_trackerContext,
+ TestCaseTracking::NameAndLocation( static_cast<std::string>(generatorName), lineInfo ) );
m_lastAssertionInfo.lineInfo = lineInfo;
return tracker;
}
@@ -12169,17 +12811,17 @@ namespace Catch {
#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
void RunContext::benchmarkPreparing(std::string const& name) {
- m_reporter->benchmarkPreparing(name);
- }
+ m_reporter->benchmarkPreparing(name);
+ }
void RunContext::benchmarkStarting( BenchmarkInfo const& info ) {
m_reporter->benchmarkStarting( info );
}
void RunContext::benchmarkEnded( BenchmarkStats<> const& stats ) {
m_reporter->benchmarkEnded( stats );
}
- void RunContext::benchmarkFailed(std::string const & error) {
- m_reporter->benchmarkFailed(error);
- }
+ void RunContext::benchmarkFailed(std::string const & error) {
+ m_reporter->benchmarkFailed(error);
+ }
#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
void RunContext::pushScopedMessage(MessageInfo const & message) {
@@ -12215,7 +12857,7 @@ namespace Catch {
// Don't rebuild the result -- the stringification itself can cause more fatal errors
// Instead, fake a result data.
AssertionResultData tempResult( ResultWas::FatalErrorCondition, { false } );
- tempResult.message = message;
+ tempResult.message = static_cast<std::string>(message);
AssertionResult result(m_lastAssertionInfo, tempResult);
assertionEnded(result);
@@ -12378,7 +13020,7 @@ namespace Catch {
m_lastAssertionInfo = info;
AssertionResultData data( resultType, LazyExpression( false ) );
- data.message = message;
+ data.message = static_cast<std::string>(message);
AssertionResult assertionResult{ m_lastAssertionInfo, data };
assertionEnded( assertionResult );
if( !assertionResult.isOk() )
@@ -12441,6 +13083,18 @@ namespace Catch {
else
CATCH_INTERNAL_ERROR("No result capture instance");
}
+
+ void seedRng(IConfig const& config) {
+ if (config.rngSeed() != 0) {
+ std::srand(config.rngSeed());
+ rng().seed(config.rngSeed());
+ }
+ }
+
+ unsigned int rngSeed() {
+ return getCurrentContext().getConfig()->rngSeed();
+ }
+
}
// end catch_run_context.cpp
// start catch_section.cpp
@@ -12502,7 +13156,7 @@ namespace Catch {
void libIdentify();
int applyCommandLine( int argc, char const * const * argv );
- #if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE)
+ #if defined(CATCH_CONFIG_WCHAR) && defined(_WIN32) && defined(UNICODE)
int applyCommandLine( int argc, wchar_t const * const * argv );
#endif
@@ -12569,6 +13223,8 @@ namespace Catch {
// end catch_version.h
#include <cstdlib>
#include <iomanip>
+#include <set>
+#include <iterator>
namespace Catch {
@@ -12602,45 +13258,61 @@ namespace Catch {
return ret;
}
- Catch::Totals runTests(std::shared_ptr<Config> const& config) {
- auto reporter = makeReporter(config);
-
- RunContext context(config, std::move(reporter));
-
- Totals totals;
-
- context.testGroupStarting(config->name(), 1, 1);
-
- TestSpec testSpec = config->testSpec();
-
- auto const& allTestCases = getAllTestCasesSorted(*config);
- for (auto const& testCase : allTestCases) {
- bool matching = (!testSpec.hasFilters() && !testCase.isHidden()) ||
- (testSpec.hasFilters() && matchTest(testCase, testSpec, *config));
-
- if (!context.aborting() && matching)
- totals += context.runTest(testCase);
- else
- context.reporter().skipTest(testCase);
+ class TestGroup {
+ public:
+ explicit TestGroup(std::shared_ptr<Config> const& config)
+ : m_config{config}
+ , m_context{config, makeReporter(config)}
+ {
+ auto const& allTestCases = getAllTestCasesSorted(*m_config);
+ m_matches = m_config->testSpec().matchesByFilter(allTestCases, *m_config);
+ auto const& invalidArgs = m_config->testSpec().getInvalidArgs();
+
+ if (m_matches.empty() && invalidArgs.empty()) {
+ for (auto const& test : allTestCases)
+ if (!test.isHidden())
+ m_tests.emplace(&test);
+ } else {
+ for (auto const& match : m_matches)
+ m_tests.insert(match.tests.begin(), match.tests.end());
+ }
}
- if (config->warnAboutNoTests() && totals.testCases.total() == 0) {
- ReusableStringStream testConfig;
+ Totals execute() {
+ auto const& invalidArgs = m_config->testSpec().getInvalidArgs();
+ Totals totals;
+ m_context.testGroupStarting(m_config->name(), 1, 1);
+ for (auto const& testCase : m_tests) {
+ if (!m_context.aborting())
+ totals += m_context.runTest(*testCase);
+ else
+ m_context.reporter().skipTest(*testCase);
+ }
- bool first = true;
- for (const auto& input : config->getTestsOrTags()) {
- if (!first) { testConfig << ' '; }
- first = false;
- testConfig << input;
+ for (auto const& match : m_matches) {
+ if (match.tests.empty()) {
+ m_context.reporter().noMatchingTestCases(match.name);
+ totals.error = -1;
+ }
+ }
+
+ if (!invalidArgs.empty()) {
+ for (auto const& invalidArg: invalidArgs)
+ m_context.reporter().reportInvalidArguments(invalidArg);
}
- context.reporter().noMatchingTestCases(testConfig.str());
- totals.error = -1;
+ m_context.testGroupEnded(m_config->name(), totals, 1, 1);
+ return totals;
}
- context.testGroupEnded(config->name(), totals, 1, 1);
- return totals;
- }
+ private:
+ using Tests = std::set<TestCase const*>;
+
+ std::shared_ptr<Config> m_config;
+ RunContext m_context;
+ Tests m_tests;
+ TestSpec::Matches m_matches;
+ };
void applyFilenamesAsTags(Catch::IConfig const& config) {
auto& tests = const_cast<std::vector<TestCase>&>(getAllTestCasesSorted(config));
@@ -12709,7 +13381,7 @@ namespace Catch {
}
void Session::libIdentify() {
Catch::cout()
- << std::left << std::setw(16) << "description: " << "A Catch test executable\n"
+ << std::left << std::setw(16) << "description: " << "A Catch2 test executable\n"
<< std::left << std::setw(16) << "category: " << "testframework\n"
<< std::left << std::setw(16) << "framework: " << "Catch Test\n"
<< std::left << std::setw(16) << "version: " << libraryVersion() << std::endl;
@@ -12740,17 +13412,17 @@ namespace Catch {
return 0;
}
-#if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE)
+#if defined(CATCH_CONFIG_WCHAR) && defined(_WIN32) && defined(UNICODE)
int Session::applyCommandLine( int argc, wchar_t const * const * argv ) {
char **utf8Argv = new char *[ argc ];
for ( int i = 0; i < argc; ++i ) {
- int bufSize = WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, NULL, 0, NULL, NULL );
+ int bufSize = WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, nullptr, 0, nullptr, nullptr );
utf8Argv[ i ] = new char[ bufSize ];
- WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, NULL, NULL );
+ WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, nullptr, nullptr );
}
int returnCode = applyCommandLine( argc, utf8Argv );
@@ -12817,7 +13489,12 @@ namespace Catch {
if( Option<std::size_t> listed = list( m_config ) )
return static_cast<int>( *listed );
- auto totals = runTests( m_config );
+ TestGroup tests { m_config };
+ auto const totals = tests.execute();
+
+ if( m_config->warnAboutNoTests() && totals.error == -1 )
+ return 2;
+
// Note that on unices only the lower 8 bits are usually used, clamping
// the return value to 255 prevents false negative when some multiple
// of 256 tests has failed
@@ -12865,6 +13542,7 @@ namespace Catch {
// end catch_singletons.cpp
// start catch_startup_exception_registry.cpp
+#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
namespace Catch {
void StartupExceptionRegistry::add( std::exception_ptr const& exception ) noexcept {
CATCH_TRY {
@@ -12880,6 +13558,7 @@ void StartupExceptionRegistry::add( std::exception_ptr const& exception ) noexce
}
} // end namespace Catch
+#endif
// end catch_startup_exception_registry.cpp
// start catch_stream.cpp
@@ -13064,7 +13743,7 @@ namespace Catch {
namespace {
char toLowerCh(char c) {
- return static_cast<char>( std::tolower( c ) );
+ return static_cast<char>( std::tolower( static_cast<unsigned char>(c) ) );
}
}
@@ -13099,6 +13778,18 @@ namespace Catch {
return start != std::string::npos ? str.substr( start, 1+end-start ) : std::string();
}
+ StringRef trim(StringRef ref) {
+ const auto is_ws = [](char c) {
+ return c == ' ' || c == '\t' || c == '\n' || c == '\r';
+ };
+ size_t real_begin = 0;
+ while (real_begin < ref.size() && is_ws(ref[real_begin])) { ++real_begin; }
+ size_t real_end = ref.size();
+ while (real_end > real_begin && is_ws(ref[real_end - 1])) { --real_end; }
+
+ return ref.substr(real_begin, real_end - real_begin);
+ }
+
bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
bool replaced = false;
std::size_t i = str.find( replaceThis );
@@ -13144,124 +13835,46 @@ namespace Catch {
// end catch_string_manip.cpp
// start catch_stringref.cpp
-#if defined(__clang__)
-# pragma clang diagnostic push
-# pragma clang diagnostic ignored "-Wexit-time-destructors"
-#endif
-
+#include <algorithm>
#include <ostream>
#include <cstring>
#include <cstdint>
-namespace {
- const uint32_t byte_2_lead = 0xC0;
- const uint32_t byte_3_lead = 0xE0;
- const uint32_t byte_4_lead = 0xF0;
-}
-
namespace Catch {
StringRef::StringRef( char const* rawChars ) noexcept
: StringRef( rawChars, static_cast<StringRef::size_type>(std::strlen(rawChars) ) )
{}
- StringRef::operator std::string() const {
- return std::string( m_start, m_size );
- }
-
- void StringRef::swap( StringRef& other ) noexcept {
- std::swap( m_start, other.m_start );
- std::swap( m_size, other.m_size );
- std::swap( m_data, other.m_data );
- }
-
auto StringRef::c_str() const -> char const* {
- if( !isSubstring() )
- return m_start;
-
- const_cast<StringRef *>( this )->takeOwnership();
- return m_data;
- }
- auto StringRef::currentData() const noexcept -> char const* {
+ CATCH_ENFORCE(isNullTerminated(), "Called StringRef::c_str() on a non-null-terminated instance");
return m_start;
}
-
- auto StringRef::isOwned() const noexcept -> bool {
- return m_data != nullptr;
- }
- auto StringRef::isSubstring() const noexcept -> bool {
- return m_start[m_size] != '\0';
+ auto StringRef::data() const noexcept -> char const* {
+ return m_start;
}
- void StringRef::takeOwnership() {
- if( !isOwned() ) {
- m_data = new char[m_size+1];
- memcpy( m_data, m_start, m_size );
- m_data[m_size] = '\0';
- }
- }
auto StringRef::substr( size_type start, size_type size ) const noexcept -> StringRef {
- if( start < m_size )
- return StringRef( m_start+start, size );
- else
+ if (start < m_size) {
+ return StringRef(m_start + start, (std::min)(m_size - start, size));
+ } else {
return StringRef();
- }
- auto StringRef::operator == ( StringRef const& other ) const noexcept -> bool {
- return
- size() == other.size() &&
- (std::strncmp( m_start, other.m_start, size() ) == 0);
- }
- auto StringRef::operator != ( StringRef const& other ) const noexcept -> bool {
- return !operator==( other );
- }
-
- auto StringRef::operator[](size_type index) const noexcept -> char {
- return m_start[index];
- }
-
- auto StringRef::numberOfCharacters() const noexcept -> size_type {
- size_type noChars = m_size;
- // Make adjustments for uft encodings
- for( size_type i=0; i < m_size; ++i ) {
- char c = m_start[i];
- if( ( c & byte_2_lead ) == byte_2_lead ) {
- noChars--;
- if (( c & byte_3_lead ) == byte_3_lead )
- noChars--;
- if( ( c & byte_4_lead ) == byte_4_lead )
- noChars--;
- }
}
- return noChars;
- }
-
- auto operator + ( StringRef const& lhs, StringRef const& rhs ) -> std::string {
- std::string str;
- str.reserve( lhs.size() + rhs.size() );
- str += lhs;
- str += rhs;
- return str;
- }
- auto operator + ( StringRef const& lhs, const char* rhs ) -> std::string {
- return std::string( lhs ) + std::string( rhs );
}
- auto operator + ( char const* lhs, StringRef const& rhs ) -> std::string {
- return std::string( lhs ) + std::string( rhs );
+ auto StringRef::operator == ( StringRef const& other ) const noexcept -> bool {
+ return m_size == other.m_size
+ && (std::memcmp( m_start, other.m_start, m_size ) == 0);
}
auto operator << ( std::ostream& os, StringRef const& str ) -> std::ostream& {
- return os.write(str.currentData(), str.size());
+ return os.write(str.data(), str.size());
}
auto operator+=( std::string& lhs, StringRef const& rhs ) -> std::string& {
- lhs.append(rhs.currentData(), rhs.size());
+ lhs.append(rhs.data(), rhs.size());
return lhs;
}
} // namespace Catch
-
-#if defined(__clang__)
-# pragma clang diagnostic pop
-#endif
// end catch_stringref.cpp
// start catch_tag_alias.cpp
@@ -13380,8 +13993,7 @@ namespace Catch {
std::vector<std::string> tags;
std::string desc, tag;
bool inTag = false;
- std::string _descOrTags = nameAndTags.tags;
- for (char c : _descOrTags) {
+ for (char c : nameAndTags.tags) {
if( !inTag ) {
if( c == '[' )
inTag = true;
@@ -13411,10 +14023,11 @@ namespace Catch {
}
}
if( isHidden ) {
- tags.push_back( "." );
+ // Add all "hidden" tags to make them behave identically
+ tags.insert( tags.end(), { ".", "!hide" } );
}
- TestCaseInfo info( nameAndTags.name, _className, desc, tags, _lineInfo );
+ TestCaseInfo info( static_cast<std::string>(nameAndTags.name), _className, desc, tags, _lineInfo );
return TestCase( _testCase, std::move(info) );
}
@@ -13506,30 +14119,89 @@ namespace Catch {
// end catch_test_case_info.cpp
// start catch_test_case_registry_impl.cpp
+#include <algorithm>
#include <sstream>
namespace Catch {
- std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ) {
+ namespace {
+ struct TestHasher {
+ using hash_t = uint64_t;
+
+ explicit TestHasher( hash_t hashSuffix ):
+ m_hashSuffix{ hashSuffix } {}
+
+ uint32_t operator()( TestCase const& t ) const {
+ // FNV-1a hash with multiplication fold.
+ const hash_t prime = 1099511628211u;
+ hash_t hash = 14695981039346656037u;
+ for ( const char c : t.name ) {
+ hash ^= c;
+ hash *= prime;
+ }
+ hash ^= m_hashSuffix;
+ hash *= prime;
+ const uint32_t low{ static_cast<uint32_t>( hash ) };
+ const uint32_t high{ static_cast<uint32_t>( hash >> 32 ) };
+ return low * high;
+ }
- std::vector<TestCase> sorted = unsortedTestCases;
+ private:
+ hash_t m_hashSuffix;
+ };
+ } // end unnamed namespace
+ std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ) {
switch( config.runOrder() ) {
- case RunTests::InLexicographicalOrder:
- std::sort( sorted.begin(), sorted.end() );
- break;
- case RunTests::InRandomOrder:
- seedRng( config );
- std::shuffle( sorted.begin(), sorted.end(), rng() );
- break;
case RunTests::InDeclarationOrder:
// already in declaration order
break;
+
+ case RunTests::InLexicographicalOrder: {
+ std::vector<TestCase> sorted = unsortedTestCases;
+ std::sort( sorted.begin(), sorted.end() );
+ return sorted;
+ }
+
+ case RunTests::InRandomOrder: {
+ seedRng( config );
+ TestHasher h{ config.rngSeed() };
+
+ using hashedTest = std::pair<TestHasher::hash_t, TestCase const*>;
+ std::vector<hashedTest> indexed_tests;
+ indexed_tests.reserve( unsortedTestCases.size() );
+
+ for (auto const& testCase : unsortedTestCases) {
+ indexed_tests.emplace_back(h(testCase), &testCase);
+ }
+
+ std::sort(indexed_tests.begin(), indexed_tests.end(),
+ [](hashedTest const& lhs, hashedTest const& rhs) {
+ if (lhs.first == rhs.first) {
+ return lhs.second->name < rhs.second->name;
+ }
+ return lhs.first < rhs.first;
+ });
+
+ std::vector<TestCase> sorted;
+ sorted.reserve( indexed_tests.size() );
+
+ for (auto const& hashed : indexed_tests) {
+ sorted.emplace_back(*hashed.second);
+ }
+
+ return sorted;
+ }
}
- return sorted;
+ return unsortedTestCases;
+ }
+
+ bool isThrowSafe( TestCase const& testCase, IConfig const& config ) {
+ return !testCase.throws() || config.allowThrows();
}
+
bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) {
- return testSpec.matches( testCase ) && ( config.allowThrows() || !testCase.throws() );
+ return testSpec.matches( testCase ) && isThrowSafe( testCase, config );
}
void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions ) {
@@ -13590,7 +14262,7 @@ namespace Catch {
}
std::string extractClassName( StringRef const& classOrQualifiedMethodName ) {
- std::string className = classOrQualifiedMethodName;
+ std::string className(classOrQualifiedMethodName);
if( startsWith( className, '&' ) )
{
std::size_t lastColons = className.rfind( "::" );
@@ -13658,15 +14330,12 @@ namespace TestCaseTracking {
m_currentTracker = tracker;
}
- TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
- : m_nameAndLocation( nameAndLocation ),
+ TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ):
+ ITracker(nameAndLocation),
m_ctx( ctx ),
m_parent( parent )
{}
- NameAndLocation const& TrackerBase::nameAndLocation() const {
- return m_nameAndLocation;
- }
bool TrackerBase::isComplete() const {
return m_runState == CompletedSuccessfully || m_runState == Failed;
}
@@ -13732,7 +14401,7 @@ namespace TestCaseTracking {
m_runState = CompletedSuccessfully;
break;
case ExecutingChildren:
- if( m_children.empty() || m_children.back()->isComplete() )
+ if( std::all_of(m_children.begin(), m_children.end(), [](ITrackerPtr const& t){ return t->isComplete(); }) )
m_runState = CompletedSuccessfully;
break;
@@ -13767,7 +14436,8 @@ namespace TestCaseTracking {
}
SectionTracker::SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
- : TrackerBase( nameAndLocation, ctx, parent )
+ : TrackerBase( nameAndLocation, ctx, parent ),
+ m_trimmed_name(trim(nameAndLocation.name))
{
if( parent ) {
while( !parent->isSectionTracker() )
@@ -13781,12 +14451,12 @@ namespace TestCaseTracking {
bool SectionTracker::isComplete() const {
bool complete = true;
- if ((m_filters.empty() || m_filters[0] == "") ||
- std::find(m_filters.begin(), m_filters.end(),
- m_nameAndLocation.name) != m_filters.end())
+ if (m_filters.empty()
+ || m_filters[0] == ""
+ || std::find(m_filters.begin(), m_filters.end(), m_trimmed_name) != m_filters.end()) {
complete = TrackerBase::isComplete();
+ }
return complete;
-
}
bool SectionTracker::isSectionTracker() const { return true; }
@@ -13810,20 +14480,29 @@ namespace TestCaseTracking {
}
void SectionTracker::tryOpen() {
- if( !isComplete() && (m_filters.empty() || m_filters[0].empty() || m_filters[0] == m_nameAndLocation.name ) )
+ if( !isComplete() )
open();
}
void SectionTracker::addInitialFilters( std::vector<std::string> const& filters ) {
if( !filters.empty() ) {
- m_filters.push_back(""); // Root - should never be consulted
- m_filters.push_back(""); // Test Case - not a section filter
+ m_filters.reserve( m_filters.size() + filters.size() + 2 );
+ m_filters.emplace_back(""); // Root - should never be consulted
+ m_filters.emplace_back(""); // Test Case - not a section filter
m_filters.insert( m_filters.end(), filters.begin(), filters.end() );
}
}
void SectionTracker::addNextFilters( std::vector<std::string> const& filters ) {
if( filters.size() > 1 )
- m_filters.insert( m_filters.end(), ++filters.begin(), filters.end() );
+ m_filters.insert( m_filters.end(), filters.begin()+1, filters.end() );
+ }
+
+ std::vector<std::string> const& SectionTracker::getFilters() const {
+ return m_filters;
+ }
+
+ std::string const& SectionTracker::trimmedName() const {
+ return m_trimmed_name;
}
} // namespace TestCaseTracking
@@ -13875,47 +14554,81 @@ namespace Catch {
namespace Catch {
+ TestSpec::Pattern::Pattern( std::string const& name )
+ : m_name( name )
+ {}
+
TestSpec::Pattern::~Pattern() = default;
- TestSpec::NamePattern::~NamePattern() = default;
- TestSpec::TagPattern::~TagPattern() = default;
- TestSpec::ExcludedPattern::~ExcludedPattern() = default;
- TestSpec::NamePattern::NamePattern( std::string const& name )
- : m_wildcardPattern( toLower( name ), CaseSensitive::No )
+ std::string const& TestSpec::Pattern::name() const {
+ return m_name;
+ }
+
+ TestSpec::NamePattern::NamePattern( std::string const& name, std::string const& filterString )
+ : Pattern( filterString )
+ , m_wildcardPattern( toLower( name ), CaseSensitive::No )
{}
+
bool TestSpec::NamePattern::matches( TestCaseInfo const& testCase ) const {
- return m_wildcardPattern.matches( toLower( testCase.name ) );
+ return m_wildcardPattern.matches( testCase.name );
}
- TestSpec::TagPattern::TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {}
+ TestSpec::TagPattern::TagPattern( std::string const& tag, std::string const& filterString )
+ : Pattern( filterString )
+ , m_tag( toLower( tag ) )
+ {}
+
bool TestSpec::TagPattern::matches( TestCaseInfo const& testCase ) const {
return std::find(begin(testCase.lcaseTags),
end(testCase.lcaseTags),
m_tag) != end(testCase.lcaseTags);
}
- TestSpec::ExcludedPattern::ExcludedPattern( PatternPtr const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {}
- bool TestSpec::ExcludedPattern::matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); }
+ TestSpec::ExcludedPattern::ExcludedPattern( PatternPtr const& underlyingPattern )
+ : Pattern( underlyingPattern->name() )
+ , m_underlyingPattern( underlyingPattern )
+ {}
+
+ bool TestSpec::ExcludedPattern::matches( TestCaseInfo const& testCase ) const {
+ return !m_underlyingPattern->matches( testCase );
+ }
bool TestSpec::Filter::matches( TestCaseInfo const& testCase ) const {
- // All patterns in a filter must match for the filter to be a match
- for( auto const& pattern : m_patterns ) {
- if( !pattern->matches( testCase ) )
- return false;
- }
- return true;
+ return std::all_of( m_patterns.begin(), m_patterns.end(), [&]( PatternPtr const& p ){ return p->matches( testCase ); } );
+ }
+
+ std::string TestSpec::Filter::name() const {
+ std::string name;
+ for( auto const& p : m_patterns )
+ name += p->name();
+ return name;
}
bool TestSpec::hasFilters() const {
return !m_filters.empty();
}
+
bool TestSpec::matches( TestCaseInfo const& testCase ) const {
- // A TestSpec matches if any filter matches
- for( auto const& filter : m_filters )
- if( filter.matches( testCase ) )
- return true;
- return false;
+ return std::any_of( m_filters.begin(), m_filters.end(), [&]( Filter const& f ){ return f.matches( testCase ); } );
}
+
+ TestSpec::Matches TestSpec::matchesByFilter( std::vector<TestCase> const& testCases, IConfig const& config ) const
+ {
+ Matches matches( m_filters.size() );
+ std::transform( m_filters.begin(), m_filters.end(), matches.begin(), [&]( Filter const& filter ){
+ std::vector<TestCase const*> currentMatches;
+ for( auto const& test : testCases )
+ if( isThrowSafe( test, config ) && filter.matches( test ) )
+ currentMatches.emplace_back( &test );
+ return FilterMatch{ filter.name(), currentMatches };
+ } );
+ return matches;
+ }
+
+ const TestSpec::vectorStrings& TestSpec::getInvalidArgs() const{
+ return (m_invalidArgs);
+ }
+
}
// end catch_test_spec.cpp
// start catch_test_spec_parser.cpp
@@ -13927,64 +14640,136 @@ namespace Catch {
TestSpecParser& TestSpecParser::parse( std::string const& arg ) {
m_mode = None;
m_exclusion = false;
- m_start = std::string::npos;
m_arg = m_tagAliases->expandAliases( arg );
m_escapeChars.clear();
+ m_substring.reserve(m_arg.size());
+ m_patternName.reserve(m_arg.size());
+ m_realPatternPos = 0;
+
for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
- visitChar( m_arg[m_pos] );
- if( m_mode == Name )
- addPattern<TestSpec::NamePattern>();
+ //if visitChar fails
+ if( !visitChar( m_arg[m_pos] ) ){
+ m_testSpec.m_invalidArgs.push_back(arg);
+ break;
+ }
+ endMode();
return *this;
}
TestSpec TestSpecParser::testSpec() {
addFilter();
return m_testSpec;
}
+ bool TestSpecParser::visitChar( char c ) {
+ if( (m_mode != EscapedName) && (c == '\\') ) {
+ escape();
+ addCharToPattern(c);
+ return true;
+ }else if((m_mode != EscapedName) && (c == ',') ) {
+ return separate();
+ }
- void TestSpecParser::visitChar( char c ) {
- if( m_mode == None ) {
- switch( c ) {
- case ' ': return;
- case '~': m_exclusion = true; return;
- case '[': return startNewMode( Tag, ++m_pos );
- case '"': return startNewMode( QuotedName, ++m_pos );
- case '\\': return escape();
- default: startNewMode( Name, m_pos ); break;
- }
+ switch( m_mode ) {
+ case None:
+ if( processNoneChar( c ) )
+ return true;
+ break;
+ case Name:
+ processNameChar( c );
+ break;
+ case EscapedName:
+ endMode();
+ addCharToPattern(c);
+ return true;
+ default:
+ case Tag:
+ case QuotedName:
+ if( processOtherChar( c ) )
+ return true;
+ break;
}
- if( m_mode == Name ) {
- if( c == ',' ) {
- addPattern<TestSpec::NamePattern>();
- addFilter();
- }
- else if( c == '[' ) {
- if( subString() == "exclude:" )
- m_exclusion = true;
- else
- addPattern<TestSpec::NamePattern>();
- startNewMode( Tag, ++m_pos );
- }
- else if( c == '\\' )
- escape();
+
+ m_substring += c;
+ if( !isControlChar( c ) ) {
+ m_patternName += c;
+ m_realPatternPos++;
+ }
+ return true;
+ }
+ // Two of the processing methods return true to signal the caller to return
+ // without adding the given character to the current pattern strings
+ bool TestSpecParser::processNoneChar( char c ) {
+ switch( c ) {
+ case ' ':
+ return true;
+ case '~':
+ m_exclusion = true;
+ return false;
+ case '[':
+ startNewMode( Tag );
+ return false;
+ case '"':
+ startNewMode( QuotedName );
+ return false;
+ default:
+ startNewMode( Name );
+ return false;
}
- else if( m_mode == EscapedName )
- m_mode = Name;
- else if( m_mode == QuotedName && c == '"' )
- addPattern<TestSpec::NamePattern>();
- else if( m_mode == Tag && c == ']' )
- addPattern<TestSpec::TagPattern>();
}
- void TestSpecParser::startNewMode( Mode mode, std::size_t start ) {
+ void TestSpecParser::processNameChar( char c ) {
+ if( c == '[' ) {
+ if( m_substring == "exclude:" )
+ m_exclusion = true;
+ else
+ endMode();
+ startNewMode( Tag );
+ }
+ }
+ bool TestSpecParser::processOtherChar( char c ) {
+ if( !isControlChar( c ) )
+ return false;
+ m_substring += c;
+ endMode();
+ return true;
+ }
+ void TestSpecParser::startNewMode( Mode mode ) {
m_mode = mode;
- m_start = start;
+ }
+ void TestSpecParser::endMode() {
+ switch( m_mode ) {
+ case Name:
+ case QuotedName:
+ return addNamePattern();
+ case Tag:
+ return addTagPattern();
+ case EscapedName:
+ revertBackToLastMode();
+ return;
+ case None:
+ default:
+ return startNewMode( None );
+ }
}
void TestSpecParser::escape() {
- if( m_mode == None )
- m_start = m_pos;
+ saveLastMode();
m_mode = EscapedName;
- m_escapeChars.push_back( m_pos );
+ m_escapeChars.push_back(m_realPatternPos);
+ }
+ bool TestSpecParser::isControlChar( char c ) const {
+ switch( m_mode ) {
+ default:
+ return false;
+ case None:
+ return c == '~';
+ case Name:
+ return c == '[';
+ case EscapedName:
+ return true;
+ case QuotedName:
+ return c == '"';
+ case Tag:
+ return c == '[' || c == ']';
+ }
}
- std::string TestSpecParser::subString() const { return m_arg.substr( m_start, m_pos - m_start ); }
void TestSpecParser::addFilter() {
if( !m_currentFilter.m_patterns.empty() ) {
@@ -13993,6 +14778,86 @@ namespace Catch {
}
}
+ void TestSpecParser::saveLastMode() {
+ lastMode = m_mode;
+ }
+
+ void TestSpecParser::revertBackToLastMode() {
+ m_mode = lastMode;
+ }
+
+ bool TestSpecParser::separate() {
+ if( (m_mode==QuotedName) || (m_mode==Tag) ){
+ //invalid argument, signal failure to previous scope.
+ m_mode = None;
+ m_pos = m_arg.size();
+ m_substring.clear();
+ m_patternName.clear();
+ m_realPatternPos = 0;
+ return false;
+ }
+ endMode();
+ addFilter();
+ return true; //success
+ }
+
+ std::string TestSpecParser::preprocessPattern() {
+ std::string token = m_patternName;
+ for (std::size_t i = 0; i < m_escapeChars.size(); ++i)
+ token = token.substr(0, m_escapeChars[i] - i) + token.substr(m_escapeChars[i] - i + 1);
+ m_escapeChars.clear();
+ if (startsWith(token, "exclude:")) {
+ m_exclusion = true;
+ token = token.substr(8);
+ }
+
+ m_patternName.clear();
+ m_realPatternPos = 0;
+
+ return token;
+ }
+
+ void TestSpecParser::addNamePattern() {
+ auto token = preprocessPattern();
+
+ if (!token.empty()) {
+ TestSpec::PatternPtr pattern = std::make_shared<TestSpec::NamePattern>(token, m_substring);
+ if (m_exclusion)
+ pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);
+ m_currentFilter.m_patterns.push_back(pattern);
+ }
+ m_substring.clear();
+ m_exclusion = false;
+ m_mode = None;
+ }
+
+ void TestSpecParser::addTagPattern() {
+ auto token = preprocessPattern();
+
+ if (!token.empty()) {
+ // If the tag pattern is the "hide and tag" shorthand (e.g. [.foo])
+ // we have to create a separate hide tag and shorten the real one
+ if (token.size() > 1 && token[0] == '.') {
+ token.erase(token.begin());
+ TestSpec::PatternPtr pattern = std::make_shared<TestSpec::TagPattern>(".", m_substring);
+ if (m_exclusion) {
+ pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);
+ }
+ m_currentFilter.m_patterns.push_back(pattern);
+ }
+
+ TestSpec::PatternPtr pattern = std::make_shared<TestSpec::TagPattern>(token, m_substring);
+
+ if (m_exclusion) {
+ pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);
+ }
+ m_currentFilter.m_patterns.push_back(pattern);
+ }
+ m_substring.clear();
+ m_exclusion = false;
+ m_mode = None;
+ }
+
TestSpec parseTestSpec( std::string const& arg ) {
return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
}
@@ -14094,13 +14959,11 @@ namespace Detail {
enum Arch { Big, Little };
static Arch which() {
- union _{
- int asInt;
- char asChar[sizeof (int)];
- } u;
-
- u.asInt = 1;
- return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little;
+ int one = 1;
+ // If the lowest byte we read is non-zero, we can assume
+ // that little endian format is used.
+ auto value = *reinterpret_cast<char*>(&one);
+ return value ? Little : Big;
}
};
}
@@ -14224,6 +15087,13 @@ std::string StringMaker<wchar_t *>::convert(wchar_t * str) {
}
#endif
+#if defined(CATCH_CONFIG_CPP17_BYTE)
+#include <cstddef>
+std::string StringMaker<std::byte>::convert(std::byte value) {
+ return ::Catch::Detail::stringify(std::to_integer<unsigned long long>(value));
+}
+#endif // defined(CATCH_CONFIG_CPP17_BYTE)
+
std::string StringMaker<int>::convert(int value) {
return ::Catch::Detail::stringify(static_cast<long long>(value));
}
@@ -14369,11 +15239,48 @@ namespace Catch {
// end catch_totals.cpp
// start catch_uncaught_exceptions.cpp
+// start catch_config_uncaught_exceptions.hpp
+
+// Copyright Catch2 Authors
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// https://www.boost.org/LICENSE_1_0.txt)
+
+// SPDX-License-Identifier: BSL-1.0
+
+#ifndef CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP
+#define CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP
+
+#if defined(_MSC_VER)
+# if _MSC_VER >= 1900 // Visual Studio 2015 or newer
+# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
+# endif
+#endif
+
+#include <exception>
+
+#if defined(__cpp_lib_uncaught_exceptions) \
+ && !defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
+
+# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
+#endif // __cpp_lib_uncaught_exceptions
+
+#if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) \
+ && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) \
+ && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
+
+# define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
+#endif
+
+#endif // CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP
+// end catch_config_uncaught_exceptions.hpp
#include <exception>
namespace Catch {
bool uncaught_exceptions() {
-#if defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
+#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
+ return false;
+#elif defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)
return std::uncaught_exceptions() > 0;
#else
return std::uncaught_exception();
@@ -14413,7 +15320,7 @@ namespace Catch {
}
Version const& libraryVersion() {
- static Version version( 2, 9, 0, "", 0 );
+ static Version version( 2, 13, 4, "", 0 );
return version;
}
@@ -14421,14 +15328,12 @@ namespace Catch {
// end catch_version.cpp
// start catch_wildcard_pattern.cpp
-#include <sstream>
-
namespace Catch {
WildcardPattern::WildcardPattern( std::string const& pattern,
CaseSensitive::Choice caseSensitivity )
: m_caseSensitivity( caseSensitivity ),
- m_pattern( adjustCase( pattern ) )
+ m_pattern( normaliseString( pattern ) )
{
if( startsWith( m_pattern, '*' ) ) {
m_pattern = m_pattern.substr( 1 );
@@ -14443,28 +15348,27 @@ namespace Catch {
bool WildcardPattern::matches( std::string const& str ) const {
switch( m_wildcard ) {
case NoWildcard:
- return m_pattern == adjustCase( str );
+ return m_pattern == normaliseString( str );
case WildcardAtStart:
- return endsWith( adjustCase( str ), m_pattern );
+ return endsWith( normaliseString( str ), m_pattern );
case WildcardAtEnd:
- return startsWith( adjustCase( str ), m_pattern );
+ return startsWith( normaliseString( str ), m_pattern );
case WildcardAtBothEnds:
- return contains( adjustCase( str ), m_pattern );
+ return contains( normaliseString( str ), m_pattern );
default:
CATCH_INTERNAL_ERROR( "Unknown enum" );
}
}
- std::string WildcardPattern::adjustCase( std::string const& str ) const {
- return m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str;
+ std::string WildcardPattern::normaliseString( std::string const& str ) const {
+ return trim( m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str );
}
}
// end catch_wildcard_pattern.cpp
// start catch_xmlwriter.cpp
#include <iomanip>
-
-using uchar = unsigned char;
+#include <type_traits>
namespace Catch {
@@ -14504,8 +15408,30 @@ namespace {
os.flags(f);
}
+ bool shouldNewline(XmlFormatting fmt) {
+ return !!(static_cast<std::underlying_type<XmlFormatting>::type>(fmt & XmlFormatting::Newline));
+ }
+
+ bool shouldIndent(XmlFormatting fmt) {
+ return !!(static_cast<std::underlying_type<XmlFormatting>::type>(fmt & XmlFormatting::Indent));
+ }
+
} // anonymous namespace
+ XmlFormatting operator | (XmlFormatting lhs, XmlFormatting rhs) {
+ return static_cast<XmlFormatting>(
+ static_cast<std::underlying_type<XmlFormatting>::type>(lhs) |
+ static_cast<std::underlying_type<XmlFormatting>::type>(rhs)
+ );
+ }
+
+ XmlFormatting operator & (XmlFormatting lhs, XmlFormatting rhs) {
+ return static_cast<XmlFormatting>(
+ static_cast<std::underlying_type<XmlFormatting>::type>(lhs) &
+ static_cast<std::underlying_type<XmlFormatting>::type>(rhs)
+ );
+ }
+
XmlEncode::XmlEncode( std::string const& str, ForWhat forWhat )
: m_str( str ),
m_forWhat( forWhat )
@@ -14516,7 +15442,7 @@ namespace {
// (see: http://www.w3.org/TR/xml/#syntax)
for( std::size_t idx = 0; idx < m_str.size(); ++ idx ) {
- uchar c = m_str[idx];
+ unsigned char c = m_str[idx];
switch (c) {
case '<': os << "&lt;"; break;
case '&': os << "&amp;"; break;
@@ -14576,7 +15502,7 @@ namespace {
bool valid = true;
uint32_t value = headerValue(c);
for (std::size_t n = 1; n < encBytes; ++n) {
- uchar nc = m_str[idx + n];
+ unsigned char nc = m_str[idx + n];
valid &= ((nc & 0xC0) == 0x80);
value = (value << 6) | (nc & 0x3F);
}
@@ -14610,13 +15536,17 @@ namespace {
return os;
}
- XmlWriter::ScopedElement::ScopedElement( XmlWriter* writer )
- : m_writer( writer )
+ XmlWriter::ScopedElement::ScopedElement( XmlWriter* writer, XmlFormatting fmt )
+ : m_writer( writer ),
+ m_fmt(fmt)
{}
XmlWriter::ScopedElement::ScopedElement( ScopedElement&& other ) noexcept
- : m_writer( other.m_writer ){
+ : m_writer( other.m_writer ),
+ m_fmt(other.m_fmt)
+ {
other.m_writer = nullptr;
+ other.m_fmt = XmlFormatting::None;
}
XmlWriter::ScopedElement& XmlWriter::ScopedElement::operator=( ScopedElement&& other ) noexcept {
if ( m_writer ) {
@@ -14624,16 +15554,19 @@ namespace {
}
m_writer = other.m_writer;
other.m_writer = nullptr;
+ m_fmt = other.m_fmt;
+ other.m_fmt = XmlFormatting::None;
return *this;
}
XmlWriter::ScopedElement::~ScopedElement() {
- if( m_writer )
- m_writer->endElement();
+ if (m_writer) {
+ m_writer->endElement(m_fmt);
+ }
}
- XmlWriter::ScopedElement& XmlWriter::ScopedElement::writeText( std::string const& text, bool indent ) {
- m_writer->writeText( text, indent );
+ XmlWriter::ScopedElement& XmlWriter::ScopedElement::writeText( std::string const& text, XmlFormatting fmt ) {
+ m_writer->writeText( text, fmt );
return *this;
}
@@ -14643,37 +15576,47 @@ namespace {
}
XmlWriter::~XmlWriter() {
- while( !m_tags.empty() )
+ while (!m_tags.empty()) {
endElement();
+ }
+ newlineIfNecessary();
}
- XmlWriter& XmlWriter::startElement( std::string const& name ) {
+ XmlWriter& XmlWriter::startElement( std::string const& name, XmlFormatting fmt ) {
ensureTagClosed();
newlineIfNecessary();
- m_os << m_indent << '<' << name;
+ if (shouldIndent(fmt)) {
+ m_os << m_indent;
+ m_indent += " ";
+ }
+ m_os << '<' << name;
m_tags.push_back( name );
- m_indent += " ";
m_tagIsOpen = true;
+ applyFormatting(fmt);
return *this;
}
- XmlWriter::ScopedElement XmlWriter::scopedElement( std::string const& name ) {
- ScopedElement scoped( this );
- startElement( name );
+ XmlWriter::ScopedElement XmlWriter::scopedElement( std::string const& name, XmlFormatting fmt ) {
+ ScopedElement scoped( this, fmt );
+ startElement( name, fmt );
return scoped;
}
- XmlWriter& XmlWriter::endElement() {
- newlineIfNecessary();
- m_indent = m_indent.substr( 0, m_indent.size()-2 );
+ XmlWriter& XmlWriter::endElement(XmlFormatting fmt) {
+ m_indent = m_indent.substr(0, m_indent.size() - 2);
+
if( m_tagIsOpen ) {
m_os << "/>";
m_tagIsOpen = false;
+ } else {
+ newlineIfNecessary();
+ if (shouldIndent(fmt)) {
+ m_os << m_indent;
+ }
+ m_os << "</" << m_tags.back() << ">";
}
- else {
- m_os << m_indent << "</" << m_tags.back() << ">";
- }
- m_os << std::endl;
+ m_os << std::flush;
+ applyFormatting(fmt);
m_tags.pop_back();
return *this;
}
@@ -14689,22 +15632,26 @@ namespace {
return *this;
}
- XmlWriter& XmlWriter::writeText( std::string const& text, bool indent ) {
+ XmlWriter& XmlWriter::writeText( std::string const& text, XmlFormatting fmt) {
if( !text.empty() ){
bool tagWasOpen = m_tagIsOpen;
ensureTagClosed();
- if( tagWasOpen && indent )
+ if (tagWasOpen && shouldIndent(fmt)) {
m_os << m_indent;
+ }
m_os << XmlEncode( text );
- m_needsNewline = true;
+ applyFormatting(fmt);
}
return *this;
}
- XmlWriter& XmlWriter::writeComment( std::string const& text ) {
+ XmlWriter& XmlWriter::writeComment( std::string const& text, XmlFormatting fmt) {
ensureTagClosed();
- m_os << m_indent << "<!--" << text << "-->";
- m_needsNewline = true;
+ if (shouldIndent(fmt)) {
+ m_os << m_indent;
+ }
+ m_os << "<!--" << text << "-->";
+ applyFormatting(fmt);
return *this;
}
@@ -14720,11 +15667,16 @@ namespace {
void XmlWriter::ensureTagClosed() {
if( m_tagIsOpen ) {
- m_os << ">" << std::endl;
+ m_os << '>' << std::flush;
+ newlineIfNecessary();
m_tagIsOpen = false;
}
}
+ void XmlWriter::applyFormatting(XmlFormatting fmt) {
+ m_needsNewline = shouldNewline(fmt);
+ }
+
void XmlWriter::writeDeclaration() {
m_os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
}
@@ -14770,6 +15722,17 @@ namespace Catch {
return std::string(buffer);
}
+ bool shouldShowDuration( IConfig const& config, double duration ) {
+ if ( config.showDurations() == ShowDurations::Always ) {
+ return true;
+ }
+ if ( config.showDurations() == ShowDurations::Never ) {
+ return false;
+ }
+ const double min = config.minDuration();
+ return min >= 0 && duration >= min;
+ }
+
std::string serializeFilters( std::vector<std::string> const& container ) {
ReusableStringStream oss;
bool first = true;
@@ -15000,24 +15963,25 @@ private:
if (itMessage == messages.end())
return;
- // using messages.end() directly yields (or auto) compilation error:
- std::vector<MessageInfo>::const_iterator itEnd = messages.end();
- const std::size_t N = static_cast<std::size_t>(std::distance(itMessage, itEnd));
+ const auto itEnd = messages.cend();
+ const auto N = static_cast<std::size_t>(std::distance(itMessage, itEnd));
{
Colour colourGuard(colour);
stream << " with " << pluralise(N, "message") << ':';
}
- for (; itMessage != itEnd; ) {
+ while (itMessage != itEnd) {
// If this assertion is a warning ignore any INFO messages
if (printInfoMessages || itMessage->type != ResultWas::Info) {
- stream << " '" << itMessage->message << '\'';
- if (++itMessage != itEnd) {
+ printMessage();
+ if (itMessage != itEnd) {
Colour colourGuard(dimColour());
stream << " and";
}
+ continue;
}
+ ++itMessage;
}
}
@@ -15035,10 +15999,6 @@ private:
return "Reports test results on a single line, suitable for IDEs";
}
- ReporterPreferences CompactReporter::getPreferences() const {
- return m_reporterPrefs;
- }
-
void CompactReporter::noMatchingTestCases( std::string const& spec ) {
stream << "No test cases matched '" << spec << '\'' << std::endl;
}
@@ -15065,8 +16025,9 @@ private:
}
void CompactReporter::sectionEnded(SectionStats const& _sectionStats) {
- if (m_config->showDurations() == ShowDurations::Always) {
- stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
+ double dur = _sectionStats.durationInSeconds;
+ if ( shouldShowDuration( *m_config, dur ) ) {
+ stream << getFormattedDuration( dur ) << " s: " << _sectionStats.sectionInfo.name << std::endl;
}
}
@@ -15278,15 +16239,11 @@ class Duration {
static const uint64_t s_nanosecondsInASecond = 1000 * s_nanosecondsInAMillisecond;
static const uint64_t s_nanosecondsInAMinute = 60 * s_nanosecondsInASecond;
- uint64_t m_inNanoseconds;
+ double m_inNanoseconds;
Unit m_units;
public:
- explicit Duration(double inNanoseconds, Unit units = Unit::Auto)
- : Duration(static_cast<uint64_t>(inNanoseconds), units) {
- }
-
- explicit Duration(uint64_t inNanoseconds, Unit units = Unit::Auto)
+ explicit Duration(double inNanoseconds, Unit units = Unit::Auto)
: m_inNanoseconds(inNanoseconds),
m_units(units) {
if (m_units == Unit::Auto) {
@@ -15315,7 +16272,7 @@ public:
case Unit::Minutes:
return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMinute);
default:
- return static_cast<double>(m_inNanoseconds);
+ return m_inNanoseconds;
}
}
auto unitsAsString() const -> std::string {
@@ -15336,7 +16293,7 @@ public:
}
friend auto operator << (std::ostream& os, Duration const& duration) -> std::ostream& {
- return os << duration.value() << " " << duration.unitsAsString();
+ return os << duration.value() << ' ' << duration.unitsAsString();
}
};
} // end anon namespace
@@ -15368,9 +16325,9 @@ public:
headerCols += Column(info.name).width(static_cast<std::size_t>(info.width - 2));
headerCols += spacer;
}
- m_os << headerCols << "\n";
+ m_os << headerCols << '\n';
- m_os << Catch::getLineOfChars<'-'>() << "\n";
+ m_os << Catch::getLineOfChars<'-'>() << '\n';
}
}
void close() {
@@ -15389,30 +16346,29 @@ public:
friend TablePrinter& operator << (TablePrinter& tp, ColumnBreak) {
auto colStr = tp.m_oss.str();
- // This takes account of utf8 encodings
- auto strSize = Catch::StringRef(colStr).numberOfCharacters();
+ const auto strSize = colStr.size();
tp.m_oss.str("");
tp.open();
if (tp.m_currentColumn == static_cast<int>(tp.m_columnInfos.size() - 1)) {
tp.m_currentColumn = -1;
- tp.m_os << "\n";
+ tp.m_os << '\n';
}
tp.m_currentColumn++;
auto colInfo = tp.m_columnInfos[tp.m_currentColumn];
- auto padding = (strSize + 2 < static_cast<std::size_t>(colInfo.width))
- ? std::string(colInfo.width - (strSize + 2), ' ')
+ auto padding = (strSize + 1 < static_cast<std::size_t>(colInfo.width))
+ ? std::string(colInfo.width - (strSize + 1), ' ')
: std::string();
if (colInfo.justification == ColumnInfo::Left)
- tp.m_os << colStr << padding << " ";
+ tp.m_os << colStr << padding << ' ';
else
- tp.m_os << padding << colStr << " ";
+ tp.m_os << padding << colStr << ' ';
return tp;
}
friend TablePrinter& operator << (TablePrinter& tp, RowBreak) {
if (tp.m_currentColumn > 0) {
- tp.m_os << "\n";
+ tp.m_os << '\n';
tp.m_currentColumn = -1;
}
return tp;
@@ -15422,12 +16378,26 @@ public:
ConsoleReporter::ConsoleReporter(ReporterConfig const& config)
: StreamingReporterBase(config),
m_tablePrinter(new TablePrinter(config.stream(),
- {
- { "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 32, ColumnInfo::Left },
- { "samples mean std dev", 14, ColumnInfo::Right },
- { "iterations low mean low std dev", 14, ColumnInfo::Right },
- { "estimated high mean high std dev", 14, ColumnInfo::Right }
- })) {}
+ [&config]() -> std::vector<ColumnInfo> {
+ if (config.fullConfig()->benchmarkNoAnalysis())
+ {
+ return{
+ { "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 43, ColumnInfo::Left },
+ { " samples", 14, ColumnInfo::Right },
+ { " iterations", 14, ColumnInfo::Right },
+ { " mean", 14, ColumnInfo::Right }
+ };
+ }
+ else
+ {
+ return{
+ { "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 43, ColumnInfo::Left },
+ { "samples mean std dev", 14, ColumnInfo::Right },
+ { "iterations low mean low std dev", 14, ColumnInfo::Right },
+ { "estimated high mean high std dev", 14, ColumnInfo::Right }
+ };
+ }
+ }())) {}
ConsoleReporter::~ConsoleReporter() = default;
std::string ConsoleReporter::getDescription() {
@@ -15438,6 +16408,10 @@ void ConsoleReporter::noMatchingTestCases(std::string const& spec) {
stream << "No test cases matched '" << spec << '\'' << std::endl;
}
+void ConsoleReporter::reportInvalidArguments(std::string const&arg){
+ stream << "Invalid Filter: " << arg << std::endl;
+}
+
void ConsoleReporter::assertionStarting(AssertionInfo const&) {}
bool ConsoleReporter::assertionEnded(AssertionStats const& _assertionStats) {
@@ -15473,8 +16447,9 @@ void ConsoleReporter::sectionEnded(SectionStats const& _sectionStats) {
stream << "\nNo assertions in test case";
stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl;
}
- if (m_config->showDurations() == ShowDurations::Always) {
- stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl;
+ double dur = _sectionStats.durationInSeconds;
+ if (shouldShowDuration(*m_config, dur)) {
+ stream << getFormattedDuration(dur) << " s: " << _sectionStats.sectionInfo.name << std::endl;
}
if (m_headerPrinted) {
m_headerPrinted = false;
@@ -15500,24 +16475,32 @@ void ConsoleReporter::benchmarkPreparing(std::string const& name) {
}
void ConsoleReporter::benchmarkStarting(BenchmarkInfo const& info) {
- (*m_tablePrinter) << info.samples << ColumnBreak()
- << info.iterations << ColumnBreak()
- << Duration(info.estimatedDuration) << ColumnBreak();
+ (*m_tablePrinter) << info.samples << ColumnBreak()
+ << info.iterations << ColumnBreak();
+ if (!m_config->benchmarkNoAnalysis())
+ (*m_tablePrinter) << Duration(info.estimatedDuration) << ColumnBreak();
}
void ConsoleReporter::benchmarkEnded(BenchmarkStats<> const& stats) {
- (*m_tablePrinter) << ColumnBreak()
- << Duration(stats.mean.point.count()) << ColumnBreak()
- << Duration(stats.mean.lower_bound.count()) << ColumnBreak()
- << Duration(stats.mean.upper_bound.count()) << ColumnBreak() << ColumnBreak()
- << Duration(stats.standardDeviation.point.count()) << ColumnBreak()
- << Duration(stats.standardDeviation.lower_bound.count()) << ColumnBreak()
- << Duration(stats.standardDeviation.upper_bound.count()) << ColumnBreak() << ColumnBreak() << ColumnBreak() << ColumnBreak() << ColumnBreak();
+ if (m_config->benchmarkNoAnalysis())
+ {
+ (*m_tablePrinter) << Duration(stats.mean.point.count()) << ColumnBreak();
+ }
+ else
+ {
+ (*m_tablePrinter) << ColumnBreak()
+ << Duration(stats.mean.point.count()) << ColumnBreak()
+ << Duration(stats.mean.lower_bound.count()) << ColumnBreak()
+ << Duration(stats.mean.upper_bound.count()) << ColumnBreak() << ColumnBreak()
+ << Duration(stats.standardDeviation.point.count()) << ColumnBreak()
+ << Duration(stats.standardDeviation.lower_bound.count()) << ColumnBreak()
+ << Duration(stats.standardDeviation.upper_bound.count()) << ColumnBreak() << ColumnBreak() << ColumnBreak() << ColumnBreak() << ColumnBreak();
+ }
}
void ConsoleReporter::benchmarkFailed(std::string const& error) {
Colour colour(Colour::Red);
(*m_tablePrinter)
- << "Benchmark failed (" << error << ")"
+ << "Benchmark failed (" << error << ')'
<< ColumnBreak() << RowBreak();
}
#endif // CATCH_CONFIG_ENABLE_BENCHMARKING
@@ -15599,11 +16582,9 @@ void ConsoleReporter::printTestCaseAndSectionHeader() {
SourceLineInfo lineInfo = m_sectionStack.back().lineInfo;
- if (!lineInfo.empty()) {
- stream << getLineOfChars<'-'>() << '\n';
- Colour colourGuard(Colour::FileName);
- stream << lineInfo << '\n';
- }
+ stream << getLineOfChars<'-'>() << '\n';
+ Colour colourGuard(Colour::FileName);
+ stream << lineInfo << '\n';
stream << getLineOfChars<'.'>() << '\n' << std::endl;
}
@@ -15728,8 +16709,10 @@ void ConsoleReporter::printSummaryDivider() {
}
void ConsoleReporter::printTestFilters() {
- if (m_config->testSpec().hasFilters())
- stream << Colour(Colour::BrightYellow) << "Filters: " << serializeFilters( m_config->getTestsOrTags() ) << '\n';
+ if (m_config->testSpec().hasFilters()) {
+ Colour guard(Colour::BrightYellow);
+ stream << "Filters: " << serializeFilters(m_config->getTestsOrTags()) << '\n';
+ }
}
CATCH_REGISTER_REPORTER("console", ConsoleReporter)
@@ -15879,8 +16862,8 @@ namespace Catch {
for( auto const& child : groupNode.children )
writeTestCase( *child );
- xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite ), false );
- xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite ), false );
+ xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite ), XmlFormatting::Newline );
+ xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite ), XmlFormatting::Newline );
}
void JunitReporter::writeTestCase( TestCaseNode const& testCaseNode ) {
@@ -15925,13 +16908,18 @@ namespace Catch {
xml.writeAttribute( "name", name );
}
xml.writeAttribute( "time", ::Catch::Detail::stringify( sectionNode.stats.durationInSeconds ) );
+ // This is not ideal, but it should be enough to mimic gtest's
+ // junit output.
+ // Ideally the JUnit reporter would also handle `skipTest`
+ // events and write those out appropriately.
+ xml.writeAttribute( "status", "run" );
writeAssertions( sectionNode );
if( !sectionNode.stdOut.empty() )
- xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), false );
+ xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), XmlFormatting::Newline );
if( !sectionNode.stdErr.empty() )
- xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), false );
+ xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), XmlFormatting::Newline );
}
for( auto const& childNode : sectionNode.childSections )
if( className.empty() )
@@ -15955,11 +16943,7 @@ namespace Catch {
elementName = "error";
break;
case ResultWas::ExplicitFailure:
- elementName = "failure";
- break;
case ResultWas::ExpressionFailed:
- elementName = "failure";
- break;
case ResultWas::DidntThrowException:
elementName = "failure";
break;
@@ -15977,10 +16961,25 @@ namespace Catch {
XmlWriter::ScopedElement e = xml.scopedElement( elementName );
- xml.writeAttribute( "message", result.getExpandedExpression() );
+ xml.writeAttribute( "message", result.getExpression() );
xml.writeAttribute( "type", result.getTestMacroName() );
ReusableStringStream rss;
+ if (stats.totals.assertions.total() > 0) {
+ rss << "FAILED" << ":\n";
+ if (result.hasExpression()) {
+ rss << " ";
+ rss << result.getExpressionInMacro();
+ rss << '\n';
+ }
+ if (result.hasExpandedExpression()) {
+ rss << "with expansion:\n";
+ rss << Column(result.getExpandedExpression()).indent(2) << '\n';
+ }
+ } else {
+ rss << '\n';
+ }
+
if( !result.getMessage().empty() )
rss << result.getMessage() << '\n';
for( auto const& msg : stats.infoMessages )
@@ -15988,7 +16987,7 @@ namespace Catch {
rss << msg.message << '\n';
rss << "at " << result.getSourceInfo();
- xml.writeText( rss.str(), false );
+ xml.writeText( rss.str(), XmlFormatting::Newline );
}
}
@@ -16032,6 +17031,13 @@ namespace Catch {
m_reporter->noMatchingTestCases( spec );
}
+ void ListeningReporter::reportInvalidArguments(std::string const&arg){
+ for ( auto const& listener : m_listeners ) {
+ listener->reportInvalidArguments( arg );
+ }
+ m_reporter->reportInvalidArguments( arg );
+ }
+
#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
void ListeningReporter::benchmarkPreparing( std::string const& name ) {
for (auto const& listener : m_listeners) {
@@ -16327,9 +17333,9 @@ namespace Catch {
e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() );
if( !testCaseStats.stdOut.empty() )
- m_xml.scopedElement( "StdOut" ).writeText( trim( testCaseStats.stdOut ), false );
+ m_xml.scopedElement( "StdOut" ).writeText( trim( testCaseStats.stdOut ), XmlFormatting::Newline );
if( !testCaseStats.stdErr.empty() )
- m_xml.scopedElement( "StdErr" ).writeText( trim( testCaseStats.stdErr ), false );
+ m_xml.scopedElement( "StdErr" ).writeText( trim( testCaseStats.stdErr ), XmlFormatting::Newline );
m_xml.endElement();
}
@@ -16341,6 +17347,10 @@ namespace Catch {
.writeAttribute( "successes", testGroupStats.totals.assertions.passed )
.writeAttribute( "failures", testGroupStats.totals.assertions.failed )
.writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk );
+ m_xml.scopedElement( "OverallResultsCases")
+ .writeAttribute( "successes", testGroupStats.totals.testCases.passed )
+ .writeAttribute( "failures", testGroupStats.totals.testCases.failed )
+ .writeAttribute( "expectedFailures", testGroupStats.totals.testCases.failedButOk );
m_xml.endElement();
}
@@ -16350,26 +17360,33 @@ namespace Catch {
.writeAttribute( "successes", testRunStats.totals.assertions.passed )
.writeAttribute( "failures", testRunStats.totals.assertions.failed )
.writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk );
+ m_xml.scopedElement( "OverallResultsCases")
+ .writeAttribute( "successes", testRunStats.totals.testCases.passed )
+ .writeAttribute( "failures", testRunStats.totals.testCases.failed )
+ .writeAttribute( "expectedFailures", testRunStats.totals.testCases.failedButOk );
m_xml.endElement();
}
#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
- void XmlReporter::benchmarkStarting(BenchmarkInfo const &info) {
+ void XmlReporter::benchmarkPreparing(std::string const& name) {
m_xml.startElement("BenchmarkResults")
- .writeAttribute("name", info.name)
- .writeAttribute("samples", info.samples)
+ .writeAttribute("name", name);
+ }
+
+ void XmlReporter::benchmarkStarting(BenchmarkInfo const &info) {
+ m_xml.writeAttribute("samples", info.samples)
.writeAttribute("resamples", info.resamples)
.writeAttribute("iterations", info.iterations)
- .writeAttribute("clockResolution", static_cast<uint64_t>(info.clockResolution))
- .writeAttribute("estimatedDuration", static_cast<uint64_t>(info.estimatedDuration))
+ .writeAttribute("clockResolution", info.clockResolution)
+ .writeAttribute("estimatedDuration", info.estimatedDuration)
.writeComment("All values in nano seconds");
}
void XmlReporter::benchmarkEnded(BenchmarkStats<> const& benchmarkStats) {
m_xml.startElement("mean")
- .writeAttribute("value", static_cast<uint64_t>(benchmarkStats.mean.point.count()))
- .writeAttribute("lowerBound", static_cast<uint64_t>(benchmarkStats.mean.lower_bound.count()))
- .writeAttribute("upperBound", static_cast<uint64_t>(benchmarkStats.mean.upper_bound.count()))
+ .writeAttribute("value", benchmarkStats.mean.point.count())
+ .writeAttribute("lowerBound", benchmarkStats.mean.lower_bound.count())
+ .writeAttribute("upperBound", benchmarkStats.mean.upper_bound.count())
.writeAttribute("ci", benchmarkStats.mean.confidence_interval);
m_xml.endElement();
m_xml.startElement("standardDeviation")
@@ -16420,7 +17437,7 @@ namespace Catch {
#ifndef __OBJC__
-#if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN)
+#if defined(CATCH_CONFIG_WCHAR) && defined(CATCH_PLATFORM_WINDOWS) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN)
// Standard C/C++ Win32 Unicode wmain entry point
extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) {
#else
diff --git a/3rdparty/bx/LICENSE b/3rdparty/bx/LICENSE
index 1c8e1e05472..9fbd22dcba1 100644
--- a/3rdparty/bx/LICENSE
+++ b/3rdparty/bx/LICENSE
@@ -1,4 +1,4 @@
-Copyright 2010-2019 Branimir Karadzic
+Copyright 2010-2021 Branimir Karadzic
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
diff --git a/3rdparty/bx/README.md b/3rdparty/bx/README.md
index 00d6d8a0205..3a6547daf5c 100644
--- a/3rdparty/bx/README.md
+++ b/3rdparty/bx/README.md
@@ -3,10 +3,10 @@ bx
Base library.
-[![Build Status](https://travis-ci.org/bkaradzic/bx.svg?branch=master)](https://travis-ci.org/bkaradzic/bx)
+[![Build Status](https://travis-ci.com/bkaradzic/bx.svg?branch=master)](https://travis-ci.com/bkaradzic/bx)
[![Build status](https://ci.appveyor.com/api/projects/status/edras3mltmoy31g5?svg=true)](https://ci.appveyor.com/project/bkaradzic/bx)
[![License](https://img.shields.io/badge/license-BSD--2%20clause-blue.svg)](https://bkaradzic.github.io/bgfx/license.html)
-[![Join the chat at https://gitter.im/bkaradzic/bgfx](https://badges.gitter.im/bkaradzic/bgfx.svg)](https://gitter.im/bkaradzic/bgfx)
+[![Join the chat at https://discord.gg/9eMbv7J](https://img.shields.io/discord/712512073522872352?color=%237289DA&label=bx&logo=discord&logoColor=white)](https://discord.gg/9eMbv7J)
Contact
-------
@@ -23,7 +23,7 @@ https://github.com/bkaradzic/bx
<img align="right" src="http://opensource.org/trademarks/opensource/OSI-Approved-License-100x137.png">
</a>
- Copyright 2010-2019 Branimir Karadzic
+ Copyright 2010-2021 Branimir Karadzic
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
diff --git a/3rdparty/bx/include/bx/allocator.h b/3rdparty/bx/include/bx/allocator.h
index 7a140b0b562..94d7835da8a 100644
--- a/3rdparty/bx/include/bx/allocator.h
+++ b/3rdparty/bx/include/bx/allocator.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -7,6 +7,7 @@
#define BX_ALLOCATOR_H_HEADER_GUARD
#include "bx.h"
+#include "uint32_t.h"
#if BX_CONFIG_ALLOCATOR_DEBUG
# define BX_ALLOC(_allocator, _size) bx::alloc(_allocator, _size, 0, __FILE__, __LINE__)
diff --git a/3rdparty/bx/include/bx/bx.h b/3rdparty/bx/include/bx/bx.h
index 2cfc676d795..36f40aab493 100644
--- a/3rdparty/bx/include/bx/bx.h
+++ b/3rdparty/bx/include/bx/bx.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -20,24 +20,28 @@
#define BX_COUNTOF(_x) sizeof(bx::CountOfRequireArrayArgumentT(_x) )
///
-#define BX_IGNORE_C4127(_x) bx::ignoreC4127(!!(_x) )
+#if BX_COMPILER_MSVC
+# define BX_IGNORE_C4127(_x) bx::ignoreC4127(!!(_x) )
+#else
+# define BX_IGNORE_C4127(_x) (!!(_x) )
+#endif // BX_COMPILER_MSVC
///
-#define BX_ENABLED(_x) bx::isEnabled<!!(_x)>()
+#define BX_ENABLED(_x) BX_IGNORE_C4127(bx::isEnabled<!!(_x)>::value)
namespace bx
{
constexpr int32_t kExitSuccess = 0;
constexpr int32_t kExitFailure = 1;
- /// Template for avoiding MSVC: C4127: conditional expression is constant
- template<bool>
- constexpr bool isEnabled();
-
///
template<class Ty>
constexpr bool isTriviallyCopyable();
+ /// Find the address of an object of a class that has an overloaded unary ampersand (&) operator.
+ template <class Ty>
+ Ty* addressOf(Ty& _a);
+
/// Swap two values.
template<typename Ty>
void swap(Ty& _a, Ty& _b);
diff --git a/3rdparty/bx/include/bx/commandline.h b/3rdparty/bx/include/bx/commandline.h
index 058b51c5a5a..48815ddccce 100644
--- a/3rdparty/bx/include/bx/commandline.h
+++ b/3rdparty/bx/include/bx/commandline.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/include/bx/config.h b/3rdparty/bx/include/bx/config.h
index 247968a04d7..9a9670731a8 100644
--- a/3rdparty/bx/include/bx/config.h
+++ b/3rdparty/bx/include/bx/config.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/include/bx/cpu.h b/3rdparty/bx/include/bx/cpu.h
index 9cadf408bd0..20f6a5fd970 100644
--- a/3rdparty/bx/include/bx/cpu.h
+++ b/3rdparty/bx/include/bx/cpu.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/include/bx/debug.h b/3rdparty/bx/include/bx/debug.h
index b5a9bc0534e..d8cf15e0690 100644
--- a/3rdparty/bx/include/bx/debug.h
+++ b/3rdparty/bx/include/bx/debug.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/include/bx/easing.h b/3rdparty/bx/include/bx/easing.h
index 034999081cf..3aa44ca0a20 100644
--- a/3rdparty/bx/include/bx/easing.h
+++ b/3rdparty/bx/include/bx/easing.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2011-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2011-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/include/bx/endian.h b/3rdparty/bx/include/bx/endian.h
index f9eeba0ec54..9eeb0ef19e5 100644
--- a/3rdparty/bx/include/bx/endian.h
+++ b/3rdparty/bx/include/bx/endian.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/include/bx/error.h b/3rdparty/bx/include/bx/error.h
index f1416b64a7b..d00d8af4b48 100644
--- a/3rdparty/bx/include/bx/error.h
+++ b/3rdparty/bx/include/bx/error.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -8,22 +8,22 @@
#include "string.h"
-#define BX_ERROR_SET(_ptr, _result, _msg) \
- BX_MACRO_BLOCK_BEGIN \
- (_ptr)->setError(_result, "" _msg); \
- BX_MACRO_BLOCK_END
+#define BX_ERROR_SET(_ptr, _result, _msg) \
+ BX_MACRO_BLOCK_BEGIN \
+ (_ptr)->setError(_result, "" _msg); \
+ BX_MACRO_BLOCK_END
-#define BX_ERROR_USE_TEMP_WHEN_NULL(_ptr) \
- const bx::Error tmpError; /* It should not be used directly! */ \
- _ptr = NULL == _ptr ? const_cast<bx::Error*>(&tmpError) : _ptr
+#define BX_ERROR_USE_TEMP_WHEN_NULL(_ptr) \
+ const bx::Error tmpError; /* It should not be used directly! */ \
+ _ptr = NULL == _ptr ? const_cast<bx::Error*>(&tmpError) : _ptr
-#define BX_ERROR_SCOPE(_ptr) \
- BX_ERROR_USE_TEMP_WHEN_NULL(_ptr); \
- bx::ErrorScope bxErrorScope(const_cast<bx::Error*>(&tmpError) )
+#define BX_ERROR_SCOPE(_ptr, ...) \
+ BX_ERROR_USE_TEMP_WHEN_NULL(_ptr); \
+ bx::ErrorScope bxErrorScope(const_cast<bx::Error*>(&tmpError), "" __VA_ARGS__)
-#define BX_ERROR_RESULT(_err, _code) \
- BX_STATIC_ASSERT(_code != 0, "ErrorCode 0 is reserved!"); \
- static const bx::ErrorResult _err = { _code }
+#define BX_ERROR_RESULT(_err, _code) \
+ BX_STATIC_ASSERT(_code != 0, "ErrorCode 0 is reserved!"); \
+ static constexpr bx::ErrorResult _err = { _code }
namespace bx
{
@@ -81,13 +81,17 @@ namespace bx
public:
///
- ErrorScope(Error* _err);
+ ErrorScope(Error* _err, const StringView& _name);
///
~ErrorScope();
+ ///
+ const StringView& getName() const;
+
private:
Error* m_err;
+ const StringView m_name;
};
} // namespace bx
diff --git a/3rdparty/bx/include/bx/file.h b/3rdparty/bx/include/bx/file.h
index 42c15ba9622..e692224131c 100644
--- a/3rdparty/bx/include/bx/file.h
+++ b/3rdparty/bx/include/bx/file.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/include/bx/filepath.h b/3rdparty/bx/include/bx/filepath.h
index 920c0b4bbe2..3de0ce0d4fc 100644
--- a/3rdparty/bx/include/bx/filepath.h
+++ b/3rdparty/bx/include/bx/filepath.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -9,11 +9,11 @@
#include "error.h"
#include "string.h"
-BX_ERROR_RESULT(BX_ERROR_ACCESS, BX_MAKEFOURCC('b', 'x', 0, 0) );
-BX_ERROR_RESULT(BX_ERROR_NOT_DIRECTORY, BX_MAKEFOURCC('b', 'x', 0, 1) );
-
namespace bx
{
+ BX_ERROR_RESULT(kErrorAccess, BX_MAKEFOURCC('b', 'x', 1, 1) );
+ BX_ERROR_RESULT(kErrorNotDirectory, BX_MAKEFOURCC('b', 'x', 1, 2) );
+
constexpr int32_t kMaxFilePath = 1024;
/// Special predefined OS directories.
diff --git a/3rdparty/bx/include/bx/float4x4_t.h b/3rdparty/bx/include/bx/float4x4_t.h
index 9ec367f0739..893029cc290 100644
--- a/3rdparty/bx/include/bx/float4x4_t.h
+++ b/3rdparty/bx/include/bx/float4x4_t.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -10,25 +10,35 @@
namespace bx
{
- ///
+ /// 4x4 matrix.
BX_ALIGN_DECL_16(struct) float4x4_t
{
simd128_t col[4];
};
- ///
+ /// Multiplies vector `_a` with matrix `_b` ignoring W component of vector `_a`.
simd128_t simd_mul_xyz1(simd128_t _a, const float4x4_t* _b);
- ///
+ /// Multiplies vector `_a` with matrix `_b`.
simd128_t simd_mul(simd128_t _a, const float4x4_t* _b);
- ///
+ /// Multiplies two matrices.
void float4x4_mul(float4x4_t* _result, const float4x4_t* _a, const float4x4_t* _b);
- ///
+ /// Multiplies two 3x4 affine matrices (i.e. "model" or "world" matrices).
+ /// This function is a micro-optimized version of float4x4_mul() in the case
+ /// when the last row of the both input matrices are (0, 0, 0, 1).
+ void model4x4_mul(float4x4_t* _result, const float4x4_t* _a, const float4x4_t* _b);
+
+ /// Multiplies a 3x4 affine matrix with a general 4x4 matrix.
+ /// This function is a micro-optimized version of float4x4_mul() in the case
+ /// when the last row of the _model input matrix is (0, 0, 0, 1).
+ void model4x4_mul_viewproj4x4(float4x4_t* _result, const float4x4_t* _model, const float4x4_t* _viewProj);
+
+ /// Transpose of matrix.
void float4x4_transpose(float4x4_t* _result, const float4x4_t* _mtx);
- ///
+ /// Inverse of matrix.
void float4x4_inverse(float4x4_t* _result, const float4x4_t* _a);
} // namespace bx
diff --git a/3rdparty/bx/include/bx/handlealloc.h b/3rdparty/bx/include/bx/handlealloc.h
index a4432b9d176..92a9d8671ed 100644
--- a/3rdparty/bx/include/bx/handlealloc.h
+++ b/3rdparty/bx/include/bx/handlealloc.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -12,7 +12,7 @@
namespace bx
{
- static const uint16_t kInvalidHandle = UINT16_MAX;
+ constexpr uint16_t kInvalidHandle = UINT16_MAX;
///
class HandleAlloc
diff --git a/3rdparty/bx/include/bx/hash.h b/3rdparty/bx/include/bx/hash.h
index 976fa21acb7..42d76e1a681 100644
--- a/3rdparty/bx/include/bx/hash.h
+++ b/3rdparty/bx/include/bx/hash.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/include/bx/inline/allocator.inl b/3rdparty/bx/include/bx/inline/allocator.inl
index ce4ccc92a72..8e5085fa4a7 100644
--- a/3rdparty/bx/include/bx/inline/allocator.inl
+++ b/3rdparty/bx/include/bx/inline/allocator.inl
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -22,20 +22,12 @@ namespace bx
{
}
- inline bool isAligned(const void* _ptr, size_t _align)
- {
- union { const void* ptr; uintptr_t addr; } un;
- un.ptr = _ptr;
- return 0 == (un.addr & (_align-1) );
- }
-
inline void* alignPtr(void* _ptr, size_t _extra, size_t _align)
{
union { void* ptr; uintptr_t addr; } un;
un.ptr = _ptr;
uintptr_t unaligned = un.addr + _extra; // space for header
- uintptr_t mask = _align-1;
- uintptr_t aligned = BX_ALIGN_MASK(unaligned, mask);
+ uintptr_t aligned = bx::alignUp(unaligned, int32_t(_align) );
un.addr = aligned;
return un.ptr;
}
diff --git a/3rdparty/bx/include/bx/inline/bx.inl b/3rdparty/bx/include/bx/inline/bx.inl
index b0083571ac4..fc527ec79ce 100644
--- a/3rdparty/bx/include/bx/inline/bx.inl
+++ b/3rdparty/bx/include/bx/inline/bx.inl
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -15,10 +15,16 @@ namespace bx
template<typename Ty, size_t Num>
char(&CountOfRequireArrayArgumentT(const Ty(&)[Num]))[Num];
- template<bool>
- inline constexpr bool isEnabled()
+ template<bool B>
+ struct isEnabled
{
- return true;
+ // Template for avoiding MSVC: C4127: conditional expression is constant
+ static constexpr bool value = B;
+ };
+
+ inline constexpr bool ignoreC4127(bool _x)
+ {
+ return _x;
}
template<class Ty>
@@ -27,15 +33,14 @@ namespace bx
return __is_trivially_copyable(Ty);
}
- template<>
- inline constexpr bool isEnabled<false>()
- {
- return false;
- }
-
- inline constexpr bool ignoreC4127(bool _x)
+ template<class Ty>
+ inline Ty* addressOf(Ty& _a)
{
- return _x;
+ return reinterpret_cast<Ty*>(
+ &const_cast<char&>(
+ reinterpret_cast<const volatile char&>(_a)
+ )
+ );
}
template<typename Ty>
diff --git a/3rdparty/bx/include/bx/inline/cpu.inl b/3rdparty/bx/include/bx/inline/cpu.inl
index b5a83a4f68d..f02fc177175 100644
--- a/3rdparty/bx/include/bx/inline/cpu.inl
+++ b/3rdparty/bx/include/bx/inline/cpu.inl
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -8,13 +8,16 @@
#endif // BX_CPU_H_HEADER_GUARD
#if BX_COMPILER_MSVC
-# if BX_PLATFORM_WINRT
+# if BX_PLATFORM_WINRT || (BX_PLATFORM_WINDOWS && !BX_CPU_X86)
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+# endif // WIN32_LEAN_AND_MEAN
# include <windows.h>
-# endif // BX_PLATFORM_WINRT
+# endif // BX_PLATFORM_WINRT || (BX_PLATFORM_WINDOWS && !BX_CPU_X86)
# if BX_CPU_X86
# include <emmintrin.h> // _mm_fence
-# endif
+# endif // BX_CPU_X86
extern "C" void _ReadBarrier();
# pragma intrinsic(_ReadBarrier)
@@ -68,7 +71,7 @@ namespace bx
_ReadBarrier();
#else
asm volatile("":::"memory");
-#endif // BX_COMPILER
+#endif // BX_COMPILER_*
}
inline void writeBarrier()
@@ -77,7 +80,7 @@ namespace bx
_WriteBarrier();
#else
asm volatile("":::"memory");
-#endif // BX_COMPILER
+#endif // BX_COMPILER_*
}
inline void readWriteBarrier()
@@ -86,18 +89,20 @@ namespace bx
_ReadWriteBarrier();
#else
asm volatile("":::"memory");
-#endif // BX_COMPILER
+#endif // BX_COMPILER_*
}
inline void memoryBarrier()
{
-#if BX_PLATFORM_WINRT
- MemoryBarrier();
-#elif BX_COMPILER_MSVC
+#if BX_COMPILER_MSVC
+# if BX_CPU_X86
_mm_mfence();
+# else
+ MemoryBarrier();
+# endif // BX_CPU_X86
#else
__sync_synchronize();
-#endif // BX_COMPILER
+#endif // BX_COMPILER_MSVC
}
template<>
@@ -107,7 +112,7 @@ namespace bx
return int32_t(_InterlockedCompareExchange( (volatile long*)(_ptr), long(_new), long(_old) ) );
#else
return __sync_val_compare_and_swap( (volatile int32_t*)_ptr, _old, _new);
-#endif // BX_COMPILER
+#endif // BX_COMPILER_*
}
template<>
@@ -117,7 +122,7 @@ namespace bx
return uint32_t(_InterlockedCompareExchange( (volatile long*)(_ptr), long(_new), long(_old) ) );
#else
return __sync_val_compare_and_swap( (volatile int32_t*)_ptr, _old, _new);
-#endif // BX_COMPILER
+#endif // BX_COMPILER_*
}
template<>
@@ -127,7 +132,7 @@ namespace bx
return _InterlockedCompareExchange64(_ptr, _new, _old);
#else
return __sync_val_compare_and_swap( (volatile int64_t*)_ptr, _old, _new);
-#endif // BX_COMPILER
+#endif // BX_COMPILER_*
}
template<>
@@ -137,7 +142,7 @@ namespace bx
return uint64_t(_InterlockedCompareExchange64( (volatile int64_t*)(_ptr), int64_t(_new), int64_t(_old) ) );
#else
return __sync_val_compare_and_swap( (volatile int64_t*)_ptr, _old, _new);
-#endif // BX_COMPILER
+#endif // BX_COMPILER_*
}
template<>
@@ -147,7 +152,7 @@ namespace bx
return _InterlockedExchangeAdd( (volatile long*)_ptr, _add);
#else
return __sync_fetch_and_add(_ptr, _add);
-#endif // BX_COMPILER_
+#endif // BX_COMPILER_*
}
template<>
@@ -176,7 +181,7 @@ namespace bx
# endif
#else
return __sync_fetch_and_add(_ptr, _add);
-#endif // BX_COMPILER_
+#endif // BX_COMPILER_*
}
template<>
@@ -192,7 +197,7 @@ namespace bx
return atomicFetchAndAdd(_ptr, _add) + _add;
#else
return __sync_add_and_fetch(_ptr, _add);
-#endif // BX_COMPILER_
+#endif // BX_COMPILER_*
}
template<>
@@ -202,7 +207,7 @@ namespace bx
return atomicFetchAndAdd(_ptr, _add) + _add;
#else
return __sync_add_and_fetch(_ptr, _add);
-#endif // BX_COMPILER_
+#endif // BX_COMPILER_*
}
template<>
@@ -224,7 +229,7 @@ namespace bx
return atomicFetchAndAdd(_ptr, -_sub);
#else
return __sync_fetch_and_sub(_ptr, _sub);
-#endif // BX_COMPILER_
+#endif // BX_COMPILER_*
}
template<>
@@ -234,7 +239,7 @@ namespace bx
return atomicFetchAndAdd(_ptr, -_sub);
#else
return __sync_fetch_and_sub(_ptr, _sub);
-#endif // BX_COMPILER_
+#endif // BX_COMPILER_*
}
template<>
@@ -256,7 +261,7 @@ namespace bx
return atomicFetchAndAdd(_ptr, -_sub) - _sub;
#else
return __sync_sub_and_fetch(_ptr, _sub);
-#endif // BX_COMPILER_
+#endif // BX_COMPILER_*
}
template<>
@@ -266,7 +271,7 @@ namespace bx
return atomicFetchAndAdd(_ptr, -_sub) - _sub;
#else
return __sync_sub_and_fetch(_ptr, _sub);
-#endif // BX_COMPILER_
+#endif // BX_COMPILER_*
}
template<>
@@ -347,7 +352,7 @@ namespace bx
return _InterlockedExchangePointer(_ptr, _new);
#else
return __sync_lock_test_and_set(_ptr, _new);
-#endif // BX_COMPILER
+#endif // BX_COMPILER_*
}
} // namespace bx
diff --git a/3rdparty/bx/include/bx/inline/easing.inl b/3rdparty/bx/include/bx/inline/easing.inl
index 02bd7d4e225..18bbe943091 100644
--- a/3rdparty/bx/include/bx/inline/easing.inl
+++ b/3rdparty/bx/include/bx/inline/easing.inl
@@ -1,5 +1,5 @@
/*
- * Copyright 2011-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2011-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/include/bx/inline/endian.inl b/3rdparty/bx/include/bx/inline/endian.inl
index c0fd7480c7a..de0f7abf945 100644
--- a/3rdparty/bx/include/bx/inline/endian.inl
+++ b/3rdparty/bx/include/bx/inline/endian.inl
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/include/bx/inline/error.inl b/3rdparty/bx/include/bx/inline/error.inl
index badb75633b0..382c624990a 100644
--- a/3rdparty/bx/include/bx/inline/error.inl
+++ b/3rdparty/bx/include/bx/inline/error.inl
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -22,7 +22,7 @@ namespace bx
inline void Error::setError(ErrorResult _errorResult, const StringView& _msg)
{
- BX_CHECK(0 != _errorResult.code, "Invalid ErrorResult passed to setError!");
+ BX_ASSERT(0 != _errorResult.code, "Invalid ErrorResult passed to setError!");
if (!isOk() )
{
@@ -59,15 +59,38 @@ namespace bx
return _rhs.code != m_code;
}
- inline ErrorScope::ErrorScope(Error* _err)
+ inline ErrorScope::ErrorScope(Error* _err, const StringView& _name)
: m_err(_err)
+ , m_name(_name)
{
- BX_CHECK(NULL != _err, "_err can't be NULL");
+ BX_ASSERT(NULL != _err, "_err can't be NULL");
}
inline ErrorScope::~ErrorScope()
{
- BX_CHECK(m_err->isOk(), "Error: %d", m_err->get().code);
+ if (m_name.isEmpty() )
+ {
+ BX_ASSERT(m_err->isOk(), "Error: 0x%08x `%.*s`"
+ , m_err->get().code
+ , m_err->getMessage().getLength()
+ , m_err->getMessage().getPtr()
+ );
+ }
+ else
+ {
+ BX_ASSERT(m_err->isOk(), "Error: %.*s - 0x%08x `%.*s`"
+ , m_name.getLength()
+ , m_name.getPtr()
+ , m_err->get().code
+ , m_err->getMessage().getLength()
+ , m_err->getMessage().getPtr()
+ );
+ }
+ }
+
+ inline const StringView& ErrorScope::getName() const
+ {
+ return m_name;
}
} // namespace bx
diff --git a/3rdparty/bx/include/bx/inline/float4x4_t.inl b/3rdparty/bx/include/bx/inline/float4x4_t.inl
index 27bf00d5618..6a3bfb6d90a 100644
--- a/3rdparty/bx/include/bx/inline/float4x4_t.inl
+++ b/3rdparty/bx/include/bx/inline/float4x4_t.inl
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -40,10 +40,99 @@ namespace bx
BX_SIMD_INLINE void float4x4_mul(float4x4_t* _result, const float4x4_t* _a, const float4x4_t* _b)
{
+#if BX_CONFIG_SUPPORTS_SIMD
_result->col[0] = simd_mul(_a->col[0], _b);
_result->col[1] = simd_mul(_a->col[1], _b);
_result->col[2] = simd_mul(_a->col[2], _b);
_result->col[3] = simd_mul(_a->col[3], _b);
+#else
+ const float* aa = (const float*)_a;
+ const float* bb = (const float*)_b;
+ float *rr = (float*)_result;
+
+ rr[ 0] = aa[ 0]*bb[ 0] + aa[ 1]*bb[ 4] + aa[ 2]*bb[ 8] + aa[ 3]*bb[12];
+ rr[ 1] = aa[ 0]*bb[ 1] + aa[ 1]*bb[ 5] + aa[ 2]*bb[ 9] + aa[ 3]*bb[13];
+ rr[ 2] = aa[ 0]*bb[ 2] + aa[ 1]*bb[ 6] + aa[ 2]*bb[10] + aa[ 3]*bb[14];
+ rr[ 3] = aa[ 0]*bb[ 3] + aa[ 1]*bb[ 7] + aa[ 2]*bb[11] + aa[ 3]*bb[15];
+
+ rr[ 4] = aa[ 4]*bb[ 0] + aa[ 5]*bb[ 4] + aa[ 6]*bb[ 8] + aa[ 7]*bb[12];
+ rr[ 5] = aa[ 4]*bb[ 1] + aa[ 5]*bb[ 5] + aa[ 6]*bb[ 9] + aa[ 7]*bb[13];
+ rr[ 6] = aa[ 4]*bb[ 2] + aa[ 5]*bb[ 6] + aa[ 6]*bb[10] + aa[ 7]*bb[14];
+ rr[ 7] = aa[ 4]*bb[ 3] + aa[ 5]*bb[ 7] + aa[ 6]*bb[11] + aa[ 7]*bb[15];
+
+ rr[ 8] = aa[ 8]*bb[ 0] + aa[ 9]*bb[ 4] + aa[10]*bb[ 8] + aa[11]*bb[12];
+ rr[ 9] = aa[ 8]*bb[ 1] + aa[ 9]*bb[ 5] + aa[10]*bb[ 9] + aa[11]*bb[13];
+ rr[10] = aa[ 8]*bb[ 2] + aa[ 9]*bb[ 6] + aa[10]*bb[10] + aa[11]*bb[14];
+ rr[11] = aa[ 8]*bb[ 3] + aa[ 9]*bb[ 7] + aa[10]*bb[11] + aa[11]*bb[15];
+
+ rr[12] = aa[12]*bb[ 0] + aa[13]*bb[ 4] + aa[14]*bb[ 8] + aa[15]*bb[12];
+ rr[13] = aa[12]*bb[ 1] + aa[13]*bb[ 5] + aa[14]*bb[ 9] + aa[15]*bb[13];
+ rr[14] = aa[12]*bb[ 2] + aa[13]*bb[ 6] + aa[14]*bb[10] + aa[15]*bb[14];
+ rr[15] = aa[12]*bb[ 3] + aa[13]*bb[ 7] + aa[14]*bb[11] + aa[15]*bb[15];
+#endif // BX_CONFIG_SUPPORTS_SIMD
+ }
+
+ BX_SIMD_INLINE void model4x4_mul(float4x4_t* _result, const float4x4_t* _a, const float4x4_t* _b)
+ {
+#if BX_CONFIG_SUPPORTS_SIMD
+ // With SIMD faster to do the general 4x4 form:
+ float4x4_mul(_result, _a, _b);
+#else
+ const float* aa = (const float*)_a; // aa[ 3] == aa[ 7] == aa[11] == 0.0f, aa[15] = 1.0f
+ const float* bb = (const float*)_b; // bb[ 3] == bb[ 7] == bb[11] == 0.0f, bb[15] = 1.0f
+ float *rr = (float*)_result;
+
+ rr[ 0] = aa[ 0]*bb[ 0] + aa[ 1]*bb[ 4] + aa[ 2]*bb[ 8];
+ rr[ 1] = aa[ 0]*bb[ 1] + aa[ 1]*bb[ 5] + aa[ 2]*bb[ 9];
+ rr[ 2] = aa[ 0]*bb[ 2] + aa[ 1]*bb[ 6] + aa[ 2]*bb[10];
+ rr[ 3] = 0.0f;
+
+ rr[ 4] = aa[ 4]*bb[ 0] + aa[ 5]*bb[ 4] + aa[ 6]*bb[ 8];
+ rr[ 5] = aa[ 4]*bb[ 1] + aa[ 5]*bb[ 5] + aa[ 6]*bb[ 9];
+ rr[ 6] = aa[ 4]*bb[ 2] + aa[ 5]*bb[ 6] + aa[ 6]*bb[10];
+ rr[ 7] = 0.0f;
+
+ rr[ 8] = aa[ 8]*bb[ 0] + aa[ 9]*bb[ 4] + aa[10]*bb[ 8];
+ rr[ 9] = aa[ 8]*bb[ 1] + aa[ 9]*bb[ 5] + aa[10]*bb[ 9];
+ rr[10] = aa[ 8]*bb[ 2] + aa[ 9]*bb[ 6] + aa[10]*bb[10];
+ rr[11] = 0.0f;
+
+ rr[12] = aa[12]*bb[ 0] + aa[13]*bb[ 4] + aa[14]*bb[ 8] + bb[12];
+ rr[13] = aa[12]*bb[ 1] + aa[13]*bb[ 5] + aa[14]*bb[ 9] + bb[13];
+ rr[14] = aa[12]*bb[ 2] + aa[13]*bb[ 6] + aa[14]*bb[10] + bb[14];
+ rr[15] = 1.0f;
+#endif // BX_CONFIG_SUPPORTS_SIMD
+ }
+
+ BX_SIMD_INLINE void model4x4_mul_viewproj4x4(float4x4_t* _result, const float4x4_t* _model, const float4x4_t* _viewProj)
+ {
+#if BX_CONFIG_SUPPORTS_SIMD
+ // With SIMD faster to do the general 4x4 form:
+ float4x4_mul(_result, _model, _viewProj);
+#else
+ const float* aa = (const float*)_model; // aa[ 3] == aa[ 7] == aa[11] == 0.0f, aa[15] == 1.0f
+ const float* bb = (const float*)_viewProj;
+ float *rr = (float*)_result;
+ rr[ 0] = aa[ 0]*bb[ 0] + aa[ 1]*bb[ 4] + aa[ 2]*bb[ 8];
+ rr[ 1] = aa[ 0]*bb[ 1] + aa[ 1]*bb[ 5] + aa[ 2]*bb[ 9];
+ rr[ 2] = aa[ 0]*bb[ 2] + aa[ 1]*bb[ 6] + aa[ 2]*bb[10];
+ rr[ 3] = aa[ 0]*bb[ 3] + aa[ 1]*bb[ 7] + aa[ 2]*bb[11];
+
+ rr[ 4] = aa[ 4]*bb[ 0] + aa[ 5]*bb[ 4] + aa[ 6]*bb[ 8];
+ rr[ 5] = aa[ 4]*bb[ 1] + aa[ 5]*bb[ 5] + aa[ 6]*bb[ 9];
+ rr[ 6] = aa[ 4]*bb[ 2] + aa[ 5]*bb[ 6] + aa[ 6]*bb[10];
+ rr[ 7] = aa[ 4]*bb[ 3] + aa[ 5]*bb[ 7] + aa[ 6]*bb[11];
+
+ rr[ 8] = aa[ 8]*bb[ 0] + aa[ 9]*bb[ 4] + aa[10]*bb[ 8];
+ rr[ 9] = aa[ 8]*bb[ 1] + aa[ 9]*bb[ 5] + aa[10]*bb[ 9];
+ rr[10] = aa[ 8]*bb[ 2] + aa[ 9]*bb[ 6] + aa[10]*bb[10];
+ rr[11] = aa[ 8]*bb[ 3] + aa[ 9]*bb[ 7] + aa[10]*bb[11];
+
+ rr[12] = aa[12]*bb[ 0] + aa[13]*bb[ 4] + aa[14]*bb[ 8] + bb[12];
+ rr[13] = aa[12]*bb[ 1] + aa[13]*bb[ 5] + aa[14]*bb[ 9] + bb[13];
+ rr[14] = aa[12]*bb[ 2] + aa[13]*bb[ 6] + aa[14]*bb[10] + bb[14];
+ rr[15] = aa[12]*bb[ 3] + aa[13]*bb[ 7] + aa[14]*bb[11] + bb[15];
+#endif // BX_CONFIG_SUPPORTS_SIMD
}
BX_SIMD_FORCE_INLINE void float4x4_transpose(float4x4_t* _result, const float4x4_t* _mtx)
diff --git a/3rdparty/bx/include/bx/inline/handlealloc.inl b/3rdparty/bx/include/bx/inline/handlealloc.inl
index 94b7ebbda4a..4579e05ba43 100644
--- a/3rdparty/bx/include/bx/inline/handlealloc.inl
+++ b/3rdparty/bx/include/bx/inline/handlealloc.inl
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -186,7 +186,7 @@ namespace bx
template <uint16_t MaxHandlesT>
inline uint16_t HandleListT<MaxHandlesT>::getNext(uint16_t _handle) const
{
- BX_CHECK(isValid(_handle), "Invalid handle %d!", _handle);
+ BX_ASSERT(isValid(_handle), "Invalid handle %d!", _handle);
const Link& curr = m_links[_handle];
return curr.m_next;
}
@@ -194,7 +194,7 @@ namespace bx
template <uint16_t MaxHandlesT>
inline uint16_t HandleListT<MaxHandlesT>::getPrev(uint16_t _handle) const
{
- BX_CHECK(isValid(_handle), "Invalid handle %d!", _handle);
+ BX_ASSERT(isValid(_handle), "Invalid handle %d!", _handle);
const Link& curr = m_links[_handle];
return curr.m_prev;
}
@@ -202,7 +202,7 @@ namespace bx
template <uint16_t MaxHandlesT>
inline void HandleListT<MaxHandlesT>::remove(uint16_t _handle)
{
- BX_CHECK(isValid(_handle), "Invalid handle %d!", _handle);
+ BX_ASSERT(isValid(_handle), "Invalid handle %d!", _handle);
Link& curr = m_links[_handle];
if (kInvalidHandle != curr.m_prev)
@@ -358,7 +358,7 @@ namespace bx
template <uint16_t MaxHandlesT>
inline void HandleAllocLruT<MaxHandlesT>::free(uint16_t _handle)
{
- BX_CHECK(isValid(_handle), "Invalid handle %d!", _handle);
+ BX_ASSERT(isValid(_handle), "Invalid handle %d!", _handle);
m_list.remove(_handle);
m_alloc.free(_handle);
}
@@ -366,7 +366,7 @@ namespace bx
template <uint16_t MaxHandlesT>
inline void HandleAllocLruT<MaxHandlesT>::touch(uint16_t _handle)
{
- BX_CHECK(isValid(_handle), "Invalid handle %d!", _handle);
+ BX_ASSERT(isValid(_handle), "Invalid handle %d!", _handle);
m_list.remove(_handle);
m_list.pushFront(_handle);
}
diff --git a/3rdparty/bx/include/bx/inline/hash.inl b/3rdparty/bx/include/bx/inline/hash.inl
index 56430e1470b..6b2ebcc8de0 100644
--- a/3rdparty/bx/include/bx/inline/hash.inl
+++ b/3rdparty/bx/include/bx/inline/hash.inl
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/include/bx/inline/math.inl b/3rdparty/bx/include/bx/inline/math.inl
index 6f946e1f82a..1da6b2d2c32 100644
--- a/3rdparty/bx/include/bx/inline/math.inl
+++ b/3rdparty/bx/include/bx/inline/math.inl
@@ -1,5 +1,5 @@
/*
- * Copyright 2011-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2011-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -124,7 +124,11 @@ namespace bx
inline BX_CONSTEXPR_FUNC float lerp(float _a, float _b, float _t)
{
- return _a + (_b - _a) * _t;
+ // Reference(s):
+ // - Linear interpolation past, present and future
+ // https://web.archive.org/web/20200404165201/https://fgiesen.wordpress.com/2012/08/15/linear-interpolation-past-present-and-future/
+ //
+ return mad(_t, _b, nms(_t, _a, _a) );
}
inline BX_CONSTEXPR_FUNC float invLerp(float _a, float _b, float _value)
@@ -277,11 +281,21 @@ namespace bx
return _a - trunc(_a);
}
+ inline BX_CONSTEXPR_FUNC float nms(float _a, float _b, float _c)
+ {
+ return _c - _a * _b;
+ }
+
inline BX_CONSTEXPR_FUNC float mad(float _a, float _b, float _c)
{
return _a * _b + _c;
}
+ inline BX_CONSTEXPR_FUNC float rcp(float _a)
+ {
+ return 1.0f / _a;
+ }
+
inline BX_CONST_FUNC float mod(float _a, float _b)
{
return _a - _b * floor(_a / _b);
@@ -330,6 +344,11 @@ namespace bx
return square(_a)*(3.0f - 2.0f*_a);
}
+ inline BX_CONST_FUNC float invSmoothStep(float _a)
+ {
+ return 0.5f - sin(asin(1.0f - 2.0f * _a) / 3.0f);
+ }
+
inline BX_CONSTEXPR_FUNC float bias(float _time, float _bias)
{
return _time / ( ( (1.0f/_bias - 2.0f)*(1.0f - _time) ) + 1.0f);
@@ -483,6 +502,16 @@ namespace bx
};
}
+ inline BX_CONSTEXPR_FUNC Vec3 div(const Vec3 _a, const Vec3 _b)
+ {
+ return mul(_a, rcp(_b) );
+ }
+
+ inline BX_CONSTEXPR_FUNC Vec3 div(const Vec3 _a, float _b)
+ {
+ return mul(_a, rcp(_b) );
+ }
+
inline BX_CONSTEXPR_FUNC Vec3 mad(const Vec3 _a, const float _b, const Vec3 _c)
{
return add(mul(_a, _b), _c);
diff --git a/3rdparty/bx/include/bx/inline/mpscqueue.inl b/3rdparty/bx/include/bx/inline/mpscqueue.inl
index fcff39bff86..c05d8eb8c52 100644
--- a/3rdparty/bx/include/bx/inline/mpscqueue.inl
+++ b/3rdparty/bx/include/bx/inline/mpscqueue.inl
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/include/bx/inline/mutex.inl b/3rdparty/bx/include/bx/inline/mutex.inl
index 7b1ee37c909..6d06f522707 100644
--- a/3rdparty/bx/include/bx/inline/mutex.inl
+++ b/3rdparty/bx/include/bx/inline/mutex.inl
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/include/bx/inline/os.inl b/3rdparty/bx/include/bx/inline/os.inl
new file mode 100644
index 00000000000..3c7eee96a44
--- /dev/null
+++ b/3rdparty/bx/include/bx/inline/os.inl
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
+ */
+
+#ifndef BX_H_HEADER_GUARD
+# error "Must be included from bx/os.h!"
+#endif // BX_H_HEADER_GUARD
+
+namespace bx
+{
+ template<typename ProtoT>
+ inline ProtoT dlsym(void* _handle, const StringView& _symbol)
+ {
+ return reinterpret_cast<ProtoT>(dlsym(_handle, _symbol) );
+ }
+
+} // namespace bx
diff --git a/3rdparty/bx/include/bx/inline/pixelformat.inl b/3rdparty/bx/include/bx/inline/pixelformat.inl
index 72e2c943c86..7985b32a088 100644
--- a/3rdparty/bx/include/bx/inline/pixelformat.inl
+++ b/3rdparty/bx/include/bx/inline/pixelformat.inl
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/include/bx/inline/readerwriter.inl b/3rdparty/bx/include/bx/inline/readerwriter.inl
index 66c8d6d45a7..27f848423bb 100644
--- a/3rdparty/bx/include/bx/inline/readerwriter.inl
+++ b/3rdparty/bx/include/bx/inline/readerwriter.inl
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -118,7 +118,7 @@ namespace bx
inline int32_t SizerWriter::write(const void* /*_data*/, int32_t _size, Error* _err)
{
- BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
+ BX_ASSERT(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
int32_t morecore = int32_t(m_pos - m_top) + _size;
@@ -132,7 +132,7 @@ namespace bx
m_pos += size;
if (size != _size)
{
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_WRITE, "SizerWriter: write truncated.");
+ BX_ERROR_SET(_err, kErrorReaderWriterWrite, "SizerWriter: write truncated.");
}
return size;
}
@@ -170,7 +170,7 @@ namespace bx
inline int32_t MemoryReader::read(void* _data, int32_t _size, Error* _err)
{
- BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
+ BX_ASSERT(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
int64_t remainder = m_top-m_pos;
int32_t size = uint32_min(_size, uint32_t(min<int64_t>(remainder, INT32_MAX) ) );
@@ -178,7 +178,7 @@ namespace bx
m_pos += size;
if (size != _size)
{
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_READ, "MemoryReader: read truncated.");
+ BX_ERROR_SET(_err, kErrorReaderWriterRead, "MemoryReader: read truncated.");
}
return size;
}
@@ -233,13 +233,13 @@ namespace bx
inline int32_t MemoryWriter::write(const void* _data, int32_t _size, Error* _err)
{
- BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
+ BX_ASSERT(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
int32_t morecore = int32_t(m_pos - m_size) + _size;
if (0 < morecore)
{
- morecore = BX_ALIGN_MASK(morecore, 0xfff);
+ morecore = alignUp(morecore, 0x1000);
m_data = (uint8_t*)m_memBlock->more(morecore);
m_size = m_memBlock->getSize();
}
@@ -251,7 +251,7 @@ namespace bx
m_top = max(m_top, m_pos);
if (size != _size)
{
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_WRITE, "MemoryWriter: write truncated.");
+ BX_ERROR_SET(_err, kErrorReaderWriterWrite, "MemoryWriter: write truncated.");
}
return size;
}
@@ -422,7 +422,7 @@ namespace bx
const int64_t offset = bx::seek(_reader, size);
if (offset != aligned)
{
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_WRITE, "Align: read truncated.");
+ BX_ERROR_SET(_err, kErrorReaderWriterWrite, "Align: read truncated.");
}
return int32_t(offset - current);
}
diff --git a/3rdparty/bx/include/bx/inline/ringbuffer.inl b/3rdparty/bx/include/bx/inline/ringbuffer.inl
index d0f0a8b2eda..d4ec68239b8 100644
--- a/3rdparty/bx/include/bx/inline/ringbuffer.inl
+++ b/3rdparty/bx/include/bx/inline/ringbuffer.inl
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -161,7 +161,7 @@ namespace bx
, m_size(_size)
, m_buffer(_buffer)
{
- BX_CHECK(_control.available() >= _size, "%d >= %d", _control.available(), _size);
+ BX_ASSERT(_control.available() >= _size, "%d >= %d", _control.available(), _size);
}
template <typename ControlT>
@@ -210,7 +210,7 @@ namespace bx
{
uint32_t size = m_control.reserve(_size);
BX_UNUSED(size);
- BX_CHECK(size == _size, "%d == %d", size, _size);
+ BX_ASSERT(size == _size, "%d == %d", size, _size);
m_write = m_control.m_current;
m_end = m_write+_size;
}
diff --git a/3rdparty/bx/include/bx/inline/rng.inl b/3rdparty/bx/include/bx/inline/rng.inl
index 4ac29703f0c..0aebbf101c3 100644
--- a/3rdparty/bx/include/bx/inline/rng.inl
+++ b/3rdparty/bx/include/bx/inline/rng.inl
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -137,7 +137,7 @@ namespace bx
template<typename Rng, typename Ty>
inline void shuffle(Rng* _rng, Ty* _array, uint32_t _num)
{
- BX_CHECK(_num != 0, "Number of elements can't be 0!");
+ BX_ASSERT(_num != 0, "Number of elements can't be 0!");
for (uint32_t ii = 0, num = _num-1; ii < num; ++ii)
{
diff --git a/3rdparty/bx/include/bx/inline/simd128_langext.inl b/3rdparty/bx/include/bx/inline/simd128_langext.inl
index 2c58becd247..f007de35cd6 100644
--- a/3rdparty/bx/include/bx/inline/simd128_langext.inl
+++ b/3rdparty/bx/include/bx/inline/simd128_langext.inl
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -347,6 +347,14 @@ BX_SIMD128_IMPLEMENT_TEST(xyzw , 0xf);
}
template<>
+ BX_SIMD_FORCE_INLINE simd128_langext_t simd_cmpneq(simd128_langext_t _a, simd128_langext_t _b)
+ {
+ simd128_langext_t result;
+ result.vi = _a.vf != _b.vf;
+ return result;
+ }
+
+ template<>
BX_SIMD_FORCE_INLINE simd128_langext_t simd_cmplt(simd128_langext_t _a, simd128_langext_t _b)
{
simd128_langext_t result;
diff --git a/3rdparty/bx/include/bx/inline/simd128_neon.inl b/3rdparty/bx/include/bx/inline/simd128_neon.inl
index 1aa40952e31..d71ffb6969e 100644
--- a/3rdparty/bx/include/bx/inline/simd128_neon.inl
+++ b/3rdparty/bx/include/bx/inline/simd128_neon.inl
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -9,6 +9,15 @@
namespace bx
{
+
+#if BX_COMPILER_CLANG
+# define SHUFFLE_A(_a, _i0, _i1, _i2, _i3) __builtin_shufflevector(_a, _a, _i0, _i1, _i2, _i3 )
+# define SHUFFLE_AB(_a, _b, _i0, _i1, _i2, _i3) __builtin_shufflevector(_a, _b, _i0, _i1, _i2, _i3 )
+#else
+# define SHUFFLE_A(_a, _i0, _i1, _i2, _i3) __builtin_shuffle(_a, (uint32x4_t){ _i0, _i1, _i2, _i3 })
+# define SHUFFLE_AB(_a, _b, _i0, _i1, _i2, _i3) __builtin_shuffle(_a, _b, (uint32x4_t){ _i0, _i1, _i2, _i3 })
+#endif
+
#define ELEMx 0
#define ELEMy 1
#define ELEMz 2
@@ -17,7 +26,7 @@ namespace bx
template<> \
BX_SIMD_FORCE_INLINE simd128_neon_t simd_swiz_##_x##_y##_z##_w(simd128_neon_t _a) \
{ \
- return __builtin_shuffle(_a, (uint32x4_t){ ELEM##_x, ELEM##_y, ELEM##_z, ELEM##_w }); \
+ return SHUFFLE_A(_a, ELEM##_x, ELEM##_y, ELEM##_z, ELEM##_w ); \
}
#include "simd128_swizzle.inl"
@@ -74,50 +83,52 @@ BX_SIMD128_IMPLEMENT_TEST(yzw, yzww);
template<>
BX_SIMD_FORCE_INLINE simd128_neon_t simd_shuf_xyAB(simd128_neon_t _a, simd128_neon_t _b)
{
- return __builtin_shuffle(_a, _b, (uint32x4_t){ 0, 1, 4, 5 });
+ return SHUFFLE_AB(_a, _b, 0, 1, 4, 5 );
}
template<>
BX_SIMD_FORCE_INLINE simd128_neon_t simd_shuf_ABxy(simd128_neon_t _a, simd128_neon_t _b)
{
- return __builtin_shuffle(_a, _b, (uint32x4_t){ 4, 5, 0, 1 });
+ return SHUFFLE_AB(_a, _b, 4, 5, 0, 1 );
}
template<>
BX_SIMD_FORCE_INLINE simd128_neon_t simd_shuf_CDzw(simd128_neon_t _a, simd128_neon_t _b)
{
- return __builtin_shuffle(_a, _b, (uint32x4_t){ 6, 7, 2, 3 });
+ return SHUFFLE_AB(_a, _b, 6, 7, 2, 3 );
}
template<>
BX_SIMD_FORCE_INLINE simd128_neon_t simd_shuf_zwCD(simd128_neon_t _a, simd128_neon_t _b)
{
- return __builtin_shuffle(_a, _b, (uint32x4_t){ 2, 3, 6, 7 });
+ return SHUFFLE_AB(_a, _b, 2, 3, 6, 7 );
}
template<>
BX_SIMD_FORCE_INLINE simd128_neon_t simd_shuf_xAyB(simd128_neon_t _a, simd128_neon_t _b)
{
- return __builtin_shuffle(_a, _b, (uint32x4_t){ 0, 4, 1, 5 });
+ return SHUFFLE_AB(_a, _b, 0, 4, 1, 5 );
}
template<>
BX_SIMD_FORCE_INLINE simd128_neon_t simd_shuf_AxBy(simd128_neon_t _a, simd128_neon_t _b)
{
- return __builtin_shuffle(_a, _b, (uint32x4_t){ 1, 5, 0, 4 });
+ return SHUFFLE_AB(_a, _b, 4, 0, 5, 1 );
}
template<>
BX_SIMD_FORCE_INLINE simd128_neon_t simd_shuf_zCwD(simd128_neon_t _a, simd128_neon_t _b)
{
- return __builtin_shuffle(_a, _b, (uint32x4_t){ 2, 6, 3, 7 });
+ return SHUFFLE_AB(_a, _b, 2, 6, 3, 7 );
}
template<>
BX_SIMD_FORCE_INLINE simd128_neon_t simd_shuf_CzDw(simd128_neon_t _a, simd128_neon_t _b)
{
- return __builtin_shuffle(_a, _b, (uint32x4_t){ 6, 2, 7, 3 });
+ return SHUFFLE_AB(_a, _b, 6, 2, 7, 3 );
}
+#undef SHUFFLE_A
+#undef SHUFFLE_AB
template<>
BX_SIMD_FORCE_INLINE float simd_x(simd128_neon_t _a)
@@ -273,10 +284,16 @@ BX_SIMD128_IMPLEMENT_TEST(yzw, yzww);
}
template<>
+ BX_SIMD_FORCE_INLINE simd128_neon_t simd_cmpneq(simd128_neon_t _a, simd128_neon_t _b)
+ {
+ return simd_cmpneq_ni(_a, _b);
+ }
+
+ template<>
BX_SIMD_FORCE_INLINE simd128_neon_t simd_cmplt(simd128_neon_t _a, simd128_neon_t _b)
{
- const uint32x4_t tmp = vcltq_f32(_a, _b);
- const simd128_neon_t result = vreinterpretq_f32_u32(tmp);
+ const uint32x4_t tmp = vcltq_f32(_a, _b);
+ const simd128_neon_t result = vreinterpretq_f32_u32(tmp);
return result;
}
@@ -284,8 +301,8 @@ BX_SIMD128_IMPLEMENT_TEST(yzw, yzww);
template<>
BX_SIMD_FORCE_INLINE simd128_neon_t simd_cmple(simd128_neon_t _a, simd128_neon_t _b)
{
- const uint32x4_t tmp = vcleq_f32(_a, _b);
- const simd128_neon_t result = vreinterpretq_f32_u32(tmp);
+ const uint32x4_t tmp = vcleq_f32(_a, _b);
+ const simd128_neon_t result = vreinterpretq_f32_u32(tmp);
return result;
}
@@ -293,8 +310,8 @@ BX_SIMD128_IMPLEMENT_TEST(yzw, yzww);
template<>
BX_SIMD_FORCE_INLINE simd128_neon_t simd_cmpgt(simd128_neon_t _a, simd128_neon_t _b)
{
- const uint32x4_t tmp = vcgtq_f32(_a, _b);
- const simd128_neon_t result = vreinterpretq_f32_u32(tmp);
+ const uint32x4_t tmp = vcgtq_f32(_a, _b);
+ const simd128_neon_t result = vreinterpretq_f32_u32(tmp);
return result;
}
@@ -302,8 +319,8 @@ BX_SIMD128_IMPLEMENT_TEST(yzw, yzww);
template<>
BX_SIMD_FORCE_INLINE simd128_neon_t simd_cmpge(simd128_neon_t _a, simd128_neon_t _b)
{
- const uint32x4_t tmp = vcgeq_f32(_a, _b);
- const simd128_neon_t result = vreinterpretq_f32_u32(tmp);
+ const uint32x4_t tmp = vcgeq_f32(_a, _b);
+ const simd128_neon_t result = vreinterpretq_f32_u32(tmp);
return result;
}
@@ -367,6 +384,7 @@ BX_SIMD128_IMPLEMENT_TEST(yzw, yzww);
template<>
BX_SIMD_FORCE_INLINE simd128_neon_t simd_sll(simd128_neon_t _a, int _count)
{
+#if !BX_COMPILER_CLANG
if (__builtin_constant_p(_count) )
{
const uint32x4_t tmp0 = vreinterpretq_u32_f32(_a);
@@ -375,7 +393,7 @@ BX_SIMD128_IMPLEMENT_TEST(yzw, yzww);
return result;
}
-
+#endif
const uint32x4_t tmp0 = vreinterpretq_u32_f32(_a);
const int32x4_t shift = vdupq_n_s32(_count);
const uint32x4_t tmp1 = vshlq_u32(tmp0, shift);
@@ -387,6 +405,7 @@ BX_SIMD128_IMPLEMENT_TEST(yzw, yzww);
template<>
BX_SIMD_FORCE_INLINE simd128_neon_t simd_srl(simd128_neon_t _a, int _count)
{
+#if !BX_COMPILER_CLANG
if (__builtin_constant_p(_count) )
{
const uint32x4_t tmp0 = vreinterpretq_u32_f32(_a);
@@ -395,7 +414,7 @@ BX_SIMD128_IMPLEMENT_TEST(yzw, yzww);
return result;
}
-
+#endif
const uint32x4_t tmp0 = vreinterpretq_u32_f32(_a);
const int32x4_t shift = vdupq_n_s32(-_count);
const uint32x4_t tmp1 = vshlq_u32(tmp0, shift);
@@ -407,6 +426,7 @@ BX_SIMD128_IMPLEMENT_TEST(yzw, yzww);
template<>
BX_SIMD_FORCE_INLINE simd128_neon_t simd_sra(simd128_neon_t _a, int _count)
{
+#if !BX_COMPILER_CLANG
if (__builtin_constant_p(_count) )
{
const int32x4_t tmp0 = vreinterpretq_s32_f32(_a);
@@ -415,7 +435,7 @@ BX_SIMD128_IMPLEMENT_TEST(yzw, yzww);
return result;
}
-
+#endif
const int32x4_t tmp0 = vreinterpretq_s32_f32(_a);
const int32x4_t shift = vdupq_n_s32(-_count);
const int32x4_t tmp1 = vshlq_s32(tmp0, shift);
diff --git a/3rdparty/bx/include/bx/inline/simd128_ref.inl b/3rdparty/bx/include/bx/inline/simd128_ref.inl
index 5cd98c74478..28c525a3168 100644
--- a/3rdparty/bx/include/bx/inline/simd128_ref.inl
+++ b/3rdparty/bx/include/bx/inline/simd128_ref.inl
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -59,21 +59,21 @@ namespace bx
return (_mask) == (tmp&(_mask) ); \
}
-BX_SIMD128_IMPLEMENT_TEST(x , 0x1);
-BX_SIMD128_IMPLEMENT_TEST(y , 0x2);
-BX_SIMD128_IMPLEMENT_TEST(xy , 0x3);
-BX_SIMD128_IMPLEMENT_TEST(z , 0x4);
-BX_SIMD128_IMPLEMENT_TEST(xz , 0x5);
-BX_SIMD128_IMPLEMENT_TEST(yz , 0x6);
-BX_SIMD128_IMPLEMENT_TEST(xyz , 0x7);
-BX_SIMD128_IMPLEMENT_TEST(w , 0x8);
-BX_SIMD128_IMPLEMENT_TEST(xw , 0x9);
-BX_SIMD128_IMPLEMENT_TEST(yw , 0xa);
-BX_SIMD128_IMPLEMENT_TEST(xyw , 0xb);
-BX_SIMD128_IMPLEMENT_TEST(zw , 0xc);
-BX_SIMD128_IMPLEMENT_TEST(xzw , 0xd);
-BX_SIMD128_IMPLEMENT_TEST(yzw , 0xe);
-BX_SIMD128_IMPLEMENT_TEST(xyzw , 0xf);
+BX_SIMD128_IMPLEMENT_TEST(x , 0x1)
+BX_SIMD128_IMPLEMENT_TEST(y , 0x2)
+BX_SIMD128_IMPLEMENT_TEST(xy , 0x3)
+BX_SIMD128_IMPLEMENT_TEST(z , 0x4)
+BX_SIMD128_IMPLEMENT_TEST(xz , 0x5)
+BX_SIMD128_IMPLEMENT_TEST(yz , 0x6)
+BX_SIMD128_IMPLEMENT_TEST(xyz , 0x7)
+BX_SIMD128_IMPLEMENT_TEST(w , 0x8)
+BX_SIMD128_IMPLEMENT_TEST(xw , 0x9)
+BX_SIMD128_IMPLEMENT_TEST(yw , 0xa)
+BX_SIMD128_IMPLEMENT_TEST(xyw , 0xb)
+BX_SIMD128_IMPLEMENT_TEST(zw , 0xc)
+BX_SIMD128_IMPLEMENT_TEST(xzw , 0xd)
+BX_SIMD128_IMPLEMENT_TEST(yzw , 0xe)
+BX_SIMD128_IMPLEMENT_TEST(xyzw , 0xf)
#undef BX_SIMD128_IMPLEMENT_TEST
@@ -397,6 +397,17 @@ BX_SIMD128_IMPLEMENT_TEST(xyzw , 0xf);
}
template<>
+ BX_SIMD_FORCE_INLINE simd128_ref_t simd_cmpneq(simd128_ref_t _a, simd128_ref_t _b)
+ {
+ simd128_ref_t result;
+ result.ixyzw[0] = _a.fxyzw[0] != _b.fxyzw[0] ? 0xffffffff : 0x0;
+ result.ixyzw[1] = _a.fxyzw[1] != _b.fxyzw[1] ? 0xffffffff : 0x0;
+ result.ixyzw[2] = _a.fxyzw[2] != _b.fxyzw[2] ? 0xffffffff : 0x0;
+ result.ixyzw[3] = _a.fxyzw[3] != _b.fxyzw[3] ? 0xffffffff : 0x0;
+ return result;
+ }
+
+ template<>
BX_SIMD_FORCE_INLINE simd128_ref_t simd_cmplt(simd128_ref_t _a, simd128_ref_t _b)
{
simd128_ref_t result;
diff --git a/3rdparty/bx/include/bx/inline/simd128_sse.inl b/3rdparty/bx/include/bx/inline/simd128_sse.inl
index 213fe174b98..8f6586b71f0 100644
--- a/3rdparty/bx/include/bx/inline/simd128_sse.inl
+++ b/3rdparty/bx/include/bx/inline/simd128_sse.inl
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -41,21 +41,21 @@ namespace bx
return (_mask) == (_mm_movemask_ps(_test)&(_mask) ); \
}
-BX_SIMD128_IMPLEMENT_TEST(x , 0x1);
-BX_SIMD128_IMPLEMENT_TEST(y , 0x2);
-BX_SIMD128_IMPLEMENT_TEST(xy , 0x3);
-BX_SIMD128_IMPLEMENT_TEST(z , 0x4);
-BX_SIMD128_IMPLEMENT_TEST(xz , 0x5);
-BX_SIMD128_IMPLEMENT_TEST(yz , 0x6);
-BX_SIMD128_IMPLEMENT_TEST(xyz , 0x7);
-BX_SIMD128_IMPLEMENT_TEST(w , 0x8);
-BX_SIMD128_IMPLEMENT_TEST(xw , 0x9);
-BX_SIMD128_IMPLEMENT_TEST(yw , 0xa);
-BX_SIMD128_IMPLEMENT_TEST(xyw , 0xb);
-BX_SIMD128_IMPLEMENT_TEST(zw , 0xc);
-BX_SIMD128_IMPLEMENT_TEST(xzw , 0xd);
-BX_SIMD128_IMPLEMENT_TEST(yzw , 0xe);
-BX_SIMD128_IMPLEMENT_TEST(xyzw , 0xf);
+BX_SIMD128_IMPLEMENT_TEST(x , 0x1)
+BX_SIMD128_IMPLEMENT_TEST(y , 0x2)
+BX_SIMD128_IMPLEMENT_TEST(xy , 0x3)
+BX_SIMD128_IMPLEMENT_TEST(z , 0x4)
+BX_SIMD128_IMPLEMENT_TEST(xz , 0x5)
+BX_SIMD128_IMPLEMENT_TEST(yz , 0x6)
+BX_SIMD128_IMPLEMENT_TEST(xyz , 0x7)
+BX_SIMD128_IMPLEMENT_TEST(w , 0x8)
+BX_SIMD128_IMPLEMENT_TEST(xw , 0x9)
+BX_SIMD128_IMPLEMENT_TEST(yw , 0xa)
+BX_SIMD128_IMPLEMENT_TEST(xyw , 0xb)
+BX_SIMD128_IMPLEMENT_TEST(zw , 0xc)
+BX_SIMD128_IMPLEMENT_TEST(xzw , 0xd)
+BX_SIMD128_IMPLEMENT_TEST(yzw , 0xe)
+BX_SIMD128_IMPLEMENT_TEST(xyzw , 0xf)
#undef BX_SIMD128_IMPLEMENT_TEST
@@ -309,6 +309,12 @@ BX_SIMD128_IMPLEMENT_TEST(xyzw , 0xf);
}
template<>
+ BX_SIMD_FORCE_INLINE simd128_sse_t simd_cmpneq(simd128_sse_t _a, simd128_sse_t _b)
+ {
+ return _mm_cmpneq_ps(_a, _b);
+ }
+
+ template<>
BX_SIMD_FORCE_INLINE simd128_sse_t simd_cmplt(simd128_sse_t _a, simd128_sse_t _b)
{
return _mm_cmplt_ps(_a, _b);
diff --git a/3rdparty/bx/include/bx/inline/simd256_avx.inl b/3rdparty/bx/include/bx/inline/simd256_avx.inl
index 221c1d283fc..c29a899d996 100644
--- a/3rdparty/bx/include/bx/inline/simd256_avx.inl
+++ b/3rdparty/bx/include/bx/inline/simd256_avx.inl
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/include/bx/inline/simd256_ref.inl b/3rdparty/bx/include/bx/inline/simd256_ref.inl
index cbcdd726e6a..f5202bca42f 100644
--- a/3rdparty/bx/include/bx/inline/simd256_ref.inl
+++ b/3rdparty/bx/include/bx/inline/simd256_ref.inl
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/include/bx/inline/simd_ni.inl b/3rdparty/bx/include/bx/inline/simd_ni.inl
index 6b78be8a308..ad648826ddb 100644
--- a/3rdparty/bx/include/bx/inline/simd_ni.inl
+++ b/3rdparty/bx/include/bx/inline/simd_ni.inl
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -125,6 +125,15 @@ namespace bx
}
template<typename Ty>
+ BX_SIMD_INLINE Ty simd_cmpneq_ni(Ty _a, Ty _b)
+ {
+ const Ty tmp0 = simd_cmpeq(_a, _b);
+ const Ty result = simd_not(tmp0);
+
+ return result;
+ }
+
+ template<typename Ty>
BX_SIMD_INLINE Ty simd_min_ni(Ty _a, Ty _b)
{
const Ty mask = simd_cmplt(_a, _b);
diff --git a/3rdparty/bx/include/bx/inline/sort.inl b/3rdparty/bx/include/bx/inline/sort.inl
index 85e7b0a9fd0..928f1cbdcd0 100644
--- a/3rdparty/bx/include/bx/inline/sort.inl
+++ b/3rdparty/bx/include/bx/inline/sort.inl
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -9,21 +9,25 @@
namespace bx
{
-#define BX_RADIXSORT_BITS 11
-#define BX_RADIXSORT_HISTOGRAM_SIZE (1<<BX_RADIXSORT_BITS)
-#define BX_RADIXSORT_BIT_MASK (BX_RADIXSORT_HISTOGRAM_SIZE-1)
+ namespace radix_sort_detail
+ {
+ constexpr uint32_t kBits = 11;
+ constexpr uint32_t kHistogramSize = 1<<kBits;
+ constexpr uint32_t kBitMask = kHistogramSize-1;
+
+ } // namespace radix_sort_detail
inline void radixSort(uint32_t* _keys, uint32_t* _tempKeys, uint32_t _size)
{
uint32_t* keys = _keys;
uint32_t* tempKeys = _tempKeys;
- uint32_t histogram[BX_RADIXSORT_HISTOGRAM_SIZE];
+ uint32_t histogram[radix_sort_detail::kHistogramSize];
uint16_t shift = 0;
uint32_t pass = 0;
for (; pass < 3; ++pass)
{
- memSet(histogram, 0, sizeof(uint32_t)*BX_RADIXSORT_HISTOGRAM_SIZE);
+ memSet(histogram, 0, sizeof(uint32_t)*radix_sort_detail::kHistogramSize);
bool sorted = true;
{
@@ -32,7 +36,7 @@ namespace bx
for (uint32_t ii = 0; ii < _size; ++ii, prevKey = key)
{
key = keys[ii];
- uint16_t index = (key>>shift)&BX_RADIXSORT_BIT_MASK;
+ uint16_t index = (key>>shift)&radix_sort_detail::kBitMask;
++histogram[index];
sorted &= prevKey <= key;
}
@@ -44,7 +48,7 @@ namespace bx
}
uint32_t offset = 0;
- for (uint32_t ii = 0; ii < BX_RADIXSORT_HISTOGRAM_SIZE; ++ii)
+ for (uint32_t ii = 0; ii < radix_sort_detail::kHistogramSize; ++ii)
{
uint32_t count = histogram[ii];
histogram[ii] = offset;
@@ -54,7 +58,7 @@ namespace bx
for (uint32_t ii = 0; ii < _size; ++ii)
{
uint32_t key = keys[ii];
- uint16_t index = (key>>shift)&BX_RADIXSORT_BIT_MASK;
+ uint16_t index = (key>>shift)&radix_sort_detail::kBitMask;
uint32_t dest = histogram[index]++;
tempKeys[dest] = key;
}
@@ -63,7 +67,7 @@ namespace bx
tempKeys = keys;
keys = swapKeys;
- shift += BX_RADIXSORT_BITS;
+ shift += radix_sort_detail::kBits;
}
done:
@@ -82,12 +86,12 @@ done:
Ty* values = _values;
Ty* tempValues = _tempValues;
- uint32_t histogram[BX_RADIXSORT_HISTOGRAM_SIZE];
+ uint32_t histogram[radix_sort_detail::kHistogramSize];
uint16_t shift = 0;
uint32_t pass = 0;
for (; pass < 3; ++pass)
{
- memSet(histogram, 0, sizeof(uint32_t)*BX_RADIXSORT_HISTOGRAM_SIZE);
+ memSet(histogram, 0, sizeof(uint32_t)*radix_sort_detail::kHistogramSize);
bool sorted = true;
{
@@ -96,7 +100,7 @@ done:
for (uint32_t ii = 0; ii < _size; ++ii, prevKey = key)
{
key = keys[ii];
- uint16_t index = (key>>shift)&BX_RADIXSORT_BIT_MASK;
+ uint16_t index = (key>>shift)&radix_sort_detail::kBitMask;
++histogram[index];
sorted &= prevKey <= key;
}
@@ -108,7 +112,7 @@ done:
}
uint32_t offset = 0;
- for (uint32_t ii = 0; ii < BX_RADIXSORT_HISTOGRAM_SIZE; ++ii)
+ for (uint32_t ii = 0; ii < radix_sort_detail::kHistogramSize; ++ii)
{
uint32_t count = histogram[ii];
histogram[ii] = offset;
@@ -118,7 +122,7 @@ done:
for (uint32_t ii = 0; ii < _size; ++ii)
{
uint32_t key = keys[ii];
- uint16_t index = (key>>shift)&BX_RADIXSORT_BIT_MASK;
+ uint16_t index = (key>>shift)&radix_sort_detail::kBitMask;
uint32_t dest = histogram[index]++;
tempKeys[dest] = key;
tempValues[dest] = values[ii];
@@ -132,7 +136,7 @@ done:
tempValues = values;
values = swapValues;
- shift += BX_RADIXSORT_BITS;
+ shift += radix_sort_detail::kBits;
}
done:
@@ -152,12 +156,12 @@ done:
uint64_t* keys = _keys;
uint64_t* tempKeys = _tempKeys;
- uint32_t histogram[BX_RADIXSORT_HISTOGRAM_SIZE];
+ uint32_t histogram[radix_sort_detail::kHistogramSize];
uint16_t shift = 0;
uint32_t pass = 0;
for (; pass < 6; ++pass)
{
- memSet(histogram, 0, sizeof(uint32_t)*BX_RADIXSORT_HISTOGRAM_SIZE);
+ memSet(histogram, 0, sizeof(uint32_t)*radix_sort_detail::kHistogramSize);
bool sorted = true;
{
@@ -166,7 +170,7 @@ done:
for (uint32_t ii = 0; ii < _size; ++ii, prevKey = key)
{
key = keys[ii];
- uint16_t index = (key>>shift)&BX_RADIXSORT_BIT_MASK;
+ uint16_t index = (key>>shift)&radix_sort_detail::kBitMask;
++histogram[index];
sorted &= prevKey <= key;
}
@@ -178,7 +182,7 @@ done:
}
uint32_t offset = 0;
- for (uint32_t ii = 0; ii < BX_RADIXSORT_HISTOGRAM_SIZE; ++ii)
+ for (uint32_t ii = 0; ii < radix_sort_detail::kHistogramSize; ++ii)
{
uint32_t count = histogram[ii];
histogram[ii] = offset;
@@ -188,7 +192,7 @@ done:
for (uint32_t ii = 0; ii < _size; ++ii)
{
uint64_t key = keys[ii];
- uint16_t index = (key>>shift)&BX_RADIXSORT_BIT_MASK;
+ uint16_t index = (key>>shift)&radix_sort_detail::kBitMask;
uint32_t dest = histogram[index]++;
tempKeys[dest] = key;
}
@@ -197,7 +201,7 @@ done:
tempKeys = keys;
keys = swapKeys;
- shift += BX_RADIXSORT_BITS;
+ shift += radix_sort_detail::kBits;
}
done:
@@ -216,12 +220,12 @@ done:
Ty* values = _values;
Ty* tempValues = _tempValues;
- uint32_t histogram[BX_RADIXSORT_HISTOGRAM_SIZE];
+ uint32_t histogram[radix_sort_detail::kHistogramSize];
uint16_t shift = 0;
uint32_t pass = 0;
for (; pass < 6; ++pass)
{
- memSet(histogram, 0, sizeof(uint32_t)*BX_RADIXSORT_HISTOGRAM_SIZE);
+ memSet(histogram, 0, sizeof(uint32_t)*radix_sort_detail::kHistogramSize);
bool sorted = true;
{
@@ -230,7 +234,7 @@ done:
for (uint32_t ii = 0; ii < _size; ++ii, prevKey = key)
{
key = keys[ii];
- uint16_t index = (key>>shift)&BX_RADIXSORT_BIT_MASK;
+ uint16_t index = (key>>shift)&radix_sort_detail::kBitMask;
++histogram[index];
sorted &= prevKey <= key;
}
@@ -242,7 +246,7 @@ done:
}
uint32_t offset = 0;
- for (uint32_t ii = 0; ii < BX_RADIXSORT_HISTOGRAM_SIZE; ++ii)
+ for (uint32_t ii = 0; ii < radix_sort_detail::kHistogramSize; ++ii)
{
uint32_t count = histogram[ii];
histogram[ii] = offset;
@@ -252,7 +256,7 @@ done:
for (uint32_t ii = 0; ii < _size; ++ii)
{
uint64_t key = keys[ii];
- uint16_t index = (key>>shift)&BX_RADIXSORT_BIT_MASK;
+ uint16_t index = (key>>shift)&radix_sort_detail::kBitMask;
uint32_t dest = histogram[index]++;
tempKeys[dest] = key;
tempValues[dest] = values[ii];
@@ -266,7 +270,7 @@ done:
tempValues = values;
values = swapValues;
- shift += BX_RADIXSORT_BITS;
+ shift += radix_sort_detail::kBits;
}
done:
@@ -281,8 +285,4 @@ done:
}
}
-#undef BX_RADIXSORT_BITS
-#undef BX_RADIXSORT_HISTOGRAM_SIZE
-#undef BX_RADIXSORT_BIT_MASK
-
} // namespace bx
diff --git a/3rdparty/bx/include/bx/inline/spscqueue.inl b/3rdparty/bx/include/bx/inline/spscqueue.inl
index 94c05d81712..80d316e62a3 100644
--- a/3rdparty/bx/include/bx/inline/spscqueue.inl
+++ b/3rdparty/bx/include/bx/inline/spscqueue.inl
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/include/bx/inline/string.inl b/3rdparty/bx/include/bx/inline/string.inl
index 61c49339cd8..1aa830f2f74 100644
--- a/3rdparty/bx/include/bx/inline/string.inl
+++ b/3rdparty/bx/include/bx/inline/string.inl
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -226,6 +226,12 @@ namespace bx
}
template<bx::AllocatorI** AllocatorT>
+ inline void StringT<AllocatorT>::append(const char* _ptr, const char* _term)
+ {
+ append(StringView(_ptr, _term) );
+ }
+
+ template<bx::AllocatorI** AllocatorT>
inline void StringT<AllocatorT>::clear()
{
if (0 != m_len)
@@ -236,6 +242,12 @@ namespace bx
}
}
+ template<bx::AllocatorI** AllocatorT>
+ inline const char* StringT<AllocatorT>::getCPtr() const
+ {
+ return getPtr();
+ }
+
inline StringView strSubstr(const StringView& _str, int32_t _start, int32_t _len)
{
return StringView(_str, _start, _len);
@@ -264,7 +276,7 @@ namespace bx
StringView line(curr.getPtr(), m_curr.getPtr() );
- return strRTrim(line, "\n\r");
+ return strRTrim(strRTrim(line, "\n"), "\r");
}
return m_curr;
diff --git a/3rdparty/bx/include/bx/inline/uint32_t.inl b/3rdparty/bx/include/bx/inline/uint32_t.inl
index 8fc1af6199b..c2965c53bc2 100644
--- a/3rdparty/bx/include/bx/inline/uint32_t.inl
+++ b/3rdparty/bx/include/bx/inline/uint32_t.inl
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -687,6 +687,72 @@ namespace bx
return result;
}
+ template <typename Ty>
+ inline bool isAligned(Ty _a, int32_t _align)
+ {
+ const Ty mask = Ty(_align - 1);
+ return 0 == (_a & mask);
+ }
+
+ template <typename Ty>
+ inline bool isAligned(const Ty* _ptr, int32_t _align)
+ {
+ union { const void* ptr; uintptr_t addr; } un = { _ptr };
+ return isAligned(un.addr, _align);
+ }
+
+ template <typename Ty>
+ inline bool isAligned(Ty* _ptr, int32_t _align)
+ {
+ return isAligned( (const void*)_ptr, _align);
+ }
+
+ template <typename Ty>
+ inline Ty alignDown(Ty _a, int32_t _align)
+ {
+ const Ty mask = Ty(_align - 1);
+ return Ty(_a & ~mask);
+ }
+
+ template <typename Ty>
+ inline Ty* alignDown(Ty* _ptr, int32_t _align)
+ {
+ union { Ty* ptr; uintptr_t addr; } un = { _ptr };
+ un.addr = alignDown(un.addr, _align);
+ return un.ptr;
+ }
+
+ template <typename Ty>
+ inline const Ty* alignDown(const Ty* _ptr, int32_t _align)
+ {
+ union { const Ty* ptr; uintptr_t addr; } un = { _ptr };
+ un.addr = alignDown(un.addr, _align);
+ return un.ptr;
+ }
+
+ template <typename Ty>
+ inline Ty alignUp(Ty _a, int32_t _align)
+ {
+ const Ty mask = Ty(_align - 1);
+ return Ty( (_a + mask) & ~mask);
+ }
+
+ template <typename Ty>
+ inline Ty* alignUp(Ty* _ptr, int32_t _align)
+ {
+ union { Ty* ptr; uintptr_t addr; } un = { _ptr };
+ un.addr = alignUp(un.addr, _align);
+ return un.ptr;
+ }
+
+ template <typename Ty>
+ inline const Ty* alignUp(const Ty* _ptr, int32_t _align)
+ {
+ union { const Ty* ptr; uintptr_t addr; } un = { _ptr };
+ un.addr = alignUp(un.addr, _align);
+ return un.ptr;
+ }
+
inline BX_CONST_FUNC uint16_t halfFromFloat(float _a)
{
union { uint32_t ui; float flt; } ftou;
diff --git a/3rdparty/bx/include/bx/macros.h b/3rdparty/bx/include/bx/macros.h
index 2f92c1ff424..0d13cc96948 100644
--- a/3rdparty/bx/include/bx/macros.h
+++ b/3rdparty/bx/include/bx/macros.h
@@ -1,13 +1,15 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
+#ifndef BX_H_HEADER_GUARD
+# error "Do not include macros.h directly #include <bx/bx.h> instead."
+#endif // BX_H_HEADER_GUARD
+
#ifndef BX_MACROS_H_HEADER_GUARD
#define BX_MACROS_H_HEADER_GUARD
-#include "bx.h"
-
///
#if BX_COMPILER_MSVC
// Workaround MSVS bug...
@@ -41,12 +43,6 @@
#define BX_FILE_LINE_LITERAL "" __FILE__ "(" BX_STRINGIZE(__LINE__) "): "
///
-#define BX_ALIGN_MASK(_value, _mask) ( ( (_value)+(_mask) ) & ( (~0)&(~(_mask) ) ) )
-#define BX_ALIGN_16(_value) BX_ALIGN_MASK(_value, 0xf)
-#define BX_ALIGN_256(_value) BX_ALIGN_MASK(_value, 0xff)
-#define BX_ALIGN_4096(_value) BX_ALIGN_MASK(_value, 0xfff)
-
-///
#define BX_ALIGNOF(_type) __alignof(_type)
#if defined(__has_feature)
@@ -81,11 +77,9 @@
# define BX_NO_VTABLE
# define BX_PRINTF_ARGS(_format, _args) __attribute__( (format(__printf__, _format, _args) ) )
-# if BX_CLANG_HAS_FEATURE(cxx_thread_local)
-# define BX_THREAD_LOCAL __thread
-# endif // BX_COMPILER_CLANG
-
-# if (!BX_PLATFORM_OSX && (BX_COMPILER_GCC >= 40200)) || (BX_COMPILER_GCC >= 40500)
+# if BX_CLANG_HAS_FEATURE(cxx_thread_local) \
+ || (!BX_PLATFORM_OSX && (BX_COMPILER_GCC >= 40200) ) \
+ || (BX_COMPILER_GCC >= 40500)
# define BX_THREAD_LOCAL __thread
# endif // BX_COMPILER_GCC
@@ -234,9 +228,9 @@
# define BX_CLASS(_class, ...) BX_MACRO_DISPATCHER(BX_CLASS_, __VA_ARGS__)(_class, __VA_ARGS__)
#endif // BX_COMPILER_MSVC
-#ifndef BX_CHECK
-# define BX_CHECK(_condition, ...) BX_NOOP()
-#endif // BX_CHECK
+#ifndef BX_ASSERT
+# define BX_ASSERT(_condition, ...) BX_NOOP()
+#endif // BX_ASSERT
#ifndef BX_TRACE
# define BX_TRACE(...) BX_NOOP()
@@ -244,7 +238,7 @@
#ifndef BX_WARN
# define BX_WARN(_condition, ...) BX_NOOP()
-#endif // BX_CHECK
+#endif // BX_ASSERT
// static_assert sometimes causes unused-local-typedef...
BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG("-Wunused-local-typedef")
diff --git a/3rdparty/bx/include/bx/maputil.h b/3rdparty/bx/include/bx/maputil.h
index fcdc4b58d97..9b61d49cd8f 100644
--- a/3rdparty/bx/include/bx/maputil.h
+++ b/3rdparty/bx/include/bx/maputil.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/include/bx/math.h b/3rdparty/bx/include/bx/math.h
index ebd06625102..bd05e84d7ac 100644
--- a/3rdparty/bx/include/bx/math.h
+++ b/3rdparty/bx/include/bx/math.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2011-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2011-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -249,10 +249,17 @@ namespace bx
///
BX_CONSTEXPR_FUNC float fract(float _a);
+ /// Returns result of negated multiply-sub operation -(_a * _b - _c).
+ ///
+ BX_CONSTEXPR_FUNC float nms(float _a, float _b, float _c);
+
/// Returns result of multipla and add (_a * _b + _c).
///
BX_CONSTEXPR_FUNC float mad(float _a, float _b, float _c);
+ /// Returns reciprocal of _a.
+ BX_CONSTEXPR_FUNC float rcp(float _a);
+
/// Returns the floating-point remainder of the division operation _a/_b.
///
BX_CONST_FUNC float mod(float _a, float _b);
@@ -276,6 +283,9 @@ namespace bx
BX_CONSTEXPR_FUNC float smoothStep(float _a);
///
+ BX_CONST_FUNC float invSmoothStep(float _a);
+
+ ///
BX_CONSTEXPR_FUNC float bias(float _time, float _bias);
///
@@ -324,6 +334,12 @@ namespace bx
BX_CONSTEXPR_FUNC Vec3 mul(const Vec3 _a, float _b);
///
+ BX_CONSTEXPR_FUNC Vec3 div(const Vec3 _a, const Vec3 _b);
+
+ ///
+ BX_CONSTEXPR_FUNC Vec3 div(const Vec3 _a, float _b);
+
+ ///
BX_CONSTEXPR_FUNC Vec3 mad(const Vec3 _a, const float _b, const Vec3 _c);
///
@@ -359,7 +375,7 @@ namespace bx
///
BX_CONSTEXPR_FUNC Vec3 max(const Vec3 _a, const Vec3 _b);
- ///
+ /// Returns component wise reciprocal of _a.
BX_CONSTEXPR_FUNC Vec3 rcp(const Vec3 _a);
///
diff --git a/3rdparty/bx/include/bx/mpscqueue.h b/3rdparty/bx/include/bx/mpscqueue.h
index bbc80049872..f738c22dbef 100644
--- a/3rdparty/bx/include/bx/mpscqueue.h
+++ b/3rdparty/bx/include/bx/mpscqueue.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/include/bx/mutex.h b/3rdparty/bx/include/bx/mutex.h
index 8f8ec18de08..ef9337bdc99 100644
--- a/3rdparty/bx/include/bx/mutex.h
+++ b/3rdparty/bx/include/bx/mutex.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/include/bx/os.h b/3rdparty/bx/include/bx/os.h
index 2a8cb0d6883..f2102810b14 100644
--- a/3rdparty/bx/include/bx/os.h
+++ b/3rdparty/bx/include/bx/os.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -41,6 +41,10 @@ namespace bx
void* dlsym(void* _handle, const StringView& _symbol);
///
+ template<typename ProtoT>
+ ProtoT dlsym(void* _handle, const StringView& _symbol);
+
+ ///
bool getEnv(char* _out, uint32_t* _inOutSize, const StringView& _name);
///
@@ -54,4 +58,6 @@ namespace bx
} // namespace bx
+#include "inline/os.inl"
+
#endif // BX_OS_H_HEADER_GUARD
diff --git a/3rdparty/bx/include/bx/pixelformat.h b/3rdparty/bx/include/bx/pixelformat.h
index 03c5f62415b..3895e85b31e 100644
--- a/3rdparty/bx/include/bx/pixelformat.h
+++ b/3rdparty/bx/include/bx/pixelformat.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2011-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2011-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/include/bx/platform.h b/3rdparty/bx/include/bx/platform.h
index d4445d3a3b9..eea5fcb04e2 100644
--- a/3rdparty/bx/include/bx/platform.h
+++ b/3rdparty/bx/include/bx/platform.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -57,7 +57,6 @@
#define BX_PLATFORM_OSX 0
#define BX_PLATFORM_PS4 0
#define BX_PLATFORM_RPI 0
-#define BX_PLATFORM_STEAMLINK 0
#define BX_PLATFORM_WINDOWS 0
#define BX_PLATFORM_WINRT 0
#define BX_PLATFORM_XBOXONE 0
@@ -135,18 +134,18 @@
#endif //
#if BX_CPU_PPC
-// _LITTLE_ENDIAN exists on ppc64le.
-# if _LITTLE_ENDIAN
-# undef BX_CPU_ENDIAN_LITTLE
-# define BX_CPU_ENDIAN_LITTLE 1
-# else
+// __BIG_ENDIAN__ is gcc predefined macro
+# if defined(__BIG_ENDIAN__)
# undef BX_CPU_ENDIAN_BIG
# define BX_CPU_ENDIAN_BIG 1
+# else
+# undef BX_CPU_ENDIAN_LITTLE
+# define BX_CPU_ENDIAN_LITTLE 1
# endif
#else
# undef BX_CPU_ENDIAN_LITTLE
# define BX_CPU_ENDIAN_LITTLE 1
-#endif // BX_PLATFORM_
+#endif // BX_CPU_PPC
// http://sourceforge.net/apps/mediawiki/predef/index.php?title=Operating_Systems
#if defined(_DURANGO) || defined(_XBOX_ONE)
@@ -184,10 +183,6 @@
# include <sys/cdefs.h> // Defines __BIONIC__ and includes android/api-level.h
# undef BX_PLATFORM_ANDROID
# define BX_PLATFORM_ANDROID __ANDROID_API__
-#elif defined(__STEAMLINK__)
-// SteamLink compiler defines __linux__
-# undef BX_PLATFORM_STEAMLINK
-# define BX_PLATFORM_STEAMLINK 1
#elif defined(__VCCOREVER__)
// RaspberryPi compiler defines __linux__
# undef BX_PLATFORM_RPI
@@ -274,7 +269,6 @@
|| BX_PLATFORM_OSX \
|| BX_PLATFORM_PS4 \
|| BX_PLATFORM_RPI \
- || BX_PLATFORM_STEAMLINK \
)
///
@@ -290,7 +284,6 @@
|| BX_PLATFORM_OSX \
|| BX_PLATFORM_PS4 \
|| BX_PLATFORM_RPI \
- || BX_PLATFORM_STEAMLINK \
|| BX_PLATFORM_WINDOWS \
|| BX_PLATFORM_WINRT \
|| BX_PLATFORM_XBOXONE \
@@ -317,7 +310,6 @@
///
#define BX_PLATFORM_OS_EMBEDDED (0 \
|| BX_PLATFORM_RPI \
- || BX_PLATFORM_STEAMLINK \
)
///
@@ -390,8 +382,6 @@
# define BX_PLATFORM_NAME "PlayStation 4"
#elif BX_PLATFORM_RPI
# define BX_PLATFORM_NAME "RaspberryPi"
-#elif BX_PLATFORM_STEAMLINK
-# define BX_PLATFORM_NAME "SteamLink"
#elif BX_PLATFORM_WINDOWS
# define BX_PLATFORM_NAME "Windows"
#elif BX_PLATFORM_WINRT
diff --git a/3rdparty/bx/include/bx/process.h b/3rdparty/bx/include/bx/process.h
index 222b8ed79a8..9c5ee0403a2 100644
--- a/3rdparty/bx/include/bx/process.h
+++ b/3rdparty/bx/include/bx/process.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/include/bx/readerwriter.h b/3rdparty/bx/include/bx/readerwriter.h
index ed61f46aa82..45265b2c112 100644
--- a/3rdparty/bx/include/bx/readerwriter.h
+++ b/3rdparty/bx/include/bx/readerwriter.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -14,21 +14,21 @@
#include "string.h"
#include "uint32_t.h"
-BX_ERROR_RESULT(BX_ERROR_READERWRITER_OPEN, BX_MAKEFOURCC('R', 'W', 0, 1) );
-BX_ERROR_RESULT(BX_ERROR_READERWRITER_READ, BX_MAKEFOURCC('R', 'W', 0, 2) );
-BX_ERROR_RESULT(BX_ERROR_READERWRITER_WRITE, BX_MAKEFOURCC('R', 'W', 0, 3) );
-BX_ERROR_RESULT(BX_ERROR_READERWRITER_EOF, BX_MAKEFOURCC('R', 'W', 0, 4) );
-BX_ERROR_RESULT(BX_ERROR_READERWRITER_ALREADY_OPEN, BX_MAKEFOURCC('R', 'W', 0, 5) );
-
namespace bx
{
+ BX_ERROR_RESULT(kErrorReaderWriterOpen, BX_MAKEFOURCC('b', 'x', 2, 1) );
+ BX_ERROR_RESULT(kErrorReaderWriterRead, BX_MAKEFOURCC('b', 'x', 2, 2) );
+ BX_ERROR_RESULT(kErrorReaderWriterWrite, BX_MAKEFOURCC('b', 'x', 2, 3) );
+ BX_ERROR_RESULT(kErrorReaderWriterEof, BX_MAKEFOURCC('b', 'x', 2, 4) );
+ BX_ERROR_RESULT(kErrorReaderWriterAlreadyOpen, BX_MAKEFOURCC('b', 'x', 2, 5) );
+
/// The position from where offset is added.
struct Whence
{
/// Whence values:
enum Enum
{
- Begin, //!< From begining of file.
+ Begin, //!< From beginning of file.
Current, //!< From current position of file.
End, //!< From end of file.
};
@@ -285,13 +285,13 @@ namespace bx
/// Write string view.
int32_t write(WriterI* _writer, const StringView& _str, Error* _err = NULL);
- /// Write formated string.
+ /// Write formatted string.
int32_t write(WriterI* _writer, const StringView& _format, va_list _argList, Error* _err);
- /// Write formated string.
+ /// Write formatted string.
int32_t write(WriterI* _writer, Error* _err, const StringView* _format, ...);
- /// Write formated string.
+ /// Write formatted string.
int32_t write(WriterI* _writer, Error* _err, const char* _format, ...);
/// Write repeat the same value.
@@ -337,7 +337,7 @@ namespace bx
/// Open for read.
bool open(ReaderOpenI* _reader, const FilePath& _filePath, Error* _err = NULL);
- /// Open fro write.
+ /// Open for write.
bool open(WriterOpenI* _writer, const FilePath& _filePath, bool _append = false, Error* _err = NULL);
/// Open process.
diff --git a/3rdparty/bx/include/bx/ringbuffer.h b/3rdparty/bx/include/bx/ringbuffer.h
index 2a93b985b4a..112c7c13ba7 100644
--- a/3rdparty/bx/include/bx/ringbuffer.h
+++ b/3rdparty/bx/include/bx/ringbuffer.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/include/bx/rng.h b/3rdparty/bx/include/bx/rng.h
index 5469b5efd9c..b8b4a457edc 100644
--- a/3rdparty/bx/include/bx/rng.h
+++ b/3rdparty/bx/include/bx/rng.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/include/bx/semaphore.h b/3rdparty/bx/include/bx/semaphore.h
index e3bd3899305..3e0fa49f918 100644
--- a/3rdparty/bx/include/bx/semaphore.h
+++ b/3rdparty/bx/include/bx/semaphore.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/include/bx/settings.h b/3rdparty/bx/include/bx/settings.h
index 7dd45e626fb..e5dbc8ac68d 100644
--- a/3rdparty/bx/include/bx/settings.h
+++ b/3rdparty/bx/include/bx/settings.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2011-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2011-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/include/bx/simd_t.h b/3rdparty/bx/include/bx/simd_t.h
index 0c41844655b..c804c990118 100644
--- a/3rdparty/bx/include/bx/simd_t.h
+++ b/3rdparty/bx/include/bx/simd_t.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -32,7 +32,7 @@
# include <xmmintrin.h> // __m128
# undef BX_SIMD_SSE
# define BX_SIMD_SSE 1
-#elif defined(__ARM_NEON__) && !BX_COMPILER_CLANG
+#elif defined(__ARM_NEON__) && (!BX_COMPILER_CLANG || BX_CLANG_HAS_EXTENSION(attribute_ext_vector_type) )
# include <arm_neon.h>
# undef BX_SIMD_NEON
# define BX_SIMD_NEON 1
@@ -197,6 +197,9 @@ BX_SIMD128_IMPLEMENT_TEST(xyzw);
Ty simd_cmpeq(Ty _a, Ty _b);
template<typename Ty>
+ Ty simd_cmpneq(Ty _a, Ty _b);
+
+ template<typename Ty>
Ty simd_cmplt(Ty _a, Ty _b);
template<typename Ty>
@@ -371,6 +374,9 @@ BX_SIMD128_IMPLEMENT_TEST(xyzw);
Ty simd_not_ni(Ty _a);
template<typename Ty>
+ Ty simd_cmpneq_ni(Ty _a, Ty _b);
+
+ template<typename Ty>
Ty simd_min_ni(Ty _a, Ty _b);
template<typename Ty>
diff --git a/3rdparty/bx/include/bx/sort.h b/3rdparty/bx/include/bx/sort.h
index b32febd90ff..bd4c2b17d80 100644
--- a/3rdparty/bx/include/bx/sort.h
+++ b/3rdparty/bx/include/bx/sort.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/include/bx/spscqueue.h b/3rdparty/bx/include/bx/spscqueue.h
index 7ea7c448750..e4381b0443c 100644
--- a/3rdparty/bx/include/bx/spscqueue.h
+++ b/3rdparty/bx/include/bx/spscqueue.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/include/bx/string.h b/3rdparty/bx/include/bx/string.h
index 43798a4f549..7b27cc3a103 100644
--- a/3rdparty/bx/include/bx/string.h
+++ b/3rdparty/bx/include/bx/string.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -129,7 +129,14 @@ namespace bx
void append(const StringView& _str);
///
+ void append(const char* _ptr, const char* _term);
+
+ ///
void clear();
+
+ /// Returns zero-terminated C string pointer.
+ ///
+ const char* getCPtr() const;
};
/// Retruns true if character is part of space set.
@@ -244,9 +251,15 @@ namespace bx
/// Returns string view with characters _chars trimmed from right.
StringView strRTrim(const StringView& _str, const StringView& _chars);
+ /// Returns string view with whitespace characters trimmed from right.
+ StringView strRTrimSpace(const StringView& _str);
+
/// Returns string view with characters _chars trimmed from left and right.
StringView strTrim(const StringView& _str, const StringView& _chars);
+ /// Returns string view with whitespace characters trimmed from left and right.
+ StringView strTrimSpace(const StringView& _str);
+
/// Find new line. Returns pointer after new line terminator.
StringView strFindNl(const StringView& _str);
diff --git a/3rdparty/bx/include/bx/thread.h b/3rdparty/bx/include/bx/thread.h
index 2526741ce08..10d11cbfd1f 100644
--- a/3rdparty/bx/include/bx/thread.h
+++ b/3rdparty/bx/include/bx/thread.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -9,6 +9,8 @@
#include "allocator.h"
#include "mpscqueue.h"
+#if BX_CONFIG_SUPPORTS_THREADING
+
namespace bx
{
///
@@ -29,8 +31,16 @@ namespace bx
///
virtual ~Thread();
+ /// Create and initialize thread.
+ ///
+ /// @param[in] _fn Thread function.
+ /// @param[in] _userData User data passed to thread function.
+ /// @param[in] _stackSize Stack size, if zero is passed it will use OS default thread stack
+ /// size.
+ /// @param[in] _name Thread name used by debugger.
+ /// @returns True if thread is created, otherwise returns false.
///
- void init(ThreadFn _fn, void* _userData = NULL, uint32_t _stackSize = 0, const char* _name = NULL);
+ bool init(ThreadFn _fn, void* _userData = NULL, uint32_t _stackSize = 0, const char* _name = NULL);
///
void shutdown();
@@ -87,4 +97,6 @@ namespace bx
} // namespace bx
+#endif
+
#endif // BX_THREAD_H_HEADER_GUARD
diff --git a/3rdparty/bx/include/bx/timer.h b/3rdparty/bx/include/bx/timer.h
index bbe5e084d4f..3ff8ed5e747 100644
--- a/3rdparty/bx/include/bx/timer.h
+++ b/3rdparty/bx/include/bx/timer.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/include/bx/uint32_t.h b/3rdparty/bx/include/bx/uint32_t.h
index 3eb8bdfd3c8..6053cdfdab6 100644
--- a/3rdparty/bx/include/bx/uint32_t.h
+++ b/3rdparty/bx/include/bx/uint32_t.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -251,6 +251,42 @@ namespace bx
template<uint32_t Min>
BX_CONSTEXPR_FUNC uint32_t strideAlign(uint32_t _offset, uint32_t _stride);
+ ///
+ template <typename Ty>
+ bool isAligned(Ty _a, int32_t _align);
+
+ ///
+ template <typename Ty>
+ bool isAligned(void* _ptr, int32_t _align);
+
+ ///
+ template <typename Ty>
+ bool isAligned(const void* _ptr, int32_t _align);
+
+ ///
+ template <typename Ty>
+ Ty alignDown(Ty _a, int32_t _align);
+
+ ///
+ template <typename Ty>
+ Ty* alignDown(Ty* _ptr, int32_t _align);
+
+ ///
+ template <typename Ty>
+ const Ty* alignDown(const Ty* _ptr, int32_t _align);
+
+ ///
+ template <typename Ty>
+ Ty alignUp(Ty _a, int32_t _align);
+
+ ///
+ template <typename Ty>
+ Ty* alignUp(Ty* _ptr, int32_t _align);
+
+ ///
+ template <typename Ty>
+ const Ty* alignUp(const Ty* _ptr, int32_t _align);
+
/// Convert float to half-float.
///
BX_CONST_FUNC uint16_t halfFromFloat(float _a);
diff --git a/3rdparty/bx/include/bx/url.h b/3rdparty/bx/include/bx/url.h
index 320db14e398..769b3c8db84 100644
--- a/3rdparty/bx/include/bx/url.h
+++ b/3rdparty/bx/include/bx/url.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/makefile b/3rdparty/bx/makefile
index 985c94b83f4..43675305b7f 100644
--- a/3rdparty/bx/makefile
+++ b/3rdparty/bx/makefile
@@ -1,24 +1,25 @@
#
-# Copyright 2011-2019 Branimir Karadzic. All rights reserved.
+# Copyright 2011-2021 Branimir Karadzic. All rights reserved.
# License: https://github.com/bkaradzic/bx#license-bsd-2-clause
#
GENIE=../bx/tools/bin/$(OS)/genie
all:
- $(GENIE) vs2017
- $(GENIE) --gcc=android-arm gmake
- $(GENIE) --gcc=android-arm64 gmake
- $(GENIE) --gcc=android-mips gmake
- $(GENIE) --gcc=android-x86 gmake
- $(GENIE) --gcc=mingw-gcc gmake
- $(GENIE) --gcc=linux-gcc gmake
- $(GENIE) --gcc=haiku gmake
- $(GENIE) --gcc=osx gmake
- $(GENIE) --gcc=ios-arm gmake
- $(GENIE) --gcc=ios-simulator gmake
+ $(GENIE) vs2017
+ $(GENIE) vs2019
+ $(GENIE) --gcc=android-arm gmake
+ $(GENIE) --gcc=android-arm64 gmake
+ $(GENIE) --gcc=android-x86 gmake
+ $(GENIE) --gcc=mingw-gcc gmake
+ $(GENIE) --gcc=linux-gcc gmake
+ $(GENIE) --gcc=haiku gmake
+ $(GENIE) --gcc=osx-x64 gmake
+ $(GENIE) --gcc=osx-arm64 gmake
+ $(GENIE) --gcc=ios-arm gmake
+ $(GENIE) --gcc=ios-simulator gmake
$(GENIE) --gcc=ios-simulator64 gmake
- $(GENIE) xcode8
+ $(GENIE) xcode8
.build/projects/gmake-android-arm:
$(GENIE) --gcc=android-arm gmake
@@ -36,14 +37,6 @@ android-arm64-release: .build/projects/gmake-android-arm64
make -R -C .build/projects/gmake-android-arm64 config=release
android-arm64: android-arm64-debug android-arm64-release
-.build/projects/gmake-android-mips:
- $(GENIE) --gcc=android-mips gmake
-android-mips-debug: .build/projects/gmake-android-mips
- make -R -C .build/projects/gmake-android-mips config=debug
-android-mips-release: .build/projects/gmake-android-mips
- make -R -C .build/projects/gmake-android-mips config=release
-android-mips: android-mips-debug android-mips-release
-
.build/projects/gmake-android-x86:
$(GENIE) --gcc=android-x86 gmake
android-x86-debug: .build/projects/gmake-android-x86
@@ -95,13 +88,13 @@ mingw-clang: mingw-clang-debug32 mingw-clang-release32 mingw-clang-debug64 mingw
.build/projects/vs2017:
$(GENIE) vs2017
-.build/projects/gmake-osx:
- $(GENIE) --gcc=osx gmake
-osx-debug64: .build/projects/gmake-osx
- make -C .build/projects/gmake-osx config=debug64
-osx-release64: .build/projects/gmake-osx
- make -C .build/projects/gmake-osx config=release64
-osx: osx-debug64 osx-release64
+.build/projects/gmake-osx-x64:
+ $(GENIE) --gcc=osx-x64 gmake
+osx-x64-debug: .build/projects/gmake-osx-x64
+ make -C .build/projects/gmake-osx config=debug
+osx-x64-release: .build/projects/gmake-osx-x64
+ make -C .build/projects/gmake-osx config=release
+osx-x64: osx-x64-debug osx-x64-release
.build/projects/gmake-ios-arm:
$(GENIE) --gcc=ios-arm gmake
@@ -152,9 +145,9 @@ ifeq ($(UNAME),$(filter $(UNAME),Linux GNU Darwin Haiku))
ifeq ($(UNAME),$(filter $(UNAME),Darwin Haiku))
ifeq ($(UNAME),$(filter $(UNAME),Darwin))
OS=darwin
-BUILD_PROJECT_DIR=gmake-osx
-BUILD_OUTPUT_DIR=osx64_clang
-BUILD_TOOLS_CONFIG=release64
+BUILD_PROJECT_DIR=gmake-osx-x64
+BUILD_OUTPUT_DIR=osx-x64
+BUILD_TOOLS_CONFIG=release
EXE=
else
OS=haiku
@@ -179,10 +172,10 @@ EXE=.exe
endif
# bin2c
-.build/osx64_clang/bin/bin2cRelease: .build/projects/gmake-osx
- $(SILENT) make -C .build/projects/gmake-osx bin2c config=$(BUILD_TOOLS_CONFIG)
+.build/osx-x64/bin/bin2cRelease: .build/projects/gmake-osx-x64
+ $(SILENT) make -C .build/projects/gmake-osx-x64 bin2c config=$(BUILD_TOOLS_CONFIG)
-tools/bin/darwin/bin2c: .build/osx64_clang/bin/bin2cRelease
+tools/bin/darwin/bin2c: .build/osx-x64/bin/bin2cRelease
$(SILENT) cp $(<) $(@)
.build/linux64_gcc/bin/bin2cRelease: .build/projects/gmake-linux
@@ -206,10 +199,10 @@ tools/bin/windows/bin2c.exe: .build/win64_mingw-gcc/bin/bin2cRelease.exe
bin2c: tools/bin/$(OS)/bin2c$(EXE)
# lemon
-.build/osx64_clang/bin/lemonRelease: .build/projects/gmake-osx
- $(SILENT) make -C .build/projects/gmake-osx lemon config=$(BUILD_TOOLS_CONFIG)
+.build/osx-x64/bin/lemonRelease: .build/projects/gmake-osx-x64
+ $(SILENT) make -C .build/projects/gmake-osx-x64 lemon config=$(BUILD_TOOLS_CONFIG)
-tools/bin/darwin/lemon: .build/osx64_clang/bin/lemonRelease
+tools/bin/darwin/lemon: .build/osx-x64/bin/lemonRelease
$(SILENT) cp $(<) $(@)
.build/linux64_gcc/bin/lemonRelease: .build/projects/gmake-linux
diff --git a/3rdparty/bx/scripts/bin2c.lua b/3rdparty/bx/scripts/bin2c.lua
index f81031879ca..3ebc0014629 100644
--- a/3rdparty/bx/scripts/bin2c.lua
+++ b/3rdparty/bx/scripts/bin2c.lua
@@ -1,5 +1,5 @@
--
--- Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+-- Copyright 2010-2021 Branimir Karadzic. All rights reserved.
-- License: https://github.com/bkaradzic/bx#license-bsd-2-clause
--
diff --git a/3rdparty/bx/scripts/bx.lua b/3rdparty/bx/scripts/bx.lua
index 60f67641362..1e54ac521fc 100644
--- a/3rdparty/bx/scripts/bx.lua
+++ b/3rdparty/bx/scripts/bx.lua
@@ -1,8 +1,20 @@
--
--- Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+-- Copyright 2010-2021 Branimir Karadzic. All rights reserved.
-- License: https://github.com/bkaradzic/bx#license-bsd-2-clause
--
+local function userdefines()
+ local defines = {}
+ local BX_CONFIG = os.getenv("BX_CONFIG")
+ if BX_CONFIG then
+ for def in BX_CONFIG:gmatch "[^%s:]+" do
+ table.insert(defines, "BX_CONFIG_" .. def)
+ end
+ end
+
+ return defines
+end
+
project "bx"
kind "StaticLib"
@@ -18,6 +30,8 @@ project "bx"
path.join(BX_DIR, "scripts/**.natvis"),
}
+ defines (userdefines())
+
configuration { "Debug" }
defines {
"BX_CONFIG_DEBUG=1",
diff --git a/3rdparty/bx/scripts/genie.lua b/3rdparty/bx/scripts/genie.lua
index 600bd7fab9c..8801b224ad2 100644
--- a/3rdparty/bx/scripts/genie.lua
+++ b/3rdparty/bx/scripts/genie.lua
@@ -1,5 +1,5 @@
--
--- Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+-- Copyright 2010-2021 Branimir Karadzic. All rights reserved.
-- License: https://github.com/bkaradzic/bx#license-bsd-2-clause
--
@@ -81,7 +81,7 @@ project "bx.test"
"pthread",
}
- configuration { "osx" }
+ configuration { "osx*" }
links {
"Cocoa.framework",
}
@@ -126,7 +126,7 @@ project "bx.bench"
"pthread",
}
- configuration { "osx" }
+ configuration { "osx*" }
links {
"Cocoa.framework",
}
diff --git a/3rdparty/bx/scripts/lemon.lua b/3rdparty/bx/scripts/lemon.lua
index 2759ea60972..b488896055d 100644
--- a/3rdparty/bx/scripts/lemon.lua
+++ b/3rdparty/bx/scripts/lemon.lua
@@ -1,5 +1,5 @@
--
--- Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+-- Copyright 2010-2021 Branimir Karadzic. All rights reserved.
-- License: https://github.com/bkaradzic/bx#license-bsd-2-clause
--
diff --git a/3rdparty/bx/scripts/toolchain.lua b/3rdparty/bx/scripts/toolchain.lua
index e9b336e6e7d..cb91d3ac750 100644
--- a/3rdparty/bx/scripts/toolchain.lua
+++ b/3rdparty/bx/scripts/toolchain.lua
@@ -1,5 +1,5 @@
--
--- Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+-- Copyright 2010-2021 Branimir Karadzic. All rights reserved.
-- License: https://github.com/bkaradzic/bx#license-bsd-2-clause
--
@@ -52,7 +52,8 @@ function toolchain(_buildDir, _libDir)
{ "android-arm", "Android - ARM" },
{ "android-arm64", "Android - ARM64" },
{ "android-x86", "Android - x86" },
- { "asmjs", "Emscripten/asm.js" },
+ { "wasm2js", "Emscripten/Wasm2JS" },
+ { "wasm", "Emscripten/Wasm" },
{ "freebsd", "FreeBSD" },
{ "linux-gcc", "Linux (GCC compiler)" },
{ "linux-gcc-afl", "Linux (GCC + AFL fuzzer)" },
@@ -70,11 +71,11 @@ function toolchain(_buildDir, _libDir)
{ "mingw-gcc", "MinGW" },
{ "mingw-clang", "MinGW (clang compiler)" },
{ "netbsd", "NetBSD" },
- { "osx", "OSX" },
+ { "osx-x64", "OSX - x64" },
+ { "osx-arm64", "OSX - ARM64" },
{ "orbis", "Orbis" },
{ "riscv", "RISC-V" },
{ "rpi", "RaspberryPi" },
- { "haiku", "Haiku" },
},
}
@@ -251,17 +252,18 @@ function toolchain(_buildDir, _libDir)
premake.gcc.llvm = true
location (path.join(_buildDir, "projects", _ACTION .. "-android-x86"))
- elseif "asmjs" == _OPTIONS["gcc"] then
+ elseif "wasm2js" == _OPTIONS["gcc"] or "wasm" == _OPTIONS["gcc"] then
- if not os.getenv("EMSDK") then
- print("Set EMSDK environment variable.")
+ if not os.getenv("EMSCRIPTEN") then
+ print("Set EMSCRIPTEN environment variable to root directory of your Emscripten installation. (e.g. by entering the EMSDK command prompt)")
end
- premake.gcc.cc = "\"$(EMSDK)/fastcomp/bin/emcc\""
- premake.gcc.cxx = "\"$(EMSDK)/fastcomp/bin/em++\""
- premake.gcc.ar = "\"$(EMSDK)/fastcomp/bin/emar\""
+ premake.gcc.cc = "\"$(EMSCRIPTEN)/emcc\""
+ premake.gcc.cxx = "\"$(EMSCRIPTEN)/em++\""
+ premake.gcc.ar = "\"$(EMSCRIPTEN)/emar\""
premake.gcc.llvm = true
- location (path.join(_buildDir, "projects", _ACTION .. "-asmjs"))
+ premake.gcc.namestyle = "Emscripten"
+ location (path.join(_buildDir, "projects", _ACTION .. "-" .. _OPTIONS["gcc"]))
elseif "freebsd" == _OPTIONS["gcc"] then
location (path.join(_buildDir, "projects", _ACTION .. "-freebsd"))
@@ -330,16 +332,6 @@ function toolchain(_buildDir, _libDir)
elseif "linux-arm-gcc" == _OPTIONS["gcc"] then
location (path.join(_buildDir, "projects", _ACTION .. "-linux-arm-gcc"))
- elseif "linux-steamlink" == _OPTIONS["gcc"] then
- if not os.getenv("MARVELL_SDK_PATH") then
- print("Set MARVELL_SDK_PATH environment variable.")
- end
-
- premake.gcc.cc = "$(MARVELL_SDK_PATH)/toolchain/bin/armv7a-cros-linux-gnueabi-gcc"
- premake.gcc.cxx = "$(MARVELL_SDK_PATH)/toolchain/bin/armv7a-cros-linux-gnueabi-g++"
- premake.gcc.ar = "$(MARVELL_SDK_PATH)/toolchain/bin/armv7a-cros-linux-gnueabi-ar"
- location (path.join(_buildDir, "projects", _ACTION .. "-linux-steamlink"))
-
elseif "mingw-gcc" == _OPTIONS["gcc"] then
if not os.getenv("MINGW") then
print("Set MINGW environment variable.")
@@ -370,7 +362,9 @@ function toolchain(_buildDir, _libDir)
elseif "netbsd" == _OPTIONS["gcc"] then
location (path.join(_buildDir, "projects", _ACTION .. "-netbsd"))
- elseif "osx" == _OPTIONS["gcc"] then
+ elseif "osx-x64" == _OPTIONS["gcc"]
+ or "osx-arm64" == _OPTIONS["gcc"] then
+
if os.is("linux") then
if not os.getenv("OSXCROSS") then
@@ -382,7 +376,8 @@ function toolchain(_buildDir, _libDir)
premake.gcc.cxx = "$(OSXCROSS)/target/bin/" .. osxToolchain .. "clang++"
premake.gcc.ar = "$(OSXCROSS)/target/bin/" .. osxToolchain .. "ar"
end
- location (path.join(_buildDir, "projects", _ACTION .. "-osx"))
+
+ location (path.join(_buildDir, "projects", _ACTION .. "-" .. _OPTIONS["gcc"]))
elseif "orbis" == _OPTIONS["gcc"] then
@@ -471,9 +466,7 @@ function toolchain(_buildDir, _libDir)
end
- elseif _ACTION == "xcode4"
- or _ACTION == "xcode8"
- or _ACTION == "xcode9" then
+ elseif _ACTION and _ACTION:match("^xcode.+$") then
local action = premake.action.current()
local str_or = function(str, def)
return #str > 0 and str or def
@@ -556,8 +549,6 @@ function toolchain(_buildDir, _libDir)
"WIN32",
"_WIN32",
"_HAS_EXCEPTIONS=0",
- "_HAS_ITERATOR_DEBUGGING=0",
- "_ITERATOR_DEBUG_LEVEL=0",
"_SCL_SECURE=0",
"_SECURE_SCL=0",
"_SCL_SECURE_NO_WARNINGS",
@@ -857,29 +848,6 @@ function toolchain(_buildDir, _libDir)
"-Wl,-z,now",
}
- configuration { "linux-steamlink" }
- targetdir (path.join(_buildDir, "steamlink/bin"))
- objdir (path.join(_buildDir, "steamlink/obj"))
- libdirs { path.join(_libDir, "lib/steamlink") }
- includedirs { path.join(bxDir, "include/compat/linux") }
- defines {
- "__STEAMLINK__=1", -- There is no special prefedined compiler symbol to detect SteamLink, faking it.
- }
- buildoptions {
- "-Wfatal-errors",
- "-Wunused-value",
- "-Wundef",
- "-pthread",
- "-marm",
- "-mfloat-abi=hard",
- "--sysroot=$(MARVELL_SDK_PATH)/rootfs",
- }
- linkoptions {
- "-static-libgcc",
- "-static-libstdc++",
- "--sysroot=$(MARVELL_SDK_PATH)/rootfs",
- }
-
configuration { "android-arm" }
targetdir (path.join(_buildDir, "android-arm/bin"))
objdir (path.join(_buildDir, "android-arm/obj"))
@@ -907,7 +875,6 @@ function toolchain(_buildDir, _libDir)
path.join("$(ANDROID_NDK_ROOT)/platforms", androidPlatform, "arch-arm/usr/lib/crtend_so.o"),
"-target armv7-none-linux-androideabi",
"-march=armv7-a",
- "-Wl,--fix-cortex-a8",
}
configuration { "android-arm64" }
@@ -934,7 +901,6 @@ function toolchain(_buildDir, _libDir)
path.join("$(ANDROID_NDK_ROOT)/platforms", androidPlatform, "arch-arm64/usr/lib/crtend_so.o"),
"-target aarch64-none-linux-androideabi",
"-march=armv8-a",
- "-Wl,--fix-cortex-a8",
}
configuration { "android-x86" }
@@ -966,16 +932,29 @@ function toolchain(_buildDir, _libDir)
"-target i686-none-linux-android",
}
- configuration { "asmjs" }
- targetdir (path.join(_buildDir, "asmjs/bin"))
- objdir (path.join(_buildDir, "asmjs/obj"))
- libdirs { path.join(_libDir, "lib/asmjs") }
+ configuration { "wasm*" }
buildoptions {
- "-isystem \"$(EMSDK)/fastcomp/emscripten\"",
"-Wunused-value",
"-Wundef",
}
+ linkoptions {
+ "-s MAX_WEBGL_VERSION=2"
+ }
+
+ configuration { "wasm2js" }
+ targetdir (path.join(_buildDir, "wasm2js/bin"))
+ objdir (path.join(_buildDir, "wasm2js/obj"))
+ libdirs { path.join(_libDir, "lib/wasm2js") }
+ linkoptions {
+ "-s WASM=0"
+ }
+
+ configuration { "wasm" }
+ targetdir (path.join(_buildDir, "wasm/bin"))
+ objdir (path.join(_buildDir, "wasm/obj"))
+ libdirs { path.join(_libDir, "lib/wasm") }
+
configuration { "freebsd" }
targetdir (path.join(_buildDir, "freebsd/bin"))
objdir (path.join(_buildDir, "freebsd/obj"))
@@ -1011,33 +990,35 @@ function toolchain(_buildDir, _libDir)
path.join(bxDir, "include/compat/freebsd"),
}
- configuration { "osx", "x32" }
- targetdir (path.join(_buildDir, "osx32_clang/bin"))
- objdir (path.join(_buildDir, "osx32_clang/obj"))
- --libdirs { path.join(_libDir, "lib/osx32_clang") }
+ configuration { "osx-x64" }
+ targetdir (path.join(_buildDir, "osx-x64/bin"))
+ objdir (path.join(_buildDir, "osx-x64/obj"))
+ linkoptions {
+ "-arch x86_64",
+ }
buildoptions {
- "-m32",
+ "-arch x86_64",
+ "-msse2",
+ "-target x86_64-apple-macos" .. (#macosPlatform > 0 and macosPlatform or "10.11"),
}
- configuration { "osx", "x64" }
- targetdir (path.join(_buildDir, "osx64_clang/bin"))
- objdir (path.join(_buildDir, "osx64_clang/obj"))
- --libdirs { path.join(_libDir, "lib/osx64_clang") }
+ configuration { "osx-arm64" }
+ targetdir (path.join(_buildDir, "osx-arm64/bin"))
+ objdir (path.join(_buildDir, "osx-arm64/obj"))
+ linkoptions {
+ "-arch arm64",
+ }
buildoptions {
- "-m64",
+ "-arch arm64",
+ "-Wno-error=unused-command-line-argument",
+ "-Wno-unused-command-line-argument",
}
- configuration { "osx", "Universal" }
- targetdir (path.join(_buildDir, "osx_universal/bin"))
- objdir (path.join(_buildDir, "osx_universal/bin"))
-
- configuration { "osx" }
+ configuration { "osx*" }
buildoptions {
"-Wfatal-errors",
- "-msse2",
"-Wunused-value",
"-Wundef",
- "-target x86_64-apple-macos" .. (#macosPlatform > 0 and macosPlatform or "10.11"),
}
includedirs { path.join(bxDir, "include/compat/osx") }
@@ -1080,14 +1061,14 @@ function toolchain(_buildDir, _libDir)
configuration { "ios-arm*" }
linkoptions {
- "-miphoneos-version-min=7.0",
+ "-miphoneos-version-min=9.0",
"--sysroot=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS" ..iosPlatform .. ".sdk",
"-L/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS" ..iosPlatform .. ".sdk/usr/lib/system",
"-F/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS" ..iosPlatform .. ".sdk/System/Library/Frameworks",
"-F/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS" ..iosPlatform .. ".sdk/System/Library/PrivateFrameworks",
}
buildoptions {
- "-miphoneos-version-min=7.0",
+ "-miphoneos-version-min=9.0",
"--sysroot=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS" ..iosPlatform .. ".sdk",
"-fembed-bitcode",
}
@@ -1097,7 +1078,7 @@ function toolchain(_buildDir, _libDir)
objdir (path.join(_buildDir, "ios-simulator/obj"))
libdirs { path.join(_libDir, "lib/ios-simulator") }
linkoptions {
- "-mios-simulator-version-min=7.0",
+ "-mios-simulator-version-min=9.0",
"-arch i386",
"--sysroot=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator" ..iosPlatform .. ".sdk",
"-L/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator" ..iosPlatform .. ".sdk/usr/lib/system",
@@ -1105,7 +1086,7 @@ function toolchain(_buildDir, _libDir)
"-F/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator" ..iosPlatform .. ".sdk/System/Library/PrivateFrameworks",
}
buildoptions {
- "-mios-simulator-version-min=7.0",
+ "-mios-simulator-version-min=9.0",
"-arch i386",
"--sysroot=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator" ..iosPlatform .. ".sdk",
}
@@ -1115,7 +1096,7 @@ function toolchain(_buildDir, _libDir)
objdir (path.join(_buildDir, "ios-simulator64/obj"))
libdirs { path.join(_libDir, "lib/ios-simulator64") }
linkoptions {
- "-mios-simulator-version-min=7.0",
+ "-mios-simulator-version-min=9.0",
"-arch x86_64",
"--sysroot=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator" ..iosPlatform .. ".sdk",
"-L/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator" ..iosPlatform .. ".sdk/usr/lib/system",
@@ -1123,7 +1104,7 @@ function toolchain(_buildDir, _libDir)
"-F/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator" ..iosPlatform .. ".sdk/System/Library/PrivateFrameworks",
}
buildoptions {
- "-mios-simulator-version-min=7.0",
+ "-mios-simulator-version-min=9.0",
"-arch x86_64",
"--sysroot=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator" ..iosPlatform .. ".sdk",
}
@@ -1259,13 +1240,7 @@ function strip()
"$(SILENT) $(ANDROID_NDK_X86)/bin/i686-linux-android-strip -s \"$(TARGET)\""
}
- configuration { "linux-steamlink", "Release" }
- postbuildcommands {
- "$(SILENT) echo Stripping symbols.",
- "$(SILENT) $(MARVELL_SDK_PATH)/toolchain/bin/armv7a-cros-linux-gnueabi-strip -s \"$(TARGET)\""
- }
-
- configuration { "linux-* or rpi", "not linux-steamlink", "Release" }
+ configuration { "linux-* or rpi", "Release" }
postbuildcommands {
"$(SILENT) echo Stripping symbols.",
"$(SILENT) strip -s \"$(TARGET)\""
@@ -1277,24 +1252,6 @@ function strip()
"$(SILENT) $(MINGW)/bin/strip -s \"$(TARGET)\""
}
- configuration { "asmjs" }
- postbuildcommands {
- "$(SILENT) echo Running asmjs finalize.",
- "$(SILENT) \"$(EMSDK)/fastcomp/bin/emcc\" -O2 "
-
--- .. "-s ALLOW_MEMORY_GROWTH=1 "
--- .. "-s ASSERTIONS=2 "
--- .. "-s EMTERPRETIFY=1 "
--- .. "-s EMTERPRETIFY_ASYNC=1 "
- .. "-s PRECISE_F32=1 "
- .. "-s TOTAL_MEMORY=268435456 "
--- .. "-s USE_WEBGL2=1 "
-
- .. "--memory-init-file 1 "
- .. "\"$(TARGET)\" -o \"$(TARGET)\".html "
--- .. "--preload-file ../../../examples/runtime@/ "
- }
-
configuration { "riscv" }
postbuildcommands {
"$(SILENT) echo Stripping symbols.",
diff --git a/3rdparty/bx/src/allocator.cpp b/3rdparty/bx/src/allocator.cpp
index 50c1505874c..0bcf2cd43c7 100644
--- a/3rdparty/bx/src/allocator.cpp
+++ b/3rdparty/bx/src/allocator.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/src/amalgamated.cpp b/3rdparty/bx/src/amalgamated.cpp
index e274b69019d..4aeac822870 100644
--- a/3rdparty/bx/src/amalgamated.cpp
+++ b/3rdparty/bx/src/amalgamated.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2011-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2011-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/src/bx.cpp b/3rdparty/bx/src/bx.cpp
index ab28bc25d2f..d6bdbf026c3 100644
--- a/3rdparty/bx/src/bx.cpp
+++ b/3rdparty/bx/src/bx.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/src/bx_p.h b/3rdparty/bx/src/bx_p.h
index de02ccce2da..d44901c58ee 100644
--- a/3rdparty/bx/src/bx_p.h
+++ b/3rdparty/bx/src/bx_p.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -13,7 +13,7 @@
#if BX_CONFIG_DEBUG
# define BX_TRACE _BX_TRACE
# define BX_WARN _BX_WARN
-# define BX_CHECK _BX_CHECK
+# define BX_ASSERT _BX_ASSERT
# define BX_CONFIG_ALLOCATOR_DEBUG 1
#endif // BX_CONFIG_DEBUG
@@ -30,7 +30,7 @@
} \
BX_MACRO_BLOCK_END
-#define _BX_CHECK(_condition, _format, ...) \
+#define _BX_ASSERT(_condition, _format, ...) \
BX_MACRO_BLOCK_BEGIN \
if (!BX_IGNORE_C4127(_condition) ) \
{ \
diff --git a/3rdparty/bx/src/commandline.cpp b/3rdparty/bx/src/commandline.cpp
index d9f6fb4e8de..2ff57f6dbd1 100644
--- a/3rdparty/bx/src/commandline.cpp
+++ b/3rdparty/bx/src/commandline.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/src/crtnone.cpp b/3rdparty/bx/src/crtnone.cpp
index 72dd8747eaa..7852f374f44 100644
--- a/3rdparty/bx/src/crtnone.cpp
+++ b/3rdparty/bx/src/crtnone.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -100,7 +100,7 @@ extern "C" const char* strstr(const char* _str, const char* _find)
extern "C" void qsort(void* _base, size_t _num, size_t _size, bx::ComparisonFn _fn)
{
- BX_CHECK(_num <= UINT32_MAX && _size <= UINT32_MAX, "");
+ BX_ASSERT(_num <= UINT32_MAX && _size <= UINT32_MAX, "");
return bx::quickSort(_base, _num, _size, _fn);
}
diff --git a/3rdparty/bx/src/debug.cpp b/3rdparty/bx/src/debug.cpp
index 623a2213b47..b02e53f1380 100644
--- a/3rdparty/bx/src/debug.cpp
+++ b/3rdparty/bx/src/debug.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -142,7 +142,7 @@ namespace bx
if (NULL != _data)
{
- const uint8_t* data = reinterpret_cast<const uint8_t*>(_data);
+ const uint8_t* data = (const uint8_t*)_data;
char hex[HEX_DUMP_WIDTH*3+1];
char ascii[HEX_DUMP_WIDTH+1];
uint32_t hexPos = 0;
diff --git a/3rdparty/bx/src/dtoa.cpp b/3rdparty/bx/src/dtoa.cpp
index 686d5c6a12d..99b27a5a36c 100644
--- a/3rdparty/bx/src/dtoa.cpp
+++ b/3rdparty/bx/src/dtoa.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -74,8 +74,8 @@ namespace bx
DiyFp operator-(const DiyFp& rhs) const
{
- BX_CHECK(e == rhs.e, "");
- BX_CHECK(f >= rhs.f, "");
+ BX_ASSERT(e == rhs.e, "");
+ BX_ASSERT(f >= rhs.f, "");
return DiyFp(f - rhs.f, e);
}
@@ -224,7 +224,7 @@ namespace bx
uint32_t index = static_cast<uint32_t>( (k >> 3) + 1);
*K = -(-348 + static_cast<int32_t>(index << 3) ); // decimal exponent no need lookup table
- BX_CHECK(index < sizeof(s_kCachedPowers_F) / sizeof(s_kCachedPowers_F[0]), "");
+ BX_ASSERT(index < sizeof(s_kCachedPowers_F) / sizeof(s_kCachedPowers_F[0]), "");
return DiyFp(s_kCachedPowers_F[index], s_kCachedPowers_E[index]);
}
diff --git a/3rdparty/bx/src/easing.cpp b/3rdparty/bx/src/easing.cpp
index 8984abccd0c..ec4c4517196 100644
--- a/3rdparty/bx/src/easing.cpp
+++ b/3rdparty/bx/src/easing.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/src/file.cpp b/3rdparty/bx/src/file.cpp
index aea285ea23f..c47eb37a0b6 100644
--- a/3rdparty/bx/src/file.cpp
+++ b/3rdparty/bx/src/file.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -100,18 +100,18 @@ namespace bx
virtual bool open(const FilePath& _filePath, Error* _err) override
{
- BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
+ BX_ASSERT(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
if (NULL != m_file)
{
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_ALREADY_OPEN, "FileReader: File is already open.");
+ BX_ERROR_SET(_err, kErrorReaderWriterAlreadyOpen, "FileReader: File is already open.");
return false;
}
m_file = fopen(_filePath.getCPtr(), "rb");
if (NULL == m_file)
{
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "FileReader: Failed to open file.");
+ BX_ERROR_SET(_err, kErrorReaderWriterOpen, "FileReader: Failed to open file.");
return false;
}
@@ -131,26 +131,26 @@ namespace bx
virtual int64_t seek(int64_t _offset, Whence::Enum _whence) override
{
- BX_CHECK(NULL != m_file, "Reader/Writer file is not open.");
+ BX_ASSERT(NULL != m_file, "Reader/Writer file is not open.");
fseeko64(m_file, _offset, _whence);
return ftello64(m_file);
}
virtual int32_t read(void* _data, int32_t _size, Error* _err) override
{
- BX_CHECK(NULL != m_file, "Reader/Writer file is not open.");
- BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
+ BX_ASSERT(NULL != m_file, "Reader/Writer file is not open.");
+ BX_ASSERT(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
int32_t size = (int32_t)fread(_data, 1, _size, m_file);
if (size != _size)
{
if (0 != feof(m_file) )
{
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_EOF, "FileReader: EOF.");
+ BX_ERROR_SET(_err, kErrorReaderWriterEof, "FileReader: EOF.");
}
else if (0 != ferror(m_file) )
{
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_READ, "FileReader: read error.");
+ BX_ERROR_SET(_err, kErrorReaderWriterRead, "FileReader: read error.");
}
return size >= 0 ? size : 0;
@@ -180,11 +180,11 @@ namespace bx
virtual bool open(const FilePath& _filePath, bool _append, Error* _err) override
{
- BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
+ BX_ASSERT(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
if (NULL != m_file)
{
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_ALREADY_OPEN, "FileReader: File is already open.");
+ BX_ERROR_SET(_err, kErrorReaderWriterAlreadyOpen, "FileReader: File is already open.");
return false;
}
@@ -192,7 +192,7 @@ namespace bx
if (NULL == m_file)
{
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "FileWriter: Failed to open file.");
+ BX_ERROR_SET(_err, kErrorReaderWriterOpen, "FileWriter: Failed to open file.");
return false;
}
@@ -212,20 +212,20 @@ namespace bx
virtual int64_t seek(int64_t _offset, Whence::Enum _whence) override
{
- BX_CHECK(NULL != m_file, "Reader/Writer file is not open.");
+ BX_ASSERT(NULL != m_file, "Reader/Writer file is not open.");
fseeko64(m_file, _offset, _whence);
return ftello64(m_file);
}
virtual int32_t write(const void* _data, int32_t _size, Error* _err) override
{
- BX_CHECK(NULL != m_file, "Reader/Writer file is not open.");
- BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
+ BX_ASSERT(NULL != m_file, "Reader/Writer file is not open.");
+ BX_ASSERT(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
int32_t size = (int32_t)fwrite(_data, 1, _size, m_file);
if (size != _size)
{
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_WRITE, "FileWriter: write failed.");
+ BX_ERROR_SET(_err, kErrorReaderWriterWrite, "FileWriter: write failed.");
return size >= 0 ? size : 0;
}
@@ -272,11 +272,11 @@ namespace bx
virtual bool open(const FilePath& _filePath, Error* _err) override
{
- BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
+ BX_ASSERT(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
if (0 != m_fd)
{
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_ALREADY_OPEN, "FileReader: File is already open.");
+ BX_ERROR_SET(_err, kErrorReaderWriterAlreadyOpen, "FileReader: File is already open.");
return false;
}
@@ -284,7 +284,7 @@ namespace bx
if (0 >= m_fd)
{
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "FileReader: Failed to open file.");
+ BX_ERROR_SET(_err, kErrorReaderWriterOpen, "FileReader: Failed to open file.");
return false;
}
@@ -304,14 +304,14 @@ namespace bx
virtual int64_t seek(int64_t _offset, Whence::Enum _whence) override
{
- BX_CHECK(0 != m_fd, "Reader/Writer file is not open.");
+ BX_ASSERT(0 != m_fd, "Reader/Writer file is not open.");
return crt0::seek(m_fd, _offset, crt0::Whence::Enum(_whence) );
}
virtual int32_t read(void* _data, int32_t _size, Error* _err) override
{
- BX_CHECK(0 != m_fd, "Reader/Writer file is not open.");
- BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
+ BX_ASSERT(0 != m_fd, "Reader/Writer file is not open.");
+ BX_ASSERT(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
int32_t size = crt0::read(m_fd, _data, _size);
if (size != _size)
@@ -319,11 +319,11 @@ namespace bx
BX_UNUSED(_err);
// if (0 != feof(m_file) )
// {
-// BX_ERROR_SET(_err, BX_ERROR_READERWRITER_EOF, "FileReader: EOF.");
+// BX_ERROR_SET(_err, kErrorReaderWriterEof, "FileReader: EOF.");
// }
// else if (0 != ferror(m_file) )
// {
-// BX_ERROR_SET(_err, BX_ERROR_READERWRITER_READ, "FileReader: read error.");
+// BX_ERROR_SET(_err, kErrorReaderWriterRead, "FileReader: read error.");
// }
return size >= 0 ? size : 0;
@@ -353,11 +353,11 @@ namespace bx
virtual bool open(const FilePath& _filePath, bool _append, Error* _err) override
{
- BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
+ BX_ASSERT(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
if (0 != m_fd)
{
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_ALREADY_OPEN, "FileReader: File is already open.");
+ BX_ERROR_SET(_err, kErrorReaderWriterAlreadyOpen, "FileReader: File is already open.");
return false;
}
@@ -365,7 +365,7 @@ namespace bx
if (0 >= m_fd)
{
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "FileWriter: Failed to open file.");
+ BX_ERROR_SET(_err, kErrorReaderWriterOpen, "FileWriter: Failed to open file.");
return false;
}
@@ -385,19 +385,19 @@ namespace bx
virtual int64_t seek(int64_t _offset, Whence::Enum _whence) override
{
- BX_CHECK(0 != m_fd, "Reader/Writer file is not open.");
+ BX_ASSERT(0 != m_fd, "Reader/Writer file is not open.");
return crt0::seek(m_fd, _offset, crt0::Whence::Enum(_whence) );
}
virtual int32_t write(const void* _data, int32_t _size, Error* _err) override
{
- BX_CHECK(0 != m_fd, "Reader/Writer file is not open.");
- BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
+ BX_ASSERT(0 != m_fd, "Reader/Writer file is not open.");
+ BX_ASSERT(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
int32_t size = crt0::write(m_fd, _data, _size);
if (size != _size)
{
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_WRITE, "FileWriter: write failed.");
+ BX_ERROR_SET(_err, kErrorReaderWriterWrite, "FileWriter: write failed.");
return size >= 0 ? size : 0;
}
@@ -582,13 +582,13 @@ namespace bx
virtual bool open(const FilePath& _filePath, Error* _err) override
{
- BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
+ BX_ASSERT(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
m_dir = opendir(_filePath.getCPtr() );
if (NULL == m_dir)
{
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "DirectoryReader: Failed to open directory.");
+ BX_ERROR_SET(_err, kErrorReaderWriterOpen, "DirectoryReader: Failed to open directory.");
return false;
}
@@ -608,7 +608,7 @@ namespace bx
virtual int32_t read(void* _data, int32_t _size, Error* _err) override
{
- BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
+ BX_ASSERT(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
int32_t total = 0;
@@ -620,7 +620,7 @@ namespace bx
{
if (!fetch(m_cache, m_dir) )
{
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_EOF, "DirectoryReader: EOF.");
+ BX_ERROR_SET(_err, kErrorReaderWriterEof, "DirectoryReader: EOF.");
return total;
}
}
@@ -690,7 +690,7 @@ namespace bx
virtual bool open(const FilePath& _filePath, Error* _err) override
{
BX_UNUSED(_filePath);
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "DirectoryReader: Failed to open directory.");
+ BX_ERROR_SET(_err, kErrorReaderWriterOpen, "DirectoryReader: Failed to open directory.");
return false;
}
@@ -701,8 +701,8 @@ namespace bx
virtual int32_t read(void* _data, int32_t _size, Error* _err) override
{
BX_UNUSED(_data, _size);
- BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_EOF, "DirectoryReader: EOF.");
+ BX_ASSERT(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
+ BX_ERROR_SET(_err, kErrorReaderWriterEof, "DirectoryReader: EOF.");
return 0;
}
};
@@ -811,7 +811,7 @@ namespace bx
if (0 != result)
{
- BX_ERROR_SET(_err, BX_ERROR_ACCESS, "The parent directory does not allow write permission to the process.");
+ BX_ERROR_SET(_err, kErrorAccess, "The parent directory does not allow write permission to the process.");
return false;
}
@@ -836,7 +836,7 @@ namespace bx
return true;
}
- BX_ERROR_SET(_err, BX_ERROR_NOT_DIRECTORY, "File already exist, and is not directory.");
+ BX_ERROR_SET(_err, kErrorNotDirectory, "File already exist, and is not directory.");
return false;
}
@@ -888,7 +888,7 @@ namespace bx
if (0 != result)
{
- BX_ERROR_SET(_err, BX_ERROR_ACCESS, "The parent directory does not allow write permission to the process.");
+ BX_ERROR_SET(_err, kErrorAccess, "The parent directory does not allow write permission to the process.");
return false;
}
@@ -910,13 +910,13 @@ namespace bx
if (!stat(fi, _filePath) )
{
- BX_ERROR_SET(_err, BX_ERROR_ACCESS, "The parent directory does not allow write permission to the process.");
+ BX_ERROR_SET(_err, kErrorAccess, "The parent directory does not allow write permission to the process.");
return false;
}
if (FileType::Dir != fi.type)
{
- BX_ERROR_SET(_err, BX_ERROR_NOT_DIRECTORY, "File already exist, and is not directory.");
+ BX_ERROR_SET(_err, kErrorNotDirectory, "File already exist, and is not directory.");
return false;
}
@@ -925,7 +925,7 @@ namespace bx
if (!bx::open(&dr, _filePath) )
{
- BX_ERROR_SET(_err, BX_ERROR_NOT_DIRECTORY, "File already exist, and is not directory.");
+ BX_ERROR_SET(_err, kErrorNotDirectory, "File already exist, and is not directory.");
return false;
}
diff --git a/3rdparty/bx/src/filepath.cpp b/3rdparty/bx/src/filepath.cpp
index 28149403aba..14b34782705 100644
--- a/3rdparty/bx/src/filepath.cpp
+++ b/3rdparty/bx/src/filepath.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/src/hash.cpp b/3rdparty/bx/src/hash.cpp
index d48a1e22f28..bdef60796c0 100644
--- a/3rdparty/bx/src/hash.cpp
+++ b/3rdparty/bx/src/hash.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2011-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2011-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/src/math.cpp b/3rdparty/bx/src/math.cpp
index 4e3380a3774..71f96c5ac20 100644
--- a/3rdparty/bx/src/math.cpp
+++ b/3rdparty/bx/src/math.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2011-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2011-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/src/mutex.cpp b/3rdparty/bx/src/mutex.cpp
index 2fe5eaf33d4..b3e9677e62b 100644
--- a/3rdparty/bx/src/mutex.cpp
+++ b/3rdparty/bx/src/mutex.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -158,4 +158,26 @@ namespace bx
} // namespace bx
-#endif // BX_MUTEX_H_HEADER_GUARD
+#else
+
+namespace bx
+{
+ Mutex::Mutex()
+ {
+ }
+
+ Mutex::~Mutex()
+ {
+ }
+
+ void Mutex::lock()
+ {
+ }
+
+ void Mutex::unlock()
+ {
+ }
+
+} // namespace bx
+
+#endif // BX_CONFIG_SUPPORTS_THREADING
diff --git a/3rdparty/bx/src/os.cpp b/3rdparty/bx/src/os.cpp
index ab5d6bd0935..12586aa8862 100644
--- a/3rdparty/bx/src/os.cpp
+++ b/3rdparty/bx/src/os.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -27,15 +27,13 @@
|| BX_PLATFORM_NX \
|| BX_PLATFORM_OSX \
|| BX_PLATFORM_PS4 \
- || BX_PLATFORM_RPI \
- || BX_PLATFORM_STEAMLINK
+ || BX_PLATFORM_RPI
# include <sched.h> // sched_yield
# if BX_PLATFORM_BSD \
|| BX_PLATFORM_HAIKU \
|| BX_PLATFORM_IOS \
|| BX_PLATFORM_OSX \
- || BX_PLATFORM_PS4 \
- || BX_PLATFORM_STEAMLINK
+ || BX_PLATFORM_PS4
# include <pthread.h> // mach_port_t
# endif // BX_PLATFORM_*
@@ -47,8 +45,7 @@
# if BX_PLATFORM_ANDROID
# include <malloc.h> // mallinfo
# elif BX_PLATFORM_LINUX \
- || BX_PLATFORM_RPI \
- || BX_PLATFORM_STEAMLINK
+ || BX_PLATFORM_RPI
# include <stdio.h> // fopen
# include <unistd.h> // syscall
# include <sys/syscall.h>
@@ -101,8 +98,7 @@ namespace bx
#if BX_PLATFORM_WINDOWS
return ::GetCurrentThreadId();
#elif BX_PLATFORM_LINUX \
- || BX_PLATFORM_RPI \
- || BX_PLATFORM_STEAMLINK
+ || BX_PLATFORM_RPI
return (pid_t)::syscall(SYS_gettid);
#elif BX_PLATFORM_IOS \
|| BX_PLATFORM_OSX
diff --git a/3rdparty/bx/src/process.cpp b/3rdparty/bx/src/process.cpp
index b079bbc77e5..8dc2a6b0717 100644
--- a/3rdparty/bx/src/process.cpp
+++ b/3rdparty/bx/src/process.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -34,16 +34,16 @@ namespace bx
ProcessReader::~ProcessReader()
{
- BX_CHECK(NULL == m_file, "Process not closed!");
+ BX_ASSERT(NULL == m_file, "Process not closed!");
}
bool ProcessReader::open(const FilePath& _filePath, const StringView& _args, Error* _err)
{
- BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
+ BX_ASSERT(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
if (NULL != m_file)
{
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_ALREADY_OPEN, "ProcessReader: File is already open.");
+ BX_ERROR_SET(_err, kErrorReaderWriterAlreadyOpen, "ProcessReader: File is already open.");
return false;
}
@@ -55,7 +55,7 @@ namespace bx
m_file = popen(tmp, "r");
if (NULL == m_file)
{
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "ProcessReader: Failed to open process.");
+ BX_ERROR_SET(_err, kErrorReaderWriterOpen, "ProcessReader: Failed to open process.");
return false;
}
@@ -64,7 +64,7 @@ namespace bx
void ProcessReader::close()
{
- BX_CHECK(NULL != m_file, "Process not open!");
+ BX_ASSERT(NULL != m_file, "Process not open!");
FILE* file = (FILE*)m_file;
m_exitCode = pclose(file);
m_file = NULL;
@@ -72,7 +72,7 @@ namespace bx
int32_t ProcessReader::read(void* _data, int32_t _size, Error* _err)
{
- BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); BX_UNUSED(_err);
+ BX_ASSERT(NULL != _err, "Reader/Writer interface calling functions must handle errors."); BX_UNUSED(_err);
FILE* file = (FILE*)m_file;
int32_t size = (int32_t)fread(_data, 1, _size, file);
@@ -80,11 +80,11 @@ namespace bx
{
if (0 != feof(file) )
{
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_EOF, "ProcessReader: EOF.");
+ BX_ERROR_SET(_err, kErrorReaderWriterEof, "ProcessReader: EOF.");
}
else if (0 != ferror(file) )
{
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_READ, "ProcessReader: read error.");
+ BX_ERROR_SET(_err, kErrorReaderWriterRead, "ProcessReader: read error.");
}
return size >= 0 ? size : 0;
@@ -105,16 +105,16 @@ namespace bx
ProcessWriter::~ProcessWriter()
{
- BX_CHECK(NULL == m_file, "Process not closed!");
+ BX_ASSERT(NULL == m_file, "Process not closed!");
}
bool ProcessWriter::open(const FilePath& _filePath, const StringView& _args, Error* _err)
{
- BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
+ BX_ASSERT(NULL != _err, "Reader/Writer interface calling functions must handle errors.");
if (NULL != m_file)
{
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_ALREADY_OPEN, "ProcessWriter: File is already open.");
+ BX_ERROR_SET(_err, kErrorReaderWriterAlreadyOpen, "ProcessWriter: File is already open.");
return false;
}
@@ -126,7 +126,7 @@ namespace bx
m_file = popen(tmp, "w");
if (NULL == m_file)
{
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_OPEN, "ProcessWriter: Failed to open process.");
+ BX_ERROR_SET(_err, kErrorReaderWriterOpen, "ProcessWriter: Failed to open process.");
return false;
}
@@ -135,7 +135,7 @@ namespace bx
void ProcessWriter::close()
{
- BX_CHECK(NULL != m_file, "Process not open!");
+ BX_ASSERT(NULL != m_file, "Process not open!");
FILE* file = (FILE*)m_file;
m_exitCode = pclose(file);
m_file = NULL;
@@ -143,7 +143,7 @@ namespace bx
int32_t ProcessWriter::write(const void* _data, int32_t _size, Error* _err)
{
- BX_CHECK(NULL != _err, "Reader/Writer interface calling functions must handle errors."); BX_UNUSED(_err);
+ BX_ASSERT(NULL != _err, "Reader/Writer interface calling functions must handle errors."); BX_UNUSED(_err);
FILE* file = (FILE*)m_file;
int32_t size = (int32_t)fwrite(_data, 1, _size, file);
@@ -151,7 +151,7 @@ namespace bx
{
if (0 != ferror(file) )
{
- BX_ERROR_SET(_err, BX_ERROR_READERWRITER_WRITE, "ProcessWriter: write error.");
+ BX_ERROR_SET(_err, kErrorReaderWriterWrite, "ProcessWriter: write error.");
}
return size >= 0 ? size : 0;
diff --git a/3rdparty/bx/src/semaphore.cpp b/3rdparty/bx/src/semaphore.cpp
index f4e99c66637..3e3083d3254 100644
--- a/3rdparty/bx/src/semaphore.cpp
+++ b/3rdparty/bx/src/semaphore.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -76,7 +76,7 @@ namespace bx
SemaphoreInternal* si = (SemaphoreInternal*)m_internal;
si->m_handle = dispatch_semaphore_create(0);
- BX_CHECK(NULL != si->m_handle, "dispatch_semaphore_create failed.");
+ BX_ASSERT(NULL != si->m_handle, "dispatch_semaphore_create failed.");
}
Semaphore::~Semaphore()
@@ -140,10 +140,10 @@ namespace bx
int result;
result = pthread_mutex_init(&si->m_mutex, NULL);
- BX_CHECK(0 == result, "pthread_mutex_init %d", result);
+ BX_ASSERT(0 == result, "pthread_mutex_init %d", result);
result = pthread_cond_init(&si->m_cond, NULL);
- BX_CHECK(0 == result, "pthread_cond_init %d", result);
+ BX_ASSERT(0 == result, "pthread_cond_init %d", result);
BX_UNUSED(result);
}
@@ -154,10 +154,10 @@ namespace bx
int result;
result = pthread_cond_destroy(&si->m_cond);
- BX_CHECK(0 == result, "pthread_cond_destroy %d", result);
+ BX_ASSERT(0 == result, "pthread_cond_destroy %d", result);
result = pthread_mutex_destroy(&si->m_mutex);
- BX_CHECK(0 == result, "pthread_mutex_destroy %d", result);
+ BX_ASSERT(0 == result, "pthread_mutex_destroy %d", result);
BX_UNUSED(result);
}
@@ -167,18 +167,18 @@ namespace bx
SemaphoreInternal* si = (SemaphoreInternal*)m_internal;
int result = pthread_mutex_lock(&si->m_mutex);
- BX_CHECK(0 == result, "pthread_mutex_lock %d", result);
+ BX_ASSERT(0 == result, "pthread_mutex_lock %d", result);
for (uint32_t ii = 0; ii < _count; ++ii)
{
result = pthread_cond_signal(&si->m_cond);
- BX_CHECK(0 == result, "pthread_cond_signal %d", result);
+ BX_ASSERT(0 == result, "pthread_cond_signal %d", result);
}
si->m_count += _count;
result = pthread_mutex_unlock(&si->m_mutex);
- BX_CHECK(0 == result, "pthread_mutex_unlock %d", result);
+ BX_ASSERT(0 == result, "pthread_mutex_unlock %d", result);
BX_UNUSED(result);
}
@@ -188,7 +188,7 @@ namespace bx
SemaphoreInternal* si = (SemaphoreInternal*)m_internal;
int result = pthread_mutex_lock(&si->m_mutex);
- BX_CHECK(0 == result, "pthread_mutex_lock %d", result);
+ BX_ASSERT(0 == result, "pthread_mutex_lock %d", result);
if (-1 == _msecs)
{
@@ -219,7 +219,7 @@ namespace bx
}
result = pthread_mutex_unlock(&si->m_mutex);
- BX_CHECK(0 == result, "pthread_mutex_unlock %d", result);
+ BX_ASSERT(0 == result, "pthread_mutex_unlock %d", result);
BX_UNUSED(result);
@@ -240,7 +240,7 @@ namespace bx
#else
si->m_handle = CreateSemaphoreA(NULL, 0, LONG_MAX, NULL);
#endif
- BX_CHECK(NULL != si->m_handle, "Failed to create Semaphore!");
+ BX_ASSERT(NULL != si->m_handle, "Failed to create Semaphore!");
}
Semaphore::~Semaphore()
diff --git a/3rdparty/bx/src/settings.cpp b/3rdparty/bx/src/settings.cpp
index 49bcc596817..daed2f1b90a 100644
--- a/3rdparty/bx/src/settings.cpp
+++ b/3rdparty/bx/src/settings.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2011-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2011-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/src/sort.cpp b/3rdparty/bx/src/sort.cpp
index 56cb7d48a98..ce1b3e3a8a4 100644
--- a/3rdparty/bx/src/sort.cpp
+++ b/3rdparty/bx/src/sort.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/src/string.cpp b/3rdparty/bx/src/string.cpp
index 678af6664ce..0c5f06d0301 100644
--- a/3rdparty/bx/src/string.cpp
+++ b/3rdparty/bx/src/string.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -310,9 +310,9 @@ namespace bx
inline int32_t strCopy(char* _dst, int32_t _dstSize, const char* _src, int32_t _num)
{
- BX_CHECK(NULL != _dst, "_dst can't be NULL!");
- BX_CHECK(NULL != _src, "_src can't be NULL!");
- BX_CHECK(0 < _dstSize, "_dstSize can't be 0!");
+ BX_ASSERT(NULL != _dst, "_dst can't be NULL!");
+ BX_ASSERT(NULL != _src, "_src can't be NULL!");
+ BX_ASSERT(0 < _dstSize, "_dstSize can't be 0!");
const int32_t len = strLen(_src, _num);
const int32_t max = _dstSize-1;
@@ -330,9 +330,9 @@ namespace bx
inline int32_t strCat(char* _dst, int32_t _dstSize, const char* _src, int32_t _num)
{
- BX_CHECK(NULL != _dst, "_dst can't be NULL!");
- BX_CHECK(NULL != _src, "_src can't be NULL!");
- BX_CHECK(0 < _dstSize, "_dstSize can't be 0!");
+ BX_ASSERT(NULL != _dst, "_dst can't be NULL!");
+ BX_ASSERT(NULL != _src, "_src can't be NULL!");
+ BX_ASSERT(0 < _dstSize, "_dstSize can't be 0!");
const int32_t max = _dstSize;
const int32_t len = strLen(_dst, max);
@@ -420,18 +420,9 @@ namespace bx
}
}
- // Set pointers.
- const char* string = ptr;
- const char* search = _find;
-
- // Start comparing.
- while (fn(*string++) == fn(*search++) )
+ if (0 == strCmp<fn>(ptr, _findMax, _find, _findMax) )
{
- // If end of the 'search' string is reached, all characters match.
- if ('\0' == *search)
- {
- return ptr;
- }
+ return ptr;
}
}
@@ -539,34 +530,47 @@ namespace bx
return _str;
}
+ StringView strRTrimSpace(const StringView& _str)
+ {
+ if (!_str.isEmpty() )
+ {
+ const char* ptr = _str.getPtr();
+
+ for (int32_t len = _str.getLength(), ii = len - 1; 0 <= ii; --ii)
+ {
+ if (!isSpace(ptr[ii]) )
+ {
+ return StringView(ptr, ii + 1);
+ }
+ }
+ }
+
+ return _str;
+ }
+
StringView strTrim(const StringView& _str, const StringView& _chars)
{
return strLTrim(strRTrim(_str, _chars), _chars);
}
+ StringView strTrimSpace(const StringView& _str)
+ {
+ return strLTrimSpace(strRTrimSpace(_str) );
+ }
+
constexpr uint32_t kFindStep = 1024;
StringView strFindNl(const StringView& _str)
{
StringView str(_str);
- for (; str.getPtr() != _str.getTerm()
- ; str = StringView(min(str.getPtr() + kFindStep, _str.getTerm() ), min(str.getPtr() + kFindStep*2, _str.getTerm() ) )
- )
+ // This method returns the character past the \n, so
+ // there is no need to look for he \r which preceedes it.
+ StringView eol = strFind(str, "\n");
+ if (!eol.isEmpty() )
{
- StringView eol = strFind(str, "\r\n");
- if (!eol.isEmpty() )
- {
- return StringView(eol.getTerm(), _str.getTerm() );
- }
-
- eol = strFind(str, '\n');
- if (!eol.isEmpty() )
- {
- return StringView(eol.getTerm(), _str.getTerm() );
- }
+ return StringView(eol.getTerm(), str.getTerm() );
}
-
return StringView(_str.getTerm(), _str.getTerm() );
}
@@ -674,7 +678,7 @@ namespace bx
StringView ptr = strFind(_str, _word);
for (; !ptr.isEmpty(); ptr = strFind(StringView(ptr.getPtr() + len, _str.getTerm() ), _word) )
{
- char ch = *(ptr.getPtr() - 1);
+ char ch = ptr.getPtr() != _str.getPtr() ? *(ptr.getPtr() - 1) : ' ';
if (isAlphaNum(ch) || '_' == ch)
{
continue;
@@ -739,13 +743,40 @@ namespace bx
{
int32_t size = 0;
int32_t len = (int32_t)strLen(_str, _len);
- int32_t padding = _param.width > len ? _param.width - len : 0;
- bool sign = _param.sign && len > 1 && _str[0] != '-';
- padding = padding > 0 ? padding - sign : 0;
+
+ if (_param.width > 0)
+ {
+ len = min(_param.width, len);
+ }
+
+ const bool hasMinus = (NULL != _str && '-' == _str[0]);
+ const bool hasSign = _param.sign || hasMinus;
+ char sign = hasSign ? hasMinus ? '-' : '+' : '\0';
+
+ const char* str = _str;
+ if (hasMinus)
+ {
+ str++;
+ len--;
+ }
+
+ int32_t padding = _param.width > len ? _param.width - len - hasSign: 0;
if (!_param.left)
{
- size += writeRep(_writer, _param.fill, padding, _err);
+ if (' ' != _param.fill
+ && '\0' != sign)
+ {
+ size += write(_writer, sign, _err);
+ sign = '\0';
+ }
+
+ size += writeRep(_writer, _param.fill, max(0, padding), _err);
+ }
+
+ if ('\0' != sign)
+ {
+ size += write(_writer, sign, _err);
}
if (NULL == _str)
@@ -756,17 +787,12 @@ namespace bx
{
for (int32_t ii = 0; ii < len; ++ii)
{
- size += write(_writer, toUpper(_str[ii]), _err);
+ size += write(_writer, toUpper(str[ii]), _err);
}
}
- else if (sign)
- {
- size += write(_writer, '+', _err);
- size += write(_writer, _str, len, _err);
- }
else
{
- size += write(_writer, _str, len, _err);
+ size += write(_writer, str, len, _err);
}
if (_param.left)
diff --git a/3rdparty/bx/src/thread.cpp b/3rdparty/bx/src/thread.cpp
index 952510569b1..17ace0927e7 100644
--- a/3rdparty/bx/src/thread.cpp
+++ b/3rdparty/bx/src/thread.cpp
@@ -1,9 +1,10 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
#include "bx_p.h"
+#include <bx/os.h>
#include <bx/thread.h>
#if BX_CONFIG_SUPPORTS_THREADING
@@ -31,15 +32,11 @@
# endif // BX_PLATFORM_
#elif BX_PLATFORM_WINDOWS \
|| BX_PLATFORM_WINRT \
- || BX_PLATFORM_XBOXONE
+ || BX_PLATFORM_XBOXONE \
+ || BX_PLATFORM_WINRT
# include <windows.h>
# include <limits.h>
# include <errno.h>
-# if BX_PLATFORM_WINRT
-using namespace Platform;
-using namespace Windows::Foundation;
-using namespace Windows::System::Threading;
-# endif // BX_PLATFORM_WINRT
#endif // BX_PLATFORM_
namespace bx
@@ -128,20 +125,25 @@ namespace bx
}
}
- void Thread::init(ThreadFn _fn, void* _userData, uint32_t _stackSize, const char* _name)
+ bool Thread::init(ThreadFn _fn, void* _userData, uint32_t _stackSize, const char* _name)
{
- BX_CHECK(!m_running, "Already running!");
+ BX_ASSERT(!m_running, "Already running!");
m_fn = _fn;
m_userData = _userData;
m_stackSize = _stackSize;
- m_running = true;
ThreadInternal* ti = (ThreadInternal*)m_internal;
#if BX_CRT_NONE
ti->m_handle = crt0::threadCreate(&ti->threadFunc, _userData, m_stackSize, _name);
+
+ if (NULL == ti->m_handle)
+ {
+ return false;
+ }
#elif BX_PLATFORM_WINDOWS \
- || BX_PLATFORM_XBOXONE
+ || BX_PLATFORM_XBOXONE \
+ || BX_PLATFORM_WINRT
ti->m_handle = ::CreateThread(NULL
, m_stackSize
, (LPTHREAD_START_ROUTINE)ti->threadFunc
@@ -149,48 +151,57 @@ namespace bx
, 0
, NULL
);
-#elif BX_PLATFORM_WINRT
- ti->m_handle = CreateEventEx(nullptr, nullptr, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS);
- auto workItemHandler = ref new WorkItemHandler([=](IAsyncAction^)
- {
- m_exitCode = ti->threadFunc(this);
- SetEvent(ti->m_handle);
- }
- , CallbackContext::Any
- );
-
- ThreadPool::RunAsync(workItemHandler, WorkItemPriority::Normal, WorkItemOptions::TimeSliced);
+ if (NULL == ti->m_handle)
+ {
+ return false;
+ }
#elif BX_PLATFORM_POSIX
int result;
BX_UNUSED(result);
pthread_attr_t attr;
result = pthread_attr_init(&attr);
- BX_CHECK(0 == result, "pthread_attr_init failed! %d", result);
+ BX_WARN(0 == result, "pthread_attr_init failed! %d", result);
+ if (0 != result)
+ {
+ return false;
+ }
if (0 != m_stackSize)
{
result = pthread_attr_setstacksize(&attr, m_stackSize);
- BX_CHECK(0 == result, "pthread_attr_setstacksize failed! %d", result);
+ BX_WARN(0 == result, "pthread_attr_setstacksize failed! %d", result);
+
+ if (0 != result)
+ {
+ return false;
+ }
}
result = pthread_create(&ti->m_handle, &attr, &ti->threadFunc, this);
- BX_CHECK(0 == result, "pthread_attr_setschedparam failed! %d", result);
+ BX_WARN(0 == result, "pthread_attr_setschedparam failed! %d", result);
+ if (0 != result)
+ {
+ return false;
+ }
#else
# error "Not implemented!"
#endif // BX_PLATFORM_
+ m_running = true;
m_sem.wait();
if (NULL != _name)
{
setThreadName(_name);
}
+
+ return true;
}
void Thread::shutdown()
{
- BX_CHECK(m_running, "Not running!");
+ BX_ASSERT(m_running, "Not running!");
ThreadInternal* ti = (ThreadInternal*)m_internal;
#if BX_CRT_NONE
crt0::threadJoin(ti->m_handle, NULL);
@@ -249,8 +260,9 @@ namespace bx
#elif BX_PLATFORM_WINDOWS
// Try to use the new thread naming API from Win10 Creators update onwards if we have it
typedef HRESULT (WINAPI *SetThreadDescriptionProc)(HANDLE, PCWSTR);
- SetThreadDescriptionProc SetThreadDescription = (SetThreadDescriptionProc)(GetProcAddress(GetModuleHandleA("Kernel32.dll"), "SetThreadDescription"));
- if (SetThreadDescription)
+ SetThreadDescriptionProc SetThreadDescription = dlsym<SetThreadDescriptionProc>((void*)GetModuleHandleA("Kernel32.dll"), "SetThreadDescription");
+
+ if (NULL != SetThreadDescription)
{
uint32_t length = (uint32_t)bx::strLen(_name)+1;
uint32_t size = length*sizeof(wchar_t);
@@ -358,14 +370,14 @@ namespace bx
TlsDataInternal* ti = (TlsDataInternal*)m_internal;
ti->m_id = TlsAlloc();
- BX_CHECK(TLS_OUT_OF_INDEXES != ti->m_id, "Failed to allocated TLS index (err: 0x%08x).", GetLastError() );
+ BX_ASSERT(TLS_OUT_OF_INDEXES != ti->m_id, "Failed to allocated TLS index (err: 0x%08x).", GetLastError() );
}
TlsData::~TlsData()
{
TlsDataInternal* ti = (TlsDataInternal*)m_internal;
BOOL result = TlsFree(ti->m_id);
- BX_CHECK(0 != result, "Failed to free TLS index (err: 0x%08x).", GetLastError() ); BX_UNUSED(result);
+ BX_ASSERT(0 != result, "Failed to free TLS index (err: 0x%08x).", GetLastError() ); BX_UNUSED(result);
}
void* TlsData::get() const
@@ -388,14 +400,14 @@ namespace bx
TlsDataInternal* ti = (TlsDataInternal*)m_internal;
int result = pthread_key_create(&ti->m_id, NULL);
- BX_CHECK(0 == result, "pthread_key_create failed %d.", result); BX_UNUSED(result);
+ BX_ASSERT(0 == result, "pthread_key_create failed %d.", result); BX_UNUSED(result);
}
TlsData::~TlsData()
{
TlsDataInternal* ti = (TlsDataInternal*)m_internal;
int result = pthread_key_delete(ti->m_id);
- BX_CHECK(0 == result, "pthread_key_delete failed %d.", result); BX_UNUSED(result);
+ BX_ASSERT(0 == result, "pthread_key_delete failed %d.", result); BX_UNUSED(result);
}
void* TlsData::get() const
@@ -408,7 +420,7 @@ namespace bx
{
TlsDataInternal* ti = (TlsDataInternal*)m_internal;
int result = pthread_setspecific(ti->m_id, _ptr);
- BX_CHECK(0 == result, "pthread_setspecific failed %d.", result); BX_UNUSED(result);
+ BX_ASSERT(0 == result, "pthread_setspecific failed %d.", result); BX_UNUSED(result);
}
#endif // BX_PLATFORM_*
diff --git a/3rdparty/bx/src/timer.cpp b/3rdparty/bx/src/timer.cpp
index 80bc28a8448..45806b10777 100644
--- a/3rdparty/bx/src/timer.cpp
+++ b/3rdparty/bx/src/timer.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -41,7 +41,7 @@ namespace bx
gettimeofday(&now, 0);
int64_t i64 = now.tv_sec*INT64_C(1000000) + now.tv_usec;
#else
- BX_CHECK(false, "Not implemented!");
+ BX_ASSERT(false, "Not implemented!");
int64_t i64 = UINT64_MAX;
#endif // BX_PLATFORM_
return i64;
diff --git a/3rdparty/bx/src/url.cpp b/3rdparty/bx/src/url.cpp
index b64a50b43b3..ce02bd35bd8 100644
--- a/3rdparty/bx/src/url.cpp
+++ b/3rdparty/bx/src/url.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2011-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2011-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bnet#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/tests/atomic_test.cpp b/3rdparty/bx/tests/atomic_test.cpp
index 219b0959d27..43d87b63589 100644
--- a/3rdparty/bx/tests/atomic_test.cpp
+++ b/3rdparty/bx/tests/atomic_test.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/tests/crt_test.cpp b/3rdparty/bx/tests/crt_test.cpp
index bddcb2b2d76..d40270641b8 100644
--- a/3rdparty/bx/tests/crt_test.cpp
+++ b/3rdparty/bx/tests/crt_test.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/tests/dbg.h b/3rdparty/bx/tests/dbg.h
index 2fb211862d1..880b0188de4 100644
--- a/3rdparty/bx/tests/dbg.h
+++ b/3rdparty/bx/tests/dbg.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2011-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2011-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/tests/easing_test.cpp b/3rdparty/bx/tests/easing_test.cpp
index 4556c3ad19c..ff0a81934c8 100644
--- a/3rdparty/bx/tests/easing_test.cpp
+++ b/3rdparty/bx/tests/easing_test.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/tests/filepath_test.cpp b/3rdparty/bx/tests/filepath_test.cpp
index fa912105569..afd46f6bf58 100644
--- a/3rdparty/bx/tests/filepath_test.cpp
+++ b/3rdparty/bx/tests/filepath_test.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/tests/handle_bench.cpp b/3rdparty/bx/tests/handle_bench.cpp
index 082bee0e182..a7c88a864b8 100644
--- a/3rdparty/bx/tests/handle_bench.cpp
+++ b/3rdparty/bx/tests/handle_bench.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/tests/handle_test.cpp b/3rdparty/bx/tests/handle_test.cpp
index 5c367f34531..80ff28cda01 100644
--- a/3rdparty/bx/tests/handle_test.cpp
+++ b/3rdparty/bx/tests/handle_test.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/tests/hash_test.cpp b/3rdparty/bx/tests/hash_test.cpp
index 5c2d258dcc9..56556e9d91e 100644
--- a/3rdparty/bx/tests/hash_test.cpp
+++ b/3rdparty/bx/tests/hash_test.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/tests/macros_test.cpp b/3rdparty/bx/tests/macros_test.cpp
index 3576b1cf2a9..afcc75788bd 100644
--- a/3rdparty/bx/tests/macros_test.cpp
+++ b/3rdparty/bx/tests/macros_test.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -24,20 +24,6 @@ BX_STATIC_ASSERT(4 == BX_VA_ARGS_COUNT(1, 2, 3, 4) );
BX_STATIC_ASSERT(5 == BX_VA_ARGS_COUNT(1, 2, 3, 4, 5) );
BX_STATIC_ASSERT(6 == BX_VA_ARGS_COUNT(1, 2, 3, 4, 5, 6) );
-BX_STATIC_ASSERT( 0 == BX_ALIGN_16( 0) );
-BX_STATIC_ASSERT( 16 == BX_ALIGN_16( 1) );
-BX_STATIC_ASSERT( 16 == BX_ALIGN_16( 15) );
-BX_STATIC_ASSERT( 16 == BX_ALIGN_16( 16) );
-BX_STATIC_ASSERT(256 == BX_ALIGN_16(255) );
-
-BX_STATIC_ASSERT( 0 == BX_ALIGN_256( 0) );
-BX_STATIC_ASSERT(256 == BX_ALIGN_256( 1) );
-BX_STATIC_ASSERT(256 == BX_ALIGN_256( 15) );
-BX_STATIC_ASSERT(256 == BX_ALIGN_256(255) );
-BX_STATIC_ASSERT(256 == BX_ALIGN_256(256) );
-BX_STATIC_ASSERT(256 == BX_ALIGN_256(256) );
-BX_STATIC_ASSERT(512 == BX_ALIGN_256(511) );
-
BX_NO_INLINE void unusedFunction()
{
CHECK(false);
diff --git a/3rdparty/bx/tests/main_test.cpp b/3rdparty/bx/tests/main_test.cpp
index 2e0fbe2b431..251d45cb142 100644
--- a/3rdparty/bx/tests/main_test.cpp
+++ b/3rdparty/bx/tests/main_test.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/tests/math_bench.cpp b/3rdparty/bx/tests/math_bench.cpp
index e9e083e385c..7a9fb9af613 100644
--- a/3rdparty/bx/tests/math_bench.cpp
+++ b/3rdparty/bx/tests/math_bench.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/tests/math_test.cpp b/3rdparty/bx/tests/math_test.cpp
index 00a73b283ce..d2a36420974 100644
--- a/3rdparty/bx/tests/math_test.cpp
+++ b/3rdparty/bx/tests/math_test.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -196,6 +196,13 @@ TEST_CASE("ToBits", "")
REQUIRE(UINT64_C(0x123456789abcdef0) == bx::doubleToBits(bx::bitsToDouble(UINT32_C(0x123456789abcdef0) ) ) );
}
+TEST_CASE("lerp", "")
+{
+ REQUIRE(1389.0f == bx::lerp(1389.0f, 1453.0f, 0.0f) );
+ REQUIRE(1453.0f == bx::lerp(1389.0f, 1453.0f, 1.0f) );
+ REQUIRE(0.5f == bx::lerp(0.0f, 1.0f, 0.5f) );
+}
+
void mtxCheck(const float* _a, const float* _b)
{
if (!bx::equal(_a, _b, 16, 0.01f) )
diff --git a/3rdparty/bx/tests/nlalloc_test.cpp b/3rdparty/bx/tests/nlalloc_test.cpp
index 14c44e5f23f..dd44b3bacaf 100644
--- a/3rdparty/bx/tests/nlalloc_test.cpp
+++ b/3rdparty/bx/tests/nlalloc_test.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -90,7 +90,7 @@ namespace bx
Blk remove()
{
- BX_CHECK(0 == m_used, "");
+ BX_ASSERT(0 == m_used, "");
if (0 < m_free.size() )
{
@@ -134,7 +134,7 @@ namespace bx
void free(const Blk& _blk)
{
- BX_CHECK(isValid(_blk), "Freeing invalid block!");
+ BX_ASSERT(isValid(_blk), "Freeing invalid block!");
m_used -= _blk.size;
diff --git a/3rdparty/bx/tests/os_test.cpp b/3rdparty/bx/tests/os_test.cpp
index bd28bf51d2d..5d72aa68af7 100644
--- a/3rdparty/bx/tests/os_test.cpp
+++ b/3rdparty/bx/tests/os_test.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/tests/queue_test.cpp b/3rdparty/bx/tests/queue_test.cpp
index c035dcc8db1..b68fe5fc66f 100644
--- a/3rdparty/bx/tests/queue_test.cpp
+++ b/3rdparty/bx/tests/queue_test.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/tests/readerwriter_test.cpp b/3rdparty/bx/tests/readerwriter_test.cpp
index 53fa3f80cd3..b82238a53a5 100644
--- a/3rdparty/bx/tests/readerwriter_test.cpp
+++ b/3rdparty/bx/tests/readerwriter_test.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/tests/ringbuffer_test.cpp b/3rdparty/bx/tests/ringbuffer_test.cpp
index fb78b0862d7..cc2ac02920b 100644
--- a/3rdparty/bx/tests/ringbuffer_test.cpp
+++ b/3rdparty/bx/tests/ringbuffer_test.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/tests/rng_test.cpp b/3rdparty/bx/tests/rng_test.cpp
index c6586275e47..3b13284a6a2 100644
--- a/3rdparty/bx/tests/rng_test.cpp
+++ b/3rdparty/bx/tests/rng_test.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/tests/run_test.cpp b/3rdparty/bx/tests/run_test.cpp
index 1f7e0509273..91f40c6b89f 100644
--- a/3rdparty/bx/tests/run_test.cpp
+++ b/3rdparty/bx/tests/run_test.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/tests/settings_test.cpp b/3rdparty/bx/tests/settings_test.cpp
index fbf6c9a1112..85b72c44eb6 100644
--- a/3rdparty/bx/tests/settings_test.cpp
+++ b/3rdparty/bx/tests/settings_test.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/tests/simd_bench.cpp b/3rdparty/bx/tests/simd_bench.cpp
index 5e77d4190d3..50ea99f9706 100644
--- a/3rdparty/bx/tests/simd_bench.cpp
+++ b/3rdparty/bx/tests/simd_bench.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/tests/simd_test.cpp b/3rdparty/bx/tests/simd_test.cpp
index 8b959c8dffb..39459dcf9a4 100644
--- a/3rdparty/bx/tests/simd_test.cpp
+++ b/3rdparty/bx/tests/simd_test.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/tests/sort_test.cpp b/3rdparty/bx/tests/sort_test.cpp
index a46a80b64f8..dc565aeaf33 100644
--- a/3rdparty/bx/tests/sort_test.cpp
+++ b/3rdparty/bx/tests/sort_test.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/tests/string_test.cpp b/3rdparty/bx/tests/string_test.cpp
index c1c4b85f546..40f58cf636e 100644
--- a/3rdparty/bx/tests/string_test.cpp
+++ b/3rdparty/bx/tests/string_test.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -226,6 +226,18 @@ TEST_CASE("strFind", "")
REQUIRE(bx::strFind("vgd", 'a').isEmpty() );
}
+
+ {
+ bx::StringView test = bx::strFind("a", "a");
+ REQUIRE(test.getLength() == 1);
+ REQUIRE(*test.getPtr() == 'a');
+ }
+
+ {
+ bx::StringView test = bx::strFind("a", bx::StringView("a ", 1) );
+ REQUIRE(test.getLength() == 1);
+ REQUIRE(*test.getPtr() == 'a');
+ }
}
TEST_CASE("strSkip", "")
@@ -482,6 +494,33 @@ TEST_CASE("Trim", "")
REQUIRE(0 == bx::strCmp(bx::strTrim(uri.getPath(), "/"), "555333/podmac") );
}
+TEST_CASE("TrimSpace", "")
+{
+ REQUIRE(bx::strLTrimSpace("").isEmpty() );
+ REQUIRE(bx::strRTrimSpace("").isEmpty() );
+ REQUIRE(bx::strTrimSpace( "").isEmpty() );
+
+ const bx::StringView t0("1389");
+ const bx::StringView t1(" 1389");
+ const bx::StringView t2("1389 ");
+ const bx::StringView t3(" 1389 ");
+
+ REQUIRE(0 == bx::strCmp(bx::strLTrimSpace(t0), t0) );
+ REQUIRE(0 == bx::strCmp(bx::strLTrimSpace(t1), t0) );
+ REQUIRE(0 == bx::strCmp(bx::strLTrimSpace(t2), t2) );
+ REQUIRE(0 == bx::strCmp(bx::strLTrimSpace(t3), "1389 ") );
+
+ REQUIRE(0 == bx::strCmp(bx::strRTrimSpace(t0), t0) );
+ REQUIRE(0 == bx::strCmp(bx::strRTrimSpace(t1), t1) );
+ REQUIRE(0 == bx::strCmp(bx::strRTrimSpace(t2), t0) );
+ REQUIRE(0 == bx::strCmp(bx::strRTrimSpace(t3), " 1389") );
+
+ REQUIRE(0 == bx::strCmp(bx::strTrimSpace(t0), t0) );
+ REQUIRE(0 == bx::strCmp(bx::strTrimSpace(t1), t0) );
+ REQUIRE(0 == bx::strCmp(bx::strTrimSpace(t2), t0) );
+ REQUIRE(0 == bx::strCmp(bx::strTrimSpace(t3), t0) );
+}
+
TEST_CASE("strWord", "")
{
REQUIRE(bx::strWord(" abvgd-1389.0").isEmpty() );
diff --git a/3rdparty/bx/tests/test.h b/3rdparty/bx/tests/test.h
index b7654aba1e2..88c39f8f5b7 100644
--- a/3rdparty/bx/tests/test.h
+++ b/3rdparty/bx/tests/test.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/tests/thread_test.cpp b/3rdparty/bx/tests/thread_test.cpp
index a174e9f86d6..3c935fa6323 100644
--- a/3rdparty/bx/tests/thread_test.cpp
+++ b/3rdparty/bx/tests/thread_test.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -42,7 +42,9 @@ TEST_CASE("Thread", "")
REQUIRE(!th.isRunning() );
- th.init(threadExit0);
+ bool init = th.init(threadExit0, NULL, 0, NULL);
+ REQUIRE(init);
+
REQUIRE(th.isRunning() );
th.push(NULL);
th.shutdown();
diff --git a/3rdparty/bx/tests/tokenizecmd_test.cpp b/3rdparty/bx/tests/tokenizecmd_test.cpp
index c453ddaf1d9..569d14898c7 100644
--- a/3rdparty/bx/tests/tokenizecmd_test.cpp
+++ b/3rdparty/bx/tests/tokenizecmd_test.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2012-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/tests/uint32_test.cpp b/3rdparty/bx/tests/uint32_test.cpp
index b209219cd56..663ac3f1dd1 100644
--- a/3rdparty/bx/tests/uint32_test.cpp
+++ b/3rdparty/bx/tests/uint32_test.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -117,3 +117,35 @@ TEST_CASE("uint64_roX", "")
REQUIRE(bx::uint64_rol(0x8000000000000000, 1) == 1);
REQUIRE(bx::uint64_ror(1, 1) == 0x8000000000000000);
}
+
+TEST_CASE("align", "")
+{
+ REQUIRE( bx::isAligned(0, 8) );
+ REQUIRE(!bx::isAligned(7, 8) );
+ REQUIRE( bx::isAligned(64, 8) );
+ REQUIRE(!bx::isAligned(63, 8) );
+
+ REQUIRE( 0 == bx::alignUp( 0, 16) );
+ REQUIRE( 16 == bx::alignUp( 1, 16) );
+ REQUIRE( 16 == bx::alignUp( 15, 16) );
+ REQUIRE( 16 == bx::alignUp( 16, 16) );
+ REQUIRE(256 == bx::alignUp(255, 16) );
+ REQUIRE( 0 == bx::alignUp(-1, 16) );
+ REQUIRE(-16 == bx::alignUp(-31, 16) );
+
+ REQUIRE( 0 == bx::alignUp( 0, 256) );
+ REQUIRE(256 == bx::alignUp( 1, 256) );
+ REQUIRE(256 == bx::alignUp( 15, 256) );
+ REQUIRE(256 == bx::alignUp(255, 256) );
+ REQUIRE(256 == bx::alignUp(256, 256) );
+ REQUIRE(256 == bx::alignUp(256, 256) );
+ REQUIRE(512 == bx::alignUp(511, 256) );
+
+ REQUIRE( 0 == bx::alignDown( 0, 16) );
+ REQUIRE( 0 == bx::alignDown( 1, 16) );
+ REQUIRE( 0 == bx::alignDown( 15, 16) );
+ REQUIRE( 16 == bx::alignDown( 16, 16) );
+ REQUIRE(240 == bx::alignDown(255, 16) );
+ REQUIRE(-16 == bx::alignDown(-1, 16) );
+ REQUIRE(-32 == bx::alignDown(-31, 16) );
+}
diff --git a/3rdparty/bx/tests/url_test.cpp b/3rdparty/bx/tests/url_test.cpp
index b43488c157e..c0a9f62d1b4 100644
--- a/3rdparty/bx/tests/url_test.cpp
+++ b/3rdparty/bx/tests/url_test.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
diff --git a/3rdparty/bx/tests/vsnprintf_test.cpp b/3rdparty/bx/tests/vsnprintf_test.cpp
index 50bf5449ff7..8d09210825f 100644
--- a/3rdparty/bx/tests/vsnprintf_test.cpp
+++ b/3rdparty/bx/tests/vsnprintf_test.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2010-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -66,6 +66,18 @@ TEST_CASE("vsnprintf f")
REQUIRE(test(" inf", "%8f", std::numeric_limits<double>::infinity() ) );
REQUIRE(test("inf ", "%-8f", std::numeric_limits<double>::infinity() ) );
REQUIRE(test(" -INF", "%8F", -std::numeric_limits<double>::infinity() ) );
+
+ REQUIRE(test(" 1.0", "%4.1f", 1.0) );
+ REQUIRE(test(" 1.500", "%6.3f", 1.5) );
+ REQUIRE(test("0001.500", "%08.3f", 1.5) );
+ REQUIRE(test("+001.500", "%+08.3f", 1.5) );
+ REQUIRE(test("-001.500", "%+08.3f", -1.5) );
+ REQUIRE(test("0.003906", "%f", 0.00390625) );
+ REQUIRE(test("0.0039", "%.4f", 0.00390625) );
+
+ REQUIRE(test("0.00390625", "%.8f", 0.00390625) );
+ REQUIRE(test("-0.00390625", "%.8f", -0.00390625) );
+ REQUIRE(test("1.50000000000000000", "%.17f", 1.5) );
}
TEST_CASE("vsnprintf d/i/o/u/x")
@@ -82,6 +94,8 @@ TEST_CASE("vsnprintf d/i/o/u/x")
REQUIRE(test("2471", "%o", 1337) );
REQUIRE(test("1337 ", "%-20o", 01337) );
REQUIRE(test("37777776441 ", "%-20o", -01337) );
+ REQUIRE(test(" 2471", "%20o", 1337) );
+ REQUIRE(test("00000000000000002471", "%020o", 1337) );
REQUIRE(test("1337", "%u", 1337) );
REQUIRE(test("1337 ", "%-20u", 1337) );
@@ -92,11 +106,40 @@ TEST_CASE("vsnprintf d/i/o/u/x")
REQUIRE(test("1234ABCD ", "%-20X", 0x1234abcd) );
REQUIRE(test("edcb5433 ", "%-20x", -0x1234abcd) );
REQUIRE(test("EDCB5433 ", "%-20X", -0x1234abcd) );
+ REQUIRE(test(" 1234abcd", "% 20x", 0x1234abcd) );
+ REQUIRE(test(" 1234ABCD", "% 20X", 0x1234abcd) );
+ REQUIRE(test(" edcb5433", "% 20x", -0x1234abcd) );
+ REQUIRE(test(" EDCB5433", "% 20X", -0x1234abcd) );
REQUIRE(test("0000000000001234abcd", "%020x", 0x1234abcd) );
REQUIRE(test("0000000000001234ABCD", "%020X", 0x1234abcd) );
REQUIRE(test("000000000000edcb5433", "%020x", -0x1234abcd) );
REQUIRE(test("000000000000EDCB5433", "%020X", -0x1234abcd) );
+ REQUIRE(test("0xf", "0x%01x", -1) );
+ REQUIRE(test("0xff", "0x%02x", -1) );
+ REQUIRE(test("0xfff", "0x%03x", -1) );
+ REQUIRE(test("0xffff", "0x%04x", -1) );
+ REQUIRE(test("0xfffff", "0x%05x", -1) );
+ REQUIRE(test("0xffffff", "0x%06x", -1) );
+ REQUIRE(test("0xfffffff", "0x%07x", -1) );
+ REQUIRE(test("0xffffffff", "0x%08x", -1) );
+
+ REQUIRE(test(" -1", "% 4i", -1) );
+ REQUIRE(test(" -1", "% 4i", -1) );
+ REQUIRE(test(" 0", "% 4i", 0) );
+ REQUIRE(test(" 1", "% 4i", 1) );
+ REQUIRE(test(" 1", "% 4o", 1) );
+ REQUIRE(test(" +1", "%+4i", 1) );
+ REQUIRE(test(" +1", "%+4o", 1) );
+ REQUIRE(test(" +0", "%+4i", 0) );
+ REQUIRE(test(" -1", "%+4i", -1) );
+ REQUIRE(test("0001", "%04i", 1) );
+ REQUIRE(test("0001", "%04o", 1) );
+ REQUIRE(test("0000", "%04i", 0) );
+ REQUIRE(test("0000", "%04o", 0) );
+ REQUIRE(test("-001", "%04i", -1) );
+ REQUIRE(test("+001", "%+04i", 1) );
+
if (BX_ENABLED(BX_ARCH_32BIT) )
{
REQUIRE(test("2147483647", "%jd", INTMAX_MAX) );
@@ -152,6 +195,12 @@ TEST_CASE("vsnprintf")
REQUIRE(test("hello ", "%-20s", "hello") );
REQUIRE(test("hello, world!", "%s, %s!", "hello", "world") );
+ REQUIRE(test("h", "%1s", "hello") );
+ REQUIRE(test("he", "%2s", "hello") );
+ REQUIRE(test("hel", "%3s", "hello") );
+ REQUIRE(test("hell", "%4s", "hello") );
+ REQUIRE(test("hello", "%5s", "hello") );
+
bx::StringView str("0hello1world2");
bx::StringView hello(str, 1, 5);
bx::StringView world(str, 7, 5);
diff --git a/3rdparty/bx/tools/bin/darwin/bin2c b/3rdparty/bx/tools/bin/darwin/bin2c
index 7aa45d00061..7aa45d00061 100644..100755
--- a/3rdparty/bx/tools/bin/darwin/bin2c
+++ b/3rdparty/bx/tools/bin/darwin/bin2c
Binary files differ
diff --git a/3rdparty/bx/tools/bin/darwin/genie b/3rdparty/bx/tools/bin/darwin/genie
index 7ebe0a3cf11..d12f53ec4c1 100755
--- a/3rdparty/bx/tools/bin/darwin/genie
+++ b/3rdparty/bx/tools/bin/darwin/genie
Binary files differ
diff --git a/3rdparty/bx/tools/bin/darwin/lemon b/3rdparty/bx/tools/bin/darwin/lemon
index c00a276b405..c00a276b405 100644..100755
--- a/3rdparty/bx/tools/bin/darwin/lemon
+++ b/3rdparty/bx/tools/bin/darwin/lemon
Binary files differ
diff --git a/3rdparty/bx/tools/bin/darwin/ninja b/3rdparty/bx/tools/bin/darwin/ninja
index d26afc28e73..d26afc28e73 100644..100755
--- a/3rdparty/bx/tools/bin/darwin/ninja
+++ b/3rdparty/bx/tools/bin/darwin/ninja
Binary files differ
diff --git a/3rdparty/bx/tools/bin/linux/bin2c b/3rdparty/bx/tools/bin/linux/bin2c
index d825698d97a..39015b9b40e 100644..100755
--- a/3rdparty/bx/tools/bin/linux/bin2c
+++ b/3rdparty/bx/tools/bin/linux/bin2c
Binary files differ
diff --git a/3rdparty/bx/tools/bin/linux/genie b/3rdparty/bx/tools/bin/linux/genie
index f61c3ee0039..996d64acd06 100755
--- a/3rdparty/bx/tools/bin/linux/genie
+++ b/3rdparty/bx/tools/bin/linux/genie
Binary files differ
diff --git a/3rdparty/bx/tools/bin/linux/lemon b/3rdparty/bx/tools/bin/linux/lemon
index 79e1aa9213d..be869ab1886 100644..100755
--- a/3rdparty/bx/tools/bin/linux/lemon
+++ b/3rdparty/bx/tools/bin/linux/lemon
Binary files differ
diff --git a/3rdparty/bx/tools/bin/linux/ninja b/3rdparty/bx/tools/bin/linux/ninja
index 189832fdb4b..189832fdb4b 100644..100755
--- a/3rdparty/bx/tools/bin/linux/ninja
+++ b/3rdparty/bx/tools/bin/linux/ninja
Binary files differ
diff --git a/3rdparty/bx/tools/bin/windows/bin2c.exe b/3rdparty/bx/tools/bin/windows/bin2c.exe
index d93eff18e60..d93eff18e60 100644..100755
--- a/3rdparty/bx/tools/bin/windows/bin2c.exe
+++ b/3rdparty/bx/tools/bin/windows/bin2c.exe
Binary files differ
diff --git a/3rdparty/bx/tools/bin/windows/genie.exe b/3rdparty/bx/tools/bin/windows/genie.exe
index c8cecc1559c..cd5ebbb2eed 100644
--- a/3rdparty/bx/tools/bin/windows/genie.exe
+++ b/3rdparty/bx/tools/bin/windows/genie.exe
Binary files differ
diff --git a/3rdparty/bx/tools/bin/windows/ninja.exe b/3rdparty/bx/tools/bin/windows/ninja.exe
index 1b30c1eb432..1b30c1eb432 100644..100755
--- a/3rdparty/bx/tools/bin/windows/ninja.exe
+++ b/3rdparty/bx/tools/bin/windows/ninja.exe
Binary files differ
diff --git a/3rdparty/bx/tools/bin2c/bin2c.cpp b/3rdparty/bx/tools/bin2c/bin2c.cpp
index afc64385be9..066d9e25f8d 100644
--- a/3rdparty/bx/tools/bin2c/bin2c.cpp
+++ b/3rdparty/bx/tools/bin2c/bin2c.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2011-2019 Branimir Karadzic. All rights reserved.
+ * Copyright 2011-2021 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bx#license-bsd-2-clause
*/
@@ -27,20 +27,21 @@ public:
virtual int32_t write(const void* _data, int32_t _size, bx::Error* _err) override
{
- m_outputAsCStr = true;
+ bool asCStr = true;
const char* data = (const char*)_data;
- for (int32_t ii = 0; ii < _size; ++ii)
+ for (int32_t ii = 0; ii < _size && asCStr; ++ii)
{
char ch = data[ii];
- if (!bx::isPrint(ch)
- && !bx::isSpace(ch) )
- {
- m_outputAsCStr = false;
- break;
- }
+
+ asCStr &= false
+ | bx::isPrint(ch)
+ | bx::isSpace(ch)
+ ;
}
+ m_outputAsCStr = asCStr;
+
return bx::write(&m_mw, _data, _size, _err);
}
@@ -58,7 +59,7 @@ public:
void outputString(bx::WriterI* _writer)
{
- const char* data = (const char*)m_mb.more(0);
+ const uint8_t* data = (const uint8_t*)m_mb.more(0);
uint32_t size = uint32_t(bx::seek(&m_mw) );
bx::Error err;
@@ -77,7 +78,7 @@ public:
for (uint32_t ii = 0; ii < size; ++ii)
{
- char ch = data[ii];
+ const char ch = char(data[ii]);
if (!escaped)
{
@@ -113,7 +114,7 @@ public:
#define HEX_DUMP_WIDTH 16
#define HEX_DUMP_SPACE_WIDTH 96
#define HEX_DUMP_FORMAT "%-" BX_STRINGIZE(HEX_DUMP_SPACE_WIDTH) "." BX_STRINGIZE(HEX_DUMP_SPACE_WIDTH) "s"
- const char* data = (const char*)m_mb.more(0);
+ const uint8_t* data = (const uint8_t*)m_mb.more(0);
uint32_t size = uint32_t(bx::seek(&m_mw) );
bx::Error err;
@@ -170,6 +171,19 @@ public:
bool m_outputAsCStr;
};
+void error(const char* _format, ...)
+{
+ bx::WriterI* stdOut = bx::getStdOut();
+ bx::Error err;
+
+ va_list argList;
+ va_start(argList, _format);
+ bx::write(stdOut, &err, "Error:\n");
+ bx::write(stdOut, _format, argList, &err);
+ bx::write(stdOut, &err, "\n\n");
+ va_end(argList);
+}
+
void help(const char* _error = NULL)
{
bx::WriterI* stdOut = bx::getStdOut();
@@ -177,12 +191,12 @@ void help(const char* _error = NULL)
if (NULL != _error)
{
- bx::write(stdOut, &err, "Error:\n%s\n\n", _error);
+ error(_error);
}
bx::write(stdOut, &err
, "bin2c, binary to C\n"
- "Copyright 2011-2019 Branimir Karadzic. All rights reserved.\n"
+ "Copyright 2011-2021 Branimir Karadzic. All rights reserved.\n"
"License: https://github.com/bkaradzic/bx#license-bsd-2-clause\n\n"
);
@@ -250,9 +264,19 @@ int main(int _argc, const char* _argv[])
writer.output(&fw);
bx::close(&fw);
}
+ else
+ {
+ bx::StringView path = outFilePath;
+ error("Failed to open output file '%.*s'.\n", path.getLength(), path.getPtr() );
+ }
BX_FREE(&allocator, data);
}
+ else
+ {
+ bx::StringView path = filePath;
+ error("Failed to open input file '%.*s'.\n", path.getLength(), path.getPtr() );
+ }
return 0;
}