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";