diff options
Diffstat (limited to 'boost/log/sources/severity_feature.hpp')
-rw-r--r-- | boost/log/sources/severity_feature.hpp | 310 |
1 files changed, 310 insertions, 0 deletions
diff --git a/boost/log/sources/severity_feature.hpp b/boost/log/sources/severity_feature.hpp new file mode 100644 index 0000000000..ae34c4c587 --- /dev/null +++ b/boost/log/sources/severity_feature.hpp @@ -0,0 +1,310 @@ +/* + * 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 severity_feature.hpp + * \author Andrey Semashev + * \date 08.03.2007 + * + * The header contains implementation of a severity level support feature. + */ + +#ifndef BOOST_LOG_SOURCES_SEVERITY_FEATURE_HPP_INCLUDED_ +#define BOOST_LOG_SOURCES_SEVERITY_FEATURE_HPP_INCLUDED_ + +#include <boost/cstdint.hpp> +#include <boost/static_assert.hpp> +#include <boost/smart_ptr/intrusive_ptr.hpp> +#include <boost/move/core.hpp> +#include <boost/move/utility.hpp> +#include <boost/log/detail/config.hpp> +#include <boost/log/detail/locks.hpp> +#include <boost/log/detail/default_attribute_names.hpp> +#include <boost/log/attributes/attribute.hpp> +#include <boost/log/attributes/attribute_cast.hpp> +#include <boost/log/attributes/attribute_value_impl.hpp> +#include <boost/log/utility/strictest_lock.hpp> +#include <boost/log/utility/type_dispatch/type_dispatcher.hpp> +#include <boost/log/keywords/severity.hpp> +#include <boost/log/core/record.hpp> +#include <boost/log/detail/header.hpp> + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { + +BOOST_LOG_OPEN_NAMESPACE + +namespace sources { + +namespace aux { + + //! The method returns the storage for severity level for the current thread + BOOST_LOG_API uintmax_t& get_severity_level(); + + //! Severity level attribute implementation + template< typename LevelT > + class severity_level : + public attribute + { + typedef severity_level this_type; + BOOST_COPYABLE_AND_MOVABLE(this_type) + + public: + //! Stored level type + typedef LevelT value_type; + BOOST_STATIC_ASSERT_MSG(sizeof(value_type) <= sizeof(uintmax_t), "Boost.Log: Unsupported severity level type, the severity level must fit into uintmax_t"); + + protected: + //! Factory implementation + class BOOST_SYMBOL_VISIBLE impl : + public attribute_value::impl + { + public: + //! The method dispatches the value to the given object + bool dispatch(type_dispatcher& dispatcher) + { + type_dispatcher::callback< value_type > callback = dispatcher.get_callback< value_type >(); + if (callback) + { + callback(reinterpret_cast< value_type const& >(get_severity_level())); + return true; + } + else + return false; + } + + //! The method is called when the attribute value is passed to another thread + intrusive_ptr< attribute_value::impl > detach_from_thread() + { + #if !defined(BOOST_LOG_NO_THREADS) + return new attributes::attribute_value_impl< value_type >( + reinterpret_cast< value_type const& >(get_severity_level())); + #else + // With multithreading disabled we may safely return this here. This method will not be called anyway. + return this; + #endif + } + }; + + public: + //! Default constructor + severity_level() : attribute(new impl()) + { + } + //! Copy constructor + severity_level(severity_level const& that) : attribute(static_cast< attribute const& >(that)) + { + } + //! Move constructor + severity_level(BOOST_RV_REF(severity_level) that) : attribute(boost::move(static_cast< attribute& >(that))) + { + } + //! Constructor for casting support + explicit severity_level(attributes::cast_source const& source) : + attribute(source.as< impl >()) + { + } + + /*! + * Copy assignment + */ + severity_level& operator= (BOOST_COPY_ASSIGN_REF(severity_level) that) + { + attribute::operator= (that); + return *this; + } + + /*! + * Move assignment + */ + severity_level& operator= (BOOST_RV_REF(severity_level) that) + { + this->swap(that); + return *this; + } + + //! The method sets the actual level + void set_value(value_type level) + { + reinterpret_cast< value_type& >(get_severity_level()) = level; + } + }; + +} // namespace aux + +/*! + * \brief Severity level feature implementation + */ +template< typename BaseT, typename LevelT = int > +class basic_severity_logger : + public BaseT +{ + //! Base type + typedef BaseT base_type; + typedef basic_severity_logger this_type; + BOOST_COPYABLE_AND_MOVABLE_ALT(this_type) + +public: + //! Character type + typedef typename base_type::char_type char_type; + //! Final type + typedef typename base_type::final_type final_type; + //! Threading model being used + typedef typename base_type::threading_model threading_model; + + //! Severity level type + typedef LevelT severity_level; + //! Severity attribute type + typedef aux::severity_level< severity_level > severity_attribute; + +#if defined(BOOST_LOG_DOXYGEN_PASS) + //! Lock requirement for the \c open_record_unlocked method + typedef typename strictest_lock< + typename base_type::open_record_lock, + no_lock< threading_model > + >::type open_record_lock; +#endif // defined(BOOST_LOG_DOXYGEN_PASS) + + //! Lock requirement for the \c swap_unlocked method + typedef typename strictest_lock< + typename base_type::swap_lock, +#ifndef BOOST_LOG_NO_THREADS + boost::log::aux::exclusive_lock_guard< threading_model > +#else + no_lock< threading_model > +#endif // !defined(BOOST_LOG_NO_THREADS) + >::type swap_lock; + +private: + //! Default severity + severity_level m_DefaultSeverity; + //! Severity attribute + severity_attribute m_SeverityAttr; + +public: + /*! + * Default constructor. The constructed logger will have a severity attribute registered. + * The default level for log records will be 0. + */ + basic_severity_logger() : + base_type(), + m_DefaultSeverity(static_cast< severity_level >(0)) + { + base_type::add_attribute_unlocked(boost::log::aux::default_attribute_names::severity(), m_SeverityAttr); + } + /*! + * Copy constructor + */ + basic_severity_logger(basic_severity_logger const& that) : + base_type(static_cast< base_type const& >(that)), + m_DefaultSeverity(that.m_DefaultSeverity), + m_SeverityAttr(that.m_SeverityAttr) + { + base_type::attributes()[boost::log::aux::default_attribute_names::severity()] = m_SeverityAttr; + } + /*! + * Move constructor + */ + basic_severity_logger(BOOST_RV_REF(basic_severity_logger) that) : + base_type(boost::move(static_cast< base_type& >(that))), + m_DefaultSeverity(boost::move(that.m_DefaultSeverity)), + m_SeverityAttr(boost::move(that.m_SeverityAttr)) + { + base_type::attributes()[boost::log::aux::default_attribute_names::severity()] = m_SeverityAttr; + } + /*! + * Constructor with named arguments. Allows to setup the default level for log records. + * + * \param args A set of named arguments. The following arguments are supported: + * \li \c severity - default severity value + */ + template< typename ArgsT > + explicit basic_severity_logger(ArgsT const& args) : + base_type(args), + m_DefaultSeverity(args[keywords::severity | severity_level()]) + { + base_type::add_attribute_unlocked(boost::log::aux::default_attribute_names::severity(), m_SeverityAttr); + } + + /*! + * Default severity value getter + */ + severity_level default_severity() const { return m_DefaultSeverity; } + +protected: + /*! + * Severity attribute accessor + */ + severity_attribute const& get_severity_attribute() const { return m_SeverityAttr; } + + /*! + * Unlocked \c open_record + */ + template< typename ArgsT > + record open_record_unlocked(ArgsT const& args) + { + m_SeverityAttr.set_value(args[keywords::severity | m_DefaultSeverity]); + return base_type::open_record_unlocked(args); + } + + //! Unlocked \c swap + void swap_unlocked(basic_severity_logger& that) + { + base_type::swap_unlocked(static_cast< base_type& >(that)); + severity_level t = m_DefaultSeverity; + m_DefaultSeverity = that.m_DefaultSeverity; + that.m_DefaultSeverity = t; + m_SeverityAttr.swap(that.m_SeverityAttr); + } +}; + +/*! + * \brief Severity level support feature + * + * The logger with this feature registers a special attribute with an integral value type on construction. + * This attribute will provide severity level for each log record being made through the logger. + * The severity level can be omitted on logging record construction, in which case the default + * level will be used. The default level can also be customized by passing it to the logger constructor. + * + * The type of the severity level attribute can be specified as a template parameter for the feature + * template. By default, \c int will be used. + */ +template< typename LevelT = int > +struct severity +{ + template< typename BaseT > + struct apply + { + typedef basic_severity_logger< + BaseT, + LevelT + > type; + }; +}; + +} // namespace sources + +BOOST_LOG_CLOSE_NAMESPACE // namespace log + +} // namespace boost + +//! The macro allows to put a record with a specific severity level into log +#define BOOST_LOG_STREAM_SEV(logger, lvl)\ + BOOST_LOG_STREAM_WITH_PARAMS((logger), (::boost::log::keywords::severity = (lvl))) + +#ifndef BOOST_LOG_NO_SHORTHAND_NAMES + +//! An equivalent to BOOST_LOG_STREAM_SEV(logger, lvl) +#define BOOST_LOG_SEV(logger, lvl) BOOST_LOG_STREAM_SEV(logger, lvl) + +#endif // BOOST_LOG_NO_SHORTHAND_NAMES + +#include <boost/log/detail/footer.hpp> + +#endif // BOOST_LOG_SOURCES_SEVERITY_FEATURE_HPP_INCLUDED_ |