Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:39:26

0001 /*
0002  *          Copyright Andrey Semashev 2007 - 2015.
0003  * Distributed under the Boost Software License, Version 1.0.
0004  *    (See accompanying file LICENSE_1_0.txt or copy at
0005  *          http://www.boost.org/LICENSE_1_0.txt)
0006  */
0007 /*!
0008  * \file   severity_feature.hpp
0009  * \author Andrey Semashev
0010  * \date   08.03.2007
0011  *
0012  * The header contains implementation of a severity level support feature.
0013  */
0014 
0015 #ifndef BOOST_LOG_SOURCES_SEVERITY_FEATURE_HPP_INCLUDED_
0016 #define BOOST_LOG_SOURCES_SEVERITY_FEATURE_HPP_INCLUDED_
0017 
0018 #include <boost/cstdint.hpp>
0019 #include <boost/core/invoke_swap.hpp>
0020 #include <boost/smart_ptr/intrusive_ptr.hpp>
0021 #include <boost/move/core.hpp>
0022 #include <boost/move/utility_core.hpp>
0023 #include <boost/type_traits/is_nothrow_move_constructible.hpp>
0024 #include <boost/log/detail/config.hpp>
0025 #include <boost/log/detail/locks.hpp>
0026 #include <boost/log/detail/default_attribute_names.hpp>
0027 #include <boost/log/attributes/attribute.hpp>
0028 #include <boost/log/attributes/attribute_cast.hpp>
0029 #include <boost/log/attributes/attribute_value_impl.hpp>
0030 #include <boost/log/utility/strictest_lock.hpp>
0031 #include <boost/log/utility/type_dispatch/type_dispatcher.hpp>
0032 #include <boost/log/keywords/severity.hpp>
0033 #include <boost/log/core/record.hpp>
0034 #include <boost/log/detail/header.hpp>
0035 
0036 #ifdef BOOST_HAS_PRAGMA_ONCE
0037 #pragma once
0038 #endif
0039 
0040 namespace boost {
0041 
0042 BOOST_LOG_OPEN_NAMESPACE
0043 
0044 namespace sources {
0045 
0046 namespace aux {
0047 
0048     //! The method returns the storage for severity level for the current thread
0049     BOOST_LOG_API uintmax_t& get_severity_level();
0050 
0051     //! Severity level attribute implementation
0052     template< typename LevelT >
0053     class severity_level :
0054         public attribute
0055     {
0056         typedef severity_level this_type;
0057         BOOST_COPYABLE_AND_MOVABLE(this_type)
0058 
0059     public:
0060         //! Stored level type
0061         typedef LevelT value_type;
0062         static_assert(sizeof(value_type) <= sizeof(uintmax_t), "Boost.Log: Unsupported severity level type, the severity level must fit into uintmax_t");
0063 
0064     protected:
0065         //! Factory implementation
0066         class BOOST_SYMBOL_VISIBLE impl :
0067             public attribute_value::impl
0068         {
0069         public:
0070             //! The method dispatches the value to the given object
0071             bool dispatch(type_dispatcher& dispatcher) BOOST_OVERRIDE
0072             {
0073                 type_dispatcher::callback< value_type > callback = dispatcher.get_callback< value_type >();
0074                 if (callback)
0075                 {
0076                     callback(reinterpret_cast< value_type const& >(get_severity_level()));
0077                     return true;
0078                 }
0079                 else
0080                     return false;
0081             }
0082 
0083             //! The method is called when the attribute value is passed to another thread
0084             intrusive_ptr< attribute_value::impl > detach_from_thread() BOOST_OVERRIDE
0085             {
0086     #if !defined(BOOST_LOG_NO_THREADS)
0087                 return new attributes::attribute_value_impl< value_type >(
0088                     reinterpret_cast< value_type const& >(get_severity_level()));
0089     #else
0090                 // With multithreading disabled we may safely return this here. This method will not be called anyway.
0091                 return this;
0092     #endif
0093             }
0094         };
0095 
0096     public:
0097         //! Default constructor
0098         severity_level() : attribute(new impl())
0099         {
0100         }
0101         //! Copy constructor
0102         severity_level(severity_level const& that) BOOST_NOEXCEPT : attribute(static_cast< attribute const& >(that))
0103         {
0104         }
0105         //! Move constructor
0106         severity_level(BOOST_RV_REF(severity_level) that) BOOST_NOEXCEPT : attribute(boost::move(static_cast< attribute& >(that)))
0107         {
0108         }
0109         //! Constructor for casting support
0110         explicit severity_level(attributes::cast_source const& source) :
0111             attribute(source.as< impl >())
0112         {
0113         }
0114 
0115         /*!
0116          * Copy assignment
0117          */
0118         severity_level& operator= (BOOST_COPY_ASSIGN_REF(severity_level) that) BOOST_NOEXCEPT
0119         {
0120             attribute::operator= (static_cast< attribute const& >(that));
0121             return *this;
0122         }
0123 
0124         /*!
0125          * Move assignment
0126          */
0127         severity_level& operator= (BOOST_RV_REF(severity_level) that) BOOST_NOEXCEPT
0128         {
0129             this->swap(that);
0130             return *this;
0131         }
0132 
0133         //! The method sets the actual level
0134         void set_value(value_type level)
0135         {
0136             reinterpret_cast< value_type& >(get_severity_level()) = level;
0137         }
0138     };
0139 
0140 } // namespace aux
0141 
0142 /*!
0143  * \brief Severity level feature implementation
0144  */
0145 template< typename BaseT, typename LevelT = int >
0146 class basic_severity_logger :
0147     public BaseT
0148 {
0149     //! Base type
0150     typedef BaseT base_type;
0151     typedef basic_severity_logger this_type;
0152     BOOST_COPYABLE_AND_MOVABLE_ALT(this_type)
0153 
0154 public:
0155     //! Character type
0156     typedef typename base_type::char_type char_type;
0157     //! Final type
0158     typedef typename base_type::final_type final_type;
0159     //! Threading model being used
0160     typedef typename base_type::threading_model threading_model;
0161 
0162     //! Severity level type
0163     typedef LevelT severity_level;
0164     //! Severity attribute type
0165     typedef aux::severity_level< severity_level > severity_attribute;
0166 
0167 #if defined(BOOST_LOG_DOXYGEN_PASS)
0168     //! Lock requirement for the \c open_record_unlocked method
0169     typedef typename strictest_lock<
0170         typename base_type::open_record_lock,
0171         no_lock< threading_model >
0172     >::type open_record_lock;
0173 #endif // defined(BOOST_LOG_DOXYGEN_PASS)
0174 
0175     //! Lock requirement for the \c swap_unlocked method
0176     typedef typename strictest_lock<
0177         typename base_type::swap_lock,
0178 #ifndef BOOST_LOG_NO_THREADS
0179         boost::log::aux::multiple_unique_lock2< threading_model, threading_model >
0180 #else
0181         no_lock< threading_model >
0182 #endif // !defined(BOOST_LOG_NO_THREADS)
0183     >::type swap_lock;
0184 
0185 private:
0186     //! Default severity
0187     severity_level m_DefaultSeverity;
0188     //! Severity attribute
0189     severity_attribute m_SeverityAttr;
0190 
0191 public:
0192     /*!
0193      * Default constructor. The constructed logger will have a severity attribute registered.
0194      * The default level for log records will be 0.
0195      */
0196     basic_severity_logger() :
0197         base_type(),
0198         m_DefaultSeverity(static_cast< severity_level >(0))
0199     {
0200         base_type::add_attribute_unlocked(boost::log::aux::default_attribute_names::severity(), m_SeverityAttr);
0201     }
0202     /*!
0203      * Copy constructor
0204      */
0205     basic_severity_logger(basic_severity_logger const& that) :
0206         base_type(static_cast< base_type const& >(that)),
0207         m_DefaultSeverity(that.m_DefaultSeverity),
0208         m_SeverityAttr(that.m_SeverityAttr)
0209     {
0210         // Our attributes must refer to our severity attribute
0211         base_type::attributes()[boost::log::aux::default_attribute_names::severity()] = m_SeverityAttr;
0212     }
0213     /*!
0214      * Move constructor
0215      */
0216     basic_severity_logger(BOOST_RV_REF(basic_severity_logger) that) BOOST_NOEXCEPT_IF(boost::is_nothrow_move_constructible< base_type >::value &&
0217                                                                                       boost::is_nothrow_move_constructible< severity_level >::value &&
0218                                                                                       boost::is_nothrow_move_constructible< severity_attribute >::value) :
0219         base_type(boost::move(static_cast< base_type& >(that))),
0220         m_DefaultSeverity(boost::move(that.m_DefaultSeverity)),
0221         m_SeverityAttr(boost::move(that.m_SeverityAttr))
0222     {
0223     }
0224     /*!
0225      * Constructor with named arguments. Allows to setup the default level for log records.
0226      *
0227      * \param args A set of named arguments. The following arguments are supported:
0228      *             \li \c severity - default severity value
0229      */
0230     template< typename ArgsT >
0231     explicit basic_severity_logger(ArgsT const& args) :
0232         base_type(args),
0233         m_DefaultSeverity(args[keywords::severity | severity_level()])
0234     {
0235         base_type::add_attribute_unlocked(boost::log::aux::default_attribute_names::severity(), m_SeverityAttr);
0236     }
0237 
0238     /*!
0239      * Default severity value getter
0240      */
0241     severity_level default_severity() const { return m_DefaultSeverity; }
0242 
0243 protected:
0244     /*!
0245      * Severity attribute accessor
0246      */
0247     severity_attribute const& get_severity_attribute() const { return m_SeverityAttr; }
0248 
0249     /*!
0250      * Unlocked \c open_record
0251      */
0252     template< typename ArgsT >
0253     record open_record_unlocked(ArgsT const& args)
0254     {
0255         m_SeverityAttr.set_value(args[keywords::severity | m_DefaultSeverity]);
0256         return base_type::open_record_unlocked(args);
0257     }
0258 
0259     //! Unlocked \c swap
0260     void swap_unlocked(basic_severity_logger& that)
0261     {
0262         base_type::swap_unlocked(static_cast< base_type& >(that));
0263         boost::core::invoke_swap(m_DefaultSeverity, that.m_DefaultSeverity);
0264         m_SeverityAttr.swap(that.m_SeverityAttr);
0265     }
0266 };
0267 
0268 /*!
0269  * \brief Severity level support feature
0270  *
0271  * The logger with this feature registers a special attribute with an integral value type on construction.
0272  * This attribute will provide severity level for each log record being made through the logger.
0273  * The severity level can be omitted on logging record construction, in which case the default
0274  * level will be used. The default level can also be customized by passing it to the logger constructor.
0275  *
0276  * The type of the severity level attribute can be specified as a template parameter for the feature
0277  * template. By default, \c int will be used.
0278  */
0279 template< typename LevelT = int >
0280 struct severity
0281 {
0282     template< typename BaseT >
0283     struct apply
0284     {
0285         typedef basic_severity_logger<
0286             BaseT,
0287             LevelT
0288         > type;
0289     };
0290 };
0291 
0292 } // namespace sources
0293 
0294 BOOST_LOG_CLOSE_NAMESPACE // namespace log
0295 
0296 } // namespace boost
0297 
0298 //! The macro allows to put a record with a specific severity level into log
0299 #define BOOST_LOG_STREAM_SEV(logger, lvl)\
0300     BOOST_LOG_STREAM_WITH_PARAMS((logger), (::boost::log::keywords::severity = (lvl)))
0301 
0302 #ifndef BOOST_LOG_NO_SHORTHAND_NAMES
0303 
0304 //! An equivalent to BOOST_LOG_STREAM_SEV(logger, lvl)
0305 #define BOOST_LOG_SEV(logger, lvl) BOOST_LOG_STREAM_SEV(logger, lvl)
0306 
0307 #endif // BOOST_LOG_NO_SHORTHAND_NAMES
0308 
0309 #include <boost/log/detail/footer.hpp>
0310 
0311 #endif // BOOST_LOG_SOURCES_SEVERITY_FEATURE_HPP_INCLUDED_