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   channel_feature.hpp
0009  * \author Andrey Semashev
0010  * \date   28.02.2008
0011  *
0012  * The header contains implementation of a channel support feature.
0013  */
0014 
0015 #ifndef BOOST_LOG_SOURCES_CHANNEL_FEATURE_HPP_INCLUDED_
0016 #define BOOST_LOG_SOURCES_CHANNEL_FEATURE_HPP_INCLUDED_
0017 
0018 #include <string>
0019 #include <boost/move/core.hpp>
0020 #include <boost/move/utility_core.hpp>
0021 #include <boost/type_traits/is_nothrow_move_constructible.hpp>
0022 #include <boost/log/detail/config.hpp>
0023 #include <boost/log/detail/locks.hpp>
0024 #include <boost/log/detail/default_attribute_names.hpp>
0025 #include <boost/log/keywords/channel.hpp>
0026 #include <boost/log/attributes/mutable_constant.hpp>
0027 #include <boost/log/utility/strictest_lock.hpp>
0028 #include <boost/log/core/record.hpp>
0029 #include <boost/log/detail/header.hpp>
0030 
0031 #ifdef BOOST_HAS_PRAGMA_ONCE
0032 #pragma once
0033 #endif
0034 
0035 namespace boost {
0036 
0037 BOOST_LOG_OPEN_NAMESPACE
0038 
0039 namespace sources {
0040 
0041 /*!
0042  * \brief Channel feature implementation
0043  */
0044 template< typename BaseT, typename ChannelT >
0045 class basic_channel_logger :
0046     public BaseT
0047 {
0048     //! Base type
0049     typedef BaseT base_type;
0050     typedef basic_channel_logger this_type;
0051     BOOST_COPYABLE_AND_MOVABLE_ALT(this_type)
0052 
0053 public:
0054     //! Character type
0055     typedef typename base_type::char_type char_type;
0056     //! Final type
0057     typedef typename base_type::final_type final_type;
0058     //! Threading model being used
0059     typedef typename base_type::threading_model threading_model;
0060 
0061     //! Channel type
0062     typedef ChannelT channel_type;
0063     //! Channel attribute type
0064     typedef attributes::mutable_constant< channel_type > channel_attribute;
0065 
0066     //! Lock requirement for the \c open_record_unlocked method
0067     typedef typename strictest_lock<
0068         typename base_type::open_record_lock,
0069 #ifndef BOOST_LOG_NO_THREADS
0070         boost::log::aux::exclusive_lock_guard< threading_model >
0071 #else
0072         no_lock< threading_model >
0073 #endif // !defined(BOOST_LOG_NO_THREADS)
0074     >::type open_record_lock;
0075 
0076     //! Lock requirement for the \c swap_unlocked method
0077     typedef typename strictest_lock<
0078         typename base_type::swap_lock,
0079 #ifndef BOOST_LOG_NO_THREADS
0080         boost::log::aux::multiple_unique_lock2< threading_model, threading_model >
0081 #else
0082         no_lock< threading_model >
0083 #endif // !defined(BOOST_LOG_NO_THREADS)
0084     >::type swap_lock;
0085 
0086 private:
0087     //! Default channel name generator
0088     struct make_default_channel_name
0089     {
0090         typedef channel_type result_type;
0091         result_type operator() () const { return result_type(); }
0092     };
0093 
0094 private:
0095     //! Channel attribute
0096     channel_attribute m_ChannelAttr;
0097 
0098 public:
0099     /*!
0100      * Default constructor. The constructed logger has the default-constructed channel name.
0101      */
0102     basic_channel_logger() : base_type(), m_ChannelAttr(channel_type())
0103     {
0104         base_type::add_attribute_unlocked(boost::log::aux::default_attribute_names::channel(), m_ChannelAttr);
0105     }
0106     /*!
0107      * Copy constructor
0108      */
0109     basic_channel_logger(basic_channel_logger const& that) :
0110         base_type(static_cast< base_type const& >(that)),
0111         m_ChannelAttr(that.m_ChannelAttr.get())
0112     {
0113         // Our attributes must refer to our channel attribute
0114         base_type::attributes()[boost::log::aux::default_attribute_names::channel()] = m_ChannelAttr;
0115     }
0116     /*!
0117      * Move constructor
0118      */
0119     basic_channel_logger(BOOST_RV_REF(basic_channel_logger) that) BOOST_NOEXCEPT_IF(boost::is_nothrow_move_constructible< base_type >::value && boost::is_nothrow_move_constructible< channel_attribute >::value) :
0120         base_type(boost::move(static_cast< base_type& >(that))),
0121         m_ChannelAttr(boost::move(that.m_ChannelAttr))
0122     {
0123     }
0124     /*!
0125      * Constructor with arguments. Allows to register a channel name attribute on construction.
0126      *
0127      * \param args A set of named arguments. The following arguments are supported:
0128      *             \li \c channel - a string that represents the channel name
0129      */
0130     template< typename ArgsT >
0131     explicit basic_channel_logger(ArgsT const& args) :
0132         base_type(args),
0133         m_ChannelAttr(args[keywords::channel || make_default_channel_name()])
0134     {
0135         base_type::add_attribute_unlocked(boost::log::aux::default_attribute_names::channel(), m_ChannelAttr);
0136     }
0137 
0138     /*!
0139      * The observer of the channel name
0140      *
0141      * \return The channel name that was set by the logger
0142      */
0143     channel_type channel() const
0144     {
0145         BOOST_LOG_EXPR_IF_MT(boost::log::aux::shared_lock_guard< const threading_model > lock(this->get_threading_model());)
0146         return m_ChannelAttr.get();
0147     }
0148 
0149     /*!
0150      * The setter of the channel name
0151      *
0152      * \param ch The channel name to be set for the logger
0153      */
0154     void channel(channel_type const& ch)
0155     {
0156         BOOST_LOG_EXPR_IF_MT(boost::log::aux::exclusive_lock_guard< threading_model > lock(this->get_threading_model());)
0157         m_ChannelAttr.set(ch);
0158     }
0159 
0160 protected:
0161     /*!
0162      * Channel attribute accessor
0163      */
0164     channel_attribute const& get_channel_attribute() const { return m_ChannelAttr; }
0165 
0166     /*!
0167      * Unlocked \c open_record
0168      */
0169     template< typename ArgsT >
0170     record open_record_unlocked(ArgsT const& args)
0171     {
0172         return open_record_with_channel_unlocked(args, args[keywords::channel | parameter::void_()]);
0173     }
0174 
0175     /*!
0176      * Unlocked swap
0177      */
0178     void swap_unlocked(basic_channel_logger& that)
0179     {
0180         base_type::swap_unlocked(static_cast< base_type& >(that));
0181         m_ChannelAttr.swap(that.m_ChannelAttr);
0182     }
0183 
0184 private:
0185     //! The \c open_record implementation for the case when the channel is specified in log statement
0186     template< typename ArgsT, typename T >
0187     record open_record_with_channel_unlocked(ArgsT const& args, T const& ch)
0188     {
0189         m_ChannelAttr.set(ch);
0190         return base_type::open_record_unlocked(args);
0191     }
0192     //! The \c open_record implementation for the case when the channel is not specified in log statement
0193     template< typename ArgsT >
0194     record open_record_with_channel_unlocked(ArgsT const& args, parameter::void_)
0195     {
0196         return base_type::open_record_unlocked(args);
0197     }
0198 };
0199 
0200 /*!
0201  * \brief Channel support feature
0202  *
0203  * The logger with this feature automatically registers an attribute with the specified
0204  * on construction value, which is a channel name. The channel name can be modified
0205  * through the logger life time, either by calling the \c channel method or by specifying
0206  * the name in the logging statement.
0207  *
0208  * The type of the channel name can be customized by providing it as a template parameter
0209  * to the feature template. By default, a string will be used.
0210  */
0211 template< typename ChannelT = std::string >
0212 struct channel
0213 {
0214     template< typename BaseT >
0215     struct apply
0216     {
0217         typedef basic_channel_logger<
0218             BaseT,
0219             ChannelT
0220         > type;
0221     };
0222 };
0223 
0224 } // namespace sources
0225 
0226 BOOST_LOG_CLOSE_NAMESPACE // namespace log
0227 
0228 } // namespace boost
0229 
0230 //! The macro allows to put a record with a specific channel name into log
0231 #define BOOST_LOG_STREAM_CHANNEL(logger, chan)\
0232     BOOST_LOG_STREAM_WITH_PARAMS((logger), (::boost::log::keywords::channel = (chan)))
0233 
0234 #ifndef BOOST_LOG_NO_SHORTHAND_NAMES
0235 
0236 //! An equivalent to BOOST_LOG_STREAM_CHANNEL(logger, chan)
0237 #define BOOST_LOG_CHANNEL(logger, chan) BOOST_LOG_STREAM_CHANNEL(logger, chan)
0238 
0239 #endif // BOOST_LOG_NO_SHORTHAND_NAMES
0240 
0241 #include <boost/log/detail/footer.hpp>
0242 
0243 #endif // BOOST_LOG_SOURCES_CHANNEL_FEATURE_HPP_INCLUDED_