$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
From: john.groups_at_[hidden]
Date: 2008-01-20 14:08:14
Author: jtorjo
Date: 2008-01-20 14:08:13 EST (Sun, 20 Jan 2008)
New Revision: 42883
URL: http://svn.boost.org/trac/boost/changeset/42883
Log:
[logging]
v0.20.11, 20 jan 2008
- refactored finding the writer; added logger_to_writer class
- fully implemented profiling (not tested yet)
Added:
   sandbox/logging/boost/logging/detail/find_format_writer.hpp   (contents, props changed)
Text files modified: 
   sandbox/logging/boost/logging/detail/after_being_destroyed.hpp        |    12 +-                                      
   sandbox/logging/boost/logging/detail/format_msg_type.hpp              |     7 -                                       
   sandbox/logging/boost/logging/detail/logger.hpp                       |     4                                         
   sandbox/logging/boost/logging/detail/macros.hpp                       |     4                                         
   sandbox/logging/boost/logging/detail/manipulator.hpp                  |    29 +++--                                   
   sandbox/logging/boost/logging/detail/raw_doc/changelog.hpp            |     3                                         
   sandbox/logging/boost/logging/detail/use_format_write.hpp             |   101 +--------------------                   
   sandbox/logging/boost/logging/detail/util.hpp                         |    24 +++++                                   
   sandbox/logging/boost/logging/format.hpp                              |     3                                         
   sandbox/logging/boost/logging/format_fwd.hpp                          |    29 ++----                                  
   sandbox/logging/boost/logging/profile.hpp                             |   168 +++++++++++++++++++++++++++++++++--     
   sandbox/logging/lib/logging/internal/vc8/loggingvc8/loggingvc8.vcproj |     4                                         
   sandbox/logging/lib/logging/internal/vc8/loggingvc8/test_now.cpp      |   186 ++++++++++++++++++++++++++------------- 
   13 files changed, 351 insertions(+), 223 deletions(-)
Modified: sandbox/logging/boost/logging/detail/after_being_destroyed.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/after_being_destroyed.hpp	(original)
+++ sandbox/logging/boost/logging/detail/after_being_destroyed.hpp	2008-01-20 14:08:13 EST (Sun, 20 Jan 2008)
@@ -51,15 +51,15 @@
 
     */
     template<class T = override> struct after_being_destroyed_defer_to_function {
-        typedef typename destination::msg_type<T>::raw_type raw_type;
-        typedef void (*after_destroyed_func)(const raw_type&) ;
+        typedef typename destination::msg_type<T>::type type;
+        typedef void (*after_destroyed_func)(const type&) ;
 
     protected:
         // default implementation - do nothing
-        static void nothing(const raw_type&) {}
+        static void nothing(const type&) {}
 
         bool is_still_alive() const { return !m_is_destroyed; }
-        void call_after_destroyed(const raw_type& msg) const { 
+        void call_after_destroyed(const type& msg) const { 
             m_after_being_destroyed(msg); 
         }
 
@@ -74,8 +74,8 @@
     };
 
     template<class T = override> struct after_being_destroyed_none {
-        typedef typename destination::msg_type<T>::raw_type raw_type;
-        typedef void (*after_destroyed_func)(const raw_type&) ;
+        typedef typename destination::msg_type<T>::type type;
+        typedef void (*after_destroyed_func)(const type&) ;
 
     protected:
         after_being_destroyed_none () : m_after_being_destroyed(0) {}
Added: sandbox/logging/boost/logging/detail/find_format_writer.hpp
==============================================================================
--- (empty file)
+++ sandbox/logging/boost/logging/detail/find_format_writer.hpp	2008-01-20 14:08:13 EST (Sun, 20 Jan 2008)
@@ -0,0 +1,158 @@
+// logger_to_writer.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_logger_to_writer_HPP_DEFINED
+#define JT28092007_logger_to_writer_HPP_DEFINED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <boost/logging/detail/fwd.hpp>
+#include <boost/logging/format_fwd.hpp>
+
+namespace boost { namespace logging {
+
+
+
+// ... the hard part - for logger_format_write
+
+namespace formatter {
+    template< class arg_type, class ptr_type_> struct base ;
+}
+
+namespace destination {
+    template< class arg_type, class ptr_type_> struct base ;
+}
+
+namespace msg_route {
+    template<class formatter_base, class destination_base, class lock_resource > struct simple ;
+    template<class formatter_base, class destination_base, class lock_resource, class formatter_array, class destination_array> class with_route;
+}
+
+namespace format_and_write {
+    template<class msg_type> struct simple ;
+
+    template<class formatter_base, class destination_base, class msg_type> struct use_cache ;
+}
+namespace array {
+    template <class base_type, class mutex > class shared_ptr_holder ;
+}
+
+namespace writer {
+    template<
+            class formatter_base, 
+            class destination_base,
+            class lock_resource ,
+            class apply_format_and_write ,
+            class router_type ,
+            class formatter_array , 
+            class destination_array >
+    struct format_write ;
+}
+
+
+namespace detail {
+
+    //////////// find_format_write_params 
+    template<class string, class formatter_base, class destination_base, class lock_resource> struct find_format_write_params {
+        typedef typename ::boost::logging::format_and_write::simple<string> apply_format_and_write ;
+        typedef typename ::boost::logging::msg_route::simple<formatter_base, destination_base, lock_resource> router_type;
+    };
+
+    template<class string_type, class formatter_base, class destination_base, class lock_resource> 
+        struct find_format_write_params< typename boost::logging::optimize::cache_string_several_str<string_type>, formatter_base, destination_base, lock_resource>
+    {
+        typedef typename boost::logging::optimize::cache_string_several_str<string_type> cache_string;
+        typedef typename boost::logging::format_and_write::use_cache<formatter_base, destination_base, cache_string> apply_format_and_write ;
+
+        typedef boost::logging::array::shared_ptr_holder<formatter_base, boost::logging::threading::mutex > formatter_array ;
+        typedef boost::logging::array::shared_ptr_holder<destination_base, boost::logging::threading::mutex > destination_array ;
+
+        typedef typename msg_route::with_route<formatter_base, destination_base, lock_resource, formatter_array, destination_array > router_type;
+    };
+
+
+
+    ///////////// find_writer_with_thread_safety
+    template<class thread_safety, class format_write> struct find_writer_with_thread_safety {
+        // for default_
+#ifdef BOOST_HAS_THREADS
+        // use ts_write
+        typedef writer::ts_write<format_write> type;
+#else
+        typedef format_write type;
+#endif
+    };
+
+    template<class format_write> struct find_writer_with_thread_safety<boost::logging::writer::threading::no_ts,format_write> {
+        typedef format_write type;
+    };
+
+    template<class format_write> struct find_writer_with_thread_safety<boost::logging::writer::threading::ts_write,format_write> {
+        typedef writer::ts_write<format_write> type;
+    };
+
+    template<class format_write> struct find_writer_with_thread_safety<boost::logging::writer::threading::on_dedicated_thread,format_write> {
+        typedef typename detail::to_override<format_write>::type override_;
+        typedef typename formatter::msg_type<override_>::type msg_type;
+
+        typedef writer::on_dedicated_thread<msg_type, format_write> type;
+    };
+}
+
+
+namespace detail {
+    template< class format_base_type , class destination_base_type , class lock_resource, class thread_safety > struct format_find_writer {
+
+        typedef typename detail::to_override<format_base_type>::type override_;
+        typedef typename ::boost::logging::formatter::msg_type<override_>::type format_msg_type;
+        typedef typename ::boost::logging::destination::msg_type<override_>::type destination_msg_type;
+        typedef typename ::boost::logging::types<override_>::lock_resource default_lock_resource;
+
+        typedef ::boost::logging::formatter::base< format_msg_type, default_ > default_format_base;
+        typedef ::boost::logging::destination::base< destination_msg_type, default_ > default_destination_base;
+
+        typedef typename use_default<format_base_type, default_format_base > ::type format_base;
+        typedef typename use_default<destination_base_type, default_destination_base > ::type destination_base;
+        typedef typename use_default<lock_resource, default_lock_resource > ::type lock_resource_type;
+
+        
+
+        typedef typename detail::find_format_write_params<format_msg_type, format_base, destination_base, lock_resource_type >::apply_format_and_write apply_format_and_write;
+        typedef typename detail::find_format_write_params<format_msg_type, format_base, destination_base, lock_resource_type >::router_type router_type;
+
+        typedef ::boost::logging::array::shared_ptr_holder<format_base, boost::logging::threading::mutex > formatter_array ;
+        typedef ::boost::logging::array::shared_ptr_holder<destination_base, boost::logging::threading::mutex > destination_array ;
+
+        // now find the writer based on thread safety
+        typedef writer::format_write< 
+            format_base, 
+            destination_base, 
+            lock_resource_type, 
+            apply_format_and_write, 
+            router_type,
+            formatter_array,
+            destination_array > format_write_type;
+        typedef typename find_writer_with_thread_safety<thread_safety, format_write_type>::type type;
+    };
+}
+
+
+}}
+
+#endif
+
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	2008-01-20 14:08:13 EST (Sun, 20 Jan 2008)
@@ -23,7 +23,6 @@
 
 #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 {
@@ -35,8 +34,7 @@
     @brief what is the default type of your string, in formatter_base ? See BOOST_LOG_FORMAT_MSG
     */
     template<class T = override> struct msg_type {
-        typedef hold_string_type& type;
-        typedef hold_string_type raw_type;
+        typedef hold_string_type type;
     };
 }
 
@@ -46,8 +44,7 @@
     */
     template<class T = override> struct msg_type {
         // by default  - the default string
-        typedef const hold_string_type& type;
-        typedef hold_string_type raw_type;
+        typedef hold_string_type type;
     };
 }
 
Modified: sandbox/logging/boost/logging/detail/logger.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/logger.hpp	(original)
+++ sandbox/logging/boost/logging/detail/logger.hpp	2008-01-20 14:08:13 EST (Sun, 20 Jan 2008)
@@ -315,9 +315,7 @@
 
 
 
-    /** 
-        Given a logger class, finds its gather_msg , without needing to know the logger's definition
-        (a typedef is enough)
+    /** @brief Given a logger class, finds its gather_msg , without needing to know the logger's definition (a typedef is enough)
     */
     template<class> struct logger_to_gather {};
     template<class gather_msg, class write_msg> struct logger_to_gather< logger<gather_msg,write_msg> > {
Modified: sandbox/logging/boost/logging/detail/macros.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/macros.hpp	(original)
+++ sandbox/logging/boost/logging/detail/macros.hpp	2008-01-20 14:08:13 EST (Sun, 20 Jan 2008)
@@ -637,7 +637,7 @@
 */
 #define BOOST_LOG_FORMAT_MSG(msg_class) \
     namespace boost { namespace logging { namespace formatter { \
-    template<> struct msg_type<override> { typedef msg_class & type; typedef msg_class raw_type; }; \
+    template<> struct msg_type<override> { typedef msg_class type; }; \
     }}}
 
 /** @section BOOST_LOG_DESTINATION_MSG BOOST_LOG_DESTINATION_MSG
@@ -650,7 +650,7 @@
 */
 #define BOOST_LOG_DESTINATION_MSG(msg_class) \
     namespace boost { namespace logging { namespace destination { \
-    template<> struct msg_type<override> { typedef const msg_class & type; typedef msg_class raw_type; }; \
+    template<> struct msg_type<override> { typedef msg_class type; }; \
     }}}
 
 
Modified: sandbox/logging/boost/logging/detail/manipulator.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/manipulator.hpp	(original)
+++ sandbox/logging/boost/logging/detail/manipulator.hpp	2008-01-20 14:08:13 EST (Sun, 20 Jan 2008)
@@ -32,7 +32,6 @@
 #include <boost/logging/format/op_equal.hpp>
 #include <boost/logging/detail/forward_constructor.hpp> // BOOST_LOGGING_FORWARD_CONSTRUCTOR_WITH_NEW
 #include <boost/shared_ptr.hpp>
-#include <boost/type_traits/remove_const.hpp>
 
 
 namespace boost { namespace logging {
@@ -317,23 +316,29 @@
 
     When using formatters and destinations, formatters must share a %base class,
     and destinations must share a %base class - see manipulator namespace.
+
+    @note
+    Don't use directly. Use formatter::base<> or destination::base<> instead.
 */
 template<
-        class arg_type, 
+        class raw_param_type, 
+        class param_type,
         class ptr_type_ = default_ > 
     struct base : boost::logging::op_equal::same_type_op_equal_base {
 
-    typedef base<arg_type, ptr_type_> self_type;
+    typedef base<raw_param_type, param_type, ptr_type_> self_type;
 
     typedef typename use_default<ptr_type_, self_type*>::type ptr_type;
-    typedef arg_type param;
 
-    typedef typename boost::remove_const<param>::type non_const_param;
     // used as msg_type in format_and_write classes
-    typedef typename boost::remove_reference<non_const_param>::type raw_param;
+    typedef raw_param_type raw_param;
+    typedef param_type param;
 
-    virtual ~base() {}
     virtual void operator()(param val) const = 0;
+protected:
+    // signify that we're only a base class - not to be used directly
+    base() {}
+    virtual ~base() {}
 };
 
 
@@ -510,9 +515,10 @@
     and destinations must share a %base class - see manipulator namespace.
     */
     template<
+        // note: I'm counting on these defaults, in format_find_writer class
         class arg_type = typename msg_type<override>::type, 
         class ptr_type_ = default_ > 
-    struct base : boost::logging::manipulator::base<arg_type, ptr_type_> {
+    struct base : boost::logging::manipulator::base< arg_type, arg_type& , ptr_type_> {
     };
 
     /** 
@@ -547,10 +553,6 @@
 Some viable destinations are : the console, a file, a socket, etc.
 
 
-talk about destination_base
-
-FIXME
-
 */
 namespace destination {
     /** 
@@ -560,9 +562,10 @@
     and destinations must share a %base class - see manipulator namespace.
     */
     template<
+        // note: I'm counting on these defaults, in format_find_writer class
         class arg_type = typename msg_type<override>::type, 
         class ptr_type_ = default_ > 
-    struct base : boost::logging::manipulator::base<arg_type, ptr_type_> {
+    struct base : boost::logging::manipulator::base< arg_type, const arg_type& , ptr_type_> {
     };
 
     using boost::logging::manipulator::non_const_context;
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	2008-01-20 14:08:13 EST (Sun, 20 Jan 2008)
@@ -2,7 +2,8 @@
 @page page_changelog Changelog
 
 @section changelog_cur_ver Current Version: v0.20.10, 20 jan 2008
-- added logger_to_gather, 
+- added logger_to_gather, removed DEFINE_GATHER_CLASS; 
+- modified compile_time example, to see compile time with precompiled header
 - added profiler - allow profiling the logging code
 - solved bug in logger_holder_by_value - many thanks to Olaf!
 - refactored logger_holder - that is, we need to return logger_holder, 
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	2008-01-20 14:08:13 EST (Sun, 20 Jan 2008)
@@ -29,79 +29,13 @@
 #include <boost/logging/gather/ostream_like.hpp>
 #include <boost/logging/detail/manipulator.hpp>
 #include <boost/logging/detail/find_gather.hpp>
+#include <boost/logging/detail/find_format_writer.hpp>
 
 namespace boost { namespace logging {
 
 
 
 
-    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-    // specialize logger for format_write class
-    //
-
-    namespace detail {
-
-        template<class string, class formatter_base, class destination_base, class lock_resource> struct find_format_write_params {
-            typedef typename boost::logging::format_and_write::simple<string> apply_format_and_write ;
-            typedef typename msg_route::simple<formatter_base, destination_base, lock_resource> router_type;
-        };
-
-        template<class string_type, class formatter_base, class destination_base, class lock_resource> 
-            struct find_format_write_params< typename boost::logging::optimize::cache_string_several_str<string_type>, formatter_base, destination_base, lock_resource>
-        {
-            typedef typename boost::logging::optimize::cache_string_several_str<string_type> cache_string;
-            typedef typename boost::logging::format_and_write::use_cache<formatter_base, destination_base, cache_string> apply_format_and_write ;
-            typedef typename msg_route::with_route<formatter_base, destination_base, lock_resource> router_type;
-        };
-
-        template<class thread_safety, class gather_type, class format_write> struct find_writer_with_thread_safety {
-#ifdef BOOST_HAS_THREADS
-            // use ts_write
-            typedef writer::ts_write<format_write> type;
-#else
-            typedef format_write type;
-#endif
-        };
-
-        template<class gather_type, class format_write> struct find_writer_with_thread_safety<boost::logging::writer::threading::no_ts,gather_type,format_write> {
-            typedef format_write type;
-        };
-
-        template<class gather_type, class format_write> struct find_writer_with_thread_safety<boost::logging::writer::threading::ts_write,gather_type,format_write> {
-            typedef writer::ts_write<format_write> type;
-        };
-
-        template<class gather_type, class format_write> struct find_writer_with_thread_safety<boost::logging::writer::threading::on_dedicated_thread,gather_type,format_write> {
-            typedef typename gather_type::msg_type msg_type;
-    
-            typedef writer::on_dedicated_thread<msg_type, format_write> type;
-        };
-    }
-
-
-
-
-template<
-            class format_base_type , 
-            class destination_base_type ,
-            class gather ,
-            class lock_resource
-    >
-struct use_format_write {
-
-    typedef typename use_default<format_base_type, boost::logging::formatter::base<> > ::type format_base;
-    typedef typename use_default<destination_base_type, boost::logging::destination::base<> > ::type destination_base;
-    typedef typename use_default<lock_resource, ::boost::logging::types<override>::lock_resource> ::type lock_resource_type;
-
-    // FIXME I might be able to get this from formatter::msg_type<>::raw_type
-    typedef typename format_base::raw_param format_param;
-    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;
-};
-
-
 /** 
 @brief Makes it easier to use a logger with format_write class
 
@@ -130,37 +64,12 @@
 template<class format_base, class destination_base, class thread_safety, class gather, class lock_resource> 
 struct logger_format_write
     : logger< 
-            typename use_format_write<format_base, destination_base, gather, lock_resource>::gather_type,
-            typename detail::find_writer_with_thread_safety<
-                thread_safety,
-                typename use_format_write<format_base, destination_base, gather, lock_resource>::gather_type,
-                writer::format_write<
-                    typename use_format_write<format_base, destination_base, gather, lock_resource>::format_base,
-                    typename use_format_write<format_base, destination_base, gather, lock_resource>::destination_base,
-                    typename use_format_write<format_base, destination_base, gather, lock_resource>::lock_resource_type,
-                    typename use_format_write<format_base, destination_base, gather, lock_resource>::apply_format_and_write,
-                    typename use_format_write<format_base, destination_base, gather, lock_resource>::router_type
-                > 
-            >::type
-    >
+            typename detail::format_find_gather<gather>::type ,
+            typename detail::format_find_writer<format_base, destination_base, lock_resource, thread_safety>::type >
 {
-    // FIXME we don't use gather - to see what we should do here
-
     typedef logger< 
-            typename use_format_write<format_base, destination_base, gather, lock_resource>::gather_type,
-            typename detail::find_writer_with_thread_safety<
-                thread_safety,
-                typename use_format_write<format_base, destination_base, gather, lock_resource>::gather_type,
-                writer::format_write<
-                    typename use_format_write<format_base, destination_base, gather, lock_resource>::format_base,
-                    typename use_format_write<format_base, destination_base, gather, lock_resource>::destination_base,
-                    typename use_format_write<format_base, destination_base, gather, lock_resource>::lock_resource_type,
-                    typename use_format_write<format_base, destination_base, gather, lock_resource>::apply_format_and_write,
-                    typename use_format_write<format_base, destination_base, gather, lock_resource>::router_type
-                > 
-            >::type
-    >
-     logger_base_type;
+            typename detail::format_find_gather<gather>::type ,
+            typename detail::format_find_writer<format_base, destination_base, lock_resource, thread_safety>::type > logger_base_type;
 
     BOOST_LOGGING_FORWARD_CONSTRUCTOR(logger_format_write, logger_base_type)
 };
Modified: sandbox/logging/boost/logging/detail/util.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/util.hpp	(original)
+++ sandbox/logging/boost/logging/detail/util.hpp	2008-01-20 14:08:13 EST (Sun, 20 Jan 2008)
@@ -38,6 +38,30 @@
 
     struct void_ {};
 
+
+    namespace detail {
+        /** this is just a simple way to always return override; however, in this case we postpone the instantiation
+         until our template parameter is known
+        
+
+        For instance:
+        @code
+        typedef typename formatter::msg_type<override>::type msg_type;
+        @endcode
+
+        would compute msg_type right now; however, we want the compiler to wait, until the user has actually set the msg_type,
+        for example, using the BOOST_LOG_FORMAT_MSG macro. Thus, we do:
+
+        @code
+        typedef typename detail::to_override<format_base>::type T;
+        typedef typename formatter::msg_type<T>::type msg_type;
+        @endcode
+        */
+        template<class> struct to_override { typedef override type; };
+        template<> struct to_override<void_> { typedef void_ type; };
+    }
+
+
     struct ansi_unicode_char_holder {
         const char * str;
         const wchar_t * wstr;
Modified: sandbox/logging/boost/logging/format.hpp
==============================================================================
--- sandbox/logging/boost/logging/format.hpp	(original)
+++ sandbox/logging/boost/logging/format.hpp	2008-01-20 14:08:13 EST (Sun, 20 Jan 2008)
@@ -29,8 +29,6 @@
 #include <set>
 #include <boost/shared_ptr.hpp>
 
-#include <boost/type_traits/remove_reference.hpp>
-#include <boost/type_traits/remove_const.hpp>
 #include <boost/type_traits/is_base_of.hpp>
 #include <boost/logging/detail/manipulator.hpp>
 #include <boost/logging/format_fwd.hpp>
@@ -357,6 +355,7 @@
     template<
             class formatter_base, 
             class destination_base,
+            // note: we're counting on these defaults in format_find_writer
             class lock_resource = typename boost::logging::types<override>::lock_resource ,
             class formatter_array = boost::logging::array::shared_ptr_holder<formatter_base>,
             class destination_array = boost::logging::array::shared_ptr_holder<destination_base>
Modified: sandbox/logging/boost/logging/format_fwd.hpp
==============================================================================
--- sandbox/logging/boost/logging/format_fwd.hpp	(original)
+++ sandbox/logging/boost/logging/format_fwd.hpp	2008-01-20 14:08:13 EST (Sun, 20 Jan 2008)
@@ -117,32 +117,23 @@
 };
 
 
-
 namespace detail {
-    /** this is just a simple way to always return override; however, in this case we postpone the instantiation
-     until the type parameter is known
-    
-
-    For instance:
-    typedef typename formatter::msg_type<override>::raw_type msg_type;
-
-    would compute msg_type right now; however, we want the compiler to wait, until the user has actually set the msg_type,
-    for example, using the BOOST_LOG_FORMAT_MSG macro
-    */
-    template<class> struct to_override { typedef override type; };
-    template<> struct to_override<void_> { typedef void_ type; };
+    // finds the gather type, when using formatting (for logger_format_write)
+    template<class gather> struct format_find_gather {
+        typedef typename detail::to_override<gather>::type override_;
+
+        // FIXME in the future, I might provide gather as a specific class!
+        typedef typename formatter::msg_type<override_>::type msg_type;
+        typedef typename ::boost::logging::gather::find<override_>::template from_msg_type<msg_type>::type type;
+    };
 }
 
+
 // specialize for logger_format_write
 template<class format_base, class destination_base, class thread_safety, class gather, class lock_resource> 
         struct logger_to_gather< logger_format_write<format_base, destination_base, thread_safety, gather, lock_resource> > {
 
-    typedef typename detail::to_override<format_base>::type T;
-
-    // FIXME in the future, I might provide gather as a specific class!
-    typedef typename formatter::msg_type<T>::raw_type msg_type;
-    typedef typename ::boost::logging::gather::find<T>::template from_msg_type<msg_type>::type gather_type;
-        
+    typedef typename detail::format_find_gather<gather>::type gather_type;
 };
 
 
Modified: sandbox/logging/boost/logging/profile.hpp
==============================================================================
--- sandbox/logging/boost/logging/profile.hpp	(original)
+++ sandbox/logging/boost/logging/profile.hpp	2008-01-20 14:08:13 EST (Sun, 20 Jan 2008)
@@ -34,8 +34,20 @@
 #include <boost/function.hpp>
 #include <string>
 #include <sstream>
+#include <boost/logging/format_fwd.hpp>
+#include <boost/logging/detail/find_format_writer.hpp>
 
-namespace boost { namespace logging { namespace profile {
+namespace boost { namespace logging { 
+    
+namespace writer {
+    template<class msg_type, class base_type> struct on_dedicated_thread ;
+}
+
+/** @brief Allows profiling your application
+
+See compute_for_logger and compute_for_filter classes
+*/    
+namespace profile {
 
 
 /** 
@@ -123,11 +135,10 @@
 };
 
 
-template<class msg_type, class base_type> struct on_dedicated_thread ;
 
 template<class gather_msg> struct compute_gather : gather_msg {
     compute_gather() : m_lk( get_compute(), compute::gather) {}
-    compute_gather(const compute_gather& other) : : m_lk( get_compute(), compute::gather), gather_msg(other) {}
+    compute_gather(const compute_gather& other) : m_lk( get_compute(), compute::gather), gather_msg(other) {}
 
     compute& get_compute() const { return compute::inst(); }
 private:
@@ -137,7 +148,7 @@
 template<class writer_msg> struct compute_write : writer_msg {
     compute& get_compute() const { return compute::inst(); }
 
-    template<class msg_type> void operator()(const msg_type& msg) const {
+    template<class msg_type> void operator()(msg_type& msg) const {
         scoped_compute lk( get_compute(), compute::writer );
         writer_msg::operator()(msg);
     }
@@ -145,23 +156,24 @@
     // just in case you do write on another thread
     virtual void write_array() const {
         scoped_compute lk( get_compute(), compute::on_other_thread );
-        write_array_impl( *this);
+        write_array_impl( this);
     }
 private:
-    template<class msg_type, class base_type> void write_array_impl(const on_dedicated_thread<msg_type,base_type> &) const {
+    template<class msg_type, class base_type> void write_array_impl(const ::boost::logging::writer::on_dedicated_thread<msg_type,base_type> *) const {
         // call base class's implementation
         writer_msg::write_array();
     }
 
     // does not derive from on_dedicated_thread
-    void write_array_impl(...) const {}
+    void write_array_impl(const void *) const {}
 };
 
-/** 
-    In case you want to profile your filter, there's just one requirement:
-    - your function must be called @c is_enabled() and be const
+/** @brief Profiles a filter. Don't use directly, use compute_for_filter instead.
+
 */
 template<class filter_msg> struct compute_filter : filter_msg {
+    BOOST_LOGGING_FORWARD_CONSTRUCTOR(compute_filter, filter_msg)
+
     // is_enabled - for any up to 5 params - const function
     compute& get_compute() const { return compute::inst(); }
 
@@ -185,7 +197,7 @@
         scoped_compute lk( get_compute(), compute::filter );
         return filter_msg::is_enabled(v1, v2, v3, v4);
     }
-    template<class p1, class p2, class p3, class p4, class p5> bool is_enabled(const p1 & v1, const p2 &v2, const p3 & v3, const p4 & v4, class p5 & v5) const {
+    template<class p1, class p2, class p3, class p4, class p5> bool is_enabled(const p1 & v1, const p2 &v2, const p3 & v3, const p4 & v4, const p5 & v5) const {
         scoped_compute lk( get_compute(), compute::filter );
         return filter_msg::is_enabled(v1, v2, v3, v4, v5);
     }
@@ -193,6 +205,140 @@
 };
 
 
+
+
+/** @brief given the logger type, gets the write_msg part, without needing to know the logger's definition (a typedef is enough)
+
+*/
+template<class> struct logger_to_write {};
+template<class gather_msg, class write_msg> struct logger_to_write< logger<gather_msg,write_msg> > {
+    // ... the easy part
+    typedef write_msg write_type;
+};
+
+// specialize for logger_format_write
+template<class format_base, class destination_base, class thread_safety, class gather, class lock_resource> 
+        struct logger_to_write< logger_format_write<format_base, destination_base, thread_safety, gather, lock_resource> > {
+
+    typedef typename detail::format_find_writer<format_base, destination_base, lock_resource, thread_safety>::type write_type;
+};
+
+
+
+/** @brief Allows you to compute profiling for your logger class
+
+@code
+#include <boost/logging/profile.hpp>
+@endcode
+
+To do profiling for a logger, just surround it with compute_for_logger. Example:
+
+<b>Old code</b>
+
+@code
+#include <boost/logging/format_fwd.hpp>
+
+namespace bl = boost::logging ;
+typedef bl::logger_format_write< > log_type;
+
+BOOST_DECLARE_LOG(g_l, log_type) 
+...
+BOOST_DEFINE_LOG(g_l, log_type) 
+
+@endcode
+
+
+<b>New code</b>
+
+@code
+#include <boost/logging/format_fwd.hpp>
+#include <boost/logging/profile.hpp>
+
+namespace bl = boost::logging ;
+typedef bl::logger_format_write< > <b>raw_log_type</b>;
+typedef bl::profile::compute_for_logger<raw_log_type>::type log_type;
+
+BOOST_DECLARE_LOG(g_l, log_type) 
+...
+BOOST_DEFINE_LOG(g_l, log_type) 
+
+@endcode
+
+@sa compute_for_filter
+
+*/
+template<class logger_type> struct compute_for_logger {
+    typedef logger<
+        compute_gather< typename logger_to_gather<logger_type>::gather_type > ,
+        compute_write< typename logger_to_write<logger_type>::write_type > > type;
+
+};
+
+
+
+
+/** @brief Allows you to compute profiling for your filter class
+
+@code
+#include <boost/logging/profile.hpp>
+@endcode
+
+In case you want to profile your filter, there's just one requirement:
+- your function must be called @c is_enabled() and be const
+
+
+
+
+
+
+To do profiling for a filter, just surround it with compute_for_filter. Example:
+
+<b>Old code</b>
+
+@code
+#include <boost/logging/format_fwd.hpp>
+
+namespace bl = boost::logging ;
+typedef bl::filter::no_ts filter;
+
+BOOST_DECLARE_LOG_FILTER(g_l_filter, filter) 
+...
+BOOST_DEFINE_LOG_FILTER(g_l_filter, filter) 
+
+@endcode
+
+
+<b>New code</b>
+
+@code
+#include <boost/logging/format_fwd.hpp>
+#include <boost/logging/profile.hpp>
+
+namespace bl = boost::logging ;
+typedef bl::filter::no_ts <b>raw_filter</b>;
+typedef compute_for_filter<raw_filter>::type filter;
+
+BOOST_DECLARE_LOG_FILTER(g_l_filter, filter) 
+...
+BOOST_DEFINE_LOG_FILTER(g_l_filter, filter) 
+
+@endcode
+
+
+
+
+
+
+
+@sa compute_for_logger
+
+*/
+template<class filter_type> struct compute_for_filter {
+    typedef compute_filter<filter_type> type;
+};
+
+
+
 }}}
 
 #endif
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	2008-01-20 14:08:13 EST (Sun, 20 Jan 2008)
@@ -513,6 +513,10 @@
 					>
                                 </File>
                                 <File
+					RelativePath="..\..\..\..\..\boost\logging\detail\find_format_writer.hpp"
+					>
+				</File>
+				<File
                                         RelativePath="..\..\..\..\..\boost\logging\detail\find_gather.hpp"
 					>
                                 </File>
Modified: sandbox/logging/lib/logging/internal/vc8/loggingvc8/test_now.cpp
==============================================================================
--- sandbox/logging/lib/logging/internal/vc8/loggingvc8/test_now.cpp	(original)
+++ sandbox/logging/lib/logging/internal/vc8/loggingvc8/test_now.cpp	2008-01-20 14:08:13 EST (Sun, 20 Jan 2008)
@@ -1,97 +1,153 @@
-// log.h
-#ifndef LOG_H_header
-#define LOG_H_header
+/**
+@example custom_fmt_dest.cpp
 
-#include <boost/logging/format_fwd.hpp>
-// If you want to use tags...
-#include <boost/logging/tags.hpp>
-
-// Step 1: Specify the class to hold the message
-namespace b_l = boost::logging;
-typedef b_l::tag::holder<
-    // string class
-    b_l::optimize::cache_string_one_str<>,
-    // tags
-    b_l::tag::thread_id, b_l::tag::time> log_string_type;
-// note: if you don't use tags, you can simply use a string class:
-// typedef b_l::optimize::cache_string_one_str<> log_string_type;
-BOOST_LOG_FORMAT_MSG( log_string_type )
+@copydoc custom_fmt_dest
 
-// if not compiling fast...
-#ifndef BOOST_LOG_COMPILE_FAST
-#include <boost/logging/format.hpp>
-#include <boost/logging/writer/ts_write.hpp>
+@page custom_fmt_dest custom_fmt_dest.cpp Example
 
-// If you use tags...
-#include <boost/logging/format/formatter/tags.hpp>
+This example shows you how easy it is to add your custom formatter /destination classes.
 
-// uncomment if you want to use do logging on a dedicated thread
-// #include <boost/logging/writer/on_dedicated_thread.hpp>
-#endif
+This usage:
+- You have one logger
+- You have one filter, which can be turned on or off
+- You want to format the message before it's written 
+- The logger has several log destinations
+    - The output goes to console, debug output window, and a file called out.txt - as XML
+    - Formatting - prefix each message by its start time, its index, and append newline
 
+\n\n
+Custom classes:
+- secs_since_start - custom formatter
+- as_xml - custom destination
 
-// Step 3 : Specify your logging class(es)
-using namespace boost::logging::scenario::usage;
-typedef use<
-        //  how often do you manipulate (change) the filter?
-        filter_::change::often<10>,
-        //  does the filter use levels?
-        filter_::level::no_levels,
-        // how often do you manipulate (change) the logger?
-        logger_::change::often<10>,
-        // for the logger: do you favor speed or correctness?
-        logger_::favor::correctness> finder;
-
-// Step 4: declare which filters and loggers you'll use
-BOOST_DECLARE_LOG_FILTER(g_l_filter, finder::filter)
-BOOST_DECLARE_LOG(g_l, finder::logger)
-
-// 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() ) 
 
-// initialize thy logs..
-void init_logs();
+\n\n
+Optimizations:
+- use a cache string (from optimize namespace), in order to make formatting the message faster
 
-#endif
 
+\n\n
+The output will look similar to this one:
 
 
+The console and the debug window will be the same:
+@code
++6s [1] this is so cool 1
++6s [2] this is so cool again 2
++7s [3] hello, world
++7s [4] good to be back ;) 3
+@endcode
 
 
+The out.txt file will look like this:
 
 
+@code
+<msg>+6s [1] this is so cool 1
+</msg>
+<msg>+6s [2] this is so cool again 2
+</msg>
+<msg>+7s [3] hello, world
+</msg>
+<msg>+7s [4] good to be back ;) 3
+</msg>
+@endcode
 
+*/
 
 
+#include <boost/logging/format_fwd.hpp>
+#include <boost/logging/profile.hpp>
 
+// Step 1: Optimize : use a cache string, to make formatting the message faster
+BOOST_LOG_FORMAT_MSG( optimize::cache_string_one_str<> )
 
+#include <boost/logging/format.hpp>
+using namespace boost::logging;
 
+// Step 3 : Specify your logging class(es)
+typedef logger_format_write< default_, default_, writer::threading::no_ts > raw_log_type;
+//typedef raw_log_type log_type;
+typedef profile::compute_for_logger<raw_log_type>::type 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) 
 
-// log.cpp
-#include <boost/logging/format.hpp>
-#include <boost/logging/writer/ts_write.hpp>
-#include <boost/logging/format/formatter/tags.hpp>
+// 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() ) 
 
-// uncomment if you want to use do logging on a dedicated thread
-// #include <boost/logging/writer/on_dedicated_thread.hpp>
+// Step 6: Define the filters and loggers you'll use (usually in a source file)
+BOOST_DEFINE_LOG(g_l, log_type)
+BOOST_DEFINE_LOG_FILTER(g_log_filter, filter::no_ts )
 
-using namespace boost::logging;
 
-// Step 6: Define the filters and loggers you'll use
-BOOST_DEFINE_LOG_FILTER(g_log_filter, finder::filter ) 
-BOOST_DEFINE_LOG(g_l, finder::logger) 
 
+// Example of custom formatter:
+// dump the no. of seconds since start of program
+struct secs_since_start : formatter::class_<secs_since_start, formatter::implement_op_equal::no_context> {
+    ::time_t m_start;
+    secs_since_start() : m_start( ::time(0) ) {}
+    void operator()(param str) const {
+        ::time_t now = ::time(0);
+        std::stringstream out;
+        out << "+" << (int)(now-m_start) << "s ";
+        str.prepend_string( out.str() );
+    }
+};
+
+// Example of custom destination:
+// Dump each message as XML
+struct as_xml : 
+        destination::class_<as_xml, destination::implement_op_equal::has_context>, 
+        destination::non_const_context<std::ofstream> {
+
+    std::string m_name;
+    as_xml(const char* name) : non_const_context_base(name), m_name(name) {}
+    void operator()(param str) const {
+        context() << "<msg>" << str << "</msg>" << std::endl; 
+    }
+
+    bool operator==(const as_xml& other) const { return m_name == other.m_name; }
+};
+
+
+void custom_fmt_dest_example() {
+    // Step 7: add formatters and destinations
+    //         That is, how the message is to be formatted and where should it be written to
 
-void init_logs() {
-    // Add formatters and destinations
-    // That is, how the message is to be formatted...
-    g_l()->writer().add_formatter( formatter::tag::thread_id() );
-    g_l()->writer().add_formatter( formatter::tag::time("$hh:$mm.$ss ") );
-    g_l()->writer().add_formatter( formatter::idx() );
+    g_l()->writer().add_formatter( formatter::idx(), "[%] " );
     g_l()->writer().add_formatter( formatter::append_newline() );
+    g_l()->writer().add_formatter( secs_since_start() );
 
-    //        ... and where should it be written to
     g_l()->writer().add_destination( destination::cout() );
     g_l()->writer().add_destination( destination::dbg_window() );
-    g_l()->writer().add_destination( destination::file("out.txt") );
+    g_l()->writer().add_destination( as_xml("out.txt") );
+    g_l()->turn_cache_off();
+
+    // Step 8: use it...
+    int i = 1;
+    L_ << "this is so cool " << i++;
+    L_ << "this is so cool again " << i++;
+
+    std::string hello = "hello", world = "world";
+    L_ << hello << ", " << world;
+
+    g_log_filter()->set_enabled(false);
+    L_ << "this will not be written to the log";
+    L_ << "this won't be written to the log";
+
+    g_log_filter()->set_enabled(true);
+    L_ << "good to be back ;) " << i++;
+
+    // Step 9 : Enjoy!
 }
+
+
+
+int main() {
+    custom_fmt_dest_example();
+}
+
+
+// End of file