$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
From: john.groups_at_[hidden]
Date: 2007-12-29 13:15:09
Author: jtorjo
Date: 2007-12-29 13:15:08 EST (Sat, 29 Dec 2007)
New Revision: 42340
URL: http://svn.boost.org/trac/boost/changeset/42340
Log:
[logging]
v0.12.13, 29 dec 2007
- added tss_ostringstream - allow faster creation of stringstreams (one stringstream per thread)
Added:
   sandbox/logging/boost/logging/detail/tss/tss_ostringstream.hpp   (contents, props changed)
   sandbox/logging/lib/logging/samples/scenarios/use_tss_ostringstream.cpp   (contents, props changed)
Text files modified: 
   sandbox/logging/boost/logging/detail/find_gather.hpp                    |    22 +++++++++++-----------                  
   sandbox/logging/boost/logging/detail/format_msg_type.hpp                |    38 +++++++++++++++++++++++++++++++++++---  
   sandbox/logging/boost/logging/detail/macros.hpp                         |     9 ++++++---                               
   sandbox/logging/boost/logging/detail/raw_doc/changelog.hpp              |     3 ++-                                     
   sandbox/logging/boost/logging/detail/raw_doc/todo.hpp                   |     1 +                                       
   sandbox/logging/boost/logging/detail/ts/ts_resource.hpp                 |     4 ++--                                    
   sandbox/logging/boost/logging/detail/tss/tss.hpp                        |    35 +++++++++++++++++++++++++++++------     
   sandbox/logging/boost/logging/detail/use_format_write.hpp               |     6 +++++-                                  
   sandbox/logging/lib/logging/internal/vc8/loggingvc8/loggingvc8.vcproj   |     9 +++++++++                               
   sandbox/logging/lib/logging/samples/scenarios/mul_levels_one_logger.cpp |     4 ++--                                    
   10 files changed, 102 insertions(+), 29 deletions(-)
Modified: sandbox/logging/boost/logging/detail/find_gather.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/find_gather.hpp	(original)
+++ sandbox/logging/boost/logging/detail/find_gather.hpp	2007-12-29 13:15:08 EST (Sat, 29 Dec 2007)
@@ -54,23 +54,23 @@
     }
 
     namespace detail {
-        template<class param> struct find_gather {};
-        template<> struct find_gather< std::basic_string<char_type> > { typedef gather::ostream_like::return_str< std::basic_string<char_type>, std::basic_ostringstream<char_type> > type ; };
+        template<class stream, class param> struct find_gather {};
+        template<class stream> struct find_gather< stream, std::basic_string<char_type> > { typedef gather::ostream_like::return_str< std::basic_string<char_type>, stream > type ; };
 
-        template< class string_type> 
-        struct find_gather< boost::logging::optimize::cache_string_one_str<string_type> > { 
-            typedef gather::ostream_like::return_str< boost::logging::optimize::cache_string_one_str<string_type>, std::basic_ostringstream<char_type> > type;
+        template< class stream, class string_type> 
+        struct find_gather< stream, boost::logging::optimize::cache_string_one_str<string_type> > { 
+            typedef gather::ostream_like::return_str< boost::logging::optimize::cache_string_one_str<string_type>, stream > type;
         };
 
-        template< class string_type> 
-        struct find_gather< boost::logging::optimize::cache_string_several_str<string_type,void*> > { 
-            typedef gather::ostream_like::return_str< boost::logging::optimize::cache_string_several_str<string_type,void*>, std::basic_ostringstream<char_type> > type;
+        template< class stream, class string_type> 
+        struct find_gather< stream, boost::logging::optimize::cache_string_several_str<string_type,void*> > { 
+            typedef gather::ostream_like::return_str< boost::logging::optimize::cache_string_several_str<string_type,void*>, stream > type;
         };
 
 
-        template<class string, class p1, class p2, class p3, class p4, class p5, class p6, class p7, class p8, class p9, class p10>
-        struct find_gather< tag::holder<string,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10> > {
-            typedef gather::ostream_like::return_tag_holder< tag::holder<string,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10> , std::basic_ostringstream<char_type> > type;
+        template<class stream, class string, class p1, class p2, class p3, class p4, class p5, class p6, class p7, class p8, class p9, class p10>
+        struct find_gather< stream, tag::holder<string,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10> > {
+            typedef gather::ostream_like::return_tag_holder< tag::holder<string,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10> , stream > type;
         };
     }
 
Modified: sandbox/logging/boost/logging/detail/format_msg_type.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/format_msg_type.hpp	(original)
+++ sandbox/logging/boost/logging/detail/format_msg_type.hpp	2007-12-29 13:15:08 EST (Sat, 29 Dec 2007)
@@ -24,7 +24,7 @@
 #include <boost/logging/detail/fwd.hpp>
 #include <boost/logging/detail/find_gather.hpp>
 #include <boost/type_traits/remove_reference.hpp>
-
+#include <boost/logging/detail/tss/tss_ostringstream.hpp>
 
 namespace boost { namespace logging {
 
@@ -42,7 +42,7 @@
 
 namespace destination {
     /** 
-    @brief what is the default type of your string, in formatter_base ? See BOOST_LOG_DESTINATION_MSG
+    @brief what is the default type of your string, in destination_base ? See BOOST_LOG_DESTINATION_MSG
     */
     template<class T = override> struct msg_type {
         // by default  - the default string
@@ -51,6 +51,37 @@
     };
 }
 
+namespace gather {
+    template<class T = override> struct find {
+        template<class msg_type> struct from_msg_type {
+            typedef typename ::boost::logging::detail::find_gather< std::basic_ostringstream<char_type>, msg_type >::type type;
+        };
+    };
+}
+
+
+/** 
+    @brief ... just in case you want to specify the ostringstream for the gather class.
+*/
+template<class ostringstream> struct use_ostringstream { };
+
+namespace detail {
+    // gather - if default -> use find_gather< default, default >
+    //        - if use_ostringstream -> use find_gather< default, ostringstream>
+    //        - else -> use it
+    template<class msg_type, class gather> struct find_gather_from_class {
+        typedef gather type;
+    };
+
+    template<class msg_type> struct find_gather_from_class<msg_type, default_> {
+        typedef typename find_gather< std::basic_ostringstream<char_type>, msg_type >::type type;
+    };
+
+    template<class msg_type, class stream> struct find_gather_from_class<msg_type, use_ostringstream<stream> > {
+        typedef typename find_gather< stream, msg_type >::type type;
+    };
+}
+
 
 /* 
     for when compiling fast, and:
@@ -63,7 +94,8 @@
         typedef typename boost::logging::formatter::msg_type<T>::type msg_type_ref;
         typedef typename boost::remove_reference<msg_type_ref>::type msg_type;
 
-        typedef typename find_gather< msg_type >::type gather_msg;
+        typedef typename ::boost::logging::gather::find<T>::template from_msg_type<msg_type>::type gather_msg;
+        //typedef typename find_gather< std::basic_ostringstream<char_type>, msg_type >::type gather_msg;
         typedef logger< gather_msg, default_ > log_type;
     };
 
Modified: sandbox/logging/boost/logging/detail/macros.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/macros.hpp	(original)
+++ sandbox/logging/boost/logging/detail/macros.hpp	2007-12-29 13:15:08 EST (Sat, 29 Dec 2007)
@@ -603,7 +603,7 @@
     template<> struct msg_type<override> { typedef msg_class & type; typedef msg_class raw_type; }; \
     }}}
 
-/**
+/** @section BOOST_LOG_DESTINATION_MSG BOOST_LOG_DESTINATION_MSG
 
 @note
     When using BOOST_LOG_FORMAT_MSG or BOOST_LOG_DESTINATION_MSG, you must not be within any namespace scope.
@@ -617,8 +617,11 @@
     }}}
 
 
-
-
+#define BOOST_LOG_GATHER_CLASS(gather_class) \
+    namespace boost { namespace logging { namespace gather { \
+        template<> struct find<override> { template<class msg_type> struct from_msg_type { \
+            typedef typename ::boost::logging::detail::find_gather_from_class<msg_type, gather_class > ::type type; }; }; \
+    }}}
 
 
 
Modified: sandbox/logging/boost/logging/detail/raw_doc/changelog.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/raw_doc/changelog.hpp	(original)
+++ sandbox/logging/boost/logging/detail/raw_doc/changelog.hpp	2007-12-29 13:15:08 EST (Sat, 29 Dec 2007)
@@ -1,7 +1,8 @@
 /** 
 @page page_changelog Changelog
 
-_at_section changelog_cur_ver Current Version: v0.12.12, 29 dec 2007
+@section changelog_cur_ver Current Version: v0.12.13, 29 dec 2007
+- added tss_ostringstream - allow faster creation of stringstreams (one stringstream per thread)
 - added destination::named - similar to formatter::named_spacer, but for destinations
 - added possibility to flush a rolling file, and fixed a bug
 - added high precision_time tag
Modified: sandbox/logging/boost/logging/detail/raw_doc/todo.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/raw_doc/todo.hpp	(original)
+++ sandbox/logging/boost/logging/detail/raw_doc/todo.hpp	2007-12-29 13:15:08 EST (Sat, 29 Dec 2007)
@@ -125,6 +125,7 @@
 
 - @c normal         Explain about config files - you can use named_spacer,named.
 
+- @c normal         explain about gather class - how to define (BOOST_LOG_GATHER_CLASS)
 */
 
 }}
Modified: sandbox/logging/boost/logging/detail/ts/ts_resource.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/ts/ts_resource.hpp	(original)
+++ sandbox/logging/boost/logging/detail/ts/ts_resource.hpp	2007-12-29 13:15:08 EST (Sat, 29 Dec 2007)
@@ -242,13 +242,13 @@
 
     private:
         struct cached_value {
-            cached_value(const type & val = type() ) : val(val), is_cached(false) {}
+            cached_value( ) : val( type() ), is_cached(false) {}
             type val;
             bool is_cached;
         };
 
     public:
-        tss_resource_once_init(const type& val = type() ) : m_val(val), m_cache(val), m_initialized(false) {}
+        tss_resource_once_init(const type& val = type() ) : m_val(val), m_initialized(false) {}
 
         struct read;
         struct write;
Modified: sandbox/logging/boost/logging/detail/tss/tss.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/tss/tss.hpp	(original)
+++ sandbox/logging/boost/logging/detail/tss/tss.hpp	2007-12-29 13:15:08 EST (Sat, 29 Dec 2007)
@@ -45,16 +45,40 @@
 
 
 template<class type, template<typename> class thread_specific_ptr_type BOOST_LOG_TSS_DEFAULT_CLASS > struct tss_value {
-    tss_value(const type & default_ ) : m_default( default_), m_use_default(true) {}
-    tss_value() : m_use_default(false) {}
+    tss_value() {}
 
     type * get() const {
         type * result = m_value.get();
         if ( !result) {
 #if defined(BOOST_LOG_TSS_USE_INTERNAL)
-            result = m_use_default ? detail::new_object_ensure_delete<type>(m_default) : detail::new_object_ensure_delete<type>();
+            result = detail::new_object_ensure_delete<type>();
 #else
-            result = m_use_default ? (new type(m_default)) : (new type);
+            result = new type;
+#endif
+            m_value.reset( result );
+        }
+        return result;
+    }
+
+    type* operator->() const { return get(); }
+    type& operator*() const { return *get(); }
+private:
+    mutable thread_specific_ptr_type<type> m_value;
+};
+
+
+
+
+template<class type, template<typename> class thread_specific_ptr_type BOOST_LOG_TSS_DEFAULT_CLASS > struct tss_value_with_default {
+    tss_value_with_default(const type & default_ ) : m_default( default_) {}
+
+    type * get() const {
+        type * result = m_value.get();
+        if ( !result) {
+#if defined(BOOST_LOG_TSS_USE_INTERNAL)
+            result = detail::new_object_ensure_delete<type>(m_default) ;
+#else
+            result = new type(m_default);
 #endif
             m_value.reset( result );
         }
@@ -67,10 +91,9 @@
     mutable thread_specific_ptr_type<type> m_value;
     // the default value - to assign each time a new value is created
     type m_default;
-    // if true, use default, otherwise not
-    bool m_use_default;
 };
 
+
 }}
 
 #endif // !BOOST_LOG_NO_TSS
Added: sandbox/logging/boost/logging/detail/tss/tss_ostringstream.hpp
==============================================================================
--- (empty file)
+++ sandbox/logging/boost/logging/detail/tss/tss_ostringstream.hpp	2007-12-29 13:15:08 EST (Sat, 29 Dec 2007)
@@ -0,0 +1,68 @@
+// tss_stream.hpp
+
+// Boost Logging library
+//
+// Author: John Torjo, www.torjo.com
+//
+// Copyright (C) 2007 John Torjo (see www.torjo.com for email)
+//
+// Distributed under the Boost Software License, Version 1.0.
+//    (See accompanying file LICENSE_1_0.txt or copy at
+//          http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org for updates, documentation, and revision history.
+// See http://www.torjo.com/log2/ for more details
+
+
+#ifndef JT28092007_tss_ostringstream_HPP_DEFINED
+#define JT28092007_tss_ostringstream_HPP_DEFINED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <boost/logging/detail/fwd.hpp>
+#include <boost/logging/detail/tss/tss.hpp>
+#include <sstream>
+
+namespace boost { namespace logging {
+
+/** 
+@brief Represents an ostringstream that takes advantage of TSS (Thread Specific Storage). In other words, each thread has its 
+       own copy of an ostringstream, thus when needed, we avoid the cost of re-creating it (it's created only once per thread).
+*/
+template< class stream = std::basic_ostringstream<char_type> > struct tss_ostringstream {
+    typedef stream stream_type;
+    typedef hold_string_type string_type;
+
+    tss_ostringstream() {}
+    tss_ostringstream(const tss_ostringstream&) {}
+
+
+    stream_type & get() {
+        stream_type & val = *(m_cache.get());
+        val.str( BOOST_LOG_STR("") );
+        return val;
+    }
+
+    string_type str() const { 
+        stream_type & val = *(m_cache.get());
+        return val.str();
+    }
+
+
+private:
+    mutable tss_value<stream_type> m_cache;
+};
+
+template<class stream, class value_type> inline stream& operator<<( tss_ostringstream<stream> & out, const value_type & val) {
+    stream & result = out.get();
+    result << val;
+    return result;
+}
+
+
+}}
+
+#endif
+
Modified: sandbox/logging/boost/logging/detail/use_format_write.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/use_format_write.hpp	(original)
+++ sandbox/logging/boost/logging/detail/use_format_write.hpp	2007-12-29 13:15:08 EST (Sat, 29 Dec 2007)
@@ -84,6 +84,7 @@
 
 
 
+
 template<
             class format_base_type , 
             class destination_base_type ,
@@ -97,7 +98,7 @@
     typedef typename use_default<lock_resource, ::boost::logging::types<override>::lock_resource> ::type lock_resource_type;
 
     typedef typename format_base::raw_param format_param;
-    typedef typename detail::find_gather<format_param>::type gather_type;
+    typedef typename ::boost::logging::gather::find<override>::template from_msg_type<format_param>::type gather_type;
 
     typedef typename detail::find_format_write_params<format_param, format_base, destination_base, lock_resource_type >::apply_format_and_write apply_format_and_write;
     typedef typename detail::find_format_write_params<format_param, format_base, destination_base, lock_resource_type >::router_type router_type;
@@ -117,6 +118,7 @@
 
 @code
 typedef logger_format_write< 
+        format_base, destination_base
         gather::ostream_like::return_str<>, 
         writer::format_write<formatter_base,destination_base> > > logger_type;
 @endcode
@@ -145,6 +147,8 @@
             >::type
     >
 {
+    // FIXME we don't use gather - to define the gather class you use BOOST_LOG_GATHER_CLASS
+
     typedef logger< 
             typename use_format_write<format_base, destination_base, gather, lock_resource>::gather_type,
             typename detail::find_writer_with_thread_safety<
Modified: sandbox/logging/lib/logging/internal/vc8/loggingvc8/loggingvc8.vcproj
==============================================================================
--- sandbox/logging/lib/logging/internal/vc8/loggingvc8/loggingvc8.vcproj	(original)
+++ sandbox/logging/lib/logging/internal/vc8/loggingvc8/loggingvc8.vcproj	2007-12-29 13:15:08 EST (Sat, 29 Dec 2007)
@@ -652,6 +652,10 @@
                                         RelativePath="..\..\..\..\..\boost\logging\detail\tss\tss_impl_win32.hpp"
 					>
                                 </File>
+				<File
+					RelativePath="..\..\..\..\..\boost\logging\detail\tss\tss_ostringstream.hpp"
+					>
+				</File>
                         </Filter>
                         <Filter
                                 Name="tags"
@@ -834,6 +838,7 @@
 				>
                                 <FileConfiguration
                                         Name="Test|Win32"
+					ExcludedFromBuild="true"
 					>
                                         <Tool
                                                 Name="VCCLCompilerTool"
@@ -889,6 +894,10 @@
                                 </FileConfiguration>
                         </File>
                         <File
+				RelativePath="..\..\..\samples\scenarios\use_tss_ostringstream.cpp"
+				>
+			</File>
+			<File
                                 RelativePath="..\..\..\samples\scenarios\using_tags.cpp"
 				>
                                 <FileConfiguration
Modified: sandbox/logging/lib/logging/samples/scenarios/mul_levels_one_logger.cpp
==============================================================================
--- sandbox/logging/lib/logging/samples/scenarios/mul_levels_one_logger.cpp	(original)
+++ sandbox/logging/lib/logging/samples/scenarios/mul_levels_one_logger.cpp	2007-12-29 13:15:08 EST (Sat, 29 Dec 2007)
@@ -30,7 +30,7 @@
 
 #include <boost/logging/format.hpp>
 #include <boost/logging/writer/ts_write.hpp>
-#include <boost/logging/format/formatter/high_precision_time.hpp>
+//#include <boost/logging/format/formatter/high_precision_time.hpp>
 #include <boost/logging/format/destination/named.hpp>
 
 using namespace boost::logging;
@@ -55,7 +55,7 @@
     // Step 7: add formatters and destinations
     //         That is, how the message is to be formatted...
     g_l->writer().add_formatter( formatter::idx(), "[%] "  );
-    g_l->writer().add_formatter( formatter::high_precision_time("$hh:$mm:$ss.$mili ") );
+    //g_l->writer().add_formatter( formatter::high_precision_time("$hh:$mm:$ss.$mili ") );
     g_l->writer().add_formatter( formatter::append_newline() );
 
     //        ... and where should it be written to
Added: sandbox/logging/lib/logging/samples/scenarios/use_tss_ostringstream.cpp
==============================================================================
--- (empty file)
+++ sandbox/logging/lib/logging/samples/scenarios/use_tss_ostringstream.cpp	2007-12-29 13:15:08 EST (Sat, 29 Dec 2007)
@@ -0,0 +1,101 @@
+/**
+@example use_tss_ostringstream.cpp
+
+@copydoc use_tss_ostringstream
+
+@page use_tss_ostringstream use_tss_ostringstream.cpp Example
+
+
+This usage:
+- You have one logger
+- You have one filter, always turned on
+- You want to format the message before it's written 
+- The logger has several log destinations
+    - The output goes to console and debug output window
+    - Formatting - prefix each message by its index, and append newline
+
+Optimizations:
+- use tss_ostringstream (each thread has its own ostringstream copy, to make writing faster: 
+  when logging of a message, we won't need to create the ostringstream first ; it's created only once per thread )
+- use a cache string (from optimize namespace), in order to make formatting the message faster
+
+
+In this example, all output will be written to the console and debug window.
+It will be:
+
+@code
+[1] this is so cool 1
+[2] this is so cool again 2
+[3] this is too cool 3
+@endcode
+
+*/
+
+
+
+#include <boost/logging/format_fwd.hpp>
+
+// Step 1: Optimize : use a cache string, to make formatting the message faster
+BOOST_LOG_FORMAT_MSG( optimize::cache_string_one_str<> )
+
+//BOOST_LOG_GATHER_CLASS( use_ostringstream< tss_ostringstream<> > )
+
+    namespace boost { namespace logging { namespace gather { 
+        template<> struct find<override> { 
+            template<class msg_type> struct from_msg_type { 
+                typedef typename ::boost::logging::detail::find_gather_from_class<msg_type, use_ostringstream< tss_ostringstream<> > > ::type type; 
+            }; 
+        }; 
+    }}}
+
+
+
+#include <boost/logging/format.hpp>
+#include <boost/logging/writer/ts_write.hpp>
+
+using namespace boost::logging;
+
+// Step 3 : Specify your logging class(es)
+typedef logger_format_write< > log_type;
+
+
+// Step 4: declare which filters and loggers you'll use (usually in a header file)
+BOOST_DECLARE_LOG_FILTER(g_log_filter, filter::no_ts ) 
+BOOST_DECLARE_LOG(g_l, log_type) 
+
+// Step 5: define the macros through which you'll log
+#define L_ BOOST_LOG_USE_LOG_IF_FILTER(g_l, g_log_filter->is_enabled() ) 
+
+// Step 6: Define the filters and loggers you'll use (usually in a source file)
+BOOST_DEFINE_LOG_FILTER(g_log_filter, filter::no_ts ) 
+BOOST_DEFINE_LOG(g_l, log_type)
+
+
+void use_tss_ostringstream_example() {
+    // Step 7: add formatters and destinations
+    //         That is, how the message is to be formatted and where should it be written to
+
+    g_l->writer().add_formatter( formatter::idx(), "[%] "  );
+    g_l->writer().add_formatter( formatter::append_newline_if_needed() );
+    g_l->writer().add_destination( destination::cout() );
+    g_l->writer().add_destination( destination::dbg_window() );
+
+    // Step 8: use it...
+    int i = 1;
+    L_ << "this is so cool " << i++;
+    L_ << "this is so cool again " << i++;
+    L_ << "this is so too cool " << i++;
+
+    // Step 9 : Enjoy!
+}
+
+
+
+
+int main() {
+    use_tss_ostringstream_example();
+}
+
+
+// End of file
+