diff options
Diffstat (limited to 'boost/log/sinks/attribute_mapping.hpp')
-rw-r--r-- | boost/log/sinks/attribute_mapping.hpp | 290 |
1 files changed, 290 insertions, 0 deletions
diff --git a/boost/log/sinks/attribute_mapping.hpp b/boost/log/sinks/attribute_mapping.hpp new file mode 100644 index 0000000000..a336265ff4 --- /dev/null +++ b/boost/log/sinks/attribute_mapping.hpp @@ -0,0 +1,290 @@ +/* + * Copyright Andrey Semashev 2007 - 2014. + * 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_ |