|
Boost-Commit : |
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 ....
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk