diff --git a/docs/Readme.md b/docs/Readme.md
index f4230506de..176f19e9d0 100644
--- a/docs/Readme.md
+++ b/docs/Readme.md
@@ -10,6 +10,7 @@ Once you're up and running consider the following reference material.
* [Comparing floating point numbers](comparing-floating-point-numbers.md#top)
* [Logging macros](logging.md#top)
* [Test cases and sections](test-cases-and-sections.md#top)
+* [Compile time testing](./compile-time-testing.md#top)
* [Test fixtures](test-fixtures.md#top)
* [Explicitly skipping, passing, and failing tests at runtime](skipping-passing-failing.md#top)
* [Reporters (output customization)](reporters.md#top)
diff --git a/docs/compile-time-testing.md b/docs/compile-time-testing.md
new file mode 100644
index 0000000000..9d41ba2490
--- /dev/null
+++ b/docs/compile-time-testing.md
@@ -0,0 +1,153 @@
+
+
+# Compile-time testing
+
+Catch2 provides a way to test code during compilation. This is
+useful for ensuring the code does not lead to undefined behavior.
+
+> [!IMPORTANT]
+> This feature is only available with **C++17**
+
+## Why should I test code at compile-time ?
+
+Testing code during compilation is the only way for ensuring the code does
+not lead to [undefined behavior](https://en.cppreference.com/w/cpp/language/ub.html).
+This is critical to make your program safe, prevent unexpected crashes and worse
+consequences of undefined behavior.
+
+## How ?
+
+Catch2 made it easy to test code at compile-time.
+
+The usage is pretty similar to testing at runtime:
+
+| Runtime macro | Compile time macro |
+|-----------------|---------------------------|
+| `SECTION` | `CONSTEXPR_SECTION` |
+| `REQUIRE` | `CONSTEXPR_REQUIRE` |
+| `REQUIRE_FALSE` | `CONSTEXPR_REQUIRE_FALSE` |
+| `CHECK` | - |
+| `CHECK_FALSE` | - |
+
+```c++
+TEST_CASE("My compile time test")
+{
+ CONSTEXPR_SECTION("std::array subscript and size")
+ {
+ std::array v = {1, 2, 3, 4, 5};
+ CONSTEXPR_REQUIRE( v.size() == 5 );
+ CONSTEXPR_REQUIRE( v[2] == 3 );
+
+ }; // <-- Don't forget the semicolon here!
+}
+```
+
+All code inside the `CONSTEXPR_SECTION` will be evaluated during compilation.
+If any of the `CONSTEXPR_REQUIRE` or `CONSTEXPR_REQUIRE_FALSE` fails,
+it will cause a **compilation error**.
+
+> [!WARNING]
+> You cannot use `REQUIRE` or `CHECK` inside a `CONSTEXPR_SECTION`.
+> Be careful not to mistake `CONSTEXPR_REQUIRE` with `STATIC_REQUIRE`.
+> They both concern compilation-time testing, but they do not have the same
+> purpose.
+
+> [!WARNING]
+> You cannot nest `CONSTEXPR_SECTION`s or put a `SECTION` inside a
+> `CONSTEXPR_SECTION`
+
+> [!NOTE]
+> The code inside the `CONSTEXPR_SECTION` is also evaluated at
+> runtime. This way, it remains debuggable, and it contributes to the code
+> coverage analysis.
+
+## What can I test ?
+
+You can test anything that can be evaluated in a `constexpr` function.
+This will depend on your compiler and the C++ standard you are using.
+C++20, C++23 and C++26 improved a lot the support for `constexpr`.
+
+Take a look at the C++ compiler support on [cppreference](https://en.cppreference.com/w/cpp/compiler_support.html)
+to see what you can use.
+
+## Debug failing compile-time tests
+
+### Investigate from the compiler output
+
+You can check the output of your compiler to find the failing assertion.
+The failing line should be highlighted somewhere. If you cannot see any
+line:
+
+- Ensure the `CONSTEXPR_SECTION` runs only code that can be evaluated
+at compile-time. This will depend on your compiler and the C++ standard you
+are using.
+- Ensure you did not use unsupported Catch2 macros inside the `CONSTEXPR_SECTION`.
+The only supported macros are `CONSTEXPR_REQUIRE` and `CONSTEXPR_REQUIRE_FALSE`.
+- Ensure the code you wrote doesn't produce undefined behavior (UB cannot
+compile). Reading a range outside its bounds, dereferencing an invalid pointer,
+reading a variable after it has been destroyed, are widespread undefined
+behaviors. They will be all caught by these tests.
+
+### Investigate at runtime
+
+> [!TIP]
+> If you want to debug the code in a `CONSTEXPR_SECTION`, you can simply replace
+> the `CONSTEXPR_SECTION` with a `SECTION` and the code will be evaluated at runtime
+> only instead. Remember to come back to the `CONSTEXPR_SECTION` once you are
+> done !
+
+## Compile time test report
+
+At runtime, a `CONSTEXPR_SECTION` will add a section in the test report. These sections
+provide a way to see what was tested during compilation in the test report.
+
+For instance, given the following test case:
+
+```C++
+TEST_CASE("My other compile time test")
+{
+ SECTION("Any runtime section")
+ {
+ SECTION("Nested section")
+ {
+ CONSTEXPR_SECTION("First constexpr section")
+ {
+ // ...
+ };
+ };
+
+ CONSTEXPR_SECTION("Second constexpr section")
+ {
+ // ...
+ };
+ CONSTEXPR_SECTION("Third constexpr section")
+ {
+ // ...
+ };
+ CONSTEXPR_SECTION("Fourth section")
+ {
+ // ...
+ };
+ }
+
+ SECTION("Another runtime section")
+ {
+ SECTION("Nested runtime section")
+ {
+ // ...
+ }
+ }
+}
+```
+
+The report would look like this:
+
+- ✅ My other compile time test
+ - ✅ Any runtime section
+ - ✅ Nested section
+ - ✅ [Passed during compilation] First constexpr section
+ - ✅ [Passed during compilation] Second constexpr section
+ - ✅ [Passed during compilation] Third constexpr section
+ - ✅ [Passed during compilation] Fourth constexpr section
+ - ✅ Another runtime section
+ - ✅ Nested runtime section
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 1e3af147a8..806fe4814d 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -80,6 +80,8 @@ set(IMPL_HEADERS
${SOURCES_DIR}/internal/catch_config_wchar.hpp
${SOURCES_DIR}/internal/catch_console_colour.hpp
${SOURCES_DIR}/internal/catch_console_width.hpp
+ ${SOURCES_DIR}/internal/catch_constexpr_asserts.hpp
+ ${SOURCES_DIR}/internal/catch_constexpr_section.hpp
${SOURCES_DIR}/internal/catch_container_nonmembers.hpp
${SOURCES_DIR}/internal/catch_context.hpp
${SOURCES_DIR}/internal/catch_debug_console.hpp
@@ -173,6 +175,7 @@ set(IMPL_SOURCES
${SOURCES_DIR}/internal/catch_clara.cpp
${SOURCES_DIR}/internal/catch_commandline.cpp
${SOURCES_DIR}/internal/catch_console_colour.cpp
+ ${SOURCES_DIR}/internal/catch_constexpr_section.cpp
${SOURCES_DIR}/internal/catch_context.cpp
${SOURCES_DIR}/internal/catch_debug_console.cpp
${SOURCES_DIR}/internal/catch_debugger.cpp
diff --git a/src/catch2/catch_all.hpp b/src/catch2/catch_all.hpp
index 2417d8567e..719ac27356 100644
--- a/src/catch2/catch_all.hpp
+++ b/src/catch2/catch_all.hpp
@@ -61,6 +61,8 @@
#include
#include
#include
+#include
+#include
#include
#include
#include
diff --git a/src/catch2/catch_test_macros.hpp b/src/catch2/catch_test_macros.hpp
index 97708557f9..f78f4fa2c1 100644
--- a/src/catch2/catch_test_macros.hpp
+++ b/src/catch2/catch_test_macros.hpp
@@ -8,15 +8,16 @@
#ifndef CATCH_TEST_MACROS_HPP_INCLUDED
#define CATCH_TEST_MACROS_HPP_INCLUDED
-#include
#include
#include
+#include
+#include
#include
+#include
#include
#include
#include
-
// All of our user-facing macros support configuration toggle, that
// forces them to be defined prefixed with CATCH_. We also like to
// support another toggle that can minimize (disable) their implementation.
@@ -48,6 +49,7 @@
#define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
#define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
#define CATCH_DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )
+ #define CATCH_CONSTEXPR_SECTION( ... ) INTERNAL_CATCH_CONSTEXPR_SECTION( __VA_ARGS__ )
#define CATCH_FAIL( ... ) do { \
INTERNAL_CATCH_MSG("CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ ); \
Catch::Detail::Unreachable(); \
@@ -72,6 +74,8 @@
#define CATCH_STATIC_CHECK_FALSE( ... ) CATCH_CHECK_FALSE( __VA_ARGS__ )
#endif
+ #define CATCH_CONSTEXPR_REQUIRE( ... ) INTERNAL_CATCH_CONSTEXPR_ASSERT( "CONSTEXPR_REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ )
+ #define CATCH_CONSTEXPR_REQUIRE_FALSE( ... ) INTERNAL_CATCH_CONSTEXPR_ASSERT( "CONSTEXPR_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
// "BDD-style" convenience wrappers
#define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
@@ -109,6 +113,7 @@
#define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0)
#define CATCH_SECTION( ... )
#define CATCH_DYNAMIC_SECTION( ... )
+ #define CATCH_CONSTEXPR_SECTION( ... )
#define CATCH_FAIL( ... ) (void)(0)
#define CATCH_FAIL_CHECK( ... ) (void)(0)
#define CATCH_SUCCEED( ... ) (void)(0)
@@ -119,6 +124,9 @@
#define CATCH_STATIC_CHECK( ... ) (void)(0)
#define CATCH_STATIC_CHECK_FALSE( ... ) (void)(0)
+ #define CATCH_CONSTEXPR_REQUIRE( ... ) (void)(0)
+ #define CATCH_CONSTEXPR_REQUIRE_FALSE( ... ) (void)(0)
+
// "BDD-style" convenience wrappers
#define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEST_ ))
#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEST_ ), className )
@@ -155,6 +163,8 @@
#define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
#define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
#define DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )
+ #define CONSTEXPR_SECTION( ... ) INTERNAL_CATCH_CONSTEXPR_SECTION( __VA_ARGS__ )
+ #define SILENT_CONSTEXPR_SECTION( ... ) INTERNAL_CATCH_SILENT_CONSTEXPR_SECTION( __VA_ARGS__ )
#define FAIL( ... ) do { \
INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ ); \
Catch::Detail::Unreachable(); \
@@ -179,6 +189,9 @@
#define STATIC_CHECK_FALSE( ... ) CHECK_FALSE( __VA_ARGS__ )
#endif
+ #define CONSTEXPR_REQUIRE( ... ) INTERNAL_CATCH_CONSTEXPR_ASSERT( "CONSTEXPR_REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ )
+ #define CONSTEXPR_REQUIRE_FALSE( ... ) INTERNAL_CATCH_CONSTEXPR_ASSERT( "CONSTEXPR_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )
+
// "BDD-style" convenience wrappers
#define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
@@ -215,6 +228,7 @@
#define REGISTER_TEST_CASE( Function, ... ) (void)(0)
#define SECTION( ... )
#define DYNAMIC_SECTION( ... )
+ #define CONSTEXPR_SECTION( ... )
#define FAIL( ... ) (void)(0)
#define FAIL_CHECK( ... ) (void)(0)
#define SUCCEED( ... ) (void)(0)
@@ -224,6 +238,8 @@
#define STATIC_REQUIRE_FALSE( ... ) (void)(0)
#define STATIC_CHECK( ... ) (void)(0)
#define STATIC_CHECK_FALSE( ... ) (void)(0)
+ #define CONSTEXPR_REQUIRE( ... ) (void)(0)
+ #define CONSTEXPR_REQUIRE_FALSE( ... ) (void)(0)
// "BDD-style" convenience wrappers
#define SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEST_ ) )
diff --git a/src/catch2/internal/catch_constexpr_asserts.hpp b/src/catch2/internal/catch_constexpr_asserts.hpp
new file mode 100644
index 0000000000..21c12317a8
--- /dev/null
+++ b/src/catch2/internal/catch_constexpr_asserts.hpp
@@ -0,0 +1,43 @@
+
+// Copyright Catch2 Authors
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.txt or copy at
+// https://www.boost.org/LICENSE_1_0.txt)
+
+// SPDX-License-Identifier: BSL-1.0
+#ifndef CATCH_CONSTEXPR_ASSERTS_HPP_INCLUDED
+#define CATCH_CONSTEXPR_ASSERTS_HPP_INCLUDED
+#include
+#include
+
+namespace Catch {
+ template
+ void handleExpression( StringRef macroName,
+ SourceLineInfo const& lineInfo,
+ StringRef capturedExpression,
+ ResultDisposition::Flags resultDisposition,
+ ExpressionType decomposedExpression ) {
+ AssertionHandler catchAssertionHandler(
+ macroName, lineInfo, capturedExpression, resultDisposition );
+ catchAssertionHandler.handleExpr( decomposedExpression );
+ catchAssertionHandler.complete();
+ }
+} // namespace Catch
+
+#define INTERNAL_CATCH_CONSTEXPR_ASSERT( macroName, resultDisposition, ... ) \
+ do { \
+ CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
+ CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
+ const auto expr__InternalCatch__ = Catch::Decomposer() <= __VA_ARGS__; \
+ CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
+ if ( expr__InternalCatch__.getResult() != \
+ Catch::isFalseTest( resultDisposition ) ) { \
+ } else \
+ Catch::handleExpression( macroName##_catch_sr, \
+ CATCH_INTERNAL_LINEINFO, \
+ CATCH_INTERNAL_STRINGIFY( __VA_ARGS__ ), \
+ resultDisposition, \
+ expr__InternalCatch__ ); \
+ } while ( false )
+
+#endif // CATCH_CONSTEXPR_ASSERTS_HPP_INCLUDED
diff --git a/src/catch2/internal/catch_constexpr_section.cpp b/src/catch2/internal/catch_constexpr_section.cpp
new file mode 100644
index 0000000000..2e5c46c4fb
--- /dev/null
+++ b/src/catch2/internal/catch_constexpr_section.cpp
@@ -0,0 +1,23 @@
+
+// Copyright Catch2 Authors
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.txt or copy at
+// https://www.boost.org/LICENSE_1_0.txt)
+
+// SPDX-License-Identifier: BSL-1.0
+
+#include
+#include
+
+namespace Catch {
+ void ConstexprSection::addFakeAssertion() {
+ AssertionHandler catchAssertionHandler(
+ "CONSTEXPR_SECTION",
+ SourceLineInfo( "unknown-file", 0 ),
+ "[Passed during compilation]",
+ ResultDisposition::Normal );
+ catchAssertionHandler.handleMessage( ResultWas::Ok,
+ "[Passed during compilation]" );
+ catchAssertionHandler.complete();
+ }
+} // namespace Catch
\ No newline at end of file
diff --git a/src/catch2/internal/catch_constexpr_section.hpp b/src/catch2/internal/catch_constexpr_section.hpp
new file mode 100644
index 0000000000..9205591324
--- /dev/null
+++ b/src/catch2/internal/catch_constexpr_section.hpp
@@ -0,0 +1,49 @@
+
+// Copyright Catch2 Authors
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.txt or copy at
+// https://www.boost.org/LICENSE_1_0.txt)
+
+// SPDX-License-Identifier: BSL-1.0
+#ifndef CATCH_CONSTEXPR_SECTION_HPP_INCLUDED
+#define CATCH_CONSTEXPR_SECTION_HPP_INCLUDED
+
+#if defined( CATCH_CPP17_OR_GREATER ) && __cpp_constexpr >= 201603
+# define CATCH_CONFIG_CONSTEXPR_SECTIONS
+#endif
+
+#include
+#include
+#include
+
+namespace Catch {
+
+ struct ConstexprSection {
+ template
+ ConstexprSection( Callable callable ) {
+ static_assert( ( callable(), true ), "CONSTEXPR_SECTION failure" );
+ addFakeAssertion();
+ callable();
+ }
+
+ // Add a fake assertion to the section to avoid failures because the
+ // section is empty
+ static void addFakeAssertion();
+ };
+} // namespace Catch
+
+#ifdef CATCH_CONFIG_CONSTEXPR_SECTIONS
+
+# define INTERNAL_CATCH_CONSTEXPR_SECTION( ... ) \
+ INTERNAL_CATCH_SECTION( "[Passed during compilation] " __VA_ARGS__ ) \
+ [[maybe_unused]] const ::Catch::ConstexprSection \
+ INTERNAL_CATCH_UNIQUE_NAME( \
+ catch_internal_CompileTimeSection ) = [&]()
+
+#else
+# define INTERNAL_CATCH_CONSTEXPR_SECTION( ... ) \
+ static_assert( false, "C++17 is required for CONSTEXPR_SECTION" ); \
+ if ( false )
+#endif
+
+#endif // CATCH_CONSTEXPR_SECTION_HPP_INCLUDED
diff --git a/src/catch2/internal/catch_decomposer.hpp b/src/catch2/internal/catch_decomposer.hpp
index fcc017dda9..1feba6cc80 100644
--- a/src/catch2/internal/catch_decomposer.hpp
+++ b/src/catch2/internal/catch_decomposer.hpp
@@ -436,6 +436,10 @@ namespace Catch {
constexpr auto makeUnaryExpr() const -> UnaryExpr {
return UnaryExpr{ m_lhs };
}
+
+ constexpr auto getResult() const -> bool {
+ return makeUnaryExpr().getResult();
+ }
};
struct Decomposer {
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 8f8a3755ae..cfc748ef20 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -105,6 +105,7 @@ set(TEST_SOURCES
${SELF_TEST_DIR}/UsageTests/Benchmark.tests.cpp
${SELF_TEST_DIR}/UsageTests/Class.tests.cpp
${SELF_TEST_DIR}/UsageTests/Compilation.tests.cpp
+ ${SELF_TEST_DIR}/UsageTests/CompileTimeTests.tests.cpp
${SELF_TEST_DIR}/UsageTests/Condition.tests.cpp
${SELF_TEST_DIR}/UsageTests/Decomposition.tests.cpp
${SELF_TEST_DIR}/UsageTests/EnumToString.tests.cpp
diff --git a/tests/SelfTest/Baselines/automake.sw.approved.txt b/tests/SelfTest/Baselines/automake.sw.approved.txt
index 4a6886d6c2..7e4a9ccce2 100644
--- a/tests/SelfTest/Baselines/automake.sw.approved.txt
+++ b/tests/SelfTest/Baselines/automake.sw.approved.txt
@@ -104,6 +104,9 @@ Nor would this
:test-result: PASS CAPTURE can deal with complex expressions
:test-result: PASS CAPTURE can deal with complex expressions involving commas
:test-result: PASS CAPTURE parses string and character constants
+:test-result: XFAIL CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only once at runtime in case of failure
+:test-result: PASS CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only once at runtime in case of success
+:test-result: PASS CONSTEXPR_SECTION, CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE behavior during compilation
:test-result: PASS Capture and info messages
:test-result: FAIL Captures do not leave block with an exception
:test-result: FAIL Captures outlive section end
@@ -241,6 +244,7 @@ A string sent directly to stdout
A string sent directly to stderr
A string sent to stderr via clog
:test-result: FAIL Sends stuff to stdout and stderr
+:test-result: PASS Simple compile time section
:test-result: PASS Some simple comparisons between doubles
Message from section one
Message from section two
diff --git a/tests/SelfTest/Baselines/automake.sw.multi.approved.txt b/tests/SelfTest/Baselines/automake.sw.multi.approved.txt
index b0d30b87d9..6b31be73fd 100644
--- a/tests/SelfTest/Baselines/automake.sw.multi.approved.txt
+++ b/tests/SelfTest/Baselines/automake.sw.multi.approved.txt
@@ -102,6 +102,9 @@
:test-result: PASS CAPTURE can deal with complex expressions
:test-result: PASS CAPTURE can deal with complex expressions involving commas
:test-result: PASS CAPTURE parses string and character constants
+:test-result: XFAIL CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only once at runtime in case of failure
+:test-result: PASS CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only once at runtime in case of success
+:test-result: PASS CONSTEXPR_SECTION, CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE behavior during compilation
:test-result: PASS Capture and info messages
:test-result: FAIL Captures do not leave block with an exception
:test-result: FAIL Captures outlive section end
@@ -236,6 +239,7 @@
:test-result: FAIL Scoped messages do not leave block with an exception
:test-result: FAIL Scoped messages outlive section end
:test-result: FAIL Sends stuff to stdout and stderr
+:test-result: PASS Simple compile time section
:test-result: PASS Some simple comparisons between doubles
:test-result: FAIL Standard output from all sections is reported
:test-result: FAIL StartsWith string matcher
diff --git a/tests/SelfTest/Baselines/compact.sw.approved.txt b/tests/SelfTest/Baselines/compact.sw.approved.txt
index cacb898afb..7922121661 100644
--- a/tests/SelfTest/Baselines/compact.sw.approved.txt
+++ b/tests/SelfTest/Baselines/compact.sw.approved.txt
@@ -368,6 +368,18 @@ MatchersRanges.tests.cpp:: passed: unrelated::ADL_empty{}, IsEmpty(
Message.tests.cpp:: passed: with 7 messages: 'a := 1' and 'b := 2' and 'c := 3' and 'a + b := 3' and 'a+b := 3' and 'c > b := true' and 'a == 1 := true'
Message.tests.cpp:: passed: with 7 messages: 'custom_index_op{1, 2, 3}[0, 1, 2] := 0' and 'custom_index_op{1, 2, 3}[(0, 1)] := 0' and 'custom_index_op{1, 2, 3}[0] := 0' and '(helper_1436{12, -12}) := { 12, -12 }' and '(helper_1436(-12, 12)) := { -12, 12 }' and '(1, 2) := 2' and '(2, 3) := 3'
Message.tests.cpp:: passed: with 11 messages: '("comma, in string", "escaped, \", ") := "escaped, ", "' and '"single quote in string,'," := "single quote in string,',"' and '"some escapes, \\,\\\\" := "some escapes, \,\\"' and '"some, ), unmatched, } prenheses {[<" := "some, ), unmatched, } prenheses {[<"' and ''"' := '"'' and ''\'' := '''' and '',' := ','' and ''}' := '}'' and '')' := ')'' and ''(' := '('' and ''{' := '{''
+CompileTimeTests.tests.cpp:: passed: numberOfCalls < 2 for: 1 < 2
+CompileTimeTests.tests.cpp:: failed: ( lambda() != 50 ) for: false
+CompileTimeTests.tests.cpp:: passed: numberOfCalls < 2 for: 1 < 2
+CompileTimeTests.tests.cpp:: failed: lambda() != 50 for: 50 != 50
+CompileTimeTests.tests.cpp:: passed: with 1 message: 'Silent empty section warning'
+CompileTimeTests.tests.cpp:: passed: with 1 message: 'Silent empty section warning (at runtime, CONSTEXPR_REQUIRE does nothing if passed)'
+CompileTimeTests.tests.cpp:: passed: with 1 message: 'Silent empty section warning'
+CompileTimeTests.tests.cpp:: passed: with 1 message: 'Silent empty section warning (at runtime, CONSTEXPR_REQUIRE does nothing if passed)'
+CompileTimeTests.tests.cpp:: passed: with 1 message: 'Silent empty section warning'
+unknown-file:0: passed: [Passed during compilation] with 1 message: '[Passed during compilation]'
+unknown-file:0: passed: [Passed during compilation] with 1 message: '[Passed during compilation]'
+unknown-file:0: passed: [Passed during compilation] with 1 message: '[Passed during compilation]'
ToStringGeneral.tests.cpp:: passed: true with 1 message: 'i := 2'
ToStringGeneral.tests.cpp:: passed: true with 1 message: '3'
Message.tests.cpp:: failed: false with 1 message: 'a := 1'
@@ -1766,6 +1778,7 @@ Message.tests.cpp:: failed: false with 1 message: 'Should survive a
A string sent directly to stdout
A string sent directly to stderr
A string sent to stderr via clog
+unknown-file:0: passed: [Passed during compilation] with 1 message: '[Passed during compilation]'
Approx.tests.cpp:: passed: d == Approx( 1.23 ) for: 1.22999999999999998
==
Approx( 1.22999999999999998 )
@@ -2888,7 +2901,7 @@ InternalBenchmark.tests.cpp:: passed: med == 18. for: 18.0 == 18.0
InternalBenchmark.tests.cpp:: passed: q3 == 23. for: 23.0 == 23.0
Misc.tests.cpp:: passed:
Misc.tests.cpp:: passed:
-test cases: 435 | 317 passed | 95 failed | 6 skipped | 17 failed as expected
-assertions: 2303 | 2105 passed | 157 failed | 41 failed as expected
+test cases: 439 | 320 passed | 95 failed | 6 skipped | 18 failed as expected
+assertions: 2316 | 2116 passed | 157 failed | 43 failed as expected
diff --git a/tests/SelfTest/Baselines/compact.sw.multi.approved.txt b/tests/SelfTest/Baselines/compact.sw.multi.approved.txt
index 10395c9adf..f3821e1dbe 100644
--- a/tests/SelfTest/Baselines/compact.sw.multi.approved.txt
+++ b/tests/SelfTest/Baselines/compact.sw.multi.approved.txt
@@ -366,6 +366,18 @@ MatchersRanges.tests.cpp:: passed: unrelated::ADL_empty{}, IsEmpty(
Message.tests.cpp:: passed: with 7 messages: 'a := 1' and 'b := 2' and 'c := 3' and 'a + b := 3' and 'a+b := 3' and 'c > b := true' and 'a == 1 := true'
Message.tests.cpp:: passed: with 7 messages: 'custom_index_op{1, 2, 3}[0, 1, 2] := 0' and 'custom_index_op{1, 2, 3}[(0, 1)] := 0' and 'custom_index_op{1, 2, 3}[0] := 0' and '(helper_1436{12, -12}) := { 12, -12 }' and '(helper_1436(-12, 12)) := { -12, 12 }' and '(1, 2) := 2' and '(2, 3) := 3'
Message.tests.cpp:: passed: with 11 messages: '("comma, in string", "escaped, \", ") := "escaped, ", "' and '"single quote in string,'," := "single quote in string,',"' and '"some escapes, \\,\\\\" := "some escapes, \,\\"' and '"some, ), unmatched, } prenheses {[<" := "some, ), unmatched, } prenheses {[<"' and ''"' := '"'' and ''\'' := '''' and '',' := ','' and ''}' := '}'' and '')' := ')'' and ''(' := '('' and ''{' := '{''
+CompileTimeTests.tests.cpp:: passed: numberOfCalls < 2 for: 1 < 2
+CompileTimeTests.tests.cpp:: failed: ( lambda() != 50 ) for: false
+CompileTimeTests.tests.cpp:: passed: numberOfCalls < 2 for: 1 < 2
+CompileTimeTests.tests.cpp:: failed: lambda() != 50 for: 50 != 50
+CompileTimeTests.tests.cpp:: passed: with 1 message: 'Silent empty section warning'
+CompileTimeTests.tests.cpp:: passed: with 1 message: 'Silent empty section warning (at runtime, CONSTEXPR_REQUIRE does nothing if passed)'
+CompileTimeTests.tests.cpp:: passed: with 1 message: 'Silent empty section warning'
+CompileTimeTests.tests.cpp:: passed: with 1 message: 'Silent empty section warning (at runtime, CONSTEXPR_REQUIRE does nothing if passed)'
+CompileTimeTests.tests.cpp:: passed: with 1 message: 'Silent empty section warning'
+unknown-file:0: passed: [Passed during compilation] with 1 message: '[Passed during compilation]'
+unknown-file:0: passed: [Passed during compilation] with 1 message: '[Passed during compilation]'
+unknown-file:0: passed: [Passed during compilation] with 1 message: '[Passed during compilation]'
ToStringGeneral.tests.cpp:: passed: true with 1 message: 'i := 2'
ToStringGeneral.tests.cpp:: passed: true with 1 message: '3'
Message.tests.cpp:: failed: false with 1 message: 'a := 1'
@@ -1761,6 +1773,7 @@ Message.tests.cpp:: failed: false with 1 message: 'This will be rep
Message.tests.cpp:: failed: false with 1 message: 'Should be in scope at the end'
Message.tests.cpp:: passed: true with 1 message: 'Should survive a section end'
Message.tests.cpp:: failed: false with 1 message: 'Should survive a section end'
+unknown-file:0: passed: [Passed during compilation] with 1 message: '[Passed during compilation]'
Approx.tests.cpp:: passed: d == Approx( 1.23 ) for: 1.22999999999999998
==
Approx( 1.22999999999999998 )
@@ -2877,7 +2890,7 @@ InternalBenchmark.tests.cpp:: passed: med == 18. for: 18.0 == 18.0
InternalBenchmark.tests.cpp:: passed: q3 == 23. for: 23.0 == 23.0
Misc.tests.cpp:: passed:
Misc.tests.cpp:: passed:
-test cases: 435 | 317 passed | 95 failed | 6 skipped | 17 failed as expected
-assertions: 2303 | 2105 passed | 157 failed | 41 failed as expected
+test cases: 439 | 320 passed | 95 failed | 6 skipped | 18 failed as expected
+assertions: 2316 | 2116 passed | 157 failed | 43 failed as expected
diff --git a/tests/SelfTest/Baselines/console.std.approved.txt b/tests/SelfTest/Baselines/console.std.approved.txt
index c1512db5c9..f9e59e7f42 100644
--- a/tests/SelfTest/Baselines/console.std.approved.txt
+++ b/tests/SelfTest/Baselines/console.std.approved.txt
@@ -379,6 +379,32 @@ AssertionHandler.tests.cpp:: FAILED:
due to unexpected exception with message:
{ nested assertion failed }
+-------------------------------------------------------------------------------
+CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only
+once at runtime in case of failure
+ Unary -> Expression should be evaluated only once
+-------------------------------------------------------------------------------
+CompileTimeTests.tests.cpp:
+...............................................................................
+
+CompileTimeTests.tests.cpp:: FAILED:
+ CONSTEXPR_REQUIRE( ( lambda() != 50 ) )
+with expansion:
+ false
+
+-------------------------------------------------------------------------------
+CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only
+once at runtime in case of failure
+ Binary -> Expression should be evaluated only once
+-------------------------------------------------------------------------------
+CompileTimeTests.tests.cpp:
+...............................................................................
+
+CompileTimeTests.tests.cpp:: FAILED:
+ CONSTEXPR_REQUIRE( lambda() != 50 )
+with expansion:
+ 50 != 50
+
-------------------------------------------------------------------------------
Captures do not leave block with an exception
-------------------------------------------------------------------------------
@@ -1719,6 +1745,6 @@ due to unexpected exception with message:
Why would you throw a std::string?
===============================================================================
-test cases: 435 | 335 passed | 76 failed | 7 skipped | 17 failed as expected
-assertions: 2282 | 2105 passed | 136 failed | 41 failed as expected
+test cases: 439 | 338 passed | 76 failed | 7 skipped | 18 failed as expected
+assertions: 2295 | 2116 passed | 136 failed | 43 failed as expected
diff --git a/tests/SelfTest/Baselines/console.sw.approved.txt b/tests/SelfTest/Baselines/console.sw.approved.txt
index 7fd5951481..d6e6099f26 100644
--- a/tests/SelfTest/Baselines/console.sw.approved.txt
+++ b/tests/SelfTest/Baselines/console.sw.approved.txt
@@ -2893,6 +2893,140 @@ with messages:
'(' := '('
'{' := '{'
+-------------------------------------------------------------------------------
+CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only
+once at runtime in case of failure
+ Unary -> Expression should be evaluated only once
+-------------------------------------------------------------------------------
+CompileTimeTests.tests.cpp:
+...............................................................................
+
+CompileTimeTests.tests.cpp:: PASSED:
+ REQUIRE( numberOfCalls < 2 )
+with expansion:
+ 1 < 2
+
+CompileTimeTests.tests.cpp:: FAILED:
+ CONSTEXPR_REQUIRE( ( lambda() != 50 ) )
+with expansion:
+ false
+
+-------------------------------------------------------------------------------
+CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only
+once at runtime in case of failure
+ Binary -> Expression should be evaluated only once
+-------------------------------------------------------------------------------
+CompileTimeTests.tests.cpp:
+...............................................................................
+
+CompileTimeTests.tests.cpp:: PASSED:
+ REQUIRE( numberOfCalls < 2 )
+with expansion:
+ 1 < 2
+
+CompileTimeTests.tests.cpp:: FAILED:
+ CONSTEXPR_REQUIRE( lambda() != 50 )
+with expansion:
+ 50 != 50
+
+-------------------------------------------------------------------------------
+CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only
+once at runtime in case of failure
+-------------------------------------------------------------------------------
+CompileTimeTests.tests.cpp:
+...............................................................................
+
+CompileTimeTests.tests.cpp:: PASSED:
+with message:
+ Silent empty section warning
+
+-------------------------------------------------------------------------------
+CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only
+once at runtime in case of success
+ Unary -> Expression should be evaluated only once
+-------------------------------------------------------------------------------
+CompileTimeTests.tests.cpp:
+...............................................................................
+
+CompileTimeTests.tests.cpp:: PASSED:
+with message:
+ Silent empty section warning (at runtime, CONSTEXPR_REQUIRE does nothing if
+ passed)
+
+-------------------------------------------------------------------------------
+CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only
+once at runtime in case of success
+-------------------------------------------------------------------------------
+CompileTimeTests.tests.cpp:
+...............................................................................
+
+CompileTimeTests.tests.cpp:: PASSED:
+with message:
+ Silent empty section warning
+
+-------------------------------------------------------------------------------
+CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only
+once at runtime in case of success
+ Binary -> Expression should be evaluated only once
+-------------------------------------------------------------------------------
+CompileTimeTests.tests.cpp:
+...............................................................................
+
+CompileTimeTests.tests.cpp:: PASSED:
+with message:
+ Silent empty section warning (at runtime, CONSTEXPR_REQUIRE does nothing if
+ passed)
+
+-------------------------------------------------------------------------------
+CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only
+once at runtime in case of success
+-------------------------------------------------------------------------------
+CompileTimeTests.tests.cpp:
+...............................................................................
+
+CompileTimeTests.tests.cpp:: PASSED:
+with message:
+ Silent empty section warning
+
+-------------------------------------------------------------------------------
+CONSTEXPR_SECTION, CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE behavior during
+compilation
+ [Passed during compilation] First
+-------------------------------------------------------------------------------
+CompileTimeTests.tests.cpp:
+...............................................................................
+
+unknown-file:0: PASSED:
+ CONSTEXPR_SECTION( [Passed during compilation] )
+with message:
+ [Passed during compilation]
+
+-------------------------------------------------------------------------------
+CONSTEXPR_SECTION, CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE behavior during
+compilation
+ [Passed during compilation] Second
+-------------------------------------------------------------------------------
+CompileTimeTests.tests.cpp:
+...............................................................................
+
+unknown-file:0: PASSED:
+ CONSTEXPR_SECTION( [Passed during compilation] )
+with message:
+ [Passed during compilation]
+
+-------------------------------------------------------------------------------
+CONSTEXPR_SECTION, CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE behavior during
+compilation
+ [Passed during compilation] Third
+-------------------------------------------------------------------------------
+CompileTimeTests.tests.cpp:
+...............................................................................
+
+unknown-file:0: PASSED:
+ CONSTEXPR_SECTION( [Passed during compilation] )
+with message:
+ [Passed during compilation]
+
-------------------------------------------------------------------------------
Capture and info messages
Capture should stringify like assertions
@@ -11269,6 +11403,18 @@ Misc.tests.cpp:
No assertions in test case 'Sends stuff to stdout and stderr'
+-------------------------------------------------------------------------------
+Simple compile time section
+ [Passed during compilation] Simple compile time section
+-------------------------------------------------------------------------------
+CompileTimeTests.tests.cpp:
+...............................................................................
+
+unknown-file:0: PASSED:
+ CONSTEXPR_SECTION( [Passed during compilation] )
+with message:
+ [Passed during compilation]
+
-------------------------------------------------------------------------------
Some simple comparisons between doubles
-------------------------------------------------------------------------------
@@ -19295,6 +19441,6 @@ Misc.tests.cpp:
Misc.tests.cpp:: PASSED:
===============================================================================
-test cases: 435 | 317 passed | 95 failed | 6 skipped | 17 failed as expected
-assertions: 2303 | 2105 passed | 157 failed | 41 failed as expected
+test cases: 439 | 320 passed | 95 failed | 6 skipped | 18 failed as expected
+assertions: 2316 | 2116 passed | 157 failed | 43 failed as expected
diff --git a/tests/SelfTest/Baselines/console.sw.multi.approved.txt b/tests/SelfTest/Baselines/console.sw.multi.approved.txt
index 08ab1b2bef..1d506c8825 100644
--- a/tests/SelfTest/Baselines/console.sw.multi.approved.txt
+++ b/tests/SelfTest/Baselines/console.sw.multi.approved.txt
@@ -2891,6 +2891,140 @@ with messages:
'(' := '('
'{' := '{'
+-------------------------------------------------------------------------------
+CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only
+once at runtime in case of failure
+ Unary -> Expression should be evaluated only once
+-------------------------------------------------------------------------------
+CompileTimeTests.tests.cpp:
+...............................................................................
+
+CompileTimeTests.tests.cpp:: PASSED:
+ REQUIRE( numberOfCalls < 2 )
+with expansion:
+ 1 < 2
+
+CompileTimeTests.tests.cpp:: FAILED:
+ CONSTEXPR_REQUIRE( ( lambda() != 50 ) )
+with expansion:
+ false
+
+-------------------------------------------------------------------------------
+CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only
+once at runtime in case of failure
+ Binary -> Expression should be evaluated only once
+-------------------------------------------------------------------------------
+CompileTimeTests.tests.cpp:
+...............................................................................
+
+CompileTimeTests.tests.cpp:: PASSED:
+ REQUIRE( numberOfCalls < 2 )
+with expansion:
+ 1 < 2
+
+CompileTimeTests.tests.cpp:: FAILED:
+ CONSTEXPR_REQUIRE( lambda() != 50 )
+with expansion:
+ 50 != 50
+
+-------------------------------------------------------------------------------
+CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only
+once at runtime in case of failure
+-------------------------------------------------------------------------------
+CompileTimeTests.tests.cpp:
+...............................................................................
+
+CompileTimeTests.tests.cpp:: PASSED:
+with message:
+ Silent empty section warning
+
+-------------------------------------------------------------------------------
+CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only
+once at runtime in case of success
+ Unary -> Expression should be evaluated only once
+-------------------------------------------------------------------------------
+CompileTimeTests.tests.cpp:
+...............................................................................
+
+CompileTimeTests.tests.cpp:: PASSED:
+with message:
+ Silent empty section warning (at runtime, CONSTEXPR_REQUIRE does nothing if
+ passed)
+
+-------------------------------------------------------------------------------
+CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only
+once at runtime in case of success
+-------------------------------------------------------------------------------
+CompileTimeTests.tests.cpp:
+...............................................................................
+
+CompileTimeTests.tests.cpp:: PASSED:
+with message:
+ Silent empty section warning
+
+-------------------------------------------------------------------------------
+CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only
+once at runtime in case of success
+ Binary -> Expression should be evaluated only once
+-------------------------------------------------------------------------------
+CompileTimeTests.tests.cpp:
+...............................................................................
+
+CompileTimeTests.tests.cpp:: PASSED:
+with message:
+ Silent empty section warning (at runtime, CONSTEXPR_REQUIRE does nothing if
+ passed)
+
+-------------------------------------------------------------------------------
+CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only
+once at runtime in case of success
+-------------------------------------------------------------------------------
+CompileTimeTests.tests.cpp:
+...............................................................................
+
+CompileTimeTests.tests.cpp:: PASSED:
+with message:
+ Silent empty section warning
+
+-------------------------------------------------------------------------------
+CONSTEXPR_SECTION, CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE behavior during
+compilation
+ [Passed during compilation] First
+-------------------------------------------------------------------------------
+CompileTimeTests.tests.cpp:
+...............................................................................
+
+unknown-file:0: PASSED:
+ CONSTEXPR_SECTION( [Passed during compilation] )
+with message:
+ [Passed during compilation]
+
+-------------------------------------------------------------------------------
+CONSTEXPR_SECTION, CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE behavior during
+compilation
+ [Passed during compilation] Second
+-------------------------------------------------------------------------------
+CompileTimeTests.tests.cpp:
+...............................................................................
+
+unknown-file:0: PASSED:
+ CONSTEXPR_SECTION( [Passed during compilation] )
+with message:
+ [Passed during compilation]
+
+-------------------------------------------------------------------------------
+CONSTEXPR_SECTION, CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE behavior during
+compilation
+ [Passed during compilation] Third
+-------------------------------------------------------------------------------
+CompileTimeTests.tests.cpp:
+...............................................................................
+
+unknown-file:0: PASSED:
+ CONSTEXPR_SECTION( [Passed during compilation] )
+with message:
+ [Passed during compilation]
+
-------------------------------------------------------------------------------
Capture and info messages
Capture should stringify like assertions
@@ -11264,6 +11398,18 @@ Misc.tests.cpp:
No assertions in test case 'Sends stuff to stdout and stderr'
+-------------------------------------------------------------------------------
+Simple compile time section
+ [Passed during compilation] Simple compile time section
+-------------------------------------------------------------------------------
+CompileTimeTests.tests.cpp:
+...............................................................................
+
+unknown-file:0: PASSED:
+ CONSTEXPR_SECTION( [Passed during compilation] )
+with message:
+ [Passed during compilation]
+
-------------------------------------------------------------------------------
Some simple comparisons between doubles
-------------------------------------------------------------------------------
@@ -19284,6 +19430,6 @@ Misc.tests.cpp:
Misc.tests.cpp:: PASSED:
===============================================================================
-test cases: 435 | 317 passed | 95 failed | 6 skipped | 17 failed as expected
-assertions: 2303 | 2105 passed | 157 failed | 41 failed as expected
+test cases: 439 | 320 passed | 95 failed | 6 skipped | 18 failed as expected
+assertions: 2316 | 2116 passed | 157 failed | 43 failed as expected
diff --git a/tests/SelfTest/Baselines/junit.sw.approved.txt b/tests/SelfTest/Baselines/junit.sw.approved.txt
index c12b61787b..a06296e659 100644
--- a/tests/SelfTest/Baselines/junit.sw.approved.txt
+++ b/tests/SelfTest/Baselines/junit.sw.approved.txt
@@ -1,7 +1,7 @@
-
+
@@ -441,6 +441,34 @@ at AssertionHandler.tests.cpp:
+
+
+
+
+FAILED:
+ CONSTEXPR_REQUIRE( ( lambda() != 50 ) )
+with expansion:
+ false
+at CompileTimeTests.tests.cpp:
+
+
+
+
+
+FAILED:
+ CONSTEXPR_REQUIRE( lambda() != 50 )
+with expansion:
+ 50 != 50
+at CompileTimeTests.tests.cpp:
+
+
+
+
+
+
+
+
+
@@ -1456,6 +1484,8 @@ A string sent directly to stderr
A string sent to stderr via clog
+
+
diff --git a/tests/SelfTest/Baselines/junit.sw.multi.approved.txt b/tests/SelfTest/Baselines/junit.sw.multi.approved.txt
index e844ca6cb0..f339599554 100644
--- a/tests/SelfTest/Baselines/junit.sw.multi.approved.txt
+++ b/tests/SelfTest/Baselines/junit.sw.multi.approved.txt
@@ -1,6 +1,6 @@
-
+
@@ -440,6 +440,34 @@ at AssertionHandler.tests.cpp:
+
+
+
+
+FAILED:
+ CONSTEXPR_REQUIRE( ( lambda() != 50 ) )
+with expansion:
+ false
+at CompileTimeTests.tests.cpp:
+
+
+
+
+
+FAILED:
+ CONSTEXPR_REQUIRE( lambda() != 50 )
+with expansion:
+ 50 != 50
+at CompileTimeTests.tests.cpp:
+
+
+
+
+
+
+
+
+
@@ -1455,6 +1483,8 @@ A string sent directly to stderr
A string sent to stderr via clog
+
+
diff --git a/tests/SelfTest/Baselines/sonarqube.sw.approved.txt b/tests/SelfTest/Baselines/sonarqube.sw.approved.txt
index d79abd3748..2f64b4ec85 100644
--- a/tests/SelfTest/Baselines/sonarqube.sw.approved.txt
+++ b/tests/SelfTest/Baselines/sonarqube.sw.approved.txt
@@ -665,6 +665,36 @@ at Class.tests.cpp:
+
+
+
+
+FAILED:
+ CONSTEXPR_REQUIRE( ( lambda() != 50 ) )
+with expansion:
+ false
+at CompileTimeTests.tests.cpp:
+
+
+
+
+FAILED:
+ CONSTEXPR_REQUIRE( lambda() != 50 )
+with expansion:
+ 50 != 50
+at CompileTimeTests.tests.cpp:
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/SelfTest/Baselines/sonarqube.sw.multi.approved.txt b/tests/SelfTest/Baselines/sonarqube.sw.multi.approved.txt
index 98a06c1491..63351d6c54 100644
--- a/tests/SelfTest/Baselines/sonarqube.sw.multi.approved.txt
+++ b/tests/SelfTest/Baselines/sonarqube.sw.multi.approved.txt
@@ -664,6 +664,36 @@ at Class.tests.cpp:
+
+
+
+
+FAILED:
+ CONSTEXPR_REQUIRE( ( lambda() != 50 ) )
+with expansion:
+ false
+at CompileTimeTests.tests.cpp:
+
+
+
+
+FAILED:
+ CONSTEXPR_REQUIRE( lambda() != 50 )
+with expansion:
+ 50 != 50
+at CompileTimeTests.tests.cpp:
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/SelfTest/Baselines/tap.sw.approved.txt b/tests/SelfTest/Baselines/tap.sw.approved.txt
index 3e5d18321a..6f85b6508a 100644
--- a/tests/SelfTest/Baselines/tap.sw.approved.txt
+++ b/tests/SelfTest/Baselines/tap.sw.approved.txt
@@ -684,6 +684,30 @@ ok {test-number} - with 7 messages: 'a := 1' and 'b := 2' and 'c := 3' and 'a +
ok {test-number} - with 7 messages: 'custom_index_op{1, 2, 3}[0, 1, 2] := 0' and 'custom_index_op{1, 2, 3}[(0, 1)] := 0' and 'custom_index_op{1, 2, 3}[0] := 0' and '(helper_1436{12, -12}) := { 12, -12 }' and '(helper_1436(-12, 12)) := { -12, 12 }' and '(1, 2) := 2' and '(2, 3) := 3'
# CAPTURE parses string and character constants
ok {test-number} - with 11 messages: '("comma, in string", "escaped, \", ") := "escaped, ", "' and '"single quote in string,'," := "single quote in string,',"' and '"some escapes, \\,\\\\" := "some escapes, \,\\"' and '"some, ), unmatched, } prenheses {[<" := "some, ), unmatched, } prenheses {[<"' and ''"' := '"'' and ''\'' := '''' and '',' := ','' and ''}' := '}'' and '')' := ')'' and ''(' := '('' and ''{' := '{''
+# CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only once at runtime in case of failure
+ok {test-number} - numberOfCalls < 2 for: 1 < 2
+# CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only once at runtime in case of failure
+not ok {test-number} - ( lambda() != 50 ) for: false
+# CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only once at runtime in case of failure
+ok {test-number} - numberOfCalls < 2 for: 1 < 2
+# CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only once at runtime in case of failure
+not ok {test-number} - lambda() != 50 for: 50 != 50
+# CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only once at runtime in case of failure
+ok {test-number} - with 1 message: 'Silent empty section warning'
+# CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only once at runtime in case of success
+ok {test-number} - with 1 message: 'Silent empty section warning (at runtime, CONSTEXPR_REQUIRE does nothing if passed)'
+# CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only once at runtime in case of success
+ok {test-number} - with 1 message: 'Silent empty section warning'
+# CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only once at runtime in case of success
+ok {test-number} - with 1 message: 'Silent empty section warning (at runtime, CONSTEXPR_REQUIRE does nothing if passed)'
+# CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only once at runtime in case of success
+ok {test-number} - with 1 message: 'Silent empty section warning'
+# CONSTEXPR_SECTION, CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE behavior during compilation
+ok {test-number} - [Passed during compilation] with 1 message: '[Passed during compilation]'
+# CONSTEXPR_SECTION, CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE behavior during compilation
+ok {test-number} - [Passed during compilation] with 1 message: '[Passed during compilation]'
+# CONSTEXPR_SECTION, CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE behavior during compilation
+ok {test-number} - [Passed during compilation] with 1 message: '[Passed during compilation]'
# Capture and info messages
ok {test-number} - true with 1 message: 'i := 2'
# Capture and info messages
@@ -2677,6 +2701,8 @@ not ok {test-number} - false with 1 message: 'Should survive a section end'
A string sent directly to stdout
A string sent directly to stderr
A string sent to stderr via clog
+# Simple compile time section
+ok {test-number} - [Passed during compilation] with 1 message: '[Passed during compilation]'
# Some simple comparisons between doubles
ok {test-number} - d == Approx( 1.23 ) for: 1.22999999999999998 == Approx( 1.22999999999999998 )
# Some simple comparisons between doubles
@@ -4627,5 +4653,5 @@ ok {test-number} - q3 == 23. for: 23.0 == 23.0
ok {test-number} -
# xmlentitycheck
ok {test-number} -
-1..2315
+1..2328
diff --git a/tests/SelfTest/Baselines/tap.sw.multi.approved.txt b/tests/SelfTest/Baselines/tap.sw.multi.approved.txt
index 0fdb266a2a..e0cf579c7d 100644
--- a/tests/SelfTest/Baselines/tap.sw.multi.approved.txt
+++ b/tests/SelfTest/Baselines/tap.sw.multi.approved.txt
@@ -682,6 +682,30 @@ ok {test-number} - with 7 messages: 'a := 1' and 'b := 2' and 'c := 3' and 'a +
ok {test-number} - with 7 messages: 'custom_index_op{1, 2, 3}[0, 1, 2] := 0' and 'custom_index_op{1, 2, 3}[(0, 1)] := 0' and 'custom_index_op{1, 2, 3}[0] := 0' and '(helper_1436{12, -12}) := { 12, -12 }' and '(helper_1436(-12, 12)) := { -12, 12 }' and '(1, 2) := 2' and '(2, 3) := 3'
# CAPTURE parses string and character constants
ok {test-number} - with 11 messages: '("comma, in string", "escaped, \", ") := "escaped, ", "' and '"single quote in string,'," := "single quote in string,',"' and '"some escapes, \\,\\\\" := "some escapes, \,\\"' and '"some, ), unmatched, } prenheses {[<" := "some, ), unmatched, } prenheses {[<"' and ''"' := '"'' and ''\'' := '''' and '',' := ','' and ''}' := '}'' and '')' := ')'' and ''(' := '('' and ''{' := '{''
+# CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only once at runtime in case of failure
+ok {test-number} - numberOfCalls < 2 for: 1 < 2
+# CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only once at runtime in case of failure
+not ok {test-number} - ( lambda() != 50 ) for: false
+# CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only once at runtime in case of failure
+ok {test-number} - numberOfCalls < 2 for: 1 < 2
+# CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only once at runtime in case of failure
+not ok {test-number} - lambda() != 50 for: 50 != 50
+# CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only once at runtime in case of failure
+ok {test-number} - with 1 message: 'Silent empty section warning'
+# CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only once at runtime in case of success
+ok {test-number} - with 1 message: 'Silent empty section warning (at runtime, CONSTEXPR_REQUIRE does nothing if passed)'
+# CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only once at runtime in case of success
+ok {test-number} - with 1 message: 'Silent empty section warning'
+# CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only once at runtime in case of success
+ok {test-number} - with 1 message: 'Silent empty section warning (at runtime, CONSTEXPR_REQUIRE does nothing if passed)'
+# CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only once at runtime in case of success
+ok {test-number} - with 1 message: 'Silent empty section warning'
+# CONSTEXPR_SECTION, CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE behavior during compilation
+ok {test-number} - [Passed during compilation] with 1 message: '[Passed during compilation]'
+# CONSTEXPR_SECTION, CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE behavior during compilation
+ok {test-number} - [Passed during compilation] with 1 message: '[Passed during compilation]'
+# CONSTEXPR_SECTION, CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE behavior during compilation
+ok {test-number} - [Passed during compilation] with 1 message: '[Passed during compilation]'
# Capture and info messages
ok {test-number} - true with 1 message: 'i := 2'
# Capture and info messages
@@ -2672,6 +2696,8 @@ not ok {test-number} - false with 1 message: 'Should be in scope at the end'
ok {test-number} - true with 1 message: 'Should survive a section end'
# Scoped messages outlive section end
not ok {test-number} - false with 1 message: 'Should survive a section end'
+# Simple compile time section
+ok {test-number} - [Passed during compilation] with 1 message: '[Passed during compilation]'
# Some simple comparisons between doubles
ok {test-number} - d == Approx( 1.23 ) for: 1.22999999999999998 == Approx( 1.22999999999999998 )
# Some simple comparisons between doubles
@@ -4616,5 +4642,5 @@ ok {test-number} - q3 == 23. for: 23.0 == 23.0
ok {test-number} -
# xmlentitycheck
ok {test-number} -
-1..2315
+1..2328
diff --git a/tests/SelfTest/Baselines/teamcity.sw.approved.txt b/tests/SelfTest/Baselines/teamcity.sw.approved.txt
index 853f3d8048..d9e467f79e 100644
--- a/tests/SelfTest/Baselines/teamcity.sw.approved.txt
+++ b/tests/SelfTest/Baselines/teamcity.sw.approved.txt
@@ -247,6 +247,14 @@
##teamcity[testFinished name='CAPTURE can deal with complex expressions involving commas' duration="{duration}"]
##teamcity[testStarted name='CAPTURE parses string and character constants']
##teamcity[testFinished name='CAPTURE parses string and character constants' duration="{duration}"]
+##teamcity[testStarted name='CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only once at runtime in case of failure']
+##teamcity[testIgnored name='CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only once at runtime in case of failure' message='-------------------------------------------------------------------------------|nUnary -> Expression should be evaluated only once|n-------------------------------------------------------------------------------|nCompileTimeTests.tests.cpp:|n...............................................................................|n|nCompileTimeTests.tests.cpp:|nexpression failed|n CONSTEXPR_REQUIRE( ( lambda() != 50 ) )|nwith expansion:|n false|n- failure ignore as test marked as |'ok to fail|'|n']
+##teamcity[testIgnored name='CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only once at runtime in case of failure' message='-------------------------------------------------------------------------------|nBinary -> Expression should be evaluated only once|n-------------------------------------------------------------------------------|nCompileTimeTests.tests.cpp:|n...............................................................................|n|nCompileTimeTests.tests.cpp:|nexpression failed|n CONSTEXPR_REQUIRE( lambda() != 50 )|nwith expansion:|n 50 != 50|n- failure ignore as test marked as |'ok to fail|'|n']
+##teamcity[testFinished name='CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only once at runtime in case of failure' duration="{duration}"]
+##teamcity[testStarted name='CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only once at runtime in case of success']
+##teamcity[testFinished name='CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only once at runtime in case of success' duration="{duration}"]
+##teamcity[testStarted name='CONSTEXPR_SECTION, CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE behavior during compilation']
+##teamcity[testFinished name='CONSTEXPR_SECTION, CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE behavior during compilation' duration="{duration}"]
##teamcity[testStarted name='Capture and info messages']
##teamcity[testFinished name='Capture and info messages' duration="{duration}"]
##teamcity[testStarted name='Captures do not leave block with an exception']
@@ -604,6 +612,8 @@
##teamcity[testStdOut name='Sends stuff to stdout and stderr' out='A string sent directly to stdout|n']
##teamcity[testStdErr name='Sends stuff to stdout and stderr' out='A string sent directly to stderr|nA string sent to stderr via clog|n']
##teamcity[testFinished name='Sends stuff to stdout and stderr' duration="{duration}"]
+##teamcity[testStarted name='Simple compile time section']
+##teamcity[testFinished name='Simple compile time section' duration="{duration}"]
##teamcity[testStarted name='Some simple comparisons between doubles']
##teamcity[testFinished name='Some simple comparisons between doubles' duration="{duration}"]
##teamcity[testStarted name='Standard output from all sections is reported']
diff --git a/tests/SelfTest/Baselines/teamcity.sw.multi.approved.txt b/tests/SelfTest/Baselines/teamcity.sw.multi.approved.txt
index 10e318de5c..7b56090bb8 100644
--- a/tests/SelfTest/Baselines/teamcity.sw.multi.approved.txt
+++ b/tests/SelfTest/Baselines/teamcity.sw.multi.approved.txt
@@ -247,6 +247,14 @@
##teamcity[testFinished name='CAPTURE can deal with complex expressions involving commas' duration="{duration}"]
##teamcity[testStarted name='CAPTURE parses string and character constants']
##teamcity[testFinished name='CAPTURE parses string and character constants' duration="{duration}"]
+##teamcity[testStarted name='CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only once at runtime in case of failure']
+##teamcity[testIgnored name='CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only once at runtime in case of failure' message='-------------------------------------------------------------------------------|nUnary -> Expression should be evaluated only once|n-------------------------------------------------------------------------------|nCompileTimeTests.tests.cpp:|n...............................................................................|n|nCompileTimeTests.tests.cpp:|nexpression failed|n CONSTEXPR_REQUIRE( ( lambda() != 50 ) )|nwith expansion:|n false|n- failure ignore as test marked as |'ok to fail|'|n']
+##teamcity[testIgnored name='CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only once at runtime in case of failure' message='-------------------------------------------------------------------------------|nBinary -> Expression should be evaluated only once|n-------------------------------------------------------------------------------|nCompileTimeTests.tests.cpp:|n...............................................................................|n|nCompileTimeTests.tests.cpp:|nexpression failed|n CONSTEXPR_REQUIRE( lambda() != 50 )|nwith expansion:|n 50 != 50|n- failure ignore as test marked as |'ok to fail|'|n']
+##teamcity[testFinished name='CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only once at runtime in case of failure' duration="{duration}"]
+##teamcity[testStarted name='CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only once at runtime in case of success']
+##teamcity[testFinished name='CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate the expression only once at runtime in case of success' duration="{duration}"]
+##teamcity[testStarted name='CONSTEXPR_SECTION, CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE behavior during compilation']
+##teamcity[testFinished name='CONSTEXPR_SECTION, CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE behavior during compilation' duration="{duration}"]
##teamcity[testStarted name='Capture and info messages']
##teamcity[testFinished name='Capture and info messages' duration="{duration}"]
##teamcity[testStarted name='Captures do not leave block with an exception']
@@ -604,6 +612,8 @@
##teamcity[testStdOut name='Sends stuff to stdout and stderr' out='A string sent directly to stdout|n']
##teamcity[testStdErr name='Sends stuff to stdout and stderr' out='A string sent directly to stderr|nA string sent to stderr via clog|n']
##teamcity[testFinished name='Sends stuff to stdout and stderr' duration="{duration}"]
+##teamcity[testStarted name='Simple compile time section']
+##teamcity[testFinished name='Simple compile time section' duration="{duration}"]
##teamcity[testStarted name='Some simple comparisons between doubles']
##teamcity[testFinished name='Some simple comparisons between doubles' duration="{duration}"]
##teamcity[testStarted name='Standard output from all sections is reported']
diff --git a/tests/SelfTest/Baselines/xml.sw.approved.txt b/tests/SelfTest/Baselines/xml.sw.approved.txt
index 142d662016..35f04954fa 100644
--- a/tests/SelfTest/Baselines/xml.sw.approved.txt
+++ b/tests/SelfTest/Baselines/xml.sw.approved.txt
@@ -3127,6 +3127,92 @@ Approx( 1.23399996757507324 )
+
+
+
+
+ numberOfCalls < 2
+
+
+ 1 < 2
+
+
+
+
+ ( lambda() != 50 )
+
+
+ false
+
+
+
+
+
+
+
+ numberOfCalls < 2
+
+
+ 1 < 2
+
+
+
+
+ lambda() != 50
+
+
+ 50 != 50
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ [Passed during compilation]
+
+
+ [Passed during compilation]
+
+
+
+
+
+
+
+ [Passed during compilation]
+
+
+ [Passed during compilation]
+
+
+
+
+
+
+
+ [Passed during compilation]
+
+
+ [Passed during compilation]
+
+
+
+
+
+
@@ -13208,6 +13294,20 @@ A string sent to stderr via clog
+
+
+
+
+ [Passed during compilation]
+
+
+ [Passed during compilation]
+
+
+
+
+
+
@@ -22324,6 +22424,6 @@ Approx( -1.95996398454005449 )
-
-
+
+
diff --git a/tests/SelfTest/Baselines/xml.sw.multi.approved.txt b/tests/SelfTest/Baselines/xml.sw.multi.approved.txt
index 62562332c9..e51acfcb5a 100644
--- a/tests/SelfTest/Baselines/xml.sw.multi.approved.txt
+++ b/tests/SelfTest/Baselines/xml.sw.multi.approved.txt
@@ -3127,6 +3127,92 @@ Approx( 1.23399996757507324 )
+
+
+
+
+ numberOfCalls < 2
+
+
+ 1 < 2
+
+
+
+
+ ( lambda() != 50 )
+
+
+ false
+
+
+
+
+
+
+
+ numberOfCalls < 2
+
+
+ 1 < 2
+
+
+
+
+ lambda() != 50
+
+
+ 50 != 50
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ [Passed during compilation]
+
+
+ [Passed during compilation]
+
+
+
+
+
+
+
+ [Passed during compilation]
+
+
+ [Passed during compilation]
+
+
+
+
+
+
+
+ [Passed during compilation]
+
+
+ [Passed during compilation]
+
+
+
+
+
+
@@ -13208,6 +13294,20 @@ A string sent to stderr via clog
+
+
+
+
+ [Passed during compilation]
+
+
+ [Passed during compilation]
+
+
+
+
+
+
@@ -22323,6 +22423,6 @@ Approx( -1.95996398454005449 )
-
-
+
+
diff --git a/tests/SelfTest/UsageTests/CompileTimeTests.tests.cpp b/tests/SelfTest/UsageTests/CompileTimeTests.tests.cpp
new file mode 100644
index 0000000000..dd06806116
--- /dev/null
+++ b/tests/SelfTest/UsageTests/CompileTimeTests.tests.cpp
@@ -0,0 +1,126 @@
+
+// Copyright Catch2 Authors
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.txt or copy at
+// https://www.boost.org/LICENSE_1_0.txt)
+
+// SPDX-License-Identifier: BSL-1.0
+
+#include
+#include
+
+// In C++14, CONSTEXPR_SECTIONS are not supported.
+// For consistency between test results across C++ standard versions, we
+// redefine here CONSTEXPR_SECTION as a SECTION with a mock assertion.
+#ifndef CATCH_CONFIG_CONSTEXPR_SECTIONS
+
+# if defined( __GNUC__ ) && !defined( __clang__ ) && !defined( __ICC ) && \
+ !defined( __CUDACC__ ) && !defined( __LCC__ ) && \
+ !defined( __NVCOMPILER ) && __GNUC__ <= 9
+# define SUPPRESS_MISLEADING_INDENTATION_WARNINGS \
+ _Pragma( "GCC diagnostic ignored \"-Wmisleading-indentation\"" )
+# else
+# define SUPPRESS_MISLEADING_INDENTATION_WARNINGS
+# endif
+
+# undef CONSTEXPR_SECTION
+# define CONSTEXPR_SECTION( ... ) \
+ CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
+ SUPPRESS_MISLEADING_INDENTATION_WARNINGS \
+ SECTION( "[Passed during compilation] " __VA_ARGS__ ) { \
+ Catch::ConstexprSection::addFakeAssertion(); \
+ } \
+ CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
+#endif
+
+TEST_CASE( "Simple compile time section" ) {
+ CONSTEXPR_SECTION( "Simple compile time section" ) {
+ int x = 5;
+ x *= 10;
+ CONSTEXPR_REQUIRE( x == 50 );
+ CONSTEXPR_REQUIRE_FALSE( x != 50 );
+ };
+}
+
+TEST_CASE( "CONSTEXPR_SECTION, CONSTEXPR_REQUIRE, "
+ "CONSTEXPR_REQUIRE_FALSE behavior during compilation" ) {
+ CONSTEXPR_SECTION( "First" ) {
+ int x = 19;
+ CONSTEXPR_REQUIRE( x == 19 );
+ x *= 10;
+ CONSTEXPR_REQUIRE( x == 190 );
+
+ bool b = false;
+ CONSTEXPR_REQUIRE_FALSE( b );
+ b = true;
+ CONSTEXPR_REQUIRE( b );
+ };
+
+ CONSTEXPR_SECTION( "Second", "Having a description should be ok" ) {
+ double x = 1.1;
+ x *= 10;
+ CONSTEXPR_REQUIRE( x > 10.0 );
+ CONSTEXPR_REQUIRE_FALSE( x < -9.0 );
+ };
+
+ CONSTEXPR_SECTION( "Third" ){
+ // Keeping the implementation should be perfectly fine
+ };
+}
+
+TEST_CASE( "CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate "
+ "the expression only once at runtime in case of success" ) {
+ SECTION( "Unary -> Expression should be evaluated only once" ) {
+ int r = 5;
+ auto lambda = [&] {
+ r *= 10;
+ return r;
+ };
+ CONSTEXPR_REQUIRE( ( lambda() == 50 ) );
+ CONSTEXPR_REQUIRE( ( lambda() == 500 ) );
+ const bool result = lambda() == 5000;
+ CONSTEXPR_REQUIRE( result );
+ CONSTEXPR_REQUIRE_FALSE( !result );
+
+ CONSTEXPR_REQUIRE( true );
+ CONSTEXPR_REQUIRE_FALSE( false );
+ SUCCEED( "Silent empty section warning (at runtime, "
+ "CONSTEXPR_REQUIRE does nothing if passed)" );
+ }
+ SECTION( "Binary -> Expression should be evaluated only once" ) {
+ int r = 5;
+ auto lambda = [&] {
+ r *= 10;
+ return r;
+ };
+ CONSTEXPR_REQUIRE( lambda() == 50 );
+ CONSTEXPR_REQUIRE( lambda() == 500 );
+ SUCCEED( "Silent empty section warning (at runtime, "
+ "CONSTEXPR_REQUIRE does nothing if passed)" );
+ }
+ SUCCEED( "Silent empty section warning" );
+}
+
+TEST_CASE( "CONSTEXPR_REQUIRE, CONSTEXPR_REQUIRE_FALSE should evaluate "
+ "the expression only once at runtime in case of failure",
+ "[!shouldfail]" ) {
+ SECTION( "Unary -> Expression should be evaluated only once" ) {
+ int numberOfCalls = 0;
+ auto lambda = [&] {
+ ++numberOfCalls;
+ REQUIRE( numberOfCalls < 2 ); // lambda() was evaluated
+ return 50;
+ };
+ CONSTEXPR_REQUIRE( ( lambda() != 50 ) );
+ }
+ SECTION( "Binary -> Expression should be evaluated only once" ) {
+ int numberOfCalls = 0;
+ auto lambda = [&] {
+ ++numberOfCalls;
+ REQUIRE( numberOfCalls < 2 ); // lambda() was evaluated twice
+ return 50;
+ };
+ CONSTEXPR_REQUIRE( lambda() != 50 );
+ }
+ SUCCEED( "Silent empty section warning" );
+}