// $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
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>
: 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_<
}}}
+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( \
senf::log::detail::empty, \
(SENFLogDefaultStream)(SENFLogDefaultArea)(SENFLogDefaultLevel)args) >
+#define SENF_LOG_MERGE_PARAMETERS_TPL(args) \
+ senf::log::detail::Parameters< typename SENF_LOG_MERGE_PARAMETERS_I( \
+ senf::log::detail::empty, \
+ (SENFLogDefaultStream)(SENFLogDefaultArea)(SENFLogDefaultLevel)args) >
+
///////////////////////////////ih.e////////////////////////////////////////
#endif