Chris@16: /* Chris@101: * Copyright Andrey Semashev 2007 - 2015. Chris@16: * Distributed under the Boost Software License, Version 1.0. Chris@16: * (See accompanying file LICENSE_1_0.txt or copy at Chris@16: * http://www.boost.org/LICENSE_1_0.txt) Chris@16: */ Chris@16: /*! Chris@16: * \file basic_logger.hpp Chris@16: * \author Andrey Semashev Chris@16: * \date 08.03.2007 Chris@16: * Chris@16: * The header contains implementation of a base class for loggers. Convenience macros Chris@16: * for defining custom loggers are also provided. Chris@16: */ Chris@16: Chris@16: #ifndef BOOST_LOG_SOURCES_BASIC_LOGGER_HPP_INCLUDED_ Chris@16: #define BOOST_LOG_SOURCES_BASIC_LOGGER_HPP_INCLUDED_ Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #ifdef BOOST_HAS_PRAGMA_ONCE Chris@16: #pragma once Chris@16: #endif Chris@16: Chris@16: namespace boost { Chris@16: Chris@16: BOOST_LOG_OPEN_NAMESPACE Chris@16: Chris@16: namespace sources { Chris@16: Chris@16: /*! Chris@16: * \brief Basic logger class Chris@16: * Chris@16: * The \c basic_logger class template serves as a base class for all loggers Chris@16: * provided by the library. It can also be used as a base for user-defined Chris@16: * loggers. The template parameters are: Chris@16: * Chris@16: * \li \c CharT - logging character type Chris@16: * \li \c FinalT - final type of the logger that eventually derives from Chris@16: * the \c basic_logger. There may be other classes in the hierarchy Chris@16: * between the final class and \c basic_logger. Chris@16: * \li \c ThreadingModelT - threading model policy. Must provide methods Chris@16: * of the Boost.Thread locking concept used in \c basic_logger class Chris@16: * and all its derivatives in the hierarchy up to the \c FinalT class. Chris@16: * The \c basic_logger class itself requires methods of the Chris@16: * SharedLockable concept. The threading model policy must also be Chris@16: * default and copy-constructible and support member function \c swap. Chris@16: * There are currently two policies provided: \c single_thread_model Chris@16: * and \c multi_thread_model. Chris@16: * Chris@16: * The logger implements fundamental facilities of loggers, such as storing Chris@16: * source-specific attribute set and formatting log record messages. The basic Chris@16: * logger interacts with the logging core in order to apply filtering and Chris@16: * pass records to sinks. Chris@16: */ Chris@16: template< typename CharT, typename FinalT, typename ThreadingModelT > Chris@16: class basic_logger : Chris@16: public ThreadingModelT Chris@16: { Chris@16: typedef basic_logger this_type; Chris@16: BOOST_COPYABLE_AND_MOVABLE_ALT(this_type) Chris@16: Chris@16: public: Chris@16: //! Character type Chris@16: typedef CharT char_type; Chris@16: //! Final logger type Chris@16: typedef FinalT final_type; Chris@16: //! Threading model type Chris@16: typedef ThreadingModelT threading_model; Chris@16: Chris@16: #if !defined(BOOST_LOG_NO_THREADS) Chris@16: //! Lock requirement for the swap_unlocked method Chris@16: typedef boost::log::aux::exclusive_lock_guard< threading_model > swap_lock; Chris@16: //! Lock requirement for the add_attribute_unlocked method Chris@16: typedef boost::log::aux::exclusive_lock_guard< threading_model > add_attribute_lock; Chris@16: //! Lock requirement for the remove_attribute_unlocked method Chris@16: typedef boost::log::aux::exclusive_lock_guard< threading_model > remove_attribute_lock; Chris@16: //! Lock requirement for the remove_all_attributes_unlocked method Chris@16: typedef boost::log::aux::exclusive_lock_guard< threading_model > remove_all_attributes_lock; Chris@16: //! Lock requirement for the get_attributes method Chris@101: typedef boost::log::aux::shared_lock_guard< const threading_model > get_attributes_lock; Chris@16: //! Lock requirement for the open_record_unlocked method Chris@16: typedef boost::log::aux::shared_lock_guard< threading_model > open_record_lock; Chris@16: //! Lock requirement for the set_attributes method Chris@16: typedef boost::log::aux::exclusive_lock_guard< threading_model > set_attributes_lock; Chris@16: #else Chris@16: typedef no_lock< threading_model > swap_lock; Chris@16: typedef no_lock< threading_model > add_attribute_lock; Chris@16: typedef no_lock< threading_model > remove_attribute_lock; Chris@16: typedef no_lock< threading_model > remove_all_attributes_lock; Chris@101: typedef no_lock< const threading_model > get_attributes_lock; Chris@16: typedef no_lock< threading_model > open_record_lock; Chris@16: typedef no_lock< threading_model > set_attributes_lock; Chris@16: #endif Chris@16: Chris@16: //! Lock requirement for the push_record_unlocked method Chris@16: typedef no_lock< threading_model > push_record_lock; Chris@16: Chris@16: private: Chris@16: //! A pointer to the logging system Chris@16: core_ptr m_pCore; Chris@16: Chris@16: //! Logger-specific attribute set Chris@16: attribute_set m_Attributes; Chris@16: Chris@16: public: Chris@16: /*! Chris@16: * Constructor. Initializes internal data structures of the basic logger class, Chris@16: * acquires reference to the logging core. Chris@16: */ Chris@16: basic_logger() : Chris@16: threading_model(), Chris@16: m_pCore(core::get()) Chris@16: { Chris@16: } Chris@16: /*! Chris@16: * Copy constructor. Copies all attributes from the source logger. Chris@16: * Chris@16: * \note Not thread-safe. The source logger must be locked in the final class before copying. Chris@16: * Chris@16: * \param that Source logger Chris@16: */ Chris@16: basic_logger(basic_logger const& that) : Chris@16: threading_model(static_cast< threading_model const& >(that)), Chris@16: m_pCore(core::get()), Chris@16: m_Attributes(that.m_Attributes) Chris@16: { Chris@16: } Chris@16: /*! Chris@16: * Move constructor. Moves all attributes from the source logger. Chris@16: * Chris@16: * \note Not thread-safe. The source logger must be locked in the final class before copying. Chris@16: * Chris@16: * \param that Source logger Chris@16: */ Chris@16: basic_logger(BOOST_RV_REF(basic_logger) that) : Chris@16: threading_model(boost::move(static_cast< threading_model& >(that))) Chris@16: { Chris@16: m_pCore.swap(that.m_pCore); Chris@16: m_Attributes.swap(that.m_Attributes); Chris@16: } Chris@16: /*! Chris@16: * Constructor with named arguments. The constructor ignores all arguments. The result of Chris@16: * construction is equivalent to default construction. Chris@16: */ Chris@16: template< typename ArgsT > Chris@16: explicit basic_logger(ArgsT const&) : Chris@16: threading_model(), Chris@16: m_pCore(core::get()) Chris@16: { Chris@16: } Chris@16: Chris@16: protected: Chris@16: /*! Chris@16: * An accessor to the logging system pointer Chris@16: */ Chris@16: core_ptr const& core() const { return m_pCore; } Chris@16: /*! Chris@16: * An accessor to the logger attributes Chris@16: */ Chris@16: attribute_set& attributes() { return m_Attributes; } Chris@16: /*! Chris@16: * An accessor to the logger attributes Chris@16: */ Chris@16: attribute_set const& attributes() const { return m_Attributes; } Chris@16: /*! Chris@16: * An accessor to the threading model base Chris@16: */ Chris@16: threading_model& get_threading_model() { return *this; } Chris@16: /*! Chris@16: * An accessor to the threading model base Chris@16: */ Chris@16: threading_model const& get_threading_model() const { return *this; } Chris@16: /*! Chris@16: * An accessor to the final logger Chris@16: */ Chris@16: final_type* final_this() Chris@16: { Chris@16: BOOST_LOG_ASSUME(this != NULL); Chris@16: return static_cast< final_type* >(this); Chris@16: } Chris@16: /*! Chris@16: * An accessor to the final logger Chris@16: */ Chris@16: final_type const* final_this() const Chris@16: { Chris@16: BOOST_LOG_ASSUME(this != NULL); Chris@16: return static_cast< final_type const* >(this); Chris@16: } Chris@16: Chris@16: /*! Chris@16: * Unlocked \c swap Chris@16: */ Chris@16: void swap_unlocked(basic_logger& that) Chris@16: { Chris@16: get_threading_model().swap(that.get_threading_model()); Chris@16: m_Attributes.swap(that.m_Attributes); Chris@16: } Chris@16: Chris@16: /*! Chris@16: * Unlocked \c add_attribute Chris@16: */ Chris@16: std::pair< attribute_set::iterator, bool > add_attribute_unlocked(attribute_name const& name, attribute const& attr) Chris@16: { Chris@16: return m_Attributes.insert(name, attr); Chris@16: } Chris@16: Chris@16: /*! Chris@16: * Unlocked \c remove_attribute Chris@16: */ Chris@16: void remove_attribute_unlocked(attribute_set::iterator it) Chris@16: { Chris@16: m_Attributes.erase(it); Chris@16: } Chris@16: Chris@16: /*! Chris@16: * Unlocked \c remove_all_attributes Chris@16: */ Chris@16: void remove_all_attributes_unlocked() Chris@16: { Chris@16: m_Attributes.clear(); Chris@16: } Chris@16: Chris@16: /*! Chris@16: * Unlocked \c open_record Chris@16: */ Chris@16: record open_record_unlocked() Chris@16: { Chris@16: return m_pCore->open_record(m_Attributes); Chris@16: } Chris@16: /*! Chris@16: * Unlocked \c open_record Chris@16: */ Chris@16: template< typename ArgsT > Chris@16: record open_record_unlocked(ArgsT const&) Chris@16: { Chris@16: return m_pCore->open_record(m_Attributes); Chris@16: } Chris@16: Chris@16: /*! Chris@16: * Unlocked \c push_record Chris@16: */ Chris@16: void push_record_unlocked(BOOST_RV_REF(record) rec) Chris@16: { Chris@16: m_pCore->push_record(boost::move(rec)); Chris@16: } Chris@16: Chris@16: /*! Chris@16: * Unlocked \c get_attributes Chris@16: */ Chris@16: attribute_set get_attributes_unlocked() const Chris@16: { Chris@16: return m_Attributes; Chris@16: } Chris@16: Chris@16: /*! Chris@16: * Unlocked \c set_attributes Chris@16: */ Chris@16: void set_attributes_unlocked(attribute_set const& attrs) Chris@16: { Chris@16: m_Attributes = attrs; Chris@16: } Chris@16: Chris@16: //! Assignment is closed (should be implemented through copy and swap in the final class) Chris@16: BOOST_DELETED_FUNCTION(basic_logger& operator= (basic_logger const&)) Chris@16: }; Chris@16: Chris@16: /*! Chris@16: * Free-standing swap for all loggers Chris@16: */ Chris@16: template< typename CharT, typename FinalT, typename ThreadingModelT > Chris@16: inline void swap( Chris@16: basic_logger< CharT, FinalT, ThreadingModelT >& left, Chris@16: basic_logger< CharT, FinalT, ThreadingModelT >& right) Chris@16: { Chris@16: static_cast< FinalT& >(left).swap(static_cast< FinalT& >(right)); Chris@16: } Chris@16: Chris@16: /*! Chris@16: * \brief A composite logger that inherits a number of features Chris@16: * Chris@16: * The composite logger is a helper class that simplifies feature composition into the final logger. Chris@16: * The user's logger class is expected to derive from the composite logger class, instantiated with Chris@16: * the character type, the user's logger class, the threading model and the list of the required features. Chris@16: * The former three parameters are passed to the \c basic_logger class template. The feature list Chris@16: * must be an MPL type sequence, where each element is a unary MPL metafunction class, that upon Chris@16: * applying on its argument results in a logging feature class that derives from the argument. Chris@16: * Every logger feature provided by the library can participate in the feature list. Chris@16: */ Chris@16: template< typename CharT, typename FinalT, typename ThreadingModelT, typename FeaturesT > Chris@16: class basic_composite_logger : Chris@16: public boost::log::sources::aux::inherit_features< Chris@16: basic_logger< CharT, FinalT, ThreadingModelT >, Chris@16: FeaturesT Chris@16: >::type Chris@16: { Chris@16: private: Chris@16: //! Base type (the hierarchy of features) Chris@16: typedef typename boost::log::sources::aux::inherit_features< Chris@16: basic_logger< CharT, FinalT, ThreadingModelT >, Chris@16: FeaturesT Chris@16: >::type base_type; Chris@16: Chris@16: protected: Chris@16: //! The composite logger type (for use in the user's logger class) Chris@16: typedef basic_composite_logger logger_base; Chris@16: BOOST_COPYABLE_AND_MOVABLE_ALT(logger_base) Chris@16: Chris@16: public: Chris@16: //! Threading model being used Chris@16: typedef typename base_type::threading_model threading_model; Chris@16: Chris@16: #if !defined(BOOST_LOG_NO_THREADS) Chris@16: Chris@16: public: Chris@16: /*! Chris@16: * Default constructor (default-constructs all features) Chris@16: */ Chris@16: basic_composite_logger() {} Chris@16: /*! Chris@16: * Copy constructor Chris@16: */ Chris@16: basic_composite_logger(basic_composite_logger const& that) : Chris@16: base_type Chris@16: (( Chris@16: boost::log::aux::shared_lock_guard< const threading_model >(that.get_threading_model()), Chris@16: static_cast< base_type const& >(that) Chris@16: )) Chris@16: { Chris@16: } Chris@16: /*! Chris@16: * Move constructor Chris@16: */ Chris@16: basic_composite_logger(BOOST_RV_REF(logger_base) that) : Chris@16: base_type(boost::move(static_cast< base_type& >(that))) Chris@16: { Chris@16: } Chris@16: /*! Chris@16: * Constructor with named parameters Chris@16: */ Chris@16: template< typename ArgsT > Chris@16: explicit basic_composite_logger(ArgsT const& args) : base_type(args) Chris@16: { Chris@16: } Chris@16: Chris@16: /*! Chris@16: * The method adds an attribute to the source-specific attribute set. The attribute will be implicitly added to Chris@16: * every log record made with the current logger. Chris@16: * Chris@16: * \param name The attribute name. Chris@16: * \param attr The attribute factory. Chris@16: * \return A pair of values. If the second member is \c true, then the attribute is added and the first member points to the Chris@16: * attribute. Otherwise the attribute was not added and the first member points to the attribute that prevents Chris@16: * addition. Chris@16: */ Chris@16: std::pair< attribute_set::iterator, bool > add_attribute(attribute_name const& name, attribute const& attr) Chris@16: { Chris@16: typename base_type::add_attribute_lock lock(base_type::get_threading_model()); Chris@16: return base_type::add_attribute_unlocked(name, attr); Chris@16: } Chris@16: /*! Chris@16: * The method removes an attribute from the source-specific attribute set. Chris@16: * Chris@16: * \pre The attribute was added with the add_attribute call for this instance of the logger. Chris@16: * \post The attribute is no longer registered as a source-specific attribute for this logger. The iterator is invalidated after removal. Chris@16: * Chris@16: * \param it Iterator to the previously added attribute. Chris@16: */ Chris@16: void remove_attribute(attribute_set::iterator it) Chris@16: { Chris@16: typename base_type::remove_attribute_lock lock(base_type::get_threading_model()); Chris@16: base_type::remove_attribute_unlocked(it); Chris@16: } Chris@16: Chris@16: /*! Chris@16: * The method removes all attributes from the logger. All iterators and references to the removed attributes are invalidated. Chris@16: */ Chris@16: void remove_all_attributes() Chris@16: { Chris@16: typename base_type::remove_all_attributes_lock lock(base_type::get_threading_model()); Chris@16: base_type::remove_all_attributes_unlocked(); Chris@16: } Chris@16: Chris@16: /*! Chris@16: * The method retrieves a copy of a set with all attributes from the logger. Chris@16: * Chris@16: * \return The copy of the attribute set. Attributes are shallow-copied. Chris@16: */ Chris@16: attribute_set get_attributes() const Chris@16: { Chris@16: typename base_type::get_attributes_lock lock(base_type::get_threading_model()); Chris@16: return base_type::get_attributes_unlocked(); Chris@16: } Chris@16: Chris@16: /*! Chris@16: * The method installs the whole attribute set into the logger. All iterators and references to elements of Chris@16: * the previous set are invalidated. Iterators to the \a attrs set are not valid to be used with the logger (that is, Chris@16: * the logger owns a copy of \a attrs after completion). Chris@16: * Chris@16: * \param attrs The set of attributes to install into the logger. Attributes are shallow-copied. Chris@16: */ Chris@16: void set_attributes(attribute_set const& attrs) Chris@16: { Chris@16: typename base_type::set_attributes_lock lock(base_type::get_threading_model()); Chris@16: base_type::set_attributes_unlocked(attrs); Chris@16: } Chris@16: Chris@16: /*! Chris@16: * The method opens a new log record in the logging core. Chris@16: * Chris@16: * \return A valid record handle if the logging record is opened successfully, an invalid handle otherwise. Chris@16: */ Chris@16: record open_record() Chris@16: { Chris@16: // Perform a quick check first Chris@16: if (this->core()->get_logging_enabled()) Chris@16: { Chris@16: typename base_type::open_record_lock lock(base_type::get_threading_model()); Chris@16: return base_type::open_record_unlocked(boost::log::aux::empty_arg_list()); Chris@16: } Chris@16: else Chris@16: return record(); Chris@16: } Chris@16: /*! Chris@16: * The method opens a new log record in the logging core. Chris@16: * Chris@16: * \param args A set of additional named arguments. The parameter is ignored. Chris@16: * \return A valid record handle if the logging record is opened successfully, an invalid handle otherwise. Chris@16: */ Chris@16: template< typename ArgsT > Chris@16: record open_record(ArgsT const& args) Chris@16: { Chris@16: // Perform a quick check first Chris@16: if (this->core()->get_logging_enabled()) Chris@16: { Chris@16: typename base_type::open_record_lock lock(base_type::get_threading_model()); Chris@16: return base_type::open_record_unlocked(args); Chris@16: } Chris@16: else Chris@16: return record(); Chris@16: } Chris@16: /*! Chris@16: * The method pushes the constructed message to the logging core Chris@16: * Chris@16: * \param rec The log record with the formatted message Chris@16: */ Chris@16: void push_record(BOOST_RV_REF(record) rec) Chris@16: { Chris@16: typename base_type::push_record_lock lock(base_type::get_threading_model()); Chris@16: base_type::push_record_unlocked(boost::move(rec)); Chris@16: } Chris@16: /*! Chris@16: * Thread-safe implementation of swap Chris@16: */ Chris@16: void swap(basic_composite_logger& that) Chris@16: { Chris@16: boost::log::aux::multiple_unique_lock2< Chris@16: threading_model, Chris@16: threading_model Chris@16: > lock(base_type::get_threading_model(), that.get_threading_model()); Chris@16: base_type::swap_unlocked(that); Chris@16: } Chris@16: Chris@16: protected: Chris@16: /*! Chris@16: * Assignment for the final class. Threadsafe, provides strong exception guarantee. Chris@16: */ Chris@16: FinalT& assign(FinalT const& that) Chris@16: { Chris@16: BOOST_LOG_ASSUME(this != NULL); Chris@16: if (static_cast< FinalT* >(this) != boost::addressof(that)) Chris@16: { Chris@16: // We'll have to explicitly create the copy in order to make sure it's unlocked when we attempt to lock *this Chris@16: FinalT tmp(that); Chris@16: boost::log::aux::exclusive_lock_guard< threading_model > lock(base_type::get_threading_model()); Chris@16: base_type::swap_unlocked(tmp); Chris@16: } Chris@16: return static_cast< FinalT& >(*this); Chris@16: } Chris@16: }; Chris@16: Chris@16: //! An optimized composite logger version with no multithreading support Chris@16: template< typename CharT, typename FinalT, typename FeaturesT > Chris@16: class basic_composite_logger< CharT, FinalT, single_thread_model, FeaturesT > : Chris@16: public boost::log::sources::aux::inherit_features< Chris@16: basic_logger< CharT, FinalT, single_thread_model >, Chris@16: FeaturesT Chris@16: >::type Chris@16: { Chris@16: private: Chris@16: typedef typename boost::log::sources::aux::inherit_features< Chris@16: basic_logger< CharT, FinalT, single_thread_model >, Chris@16: FeaturesT Chris@16: >::type base_type; Chris@16: Chris@16: protected: Chris@16: typedef basic_composite_logger logger_base; Chris@16: BOOST_COPYABLE_AND_MOVABLE_ALT(logger_base) Chris@16: Chris@16: public: Chris@16: typedef typename base_type::threading_model threading_model; Chris@16: Chris@16: #endif // !defined(BOOST_LOG_NO_THREADS) Chris@16: Chris@16: public: Chris@16: basic_composite_logger() {} Chris@16: basic_composite_logger(basic_composite_logger const& that) : Chris@16: base_type(static_cast< base_type const& >(that)) Chris@16: { Chris@16: } Chris@16: basic_composite_logger(BOOST_RV_REF(logger_base) that) : Chris@16: base_type(boost::move(static_cast< base_type& >(that))) Chris@16: { Chris@16: } Chris@16: template< typename ArgsT > Chris@16: explicit basic_composite_logger(ArgsT const& args) : base_type(args) Chris@16: { Chris@16: } Chris@16: Chris@16: std::pair< attribute_set::iterator, bool > add_attribute(attribute_name const& name, attribute const& attr) Chris@16: { Chris@16: return base_type::add_attribute_unlocked(name, attr); Chris@16: } Chris@16: void remove_attribute(attribute_set::iterator it) Chris@16: { Chris@16: base_type::remove_attribute_unlocked(it); Chris@16: } Chris@16: void remove_all_attributes() Chris@16: { Chris@16: base_type::remove_all_attributes_unlocked(); Chris@16: } Chris@16: attribute_set get_attributes() const Chris@16: { Chris@16: return base_type::get_attributes_unlocked(); Chris@16: } Chris@16: void set_attributes(attribute_set const& attrs) Chris@16: { Chris@16: base_type::set_attributes_unlocked(attrs); Chris@16: } Chris@16: record open_record() Chris@16: { Chris@16: // Perform a quick check first Chris@16: if (this->core()->get_logging_enabled()) Chris@16: return base_type::open_record_unlocked(boost::log::aux::empty_arg_list()); Chris@16: else Chris@16: return record(); Chris@16: } Chris@16: template< typename ArgsT > Chris@16: record open_record(ArgsT const& args) Chris@16: { Chris@16: // Perform a quick check first Chris@16: if (this->core()->get_logging_enabled()) Chris@16: return base_type::open_record_unlocked(args); Chris@16: else Chris@16: return record(); Chris@16: } Chris@16: void push_record(BOOST_RV_REF(record) rec) Chris@16: { Chris@16: base_type::push_record_unlocked(boost::move(rec)); Chris@16: } Chris@16: void swap(basic_composite_logger& that) Chris@16: { Chris@16: base_type::swap_unlocked(that); Chris@16: } Chris@16: Chris@16: protected: Chris@16: FinalT& assign(FinalT that) Chris@16: { Chris@16: base_type::swap_unlocked(that); Chris@16: return static_cast< FinalT& >(*this); Chris@16: } Chris@16: }; Chris@16: Chris@16: Chris@16: #ifndef BOOST_LOG_DOXYGEN_PASS Chris@16: Chris@16: #define BOOST_LOG_FORWARD_LOGGER_CONSTRUCTORS_IMPL(class_type, typename_keyword)\ Chris@16: public:\ Chris@16: BOOST_DEFAULTED_FUNCTION(class_type(), {})\ Chris@16: class_type(class_type const& that) : class_type::logger_base(\ Chris@16: static_cast< typename_keyword() class_type::logger_base const& >(that)) {}\ Chris@16: class_type(BOOST_RV_REF(class_type) that) : class_type::logger_base(\ Chris@16: ::boost::move(static_cast< typename_keyword() class_type::logger_base& >(that))) {}\ Chris@16: BOOST_LOG_PARAMETRIZED_CONSTRUCTORS_FORWARD(class_type, class_type::logger_base)\ Chris@16: Chris@16: #endif // BOOST_LOG_DOXYGEN_PASS Chris@16: Chris@16: #define BOOST_LOG_FORWARD_LOGGER_CONSTRUCTORS(class_type)\ Chris@16: BOOST_LOG_FORWARD_LOGGER_CONSTRUCTORS_IMPL(class_type, BOOST_PP_EMPTY) Chris@16: Chris@16: #define BOOST_LOG_FORWARD_LOGGER_CONSTRUCTORS_TEMPLATE(class_type)\ Chris@16: BOOST_LOG_FORWARD_LOGGER_CONSTRUCTORS_IMPL(class_type, BOOST_PP_IDENTITY(typename)) Chris@16: Chris@16: #define BOOST_LOG_FORWARD_LOGGER_ASSIGNMENT(class_type)\ Chris@16: public:\ Chris@16: class_type& operator= (BOOST_COPY_ASSIGN_REF(class_type) that)\ Chris@16: {\ Chris@16: return class_type::logger_base::assign(static_cast< class_type const& >(that));\ Chris@16: }\ Chris@16: class_type& operator= (BOOST_RV_REF(class_type) that)\ Chris@16: {\ Chris@16: BOOST_LOG_EXPR_IF_MT(::boost::log::aux::exclusive_lock_guard< class_type::threading_model > lock(this->get_threading_model());)\ Chris@16: this->swap_unlocked(that);\ Chris@16: return *this;\ Chris@16: } Chris@16: Chris@16: #define BOOST_LOG_FORWARD_LOGGER_ASSIGNMENT_TEMPLATE(class_type)\ Chris@16: public:\ Chris@16: class_type& operator= (BOOST_COPY_ASSIGN_REF(class_type) that)\ Chris@16: {\ Chris@16: return class_type::logger_base::assign(static_cast< class_type const& >(that));\ Chris@16: }\ Chris@16: class_type& operator= (BOOST_RV_REF(class_type) that)\ Chris@16: {\ Chris@16: BOOST_LOG_EXPR_IF_MT(::boost::log::aux::exclusive_lock_guard< typename class_type::threading_model > lock(this->get_threading_model());)\ Chris@16: this->swap_unlocked(that);\ Chris@16: return *this;\ Chris@16: } Chris@16: Chris@16: #define BOOST_LOG_FORWARD_LOGGER_MEMBERS(class_type)\ Chris@16: BOOST_COPYABLE_AND_MOVABLE(class_type)\ Chris@16: BOOST_LOG_FORWARD_LOGGER_CONSTRUCTORS(class_type)\ Chris@16: BOOST_LOG_FORWARD_LOGGER_ASSIGNMENT(class_type) Chris@16: Chris@16: #define BOOST_LOG_FORWARD_LOGGER_MEMBERS_TEMPLATE(class_type)\ Chris@16: BOOST_COPYABLE_AND_MOVABLE(class_type)\ Chris@16: BOOST_LOG_FORWARD_LOGGER_CONSTRUCTORS_TEMPLATE(class_type)\ Chris@16: BOOST_LOG_FORWARD_LOGGER_ASSIGNMENT_TEMPLATE(class_type) Chris@16: Chris@16: } // namespace sources Chris@16: Chris@16: BOOST_LOG_CLOSE_NAMESPACE // namespace log Chris@16: Chris@16: } // namespace boost Chris@16: Chris@16: /*! Chris@16: * \brief The macro declares a logger class that inherits a number of base classes Chris@16: * Chris@16: * \param type_name The name of the logger class to declare Chris@16: * \param char_type The character type of the logger. Either char or wchar_t expected. Chris@16: * \param base_seq A Boost.Preprocessor sequence of type identifiers of the base classes templates Chris@16: * \param threading A threading model class Chris@16: */ Chris@16: #define BOOST_LOG_DECLARE_LOGGER_TYPE(type_name, char_type, base_seq, threading)\ Chris@16: class type_name :\ Chris@16: public ::boost::log::sources::basic_composite_logger<\ Chris@16: char_type,\ Chris@16: type_name,\ Chris@16: threading,\ Chris@16: ::boost::log::sources::features< BOOST_PP_SEQ_ENUM(base_seq) >\ Chris@16: >\ Chris@16: {\ Chris@16: BOOST_LOG_FORWARD_LOGGER_MEMBERS(type_name)\ Chris@16: } Chris@16: Chris@16: Chris@16: Chris@16: #ifdef BOOST_LOG_USE_CHAR Chris@16: Chris@16: /*! Chris@16: * \brief The macro declares a narrow-char logger class that inherits a number of base classes Chris@16: * Chris@16: * Equivalent to BOOST_LOG_DECLARE_LOGGER_TYPE(type_name, char, base_seq, single_thread_model) Chris@16: * Chris@16: * \param type_name The name of the logger class to declare Chris@16: * \param base_seq A Boost.Preprocessor sequence of type identifiers of the base classes templates Chris@16: */ Chris@16: #define BOOST_LOG_DECLARE_LOGGER(type_name, base_seq)\ Chris@16: BOOST_LOG_DECLARE_LOGGER_TYPE(type_name, char, base_seq, ::boost::log::sources::single_thread_model) Chris@16: Chris@16: #if !defined(BOOST_LOG_NO_THREADS) Chris@16: Chris@16: /*! Chris@16: * \brief The macro declares a narrow-char thread-safe logger class that inherits a number of base classes Chris@16: * Chris@16: * Equivalent to BOOST_LOG_DECLARE_LOGGER_TYPE(type_name, char, base_seq, multi_thread_model< shared_mutex >) Chris@16: * Chris@16: * \param type_name The name of the logger class to declare Chris@16: * \param base_seq A Boost.Preprocessor sequence of type identifiers of the base classes templates Chris@16: */ Chris@16: #define BOOST_LOG_DECLARE_LOGGER_MT(type_name, base_seq)\ Chris@16: BOOST_LOG_DECLARE_LOGGER_TYPE(type_name, char, base_seq,\ Chris@16: ::boost::log::sources::multi_thread_model< ::boost::shared_mutex >) Chris@16: Chris@16: #endif // !defined(BOOST_LOG_NO_THREADS) Chris@16: #endif // BOOST_LOG_USE_CHAR Chris@16: Chris@16: #ifdef BOOST_LOG_USE_WCHAR_T Chris@16: Chris@16: /*! Chris@16: * \brief The macro declares a wide-char logger class that inherits a number of base classes Chris@16: * Chris@16: * Equivalent to BOOST_LOG_DECLARE_LOGGER_TYPE(type_name, wchar_t, base_seq, single_thread_model) Chris@16: * Chris@16: * \param type_name The name of the logger class to declare Chris@16: * \param base_seq A Boost.Preprocessor sequence of type identifiers of the base classes templates Chris@16: */ Chris@16: #define BOOST_LOG_DECLARE_WLOGGER(type_name, base_seq)\ Chris@16: BOOST_LOG_DECLARE_LOGGER_TYPE(type_name, wchar_t, base_seq, ::boost::log::sources::single_thread_model) Chris@16: Chris@16: #if !defined(BOOST_LOG_NO_THREADS) Chris@16: Chris@16: /*! Chris@16: * \brief The macro declares a wide-char thread-safe logger class that inherits a number of base classes Chris@16: * Chris@16: * Equivalent to BOOST_LOG_DECLARE_LOGGER_TYPE(type_name, wchar_t, base_seq, multi_thread_model< shared_mutex >) Chris@16: * Chris@16: * \param type_name The name of the logger class to declare Chris@16: * \param base_seq A Boost.Preprocessor sequence of type identifiers of the base classes templates Chris@16: */ Chris@16: #define BOOST_LOG_DECLARE_WLOGGER_MT(type_name, base_seq)\ Chris@16: BOOST_LOG_DECLARE_LOGGER_TYPE(type_name, wchar_t, base_seq,\ Chris@16: ::boost::log::sources::multi_thread_model< ::boost::shared_mutex >) Chris@16: Chris@16: #endif // !defined(BOOST_LOG_NO_THREADS) Chris@16: #endif // BOOST_LOG_USE_WCHAR_T Chris@16: Chris@16: #include Chris@16: Chris@16: #endif // BOOST_LOG_SOURCES_BASIC_LOGGER_HPP_INCLUDED_