$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
From: john.groups_at_[hidden]
Date: 2007-10-13 11:38:16
Author: jtorjo
Date: 2007-10-13 11:38:14 EDT (Sat, 13 Oct 2007)
New Revision: 39970
URL: http://svn.boost.org/trac/boost/changeset/39970
Log:
v0.6, 13 oct 2007
- added formatters from v1. of the library
- added convert_format cool function :P
Added:
   sandbox/logging/boost/logging/detail/manipulator.hpp   (contents, props changed)
   sandbox/logging/boost/logging/detail/raw_doc/acknowledgments.hpp   (contents, props changed)
   sandbox/logging/boost/logging/detail/raw_doc/thread_safety.hpp   (contents, props changed)
   sandbox/logging/boost/logging/format/destination/
   sandbox/logging/boost/logging/format/destination/defaults.hpp   (contents, props changed)
   sandbox/logging/boost/logging/format/destination/file.hpp   (contents, props changed)
   sandbox/logging/boost/logging/format/formatter/
   sandbox/logging/boost/logging/format/formatter/convert_format.hpp   (contents, props changed)
   sandbox/logging/boost/logging/format/formatter/defaults.hpp   (contents, props changed)
   sandbox/logging/boost/logging/format/formatter/thread_id.hpp   (contents, props changed)
   sandbox/logging/boost/logging/format/formatter/time.hpp   (contents, props changed)
Text files modified: 
   sandbox/logging/boost/logging/defaults.hpp                          |     6                                         
   sandbox/logging/boost/logging/detail/fwd.hpp                        |     1                                         
   sandbox/logging/boost/logging/detail/raw_doc/fixme.hpp              |    11 +                                       
   sandbox/logging/boost/logging/detail/raw_doc/namespace_concepts.hpp |     6                                         
   sandbox/logging/boost/logging/detail/raw_doc/table_of_contents.hpp  |     1                                         
   sandbox/logging/boost/logging/detail/raw_doc/workflow.hpp           |    14 +-                                      
   sandbox/logging/boost/logging/filter.hpp                            |     2                                         
   sandbox/logging/boost/logging/format.hpp                            |   275 --------------------------------------- 
   sandbox/logging/boost/logging/macros.hpp                            |     4                                         
   9 files changed, 31 insertions(+), 289 deletions(-)
Modified: sandbox/logging/boost/logging/defaults.hpp
==============================================================================
--- sandbox/logging/boost/logging/defaults.hpp	(original)
+++ sandbox/logging/boost/logging/defaults.hpp	2007-10-13 11:38:14 EDT (Sat, 13 Oct 2007)
@@ -36,6 +36,7 @@
 - @c hold_string_type - the type used to hold a string; by default, it's @c std::string
 - @c filter_type - the default filter; by default, it's filter::no_ts
 - @c lock_resource - used to lock resources for access. See locker namespace.
+- @c mutex - the mutex class used throughout the library. By default, it's mutex_win32 for Windows, or mutex_posix for POSIX 
 
 They are all present in @c default_types structure.
 
@@ -71,7 +72,9 @@
 
     namespace filter {
         struct no_ts;
-    };
+    }
+
+
 
     struct default_types {
         typedef char char_type;
@@ -87,6 +90,7 @@
             };
         };
 
+        typedef boost::logging::threading::mutex mutex;
 
     };
 
Modified: sandbox/logging/boost/logging/detail/fwd.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/fwd.hpp	(original)
+++ sandbox/logging/boost/logging/detail/fwd.hpp	2007-10-13 11:38:14 EDT (Sat, 13 Oct 2007)
@@ -45,6 +45,7 @@
     typedef types<override>::char_type char_type;
     typedef types<override>::hold_string_type hold_string_type;
     typedef types<override>::filter_type filter_type;
+    typedef types<override>::mutex mutex;
 
     namespace writer {};
 
Added: sandbox/logging/boost/logging/detail/manipulator.hpp
==============================================================================
--- (empty file)
+++ sandbox/logging/boost/logging/detail/manipulator.hpp	2007-10-13 11:38:14 EDT (Sat, 13 Oct 2007)
@@ -0,0 +1,323 @@
+// manipulator.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_manipulator_HPP_DEFINED
+#define JT28092007_manipulator_HPP_DEFINED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <boost/logging/detail/fwd.hpp>
+
+namespace boost { namespace logging {
+
+
+/** 
+@brief Manipulators = Formatters and/or destinations.
+
+All formatters need to derive from a <b>common %base class</b>. Same goes for destinations.
+
+Remember:
+- formatter - allows formatting the message before writing it (like, prepending extra information - an index, the time, thread id, etc)
+- destination - is a place where the message is to be written to (like, the console, a file, a socket, etc)
+
+In your @ref boost::logging::writer::format_write "format_write" object, you can have several formatters and destinations. Note that each formatter class and each destination class is a @c %manipulator.
+
+
+
+When dealing with formatters, the first thing you must do is to specify that common %base class.
+All formatter classes will derive from it, directly or indirectly. Again, same goes for destinations.
+
+
+Note that the %formatter %base class and the %destination %base class don't need to be the same. Example:
+
+@code
+typedef optimize::cache_string_one_str<> cache_string;
+typedef formatter::base<cache_string&, op_equal::same_type > format_base;
+
+
+struct write_time : format_base {
+    void operator()(cache_string & str) const {
+        char t[10];
+        time_t now = time(0);
+        tm details = *localtime(&now);
+        strftime(t, 10, "%M:%S ", &details);
+        str.prepend_string(t);
+    }
+};
+//...
+
+typedef destination::base<const std::string &, op_equal::same_type> destination_base;
+struct write_to_cout : destination_base {
+    void operator()(param msg) const {
+        std::cout << msg ;
+    }
+};
+
+@endcode
+
+This namespace contains the classes formatter or destination classes need to use as %base class.
+
+
+
+@section manipulator_base Manipulator base classes
+
+Your formatter or destination class should derive from either of the following:
+- base - recommented %base class 
+- base_no_operator_call - %base class , not implementing the operator() call
+
+
+
+
+@section share_data Sharing data for manipulator classes
+
+The manipulator classes need to contain data as constant:
+
+@code
+struct my_formatter : format_base {
+    ...
+private:
+    const int m_idx;
+};
+@endcode
+
+As long as data is constant, it's all ok - that is, no matter what functions get called, all the data in the formatter/destination
+must remain constant. We need constant functors - just like in STL - because internally, we copy formatters/destinations: that is, we keep
+several copies of a certain object - they all need to be syncronized. In case the objects' data is constant, that's no problem.
+
+In case the data needs to be changed - it needs to be shared. Several copies of the same instance must point to the same data. In other words,
+use shared pointers:
+
+@code
+struct write_to_file {
+    typedef boost::shared_ptr<std::ofstream> ptr;
+    write_to_file(const std::string & filename) : m_out(new std::ofstream(filename.c_str())) {}
+    void operator()(const std::string & msg) const {
+        (*m_out) << msg << std::endl ;
+    }
+    mutable ptr m_out;
+};
+@endcode
+
+Since quite a few of the manipulator objects will need this, it's quite acceptable to have a class that deals with this:
+the non_const_context class.
+
+
+*/
+namespace manipulator {
+
+    namespace detail {
+        struct default_type {};
+        template<class type_> struct ptr_finder { 
+            template<class other_type> struct find { typedef other_type type ; };            
+        };
+        template<> struct ptr_finder<default_type> {
+            template<class other_type> struct find { typedef other_type* type ; };
+        };
+    }
+
+/** 
+Formatters and/or destinations are Manipulators.
+    
+All formatter or destination class need to directly or indirectly derive from this.
+
+All formatters need to derive from a common %base class.
+When dealing with formatters, the first thing you must do is to specify that common base class.
+All formatter classes will derive from it, directly or indirectly.
+
+Same goes for destinations.
+
+Note that the formatter base class and the destination base class don't need to be the same.
+
+You should derive your formatter or destination class from this, ONLY if you want to provide 
+your own operator() which could take more than one argument. Otherwise, derive from base.
+
+
+@section implementing_op_equal_ Implementing operator==
+
+Formatter objects must be able to be compared. Same goes for destination objects. This is especially 
+needed when a formatter or destination is to be erased - from a @ref boost::logging::writer::format_write "format_write" object.
+
+There are multiple ways to be able to compare formatter/destination objects - see op_equal namespace.
+
+By default, @ref boost::logging::op_equal::same_type_op_equal_base is used.
+
+
+
+
+@param implement_op_equal see @ref implementing_op_equal_ 
+
+@param ptr_type_ the type used to hold a pointer to the type. By defaut, it's the type itself.
+
+*/
+template<
+        class implement_op_equal = op_equal::same_type_op_equal_base,
+        class ptr_type_ = detail::default_type > 
+            struct base_no_operator_call : implement_op_equal {
+
+    typedef base_no_operator_call<implement_op_equal, ptr_type_> self_type;
+    typedef typename detail::ptr_finder<ptr_type_> type_finder;
+    typedef typename type_finder::find<self_type>::type ptr_type;
+
+    virtual ~base_no_operator_call() {}
+};
+
+
+/** 
+    Helper - in case your formatter or destination, in its operator(), it has only one argument
+    (which is most of the time, unless you're doing something extreme ;)), you should derive from this.
+
+
+    Examples:
+    @code
+    // takes a "string&" as argument:
+    struct append_enter : single_param_base<std::string&> {
+        // param - typedef defined in base class; param = std::string&
+        void operator()(param a) {
+            a += "\n";
+        }
+    }
+
+    // takes a "const std::string&" as argument
+    struct write_to_cout : single_param_base<const std::string&> {
+        void operator()(param msg) const {
+            std::cout << msg << std::endl ;
+        }
+    };
+    @endcode
+
+
+@param implement_op_equal see @ref implementing_op_equal_ 
+
+*/
+template<
+        class arg_type, 
+        class implement_op_equal = op_equal::same_type_op_equal_base,
+        class ptr_type_ = detail::default_type > 
+            struct base : base_no_operator_call<implement_op_equal, ptr_type_> {
+
+    typedef base<arg_type, implement_op_equal, ptr_type_> self_type;
+    typedef typename detail::ptr_finder<ptr_type_> type_finder;
+    typedef typename type_finder::find<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> raw_param;
+
+    virtual ~base() {}
+    virtual void operator()(param val) const = 0;
+};
+
+/** 
+    In case your manipulator (formatter or destination) needs to hold non-const context information, it can to derive from this.
+    This automatically creates a shared pointer to the context information.
+
+    Also, it provides the following operations:
+
+    @c context(), which returns a <tt>context_type &</tt> reference
+
+    Example:
+
+@code
+struct write_to_file : destination_base, destination::non_const_context<std::ofstream> {
+write_to_file(const char* filename) : non_const_context_base(filename) {}
+void operator()(param msg) const {
+    context() << msg ;
+}
+};
+@endcode
+
+
+    @remarks
+    In case your manipulator has constant data, you don't need this
+*/
+template<class context_type> struct non_const_context {
+
+    // this can be used in the parent class, to forward data from its constructor
+    typedef non_const_context<context_type> non_const_context_base;
+private:
+    typedef non_const_context<context_type> self_type;
+    typedef boost::shared_ptr<context_type> ptr_type;
+
+protected:
+    non_const_context() : m_context(new context_type) {}
+    non_const_context(const non_const_context& other) : m_context(other.m_context) {}
+    
+    BOOST_LOGGING_FORWARD_CONSTRUCTOR_WITH_NEW(non_const_context,m_context,context_type)
+
+    context_type & context() const    { return *(m_context.get()); }
+
+private:
+    mutable ptr_type m_context;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+} // namespace manipulator
+
+/** 
+@brief Formatter is a manipulator. It allows you to format the message before writing it to the destination(s)
+
+talk about format_base
+
+FIXME
+
+@sa manipulator::base, manipulator::base_no_opearator_call, manipulator::non_const_context
+*/
+namespace formatter {
+    using boost::logging::manipulator::base;
+    using boost::logging::manipulator::base_no_operator_call;
+    using boost::logging::manipulator::non_const_context;
+}
+
+/**  
+@brief Destination is a manipulator. It contains a place where the message, after being formatted, is to be written to.
+
+Some viable destinations are : the console, a file, a socket, etc.
+
+
+talk about destination_base
+
+FIXME
+
+*/
+namespace destination {
+    using boost::logging::manipulator::base;
+    using boost::logging::manipulator::base_no_operator_call;
+    using boost::logging::manipulator::non_const_context;
+}
+
+}}
+
+#endif
+
Added: sandbox/logging/boost/logging/detail/raw_doc/acknowledgments.hpp
==============================================================================
--- (empty file)
+++ sandbox/logging/boost/logging/detail/raw_doc/acknowledgments.hpp	2007-10-13 11:38:14 EDT (Sat, 13 Oct 2007)
@@ -0,0 +1,17 @@
+namespace boost { namespace logging {
+
+/** 
+@page acknowledgements Acknowledgements
+
+There are quite a few thanks I owe:
+
+- The Boost community - for making me realize what was wrong with my first proposal
+- Charles Brockman - for thoroughly analyzing the docs
+- Darryl Green - for giving me lots of feedback and showing me other ways to solve things
+- Caleb Epstein - for porting parts of my code to any non-Windows OS, and implementing several formatters and destinations
+- Stefan Slapeta and Bill Wade and a lot of others for giving me early feedback.
+- Pavel Vozelinek - for very thourough reviews and lots of comments
+
+*/
+
+}}
Modified: sandbox/logging/boost/logging/detail/raw_doc/fixme.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/raw_doc/fixme.hpp	(original)
+++ sandbox/logging/boost/logging/detail/raw_doc/fixme.hpp	2007-10-13 11:38:14 EDT (Sat, 13 Oct 2007)
@@ -1,6 +1,12 @@
 /*
 compile all!
 
+
+in examples:
+write the results of each!!!!
+
+
+
 about process_msg
 about macros - macros.hpp -> have specific page
 about non_const_context
@@ -14,7 +20,10 @@
 where the code is - boost-sandbox
 
 
-overriding defaults
+convert_format - also explain that you can convert from str x to y; for instance write_time can actually append the time (instead of prepending it - default)!
+
+
+
 
 
 
Modified: sandbox/logging/boost/logging/detail/raw_doc/namespace_concepts.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/raw_doc/namespace_concepts.hpp	(original)
+++ sandbox/logging/boost/logging/detail/raw_doc/namespace_concepts.hpp	2007-10-13 11:38:14 EDT (Sat, 13 Oct 2007)
@@ -15,7 +15,7 @@
 In the given namespace, you'll find possible implementations of that concept. Of course, to those implementations, you can add your own ;)
 
 \n\n
-_at_section namespace_general General contepts
+@section namespace_general General concepts
 - filter - available filter implementations
 - level - in case you want to use Log Levels
 - writer - %writer objects; they do the actual write of the message 
@@ -30,14 +30,14 @@
 
 
 \n\n
-_at_section namespace_manipulator Manipulator contepts
+@section namespace_manipulator Manipulator concepts
 - manipulator - what a manipulator is: a formatter or a destination
 - formatter - available formatters
 - destination - available destinations
 
 
 \n\n
-_at_section namespace_write Writing contepts
+@section namespace_write Writing concepts
 - format_and_write - contains the logic for formatting and writing to destinations
 - msg_route - contains the logic for routing the message to the formatters and destinations
 - op_equal - implements operator==, in order to compare formatters and/or destinations. Useful when you want to 
Modified: sandbox/logging/boost/logging/detail/raw_doc/table_of_contents.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/raw_doc/table_of_contents.hpp	(original)
+++ sandbox/logging/boost/logging/detail/raw_doc/table_of_contents.hpp	2007-10-13 11:38:14 EDT (Sat, 13 Oct 2007)
@@ -33,6 +33,7 @@
 
 - @ref macros
 
+- @ref acknowledgements
 
 
 */
Added: sandbox/logging/boost/logging/detail/raw_doc/thread_safety.hpp
==============================================================================
--- (empty file)
+++ sandbox/logging/boost/logging/detail/raw_doc/thread_safety.hpp	2007-10-13 11:38:14 EDT (Sat, 13 Oct 2007)
@@ -0,0 +1,9 @@
+namespace boost { namespace logging {
+
+/** 
+@page thread_safety Thread safety
+
+
+*/
+
+}}
Modified: sandbox/logging/boost/logging/detail/raw_doc/workflow.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/raw_doc/workflow.hpp	(original)
+++ sandbox/logging/boost/logging/detail/raw_doc/workflow.hpp	2007-10-13 11:38:14 EDT (Sat, 13 Oct 2007)
@@ -15,7 +15,7 @@
 
 @section workflow_introduction Introduction
 
-So, what happens when a message is written to the log?
+What happens when a message is written to the log?
 
 First, you have a logger you write to. @b Every logger contains 2 things:
 - a filter, which indicates if the log is turned on or off
@@ -39,7 +39,7 @@
 
 @section workflow_filter Step 1: Filtering the message
 
-So, first time the message is filtered. The filter class only needs to provide the @c is_enabled function.
+First time the message is filtered. The filter class only needs to provide the @c is_enabled function.
 Then, the logger provides 2 helpers:
 - operator bool()
 - operator !
@@ -65,7 +65,7 @@
 
 @section workflow_processing Step 2: Processing the message
 
-So, once we've established that the logger is enabled, we'll @em process the message.
+Once we've established that the logger is enabled, we'll @em process the message.
 Processing means whatever your application thinks logging means.
 
 This can be as simple as dumping the message to cout or whatever.
@@ -99,7 +99,7 @@
 \n\n
 @section workflow_2a Step 2A: Gathering the message
 
-The meaning of "gathering the message" dependends on your application. The message can:
+The meaning of "gathering the message" depends on your application. The message can:
 - be a simple string,
 - it can contain extra info, like: level, category, etc.
 - it can be written all at once, or using the cool "<<" operator
@@ -120,7 +120,7 @@
 
 How you gather your message, depends on how you <tt>\#define L_ ...</tt>.
 
-So, in other words, gathering the message means getting all the message in "one piece", so that it can further be written. 
+In other words, gathering the message means getting all the message in "one piece", so that it can be written. 
 
 
 
@@ -150,12 +150,12 @@
 L_ << idx << " : reading word " << word;
 @endcode
 
-You can define your own types of writers. At this time, the %writer classes that come with this library are in <tt>namespace writer</tt>.
+You can define your own types of writers. The %writer classes that come with this library are in <tt>namespace writer</tt>.
 
 At this time, I've defined the concept of writer::format_write - writing using Formatters and Destinations.
 Simply put, this means formatting the message, and then writing it to destination(s).
 
-For each log, you decide where how messages are formatted, and to what destinations they are written. Example:
+For each log, you decide how messages are formatted and to what destinations they are written. Example:
 
 @code
 typedef process_msg< gather::ostream_like::return_cache_str<> , 
Modified: sandbox/logging/boost/logging/filter.hpp
==============================================================================
--- sandbox/logging/boost/logging/filter.hpp	(original)
+++ sandbox/logging/boost/logging/filter.hpp	2007-10-13 11:38:14 EDT (Sat, 13 Oct 2007)
@@ -106,7 +106,7 @@
     Filter that is always disabled
 */
 struct always_disabled {
-    static bool is_enabled() { return true; }
+    static bool is_enabled() { return false; }
 };
 
 
Modified: sandbox/logging/boost/logging/format.hpp
==============================================================================
--- sandbox/logging/boost/logging/format.hpp	(original)
+++ sandbox/logging/boost/logging/format.hpp	2007-10-13 11:38:14 EDT (Sat, 13 Oct 2007)
@@ -541,283 +541,10 @@
     //
 
 
-    /** 
-    @brief Manipulators = Formatters and/or destinations.
-
-    All formatters need to derive from a <b>common %base class</b>. Same goes for destinations.
-
-    Remember:
-    - formatter - allows formatting the message before writing it (like, prepending extra information - an index, the time, thread id, etc)
-    - destination - is a place where the message is to be written to (like, the console, a file, a socket, etc)
-
-    In your @ref boost::logging::writer::format_write "format_write" object, you can have several formatters and destinations. Note that each formatter class and each destination class is a @c %manipulator.
-
-
-
-    When dealing with formatters, the first thing you must do is to specify that common %base class.
-    All formatter classes will derive from it, directly or indirectly. Again, same goes for destinations.
-
-
-    Note that the %formatter %base class and the %destination %base class don't need to be the same. Example:
-
-    @code
-    typedef optimize::cache_string_one_str<> cache_string;
-    typedef formatter::base<cache_string&, op_equal::same_type > format_base;
-    
-    
-    struct write_time : format_base {
-        void operator()(cache_string & str) const {
-            char t[10];
-            time_t now = time(0);
-            tm details = *localtime(&now);
-            strftime(t, 10, "%M:%S ", &details);
-            str.prepend_string(t);
-        }
-    };
-    //...
-
-    typedef destination::base<const std::string &, op_equal::same_type> destination_base;
-    struct write_to_cout : destination_base {
-        void operator()(param msg) const {
-            std::cout << msg ;
-        }
-    };
-
-    @endcode
-
-    This namespace contains the classes formatter or destination classes need to use as %base class.
-
-
-
-    @section manipulator_base Manipulator base classes
-
-    Your formatter or destination class should derive from either of the following:
-    - base - recommented %base class 
-    - base_no_operator_call - %base class , not implementing the operator() call
-
-    
-
-
-    @section share_data Sharing data for manipulator classes
-
-    The manipulator classes need to contain data as constant:
-
-    @code
-    struct my_formatter : format_base {
-        ...
-    private:
-        const int m_idx;
-    };
-    @endcode
-
-    As long as data is constant, it's all ok - that is, no matter what functions get called, all the data in the formatter/destination
-    must remain constant. We need constant functors - just like in STL - because internally, we copy formatters/destinations: that is, we keep
-    several copies of a certain object - they all need to be syncronized. In case the objects' data is constant, that's no problem.
-
-    In case the data needs to be changed - it needs to be shared. Several copies of the same instance must point to the same data. In other words,
-    use shared pointers:
-
-    @code
-    struct write_to_file {
-        typedef boost::shared_ptr<std::ofstream> ptr;
-        write_to_file(const std::string & filename) : m_out(new std::ofstream(filename.c_str())) {}
-        void operator()(const std::string & msg) const {
-            (*m_out) << msg << std::endl ;
-        }
-        mutable ptr m_out;
-    };
-    @endcode
-
-    Since quite a few of the manipulator objects will need this, it's quite acceptable to have a class that deals with this:
-    the non_const_context class.
-
-    
-    */
-    namespace manipulator {
-
-        namespace detail {
-            struct default_type {};
-            template<class type_> struct ptr_finder { 
-                template<class other_type> struct find { typedef other_type type ; };            
-            };
-            template<> struct ptr_finder<default_type> {
-                template<class other_type> struct find { typedef other_type* type ; };
-            };
-        }
-
-    /** 
-    Formatters and/or destinations are Manipulators.
-        
-    All formatter or destination class need to directly or indirectly derive from this.
-
-    All formatters need to derive from a common %base class.
-    When dealing with formatters, the first thing you must do is to specify that common base class.
-    All formatter classes will derive from it, directly or indirectly.
-
-    Same goes for destinations.
-
-    Note that the formatter base class and the destination base class don't need to be the same.
-
-    You should derive your formatter or destination class from this, ONLY if you want to provide 
-    your own operator() which could take more than one argument. Otherwise, derive from base.
-
-
-    @section implementing_op_equal_ Implementing operator==
-
-    Formatter objects must be able to be compared. Same goes for destination objects. This is especially 
-    needed when a formatter or destination is to be erased - from a @ref boost::logging::writer::format_write "format_write" object.
-
-    There are multiple ways to be able to compare formatter/destination objects - see op_equal namespace.
-
-    By default, @ref boost::logging::op_equal::same_type_op_equal_base is used.
-
-
-
-
-    @param implement_op_equal see @ref implementing_op_equal_ 
-
-    @param ptr_type_ the type used to hold a pointer to the type. By defaut, it's the type itself.
-
-    */
-    template<
-            class implement_op_equal = op_equal::same_type_op_equal_base,
-            class ptr_type_ = detail::default_type > 
-                struct base_no_operator_call : implement_op_equal {
-
-        typedef base_no_operator_call<implement_op_equal, ptr_type_> self_type;
-        typedef typename detail::ptr_finder<ptr_type_> type_finder;
-        typedef typename type_finder::find<self_type>::type ptr_type;
-
-        virtual ~base_no_operator_call() {}
-    };
-
-
-    /** 
-        Helper - in case your formatter or destination, in its operator(), it has only one argument
-        (which is most of the time, unless you're doing something extreme ;)), you should derive from this.
-
-
-        Examples:
-        @code
-        // takes a "string&" as argument:
-        struct append_enter : single_param_base<std::string&> {
-            // param - typedef defined in base class; param = std::string&
-            void operator()(param a) {
-                a += "\n";
-            }
-        }
-
-        // takes a "const std::string&" as argument
-        struct write_to_cout : single_param_base<const std::string&> {
-            void operator()(param msg) const {
-                std::cout << msg << std::endl ;
-            }
-        };
-        @endcode
-
-
-    @param implement_op_equal see @ref implementing_op_equal_ 
-
-    */
-    template<
-            class arg_type, 
-            class implement_op_equal = op_equal::same_type_op_equal_base,
-            class ptr_type_ = detail::default_type > 
-                struct base : base_no_operator_call<implement_op_equal, ptr_type_> {
-
-        typedef base<arg_type, implement_op_equal, ptr_type_> self_type;
-        typedef typename detail::ptr_finder<ptr_type_> type_finder;
-        typedef typename type_finder::find<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> raw_param;
-
-        virtual ~base() {}
-        virtual void operator()(param val) const = 0;
-    };
-
-    /** 
-        In case your manipulator (formatter or destination) needs to hold non-const context information, it can to derive from this.
-        This automatically creates a shared pointer to the context information.
-
-        Also, it provides the following operations:
-
-        @c context(), which returns a <tt>context_type &</tt> reference
-
-        Example:
-
-_at_code
-struct write_to_file : destination_base, destination::non_const_context<std::ofstream> {
-    write_to_file(const char* filename) : non_const_context_base(filename) {}
-    void operator()(param msg) const {
-        context() << msg ;
-    }
-};
-_at_endcode
-
-
-        @remarks
-        In case your manipulator has constant data, you don't need this
-    */
-    template<class context_type> struct non_const_context {
-
-        // this can be used in the parent class, to forward data from its constructor
-        typedef non_const_context<context_type> non_const_context_base;
-    private:
-        typedef non_const_context<context_type> self_type;
-        typedef boost::shared_ptr<context_type> ptr_type;
-
-    protected:
-        non_const_context() : m_context(new context_type) {}
-        non_const_context(const non_const_context& other) : m_context(other.m_context) {}
-        
-        BOOST_LOGGING_FORWARD_CONSTRUCTOR_WITH_NEW(non_const_context,m_context,context_type)
-
-        context_type & context() const    { return *(m_context.get()); }
-
-    private:
-        mutable ptr_type m_context;
-    };
-
-    } // namespace manipulator
-
-    /** 
-    @brief Formatter is a manipulator. It allows you to format the message before writing it to the destination(s)
-
-    talk about format_base
-
-    FIXME
-
-    @sa manipulator::base, manipulator::base_no_opearator_call, manipulator::non_const_context
-    */
-    namespace formatter {
-        using boost::logging::manipulator::base;
-        using boost::logging::manipulator::base_no_operator_call;
-        using boost::logging::manipulator::non_const_context;
-    }
-
-    /**  
-    @brief Destination is a manipulator. It contains a place where the message, after being formatted, is to be written to.
-
-    Some viable destinations are : the console, a file, a socket, etc.
-
-
-    talk about destination_base
-
-    FIXME
-    
-    */
-    namespace destination {
-        using boost::logging::manipulator::base;
-        using boost::logging::manipulator::base_no_operator_call;
-        using boost::logging::manipulator::non_const_context;
-    }
 
 }}
 
+#include <boost/logging/detail/manipulator.hpp>
 #include <boost/logging/writer/format_write.hpp>
 
 #endif
Added: sandbox/logging/boost/logging/format/destination/defaults.hpp
==============================================================================
--- (empty file)
+++ sandbox/logging/boost/logging/format/destination/defaults.hpp	2007-10-13 11:38:14 EDT (Sat, 13 Oct 2007)
@@ -0,0 +1,37 @@
+// destination_defaults.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_destination_defaults_HPP_DEFINED
+#define JT28092007_destination_defaults_HPP_DEFINED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <boost/logging/detail/fwd.hpp>
+
+namespace boost { namespace logging { namespace destination {
+
+// console, file, debug window
+
+
+
+rolling files/sharing memory
+
+}}}
+
+#endif
+
Added: sandbox/logging/boost/logging/format/destination/file.hpp
==============================================================================
--- (empty file)
+++ sandbox/logging/boost/logging/format/destination/file.hpp	2007-10-13 11:38:14 EDT (Sat, 13 Oct 2007)
@@ -0,0 +1,33 @@
+// destination_file.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_destination_file_HPP_DEFINED
+#define JT28092007_destination_file_HPP_DEFINED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <boost/logging/detail/fwd.hpp>
+
+namespace boost { namespace logging { namespace destination {
+
+
+
+}}}
+
+#endif
+
Added: sandbox/logging/boost/logging/format/formatter/convert_format.hpp
==============================================================================
--- (empty file)
+++ sandbox/logging/boost/logging/format/formatter/convert_format.hpp	2007-10-13 11:38:14 EDT (Sat, 13 Oct 2007)
@@ -0,0 +1,111 @@
+// convert_format.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_convert_format_HPP_DEFINED
+#define JT28092007_convert_format_HPP_DEFINED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <boost/logging/detail/fwd.hpp>
+#include <boost/logging/format/optimize.hpp>
+
+namespace boost { namespace logging { namespace formatter {
+
+
+/** 
+    @brief Allows format convertions - In case you're using a formatter that does not match your string type
+
+    In case you want to use a formatter developed by someone else (for instance, a formatter provided by this lib),
+    perhaps you're using another type of string to hold the message - thus, you need to provide a conversion function
+
+    Example:
+    FIXME
+
+    --> convert_format::prepend
+
+    explain that you can extend the following - since they're namespaces!!!
+    so that you can "inject" your own write function in the convert_format::prepend/orwhatever namespace, and
+    then it'll be automatically used!
+*/
+namespace convert_format {
+    typedef boost::logging::char_type char_type;
+    typedef std::basic_string<char_type> string_type;
+
+    /**
+    Example : write_time
+    */
+    namespace prepend {
+        void write(const string_type & src, string & dest) {
+            dest.insert( dest.begin(), src.begin(), src.end() );
+        }
+        template<class string> void write(const string_type & src, boost::logging::optimize::cache_string_one_str<string> & dest) {
+            dest.prepend_string(src);
+        }
+    }
+
+    /** 
+    */
+    namespace append {
+        void write(const string_type & src, string & dest) {
+            dest += src;
+        }
+        template<class string> void write(const string_type & src, boost::logging::optimize::cache_string_one_str<string> & dest) {
+            dest.append_string(src);
+        }
+    }
+
+    /** 
+    */
+    namespace modify {
+        void write(const string_type & src, string & dest) {
+            dest = src;
+        }
+        template<class string> void write(const string_type & src, boost::logging::optimize::cache_string_one_str<string> & dest) {
+            dest.set_string(src);
+        }
+    }
+}
+
+
+
+struct do_convert_format {
+    struct prepend {
+        template<class string> void write(const string_type & src, string & dest) {
+            convert_format::prepend::write(src, dest);
+        }
+    };
+
+    struct append {
+        template<class string> void write(const string_type & src, string & dest) {
+            convert_format::append::write(src, dest);
+        }
+    };
+
+    struct modify {
+        template<class string> void write(const string_type & src, string & dest) {
+            convert_format::modify::write(src, dest);
+        }
+    };
+};
+
+
+
+}}}
+
+#endif
+
Added: sandbox/logging/boost/logging/format/formatter/defaults.hpp
==============================================================================
--- (empty file)
+++ sandbox/logging/boost/logging/format/formatter/defaults.hpp	2007-10-13 11:38:14 EDT (Sat, 13 Oct 2007)
@@ -0,0 +1,99 @@
+// formatter_defaults.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_formatter_defaults_HPP_DEFINED
+#define JT28092007_formatter_defaults_HPP_DEFINED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <boost/logging/detail/fwd.hpp>
+#include <boost/logging/detail/manipulator.hpp>
+#include <boost/logging/format/formatter/time.hpp>
+#include <stdio.h>
+#include <time.h>
+
+namespace boost { namespace logging { namespace formatter {
+
+
+/** 
+@brief prefixes each message with an index. 
+
+Example:
+@code
+L_ << "my message";
+L_ << "my 2nd message";
+@endcode
+
+This will output something similar to:
+
+@code
+[1] my message
+[2] my 2nd message
+@endcode
+
+
+@param convert [optional] In case there needs to be a conversion between std::(w)string and the string that holds your logged message. See convert_format.
+For instance, you might use @ref boost::logging::optimize::cache_string_one_str "a cached_string class" (see @ref boost::logging::optimize "optimize namespace").
+*/
+template<class convert = do_convert_format::prepend> struct write_idx : formatter::non_const_context<int> {
+    write_idx() : non_const_context_base((int)0) {}
+    template<class msg_type> void operator()(msg_type & str) const {
+        std::basic_ostringstream<char_type> idx;
+        idx << _T("[") << ++context() << _T("] ");
+
+        convert::write( idx.str(), str );
+    }
+};
+
+
+/** 
+@brief Appends an enter
+
+@param convert [optional] In case there needs to be a conversion between std::(w)string and the string that holds your logged message. See convert_format.
+For instance, you might use @ref boost::logging::optimize::cache_string_one_str "a cached_string class" (see @ref boost::logging::optimize "optimize namespace").
+*/
+template<class convert = do_convert_format::prepend> struct append_enter {
+    template<class msg_type> void operator()(msg_type & str) const {
+        convert::write( _T("\n"), str );
+    }
+};
+
+
+/** 
+@brief Appends an enter, if not already there
+
+@param convert [optional] In case there needs to be a conversion between std::(w)string and the string that holds your logged message. See convert_format.
+For instance, you might use @ref boost::logging::optimize::cache_string_one_str "a cached_string class" (see @ref boost::logging::optimize "optimize namespace").
+*/
+template<class convert = do_convert_format::append> struct append_enter_if_needed {
+    template<class msg_type> void operator()(msg_type & str) const {
+        bool is_needed = true;
+        if ( !str.empty())
+            if ( str[ str.size() - 1] == '\n')
+                is_needed = false;
+
+        if ( is_needed)
+            convert::write( _T("\n"), str );
+    }
+};
+
+
+}}}
+
+#endif
+
Added: sandbox/logging/boost/logging/format/formatter/thread_id.hpp
==============================================================================
--- (empty file)
+++ sandbox/logging/boost/logging/format/formatter/thread_id.hpp	2007-10-13 11:38:14 EDT (Sat, 13 Oct 2007)
@@ -0,0 +1,53 @@
+// formatter_thread_id.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_formatter_thread_id_HPP_DEFINED
+#define JT28092007_formatter_thread_id_HPP_DEFINED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <boost/logging/detail/fwd.hpp>
+
+namespace boost { namespace logging { namespace formatter {
+
+/** 
+@brief Writes the thread_id to the log
+
+@param convert [optional] In case there needs to be a conversion between std::(w)string and the string that holds your logged message. See convert_format.
+For instance, you might use @ref boost::logging::optimize::cache_string_one_str "a cached_string class" (see @ref boost::logging::optimize "optimize namespace").
+*/
+template<class convert = do_convert_format::prepend> struct thread_id {
+    template<class msg_type> void operator()(msg_type & msg) {
+        std::basic_ostringstream<char_type> out;
+        out << _T("[T")
+    #if defined (BOOST_HAS_WINTHREADS)
+            << ::GetCurrentThreadId()
+    #elif defined (BOOST_HAS_PTHREADS)
+            << pthread_self ()
+    #elif defined (BOOST_HAS_MPTASKS)
+            << MPCurrentTaskID()
+    #endif
+            << _T("] ");
+
+        convert::write( out.str(), msg );
+    }
+
+}}}
+
+#endif
+
Added: sandbox/logging/boost/logging/format/formatter/time.hpp
==============================================================================
--- (empty file)
+++ sandbox/logging/boost/logging/format/formatter/time.hpp	2007-10-13 11:38:14 EDT (Sat, 13 Oct 2007)
@@ -0,0 +1,197 @@
+// formatter_time.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_formatter_time_HPP_DEFINED
+#define JT28092007_formatter_time_HPP_DEFINED
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <boost/logging/detail/fwd.hpp>
+#include <boost/logging/format/formatter/convert_format.hpp>
+#include <stdio.h>
+#include <time.h>
+
+namespace boost { namespace logging { namespace formatter {
+
+/**
+@brief Prefixes the message with the time. You pass the format string at construction.
+
+It's friendlier than write_time_strf (which uses strftime).
+
+The format can contain escape sequences:
+$dd - day, 2 digits
+$MM - month, 2 digits
+$yy - year, 2 digits
+$yyyy - year, 4 digits
+$hh - hour, 2 digits
+$mm - minute, 2 digits
+$ss - second, 2 digits
+
+Example: write_time("Today is $dd/$MM/$yyyy");
+
+@param convert [optional] In case there needs to be a conversion between std::(w)string and the string that holds your logged message. See convert_format.
+For instance, you might use @ref boost::logging::optimize::cache_string_one_str "a cached_string class" (see @ref boost::logging::optimize "optimize namespace").
+*/
+template<class convert = do_convert_format::prepend> struct write_time {
+private:
+    typedef std::basic_string<c_type> string_type;
+
+    struct index_info {
+        typedef string_type::size_type uint;
+        
+        index_info(uint src_idx, int *format_idx, int size = 2) : src_idx(src_idx), format_idx(format_idx), size(size) {}
+        uint src_idx;
+        int * format_idx;
+        int size;
+
+        static bool by_index(const index_info & first, const index_info & second) {
+            return first.src_idx < second.src_idx;
+        }
+    };
+
+public:
+
+    /** 
+        constructs a write_time object
+    */
+    write_time(const string_type & format) : m_day(-1), m_month(-1), m_yy(-1), m_yyyy(-1), m_hour(-1), m_min(-1), m_sec(-1) {
+        // format too big
+        assert( format.size() < 64);
+
+        typedef string_type::size_type uint;
+        uint day_idx    = format.find(_T("$dd"));
+        uint month_idx  = format.find(_T("$MM"));
+        uint yy_idx     = format.find(_T("$yy"));
+        uint yyyy_idx   = format.find(_T("$yyyy"));
+        uint hour_idx   = format.find(_T("$hh"));
+        uint min_idx    = format.find(_T("$mm"));
+        uint sec_idx    = format.find(_T("$ss"));
+
+        typedef std::vector<index_info> array;
+        array indexes;
+        if ( day_idx != logging_types::string::npos)
+            indexes.push_back( index_info(day_idx, &m_day) );
+        if ( month_idx != logging_types::string::npos)
+            indexes.push_back( index_info(month_idx, &m_month) );
+
+        if ( yy_idx != logging_types::string::npos || yyyy_idx != logging_types::string::npos)
+            if ( yyyy_idx  != logging_types::string::npos)
+                indexes.push_back( index_info(yyyy_idx, &m_yyyy, 4) );
+            else
+                indexes.push_back( index_info(yy_idx, &m_yy) );
+
+        if ( hour_idx != logging_types::string::npos)
+            indexes.push_back( index_info(hour_idx, &m_hour ) );
+        if ( min_idx != logging_types::string::npos)
+            indexes.push_back( index_info(min_idx, &m_min) );
+        if ( sec_idx != logging_types::string::npos)
+            indexes.push_back( index_info(sec_idx, &m_sec) );
+        std::sort( indexes.begin(), indexes.end(), index_info::by_index);
+        
+        // create the format string, that we can actually pass to sprintf 
+        uint prev_idx = 0;
+        int idx = 0;
+        for ( array::iterator begin = indexes.begin(), end = indexes.end(); begin != end; ++begin) {
+            m_format += format.substr( prev_idx, begin->src_idx - prev_idx);
+            *begin->format_idx = idx;
+            m_format += (begin->size == 4) ? _T("%04d") : _T("%02d");
+            prev_idx = begin->src_idx + begin->size + 1;
+            ++idx;
+        }
+
+        m_format += format.substr(prev_idx);
+    }
+
+
+
+
+    template<class msg_type> void operator()(msg_type & msg) {
+        char_type buffer[64];
+
+        time_t t = time(0); 
+        tm details = *localtime( &t);
+
+        int vals[8];
+        vals[m_day + 1]      = details.tm_mday;
+        vals[m_month + 1]    = details.tm_mon + 1; // many thanks to Matthew P. Cashdollar
+        vals[m_yy + 1]       = details.tm_year % 100; // many thanks to Andy Schweitzer
+        vals[m_yyyy + 1]     = details.tm_year + 1900;
+        vals[m_hour + 1]     = details.tm_hour;
+        vals[m_min + 1]      = details.tm_min;
+        vals[m_sec + 1]      = details.tm_sec;
+      
+        // ignore value at index 0 - it's there so that I don't have to test for an index being -1
+    #ifdef UNICODE
+        swprintf( buffer, m_format.c_str(), vals[1], vals[2], vals[3], vals[4], vals[5], vals[6], vals[7] );
+    #else
+        sprintf( buffer, m_format.c_str(), vals[1], vals[2], vals[3], vals[4], vals[5], vals[6], vals[7] );
+    #endif
+
+        convert::write(buffer, msg);
+    }
+
+
+private:
+    // the indexes of each escape sequence within the format string
+    int m_day, m_month, m_yy, m_yyyy, m_hour, m_min, m_sec;
+    hold_string_type m_format;
+};
+
+
+/**
+@brief Prefixes the message with the time, by using strftime function. You pass the format string at construction.
+
+@param msg_type The type that holds your logged message.
+
+@param convert [optional] In case there needs to be a conversion between std::(w)string and the string that holds your logged message. See convert_format.
+For instance, you might use @ref boost::logging::optimize::cache_string_one_str "a cached_string class" (see @ref boost::logging::optimize "optimize namespace").
+*/
+template<class convert = do_convert_format::prepend> struct write_time_strf {
+
+    /** 
+        constructs a write_time_strf object
+
+        @param format the time format , strftime-like
+        @param localtime if true, use localtime, otherwise global time
+    */
+    write_time_strf(const logging_types::string & format, bool localtime)
+        : m_format (format), m_localtime (localtime)
+    {}
+
+    template<class msg_type> void operator()(msg_type & msg) {
+        char_type buffer[64];
+        time_t t = time (0); 
+        tm t_details = m_localtime ? *localtime( &m_t) : *gmtime( &m_t);
+    #ifdef UNICODE
+        if (0 != wcsftime (buffer, sizeof (buffer), m_format.c_str (), &t_details))
+    #else
+        if (0 != strftime (buffer, sizeof (buffer), m_format.c_str (), &t_details))
+    #endif
+            convert::write(buffer, msg);
+    }
+
+    logging_types::string m_format;
+    bool m_localtime;
+
+};
+
+
+}}}
+
+#endif
+
Modified: sandbox/logging/boost/logging/macros.hpp
==============================================================================
--- sandbox/logging/boost/logging/macros.hpp	(original)
+++ sandbox/logging/boost/logging/macros.hpp	2007-10-13 11:38:14 EDT (Sat, 13 Oct 2007)
@@ -29,9 +29,9 @@
     @page macros Macros - how, what for?
 
     When dealing with logs, you will most likely want to use macros: simply to write less.
-    If order to be efficient, you usually want to write to a log only if it's enabled.
+    To be efficient, you usually want to write to a log only if it's enabled.
 
-    So, either you always write: <tt> if ( g_log) g_log .... </tt>, or, you create macros:
+    Either you always write: <tt> if ( g_log) g_log .... </tt>, or, you create macros:
     
     @code
     #define L_ if ( g_log) g_log ....