stabilize build system: depends, installer, boost/bdb fixes, cross targets groundwork
This commit is contained in:
@@ -0,0 +1,742 @@
|
||||
/*
|
||||
* Copyright Andrey Semashev 2007 - 2015.
|
||||
* 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 basic_logger.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 08.03.2007
|
||||
*
|
||||
* The header contains implementation of a base class for loggers. Convenience macros
|
||||
* for defining custom loggers are also provided.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_SOURCES_BASIC_LOGGER_HPP_INCLUDED_
|
||||
#define BOOST_LOG_SOURCES_BASIC_LOGGER_HPP_INCLUDED_
|
||||
|
||||
#include <exception>
|
||||
#include <utility>
|
||||
#include <ostream>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include <boost/core/addressof.hpp>
|
||||
#include <boost/preprocessor/facilities/empty.hpp>
|
||||
#include <boost/preprocessor/facilities/identity.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
|
||||
#include <boost/preprocessor/seq/enum.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/parameter_tools.hpp>
|
||||
#include <boost/log/attributes/attribute_set.hpp>
|
||||
#include <boost/log/attributes/attribute_name.hpp>
|
||||
#include <boost/log/attributes/attribute.hpp>
|
||||
#include <boost/log/core/core.hpp>
|
||||
#include <boost/log/core/record.hpp>
|
||||
#include <boost/log/sources/features.hpp>
|
||||
#include <boost/log/sources/threading_models.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace sources {
|
||||
|
||||
/*!
|
||||
* \brief Basic logger class
|
||||
*
|
||||
* The \c basic_logger class template serves as a base class for all loggers
|
||||
* provided by the library. It can also be used as a base for user-defined
|
||||
* loggers. The template parameters are:
|
||||
*
|
||||
* \li \c CharT - logging character type
|
||||
* \li \c FinalT - final type of the logger that eventually derives from
|
||||
* the \c basic_logger. There may be other classes in the hierarchy
|
||||
* between the final class and \c basic_logger.
|
||||
* \li \c ThreadingModelT - threading model policy. Must provide methods
|
||||
* of the Boost.Thread locking concept used in \c basic_logger class
|
||||
* and all its derivatives in the hierarchy up to the \c FinalT class.
|
||||
* The \c basic_logger class itself requires methods of the
|
||||
* SharedLockable concept. The threading model policy must also be
|
||||
* default and copy-constructible and support member function \c swap.
|
||||
* There are currently two policies provided: \c single_thread_model
|
||||
* and \c multi_thread_model.
|
||||
*
|
||||
* The logger implements fundamental facilities of loggers, such as storing
|
||||
* source-specific attribute set and formatting log record messages. The basic
|
||||
* logger interacts with the logging core in order to apply filtering and
|
||||
* pass records to sinks.
|
||||
*/
|
||||
template< typename CharT, typename FinalT, typename ThreadingModelT >
|
||||
class basic_logger :
|
||||
public ThreadingModelT
|
||||
{
|
||||
typedef basic_logger this_type;
|
||||
BOOST_COPYABLE_AND_MOVABLE_ALT(this_type)
|
||||
|
||||
public:
|
||||
//! Character type
|
||||
typedef CharT char_type;
|
||||
//! Final logger type
|
||||
typedef FinalT final_type;
|
||||
//! Threading model type
|
||||
typedef ThreadingModelT threading_model;
|
||||
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
//! Lock requirement for the swap_unlocked method
|
||||
typedef boost::log::aux::exclusive_lock_guard< threading_model > swap_lock;
|
||||
//! Lock requirement for the add_attribute_unlocked method
|
||||
typedef boost::log::aux::exclusive_lock_guard< threading_model > add_attribute_lock;
|
||||
//! Lock requirement for the remove_attribute_unlocked method
|
||||
typedef boost::log::aux::exclusive_lock_guard< threading_model > remove_attribute_lock;
|
||||
//! Lock requirement for the remove_all_attributes_unlocked method
|
||||
typedef boost::log::aux::exclusive_lock_guard< threading_model > remove_all_attributes_lock;
|
||||
//! Lock requirement for the get_attributes method
|
||||
typedef boost::log::aux::shared_lock_guard< const threading_model > get_attributes_lock;
|
||||
//! Lock requirement for the open_record_unlocked method
|
||||
typedef boost::log::aux::shared_lock_guard< threading_model > open_record_lock;
|
||||
//! Lock requirement for the set_attributes method
|
||||
typedef boost::log::aux::exclusive_lock_guard< threading_model > set_attributes_lock;
|
||||
#else
|
||||
typedef no_lock< threading_model > swap_lock;
|
||||
typedef no_lock< threading_model > add_attribute_lock;
|
||||
typedef no_lock< threading_model > remove_attribute_lock;
|
||||
typedef no_lock< threading_model > remove_all_attributes_lock;
|
||||
typedef no_lock< const threading_model > get_attributes_lock;
|
||||
typedef no_lock< threading_model > open_record_lock;
|
||||
typedef no_lock< threading_model > set_attributes_lock;
|
||||
#endif
|
||||
|
||||
//! Lock requirement for the push_record_unlocked method
|
||||
typedef no_lock< threading_model > push_record_lock;
|
||||
|
||||
private:
|
||||
//! A pointer to the logging system
|
||||
core_ptr m_pCore;
|
||||
|
||||
//! Logger-specific attribute set
|
||||
attribute_set m_Attributes;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Constructor. Initializes internal data structures of the basic logger class,
|
||||
* acquires reference to the logging core.
|
||||
*/
|
||||
basic_logger() :
|
||||
threading_model(),
|
||||
m_pCore(core::get())
|
||||
{
|
||||
}
|
||||
/*!
|
||||
* Copy constructor. Copies all attributes from the source logger.
|
||||
*
|
||||
* \note Not thread-safe. The source logger must be locked in the final class before copying.
|
||||
*
|
||||
* \param that Source logger
|
||||
*/
|
||||
basic_logger(basic_logger const& that) :
|
||||
threading_model(static_cast< threading_model const& >(that)),
|
||||
m_pCore(core::get()),
|
||||
m_Attributes(that.m_Attributes)
|
||||
{
|
||||
}
|
||||
/*!
|
||||
* Move constructor. Moves all attributes from the source logger.
|
||||
*
|
||||
* \note Not thread-safe. The source logger must be locked in the final class before copying.
|
||||
*
|
||||
* \param that Source logger
|
||||
*/
|
||||
basic_logger(BOOST_RV_REF(basic_logger) that) :
|
||||
threading_model(boost::move(static_cast< threading_model& >(that)))
|
||||
{
|
||||
m_pCore.swap(that.m_pCore);
|
||||
m_Attributes.swap(that.m_Attributes);
|
||||
}
|
||||
/*!
|
||||
* Constructor with named arguments. The constructor ignores all arguments. The result of
|
||||
* construction is equivalent to default construction.
|
||||
*/
|
||||
template< typename ArgsT >
|
||||
explicit basic_logger(ArgsT const&) :
|
||||
threading_model(),
|
||||
m_pCore(core::get())
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
/*!
|
||||
* An accessor to the logging system pointer
|
||||
*/
|
||||
core_ptr const& core() const { return m_pCore; }
|
||||
/*!
|
||||
* An accessor to the logger attributes
|
||||
*/
|
||||
attribute_set& attributes() { return m_Attributes; }
|
||||
/*!
|
||||
* An accessor to the logger attributes
|
||||
*/
|
||||
attribute_set const& attributes() const { return m_Attributes; }
|
||||
/*!
|
||||
* An accessor to the threading model base
|
||||
*/
|
||||
threading_model& get_threading_model() { return *this; }
|
||||
/*!
|
||||
* An accessor to the threading model base
|
||||
*/
|
||||
threading_model const& get_threading_model() const { return *this; }
|
||||
/*!
|
||||
* An accessor to the final logger
|
||||
*/
|
||||
final_type* final_this()
|
||||
{
|
||||
BOOST_LOG_ASSUME(this != NULL);
|
||||
return static_cast< final_type* >(this);
|
||||
}
|
||||
/*!
|
||||
* An accessor to the final logger
|
||||
*/
|
||||
final_type const* final_this() const
|
||||
{
|
||||
BOOST_LOG_ASSUME(this != NULL);
|
||||
return static_cast< final_type const* >(this);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Unlocked \c swap
|
||||
*/
|
||||
void swap_unlocked(basic_logger& that)
|
||||
{
|
||||
get_threading_model().swap(that.get_threading_model());
|
||||
m_Attributes.swap(that.m_Attributes);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Unlocked \c add_attribute
|
||||
*/
|
||||
std::pair< attribute_set::iterator, bool > add_attribute_unlocked(attribute_name const& name, attribute const& attr)
|
||||
{
|
||||
return m_Attributes.insert(name, attr);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Unlocked \c remove_attribute
|
||||
*/
|
||||
void remove_attribute_unlocked(attribute_set::iterator it)
|
||||
{
|
||||
m_Attributes.erase(it);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Unlocked \c remove_all_attributes
|
||||
*/
|
||||
void remove_all_attributes_unlocked()
|
||||
{
|
||||
m_Attributes.clear();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Unlocked \c open_record
|
||||
*/
|
||||
record open_record_unlocked()
|
||||
{
|
||||
return m_pCore->open_record(m_Attributes);
|
||||
}
|
||||
/*!
|
||||
* Unlocked \c open_record
|
||||
*/
|
||||
template< typename ArgsT >
|
||||
record open_record_unlocked(ArgsT const&)
|
||||
{
|
||||
return m_pCore->open_record(m_Attributes);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Unlocked \c push_record
|
||||
*/
|
||||
void push_record_unlocked(BOOST_RV_REF(record) rec)
|
||||
{
|
||||
m_pCore->push_record(boost::move(rec));
|
||||
}
|
||||
|
||||
/*!
|
||||
* Unlocked \c get_attributes
|
||||
*/
|
||||
attribute_set get_attributes_unlocked() const
|
||||
{
|
||||
return m_Attributes;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Unlocked \c set_attributes
|
||||
*/
|
||||
void set_attributes_unlocked(attribute_set const& attrs)
|
||||
{
|
||||
m_Attributes = attrs;
|
||||
}
|
||||
|
||||
//! Assignment is closed (should be implemented through copy and swap in the final class)
|
||||
BOOST_DELETED_FUNCTION(basic_logger& operator= (basic_logger const&))
|
||||
};
|
||||
|
||||
/*!
|
||||
* Free-standing swap for all loggers
|
||||
*/
|
||||
template< typename CharT, typename FinalT, typename ThreadingModelT >
|
||||
inline void swap(
|
||||
basic_logger< CharT, FinalT, ThreadingModelT >& left,
|
||||
basic_logger< CharT, FinalT, ThreadingModelT >& right)
|
||||
{
|
||||
static_cast< FinalT& >(left).swap(static_cast< FinalT& >(right));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief A composite logger that inherits a number of features
|
||||
*
|
||||
* The composite logger is a helper class that simplifies feature composition into the final logger.
|
||||
* The user's logger class is expected to derive from the composite logger class, instantiated with
|
||||
* the character type, the user's logger class, the threading model and the list of the required features.
|
||||
* The former three parameters are passed to the \c basic_logger class template. The feature list
|
||||
* must be an MPL type sequence, where each element is a unary MPL metafunction class, that upon
|
||||
* applying on its argument results in a logging feature class that derives from the argument.
|
||||
* Every logger feature provided by the library can participate in the feature list.
|
||||
*/
|
||||
template< typename CharT, typename FinalT, typename ThreadingModelT, typename FeaturesT >
|
||||
class basic_composite_logger :
|
||||
public boost::log::sources::aux::inherit_features<
|
||||
basic_logger< CharT, FinalT, ThreadingModelT >,
|
||||
FeaturesT
|
||||
>::type
|
||||
{
|
||||
private:
|
||||
//! Base type (the hierarchy of features)
|
||||
typedef typename boost::log::sources::aux::inherit_features<
|
||||
basic_logger< CharT, FinalT, ThreadingModelT >,
|
||||
FeaturesT
|
||||
>::type base_type;
|
||||
|
||||
protected:
|
||||
//! The composite logger type (for use in the user's logger class)
|
||||
typedef basic_composite_logger logger_base;
|
||||
BOOST_COPYABLE_AND_MOVABLE_ALT(logger_base)
|
||||
|
||||
public:
|
||||
//! Threading model being used
|
||||
typedef typename base_type::threading_model threading_model;
|
||||
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Default constructor (default-constructs all features)
|
||||
*/
|
||||
basic_composite_logger() {}
|
||||
/*!
|
||||
* Copy constructor
|
||||
*/
|
||||
basic_composite_logger(basic_composite_logger const& that) :
|
||||
base_type
|
||||
((
|
||||
boost::log::aux::shared_lock_guard< const threading_model >(that.get_threading_model()),
|
||||
static_cast< base_type const& >(that)
|
||||
))
|
||||
{
|
||||
}
|
||||
/*!
|
||||
* Move constructor
|
||||
*/
|
||||
basic_composite_logger(BOOST_RV_REF(logger_base) that) :
|
||||
base_type(boost::move(static_cast< base_type& >(that)))
|
||||
{
|
||||
}
|
||||
/*!
|
||||
* Constructor with named parameters
|
||||
*/
|
||||
template< typename ArgsT >
|
||||
explicit basic_composite_logger(ArgsT const& args) : base_type(args)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method adds an attribute to the source-specific attribute set. The attribute will be implicitly added to
|
||||
* every log record made with the current logger.
|
||||
*
|
||||
* \param name The attribute name.
|
||||
* \param attr The attribute factory.
|
||||
* \return A pair of values. If the second member is \c true, then the attribute is added and the first member points to the
|
||||
* attribute. Otherwise the attribute was not added and the first member points to the attribute that prevents
|
||||
* addition.
|
||||
*/
|
||||
std::pair< attribute_set::iterator, bool > add_attribute(attribute_name const& name, attribute const& attr)
|
||||
{
|
||||
typename base_type::add_attribute_lock lock(base_type::get_threading_model());
|
||||
return base_type::add_attribute_unlocked(name, attr);
|
||||
}
|
||||
/*!
|
||||
* The method removes an attribute from the source-specific attribute set.
|
||||
*
|
||||
* \pre The attribute was added with the add_attribute call for this instance of the logger.
|
||||
* \post The attribute is no longer registered as a source-specific attribute for this logger. The iterator is invalidated after removal.
|
||||
*
|
||||
* \param it Iterator to the previously added attribute.
|
||||
*/
|
||||
void remove_attribute(attribute_set::iterator it)
|
||||
{
|
||||
typename base_type::remove_attribute_lock lock(base_type::get_threading_model());
|
||||
base_type::remove_attribute_unlocked(it);
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method removes all attributes from the logger. All iterators and references to the removed attributes are invalidated.
|
||||
*/
|
||||
void remove_all_attributes()
|
||||
{
|
||||
typename base_type::remove_all_attributes_lock lock(base_type::get_threading_model());
|
||||
base_type::remove_all_attributes_unlocked();
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method retrieves a copy of a set with all attributes from the logger.
|
||||
*
|
||||
* \return The copy of the attribute set. Attributes are shallow-copied.
|
||||
*/
|
||||
attribute_set get_attributes() const
|
||||
{
|
||||
typename base_type::get_attributes_lock lock(base_type::get_threading_model());
|
||||
return base_type::get_attributes_unlocked();
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method installs the whole attribute set into the logger. All iterators and references to elements of
|
||||
* the previous set are invalidated. Iterators to the \a attrs set are not valid to be used with the logger (that is,
|
||||
* the logger owns a copy of \a attrs after completion).
|
||||
*
|
||||
* \param attrs The set of attributes to install into the logger. Attributes are shallow-copied.
|
||||
*/
|
||||
void set_attributes(attribute_set const& attrs)
|
||||
{
|
||||
typename base_type::set_attributes_lock lock(base_type::get_threading_model());
|
||||
base_type::set_attributes_unlocked(attrs);
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method opens a new log record in the logging core.
|
||||
*
|
||||
* \return A valid record handle if the logging record is opened successfully, an invalid handle otherwise.
|
||||
*/
|
||||
record open_record()
|
||||
{
|
||||
// Perform a quick check first
|
||||
if (this->core()->get_logging_enabled())
|
||||
{
|
||||
typename base_type::open_record_lock lock(base_type::get_threading_model());
|
||||
return base_type::open_record_unlocked(boost::log::aux::empty_arg_list());
|
||||
}
|
||||
else
|
||||
return record();
|
||||
}
|
||||
/*!
|
||||
* The method opens a new log record in the logging core.
|
||||
*
|
||||
* \param args A set of additional named arguments. The parameter is ignored.
|
||||
* \return A valid record handle if the logging record is opened successfully, an invalid handle otherwise.
|
||||
*/
|
||||
template< typename ArgsT >
|
||||
record open_record(ArgsT const& args)
|
||||
{
|
||||
// Perform a quick check first
|
||||
if (this->core()->get_logging_enabled())
|
||||
{
|
||||
typename base_type::open_record_lock lock(base_type::get_threading_model());
|
||||
return base_type::open_record_unlocked(args);
|
||||
}
|
||||
else
|
||||
return record();
|
||||
}
|
||||
/*!
|
||||
* The method pushes the constructed message to the logging core
|
||||
*
|
||||
* \param rec The log record with the formatted message
|
||||
*/
|
||||
void push_record(BOOST_RV_REF(record) rec)
|
||||
{
|
||||
typename base_type::push_record_lock lock(base_type::get_threading_model());
|
||||
base_type::push_record_unlocked(boost::move(rec));
|
||||
}
|
||||
/*!
|
||||
* Thread-safe implementation of swap
|
||||
*/
|
||||
void swap(basic_composite_logger& that)
|
||||
{
|
||||
boost::log::aux::multiple_unique_lock2<
|
||||
threading_model,
|
||||
threading_model
|
||||
> lock(base_type::get_threading_model(), that.get_threading_model());
|
||||
base_type::swap_unlocked(that);
|
||||
}
|
||||
|
||||
protected:
|
||||
/*!
|
||||
* Assignment for the final class. Threadsafe, provides strong exception guarantee.
|
||||
*/
|
||||
FinalT& assign(FinalT const& that)
|
||||
{
|
||||
BOOST_LOG_ASSUME(this != NULL);
|
||||
if (static_cast< FinalT* >(this) != boost::addressof(that))
|
||||
{
|
||||
// We'll have to explicitly create the copy in order to make sure it's unlocked when we attempt to lock *this
|
||||
FinalT tmp(that);
|
||||
boost::log::aux::exclusive_lock_guard< threading_model > lock(base_type::get_threading_model());
|
||||
base_type::swap_unlocked(tmp);
|
||||
}
|
||||
return static_cast< FinalT& >(*this);
|
||||
}
|
||||
};
|
||||
|
||||
//! An optimized composite logger version with no multithreading support
|
||||
template< typename CharT, typename FinalT, typename FeaturesT >
|
||||
class basic_composite_logger< CharT, FinalT, single_thread_model, FeaturesT > :
|
||||
public boost::log::sources::aux::inherit_features<
|
||||
basic_logger< CharT, FinalT, single_thread_model >,
|
||||
FeaturesT
|
||||
>::type
|
||||
{
|
||||
private:
|
||||
typedef typename boost::log::sources::aux::inherit_features<
|
||||
basic_logger< CharT, FinalT, single_thread_model >,
|
||||
FeaturesT
|
||||
>::type base_type;
|
||||
|
||||
protected:
|
||||
typedef basic_composite_logger logger_base;
|
||||
BOOST_COPYABLE_AND_MOVABLE_ALT(logger_base)
|
||||
|
||||
public:
|
||||
typedef typename base_type::threading_model threading_model;
|
||||
|
||||
#endif // !defined(BOOST_LOG_NO_THREADS)
|
||||
|
||||
public:
|
||||
basic_composite_logger() {}
|
||||
basic_composite_logger(basic_composite_logger const& that) :
|
||||
base_type(static_cast< base_type const& >(that))
|
||||
{
|
||||
}
|
||||
basic_composite_logger(BOOST_RV_REF(logger_base) that) :
|
||||
base_type(boost::move(static_cast< base_type& >(that)))
|
||||
{
|
||||
}
|
||||
template< typename ArgsT >
|
||||
explicit basic_composite_logger(ArgsT const& args) : base_type(args)
|
||||
{
|
||||
}
|
||||
|
||||
std::pair< attribute_set::iterator, bool > add_attribute(attribute_name const& name, attribute const& attr)
|
||||
{
|
||||
return base_type::add_attribute_unlocked(name, attr);
|
||||
}
|
||||
void remove_attribute(attribute_set::iterator it)
|
||||
{
|
||||
base_type::remove_attribute_unlocked(it);
|
||||
}
|
||||
void remove_all_attributes()
|
||||
{
|
||||
base_type::remove_all_attributes_unlocked();
|
||||
}
|
||||
attribute_set get_attributes() const
|
||||
{
|
||||
return base_type::get_attributes_unlocked();
|
||||
}
|
||||
void set_attributes(attribute_set const& attrs)
|
||||
{
|
||||
base_type::set_attributes_unlocked(attrs);
|
||||
}
|
||||
record open_record()
|
||||
{
|
||||
// Perform a quick check first
|
||||
if (this->core()->get_logging_enabled())
|
||||
return base_type::open_record_unlocked(boost::log::aux::empty_arg_list());
|
||||
else
|
||||
return record();
|
||||
}
|
||||
template< typename ArgsT >
|
||||
record open_record(ArgsT const& args)
|
||||
{
|
||||
// Perform a quick check first
|
||||
if (this->core()->get_logging_enabled())
|
||||
return base_type::open_record_unlocked(args);
|
||||
else
|
||||
return record();
|
||||
}
|
||||
void push_record(BOOST_RV_REF(record) rec)
|
||||
{
|
||||
base_type::push_record_unlocked(boost::move(rec));
|
||||
}
|
||||
void swap(basic_composite_logger& that)
|
||||
{
|
||||
base_type::swap_unlocked(that);
|
||||
}
|
||||
|
||||
protected:
|
||||
FinalT& assign(FinalT that)
|
||||
{
|
||||
base_type::swap_unlocked(that);
|
||||
return static_cast< FinalT& >(*this);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
#define BOOST_LOG_FORWARD_LOGGER_CONSTRUCTORS_IMPL(class_type, typename_keyword)\
|
||||
public:\
|
||||
BOOST_DEFAULTED_FUNCTION(class_type(), {})\
|
||||
class_type(class_type const& that) : class_type::logger_base(\
|
||||
static_cast< typename_keyword() class_type::logger_base const& >(that)) {}\
|
||||
class_type(BOOST_RV_REF(class_type) that) : class_type::logger_base(\
|
||||
::boost::move(static_cast< typename_keyword() class_type::logger_base& >(that))) {}\
|
||||
BOOST_LOG_PARAMETRIZED_CONSTRUCTORS_FORWARD(class_type, class_type::logger_base)\
|
||||
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
#define BOOST_LOG_FORWARD_LOGGER_CONSTRUCTORS(class_type)\
|
||||
BOOST_LOG_FORWARD_LOGGER_CONSTRUCTORS_IMPL(class_type, BOOST_PP_EMPTY)
|
||||
|
||||
#define BOOST_LOG_FORWARD_LOGGER_CONSTRUCTORS_TEMPLATE(class_type)\
|
||||
BOOST_LOG_FORWARD_LOGGER_CONSTRUCTORS_IMPL(class_type, BOOST_PP_IDENTITY(typename))
|
||||
|
||||
#define BOOST_LOG_FORWARD_LOGGER_ASSIGNMENT(class_type)\
|
||||
public:\
|
||||
class_type& operator= (BOOST_COPY_ASSIGN_REF(class_type) that)\
|
||||
{\
|
||||
return class_type::logger_base::assign(static_cast< class_type const& >(that));\
|
||||
}\
|
||||
class_type& operator= (BOOST_RV_REF(class_type) that)\
|
||||
{\
|
||||
BOOST_LOG_EXPR_IF_MT(::boost::log::aux::exclusive_lock_guard< class_type::threading_model > lock(this->get_threading_model());)\
|
||||
this->swap_unlocked(that);\
|
||||
return *this;\
|
||||
}
|
||||
|
||||
#define BOOST_LOG_FORWARD_LOGGER_ASSIGNMENT_TEMPLATE(class_type)\
|
||||
public:\
|
||||
class_type& operator= (BOOST_COPY_ASSIGN_REF(class_type) that)\
|
||||
{\
|
||||
return class_type::logger_base::assign(static_cast< class_type const& >(that));\
|
||||
}\
|
||||
class_type& operator= (BOOST_RV_REF(class_type) that)\
|
||||
{\
|
||||
BOOST_LOG_EXPR_IF_MT(::boost::log::aux::exclusive_lock_guard< typename class_type::threading_model > lock(this->get_threading_model());)\
|
||||
this->swap_unlocked(that);\
|
||||
return *this;\
|
||||
}
|
||||
|
||||
#define BOOST_LOG_FORWARD_LOGGER_MEMBERS(class_type)\
|
||||
BOOST_COPYABLE_AND_MOVABLE(class_type)\
|
||||
BOOST_LOG_FORWARD_LOGGER_CONSTRUCTORS(class_type)\
|
||||
BOOST_LOG_FORWARD_LOGGER_ASSIGNMENT(class_type)
|
||||
|
||||
#define BOOST_LOG_FORWARD_LOGGER_MEMBERS_TEMPLATE(class_type)\
|
||||
BOOST_COPYABLE_AND_MOVABLE(class_type)\
|
||||
BOOST_LOG_FORWARD_LOGGER_CONSTRUCTORS_TEMPLATE(class_type)\
|
||||
BOOST_LOG_FORWARD_LOGGER_ASSIGNMENT_TEMPLATE(class_type)
|
||||
|
||||
} // namespace sources
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
/*!
|
||||
* \brief The macro declares a logger class that inherits a number of base classes
|
||||
*
|
||||
* \param type_name The name of the logger class to declare
|
||||
* \param char_type The character type of the logger. Either char or wchar_t expected.
|
||||
* \param base_seq A Boost.Preprocessor sequence of type identifiers of the base classes templates
|
||||
* \param threading A threading model class
|
||||
*/
|
||||
#define BOOST_LOG_DECLARE_LOGGER_TYPE(type_name, char_type, base_seq, threading)\
|
||||
class type_name :\
|
||||
public ::boost::log::sources::basic_composite_logger<\
|
||||
char_type,\
|
||||
type_name,\
|
||||
threading,\
|
||||
::boost::log::sources::features< BOOST_PP_SEQ_ENUM(base_seq) >\
|
||||
>\
|
||||
{\
|
||||
BOOST_LOG_FORWARD_LOGGER_MEMBERS(type_name)\
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef BOOST_LOG_USE_CHAR
|
||||
|
||||
/*!
|
||||
* \brief The macro declares a narrow-char logger class that inherits a number of base classes
|
||||
*
|
||||
* Equivalent to BOOST_LOG_DECLARE_LOGGER_TYPE(type_name, char, base_seq, single_thread_model)
|
||||
*
|
||||
* \param type_name The name of the logger class to declare
|
||||
* \param base_seq A Boost.Preprocessor sequence of type identifiers of the base classes templates
|
||||
*/
|
||||
#define BOOST_LOG_DECLARE_LOGGER(type_name, base_seq)\
|
||||
BOOST_LOG_DECLARE_LOGGER_TYPE(type_name, char, base_seq, ::boost::log::sources::single_thread_model)
|
||||
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
|
||||
/*!
|
||||
* \brief The macro declares a narrow-char thread-safe logger class that inherits a number of base classes
|
||||
*
|
||||
* Equivalent to <tt>BOOST_LOG_DECLARE_LOGGER_TYPE(type_name, char, base_seq, multi_thread_model< shared_mutex >)</tt>
|
||||
*
|
||||
* \param type_name The name of the logger class to declare
|
||||
* \param base_seq A Boost.Preprocessor sequence of type identifiers of the base classes templates
|
||||
*/
|
||||
#define BOOST_LOG_DECLARE_LOGGER_MT(type_name, base_seq)\
|
||||
BOOST_LOG_DECLARE_LOGGER_TYPE(type_name, char, base_seq,\
|
||||
::boost::log::sources::multi_thread_model< ::boost::shared_mutex >)
|
||||
|
||||
#endif // !defined(BOOST_LOG_NO_THREADS)
|
||||
#endif // BOOST_LOG_USE_CHAR
|
||||
|
||||
#ifdef BOOST_LOG_USE_WCHAR_T
|
||||
|
||||
/*!
|
||||
* \brief The macro declares a wide-char logger class that inherits a number of base classes
|
||||
*
|
||||
* Equivalent to BOOST_LOG_DECLARE_LOGGER_TYPE(type_name, wchar_t, base_seq, single_thread_model)
|
||||
*
|
||||
* \param type_name The name of the logger class to declare
|
||||
* \param base_seq A Boost.Preprocessor sequence of type identifiers of the base classes templates
|
||||
*/
|
||||
#define BOOST_LOG_DECLARE_WLOGGER(type_name, base_seq)\
|
||||
BOOST_LOG_DECLARE_LOGGER_TYPE(type_name, wchar_t, base_seq, ::boost::log::sources::single_thread_model)
|
||||
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
|
||||
/*!
|
||||
* \brief The macro declares a wide-char thread-safe logger class that inherits a number of base classes
|
||||
*
|
||||
* Equivalent to <tt>BOOST_LOG_DECLARE_LOGGER_TYPE(type_name, wchar_t, base_seq, multi_thread_model< shared_mutex >)</tt>
|
||||
*
|
||||
* \param type_name The name of the logger class to declare
|
||||
* \param base_seq A Boost.Preprocessor sequence of type identifiers of the base classes templates
|
||||
*/
|
||||
#define BOOST_LOG_DECLARE_WLOGGER_MT(type_name, base_seq)\
|
||||
BOOST_LOG_DECLARE_LOGGER_TYPE(type_name, wchar_t, base_seq,\
|
||||
::boost::log::sources::multi_thread_model< ::boost::shared_mutex >)
|
||||
|
||||
#endif // !defined(BOOST_LOG_NO_THREADS)
|
||||
#endif // BOOST_LOG_USE_WCHAR_T
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_SOURCES_BASIC_LOGGER_HPP_INCLUDED_
|
||||
@@ -0,0 +1,242 @@
|
||||
/*
|
||||
* Copyright Andrey Semashev 2007 - 2015.
|
||||
* 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 channel_feature.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 28.02.2008
|
||||
*
|
||||
* The header contains implementation of a channel support feature.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_SOURCES_CHANNEL_FEATURE_HPP_INCLUDED_
|
||||
#define BOOST_LOG_SOURCES_CHANNEL_FEATURE_HPP_INCLUDED_
|
||||
|
||||
#include <string>
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/locks.hpp>
|
||||
#include <boost/log/detail/default_attribute_names.hpp>
|
||||
#include <boost/log/keywords/channel.hpp>
|
||||
#include <boost/log/attributes/mutable_constant.hpp>
|
||||
#include <boost/log/utility/strictest_lock.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 {
|
||||
|
||||
/*!
|
||||
* \brief Channel feature implementation
|
||||
*/
|
||||
template< typename BaseT, typename ChannelT >
|
||||
class basic_channel_logger :
|
||||
public BaseT
|
||||
{
|
||||
//! Base type
|
||||
typedef BaseT base_type;
|
||||
typedef basic_channel_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;
|
||||
|
||||
//! Channel type
|
||||
typedef ChannelT channel_type;
|
||||
//! Channel attribute type
|
||||
typedef attributes::mutable_constant< channel_type > channel_attribute;
|
||||
|
||||
//! Lock requirement for the \c open_record_unlocked method
|
||||
typedef typename strictest_lock<
|
||||
typename base_type::open_record_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 open_record_lock;
|
||||
|
||||
//! 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 channel name generator
|
||||
struct make_default_channel_name
|
||||
{
|
||||
typedef channel_type result_type;
|
||||
result_type operator() () const { return result_type(); }
|
||||
};
|
||||
|
||||
private:
|
||||
//! Channel attribute
|
||||
channel_attribute m_ChannelAttr;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Default constructor. The constructed logger has the default-constructed channel name.
|
||||
*/
|
||||
basic_channel_logger() : base_type(), m_ChannelAttr(channel_type())
|
||||
{
|
||||
base_type::add_attribute_unlocked(boost::log::aux::default_attribute_names::channel(), m_ChannelAttr);
|
||||
}
|
||||
/*!
|
||||
* Copy constructor
|
||||
*/
|
||||
basic_channel_logger(basic_channel_logger const& that) :
|
||||
base_type(static_cast< base_type const& >(that)),
|
||||
m_ChannelAttr(that.m_ChannelAttr)
|
||||
{
|
||||
base_type::attributes()[boost::log::aux::default_attribute_names::channel()] = m_ChannelAttr;
|
||||
}
|
||||
/*!
|
||||
* Move constructor
|
||||
*/
|
||||
basic_channel_logger(BOOST_RV_REF(basic_channel_logger) that) :
|
||||
base_type(boost::move(static_cast< base_type& >(that))),
|
||||
m_ChannelAttr(boost::move(that.m_ChannelAttr))
|
||||
{
|
||||
base_type::attributes()[boost::log::aux::default_attribute_names::channel()] = m_ChannelAttr;
|
||||
}
|
||||
/*!
|
||||
* Constructor with arguments. Allows to register a channel name attribute on construction.
|
||||
*
|
||||
* \param args A set of named arguments. The following arguments are supported:
|
||||
* \li \c channel - a string that represents the channel name
|
||||
*/
|
||||
template< typename ArgsT >
|
||||
explicit basic_channel_logger(ArgsT const& args) :
|
||||
base_type(args),
|
||||
m_ChannelAttr(args[keywords::channel || make_default_channel_name()])
|
||||
{
|
||||
base_type::add_attribute_unlocked(boost::log::aux::default_attribute_names::channel(), m_ChannelAttr);
|
||||
}
|
||||
|
||||
/*!
|
||||
* The observer of the channel name
|
||||
*
|
||||
* \return The channel name that was set by the logger
|
||||
*/
|
||||
channel_type channel() const
|
||||
{
|
||||
BOOST_LOG_EXPR_IF_MT(boost::log::aux::shared_lock_guard< const threading_model > lock(this->get_threading_model());)
|
||||
return m_ChannelAttr.get();
|
||||
}
|
||||
|
||||
/*!
|
||||
* The setter of the channel name
|
||||
*
|
||||
* \param ch The channel name to be set for the logger
|
||||
*/
|
||||
void channel(channel_type const& ch)
|
||||
{
|
||||
BOOST_LOG_EXPR_IF_MT(boost::log::aux::exclusive_lock_guard< threading_model > lock(this->get_threading_model());)
|
||||
m_ChannelAttr.set(ch);
|
||||
}
|
||||
|
||||
protected:
|
||||
/*!
|
||||
* Channel attribute accessor
|
||||
*/
|
||||
channel_attribute const& get_channel_attribute() const { return m_ChannelAttr; }
|
||||
|
||||
/*!
|
||||
* Unlocked \c open_record
|
||||
*/
|
||||
template< typename ArgsT >
|
||||
record open_record_unlocked(ArgsT const& args)
|
||||
{
|
||||
return open_record_with_channel_unlocked(args, args[keywords::channel | parameter::void_()]);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Unlocked swap
|
||||
*/
|
||||
void swap_unlocked(basic_channel_logger& that)
|
||||
{
|
||||
base_type::swap_unlocked(static_cast< base_type& >(that));
|
||||
m_ChannelAttr.swap(that.m_ChannelAttr);
|
||||
}
|
||||
|
||||
private:
|
||||
//! The \c open_record implementation for the case when the channel is specified in log statement
|
||||
template< typename ArgsT, typename T >
|
||||
record open_record_with_channel_unlocked(ArgsT const& args, T const& ch)
|
||||
{
|
||||
m_ChannelAttr.set(ch);
|
||||
return base_type::open_record_unlocked(args);
|
||||
}
|
||||
//! The \c open_record implementation for the case when the channel is not specified in log statement
|
||||
template< typename ArgsT >
|
||||
record open_record_with_channel_unlocked(ArgsT const& args, parameter::void_)
|
||||
{
|
||||
return base_type::open_record_unlocked(args);
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Channel support feature
|
||||
*
|
||||
* The logger with this feature automatically registers an attribute with the specified
|
||||
* on construction value, which is a channel name. The channel name can be modified
|
||||
* through the logger life time, either by calling the \c channel method or by specifying
|
||||
* the name in the logging statement.
|
||||
*
|
||||
* The type of the channel name can be customized by providing it as a template parameter
|
||||
* to the feature template. By default, a string will be used.
|
||||
*/
|
||||
template< typename ChannelT = std::string >
|
||||
struct channel
|
||||
{
|
||||
template< typename BaseT >
|
||||
struct apply
|
||||
{
|
||||
typedef basic_channel_logger<
|
||||
BaseT,
|
||||
ChannelT
|
||||
> type;
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace sources
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
//! The macro allows to put a record with a specific channel name into log
|
||||
#define BOOST_LOG_STREAM_CHANNEL(logger, chan)\
|
||||
BOOST_LOG_STREAM_WITH_PARAMS((logger), (::boost::log::keywords::channel = (chan)))
|
||||
|
||||
#ifndef BOOST_LOG_NO_SHORTHAND_NAMES
|
||||
|
||||
//! An equivalent to BOOST_LOG_STREAM_CHANNEL(logger, chan)
|
||||
#define BOOST_LOG_CHANNEL(logger, chan) BOOST_LOG_STREAM_CHANNEL(logger, chan)
|
||||
|
||||
#endif // BOOST_LOG_NO_SHORTHAND_NAMES
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_SOURCES_CHANNEL_FEATURE_HPP_INCLUDED_
|
||||
@@ -0,0 +1,325 @@
|
||||
/*
|
||||
* Copyright Andrey Semashev 2007 - 2015.
|
||||
* 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 channel_logger.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 28.02.2008
|
||||
*
|
||||
* The header contains implementation of a logger with channel support.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_SOURCES_CHANNEL_LOGGER_HPP_INCLUDED_
|
||||
#define BOOST_LOG_SOURCES_CHANNEL_LOGGER_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
#include <boost/log/detail/light_rw_mutex.hpp>
|
||||
#endif // !defined(BOOST_LOG_NO_THREADS)
|
||||
#include <boost/log/sources/features.hpp>
|
||||
#include <boost/log/sources/basic_logger.hpp>
|
||||
#include <boost/log/sources/threading_models.hpp>
|
||||
#include <boost/log/sources/channel_feature.hpp>
|
||||
#include <boost/log/keywords/channel.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace sources {
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
#ifdef BOOST_LOG_USE_CHAR
|
||||
|
||||
//! Narrow-char logger with channel support
|
||||
template< typename ChannelT = std::string >
|
||||
class channel_logger :
|
||||
public basic_composite_logger<
|
||||
char,
|
||||
channel_logger< ChannelT >,
|
||||
single_thread_model,
|
||||
features< channel< ChannelT > >
|
||||
>
|
||||
{
|
||||
typedef typename channel_logger::logger_base base_type;
|
||||
|
||||
public:
|
||||
BOOST_LOG_FORWARD_LOGGER_MEMBERS_TEMPLATE(channel_logger)
|
||||
|
||||
explicit channel_logger(ChannelT const& channel) : base_type(keywords::channel = channel)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
|
||||
//! Narrow-char thread-safe logger with channel support
|
||||
template< typename ChannelT = std::string >
|
||||
class channel_logger_mt :
|
||||
public basic_composite_logger<
|
||||
char,
|
||||
channel_logger_mt< ChannelT >,
|
||||
multi_thread_model< boost::log::aux::light_rw_mutex >,
|
||||
features< channel< ChannelT > >
|
||||
>
|
||||
{
|
||||
typedef typename channel_logger_mt::logger_base base_type;
|
||||
|
||||
public:
|
||||
BOOST_LOG_FORWARD_LOGGER_MEMBERS_TEMPLATE(channel_logger_mt)
|
||||
|
||||
explicit channel_logger_mt(ChannelT const& channel) : base_type(keywords::channel = channel)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
#endif // !defined(BOOST_LOG_NO_THREADS)
|
||||
|
||||
#endif // BOOST_LOG_USE_CHAR
|
||||
|
||||
#ifdef BOOST_LOG_USE_WCHAR_T
|
||||
|
||||
//! Wide-char logger with channel support
|
||||
template< typename ChannelT = std::wstring >
|
||||
class wchannel_logger :
|
||||
public basic_composite_logger<
|
||||
wchar_t,
|
||||
wchannel_logger< ChannelT >,
|
||||
single_thread_model,
|
||||
features< channel< ChannelT > >
|
||||
>
|
||||
{
|
||||
typedef typename wchannel_logger::logger_base base_type;
|
||||
|
||||
public:
|
||||
BOOST_LOG_FORWARD_LOGGER_MEMBERS_TEMPLATE(wchannel_logger)
|
||||
|
||||
explicit wchannel_logger(ChannelT const& channel) : base_type(keywords::channel = channel)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
|
||||
//! Wide-char thread-safe logger with channel support
|
||||
template< typename ChannelT = std::wstring >
|
||||
class wchannel_logger_mt :
|
||||
public basic_composite_logger<
|
||||
wchar_t,
|
||||
wchannel_logger< ChannelT >,
|
||||
multi_thread_model< boost::log::aux::light_rw_mutex >,
|
||||
features< channel< ChannelT > >
|
||||
>
|
||||
{
|
||||
typedef typename wchannel_logger_mt::logger_base base_type;
|
||||
|
||||
public:
|
||||
BOOST_LOG_FORWARD_LOGGER_MEMBERS_TEMPLATE(wchannel_logger_mt)
|
||||
|
||||
explicit wchannel_logger_mt(ChannelT const& channel) : base_type(keywords::channel = channel)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
#endif // !defined(BOOST_LOG_NO_THREADS)
|
||||
|
||||
#endif // BOOST_LOG_USE_WCHAR_T
|
||||
|
||||
#else // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
/*!
|
||||
* \brief Narrow-char logger. Functionally equivalent to \c basic_channel_logger.
|
||||
*
|
||||
* See \c channel class template for a more detailed description
|
||||
*/
|
||||
template< typename ChannelT = std::string >
|
||||
class channel_logger :
|
||||
public basic_composite_logger<
|
||||
char,
|
||||
channel_logger< ChannelT >,
|
||||
single_thread_model,
|
||||
features< channel< ChannelT > >
|
||||
>
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* Default constructor
|
||||
*/
|
||||
channel_logger();
|
||||
/*!
|
||||
* Copy constructor
|
||||
*/
|
||||
channel_logger(channel_logger const& that);
|
||||
/*!
|
||||
* Constructor with named arguments
|
||||
*/
|
||||
template< typename... ArgsT >
|
||||
explicit channel_logger(ArgsT... const& args);
|
||||
/*!
|
||||
* The constructor creates the logger with the specified channel name
|
||||
*
|
||||
* \param channel The channel name
|
||||
*/
|
||||
explicit channel_logger(ChannelT const& channel);
|
||||
/*!
|
||||
* Assignment operator
|
||||
*/
|
||||
channel_logger& operator= (channel_logger const& that)
|
||||
/*!
|
||||
* Swaps two loggers
|
||||
*/
|
||||
void swap(channel_logger& that);
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Narrow-char thread-safe logger. Functionally equivalent to \c basic_channel_logger.
|
||||
*
|
||||
* See \c channel class template for a more detailed description
|
||||
*/
|
||||
template< typename ChannelT = std::string >
|
||||
class channel_logger_mt :
|
||||
public basic_composite_logger<
|
||||
char,
|
||||
channel_logger_mt< ChannelT >,
|
||||
multi_thread_model< implementation_defined >,
|
||||
features< channel< ChannelT > >
|
||||
>
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* Default constructor
|
||||
*/
|
||||
channel_logger_mt();
|
||||
/*!
|
||||
* Copy constructor
|
||||
*/
|
||||
channel_logger_mt(channel_logger_mt const& that);
|
||||
/*!
|
||||
* Constructor with named arguments
|
||||
*/
|
||||
template< typename... ArgsT >
|
||||
explicit channel_logger_mt(ArgsT... const& args);
|
||||
/*!
|
||||
* The constructor creates the logger with the specified channel name
|
||||
*
|
||||
* \param channel The channel name
|
||||
*/
|
||||
explicit channel_logger_mt(ChannelT const& channel);
|
||||
/*!
|
||||
* Assignment operator
|
||||
*/
|
||||
channel_logger_mt& operator= (channel_logger_mt const& that)
|
||||
/*!
|
||||
* Swaps two loggers
|
||||
*/
|
||||
void swap(channel_logger_mt& that);
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Wide-char logger. Functionally equivalent to \c basic_channel_logger.
|
||||
*
|
||||
* See \c channel class template for a more detailed description
|
||||
*/
|
||||
template< typename ChannelT = std::wstring >
|
||||
class wchannel_logger :
|
||||
public basic_composite_logger<
|
||||
wchar_t,
|
||||
wchannel_logger< ChannelT >,
|
||||
single_thread_model,
|
||||
features< channel< ChannelT > >
|
||||
>
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* Default constructor
|
||||
*/
|
||||
wchannel_logger();
|
||||
/*!
|
||||
* Copy constructor
|
||||
*/
|
||||
wchannel_logger(wchannel_logger const& that);
|
||||
/*!
|
||||
* Constructor with named arguments
|
||||
*/
|
||||
template< typename... ArgsT >
|
||||
explicit wchannel_logger(ArgsT... const& args);
|
||||
/*!
|
||||
* The constructor creates the logger with the specified channel name
|
||||
*
|
||||
* \param channel The channel name
|
||||
*/
|
||||
explicit wchannel_logger(ChannelT const& channel);
|
||||
/*!
|
||||
* Assignment operator
|
||||
*/
|
||||
wchannel_logger& operator= (wchannel_logger const& that)
|
||||
/*!
|
||||
* Swaps two loggers
|
||||
*/
|
||||
void swap(wchannel_logger& that);
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Wide-char thread-safe logger. Functionally equivalent to \c basic_channel_logger.
|
||||
*
|
||||
* See \c channel class template for a more detailed description
|
||||
*/
|
||||
template< typename ChannelT = std::wstring >
|
||||
class wchannel_logger_mt :
|
||||
public basic_composite_logger<
|
||||
wchar_t,
|
||||
wchannel_logger< ChannelT >,
|
||||
multi_thread_model< implementation_defined >,
|
||||
features< channel< ChannelT > >
|
||||
>
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* Default constructor
|
||||
*/
|
||||
wchannel_logger_mt();
|
||||
/*!
|
||||
* Copy constructor
|
||||
*/
|
||||
wchannel_logger_mt(wchannel_logger_mt const& that);
|
||||
/*!
|
||||
* Constructor with named arguments
|
||||
*/
|
||||
template< typename... ArgsT >
|
||||
explicit wchannel_logger_mt(ArgsT... const& args);
|
||||
/*!
|
||||
* The constructor creates the logger with the specified channel name
|
||||
*
|
||||
* \param channel The channel name
|
||||
*/
|
||||
explicit wchannel_logger_mt(ChannelT const& channel);
|
||||
/*!
|
||||
* Assignment operator
|
||||
*/
|
||||
wchannel_logger_mt& operator= (wchannel_logger_mt const& that)
|
||||
/*!
|
||||
* Swaps two loggers
|
||||
*/
|
||||
void swap(wchannel_logger_mt& that);
|
||||
};
|
||||
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
} // namespace sources
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_SOURCES_CHANNEL_LOGGER_HPP_INCLUDED_
|
||||
@@ -0,0 +1,253 @@
|
||||
/*
|
||||
* Copyright Andrey Semashev 2007 - 2015.
|
||||
* 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 exception_handler_feature.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 17.07.2009
|
||||
*
|
||||
* The header contains implementation of an exception handler support feature.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_SOURCES_EXCEPTION_HANDLER_FEATURE_HPP_INCLUDED_
|
||||
#define BOOST_LOG_SOURCES_EXCEPTION_HANDLER_FEATURE_HPP_INCLUDED_
|
||||
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/light_function.hpp>
|
||||
#include <boost/log/detail/locks.hpp>
|
||||
#include <boost/log/core/record.hpp>
|
||||
#include <boost/log/sources/threading_models.hpp>
|
||||
#include <boost/log/utility/strictest_lock.hpp>
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
#include <boost/thread/exceptions.hpp>
|
||||
#endif
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace sources {
|
||||
|
||||
/*!
|
||||
* \brief Exception handler feature implementation
|
||||
*/
|
||||
template< typename BaseT >
|
||||
class basic_exception_handler_logger :
|
||||
public BaseT
|
||||
{
|
||||
//! Base type
|
||||
typedef BaseT base_type;
|
||||
typedef basic_exception_handler_logger this_type;
|
||||
BOOST_COPYABLE_AND_MOVABLE_ALT(this_type)
|
||||
|
||||
public:
|
||||
//! Threading model being used
|
||||
typedef typename base_type::threading_model threading_model;
|
||||
//! Final logger type
|
||||
typedef typename base_type::final_type final_type;
|
||||
//! Exception handler function type
|
||||
typedef boost::log::aux::light_function< void () > exception_handler_type;
|
||||
|
||||
#if defined(BOOST_LOG_DOXYGEN_PASS)
|
||||
//! Lock requirement for the open_record_unlocked method
|
||||
typedef typename strictest_lock<
|
||||
typename base_type::open_record_lock,
|
||||
no_lock< threading_model >
|
||||
>::type open_record_lock;
|
||||
//! Lock requirement for the push_record_unlocked method
|
||||
typedef typename strictest_lock<
|
||||
typename base_type::push_record_lock,
|
||||
no_lock< threading_model >
|
||||
>::type push_record_lock;
|
||||
#endif // defined(BOOST_LOG_DOXYGEN_PASS)
|
||||
|
||||
//! Lock requirement for the 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:
|
||||
//! Exception handler
|
||||
exception_handler_type m_ExceptionHandler;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Default constructor. The constructed logger does not have an exception handler.
|
||||
*/
|
||||
basic_exception_handler_logger() : base_type()
|
||||
{
|
||||
}
|
||||
/*!
|
||||
* Copy constructor
|
||||
*/
|
||||
basic_exception_handler_logger(basic_exception_handler_logger const& that) :
|
||||
base_type(static_cast< base_type const& >(that)),
|
||||
m_ExceptionHandler(that.m_ExceptionHandler)
|
||||
{
|
||||
}
|
||||
/*!
|
||||
* Move constructor
|
||||
*/
|
||||
basic_exception_handler_logger(BOOST_RV_REF(basic_exception_handler_logger) that) :
|
||||
base_type(boost::move(static_cast< base_type& >(that))),
|
||||
m_ExceptionHandler(boost::move(that.m_ExceptionHandler))
|
||||
{
|
||||
}
|
||||
/*!
|
||||
* Constructor with arguments. Passes arguments to other features.
|
||||
*/
|
||||
template< typename ArgsT >
|
||||
explicit basic_exception_handler_logger(ArgsT const& args) :
|
||||
base_type(args)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method sets exception handler function. The function will be called with no arguments
|
||||
* in case if an exception occurs during either \c open_record or \c push_record method
|
||||
* execution. Since exception handler is called from a \c catch statement, the exception
|
||||
* can be rethrown in order to determine its type.
|
||||
*
|
||||
* By default no handler is installed, thus any exception is propagated as usual.
|
||||
*
|
||||
* \sa <tt>utility/exception_handler.hpp</tt>
|
||||
* \param handler Exception handling function
|
||||
*
|
||||
* \note The exception handler can be invoked in several threads concurrently.
|
||||
*
|
||||
* \note Thread interruptions are not affected by exception handlers.
|
||||
*/
|
||||
template< typename HandlerT >
|
||||
void set_exception_handler(HandlerT const& handler)
|
||||
{
|
||||
#ifndef BOOST_LOG_NO_THREADS
|
||||
boost::log::aux::exclusive_lock_guard< threading_model > lock(this->get_threading_model());
|
||||
#endif
|
||||
m_ExceptionHandler = handler;
|
||||
}
|
||||
|
||||
protected:
|
||||
/*!
|
||||
* Unlocked \c open_record
|
||||
*/
|
||||
template< typename ArgsT >
|
||||
record open_record_unlocked(ArgsT const& args)
|
||||
{
|
||||
try
|
||||
{
|
||||
return base_type::open_record_unlocked(args);
|
||||
}
|
||||
#ifndef BOOST_LOG_NO_THREADS
|
||||
catch (thread_interrupted&)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
#endif
|
||||
catch (...)
|
||||
{
|
||||
handle_exception();
|
||||
return record();
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Unlocked \c push_record
|
||||
*/
|
||||
void push_record_unlocked(BOOST_RV_REF(record) rec)
|
||||
{
|
||||
try
|
||||
{
|
||||
base_type::push_record_unlocked(boost::move(rec));
|
||||
}
|
||||
#ifndef BOOST_LOG_NO_THREADS
|
||||
catch (thread_interrupted&)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
#endif
|
||||
catch (...)
|
||||
{
|
||||
handle_exception();
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Unlocked swap
|
||||
*/
|
||||
void swap_unlocked(basic_exception_handler_logger& that)
|
||||
{
|
||||
base_type::swap_unlocked(static_cast< base_type& >(that));
|
||||
m_ExceptionHandler.swap(that.m_ExceptionHandler);
|
||||
}
|
||||
|
||||
private:
|
||||
#if !defined(BOOST_LOG_DOXYGEN_PASS)
|
||||
//! The function handles the intercepted exception
|
||||
void handle_exception()
|
||||
{
|
||||
#ifndef BOOST_LOG_NO_THREADS
|
||||
// Here's the trick with the lock type. Since the lock
|
||||
// is only needed when an exception is caught, we indicate
|
||||
// no locking requirements in the push_record_lock type.
|
||||
// However, if other features don't require locking either,
|
||||
// we shall acquire a read lock here, when an exception is caught.
|
||||
// If other features do require locking, the thread model is
|
||||
// already locked by now, and we don't do locking at all.
|
||||
typedef typename mpl::if_<
|
||||
is_same< no_lock< threading_model >, typename final_type::push_record_lock >,
|
||||
boost::log::aux::shared_lock_guard< threading_model >,
|
||||
no_lock< threading_model >
|
||||
>::type lock_type;
|
||||
lock_type lock(base_type::get_threading_model());
|
||||
#endif // !defined(BOOST_LOG_NO_THREADS)
|
||||
|
||||
if (m_ExceptionHandler.empty())
|
||||
throw;
|
||||
m_ExceptionHandler();
|
||||
}
|
||||
#endif // !defined(BOOST_LOG_DOXYGEN_PASS)
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Exception handler support feature
|
||||
*
|
||||
* The logger with this feature will provide an additional method to
|
||||
* install an exception handler functional object. This functional
|
||||
* object will be called if during either opening or pushing a record
|
||||
* an exception is thrown from the logging core.
|
||||
*/
|
||||
struct exception_handler
|
||||
{
|
||||
template< typename BaseT >
|
||||
struct apply
|
||||
{
|
||||
typedef basic_exception_handler_logger< BaseT > type;
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace sources
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_SOURCES_EXCEPTION_HANDLER_FEATURE_HPP_INCLUDED_
|
||||
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright Andrey Semashev 2007 - 2015.
|
||||
* 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 sources/features.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 17.07.2009
|
||||
*
|
||||
* The header contains definition of a features list class template.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_SOURCES_FEATURES_HPP_INCLUDED_
|
||||
#define BOOST_LOG_SOURCES_FEATURES_HPP_INCLUDED_
|
||||
|
||||
#include <boost/mpl/lambda.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_shifted_params.hpp>
|
||||
#include <boost/preprocessor/facilities/intercept.hpp>
|
||||
|
||||
//! The macro defines the maximum number of features that can be specified for a logger
|
||||
#ifndef BOOST_LOG_FEATURES_LIMIT
|
||||
#define BOOST_LOG_FEATURES_LIMIT 10
|
||||
#endif // BOOST_LOG_FEATURES_LIMIT
|
||||
|
||||
#endif
|
||||
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace sources {
|
||||
|
||||
#if defined(BOOST_LOG_DOXYGEN_PASS) || !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
/*!
|
||||
* \brief A type sequence of logger features
|
||||
*
|
||||
* This class template can be used to specify logger features in a \c basic_composite_logger instantiation.
|
||||
*/
|
||||
template< typename... FeaturesT >
|
||||
struct features
|
||||
{
|
||||
};
|
||||
|
||||
namespace aux {
|
||||
|
||||
//! The metafunction produces the inherited features hierarchy with \c RootT as the ultimate base type
|
||||
template< typename RootT, typename FeaturesT >
|
||||
struct inherit_features;
|
||||
|
||||
template< typename RootT, typename FeatureT0, typename... FeaturesT >
|
||||
struct inherit_features< RootT, features< FeatureT0, FeaturesT... > >
|
||||
{
|
||||
typedef typename mpl::lambda<
|
||||
FeatureT0
|
||||
>::type::BOOST_NESTED_TEMPLATE apply<
|
||||
typename inherit_features<
|
||||
RootT,
|
||||
features< FeaturesT... >
|
||||
>::type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template< typename RootT, typename FeatureT0 >
|
||||
struct inherit_features< RootT, features< FeatureT0 > >
|
||||
{
|
||||
typedef typename mpl::lambda<
|
||||
FeatureT0
|
||||
>::type::BOOST_NESTED_TEMPLATE apply<
|
||||
RootT
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template< typename RootT >
|
||||
struct inherit_features< RootT, features< > >
|
||||
{
|
||||
typedef RootT type;
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
#else
|
||||
|
||||
//! A type sequence of logger features
|
||||
template< BOOST_PP_ENUM_BINARY_PARAMS(BOOST_LOG_FEATURES_LIMIT, typename FeatureT, = void BOOST_PP_INTERCEPT) >
|
||||
struct features
|
||||
{
|
||||
};
|
||||
|
||||
namespace aux {
|
||||
|
||||
template< typename RootT, typename FeaturesT >
|
||||
struct inherit_features;
|
||||
|
||||
template< typename RootT, BOOST_PP_ENUM_PARAMS(BOOST_LOG_FEATURES_LIMIT, typename FeatureT) >
|
||||
struct inherit_features< RootT, features< BOOST_PP_ENUM_PARAMS(BOOST_LOG_FEATURES_LIMIT, FeatureT) > >
|
||||
{
|
||||
typedef typename mpl::lambda<
|
||||
FeatureT0
|
||||
>::type::BOOST_NESTED_TEMPLATE apply<
|
||||
typename inherit_features<
|
||||
RootT,
|
||||
features< BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_LOG_FEATURES_LIMIT, FeatureT) >
|
||||
>::type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template< typename RootT, typename FeatureT0 >
|
||||
struct inherit_features< RootT, features< FeatureT0, BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_LOG_FEATURES_LIMIT, void BOOST_PP_INTERCEPT) > >
|
||||
{
|
||||
typedef typename mpl::lambda<
|
||||
FeatureT0
|
||||
>::type::BOOST_NESTED_TEMPLATE apply<
|
||||
RootT
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template< typename RootT >
|
||||
struct inherit_features< RootT, features< BOOST_PP_ENUM_PARAMS(BOOST_LOG_FEATURES_LIMIT, void BOOST_PP_INTERCEPT) > >
|
||||
{
|
||||
typedef RootT type;
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace sources
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_SOURCES_FEATURES_HPP_INCLUDED_
|
||||
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
* Copyright Andrey Semashev 2007 - 2015.
|
||||
* 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 global_logger_storage.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 21.04.2008
|
||||
*
|
||||
* The header contains implementation of facilities to declare global loggers.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_SOURCES_GLOBAL_LOGGER_STORAGE_HPP_INCLUDED_
|
||||
#define BOOST_LOG_SOURCES_GLOBAL_LOGGER_STORAGE_HPP_INCLUDED_
|
||||
|
||||
#include <stdexcept>
|
||||
#include <boost/type_index.hpp>
|
||||
#include <boost/smart_ptr/shared_ptr.hpp>
|
||||
#include <boost/smart_ptr/make_shared_object.hpp>
|
||||
#include <boost/preprocessor/seq/enum.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/singleton.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 base class for logger holders
|
||||
struct logger_holder_base
|
||||
{
|
||||
//! The source file name where the logger was registered
|
||||
const char* const m_RegistrationFile;
|
||||
//! The line number where the logger was registered
|
||||
const unsigned int m_RegistrationLine;
|
||||
//! Stored logger type
|
||||
const typeindex::type_index m_LoggerType;
|
||||
|
||||
logger_holder_base(const char* file, unsigned int line, typeindex::type_index logger_type) BOOST_NOEXCEPT :
|
||||
m_RegistrationFile(file),
|
||||
m_RegistrationLine(line),
|
||||
m_LoggerType(logger_type)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//! The actual logger holder class
|
||||
template< typename LoggerT >
|
||||
struct logger_holder :
|
||||
public logger_holder_base
|
||||
{
|
||||
//! The logger instance
|
||||
LoggerT m_Logger;
|
||||
|
||||
logger_holder(const char* file, unsigned int line, LoggerT const& logger) :
|
||||
logger_holder_base(file, line, typeindex::type_id< LoggerT >()),
|
||||
m_Logger(logger)
|
||||
{
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
logger_holder(const char* file, unsigned int line, LoggerT&& logger) :
|
||||
logger_holder_base(file, line, typeindex::type_id< LoggerT >()),
|
||||
m_Logger(static_cast< LoggerT&& >(logger))
|
||||
{
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
//! The class implements a global repository of tagged loggers
|
||||
struct global_storage
|
||||
{
|
||||
typedef shared_ptr< logger_holder_base >(*initializer_t)();
|
||||
|
||||
//! Finds or creates the logger and returns its holder
|
||||
BOOST_LOG_API static shared_ptr< logger_holder_base > get_or_init(typeindex::type_index key, initializer_t initializer);
|
||||
|
||||
// Non-constructible, non-copyable, non-assignable
|
||||
BOOST_DELETED_FUNCTION(global_storage())
|
||||
BOOST_DELETED_FUNCTION(global_storage(global_storage const&))
|
||||
BOOST_DELETED_FUNCTION(global_storage& operator= (global_storage const&))
|
||||
};
|
||||
|
||||
//! Throws the \c odr_violation exception
|
||||
BOOST_LOG_API BOOST_LOG_NORETURN void throw_odr_violation(
|
||||
typeindex::type_index tag_type,
|
||||
typeindex::type_index logger_type,
|
||||
logger_holder_base const& registered);
|
||||
|
||||
//! The class implements a logger singleton
|
||||
template< typename TagT >
|
||||
struct logger_singleton :
|
||||
public boost::log::aux::lazy_singleton<
|
||||
logger_singleton< TagT >,
|
||||
shared_ptr< logger_holder< typename TagT::logger_type > >
|
||||
>
|
||||
{
|
||||
//! Base type
|
||||
typedef boost::log::aux::lazy_singleton<
|
||||
logger_singleton< TagT >,
|
||||
shared_ptr< logger_holder< typename TagT::logger_type > >
|
||||
> base_type;
|
||||
//! Logger type
|
||||
typedef typename TagT::logger_type logger_type;
|
||||
|
||||
//! Returns the logger instance
|
||||
static logger_type& get()
|
||||
{
|
||||
return base_type::get()->m_Logger;
|
||||
}
|
||||
|
||||
//! Initializes the logger instance (called only once)
|
||||
static void init_instance()
|
||||
{
|
||||
shared_ptr< logger_holder< logger_type > >& instance = base_type::get_instance();
|
||||
const typeindex::type_index tag_type_index = typeindex::type_id< TagT >();
|
||||
shared_ptr< logger_holder_base > holder = global_storage::get_or_init(tag_type_index, &logger_singleton::construct_logger);
|
||||
const typeindex::type_index logger_type_index = typeindex::type_id< logger_type >();
|
||||
if (holder->m_LoggerType == logger_type_index)
|
||||
{
|
||||
// Note: dynamic_cast may fail here if logger_type is not visible (for example, with Clang on Linux, if the original logger
|
||||
// instance was initialized in a different DSO than where it's being queried). logger_holder visibility doesn't
|
||||
// have effect since it is inhibited by the template parameter visibility.
|
||||
instance = boost::static_pointer_cast< logger_holder< logger_type > >(holder);
|
||||
}
|
||||
else
|
||||
{
|
||||
// In pure C++ this should never happen, since there cannot be two
|
||||
// different tag types that have equal type_infos. In real life it can
|
||||
// happen if the same-named tag is defined differently in two or more
|
||||
// dlls. This check is intended to detect such ODR violations. However, there
|
||||
// is no protection against different definitions of the logger type itself.
|
||||
boost::log::sources::aux::throw_odr_violation(tag_type_index, logger_type_index, *holder);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
//! Constructs a logger holder
|
||||
static shared_ptr< logger_holder_base > construct_logger()
|
||||
{
|
||||
return boost::make_shared< logger_holder< logger_type > >(
|
||||
TagT::registration_file(),
|
||||
static_cast< unsigned int >(TagT::registration_line),
|
||||
TagT::construct_logger());
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
//! The macro forward-declares a global logger with a custom initialization
|
||||
#define BOOST_LOG_GLOBAL_LOGGER(tag_name, logger)\
|
||||
struct tag_name\
|
||||
{\
|
||||
typedef logger logger_type;\
|
||||
enum registration_line_t { registration_line = __LINE__ };\
|
||||
static const char* registration_file() { return __FILE__; }\
|
||||
static logger_type construct_logger();\
|
||||
static inline logger_type& get()\
|
||||
{\
|
||||
return ::boost::log::sources::aux::logger_singleton< tag_name >::get();\
|
||||
}\
|
||||
};
|
||||
|
||||
//! The macro defines a global logger initialization routine
|
||||
#define BOOST_LOG_GLOBAL_LOGGER_INIT(tag_name, logger)\
|
||||
tag_name::logger_type tag_name::construct_logger()
|
||||
|
||||
//! The macro defines a global logger initializer that will default-construct the logger
|
||||
#define BOOST_LOG_GLOBAL_LOGGER_DEFAULT(tag_name, logger)\
|
||||
BOOST_LOG_GLOBAL_LOGGER_INIT(tag_name, logger)\
|
||||
{\
|
||||
return logger_type();\
|
||||
}
|
||||
|
||||
//! The macro defines a global logger initializer that will construct the logger with the specified constructor arguments
|
||||
#define BOOST_LOG_GLOBAL_LOGGER_CTOR_ARGS(tag_name, logger, args)\
|
||||
BOOST_LOG_GLOBAL_LOGGER_INIT(tag_name, logger)\
|
||||
{\
|
||||
return logger_type(BOOST_PP_SEQ_ENUM(args));\
|
||||
}
|
||||
|
||||
//! The macro declares a global logger with a custom initialization
|
||||
#define BOOST_LOG_INLINE_GLOBAL_LOGGER_INIT(tag_name, logger)\
|
||||
BOOST_LOG_GLOBAL_LOGGER(tag_name, logger)\
|
||||
inline BOOST_LOG_GLOBAL_LOGGER_INIT(tag_name, logger)
|
||||
|
||||
//! The macro declares a global logger that will be default-constructed
|
||||
#define BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT(tag_name, logger)\
|
||||
BOOST_LOG_INLINE_GLOBAL_LOGGER_INIT(tag_name, logger)\
|
||||
{\
|
||||
return logger_type();\
|
||||
}
|
||||
|
||||
//! The macro declares a global logger that will be constructed with the specified arguments
|
||||
#define BOOST_LOG_INLINE_GLOBAL_LOGGER_CTOR_ARGS(tag_name, logger, args)\
|
||||
BOOST_LOG_INLINE_GLOBAL_LOGGER_INIT(tag_name, logger)\
|
||||
{\
|
||||
return logger_type(BOOST_PP_SEQ_ENUM(args));\
|
||||
}
|
||||
|
||||
} // namespace sources
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_SOURCES_GLOBAL_LOGGER_STORAGE_HPP_INCLUDED_
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright Andrey Semashev 2007 - 2015.
|
||||
* 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 logger.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 08.03.2007
|
||||
*
|
||||
* The header contains implementation of a simplistic logger with no features.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_SOURCES_LOGGER_HPP_INCLUDED_
|
||||
#define BOOST_LOG_SOURCES_LOGGER_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/sources/basic_logger.hpp>
|
||||
#include <boost/log/sources/features.hpp>
|
||||
#include <boost/log/sources/threading_models.hpp>
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
#include <boost/log/detail/light_rw_mutex.hpp>
|
||||
#endif // !defined(BOOST_LOG_NO_THREADS)
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace sources {
|
||||
|
||||
#ifdef BOOST_LOG_USE_CHAR
|
||||
|
||||
/*!
|
||||
* \brief Narrow-char logger. Functionally equivalent to \c basic_logger.
|
||||
*
|
||||
* See \c basic_logger class template for a more detailed description.
|
||||
*/
|
||||
class logger :
|
||||
public basic_composite_logger< char, logger, single_thread_model, features< > >
|
||||
{
|
||||
BOOST_LOG_FORWARD_LOGGER_MEMBERS(logger)
|
||||
};
|
||||
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
|
||||
/*!
|
||||
* \brief Narrow-char thread-safe logger. Functionally equivalent to \c basic_logger.
|
||||
*
|
||||
* See \c basic_logger class template for a more detailed description.
|
||||
*/
|
||||
class logger_mt :
|
||||
public basic_composite_logger< char, logger_mt, multi_thread_model< boost::log::aux::light_rw_mutex >, features< > >
|
||||
{
|
||||
BOOST_LOG_FORWARD_LOGGER_MEMBERS(logger_mt)
|
||||
};
|
||||
|
||||
#endif // !defined(BOOST_LOG_NO_THREADS)
|
||||
#endif // BOOST_LOG_USE_CHAR
|
||||
|
||||
#ifdef BOOST_LOG_USE_WCHAR_T
|
||||
|
||||
/*!
|
||||
* \brief Wide-char logger. Functionally equivalent to \c basic_logger.
|
||||
*
|
||||
* See \c basic_logger class template for a more detailed description.
|
||||
*/
|
||||
class wlogger :
|
||||
public basic_composite_logger< wchar_t, wlogger, single_thread_model, features< > >
|
||||
{
|
||||
BOOST_LOG_FORWARD_LOGGER_MEMBERS(wlogger)
|
||||
};
|
||||
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
|
||||
/*!
|
||||
* \brief Wide-char thread-safe logger. Functionally equivalent to \c basic_logger.
|
||||
*
|
||||
* See \c basic_logger class template for a more detailed description.
|
||||
*/
|
||||
class wlogger_mt :
|
||||
public basic_composite_logger< wchar_t, wlogger_mt, multi_thread_model< boost::log::aux::light_rw_mutex >, features< > >
|
||||
{
|
||||
BOOST_LOG_FORWARD_LOGGER_MEMBERS(wlogger_mt)
|
||||
};
|
||||
|
||||
#endif // !defined(BOOST_LOG_NO_THREADS)
|
||||
#endif // BOOST_LOG_USE_WCHAR_T
|
||||
|
||||
} // namespace sources
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_SOURCES_LOGGER_HPP_INCLUDED_
|
||||
@@ -0,0 +1,583 @@
|
||||
/*
|
||||
* Copyright Andrey Semashev 2007 - 2015.
|
||||
* 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 record_ostream.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 09.03.2009
|
||||
*
|
||||
* This header contains a wrapper class around a logging record that allows to compose the
|
||||
* record message with a streaming expression.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_SOURCES_RECORD_OSTREAM_HPP_INCLUDED_
|
||||
#define BOOST_LOG_SOURCES_RECORD_OSTREAM_HPP_INCLUDED_
|
||||
|
||||
#include <string>
|
||||
#include <iosfwd>
|
||||
#include <ostream>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include <boost/type_traits/is_enum.hpp>
|
||||
#include <boost/type_traits/is_scalar.hpp>
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
#include <boost/core/addressof.hpp>
|
||||
#include <boost/core/enable_if.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/native_typeof.hpp>
|
||||
#include <boost/log/detail/unhandled_exception_count.hpp>
|
||||
#include <boost/log/core/record.hpp>
|
||||
#include <boost/log/utility/unique_identifier_name.hpp>
|
||||
#include <boost/utility/explicit_operator_bool.hpp>
|
||||
#include <boost/log/utility/formatting_ostream.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
template< typename CharT >
|
||||
class basic_record_ostream;
|
||||
|
||||
namespace aux {
|
||||
|
||||
template< typename StreamT, typename T, bool ByValueV, typename R >
|
||||
struct enable_record_ostream_generic_operator {};
|
||||
template< typename CharT, typename T, typename R >
|
||||
struct enable_record_ostream_generic_operator< basic_record_ostream< CharT >, T, false, R > :
|
||||
public boost::disable_if_c< boost::is_scalar< typename boost::remove_cv< T >::type >::value, R >
|
||||
{
|
||||
};
|
||||
template< typename CharT, typename T, typename R >
|
||||
struct enable_record_ostream_generic_operator< basic_record_ostream< CharT >, T, true, R > :
|
||||
public boost::enable_if_c< boost::is_enum< typename boost::remove_cv< T >::type >::value, R >
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
/*!
|
||||
* \brief Logging record adapter with a streaming capability
|
||||
*
|
||||
* This class allows to compose the logging record message by streaming operations. It
|
||||
* aggregates the log record and provides the standard output stream interface.
|
||||
*/
|
||||
template< typename CharT >
|
||||
class basic_record_ostream :
|
||||
public basic_formatting_ostream< CharT >
|
||||
{
|
||||
//! Self type
|
||||
typedef basic_record_ostream< CharT > this_type;
|
||||
//! Base stream class
|
||||
typedef basic_formatting_ostream< CharT > base_type;
|
||||
|
||||
public:
|
||||
//! Character type
|
||||
typedef CharT char_type;
|
||||
//! String type to be used as a message text holder
|
||||
typedef std::basic_string< char_type > string_type;
|
||||
//! Stream type
|
||||
typedef std::basic_ostream< char_type > stream_type;
|
||||
//! Character traits
|
||||
typedef typename base_type::traits_type traits_type;
|
||||
|
||||
private:
|
||||
//! Log record
|
||||
record* m_record;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Default constructor. Creates an empty record that is equivalent to the invalid record handle.
|
||||
* The stream capability is not available after construction.
|
||||
*
|
||||
* \post <tt>!*this == true</tt>
|
||||
*/
|
||||
basic_record_ostream() BOOST_NOEXCEPT : m_record(NULL) {}
|
||||
|
||||
/*!
|
||||
* Constructor from a record object. Attaches to the provided record.
|
||||
*
|
||||
* \pre <tt>!!rec == true</tt>
|
||||
* \post <tt>&this->get_record() == &rec</tt>
|
||||
* \param rec The record handle being attached to
|
||||
*/
|
||||
explicit basic_record_ostream(record& rec)
|
||||
{
|
||||
BOOST_ASSERT_MSG(!!rec, "Boost.Log: basic_record_ostream should only be attached to a valid record");
|
||||
m_record = &rec;
|
||||
init_stream();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Destructor. Destroys the record, releases any sinks and attribute values that were involved in processing this record.
|
||||
*/
|
||||
~basic_record_ostream() BOOST_NOEXCEPT
|
||||
{
|
||||
detach_from_record();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Conversion to an unspecified boolean type
|
||||
*
|
||||
* \return \c true, if stream is valid and ready for formatting, \c false, if the stream is not valid. The latter also applies to
|
||||
* the case when the stream is not attached to a log record.
|
||||
*/
|
||||
BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
|
||||
|
||||
/*!
|
||||
* Inverted conversion to an unspecified boolean type
|
||||
*
|
||||
* \return \c false, if stream is valid and ready for formatting, \c true, if the stream is not valid. The latter also applies to
|
||||
* the case when the stream is not attached to a log record.
|
||||
*/
|
||||
bool operator! () const BOOST_NOEXCEPT
|
||||
{
|
||||
return (!m_record || base_type::fail());
|
||||
}
|
||||
|
||||
/*!
|
||||
* Flushes internal buffers to complete all pending formatting operations and returns the aggregated log record
|
||||
*
|
||||
* \return The aggregated record object
|
||||
*/
|
||||
record& get_record()
|
||||
{
|
||||
BOOST_ASSERT(m_record != NULL);
|
||||
this->flush();
|
||||
return *m_record;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Flushes internal buffers to complete all pending formatting operations and returns the aggregated log record
|
||||
*
|
||||
* \return The aggregated record object
|
||||
*/
|
||||
record const& get_record() const
|
||||
{
|
||||
BOOST_ASSERT(m_record != NULL);
|
||||
const_cast< this_type* >(this)->flush();
|
||||
return *m_record;
|
||||
}
|
||||
|
||||
/*!
|
||||
* If the stream is attached to a log record, flushes internal buffers to complete all pending formatting operations.
|
||||
* Then reattaches the stream to another log record.
|
||||
*
|
||||
* \param rec New log record to attach to
|
||||
*/
|
||||
void attach_record(record& rec)
|
||||
{
|
||||
BOOST_ASSERT_MSG(!!rec, "Boost.Log: basic_record_ostream should only be attached to a valid record");
|
||||
detach_from_record();
|
||||
m_record = &rec;
|
||||
init_stream();
|
||||
}
|
||||
|
||||
//! The function resets the stream into a detached (default initialized) state
|
||||
BOOST_LOG_API void detach_from_record() BOOST_NOEXCEPT;
|
||||
|
||||
basic_record_ostream& operator<< (typename base_type::ios_base_manip manip)
|
||||
{
|
||||
static_cast< base_type& >(*this) << manip;
|
||||
return *this;
|
||||
}
|
||||
basic_record_ostream& operator<< (typename base_type::basic_ios_manip manip)
|
||||
{
|
||||
static_cast< base_type& >(*this) << manip;
|
||||
return *this;
|
||||
}
|
||||
basic_record_ostream& operator<< (typename base_type::stream_manip manip)
|
||||
{
|
||||
static_cast< base_type& >(*this) << manip;
|
||||
return *this;
|
||||
}
|
||||
|
||||
basic_record_ostream& operator<< (char c)
|
||||
{
|
||||
static_cast< base_type& >(*this) << c;
|
||||
return *this;
|
||||
}
|
||||
basic_record_ostream& operator<< (const char* p)
|
||||
{
|
||||
static_cast< base_type& >(*this) << p;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// When no native character type is supported, the following overloads are disabled as they have ambiguous meaning.
|
||||
// Use basic_string_view or basic_string to explicitly indicate that the data is a string.
|
||||
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
|
||||
basic_record_ostream& operator<< (wchar_t c)
|
||||
{
|
||||
static_cast< base_type& >(*this) << c;
|
||||
return *this;
|
||||
}
|
||||
basic_record_ostream& operator<< (const wchar_t* p)
|
||||
{
|
||||
static_cast< base_type& >(*this) << p;
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
#if !defined(BOOST_LOG_NO_CXX11_CODECVT_FACETS)
|
||||
#if !defined(BOOST_NO_CXX11_CHAR16_T)
|
||||
basic_record_ostream& operator<< (char16_t c)
|
||||
{
|
||||
static_cast< base_type& >(*this) << c;
|
||||
return *this;
|
||||
}
|
||||
basic_record_ostream& operator<< (const char16_t* p)
|
||||
{
|
||||
static_cast< base_type& >(*this) << p;
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
#if !defined(BOOST_NO_CXX11_CHAR32_T)
|
||||
basic_record_ostream& operator<< (char32_t c)
|
||||
{
|
||||
static_cast< base_type& >(*this) << c;
|
||||
return *this;
|
||||
}
|
||||
basic_record_ostream& operator<< (const char32_t* p)
|
||||
{
|
||||
static_cast< base_type& >(*this) << p;
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
basic_record_ostream& operator<< (bool value)
|
||||
{
|
||||
static_cast< base_type& >(*this) << value;
|
||||
return *this;
|
||||
}
|
||||
basic_record_ostream& operator<< (signed char value)
|
||||
{
|
||||
static_cast< base_type& >(*this) << value;
|
||||
return *this;
|
||||
}
|
||||
basic_record_ostream& operator<< (unsigned char value)
|
||||
{
|
||||
static_cast< base_type& >(*this) << value;
|
||||
return *this;
|
||||
}
|
||||
basic_record_ostream& operator<< (short value)
|
||||
{
|
||||
static_cast< base_type& >(*this) << value;
|
||||
return *this;
|
||||
}
|
||||
basic_record_ostream& operator<< (unsigned short value)
|
||||
{
|
||||
static_cast< base_type& >(*this) << value;
|
||||
return *this;
|
||||
}
|
||||
basic_record_ostream& operator<< (int value)
|
||||
{
|
||||
static_cast< base_type& >(*this) << value;
|
||||
return *this;
|
||||
}
|
||||
basic_record_ostream& operator<< (unsigned int value)
|
||||
{
|
||||
static_cast< base_type& >(*this) << value;
|
||||
return *this;
|
||||
}
|
||||
basic_record_ostream& operator<< (long value)
|
||||
{
|
||||
static_cast< base_type& >(*this) << value;
|
||||
return *this;
|
||||
}
|
||||
basic_record_ostream& operator<< (unsigned long value)
|
||||
{
|
||||
static_cast< base_type& >(*this) << value;
|
||||
return *this;
|
||||
}
|
||||
#if !defined(BOOST_NO_LONG_LONG)
|
||||
basic_record_ostream& operator<< (long long value)
|
||||
{
|
||||
static_cast< base_type& >(*this) << value;
|
||||
return *this;
|
||||
}
|
||||
basic_record_ostream& operator<< (unsigned long long value)
|
||||
{
|
||||
static_cast< base_type& >(*this) << value;
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
basic_record_ostream& operator<< (float value)
|
||||
{
|
||||
static_cast< base_type& >(*this) << value;
|
||||
return *this;
|
||||
}
|
||||
basic_record_ostream& operator<< (double value)
|
||||
{
|
||||
static_cast< base_type& >(*this) << value;
|
||||
return *this;
|
||||
}
|
||||
basic_record_ostream& operator<< (long double value)
|
||||
{
|
||||
static_cast< base_type& >(*this) << value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
basic_record_ostream& operator<< (const void* value)
|
||||
{
|
||||
static_cast< base_type& >(*this) << value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
basic_record_ostream& operator<< (std::basic_streambuf< char_type, traits_type >* buf)
|
||||
{
|
||||
static_cast< base_type& >(*this) << buf;
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
//! The function initializes the stream and the stream buffer
|
||||
BOOST_LOG_API void init_stream();
|
||||
|
||||
// Copy and assignment are closed
|
||||
BOOST_DELETED_FUNCTION(basic_record_ostream(basic_record_ostream const&))
|
||||
BOOST_DELETED_FUNCTION(basic_record_ostream& operator= (basic_record_ostream const&))
|
||||
};
|
||||
|
||||
|
||||
#ifdef BOOST_LOG_USE_CHAR
|
||||
typedef basic_record_ostream< char > record_ostream; //!< Convenience typedef for narrow-character logging
|
||||
#endif
|
||||
#ifdef BOOST_LOG_USE_WCHAR_T
|
||||
typedef basic_record_ostream< wchar_t > wrecord_ostream; //!< Convenience typedef for wide-character logging
|
||||
#endif
|
||||
|
||||
// Implementation note: these operators below should be the least attractive for the compiler
|
||||
// so that user's overloads are chosen, when present. We use function template partial ordering for this purpose.
|
||||
// We also don't use perfect forwarding for the right hand argument because in ths case the generic overload
|
||||
// would be more preferred than the typical one written by users:
|
||||
//
|
||||
// record_ostream& operator<< (record_ostream& strm, my_type const& arg);
|
||||
//
|
||||
// This is because my_type rvalues require adding const to the type, which counts as a conversion that is not required
|
||||
// if there is a perfect forwarding overload.
|
||||
template< typename StreamT, typename T >
|
||||
inline typename boost::log::aux::enable_record_ostream_generic_operator< StreamT, T, true, StreamT& >::type
|
||||
operator<< (StreamT& strm, T value)
|
||||
{
|
||||
typedef basic_formatting_ostream< typename StreamT::char_type > formatting_ostream_type;
|
||||
static_cast< formatting_ostream_type& >(strm) << value;
|
||||
return strm;
|
||||
}
|
||||
|
||||
template< typename StreamT, typename T >
|
||||
inline typename boost::log::aux::enable_record_ostream_generic_operator< StreamT, T, false, StreamT& >::type
|
||||
operator<< (StreamT& strm, T const& value)
|
||||
{
|
||||
typedef basic_formatting_ostream< typename StreamT::char_type > formatting_ostream_type;
|
||||
static_cast< formatting_ostream_type& >(strm) << value;
|
||||
return strm;
|
||||
}
|
||||
|
||||
template< typename StreamT, typename T >
|
||||
inline typename boost::log::aux::enable_record_ostream_generic_operator< StreamT, T, false, StreamT& >::type
|
||||
operator<< (StreamT& strm, T& value)
|
||||
{
|
||||
typedef basic_formatting_ostream< typename StreamT::char_type > formatting_ostream_type;
|
||||
static_cast< formatting_ostream_type& >(strm) << value;
|
||||
return strm;
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
|
||||
template< typename StreamT, typename T >
|
||||
inline typename boost::log::aux::enable_record_ostream_generic_operator< StreamT, T, true, StreamT& >::type
|
||||
operator<< (StreamT&& strm, T value)
|
||||
{
|
||||
typedef basic_formatting_ostream< typename StreamT::char_type > formatting_ostream_type;
|
||||
static_cast< formatting_ostream_type& >(strm) << value;
|
||||
return strm;
|
||||
}
|
||||
|
||||
template< typename StreamT, typename T >
|
||||
inline typename boost::log::aux::enable_record_ostream_generic_operator< StreamT, T, false, StreamT& >::type
|
||||
operator<< (StreamT&& strm, T const& value)
|
||||
{
|
||||
typedef basic_formatting_ostream< typename StreamT::char_type > formatting_ostream_type;
|
||||
static_cast< formatting_ostream_type& >(strm) << value;
|
||||
return strm;
|
||||
}
|
||||
|
||||
template< typename StreamT, typename T >
|
||||
inline typename boost::log::aux::enable_record_ostream_generic_operator< StreamT, T, false, StreamT& >::type
|
||||
operator<< (StreamT&& strm, T& value)
|
||||
{
|
||||
typedef basic_formatting_ostream< typename StreamT::char_type > formatting_ostream_type;
|
||||
static_cast< formatting_ostream_type& >(strm) << value;
|
||||
return strm;
|
||||
}
|
||||
|
||||
#endif // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
|
||||
namespace aux {
|
||||
|
||||
//! Internal class that provides formatting streams for record pumps
|
||||
template< typename CharT >
|
||||
struct stream_provider
|
||||
{
|
||||
//! Character type
|
||||
typedef CharT char_type;
|
||||
|
||||
//! Formatting stream compound
|
||||
struct stream_compound
|
||||
{
|
||||
stream_compound* next;
|
||||
|
||||
//! Log record stream adapter
|
||||
basic_record_ostream< char_type > stream;
|
||||
|
||||
//! Initializing constructor
|
||||
explicit stream_compound(record& rec) : next(NULL), stream(rec) {}
|
||||
};
|
||||
|
||||
//! The method returns an allocated stream compound
|
||||
BOOST_LOG_API static stream_compound* allocate_compound(record& rec);
|
||||
//! The method releases a compound
|
||||
BOOST_LOG_API static void release_compound(stream_compound* compound) BOOST_NOEXCEPT;
|
||||
|
||||
// Non-constructible, non-copyable, non-assignable
|
||||
BOOST_DELETED_FUNCTION(stream_provider())
|
||||
BOOST_DELETED_FUNCTION(stream_provider(stream_provider const&))
|
||||
BOOST_DELETED_FUNCTION(stream_provider& operator= (stream_provider const&))
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Logging record pump implementation
|
||||
*
|
||||
* The pump is used to format the logging record message text and then
|
||||
* push it to the logging core. It is constructed on each attempt to write
|
||||
* a log record and destroyed afterwards.
|
||||
*
|
||||
* The pump class template is instantiated on the logger type.
|
||||
*/
|
||||
template< typename LoggerT >
|
||||
class record_pump
|
||||
{
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(record_pump)
|
||||
|
||||
private:
|
||||
//! Logger type
|
||||
typedef LoggerT logger_type;
|
||||
//! Character type
|
||||
typedef typename logger_type::char_type char_type;
|
||||
//! Stream compound provider
|
||||
typedef stream_provider< char_type > stream_provider_type;
|
||||
//! Stream compound type
|
||||
typedef typename stream_provider_type::stream_compound stream_compound;
|
||||
|
||||
//! Stream compound release guard
|
||||
class auto_release;
|
||||
friend class auto_release;
|
||||
class auto_release
|
||||
{
|
||||
stream_compound* m_pCompound;
|
||||
|
||||
public:
|
||||
explicit auto_release(stream_compound* p) BOOST_NOEXCEPT : m_pCompound(p) {}
|
||||
~auto_release() BOOST_NOEXCEPT { stream_provider_type::release_compound(m_pCompound); }
|
||||
};
|
||||
|
||||
protected:
|
||||
//! A reference to the logger
|
||||
logger_type* m_pLogger;
|
||||
//! Stream compound
|
||||
stream_compound* m_pStreamCompound;
|
||||
//! Exception state
|
||||
const unsigned int m_ExceptionCount;
|
||||
|
||||
public:
|
||||
//! Constructor
|
||||
explicit record_pump(logger_type& lg, record& rec) :
|
||||
m_pLogger(boost::addressof(lg)),
|
||||
m_pStreamCompound(stream_provider_type::allocate_compound(rec)),
|
||||
m_ExceptionCount(unhandled_exception_count())
|
||||
{
|
||||
}
|
||||
//! Move constructor
|
||||
record_pump(BOOST_RV_REF(record_pump) that) BOOST_NOEXCEPT :
|
||||
m_pLogger(that.m_pLogger),
|
||||
m_pStreamCompound(that.m_pStreamCompound),
|
||||
m_ExceptionCount(that.m_ExceptionCount)
|
||||
{
|
||||
that.m_pLogger = 0;
|
||||
that.m_pStreamCompound = 0;
|
||||
}
|
||||
//! Destructor. Pushes the composed message to log.
|
||||
~record_pump() BOOST_NOEXCEPT_IF(false)
|
||||
{
|
||||
if (m_pLogger)
|
||||
{
|
||||
auto_release cleanup(m_pStreamCompound); // destructor doesn't throw
|
||||
// Only push the record if no exception has been thrown in the streaming expression (if possible)
|
||||
if (m_ExceptionCount >= unhandled_exception_count())
|
||||
m_pLogger->push_record(boost::move(m_pStreamCompound->stream.get_record()));
|
||||
}
|
||||
}
|
||||
|
||||
//! Returns the stream to be used for message text formatting
|
||||
basic_record_ostream< char_type >& stream() const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_ASSERT(m_pStreamCompound != 0);
|
||||
return m_pStreamCompound->stream;
|
||||
}
|
||||
};
|
||||
|
||||
template< typename LoggerT >
|
||||
BOOST_FORCEINLINE record_pump< LoggerT > make_record_pump(LoggerT& lg, record& rec)
|
||||
{
|
||||
return record_pump< LoggerT >(lg, rec);
|
||||
}
|
||||
|
||||
} // namespace aux
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
#define BOOST_LOG_STREAM_INTERNAL(logger, rec_var)\
|
||||
for (::boost::log::record rec_var = (logger).open_record(); !!rec_var;)\
|
||||
::boost::log::aux::make_record_pump((logger), rec_var).stream()
|
||||
|
||||
#define BOOST_LOG_STREAM_WITH_PARAMS_INTERNAL(logger, rec_var, params_seq)\
|
||||
for (::boost::log::record rec_var = (logger).open_record((BOOST_PP_SEQ_ENUM(params_seq))); !!rec_var;)\
|
||||
::boost::log::aux::make_record_pump((logger), rec_var).stream()
|
||||
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
//! The macro writes a record to the log
|
||||
#define BOOST_LOG_STREAM(logger)\
|
||||
BOOST_LOG_STREAM_INTERNAL(logger, BOOST_LOG_UNIQUE_IDENTIFIER_NAME(_boost_log_record_))
|
||||
|
||||
//! The macro writes a record to the log and allows to pass additional named arguments to the logger
|
||||
#define BOOST_LOG_STREAM_WITH_PARAMS(logger, params_seq)\
|
||||
BOOST_LOG_STREAM_WITH_PARAMS_INTERNAL(logger, BOOST_LOG_UNIQUE_IDENTIFIER_NAME(_boost_log_record_), params_seq)
|
||||
|
||||
#ifndef BOOST_LOG_NO_SHORTHAND_NAMES
|
||||
|
||||
//! An equivalent to BOOST_LOG_STREAM(logger)
|
||||
#define BOOST_LOG(logger) BOOST_LOG_STREAM(logger)
|
||||
|
||||
//! An equivalent to BOOST_LOG_STREAM_WITH_PARAMS(logger, params_seq)
|
||||
#define BOOST_LOG_WITH_PARAMS(logger, params_seq) BOOST_LOG_STREAM_WITH_PARAMS(logger, params_seq)
|
||||
|
||||
#endif // BOOST_LOG_NO_SHORTHAND_NAMES
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_SOURCES_RECORD_OSTREAM_HPP_INCLUDED_
|
||||
@@ -0,0 +1,309 @@
|
||||
/*
|
||||
* Copyright Andrey Semashev 2007 - 2015.
|
||||
* 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_channel_logger.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 28.02.2008
|
||||
*
|
||||
* The header contains implementation of a logger with severity level and channel support.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_SOURCES_SEVERITY_CHANNEL_LOGGER_HPP_INCLUDED_
|
||||
#define BOOST_LOG_SOURCES_SEVERITY_CHANNEL_LOGGER_HPP_INCLUDED_
|
||||
|
||||
#include <string>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
#include <boost/log/detail/light_rw_mutex.hpp>
|
||||
#endif // !defined(BOOST_LOG_NO_THREADS)
|
||||
#include <boost/log/sources/features.hpp>
|
||||
#include <boost/log/sources/basic_logger.hpp>
|
||||
#include <boost/log/sources/threading_models.hpp>
|
||||
#include <boost/log/sources/severity_feature.hpp>
|
||||
#include <boost/log/sources/channel_feature.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace sources {
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
#ifdef BOOST_LOG_USE_CHAR
|
||||
|
||||
//! Narrow-char logger with severity level and channel support
|
||||
template< typename LevelT = int, typename ChannelT = std::string >
|
||||
class severity_channel_logger :
|
||||
public basic_composite_logger<
|
||||
char,
|
||||
severity_channel_logger< LevelT, ChannelT >,
|
||||
single_thread_model,
|
||||
features<
|
||||
severity< LevelT >,
|
||||
channel< ChannelT >
|
||||
>
|
||||
>
|
||||
{
|
||||
BOOST_LOG_FORWARD_LOGGER_MEMBERS_TEMPLATE(severity_channel_logger)
|
||||
};
|
||||
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
|
||||
//! Narrow-char thread-safe logger with severity level and channel support
|
||||
template< typename LevelT = int, typename ChannelT = std::string >
|
||||
class severity_channel_logger_mt :
|
||||
public basic_composite_logger<
|
||||
char,
|
||||
severity_channel_logger_mt< LevelT, ChannelT >,
|
||||
multi_thread_model< boost::log::aux::light_rw_mutex >,
|
||||
features<
|
||||
severity< LevelT >,
|
||||
channel< ChannelT >
|
||||
>
|
||||
>
|
||||
{
|
||||
BOOST_LOG_FORWARD_LOGGER_MEMBERS_TEMPLATE(severity_channel_logger_mt)
|
||||
};
|
||||
|
||||
#endif // !defined(BOOST_LOG_NO_THREADS)
|
||||
|
||||
#endif // BOOST_LOG_USE_CHAR
|
||||
|
||||
#ifdef BOOST_LOG_USE_WCHAR_T
|
||||
|
||||
//! Wide-char logger with severity level and channel support
|
||||
template< typename LevelT = int, typename ChannelT = std::wstring >
|
||||
class wseverity_channel_logger :
|
||||
public basic_composite_logger<
|
||||
wchar_t,
|
||||
wseverity_channel_logger< LevelT, ChannelT >,
|
||||
single_thread_model,
|
||||
features<
|
||||
severity< LevelT >,
|
||||
channel< ChannelT >
|
||||
>
|
||||
>
|
||||
{
|
||||
BOOST_LOG_FORWARD_LOGGER_MEMBERS_TEMPLATE(wseverity_channel_logger)
|
||||
};
|
||||
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
|
||||
//! Wide-char thread-safe logger with severity level and channel support
|
||||
template< typename LevelT = int, typename ChannelT = std::wstring >
|
||||
class wseverity_channel_logger_mt :
|
||||
public basic_composite_logger<
|
||||
wchar_t,
|
||||
wseverity_channel_logger_mt< LevelT, ChannelT >,
|
||||
multi_thread_model< boost::log::aux::light_rw_mutex >,
|
||||
features<
|
||||
severity< LevelT >,
|
||||
channel< ChannelT >
|
||||
>
|
||||
>
|
||||
{
|
||||
BOOST_LOG_FORWARD_LOGGER_MEMBERS_TEMPLATE(wseverity_channel_logger_mt)
|
||||
};
|
||||
|
||||
#endif // !defined(BOOST_LOG_NO_THREADS)
|
||||
|
||||
#endif // BOOST_LOG_USE_WCHAR_T
|
||||
|
||||
#else // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
/*!
|
||||
* \brief Narrow-char logger. Functionally equivalent to \c basic_severity_logger and \c basic_channel_logger.
|
||||
*
|
||||
* See \c severity and \c channel class templates for a more detailed description
|
||||
*/
|
||||
template< typename LevelT = int, typename ChannelT = std::string >
|
||||
class severity_channel_logger :
|
||||
public basic_composite_logger<
|
||||
char,
|
||||
severity_channel_logger< LevelT, ChannelT >,
|
||||
single_thread_model,
|
||||
features<
|
||||
severity< LevelT >,
|
||||
channel< ChannelT >
|
||||
>
|
||||
>
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* Default constructor
|
||||
*/
|
||||
severity_channel_logger();
|
||||
/*!
|
||||
* Copy constructor
|
||||
*/
|
||||
severity_channel_logger(severity_channel_logger const& that);
|
||||
/*!
|
||||
* Constructor with named arguments
|
||||
*/
|
||||
template< typename... ArgsT >
|
||||
explicit severity_channel_logger(ArgsT... const& args);
|
||||
/*!
|
||||
* Assignment operator
|
||||
*/
|
||||
severity_channel_logger& operator= (severity_channel_logger const& that)
|
||||
/*!
|
||||
* Swaps two loggers
|
||||
*/
|
||||
void swap(severity_channel_logger& that);
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Narrow-char thread-safe logger. Functionally equivalent to \c basic_severity_logger and \c basic_channel_logger.
|
||||
*
|
||||
* See \c severity and \c channel class templates for a more detailed description
|
||||
*/
|
||||
template< typename LevelT = int, typename ChannelT = std::string >
|
||||
class severity_channel_logger_mt :
|
||||
public basic_composite_logger<
|
||||
char,
|
||||
severity_channel_logger_mt< LevelT, ChannelT >,
|
||||
multi_thread_model< implementation_defined >,
|
||||
features<
|
||||
severity< LevelT >,
|
||||
channel< ChannelT >
|
||||
>
|
||||
>
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* Default constructor
|
||||
*/
|
||||
severity_channel_logger_mt();
|
||||
/*!
|
||||
* Copy constructor
|
||||
*/
|
||||
severity_channel_logger_mt(severity_channel_logger_mt const& that);
|
||||
/*!
|
||||
* Constructor with named arguments
|
||||
*/
|
||||
template< typename... ArgsT >
|
||||
explicit severity_channel_logger_mt(ArgsT... const& args);
|
||||
/*!
|
||||
* Assignment operator
|
||||
*/
|
||||
severity_channel_logger_mt& operator= (severity_channel_logger_mt const& that)
|
||||
/*!
|
||||
* Swaps two loggers
|
||||
*/
|
||||
void swap(severity_channel_logger_mt& that);
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Wide-char logger. Functionally equivalent to \c basic_severity_logger and \c basic_channel_logger.
|
||||
*
|
||||
* See \c severity and \c channel class templates for a more detailed description
|
||||
*/
|
||||
template< typename LevelT = int, typename ChannelT = std::wstring >
|
||||
class wseverity_channel_logger :
|
||||
public basic_composite_logger<
|
||||
wchar_t,
|
||||
wseverity_channel_logger< LevelT, ChannelT >,
|
||||
single_thread_model,
|
||||
features<
|
||||
severity< LevelT >,
|
||||
channel< ChannelT >
|
||||
>
|
||||
>
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* Default constructor
|
||||
*/
|
||||
wseverity_channel_logger();
|
||||
/*!
|
||||
* Copy constructor
|
||||
*/
|
||||
wseverity_channel_logger(wseverity_channel_logger const& that);
|
||||
/*!
|
||||
* Constructor with named arguments
|
||||
*/
|
||||
template< typename... ArgsT >
|
||||
explicit wseverity_channel_logger(ArgsT... const& args);
|
||||
/*!
|
||||
* Assignment operator
|
||||
*/
|
||||
wseverity_channel_logger& operator= (wseverity_channel_logger const& that)
|
||||
/*!
|
||||
* Swaps two loggers
|
||||
*/
|
||||
void swap(wseverity_channel_logger& that);
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Wide-char thread-safe logger. Functionally equivalent to \c basic_severity_logger and \c basic_channel_logger.
|
||||
*
|
||||
* See \c severity and \c channel class templates for a more detailed description
|
||||
*/
|
||||
template< typename LevelT = int, typename ChannelT = std::wstring >
|
||||
class wseverity_channel_logger_mt :
|
||||
public basic_composite_logger<
|
||||
wchar_t,
|
||||
wseverity_channel_logger_mt< LevelT, ChannelT >,
|
||||
multi_thread_model< implementation_defined >,
|
||||
features<
|
||||
severity< LevelT >,
|
||||
channel< ChannelT >
|
||||
>
|
||||
>
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* Default constructor
|
||||
*/
|
||||
wseverity_channel_logger_mt();
|
||||
/*!
|
||||
* Copy constructor
|
||||
*/
|
||||
wseverity_channel_logger_mt(wseverity_channel_logger_mt const& that);
|
||||
/*!
|
||||
* Constructor with named arguments
|
||||
*/
|
||||
template< typename... ArgsT >
|
||||
explicit wseverity_channel_logger_mt(ArgsT... const& args);
|
||||
/*!
|
||||
* Assignment operator
|
||||
*/
|
||||
wseverity_channel_logger_mt& operator= (wseverity_channel_logger_mt const& that)
|
||||
/*!
|
||||
* Swaps two loggers
|
||||
*/
|
||||
void swap(wseverity_channel_logger_mt& that);
|
||||
};
|
||||
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
} // namespace sources
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
//! The macro allows to put a record with a specific channel name into log
|
||||
#define BOOST_LOG_STREAM_CHANNEL_SEV(logger, chan, lvl)\
|
||||
BOOST_LOG_STREAM_WITH_PARAMS((logger), (::boost::log::keywords::channel = (chan))(::boost::log::keywords::severity = (lvl)))
|
||||
|
||||
#ifndef BOOST_LOG_NO_SHORTHAND_NAMES
|
||||
|
||||
//! An equivalent to BOOST_LOG_STREAM_CHANNEL_SEV(logger, chan, lvl)
|
||||
#define BOOST_LOG_CHANNEL_SEV(logger, chan, lvl) BOOST_LOG_STREAM_CHANNEL_SEV(logger, chan, lvl)
|
||||
|
||||
#endif // BOOST_LOG_NO_SHORTHAND_NAMES
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_SOURCES_SEVERITY_CHANNEL_LOGGER_HPP_INCLUDED_
|
||||
@@ -0,0 +1,310 @@
|
||||
/*
|
||||
* Copyright Andrey Semashev 2007 - 2015.
|
||||
* 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_core.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_
|
||||
@@ -0,0 +1,325 @@
|
||||
/*
|
||||
* Copyright Andrey Semashev 2007 - 2015.
|
||||
* 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_logger.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 08.03.2007
|
||||
*
|
||||
* The header contains implementation of a logger with severity level support.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_SOURCES_SEVERITY_LOGGER_HPP_INCLUDED_
|
||||
#define BOOST_LOG_SOURCES_SEVERITY_LOGGER_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
#include <boost/log/detail/light_rw_mutex.hpp>
|
||||
#endif // !defined(BOOST_LOG_NO_THREADS)
|
||||
#include <boost/log/sources/features.hpp>
|
||||
#include <boost/log/sources/basic_logger.hpp>
|
||||
#include <boost/log/sources/threading_models.hpp>
|
||||
#include <boost/log/sources/severity_feature.hpp>
|
||||
#include <boost/log/keywords/severity.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace sources {
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
#ifdef BOOST_LOG_USE_CHAR
|
||||
|
||||
//! Narrow-char logger with severity level support
|
||||
template< typename LevelT = int >
|
||||
class severity_logger :
|
||||
public basic_composite_logger<
|
||||
char,
|
||||
severity_logger< LevelT >,
|
||||
single_thread_model,
|
||||
features< severity< LevelT > >
|
||||
>
|
||||
{
|
||||
typedef typename severity_logger::logger_base base_type;
|
||||
|
||||
public:
|
||||
BOOST_LOG_FORWARD_LOGGER_MEMBERS_TEMPLATE(severity_logger)
|
||||
|
||||
explicit severity_logger(LevelT level) : base_type(keywords::severity = level)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
|
||||
//! Narrow-char thread-safe logger with severity level support
|
||||
template< typename LevelT = int >
|
||||
class severity_logger_mt :
|
||||
public basic_composite_logger<
|
||||
char,
|
||||
severity_logger_mt< LevelT >,
|
||||
multi_thread_model< boost::log::aux::light_rw_mutex >,
|
||||
features< severity< LevelT > >
|
||||
>
|
||||
{
|
||||
typedef typename severity_logger_mt::logger_base base_type;
|
||||
|
||||
public:
|
||||
BOOST_LOG_FORWARD_LOGGER_MEMBERS_TEMPLATE(severity_logger_mt)
|
||||
|
||||
explicit severity_logger_mt(LevelT level) : base_type(keywords::severity = level)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
#endif // !defined(BOOST_LOG_NO_THREADS)
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_LOG_USE_WCHAR_T
|
||||
|
||||
//! Wide-char logger with severity level support
|
||||
template< typename LevelT = int >
|
||||
class wseverity_logger :
|
||||
public basic_composite_logger<
|
||||
wchar_t,
|
||||
wseverity_logger< LevelT >,
|
||||
single_thread_model,
|
||||
features< severity< LevelT > >
|
||||
>
|
||||
{
|
||||
typedef typename wseverity_logger::logger_base base_type;
|
||||
|
||||
public:
|
||||
BOOST_LOG_FORWARD_LOGGER_MEMBERS_TEMPLATE(wseverity_logger)
|
||||
|
||||
explicit wseverity_logger(LevelT level) : base_type(keywords::severity = level)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
|
||||
//! Wide-char thread-safe logger with severity level support
|
||||
template< typename LevelT = int >
|
||||
class wseverity_logger_mt :
|
||||
public basic_composite_logger<
|
||||
wchar_t,
|
||||
wseverity_logger_mt< LevelT >,
|
||||
multi_thread_model< boost::log::aux::light_rw_mutex >,
|
||||
features< severity< LevelT > >
|
||||
>
|
||||
{
|
||||
typedef typename wseverity_logger_mt::logger_base base_type;
|
||||
|
||||
public:
|
||||
BOOST_LOG_FORWARD_LOGGER_MEMBERS_TEMPLATE(wseverity_logger_mt)
|
||||
|
||||
explicit wseverity_logger_mt(LevelT level) : base_type(keywords::severity = level)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
#endif // !defined(BOOST_LOG_NO_THREADS)
|
||||
|
||||
#endif
|
||||
|
||||
#else // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
/*!
|
||||
* \brief Narrow-char logger. Functionally equivalent to \c basic_severity_logger.
|
||||
*
|
||||
* See \c severity class template for a more detailed description
|
||||
*/
|
||||
template< typename LevelT = int >
|
||||
class severity_logger :
|
||||
public basic_composite_logger<
|
||||
char,
|
||||
severity_logger< LevelT >,
|
||||
single_thread_model,
|
||||
features< severity< LevelT > >
|
||||
>
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* Default constructor
|
||||
*/
|
||||
severity_logger();
|
||||
/*!
|
||||
* Copy constructor
|
||||
*/
|
||||
severity_logger(severity_logger const& that);
|
||||
/*!
|
||||
* Constructor with named arguments
|
||||
*/
|
||||
template< typename... ArgsT >
|
||||
explicit severity_logger(ArgsT... const& args);
|
||||
/*!
|
||||
* The constructor creates the logger with the specified default severity level
|
||||
*
|
||||
* \param level The default severity level
|
||||
*/
|
||||
explicit severity_logger(LevelT level);
|
||||
/*!
|
||||
* Assignment operator
|
||||
*/
|
||||
severity_logger& operator= (severity_logger const& that)
|
||||
/*!
|
||||
* Swaps two loggers
|
||||
*/
|
||||
void swap(severity_logger& that);
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Narrow-char thread-safe logger. Functionally equivalent to \c basic_severity_logger.
|
||||
*
|
||||
* See \c severity class template for a more detailed description
|
||||
*/
|
||||
template< typename LevelT = int >
|
||||
class severity_logger_mt :
|
||||
public basic_composite_logger<
|
||||
char,
|
||||
severity_logger_mt< LevelT >,
|
||||
multi_thread_model< implementation_defined >,
|
||||
features< severity< LevelT > >
|
||||
>
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* Default constructor
|
||||
*/
|
||||
severity_logger_mt();
|
||||
/*!
|
||||
* Copy constructor
|
||||
*/
|
||||
severity_logger_mt(severity_logger_mt const& that);
|
||||
/*!
|
||||
* Constructor with named arguments
|
||||
*/
|
||||
template< typename... ArgsT >
|
||||
explicit severity_logger_mt(ArgsT... const& args);
|
||||
/*!
|
||||
* The constructor creates the logger with the specified default severity level
|
||||
*
|
||||
* \param level The default severity level
|
||||
*/
|
||||
explicit severity_logger_mt(LevelT level);
|
||||
/*!
|
||||
* Assignment operator
|
||||
*/
|
||||
severity_logger_mt& operator= (severity_logger_mt const& that)
|
||||
/*!
|
||||
* Swaps two loggers
|
||||
*/
|
||||
void swap(severity_logger_mt& that);
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Wide-char logger. Functionally equivalent to \c basic_severity_logger.
|
||||
*
|
||||
* See \c severity class template for a more detailed description
|
||||
*/
|
||||
template< typename LevelT = int >
|
||||
class wseverity_logger :
|
||||
public basic_composite_logger<
|
||||
wchar_t,
|
||||
wseverity_logger< LevelT >,
|
||||
single_thread_model,
|
||||
features< severity< LevelT > >
|
||||
>
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* Default constructor
|
||||
*/
|
||||
wseverity_logger();
|
||||
/*!
|
||||
* Copy constructor
|
||||
*/
|
||||
wseverity_logger(wseverity_logger const& that);
|
||||
/*!
|
||||
* Constructor with named arguments
|
||||
*/
|
||||
template< typename... ArgsT >
|
||||
explicit wseverity_logger(ArgsT... const& args);
|
||||
/*!
|
||||
* The constructor creates the logger with the specified default severity level
|
||||
*
|
||||
* \param level The default severity level
|
||||
*/
|
||||
explicit wseverity_logger(LevelT level);
|
||||
/*!
|
||||
* Assignment operator
|
||||
*/
|
||||
wseverity_logger& operator= (wseverity_logger const& that)
|
||||
/*!
|
||||
* Swaps two loggers
|
||||
*/
|
||||
void swap(wseverity_logger& that);
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Wide-char thread-safe logger. Functionally equivalent to \c basic_severity_logger.
|
||||
*
|
||||
* See \c severity class template for a more detailed description
|
||||
*/
|
||||
template< typename LevelT = int >
|
||||
class wseverity_logger_mt :
|
||||
public basic_composite_logger<
|
||||
wchar_t,
|
||||
wseverity_logger_mt< LevelT >,
|
||||
multi_thread_model< implementation_defined >,
|
||||
features< severity< LevelT > >
|
||||
>
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* Default constructor
|
||||
*/
|
||||
wseverity_logger_mt();
|
||||
/*!
|
||||
* Copy constructor
|
||||
*/
|
||||
wseverity_logger_mt(wseverity_logger_mt const& that);
|
||||
/*!
|
||||
* Constructor with named arguments
|
||||
*/
|
||||
template< typename... ArgsT >
|
||||
explicit wseverity_logger_mt(ArgsT... const& args);
|
||||
/*!
|
||||
* The constructor creates the logger with the specified default severity level
|
||||
*
|
||||
* \param level The default severity level
|
||||
*/
|
||||
explicit wseverity_logger_mt(LevelT level);
|
||||
/*!
|
||||
* Assignment operator
|
||||
*/
|
||||
wseverity_logger_mt& operator= (wseverity_logger_mt const& that)
|
||||
/*!
|
||||
* Swaps two loggers
|
||||
*/
|
||||
void swap(wseverity_logger_mt& that);
|
||||
};
|
||||
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
} // namespace sources
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_SOURCES_SEVERITY_LOGGER_HPP_INCLUDED_
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright Andrey Semashev 2007 - 2015.
|
||||
* 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 sources/threading_models.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 04.10.2008
|
||||
*
|
||||
* The header contains definition of threading models that can be used in loggers.
|
||||
* The header also provides a number of tags that can be used to express lock requirements
|
||||
* on a function callee.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_SOURCES_THREADING_MODELS_HPP_INCLUDED_
|
||||
#define BOOST_LOG_SOURCES_THREADING_MODELS_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/locks.hpp> // is_mutex_type
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#endif
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace sources {
|
||||
|
||||
//! Single thread locking model
|
||||
struct single_thread_model
|
||||
{
|
||||
// We provide methods for the most advanced locking concept: UpgradeLockable
|
||||
void lock_shared() const {}
|
||||
bool try_lock_shared() const { return true; }
|
||||
template< typename TimeT >
|
||||
bool timed_lock_shared(TimeT const&) const { return true; }
|
||||
void unlock_shared() const {}
|
||||
void lock() const {}
|
||||
bool try_lock() const { return true; }
|
||||
template< typename TimeT >
|
||||
bool timed_lock(TimeT const&) const { return true; }
|
||||
void unlock() const {}
|
||||
void lock_upgrade() const {}
|
||||
bool try_lock_upgrade() const { return true; }
|
||||
template< typename TimeT >
|
||||
bool timed_lock_upgrade(TimeT const&) const { return true; }
|
||||
void unlock_upgrade() const {}
|
||||
void unlock_upgrade_and_lock() const {}
|
||||
void unlock_and_lock_upgrade() const {}
|
||||
void unlock_and_lock_shared() const {}
|
||||
void unlock_upgrade_and_lock_shared() const {}
|
||||
|
||||
void swap(single_thread_model&) {}
|
||||
};
|
||||
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
|
||||
//! Multi-thread locking model with maximum locking capabilities
|
||||
template< typename MutexT >
|
||||
struct multi_thread_model
|
||||
{
|
||||
multi_thread_model() {}
|
||||
multi_thread_model(multi_thread_model const&) {}
|
||||
multi_thread_model& operator= (multi_thread_model const&) { return *this; }
|
||||
|
||||
void lock_shared() const { m_Mutex.lock_shared(); }
|
||||
bool try_lock_shared() const { return m_Mutex.try_lock_shared(); }
|
||||
template< typename TimeT >
|
||||
bool timed_lock_shared(TimeT const& t) const { return m_Mutex.timed_lock_shared(t); }
|
||||
void unlock_shared() const { m_Mutex.unlock_shared(); }
|
||||
void lock() const { m_Mutex.lock(); }
|
||||
bool try_lock() const { return m_Mutex.try_lock(); }
|
||||
template< typename TimeT >
|
||||
bool timed_lock(TimeT const& t) const { return m_Mutex.timed_lock(t); }
|
||||
void unlock() const { m_Mutex.unlock(); }
|
||||
void lock_upgrade() const { m_Mutex.lock_upgrade(); }
|
||||
bool try_lock_upgrade() const { return m_Mutex.try_lock_upgrade(); }
|
||||
template< typename TimeT >
|
||||
bool timed_lock_upgrade(TimeT const& t) const { return m_Mutex.timed_lock_upgrade(t); }
|
||||
void unlock_upgrade() const { m_Mutex.unlock_upgrade(); }
|
||||
void unlock_upgrade_and_lock() const { m_Mutex.unlock_upgrade_and_lock(); }
|
||||
void unlock_and_lock_upgrade() const { m_Mutex.unlock_and_lock_upgrade(); }
|
||||
void unlock_and_lock_shared() const { m_Mutex.unlock_and_lock_shared(); }
|
||||
void unlock_upgrade_and_lock_shared() const { m_Mutex.unlock_upgrade_and_lock_shared(); }
|
||||
|
||||
void swap(multi_thread_model&) {}
|
||||
|
||||
private:
|
||||
//! Synchronization primitive
|
||||
mutable MutexT m_Mutex;
|
||||
};
|
||||
|
||||
#endif // !defined(BOOST_LOG_NO_THREADS)
|
||||
|
||||
} // namespace sources
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
#if !defined(BOOST_LOG_NO_THREADS) && !defined(BOOST_LOG_DOXYGEN_PASS)
|
||||
|
||||
template< >
|
||||
struct is_mutex_type< boost::log::sources::single_thread_model > : mpl::true_
|
||||
{
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
struct is_mutex_type< boost::log::sources::multi_thread_model< T > > : mpl::true_
|
||||
{
|
||||
};
|
||||
|
||||
#endif // !defined(BOOST_LOG_NO_THREADS)
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_SOURCES_THREADING_MODELS_HPP_INCLUDED_
|
||||
Reference in New Issue
Block a user