Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
J
json
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
json
Commits
ef826b6f
Commit
ef826b6f
authored
Mar 25, 2021
by
Benjamin A. Beasley
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update doctest from 2.4.4 to 2.4.6 (fixes #2686)
parent
82380187
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
393 additions
and
198 deletions
+393
-198
LICENSE.txt
test/thirdparty/doctest/LICENSE.txt
+2
-3
doctest.h
test/thirdparty/doctest/doctest.h
+391
-195
No files found.
test/thirdparty/doctest/LICENSE.txt
100755 → 100644
View file @
ef826b6f
The MIT License (MIT)
Copyright (c) 2016-202
0
Viktor Kirilov
Copyright (c) 2016-202
1
Viktor Kirilov
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
...
...
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
\ No newline at end of file
SOFTWARE.
test/thirdparty/doctest/doctest.h
View file @
ef826b6f
...
...
@@ -4,7 +4,7 @@
//
// doctest.h - the lightest feature-rich C++ single-header testing framework for unit tests and TDD
//
// Copyright (c) 2016-202
0
Viktor Kirilov
// Copyright (c) 2016-202
1
Viktor Kirilov
//
// Distributed under the MIT Software License
// See accompanying file LICENSE.txt or copy at
...
...
@@ -48,8 +48,8 @@
#define DOCTEST_VERSION_MAJOR 2
#define DOCTEST_VERSION_MINOR 4
#define DOCTEST_VERSION_PATCH
4
#define DOCTEST_VERSION_STR "2.4.
4
"
#define DOCTEST_VERSION_PATCH
6
#define DOCTEST_VERSION_STR "2.4.
6
"
#define DOCTEST_VERSION \
(DOCTEST_VERSION_MAJOR * 10000 + DOCTEST_VERSION_MINOR * 100 + DOCTEST_VERSION_PATCH)
...
...
@@ -354,7 +354,7 @@ DOCTEST_MSVC_SUPPRESS_WARNING(26812) // Prefer 'enum class' over 'enum'
#define DOCTEST_GLOBAL_NO_WARNINGS(var) \
DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wglobal-constructors") \
DOCTEST_CLANG_SUPPRESS_WARNING("-Wunused-variable") \
static int var DOCTEST_UNUSED // NOLINT(fuchsia-statically-constructed-objects,cert-err58-cpp)
static
const
int var DOCTEST_UNUSED // NOLINT(fuchsia-statically-constructed-objects,cert-err58-cpp)
#define DOCTEST_GLOBAL_NO_WARNINGS_END() DOCTEST_CLANG_SUPPRESS_WARNING_POP
#ifndef DOCTEST_BREAK_INTO_DEBUGGER
...
...
@@ -362,16 +362,16 @@ DOCTEST_MSVC_SUPPRESS_WARNING(26812) // Prefer 'enum class' over 'enum'
#ifdef DOCTEST_PLATFORM_LINUX
#if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))
// Break at the location of the failing check if possible
#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("int $3\n" : :)
#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("int $3\n" : :)
// NOLINT (hicpp-no-assembler)
#else
#include <signal.h>
#define DOCTEST_BREAK_INTO_DEBUGGER() raise(SIGTRAP)
#endif
#elif defined(DOCTEST_PLATFORM_MAC)
#if defined(__x86_64) || defined(__x86_64__) || defined(__amd64__) || defined(__i386)
#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("int $3\n" : :)
#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("int $3\n" : :)
// NOLINT (hicpp-no-assembler)
#else
#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("brk #0");
#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("brk #0");
// NOLINT (hicpp-no-assembler)
#endif
#elif DOCTEST_MSVC
#define DOCTEST_BREAK_INTO_DEBUGGER() __debugbreak()
...
...
@@ -656,12 +656,14 @@ DOCTEST_INTERFACE const char* skipPathFromFilename(const char* file);
struct
DOCTEST_INTERFACE
TestCaseData
{
String
m_file
;
// the file in which the test was registered
String
m_file
;
// the file in which the test was registered
(using String - see #350)
unsigned
m_line
;
// the line where the test was registered
const
char
*
m_name
;
// name of the test case
const
char
*
m_test_suite
;
// the test suite in which the test was added
const
char
*
m_description
;
bool
m_skip
;
bool
m_no_breaks
;
bool
m_no_output
;
bool
m_may_fail
;
bool
m_should_fail
;
int
m_expected_failures
;
...
...
@@ -715,12 +717,18 @@ struct DOCTEST_INTERFACE IContextScope
virtual
void
stringify
(
std
::
ostream
*
)
const
=
0
;
};
namespace
detail
{
struct
DOCTEST_INTERFACE
TestCase
;
}
// namespace detail
struct
ContextOptions
//!OCLINT too many fields
{
std
::
ostream
*
cout
;
// stdout stream - std::cout by default
std
::
ostream
*
cerr
;
// stderr stream - std::cerr by default
String
binary_name
;
// the test binary name
const
detail
::
TestCase
*
currentTest
=
nullptr
;
// == parameters from the command line
String
out
;
// output filename
String
order_by
;
// how tests should be ordered
...
...
@@ -773,6 +781,29 @@ namespace detail {
template
<
class
T
>
struct
remove_reference
<
T
&>
{
typedef
T
type
;
};
template
<
class
T
>
struct
remove_reference
<
T
&&>
{
typedef
T
type
;
};
template
<
typename
T
,
typename
U
=
T
&&>
U
declval
(
int
);
template
<
typename
T
>
T
declval
(
long
);
template
<
typename
T
>
auto
declval
()
DOCTEST_NOEXCEPT
->
decltype
(
declval
<
T
>
(
0
))
;
template
<
class
T
>
struct
is_lvalue_reference
{
const
static
bool
value
=
false
;
};
template
<
class
T
>
struct
is_lvalue_reference
<
T
&>
{
const
static
bool
value
=
true
;
};
template
<
class
T
>
inline
T
&&
forward
(
typename
remove_reference
<
T
>::
type
&
t
)
DOCTEST_NOEXCEPT
{
return
static_cast
<
T
&&>
(
t
);
}
template
<
class
T
>
inline
T
&&
forward
(
typename
remove_reference
<
T
>::
type
&&
t
)
DOCTEST_NOEXCEPT
{
static_assert
(
!
is_lvalue_reference
<
T
>::
value
,
"Can not forward an rvalue as an lvalue."
);
return
static_cast
<
T
&&>
(
t
);
}
template
<
class
T
>
struct
remove_const
{
typedef
T
type
;
};
template
<
class
T
>
struct
remove_const
<
const
T
>
{
typedef
T
type
;
};
#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
...
...
@@ -1040,10 +1071,20 @@ namespace detail {
return
toString
(
lhs
)
+
op
+
toString
(
rhs
);
}
#if DOCTEST_CLANG && DOCTEST_CLANG < DOCTEST_COMPILER(3, 6, 0)
DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH
(
"-Wunused-comparison"
)
#endif
// This will check if there is any way it could find a operator like member or friend and uses it.
// If not it doesn't find the operator or if the operator at global scope is defined after
// this template, the template won't be instantiated due to SFINAE. Once the template is not
// instantiated it can look for global operator using normal conversions.
#define SFINAE_OP(ret,op) decltype(doctest::detail::declval<L>() op doctest::detail::declval<R>(),static_cast<ret>(0))
#define DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(op, op_str, op_macro) \
template <typename R> \
DOCTEST_NOINLINE
Result operator op(const DOCTEST_REF_WRAP(R) rhs) {
\
bool res = op_macro(lhs, rhs
); \
DOCTEST_NOINLINE
SFINAE_OP(Result,op) operator op(R&& rhs) {
\
bool res = op_macro(doctest::detail::forward<L>(lhs), doctest::detail::forward<R>(rhs)
); \
if(m_at & assertType::is_false) \
res = !res; \
if(!res || doctest::getContextOptions()->success) \
...
...
@@ -1171,12 +1212,16 @@ namespace detail {
L
lhs
;
assertType
::
Enum
m_at
;
explicit
Expression_lhs
(
L
in
,
assertType
::
Enum
at
)
:
lhs
(
in
)
explicit
Expression_lhs
(
L
&&
in
,
assertType
::
Enum
at
)
:
lhs
(
doctest
::
detail
::
forward
<
L
>
(
in
)
)
,
m_at
(
at
)
{}
DOCTEST_NOINLINE
operator
Result
()
{
bool
res
=
!!
lhs
;
// this is needed only foc MSVC 2015:
// https://ci.appveyor.com/project/onqtam/doctest/builds/38181202
DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH
(
4800
)
// 'int': forcing value to bool
bool
res
=
static_cast
<
bool
>
(
lhs
);
DOCTEST_MSVC_SUPPRESS_WARNING_POP
if
(
m_at
&
assertType
::
is_false
)
//!OCLINT bitwise operator in conditional
res
=
!
res
;
...
...
@@ -1185,6 +1230,10 @@ namespace detail {
return
Result
(
res
);
}
/* This is required for user-defined conversions from Expression_lhs to L */
//operator L() const { return lhs; }
operator
L
()
const
{
return
lhs
;
}
// clang-format off
DOCTEST_DO_BINARY_EXPRESSION_COMPARISON
(
==
,
" == "
,
DOCTEST_CMP_EQ
)
//!OCLINT bitwise operator in conditional
DOCTEST_DO_BINARY_EXPRESSION_COMPARISON
(
!=
,
" != "
,
DOCTEST_CMP_NE
)
//!OCLINT bitwise operator in conditional
...
...
@@ -1225,6 +1274,10 @@ namespace detail {
#endif // DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION
#if DOCTEST_CLANG && DOCTEST_CLANG < DOCTEST_COMPILER(3, 6, 0)
DOCTEST_CLANG_SUPPRESS_WARNING_POP
#endif
struct
DOCTEST_INTERFACE
ExpressionDecomposer
{
assertType
::
Enum
m_at
;
...
...
@@ -1236,8 +1289,8 @@ namespace detail {
// https://github.com/catchorg/Catch2/issues/870
// https://github.com/catchorg/Catch2/issues/565
template
<
typename
L
>
Expression_lhs
<
const
DOCTEST_REF_WRAP
(
L
)
>
operator
<<
(
const
DOCTEST_REF_WRAP
(
L
)
operand
)
{
return
Expression_lhs
<
const
DOCTEST_REF_WRAP
(
L
)
>
(
operand
,
m_at
);
Expression_lhs
<
L
>
operator
<<
(
L
&&
operand
)
{
return
Expression_lhs
<
L
>
(
doctest
::
detail
::
forward
<
L
>
(
operand
)
,
m_at
);
}
};
...
...
@@ -1246,6 +1299,8 @@ namespace detail {
const
char
*
m_test_suite
;
const
char
*
m_description
;
bool
m_skip
;
bool
m_no_breaks
;
bool
m_no_output
;
bool
m_may_fail
;
bool
m_should_fail
;
int
m_expected_failures
;
...
...
@@ -1524,7 +1579,7 @@ namespace detail {
template
<
typename
L
>
class
ContextScope
:
public
ContextScopeBase
{
const
L
&
lambda_
;
const
L
lambda_
;
public
:
explicit
ContextScope
(
const
L
&
lambda
)
:
lambda_
(
lambda
)
{}
...
...
@@ -1585,6 +1640,8 @@ namespace detail {
DOCTEST_DEFINE_DECORATOR
(
test_suite
,
const
char
*
,
""
);
DOCTEST_DEFINE_DECORATOR
(
description
,
const
char
*
,
""
);
DOCTEST_DEFINE_DECORATOR
(
skip
,
bool
,
true
);
DOCTEST_DEFINE_DECORATOR
(
no_breaks
,
bool
,
true
);
DOCTEST_DEFINE_DECORATOR
(
no_output
,
bool
,
true
);
DOCTEST_DEFINE_DECORATOR
(
timeout
,
double
,
0
);
DOCTEST_DEFINE_DECORATOR
(
may_fail
,
bool
,
true
);
DOCTEST_DEFINE_DECORATOR
(
should_fail
,
bool
,
true
);
...
...
@@ -1921,10 +1978,12 @@ int registerReporter(const char* name, int priority, bool isReporter) {
static DOCTEST_NOINLINE doctest::detail::TestSuite& getCurrentTestSuite() { \
DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4640) \
DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wexit-time-destructors") \
static doctest::detail::TestSuite data; \
DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wmissing-field-initializers") \
static doctest::detail::TestSuite data{}; \
static bool inited = false; \
DOCTEST_MSVC_SUPPRESS_WARNING_POP \
DOCTEST_CLANG_SUPPRESS_WARNING_POP \
DOCTEST_GCC_SUPPRESS_WARNING_POP \
if(!inited) { \
data* decorators; \
inited = true; \
...
...
@@ -1979,17 +2038,15 @@ int registerReporter(const char* name, int priority, bool isReporter) {
// for logging
#define DOCTEST_INFO(...) \
DOCTEST_INFO_IMPL(DOCTEST_ANONYMOUS(_DOCTEST_CAPTURE_), DOCTEST_ANONYMOUS(_DOCTEST_CAPTURE_), \
DOCTEST_ANONYMOUS(_DOCTEST_CAPTURE_),
__VA_ARGS__)
__VA_ARGS__)
#define DOCTEST_INFO_IMPL(
lambda_name,
mb_name, s_name, ...) \
DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4626)
\
auto lambda_name = [&](std::ostream* s_name) {
\
#define DOCTEST_INFO_IMPL(mb_name, s_name, ...) \
auto DOCTEST_ANONYMOUS(_DOCTEST_CAPTURE_) = doctest::detail::MakeContextScope(
\
[&](std::ostream* s_name) {
\
doctest::detail::MessageBuilder mb_name(__FILE__, __LINE__, doctest::assertType::is_warn); \
mb_name.m_stream = s_name; \
mb_name * __VA_ARGS__; \
}; \
DOCTEST_MSVC_SUPPRESS_WARNING_POP \
auto DOCTEST_ANONYMOUS(_DOCTEST_CAPTURE_) = doctest::detail::MakeContextScope(lambda_name)
})
#define DOCTEST_CAPTURE(x) DOCTEST_INFO(#x " := ", x)
...
...
@@ -2461,7 +2518,7 @@ int registerReporter(const char* name, int priority, bool isReporter) {
#define DOCTEST_FAST_CHECK_UNARY_FALSE DOCTEST_CHECK_UNARY_FALSE
#define DOCTEST_FAST_REQUIRE_UNARY_FALSE DOCTEST_REQUIRE_UNARY_FALSE
#define DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE
DOCTEST_TEST_CASE_TEMPLATE_INVOKE
#define DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE
(id, ...) DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id,__VA_ARGS__)
// clang-format on
// BDD style macros
...
...
@@ -2481,138 +2538,138 @@ int registerReporter(const char* name, int priority, bool isReporter) {
// == SHORT VERSIONS OF THE MACROS
#if !defined(DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES)
#define TEST_CASE
DOCTEST_TEST_CASE
#define TEST_CASE_CLASS
DOCTEST_TEST_CASE_CLASS
#define TEST_CASE_FIXTURE
DOCTEST_TEST_CASE_FIXTURE
#define TYPE_TO_STRING
DOCTEST_TYPE_TO_STRING
#define TEST_CASE_TEMPLATE
DOCTEST_TEST_CASE_TEMPLATE
#define TEST_CASE_TEMPLATE_DEFINE
DOCTEST_TEST_CASE_TEMPLATE_DEFINE
#define TEST_CASE_TEMPLATE_INVOKE
DOCTEST_TEST_CASE_TEMPLATE_INVOKE
#define TEST_CASE_TEMPLATE_APPLY
DOCTEST_TEST_CASE_TEMPLATE_APPLY
#define SUBCASE
DOCTEST_SUBCASE
#define TEST_SUITE
DOCTEST_TEST_SUITE
#define TEST_SUITE_BEGIN
DOCTEST_TEST_SUITE_BEGIN
#define TEST_CASE
(name) DOCTEST_TEST_CASE(name)
#define TEST_CASE_CLASS
(name) DOCTEST_TEST_CASE_CLASS(name)
#define TEST_CASE_FIXTURE
(x, name) DOCTEST_TEST_CASE_FIXTURE(x, name)
#define TYPE_TO_STRING
(...) DOCTEST_TYPE_TO_STRING(__VA_ARGS__)
#define TEST_CASE_TEMPLATE
(name, T, ...) DOCTEST_TEST_CASE_TEMPLATE(name, T, __VA_ARGS__)
#define TEST_CASE_TEMPLATE_DEFINE
(name, T, id) DOCTEST_TEST_CASE_TEMPLATE_DEFINE(name, T, id)
#define TEST_CASE_TEMPLATE_INVOKE
(id, ...) DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id, __VA_ARGS__)
#define TEST_CASE_TEMPLATE_APPLY
(id, ...) DOCTEST_TEST_CASE_TEMPLATE_APPLY(id, __VA_ARGS__)
#define SUBCASE
(name) DOCTEST_SUBCASE(name)
#define TEST_SUITE
(decorators) DOCTEST_TEST_SUITE(decorators)
#define TEST_SUITE_BEGIN
(name) DOCTEST_TEST_SUITE_BEGIN(name)
#define TEST_SUITE_END DOCTEST_TEST_SUITE_END
#define REGISTER_EXCEPTION_TRANSLATOR
DOCTEST_REGISTER_EXCEPTION_TRANSLATOR
#define REGISTER_REPORTER
DOCTEST_REGISTER_REPORTER
#define REGISTER_LISTENER
DOCTEST_REGISTER_LISTENER
#define INFO
DOCTEST_INFO
#define CAPTURE
DOCTEST_CAPTURE
#define ADD_MESSAGE_AT
DOCTEST_ADD_MESSAGE_AT
#define ADD_FAIL_CHECK_AT
DOCTEST_ADD_FAIL_CHECK_AT
#define ADD_FAIL_AT
DOCTEST_ADD_FAIL_AT
#define MESSAGE
DOCTEST_MESSAGE
#define FAIL_CHECK
DOCTEST_FAIL_CHECK
#define FAIL
DOCTEST_FAIL
#define TO_LVALUE
DOCTEST_TO_LVALUE
#define WARN
DOCTEST_WARN
#define WARN_FALSE
DOCTEST_WARN_FALSE
#define WARN_THROWS
DOCTEST_WARN_THROWS
#define WARN_THROWS_AS
DOCTEST_WARN_THROWS_AS
#define WARN_THROWS_WITH
DOCTEST_WARN_THROWS_WITH
#define WARN_THROWS_WITH_AS
DOCTEST_WARN_THROWS_WITH_AS
#define WARN_NOTHROW
DOCTEST_WARN_NOTHROW
#define CHECK
DOCTEST_CHECK
#define CHECK_FALSE
DOCTEST_CHECK_FALSE
#define CHECK_THROWS
DOCTEST_CHECK_THROWS
#define CHECK_THROWS_AS
DOCTEST_CHECK_THROWS_AS
#define CHECK_THROWS_WITH
DOCTEST_CHECK_THROWS_WITH
#define CHECK_THROWS_WITH_AS
DOCTEST_CHECK_THROWS_WITH_AS
#define CHECK_NOTHROW
DOCTEST_CHECK_NOTHROW
#define REQUIRE
DOCTEST_REQUIRE
#define REQUIRE_FALSE
DOCTEST_REQUIRE_FALSE
#define REQUIRE_THROWS
DOCTEST_REQUIRE_THROWS
#define REQUIRE_THROWS_AS
DOCTEST_REQUIRE_THROWS_AS
#define REQUIRE_THROWS_WITH
DOCTEST_REQUIRE_THROWS_WITH
#define REQUIRE_THROWS_WITH_AS
DOCTEST_REQUIRE_THROWS_WITH_AS
#define REQUIRE_NOTHROW
DOCTEST_REQUIRE_NOTHROW
#define WARN_MESSAGE
DOCTEST_WARN_MESSAGE
#define WARN_FALSE_MESSAGE
DOCTEST_WARN_FALSE_MESSAGE
#define WARN_THROWS_MESSAGE
DOCTEST_WARN_THROWS_MESSAGE
#define WARN_THROWS_AS_MESSAGE
DOCTEST_WARN_THROWS_AS_MESSAGE
#define WARN_THROWS_WITH_MESSAGE
DOCTEST_WARN_THROWS_WITH_MESSAGE
#define WARN_THROWS_WITH_AS_MESSAGE
DOCTEST_WARN_THROWS_WITH_AS_MESSAGE
#define WARN_NOTHROW_MESSAGE
DOCTEST_WARN_NOTHROW_MESSAGE
#define CHECK_MESSAGE
DOCTEST_CHECK_MESSAGE
#define CHECK_FALSE_MESSAGE
DOCTEST_CHECK_FALSE_MESSAGE
#define CHECK_THROWS_MESSAGE
DOCTEST_CHECK_THROWS_MESSAGE
#define CHECK_THROWS_AS_MESSAGE
DOCTEST_CHECK_THROWS_AS_MESSAGE
#define CHECK_THROWS_WITH_MESSAGE
DOCTEST_CHECK_THROWS_WITH_MESSAGE
#define CHECK_THROWS_WITH_AS_MESSAGE
DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE
#define CHECK_NOTHROW_MESSAGE
DOCTEST_CHECK_NOTHROW_MESSAGE
#define REQUIRE_MESSAGE
DOCTEST_REQUIRE_MESSAGE
#define REQUIRE_FALSE_MESSAGE
DOCTEST_REQUIRE_FALSE_MESSAGE
#define REQUIRE_THROWS_MESSAGE
DOCTEST_REQUIRE_THROWS_MESSAGE
#define REQUIRE_THROWS_AS_MESSAGE
DOCTEST_REQUIRE_THROWS_AS_MESSAGE
#define REQUIRE_THROWS_WITH_MESSAGE
DOCTEST_REQUIRE_THROWS_WITH_MESSAGE
#define REQUIRE_THROWS_WITH_AS_MESSAGE
DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE
#define REQUIRE_NOTHROW_MESSAGE
DOCTEST_REQUIRE_NOTHROW_MESSAGE
#define SCENARIO
DOCTEST_SCENARIO
#define SCENARIO_CLASS
DOCTEST_SCENARIO_CLASS
#define SCENARIO_TEMPLATE
DOCTEST_SCENARIO_TEMPLATE
#define SCENARIO_TEMPLATE_DEFINE
DOCTEST_SCENARIO_TEMPLATE_DEFINE
#define GIVEN
DOCTEST_GIVEN
#define WHEN
DOCTEST_WHEN
#define AND_WHEN
DOCTEST_AND_WHEN
#define THEN
DOCTEST_THEN
#define AND_THEN
DOCTEST_AND_THEN
#define WARN_EQ
DOCTEST_WARN_EQ
#define CHECK_EQ
DOCTEST_CHECK_EQ
#define REQUIRE_EQ
DOCTEST_REQUIRE_EQ
#define WARN_NE
DOCTEST_WARN_NE
#define CHECK_NE
DOCTEST_CHECK_NE
#define REQUIRE_NE
DOCTEST_REQUIRE_NE
#define WARN_GT
DOCTEST_WARN_GT
#define CHECK_GT
DOCTEST_CHECK_GT
#define REQUIRE_GT
DOCTEST_REQUIRE_GT
#define WARN_LT
DOCTEST_WARN_LT
#define CHECK_LT
DOCTEST_CHECK_LT
#define REQUIRE_LT
DOCTEST_REQUIRE_LT
#define WARN_GE
DOCTEST_WARN_GE
#define CHECK_GE
DOCTEST_CHECK_GE
#define REQUIRE_GE
DOCTEST_REQUIRE_GE
#define WARN_LE
DOCTEST_WARN_LE
#define CHECK_LE
DOCTEST_CHECK_LE
#define REQUIRE_LE
DOCTEST_REQUIRE_LE
#define WARN_UNARY
DOCTEST_WARN_UNARY
#define CHECK_UNARY
DOCTEST_CHECK_UNARY
#define REQUIRE_UNARY
DOCTEST_REQUIRE_UNARY
#define WARN_UNARY_FALSE
DOCTEST_WARN_UNARY_FALSE
#define CHECK_UNARY_FALSE
DOCTEST_CHECK_UNARY_FALSE
#define REQUIRE_UNARY_FALSE
DOCTEST_REQUIRE_UNARY_FALSE
#define REGISTER_EXCEPTION_TRANSLATOR
(signature) DOCTEST_REGISTER_EXCEPTION_TRANSLATOR(signature)
#define REGISTER_REPORTER
(name, priority, reporter) DOCTEST_REGISTER_REPORTER(name, priority, reporter)
#define REGISTER_LISTENER
(name, priority, reporter) DOCTEST_REGISTER_LISTENER(name, priority, reporter)
#define INFO
(...) DOCTEST_INFO(__VA_ARGS__)
#define CAPTURE
(x) DOCTEST_CAPTURE(x)
#define ADD_MESSAGE_AT
(file, line, ...) DOCTEST_ADD_MESSAGE_AT(file, line, __VA_ARGS__)
#define ADD_FAIL_CHECK_AT
(file, line, ...) DOCTEST_ADD_FAIL_CHECK_AT(file, line, __VA_ARGS__)
#define ADD_FAIL_AT
(file, line, ...) DOCTEST_ADD_FAIL_AT(file, line, __VA_ARGS__)
#define MESSAGE
(...) DOCTEST_MESSAGE(__VA_ARGS__)
#define FAIL_CHECK
(...) DOCTEST_FAIL_CHECK(__VA_ARGS__)
#define FAIL
(...) DOCTEST_FAIL(__VA_ARGS__)
#define TO_LVALUE
(...) DOCTEST_TO_LVALUE(__VA_ARGS__)
#define WARN
(...) DOCTEST_WARN(__VA_ARGS__)
#define WARN_FALSE
(...) DOCTEST_WARN_FALSE(__VA_ARGS__)
#define WARN_THROWS
(...) DOCTEST_WARN_THROWS(__VA_ARGS__)
#define WARN_THROWS_AS
(expr, ...) DOCTEST_WARN_THROWS_AS(expr, __VA_ARGS__)
#define WARN_THROWS_WITH
(expr, ...) DOCTEST_WARN_THROWS_WITH(expr, __VA_ARGS__)
#define WARN_THROWS_WITH_AS
(expr, with, ...) DOCTEST_WARN_THROWS_WITH_AS(expr, with, __VA_ARGS__)
#define WARN_NOTHROW
(...) DOCTEST_WARN_NOTHROW(__VA_ARGS__)
#define CHECK
(...) DOCTEST_CHECK(__VA_ARGS__)
#define CHECK_FALSE
(...) DOCTEST_CHECK_FALSE(__VA_ARGS__)
#define CHECK_THROWS
(...) DOCTEST_CHECK_THROWS(__VA_ARGS__)
#define CHECK_THROWS_AS
(expr, ...) DOCTEST_CHECK_THROWS_AS(expr, __VA_ARGS__)
#define CHECK_THROWS_WITH
(expr, ...) DOCTEST_CHECK_THROWS_WITH(expr, __VA_ARGS__)
#define CHECK_THROWS_WITH_AS
(expr, with, ...) DOCTEST_CHECK_THROWS_WITH_AS(expr, with, __VA_ARGS__)
#define CHECK_NOTHROW
(...) DOCTEST_CHECK_NOTHROW(__VA_ARGS__)
#define REQUIRE
(...) DOCTEST_REQUIRE(__VA_ARGS__)
#define REQUIRE_FALSE
(...) DOCTEST_REQUIRE_FALSE(__VA_ARGS__)
#define REQUIRE_THROWS
(...) DOCTEST_REQUIRE_THROWS(__VA_ARGS__)
#define REQUIRE_THROWS_AS
(expr, ...) DOCTEST_REQUIRE_THROWS_AS(expr, __VA_ARGS__)
#define REQUIRE_THROWS_WITH
(expr, ...) DOCTEST_REQUIRE_THROWS_WITH(expr, __VA_ARGS__)
#define REQUIRE_THROWS_WITH_AS
(expr, with, ...) DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, __VA_ARGS__)
#define REQUIRE_NOTHROW
(...) DOCTEST_REQUIRE_NOTHROW(__VA_ARGS__)
#define WARN_MESSAGE
(cond, ...) DOCTEST_WARN_MESSAGE(cond, __VA_ARGS__)
#define WARN_FALSE_MESSAGE
(cond, ...) DOCTEST_WARN_FALSE_MESSAGE(cond, __VA_ARGS__)
#define WARN_THROWS_MESSAGE
(expr, ...) DOCTEST_WARN_THROWS_MESSAGE(expr, __VA_ARGS__)
#define WARN_THROWS_AS_MESSAGE
(expr, ex, ...) DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, __VA_ARGS__)
#define WARN_THROWS_WITH_MESSAGE
(expr, with, ...) DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, __VA_ARGS__)
#define WARN_THROWS_WITH_AS_MESSAGE
(expr, with, ex, ...) DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, __VA_ARGS__)
#define WARN_NOTHROW_MESSAGE
(expr, ...) DOCTEST_WARN_NOTHROW_MESSAGE(expr, __VA_ARGS__)
#define CHECK_MESSAGE
(cond, ...) DOCTEST_CHECK_MESSAGE(cond, __VA_ARGS__)
#define CHECK_FALSE_MESSAGE
(cond, ...) DOCTEST_CHECK_FALSE_MESSAGE(cond, __VA_ARGS__)
#define CHECK_THROWS_MESSAGE
(expr, ...) DOCTEST_CHECK_THROWS_MESSAGE(expr, __VA_ARGS__)
#define CHECK_THROWS_AS_MESSAGE
(expr, ex, ...) DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, __VA_ARGS__)
#define CHECK_THROWS_WITH_MESSAGE
(expr, with, ...) DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, __VA_ARGS__)
#define CHECK_THROWS_WITH_AS_MESSAGE
(expr, with, ex, ...) DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, __VA_ARGS__)
#define CHECK_NOTHROW_MESSAGE
(expr, ...) DOCTEST_CHECK_NOTHROW_MESSAGE(expr, __VA_ARGS__)
#define REQUIRE_MESSAGE
(cond, ...) DOCTEST_REQUIRE_MESSAGE(cond, __VA_ARGS__)
#define REQUIRE_FALSE_MESSAGE
(cond, ...) DOCTEST_REQUIRE_FALSE_MESSAGE(cond, __VA_ARGS__)
#define REQUIRE_THROWS_MESSAGE
(expr, ...) DOCTEST_REQUIRE_THROWS_MESSAGE(expr, __VA_ARGS__)
#define REQUIRE_THROWS_AS_MESSAGE
(expr, ex, ...) DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, __VA_ARGS__)
#define REQUIRE_THROWS_WITH_MESSAGE
(expr, with, ...) DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, __VA_ARGS__)
#define REQUIRE_THROWS_WITH_AS_MESSAGE
(expr, with, ex, ...) DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, __VA_ARGS__)
#define REQUIRE_NOTHROW_MESSAGE
(expr, ...) DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, __VA_ARGS__)
#define SCENARIO
(name) DOCTEST_SCENARIO(name)
#define SCENARIO_CLASS
(name) DOCTEST_SCENARIO_CLASS(name)
#define SCENARIO_TEMPLATE
(name, T, ...) DOCTEST_SCENARIO_TEMPLATE(name, T, __VA_ARGS__)
#define SCENARIO_TEMPLATE_DEFINE
(name, T, id) DOCTEST_SCENARIO_TEMPLATE_DEFINE(name, T, id)
#define GIVEN
(name) DOCTEST_GIVEN(name)
#define WHEN
(name) DOCTEST_WHEN(name)
#define AND_WHEN
(name) DOCTEST_AND_WHEN(name)
#define THEN
(name) DOCTEST_THEN(name)
#define AND_THEN
(name) DOCTEST_AND_THEN(name)
#define WARN_EQ
(...) DOCTEST_WARN_EQ(__VA_ARGS__)
#define CHECK_EQ
(...) DOCTEST_CHECK_EQ(__VA_ARGS__)
#define REQUIRE_EQ
(...) DOCTEST_REQUIRE_EQ(__VA_ARGS__)
#define WARN_NE
(...) DOCTEST_WARN_NE(__VA_ARGS__)
#define CHECK_NE
(...) DOCTEST_CHECK_NE(__VA_ARGS__)
#define REQUIRE_NE
(...) DOCTEST_REQUIRE_NE(__VA_ARGS__)
#define WARN_GT
(...) DOCTEST_WARN_GT(__VA_ARGS__)
#define CHECK_GT
(...) DOCTEST_CHECK_GT(__VA_ARGS__)
#define REQUIRE_GT
(...) DOCTEST_REQUIRE_GT(__VA_ARGS__)
#define WARN_LT
(...) DOCTEST_WARN_LT(__VA_ARGS__)
#define CHECK_LT
(...) DOCTEST_CHECK_LT(__VA_ARGS__)
#define REQUIRE_LT
(...) DOCTEST_REQUIRE_LT(__VA_ARGS__)
#define WARN_GE
(...) DOCTEST_WARN_GE(__VA_ARGS__)
#define CHECK_GE
(...) DOCTEST_CHECK_GE(__VA_ARGS__)
#define REQUIRE_GE
(...) DOCTEST_REQUIRE_GE(__VA_ARGS__)
#define WARN_LE
(...) DOCTEST_WARN_LE(__VA_ARGS__)
#define CHECK_LE
(...) DOCTEST_CHECK_LE(__VA_ARGS__)
#define REQUIRE_LE
(...) DOCTEST_REQUIRE_LE(__VA_ARGS__)
#define WARN_UNARY
(...) DOCTEST_WARN_UNARY(__VA_ARGS__)
#define CHECK_UNARY
(...) DOCTEST_CHECK_UNARY(__VA_ARGS__)
#define REQUIRE_UNARY
(...) DOCTEST_REQUIRE_UNARY(__VA_ARGS__)
#define WARN_UNARY_FALSE
(...) DOCTEST_WARN_UNARY_FALSE(__VA_ARGS__)
#define CHECK_UNARY_FALSE
(...) DOCTEST_CHECK_UNARY_FALSE(__VA_ARGS__)
#define REQUIRE_UNARY_FALSE
(...) DOCTEST_REQUIRE_UNARY_FALSE(__VA_ARGS__)
// KEPT FOR BACKWARDS COMPATIBILITY
#define FAST_WARN_EQ
DOCTEST_FAST_WARN_EQ
#define FAST_CHECK_EQ
DOCTEST_FAST_CHECK_EQ
#define FAST_REQUIRE_EQ
DOCTEST_FAST_REQUIRE_EQ
#define FAST_WARN_NE
DOCTEST_FAST_WARN_NE
#define FAST_CHECK_NE
DOCTEST_FAST_CHECK_NE
#define FAST_REQUIRE_NE
DOCTEST_FAST_REQUIRE_NE
#define FAST_WARN_GT
DOCTEST_FAST_WARN_GT
#define FAST_CHECK_GT
DOCTEST_FAST_CHECK_GT
#define FAST_REQUIRE_GT
DOCTEST_FAST_REQUIRE_GT
#define FAST_WARN_LT
DOCTEST_FAST_WARN_LT
#define FAST_CHECK_LT
DOCTEST_FAST_CHECK_LT
#define FAST_REQUIRE_LT
DOCTEST_FAST_REQUIRE_LT
#define FAST_WARN_GE
DOCTEST_FAST_WARN_GE
#define FAST_CHECK_GE
DOCTEST_FAST_CHECK_GE
#define FAST_REQUIRE_GE
DOCTEST_FAST_REQUIRE_GE
#define FAST_WARN_LE
DOCTEST_FAST_WARN_LE
#define FAST_CHECK_LE
DOCTEST_FAST_CHECK_LE
#define FAST_REQUIRE_LE
DOCTEST_FAST_REQUIRE_LE
#define FAST_WARN_UNARY
DOCTEST_FAST_WARN_UNARY
#define FAST_CHECK_UNARY
DOCTEST_FAST_CHECK_UNARY
#define FAST_REQUIRE_UNARY
DOCTEST_FAST_REQUIRE_UNARY
#define FAST_WARN_UNARY_FALSE
DOCTEST_FAST_WARN_UNARY_FALSE
#define FAST_CHECK_UNARY_FALSE
DOCTEST_FAST_CHECK_UNARY_FALSE
#define FAST_REQUIRE_UNARY_FALSE
DOCTEST_FAST_REQUIRE_UNARY_FALSE
#define TEST_CASE_TEMPLATE_INSTANTIATE
DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE
#define FAST_WARN_EQ
(...) DOCTEST_FAST_WARN_EQ(__VA_ARGS__)
#define FAST_CHECK_EQ
(...) DOCTEST_FAST_CHECK_EQ(__VA_ARGS__)
#define FAST_REQUIRE_EQ
(...) DOCTEST_FAST_REQUIRE_EQ(__VA_ARGS__)
#define FAST_WARN_NE
(...) DOCTEST_FAST_WARN_NE(__VA_ARGS__)
#define FAST_CHECK_NE
(...) DOCTEST_FAST_CHECK_NE(__VA_ARGS__)
#define FAST_REQUIRE_NE
(...) DOCTEST_FAST_REQUIRE_NE(__VA_ARGS__)
#define FAST_WARN_GT
(...) DOCTEST_FAST_WARN_GT(__VA_ARGS__)
#define FAST_CHECK_GT
(...) DOCTEST_FAST_CHECK_GT(__VA_ARGS__)
#define FAST_REQUIRE_GT
(...) DOCTEST_FAST_REQUIRE_GT(__VA_ARGS__)
#define FAST_WARN_LT
(...) DOCTEST_FAST_WARN_LT(__VA_ARGS__)
#define FAST_CHECK_LT
(...) DOCTEST_FAST_CHECK_LT(__VA_ARGS__)
#define FAST_REQUIRE_LT
(...) DOCTEST_FAST_REQUIRE_LT(__VA_ARGS__)
#define FAST_WARN_GE
(...) DOCTEST_FAST_WARN_GE(__VA_ARGS__)
#define FAST_CHECK_GE
(...) DOCTEST_FAST_CHECK_GE(__VA_ARGS__)
#define FAST_REQUIRE_GE
(...) DOCTEST_FAST_REQUIRE_GE(__VA_ARGS__)
#define FAST_WARN_LE
(...) DOCTEST_FAST_WARN_LE(__VA_ARGS__)
#define FAST_CHECK_LE
(...) DOCTEST_FAST_CHECK_LE(__VA_ARGS__)
#define FAST_REQUIRE_LE
(...) DOCTEST_FAST_REQUIRE_LE(__VA_ARGS__)
#define FAST_WARN_UNARY
(...) DOCTEST_FAST_WARN_UNARY(__VA_ARGS__)
#define FAST_CHECK_UNARY
(...) DOCTEST_FAST_CHECK_UNARY(__VA_ARGS__)
#define FAST_REQUIRE_UNARY
(...) DOCTEST_FAST_REQUIRE_UNARY(__VA_ARGS__)
#define FAST_WARN_UNARY_FALSE
(...) DOCTEST_FAST_WARN_UNARY_FALSE(__VA_ARGS__)
#define FAST_CHECK_UNARY_FALSE
(...) DOCTEST_FAST_CHECK_UNARY_FALSE(__VA_ARGS__)
#define FAST_REQUIRE_UNARY_FALSE
(...) DOCTEST_FAST_REQUIRE_UNARY_FALSE(__VA_ARGS__)
#define TEST_CASE_TEMPLATE_INSTANTIATE
(id, ...) DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE(id, __VA_ARGS__)
#endif // DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES
...
...
@@ -2689,6 +2746,7 @@ DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-field-initializers")
DOCTEST_CLANG_SUPPRESS_WARNING
(
"-Wc++98-compat"
)
DOCTEST_CLANG_SUPPRESS_WARNING
(
"-Wc++98-compat-pedantic"
)
DOCTEST_CLANG_SUPPRESS_WARNING
(
"-Wunused-member-function"
)
DOCTEST_CLANG_SUPPRESS_WARNING
(
"-Wnonportable-system-include-path"
)
DOCTEST_GCC_SUPPRESS_WARNING_PUSH
DOCTEST_GCC_SUPPRESS_WARNING
(
"-Wunknown-pragmas"
)
...
...
@@ -2794,11 +2852,7 @@ DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN
#ifdef __AFXDLL
#include <AfxWin.h>
#else
#if defined(__MINGW32__) || defined(__MINGW64__)
#include <windows.h>
#else // MINGW
#include <Windows.h>
#endif // MINGW
#endif
#include <io.h>
...
...
@@ -2834,12 +2888,24 @@ DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_END
#define DOCTEST_THREAD_LOCAL thread_local
#endif
#ifndef DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES
#define DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES 32
#endif
#ifndef DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE
#define DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE 64
#endif
#ifdef DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS
#define DOCTEST_OPTIONS_PREFIX_DISPLAY DOCTEST_CONFIG_OPTIONS_PREFIX
#else
#define DOCTEST_OPTIONS_PREFIX_DISPLAY ""
#endif
#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
#define DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS
#endif
namespace
doctest
{
bool
is_running_in_test
=
false
;
...
...
@@ -2972,18 +3038,105 @@ typedef timer_large_integer::type ticks_t;
ticks_t
m_ticks
=
0
;
};
#ifdef DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS
template
<
typename
T
>
using
AtomicOrMultiLaneAtomic
=
std
::
atomic
<
T
>
;
#else // DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS
// Provides a multilane implementation of an atomic variable that supports add, sub, load,
// store. Instead of using a single atomic variable, this splits up into multiple ones,
// each sitting on a separate cache line. The goal is to provide a speedup when most
// operations are modifying. It achieves this with two properties:
//
// * Multiple atomics are used, so chance of congestion from the same atomic is reduced.
// * Each atomic sits on a separate cache line, so false sharing is reduced.
//
// The disadvantage is that there is a small overhead due to the use of TLS, and load/store
// is slower because all atomics have to be accessed.
template
<
typename
T
>
class
MultiLaneAtomic
{
struct
CacheLineAlignedAtomic
{
std
::
atomic
<
T
>
atomic
{};
char
padding
[
DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE
-
sizeof
(
std
::
atomic
<
T
>
)];
};
CacheLineAlignedAtomic
m_atomics
[
DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES
];
static_assert
(
sizeof
(
CacheLineAlignedAtomic
)
==
DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE
,
"guarantee one atomic takes exactly one cache line"
);
public
:
T
operator
++
()
DOCTEST_NOEXCEPT
{
return
fetch_add
(
1
)
+
1
;
}
T
operator
++
(
int
)
DOCTEST_NOEXCEPT
{
return
fetch_add
(
1
);
}
T
fetch_add
(
T
arg
,
std
::
memory_order
order
=
std
::
memory_order_seq_cst
)
DOCTEST_NOEXCEPT
{
return
myAtomic
().
fetch_add
(
arg
,
order
);
}
T
fetch_sub
(
T
arg
,
std
::
memory_order
order
=
std
::
memory_order_seq_cst
)
DOCTEST_NOEXCEPT
{
return
myAtomic
().
fetch_sub
(
arg
,
order
);
}
operator
T
()
const
DOCTEST_NOEXCEPT
{
return
load
();
}
T
load
(
std
::
memory_order
order
=
std
::
memory_order_seq_cst
)
const
DOCTEST_NOEXCEPT
{
auto
result
=
T
();
for
(
auto
const
&
c
:
m_atomics
)
{
result
+=
c
.
atomic
.
load
(
order
);
}
return
result
;
}
T
operator
=
(
T
desired
)
DOCTEST_NOEXCEPT
{
store
(
desired
);
return
desired
;
}
void
store
(
T
desired
,
std
::
memory_order
order
=
std
::
memory_order_seq_cst
)
DOCTEST_NOEXCEPT
{
// first value becomes desired", all others become 0.
for
(
auto
&
c
:
m_atomics
)
{
c
.
atomic
.
store
(
desired
,
order
);
desired
=
{};
}
}
private
:
// Each thread has a different atomic that it operates on. If more than NumLanes threads
// use this, some will use the same atomic. So performance will degrate a bit, but still
// everything will work.
//
// The logic here is a bit tricky. The call should be as fast as possible, so that there
// is minimal to no overhead in determining the correct atomic for the current thread.
//
// 1. A global static counter laneCounter counts continuously up.
// 2. Each successive thread will use modulo operation of that counter so it gets an atomic
// assigned in a round-robin fashion.
// 3. This tlsLaneIdx is stored in the thread local data, so it is directly available with
// little overhead.
std
::
atomic
<
T
>&
myAtomic
()
DOCTEST_NOEXCEPT
{
static
std
::
atomic
<
size_t
>
laneCounter
;
DOCTEST_THREAD_LOCAL
size_t
tlsLaneIdx
=
laneCounter
++
%
DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES
;
return
m_atomics
[
tlsLaneIdx
].
atomic
;
}
};
template
<
typename
T
>
using
AtomicOrMultiLaneAtomic
=
MultiLaneAtomic
<
T
>
;
#endif // DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS
// this holds both parameters from the command line and runtime data for tests
struct
ContextState
:
ContextOptions
,
TestRunStats
,
CurrentTestCaseStats
{
std
::
a
tomic
<
int
>
numAssertsCurrentTest_atomic
;
std
::
a
tomic
<
int
>
numAssertsFailedCurrentTest_atomic
;
AtomicOrMultiLaneA
tomic
<
int
>
numAssertsCurrentTest_atomic
;
AtomicOrMultiLaneA
tomic
<
int
>
numAssertsFailedCurrentTest_atomic
;
std
::
vector
<
std
::
vector
<
String
>>
filters
=
decltype
(
filters
)(
9
);
// 9 different filters
std
::
vector
<
IReporter
*>
reporters_currently_used
;
const
TestCase
*
currentTest
=
nullptr
;
assert_handler
ah
=
nullptr
;
Timer
timer
;
...
...
@@ -3093,14 +3246,16 @@ String::String(const char* in)
String
::
String
(
const
char
*
in
,
unsigned
in_size
)
{
using
namespace
std
;
if
(
in_size
<=
last
)
{
memcpy
(
buf
,
in
,
in_size
+
1
);
memcpy
(
buf
,
in
,
in_size
);
buf
[
in_size
]
=
'\0'
;
setLast
(
last
-
in_size
);
}
else
{
setOnHeap
();
data
.
size
=
in_size
;
data
.
capacity
=
data
.
size
+
1
;
data
.
ptr
=
new
char
[
data
.
capacity
];
memcpy
(
data
.
ptr
,
in
,
in_size
+
1
);
memcpy
(
data
.
ptr
,
in
,
in_size
);
data
.
ptr
[
in_size
]
=
'\0'
;
}
}
...
...
@@ -3471,7 +3626,7 @@ int registerReporter(const char*, int, IReporter*) { return 0; }
namespace
doctest_detail_test_suite_ns
{
// holds the current test suite
doctest
::
detail
::
TestSuite
&
getCurrentTestSuite
()
{
static
doctest
::
detail
::
TestSuite
data
;
static
doctest
::
detail
::
TestSuite
data
{}
;
return
data
;
}
}
// namespace doctest_detail_test_suite_ns
...
...
@@ -3583,7 +3738,7 @@ namespace detail {
Subcase
::
Subcase
(
const
String
&
name
,
const
char
*
file
,
int
line
)
:
m_signature
({
name
,
file
,
line
})
{
ContextState
*
s
=
g_cs
;
auto
*
s
=
g_cs
;
// check subcase filters
if
(
s
->
subcasesStack
.
size
()
<
size_t
(
s
->
subcase_filter_levels
))
{
...
...
@@ -3625,7 +3780,7 @@ namespace detail {
g_cs
->
subcasesPassed
.
insert
(
g_cs
->
subcasesStack
);
g_cs
->
subcasesStack
.
pop_back
();
#if defined(__cpp_lib_uncaught_exceptions) && __cpp_lib_uncaught_exceptions >= 201411L
#if defined(__cpp_lib_uncaught_exceptions) && __cpp_lib_uncaught_exceptions >= 201411L
&& (!defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200)
if
(
std
::
uncaught_exceptions
()
>
0
#else
if
(
std
::
uncaught_exception
()
...
...
@@ -3660,6 +3815,8 @@ namespace detail {
// clear state
m_description
=
nullptr
;
m_skip
=
false
;
m_no_breaks
=
false
;
m_no_output
=
false
;
m_may_fail
=
false
;
m_should_fail
=
false
;
m_expected_failures
=
0
;
...
...
@@ -3675,6 +3832,8 @@ namespace detail {
m_test_suite
=
test_suite
.
m_test_suite
;
m_description
=
test_suite
.
m_description
;
m_skip
=
test_suite
.
m_skip
;
m_no_breaks
=
test_suite
.
m_no_breaks
;
m_no_output
=
test_suite
.
m_no_output
;
m_may_fail
=
test_suite
.
m_may_fail
;
m_should_fail
=
test_suite
.
m_should_fail
;
m_expected_failures
=
test_suite
.
m_expected_failures
;
...
...
@@ -3721,14 +3880,20 @@ namespace detail {
// this will be used only to differentiate between test cases - not relevant for sorting
if
(
m_line
!=
other
.
m_line
)
return
m_line
<
other
.
m_line
;
const
int
file_cmp
=
m_file
.
compare
(
other
.
m_file
);
if
(
file_cmp
!=
0
)
return
file_cmp
<
0
;
const
int
name_cmp
=
strcmp
(
m_name
,
other
.
m_name
);
if
(
name_cmp
!=
0
)
return
name_cmp
<
0
;
const
int
file_cmp
=
m_file
.
compare
(
other
.
m_file
);
if
(
file_cmp
!=
0
)
return
file_cmp
<
0
;
return
m_template_id
<
other
.
m_template_id
;
}
// all the registered tests
std
::
set
<
TestCase
>&
getRegisteredTests
()
{
static
std
::
set
<
TestCase
>
data
;
return
data
;
}
}
// namespace detail
namespace
{
using
namespace
detail
;
...
...
@@ -3760,12 +3925,6 @@ namespace {
return
suiteOrderComparator
(
lhs
,
rhs
);
}
// all the registered tests
std
::
set
<
TestCase
>&
getRegisteredTests
()
{
static
std
::
set
<
TestCase
>
data
;
return
data
;
}
#ifdef DOCTEST_CONFIG_COLORS_WINDOWS
HANDLE
g_stdoutHandle
;
WORD
g_origFgAttrs
;
...
...
@@ -3994,7 +4153,7 @@ namespace detail {
// ContextScope has been destroyed (base class destructors run after derived class destructors).
// Instead, ContextScope calls this method directly from its destructor.
void
ContextScopeBase
::
destroy
()
{
#if defined(__cpp_lib_uncaught_exceptions) && __cpp_lib_uncaught_exceptions >= 201411L
#if defined(__cpp_lib_uncaught_exceptions) && __cpp_lib_uncaught_exceptions >= 201411L
&& (!defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200)
if
(
std
::
uncaught_exceptions
()
>
0
)
{
#else
if
(
std
::
uncaught_exception
())
{
...
...
@@ -4016,7 +4175,9 @@ namespace {
#if !defined(DOCTEST_CONFIG_POSIX_SIGNALS) && !defined(DOCTEST_CONFIG_WINDOWS_SEH)
struct
FatalConditionHandler
{
void
reset
()
{}
static
void
reset
()
{}
static
void
allocateAltStackMem
()
{}
static
void
freeAltStackMem
()
{}
};
#else // DOCTEST_CONFIG_POSIX_SIGNALS || DOCTEST_CONFIG_WINDOWS_SEH
...
...
@@ -4069,6 +4230,9 @@ namespace {
std
::
exit
(
EXIT_FAILURE
);
}
static
void
allocateAltStackMem
()
{}
static
void
freeAltStackMem
()
{}
FatalConditionHandler
()
{
isSet
=
true
;
// 32k seems enough for doctest to handle stack overflow,
...
...
@@ -4086,7 +4250,7 @@ namespace {
// - std::terminate is called FROM THE TEST RUNNER THREAD
// - an exception is thrown from a destructor FROM THE TEST RUNNER THREAD
original_terminate_handler
=
std
::
get_terminate
();
std
::
set_terminate
([]()
noexcept
{
std
::
set_terminate
([]()
DOCTEST_NOEXCEPT
{
reportFatal
(
"Terminate handler called"
);
if
(
isDebuggerActive
()
&&
!
g_cs
->
no_breaks
)
DOCTEST_BREAK_INTO_DEBUGGER
();
...
...
@@ -4097,7 +4261,7 @@ namespace {
// - std::terminate is called FROM A DIFFERENT THREAD
// - an exception is thrown from a destructor FROM A DIFFERENT THREAD
// - an uncaught exception is thrown FROM A DIFFERENT THREAD
prev_sigabrt_handler
=
std
::
signal
(
SIGABRT
,
[](
int
signal
)
noexcept
{
prev_sigabrt_handler
=
std
::
signal
(
SIGABRT
,
[](
int
signal
)
DOCTEST_NOEXCEPT
{
if
(
signal
==
SIGABRT
)
{
reportFatal
(
"SIGABRT - Abort (abnormal termination) signal"
);
if
(
isDebuggerActive
()
&&
!
g_cs
->
no_breaks
)
...
...
@@ -4135,8 +4299,8 @@ namespace {
SetErrorMode
(
prev_error_mode_1
);
_set_error_mode
(
prev_error_mode_2
);
_set_abort_behavior
(
prev_abort_behavior
,
_WRITE_ABORT_MSG
|
_CALL_REPORTFAULT
);
_CrtSetReportMode
(
_CRT_ASSERT
,
prev_report_mode
);
_CrtSetReportFile
(
_CRT_ASSERT
,
prev_report_file
);
static_cast
<
void
>
(
_CrtSetReportMode
(
_CRT_ASSERT
,
prev_report_mode
)
);
static_cast
<
void
>
(
_CrtSetReportFile
(
_CRT_ASSERT
,
prev_report_file
)
);
isSet
=
false
;
}
}
...
...
@@ -4186,7 +4350,8 @@ namespace {
static
bool
isSet
;
static
struct
sigaction
oldSigActions
[
DOCTEST_COUNTOF
(
signalDefs
)];
static
stack_t
oldSigStack
;
static
char
altStackMem
[
4
*
SIGSTKSZ
];
static
size_t
altStackSize
;
static
char
*
altStackMem
;
static
void
handleSignal
(
int
sig
)
{
const
char
*
name
=
"<unknown signal>"
;
...
...
@@ -4202,11 +4367,19 @@ namespace {
raise
(
sig
);
}
static
void
allocateAltStackMem
()
{
altStackMem
=
new
char
[
altStackSize
];
}
static
void
freeAltStackMem
()
{
delete
[]
altStackMem
;
}
FatalConditionHandler
()
{
isSet
=
true
;
stack_t
sigStack
;
sigStack
.
ss_sp
=
altStackMem
;
sigStack
.
ss_size
=
sizeof
(
altStackMem
)
;
sigStack
.
ss_size
=
altStackSize
;
sigStack
.
ss_flags
=
0
;
sigaltstack
(
&
sigStack
,
&
oldSigStack
);
struct
sigaction
sa
=
{};
...
...
@@ -4231,10 +4404,11 @@ namespace {
}
};
bool
FatalConditionHandler
::
isSet
=
false
;
bool
FatalConditionHandler
::
isSet
=
false
;
struct
sigaction
FatalConditionHandler
::
oldSigActions
[
DOCTEST_COUNTOF
(
signalDefs
)]
=
{};
stack_t
FatalConditionHandler
::
oldSigStack
=
{};
char
FatalConditionHandler
::
altStackMem
[]
=
{};
stack_t
FatalConditionHandler
::
oldSigStack
=
{};
size_t
FatalConditionHandler
::
altStackSize
=
4
*
SIGSTKSZ
;
char
*
FatalConditionHandler
::
altStackMem
=
nullptr
;
#endif // DOCTEST_PLATFORM_WINDOWS
#endif // DOCTEST_CONFIG_POSIX_SIGNALS || DOCTEST_CONFIG_WINDOWS_SEH
...
...
@@ -4336,8 +4510,8 @@ namespace detail {
failed_out_of_a_testing_context
(
*
this
);
}
return
m_failed
&&
isDebuggerActive
()
&&
!
getContextOptions
()
->
no_breaks
;
// break into debugger
return
m_failed
&&
isDebuggerActive
()
&&
!
getContextOptions
()
->
no_breaks
&&
(
g_cs
->
currentTest
==
nullptr
||
!
g_cs
->
currentTest
->
m_no_breaks
)
;
// break into debugger
}
void
ResultBuilder
::
react
()
const
{
...
...
@@ -4387,7 +4561,8 @@ namespace detail {
addFailedAssert
(
m_severity
);
}
return
isDebuggerActive
()
&&
!
getContextOptions
()
->
no_breaks
&&
!
isWarn
;
// break
return
isDebuggerActive
()
&&
!
getContextOptions
()
->
no_breaks
&&
!
isWarn
&&
(
g_cs
->
currentTest
==
nullptr
||
!
g_cs
->
currentTest
->
m_no_breaks
);
// break into debugger
}
void
MessageBuilder
::
react
()
{
...
...
@@ -5495,7 +5670,7 @@ namespace {
<<
Whitespace
(
sizePrefixDisplay
*
1
)
<<
"output filename
\n
"
;
s
<<
" -"
DOCTEST_OPTIONS_PREFIX_DISPLAY
"ob, --"
DOCTEST_OPTIONS_PREFIX_DISPLAY
"order-by=<string> "
<<
Whitespace
(
sizePrefixDisplay
*
1
)
<<
"how the tests should be ordered
\n
"
;
s
<<
Whitespace
(
sizePrefixDisplay
*
3
)
<<
" <string> -
by [file/suite/name/rand
]
\n
"
;
s
<<
Whitespace
(
sizePrefixDisplay
*
3
)
<<
" <string> -
[file/suite/name/rand/none
]
\n
"
;
s
<<
" -"
DOCTEST_OPTIONS_PREFIX_DISPLAY
"rs, --"
DOCTEST_OPTIONS_PREFIX_DISPLAY
"rand-seed=<int> "
<<
Whitespace
(
sizePrefixDisplay
*
1
)
<<
"seed for random ordering
\n
"
;
s
<<
" -"
DOCTEST_OPTIONS_PREFIX_DISPLAY
"f, --"
DOCTEST_OPTIONS_PREFIX_DISPLAY
"first=<int> "
...
...
@@ -5668,6 +5843,9 @@ namespace {
}
void
test_case_end
(
const
CurrentTestCaseStats
&
st
)
override
{
if
(
tc
->
m_no_output
)
return
;
// log the preamble of the test case only if there is something
// else to print - something other than that an assert has failed
if
(
opt
.
duration
||
...
...
@@ -5702,6 +5880,9 @@ namespace {
}
void
test_case_exception
(
const
TestCaseException
&
e
)
override
{
if
(
tc
->
m_no_output
)
return
;
logTestStart
();
file_line_to_stream
(
tc
->
m_file
.
c_str
(),
tc
->
m_line
,
" "
);
...
...
@@ -5736,7 +5917,7 @@ namespace {
}
void
log_assert
(
const
AssertData
&
rb
)
override
{
if
(
!
rb
.
m_failed
&&
!
opt
.
success
)
if
(
(
!
rb
.
m_failed
&&
!
opt
.
success
)
||
tc
->
m_no_output
)
return
;
std
::
lock_guard
<
std
::
mutex
>
lock
(
mutex
);
...
...
@@ -5752,6 +5933,9 @@ namespace {
}
void
log_message
(
const
MessageData
&
mb
)
override
{
if
(
tc
->
m_no_output
)
return
;
std
::
lock_guard
<
std
::
mutex
>
lock
(
mutex
);
logTestStart
();
...
...
@@ -5782,8 +5966,10 @@ namespace {
bool with_col = g_no_colors; \
g_no_colors = false; \
ConsoleReporter::func(arg); \
DOCTEST_OUTPUT_DEBUG_STRING(oss.str().c_str()); \
oss.str(""); \
if(oss.tellp() != std::streampos{}) { \
DOCTEST_OUTPUT_DEBUG_STRING(oss.str().c_str()); \
oss.str(""); \
} \
g_no_colors = with_col; \
}
...
...
@@ -5970,7 +6156,7 @@ void Context::parseArgs(int argc, const char* const* argv, bool withDefaults) {
#define DOCTEST_PARSE_AS_BOOL_OR_FLAG(name, sname, var, default) \
if(parseIntOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX name "=", option_bool, intRes) || \
parseIntOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX sname "=", option_bool, intRes)) \
p->var =
!!intRes;
\
p->var =
static_cast<bool>(intRes);
\
else if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX name) || \
parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX sname)) \
p->var = true; \
...
...
@@ -6115,7 +6301,11 @@ int Context::run() {
p
->
cout
=
&
fstr
;
}
FatalConditionHandler
::
allocateAltStackMem
();
auto
cleanup_and_return
=
[
&
]()
{
FatalConditionHandler
::
freeAltStackMem
();
if
(
fstr
.
is_open
())
fstr
.
close
();
...
...
@@ -6187,6 +6377,9 @@ int Context::run() {
first
[
i
]
=
first
[
idxToSwap
];
first
[
idxToSwap
]
=
temp
;
}
}
else
if
(
p
->
order_by
.
compare
(
"none"
,
true
)
==
0
)
{
// means no sorting - beneficial for death tests which call into the executable
// with a specific test case in mind - we don't want to slow down the startup times
}
}
...
...
@@ -6286,10 +6479,13 @@ int Context::run() {
#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
try
{
#endif // DOCTEST_CONFIG_NO_EXCEPTIONS
// MSVC 2015 diagnoses fatalConditionHandler as unused (because reset() is a static method)
DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH
(
4101
)
// unreferenced local variable
FatalConditionHandler
fatalConditionHandler
;
// Handle signals
// execute the test
tc
.
m_test
();
fatalConditionHandler
.
reset
();
DOCTEST_MSVC_SUPPRESS_WARNING_POP
#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS
}
catch
(
const
TestFailureException
&
)
{
p
->
failure_flags
|=
TestCaseFailureReason
::
AssertFailure
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment