NEW FILE HEADER / COPYRIGHT FORMAT
[senf.git] / Utils / Logger / Parameters.ih
index 882af7c..5927a89 100644 (file)
@@ -1,8 +1,8 @@
 // $Id$
 //
 // Copyright (C) 2007 
-// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
-// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+// Fraunhofer Institute for Open Communication Systems (FOKUS) 
+// Competence Center NETwork research (NET), St. Augustin, GERMANY 
 //     Stefan Bund <g0dil@berlios.de>
 //
 // This program is free software; you can redistribute it and/or modify
 #include <boost/preprocessor/punctuation/comma_if.hpp>
 #include <boost/mpl/vector.hpp>
 #include <boost/mpl/fold.hpp>
-#include "Defaults.hh"
+#include <boost/mpl/if.hpp>
+#include <boost/utility.hpp>
+#include <boost/type_traits/is_convertible.hpp>
 #include "../mpl.hh"
-#include "Stream.hh"
-#include "Area.hh"
-#include "Levels.hh"
 #include "Config.hh"
+#include "Target.hh"
 
 ///////////////////////////////ih.p////////////////////////////////////////
 
-#ifndef _senf_LOG_STREAM
-#   define _senf_LOG_STREAM std::cerr
-#endif
-
-typedef senf::log::Debug       SENFLogDefaultStream;
-typedef senf::log::DefaultArea SENFLogDefaultArea;
-typedef senf::log::NONE        SENFLogDefaultLevel;
-
 namespace senf {
 namespace log {
+    
+    class DefaultArea;
+    class Debug;
+    class NONE;
+
 namespace detail {
 
-    struct AliasBase {};
+    class StreamBase;
+    class AreaBase;
+    class LevelBase;
+    class AliasBase;
 
+    /// Internal: Parameter extractor
     template <class Base, class Param, unsigned N>
     struct Parameters_ {};
 
+#ifndef DOXYGEN
+
     senf::mpl::rv<1> Parameters_select_(StreamBase *);
     template <class Base, class Param>
     struct Parameters_<Base,Param,1> : public Base
@@ -67,7 +70,7 @@ namespace detail {
     senf::mpl::rv<2> Parameters_select_(AreaBase *);
     template <class Base, class Param>
     struct Parameters_<Base,Param,2> : public Base
-    { typedef Param area; };
+    { typedef Param area; typedef Param area_base; };
 
     senf::mpl::rv<3> Parameters_select_(LevelBase *);
     template <class Base, class Param>
@@ -85,23 +88,48 @@ namespace detail {
         : public Param::template apply<Base>::type
     {};
 
+    // This trick makes any class with a SENFLogArea typedef member usable as area. A typedef of
+    // this name is created by SENF_LOG_CLASS_AREA()
+    template <class T>
+    senf::mpl::rv<6> Parameters_select_(
+        T *, 
+        typename boost::disable_if< boost::is_convertible<T*,StreamBase*> >::type * = 0,
+        typename boost::disable_if< boost::is_convertible<T*,AreaBase*> >::type * = 0,
+        typename boost::disable_if< boost::is_convertible<T*,LevelBase*> >::type * = 0,
+        typename boost::disable_if< boost::is_convertible<T*,AliasBase*> >::type * = 0);
+    template <class Base, class Param>
+    struct Parameters_<Base,Param,6> : public Base
+    { typedef typename Param::SENFLogArea area; typedef Param area_base; };
+
+#endif
+
+    /// Internal: Log message parameter collection
     template <class Base>
     struct Parameters : public Base
     {
+        typedef typename boost::mpl::if_c< Base::level::value == NONE::value, 
+                                           typename Base::stream::defaultLevel, 
+                                           typename Base::level >::type level;
 
-        static bool const compile_enabled = senf::log::Enabled<
+        static bool const compileEnabled = senf::log::Enabled<
             typename Base::stream, 
-            typename Base::area, 
-            typename Base::level>::value;
-
-        static bool enabled() { return compile_enabled; }
-        static std::ostream & log_stream() { return _senf_LOG_STREAM; }
+            typename Base::area_base, 
+            level>::value;
+
+        static bool enabled() { 
+            return compileEnabled
+                && ( senf::log::detail::TargetRegistry::instance().fallbackRouting() ||
+                     Base::area::instance().limit(Base::stream::instance()) <= level::value );
+        }
     };
 
+    /// Internal: Empty base class
     struct empty {};
 
-    struct Parameters_Merge_
+    /// Internal: Merge log message parameter list
+    struct Parameters_Merge
     {
+        /// Internal: Embedded mpl template meta-function
         template <class Base, class Param>
         struct apply {
             typedef Parameters_<
@@ -113,13 +141,17 @@ namespace detail {
 
 }}}
 
+typedef senf::log::Debug       SENFLogDefaultStream;
+typedef senf::log::DefaultArea SENFLogDefaultArea;
+typedef senf::log::NONE        SENFLogDefaultLevel;
+
 #define SENF_LOG_MERGE_ARG(r, data, i, elem) BOOST_PP_COMMA_IF(i) elem
 
 #define SENF_LOG_MERGE_PARAMETERS_I(base, args)                                                   \
     boost::mpl::fold<                                                                             \
         boost::mpl::vector< BOOST_PP_SEQ_FOR_EACH_I(SENF_LOG_MERGE_ARG, _, args) >,               \
         base,                                                                                     \
-        senf::log::detail::Parameters_Merge_ >::type
+        senf::log::detail::Parameters_Merge >::type
 
 #define SENF_LOG_MERGE_PARAMETERS(args)                                                           \
     senf::log::detail::Parameters< SENF_LOG_MERGE_PARAMETERS_I(                                   \