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   basic_logger.hpp
0009  * \author Andrey Semashev
0010  * \date   08.03.2007
0011  *
0012  * The header contains implementation of a base class for loggers. Convenience macros
0013  * for defining custom loggers are also provided.
0014  */
0015 
0016 #ifndef BOOST_LOG_SOURCES_BASIC_LOGGER_HPP_INCLUDED_
0017 #define BOOST_LOG_SOURCES_BASIC_LOGGER_HPP_INCLUDED_
0018 
0019 #include <exception>
0020 #include <utility>
0021 #include <ostream>
0022 #include <boost/assert.hpp>
0023 #include <boost/move/core.hpp>
0024 #include <boost/move/utility_core.hpp>
0025 #include <boost/core/addressof.hpp>
0026 #include <boost/type_traits/is_nothrow_swappable.hpp>
0027 #include <boost/type_traits/is_nothrow_move_constructible.hpp>
0028 #include <boost/preprocessor/facilities/empty.hpp>
0029 #include <boost/preprocessor/facilities/identity.hpp>
0030 #include <boost/preprocessor/seq/enum.hpp>
0031 #include <boost/log/detail/config.hpp>
0032 #include <boost/log/detail/parameter_tools.hpp>
0033 #include <boost/log/attributes/attribute_set.hpp>
0034 #include <boost/log/attributes/attribute_name.hpp>
0035 #include <boost/log/attributes/attribute.hpp>
0036 #include <boost/log/core/core.hpp>
0037 #include <boost/log/core/record.hpp>
0038 #include <boost/log/sources/features.hpp>
0039 #include <boost/log/sources/threading_models.hpp>
0040 #include <boost/log/detail/header.hpp>
0041 
0042 #ifdef BOOST_HAS_PRAGMA_ONCE
0043 #pragma once
0044 #endif
0045 
0046 namespace boost {
0047 
0048 BOOST_LOG_OPEN_NAMESPACE
0049 
0050 namespace sources {
0051 
0052 /*!
0053  * \brief Basic logger class
0054  *
0055  * The \c basic_logger class template serves as a base class for all loggers
0056  * provided by the library. It can also be used as a base for user-defined
0057  * loggers. The template parameters are:
0058  *
0059  * \li \c CharT - logging character type
0060  * \li \c FinalT - final type of the logger that eventually derives from
0061  *     the \c basic_logger. There may be other classes in the hierarchy
0062  *     between the final class and \c basic_logger.
0063  * \li \c ThreadingModelT - threading model policy. Must provide methods
0064  *     of the Boost.Thread locking concept used in \c basic_logger class
0065  *     and all its derivatives in the hierarchy up to the \c FinalT class.
0066  *     The \c basic_logger class itself requires methods of the
0067  *     SharedLockable concept. The threading model policy must also be
0068  *     default and copy-constructible and support member function \c swap.
0069  *     There are currently two policies provided: \c single_thread_model
0070  *     and \c multi_thread_model.
0071  *
0072  * The logger implements fundamental facilities of loggers, such as storing
0073  * source-specific attribute set and formatting log record messages. The basic
0074  * logger interacts with the logging core in order to apply filtering and
0075  * pass records to sinks.
0076  */
0077 template< typename CharT, typename FinalT, typename ThreadingModelT >
0078 class basic_logger :
0079     public ThreadingModelT
0080 {
0081     typedef basic_logger this_type;
0082     BOOST_COPYABLE_AND_MOVABLE_ALT(this_type)
0083 
0084 public:
0085     //! Character type
0086     typedef CharT char_type;
0087     //! Final logger type
0088     typedef FinalT final_type;
0089     //! Threading model type
0090     typedef ThreadingModelT threading_model;
0091 
0092 #if !defined(BOOST_LOG_NO_THREADS)
0093     //! Lock requirement for the swap_unlocked method
0094     typedef boost::log::aux::multiple_unique_lock2< threading_model, threading_model > swap_lock;
0095     //! Lock requirement for the add_attribute_unlocked method
0096     typedef boost::log::aux::exclusive_lock_guard< threading_model > add_attribute_lock;
0097     //! Lock requirement for the remove_attribute_unlocked method
0098     typedef boost::log::aux::exclusive_lock_guard< threading_model > remove_attribute_lock;
0099     //! Lock requirement for the remove_all_attributes_unlocked method
0100     typedef boost::log::aux::exclusive_lock_guard< threading_model > remove_all_attributes_lock;
0101     //! Lock requirement for the get_attributes method
0102     typedef boost::log::aux::shared_lock_guard< const threading_model > get_attributes_lock;
0103     //! Lock requirement for the open_record_unlocked method
0104     typedef boost::log::aux::shared_lock_guard< threading_model > open_record_lock;
0105     //! Lock requirement for the set_attributes method
0106     typedef boost::log::aux::exclusive_lock_guard< threading_model > set_attributes_lock;
0107 #else
0108     typedef no_lock< threading_model > swap_lock;
0109     typedef no_lock< threading_model > add_attribute_lock;
0110     typedef no_lock< threading_model > remove_attribute_lock;
0111     typedef no_lock< threading_model > remove_all_attributes_lock;
0112     typedef no_lock< const threading_model > get_attributes_lock;
0113     typedef no_lock< threading_model > open_record_lock;
0114     typedef no_lock< threading_model > set_attributes_lock;
0115 #endif
0116 
0117     //! Lock requirement for the push_record_unlocked method
0118     typedef no_lock< threading_model > push_record_lock;
0119 
0120 private:
0121     //! A pointer to the logging system
0122     core_ptr m_pCore;
0123 
0124     //! Logger-specific attribute set
0125     attribute_set m_Attributes;
0126 
0127 public:
0128     /*!
0129      * Constructor. Initializes internal data structures of the basic logger class,
0130      * acquires reference to the logging core.
0131      */
0132     basic_logger() :
0133         threading_model(),
0134         m_pCore(core::get())
0135     {
0136     }
0137     /*!
0138      * Copy constructor. Copies all attributes from the source logger.
0139      *
0140      * \note Not thread-safe. The source logger must be locked in the final class before copying.
0141      *
0142      * \param that Source logger
0143      */
0144     basic_logger(basic_logger const& that) :
0145         threading_model(static_cast< threading_model const& >(that)),
0146         m_pCore(that.m_pCore),
0147         m_Attributes(that.m_Attributes)
0148     {
0149     }
0150     /*!
0151      * Move constructor. Moves all attributes from the source logger.
0152      *
0153      * \note Not thread-safe. The source logger must be locked in the final class before copying.
0154      *
0155      * \param that Source logger
0156      */
0157     basic_logger(BOOST_RV_REF(basic_logger) that) BOOST_NOEXCEPT_IF(boost::is_nothrow_move_constructible< threading_model >::value &&
0158                                                                     boost::is_nothrow_move_constructible< core_ptr >::value &&
0159                                                                     boost::is_nothrow_move_constructible< attribute_set >::value) :
0160         threading_model(boost::move(static_cast< threading_model& >(that))),
0161         m_pCore(boost::move(that.m_pCore)),
0162         m_Attributes(boost::move(that.m_Attributes))
0163     {
0164     }
0165     /*!
0166      * Constructor with named arguments. The constructor ignores all arguments. The result of
0167      * construction is equivalent to default construction.
0168      */
0169     template< typename ArgsT >
0170     explicit basic_logger(ArgsT const&) :
0171         threading_model(),
0172         m_pCore(core::get())
0173     {
0174     }
0175 
0176 protected:
0177     /*!
0178      * An accessor to the logging system pointer
0179      */
0180     core_ptr const& core() const { return m_pCore; }
0181     /*!
0182      * An accessor to the logger attributes
0183      */
0184     attribute_set& attributes() { return m_Attributes; }
0185     /*!
0186      * An accessor to the logger attributes
0187      */
0188     attribute_set const& attributes() const { return m_Attributes; }
0189     /*!
0190      * An accessor to the threading model base
0191      */
0192     threading_model& get_threading_model() BOOST_NOEXCEPT { return *this; }
0193     /*!
0194      * An accessor to the threading model base
0195      */
0196     threading_model const& get_threading_model() const BOOST_NOEXCEPT { return *this; }
0197     /*!
0198      * An accessor to the final logger
0199      */
0200     final_type* final_this() BOOST_NOEXCEPT
0201     {
0202         BOOST_LOG_ASSUME(this != NULL);
0203         return static_cast< final_type* >(this);
0204     }
0205     /*!
0206      * An accessor to the final logger
0207      */
0208     final_type const* final_this() const BOOST_NOEXCEPT
0209     {
0210         BOOST_LOG_ASSUME(this != NULL);
0211         return static_cast< final_type const* >(this);
0212     }
0213 
0214     /*!
0215      * Unlocked \c swap
0216      */
0217     void swap_unlocked(basic_logger& that)
0218     {
0219         get_threading_model().swap(that.get_threading_model());
0220         m_Attributes.swap(that.m_Attributes);
0221     }
0222 
0223     /*!
0224      * Unlocked \c add_attribute
0225      */
0226     std::pair< attribute_set::iterator, bool > add_attribute_unlocked(attribute_name const& name, attribute const& attr)
0227     {
0228         return m_Attributes.insert(name, attr);
0229     }
0230 
0231     /*!
0232      * Unlocked \c remove_attribute
0233      */
0234     void remove_attribute_unlocked(attribute_set::iterator it)
0235     {
0236         m_Attributes.erase(it);
0237     }
0238 
0239     /*!
0240      * Unlocked \c remove_all_attributes
0241      */
0242     void remove_all_attributes_unlocked()
0243     {
0244         m_Attributes.clear();
0245     }
0246 
0247     /*!
0248      * Unlocked \c open_record
0249      */
0250     record open_record_unlocked()
0251     {
0252         return m_pCore->open_record(m_Attributes);
0253     }
0254     /*!
0255      * Unlocked \c open_record
0256      */
0257     template< typename ArgsT >
0258     record open_record_unlocked(ArgsT const&)
0259     {
0260         return m_pCore->open_record(m_Attributes);
0261     }
0262 
0263     /*!
0264      * Unlocked \c push_record
0265      */
0266     void push_record_unlocked(BOOST_RV_REF(record) rec)
0267     {
0268         m_pCore->push_record(boost::move(rec));
0269     }
0270 
0271     /*!
0272      * Unlocked \c get_attributes
0273      */
0274     attribute_set get_attributes_unlocked() const
0275     {
0276         return m_Attributes;
0277     }
0278 
0279     /*!
0280      * Unlocked \c set_attributes
0281      */
0282     void set_attributes_unlocked(attribute_set const& attrs)
0283     {
0284         m_Attributes = attrs;
0285     }
0286 
0287     //! Assignment is closed (should be implemented through copy and swap in the final class)
0288     BOOST_DELETED_FUNCTION(basic_logger& operator= (basic_logger const&))
0289 };
0290 
0291 /*!
0292  * Free-standing swap for all loggers
0293  */
0294 template< typename CharT, typename FinalT, typename ThreadingModelT >
0295 inline void swap(
0296     basic_logger< CharT, FinalT, ThreadingModelT >& left,
0297     basic_logger< CharT, FinalT, ThreadingModelT >& right) BOOST_NOEXCEPT_IF(boost::is_nothrow_swappable< FinalT >::value)
0298 {
0299     static_cast< FinalT& >(left).swap(static_cast< FinalT& >(right));
0300 }
0301 
0302 /*!
0303  * \brief A composite logger that inherits a number of features
0304  *
0305  * The composite logger is a helper class that simplifies feature composition into the final logger.
0306  * The user's logger class is expected to derive from the composite logger class, instantiated with
0307  * the character type, the user's logger class, the threading model and the list of the required features.
0308  * The former three parameters are passed to the \c basic_logger class template. The feature list
0309  * must be an MPL type sequence, where each element is a unary MPL metafunction class, that upon
0310  * applying on its argument results in a logging feature class that derives from the argument.
0311  * Every logger feature provided by the library can participate in the feature list.
0312  */
0313 template< typename CharT, typename FinalT, typename ThreadingModelT, typename FeaturesT >
0314 class basic_composite_logger :
0315     public boost::log::sources::aux::inherit_features<
0316         basic_logger< CharT, FinalT, ThreadingModelT >,
0317         FeaturesT
0318     >::type
0319 {
0320 private:
0321     //! Base type (the hierarchy of features)
0322     typedef typename boost::log::sources::aux::inherit_features<
0323         basic_logger< CharT, FinalT, ThreadingModelT >,
0324         FeaturesT
0325     >::type base_type;
0326 
0327 protected:
0328     //! The composite logger type (for use in the user's logger class)
0329     typedef basic_composite_logger logger_base;
0330     BOOST_COPYABLE_AND_MOVABLE_ALT(logger_base)
0331 
0332 public:
0333     //! Threading model being used
0334     typedef typename base_type::threading_model threading_model;
0335 
0336     //! Lock requirement for the swap_unlocked method
0337     typedef typename base_type::swap_lock swap_lock;
0338 
0339 #if !defined(BOOST_LOG_NO_THREADS)
0340 
0341 public:
0342     /*!
0343      * Default constructor (default-constructs all features)
0344      */
0345     basic_composite_logger() {}
0346     /*!
0347      * Copy constructor
0348      */
0349     basic_composite_logger(basic_composite_logger const& that) :
0350         base_type
0351         ((
0352             boost::log::aux::shared_lock_guard< const threading_model >(that.get_threading_model()),
0353             static_cast< base_type const& >(that)
0354         ))
0355     {
0356     }
0357     /*!
0358      * Move constructor
0359      */
0360     basic_composite_logger(BOOST_RV_REF(logger_base) that) BOOST_NOEXCEPT_IF(boost::is_nothrow_move_constructible< base_type >::value) :
0361         base_type(boost::move(static_cast< base_type& >(that)))
0362     {
0363     }
0364     /*!
0365      * Constructor with named parameters
0366      */
0367     template< typename ArgsT >
0368     explicit basic_composite_logger(ArgsT const& args) : base_type(args)
0369     {
0370     }
0371 
0372     /*!
0373      * The method adds an attribute to the source-specific attribute set. The attribute will be implicitly added to
0374      * every log record made with the current logger.
0375      *
0376      * \param name The attribute name.
0377      * \param attr The attribute factory.
0378      * \return A pair of values. If the second member is \c true, then the attribute is added and the first member points to the
0379      *         attribute. Otherwise the attribute was not added and the first member points to the attribute that prevents
0380      *         addition.
0381      */
0382     std::pair< attribute_set::iterator, bool > add_attribute(attribute_name const& name, attribute const& attr)
0383     {
0384         typename base_type::add_attribute_lock lock(base_type::get_threading_model());
0385         return base_type::add_attribute_unlocked(name, attr);
0386     }
0387     /*!
0388      * The method removes an attribute from the source-specific attribute set.
0389      *
0390      * \pre The attribute was added with the add_attribute call for this instance of the logger.
0391      * \post The attribute is no longer registered as a source-specific attribute for this logger. The iterator is invalidated after removal.
0392      *
0393      * \param it Iterator to the previously added attribute.
0394      */
0395     void remove_attribute(attribute_set::iterator it)
0396     {
0397         typename base_type::remove_attribute_lock lock(base_type::get_threading_model());
0398         base_type::remove_attribute_unlocked(it);
0399     }
0400 
0401     /*!
0402      * The method removes all attributes from the logger. All iterators and references to the removed attributes are invalidated.
0403      */
0404     void remove_all_attributes()
0405     {
0406         typename base_type::remove_all_attributes_lock lock(base_type::get_threading_model());
0407         base_type::remove_all_attributes_unlocked();
0408     }
0409 
0410     /*!
0411      * The method retrieves a copy of a set with all attributes from the logger.
0412      *
0413      * \return The copy of the attribute set. Attributes are shallow-copied.
0414      */
0415     attribute_set get_attributes() const
0416     {
0417         typename base_type::get_attributes_lock lock(base_type::get_threading_model());
0418         return base_type::get_attributes_unlocked();
0419     }
0420 
0421     /*!
0422      * The method installs the whole attribute set into the logger. All iterators and references to elements of
0423      * the previous set are invalidated. Iterators to the \a attrs set are not valid to be used with the logger (that is,
0424      * the logger owns a copy of \a attrs after completion).
0425      *
0426      * \param attrs The set of attributes to install into the logger. Attributes are shallow-copied.
0427      */
0428     void set_attributes(attribute_set const& attrs)
0429     {
0430         typename base_type::set_attributes_lock lock(base_type::get_threading_model());
0431         base_type::set_attributes_unlocked(attrs);
0432     }
0433 
0434     /*!
0435      * The method opens a new log record in the logging core.
0436      *
0437      * \return A valid record handle if the logging record is opened successfully, an invalid handle otherwise.
0438      */
0439     record open_record()
0440     {
0441         // Perform a quick check first
0442         if (this->core()->get_logging_enabled())
0443         {
0444             typename base_type::open_record_lock lock(base_type::get_threading_model());
0445             return base_type::open_record_unlocked(boost::log::aux::empty_arg_list());
0446         }
0447         else
0448             return record();
0449     }
0450     /*!
0451      * The method opens a new log record in the logging core.
0452      *
0453      * \param args A set of additional named arguments. The parameter is ignored.
0454      * \return A valid record handle if the logging record is opened successfully, an invalid handle otherwise.
0455      */
0456     template< typename ArgsT >
0457     record open_record(ArgsT const& args)
0458     {
0459         // Perform a quick check first
0460         if (this->core()->get_logging_enabled())
0461         {
0462             typename base_type::open_record_lock lock(base_type::get_threading_model());
0463             return base_type::open_record_unlocked(args);
0464         }
0465         else
0466             return record();
0467     }
0468     /*!
0469      * The method pushes the constructed message to the logging core
0470      *
0471      * \param rec The log record with the formatted message
0472      */
0473     void push_record(BOOST_RV_REF(record) rec)
0474     {
0475         typename base_type::push_record_lock lock(base_type::get_threading_model());
0476         base_type::push_record_unlocked(boost::move(rec));
0477     }
0478     /*!
0479      * Thread-safe implementation of swap
0480      */
0481     void swap(basic_composite_logger& that)
0482     {
0483         swap_lock lock(base_type::get_threading_model(), that.get_threading_model());
0484         base_type::swap_unlocked(static_cast< base_type& >(that));
0485     }
0486 
0487 protected:
0488     /*!
0489      * Assignment for the final class. Threadsafe, provides strong exception guarantee.
0490      */
0491     FinalT& assign(FinalT const& that)
0492     {
0493         BOOST_LOG_ASSUME(this != NULL);
0494         if (static_cast< FinalT* >(this) != boost::addressof(that))
0495         {
0496             // We'll have to explicitly create the copy in order to make sure it's unlocked when we attempt to lock *this
0497             FinalT tmp(that);
0498             boost::log::aux::exclusive_lock_guard< threading_model > lock(base_type::get_threading_model());
0499             base_type::swap_unlocked(tmp);
0500         }
0501         return static_cast< FinalT& >(*this);
0502     }
0503 };
0504 
0505 //! An optimized composite logger version with no multithreading support
0506 template< typename CharT, typename FinalT, typename FeaturesT >
0507 class basic_composite_logger< CharT, FinalT, single_thread_model, FeaturesT > :
0508     public boost::log::sources::aux::inherit_features<
0509         basic_logger< CharT, FinalT, single_thread_model >,
0510         FeaturesT
0511     >::type
0512 {
0513 private:
0514     typedef typename boost::log::sources::aux::inherit_features<
0515         basic_logger< CharT, FinalT, single_thread_model >,
0516         FeaturesT
0517     >::type base_type;
0518 
0519 protected:
0520     typedef basic_composite_logger logger_base;
0521     BOOST_COPYABLE_AND_MOVABLE_ALT(logger_base)
0522 
0523 public:
0524     typedef typename base_type::threading_model threading_model;
0525 
0526 #endif // !defined(BOOST_LOG_NO_THREADS)
0527 
0528 public:
0529     basic_composite_logger() {}
0530     basic_composite_logger(basic_composite_logger const& that) :
0531         base_type(static_cast< base_type const& >(that))
0532     {
0533     }
0534     basic_composite_logger(BOOST_RV_REF(logger_base) that) BOOST_NOEXCEPT_IF(boost::is_nothrow_move_constructible< base_type >::value) :
0535         base_type(boost::move(static_cast< base_type& >(that)))
0536     {
0537     }
0538     template< typename ArgsT >
0539     explicit basic_composite_logger(ArgsT const& args) : base_type(args)
0540     {
0541     }
0542 
0543     std::pair< attribute_set::iterator, bool > add_attribute(attribute_name const& name, attribute const& attr)
0544     {
0545         return base_type::add_attribute_unlocked(name, attr);
0546     }
0547     void remove_attribute(attribute_set::iterator it)
0548     {
0549         base_type::remove_attribute_unlocked(it);
0550     }
0551     void remove_all_attributes()
0552     {
0553         base_type::remove_all_attributes_unlocked();
0554     }
0555     attribute_set get_attributes() const
0556     {
0557         return base_type::get_attributes_unlocked();
0558     }
0559     void set_attributes(attribute_set const& attrs)
0560     {
0561         base_type::set_attributes_unlocked(attrs);
0562     }
0563     record open_record()
0564     {
0565         // Perform a quick check first
0566         if (this->core()->get_logging_enabled())
0567             return base_type::open_record_unlocked(boost::log::aux::empty_arg_list());
0568         else
0569             return record();
0570     }
0571     template< typename ArgsT >
0572     record open_record(ArgsT const& args)
0573     {
0574         // Perform a quick check first
0575         if (this->core()->get_logging_enabled())
0576             return base_type::open_record_unlocked(args);
0577         else
0578             return record();
0579     }
0580     void push_record(BOOST_RV_REF(record) rec)
0581     {
0582         base_type::push_record_unlocked(boost::move(rec));
0583     }
0584     void swap(basic_composite_logger& that)
0585     {
0586         base_type::swap_unlocked(static_cast< base_type& >(that));
0587     }
0588 
0589 protected:
0590     FinalT& assign(FinalT that)
0591     {
0592         base_type::swap_unlocked(that);
0593         return static_cast< FinalT& >(*this);
0594     }
0595 };
0596 
0597 
0598 #ifndef BOOST_LOG_DOXYGEN_PASS
0599 
0600 #define BOOST_LOG_FORWARD_LOGGER_CONSTRUCTORS_IMPL(class_type, typename_keyword)\
0601     public:\
0602         BOOST_DEFAULTED_FUNCTION(class_type(), {})\
0603         class_type(class_type const& that) : class_type::logger_base(\
0604             static_cast< typename_keyword() class_type::logger_base const& >(that)) {}\
0605         class_type(BOOST_RV_REF(class_type) that) BOOST_NOEXCEPT_IF(boost::is_nothrow_move_constructible< typename_keyword() class_type::logger_base >::value) : class_type::logger_base(\
0606             ::boost::move(static_cast< typename_keyword() class_type::logger_base& >(that))) {}\
0607         BOOST_LOG_PARAMETRIZED_CONSTRUCTORS_FORWARD(class_type, class_type::logger_base)\
0608 
0609 #endif // BOOST_LOG_DOXYGEN_PASS
0610 
0611 #define BOOST_LOG_FORWARD_LOGGER_CONSTRUCTORS(class_type)\
0612     BOOST_LOG_FORWARD_LOGGER_CONSTRUCTORS_IMPL(class_type, BOOST_PP_EMPTY)
0613 
0614 #define BOOST_LOG_FORWARD_LOGGER_CONSTRUCTORS_TEMPLATE(class_type)\
0615     BOOST_LOG_FORWARD_LOGGER_CONSTRUCTORS_IMPL(class_type, BOOST_PP_IDENTITY(typename))
0616 
0617 #define BOOST_LOG_FORWARD_LOGGER_ASSIGNMENT(class_type)\
0618     public:\
0619         class_type& operator= (BOOST_COPY_ASSIGN_REF(class_type) that)\
0620         {\
0621             return class_type::logger_base::assign(static_cast< class_type const& >(that));\
0622         }\
0623         class_type& operator= (BOOST_RV_REF(class_type) that)\
0624         {\
0625             BOOST_LOG_EXPR_IF_MT(::boost::log::aux::exclusive_lock_guard< class_type::threading_model > lock(this->get_threading_model());)\
0626             this->swap_unlocked(that);\
0627             return *this;\
0628         }
0629 
0630 #define BOOST_LOG_FORWARD_LOGGER_ASSIGNMENT_TEMPLATE(class_type)\
0631     public:\
0632         class_type& operator= (BOOST_COPY_ASSIGN_REF(class_type) that)\
0633         {\
0634             return class_type::logger_base::assign(static_cast< class_type const& >(that));\
0635         }\
0636         class_type& operator= (BOOST_RV_REF(class_type) that)\
0637         {\
0638             BOOST_LOG_EXPR_IF_MT(::boost::log::aux::exclusive_lock_guard< typename class_type::threading_model > lock(this->get_threading_model());)\
0639             this->swap_unlocked(that);\
0640             return *this;\
0641         }
0642 
0643 #define BOOST_LOG_FORWARD_LOGGER_MEMBERS(class_type)\
0644     BOOST_COPYABLE_AND_MOVABLE(class_type)\
0645     BOOST_LOG_FORWARD_LOGGER_CONSTRUCTORS(class_type)\
0646     BOOST_LOG_FORWARD_LOGGER_ASSIGNMENT(class_type)
0647 
0648 #define BOOST_LOG_FORWARD_LOGGER_MEMBERS_TEMPLATE(class_type)\
0649     BOOST_COPYABLE_AND_MOVABLE(class_type)\
0650     BOOST_LOG_FORWARD_LOGGER_CONSTRUCTORS_TEMPLATE(class_type)\
0651     BOOST_LOG_FORWARD_LOGGER_ASSIGNMENT_TEMPLATE(class_type)
0652 
0653 } // namespace sources
0654 
0655 BOOST_LOG_CLOSE_NAMESPACE // namespace log
0656 
0657 } // namespace boost
0658 
0659 /*!
0660  *  \brief The macro declares a logger class that inherits a number of base classes
0661  *
0662  *  \param type_name The name of the logger class to declare
0663  *  \param char_type The character type of the logger. Either char or wchar_t expected.
0664  *  \param base_seq A Boost.Preprocessor sequence of type identifiers of the base classes templates
0665  *  \param threading A threading model class
0666  */
0667 #define BOOST_LOG_DECLARE_LOGGER_TYPE(type_name, char_type, base_seq, threading)\
0668     class type_name :\
0669         public ::boost::log::sources::basic_composite_logger<\
0670             char_type,\
0671             type_name,\
0672             threading,\
0673             ::boost::log::sources::features< BOOST_PP_SEQ_ENUM(base_seq) >\
0674         >\
0675     {\
0676         BOOST_LOG_FORWARD_LOGGER_MEMBERS(type_name)\
0677     }
0678 
0679 
0680 
0681 #ifdef BOOST_LOG_USE_CHAR
0682 
0683 /*!
0684  *  \brief The macro declares a narrow-char logger class that inherits a number of base classes
0685  *
0686  *  Equivalent to BOOST_LOG_DECLARE_LOGGER_TYPE(type_name, char, base_seq, single_thread_model)
0687  *
0688  *  \param type_name The name of the logger class to declare
0689  *  \param base_seq A Boost.Preprocessor sequence of type identifiers of the base classes templates
0690  */
0691 #define BOOST_LOG_DECLARE_LOGGER(type_name, base_seq)\
0692     BOOST_LOG_DECLARE_LOGGER_TYPE(type_name, char, base_seq, ::boost::log::sources::single_thread_model)
0693 
0694 #if !defined(BOOST_LOG_NO_THREADS)
0695 
0696 /*!
0697  *  \brief The macro declares a narrow-char thread-safe logger class that inherits a number of base classes
0698  *
0699  *  Equivalent to <tt>BOOST_LOG_DECLARE_LOGGER_TYPE(type_name, char, base_seq, multi_thread_model< shared_mutex >)</tt>
0700  *
0701  *  \param type_name The name of the logger class to declare
0702  *  \param base_seq A Boost.Preprocessor sequence of type identifiers of the base classes templates
0703  */
0704 #define BOOST_LOG_DECLARE_LOGGER_MT(type_name, base_seq)\
0705     BOOST_LOG_DECLARE_LOGGER_TYPE(type_name, char, base_seq,\
0706         ::boost::log::sources::multi_thread_model< ::boost::shared_mutex >)
0707 
0708 #endif // !defined(BOOST_LOG_NO_THREADS)
0709 #endif // BOOST_LOG_USE_CHAR
0710 
0711 #ifdef BOOST_LOG_USE_WCHAR_T
0712 
0713 /*!
0714  *  \brief The macro declares a wide-char logger class that inherits a number of base classes
0715  *
0716  *  Equivalent to BOOST_LOG_DECLARE_LOGGER_TYPE(type_name, wchar_t, base_seq, single_thread_model)
0717  *
0718  *  \param type_name The name of the logger class to declare
0719  *  \param base_seq A Boost.Preprocessor sequence of type identifiers of the base classes templates
0720  */
0721 #define BOOST_LOG_DECLARE_WLOGGER(type_name, base_seq)\
0722     BOOST_LOG_DECLARE_LOGGER_TYPE(type_name, wchar_t, base_seq, ::boost::log::sources::single_thread_model)
0723 
0724 #if !defined(BOOST_LOG_NO_THREADS)
0725 
0726 /*!
0727  *  \brief The macro declares a wide-char thread-safe logger class that inherits a number of base classes
0728  *
0729  *  Equivalent to <tt>BOOST_LOG_DECLARE_LOGGER_TYPE(type_name, wchar_t, base_seq, multi_thread_model< shared_mutex >)</tt>
0730  *
0731  *  \param type_name The name of the logger class to declare
0732  *  \param base_seq A Boost.Preprocessor sequence of type identifiers of the base classes templates
0733  */
0734 #define BOOST_LOG_DECLARE_WLOGGER_MT(type_name, base_seq)\
0735     BOOST_LOG_DECLARE_LOGGER_TYPE(type_name, wchar_t, base_seq,\
0736         ::boost::log::sources::multi_thread_model< ::boost::shared_mutex >)
0737 
0738 #endif // !defined(BOOST_LOG_NO_THREADS)
0739 #endif // BOOST_LOG_USE_WCHAR_T
0740 
0741 #include <boost/log/detail/footer.hpp>
0742 
0743 #endif // BOOST_LOG_SOURCES_BASIC_LOGGER_HPP_INCLUDED_