summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/unittests/doctest.h275
1 files changed, 96 insertions, 179 deletions
diff --git a/src/unittests/doctest.h b/src/unittests/doctest.h
index 695c271b5..10ecf5158 100644
--- a/src/unittests/doctest.h
+++ b/src/unittests/doctest.h
@@ -465,6 +465,11 @@ namespace std
#endif // DOCTEST_CONFIG_WITH_NULLPTR
#ifndef DOCTEST_CONFIG_DISABLE
+
+#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
+#include <type_traits>
+#endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
+
namespace doctest
{
namespace detail
@@ -572,10 +577,12 @@ public:
// GCC 4.9/5/6 report Wstrict-overflow when optimizations are ON and it got inlined in the vector class somewhere...
// see commit 574ef95f0cd379118be5011704664e4b5351f1e0 and build https://travis-ci.org/onqtam/doctest/builds/230671611
DOCTEST_NOINLINE String& operator=(const String& other) {
- if(!isOnStack())
- delete[] data.ptr;
+ if(this != &other) {
+ if(!isOnStack())
+ delete[] data.ptr;
- copy(other);
+ copy(other);
+ }
return *this;
}
@@ -649,123 +656,13 @@ namespace detail
} // namespace static_assert_impl
#endif // DOCTEST_CONFIG_WITH_STATIC_ASSERT
- namespace traits
- {
- template <typename T>
- struct remove_const
- { typedef T type; };
-
- template <typename T>
- struct remove_const<const T>
- { typedef T type; };
-
- template <typename T>
- struct remove_volatile
- { typedef T type; };
-
- template <typename T>
- struct remove_volatile<volatile T>
- { typedef T type; };
-
- template <typename T>
- struct remove_cv
- { typedef typename remove_volatile<typename remove_const<T>::type>::type type; };
-
- template <typename T>
- struct is_pointer_helper
- { static const bool value = false; };
-
- template <typename T>
- struct is_pointer_helper<T*>
- // cppcheck-suppress unusedStructMember
- { static const bool value = true; };
-
- template <typename T>
- struct is_pointer
- // cppcheck-suppress unusedStructMember
- { static const bool value = is_pointer_helper<typename remove_cv<T>::type>::value; };
-
- template <bool CONDITION, typename TYPE = void>
- struct enable_if
- {};
-
- template <typename TYPE>
- struct enable_if<true, TYPE>
- { typedef TYPE type; };
-
- template <typename T>
- struct remove_reference
- { typedef T type; };
-
- template <typename T>
- struct remove_reference<T&>
- { typedef T type; };
-
- template <typename T, typename AT_1 = void>
- class is_constructible_impl
- {
- private:
- template <typename C_T, typename C_AT_1>
- static bool test(typename enable_if< //!OCLINT avoid private static members
- sizeof(C_T) ==
- sizeof(C_T(static_cast<C_AT_1>(
- *static_cast<typename remove_reference<C_AT_1>::type*>(
- 0))))>::type*);
-
- template <typename, typename>
- static int test(...); //!OCLINT avoid private static members
-
- public:
- static const bool value = sizeof(test<T, AT_1>(0)) == sizeof(bool);
- };
-
- template <typename T>
- class is_constructible_impl<T, void>
- {
- private:
- template <typename C_T>
- static C_T testFun(C_T); //!OCLINT avoid private static members
-
- template <typename C_T>
- static bool test(typename enable_if< //!OCLINT avoid private static members
- sizeof(C_T) == sizeof(testFun(C_T()))>::type*);
-
- template <typename>
- static int test(...); //!OCLINT avoid private static members
-
- public:
- static const bool value = sizeof(test<T>(0)) == sizeof(bool);
- };
+ template <bool CONDITION, typename TYPE = void>
+ struct enable_if
+ {};
-// is_constructible<> taken from here: http://stackoverflow.com/a/40443701/3162383
-// for GCC/Clang gives the same results as std::is_constructible<> - see here: https://wandbox.org/permlink/bNWr7Ii2fuz4Vf7A
-// modifications:
-// - reworked to support only 1 argument (mainly because of MSVC...)
-// - removed pointer support
-// MSVC support:
-// - for versions before 2012 read the CAUTION comment below
-// currently intended for use only in the Approx() helper for strong typedefs of double - see issue #62
-#ifndef _MSC_VER
- template <typename T, typename AT_1 = void>
- class is_constructible
- {
- public:
- static const bool value = is_pointer<typename remove_reference<T>::type>::value ?
- false :
- is_constructible_impl<T, AT_1>::value;
- };
-#elif defined(_MSC_VER) && (_MSC_VER >= 1700)
- template <typename T, typename AT_1>
- struct is_constructible
- { static const bool value = __is_constructible(T, AT_1); };
-#elif defined(_MSC_VER)
- // !!! USE WITH CAUTION !!!
- // will always return false - unable to implement this for versions of MSVC older than 2012 for now...
- template <typename T, typename AT_1>
- struct is_constructible
- { static const bool value = false; };
-#endif // _MSC_VER
- } // namespace traits
+ template <typename TYPE>
+ struct enable_if<true, TYPE>
+ { typedef TYPE type; };
template <typename T>
struct deferred_false
@@ -1016,13 +913,14 @@ public:
return approx;
}
+#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
template <typename T>
explicit Approx(const T& value,
- typename detail::traits::enable_if<
- detail::traits::is_constructible<double, T>::value>::type* =
+ typename detail::enable_if<std::is_constructible<double, T>::value>::type* =
static_cast<T*>(detail::getNull())) {
*this = Approx(static_cast<double>(value));
}
+#endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
// clang-format off
// overloads for double - the first one is necessary as it is in the implementation part of doctest
@@ -1040,8 +938,9 @@ public:
friend bool operator> (double lhs, Approx const& rhs) { return lhs > rhs.m_value && lhs != rhs; }
friend bool operator> (Approx const& lhs, double rhs) { return lhs.m_value > rhs && lhs != rhs; }
+#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
#define DOCTEST_APPROX_PREFIX \
- template <typename T> friend typename detail::traits::enable_if<detail::traits::is_constructible<double, T>::value, bool>::type
+ template <typename T> friend typename detail::enable_if<std::is_constructible<double, T>::value, bool>::type
DOCTEST_APPROX_PREFIX operator==(const T& lhs, const Approx& rhs) { return operator==(double(lhs), rhs); }
DOCTEST_APPROX_PREFIX operator==(const Approx& lhs, const T& rhs) { return operator==(rhs, lhs); }
@@ -1056,33 +955,37 @@ public:
DOCTEST_APPROX_PREFIX operator> (const T& lhs, const Approx& rhs) { return double(lhs) > rhs.m_value && lhs != rhs; }
DOCTEST_APPROX_PREFIX operator> (const Approx& lhs, const T& rhs) { return lhs.m_value > double(rhs) && lhs != rhs; }
#undef DOCTEST_APPROX_PREFIX
+#endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
+
// clang-format on
Approx& epsilon(double newEpsilon) {
- m_epsilon = (newEpsilon);
+ m_epsilon = newEpsilon;
return *this;
}
+#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
template <typename T>
- typename detail::traits::enable_if<detail::traits::is_constructible<double, T>::value,
- Approx&>::type
- epsilon(const T& newEpsilon) {
+ typename detail::enable_if<std::is_constructible<double, T>::value, Approx&>::type epsilon(
+ const T& newEpsilon) {
m_epsilon = static_cast<double>(newEpsilon);
return *this;
}
+#endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
Approx& scale(double newScale) {
- m_scale = (newScale);
+ m_scale = newScale;
return *this;
}
+#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
template <typename T>
- typename detail::traits::enable_if<detail::traits::is_constructible<double, T>::value,
- Approx&>::type
- scale(const T& newScale) {
+ typename detail::enable_if<std::is_constructible<double, T>::value, Approx&>::type scale(
+ const T& newScale) {
m_scale = static_cast<double>(newScale);
return *this;
}
+#endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
String toString() const;
@@ -1367,7 +1270,7 @@ namespace detail
#ifndef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
#define DOCTEST_COMPARISON_RETURN_TYPE bool
#else // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
-#define DOCTEST_COMPARISON_RETURN_TYPE typename traits::enable_if<can_use_op<L>::value || can_use_op<R>::value, bool>::type
+#define DOCTEST_COMPARISON_RETURN_TYPE typename enable_if<can_use_op<L>::value || can_use_op<R>::value, bool>::type
inline bool eq(const char* lhs, const char* rhs) { return String(lhs) == String(rhs); }
inline bool ne(const char* lhs, const char* rhs) { return String(lhs) != String(rhs); }
inline bool lt(const char* lhs, const char* rhs) { return String(lhs) < String(rhs); }
@@ -1728,9 +1631,9 @@ namespace detail
return res;
}
- struct DOCTEST_INTERFACE IExceptionTranslator //!OCLINT destructor of virtual class
+ struct DOCTEST_INTERFACE IExceptionTranslator
{
- virtual ~IExceptionTranslator();
+ virtual ~IExceptionTranslator() {}
virtual bool translate(String&) const = 0;
};
@@ -1823,8 +1726,11 @@ namespace detail
DOCTEST_INTERFACE void toStream(std::ostream* stream, int long long unsigned in);
#endif // DOCTEST_CONFIG_WITH_LONG_LONG
- struct IContextScope //!OCLINT destructor of virtual class
- { virtual void build(std::ostream*) = 0; };
+ struct IContextScope
+ {
+ virtual ~IContextScope() {}
+ virtual void build(std::ostream*) = 0;
+ };
DOCTEST_INTERFACE void addToContexts(IContextScope* ptr);
DOCTEST_INTERFACE void popFromContexts();
@@ -1835,8 +1741,11 @@ namespace detail
{
friend class ContextScope;
- struct ICapture //!OCLINT destructor of virtual class
- { virtual void toStream(std::ostream*) const = 0; };
+ struct ICapture
+ {
+ virtual ~ICapture() {}
+ virtual void toStream(std::ostream*) const = 0;
+ };
template <typename T>
struct Capture : ICapture //!OCLINT destructor of virtual class
@@ -1846,7 +1755,7 @@ namespace detail
explicit Capture(const T* in)
: capture(in) {}
virtual void toStream(std::ostream* stream) const { // override
- doctest::detail::toStream(stream, *capture);
+ detail::toStream(stream, *capture);
}
};
@@ -1892,6 +1801,8 @@ namespace detail
unsigned(int(sizeof(Chunk)) * DOCTEST_CONFIG_NUM_CAPTURES_ON_STACK));
}
+ ContextBuilder& operator=(const ContextBuilder&); // NOLINT
+
public:
// cppcheck-suppress uninitMemberVar
DOCTEST_NOINLINE ContextBuilder() // NOLINT
@@ -1945,7 +1856,7 @@ namespace detail
#endif // DOCTEST_CONFIG_WITH_RVALUE_REFERENCES
};
- class ContextScope : public IContextScope //!OCLINT destructor of virtual class
+ class ContextScope : public IContextScope
{
ContextBuilder contextBuilder;
bool built;
@@ -1971,18 +1882,18 @@ namespace detail
class DOCTEST_INTERFACE MessageBuilder
{
- std::ostream* m_stream;
- const char* m_file;
- int m_line;
- doctest::detail::assertType::Enum m_severity;
+ std::ostream* m_stream;
+ const char* m_file;
+ int m_line;
+ assertType::Enum m_severity;
public:
- MessageBuilder(const char* file, int line, doctest::detail::assertType::Enum severity);
+ MessageBuilder(const char* file, int line, assertType::Enum severity);
~MessageBuilder();
template <typename T>
MessageBuilder& operator<<(const T& in) {
- doctest::detail::toStream(m_stream, in);
+ toStream(m_stream, in);
return *this;
}
@@ -2456,7 +2367,7 @@ constexpr T to_lvalue = x;
DOCTEST_TOSTR(DOCTEST_HANDLE_BRACED_VA_ARGS(as))); \
try { \
expr; \
- } catch(DOCTEST_HANDLE_BRACED_VA_ARGS(as)) { \
+ } catch(const DOCTEST_HANDLE_BRACED_VA_ARGS(as)&) { \
_DOCTEST_RB.m_threw = true; \
_DOCTEST_RB.m_threw_as = true; \
} catch(...) { _DOCTEST_RB.unexpectedExceptionOccurred(); } \
@@ -3284,7 +3195,7 @@ namespace detail
#define DOCTEST_LOG_START() \
do { \
if(!contextState->hasLoggedCurrentTestStart) { \
- doctest::detail::logTestStart(*contextState->currentTest); \
+ logTestStart(*contextState->currentTest); \
contextState->hasLoggedCurrentTestStart = true; \
} \
} while(false)
@@ -3329,7 +3240,7 @@ namespace detail
// case insensitive strcmp
int stricmp(char const* a, char const* b) {
for(;; a++, b++) {
- int d = tolower(*a) - tolower(*b);
+ const int d = tolower(*a) - tolower(*b);
if(d != 0 || !*a)
return d;
}
@@ -3516,9 +3427,9 @@ String::String(const char* in) {
}
String& String::operator+=(const String& other) {
- unsigned my_old_size = size();
- unsigned other_size = other.size();
- unsigned total_size = my_old_size + other_size;
+ const unsigned my_old_size = size();
+ const unsigned other_size = other.size();
+ const unsigned total_size = my_old_size + other_size;
if(isOnStack()) {
if(total_size < len) {
// append to the current stack space
@@ -3572,11 +3483,13 @@ String::String(String&& other) {
}
String& String::operator=(String&& other) {
- if(!isOnStack())
- delete[] data.ptr;
- detail::my_memcpy(buf, other.buf, len);
- other.buf[0] = '\0';
- other.setLast();
+ if(this != &other) {
+ if(!isOnStack())
+ delete[] data.ptr;
+ detail::my_memcpy(buf, other.buf, len);
+ other.buf[0] = '\0';
+ other.setLast();
+ }
return *this;
}
#endif // DOCTEST_CONFIG_WITH_RVALUE_REFERENCES
@@ -3719,7 +3632,7 @@ int Context::run() { return 0; }
#define DOCTEST_PRINTF_COLORED(buffer, color) \
do { \
- doctest::detail::Color col(color); \
+ Color col(color); \
std::printf("%s", buffer); \
} while((void)0, 0)
@@ -3834,7 +3747,7 @@ namespace detail
bool TestCase::operator<(const TestCase& other) const {
if(m_line != other.m_line)
return m_line < other.m_line;
- int file_cmp = std::strcmp(m_file, other.m_file);
+ const int file_cmp = std::strcmp(m_file, other.m_file);
if(file_cmp != 0)
return file_cmp < 0;
return m_template_id < other.m_template_id;
@@ -4122,9 +4035,9 @@ namespace detail
#ifdef _MSC_VER
// this is needed because MSVC gives different case for drive letters
// for __FILE__ when evaluated in a header and a source file
- int res = stricmp(lhs->m_file, rhs->m_file);
+ const int res = stricmp(lhs->m_file, rhs->m_file);
#else // _MSC_VER
- int res = std::strcmp(lhs->m_file, rhs->m_file);
+ const int res = std::strcmp(lhs->m_file, rhs->m_file);
#endif // _MSC_VER
if(res != 0)
return res;
@@ -4136,7 +4049,7 @@ namespace detail
const TestCase* lhs = *static_cast<TestCase* const*>(a);
const TestCase* rhs = *static_cast<TestCase* const*>(b);
- int res = std::strcmp(lhs->m_test_suite, rhs->m_test_suite);
+ const int res = std::strcmp(lhs->m_test_suite, rhs->m_test_suite);
if(res != 0)
return res;
return fileOrderComparator(a, b);
@@ -4147,7 +4060,7 @@ namespace detail
const TestCase* lhs = *static_cast<TestCase* const*>(a);
const TestCase* rhs = *static_cast<TestCase* const*>(b);
- int res_name = std::strcmp(lhs->m_name, rhs->m_name);
+ const int res_name = std::strcmp(lhs->m_name, rhs->m_name);
if(res_name != 0)
return res_name;
return suiteOrderComparator(a, b);
@@ -4285,8 +4198,6 @@ namespace detail
#endif // DOCTEST_CONFIG_COLORS_WINDOWS
}
- IExceptionTranslator::~IExceptionTranslator() {}
-
std::vector<const IExceptionTranslator*>& getExceptionTranslators() {
static std::vector<const IExceptionTranslator*> data;
return data;
@@ -4351,6 +4262,10 @@ namespace detail
void addToContexts(IContextScope* ptr) { contextState->contexts.push_back(ptr); }
void popFromContexts() { contextState->contexts.pop_back(); }
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable : 4996) // std::uncaught_exception is deprecated in C++17
+#endif
void useContextIfExceptionOccurred(IContextScope* ptr) {
if(std::uncaught_exception()) {
std::ostringstream stream;
@@ -4358,6 +4273,9 @@ namespace detail
contextState->exceptionalContexts.push_back(stream.str());
}
}
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
void printSummary();
@@ -4745,7 +4663,7 @@ namespace detail
getAssertString(assert_type), decomposition);
}
- bool isWarn = assert_type & assertType::is_warn;
+ const bool isWarn = assert_type & assertType::is_warn;
DOCTEST_PRINTF_COLORED(loc, Color::LightGrey);
DOCTEST_PRINTF_COLORED(msg,
passed ? Color::BrightGreen : isWarn ? Color::Yellow : Color::Red);
@@ -4779,7 +4697,7 @@ namespace detail
if(!threw)
DOCTEST_SNPRINTF(info2, DOCTEST_COUNTOF(info2), "didn't throw at all\n");
- bool isWarn = assert_type & assertType::is_warn;
+ const bool isWarn = assert_type & assertType::is_warn;
DOCTEST_PRINTF_COLORED(loc, Color::LightGrey);
DOCTEST_PRINTF_COLORED(msg,
threw ? Color::BrightGreen : isWarn ? Color::Yellow : Color::Red);
@@ -4819,7 +4737,7 @@ namespace detail
DOCTEST_SNPRINTF(info3, DOCTEST_COUNTOF(info3), " %s\n", exception.c_str());
}
- bool isWarn = assert_type & assertType::is_warn;
+ const bool isWarn = assert_type & assertType::is_warn;
DOCTEST_PRINTF_COLORED(loc, Color::LightGrey);
DOCTEST_PRINTF_COLORED(msg,
threw_as ? Color::BrightGreen : isWarn ? Color::Yellow : Color::Red);
@@ -4856,7 +4774,7 @@ namespace detail
DOCTEST_SNPRINTF(info3, DOCTEST_COUNTOF(info3), " %s\n", exception.c_str());
}
- bool isWarn = assert_type & assertType::is_warn;
+ const bool isWarn = assert_type & assertType::is_warn;
DOCTEST_PRINTF_COLORED(loc, Color::LightGrey);
DOCTEST_PRINTF_COLORED(msg,
threw ? isWarn ? Color::Yellow : Color::Red : Color::BrightGreen);
@@ -4939,8 +4857,7 @@ namespace detail
throwException();
}
- MessageBuilder::MessageBuilder(const char* file, int line,
- doctest::detail::assertType::Enum severity)
+ MessageBuilder::MessageBuilder(const char* file, int line, assertType::Enum severity)
: m_stream(createStream())
, m_file(file)
, m_line(line)
@@ -4949,10 +4866,10 @@ namespace detail
bool MessageBuilder::log() {
DOCTEST_LOG_START();
- bool is_warn = m_severity & doctest::detail::assertType::is_warn;
+ const bool isWarn = m_severity & assertType::is_warn;
// warn is just a message in this context so we dont treat it as an assert
- if(!is_warn) {
+ if(!isWarn) {
contextState->numAssertionsForCurrentTestcase++;
addFailedAssert(m_severity);
}
@@ -4962,10 +4879,10 @@ namespace detail
lineForOutput(m_line));
char msg[DOCTEST_SNPRINTF_BUFFER_LENGTH];
DOCTEST_SNPRINTF(msg, DOCTEST_COUNTOF(msg), " %s!\n",
- is_warn ? "MESSAGE" : getFailString(m_severity));
+ isWarn ? "MESSAGE" : getFailString(m_severity));
DOCTEST_PRINTF_COLORED(loc, Color::LightGrey);
- DOCTEST_PRINTF_COLORED(msg, is_warn ? Color::Yellow : Color::Red);
+ DOCTEST_PRINTF_COLORED(msg, isWarn ? Color::Yellow : Color::Red);
String info = getStreamResult(m_stream);
if(info.size()) {
@@ -4980,7 +4897,7 @@ namespace detail
printToDebugConsole(String(loc) + msg + " " + info.c_str() + "\n" + context.c_str() +
"\n");
- return isDebuggerActive() && !contextState->no_breaks && !is_warn; // break into debugger
+ return isDebuggerActive() && !contextState->no_breaks && !isWarn; // break into debugger
}
void MessageBuilder::react() {
@@ -5037,7 +4954,7 @@ namespace detail
}
if(noBadCharsFound && argv[i][0] == '-') {
temp += my_strlen(pattern);
- unsigned len = my_strlen(temp);
+ const unsigned len = my_strlen(temp);
if(len) {
res = temp;
return true;
@@ -5211,7 +5128,7 @@ namespace detail
std::printf("test suites with unskipped test cases passing the current filters: %u\n",
p->numTestSuitesPassingFilters);
} else {
- bool anythingFailed = p->numFailed > 0 || p->numFailedAssertions > 0;
+ const bool anythingFailed = p->numFailed > 0 || p->numFailedAssertions > 0;
char buff[DOCTEST_SNPRINTF_BUFFER_LENGTH];
@@ -5236,8 +5153,8 @@ namespace detail
DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), " | ");
DOCTEST_PRINTF_COLORED(buff, Color::None);
if(p->no_skipped_summary == false) {
- int numSkipped = static_cast<unsigned>(getRegisteredTests().size()) -
- p->numTestsPassingFilters;
+ const int numSkipped = static_cast<unsigned>(getRegisteredTests().size()) -
+ p->numTestsPassingFilters;
DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), "%6d skipped", numSkipped);
DOCTEST_PRINTF_COLORED(buff, numSkipped == 0 ? Color::None : Color::Yellow);
}