attribute_mapping.hpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. /*
  2. * Copyright Andrey Semashev 2007 - 2015.
  3. * Distributed under the Boost Software License, Version 1.0.
  4. * (See accompanying file LICENSE_1_0.txt or copy at
  5. * http://www.boost.org/LICENSE_1_0.txt)
  6. */
  7. /*!
  8. * \file attribute_mapping.hpp
  9. * \author Andrey Semashev
  10. * \date 07.11.2008
  11. *
  12. * The header contains facilities that are used in different sinks to map attribute values
  13. * used throughout the application to values used with the specific native logging API.
  14. * These tools are mostly needed to map application severity levels on native levels,
  15. * required by OS-specific sink backends.
  16. */
  17. #ifndef BOOST_LOG_SINKS_ATTRIBUTE_MAPPING_HPP_INCLUDED_
  18. #define BOOST_LOG_SINKS_ATTRIBUTE_MAPPING_HPP_INCLUDED_
  19. #include <map>
  20. #include <boost/log/detail/config.hpp>
  21. #include <boost/log/detail/tagged_integer.hpp>
  22. #include <boost/log/core/record_view.hpp>
  23. #include <boost/log/attributes/attribute_name.hpp>
  24. #include <boost/log/attributes/attribute_value_set.hpp>
  25. #include <boost/log/attributes/value_visitation.hpp>
  26. #include <boost/log/detail/header.hpp>
  27. #ifdef BOOST_HAS_PRAGMA_ONCE
  28. #pragma once
  29. #endif
  30. namespace boost {
  31. BOOST_LOG_OPEN_NAMESPACE
  32. namespace sinks {
  33. //! Base class for attribute mapping function objects
  34. template< typename MappedT >
  35. struct basic_mapping
  36. {
  37. //! Mapped value type
  38. typedef MappedT mapped_type;
  39. //! Result type
  40. typedef mapped_type result_type;
  41. };
  42. namespace aux {
  43. //! Attribute value visitor
  44. template< typename MappedT >
  45. struct direct_mapping_visitor
  46. {
  47. typedef void result_type;
  48. typedef MappedT mapped_type;
  49. explicit direct_mapping_visitor(mapped_type& extracted) :
  50. m_Extracted(extracted)
  51. {
  52. }
  53. template< typename T >
  54. void operator() (T const& val) const
  55. {
  56. m_Extracted = mapped_type(val);
  57. }
  58. private:
  59. mapped_type& m_Extracted;
  60. };
  61. // Specialization for the tagged integer
  62. template< typename IntT, typename TagT >
  63. struct direct_mapping_visitor< boost::log::aux::tagged_integer< IntT, TagT > >
  64. {
  65. typedef void result_type;
  66. typedef boost::log::aux::tagged_integer< IntT, TagT > mapped_type;
  67. explicit direct_mapping_visitor(mapped_type& extracted) :
  68. m_Extracted(extracted)
  69. {
  70. }
  71. template< typename T >
  72. void operator() (T const& val) const
  73. {
  74. mapped_type v = { static_cast< IntT >(val) };
  75. m_Extracted = v;
  76. }
  77. private:
  78. mapped_type& m_Extracted;
  79. };
  80. } // namespace aux
  81. /*!
  82. * \brief Straightforward mapping
  83. *
  84. * This type of mapping assumes that attribute with a particular name always
  85. * provides values that map directly onto the native values. The mapping
  86. * simply returns the extracted attribute value converted to the native value.
  87. */
  88. template< typename MappedT, typename AttributeValueT = int >
  89. class basic_direct_mapping :
  90. public basic_mapping< MappedT >
  91. {
  92. //! Base type
  93. typedef basic_direct_mapping< MappedT > base_type;
  94. public:
  95. //! Attribute contained value type
  96. typedef AttributeValueT attribute_value_type;
  97. //! Mapped value type
  98. typedef typename base_type::mapped_type mapped_type;
  99. private:
  100. //! Attribute name
  101. const attribute_name m_Name;
  102. //! Visitor invoker for the attribute value
  103. value_visitor_invoker< attribute_value_type > m_Invoker;
  104. //! Default native value
  105. mapped_type m_DefaultValue;
  106. public:
  107. /*!
  108. * Constructor
  109. *
  110. * \param name Attribute name
  111. * \param default_value The default native value that is returned if the attribute value is not found
  112. */
  113. explicit basic_direct_mapping(attribute_name const& name, mapped_type const& default_value) :
  114. m_Name(name),
  115. m_DefaultValue(default_value)
  116. {
  117. }
  118. /*!
  119. * Extraction operator
  120. *
  121. * \param rec A log record to extract value from
  122. * \return An extracted attribute value
  123. */
  124. mapped_type operator() (record_view const& rec) const
  125. {
  126. mapped_type res = m_DefaultValue;
  127. aux::direct_mapping_visitor< mapped_type > vis(res);
  128. m_Invoker(m_Name, rec.attribute_values(), vis);
  129. return res;
  130. }
  131. };
  132. /*!
  133. * \brief Customizable mapping
  134. *
  135. * The class allows to setup a custom mapping between an attribute and native values.
  136. * The mapping should be initialized similarly to the standard \c map container, by using
  137. * indexing operator and assignment.
  138. *
  139. * \note Unlike many other components of the library, exact type of the attribute value
  140. * must be specified in the template parameter \c AttributeValueT. Type sequences
  141. * are not supported.
  142. */
  143. template< typename MappedT, typename AttributeValueT = int >
  144. class basic_custom_mapping :
  145. public basic_mapping< MappedT >
  146. {
  147. //! Base type
  148. typedef basic_mapping< MappedT > base_type;
  149. public:
  150. //! Attribute contained value type
  151. typedef AttributeValueT attribute_value_type;
  152. //! Mapped value type
  153. typedef typename base_type::mapped_type mapped_type;
  154. private:
  155. //! \cond
  156. //! Mapping type
  157. typedef std::map< attribute_value_type, mapped_type > mapping_type;
  158. //! Smart reference class for implementing insertion into the map
  159. class reference_proxy;
  160. friend class reference_proxy;
  161. class reference_proxy
  162. {
  163. mapping_type& m_Mapping;
  164. attribute_value_type m_Key;
  165. public:
  166. //! Constructor
  167. reference_proxy(mapping_type& mapping, attribute_value_type const& key) : m_Mapping(mapping), m_Key(key) {}
  168. //! Insertion
  169. reference_proxy const& operator= (mapped_type const& val) const
  170. {
  171. m_Mapping[m_Key] = val;
  172. return *this;
  173. }
  174. };
  175. //! Attribute value visitor
  176. struct visitor;
  177. friend struct visitor;
  178. struct visitor
  179. {
  180. typedef void result_type;
  181. visitor(mapping_type const& mapping, mapped_type& extracted) :
  182. m_Mapping(mapping),
  183. m_Extracted(extracted)
  184. {
  185. }
  186. template< typename T >
  187. void operator() (T const& val) const
  188. {
  189. typename mapping_type::const_iterator it = m_Mapping.find(val);
  190. if (it != m_Mapping.end())
  191. m_Extracted = it->second;
  192. }
  193. private:
  194. mapping_type const& m_Mapping;
  195. mapped_type& m_Extracted;
  196. };
  197. //! \endcond
  198. private:
  199. //! Attribute name
  200. const attribute_name m_Name;
  201. //! Visitor invoker for the attribute value
  202. value_visitor_invoker< attribute_value_type > m_Invoker;
  203. //! Default native value
  204. mapped_type m_DefaultValue;
  205. //! Conversion mapping
  206. mapping_type m_Mapping;
  207. public:
  208. /*!
  209. * Constructor
  210. *
  211. * \param name Attribute name
  212. * \param default_value The default native value that is returned if the conversion cannot be performed
  213. */
  214. explicit basic_custom_mapping(attribute_name const& name, mapped_type const& default_value) :
  215. m_Name(name),
  216. m_DefaultValue(default_value)
  217. {
  218. }
  219. /*!
  220. * Extraction operator. Extracts the attribute value and attempts to map it onto
  221. * the native value.
  222. *
  223. * \param rec A log record to extract value from
  224. * \return A mapped value, if mapping was successful, or the default value if
  225. * mapping did not succeed.
  226. */
  227. mapped_type operator() (record_view const& rec) const
  228. {
  229. mapped_type res = m_DefaultValue;
  230. visitor vis(m_Mapping, res);
  231. m_Invoker(m_Name, rec.attribute_values(), vis);
  232. return res;
  233. }
  234. /*!
  235. * Insertion operator
  236. *
  237. * \param key Attribute value to be mapped
  238. * \return An object of unspecified type that allows to insert a new mapping through assignment.
  239. * The \a key argument becomes the key attribute value, and the assigned value becomes the
  240. * mapped native value.
  241. */
  242. #ifndef BOOST_LOG_DOXYGEN_PASS
  243. reference_proxy operator[] (attribute_value_type const& key)
  244. #else
  245. implementation_defined operator[] (attribute_value_type const& key)
  246. #endif
  247. {
  248. return reference_proxy(m_Mapping, key);
  249. }
  250. };
  251. } // namespace sinks
  252. BOOST_LOG_CLOSE_NAMESPACE // namespace log
  253. } // namespace boost
  254. #include <boost/log/detail/footer.hpp>
  255. #endif // BOOST_LOG_SINKS_ATTRIBUTE_MAPPING_HPP_INCLUDED_