| /* |
| * Copyright Andrey Semashev 2007 - 2015. |
| * Distributed under the Boost Software License, Version 1.0. |
| * (See accompanying file LICENSE_1_0.txt or copy at |
| * http://www.boost.org/LICENSE_1_0.txt) |
| */ |
| /*! |
| * \file attribute_mapping.hpp |
| * \author Andrey Semashev |
| * \date 07.11.2008 |
| * |
| * The header contains facilities that are used in different sinks to map attribute values |
| * used throughout the application to values used with the specific native logging API. |
| * These tools are mostly needed to map application severity levels on native levels, |
| * required by OS-specific sink backends. |
| */ |
| |
| #ifndef BOOST_LOG_SINKS_ATTRIBUTE_MAPPING_HPP_INCLUDED_ |
| #define BOOST_LOG_SINKS_ATTRIBUTE_MAPPING_HPP_INCLUDED_ |
| |
| #include <map> |
| #include <boost/log/detail/config.hpp> |
| #include <boost/log/detail/tagged_integer.hpp> |
| #include <boost/log/core/record_view.hpp> |
| #include <boost/log/attributes/attribute_name.hpp> |
| #include <boost/log/attributes/attribute_value_set.hpp> |
| #include <boost/log/attributes/value_visitation.hpp> |
| #include <boost/log/detail/header.hpp> |
| |
| #ifdef BOOST_HAS_PRAGMA_ONCE |
| #pragma once |
| #endif |
| |
| namespace boost { |
| |
| BOOST_LOG_OPEN_NAMESPACE |
| |
| namespace sinks { |
| |
| //! Base class for attribute mapping function objects |
| template< typename MappedT > |
| struct basic_mapping |
| { |
| //! Mapped value type |
| typedef MappedT mapped_type; |
| //! Result type |
| typedef mapped_type result_type; |
| }; |
| |
| namespace aux { |
| |
| //! Attribute value visitor |
| template< typename MappedT > |
| struct direct_mapping_visitor |
| { |
| typedef void result_type; |
| typedef MappedT mapped_type; |
| |
| explicit direct_mapping_visitor(mapped_type& extracted) : |
| m_Extracted(extracted) |
| { |
| } |
| template< typename T > |
| void operator() (T const& val) const |
| { |
| m_Extracted = mapped_type(val); |
| } |
| |
| private: |
| mapped_type& m_Extracted; |
| }; |
| // Specialization for the tagged integer |
| template< typename IntT, typename TagT > |
| struct direct_mapping_visitor< boost::log::aux::tagged_integer< IntT, TagT > > |
| { |
| typedef void result_type; |
| typedef boost::log::aux::tagged_integer< IntT, TagT > mapped_type; |
| |
| explicit direct_mapping_visitor(mapped_type& extracted) : |
| m_Extracted(extracted) |
| { |
| } |
| template< typename T > |
| void operator() (T const& val) const |
| { |
| mapped_type v = { val }; |
| m_Extracted = v; |
| } |
| |
| private: |
| mapped_type& m_Extracted; |
| }; |
| |
| } // namespace aux |
| |
| /*! |
| * \brief Straightforward mapping |
| * |
| * This type of mapping assumes that attribute with a particular name always |
| * provides values that map directly onto the native values. The mapping |
| * simply returns the extracted attribute value converted to the native value. |
| */ |
| template< typename MappedT, typename AttributeValueT = int > |
| class basic_direct_mapping : |
| public basic_mapping< MappedT > |
| { |
| //! Base type |
| typedef basic_direct_mapping< MappedT > base_type; |
| |
| public: |
| //! Attribute contained value type |
| typedef AttributeValueT attribute_value_type; |
| //! Mapped value type |
| typedef typename base_type::mapped_type mapped_type; |
| |
| private: |
| //! Attribute name |
| const attribute_name m_Name; |
| //! Visitor invoker for the attribute value |
| value_visitor_invoker< attribute_value_type > m_Invoker; |
| //! Default native value |
| mapped_type m_DefaultValue; |
| |
| public: |
| /*! |
| * Constructor |
| * |
| * \param name Attribute name |
| * \param default_value The default native value that is returned if the attribute value is not found |
| */ |
| explicit basic_direct_mapping(attribute_name const& name, mapped_type const& default_value) : |
| m_Name(name), |
| m_DefaultValue(default_value) |
| { |
| } |
| |
| /*! |
| * Extraction operator |
| * |
| * \param rec A log record to extract value from |
| * \return An extracted attribute value |
| */ |
| mapped_type operator() (record_view const& rec) const |
| { |
| mapped_type res = m_DefaultValue; |
| aux::direct_mapping_visitor< mapped_type > vis(res); |
| m_Invoker(m_Name, rec.attribute_values(), vis); |
| return res; |
| } |
| }; |
| |
| /*! |
| * \brief Customizable mapping |
| * |
| * The class allows to setup a custom mapping between an attribute and native values. |
| * The mapping should be initialized similarly to the standard \c map container, by using |
| * indexing operator and assignment. |
| * |
| * \note Unlike many other components of the library, exact type of the attribute value |
| * must be specified in the template parameter \c AttributeValueT. Type sequences |
| * are not supported. |
| */ |
| template< typename MappedT, typename AttributeValueT = int > |
| class basic_custom_mapping : |
| public basic_mapping< MappedT > |
| { |
| //! Base type |
| typedef basic_mapping< MappedT > base_type; |
| |
| public: |
| //! Attribute contained value type |
| typedef AttributeValueT attribute_value_type; |
| //! Mapped value type |
| typedef typename base_type::mapped_type mapped_type; |
| |
| private: |
| //! \cond |
| |
| //! Mapping type |
| typedef std::map< attribute_value_type, mapped_type > mapping_type; |
| //! Smart reference class for implementing insertion into the map |
| class reference_proxy; |
| friend class reference_proxy; |
| class reference_proxy |
| { |
| mapping_type& m_Mapping; |
| attribute_value_type m_Key; |
| |
| public: |
| //! Constructor |
| reference_proxy(mapping_type& mapping, attribute_value_type const& key) : m_Mapping(mapping), m_Key(key) {} |
| //! Insertion |
| reference_proxy const& operator= (mapped_type const& val) const |
| { |
| m_Mapping[m_Key] = val; |
| return *this; |
| } |
| }; |
| |
| //! Attribute value visitor |
| struct visitor; |
| friend struct visitor; |
| struct visitor |
| { |
| typedef void result_type; |
| |
| visitor(mapping_type const& mapping, mapped_type& extracted) : |
| m_Mapping(mapping), |
| m_Extracted(extracted) |
| { |
| } |
| template< typename T > |
| void operator() (T const& val) const |
| { |
| typename mapping_type::const_iterator it = m_Mapping.find(val); |
| if (it != m_Mapping.end()) |
| m_Extracted = it->second; |
| } |
| |
| private: |
| mapping_type const& m_Mapping; |
| mapped_type& m_Extracted; |
| }; |
| |
| //! \endcond |
| |
| private: |
| //! Attribute name |
| const attribute_name m_Name; |
| //! Visitor invoker for the attribute value |
| value_visitor_invoker< attribute_value_type > m_Invoker; |
| //! Default native value |
| mapped_type m_DefaultValue; |
| //! Conversion mapping |
| mapping_type m_Mapping; |
| |
| public: |
| /*! |
| * Constructor |
| * |
| * \param name Attribute name |
| * \param default_value The default native value that is returned if the conversion cannot be performed |
| */ |
| explicit basic_custom_mapping(attribute_name const& name, mapped_type const& default_value) : |
| m_Name(name), |
| m_DefaultValue(default_value) |
| { |
| } |
| /*! |
| * Extraction operator. Extracts the attribute value and attempts to map it onto |
| * the native value. |
| * |
| * \param rec A log record to extract value from |
| * \return A mapped value, if mapping was successful, or the default value if |
| * mapping did not succeed. |
| */ |
| mapped_type operator() (record_view const& rec) const |
| { |
| mapped_type res = m_DefaultValue; |
| visitor vis(m_Mapping, res); |
| m_Invoker(m_Name, rec.attribute_values(), vis); |
| return res; |
| } |
| /*! |
| * Insertion operator |
| * |
| * \param key Attribute value to be mapped |
| * \return An object of unspecified type that allows to insert a new mapping through assignment. |
| * The \a key argument becomes the key attribute value, and the assigned value becomes the |
| * mapped native value. |
| */ |
| #ifndef BOOST_LOG_DOXYGEN_PASS |
| reference_proxy operator[] (attribute_value_type const& key) |
| #else |
| implementation_defined operator[] (attribute_value_type const& key) |
| #endif |
| { |
| return reference_proxy(m_Mapping, key); |
| } |
| }; |
| |
| } // namespace sinks |
| |
| BOOST_LOG_CLOSE_NAMESPACE // namespace log |
| |
| } // namespace boost |
| |
| #include <boost/log/detail/footer.hpp> |
| |
| #endif // BOOST_LOG_SINKS_ATTRIBUTE_MAPPING_HPP_INCLUDED_ |