123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311 |
- /*
- * 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 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/core/invoke_swap.hpp>
- #include <boost/smart_ptr/intrusive_ptr.hpp>
- #include <boost/move/core.hpp>
- #include <boost/move/utility_core.hpp>
- #include <boost/type_traits/is_nothrow_move_constructible.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;
- static_assert(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) BOOST_OVERRIDE
- {
- 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() BOOST_OVERRIDE
- {
- #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) BOOST_NOEXCEPT : attribute(static_cast< attribute const& >(that))
- {
- }
- //! Move constructor
- severity_level(BOOST_RV_REF(severity_level) that) BOOST_NOEXCEPT : 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) BOOST_NOEXCEPT
- {
- attribute::operator= (static_cast< attribute const& >(that));
- return *this;
- }
- /*!
- * Move assignment
- */
- severity_level& operator= (BOOST_RV_REF(severity_level) that) BOOST_NOEXCEPT
- {
- 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::multiple_unique_lock2< threading_model, 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)
- {
- // Our attributes must refer to our severity attribute
- base_type::attributes()[boost::log::aux::default_attribute_names::severity()] = m_SeverityAttr;
- }
- /*!
- * Move constructor
- */
- basic_severity_logger(BOOST_RV_REF(basic_severity_logger) that) BOOST_NOEXCEPT_IF(boost::is_nothrow_move_constructible< base_type >::value &&
- boost::is_nothrow_move_constructible< severity_level >::value &&
- boost::is_nothrow_move_constructible< severity_attribute >::value) :
- base_type(boost::move(static_cast< base_type& >(that))),
- m_DefaultSeverity(boost::move(that.m_DefaultSeverity)),
- m_SeverityAttr(boost::move(that.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));
- boost::core::invoke_swap(m_DefaultSeverity, that.m_DefaultSeverity);
- 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_
|