First draft
diff --git a/doctest/doctest.h b/doctest/doctest.h
index 71b7d1c..9629181 100644
--- a/doctest/doctest.h
+++ b/doctest/doctest.h
@@ -904,16 +904,6 @@
     DOCTEST_INTERFACE std::ostream* tlssPush();
     DOCTEST_INTERFACE String tlssPop();
 
-
-    template <bool C>
-    struct StringMakerBase
-    {
-        template <typename T>
-        static String convert(const DOCTEST_REF_WRAP(T)) {
-            return "{?}";
-        }
-    };
-
     // Vector<int> and various type other than pointer or array.
     template<typename T>
     struct filldata
@@ -923,22 +913,29 @@
         }
     };
 
-    template<typename T,unsigned long N>
+    template<typename T, unsigned long N>
     struct filldata<T[N]>
     {
         static void fill(std::ostream* stream, const T (&in)[N]) {
+            *stream << "[";
             for (unsigned long i = 0; i < N; i++) {
+                if (i != 0) { *stream << ", "; }
                 *stream << in[i];
             }
+            *stream << "]";
         }
     };
 
+    // "forward declaration" for ostream::write
+    DOCTEST_INTERFACE void writeChars(std::ostream* stream, const char* cstr, unsigned long count);
+
     // Specialized since we don't want the terminating null byte!
     template<unsigned long N>
     struct filldata<const char[N]>
     {
         static void fill(std::ostream* stream, const char(&in)[N]) {
-            *stream << in;
+            // Cut off 0 byte if null-terminated
+            writeChars(stream, in, in[N-1] == '\0' ? N-1 : N);
         }
     };
 
@@ -947,31 +944,13 @@
         filldata<T>::fill(stream, in);
     }
 
-    template<typename T,unsigned long N>
+    template<typename T, unsigned long N>
     void filloss(std::ostream* stream, const T (&in)[N]) {
         // T[N], T(&)[N], T(&&)[N] have same behaviour.
         // Hence remove reference.
         filldata<typename remove_reference<decltype(in)>::type>::fill(stream, in);
     }
 
-    template <>
-    struct StringMakerBase<true>
-    {
-        template <typename T>
-        static String convert(const DOCTEST_REF_WRAP(T) in) {
-            /* When parameter "in" is a null terminated const char* it works.
-             * When parameter "in" is a T arr[N] without '\0' we can fill the
-             * stringstream with N objects (T=char).If in is char pointer *
-             * without '\0' , it would cause segfault
-             * stepping over unaccessible memory.
-             */
-
-            std::ostream* stream = tlssPush();
-            filloss(stream, in);
-            return tlssPop();
-        }
-    };
-
     DOCTEST_INTERFACE String rawMemoryToString(const void* object, unsigned size);
 
     template <typename T>
@@ -985,34 +964,65 @@
     }
 } // namespace detail
 
-template <typename T>
-struct StringMaker : public detail::StringMakerBase<detail::has_insertion_operator<T>::value>
-{};
+namespace detail {
+    template <bool C>
+    struct StringStreamBase
+    {
+        template <typename T>
+        static void convert(std::ostream* s, const T&) {
+            *s << "{?}";
+        }
 
-template <typename T>
-struct StringMaker<T*>
-{
-    template <typename U>
-    static String convert(U* p) {
-        if(p)
-            return detail::rawMemoryToString(p);
-        return "NULL";
-    }
-};
+        // always treat char* as a string in this context - no matter
+        // if DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING is defined
+        static void convert(std::ostream* s, const char* in) { *s << String(in); }
+    };
 
-template <typename R, typename C>
-struct StringMaker<R C::*>
-{
-    static String convert(R C::*p) {
-        if(p)
-            return detail::rawMemoryToString(p);
-        return "NULL";
+    template <>
+    struct StringStreamBase<true>
+    {
+        template <typename T>
+        static void convert(std::ostream* s, const T& in) {
+            filloss(s, in);
+        }
+    };
+
+    template <typename T>
+    struct StringStream : public StringStreamBase<has_insertion_operator<T>::value>
+    {};
+
+    template <typename T>
+    void toStream(std::ostream* s, const T& value) {
+        StringStream<T>::convert(s, value);
     }
-};
+
+#ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
+    DOCTEST_INTERFACE void toStream(std::ostream* s, char* in);
+    DOCTEST_INTERFACE void toStream(std::ostream* s, const char* in);
+#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
+    DOCTEST_INTERFACE void toStream(std::ostream* s, bool in);
+    DOCTEST_INTERFACE void toStream(std::ostream* s, float in);
+    DOCTEST_INTERFACE void toStream(std::ostream* s, double in);
+    DOCTEST_INTERFACE void toStream(std::ostream* s, double long in);
+
+    DOCTEST_INTERFACE void toStream(std::ostream* s, char in);
+    DOCTEST_INTERFACE void toStream(std::ostream* s, char signed in);
+    DOCTEST_INTERFACE void toStream(std::ostream* s, char unsigned in);
+    DOCTEST_INTERFACE void toStream(std::ostream* s, int short in);
+    DOCTEST_INTERFACE void toStream(std::ostream* s, int short unsigned in);
+    DOCTEST_INTERFACE void toStream(std::ostream* s, int in);
+    DOCTEST_INTERFACE void toStream(std::ostream* s, int unsigned in);
+    DOCTEST_INTERFACE void toStream(std::ostream* s, int long in);
+    DOCTEST_INTERFACE void toStream(std::ostream* s, int long unsigned in);
+    DOCTEST_INTERFACE void toStream(std::ostream* s, int long long in);
+    DOCTEST_INTERFACE void toStream(std::ostream* s, int long long unsigned in);
+}
 
 template <typename T, typename detail::enable_if<!detail::is_enum<T>::value, bool>::type = true>
 String toString(const DOCTEST_REF_WRAP(T) value) {
-    return StringMaker<T>::convert(value);
+    std::ostream* stream = detail::tlssPush();
+    detail::toStream(stream, value);
+    return detail::tlssPop();
 }
 
 #ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
@@ -1664,58 +1674,6 @@
 
     DOCTEST_INTERFACE void registerExceptionTranslatorImpl(const IExceptionTranslator* et);
 
-    template <bool C>
-    struct StringStreamBase
-    {
-        template <typename T>
-        static void convert(std::ostream* s, const T& in) {
-            *s << toString(in);
-        }
-
-        // always treat char* as a string in this context - no matter
-        // if DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING is defined
-        static void convert(std::ostream* s, const char* in) { *s << String(in); }
-    };
-
-    template <>
-    struct StringStreamBase<true>
-    {
-        template <typename T>
-        static void convert(std::ostream* s, const T& in) {
-            *s << in;
-        }
-    };
-
-    template <typename T>
-    struct StringStream : public StringStreamBase<has_insertion_operator<T>::value>
-    {};
-
-    template <typename T>
-    void toStream(std::ostream* s, const T& value) {
-        StringStream<T>::convert(s, value);
-    }
-
-#ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
-    DOCTEST_INTERFACE void toStream(std::ostream* s, char* in);
-    DOCTEST_INTERFACE void toStream(std::ostream* s, const char* in);
-#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
-    DOCTEST_INTERFACE void toStream(std::ostream* s, bool in);
-    DOCTEST_INTERFACE void toStream(std::ostream* s, float in);
-    DOCTEST_INTERFACE void toStream(std::ostream* s, double in);
-    DOCTEST_INTERFACE void toStream(std::ostream* s, double long in);
-
-    DOCTEST_INTERFACE void toStream(std::ostream* s, char in);
-    DOCTEST_INTERFACE void toStream(std::ostream* s, char signed in);
-    DOCTEST_INTERFACE void toStream(std::ostream* s, char unsigned in);
-    DOCTEST_INTERFACE void toStream(std::ostream* s, int short in);
-    DOCTEST_INTERFACE void toStream(std::ostream* s, int short unsigned in);
-    DOCTEST_INTERFACE void toStream(std::ostream* s, int in);
-    DOCTEST_INTERFACE void toStream(std::ostream* s, int unsigned in);
-    DOCTEST_INTERFACE void toStream(std::ostream* s, int long in);
-    DOCTEST_INTERFACE void toStream(std::ostream* s, int long unsigned in);
-    DOCTEST_INTERFACE void toStream(std::ostream* s, int long long in);
-    DOCTEST_INTERFACE void toStream(std::ostream* s, int long long unsigned in);
-
     // ContextScope base class used to allow implementing methods of ContextScope 
     // that don't depend on the template parameter in doctest.cpp.
     class DOCTEST_INTERFACE ContextScopeBase : public IContextScope {
@@ -3195,6 +3153,10 @@
 } // namespace
 
 namespace detail {
+    void writeChars(std::ostream* stream, const char* cstr, unsigned long count) {
+        stream->write(cstr, count);
+    }
+
     String rawMemoryToString(const void* object, unsigned size) {
         // Reverse order for little endian architectures
         int i = 0, end = static_cast<int>(size), inc = 1;
diff --git a/doctest/parts/doctest.cpp b/doctest/parts/doctest.cpp
index 30ac73b..945c596 100644
--- a/doctest/parts/doctest.cpp
+++ b/doctest/parts/doctest.cpp
@@ -235,6 +235,10 @@
 } // namespace
 
 namespace detail {
+    void writeChars(std::ostream* stream, const char* cstr, unsigned long count) {
+        stream->write(cstr, count);
+    }
+
     String rawMemoryToString(const void* object, unsigned size) {
         // Reverse order for little endian architectures
         int i = 0, end = static_cast<int>(size), inc = 1;
diff --git a/doctest/parts/doctest_fwd.h b/doctest/parts/doctest_fwd.h
index e326947..af74b63 100644
--- a/doctest/parts/doctest_fwd.h
+++ b/doctest/parts/doctest_fwd.h
@@ -901,16 +901,6 @@
     DOCTEST_INTERFACE std::ostream* tlssPush();
     DOCTEST_INTERFACE String tlssPop();
 
-
-    template <bool C>
-    struct StringMakerBase
-    {
-        template <typename T>
-        static String convert(const DOCTEST_REF_WRAP(T)) {
-            return "{?}";
-        }
-    };
-
     // Vector<int> and various type other than pointer or array.
     template<typename T>
     struct filldata
@@ -920,22 +910,29 @@
         }
     };
 
-    template<typename T,unsigned long N>
+    template<typename T, unsigned long N>
     struct filldata<T[N]>
     {
         static void fill(std::ostream* stream, const T (&in)[N]) {
+            *stream << "[";
             for (unsigned long i = 0; i < N; i++) {
+                if (i != 0) { *stream << ", "; }
                 *stream << in[i];
             }
+            *stream << "]";
         }
     };
 
+    // "forward declaration" for ostream::write
+    DOCTEST_INTERFACE void writeChars(std::ostream* stream, const char* cstr, unsigned long count);
+
     // Specialized since we don't want the terminating null byte!
     template<unsigned long N>
     struct filldata<const char[N]>
     {
         static void fill(std::ostream* stream, const char(&in)[N]) {
-            *stream << in;
+            // Cut off 0 byte if null-terminated
+            writeChars(stream, in, in[N-1] == '\0' ? N-1 : N);
         }
     };
 
@@ -944,31 +941,13 @@
         filldata<T>::fill(stream, in);
     }
 
-    template<typename T,unsigned long N>
+    template<typename T, unsigned long N>
     void filloss(std::ostream* stream, const T (&in)[N]) {
         // T[N], T(&)[N], T(&&)[N] have same behaviour.
         // Hence remove reference.
         filldata<typename remove_reference<decltype(in)>::type>::fill(stream, in);
     }
 
-    template <>
-    struct StringMakerBase<true>
-    {
-        template <typename T>
-        static String convert(const DOCTEST_REF_WRAP(T) in) {
-            /* When parameter "in" is a null terminated const char* it works.
-             * When parameter "in" is a T arr[N] without '\0' we can fill the
-             * stringstream with N objects (T=char).If in is char pointer *
-             * without '\0' , it would cause segfault
-             * stepping over unaccessible memory.
-             */
-
-            std::ostream* stream = tlssPush();
-            filloss(stream, in);
-            return tlssPop();
-        }
-    };
-
     DOCTEST_INTERFACE String rawMemoryToString(const void* object, unsigned size);
 
     template <typename T>
@@ -982,34 +961,65 @@
     }
 } // namespace detail
 
-template <typename T>
-struct StringMaker : public detail::StringMakerBase<detail::has_insertion_operator<T>::value>
-{};
+namespace detail {
+    template <bool C>
+    struct StringStreamBase
+    {
+        template <typename T>
+        static void convert(std::ostream* s, const T&) {
+            *s << "{?}";
+        }
 
-template <typename T>
-struct StringMaker<T*>
-{
-    template <typename U>
-    static String convert(U* p) {
-        if(p)
-            return detail::rawMemoryToString(p);
-        return "NULL";
-    }
-};
+        // always treat char* as a string in this context - no matter
+        // if DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING is defined
+        static void convert(std::ostream* s, const char* in) { *s << String(in); }
+    };
 
-template <typename R, typename C>
-struct StringMaker<R C::*>
-{
-    static String convert(R C::*p) {
-        if(p)
-            return detail::rawMemoryToString(p);
-        return "NULL";
+    template <>
+    struct StringStreamBase<true>
+    {
+        template <typename T>
+        static void convert(std::ostream* s, const T& in) {
+            filloss(s, in);
+        }
+    };
+
+    template <typename T>
+    struct StringStream : public StringStreamBase<has_insertion_operator<T>::value>
+    {};
+
+    template <typename T>
+    void toStream(std::ostream* s, const T& value) {
+        StringStream<T>::convert(s, value);
     }
-};
+
+#ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
+    DOCTEST_INTERFACE void toStream(std::ostream* s, char* in);
+    DOCTEST_INTERFACE void toStream(std::ostream* s, const char* in);
+#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
+    DOCTEST_INTERFACE void toStream(std::ostream* s, bool in);
+    DOCTEST_INTERFACE void toStream(std::ostream* s, float in);
+    DOCTEST_INTERFACE void toStream(std::ostream* s, double in);
+    DOCTEST_INTERFACE void toStream(std::ostream* s, double long in);
+
+    DOCTEST_INTERFACE void toStream(std::ostream* s, char in);
+    DOCTEST_INTERFACE void toStream(std::ostream* s, char signed in);
+    DOCTEST_INTERFACE void toStream(std::ostream* s, char unsigned in);
+    DOCTEST_INTERFACE void toStream(std::ostream* s, int short in);
+    DOCTEST_INTERFACE void toStream(std::ostream* s, int short unsigned in);
+    DOCTEST_INTERFACE void toStream(std::ostream* s, int in);
+    DOCTEST_INTERFACE void toStream(std::ostream* s, int unsigned in);
+    DOCTEST_INTERFACE void toStream(std::ostream* s, int long in);
+    DOCTEST_INTERFACE void toStream(std::ostream* s, int long unsigned in);
+    DOCTEST_INTERFACE void toStream(std::ostream* s, int long long in);
+    DOCTEST_INTERFACE void toStream(std::ostream* s, int long long unsigned in);
+}
 
 template <typename T, typename detail::enable_if<!detail::is_enum<T>::value, bool>::type = true>
 String toString(const DOCTEST_REF_WRAP(T) value) {
-    return StringMaker<T>::convert(value);
+    std::ostream* stream = detail::tlssPush();
+    detail::toStream(stream, value);
+    return detail::tlssPop();
 }
 
 #ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
@@ -1661,58 +1671,6 @@
 
     DOCTEST_INTERFACE void registerExceptionTranslatorImpl(const IExceptionTranslator* et);
 
-    template <bool C>
-    struct StringStreamBase
-    {
-        template <typename T>
-        static void convert(std::ostream* s, const T& in) {
-            *s << toString(in);
-        }
-
-        // always treat char* as a string in this context - no matter
-        // if DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING is defined
-        static void convert(std::ostream* s, const char* in) { *s << String(in); }
-    };
-
-    template <>
-    struct StringStreamBase<true>
-    {
-        template <typename T>
-        static void convert(std::ostream* s, const T& in) {
-            *s << in;
-        }
-    };
-
-    template <typename T>
-    struct StringStream : public StringStreamBase<has_insertion_operator<T>::value>
-    {};
-
-    template <typename T>
-    void toStream(std::ostream* s, const T& value) {
-        StringStream<T>::convert(s, value);
-    }
-
-#ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
-    DOCTEST_INTERFACE void toStream(std::ostream* s, char* in);
-    DOCTEST_INTERFACE void toStream(std::ostream* s, const char* in);
-#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING
-    DOCTEST_INTERFACE void toStream(std::ostream* s, bool in);
-    DOCTEST_INTERFACE void toStream(std::ostream* s, float in);
-    DOCTEST_INTERFACE void toStream(std::ostream* s, double in);
-    DOCTEST_INTERFACE void toStream(std::ostream* s, double long in);
-
-    DOCTEST_INTERFACE void toStream(std::ostream* s, char in);
-    DOCTEST_INTERFACE void toStream(std::ostream* s, char signed in);
-    DOCTEST_INTERFACE void toStream(std::ostream* s, char unsigned in);
-    DOCTEST_INTERFACE void toStream(std::ostream* s, int short in);
-    DOCTEST_INTERFACE void toStream(std::ostream* s, int short unsigned in);
-    DOCTEST_INTERFACE void toStream(std::ostream* s, int in);
-    DOCTEST_INTERFACE void toStream(std::ostream* s, int unsigned in);
-    DOCTEST_INTERFACE void toStream(std::ostream* s, int long in);
-    DOCTEST_INTERFACE void toStream(std::ostream* s, int long unsigned in);
-    DOCTEST_INTERFACE void toStream(std::ostream* s, int long long in);
-    DOCTEST_INTERFACE void toStream(std::ostream* s, int long long unsigned in);
-
     // ContextScope base class used to allow implementing methods of ContextScope 
     // that don't depend on the template parameter in doctest.cpp.
     class DOCTEST_INTERFACE ContextScopeBase : public IContextScope {
diff --git a/examples/all_features/stringification.cpp b/examples/all_features/stringification.cpp
index adca1e7..8c0ce48 100644
--- a/examples/all_features/stringification.cpp
+++ b/examples/all_features/stringification.cpp
@@ -2,6 +2,17 @@
 
 #include "header.h"
 
+TEST_CASE("no headers") {
+    char chs1[] = { '1', 'a', 's' };
+    MESSAGE(chs1); CHECK(chs1 == nullptr);
+    const char* chs2{"1as"};
+    MESSAGE(chs2); CHECK(chs2 == nullptr);
+    MESSAGE("1as"); CHECK("1as" == nullptr);
+
+    int ints[] = { 0, 1, 1, 2, 3, 5, 8, 13 };
+    MESSAGE(ints); CHECK(ints == nullptr);
+}
+
 DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN
 #include <string>
 #include <vector>
@@ -18,34 +29,31 @@
 template <typename T>
 ostream& operator<<(ostream& stream, const vector<T>& in) {
     stream << "[";
-    for(size_t i = 0; i < in.size(); ++i)
-        if(i < in.size() - 1)
-            stream << in[i] << ", ";
-        else
-            stream << in[i];
+    for (size_t i = 0; i < in.size(); ++i) {
+        if (i != 0) { stream << ", "; }
+        stream << in[i];
+    }
     stream << "]";
     return stream;
 }
 }
 
 // as an alternative you may write a specialization of doctest::StringMaker
-namespace doctest
-{
+namespace doctest 
+{ namespace detail {
 template <typename T>
-struct StringMaker<std::list<T> >
+struct StringStream<std::list<T>>
 {
-    static String convert(const std::list<T>& in) {
-        std::ostringstream oss;
-
-        oss << "[";
-        for(typename std::list<T>::const_iterator it = in.begin(); it != in.end(); ++it)
-            oss << *it << ", ";
-        oss << "]";
-
-        return oss.str().c_str();
+    static void convert(std::ostream* s, const std::list<T>& in) {
+        *s << "[";
+        for (typename std::list<T>::const_iterator it = in.begin(); it != in.end();) {
+            *s << *it;
+            if (++it != in.end()) { *s << ", "; }
+        }
+        *s << "]";
     }
 };
-}
+} }
 
 template <typename T, typename K>
 struct MyType
@@ -76,8 +84,10 @@
     friend bool operator==(const Foo&, const Foo&) { return false; }
 };
 
-// as a third option you may provide an overload of toString()
-inline doctest::String toString(const Foo&) { return "Foo{}"; }
+std::ostream& operator<<(std::ostream& stream, const Bar::Foo&) {
+    stream << "Foo{}";
+    return stream;
+}
 
 struct MyOtherType
 {
@@ -106,12 +116,15 @@
     bla1.two = 4u;
 
     Bar::Foo f1;
+    MESSAGE(f1);
     Bar::Foo f2;
     CHECK(f1 == f2);
 
     // std::string already has an operator<< working with std::ostream
     std::string dummy = "omg";
 
+    MESSAGE(dummy);
+
     CHECK(dummy == "tralala"); // should fail
     CHECK("tralala" == dummy); // should fail
 
@@ -120,6 +133,8 @@
     vec1.push_back(2);
     vec1.push_back(3);
 
+    MESSAGE(vec1);
+
     std::vector<int> vec2;
     vec2.push_back(1);
     vec2.push_back(2);
@@ -132,6 +147,8 @@
     lst_1.push_back(42);
     lst_1.push_back(3);
 
+    MESSAGE(lst_1);
+
     std::list<int> lst_2;
     lst_2.push_back(1);
     lst_2.push_back(2);
diff --git a/examples/all_features/test_output/filter_2.txt b/examples/all_features/test_output/filter_2.txt
index 662a7e2..8618276 100644
--- a/examples/all_features/test_output/filter_2.txt
+++ b/examples/all_features/test_output/filter_2.txt
@@ -1,6 +1,6 @@
 [doctest] run with "--help" for options
 ===============================================================================
-[doctest] test cases: 0 | 0 passed | 0 failed | 96 skipped
+[doctest] test cases: 0 | 0 passed | 0 failed | 97 skipped
 [doctest] assertions: 0 | 0 passed | 0 failed |
 [doctest] Status: SUCCESS!
 Program code.
diff --git a/examples/all_features/test_output/filter_2_xml.txt b/examples/all_features/test_output/filter_2_xml.txt
index 8764a89..b1342f9 100644
--- a/examples/all_features/test_output/filter_2_xml.txt
+++ b/examples/all_features/test_output/filter_2_xml.txt
@@ -90,6 +90,7 @@
     <TestCase name="namespace 8 friend vs global" filename="namespace8.cpp" line="0" skipped="true"/>
     <TestCase name="namespace 9 both global" filename="namespace9.cpp" line="0" skipped="true"/>
     <TestCase name="no checks" filename="no_failures.cpp" line="0" skipped="true"/>
+    <TestCase name="no headers" filename="stringification.cpp" line="0" skipped="true"/>
     <TestCase name="normal macros" filename="assertion_macros.cpp" line="0" skipped="true"/>
   </TestSuite>
   <TestSuite name="ts1">
@@ -136,6 +137,6 @@
     <TestCase name="will end from an unknown exception" filename="coverage_maxout.cpp" line="0" skipped="true"/>
   </TestSuite>
   <OverallResultsAsserts successes="0" failures="0"/>
-  <OverallResultsTestCases successes="0" failures="0" skipped="96"/>
+  <OverallResultsTestCases successes="0" failures="0" skipped="97"/>
 </doctest>
 Program code.
diff --git a/examples/all_features/test_output/stringification.cpp.txt b/examples/all_features/test_output/stringification.cpp.txt
index 234e806..18f8bca 100644
--- a/examples/all_features/test_output/stringification.cpp.txt
+++ b/examples/all_features/test_output/stringification.cpp.txt
@@ -1,22 +1,54 @@
 [doctest] run with "--help" for options
 ===============================================================================
 stringification.cpp(0):
+TEST CASE:  no headers
+
+stringification.cpp(0): MESSAGE: 1as
+
+stringification.cpp(0): ERROR: CHECK( chs1 == nullptr ) is NOT correct!
+  values: CHECK( 1as == NULL )
+
+stringification.cpp(0): MESSAGE: 1as
+
+stringification.cpp(0): ERROR: CHECK( chs2 == nullptr ) is NOT correct!
+  values: CHECK( 1as == NULL )
+
+stringification.cpp(0): MESSAGE: 1as
+
+stringification.cpp(0): ERROR: CHECK( "1as" == nullptr ) is NOT correct!
+  values: CHECK( 1as == NULL )
+
+stringification.cpp(0): MESSAGE: [0, 1, 1, 2, 3, 5, 8, 13]
+
+stringification.cpp(0): ERROR: CHECK( ints == nullptr ) is NOT correct!
+  values: CHECK( [0, 1, 1, 2, 3, 5, 8, 13] == NULL )
+
+===============================================================================
+stringification.cpp(0):
 TEST CASE:  all asserts should fail and show how the objects get stringified
 
+stringification.cpp(0): MESSAGE: Foo{}
+
 stringification.cpp(0): ERROR: CHECK( f1 == f2 ) is NOT correct!
   values: CHECK( Foo{} == Foo{} )
 
+stringification.cpp(0): MESSAGE: omg
+
 stringification.cpp(0): ERROR: CHECK( dummy == "tralala" ) is NOT correct!
   values: CHECK( omg == tralala )
 
 stringification.cpp(0): ERROR: CHECK( "tralala" == dummy ) is NOT correct!
   values: CHECK( tralala == omg )
 
+stringification.cpp(0): MESSAGE: [1, 2, 3]
+
 stringification.cpp(0): ERROR: CHECK( vec1 == vec2 ) is NOT correct!
   values: CHECK( [1, 2, 3] == [1, 2, 4] )
 
+stringification.cpp(0): MESSAGE: [1, 42, 3]
+
 stringification.cpp(0): ERROR: CHECK( lst_1 == lst_2 ) is NOT correct!
-  values: CHECK( [1, 42, 3, ] == [1, 2, 666, ] )
+  values: CHECK( [1, 42, 3] == [1, 2, 666] )
 
 stringification.cpp(0): ERROR: CHECK( s1 == s2 ) is NOT correct!
   values: CHECK( MyOtherType: 42 == MyOtherType: 666 )
@@ -42,7 +74,7 @@
 stringification.cpp(0): ERROR: test case THREW exception: 5
 
 ===============================================================================
-[doctest] test cases: 2 | 0 passed | 2 failed |
-[doctest] assertions: 9 | 0 passed | 9 failed |
+[doctest] test cases:  3 | 0 passed |  3 failed |
+[doctest] assertions: 13 | 0 passed | 13 failed |
 [doctest] Status: FAILURE!
 Program code.
diff --git a/examples/all_features/test_output/stringification.cpp_junit.txt b/examples/all_features/test_output/stringification.cpp_junit.txt
index a5e39dc..1b2f7f0 100644
--- a/examples/all_features/test_output/stringification.cpp_junit.txt
+++ b/examples/all_features/test_output/stringification.cpp_junit.txt
@@ -1,6 +1,32 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <testsuites>
-  <testsuite name="all_features" errors="2" failures="9" tests="9">
+  <testsuite name="all_features" errors="2" failures="13" tests="13">
+    <testcase classname="stringification.cpp" name="no headers" status="run">
+      <failure message="1as == NULL" type="CHECK">
+stringification.cpp(0):
+CHECK( chs1 == nullptr ) is NOT correct!
+  values: CHECK( 1as == NULL )
+
+      </failure>
+      <failure message="1as == NULL" type="CHECK">
+stringification.cpp(0):
+CHECK( chs2 == nullptr ) is NOT correct!
+  values: CHECK( 1as == NULL )
+
+      </failure>
+      <failure message="1as == NULL" type="CHECK">
+stringification.cpp(0):
+CHECK( "1as" == nullptr ) is NOT correct!
+  values: CHECK( 1as == NULL )
+
+      </failure>
+      <failure message="[0, 1, 1, 2, 3, 5, 8, 13] == NULL" type="CHECK">
+stringification.cpp(0):
+CHECK( ints == nullptr ) is NOT correct!
+  values: CHECK( [0, 1, 1, 2, 3, 5, 8, 13] == NULL )
+
+      </failure>
+    </testcase>
     <testcase classname="stringification.cpp" name="all asserts should fail and show how the objects get stringified" status="run">
       <failure message="Foo{} == Foo{}" type="CHECK">
 stringification.cpp(0):
@@ -26,10 +52,10 @@
   values: CHECK( [1, 2, 3] == [1, 2, 4] )
 
       </failure>
-      <failure message="[1, 42, 3, ] == [1, 2, 666, ]" type="CHECK">
+      <failure message="[1, 42, 3] == [1, 2, 666]" type="CHECK">
 stringification.cpp(0):
 CHECK( lst_1 == lst_2 ) is NOT correct!
-  values: CHECK( [1, 42, 3, ] == [1, 2, 666, ] )
+  values: CHECK( [1, 42, 3] == [1, 2, 666] )
 
       </failure>
       <failure message="MyOtherType: 42 == MyOtherType: 666" type="CHECK">
diff --git a/examples/all_features/test_output/stringification.cpp_xml.txt b/examples/all_features/test_output/stringification.cpp_xml.txt
index 67f6c96..d703781 100644
--- a/examples/all_features/test_output/stringification.cpp_xml.txt
+++ b/examples/all_features/test_output/stringification.cpp_xml.txt
@@ -2,7 +2,67 @@
 <doctest binary="all_features">
   <Options order_by="file" rand_seed="324" first="0" last="4294967295" abort_after="0" subcase_filter_levels="2147483647" case_sensitive="false" no_throw="false" no_skip="false"/>
   <TestSuite>
+    <TestCase name="no headers" filename="stringification.cpp" line="0">
+      <Message type="WARNING" filename="stringification.cpp" line="0">
+        <Text>
+          1as
+        </Text>
+      </Message>
+      <Expression success="false" type="CHECK" filename="stringification.cpp" line="0">
+        <Original>
+          chs1 == nullptr
+        </Original>
+        <Expanded>
+          1as == NULL
+        </Expanded>
+      </Expression>
+      <Message type="WARNING" filename="stringification.cpp" line="0">
+        <Text>
+          1as
+        </Text>
+      </Message>
+      <Expression success="false" type="CHECK" filename="stringification.cpp" line="0">
+        <Original>
+          chs2 == nullptr
+        </Original>
+        <Expanded>
+          1as == NULL
+        </Expanded>
+      </Expression>
+      <Message type="WARNING" filename="stringification.cpp" line="0">
+        <Text>
+          1as
+        </Text>
+      </Message>
+      <Expression success="false" type="CHECK" filename="stringification.cpp" line="0">
+        <Original>
+          "1as" == nullptr
+        </Original>
+        <Expanded>
+          1as == NULL
+        </Expanded>
+      </Expression>
+      <Message type="WARNING" filename="stringification.cpp" line="0">
+        <Text>
+          [0, 1, 1, 2, 3, 5, 8, 13]
+        </Text>
+      </Message>
+      <Expression success="false" type="CHECK" filename="stringification.cpp" line="0">
+        <Original>
+          ints == nullptr
+        </Original>
+        <Expanded>
+          [0, 1, 1, 2, 3, 5, 8, 13] == NULL
+        </Expanded>
+      </Expression>
+      <OverallResultsAsserts successes="0" failures="4" test_case_success="false"/>
+    </TestCase>
     <TestCase name="all asserts should fail and show how the objects get stringified" filename="stringification.cpp" line="0">
+      <Message type="WARNING" filename="stringification.cpp" line="0">
+        <Text>
+          Foo{}
+        </Text>
+      </Message>
       <Expression success="false" type="CHECK" filename="stringification.cpp" line="0">
         <Original>
           f1 == f2
@@ -11,6 +71,11 @@
           Foo{} == Foo{}
         </Expanded>
       </Expression>
+      <Message type="WARNING" filename="stringification.cpp" line="0">
+        <Text>
+          omg
+        </Text>
+      </Message>
       <Expression success="false" type="CHECK" filename="stringification.cpp" line="0">
         <Original>
           dummy == "tralala"
@@ -27,6 +92,11 @@
           tralala == omg
         </Expanded>
       </Expression>
+      <Message type="WARNING" filename="stringification.cpp" line="0">
+        <Text>
+          [1, 2, 3]
+        </Text>
+      </Message>
       <Expression success="false" type="CHECK" filename="stringification.cpp" line="0">
         <Original>
           vec1 == vec2
@@ -35,12 +105,17 @@
           [1, 2, 3] == [1, 2, 4]
         </Expanded>
       </Expression>
+      <Message type="WARNING" filename="stringification.cpp" line="0">
+        <Text>
+          [1, 42, 3]
+        </Text>
+      </Message>
       <Expression success="false" type="CHECK" filename="stringification.cpp" line="0">
         <Original>
           lst_1 == lst_2
         </Original>
         <Expanded>
-          [1, 42, 3, ] == [1, 2, 666, ]
+          [1, 42, 3] == [1, 2, 666]
         </Expanded>
       </Expression>
       <Expression success="false" type="CHECK" filename="stringification.cpp" line="0">
@@ -96,7 +171,7 @@
       <OverallResultsAsserts successes="0" failures="0" test_case_success="false"/>
     </TestCase>
   </TestSuite>
-  <OverallResultsAsserts successes="0" failures="9"/>
-  <OverallResultsTestCases successes="0" failures="2"/>
+  <OverallResultsAsserts successes="0" failures="13"/>
+  <OverallResultsTestCases successes="0" failures="3"/>
 </doctest>
 Program code.
diff --git a/scripts/coverage_maxout.cpp b/scripts/coverage_maxout.cpp
index 8b6e574..2530089 100644
--- a/scripts/coverage_maxout.cpp
+++ b/scripts/coverage_maxout.cpp
@@ -77,21 +77,6 @@
 
     std::ostringstream oss;
 
-    // toStream
-    detail::toStream(&oss, true);
-    detail::toStream(&oss, 0.5f);
-    detail::toStream(&oss, 0.5);
-    detail::toStream(&oss, static_cast<long double>(0.1));
-    detail::toStream(&oss, 'c');
-    detail::toStream(&oss, static_cast<signed char>('c'));
-    detail::toStream(&oss, static_cast<unsigned char>(1));
-    detail::toStream(&oss, static_cast<short>(1));
-    detail::toStream(&oss, static_cast<long>(1));
-    detail::toStream(&oss, static_cast<unsigned long>(1));
-    detail::toStream(&oss, static_cast<unsigned short>(1));
-    detail::toStream(&oss, static_cast<long long>(1));
-    detail::toStream(&oss, static_cast<unsigned long long>(1));
-
     // trigger code path for String to ostream through operator<<
     oss << str;
     // trigger code path for assert string of a non-existent assert type
@@ -102,8 +87,8 @@
 #endif
     str += oss.str().c_str();
     str += failureString(assertType::is_normal);
-    CHECK(str == "omgomgomgaaaNULLtrue00.5f0.50.199991111111true0.50.50.1cc"
-                 "111111omgomgomgaaaNULLtrue00.5f0.50.199991111111");
+    CHECK(str == "omgomgomgaaaNULLtrue00.5f0.50.199991111111"
+                 "omgomgomgaaaNULLtrue00.5f0.50.199991111111");
     // trigger code path for rawMemoryToString
     bool   isThereAnything = str.size() > 0u;
     bool   len_is_zero     = detail::rawMemoryToString(isThereAnything).size() == 0u;