trying to get the operator<< stringification
diff --git a/doc/markdown/features.md b/doc/markdown/features.md
index 37b35b2..884d738 100644
--- a/doc/markdown/features.md
+++ b/doc/markdown/features.md
@@ -65,16 +65,18 @@
## TODO for release
+switch loc and msg in logTestStart
+
- assume dt- prefix is not needed - remove from the help
- even shorter versions of command line options
- add the ability to not specify bool values for command line options - treat them as true
- print sections when asserts fail (look if catch does that)
-- move to operator<<(ostream&... stringification
- floating point comparison support
- signal handling for unix: http://www.cplusplus.com/reference/csignal/signal/
(signals on *NIX platforms or structured exceptions on Windows)
+- look into https://github.com/Barro/compiler-warnings
- think about the expression decomposition static asserts
- VC6 support
diff --git a/doctest/doctest.h b/doctest/doctest.h
index f7a3c03..a40d3e7 100644
--- a/doctest/doctest.h
+++ b/doctest/doctest.h
@@ -136,6 +136,30 @@
#define DOCTEST_BREAK_INTO_DEBUGGER() ((void)0)
#endif // linux
+#ifdef __clang__
+#include <ciso646>
+#endif // __clang__
+
+#define DOCTEST_CONFIG_USE_IOSFWD
+
+#ifdef _LIBCPP_VERSION
+#include <iosfwd>
+#else // _LIBCPP_VERSION
+#ifndef DOCTEST_CONFIG_USE_IOSFWD
+namespace std
+{
+template <class charT>
+struct char_traits;
+template <>
+struct char_traits<char>;
+template <class charT, class traits>
+class basic_ostream;
+typedef basic_ostream<char, char_traits<char> > ostream;
+}
+#else // DOCTEST_CONFIG_USE_IOSFWD
+#include <iosfwd>
+#endif // DOCTEST_CONFIG_USE_IOSFWD
+#endif // _LIBCPP_VERSION
namespace doctest
{
class String
@@ -164,42 +188,89 @@
int compare(const String& other, bool no_case = false) const;
};
-struct ADL_helper
-{};
-
-template <typename T>
-String stringify(ADL_helper, const T&) {
- return "{?}";
-}
-
#if !defined(DOCTEST_CONFIG_DISABLE)
-String stringify(ADL_helper, const char* in);
-String stringify(ADL_helper, const void* in);
-String stringify(ADL_helper, bool in);
-String stringify(ADL_helper, float in);
-String stringify(ADL_helper, double in);
-String stringify(ADL_helper, double long in);
-
-String stringify(ADL_helper, char in);
-String stringify(ADL_helper, char unsigned in);
-String stringify(ADL_helper, short int in);
-String stringify(ADL_helper, short int unsigned in);
-String stringify(ADL_helper, int in);
-String stringify(ADL_helper, int unsigned in);
-String stringify(ADL_helper, long int in);
-String stringify(ADL_helper, long int unsigned in);
-
-template <typename T>
-String stringify(ADL_helper, T* in) {
- return stringify(doctest::ADL_helper(), static_cast<const void*>(in));
-}
-
namespace detail
{
+ namespace has_insertion_operator_impl
+ {
+ typedef char no;
+ typedef char yes[2];
+
+ template <bool>
+ struct static_assertion;
+
+ template <>
+ struct static_assertion<true>
+ {};
+
+ template <bool in>
+ void f() {
+ static_assertion<in>();
+ }
+
+ struct any_t
+ {
+ template <typename T>
+ any_t(T const&) {
+ f<false>();
+ }
+ };
+
+ yes& test(std::ostream&);
+ no test(no);
+
+ template <typename T>
+ struct has_insertion_operator
+ {
+ static std::ostream& s;
+ static T const& t;
+ static bool const value = sizeof(test(s << t)) == sizeof(yes);
+ };
+ } // namespace has_insertion_operator_impl
+
+ template <typename T>
+ struct has_insertion_operator : has_insertion_operator_impl::has_insertion_operator<T>
+ {};
+
+ // enable_if for c++98
+ template <bool, typename T = void>
+ struct my_enable_if
+ {};
+
+ template <typename T>
+ struct my_enable_if<true, T>
+ { typedef T value; };
+
+ std::ostream* createStream();
+ String getStreamResult(std::ostream*);
+ void freeStream(std::ostream*);
+
+ template <class T>
+ typename my_enable_if<has_insertion_operator<T>::value, String>::value stringify(const T& in) {
+ std::ostream* stream = createStream();
+ *stream << in;
+ String result = getStreamResult(stream);
+ freeStream(stream);
+ return result;
+ }
+
+ template <class T>
+ typename my_enable_if<!has_insertion_operator<T>::value, String>::value stringify(const T&) {
+ return "{?}";
+ }
+
// the function type this library works with
typedef void (*funcType)(void);
+ struct TestFailureException
+ {};
+
+ void checkIfShouldThrow(const char* assert_name);
+ void throwException();
+ bool always_false();
+ void* getNullPtr();
+
// a struct defining a registered test callback
struct TestData
{
@@ -222,14 +293,6 @@
bool operator==(const TestData& other) const;
};
- struct TestFailureException
- {};
-
- void checkIfShouldThrow(const char* assert_name);
- void throwException();
- bool always_false();
- void* getNullPtr();
-
template <class T>
class Vector
{
@@ -312,8 +375,7 @@
template <typename L, typename R>
String stringifyBinaryExpr(const L& lhs, const char* op, const R& rhs) {
- return stringify(doctest::ADL_helper(), lhs) + " " + op + " " +
- stringify(doctest::ADL_helper(), rhs);
+ return stringify(lhs) + " " + op + " " + stringify(rhs);
}
// TODO: think about this
@@ -366,7 +428,7 @@
Expression_lhs(const Expression_lhs& other)
: lhs(other.lhs) {}
- operator Result() { return Result(!!lhs, stringify(doctest::ADL_helper(), lhs)); }
+ operator Result() { return Result(!!lhs, stringify(lhs)); }
// clang-format off
template <typename R> Result operator==(const R& rhs) { return Result(lhs == rhs, stringifyBinaryExpr(lhs, "==", rhs)); }
@@ -507,6 +569,52 @@
// if registering is not disabled
#if !defined(DOCTEST_CONFIG_DISABLE)
+//std::ostream& operator<<(std::ostream&, bool val);
+
+//template int function_name<int>(int);
+
+// in the global namespace - for details see this - http://stackoverflow.com/questions/37139784/
+doctest::detail::has_insertion_operator_impl::no operator<<(std::ostream&, const doctest::detail::has_insertion_operator_impl::any_t&);
+
+template doctest::String doctest::detail::stringify<bool>(const bool&);
+
+
+//static int crap
+
+//std::ostream& operator<< (std::ostream&, short val);
+//std::ostream& operator<< (std::ostream&, unsigned short val);
+//std::ostream& operator<< (std::ostream&, int val);
+//std::ostream& operator<< (std::ostream&, unsigned int val);
+//std::ostream& operator<< (std::ostream&, long val);
+//std::ostream& operator<< (std::ostream&, unsigned long val);
+//std::ostream& operator<< (std::ostream&, float val);
+//std::ostream& operator<< (std::ostream&, double val);
+//std::ostream& operator<< (std::ostream&, long double val);
+//std::ostream& operator<< (std::ostream&, void* val);
+
+//std::ostream& operator<<(std::ostream&, const char*);
+
+
+
+//std::ostream& operator<<(std::ostream&, bool);
+//std::ostream& operator<<(std::ostream&, int);
+
+//String stringify(ADL_helper, const char* in);
+//String stringify(ADL_helper, const void* in);
+//String stringify(ADL_helper, bool in);
+//String stringify(ADL_helper, float in);
+//String stringify(ADL_helper, double in);
+//String stringify(ADL_helper, double long in);
+//
+//String stringify(ADL_helper, char in);
+//String stringify(ADL_helper, char unsigned in);
+//String stringify(ADL_helper, short int in);
+//String stringify(ADL_helper, short int unsigned in);
+//String stringify(ADL_helper, int in);
+//String stringify(ADL_helper, int unsigned in);
+//String stringify(ADL_helper, long int in);
+//String stringify(ADL_helper, long int unsigned in);
+
// registers the test by initializing a dummy var with a function
#if defined(__GNUC__) && !defined(__clang__)
#define DOCTEST_REGISTER_FUNCTION(f, name) \
@@ -868,6 +976,16 @@
#include <ctime> // time stuff
#include <cstring> // strcpy, strtok, strrchr, strncmp
#include <new> // placement new (can be skipped if the containers require 'construct()' from T)
+#include <sstream> // ostream, ostringstream
+
+//std::ostream& operator<<(std::ostream& s, const char*) {
+// //s << in;
+// return s;
+//}
+
+std::ostream& operator<<(std::ostream& s, bool in) {
+ return s.operator<<(in);
+}
// the number of buckets used for the hash set
#if !defined(DOCTEST_HASH_TABLE_NUM_BUCKETS)
@@ -913,91 +1031,15 @@
// main namespace of the library
namespace doctest
{
-String stringify(ADL_helper, const char* in) { return String("\"") + in + "\""; }
-
-String stringify(ADL_helper, const void* in) {
- char buf[64];
- sprintf(buf, "0x%p", in);
- return buf;
-}
-
-String stringify(ADL_helper, bool in) { return in ? "true" : "false"; }
-
-String stringify(ADL_helper, float in) {
- char buf[64];
- sprintf(buf, "%f", static_cast<double>(in));
- return buf;
-}
-
-String stringify(ADL_helper, double in) {
- char buf[64];
- sprintf(buf, "%f", in);
- return buf;
-}
-
-String stringify(ADL_helper, double long in) {
- char buf[64];
- sprintf(buf, "%Lf", in);
- return buf;
-}
-
-String stringify(ADL_helper, char in) {
- char buf[64];
- if(in < ' ')
- sprintf(buf, "%d", in);
- else
- sprintf(buf, "%c", in);
- return buf;
-}
-
-String stringify(ADL_helper, char unsigned in) {
- char buf[64];
- if(in < ' ')
- sprintf(buf, "%ud", in);
- else
- sprintf(buf, "%c", in);
- return buf;
-}
-
-String stringify(ADL_helper, short int in) {
- char buf[64];
- sprintf(buf, "%d", in);
- return buf;
-}
-
-String stringify(ADL_helper, short int unsigned in) {
- char buf[64];
- sprintf(buf, "%u", in);
- return buf;
-}
-
-String stringify(ADL_helper, int in) {
- char buf[64];
- sprintf(buf, "%d", in);
- return buf;
-}
-
-String stringify(ADL_helper, int unsigned in) {
- char buf[64];
- sprintf(buf, "%u", in);
- return buf;
-}
-
-String stringify(ADL_helper, long int in) {
- char buf[64];
- sprintf(buf, "%ld", in);
- return buf;
-}
-
-String stringify(ADL_helper, long int unsigned in) {
- char buf[64];
- sprintf(buf, "%lu", in);
- return buf;
-}
-
// library internals namespace
namespace detail
{
+ std::ostream* createStream() { return new std::ostringstream(); }
+ String getStreamResult(std::ostream* in) {
+ return static_cast<std::ostringstream*>(in)->str().c_str();
+ }
+ void freeStream(std::ostream* in) { delete in; }
+
bool TestData::operator==(const TestData& other) const {
return m_line == other.m_line && strcmp(m_file, other.m_file) == 0;
}
@@ -1979,7 +2021,7 @@
// allows the user to override procedurally the int/bool options from the command line
void Context::setOption(const char* option, int value) {
- setOption(option, stringify(doctest::ADL_helper(), value).c_str());
+ setOption(option, detail::stringify(value).c_str());
}
// allows the user to override procedurally the string options from the command line
diff --git a/examples/dev_testing/main.cpp b/examples/dev_testing/main.cpp
index c62d80f..150f857 100644
--- a/examples/dev_testing/main.cpp
+++ b/examples/dev_testing/main.cpp
@@ -6,6 +6,35 @@
#include <cstdio>
#include <cstdlib>
+#include <vector>
+
+//template <typename T>
+//std::ostream& operator<<(std::ostream& s, const std::vector<T>& in) {
+// s << "[";
+// for(size_t i = 0; i < in.size(); ++i)
+// if(i < in.size() - 1)
+// s << in[i] << ", ";
+// else
+// s << in[i];
+// s << "]";
+// return s;
+//}
+//
+//TEST_CASE("zzz") {
+// //CHECK(std::string("OMG2") == std::string("OMG"));
+//
+// std::vector<int> vec1;
+// vec1.push_back(1);
+// vec1.push_back(2);
+// vec1.push_back(3);
+//
+// std::vector<int> vec2;
+// vec2.push_back(1);
+// vec2.push_back(2);
+// vec2.push_back(4);
+//
+// CHECK(vec1 == vec2);
+//}
int main(int argc, char** argv) {
// initialize
diff --git a/examples/dev_testing/test.cpp b/examples/dev_testing/test.cpp
index a16ee74..86f46d2 100644
--- a/examples/dev_testing/test.cpp
+++ b/examples/dev_testing/test.cpp
@@ -7,22 +7,18 @@
#include <exception>
#include <string>
#include <vector>
-
-namespace doctest
-{
-template <>
-String stringify(ADL_helper, const std::string& in) {
- return String("\"") + in.c_str() + "\"";
-}
-
-template <typename T>
-String stringify(ADL_helper, const std::vector<T>& in) {
- String out("vector[");
- for(unsigned i = 0; i < in.size(); ++i)
- out += stringify(ADL_helper(), in[i]) + (i + 1 == in.size() ? "]" : ", ");
- return out;
-}
-} // namespace doctest
+//#include <ostream>
+//template <typename T>
+//std::ostream& operator<<(std::ostream& s, const std::vector<T>& in) {
+// s << "[";
+// for(size_t i = 0; i < in.size(); ++i)
+// if(i < in.size() - 1)
+// s << in[i] << ", ";
+// else
+// s << in[i];
+// s << "]";
+// return s;
+//}
TEST_SUITE("MAIN");
TEST_CASE("zzz") {
@@ -39,9 +35,9 @@
vec2.push_back(4);
CHECK(vec1 == vec2);
- CHECK(vec1 == vec2);
+ //CHECK(vec1 == vec2);
- //REQUIRE(true == false);
+ REQUIRE(true == false);
//
//printf("main\n");
//SUBCASE("") {
@@ -75,9 +71,9 @@
void nothrows() {}
TEST_CASE("zzz") {
- int a = 5;
- int b = 5;
- CHECK(&a == &b);
+ //int a = 5;
+ //int b = 5;
+ //CHECK(&a == &b);
CHECK(1);
diff --git a/examples/trololo/CMakeLists.txt b/examples/trololo/CMakeLists.txt
deleted file mode 100644
index f1edc80..0000000
--- a/examples/trololo/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8)
-
-get_filename_component(PROJECT_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
-project(${PROJECT_NAME})
-
-include(../../scripts/common.cmake)
-
-# suppress all warnings because this is not a real example of using the library
-if(MSVC)
- add_compiler_flags(/w)
-else()
- add_compiler_flags(-w)
-endif()
-
-include_directories("../../doctest/")
-
-add_executable(${PROJECT_NAME} main.cpp test.cpp)
-
-add_test(NAME ${PROJECT_NAME} COMMAND $<TARGET_FILE:${PROJECT_NAME}> -dt-count=1)
diff --git a/examples/trololo/in.h b/examples/trololo/in.h
deleted file mode 100644
index 028e8da..0000000
--- a/examples/trololo/in.h
+++ /dev/null
@@ -1,114 +0,0 @@
-#pragma once
-
-class String
-{
- char* m_str;
-
- void copy(const String& other);
-
-public:
- String(const char* in = "");
- String(const String& other);
- ~String();
-
- String& operator=(const String& other);
-
- String operator+(const String& other) const;
- String& operator+=(const String& other);
-
- char& operator[](unsigned pos) { return m_str[pos]; }
- const char& operator[](unsigned pos) const { return m_str[pos]; }
-
- char* c_str() { return m_str; }
- const char* c_str() const { return m_str; }
-};
-
-#ifdef __clang__
-#include <ciso646>
-#endif // __clang__
-
-#ifdef _LIBCPP_VERSION
-#include <iosfwd>
-#else // _LIBCPP_VERSION
-#ifndef DOCTEST_CONFIG_USE_IOSFWD
-namespace std
-{
-template <class charT>
-struct char_traits;
-template <>
-struct char_traits<char>;
-template <class charT, class traits>
-class basic_ostream;
-typedef basic_ostream<char, char_traits<char> > ostream;
-}
-#else // DOCTEST_CONFIG_USE_IOSFWD
-#include <iosfwd>
-#endif // DOCTEST_CONFIG_USE_IOSFWD
-#endif // _LIBCPP_VERSION
-
-namespace has_insertion_operator_impl
-{
-typedef char no;
-typedef char yes[2];
-
-template <bool>
-struct static_assertion;
-
-template <>
-struct static_assertion<true>
-{};
-
-template <bool in>
-void f() {
- static_assertion<in>(); }
-
- struct any_t {
- template <typename T>
- any_t(T const&) {
- f<false>();
- }
- };
-}
-has_insertion_operator_impl::no operator<<(std::ostream const&, has_insertion_operator_impl::any_t const&);
-namespace has_insertion_operator_impl {
- yes& test(std::ostream&);
- no test(no);
-
- template <typename T>
- struct has_insertion_operator
- {
- static std::ostream& s;
- static T const& t;
- static bool const value = sizeof(test(s << t)) == sizeof(yes);
- };
-} // namespace has_insertion_operator_impl
-
-template <typename T>
-struct has_insertion_operator : has_insertion_operator_impl::has_insertion_operator<T>
-{};
-
-template <bool, typename T = void>
-struct my_enable_if
-{};
-
-template <typename T>
-struct my_enable_if<true, T>
-{ typedef T value; };
-
-std::ostream* createStream();
-String getStreamResult(std::ostream*);
-void freeStream(std::ostream*);
-
-template <class T>
-typename my_enable_if<has_insertion_operator<T>::value, String>::value stringify(const T& in) {
- std::ostream* stream = createStream();
- *stream << in;
- String result = getStreamResult(stream);
- freeStream(stream);
- return result;
-}
-
-template <class T>
-typename my_enable_if<!has_insertion_operator<T>::value, String>::value stringify(const T&) {
- return "{?}";
-}
diff --git a/examples/trololo/main.cpp b/examples/trololo/main.cpp
deleted file mode 100644
index f1e2b07..0000000
--- a/examples/trololo/main.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-#include "in.h"
-#include <sstream>
-#include <cstdlib>
-#include <cstring>
-
-
-String::String(const char* in) {
- m_str = static_cast<char*>(malloc(strlen(in) + 1));
- strcpy(m_str, in);
-}
-
-String::String(const String& other)
- : m_str(0) {
- copy(other);
-}
-
-void String::copy(const String& other) {
- if (m_str)
- free(m_str);
- m_str = 0;
-
- if (other.m_str) {
- m_str = static_cast<char*>(malloc(strlen(other.m_str) + 1));
- strcpy(m_str, other.m_str);
- }
-}
-
-String::~String() {
- if (m_str)
- free(m_str);
-}
-
-String& String::operator=(const String& other) {
- if (this != &other)
- copy(other);
- return *this;
-}
-
-String String::operator+(const String& other) const { return String(m_str) += other; }
-
-String& String::operator+=(const String& other) {
- if (m_str == 0) {
- copy(other);
- }
- else if (other.m_str != 0) {
- char* newStr = static_cast<char*>(malloc(strlen(m_str) + strlen(other.m_str) + 1));
- strcpy(newStr, m_str);
- strcpy(newStr + strlen(m_str), other.m_str);
- free(m_str);
- m_str = newStr;
- }
- return *this;
-}
-
-std::ostream* createStream() { return new std::ostringstream(); }
-String getStreamResult(std::ostream* in) { return static_cast<std::ostringstream*>(in)->str().c_str(); }
-void freeStream(std::ostream* in) { delete in; }
-
-int main() {
- void f();
- f();
-
- //std::cout << "omg";
-
- system("pause");
-
- return 0;
-}
diff --git a/examples/trololo/test.cpp b/examples/trololo/test.cpp
deleted file mode 100644
index f07e2df..0000000
--- a/examples/trololo/test.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-#include "in.h"
-
-#include <vector>
-#include <iostream>
-
-
-
-struct myType {};
-struct myType2 {};
-std::ostream& operator<<(std::ostream& s, const myType&) { s << "myType"; return s; }
-
-
-
-
-
-template<typename T>
-std::ostream& operator<<(std::ostream& s, const std::vector<T>& in) { s << "vector<T>"; return s; }
-
-void f() {
- myType a; std::cout << stringify(a).c_str() << std::endl;
- std::cout << stringify(6).c_str() << std::endl;
- std::vector<int> v(5); std::cout << stringify(v).c_str() << std::endl;
-
-
- //std::cout << myType2();
-}
diff --git a/examples/type_reporting/main.cpp b/examples/type_reporting/main.cpp
index a9dc7ec..0901e3c 100644
--- a/examples/type_reporting/main.cpp
+++ b/examples/type_reporting/main.cpp
@@ -3,21 +3,19 @@
#include <string>
#include <vector>
+#include <ostream>
-namespace doctest
-{
- static String stringify(ADL_helper, const std::string& in) {
- return String("\"") + in.c_str() + "\"";
- }
-
- template <typename T>
- String stringify(ADL_helper, const std::vector<T>& in) {
- String out("vector[");
- for(unsigned i = 0; i < in.size(); ++i)
- out += stringify(ADL_helper(), in[i]) + (i + 1 == in.size() ? "]" : ", ");
- return out;
- }
-} // namespace doctest
+template <typename T>
+std::ostream& operator<<(std::ostream& s, const std::vector<T>& in) {
+ s << "[";
+ for(size_t i = 0; i < in.size(); ++i)
+ if(i < in.size() - 1)
+ s << in[i] << ", ";
+ else
+ s << in[i];
+ s << "]";
+ return s;
+}
TEST_CASE("the only test") {
std::string dummy1 = "omg";