Parameters.ih
Go to the documentation of this file.
1 //
2 // Copyright (c) 2020 Fraunhofer Institute for Applied Information Technology (FIT)
3 // Network Research Group (NET)
4 // Schloss Birlinghoven, 53754 Sankt Augustin, GERMANY
5 // Contact: support@wiback.org
6 //
7 // This file is part of the SENF code tree.
8 // It is licensed under the 3-clause BSD License (aka New BSD License).
9 // See LICENSE.txt in the top level directory for details or visit
10 // https://opensource.org/licenses/BSD-3-Clause
11 //
12 
13 
14 /** \file
15  \brief Parameters internal header */
16 
17 #ifndef IH_SENF_Utils_Logger_Parameters_
18 #define IH_SENF_Utils_Logger_Parameters_ 1
19 
20 // Custom includes
21 #include <boost/preprocessor/seq/for_each_i.hpp>
22 #include <boost/preprocessor/facilities/apply.hpp>
23 #include <boost/preprocessor/punctuation/comma_if.hpp>
24 #include <boost/mpl/vector.hpp>
25 #include <boost/mpl/fold.hpp>
26 #include <boost/mpl/if.hpp>
27 #include <boost/utility/enable_if.hpp>
28 #include <boost/type_traits/is_convertible.hpp>
29 #include <senf/Utils/mpl.hh>
30 #include "Config.hh"
31 #include "Target.hh"
32 
33 //-/////////////////////////////////////////////////////////////////////////////////////////////////
34 
35 namespace senf {
36 namespace log {
37 
38  struct DefaultArea;
39  struct Debug;
40  struct NONE;
41 
42 namespace detail {
43 
44  struct StreamBase;
45  struct AreaBase;
46  struct LevelBase;
47  struct AliasBase;
48 
49  /// Internal: Parameter extractor
50  template <class Base, class Param, unsigned N>
51  struct Parameters_ {};
52 
53 #ifndef DOXYGEN
54 
55  senf::mpl::rv<1> Parameters_select_(StreamBase *);
56  template <class Base, class Param>
57  struct Parameters_<Base,Param,1> : public Base
58  { typedef Param stream; };
59 
60  senf::mpl::rv<2> Parameters_select_(AreaBase *);
61  template <class Base, class Param>
62  struct Parameters_<Base,Param,2> : public Base
63  { typedef Param area; typedef Param area_base; };
64 
65  senf::mpl::rv<3> Parameters_select_(LevelBase *);
66  template <class Base, class Param>
67  struct Parameters_<Base,Param,3> : public Base
68  { typedef Param level; };
69 
70  senf::mpl::rv<4> Parameters_select_(void *);
71  template <class Base>
72  struct Parameters_<Base,void,4> : public Base
73  {};
74 
75  senf::mpl::rv<5> Parameters_select_(AliasBase *);
76  template <class Base, class Param>
77  struct Parameters_<Base,Param,5>
78  : public Param::template apply<Base>::type
79  {};
80 
81  // This trick makes any class with a SENFLogArea typedef member usable as area. A typedef of
82  // this name is created by SENF_LOG_CLASS_AREA()
83  template <class T>
84  senf::mpl::rv<6> Parameters_select_(
85  T *,
86  typename boost::disable_if< boost::is_convertible<T*,StreamBase*> >::type * = 0,
87  typename boost::disable_if< boost::is_convertible<T*,AreaBase*> >::type * = 0,
88  typename boost::disable_if< boost::is_convertible<T*,LevelBase*> >::type * = 0,
89  typename boost::disable_if< boost::is_convertible<T*,AliasBase*> >::type * = 0);
90  template <class Base, class Param>
91  struct Parameters_<Base,Param,6> : public Base
92  { typedef typename Param::SENFLogArea area; typedef Param area_base; };
93 
94 #endif
95 
96  /// Internal: Log message parameter collection
97  template <class Base>
98  struct Parameters : public Base
99  {
100  typedef typename boost::mpl::if_c< Base::level::value == NONE::value,
101  typename Base::stream::defaultLevel,
102  typename Base::level >::type level;
103 
104  static bool const compileEnabled = senf::log::Enabled<
105  typename Base::stream,
106  typename Base::area_base,
107  level>::value;
108 
109  static bool enabled() {
110  return compileEnabled
111  && ( senf::log::detail::TargetRegistry::instance().fallbackRouting() ||
112  Base::area::instance().limit(Base::stream::instance()) <= level::value );
113  }
114  };
115 
116  /// Internal: Empty base class
117  struct empty {};
118 
119  /// Internal: Merge log message parameter list
120  struct Parameters_Merge
121  {
122  /// Internal: Embedded mpl template meta-function
123  template <class Base, class Param>
124  struct apply {
125  typedef Parameters_<
126  Base,
127  Param,
128  SENF_MPL_RV(Parameters_select_(static_cast<Param*>(0)))> type;
129  };
130  };
131 
132 }}}
133 
134 typedef senf::log::Debug SENFLogDefaultStream;
135 typedef senf::log::DefaultArea SENFLogDefaultArea;
136 typedef senf::log::NONE SENFLogDefaultLevel;
137 
138 #define SENF_LOG_MERGE_ARG(r, data, i, elem) BOOST_PP_COMMA_IF(i) elem
139 
140 #define SENF_LOG_MERGE_PARAMETERS_I(base, args) \
141  boost::mpl::fold< \
142  boost::mpl::vector< BOOST_PP_SEQ_FOR_EACH_I(SENF_LOG_MERGE_ARG, _, args) >, \
143  base, \
144  senf::log::detail::Parameters_Merge >::type
145 
146 #define SENF_LOG_MERGE_PARAMETERS(args) \
147  senf::log::detail::Parameters< SENF_LOG_MERGE_PARAMETERS_I( \
148  senf::log::detail::empty, \
149  (SENFLogDefaultStream)(SENFLogDefaultArea)(SENFLogDefaultLevel)args) >
150 
151 #define SENF_LOG_MERGE_PARAMETERS_TPL(args) \
152  senf::log::detail::Parameters< typename SENF_LOG_MERGE_PARAMETERS_I( \
153  senf::log::detail::empty, \
154  (SENFLogDefaultStream)(SENFLogDefaultArea)(SENFLogDefaultLevel)args) >
155 
156 //-/////////////////////////////////////////////////////////////////////////////////////////////////
157 #endif
158 
159 
160 // Local Variables:
161 // mode: c++
162 // fill-column: 100
163 // comment-column: 40
164 // c-file-style: "senf"
165 // indent-tabs-mode: nil
166 // ispell-local-dictionary: "american"
167 // compile-command: "scons -u test"
168 // End: