switched from using the << operator to the comma operator for all logging - this solves the problem in PR #431
diff --git a/examples/all_features/logging.cpp b/examples/all_features/logging.cpp
index ba333ea..ddc95d3 100644
--- a/examples/all_features/logging.cpp
+++ b/examples/all_features/logging.cpp
@@ -23,17 +23,18 @@
 
 static int someTests() {
     int some_var = 42;
-    INFO("lots of captures - some on heap: " << some_var << " " << some_var << " " << some_var << ";");
-    FAIL_CHECK("forcing the many captures (including those on the heap) to be stringified");
+    INFO("lots of captures: ", some_var, " ", some_var, " ", some_var, ";");
+    INFO("old way of capturing - using the streaming operator: " << some_var << " " << some_var);
+    FAIL_CHECK("forcing the many captures to be stringified");
     return some_var;
 }
 
 TEST_CASE("a test case that will end from an exception") {
     int some_var = someTests();
-    INFO("someTests() returned: " << some_var); // note that we have to use a local variable - cannot pass a temporary
-    INFO("this should be printed if an exception is thrown even if no assert has failed: " << some_var);
+    INFO("someTests() returned: ", some_var); // note that we have to use a local variable - cannot pass a temporary
+    INFO("this should be printed if an exception is thrown even if no assert has failed: ", some_var);
     {
-        INFO("in a nested scope this should be printed as well: " << some_var);
+        INFO("in a nested scope this should be printed as well: ", some_var);
         {
             INFO("this should not be printed");
             CAPTURE(some_var);
diff --git a/examples/all_features/stringification.cpp b/examples/all_features/stringification.cpp
index abce6bb..d1118cc 100644
--- a/examples/all_features/stringification.cpp
+++ b/examples/all_features/stringification.cpp
@@ -77,6 +77,28 @@
 
 // as a third option you may provide an overload of toString()
 inline doctest::String toString(const Foo&) { return "Foo{}"; }
+
+struct MyStringType
+{
+    std::string s;
+    template <size_t N> MyStringType(const char (&in)[N]) : s(in, in + N) {}
+    friend bool operator==(const MyStringType &lhs, const MyStringType &rhs) { return lhs.s == rhs.s; }
+};
+
+// you can use the stream.write() method to write blocks of characters, and
+// you also can use a template operator<< if your code does not use
+// std::ostream and you'd like to avoid the include
+template <class OStream>
+OStream& operator<<(OStream& stream, const MyStringType& in) {
+    // the terminating \0 character may be present in size()
+    auto size = in.s.size() > 0u ? in.s.size() - 1u : 0u;
+    const char quote = '\'';
+    stream.write(&quote, 1u);
+    stream.write(in.s.data(), static_cast<unsigned>(size));
+    stream.write(&quote, 1u);
+    return stream;
+}
+
 } // namespace Bar
 
 // set an exception translator for MyTypeInherited<int>
@@ -127,6 +149,18 @@
 
     CHECK(lst_1 == lst_2);
 
+    {
+        // use of ostream::write() is possible:
+        Bar::MyStringType s1 = "some";
+        Bar::MyStringType s2 = "contents";
+
+        // also inside the message builder
+        INFO("s1=", s1, " s2=", s2);
+
+        CHECK(s1 == s2);
+        CHECK_MESSAGE(s1 == s2, s1, " is not really ", s2);
+    }
+
     // lets see if this exception gets translated
     throw_if(true, bla1);
 }
diff --git a/examples/all_features/test_output/logging.cpp.txt b/examples/all_features/test_output/logging.cpp.txt
index 5d25396..5c36294 100644
--- a/examples/all_features/test_output/logging.cpp.txt
+++ b/examples/all_features/test_output/logging.cpp.txt
@@ -32,8 +32,9 @@
 logging.cpp(0):
 TEST CASE:  a test case that will end from an exception
 
-logging.cpp(0): ERROR: forcing the many captures (including those on the heap) to be stringified
-  logged: lots of captures - some on heap: 42 42 42;
+logging.cpp(0): ERROR: forcing the many captures to be stringified
+  logged: lots of captures: 42 42 42;
+          old way of capturing - using the streaming operator: 42 42
 
 logging.cpp(0): ERROR: CHECK( some_var == 666 ) is NOT correct!
   values: CHECK( 42 == 666 )
diff --git a/examples/all_features/test_output/logging.cpp_xml.txt b/examples/all_features/test_output/logging.cpp_xml.txt
index a752fc2..6ff2ed9 100644
--- a/examples/all_features/test_output/logging.cpp_xml.txt
+++ b/examples/all_features/test_output/logging.cpp_xml.txt
@@ -78,10 +78,13 @@
     <TestCase name="a test case that will end from an exception" filename="logging.cpp" line="0">
       <Message type="ERROR" filename="logging.cpp" line="0">
         <Text>
-          forcing the many captures (including those on the heap) to be stringified
+          forcing the many captures to be stringified
         </Text>
         <Info>
-          lots of captures - some on heap: 42 42 42;
+          lots of captures: 42 42 42;
+        </Info>
+        <Info>
+          old way of capturing - using the streaming operator: 42 42
         </Info>
       </Message>
       <Expression success="false" type="CHECK" filename="logging.cpp" line="0">
diff --git a/examples/all_features/test_output/stringification.cpp.txt b/examples/all_features/test_output/stringification.cpp.txt
index 2f528f5..40d9f81 100644
--- a/examples/all_features/test_output/stringification.cpp.txt
+++ b/examples/all_features/test_output/stringification.cpp.txt
@@ -15,6 +15,15 @@
 stringification.cpp(0): ERROR: CHECK( lst_1 == lst_2 ) is NOT correct!
   values: CHECK( [1, 42, 3, ] == [1, 2, 666, ] )
 
+stringification.cpp(0): ERROR: CHECK( s1 == s2 ) is NOT correct!
+  values: CHECK( 'some' == 'contents' )
+  logged: s1='some' s2='contents'
+
+stringification.cpp(0): ERROR: CHECK( s1 == s2 ) is NOT correct!
+  values: CHECK( 'some' == 'contents' )
+  logged: s1='some' s2='contents'
+          'some' is not really 'contents'
+
 stringification.cpp(0): ERROR: test case THREW exception: MyTypeInherited<int>(5, 4)
 
 ===============================================================================
@@ -25,6 +34,6 @@
 
 ===============================================================================
 [doctest] test cases: 2 | 0 passed | 2 failed |
-[doctest] assertions: 4 | 0 passed | 4 failed |
+[doctest] assertions: 6 | 0 passed | 6 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 576750a..ab7f3e3 100644
--- a/examples/all_features/test_output/stringification.cpp_junit.txt
+++ b/examples/all_features/test_output/stringification.cpp_junit.txt
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <testsuites>
-  <testsuite name="all_features" errors="2" failures="4" tests="4">
+  <testsuite name="all_features" errors="2" failures="6" tests="6">
     <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,6 +26,21 @@
   values: CHECK( [1, 42, 3, ] == [1, 2, 666, ] )
 
       </failure>
+      <failure message="'some' == 'contents'" type="CHECK">
+stringification.cpp(0):
+CHECK( s1 == s2 ) is NOT correct!
+  values: CHECK( 'some' == 'contents' )
+  logged: s1='some' s2='contents'
+
+      </failure>
+      <failure message="'some' == 'contents'" type="CHECK">
+stringification.cpp(0):
+CHECK( s1 == s2 ) is NOT correct!
+  values: CHECK( 'some' == 'contents' )
+  logged: s1='some' s2='contents'
+          'some' is not really 'contents'
+
+      </failure>
       <error message="exception">
         MyTypeInherited&lt;int>(5, 4)
       </error>
diff --git a/examples/all_features/test_output/stringification.cpp_xml.txt b/examples/all_features/test_output/stringification.cpp_xml.txt
index bf273f3..16e242f 100644
--- a/examples/all_features/test_output/stringification.cpp_xml.txt
+++ b/examples/all_features/test_output/stringification.cpp_xml.txt
@@ -35,10 +35,35 @@
           [1, 42, 3, ] == [1, 2, 666, ]
         </Expanded>
       </Expression>
+      <Expression success="false" type="CHECK" filename="stringification.cpp" line="0">
+        <Original>
+          s1 == s2
+        </Original>
+        <Expanded>
+          'some' == 'contents'
+        </Expanded>
+        <Info>
+          s1='some' s2='contents'
+        </Info>
+      </Expression>
+      <Expression success="false" type="CHECK" filename="stringification.cpp" line="0">
+        <Original>
+          s1 == s2
+        </Original>
+        <Expanded>
+          'some' == 'contents'
+        </Expanded>
+        <Info>
+          s1='some' s2='contents'
+        </Info>
+        <Info>
+          'some' is not really 'contents'
+        </Info>
+      </Expression>
       <Exception crash="false">
         MyTypeInherited&lt;int>(5, 4)
       </Exception>
-      <OverallResultsAsserts successes="0" failures="4"/>
+      <OverallResultsAsserts successes="0" failures="6"/>
     </TestCase>
     <TestCase name="a test case that registers an exception translator for int and then throws one" filename="stringification.cpp" line="0">
       <Exception crash="false">
@@ -47,7 +72,7 @@
       <OverallResultsAsserts successes="0" failures="0"/>
     </TestCase>
   </TestSuite>
-  <OverallResultsAsserts successes="0" failures="4"/>
+  <OverallResultsAsserts successes="0" failures="6"/>
   <OverallResultsTestCases successes="0" failures="2"/>
 </doctest>
 Program code.