|
Boost-Commit : |
From: john.groups_at_[hidden]
Date: 2007-10-19 08:12:16
Author: jtorjo
Date: 2007-10-19 08:12:15 EDT (Fri, 19 Oct 2007)
New Revision: 40182
URL: http://svn.boost.org/trac/boost/changeset/40182
Log:
[logging]
v0.7.3, 19 oct 2007
- added the manipulator::class_ concept
- added some documentation
Added:
sandbox/logging/boost/logging/detail/raw_doc/common_usage.hpp (contents, props changed)
sandbox/logging/boost/logging/detail/raw_doc/customize_manipulator.hpp (contents, props changed)
Removed:
sandbox/logging/lib/logging/doc/html/
Text files modified:
sandbox/logging/boost/logging/detail/manipulator.hpp | 301 ++++++++++++++++++++++++---------------
sandbox/logging/boost/logging/detail/raw_doc/main.hpp | 2
sandbox/logging/boost/logging/detail/raw_doc/table_of_contents.hpp | 9
sandbox/logging/boost/logging/format.hpp | 2
sandbox/logging/boost/logging/format/destination/defaults.hpp | 2
sandbox/logging/boost/logging/format/formatter/defaults.hpp | 4
sandbox/logging/boost/logging/format/formatter/time.hpp | 12
sandbox/logging/lib/logging/samples/vc8/loggingvc8/loggingvc8.vcproj | 15 +
sandbox/logging/lib/logging/src/changelog.txt | 12 +
sandbox/logging/lib/logging/tests/format/test_manip_w_msgroute.cpp | 14 -
sandbox/logging/lib/logging/tests/format/test_simple_formatter.cpp | 16 +-
11 files changed, 245 insertions(+), 144 deletions(-)
Modified: sandbox/logging/boost/logging/detail/manipulator.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/manipulator.hpp (original)
+++ sandbox/logging/boost/logging/detail/manipulator.hpp 2007-10-19 08:12:15 EDT (Fri, 19 Oct 2007)
@@ -26,193 +26,235 @@
namespace boost { namespace logging {
+typedef enum implement_op_equal {
+ op_equal_no_context,
+ op_equal_has_context
+};
+
+
/**
@brief Manipulators = Formatters and/or destinations.
+
+- @ref manipulator_common
+- @ref manipulator_base_class
+- @ref manipulator_generic
+- @ref manipulator_create
+- @ref manipulator_share_data
+
+
+
+\n\n\n
+@section manipulator_common Common base class
+
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.
+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.
+Each formatter and destination classes implement <tt>operator()(arg_type msg);</tt>, which
+processes the message:
+- for a formatter, this formats the msg (like, prepends time to it, appends an enter, etc)
+- for a destination, this writes the message to a destination (like, to console, a file, etc)
-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.
+\n\n\n
+@section manipulator_base_class Specifying the base class
-Note that the %formatter %base class and the %destination %base class don't need to be the same. Example:
+As said @ref manipulator_common "above", formatters and destinations need a %base class.
+You do this through a typedef - one for the formatters, and one for the destinations:
@code
-typedef optimize::cache_string_one_str<> cache_string;
-typedef formatter::base<cache_string&, op_equal::same_type > format_base;
-
+// ptr_type - optional ; usualy you don't need to worry about this
+typedef formatter::base<arg_type [,ptr_type]> formatter_base;
+typedef destination::base<arg_type [,ptr_type]> destination_base;
+@endcode
-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);
- }
-};
-//...
+The @c arg_type is the argument you receive in your <tt>operator()</tt>, to process the message. It can be as simple as this:
-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 ;
- }
-};
+@code
+// formatter - needs to modify the message
+typedef formatter::base< std::string&> formatter_base;
+// destination - needs to write the message - usually, it doesn't need to modify the message
+typedef destination::base<const std::string &> destination_base;
@endcode
-This namespace contains the classes formatter or destination classes need to use as %base class.
+Or, you can use a @ref customize_manipulator "custom string class", or, even an @ref customize_optimize "optimization string class".
+So, it's not uncommon to do something like this:
+@code
+typedef optimize::cache_string_one_str<> cache_string;
+// formatter - needs to modify the message - use an optimizer while formatting
+typedef formatter::base< cache_string&> formatter_base;
-_at_section manipulator_base Manipulator base classes
+// destination - needs to write the message - which has been converted to string
+typedef destination::base<const std::string &> destination_base;
+@endcode
-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
+\n\n\n
+@section manipulator_generic Using manipulators that come with the library
+Now, you will define your @ref logger "logger(s)", to use the @ref boost::logging::writer::format_write "format_write" class:
-_at_section share_data Sharing data for manipulator classes
+@code
+logger< ... format_write<formatter_base,destination_base> > g_l;
+@endcode
-The manipulator classes need to contain data as constant:
+After this, you'll add formatter and/or destination classes to your logger(s):
@code
-struct my_formatter : format_base {
- ...
-private:
- const int m_idx;
-};
+// add formatters : [idx] [time] message [enter]
+g_l->writer().add_formatter( formatter::idx() );
+g_l->writer().add_formatter( formatter::time() );
+g_l->writer().add_formatter( formatter::append_enter() );
+
+// write to cout and file
+g_l->writer().add_destination( destination::cout() );
+g_l->writer().add_destination( destination::file("out.txt") );
@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:
+In the above case, if you were to write:
@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;
-};
+int i = 1;
+L_ << "this is so cool" << i++;
@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.
+a message similar to this would appear on both the console, and the file:
+@code
+[1] 12:57 this is so cool 1 <enter>
+@endcode
-*/
-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 ; };
- };
- }
+You can use the formatter and/or destination classes that come with the library:
+- formatters: in the formatter namespace. Here are a few examples:
+ - formatter::idx - prepends an index
+ - formatter::append_enter - appends an enter after the message
+ - formatter::time - prepends the time
+ - formatter::thread_id - prepends the current thread id
+- destinations: in the destination namespace
+ - destination::cout - writes to console
+ - destination::file - writes to file
+ - destination::rolling_file - writes to a rolling file
+ - destination::shared_memory - writes into shared memory (using @c boost::shmem::named_shared_object)
+
+Or, you can create your own formatter and/or destination class. See below:
-/**
-Formatters and/or destinations are Manipulators.
-
-All formatter or destination class need to directly or indirectly derive from this.
-_at_section manipulator_base_class Manipulator base classes
-<b>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.
+\n\n\n
+@section manipulator_create Creating your own formatter and/or destination class(es)
-Same goes for destinations.</b>
+To create your formatter class, you need to derive from @ref class_ "formatter::class_". You will need to implement
+<tt>operator()(arg_type)</tt> <br> (@c arg_type is the argument you passed in your @ref manipulator_base_class "formatter_base" typedef)
-Note that the formatter base class and the destination base class don't need to be the same.
+@code
+typedef formatter::base< std::string&> formatter_base;
+...
+
+// milliseconds since start of the program
+struct ms_since_start : formatter::class_<ms_since_start, formatter_base, op_equal_no_context> {
+ time_t m_start;
+ ms_since_start : m_start( time(0) ) {}
-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.
+ // param = std::string&
+ // (in other words, it's the parameter you used when you defined formatter_base)
+ void operator()(param msg) const {
+ std::ostringstream out;
+ time_t now = time(0);
+ out << "[" << (now-start) << "] ";
+ msg = out.str() + msg;
+ }
+};
+@endcode
+To create your destination class, you need to derive from @ref class_ "destination::class_". You will need to implement
+<tt>operator()(arg_type)</tt> <br> (@c arg_type is the argument you passed in your @ref manipulator_base_class "destination_base" typedef)
-_at_section implementing_op_equal_ Implementing operator==
+@code
+typedef destination::base< const std::string&> destination_base;
+...
-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.
+struct to_hwnd : destination::class_<to_hwnd, destination_base, op_equal_has_context> {
+ HWND h;
+ to_hwnd(HWND h) : h(h) {}
-There are multiple ways to be able to compare formatter/destination objects - see op_equal namespace.
+ bool operator==(const to_hwnd& other) { return h == other.h; }
-By default, @ref boost::logging::op_equal::same_type_op_equal_base is used.
+ // param = const std::string&
+ // (in other words, it's the parameter you used when you defined destination_base)
+ void operator()(param msg) const {
+ ::SetWindowText(h, msg.c_str());
+ }
+};
+@endcode
+\n\n\n
+@section manipulator_share_data Sharing data for manipulator classes
-_at_param implement_op_equal see @ref implementing_op_equal_
+When you implement your own %manipulator (%formatter or %destination) class, you must make sure that
+it behaves like an STL function: <b>it needs to contain data as constant.</b>
-_at_param ptr_type_ the type used to hold a pointer to the type. By defaut, it's the type itself.
+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.
-*/
-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 {
+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.
+I've already provided a class you can derive from , when this is the case: the non_const_context class.
- 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::template find<self_type>::type ptr_type;
+@code
+struct my_file : destination::class_<my_file,destination_base,op_equal_has_context>, non_const_context<std::ofstream> {
+ std::string m_filename;
+ bool operator==(const my_file & other) { return m_filename == other.m_filename; }
- virtual ~base_no_operator_call() {}
+ write_to_file(const std::string & filename) : m_filename(filename), non_const_context_base(filename.c_str()) {}
+ void operator()(param msg) const {
+ context() << msg << std::endl ;
+ }
};
+@endcode
-/**
- 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.
+*/
+namespace manipulator {
- 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";
- }
+ 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 ; };
+ };
}
- // 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
-_at_param implement_op_equal see @ref implementing_op_equal_
+/**
+ @brief What to use as base class, for your formatter and destination classes
+ When using formatters and destinations, formatters must share a %base class,
+ and destinations must share a %base class - see manipulator namespace.
*/
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_> {
+ struct base : boost::logging::op_equal::same_type_op_equal_base {
- typedef base<arg_type, implement_op_equal, ptr_type_> self_type;
+ typedef base<arg_type, ptr_type_> self_type;
typedef typename detail::ptr_finder<ptr_type_> type_finder;
typedef typename type_finder::template find<self_type>::type ptr_type;
@@ -226,6 +268,28 @@
virtual void operator()(param val) const = 0;
};
+
+namespace detail {
+ template<implement_op_equal> struct op_equal_base {
+ bool operator==(const op_equal_base& ) const { return true; }
+ };
+
+ template<> struct op_equal_base<op_equal_has_context> {};
+}
+
+/**
+ @brief Use this when implementing your own formatter or destination class
+
+ x
+*/
+template<class type, class base_type, implement_op_equal op_e> struct class_
+ : base_type,
+ detail::op_equal_base<op_e>,
+ boost::logging::op_equal::same_type_op_equal<type> {
+};
+
+
+
/**
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.
@@ -352,13 +416,18 @@
*/
namespace formatter {
using boost::logging::manipulator::base;
- using boost::logging::manipulator::base_no_operator_call;
using boost::logging::manipulator::non_const_context;
/**
+ @sa boost::logging::manipulator::class_
+ */
+ using boost::logging::manipulator::class_;
+
+ /**
@sa boost::logging::manipulator::is_generic
*/
typedef boost::logging::manipulator::is_generic is_generic;
+
}
/**
@@ -374,10 +443,14 @@
*/
namespace destination {
using boost::logging::manipulator::base;
- using boost::logging::manipulator::base_no_operator_call;
using boost::logging::manipulator::non_const_context;
/**
+ @sa boost::logging::manipulator::class_
+ */
+ using boost::logging::manipulator::class_;
+
+ /**
@sa boost::logging::manipulator::is_generic
*/
typedef boost::logging::manipulator::is_generic is_generic;
Added: sandbox/logging/boost/logging/detail/raw_doc/common_usage.hpp
==============================================================================
--- (empty file)
+++ sandbox/logging/boost/logging/detail/raw_doc/common_usage.hpp 2007-10-19 08:12:15 EDT (Fri, 19 Oct 2007)
@@ -0,0 +1,30 @@
+namespace boost { namespace logging {
+
+/**
+@page common_usage Scenario 1: Common Usage
+
+define the class_ - with @param
+
+- with levels
+- write to different thingies
+- etc
+
+Explain about samples!
+
+
+
+have 3 scenarios
+- several levels, same log
+- several levels, different logs
+- with custom router FIXME (that is, use cache_string_several_str())
+- one logger; several levels - use a sink (that is, see how we find "is_enabled")
+ - we can simply use the level.is_enabled(xxx) question, and then write to the log
+- no levels
+- etc
+- fastest , no <<
+- fastest , using <<
+- using your own formatters and destinations integrated
+
+*/
+
+}}
Added: sandbox/logging/boost/logging/detail/raw_doc/customize_manipulator.hpp
==============================================================================
--- (empty file)
+++ sandbox/logging/boost/logging/detail/raw_doc/customize_manipulator.hpp 2007-10-19 08:12:15 EDT (Fri, 19 Oct 2007)
@@ -0,0 +1,18 @@
+namespace boost { namespace logging {
+
+/**
+@page customize_manipulator Customizing manipulator arguments
+
+FIXME
+
+optimize::cache_string_on_str
+optimize::cache_string_several_str
+
+
+@section customize_optimize Optimizing manipulator arguments
+
+FIXME
+
+*/
+
+}}
Modified: sandbox/logging/boost/logging/detail/raw_doc/main.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/raw_doc/main.hpp (original)
+++ sandbox/logging/boost/logging/detail/raw_doc/main.hpp 2007-10-19 08:12:15 EDT (Fri, 19 Oct 2007)
@@ -30,7 +30,7 @@
- Efficient filtering of log messages - that is, if a log is turned off, the message is not processed at all
- Thread-safe - the library allows you several degrees of thread-safety, as you'll see
- Allows for formatters and destinations
- - formatters format the message (like, prepending extra information - an index, the time, thread is, etc)
+ - formatters format the message (like, prepending extra information - an index, the time, thread id, etc)
- destinations specify where the message is to be written
- Formatters and Destinations are orthogonal to the rest of the library - if you want you can use them, otherwise
you can define your own writing mechanism
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-19 08:12:15 EDT (Fri, 19 Oct 2007)
@@ -23,8 +23,13 @@
- @ref gather "The gather namespace"
- @ref writer "The writer namespace"
- @ref manipulator "Formatters and/or destinations (manipulators namespace)"
- - @ref manipulator_base
- - @ref share_data
+ - @ref manipulator_common
+ - @ref manipulator_base_class
+ - @ref manipulator_generic
+ - @ref manipulator_create
+ - @ref manipulator_share_data
+ - @ref formatter "Formatters"
+ - @ref destination "Destinations"
- @ref thread_safety
Modified: sandbox/logging/boost/logging/format.hpp
==============================================================================
--- sandbox/logging/boost/logging/format.hpp (original)
+++ sandbox/logging/boost/logging/format.hpp 2007-10-19 08:12:15 EDT (Fri, 19 Oct 2007)
@@ -369,7 +369,7 @@
is_fmt, is_dest, is_clear
};
struct item {
- item() : m_type(is_clear) {}
+ item() : m_type(is_clear), m_fmt(0), m_dest(0) {}
item& fmt(formatter_ptr f) { m_fmt = f; m_type = is_fmt; return *this; }
item &dest(destination_ptr d) { m_dest = d; m_type = is_dest; return *this; }
formatter_ptr m_fmt;
Modified: sandbox/logging/boost/logging/format/destination/defaults.hpp
==============================================================================
--- sandbox/logging/boost/logging/format/destination/defaults.hpp (original)
+++ sandbox/logging/boost/logging/format/destination/defaults.hpp 2007-10-19 08:12:15 EDT (Fri, 19 Oct 2007)
@@ -33,7 +33,7 @@
/**
@brief Writes the string to console
*/
-template<class convert_dest = do_convert_destination > struct cout {
+template<class convert_dest = do_convert_destination > struct cout : is_generic, same_type {
template<class msg_type> void operator()(const msg_type & msg) const {
#ifndef UNICODE
convert_dest::write(msg, std::cout);
Modified: sandbox/logging/boost/logging/format/formatter/defaults.hpp
==============================================================================
--- sandbox/logging/boost/logging/format/formatter/defaults.hpp (original)
+++ sandbox/logging/boost/logging/format/formatter/defaults.hpp 2007-10-19 08:12:15 EDT (Fri, 19 Oct 2007)
@@ -50,8 +50,8 @@
@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 convert = do_convert_format::prepend> struct idx : formatter::non_const_context<int> {
+ 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("] ");
Modified: sandbox/logging/boost/logging/format/formatter/time.hpp
==============================================================================
--- sandbox/logging/boost/logging/format/formatter/time.hpp (original)
+++ sandbox/logging/boost/logging/format/formatter/time.hpp 2007-10-19 08:12:15 EDT (Fri, 19 Oct 2007)
@@ -42,12 +42,12 @@
$mm - minute, 2 digits
$ss - second, 2 digits
-Example: write_time("Today is $dd/$MM/$yyyy");
+Example: 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 {
+template<class convert = do_convert_format::prepend> struct time {
private:
typedef std::basic_string<c_type> string_type;
@@ -67,9 +67,9 @@
public:
/**
- constructs a write_time object
+ constructs a 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) {
+ 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);
@@ -123,7 +123,7 @@
template<class msg_type> void operator()(msg_type & msg) {
char_type buffer[64];
- time_t t = time(0);
+ time_t t = ::time(0);
tm details = *localtime( &t);
int vals[8];
@@ -175,7 +175,7 @@
template<class msg_type> void operator()(msg_type & msg) {
char_type buffer[64];
- time_t t = time (0);
+ 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))
Modified: sandbox/logging/lib/logging/samples/vc8/loggingvc8/loggingvc8.vcproj
==============================================================================
--- sandbox/logging/lib/logging/samples/vc8/loggingvc8/loggingvc8.vcproj (original)
+++ sandbox/logging/lib/logging/samples/vc8/loggingvc8/loggingvc8.vcproj 2007-10-19 08:12:15 EDT (Fri, 19 Oct 2007)
@@ -423,6 +423,13 @@
<File
RelativePath="..\..\..\tests\format\test_simple_formatter.cpp"
>
+ <FileConfiguration
+ Name="Test|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
</File>
</Filter>
<Filter
@@ -713,6 +720,14 @@
>
</File>
<File
+ RelativePath="..\..\..\..\..\boost\logging\detail\raw_doc\common_usage.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\..\boost\logging\detail\raw_doc\customize_manipulator.hpp"
+ >
+ </File>
+ <File
RelativePath="..\..\..\..\..\boost\logging\detail\raw_doc\fixme.hpp"
>
</File>
Modified: sandbox/logging/lib/logging/src/changelog.txt
==============================================================================
--- sandbox/logging/lib/logging/src/changelog.txt (original)
+++ sandbox/logging/lib/logging/src/changelog.txt 2007-10-19 08:12:15 EDT (Fri, 19 Oct 2007)
@@ -1,3 +1,14 @@
+
+
+v0.7.3, 19 oct 2007
+- added the manipulator::class_ concept
+- added some documentation
+
+
+v0.7.2, 18 oct 2007
+- format_write cares if formatter/destination is generic or not
+- solved bug when deleting manipulators (same_type needed to have a virtual destructor)
+
v0.4, 9 oct 2007
- ts_write and on_dedicated_thread work
@@ -15,4 +26,3 @@
v0.7, 15 oct 2007
- compiles with gcc 3.4.2
-
Modified: sandbox/logging/lib/logging/tests/format/test_manip_w_msgroute.cpp
==============================================================================
--- sandbox/logging/lib/logging/tests/format/test_manip_w_msgroute.cpp (original)
+++ sandbox/logging/lib/logging/tests/format/test_manip_w_msgroute.cpp 2007-10-19 08:12:15 EDT (Fri, 19 Oct 2007)
@@ -42,7 +42,7 @@
to cout: [idx] [time] message [enter]
to dbg_window: [time] message [enter]
- to file: [idx] message [enter]
+ to file: message [enter]
So our route is:
@@ -52,7 +52,6 @@
prepend [idx]
to cout
clear format
- prepend [idx]
append [enter]
to file
*/
@@ -62,7 +61,7 @@
//////////////////////////////////////////////////////////////////////
// Formatters
-typedef formatter::base<cache_string&, op_equal::same_type > format_base;
+typedef formatter::base<cache_string&> format_base;
// formatter: prepend the message's index
struct write_idx : format_base, formatter::non_const_context<int> {
@@ -93,7 +92,7 @@
//////////////////////////////////////////////////////////////////////
// Destinations
-typedef destination::base<const std::string &, op_equal::same_type> destination_base;
+typedef destination::base<const std::string &> destination_base;
struct write_to_cout : destination_base {
void operator()(param msg) const {
@@ -158,14 +157,13 @@
.fmt( write_idx() )
.dest( write_to_cout() )
.clear()
- .fmt( write_idx() )
.fmt( append_enter() )
- .fmt( write_to_file())
+ .dest( write_to_file())
;
-// DOES NOT work
int i = 1;
- L_ << "must be prefixed by index and time , enter is appended as well " << i++;
+ L_ << "good to use " << i++ << " version";
+ L_ << "Boost Logging lib v" << i++;
}
#ifdef SINGLE_TEST
Modified: sandbox/logging/lib/logging/tests/format/test_simple_formatter.cpp
==============================================================================
--- sandbox/logging/lib/logging/tests/format/test_simple_formatter.cpp (original)
+++ sandbox/logging/lib/logging/tests/format/test_simple_formatter.cpp 2007-10-19 08:12:15 EDT (Fri, 19 Oct 2007)
@@ -51,10 +51,10 @@
//////////////////////////////////////////////////////////////////////
// Formatters
-typedef formatter::base<cache_string&, op_equal::same_type > format_base;
+typedef formatter::base<cache_string&> format_base;
// formatter: prepend the message's index
-struct write_idx : format_base, formatter::non_const_context<int> {
+struct write_idx : formatter::class_<write_idx, format_base, op_equal_no_context>, formatter::non_const_context<int> {
write_idx() : non_const_context_base((int)0) {}
void operator()(param str) const {
std::stringstream idx;
@@ -63,7 +63,7 @@
}
};
-struct write_time : format_base {
+struct write_time : formatter::class_<write_time, format_base, op_equal_no_context> {
void operator()(cache_string & str) const {
char t[10];
time_t now = time(0);
@@ -73,7 +73,7 @@
}
};
-struct append_enter : format_base {
+struct append_enter : formatter::class_<append_enter, format_base, op_equal_no_context> {
void operator()(cache_string & str) const {
str.append_string("\n");
}
@@ -82,15 +82,15 @@
//////////////////////////////////////////////////////////////////////
// Destinations
-typedef destination::base<const std::string &, op_equal::same_type> destination_base;
+typedef destination::base<const std::string &> destination_base;
-struct write_to_cout : destination_base {
+struct write_to_cout : destination::class_<write_to_cout, destination_base, op_equal_no_context> {
void operator()(param msg) const {
std::cout << msg ;
}
};
-struct write_to_file : destination_base, destination::non_const_context<std::ofstream> {
+struct write_to_file : destination::class_<write_to_file, destination_base, op_equal_no_context>, destination::non_const_context<std::ofstream> {
write_to_file(const char* filename) : non_const_context_base(filename) {}
void operator()(param msg) const {
context() << msg ;
@@ -118,7 +118,7 @@
g_l->writer().add_destination( write_to_file("out.txt") );
int i = 1;
- L_ << "must be prefixed by index and time , enter is appended as well " << i++;
+ L_ << "this is so cool" << i++;
L_ << "must be prefixed by index and time , enter is appended as well " << i++;
L_ << "must be prefixed by index and time , enter is appended as well " << i++;
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