$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
From: john.groups_at_[hidden]
Date: 2008-01-16 17:09:36
Author: jtorjo
Date: 2008-01-16 17:09:36 EST (Wed, 16 Jan 2008)
New Revision: 42826
URL: http://svn.boost.org/trac/boost/changeset/42826
Log:
[logging]
v0.14.1, 17 jan 2008
- added test_after_destroyed - works on VC8
- moved logger::cached into a base class and made it virtual
Added:
   sandbox/logging/lib/logging/tests/test_after_destroyed/
   sandbox/logging/lib/logging/tests/test_after_destroyed/run_test.bat   (contents, props changed)
   sandbox/logging/lib/logging/tests/test_after_destroyed/test.cpp   (contents, props changed)
   sandbox/logging/lib/logging/tests/test_after_destroyed/test.sln   (contents, props changed)
   sandbox/logging/lib/logging/tests/test_after_destroyed/test.vcproj   (contents, props changed)
Text files modified: 
   sandbox/logging/boost/logging/detail/logger.hpp            |    78 +++++++++++++++++++++++++++++++-------- 
   sandbox/logging/boost/logging/detail/macros.hpp            |     2                                         
   sandbox/logging/boost/logging/detail/raw_doc/changelog.hpp |     6 ++                                      
   3 files changed, 68 insertions(+), 18 deletions(-)
Modified: sandbox/logging/boost/logging/detail/logger.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/logger.hpp	(original)
+++ sandbox/logging/boost/logging/detail/logger.hpp	2008-01-16 17:09:36 EST (Wed, 16 Jan 2008)
@@ -57,6 +57,22 @@
                     gather::ostream_like::return_str< std::basic_string<char_type>, std::basic_ostringstream<char_type> > > ::type gather_type;
             typedef typename gather_type::msg_type msg_type;
         };
+
+        /** 
+            @brief default implementation of keeping cache 
+            
+            (note : you can override the cache() functions, to implement your own cache keeping strategy)
+        */
+        template<class cache_type> struct default_cache_keeper {
+            /** note: this call does not need to be very efficient, since the cache is used seldom, 
+                      only at the beginning of the app, when the logging hasn't yet been initialized
+                      thus, we can afford to make it virtual, and the code will become easier
+            */
+            virtual cache_type & cache()                    { return m_cache; }
+            virtual const cache_type & cache() const        { return m_cache; }
+        private:
+            cache_type m_cache;
+        };
     }
 
 
@@ -115,10 +131,13 @@
     - check out the writer namespace
     
     */
-    template<class gather_msg = default_, class write_msg = default_ > struct logger {
+    template<class gather_msg = default_, class write_msg = default_ > struct logger 
+            : detail::default_cache_keeper<  detail::cache_before_init<typename detail::find_gather_if_default<gather_msg>::msg_type > > {
         typedef typename detail::find_gather_if_default<gather_msg>::gather_type gather_type;
         typedef write_msg write_type;
         typedef detail::cache_before_init<typename detail::find_gather_if_default<gather_msg>::msg_type > cache_type;
+        typedef detail::default_cache_keeper<cache_type> cache_base;
+        using cache_base::cache;
 
         typedef logger<gather_msg, write_msg> self;
 
@@ -138,9 +157,6 @@
         write_msg & writer()                    { return m_writer; }
         const write_msg & writer() const        { return m_writer; }
 
-        cache_type & cache()                    { return m_cache; }
-        const cache_type & cache() const        { return m_cache; }
-
         // called after all data has been gathered
         void on_do_write(gather_type & gather) const {
             cache().on_do_write( detail::as_non_const(gather.msg()), writer() );
@@ -151,13 +167,15 @@
 
     private:
         write_msg m_writer;
-        cache_type m_cache;
     };
 
     // specialize for write_msg* pointer!
-    template<class gather_msg, class write_msg> struct logger<gather_msg, write_msg* > {
+    template<class gather_msg, class write_msg> struct logger<gather_msg, write_msg* > 
+            : detail::default_cache_keeper<  detail::cache_before_init<typename detail::find_gather_if_default<gather_msg>::msg_type > > {
         typedef typename detail::find_gather_if_default<gather_msg>::gather_type gather_type;
         typedef detail::cache_before_init<typename detail::find_gather_if_default<gather_msg>::msg_type > cache_type;
+        typedef detail::default_cache_keeper<cache_type> cache_base;
+        using cache_base::cache;
         typedef write_msg write_type;
 
         typedef logger<gather_msg, write_msg*> self;
@@ -181,8 +199,8 @@
         write_msg & writer()                    { return *m_writer; }
         const write_msg & writer() const        { return *m_writer; }
 
-        cache_type & cache()                    { return m_cache; }
-        const cache_type & cache() const        { return m_cache; }
+        virtual cache_type & cache()                    { return m_cache; }
+        virtual const cache_type & cache() const        { return m_cache; }
 
         // called after all data has been gathered
         void on_do_write(gather_msg & gather) const {
@@ -199,10 +217,13 @@
 
 
     // specialize when write_msg is not set - in this case, you need to derive from this
-    template<class gather_msg> struct logger<gather_msg, default_ > {
+    template<class gather_msg> struct logger<gather_msg, default_ > 
+            : detail::default_cache_keeper<  detail::cache_before_init<typename detail::find_gather_if_default<gather_msg>::msg_type > > {
         typedef typename detail::find_gather_if_default<gather_msg>::gather_type gather_type;
         typedef detail::cache_before_init<typename detail::find_gather_if_default<gather_msg>::msg_type > cache_type;
         typedef void_ write_type;
+        typedef detail::default_cache_keeper<cache_type> cache_base;
+        using cache_base::cache;
 
         typedef logger<gather_msg, default_> self;
         typedef typename gather_msg::msg_type msg_type;
@@ -222,9 +243,6 @@
         write_type & writer()                    { return m_writer; }
         const write_type & writer() const        { return m_writer; }
 
-        cache_type & cache()                    { return *m_cache; }
-        const cache_type & cache() const        { return *m_cache; }
-
         void set_cache(cache_type * cache_) {
             m_cache = cache_;
         }
@@ -274,11 +292,8 @@
     // specialization for pointers
     template<class gather_msg, class write_msg> struct implement_default_logger<gather_msg,write_msg*> : logger<gather_msg, default_> {
         typedef typename gather_msg::msg_type msg_type;
-        typedef detail::cache_before_init<typename detail::find_gather_if_default<gather_msg>::msg_type > cache_type;
-        typedef logger<gather_msg, default_> log_base;
 
-        implement_default_logger(write_msg * writer = 0, cache_type * cache_ = 0) : m_writer(writer) {
-            log_base::set_cache( cache_);
+        implement_default_logger(write_msg * writer = 0) : m_writer(writer) {
         }
 
         void set_writer(write_msg* writer) {
@@ -294,6 +309,37 @@
     };
 
 
+    /** 
+        @brief Forwards everything to a different logger. 
+        
+        This includes:
+        - the writing (writer)
+        - the caching
+        - the on_destroyed (if present)
+    */
+    template<class gather_msg, class write_msg> struct forward_to_logger : logger<gather_msg, default_> {
+        typedef typename gather_msg::msg_type msg_type;
+        typedef detail::cache_before_init<typename detail::find_gather_if_default<gather_msg>::msg_type > cache_type;
+        typedef logger<gather_msg, default_> log_base;
+
+        typedef logger<gather_msg, write_msg> original_logger_type;
+        forward_to_logger(original_logger_type &original_logger) : m_original_logger( &original_logger) {
+            m_writer = &m_original_logger->writer();
+        }
+
+        virtual void do_write(msg_type &a) const {
+            (*m_writer)(a);
+        }
+
+        virtual cache_type & cache()                    { return m_original_logger->cache(); }
+        virtual const cache_type & cache() const        { return m_original_logger->cache(); }
+
+    private:
+        write_msg * m_writer;
+        original_logger_type * m_original_logger;
+    };
+
+
 
 }}
 
Modified: sandbox/logging/boost/logging/detail/macros.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/macros.hpp	(original)
+++ sandbox/logging/boost/logging/detail/macros.hpp	2008-01-16 17:09:36 EST (Wed, 16 Jan 2008)
@@ -541,7 +541,7 @@
     ::boost::logging::detail::fast_compile_with_default_gather<>::log_type & name ## _boost_log_impl_light_()  \
     { typedef ::boost::logging::detail::fast_compile_with_default_gather<>::gather_msg gather_msg; \
     typedef type::write_type write_msg; \
-    static ::boost::logging::implement_default_logger< gather_msg, write_msg* > p( &(name ## _boost_log_impl_().writer()), &(name ## _boost_log_impl_().cache()) ); \
+    static ::boost::logging::forward_to_logger< gather_msg, write_msg > p( name ## _boost_log_impl_() ); \
     return p; } \
     namespace { boost::logging::detail::fake_using_log ensure_log_is_created_before_main ## name ( name ## _boost_log_impl_() ); } \
     boost::logging::detail::log_keeper<type, name ## _boost_log_impl_, ::boost::logging::detail::fast_compile_with_default_gather<>::log_type, name ## _boost_log_impl_light_ > name; 
Modified: sandbox/logging/boost/logging/detail/raw_doc/changelog.hpp
==============================================================================
--- sandbox/logging/boost/logging/detail/raw_doc/changelog.hpp	(original)
+++ sandbox/logging/boost/logging/detail/raw_doc/changelog.hpp	2008-01-16 17:09:36 EST (Wed, 16 Jan 2008)
@@ -1,7 +1,11 @@
 /** 
 @page page_changelog Changelog
 
-_at_section changelog_cur_ver Current Version: v0.13.17, 16 jan 2008
+@section changelog_cur_ver Current Version: v0.14.1, 17 jan 2008
+- added test_after_destroyed - works on VC8
+- moved logger::cached into a base class and made it virtual
+
+v0.13.17, 16 jan 2008
 - added sample compile_time (for testing compile time)
 - added destination::named test
 - automatically include writer/ts_write.hpp from format.hpp
Added: sandbox/logging/lib/logging/tests/test_after_destroyed/run_test.bat
==============================================================================
--- (empty file)
+++ sandbox/logging/lib/logging/tests/test_after_destroyed/run_test.bat	2008-01-16 17:09:36 EST (Wed, 16 Jan 2008)
@@ -0,0 +1,6 @@
+test ofstream
+test ifstream
+test cout
+test stringstream
+test string
+pause
Added: sandbox/logging/lib/logging/tests/test_after_destroyed/test.cpp
==============================================================================
--- (empty file)
+++ sandbox/logging/lib/logging/tests/test_after_destroyed/test.cpp	2008-01-16 17:09:36 EST (Wed, 16 Jan 2008)
@@ -0,0 +1,96 @@
+/* 
+    This tests using some functions on the destructor of a global object.
+
+    The problem with using some resources within a destructor OF A GLOBAL OBJECT,
+    is that they might reference other resources that have already been destroyed.
+
+    An example (which might or might not work on your machine), is using a std::ofstream on the destructor of a global object.
+*/
+
+#include <stdio.h>
+#include <iostream>
+#include <string>
+#include <fstream>
+#include <sstream>
+
+void nothing() {}
+
+// the test we're running
+void (*g_test)() = nothing;
+
+void run_test() {
+    g_test();
+    // if this gets executed, we're successful
+    printf("test successful");
+}
+
+void use_ofstream() {
+    std::ofstream out("out.txt");
+    out << "test";
+}
+
+void use_ifstream() {
+    std::ifstream in("test.cpp"); // read this file
+    std::string line;
+    in >> line;
+}
+
+void use_stringstream() {
+    std::ostringstream out;
+    out << "hello ";
+    if ( std::cout)
+        out << "world";
+    printf ( out.str().c_str() );
+}
+
+void use_cout() {
+    std::cout << "test write to cout " << std::endl;
+}
+
+void use_string() {
+    std::string str;
+    str += "hello ";
+    if ( std::cout)
+        str += "world";
+    printf ( str.c_str() );
+}
+
+
+
+struct run_test_in_destructor {
+    ~run_test_in_destructor() {
+        run_test();
+    }
+} g_runner;
+
+int main(int argc, char * argv[]) {
+    std::string test_name = "nothing";
+    if ( argc > 1 )
+        test_name = argv[1];
+
+    if ( test_name == "ofstream")
+        g_test = use_ofstream;
+    else if ( test_name == "ifstream")
+        g_test = use_ifstream;
+    else if ( test_name == "cout")
+        g_test = use_cout;
+    else if ( test_name == "stringstream")
+        g_test = use_stringstream;
+    else if ( test_name == "string")
+        g_test = use_string;
+
+    std::cout << "running test '" << test_name << "'" << std::endl;
+
+    // use this, so that if there are any globals, they will be initialized here
+    {
+    std::ofstream out("out.txt");
+    out << "test";
+    }
+    {
+    std::ostringstream out;
+    std::ifstream in("out.txt");
+    in >> out.rdbuf();
+    }
+}
+
+
Added: sandbox/logging/lib/logging/tests/test_after_destroyed/test.sln
==============================================================================
--- (empty file)
+++ sandbox/logging/lib/logging/tests/test_after_destroyed/test.sln	2008-01-16 17:09:36 EST (Wed, 16 Jan 2008)
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test.vcproj", "{C5897099-5FA2-4E12-AFFC-2015364347FA}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Release|Win32 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{C5897099-5FA2-4E12-AFFC-2015364347FA}.Debug|Win32.ActiveCfg = Debug|Win32
+		{C5897099-5FA2-4E12-AFFC-2015364347FA}.Debug|Win32.Build.0 = Debug|Win32
+		{C5897099-5FA2-4E12-AFFC-2015364347FA}.Release|Win32.ActiveCfg = Release|Win32
+		{C5897099-5FA2-4E12-AFFC-2015364347FA}.Release|Win32.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
Added: sandbox/logging/lib/logging/tests/test_after_destroyed/test.vcproj
==============================================================================
--- (empty file)
+++ sandbox/logging/lib/logging/tests/test_after_destroyed/test.vcproj	2008-01-16 17:09:36 EST (Wed, 16 Jan 2008)
@@ -0,0 +1,182 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="test"
+	ProjectGUID="{C5897099-5FA2-4E12-AFFC-2015364347FA}"
+	RootNamespace="test"
+	Keyword="Win32Proj"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories=".,../../../.."
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="1"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="2"
+				AdditionalLibraryDirectories="D:\boosts\boost_1_33_1\bin\boost\libs\thread\build\libboost_thread.lib\vc-8_0\debug\threading-multi"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				CommandLine="copy "$(TargetPath)" "$(SolutionDir)""
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="1"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+				RuntimeLibrary="2"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="1"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath=".\test.cpp"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>