summaryrefslogtreecommitdiff
path: root/boost/log/sources/severity_feature.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/log/sources/severity_feature.hpp')
-rw-r--r--boost/log/sources/severity_feature.hpp310
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_