stabilize build system: depends, installer, boost/bdb fixes, cross targets groundwork
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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 attributes.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 13.07.2009
|
||||
*
|
||||
* This header includes other Boost.Log headers with all attributes.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_ATTRIBUTES_HPP_INCLUDED_
|
||||
#define BOOST_LOG_ATTRIBUTES_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
|
||||
#include <boost/log/attributes/attribute.hpp>
|
||||
#include <boost/log/attributes/clock.hpp>
|
||||
#include <boost/log/attributes/constant.hpp>
|
||||
#include <boost/log/attributes/counter.hpp>
|
||||
#include <boost/log/attributes/function.hpp>
|
||||
#include <boost/log/attributes/mutable_constant.hpp>
|
||||
#include <boost/log/attributes/named_scope.hpp>
|
||||
#include <boost/log/attributes/timer.hpp>
|
||||
#include <boost/log/attributes/current_process_name.hpp>
|
||||
#include <boost/log/attributes/current_process_id.hpp>
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
#include <boost/log/attributes/current_thread_id.hpp>
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#endif // BOOST_LOG_ATTRIBUTES_HPP_INCLUDED_
|
||||
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
* 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 attribute.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 15.04.2007
|
||||
*
|
||||
* The header contains attribute interface definition.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_ATTRIBUTES_ATTRIBUTE_HPP_INCLUDED_
|
||||
#define BOOST_LOG_ATTRIBUTES_ATTRIBUTE_HPP_INCLUDED_
|
||||
|
||||
#include <new>
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/smart_ptr/intrusive_ptr.hpp>
|
||||
#include <boost/smart_ptr/intrusive_ref_counter.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/utility/explicit_operator_bool.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
class attribute_value;
|
||||
|
||||
namespace aux {
|
||||
|
||||
//! Reference proxy object to implement \c operator[]
|
||||
class attribute_set_reference_proxy;
|
||||
|
||||
} // namespace aux
|
||||
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
/*!
|
||||
* \brief A base class for an attribute value factory
|
||||
*
|
||||
* Every attribute is represented with a factory that is basically an attribute value generator.
|
||||
* The sole purpose of an attribute is to return an actual value when requested. A simplest attribute
|
||||
* can always return the same value that it stores internally, but more complex ones can
|
||||
* perform a considerable amount of work to return a value, and the returned values may differ
|
||||
* each time requested.
|
||||
*
|
||||
* A word about thread safety. An attribute should be prepared to be requested a value from
|
||||
* multiple threads concurrently.
|
||||
*/
|
||||
class attribute
|
||||
{
|
||||
BOOST_COPYABLE_AND_MOVABLE(attribute)
|
||||
|
||||
public:
|
||||
/*!
|
||||
* \brief A base class for an attribute value factory
|
||||
*
|
||||
* All attributes must derive their implementation from this class.
|
||||
*/
|
||||
struct BOOST_LOG_NO_VTABLE BOOST_SYMBOL_VISIBLE impl :
|
||||
public boost::intrusive_ref_counter< impl >
|
||||
{
|
||||
/*!
|
||||
* \brief Virtual destructor
|
||||
*/
|
||||
virtual ~impl() {}
|
||||
|
||||
/*!
|
||||
* \return The actual attribute value. It shall not return empty values (exceptions
|
||||
* shall be used to indicate errors).
|
||||
*/
|
||||
virtual attribute_value get_value() = 0;
|
||||
|
||||
BOOST_LOG_API static void* operator new (std::size_t size);
|
||||
BOOST_LOG_API static void operator delete (void* p, std::size_t size) BOOST_NOEXCEPT;
|
||||
};
|
||||
|
||||
private:
|
||||
//! Pointer to the attribute factory implementation
|
||||
intrusive_ptr< impl > m_pImpl;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Default constructor. Creates an empty attribute value factory, which is not usable until
|
||||
* \c set_impl is called.
|
||||
*/
|
||||
BOOST_DEFAULTED_FUNCTION(attribute(), {})
|
||||
|
||||
/*!
|
||||
* Copy constructor
|
||||
*/
|
||||
attribute(attribute const& that) BOOST_NOEXCEPT : m_pImpl(that.m_pImpl) {}
|
||||
|
||||
/*!
|
||||
* Move constructor
|
||||
*/
|
||||
attribute(BOOST_RV_REF(attribute) that) BOOST_NOEXCEPT { m_pImpl.swap(that.m_pImpl); }
|
||||
|
||||
/*!
|
||||
* Initializing constructor
|
||||
*
|
||||
* \param p Pointer to the implementation. Must not be \c NULL.
|
||||
*/
|
||||
explicit attribute(intrusive_ptr< impl > p) BOOST_NOEXCEPT { m_pImpl.swap(p); }
|
||||
|
||||
/*!
|
||||
* Copy assignment
|
||||
*/
|
||||
attribute& operator= (BOOST_COPY_ASSIGN_REF(attribute) that) BOOST_NOEXCEPT
|
||||
{
|
||||
m_pImpl = that.m_pImpl;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Move assignment
|
||||
*/
|
||||
attribute& operator= (BOOST_RV_REF(attribute) that) BOOST_NOEXCEPT
|
||||
{
|
||||
m_pImpl.swap(that.m_pImpl);
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
attribute& operator= (aux::attribute_set_reference_proxy const& that) BOOST_NOEXCEPT;
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Verifies that the factory is not in empty state
|
||||
*/
|
||||
BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
|
||||
|
||||
/*!
|
||||
* Verifies that the factory is in empty state
|
||||
*/
|
||||
bool operator! () const BOOST_NOEXCEPT { return !m_pImpl; }
|
||||
|
||||
/*!
|
||||
* \return The actual attribute value. It shall not return empty values (exceptions
|
||||
* shall be used to indicate errors).
|
||||
*/
|
||||
attribute_value get_value() const;
|
||||
|
||||
/*!
|
||||
* The method swaps two factories (i.e. their implementations).
|
||||
*/
|
||||
void swap(attribute& that) BOOST_NOEXCEPT { m_pImpl.swap(that.m_pImpl); }
|
||||
|
||||
protected:
|
||||
/*!
|
||||
* \returns The pointer to the implementation
|
||||
*/
|
||||
impl* get_impl() const BOOST_NOEXCEPT { return m_pImpl.get(); }
|
||||
/*!
|
||||
* Sets the pointer to the factory implementation.
|
||||
*
|
||||
* \param p Pointer to the implementation. Must not be \c NULL.
|
||||
*/
|
||||
void set_impl(intrusive_ptr< impl > p) BOOST_NOEXCEPT { m_pImpl.swap(p); }
|
||||
|
||||
template< typename T >
|
||||
friend T attribute_cast(attribute const&);
|
||||
};
|
||||
|
||||
/*!
|
||||
* The function swaps two attribute value factories
|
||||
*/
|
||||
inline void swap(attribute& left, attribute& right) BOOST_NOEXCEPT
|
||||
{
|
||||
left.swap(right);
|
||||
}
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
#if defined(BOOST_LOG_ATTRIBUTES_ATTRIBUTE_VALUE_HPP_INCLUDED_)
|
||||
#include <boost/log/detail/attribute_get_value_impl.hpp>
|
||||
#endif
|
||||
|
||||
#endif // BOOST_LOG_ATTRIBUTES_ATTRIBUTE_HPP_INCLUDED_
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 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 attribute_cast.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 06.08.2010
|
||||
*
|
||||
* The header contains utilities for casting between attribute factories.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_ATTRIBUTES_ATTRIBUTE_CAST_HPP_INCLUDED_
|
||||
#define BOOST_LOG_ATTRIBUTES_ATTRIBUTE_CAST_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/attributes/attribute.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace attributes {
|
||||
|
||||
/*!
|
||||
* The class holds a reference to the attribute factory implementation being casted
|
||||
*/
|
||||
class cast_source
|
||||
{
|
||||
private:
|
||||
attribute::impl* m_pImpl;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Initializing constructor. Creates a source that refers to the specified factory implementation.
|
||||
*/
|
||||
explicit cast_source(attribute::impl* p) : m_pImpl(p)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* The function attempts to cast the aggregated pointer to the implementation to the specified type.
|
||||
*
|
||||
* \return The converted pointer or \c NULL, if the conversion fails.
|
||||
*/
|
||||
template< typename T >
|
||||
T* as() const { return dynamic_cast< T* >(m_pImpl); }
|
||||
};
|
||||
|
||||
} // namespace attributes
|
||||
|
||||
/*!
|
||||
* The function casts one attribute factory to another
|
||||
*/
|
||||
template< typename T >
|
||||
inline T attribute_cast(attribute const& attr)
|
||||
{
|
||||
return T(attributes::cast_source(attr.get_impl()));
|
||||
}
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_ATTRIBUTES_ATTRIBUTE_CAST_HPP_INCLUDED_
|
||||
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
* 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 attribute_name.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 28.06.2010
|
||||
*
|
||||
* The header contains attribute name interface definition.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_ATTRIBUTE_NAME_HPP_INCLUDED_
|
||||
#define BOOST_LOG_ATTRIBUTE_NAME_HPP_INCLUDED_
|
||||
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/utility/explicit_operator_bool.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
/*!
|
||||
* \brief The class represents an attribute name in containers used by the library
|
||||
*
|
||||
* The class mostly serves for optimization purposes. Each attribute name that is used
|
||||
* with the library is automatically associated with a unique identifier, which is much
|
||||
* lighter in terms of memory footprint and operations complexity. This is done
|
||||
* transparently by this class, on object construction. Passing objects of this class
|
||||
* to other library methods, such as attribute lookup functions, will not require
|
||||
* this translation and/or string copying and thus will result in a more efficient code.
|
||||
*/
|
||||
class attribute_name
|
||||
{
|
||||
public:
|
||||
//! String type
|
||||
typedef std::string string_type;
|
||||
#ifdef BOOST_LOG_DOXYGEN_PASS
|
||||
//! Associated identifier
|
||||
typedef unspecified id_type;
|
||||
#else
|
||||
typedef uint32_t id_type;
|
||||
|
||||
private:
|
||||
enum { uninitialized = 0xFFFFFFFFu };
|
||||
|
||||
class repository;
|
||||
friend class repository;
|
||||
|
||||
private:
|
||||
//! Associated identifier
|
||||
id_type m_id;
|
||||
#endif
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Default constructor. Creates an object that does not refer to any attribute name.
|
||||
*/
|
||||
BOOST_CONSTEXPR attribute_name() BOOST_NOEXCEPT : m_id(static_cast< id_type >(uninitialized))
|
||||
{
|
||||
}
|
||||
/*!
|
||||
* Constructs an attribute name from the specified string
|
||||
*
|
||||
* \param name An attribute name
|
||||
* \pre \a name is not NULL and points to a zero-terminated string
|
||||
*/
|
||||
attribute_name(const char* name) :
|
||||
m_id(get_id_from_string(name))
|
||||
{
|
||||
}
|
||||
/*!
|
||||
* Constructs an attribute name from the specified string
|
||||
*
|
||||
* \param name An attribute name
|
||||
*/
|
||||
attribute_name(string_type const& name) :
|
||||
m_id(get_id_from_string(name.c_str()))
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* Compares the attribute names
|
||||
*
|
||||
* \return \c true if <tt>*this</tt> and \c that refer to the same attribute name,
|
||||
* and \c false otherwise.
|
||||
*/
|
||||
bool operator== (attribute_name const& that) const BOOST_NOEXCEPT { return m_id == that.m_id; }
|
||||
/*!
|
||||
* Compares the attribute names
|
||||
*
|
||||
* \return \c true if <tt>*this</tt> and \c that refer to different attribute names,
|
||||
* and \c false otherwise.
|
||||
*/
|
||||
bool operator!= (attribute_name const& that) const BOOST_NOEXCEPT { return m_id != that.m_id; }
|
||||
|
||||
/*!
|
||||
* Compares the attribute names
|
||||
*
|
||||
* \return \c true if <tt>*this</tt> and \c that refer to the same attribute name,
|
||||
* and \c false otherwise.
|
||||
*/
|
||||
bool operator== (const char* that) const { return (m_id != static_cast< id_type >(uninitialized)) && (this->string() == that); }
|
||||
/*!
|
||||
* Compares the attribute names
|
||||
*
|
||||
* \return \c true if <tt>*this</tt> and \c that refer to different attribute names,
|
||||
* and \c false otherwise.
|
||||
*/
|
||||
bool operator!= (const char* that) const { return !operator== (that); }
|
||||
|
||||
/*!
|
||||
* Compares the attribute names
|
||||
*
|
||||
* \return \c true if <tt>*this</tt> and \c that refer to the same attribute name,
|
||||
* and \c false otherwise.
|
||||
*/
|
||||
bool operator== (string_type const& that) const { return (m_id != static_cast< id_type >(uninitialized)) && (this->string() == that); }
|
||||
/*!
|
||||
* Compares the attribute names
|
||||
*
|
||||
* \return \c true if <tt>*this</tt> and \c that refer to different attribute names,
|
||||
* and \c false otherwise.
|
||||
*/
|
||||
bool operator!= (string_type const& that) const { return !operator== (that); }
|
||||
|
||||
/*!
|
||||
* Checks if the object was default-constructed
|
||||
*
|
||||
* \return \c true if <tt>*this</tt> was constructed with an attribute name, \c false otherwise
|
||||
*/
|
||||
BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
|
||||
/*!
|
||||
* Checks if the object was default-constructed
|
||||
*
|
||||
* \return \c true if <tt>*this</tt> was default-constructed and does not refer to any attribute name,
|
||||
* \c false otherwise
|
||||
*/
|
||||
bool operator! () const BOOST_NOEXCEPT { return (m_id == static_cast< id_type >(uninitialized)); }
|
||||
|
||||
/*!
|
||||
* \return The associated id value
|
||||
* \pre <tt>(!*this) == false</tt>
|
||||
*/
|
||||
id_type id() const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_ASSERT(m_id != static_cast< id_type >(uninitialized));
|
||||
return m_id;
|
||||
}
|
||||
/*!
|
||||
* \return The attribute name string that was used during the object construction
|
||||
* \pre <tt>(!*this) == false</tt>
|
||||
*/
|
||||
string_type const& string() const { return get_string_from_id(m_id); }
|
||||
|
||||
private:
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
static BOOST_LOG_API id_type get_id_from_string(const char* name);
|
||||
static BOOST_LOG_API string_type const& get_string_from_id(id_type id);
|
||||
#endif
|
||||
};
|
||||
|
||||
template< typename CharT, typename TraitsT >
|
||||
BOOST_LOG_API std::basic_ostream< CharT, TraitsT >& operator<< (
|
||||
std::basic_ostream< CharT, TraitsT >& strm,
|
||||
attribute_name const& name);
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_ATTRIBUTE_NAME_HPP_INCLUDED_
|
||||
@@ -0,0 +1,514 @@
|
||||
/*
|
||||
* 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 attribute_set.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 08.03.2007
|
||||
*
|
||||
* This header contains definition of the attribute set container.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_ATTRIBUTE_SET_HPP_INCLUDED_
|
||||
#define BOOST_LOG_ATTRIBUTE_SET_HPP_INCLUDED_
|
||||
|
||||
#include <cstddef>
|
||||
#include <utility>
|
||||
#include <iterator>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/attributes/attribute_name.hpp>
|
||||
#include <boost/log/attributes/attribute.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
class attribute_set;
|
||||
class attribute_value_set;
|
||||
|
||||
namespace aux {
|
||||
|
||||
//! Reference proxy object to implement \c operator[]
|
||||
class attribute_set_reference_proxy
|
||||
{
|
||||
private:
|
||||
//! Key type
|
||||
typedef attribute_name key_type;
|
||||
//! Mapped attribute type
|
||||
typedef attribute mapped_type;
|
||||
|
||||
private:
|
||||
attribute_set* const m_pContainer;
|
||||
const key_type m_key;
|
||||
|
||||
public:
|
||||
//! Constructor
|
||||
explicit attribute_set_reference_proxy(attribute_set* pContainer, key_type const& key) BOOST_NOEXCEPT :
|
||||
m_pContainer(pContainer),
|
||||
m_key(key)
|
||||
{
|
||||
}
|
||||
|
||||
//! Conversion operator (would be invoked in case of reading from the container)
|
||||
BOOST_FORCEINLINE operator mapped_type() const BOOST_NOEXCEPT
|
||||
{
|
||||
return read_mapped_value();
|
||||
}
|
||||
//! Assignment operator (would be invoked in case of writing to the container)
|
||||
mapped_type& operator= (mapped_type const& val) const;
|
||||
|
||||
private:
|
||||
//! Reads the referenced mapped value from the container
|
||||
mapped_type read_mapped_value() const BOOST_NOEXCEPT;
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
/*!
|
||||
* \brief An attribute set class.
|
||||
*
|
||||
* An attribute set is an associative container with attribute name as a key and
|
||||
* pointer to the attribute as a mapped value. The container allows storing only one element for each distinct
|
||||
* key value. In most regards attribute set container provides interface similar to \c std::unordered_map.
|
||||
* However, there are differences in \c operator[] semantics and a number of optimizations with regard to iteration.
|
||||
* Besides, attribute names are stored as a read-only <tt>attribute_name</tt>'s instead of \c std::string,
|
||||
* which saves memory and CPU time.
|
||||
*/
|
||||
class attribute_set
|
||||
{
|
||||
BOOST_COPYABLE_AND_MOVABLE_ALT(attribute_set)
|
||||
|
||||
friend class attribute_value_set;
|
||||
friend class aux::attribute_set_reference_proxy;
|
||||
|
||||
public:
|
||||
//! Key type
|
||||
typedef attribute_name key_type;
|
||||
//! Mapped attribute type
|
||||
typedef attribute mapped_type;
|
||||
|
||||
//! Value type
|
||||
typedef std::pair< const key_type, mapped_type > value_type;
|
||||
//! Reference type
|
||||
typedef value_type& reference;
|
||||
//! Const reference type
|
||||
typedef value_type const& const_reference;
|
||||
//! Pointer type
|
||||
typedef value_type* pointer;
|
||||
//! Const pointer type
|
||||
typedef value_type const* const_pointer;
|
||||
//! Size type
|
||||
typedef std::size_t size_type;
|
||||
//! Difference type
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
private:
|
||||
//! \cond
|
||||
|
||||
//! Implementation
|
||||
struct implementation;
|
||||
friend struct implementation;
|
||||
|
||||
//! A base class for the container nodes
|
||||
struct node_base
|
||||
{
|
||||
node_base* m_pPrev;
|
||||
node_base* m_pNext;
|
||||
|
||||
node_base();
|
||||
|
||||
BOOST_DELETED_FUNCTION(node_base(node_base const&))
|
||||
BOOST_DELETED_FUNCTION(node_base& operator= (node_base const&))
|
||||
};
|
||||
|
||||
//! Container elements
|
||||
struct node;
|
||||
friend struct node;
|
||||
struct node :
|
||||
public node_base
|
||||
{
|
||||
value_type m_Value;
|
||||
|
||||
node(key_type const& key, mapped_type const& data);
|
||||
};
|
||||
|
||||
//! Iterator class
|
||||
#ifndef BOOST_LOG_NO_MEMBER_TEMPLATE_FRIENDS
|
||||
template< bool fConstV > class iter;
|
||||
template< bool fConstV > friend class iter;
|
||||
#endif
|
||||
template< bool fConstV >
|
||||
class iter
|
||||
{
|
||||
friend class iter< !fConstV >;
|
||||
friend class attribute_set;
|
||||
|
||||
public:
|
||||
// Standard typedefs
|
||||
typedef attribute_set::difference_type difference_type;
|
||||
typedef attribute_set::value_type value_type;
|
||||
typedef typename mpl::if_c<
|
||||
fConstV,
|
||||
attribute_set::const_reference,
|
||||
attribute_set::reference
|
||||
>::type reference;
|
||||
typedef typename mpl::if_c<
|
||||
fConstV,
|
||||
attribute_set::const_pointer,
|
||||
attribute_set::pointer
|
||||
>::type pointer;
|
||||
typedef std::bidirectional_iterator_tag iterator_category;
|
||||
|
||||
public:
|
||||
// Constructors
|
||||
BOOST_CONSTEXPR iter() : m_pNode(NULL) {}
|
||||
explicit iter(node_base* pNode) BOOST_NOEXCEPT : m_pNode(pNode) {}
|
||||
iter(iter< false > const& that) BOOST_NOEXCEPT : m_pNode(that.m_pNode) {}
|
||||
|
||||
//! Assignment
|
||||
template< bool f >
|
||||
iter& operator= (iter< f > const& that) BOOST_NOEXCEPT
|
||||
{
|
||||
m_pNode = that.m_pNode;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Comparison
|
||||
template< bool f >
|
||||
bool operator== (iter< f > const& that) const BOOST_NOEXCEPT { return (m_pNode == that.m_pNode); }
|
||||
template< bool f >
|
||||
bool operator!= (iter< f > const& that) const BOOST_NOEXCEPT { return (m_pNode != that.m_pNode); }
|
||||
|
||||
// Modification
|
||||
iter& operator++ () BOOST_NOEXCEPT
|
||||
{
|
||||
m_pNode = m_pNode->m_pNext;
|
||||
return *this;
|
||||
}
|
||||
iter& operator-- () BOOST_NOEXCEPT
|
||||
{
|
||||
m_pNode = m_pNode->m_pPrev;
|
||||
return *this;
|
||||
}
|
||||
iter operator++ (int) BOOST_NOEXCEPT
|
||||
{
|
||||
iter tmp(*this);
|
||||
m_pNode = m_pNode->m_pNext;
|
||||
return tmp;
|
||||
}
|
||||
iter operator-- (int) BOOST_NOEXCEPT
|
||||
{
|
||||
iter tmp(*this);
|
||||
m_pNode = m_pNode->m_pPrev;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// Dereferencing
|
||||
pointer operator-> () const BOOST_NOEXCEPT { return &(static_cast< node* >(m_pNode)->m_Value); }
|
||||
reference operator* () const BOOST_NOEXCEPT { return static_cast< node* >(m_pNode)->m_Value; }
|
||||
|
||||
node_base* base() const BOOST_NOEXCEPT { return m_pNode; }
|
||||
|
||||
private:
|
||||
node_base* m_pNode;
|
||||
};
|
||||
|
||||
//! \endcond
|
||||
|
||||
public:
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
//! Iterator type
|
||||
typedef iter< false > iterator;
|
||||
//! Const iterator type
|
||||
typedef iter< true > const_iterator;
|
||||
#else
|
||||
/*!
|
||||
* Iterator type. The iterator complies to the bidirectional iterator requirements.
|
||||
*/
|
||||
typedef implementation_defined iterator;
|
||||
/*!
|
||||
* Constant iterator type. The iterator complies to the bidirectional iterator requirements with read-only capabilities.
|
||||
*/
|
||||
typedef implementation_defined const_iterator;
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
private:
|
||||
//! Pointer to implementation
|
||||
implementation* m_pImpl;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Default constructor.
|
||||
*
|
||||
* \post <tt>empty() == true</tt>
|
||||
*/
|
||||
BOOST_LOG_API attribute_set();
|
||||
|
||||
/*!
|
||||
* Copy constructor.
|
||||
*
|
||||
* \post <tt>size() == that.size() && std::equal(begin(), end(), that.begin()) == true</tt>
|
||||
*/
|
||||
BOOST_LOG_API attribute_set(attribute_set const& that);
|
||||
|
||||
/*!
|
||||
* Move constructor
|
||||
*/
|
||||
attribute_set(BOOST_RV_REF(attribute_set) that) BOOST_NOEXCEPT : m_pImpl(that.m_pImpl)
|
||||
{
|
||||
that.m_pImpl = NULL;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Destructor. All stored references to attributes are released.
|
||||
*/
|
||||
BOOST_LOG_API ~attribute_set() BOOST_NOEXCEPT;
|
||||
|
||||
/*!
|
||||
* Copy assignment operator.
|
||||
*
|
||||
* \post <tt>size() == that.size() && std::equal(begin(), end(), that.begin()) == true</tt>
|
||||
*/
|
||||
attribute_set& operator= (attribute_set that) BOOST_NOEXCEPT
|
||||
{
|
||||
this->swap(that);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Swaps two instances of the container.
|
||||
*
|
||||
* \b Throws: Nothing.
|
||||
*/
|
||||
void swap(attribute_set& that) BOOST_NOEXCEPT
|
||||
{
|
||||
implementation* const p = m_pImpl;
|
||||
m_pImpl = that.m_pImpl;
|
||||
that.m_pImpl = p;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \return Iterator to the first element of the container.
|
||||
*/
|
||||
BOOST_LOG_API iterator begin() BOOST_NOEXCEPT;
|
||||
/*!
|
||||
* \return Iterator to the after-the-last element of the container.
|
||||
*/
|
||||
BOOST_LOG_API iterator end() BOOST_NOEXCEPT;
|
||||
/*!
|
||||
* \return Constant iterator to the first element of the container.
|
||||
*/
|
||||
BOOST_LOG_API const_iterator begin() const BOOST_NOEXCEPT;
|
||||
/*!
|
||||
* \return Constant iterator to the after-the-last element of the container.
|
||||
*/
|
||||
BOOST_LOG_API const_iterator end() const BOOST_NOEXCEPT;
|
||||
|
||||
/*!
|
||||
* \return Number of elements in the container.
|
||||
*/
|
||||
BOOST_LOG_API size_type size() const BOOST_NOEXCEPT;
|
||||
/*!
|
||||
* \return true if there are no elements in the container, false otherwise.
|
||||
*/
|
||||
bool empty() const BOOST_NOEXCEPT { return (this->size() == 0); }
|
||||
|
||||
/*!
|
||||
* The method finds the attribute by name.
|
||||
*
|
||||
* \param key Attribute name.
|
||||
* \return Iterator to the found element or end() if the attribute with such name is not found.
|
||||
*/
|
||||
BOOST_LOG_API iterator find(key_type key) BOOST_NOEXCEPT;
|
||||
/*!
|
||||
* The method finds the attribute by name.
|
||||
*
|
||||
* \param key Attribute name.
|
||||
* \return Iterator to the found element or \c end() if the attribute with such name is not found.
|
||||
*/
|
||||
const_iterator find(key_type key) const BOOST_NOEXCEPT
|
||||
{
|
||||
return const_iterator(const_cast< attribute_set* >(this)->find(key));
|
||||
}
|
||||
/*!
|
||||
* The method counts the number of the attribute occurrences in the container. Since there can be only one
|
||||
* attribute with a particular key, the method always return 0 or 1.
|
||||
*
|
||||
* \param key Attribute name.
|
||||
* \return The number of times the attribute is found in the container.
|
||||
*/
|
||||
size_type count(key_type key) const BOOST_NOEXCEPT { return size_type(this->find(key) != this->end()); }
|
||||
|
||||
/*!
|
||||
* Combined lookup/insertion operator. The operator semantics depends on the further usage of the returned reference.
|
||||
* \li If the reference is used as an assignment target, the assignment expression is equivalent to element insertion,
|
||||
* where the element is composed of the second argument of the \c operator[] as a key and the second argument of assignment
|
||||
* as a mapped value.
|
||||
* \li If the returned reference is used in context where a conversion to the mapped type is required,
|
||||
* the result of the conversion is equivalent to the mapped value found with the second argument of the \c operator[] as a key,
|
||||
* if such an element exists in the container, or a default-constructed mapped value, if an element does not exist in the
|
||||
* container.
|
||||
*
|
||||
* \param key Attribute name.
|
||||
* \return A smart reference object of unspecified type.
|
||||
*/
|
||||
aux::attribute_set_reference_proxy operator[] (key_type key) BOOST_NOEXCEPT
|
||||
{
|
||||
return aux::attribute_set_reference_proxy(this, key);
|
||||
}
|
||||
/*!
|
||||
* Lookup operator
|
||||
*
|
||||
* \param key Attribute name.
|
||||
* \return If an element with the corresponding attribute name is found in the container, its mapped value
|
||||
* is returned. Otherwise a default-constructed mapped value is returned.
|
||||
*/
|
||||
mapped_type operator[] (key_type key) const BOOST_NOEXCEPT
|
||||
{
|
||||
const_iterator it = this->find(key);
|
||||
if (it != end())
|
||||
return it->second;
|
||||
else
|
||||
return mapped_type();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Insertion method
|
||||
*
|
||||
* \param key Attribute name.
|
||||
* \param data Pointer to the attribute. Must not be NULL.
|
||||
* \returns A pair of values. If second is true, the insertion succeeded and the first component points to the
|
||||
* inserted element. Otherwise the first component points to the element that prevents insertion.
|
||||
*/
|
||||
BOOST_LOG_API std::pair< iterator, bool > insert(key_type key, mapped_type const& data);
|
||||
|
||||
/*!
|
||||
* Insertion method
|
||||
*
|
||||
* \param value An element to be inserted.
|
||||
* \returns A pair of values. If second is true, the insertion succeeded and the first component points to the
|
||||
* inserted element. Otherwise the first component points to the element that prevents insertion.
|
||||
*/
|
||||
std::pair< iterator, bool > insert(const_reference value)
|
||||
{
|
||||
return this->insert(value.first, value.second);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Mass insertion method.
|
||||
*
|
||||
* \param begin A forward iterator that points to the first element to be inserted.
|
||||
* \param end A forward iterator that points to the after-the-last element to be inserted.
|
||||
*/
|
||||
template< typename FwdIteratorT >
|
||||
void insert(FwdIteratorT begin, FwdIteratorT end)
|
||||
{
|
||||
for (; begin != end; ++begin)
|
||||
this->insert(*begin);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Mass insertion method with ability to acquire iterators to the inserted elements.
|
||||
*
|
||||
* \param begin A forward iterator that points to the first element to be inserted.
|
||||
* \param end A forward iterator that points to the after-the-last element to be inserted.
|
||||
* \param out An output iterator that receives results of insertion of the elements
|
||||
*/
|
||||
template< typename FwdIteratorT, typename OutputIteratorT >
|
||||
void insert(FwdIteratorT begin, FwdIteratorT end, OutputIteratorT out)
|
||||
{
|
||||
for (; begin != end; ++begin, ++out)
|
||||
*out = this->insert(*begin);
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method erases all attributes with the specified name
|
||||
*
|
||||
* \post All iterators to the erased elements become invalid.
|
||||
* \param key Attribute name.
|
||||
* \return Tne number of erased elements
|
||||
*/
|
||||
BOOST_LOG_API size_type erase(key_type key) BOOST_NOEXCEPT;
|
||||
/*!
|
||||
* The method erases the specified attribute
|
||||
*
|
||||
* \post All iterators to the erased element become invalid.
|
||||
* \param it A valid iterator to the element to be erased.
|
||||
* \return Tne number of erased elements
|
||||
*/
|
||||
BOOST_LOG_API void erase(iterator it) BOOST_NOEXCEPT;
|
||||
/*!
|
||||
* The method erases all attributes within the specified range
|
||||
*
|
||||
* \pre \a end is reachable from \a begin with a finite number of increments.
|
||||
* \post All iterators to the erased elements become invalid.
|
||||
* \param begin An iterator that points to the first element to be erased.
|
||||
* \param end An iterator that points to the after-the-last element to be erased.
|
||||
*/
|
||||
BOOST_LOG_API void erase(iterator begin, iterator end) BOOST_NOEXCEPT;
|
||||
|
||||
/*!
|
||||
* The method removes all elements from the container
|
||||
*
|
||||
* \post <tt>empty() == true</tt>
|
||||
*/
|
||||
BOOST_LOG_API void clear() BOOST_NOEXCEPT;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Free swap overload
|
||||
*/
|
||||
inline void swap(attribute_set& left, attribute_set& right) BOOST_NOEXCEPT
|
||||
{
|
||||
left.swap(right);
|
||||
}
|
||||
|
||||
namespace aux {
|
||||
|
||||
//! Reads the referenced mapped value from the container
|
||||
inline attribute_set_reference_proxy::mapped_type attribute_set_reference_proxy::read_mapped_value() const BOOST_NOEXCEPT
|
||||
{
|
||||
attribute_set::iterator it = m_pContainer->find(m_key);
|
||||
if (it != m_pContainer->end())
|
||||
return it->second;
|
||||
else
|
||||
return mapped_type();
|
||||
}
|
||||
|
||||
//! Assignment operator (would be invoked in case of writing to the container)
|
||||
inline attribute_set_reference_proxy::mapped_type& attribute_set_reference_proxy::operator= (mapped_type const& val) const
|
||||
{
|
||||
std::pair< attribute_set::iterator, bool > res = m_pContainer->insert(m_key, val);
|
||||
if (!res.second)
|
||||
res.first->second = val;
|
||||
return res.first->second;
|
||||
}
|
||||
|
||||
} // namespace aux
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
inline attribute& attribute::operator= (aux::attribute_set_reference_proxy const& that) BOOST_NOEXCEPT
|
||||
{
|
||||
attribute attr = that;
|
||||
this->swap(attr);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_ATTRIBUTE_SET_HPP_INCLUDED_
|
||||
@@ -0,0 +1,380 @@
|
||||
/*
|
||||
* 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 attribute_value.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 21.05.2010
|
||||
*
|
||||
* The header contains \c attribute_value class definition.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_ATTRIBUTE_VALUE_HPP_INCLUDED_
|
||||
#define BOOST_LOG_ATTRIBUTE_VALUE_HPP_INCLUDED_
|
||||
|
||||
#include <boost/type_index.hpp>
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/smart_ptr/intrusive_ptr.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/utility/explicit_operator_bool.hpp>
|
||||
#include <boost/log/utility/type_dispatch/type_dispatcher.hpp>
|
||||
#include <boost/log/attributes/attribute.hpp>
|
||||
#include <boost/log/attributes/value_extraction_fwd.hpp>
|
||||
#include <boost/log/attributes/value_visitation_fwd.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
/*!
|
||||
* \brief An attribute value class
|
||||
*
|
||||
* An attribute value is an object that contains a piece of data that represents an attribute state
|
||||
* at the point of the value acquisition. All major operations with log records, such as filtering and
|
||||
* formatting, involve attribute values contained in a single view. Most likely an attribute value is
|
||||
* implemented as a simple holder of some typed value. This holder implements the
|
||||
* \c attribute_value::implementation interface and acts as a pimpl for the \c attribute_value
|
||||
* object. The \c attribute_value class provides type dispatching support in order to allow
|
||||
* to extract the value from the holder.
|
||||
*
|
||||
* Normally, attributes and their values shall be designed in order to exclude as much interference as
|
||||
* reasonable. Such approach allows to have more than one attribute value simultaneously, which improves
|
||||
* scalability and allows to implement generating attributes.
|
||||
*
|
||||
* However, there are cases when this approach does not help to achieve the required level of independency
|
||||
* of attribute values and attribute itself from each other at a reasonable performance tradeoff.
|
||||
* For example, an attribute or its values may use thread-specific data, which is global and shared
|
||||
* between all the instances of the attribute/value. Passing such an attribute value to another thread
|
||||
* would be a disaster. To solve this the library defines an additional method for attribute values,
|
||||
* namely \c detach_from_thread. The \c attribute_value class forwards the call to its pimpl,
|
||||
* which is supposed to ensure that it no longer refers to any thread-specific data after the call.
|
||||
* The pimpl can create a new holder as a result of this method and return it to the \c attribute_value
|
||||
* wrapper, which will keep the returned reference for any further calls.
|
||||
* This method is called for all attribute values that are passed to another thread.
|
||||
*/
|
||||
class attribute_value
|
||||
{
|
||||
BOOST_COPYABLE_AND_MOVABLE(attribute_value)
|
||||
|
||||
public:
|
||||
/*!
|
||||
* \brief A base class for an attribute value implementation
|
||||
*
|
||||
* All attribute value holders should derive from this interface.
|
||||
*/
|
||||
struct BOOST_LOG_NO_VTABLE impl :
|
||||
public attribute::impl
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* The method dispatches the value to the given object.
|
||||
*
|
||||
* \param dispatcher The object that attempts to dispatch the stored value.
|
||||
* \return true if \a dispatcher was capable to consume the real attribute value type and false otherwise.
|
||||
*/
|
||||
virtual bool dispatch(type_dispatcher& dispatcher) = 0;
|
||||
|
||||
/*!
|
||||
* The method is called when the attribute value is passed to another thread (e.g.
|
||||
* in case of asynchronous logging). The value should ensure it properly owns all thread-specific data.
|
||||
*
|
||||
* \return An actual pointer to the attribute value. It may either point to this object or another.
|
||||
* In the latter case the returned pointer replaces the pointer used by caller to invoke this
|
||||
* method and is considered to be a functional equivalent to the previous pointer.
|
||||
*/
|
||||
virtual intrusive_ptr< impl > detach_from_thread()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \return The attribute value that refers to self implementation.
|
||||
*/
|
||||
virtual attribute_value get_value() { return attribute_value(this); }
|
||||
|
||||
/*!
|
||||
* \return The attribute value type
|
||||
*/
|
||||
virtual typeindex::type_index get_type() const { return typeindex::type_index(); }
|
||||
};
|
||||
|
||||
private:
|
||||
//! Pointer to the value implementation
|
||||
intrusive_ptr< impl > m_pImpl;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Default constructor. Creates an empty (absent) attribute value.
|
||||
*/
|
||||
BOOST_DEFAULTED_FUNCTION(attribute_value(), {})
|
||||
|
||||
/*!
|
||||
* Copy constructor
|
||||
*/
|
||||
attribute_value(attribute_value const& that) BOOST_NOEXCEPT : m_pImpl(that.m_pImpl) {}
|
||||
|
||||
/*!
|
||||
* Move constructor
|
||||
*/
|
||||
attribute_value(BOOST_RV_REF(attribute_value) that) BOOST_NOEXCEPT { m_pImpl.swap(that.m_pImpl); }
|
||||
|
||||
/*!
|
||||
* Initializing constructor. Creates an attribute value that refers to the specified holder.
|
||||
*
|
||||
* \param p A pointer to the attribute value holder.
|
||||
*/
|
||||
explicit attribute_value(intrusive_ptr< impl > p) BOOST_NOEXCEPT { m_pImpl.swap(p); }
|
||||
|
||||
/*!
|
||||
* Copy assignment
|
||||
*/
|
||||
attribute_value& operator= (BOOST_COPY_ASSIGN_REF(attribute_value) that) BOOST_NOEXCEPT
|
||||
{
|
||||
m_pImpl = that.m_pImpl;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Move assignment
|
||||
*/
|
||||
attribute_value& operator= (BOOST_RV_REF(attribute_value) that) BOOST_NOEXCEPT
|
||||
{
|
||||
m_pImpl.swap(that.m_pImpl);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* The operator checks if the attribute value is empty
|
||||
*/
|
||||
BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
|
||||
/*!
|
||||
* The operator checks if the attribute value is empty
|
||||
*/
|
||||
bool operator! () const BOOST_NOEXCEPT { return !m_pImpl; }
|
||||
|
||||
/*!
|
||||
* The method returns the type information of the stored value of the attribute.
|
||||
* The returned type info wrapper may be empty if the attribute value is empty or
|
||||
* the information cannot be provided. If the returned value is not empty, the type
|
||||
* can be used for value extraction.
|
||||
*/
|
||||
typeindex::type_index get_type() const
|
||||
{
|
||||
if (m_pImpl.get())
|
||||
return m_pImpl->get_type();
|
||||
else
|
||||
return typeindex::type_index();
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method is called when the attribute value is passed to another thread (e.g.
|
||||
* in case of asynchronous logging). The value should ensure it properly owns all thread-specific data.
|
||||
*
|
||||
* \post The attribute value no longer refers to any thread-specific resources.
|
||||
*/
|
||||
void detach_from_thread()
|
||||
{
|
||||
if (m_pImpl.get())
|
||||
m_pImpl->detach_from_thread().swap(m_pImpl);
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method dispatches the value to the given object. This method is a low level interface for
|
||||
* attribute value visitation and extraction. For typical usage these interfaces may be more convenient.
|
||||
*
|
||||
* \param dispatcher The object that attempts to dispatch the stored value.
|
||||
* \return \c true if the value is not empty and the \a dispatcher was capable to consume
|
||||
* the real attribute value type and \c false otherwise.
|
||||
*/
|
||||
bool dispatch(type_dispatcher& dispatcher) const
|
||||
{
|
||||
if (m_pImpl.get())
|
||||
return m_pImpl->dispatch(dispatcher);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
#if !defined(BOOST_LOG_DOXYGEN_PASS)
|
||||
#if !defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
|
||||
#define BOOST_LOG_AUX_VOID_DEFAULT = void
|
||||
#else
|
||||
#define BOOST_LOG_AUX_VOID_DEFAULT
|
||||
#endif
|
||||
#endif // !defined(BOOST_LOG_DOXYGEN_PASS)
|
||||
|
||||
/*!
|
||||
* The method attempts to extract the stored value, assuming the value has the specified type.
|
||||
* One can specify either a single type or an MPL type sequence, in which case the stored value
|
||||
* is checked against every type in the sequence.
|
||||
*
|
||||
* \note Include <tt>value_extraction.hpp</tt> prior to using this method.
|
||||
*
|
||||
* \return The extracted value, if the attribute value is not empty and the value is the same
|
||||
* as specified. Otherwise returns an empty value. See description of the \c result_of::extract
|
||||
* metafunction for information on the nature of the result value.
|
||||
*/
|
||||
template< typename T, typename TagT BOOST_LOG_AUX_VOID_DEFAULT >
|
||||
typename result_of::extract< T, TagT >::type extract() const;
|
||||
|
||||
/*!
|
||||
* The method attempts to extract the stored value, assuming the value has the specified type.
|
||||
* One can specify either a single type or an MPL type sequence, in which case the stored value
|
||||
* is checked against every type in the sequence.
|
||||
*
|
||||
* \note Include <tt>value_extraction.hpp</tt> prior to using this method.
|
||||
*
|
||||
* \return The extracted value, if the attribute value is not empty and the value is the same
|
||||
* as specified. Otherwise an exception is thrown. See description of the \c result_of::extract_or_throw
|
||||
* metafunction for information on the nature of the result value.
|
||||
*/
|
||||
template< typename T, typename TagT BOOST_LOG_AUX_VOID_DEFAULT >
|
||||
typename result_of::extract_or_throw< T, TagT >::type extract_or_throw() const;
|
||||
|
||||
/*!
|
||||
* The method attempts to extract the stored value, assuming the value has the specified type.
|
||||
* One can specify either a single type or an MPL type sequence, in which case the stored value
|
||||
* is checked against every type in the sequence. If extraction fails, the default value is returned.
|
||||
*
|
||||
* \note Include <tt>value_extraction.hpp</tt> prior to using this method.
|
||||
*
|
||||
* \param def_value Default value.
|
||||
*
|
||||
* \return The extracted value, if the attribute value is not empty and the value is the same
|
||||
* as specified. Otherwise returns the default value. See description of the \c result_of::extract_or_default
|
||||
* metafunction for information on the nature of the result value.
|
||||
*/
|
||||
template< typename T, typename TagT BOOST_LOG_AUX_VOID_DEFAULT >
|
||||
typename result_of::extract_or_default< T, T, TagT >::type extract_or_default(T const& def_value) const;
|
||||
|
||||
/*!
|
||||
* The method attempts to extract the stored value, assuming the value has the specified type.
|
||||
* One can specify either a single type or an MPL type sequence, in which case the stored value
|
||||
* is checked against every type in the sequence. If extraction fails, the default value is returned.
|
||||
*
|
||||
* \note Include <tt>value_extraction.hpp</tt> prior to using this method.
|
||||
*
|
||||
* \param def_value Default value.
|
||||
*
|
||||
* \return The extracted value, if the attribute value is not empty and the value is the same
|
||||
* as specified. Otherwise returns the default value. See description of the \c result_of::extract_or_default
|
||||
* metafunction for information on the nature of the result value.
|
||||
*/
|
||||
template< typename T, typename TagT BOOST_LOG_AUX_VOID_DEFAULT, typename DefaultT >
|
||||
typename result_of::extract_or_default< T, DefaultT, TagT >::type extract_or_default(DefaultT const& def_value) const;
|
||||
|
||||
#if defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
|
||||
/*!
|
||||
* The method attempts to extract the stored value, assuming the value has the specified type.
|
||||
* One can specify either a single type or an MPL type sequence, in which case the stored value
|
||||
* is checked against every type in the sequence.
|
||||
*
|
||||
* \note Include <tt>value_extraction.hpp</tt> prior to using this method.
|
||||
*
|
||||
* \return The extracted value, if the attribute value is not empty and the value is the same
|
||||
* as specified. Otherwise returns an empty value. See description of the \c result_of::extract
|
||||
* metafunction for information on the nature of the result value.
|
||||
*/
|
||||
template< typename T >
|
||||
typename result_of::extract< T >::type extract() const;
|
||||
|
||||
/*!
|
||||
* The method attempts to extract the stored value, assuming the value has the specified type.
|
||||
* One can specify either a single type or an MPL type sequence, in which case the stored value
|
||||
* is checked against every type in the sequence.
|
||||
*
|
||||
* \note Include <tt>value_extraction.hpp</tt> prior to using this method.
|
||||
*
|
||||
* \return The extracted value, if the attribute value is not empty and the value is the same
|
||||
* as specified. Otherwise an exception is thrown. See description of the \c result_of::extract_or_throw
|
||||
* metafunction for information on the nature of the result value.
|
||||
*/
|
||||
template< typename T >
|
||||
typename result_of::extract_or_throw< T >::type extract_or_throw() const;
|
||||
|
||||
/*!
|
||||
* The method attempts to extract the stored value, assuming the value has the specified type.
|
||||
* One can specify either a single type or an MPL type sequence, in which case the stored value
|
||||
* is checked against every type in the sequence. If extraction fails, the default value is returned.
|
||||
*
|
||||
* \note Include <tt>value_extraction.hpp</tt> prior to using this method.
|
||||
*
|
||||
* \param def_value Default value.
|
||||
*
|
||||
* \return The extracted value, if the attribute value is not empty and the value is the same
|
||||
* as specified. Otherwise returns the default value. See description of the \c result_of::extract_or_default
|
||||
* metafunction for information on the nature of the result value.
|
||||
*/
|
||||
template< typename T >
|
||||
typename result_of::extract_or_default< T, T >::type extract_or_default(T const& def_value) const;
|
||||
|
||||
/*!
|
||||
* The method attempts to extract the stored value, assuming the value has the specified type.
|
||||
* One can specify either a single type or an MPL type sequence, in which case the stored value
|
||||
* is checked against every type in the sequence. If extraction fails, the default value is returned.
|
||||
*
|
||||
* \note Include <tt>value_extraction.hpp</tt> prior to using this method.
|
||||
*
|
||||
* \param def_value Default value.
|
||||
*
|
||||
* \return The extracted value, if the attribute value is not empty and the value is the same
|
||||
* as specified. Otherwise returns the default value. See description of the \c result_of::extract_or_default
|
||||
* metafunction for information on the nature of the result value.
|
||||
*/
|
||||
template< typename T, typename DefaultT >
|
||||
typename result_of::extract_or_default< T, DefaultT >::type extract_or_default(DefaultT const& def_value) const;
|
||||
#endif // defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
|
||||
|
||||
#undef BOOST_LOG_AUX_VOID_DEFAULT
|
||||
|
||||
/*!
|
||||
* The method attempts to extract the stored value, assuming the value has the specified type,
|
||||
* and pass it to the \a visitor function object.
|
||||
* One can specify either a single type or an MPL type sequence, in which case the stored value
|
||||
* is checked against every type in the sequence.
|
||||
*
|
||||
* \note Include <tt>value_visitation.hpp</tt> prior to using this method.
|
||||
*
|
||||
* \param visitor A function object that will be invoked on the extracted attribute value.
|
||||
* The visitor should be capable to be called with a single argument of
|
||||
* any type of the specified types in \c T.
|
||||
*
|
||||
* \return The result of visitation.
|
||||
*/
|
||||
template< typename T, typename VisitorT >
|
||||
visitation_result visit(VisitorT visitor) const;
|
||||
|
||||
/*!
|
||||
* The method swaps two attribute values
|
||||
*/
|
||||
void swap(attribute_value& that) BOOST_NOEXCEPT
|
||||
{
|
||||
m_pImpl.swap(that.m_pImpl);
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* The function swaps two attribute values
|
||||
*/
|
||||
inline void swap(attribute_value& left, attribute_value& right) BOOST_NOEXCEPT
|
||||
{
|
||||
left.swap(right);
|
||||
}
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
#if defined(BOOST_LOG_ATTRIBUTES_ATTRIBUTE_HPP_INCLUDED_)
|
||||
#include <boost/log/detail/attribute_get_value_impl.hpp>
|
||||
#endif
|
||||
|
||||
#endif // BOOST_LOG_ATTRIBUTE_VALUE_HPP_INCLUDED_
|
||||
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* 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 attribute_value_impl.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 24.06.2007
|
||||
*
|
||||
* The header contains an implementation of a basic attribute value implementation class.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_ATTRIBUTES_ATTRIBUTE_VALUE_IMPL_HPP_INCLUDED_
|
||||
#define BOOST_LOG_ATTRIBUTES_ATTRIBUTE_VALUE_IMPL_HPP_INCLUDED_
|
||||
|
||||
#include <boost/type_index.hpp>
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/attributes/attribute_value.hpp>
|
||||
#include <boost/log/utility/type_dispatch/type_dispatcher.hpp>
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#endif
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace attributes {
|
||||
|
||||
/*!
|
||||
* \brief Basic attribute value implementation class
|
||||
*
|
||||
* This class can be used as a boilerplate for simple attribute values. The class implements all needed
|
||||
* interfaces of attribute values and allows to store a single value of the type specified as a template parameter.
|
||||
* The stored value can be dispatched with type dispatching mechanism.
|
||||
*/
|
||||
template< typename T >
|
||||
class attribute_value_impl :
|
||||
public attribute_value::impl
|
||||
{
|
||||
public:
|
||||
//! Value type
|
||||
typedef T value_type;
|
||||
|
||||
private:
|
||||
//! Attribute value
|
||||
const value_type m_value;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Constructor with initialization of the stored value
|
||||
*/
|
||||
explicit attribute_value_impl(value_type const& v) : m_value(v) {}
|
||||
/*!
|
||||
* Constructor with initialization of the stored value
|
||||
*/
|
||||
explicit attribute_value_impl(BOOST_RV_REF(value_type) v) : m_value(boost::move(v)) {}
|
||||
|
||||
/*!
|
||||
* Attribute value dispatching method.
|
||||
*
|
||||
* \param dispatcher The dispatcher that receives the stored value
|
||||
*
|
||||
* \return \c true if the value has been dispatched, \c false otherwise
|
||||
*/
|
||||
virtual bool dispatch(type_dispatcher& dispatcher)
|
||||
{
|
||||
type_dispatcher::callback< value_type > callback = dispatcher.get_callback< value_type >();
|
||||
if (callback)
|
||||
{
|
||||
callback(m_value);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \return The attribute value type
|
||||
*/
|
||||
typeindex::type_index get_type() const { return typeindex::type_id< value_type >(); }
|
||||
|
||||
/*!
|
||||
* \return Reference to the contained value.
|
||||
*/
|
||||
value_type const& get() const { return m_value; }
|
||||
};
|
||||
|
||||
/*!
|
||||
* The function creates an attribute value from the specified object.
|
||||
*/
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
|
||||
template< typename T >
|
||||
inline attribute_value make_attribute_value(T&& v)
|
||||
{
|
||||
typedef typename remove_cv< typename remove_reference< T >::type >::type value_type;
|
||||
return attribute_value(new attribute_value_impl< value_type >(boost::forward< T >(v)));
|
||||
}
|
||||
|
||||
#else // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
|
||||
template< typename T >
|
||||
inline attribute_value make_attribute_value(T const& v)
|
||||
{
|
||||
typedef typename remove_cv< T >::type value_type;
|
||||
return attribute_value(new attribute_value_impl< value_type >(v));
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
inline attribute_value make_attribute_value(rv< T > const& v)
|
||||
{
|
||||
typedef typename remove_cv< T >::type value_type;
|
||||
return attribute_value(new attribute_value_impl< value_type >(v));
|
||||
}
|
||||
|
||||
#endif // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
|
||||
} // namespace attributes
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_ATTRIBUTES_ATTRIBUTE_VALUE_IMPL_HPP_INCLUDED_
|
||||
@@ -0,0 +1,480 @@
|
||||
/*
|
||||
* 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 attribute_value_set.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 21.04.2007
|
||||
*
|
||||
* This header file contains definition of attribute value set. The set is constructed from
|
||||
* three attribute sets (global, thread-specific and source-specific) and contains attribute
|
||||
* values.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_ATTRIBUTE_VALUE_SET_HPP_INCLUDED_
|
||||
#define BOOST_LOG_ATTRIBUTE_VALUE_SET_HPP_INCLUDED_
|
||||
|
||||
#include <cstddef>
|
||||
#include <utility>
|
||||
#include <iterator>
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/attributes/attribute_name.hpp>
|
||||
#include <boost/log/attributes/attribute.hpp>
|
||||
#include <boost/log/attributes/attribute_value.hpp>
|
||||
#include <boost/log/attributes/attribute_set.hpp>
|
||||
#include <boost/log/expressions/keyword_fwd.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
/*!
|
||||
* \brief A set of attribute values
|
||||
*
|
||||
* The set of attribute values is an associative container with attribute name as a key and
|
||||
* a pointer to attribute value object as a mapped type. This is a collection of elements with unique
|
||||
* keys, that is, there can be only one attribute value with a given name in the set. With respect to
|
||||
* read-only capabilities, the set interface is close to \c std::unordered_map.
|
||||
*
|
||||
* The set is designed to be only capable of adding elements to it. Once added, the attribute value
|
||||
* cannot be removed from the set.
|
||||
*
|
||||
* An instance of attribute value set can be constructed from three attribute sets. The constructor attempts to
|
||||
* accommodate values of all attributes from the sets. The situation when a same-named attribute is found
|
||||
* in more than one attribute set is possible. This problem is solved on construction of the value set: the three
|
||||
* attribute sets have different priorities when it comes to solving conflicts.
|
||||
*
|
||||
* From the library perspective the three source attribute sets are global, thread-specific and source-specific
|
||||
* attributes, with the latter having the highest priority. This feature allows to override attributes of wider scopes
|
||||
* with the more specific ones.
|
||||
*
|
||||
* For sake of performance, the attribute values are not immediately acquired from attribute sets at construction.
|
||||
* Instead, on-demand acquisition is performed either on iterator dereferencing or on call to the \c freeze method.
|
||||
* Once acquired, the attribute value stays within the set until its destruction. This nuance does not affect
|
||||
* other set properties, such as size or lookup ability. The logging core automatically freezes the set
|
||||
* at the right point, so users should not be bothered unless they manually create attribute value sets.
|
||||
*
|
||||
* \note The attribute sets that were used for the value set construction must not be modified or destroyed
|
||||
* until the value set is frozen. Otherwise the behavior is undefined.
|
||||
*/
|
||||
class attribute_value_set
|
||||
{
|
||||
BOOST_COPYABLE_AND_MOVABLE_ALT(attribute_value_set)
|
||||
|
||||
public:
|
||||
//! Key type
|
||||
typedef attribute_name key_type;
|
||||
//! Mapped attribute type
|
||||
typedef attribute_value mapped_type;
|
||||
|
||||
//! Value type
|
||||
typedef std::pair< const key_type, mapped_type > value_type;
|
||||
//! Reference type
|
||||
typedef value_type& reference;
|
||||
//! Const reference type
|
||||
typedef value_type const& const_reference;
|
||||
//! Pointer type
|
||||
typedef value_type* pointer;
|
||||
//! Const pointer type
|
||||
typedef value_type const* const_pointer;
|
||||
//! Size type
|
||||
typedef std::size_t size_type;
|
||||
//! Pointer difference type
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
private:
|
||||
struct implementation;
|
||||
friend struct implementation;
|
||||
|
||||
//! A base class for the container nodes
|
||||
struct node_base
|
||||
{
|
||||
node_base* m_pPrev;
|
||||
node_base* m_pNext;
|
||||
|
||||
node_base();
|
||||
|
||||
BOOST_DELETED_FUNCTION(node_base(node_base const&))
|
||||
BOOST_DELETED_FUNCTION(node_base& operator= (node_base const&))
|
||||
};
|
||||
|
||||
//! Container elements
|
||||
struct node;
|
||||
friend struct node;
|
||||
struct node :
|
||||
public node_base
|
||||
{
|
||||
value_type m_Value;
|
||||
bool m_DynamicallyAllocated;
|
||||
|
||||
node(key_type const& key, mapped_type& data, bool dynamic);
|
||||
};
|
||||
|
||||
public:
|
||||
class const_iterator;
|
||||
friend class const_iterator;
|
||||
class const_iterator
|
||||
{
|
||||
public:
|
||||
// Standard typedefs
|
||||
typedef attribute_value_set::difference_type difference_type;
|
||||
typedef attribute_value_set::value_type value_type;
|
||||
typedef attribute_value_set::const_reference reference;
|
||||
typedef attribute_value_set::const_pointer pointer;
|
||||
typedef std::bidirectional_iterator_tag iterator_category;
|
||||
|
||||
public:
|
||||
// Constructors
|
||||
BOOST_CONSTEXPR const_iterator() : m_pNode(NULL), m_pContainer(NULL) {}
|
||||
explicit const_iterator(node_base* n, attribute_value_set* cont) BOOST_NOEXCEPT :
|
||||
m_pNode(n),
|
||||
m_pContainer(cont)
|
||||
{
|
||||
}
|
||||
|
||||
// Comparison
|
||||
bool operator== (const_iterator const& that) const BOOST_NOEXCEPT
|
||||
{
|
||||
return (m_pNode == that.m_pNode);
|
||||
}
|
||||
bool operator!= (const_iterator const& that) const BOOST_NOEXCEPT
|
||||
{
|
||||
return (m_pNode != that.m_pNode);
|
||||
}
|
||||
|
||||
// Modification
|
||||
const_iterator& operator++ ()
|
||||
{
|
||||
m_pContainer->freeze();
|
||||
m_pNode = m_pNode->m_pNext;
|
||||
return *this;
|
||||
}
|
||||
const_iterator& operator-- ()
|
||||
{
|
||||
m_pContainer->freeze();
|
||||
m_pNode = m_pNode->m_pPrev;
|
||||
return *this;
|
||||
}
|
||||
const_iterator operator++ (int)
|
||||
{
|
||||
const_iterator tmp(*this);
|
||||
m_pContainer->freeze();
|
||||
m_pNode = m_pNode->m_pNext;
|
||||
return tmp;
|
||||
}
|
||||
const_iterator operator-- (int)
|
||||
{
|
||||
const_iterator tmp(*this);
|
||||
m_pContainer->freeze();
|
||||
m_pNode = m_pNode->m_pPrev;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// Dereferencing
|
||||
pointer operator-> () const BOOST_NOEXCEPT { return &(static_cast< node* >(m_pNode)->m_Value); }
|
||||
reference operator* () const BOOST_NOEXCEPT { return static_cast< node* >(m_pNode)->m_Value; }
|
||||
|
||||
private:
|
||||
node_base* m_pNode;
|
||||
attribute_value_set* m_pContainer;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
/*!
|
||||
* Constant iterator type with bidirectional capabilities.
|
||||
*/
|
||||
typedef implementation_defined const_iterator;
|
||||
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
private:
|
||||
//! Pointer to the container implementation
|
||||
implementation* m_pImpl;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Default constructor
|
||||
*
|
||||
* The constructor creates an empty set which can be filled later by subsequent
|
||||
* calls of \c insert method. Optionally, the amount of storage reserved for elements
|
||||
* to be inserted may be passed to the constructor.
|
||||
* The constructed set is frozen.
|
||||
*
|
||||
* \param reserve_count Number of elements to reserve space for.
|
||||
*/
|
||||
BOOST_LOG_API explicit attribute_value_set(size_type reserve_count = 8);
|
||||
|
||||
/*!
|
||||
* Move constructor
|
||||
*/
|
||||
attribute_value_set(BOOST_RV_REF(attribute_value_set) that) BOOST_NOEXCEPT : m_pImpl(that.m_pImpl)
|
||||
{
|
||||
that.m_pImpl = NULL;
|
||||
}
|
||||
|
||||
/*!
|
||||
* The constructor adopts three attribute sets into the value set.
|
||||
* The \a source_attrs attributes have the greatest preference when a same-named
|
||||
* attribute is found in several sets, \a global_attrs has the least.
|
||||
* The constructed set is not frozen.
|
||||
*
|
||||
* \param source_attrs A set of source-specific attributes.
|
||||
* \param thread_attrs A set of thread-specific attributes.
|
||||
* \param global_attrs A set of global attributes.
|
||||
* \param reserve_count Amount of elements to reserve space for, in addition to the elements in the three attribute sets provided.
|
||||
*/
|
||||
BOOST_LOG_API attribute_value_set(
|
||||
attribute_set const& source_attrs,
|
||||
attribute_set const& thread_attrs,
|
||||
attribute_set const& global_attrs,
|
||||
size_type reserve_count = 8);
|
||||
|
||||
/*!
|
||||
* The constructor adopts three attribute sets into the value set.
|
||||
* The \a source_attrs attributes have the greatest preference when a same-named
|
||||
* attribute is found in several sets, \a global_attrs has the least.
|
||||
* The constructed set is not frozen.
|
||||
*
|
||||
* \pre The \a source_attrs set is frozen.
|
||||
*
|
||||
* \param source_attrs A set of source-specific attributes.
|
||||
* \param thread_attrs A set of thread-specific attributes.
|
||||
* \param global_attrs A set of global attributes.
|
||||
* \param reserve_count Amount of elements to reserve space for, in addition to the elements in the three attribute sets provided.
|
||||
*/
|
||||
BOOST_LOG_API attribute_value_set(
|
||||
attribute_value_set const& source_attrs,
|
||||
attribute_set const& thread_attrs,
|
||||
attribute_set const& global_attrs,
|
||||
size_type reserve_count = 8);
|
||||
|
||||
/*!
|
||||
* The constructor adopts three attribute sets into the value set.
|
||||
* The \a source_attrs attributes have the greatest preference when a same-named
|
||||
* attribute is found in several sets, \a global_attrs has the least.
|
||||
* The constructed set is not frozen.
|
||||
*
|
||||
* \pre The \a source_attrs set is frozen.
|
||||
*
|
||||
* \param source_attrs A set of source-specific attributes.
|
||||
* \param thread_attrs A set of thread-specific attributes.
|
||||
* \param global_attrs A set of global attributes.
|
||||
* \param reserve_count Amount of elements to reserve space for, in addition to the elements in the three attribute sets provided.
|
||||
*/
|
||||
attribute_value_set(
|
||||
BOOST_RV_REF(attribute_value_set) source_attrs,
|
||||
attribute_set const& thread_attrs,
|
||||
attribute_set const& global_attrs,
|
||||
size_type reserve_count = 8) : m_pImpl(NULL)
|
||||
{
|
||||
construct(static_cast< attribute_value_set& >(source_attrs), thread_attrs, global_attrs, reserve_count);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Copy constructor.
|
||||
*
|
||||
* \pre The original set is frozen.
|
||||
* \post The constructed set is frozen, <tt>std::equal(begin(), end(), that.begin()) == true</tt>
|
||||
*/
|
||||
BOOST_LOG_API attribute_value_set(attribute_value_set const& that);
|
||||
|
||||
/*!
|
||||
* Destructor. Releases all referenced attribute values.
|
||||
*/
|
||||
BOOST_LOG_API ~attribute_value_set() BOOST_NOEXCEPT;
|
||||
|
||||
/*!
|
||||
* Assignment operator
|
||||
*/
|
||||
attribute_value_set& operator= (attribute_value_set that) BOOST_NOEXCEPT
|
||||
{
|
||||
this->swap(that);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Swaps two sets
|
||||
*
|
||||
* \b Throws: Nothing.
|
||||
*/
|
||||
void swap(attribute_value_set& that) BOOST_NOEXCEPT
|
||||
{
|
||||
implementation* const p = m_pImpl;
|
||||
m_pImpl = that.m_pImpl;
|
||||
that.m_pImpl = p;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \return Iterator to the first element of the set.
|
||||
*/
|
||||
BOOST_LOG_API const_iterator begin() const;
|
||||
/*!
|
||||
* \return Iterator to the after-the-last element of the set.
|
||||
*/
|
||||
BOOST_LOG_API const_iterator end() const;
|
||||
|
||||
/*!
|
||||
* \return Number of elements in the set.
|
||||
*/
|
||||
BOOST_LOG_API size_type size() const;
|
||||
/*!
|
||||
* \return \c true if there are no elements in the container, \c false otherwise.
|
||||
*/
|
||||
bool empty() const { return (this->size() == 0); }
|
||||
|
||||
/*!
|
||||
* The method finds the attribute value by name.
|
||||
*
|
||||
* \param key Attribute name.
|
||||
* \return Iterator to the found element or \c end() if the attribute with such name is not found.
|
||||
*/
|
||||
BOOST_LOG_API const_iterator find(key_type key) const;
|
||||
|
||||
/*!
|
||||
* Alternative lookup syntax.
|
||||
*
|
||||
* \param key Attribute name.
|
||||
* \return A pointer to the attribute value if it is found with \a key, default-constructed mapped value otherwise.
|
||||
*/
|
||||
mapped_type operator[] (key_type key) const
|
||||
{
|
||||
const_iterator it = this->find(key);
|
||||
if (it != this->end())
|
||||
return it->second;
|
||||
else
|
||||
return mapped_type();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Alternative lookup syntax.
|
||||
*
|
||||
* \param keyword Attribute keyword.
|
||||
* \return A \c value_ref with extracted attribute value if it is found, empty \c value_ref otherwise.
|
||||
*/
|
||||
template< typename DescriptorT, template< typename > class ActorT >
|
||||
typename result_of::extract< typename expressions::attribute_keyword< DescriptorT, ActorT >::value_type, DescriptorT >::type
|
||||
operator[] (expressions::attribute_keyword< DescriptorT, ActorT > const& keyword) const
|
||||
{
|
||||
typedef typename expressions::attribute_keyword< DescriptorT, ActorT >::value_type attr_value_type;
|
||||
typedef typename result_of::extract< attr_value_type, DescriptorT >::type result_type;
|
||||
const_iterator it = this->find(keyword.get_name());
|
||||
if (it != this->end())
|
||||
return it->second.extract< attr_value_type, DescriptorT >();
|
||||
else
|
||||
return result_type();
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method counts the number of the attribute value occurrences in the set. Since there can be only one
|
||||
* attribute value with a particular key, the method always return 0 or 1.
|
||||
*
|
||||
* \param key Attribute name.
|
||||
* \return The number of times the attribute value is found in the container.
|
||||
*/
|
||||
size_type count(key_type key) const { return size_type(this->find(key) != this->end()); }
|
||||
|
||||
/*!
|
||||
* The method acquires values of all adopted attributes.
|
||||
*
|
||||
* \post The set is frozen.
|
||||
*/
|
||||
BOOST_LOG_API void freeze();
|
||||
|
||||
/*!
|
||||
* Inserts an element into the set. The complexity of the operation is amortized constant.
|
||||
*
|
||||
* \pre The set is frozen.
|
||||
*
|
||||
* \param key The attribute name.
|
||||
* \param mapped The attribute value.
|
||||
*
|
||||
* \returns An iterator to the inserted element and \c true if insertion succeeded. Otherwise,
|
||||
* if the set already contains a same-named attribute value, iterator to the
|
||||
* existing element and \c false.
|
||||
*/
|
||||
BOOST_LOG_API std::pair< const_iterator, bool > insert(key_type key, mapped_type const& mapped);
|
||||
|
||||
/*!
|
||||
* Inserts an element into the set. The complexity of the operation is amortized constant.
|
||||
*
|
||||
* \pre The set is frozen.
|
||||
*
|
||||
* \param value The attribute name and value.
|
||||
*
|
||||
* \returns An iterator to the inserted element and \c true if insertion succeeded. Otherwise,
|
||||
* if the set already contains a same-named attribute value, iterator to the
|
||||
* existing element and \c false.
|
||||
*/
|
||||
std::pair< const_iterator, bool > insert(const_reference value) { return this->insert(value.first, value.second); }
|
||||
|
||||
/*!
|
||||
* Mass insertion method. The complexity of the operation is linear to the number of elements inserted.
|
||||
*
|
||||
* \pre The set is frozen.
|
||||
*
|
||||
* \param begin A forward iterator that points to the first element to be inserted.
|
||||
* \param end A forward iterator that points to the after-the-last element to be inserted.
|
||||
*/
|
||||
template< typename FwdIteratorT >
|
||||
void insert(FwdIteratorT begin, FwdIteratorT end)
|
||||
{
|
||||
for (; begin != end; ++begin)
|
||||
this->insert(*begin);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Mass insertion method with ability to acquire iterators to the inserted elements.
|
||||
* The complexity of the operation is linear to the number of elements inserted times the complexity
|
||||
* of filling the \a out iterator.
|
||||
*
|
||||
* \pre The set is frozen.
|
||||
*
|
||||
* \param begin A forward iterator that points to the first element to be inserted.
|
||||
* \param end A forward iterator that points to the after-the-last element to be inserted.
|
||||
* \param out An output iterator that receives results of insertion of the elements.
|
||||
*/
|
||||
template< typename FwdIteratorT, typename OutputIteratorT >
|
||||
void insert(FwdIteratorT begin, FwdIteratorT end, OutputIteratorT out)
|
||||
{
|
||||
for (; begin != end; ++begin, ++out)
|
||||
*out = this->insert(*begin);
|
||||
}
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
private:
|
||||
//! Constructs the object by moving from \a source_attrs. This function is mostly needed to maintain ABI stable between C++03 and C++11.
|
||||
BOOST_LOG_API void construct(
|
||||
attribute_value_set& source_attrs,
|
||||
attribute_set const& thread_attrs,
|
||||
attribute_set const& global_attrs,
|
||||
size_type reserve_count);
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
};
|
||||
|
||||
/*!
|
||||
* Free swap overload
|
||||
*/
|
||||
inline void swap(attribute_value_set& left, attribute_value_set& right) BOOST_NOEXCEPT
|
||||
{
|
||||
left.swap(right);
|
||||
}
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_ATTRIBUTE_VALUE_SET_HPP_INCLUDED_
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* 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 clock.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 01.12.2007
|
||||
*
|
||||
* The header contains wall clock attribute implementation and typedefs.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_ATTRIBUTES_CLOCK_HPP_INCLUDED_
|
||||
#define BOOST_LOG_ATTRIBUTES_CLOCK_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/attributes/attribute.hpp>
|
||||
#include <boost/log/attributes/attribute_value.hpp>
|
||||
#include <boost/log/attributes/attribute_cast.hpp>
|
||||
#include <boost/log/attributes/attribute_value_impl.hpp>
|
||||
#include <boost/log/attributes/time_traits.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace attributes {
|
||||
|
||||
/*!
|
||||
* \brief A class of an attribute that makes an attribute value of the current date and time
|
||||
*
|
||||
* The attribute generates current time stamp as a value. The type of the attribute value
|
||||
* is determined with time traits passed to the class template as a template parameter.
|
||||
* The time traits provided by the library use \c boost::posix_time::ptime as the time type.
|
||||
*
|
||||
* Time traits also determine the way time is acquired. There are two types of time traits
|
||||
* provided by the library: \c utc_time_traits and \c local_time_traits. The first returns UTC time,
|
||||
* the second returns local time.
|
||||
*/
|
||||
template< typename TimeTraitsT >
|
||||
class basic_clock :
|
||||
public attribute
|
||||
{
|
||||
public:
|
||||
//! Generated value type
|
||||
typedef typename TimeTraitsT::time_type value_type;
|
||||
|
||||
protected:
|
||||
//! Attribute factory implementation
|
||||
struct BOOST_SYMBOL_VISIBLE impl :
|
||||
public attribute::impl
|
||||
{
|
||||
attribute_value get_value()
|
||||
{
|
||||
typedef attribute_value_impl< value_type > result_value;
|
||||
return attribute_value(new result_value(TimeTraitsT::get_clock()));
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Default constructor
|
||||
*/
|
||||
basic_clock() : attribute(new impl())
|
||||
{
|
||||
}
|
||||
/*!
|
||||
* Constructor for casting support
|
||||
*/
|
||||
explicit basic_clock(cast_source const& source) : attribute(source.as< impl >())
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//! Attribute that returns current UTC time
|
||||
typedef basic_clock< utc_time_traits > utc_clock;
|
||||
//! Attribute that returns current local time
|
||||
typedef basic_clock< local_time_traits > local_clock;
|
||||
|
||||
} // namespace attributes
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_ATTRIBUTES_CLOCK_HPP_INCLUDED_
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* 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 constant.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 15.04.2007
|
||||
*
|
||||
* The header contains implementation of a constant attribute.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_ATTRIBUTES_CONSTANT_HPP_INCLUDED_
|
||||
#define BOOST_LOG_ATTRIBUTES_CONSTANT_HPP_INCLUDED_
|
||||
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/embedded_string_type.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/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace attributes {
|
||||
|
||||
/*!
|
||||
* \brief A class of an attribute that holds a single constant value
|
||||
*
|
||||
* The constant is a simplest and one of the most frequently used types of attributes.
|
||||
* It stores a constant value, which it eventually returns as its value each time
|
||||
* requested.
|
||||
*/
|
||||
template< typename T >
|
||||
class constant :
|
||||
public attribute
|
||||
{
|
||||
public:
|
||||
//! Attribute value type
|
||||
typedef T value_type;
|
||||
|
||||
protected:
|
||||
//! Factory implementation
|
||||
class BOOST_SYMBOL_VISIBLE impl :
|
||||
public attribute_value_impl< value_type >
|
||||
{
|
||||
//! Base type
|
||||
typedef attribute_value_impl< value_type > base_type;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Constructor with the stored value initialization
|
||||
*/
|
||||
explicit impl(value_type const& value) : base_type(value) {}
|
||||
/*!
|
||||
* Constructor with the stored value initialization
|
||||
*/
|
||||
explicit impl(BOOST_RV_REF(value_type) value) : base_type(boost::move(value)) {}
|
||||
};
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Constructor with the stored value initialization
|
||||
*/
|
||||
explicit constant(value_type const& value) : attribute(new impl(value)) {}
|
||||
/*!
|
||||
* Constructor with the stored value initialization
|
||||
*/
|
||||
explicit constant(BOOST_RV_REF(value_type) value) : attribute(new impl(boost::move(value))) {}
|
||||
/*!
|
||||
* Constructor for casting support
|
||||
*/
|
||||
explicit constant(cast_source const& source) : attribute(source.as< impl >())
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* \return Reference to the contained value.
|
||||
*/
|
||||
value_type const& get() const
|
||||
{
|
||||
return static_cast< impl* >(this->get_impl())->get();
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* The function constructs a \c constant attribute containing the provided value.
|
||||
* The function automatically converts C string arguments to \c std::basic_string objects.
|
||||
*/
|
||||
template< typename T >
|
||||
inline constant<
|
||||
typename boost::log::aux::make_embedded_string_type<
|
||||
typename remove_reference< T >::type
|
||||
>::type
|
||||
> make_constant(BOOST_FWD_REF(T) val)
|
||||
{
|
||||
typedef typename boost::log::aux::make_embedded_string_type<
|
||||
typename remove_reference< T >::type
|
||||
>::type value_type;
|
||||
return constant< value_type >(boost::forward< T >(val));
|
||||
}
|
||||
|
||||
} // namespace attributes
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_ATTRIBUTES_CONSTANT_HPP_INCLUDED_
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* 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 counter.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 01.05.2007
|
||||
*
|
||||
* The header contains implementation of the counter attribute.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_ATTRIBUTES_COUNTER_HPP_INCLUDED_
|
||||
#define BOOST_LOG_ATTRIBUTES_COUNTER_HPP_INCLUDED_
|
||||
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/attributes/attribute.hpp>
|
||||
#include <boost/log/attributes/attribute_cast.hpp>
|
||||
#include <boost/log/attributes/attribute_value_impl.hpp>
|
||||
#ifndef BOOST_LOG_NO_THREADS
|
||||
#include <boost/memory_order.hpp>
|
||||
#include <boost/atomic/atomic.hpp>
|
||||
#endif // 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 attributes {
|
||||
|
||||
/*!
|
||||
* \brief A class of an attribute that counts an integral value
|
||||
*
|
||||
* This attribute acts as a counter - it returns a monotonously
|
||||
* changing value each time requested. The attribute value type can be specified
|
||||
* as a template parameter. The type must be an integral type.
|
||||
*/
|
||||
template< typename T >
|
||||
class counter :
|
||||
public attribute
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(is_integral< T >::value, "Boost.Log: Only integral types are supported by the counter attribute");
|
||||
|
||||
public:
|
||||
//! A counter value type
|
||||
typedef T value_type;
|
||||
|
||||
protected:
|
||||
//! Factory implementation
|
||||
class BOOST_SYMBOL_VISIBLE impl :
|
||||
public attribute::impl
|
||||
{
|
||||
private:
|
||||
#ifndef BOOST_LOG_NO_THREADS
|
||||
boost::atomic< value_type > m_counter;
|
||||
#else
|
||||
value_type m_counter;
|
||||
#endif
|
||||
const value_type m_step;
|
||||
|
||||
public:
|
||||
impl(value_type initial, value_type step) BOOST_NOEXCEPT :
|
||||
m_counter(initial), m_step(step)
|
||||
{
|
||||
}
|
||||
|
||||
attribute_value get_value()
|
||||
{
|
||||
#ifndef BOOST_LOG_NO_THREADS
|
||||
value_type value = m_counter.fetch_add(m_step, boost::memory_order_relaxed);
|
||||
#else
|
||||
value_type value = m_counter;
|
||||
m_counter += m_step;
|
||||
#endif
|
||||
return make_attribute_value(value);
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Constructor
|
||||
*
|
||||
* \param initial Initial value of the counter
|
||||
* \param step Changing step of the counter. Each value acquired from the attribute
|
||||
* will be greater than the previous one by this amount.
|
||||
*/
|
||||
explicit counter(value_type initial = (value_type)0, value_type step = (value_type)1) :
|
||||
attribute(new impl(initial, step))
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* Constructor for casting support
|
||||
*/
|
||||
explicit counter(cast_source const& source) :
|
||||
attribute(source.as< impl >())
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace attributes
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_ATTRIBUTES_COUNTER_HPP_INCLUDED_
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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 current_process_id.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 12.09.2009
|
||||
*
|
||||
* The header contains implementation of a current process id attribute
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_ATTRIBUTES_CURRENT_PROCESS_ID_HPP_INCLUDED_
|
||||
#define BOOST_LOG_ATTRIBUTES_CURRENT_PROCESS_ID_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/process_id.hpp>
|
||||
#include <boost/log/attributes/constant.hpp>
|
||||
#include <boost/log/attributes/attribute_cast.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
//! Process identifier type used by the library
|
||||
typedef boost::log::aux::process::id process_id;
|
||||
|
||||
namespace attributes {
|
||||
|
||||
/*!
|
||||
* \brief A class of an attribute that holds the current process identifier
|
||||
*/
|
||||
class current_process_id :
|
||||
public constant< process_id >
|
||||
{
|
||||
typedef constant< process_id > base_type;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Constructor. Initializes the attribute with the current process identifier.
|
||||
*/
|
||||
current_process_id() : base_type(boost::log::aux::this_process::get_id()) {}
|
||||
/*!
|
||||
* Constructor for casting support
|
||||
*/
|
||||
explicit current_process_id(cast_source const& source) :
|
||||
base_type(source)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace attributes
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_ATTRIBUTES_CURRENT_PROCESS_ID_HPP_INCLUDED_
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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 current_process_name.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 29.07.2012
|
||||
*
|
||||
* The header contains implementation of a current process name attribute
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_ATTRIBUTES_CURRENT_PROCESS_NAME_HPP_INCLUDED_
|
||||
#define BOOST_LOG_ATTRIBUTES_CURRENT_PROCESS_NAME_HPP_INCLUDED_
|
||||
|
||||
#include <string>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/attributes/constant.hpp>
|
||||
#include <boost/log/attributes/attribute_cast.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace aux {
|
||||
|
||||
//! The function returns the current process name
|
||||
BOOST_LOG_API std::string get_process_name();
|
||||
|
||||
} // namespace aux
|
||||
|
||||
namespace attributes {
|
||||
|
||||
/*!
|
||||
* \brief A class of an attribute that holds the current process name
|
||||
*/
|
||||
class current_process_name :
|
||||
public constant< std::string >
|
||||
{
|
||||
typedef constant< std::string > base_type;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Constructor. Initializes the attribute with the current process name.
|
||||
*/
|
||||
current_process_name() : base_type(boost::log::aux::get_process_name()) {}
|
||||
/*!
|
||||
* Constructor for casting support
|
||||
*/
|
||||
explicit current_process_name(cast_source const& source) :
|
||||
base_type(source)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace attributes
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_ATTRIBUTES_CURRENT_PROCESS_NAME_HPP_INCLUDED_
|
||||
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* 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 current_thread_id.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 12.09.2009
|
||||
*
|
||||
* The header contains implementation of a current thread id attribute
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_ATTRIBUTES_CURRENT_THREAD_ID_HPP_INCLUDED_
|
||||
#define BOOST_LOG_ATTRIBUTES_CURRENT_THREAD_ID_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_LOG_NO_THREADS)
|
||||
#error Boost.Log: The current_thread_id attribute is only available in multithreaded builds
|
||||
#endif
|
||||
|
||||
#include <boost/smart_ptr/intrusive_ptr.hpp>
|
||||
#include <boost/log/detail/thread_id.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/detail/header.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
//! Thread identifier type
|
||||
typedef boost::log::aux::thread::id thread_id;
|
||||
|
||||
namespace attributes {
|
||||
|
||||
/*!
|
||||
* \brief A class of an attribute that always returns the current thread identifier
|
||||
*
|
||||
* \note This attribute can be registered globally, it will still return the correct
|
||||
* thread identifier, no matter which thread emits the log record.
|
||||
*/
|
||||
class current_thread_id :
|
||||
public attribute
|
||||
{
|
||||
public:
|
||||
//! A held attribute value type
|
||||
typedef thread_id value_type;
|
||||
|
||||
protected:
|
||||
//! Factory implementation
|
||||
class BOOST_SYMBOL_VISIBLE impl :
|
||||
public attribute_value::impl
|
||||
{
|
||||
public:
|
||||
bool dispatch(type_dispatcher& dispatcher)
|
||||
{
|
||||
type_dispatcher::callback< value_type > callback =
|
||||
dispatcher.get_callback< value_type >();
|
||||
if (callback)
|
||||
{
|
||||
callback(boost::log::aux::this_thread::get_id());
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
intrusive_ptr< attribute_value::impl > detach_from_thread()
|
||||
{
|
||||
typedef attribute_value_impl< value_type > detached_value;
|
||||
return new detached_value(boost::log::aux::this_thread::get_id());
|
||||
}
|
||||
|
||||
typeindex::type_index get_type() const { return typeindex::type_id< value_type >(); }
|
||||
};
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Default constructor
|
||||
*/
|
||||
current_thread_id() : attribute(new impl())
|
||||
{
|
||||
}
|
||||
/*!
|
||||
* Constructor for casting support
|
||||
*/
|
||||
explicit current_thread_id(cast_source const& source) :
|
||||
attribute(source.as< impl >())
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace attributes
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_ATTRIBUTES_CURRENT_THREAD_ID_HPP_INCLUDED_
|
||||
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* 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 fallback_policy.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 18.08.2012
|
||||
*
|
||||
* The header contains definition of fallback policies when attribute value visitation or extraction fails.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_ATTRIBUTES_FALLBACK_POLICY_HPP_INCLUDED_
|
||||
#define BOOST_LOG_ATTRIBUTES_FALLBACK_POLICY_HPP_INCLUDED_
|
||||
|
||||
#include <boost/type_index.hpp>
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/exceptions.hpp>
|
||||
#include <boost/log/attributes/fallback_policy_fwd.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
/*!
|
||||
* The \c fallback_to_none policy results in returning an empty value reference if the attribute value cannot be extracted.
|
||||
*/
|
||||
struct fallback_to_none
|
||||
{
|
||||
enum { guaranteed_result = false };
|
||||
|
||||
/*!
|
||||
* The method is called in order to apply a function object to the default value.
|
||||
*/
|
||||
template< typename FunT >
|
||||
static bool apply_default(FunT&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method is called in order to apply a function object to the default value.
|
||||
*/
|
||||
template< typename FunT >
|
||||
static bool apply_default(FunT const&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method is called when value extraction failed because the attribute value has different type than requested.
|
||||
*/
|
||||
static void on_invalid_type(typeindex::type_index const&)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method is called when value extraction failed because the attribute value was not found.
|
||||
*/
|
||||
static void on_missing_value()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* The \c fallback_to_throw policy results in throwing an exception if the attribute value cannot be extracted.
|
||||
*/
|
||||
struct fallback_to_throw
|
||||
{
|
||||
enum { guaranteed_result = true };
|
||||
|
||||
/*!
|
||||
* The method is called in order to apply a function object to the default value.
|
||||
*/
|
||||
template< typename FunT >
|
||||
static bool apply_default(FunT&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method is called in order to apply a function object to the default value.
|
||||
*/
|
||||
template< typename FunT >
|
||||
static bool apply_default(FunT const&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method is called when value extraction failed because the attribute value has different type than requested.
|
||||
*/
|
||||
static void on_invalid_type(typeindex::type_index const& t)
|
||||
{
|
||||
BOOST_LOG_THROW_DESCR_PARAMS(invalid_type, "Attribute value has incompatible type", (t));
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method is called when value extraction failed because the attribute value was not found.
|
||||
*/
|
||||
static void on_missing_value()
|
||||
{
|
||||
BOOST_LOG_THROW_DESCR(missing_value, "Attribute value not found");
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* The \c fallback_to_default policy results in a default value if the attribute value cannot be extracted.
|
||||
*/
|
||||
template< typename DefaultT >
|
||||
struct fallback_to_default
|
||||
{
|
||||
enum { guaranteed_result = true };
|
||||
|
||||
//! Default value type
|
||||
typedef typename remove_cv< typename remove_reference< DefaultT >::type >::type default_type;
|
||||
|
||||
/*!
|
||||
* Default constructor.
|
||||
*/
|
||||
fallback_to_default() : m_default()
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* Initializing constructor.
|
||||
*/
|
||||
explicit fallback_to_default(default_type const& def_val) : m_default(def_val)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method is called in order to apply a function object to the default value.
|
||||
*/
|
||||
template< typename FunT >
|
||||
bool apply_default(FunT& fun) const
|
||||
{
|
||||
fun(m_default);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method is called in order to apply a function object to the default value.
|
||||
*/
|
||||
template< typename FunT >
|
||||
bool apply_default(FunT const& fun) const
|
||||
{
|
||||
fun(m_default);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method is called when value extraction failed because the attribute value has different type than requested.
|
||||
*/
|
||||
static void on_invalid_type(typeindex::type_index const&)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method is called when value extraction failed because the attribute value was not found.
|
||||
*/
|
||||
static void on_missing_value()
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
//! Default value
|
||||
DefaultT m_default;
|
||||
};
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_ATTRIBUTES_FALLBACK_POLICY_HPP_INCLUDED_
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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 fallback_policy_fwd.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 18.08.2012
|
||||
*
|
||||
* The header contains forward declaration of fallback policies when attribute value visitation or extraction fails.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_ATTRIBUTES_FALLBACK_POLICY_FWD_HPP_INCLUDED_
|
||||
#define BOOST_LOG_ATTRIBUTES_FALLBACK_POLICY_FWD_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
/*!
|
||||
* The \c fallback_to_none policy results in returning an empty value reference if the attribute value cannot be extracted.
|
||||
*/
|
||||
struct fallback_to_none;
|
||||
|
||||
/*!
|
||||
* The \c fallback_to_throw policy results in throwing an exception if the attribute value cannot be extracted.
|
||||
*/
|
||||
struct fallback_to_throw;
|
||||
|
||||
/*!
|
||||
* The \c fallback_to_default policy results in a default value if the attribute value cannot be extracted.
|
||||
*/
|
||||
template< typename DefaultT >
|
||||
struct fallback_to_default;
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_LOG_ATTRIBUTES_FALLBACK_POLICY_FWD_HPP_INCLUDED_
|
||||
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* 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 function.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 24.06.2007
|
||||
*
|
||||
* The header contains implementation of an attribute that calls a third-party function on value acquisition.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_ATTRIBUTES_FUNCTION_HPP_INCLUDED_
|
||||
#define BOOST_LOG_ATTRIBUTES_FUNCTION_HPP_INCLUDED_
|
||||
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/utility/result_of.hpp>
|
||||
#include <boost/type_traits/is_void.hpp>
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/log/detail/config.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/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace attributes {
|
||||
|
||||
/*!
|
||||
* \brief A class of an attribute that acquires its value from a third-party function object
|
||||
*
|
||||
* The attribute calls a stored nullary function object to acquire each value.
|
||||
* The result type of the function object is the attribute value type.
|
||||
*
|
||||
* It is not recommended to use this class directly. Use \c make_function convenience functions
|
||||
* to construct the attribute instead.
|
||||
*/
|
||||
template< typename R >
|
||||
class function :
|
||||
public attribute
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(!is_void< R >::value, "Boost.Log: Function object return type must not be void");
|
||||
|
||||
public:
|
||||
//! The attribute value type
|
||||
typedef R value_type;
|
||||
|
||||
protected:
|
||||
//! Base class for factory implementation
|
||||
class BOOST_LOG_NO_VTABLE BOOST_SYMBOL_VISIBLE impl :
|
||||
public attribute::impl
|
||||
{
|
||||
};
|
||||
|
||||
//! Factory implementation
|
||||
template< typename T >
|
||||
class impl_template :
|
||||
public impl
|
||||
{
|
||||
private:
|
||||
//! Functor that returns attribute values
|
||||
/*!
|
||||
* \note The constness signifies that the function object should avoid
|
||||
* modifying its state since it's not protected against concurrent calls.
|
||||
*/
|
||||
const T m_Functor;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Constructor with the stored delegate initialization
|
||||
*/
|
||||
explicit impl_template(T const& fun) : m_Functor(fun) {}
|
||||
|
||||
attribute_value get_value()
|
||||
{
|
||||
return attributes::make_attribute_value(m_Functor());
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Initializing constructor
|
||||
*/
|
||||
template< typename T >
|
||||
explicit function(T const& fun) : attribute(new impl_template< T >(fun))
|
||||
{
|
||||
}
|
||||
/*!
|
||||
* Constructor for casting support
|
||||
*/
|
||||
explicit function(cast_source const& source) :
|
||||
attribute(source.as< impl >())
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
#ifndef BOOST_NO_RESULT_OF
|
||||
|
||||
/*!
|
||||
* The function constructs \c function attribute instance with the provided function object.
|
||||
*
|
||||
* \param fun Nullary functional object that returns an actual stored value for an attribute value.
|
||||
* \return Pointer to the attribute instance
|
||||
*/
|
||||
template< typename T >
|
||||
inline function<
|
||||
typename remove_cv<
|
||||
typename remove_reference<
|
||||
typename boost::result_of< T() >::type
|
||||
>::type
|
||||
>::type
|
||||
> make_function(T const& fun)
|
||||
{
|
||||
typedef typename remove_cv<
|
||||
typename remove_reference<
|
||||
typename boost::result_of< T() >::type
|
||||
>::type
|
||||
>::type result_type;
|
||||
|
||||
typedef function< result_type > function_type;
|
||||
return function_type(fun);
|
||||
}
|
||||
|
||||
#endif // BOOST_NO_RESULT_OF
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
/*!
|
||||
* The function constructs \c function attribute instance with the provided function object.
|
||||
* Use this version if your compiler fails to determine the result type of the function object.
|
||||
*
|
||||
* \param fun Nullary functional object that returns an actual stored value for an attribute value.
|
||||
* \return Pointer to the attribute instance
|
||||
*/
|
||||
template< typename R, typename T >
|
||||
inline function<
|
||||
typename remove_cv<
|
||||
typename remove_reference< R >::type
|
||||
>::type
|
||||
> make_function(T const& fun)
|
||||
{
|
||||
typedef typename remove_cv<
|
||||
typename remove_reference< R >::type
|
||||
>::type result_type;
|
||||
|
||||
typedef function< result_type > function_type;
|
||||
return function_type(fun);
|
||||
}
|
||||
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
} // namespace attributes
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_ATTRIBUTES_FUNCTOR_HPP_INCLUDED_
|
||||
@@ -0,0 +1,332 @@
|
||||
/*
|
||||
* 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 mutable_constant.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 06.11.2007
|
||||
*
|
||||
* The header contains implementation of a mutable constant attribute.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_ATTRIBUTES_MUTABLE_CONSTANT_HPP_INCLUDED_
|
||||
#define BOOST_LOG_ATTRIBUTES_MUTABLE_CONSTANT_HPP_INCLUDED_
|
||||
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/smart_ptr/intrusive_ptr.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include <boost/type_traits/is_void.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/locks.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/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace attributes {
|
||||
|
||||
/*!
|
||||
* \brief A class of an attribute that holds a single constant value with ability to change it
|
||||
*
|
||||
* The mutable_constant attribute stores a single value of type, specified as the first template argument.
|
||||
* This value is returned on each attribute value acquisition.
|
||||
*
|
||||
* The attribute also allows to modify the stored value, even if the attribute is registered in an attribute set.
|
||||
* In order to ensure thread safety of such modifications the \c mutable_constant class is also parametrized
|
||||
* with three additional template arguments: mutex type, scoped write and scoped read lock types. If not specified,
|
||||
* the lock types are automatically deduced based on the mutex type.
|
||||
*
|
||||
* The implementation may avoid using these types to actually create and use the mutex, if a more efficient synchronization method is
|
||||
* available (such as atomic operations on the value type). By default no synchronization is done.
|
||||
*/
|
||||
#ifdef BOOST_LOG_DOXYGEN_PASS
|
||||
template< typename T, typename MutexT = void, typename ScopedWriteLockT = auto, typename ScopedReadLockT = auto >
|
||||
#else // BOOST_LOG_DOXYGEN_PASS
|
||||
template<
|
||||
typename T,
|
||||
typename MutexT = void,
|
||||
typename ScopedWriteLockT =
|
||||
#ifndef BOOST_LOG_NO_THREADS
|
||||
typename mpl::if_c<
|
||||
boost::log::aux::is_exclusively_lockable< MutexT >::value,
|
||||
boost::log::aux::exclusive_lock_guard< MutexT >,
|
||||
void
|
||||
>::type,
|
||||
#else
|
||||
void,
|
||||
#endif // BOOST_LOG_NO_THREADS
|
||||
typename ScopedReadLockT =
|
||||
#ifndef BOOST_LOG_NO_THREADS
|
||||
typename mpl::if_c<
|
||||
boost::log::aux::is_shared_lockable< MutexT >::value,
|
||||
boost::log::aux::shared_lock_guard< MutexT >,
|
||||
ScopedWriteLockT
|
||||
>::type
|
||||
#else
|
||||
ScopedWriteLockT
|
||||
#endif // BOOST_LOG_NO_THREADS
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
>
|
||||
class mutable_constant :
|
||||
public attribute
|
||||
{
|
||||
public:
|
||||
//! The attribute value type
|
||||
typedef T value_type;
|
||||
|
||||
protected:
|
||||
//! Factory implementation
|
||||
class BOOST_SYMBOL_VISIBLE impl :
|
||||
public attribute::impl
|
||||
{
|
||||
private:
|
||||
//! Mutex type
|
||||
typedef MutexT mutex_type;
|
||||
//! Shared lock type
|
||||
typedef ScopedReadLockT scoped_read_lock;
|
||||
//! Exclusive lock type
|
||||
typedef ScopedWriteLockT scoped_write_lock;
|
||||
BOOST_STATIC_ASSERT_MSG(!(is_void< mutex_type >::value || is_void< scoped_read_lock >::value || is_void< scoped_write_lock >::value), "Boost.Log: Mutex and both lock types either must not be void or must all be void");
|
||||
//! Attribute value wrapper
|
||||
typedef attribute_value_impl< value_type > attr_value;
|
||||
|
||||
private:
|
||||
//! Thread protection mutex
|
||||
mutable mutex_type m_Mutex;
|
||||
//! Pointer to the actual attribute value
|
||||
intrusive_ptr< attr_value > m_Value;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Initializing constructor
|
||||
*/
|
||||
explicit impl(value_type const& value) : m_Value(new attr_value(value))
|
||||
{
|
||||
}
|
||||
/*!
|
||||
* Initializing constructor
|
||||
*/
|
||||
explicit impl(BOOST_RV_REF(value_type) value) : m_Value(new attr_value(boost::move(value)))
|
||||
{
|
||||
}
|
||||
|
||||
attribute_value get_value()
|
||||
{
|
||||
scoped_read_lock lock(m_Mutex);
|
||||
return attribute_value(m_Value);
|
||||
}
|
||||
|
||||
void set(value_type const& value)
|
||||
{
|
||||
intrusive_ptr< attr_value > p = new attr_value(value);
|
||||
scoped_write_lock lock(m_Mutex);
|
||||
m_Value.swap(p);
|
||||
}
|
||||
|
||||
void set(BOOST_RV_REF(value_type) value)
|
||||
{
|
||||
intrusive_ptr< attr_value > p = new attr_value(boost::move(value));
|
||||
scoped_write_lock lock(m_Mutex);
|
||||
m_Value.swap(p);
|
||||
}
|
||||
|
||||
value_type get() const
|
||||
{
|
||||
scoped_read_lock lock(m_Mutex);
|
||||
return m_Value->get();
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Constructor with the stored value initialization
|
||||
*/
|
||||
explicit mutable_constant(value_type const& value) : attribute(new impl(value))
|
||||
{
|
||||
}
|
||||
/*!
|
||||
* Constructor with the stored value initialization
|
||||
*/
|
||||
explicit mutable_constant(BOOST_RV_REF(value_type) value) : attribute(new impl(boost::move(value)))
|
||||
{
|
||||
}
|
||||
/*!
|
||||
* Constructor for casting support
|
||||
*/
|
||||
explicit mutable_constant(cast_source const& source) : attribute(source.as< impl >())
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method sets a new attribute value. The implementation exclusively locks the mutex in order
|
||||
* to protect the value assignment.
|
||||
*/
|
||||
void set(value_type const& value)
|
||||
{
|
||||
get_impl()->set(value);
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method sets a new attribute value.
|
||||
*/
|
||||
void set(BOOST_RV_REF(value_type) value)
|
||||
{
|
||||
get_impl()->set(boost::move(value));
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method acquires the current attribute value. The implementation non-exclusively locks the mutex in order
|
||||
* to protect the value acquisition.
|
||||
*/
|
||||
value_type get() const
|
||||
{
|
||||
return get_impl()->get();
|
||||
}
|
||||
|
||||
protected:
|
||||
/*!
|
||||
* \returns Pointer to the factory implementation
|
||||
*/
|
||||
impl* get_impl() const
|
||||
{
|
||||
return static_cast< impl* >(attribute::get_impl());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Specialization for unlocked case
|
||||
*
|
||||
* This version of attribute does not perform thread synchronization to access the stored value.
|
||||
*/
|
||||
template< typename T >
|
||||
class mutable_constant< T, void, void, void > :
|
||||
public attribute
|
||||
{
|
||||
public:
|
||||
//! The attribute value type
|
||||
typedef T value_type;
|
||||
|
||||
protected:
|
||||
//! Factory implementation
|
||||
class BOOST_SYMBOL_VISIBLE impl :
|
||||
public attribute::impl
|
||||
{
|
||||
private:
|
||||
//! Attribute value wrapper
|
||||
typedef attribute_value_impl< value_type > attr_value;
|
||||
|
||||
private:
|
||||
//! The actual value
|
||||
intrusive_ptr< attr_value > m_Value;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Initializing constructor
|
||||
*/
|
||||
explicit impl(value_type const& value) : m_Value(new attr_value(value))
|
||||
{
|
||||
}
|
||||
/*!
|
||||
* Initializing constructor
|
||||
*/
|
||||
explicit impl(BOOST_RV_REF(value_type) value) : m_Value(new attr_value(boost::move(value)))
|
||||
{
|
||||
}
|
||||
|
||||
attribute_value get_value()
|
||||
{
|
||||
return attribute_value(m_Value);
|
||||
}
|
||||
|
||||
void set(value_type const& value)
|
||||
{
|
||||
m_Value = new attr_value(value);
|
||||
}
|
||||
void set(BOOST_RV_REF(value_type) value)
|
||||
{
|
||||
m_Value = new attr_value(boost::move(value));
|
||||
}
|
||||
|
||||
value_type get() const
|
||||
{
|
||||
return m_Value->get();
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Constructor with the stored value initialization
|
||||
*/
|
||||
explicit mutable_constant(value_type const& value) : attribute(new impl(value))
|
||||
{
|
||||
}
|
||||
/*!
|
||||
* Constructor with the stored value initialization
|
||||
*/
|
||||
explicit mutable_constant(BOOST_RV_REF(value_type) value) : attribute(new impl(boost::move(value)))
|
||||
{
|
||||
}
|
||||
/*!
|
||||
* Constructor for casting support
|
||||
*/
|
||||
explicit mutable_constant(cast_source const& source) : attribute(source.as< impl >())
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method sets a new attribute value.
|
||||
*/
|
||||
void set(value_type const& value)
|
||||
{
|
||||
get_impl()->set(value);
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method sets a new attribute value.
|
||||
*/
|
||||
void set(BOOST_RV_REF(value_type) value)
|
||||
{
|
||||
get_impl()->set(boost::move(value));
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method acquires the current attribute value.
|
||||
*/
|
||||
value_type get() const
|
||||
{
|
||||
return get_impl()->get();
|
||||
}
|
||||
|
||||
protected:
|
||||
/*!
|
||||
* \returns Pointer to the factory implementation
|
||||
*/
|
||||
impl* get_impl() const
|
||||
{
|
||||
return static_cast< impl* >(attribute::get_impl());
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace attributes
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_ATTRIBUTES_MUTABLE_CONSTANT_HPP_INCLUDED_
|
||||
@@ -0,0 +1,474 @@
|
||||
/*
|
||||
* 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
|
||||
* \author Andrey Semashev
|
||||
* \date 24.06.2007
|
||||
*
|
||||
* The header contains implementation of named scope container and an attribute that allows to
|
||||
* put the named scope to log. A number of convenience macros are also provided.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_ATTRIBUTES_NAMED_SCOPE_HPP_INCLUDED_
|
||||
#define BOOST_LOG_ATTRIBUTES_NAMED_SCOPE_HPP_INCLUDED_
|
||||
|
||||
#include <ostream>
|
||||
#include <memory>
|
||||
#include <iterator>
|
||||
#include <cstddef>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/current_function.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/log/utility/string_literal.hpp>
|
||||
#include <boost/log/utility/unique_identifier_name.hpp>
|
||||
#include <boost/log/utility/unused_variable.hpp>
|
||||
#include <boost/log/attributes/attribute.hpp>
|
||||
#include <boost/log/attributes/attribute_cast.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace attributes {
|
||||
|
||||
namespace aux {
|
||||
|
||||
//! Double-linked list node
|
||||
struct named_scope_list_node
|
||||
{
|
||||
mutable named_scope_list_node* _m_pPrev;
|
||||
mutable named_scope_list_node* _m_pNext;
|
||||
|
||||
named_scope_list_node() BOOST_NOEXCEPT { _m_pPrev = _m_pNext = this; }
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
/*!
|
||||
* \brief The structure contains all information about a named scope
|
||||
*
|
||||
* The named scope entries are stored as elements of \c basic_named_scope_list container, which
|
||||
* in turn can be acquired either from the \c basic_named_scope attribute value or from a thread-local
|
||||
* instance.
|
||||
*/
|
||||
struct named_scope_entry
|
||||
//! \cond
|
||||
: public aux::named_scope_list_node
|
||||
//! \endcond
|
||||
{
|
||||
/*!
|
||||
* \brief Scope entry type
|
||||
*
|
||||
* Describes scope name specifics
|
||||
*/
|
||||
enum scope_name_type
|
||||
{
|
||||
general, //!< The scope name contains some unstructured string that should not be interpreted by the library
|
||||
function //!< The scope name contains a function signature
|
||||
};
|
||||
|
||||
/*!
|
||||
* The scope name (e.g. a function signature)
|
||||
*/
|
||||
string_literal scope_name;
|
||||
/*!
|
||||
* The source file name
|
||||
*/
|
||||
string_literal file_name;
|
||||
/*!
|
||||
* The line number in the source file
|
||||
*/
|
||||
unsigned int line;
|
||||
/*!
|
||||
* The scope name type
|
||||
*/
|
||||
scope_name_type type;
|
||||
|
||||
/*!
|
||||
* Initializing constructor
|
||||
*
|
||||
* \post <tt>scope_name == sn && file_name == fn && line == ln</tt>
|
||||
*
|
||||
* \b Throws: Nothing.
|
||||
*/
|
||||
named_scope_entry(string_literal const& sn, string_literal const& fn, unsigned int ln, scope_name_type t = general) BOOST_NOEXCEPT :
|
||||
scope_name(sn),
|
||||
file_name(fn),
|
||||
line(ln),
|
||||
type(t)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief The class implements the list of scopes
|
||||
*
|
||||
* The scope list provides a read-only access to a doubly-linked list of scopes.
|
||||
*/
|
||||
class named_scope_list
|
||||
//! \cond
|
||||
: protected std::allocator< named_scope_entry >
|
||||
//! \endcond
|
||||
{
|
||||
public:
|
||||
//! Allocator type
|
||||
typedef std::allocator< named_scope_entry > allocator_type;
|
||||
|
||||
// Standard types
|
||||
typedef allocator_type::value_type value_type;
|
||||
typedef allocator_type::reference reference;
|
||||
typedef allocator_type::const_reference const_reference;
|
||||
typedef allocator_type::pointer pointer;
|
||||
typedef allocator_type::const_pointer const_pointer;
|
||||
typedef allocator_type::size_type size_type;
|
||||
typedef allocator_type::difference_type difference_type;
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
protected:
|
||||
//! Iterator class
|
||||
#ifndef BOOST_LOG_NO_MEMBER_TEMPLATE_FRIENDS
|
||||
template< bool fConstV > class iter;
|
||||
template< bool fConstV > friend class iter;
|
||||
#endif
|
||||
template< bool fConstV >
|
||||
class iter
|
||||
{
|
||||
friend class iter< !fConstV >;
|
||||
|
||||
public:
|
||||
// Standard typedefs
|
||||
typedef named_scope_list::difference_type difference_type;
|
||||
typedef named_scope_list::value_type value_type;
|
||||
typedef typename mpl::if_c<
|
||||
fConstV,
|
||||
named_scope_list::const_reference,
|
||||
named_scope_list::reference
|
||||
>::type reference;
|
||||
typedef typename mpl::if_c<
|
||||
fConstV,
|
||||
named_scope_list::const_pointer,
|
||||
named_scope_list::pointer
|
||||
>::type pointer;
|
||||
typedef std::bidirectional_iterator_tag iterator_category;
|
||||
|
||||
public:
|
||||
// Constructors
|
||||
iter() : m_pNode(NULL) {}
|
||||
explicit iter(aux::named_scope_list_node* pNode) : m_pNode(pNode) {}
|
||||
iter(iter< false > const& that) : m_pNode(that.m_pNode) {}
|
||||
|
||||
//! Assignment
|
||||
template< bool f >
|
||||
iter& operator= (iter< f > const& that)
|
||||
{
|
||||
m_pNode = that.m_pNode;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Comparison
|
||||
template< bool f >
|
||||
bool operator== (iter< f > const& that) const { return (m_pNode == that.m_pNode); }
|
||||
template< bool f >
|
||||
bool operator!= (iter< f > const& that) const { return (m_pNode != that.m_pNode); }
|
||||
|
||||
// Modification
|
||||
iter& operator++ ()
|
||||
{
|
||||
m_pNode = m_pNode->_m_pNext;
|
||||
return *this;
|
||||
}
|
||||
iter& operator-- ()
|
||||
{
|
||||
m_pNode = m_pNode->_m_pPrev;
|
||||
return *this;
|
||||
}
|
||||
iter operator++ (int)
|
||||
{
|
||||
iter tmp(*this);
|
||||
m_pNode = m_pNode->_m_pNext;
|
||||
return tmp;
|
||||
}
|
||||
iter operator-- (int)
|
||||
{
|
||||
iter tmp(*this);
|
||||
m_pNode = m_pNode->_m_pPrev;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// Dereferencing
|
||||
pointer operator-> () const { return static_cast< pointer >(m_pNode); }
|
||||
reference operator* () const { return *static_cast< pointer >(m_pNode); }
|
||||
|
||||
private:
|
||||
aux::named_scope_list_node* m_pNode;
|
||||
};
|
||||
|
||||
public:
|
||||
typedef iter< true > const_iterator;
|
||||
typedef iter< false > iterator;
|
||||
typedef std::reverse_iterator< const_iterator > const_reverse_iterator;
|
||||
typedef std::reverse_iterator< iterator > reverse_iterator;
|
||||
|
||||
protected:
|
||||
//! The root node of the container
|
||||
aux::named_scope_list_node m_RootNode;
|
||||
//! The size of the container
|
||||
size_type m_Size;
|
||||
//! The flag shows if the contained elements are dynamically allocated
|
||||
bool m_fNeedToDeallocate;
|
||||
|
||||
#else // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
/*!
|
||||
* A constant iterator to the sequence of scopes. Complies to bidirectional iterator requirements.
|
||||
*/
|
||||
typedef implementation_defined const_iterator;
|
||||
/*!
|
||||
* An iterator to the sequence of scopes. Complies to bidirectional iterator requirements.
|
||||
*/
|
||||
typedef implementation_defined iterator;
|
||||
/*!
|
||||
* A constant reverse iterator to the sequence of scopes. Complies to bidirectional iterator requirements.
|
||||
*/
|
||||
typedef implementation_defined const_reverse_iterator;
|
||||
/*!
|
||||
* A reverse iterator to the sequence of scopes. Complies to bidirectional iterator requirements.
|
||||
*/
|
||||
typedef implementation_defined reverse_iterator;
|
||||
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Default constructor
|
||||
*
|
||||
* \post <tt>empty() == true</tt>
|
||||
*/
|
||||
named_scope_list() : m_Size(0), m_fNeedToDeallocate(false) {}
|
||||
/*!
|
||||
* Copy constructor
|
||||
*
|
||||
* \post <tt>std::equal(begin(), end(), that.begin()) == true</tt>
|
||||
*/
|
||||
BOOST_LOG_API named_scope_list(named_scope_list const& that);
|
||||
/*!
|
||||
* Destructor. Destroys the stored entries.
|
||||
*/
|
||||
BOOST_LOG_API ~named_scope_list();
|
||||
|
||||
/*!
|
||||
* Assignment operator
|
||||
*
|
||||
* \post <tt>std::equal(begin(), end(), that.begin()) == true</tt>
|
||||
*/
|
||||
named_scope_list& operator= (named_scope_list const& that)
|
||||
{
|
||||
if (this != &that)
|
||||
{
|
||||
named_scope_list tmp(that);
|
||||
swap(tmp);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \return Constant iterator to the first element of the container.
|
||||
*/
|
||||
const_iterator begin() const { return const_iterator(m_RootNode._m_pNext); }
|
||||
/*!
|
||||
* \return Constant iterator to the after-the-last element of the container.
|
||||
*/
|
||||
const_iterator end() const { return const_iterator(const_cast< aux::named_scope_list_node* >(&m_RootNode)); }
|
||||
/*!
|
||||
* \return Constant iterator to the last element of the container.
|
||||
*/
|
||||
const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
|
||||
/*!
|
||||
* \return Constant iterator to the before-the-first element of the container.
|
||||
*/
|
||||
const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
|
||||
|
||||
/*!
|
||||
* \return The number of elements in the container
|
||||
*/
|
||||
size_type size() const { return m_Size; }
|
||||
/*!
|
||||
* \return true if the container is empty and false otherwise
|
||||
*/
|
||||
bool empty() const { return (m_Size == 0); }
|
||||
|
||||
/*!
|
||||
* Swaps two instances of the container
|
||||
*/
|
||||
BOOST_LOG_API void swap(named_scope_list& that);
|
||||
|
||||
/*!
|
||||
* \return Last pushed scope entry
|
||||
*/
|
||||
const_reference back() const { return *rbegin(); }
|
||||
/*!
|
||||
* \return First pushed scope entry
|
||||
*/
|
||||
const_reference front() const { return *begin(); }
|
||||
};
|
||||
|
||||
//! Stream output operator
|
||||
template< typename CharT, typename TraitsT >
|
||||
inline std::basic_ostream< CharT, TraitsT >& operator<< (std::basic_ostream< CharT, TraitsT >& strm, named_scope_list const& sl)
|
||||
{
|
||||
if (strm.good())
|
||||
{
|
||||
named_scope_list::const_iterator it = sl.begin(), end = sl.end();
|
||||
if (it != end)
|
||||
{
|
||||
strm << it->scope_name.c_str();
|
||||
for (++it; it != end; ++it)
|
||||
strm << "->" << it->scope_name.c_str();
|
||||
}
|
||||
}
|
||||
return strm;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief A class of an attribute that holds stack of named scopes of the current thread
|
||||
*
|
||||
* The basic_named_scope attribute is essentially a hook to the thread-specific instance of
|
||||
* scope list. This means that the attribute will generate different values if get_value is
|
||||
* called in different threads. The attribute generates value with stored type
|
||||
* <tt>basic_named_scope_list< CharT ></tt>.
|
||||
*
|
||||
* The attribute class can also be used to gain access to the scope stack instance, e.g. to
|
||||
* get its copy or to push or pop a scope entry. However, it is highly not recommended to
|
||||
* maintain scope list manually. Use \c BOOST_LOG_NAMED_SCOPE or \c BOOST_LOG_FUNCTION macros instead.
|
||||
*/
|
||||
class BOOST_LOG_API named_scope :
|
||||
public attribute
|
||||
{
|
||||
public:
|
||||
//! Scope names stack (the attribute value type)
|
||||
typedef named_scope_list value_type;
|
||||
//! Scope entry
|
||||
typedef value_type::value_type scope_entry;
|
||||
|
||||
//! Sentry object class to automatically push and pop scopes
|
||||
struct sentry
|
||||
{
|
||||
/*!
|
||||
* Constructor. Pushes the specified scope to the end of the thread-local list of scopes.
|
||||
*
|
||||
* \param sn Scope name.
|
||||
* \param fn File name, in which the scope is located.
|
||||
* \param ln Line number in the file.
|
||||
*/
|
||||
sentry(string_literal const& sn, string_literal const& fn, unsigned int ln, scope_entry::scope_name_type t = scope_entry::general) BOOST_NOEXCEPT :
|
||||
m_Entry(sn, fn, ln, t)
|
||||
{
|
||||
named_scope::push_scope(m_Entry);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Destructor. Removes the last pushed scope from the thread-local list of scopes.
|
||||
*/
|
||||
~sentry() BOOST_NOEXCEPT
|
||||
{
|
||||
named_scope::pop_scope();
|
||||
}
|
||||
|
||||
BOOST_DELETED_FUNCTION(sentry(sentry const&))
|
||||
BOOST_DELETED_FUNCTION(sentry& operator= (sentry const&))
|
||||
|
||||
private:
|
||||
scope_entry m_Entry;
|
||||
};
|
||||
|
||||
private:
|
||||
//! Attribute implementation class
|
||||
struct BOOST_SYMBOL_VISIBLE impl;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Constructor. Creates an attribute.
|
||||
*/
|
||||
named_scope();
|
||||
/*!
|
||||
* Constructor for casting support
|
||||
*/
|
||||
explicit named_scope(cast_source const& source);
|
||||
|
||||
/*!
|
||||
* The method pushes the scope to the back of the current thread's scope list
|
||||
*
|
||||
* \b Throws: Nothing.
|
||||
*/
|
||||
static void push_scope(scope_entry const& entry) BOOST_NOEXCEPT;
|
||||
/*!
|
||||
* The method pops the last pushed scope from the current thread's scope list
|
||||
*
|
||||
* \b Throws: Nothing.
|
||||
*/
|
||||
static void pop_scope() BOOST_NOEXCEPT;
|
||||
|
||||
/*!
|
||||
* \return The current thread's list of scopes
|
||||
*
|
||||
* \note The returned reference is only valid until the current thread ends. The scopes in the
|
||||
* returned container may change if the execution scope is changed (i.e. either \c push_scope
|
||||
* or \c pop_scope is called). User has to copy the stack if he wants to keep it intact regardless
|
||||
* of the execution scope.
|
||||
*/
|
||||
static value_type const& get_scopes();
|
||||
};
|
||||
|
||||
} // namespace attributes
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
#define BOOST_LOG_NAMED_SCOPE_INTERNAL(var, name, file, line, type)\
|
||||
BOOST_LOG_UNUSED_VARIABLE(::boost::log::attributes::named_scope::sentry, var, (name, file, line, type));
|
||||
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
/*!
|
||||
* Macro for scope markup. The specified scope name is pushed to the end of the current thread scope list.
|
||||
*/
|
||||
#define BOOST_LOG_NAMED_SCOPE(name)\
|
||||
BOOST_LOG_NAMED_SCOPE_INTERNAL(BOOST_LOG_UNIQUE_IDENTIFIER_NAME(_boost_log_named_scope_sentry_), name, __FILE__, __LINE__, ::boost::log::attributes::named_scope_entry::general)
|
||||
|
||||
/*!
|
||||
* Macro for function scope markup. The scope name is constructed with help of compiler and contains the current function signature.
|
||||
* The scope name is pushed to the end of the current thread scope list.
|
||||
*
|
||||
* Not all compilers have support for this macro. The exact form of the scope name may vary from one compiler to another.
|
||||
*/
|
||||
#define BOOST_LOG_FUNCTION()\
|
||||
BOOST_LOG_NAMED_SCOPE_INTERNAL(BOOST_LOG_UNIQUE_IDENTIFIER_NAME(_boost_log_named_scope_sentry_), BOOST_CURRENT_FUNCTION, __FILE__, __LINE__, ::boost::log::attributes::named_scope_entry::function)
|
||||
|
||||
/*!
|
||||
* Macro for function scope markup. The scope name is constructed with help of compiler and contains the current function name. It may be shorter than what \c BOOST_LOG_FUNCTION macro produces.
|
||||
* The scope name is pushed to the end of the current thread scope list.
|
||||
*
|
||||
* Not all compilers have support for this macro. The exact form of the scope name may vary from one compiler to another.
|
||||
*/
|
||||
#if defined(_MSC_VER) || defined(__GNUC__)
|
||||
#define BOOST_LOG_FUNC() BOOST_LOG_NAMED_SCOPE(__FUNCTION__)
|
||||
#else
|
||||
#define BOOST_LOG_FUNC() BOOST_LOG_FUNCTION()
|
||||
#endif
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_ATTRIBUTES_NAMED_SCOPE_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 scoped_attribute.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 13.05.2007
|
||||
*
|
||||
* The header contains definition of facilities to define scoped attributes.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_ATTRIBUTES_SCOPED_ATTRIBUTE_HPP_INCLUDED_
|
||||
#define BOOST_LOG_ATTRIBUTES_SCOPED_ATTRIBUTE_HPP_INCLUDED_
|
||||
|
||||
#include <utility>
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include <boost/core/addressof.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/core/core.hpp>
|
||||
#include <boost/log/sources/basic_logger.hpp>
|
||||
#include <boost/log/attributes/attribute.hpp>
|
||||
#include <boost/log/attributes/attribute_set.hpp>
|
||||
#include <boost/log/attributes/attribute_name.hpp>
|
||||
#include <boost/log/attributes/constant.hpp>
|
||||
#include <boost/log/utility/unused_variable.hpp>
|
||||
#include <boost/log/utility/unique_identifier_name.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace aux {
|
||||
|
||||
//! A base class for all scoped attribute guards
|
||||
class attribute_scope_guard
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
//! Scoped attribute guard type
|
||||
typedef aux::attribute_scope_guard const& scoped_attribute;
|
||||
|
||||
namespace aux {
|
||||
|
||||
//! A scoped logger attribute guard
|
||||
template< typename LoggerT >
|
||||
class scoped_logger_attribute :
|
||||
public attribute_scope_guard
|
||||
{
|
||||
BOOST_COPYABLE_AND_MOVABLE_ALT(scoped_logger_attribute)
|
||||
|
||||
private:
|
||||
//! Logger type
|
||||
typedef LoggerT logger_type;
|
||||
|
||||
private:
|
||||
//! A reference to the logger
|
||||
logger_type* m_pLogger;
|
||||
//! An iterator to the added attribute
|
||||
attribute_set::iterator m_itAttribute;
|
||||
|
||||
public:
|
||||
//! Constructor
|
||||
scoped_logger_attribute(logger_type& l, attribute_name const& name, attribute const& attr) :
|
||||
m_pLogger(boost::addressof(l))
|
||||
{
|
||||
std::pair<
|
||||
attribute_set::iterator,
|
||||
bool
|
||||
> res = l.add_attribute(name, attr);
|
||||
if (res.second)
|
||||
m_itAttribute = res.first;
|
||||
else
|
||||
m_pLogger = 0; // if there already is a same-named attribute, don't register anything
|
||||
}
|
||||
//! Move constructor
|
||||
scoped_logger_attribute(BOOST_RV_REF(scoped_logger_attribute) that) :
|
||||
m_pLogger(that.m_pLogger),
|
||||
m_itAttribute(that.m_itAttribute)
|
||||
{
|
||||
that.m_pLogger = 0;
|
||||
}
|
||||
|
||||
//! Destructor
|
||||
~scoped_logger_attribute()
|
||||
{
|
||||
if (m_pLogger)
|
||||
m_pLogger->remove_attribute(m_itAttribute);
|
||||
}
|
||||
|
||||
#ifndef BOOST_LOG_BROKEN_REFERENCE_FROM_RVALUE_INIT
|
||||
BOOST_DELETED_FUNCTION(scoped_logger_attribute(scoped_logger_attribute const&))
|
||||
#else // BOOST_LOG_BROKEN_REFERENCE_FROM_RVALUE_INIT
|
||||
scoped_logger_attribute(scoped_logger_attribute const& that) : m_pLogger(that.m_pLogger), m_itAttribute(that.m_itAttribute)
|
||||
{
|
||||
const_cast< scoped_logger_attribute& >(that).m_pLogger = 0;
|
||||
}
|
||||
#endif // BOOST_LOG_BROKEN_REFERENCE_FROM_RVALUE_INIT
|
||||
|
||||
BOOST_DELETED_FUNCTION(scoped_logger_attribute& operator= (scoped_logger_attribute const&))
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
// Generator helper functions
|
||||
/*!
|
||||
* Registers an attribute in the logger
|
||||
*
|
||||
* \param l Logger to register the attribute in
|
||||
* \param name Attribute name
|
||||
* \param attr The attribute. Must not be NULL.
|
||||
* \return An unspecified guard object which may be used to initialize a \c scoped_attribute variable.
|
||||
*/
|
||||
template< typename LoggerT >
|
||||
BOOST_FORCEINLINE aux::scoped_logger_attribute< LoggerT > add_scoped_logger_attribute(LoggerT& l, attribute_name const& name, attribute const& attr)
|
||||
{
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
return aux::scoped_logger_attribute< LoggerT >(l, name, attr);
|
||||
#else
|
||||
aux::scoped_logger_attribute< LoggerT > guard(l, name, attr);
|
||||
return boost::move(guard);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
#define BOOST_LOG_SCOPED_LOGGER_ATTR_INTERNAL(logger, attr_name, attr, sentry_var_name)\
|
||||
BOOST_LOG_UNUSED_VARIABLE(::boost::log::scoped_attribute, sentry_var_name,\
|
||||
= ::boost::log::add_scoped_logger_attribute(logger, attr_name, (attr)));
|
||||
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
//! The macro sets a scoped logger-wide attribute in a more compact way
|
||||
#define BOOST_LOG_SCOPED_LOGGER_ATTR(logger, attr_name, attr)\
|
||||
BOOST_LOG_SCOPED_LOGGER_ATTR_INTERNAL(\
|
||||
logger,\
|
||||
attr_name,\
|
||||
attr,\
|
||||
BOOST_LOG_UNIQUE_IDENTIFIER_NAME(_boost_log_scoped_logger_attr_sentry_))
|
||||
|
||||
//! The macro sets a scoped logger-wide tag in a more compact way
|
||||
#define BOOST_LOG_SCOPED_LOGGER_TAG(logger, attr_name, attr_value)\
|
||||
BOOST_LOG_SCOPED_LOGGER_ATTR(logger, attr_name, ::boost::log::attributes::make_constant(attr_value))
|
||||
|
||||
namespace aux {
|
||||
|
||||
//! A scoped thread-specific attribute guard
|
||||
class scoped_thread_attribute :
|
||||
public attribute_scope_guard
|
||||
{
|
||||
BOOST_COPYABLE_AND_MOVABLE_ALT(scoped_thread_attribute)
|
||||
|
||||
private:
|
||||
//! A pointer to the logging core
|
||||
core_ptr m_pCore;
|
||||
//! An iterator to the added attribute
|
||||
attribute_set::iterator m_itAttribute;
|
||||
|
||||
public:
|
||||
//! Constructor
|
||||
scoped_thread_attribute(attribute_name const& name, attribute const& attr) :
|
||||
m_pCore(core::get())
|
||||
{
|
||||
std::pair<
|
||||
attribute_set::iterator,
|
||||
bool
|
||||
> res = m_pCore->add_thread_attribute(name, attr);
|
||||
if (res.second)
|
||||
m_itAttribute = res.first;
|
||||
else
|
||||
m_pCore.reset(); // if there already is a same-named attribute, don't register anything
|
||||
}
|
||||
//! Move constructor
|
||||
scoped_thread_attribute(BOOST_RV_REF(scoped_thread_attribute) that) : m_itAttribute(that.m_itAttribute)
|
||||
{
|
||||
m_pCore.swap(that.m_pCore);
|
||||
}
|
||||
|
||||
//! Destructor
|
||||
~scoped_thread_attribute()
|
||||
{
|
||||
if (!!m_pCore)
|
||||
m_pCore->remove_thread_attribute(m_itAttribute);
|
||||
}
|
||||
|
||||
#ifndef BOOST_LOG_BROKEN_REFERENCE_FROM_RVALUE_INIT
|
||||
BOOST_DELETED_FUNCTION(scoped_thread_attribute(scoped_thread_attribute const&))
|
||||
#else // BOOST_LOG_BROKEN_REFERENCE_FROM_RVALUE_INIT
|
||||
scoped_thread_attribute(scoped_thread_attribute const& that) : m_itAttribute(that.m_itAttribute)
|
||||
{
|
||||
m_pCore.swap(const_cast< scoped_thread_attribute& >(that).m_pCore);
|
||||
}
|
||||
#endif // BOOST_LOG_BROKEN_REFERENCE_FROM_RVALUE_INIT
|
||||
|
||||
BOOST_DELETED_FUNCTION(scoped_thread_attribute& operator= (scoped_thread_attribute const&))
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
// Generator helper functions
|
||||
/*!
|
||||
* Registers a thread-specific attribute
|
||||
*
|
||||
* \param name Attribute name
|
||||
* \param attr The attribute. Must not be NULL.
|
||||
* \return An unspecified guard object which may be used to initialize a \c scoped_attribute variable.
|
||||
*/
|
||||
BOOST_FORCEINLINE aux::scoped_thread_attribute add_scoped_thread_attribute(attribute_name const& name, attribute const& attr)
|
||||
{
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
return aux::scoped_thread_attribute(name, attr);
|
||||
#else
|
||||
aux::scoped_thread_attribute guard(name, attr);
|
||||
return boost::move(guard);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
#define BOOST_LOG_SCOPED_THREAD_ATTR_INTERNAL(attr_name, attr, sentry_var_name)\
|
||||
BOOST_LOG_UNUSED_VARIABLE(::boost::log::scoped_attribute, sentry_var_name,\
|
||||
= ::boost::log::add_scoped_thread_attribute(attr_name, (attr)));
|
||||
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
//! The macro sets a scoped thread-wide attribute in a more compact way
|
||||
#define BOOST_LOG_SCOPED_THREAD_ATTR(attr_name, attr)\
|
||||
BOOST_LOG_SCOPED_THREAD_ATTR_INTERNAL(\
|
||||
attr_name,\
|
||||
attr,\
|
||||
BOOST_LOG_UNIQUE_IDENTIFIER_NAME(_boost_log_scoped_thread_attr_sentry_))
|
||||
|
||||
//! The macro sets a scoped thread-wide tag in a more compact way
|
||||
#define BOOST_LOG_SCOPED_THREAD_TAG(attr_name, attr_value)\
|
||||
BOOST_LOG_SCOPED_THREAD_ATTR(attr_name, ::boost::log::attributes::make_constant(attr_value))
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_ATTRIBUTES_SCOPED_ATTRIBUTE_HPP_INCLUDED_
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* 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 time_traits.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 01.12.2007
|
||||
*
|
||||
* The header contains implementation of time traits that are used in various parts of the
|
||||
* library to acquire current time.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_ATTRIBUTES_TIME_TRAITS_HPP_INCLUDED_
|
||||
#define BOOST_LOG_ATTRIBUTES_TIME_TRAITS_HPP_INCLUDED_
|
||||
|
||||
#include <boost/date_time/posix_time/posix_time_types.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace attributes {
|
||||
|
||||
//! Base class for time traits involving Boost.DateTime.
|
||||
struct basic_time_traits
|
||||
{
|
||||
//! Time type
|
||||
typedef posix_time::ptime time_type;
|
||||
|
||||
//! Current time source
|
||||
#if defined(BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK)
|
||||
typedef posix_time::microsec_clock clock_source;
|
||||
#else
|
||||
typedef posix_time::second_clock clock_source;
|
||||
#endif // defined(BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK)
|
||||
};
|
||||
|
||||
//! Time traits that describes UTC time acquirement via Boost.DateTime facilities
|
||||
struct utc_time_traits :
|
||||
public basic_time_traits
|
||||
{
|
||||
/*!
|
||||
* \return Current time stamp
|
||||
*/
|
||||
static time_type get_clock()
|
||||
{
|
||||
return clock_source::universal_time();
|
||||
}
|
||||
};
|
||||
|
||||
//! Time traits that describes local time acquirement via Boost.DateTime facilities
|
||||
struct local_time_traits :
|
||||
public basic_time_traits
|
||||
{
|
||||
/*!
|
||||
* \return Current time stamp
|
||||
*/
|
||||
static time_type get_clock()
|
||||
{
|
||||
return clock_source::local_time();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace attributes
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_ATTRIBUTES_TIME_TRAITS_HPP_INCLUDED_
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* 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 timer.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 02.12.2007
|
||||
*
|
||||
* The header contains implementation of a stop watch attribute.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_ATTRIBUTES_TIMER_HPP_INCLUDED_
|
||||
#define BOOST_LOG_ATTRIBUTES_TIMER_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/attributes/attribute.hpp>
|
||||
#include <boost/log/attributes/attribute_cast.hpp>
|
||||
#include <boost/log/attributes/time_traits.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace attributes {
|
||||
|
||||
/*!
|
||||
* \brief A class of an attribute that makes an attribute value of the time interval since construction
|
||||
*
|
||||
* The timer attribute calculates the time passed since its construction and returns it on value acquisition.
|
||||
* The attribute value type is <tt>boost::posix_time::time_duration</tt>.
|
||||
*
|
||||
* On Windows platform there are two implementations of the attribute. The default one is more precise but
|
||||
* a bit slower. This version uses <tt>QueryPerformanceFrequence</tt>/<tt>QueryPerformanceCounter</tt> API
|
||||
* to calculate elapsed time.
|
||||
*
|
||||
* There are known problems with these functions when used with some CPUs, notably AMD Athlon with
|
||||
* Cool'n'Quiet technology enabled. See the following links for more information and possible resolutions:
|
||||
*
|
||||
* http://support.microsoft.com/?scid=kb;en-us;895980
|
||||
* http://support.microsoft.com/?id=896256
|
||||
*
|
||||
* In case if none of these solutions apply, you are free to define <tt>BOOST_LOG_NO_QUERY_PERFORMANCE_COUNTER</tt> macro to
|
||||
* fall back to another implementation based on Boost.DateTime.
|
||||
*/
|
||||
class BOOST_LOG_API timer :
|
||||
public attribute
|
||||
{
|
||||
public:
|
||||
//! Attribute value type
|
||||
typedef utc_time_traits::time_type::time_duration_type value_type;
|
||||
|
||||
private:
|
||||
//! Factory implementation
|
||||
class BOOST_SYMBOL_VISIBLE impl;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Constructor. Starts time counting.
|
||||
*/
|
||||
timer();
|
||||
/*!
|
||||
* Constructor for casting support
|
||||
*/
|
||||
explicit timer(cast_source const& source);
|
||||
};
|
||||
|
||||
} // namespace attributes
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_ATTRIBUTES_TIMER_HPP_INCLUDED_
|
||||
@@ -0,0 +1,816 @@
|
||||
/*
|
||||
* 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 value_extraction.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 01.03.2008
|
||||
*
|
||||
* The header contains implementation of tools for extracting an attribute value
|
||||
* from the view.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_ATTRIBUTES_VALUE_EXTRACTION_HPP_INCLUDED_
|
||||
#define BOOST_LOG_ATTRIBUTES_VALUE_EXTRACTION_HPP_INCLUDED_
|
||||
|
||||
#include <boost/mpl/vector.hpp>
|
||||
#include <boost/mpl/joint_view.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/eval_if.hpp>
|
||||
#include <boost/mpl/identity.hpp>
|
||||
#include <boost/mpl/is_sequence.hpp>
|
||||
#include <boost/mpl/contains.hpp>
|
||||
#include <boost/mpl/push_back.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/core/enable_if.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/exceptions.hpp>
|
||||
#include <boost/log/core/record.hpp>
|
||||
#include <boost/log/attributes/attribute_name.hpp>
|
||||
#include <boost/log/attributes/attribute_value.hpp>
|
||||
#include <boost/log/attributes/attribute.hpp>
|
||||
#include <boost/log/attributes/attribute_value_set.hpp>
|
||||
#include <boost/log/attributes/value_extraction_fwd.hpp>
|
||||
#include <boost/log/attributes/fallback_policy.hpp>
|
||||
#include <boost/log/expressions/keyword_fwd.hpp>
|
||||
#include <boost/log/utility/value_ref.hpp>
|
||||
#include <boost/log/utility/type_dispatch/static_type_dispatcher.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace result_of {
|
||||
|
||||
/*!
|
||||
* \brief A metafunction that allows to acquire the result of the value extraction
|
||||
*
|
||||
* The metafunction results in a type that is in form of <tt>T const&</tt>, if \c T is
|
||||
* not an MPL type sequence and <tt>DefaultT</tt> is the same as <tt>T</tt>,
|
||||
* or <tt>value_ref< TypesT, TagT ></tt> otherwise, with
|
||||
* \c TypesT being a type sequence comprising the types from sequence \c T and \c DefaultT,
|
||||
* if it is not present in \c T already.
|
||||
*/
|
||||
template< typename T, typename DefaultT, typename TagT >
|
||||
struct extract_or_default
|
||||
{
|
||||
typedef typename mpl::eval_if<
|
||||
mpl::is_sequence< T >,
|
||||
mpl::eval_if<
|
||||
mpl::contains< T, DefaultT >,
|
||||
mpl::identity< T >,
|
||||
mpl::push_back< T, DefaultT >
|
||||
>,
|
||||
mpl::if_<
|
||||
is_same< T, DefaultT >,
|
||||
T,
|
||||
mpl::vector2< T, DefaultT >
|
||||
>
|
||||
>::type extracted_type;
|
||||
|
||||
typedef typename mpl::if_<
|
||||
mpl::is_sequence< extracted_type >,
|
||||
value_ref< extracted_type, TagT >,
|
||||
extracted_type const&
|
||||
>::type type;
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief A metafunction that allows to acquire the result of the value extraction
|
||||
*
|
||||
* The metafunction results in a type that is in form of <tt>T const&</tt>, if \c T is
|
||||
* not an MPL type sequence, or <tt>value_ref< T, TagT ></tt> otherwise. In the latter
|
||||
* case the value reference shall never be empty.
|
||||
*/
|
||||
template< typename T, typename TagT >
|
||||
struct extract_or_throw
|
||||
{
|
||||
typedef typename mpl::if_<
|
||||
mpl::is_sequence< T >,
|
||||
value_ref< T, TagT >,
|
||||
T const&
|
||||
>::type type;
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief A metafunction that allows to acquire the result of the value extraction
|
||||
*
|
||||
* The metafunction results in a type that is in form of <tt>value_ref< T, TagT ></tt>.
|
||||
*/
|
||||
template< typename T, typename TagT >
|
||||
struct extract
|
||||
{
|
||||
typedef value_ref< T, TagT > type;
|
||||
};
|
||||
|
||||
} // namespace result_of
|
||||
|
||||
namespace aux {
|
||||
|
||||
//! The function object initializes the value reference
|
||||
template< typename RefT >
|
||||
struct value_ref_initializer
|
||||
{
|
||||
typedef void result_type;
|
||||
|
||||
value_ref_initializer(RefT& ref) : m_ref(ref)
|
||||
{
|
||||
}
|
||||
|
||||
template< typename ArgT >
|
||||
result_type operator() (ArgT const& arg) const
|
||||
{
|
||||
m_ref = RefT(arg);
|
||||
}
|
||||
|
||||
private:
|
||||
RefT& m_ref;
|
||||
};
|
||||
|
||||
//! The function unwraps \c value_ref, if possible
|
||||
template< typename T, typename TagT >
|
||||
BOOST_FORCEINLINE typename boost::enable_if_c< mpl::is_sequence< T >::value, value_ref< T, TagT > >::type
|
||||
unwrap_value_ref(value_ref< T, TagT > const& r)
|
||||
{
|
||||
return r;
|
||||
}
|
||||
|
||||
template< typename T, typename TagT >
|
||||
BOOST_FORCEINLINE typename boost::disable_if_c< mpl::is_sequence< T >::value, T const& >::type
|
||||
unwrap_value_ref(value_ref< T, TagT > const& r)
|
||||
{
|
||||
return r.get();
|
||||
}
|
||||
|
||||
} // namespace aux
|
||||
|
||||
/*!
|
||||
* \brief Generic attribute value extractor
|
||||
*
|
||||
* Attribute value extractor is a functional object that attempts to find and extract the stored
|
||||
* attribute value from the attribute values view or a log record. The extracted value is returned
|
||||
* from the extractor.
|
||||
*/
|
||||
template< typename T, typename FallbackPolicyT, typename TagT >
|
||||
class value_extractor :
|
||||
private FallbackPolicyT
|
||||
{
|
||||
public:
|
||||
//! Fallback policy
|
||||
typedef FallbackPolicyT fallback_policy;
|
||||
//! Attribute value types
|
||||
typedef T value_type;
|
||||
//! Function object result type
|
||||
typedef value_ref< value_type, TagT > result_type;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Default constructor
|
||||
*/
|
||||
BOOST_DEFAULTED_FUNCTION(value_extractor(), {})
|
||||
|
||||
/*!
|
||||
* Copy constructor
|
||||
*/
|
||||
value_extractor(value_extractor const& that) : fallback_policy(static_cast< fallback_policy const& >(that))
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* Constructor
|
||||
*
|
||||
* \param arg Fallback policy constructor argument
|
||||
*/
|
||||
template< typename U >
|
||||
explicit value_extractor(U const& arg) : fallback_policy(arg) {}
|
||||
|
||||
/*!
|
||||
* Extraction operator. Attempts to acquire the stored value of one of the supported types. If extraction succeeds,
|
||||
* the extracted value is returned.
|
||||
*
|
||||
* \param attr The attribute value to extract from.
|
||||
* \return The extracted value, if extraction succeeded, an empty value otherwise.
|
||||
*/
|
||||
result_type operator() (attribute_value const& attr) const
|
||||
{
|
||||
result_type res;
|
||||
aux::value_ref_initializer< result_type > initializer(res);
|
||||
if (!!attr)
|
||||
{
|
||||
static_type_dispatcher< value_type > disp(initializer);
|
||||
if (!attr.dispatch(disp) && !fallback_policy::apply_default(initializer))
|
||||
fallback_policy::on_invalid_type(attr.get_type());
|
||||
}
|
||||
else if (!fallback_policy::apply_default(initializer))
|
||||
{
|
||||
fallback_policy::on_missing_value();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Extraction operator. Looks for an attribute value with the specified name
|
||||
* and tries to acquire the stored value of one of the supported types. If extraction succeeds,
|
||||
* the extracted value is returned.
|
||||
*
|
||||
* \param name Attribute value name.
|
||||
* \param attrs A set of attribute values in which to look for the specified attribute value.
|
||||
* \return The extracted value, if extraction succeeded, an empty value otherwise.
|
||||
*/
|
||||
result_type operator() (attribute_name const& name, attribute_value_set const& attrs) const
|
||||
{
|
||||
try
|
||||
{
|
||||
attribute_value_set::const_iterator it = attrs.find(name);
|
||||
if (it != attrs.end())
|
||||
return operator() (it->second);
|
||||
else
|
||||
return operator() (attribute_value());
|
||||
}
|
||||
catch (exception& e)
|
||||
{
|
||||
// Attach the attribute name to the exception
|
||||
boost::log::aux::attach_attribute_name_info(e, name);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Extraction operator. Looks for an attribute value with the specified name
|
||||
* and tries to acquire the stored value of one of the supported types. If extraction succeeds,
|
||||
* the extracted value is returned.
|
||||
*
|
||||
* \param name Attribute value name.
|
||||
* \param rec A log record. The attribute value will be sought among those associated with the record.
|
||||
* \return The extracted value, if extraction succeeded, an empty value otherwise.
|
||||
*/
|
||||
result_type operator() (attribute_name const& name, record const& rec) const
|
||||
{
|
||||
return operator() (name, rec.attribute_values());
|
||||
}
|
||||
|
||||
/*!
|
||||
* Extraction operator. Looks for an attribute value with the specified name
|
||||
* and tries to acquire the stored value of one of the supported types. If extraction succeeds,
|
||||
* the extracted value is returned.
|
||||
*
|
||||
* \param name Attribute value name.
|
||||
* \param rec A log record view. The attribute value will be sought among those associated with the record.
|
||||
* \return The extracted value, if extraction succeeded, an empty value otherwise.
|
||||
*/
|
||||
result_type operator() (attribute_name const& name, record_view const& rec) const
|
||||
{
|
||||
return operator() (name, rec.attribute_values());
|
||||
}
|
||||
|
||||
/*!
|
||||
* \returns Fallback policy
|
||||
*/
|
||||
fallback_policy const& get_fallback_policy() const
|
||||
{
|
||||
return *static_cast< fallback_policy const* >(this);
|
||||
}
|
||||
};
|
||||
|
||||
#if !defined(BOOST_LOG_DOXYGEN_PASS)
|
||||
#if !defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
|
||||
#define BOOST_LOG_AUX_VOID_DEFAULT = void
|
||||
#else
|
||||
#define BOOST_LOG_AUX_VOID_DEFAULT
|
||||
#endif
|
||||
#endif // !defined(BOOST_LOG_DOXYGEN_PASS)
|
||||
|
||||
/*!
|
||||
* The function extracts an attribute value from the view. The user has to explicitly specify the
|
||||
* type or set of possible types of the attribute value to be extracted.
|
||||
*
|
||||
* \param name The name of the attribute value to extract.
|
||||
* \param attrs A set of attribute values in which to look for the specified attribute value.
|
||||
* \return A \c value_ref that refers to the extracted value, if found. An empty value otherwise.
|
||||
*/
|
||||
template< typename T, typename TagT BOOST_LOG_AUX_VOID_DEFAULT >
|
||||
inline typename result_of::extract< T, TagT >::type extract(attribute_name const& name, attribute_value_set const& attrs)
|
||||
{
|
||||
value_extractor< T, fallback_to_none, TagT > extractor;
|
||||
return extractor(name, attrs);
|
||||
}
|
||||
|
||||
/*!
|
||||
* The function extracts an attribute value from the view. The user has to explicitly specify the
|
||||
* type or set of possible types of the attribute value to be extracted.
|
||||
*
|
||||
* \param name The name of the attribute value to extract.
|
||||
* \param rec A log record. The attribute value will be sought among those associated with the record.
|
||||
* \return A \c value_ref that refers to the extracted value, if found. An empty value otherwise.
|
||||
*/
|
||||
template< typename T, typename TagT BOOST_LOG_AUX_VOID_DEFAULT >
|
||||
inline typename result_of::extract< T, TagT >::type extract(attribute_name const& name, record const& rec)
|
||||
{
|
||||
value_extractor< T, fallback_to_none, TagT > extractor;
|
||||
return extractor(name, rec);
|
||||
}
|
||||
|
||||
/*!
|
||||
* The function extracts an attribute value from the view. The user has to explicitly specify the
|
||||
* type or set of possible types of the attribute value to be extracted.
|
||||
*
|
||||
* \param name The name of the attribute value to extract.
|
||||
* \param rec A log record view. The attribute value will be sought among those associated with the record.
|
||||
* \return A \c value_ref that refers to the extracted value, if found. An empty value otherwise.
|
||||
*/
|
||||
template< typename T, typename TagT BOOST_LOG_AUX_VOID_DEFAULT >
|
||||
inline typename result_of::extract< T, TagT >::type extract(attribute_name const& name, record_view const& rec)
|
||||
{
|
||||
value_extractor< T, fallback_to_none, TagT > extractor;
|
||||
return extractor(name, rec);
|
||||
}
|
||||
|
||||
/*!
|
||||
* The function extracts an attribute value from the view. The user has to explicitly specify the
|
||||
* type or set of possible types of the attribute value to be extracted.
|
||||
*
|
||||
* \param value Attribute value.
|
||||
* \return A \c value_ref that refers to the extracted value, if found. An empty value otherwise.
|
||||
*/
|
||||
template< typename T, typename TagT BOOST_LOG_AUX_VOID_DEFAULT >
|
||||
inline typename result_of::extract< T, TagT >::type extract(attribute_value const& value)
|
||||
{
|
||||
value_extractor< T, fallback_to_none, TagT > extractor;
|
||||
return extractor(value);
|
||||
}
|
||||
|
||||
/*!
|
||||
* The function extracts an attribute value from the view. The user has to explicitly specify the
|
||||
* type or set of possible types of the attribute value to be extracted.
|
||||
*
|
||||
* \param name The name of the attribute value to extract.
|
||||
* \param attrs A set of attribute values in which to look for the specified attribute value.
|
||||
* \return The extracted value or a non-empty \c value_ref that refers to the value.
|
||||
* \throws An exception is thrown if the requested value cannot be extracted.
|
||||
*/
|
||||
template< typename T, typename TagT BOOST_LOG_AUX_VOID_DEFAULT >
|
||||
inline typename result_of::extract_or_throw< T, TagT >::type extract_or_throw(attribute_name const& name, attribute_value_set const& attrs)
|
||||
{
|
||||
value_extractor< T, fallback_to_throw, TagT > extractor;
|
||||
return aux::unwrap_value_ref(extractor(name, attrs));
|
||||
}
|
||||
|
||||
/*!
|
||||
* The function extracts an attribute value from the view. The user has to explicitly specify the
|
||||
* type or set of possible types of the attribute value to be extracted.
|
||||
*
|
||||
* \param name The name of the attribute value to extract.
|
||||
* \param rec A log record. The attribute value will be sought among those associated with the record.
|
||||
* \return The extracted value or a non-empty \c value_ref that refers to the value.
|
||||
* \throws An exception is thrown if the requested value cannot be extracted.
|
||||
*/
|
||||
template< typename T, typename TagT BOOST_LOG_AUX_VOID_DEFAULT >
|
||||
inline typename result_of::extract_or_throw< T, TagT >::type extract_or_throw(attribute_name const& name, record const& rec)
|
||||
{
|
||||
value_extractor< T, fallback_to_throw, TagT > extractor;
|
||||
return aux::unwrap_value_ref(extractor(name, rec));
|
||||
}
|
||||
|
||||
/*!
|
||||
* The function extracts an attribute value from the view. The user has to explicitly specify the
|
||||
* type or set of possible types of the attribute value to be extracted.
|
||||
*
|
||||
* \param name The name of the attribute value to extract.
|
||||
* \param rec A log record view. The attribute value will be sought among those associated with the record.
|
||||
* \return The extracted value or a non-empty \c value_ref that refers to the value.
|
||||
* \throws An exception is thrown if the requested value cannot be extracted.
|
||||
*/
|
||||
template< typename T, typename TagT BOOST_LOG_AUX_VOID_DEFAULT >
|
||||
inline typename result_of::extract_or_throw< T, TagT >::type extract_or_throw(attribute_name const& name, record_view const& rec)
|
||||
{
|
||||
value_extractor< T, fallback_to_throw, TagT > extractor;
|
||||
return aux::unwrap_value_ref(extractor(name, rec));
|
||||
}
|
||||
|
||||
/*!
|
||||
* The function extracts an attribute value from the view. The user has to explicitly specify the
|
||||
* type or set of possible types of the attribute value to be extracted.
|
||||
*
|
||||
* \param value Attribute value.
|
||||
* \return The extracted value or a non-empty \c value_ref that refers to the value.
|
||||
* \throws An exception is thrown if the requested value cannot be extracted.
|
||||
*/
|
||||
template< typename T, typename TagT BOOST_LOG_AUX_VOID_DEFAULT >
|
||||
inline typename result_of::extract_or_throw< T, TagT >::type extract_or_throw(attribute_value const& value)
|
||||
{
|
||||
value_extractor< T, fallback_to_throw, TagT > extractor;
|
||||
return aux::unwrap_value_ref(extractor(value));
|
||||
}
|
||||
|
||||
/*!
|
||||
* The function extracts an attribute value from the view. The user has to explicitly specify the
|
||||
* type or set of possible types of the attribute value to be extracted.
|
||||
*
|
||||
* \note Caution must be exercised if the default value is a temporary object. Because the function returns
|
||||
* a reference, if the temporary object is destroyed, the reference may become dangling.
|
||||
*
|
||||
* \param name The name of the attribute value to extract.
|
||||
* \param attrs A set of attribute values in which to look for the specified attribute value.
|
||||
* \param def_val The default value
|
||||
* \return The extracted value, if found. The default value otherwise.
|
||||
*/
|
||||
template< typename T, typename TagT BOOST_LOG_AUX_VOID_DEFAULT, typename DefaultT >
|
||||
inline typename result_of::extract_or_default< T, DefaultT, TagT >::type
|
||||
extract_or_default(attribute_name const& name, attribute_value_set const& attrs, DefaultT const& def_val)
|
||||
{
|
||||
typedef typename result_of::extract_or_default< T, DefaultT, TagT >::extracted_type extracted_type;
|
||||
value_extractor< extracted_type, fallback_to_default< DefaultT const& >, TagT > extractor(def_val);
|
||||
return aux::unwrap_value_ref(extractor(name, attrs));
|
||||
}
|
||||
|
||||
/*!
|
||||
* The function extracts an attribute value from the view. The user has to explicitly specify the
|
||||
* type or set of possible types of the attribute value to be visited.
|
||||
*
|
||||
* \note Caution must be exercised if the default value is a temporary object. Because the function returns
|
||||
* a reference, if the temporary object is destroyed, the reference may become dangling.
|
||||
*
|
||||
* \param name The name of the attribute value to extract.
|
||||
* \param rec A log record. The attribute value will be sought among those associated with the record.
|
||||
* \param def_val The default value
|
||||
* \return The extracted value, if found. The default value otherwise.
|
||||
*/
|
||||
template< typename T, typename TagT BOOST_LOG_AUX_VOID_DEFAULT, typename DefaultT >
|
||||
inline typename result_of::extract_or_default< T, DefaultT, TagT >::type
|
||||
extract_or_default(attribute_name const& name, record const& rec, DefaultT const& def_val)
|
||||
{
|
||||
typedef typename result_of::extract_or_default< T, DefaultT, TagT >::extracted_type extracted_type;
|
||||
value_extractor< extracted_type, fallback_to_default< DefaultT const& >, TagT > extractor(def_val);
|
||||
return aux::unwrap_value_ref(extractor(name, rec));
|
||||
}
|
||||
|
||||
/*!
|
||||
* The function extracts an attribute value from the view. The user has to explicitly specify the
|
||||
* type or set of possible types of the attribute value to be visited.
|
||||
*
|
||||
* \note Caution must be exercised if the default value is a temporary object. Because the function returns
|
||||
* a reference, if the temporary object is destroyed, the reference may become dangling.
|
||||
*
|
||||
* \param name The name of the attribute value to extract.
|
||||
* \param rec A log record view. The attribute value will be sought among those associated with the record.
|
||||
* \param def_val The default value
|
||||
* \return The extracted value, if found. The default value otherwise.
|
||||
*/
|
||||
template< typename T, typename TagT BOOST_LOG_AUX_VOID_DEFAULT, typename DefaultT >
|
||||
inline typename result_of::extract_or_default< T, DefaultT, TagT >::type
|
||||
extract_or_default(attribute_name const& name, record_view const& rec, DefaultT const& def_val)
|
||||
{
|
||||
typedef typename result_of::extract_or_default< T, DefaultT, TagT >::extracted_type extracted_type;
|
||||
value_extractor< extracted_type, fallback_to_default< DefaultT const& >, TagT > extractor(def_val);
|
||||
return aux::unwrap_value_ref(extractor(name, rec));
|
||||
}
|
||||
|
||||
/*!
|
||||
* The function extracts an attribute value from the view. The user has to explicitly specify the
|
||||
* type or set of possible types of the attribute value to be visited.
|
||||
*
|
||||
* \note Caution must be exercised if the default value is a temporary object. Because the function returns
|
||||
* a reference, if the temporary object is destroyed, the reference may become dangling.
|
||||
*
|
||||
* \param value Attribute value.
|
||||
* \param def_val The default value
|
||||
* \return The extracted value, if found. The default value otherwise.
|
||||
*/
|
||||
template< typename T, typename TagT BOOST_LOG_AUX_VOID_DEFAULT, typename DefaultT >
|
||||
inline typename result_of::extract_or_default< T, DefaultT, TagT >::type extract_or_default(attribute_value const& value, DefaultT const& def_val)
|
||||
{
|
||||
typedef typename result_of::extract_or_default< T, DefaultT, TagT >::extracted_type extracted_type;
|
||||
value_extractor< extracted_type, fallback_to_default< DefaultT const& >, TagT > extractor(def_val);
|
||||
return aux::unwrap_value_ref(extractor(value));
|
||||
}
|
||||
|
||||
#if defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
|
||||
|
||||
template< typename T >
|
||||
inline typename result_of::extract< T >::type extract(attribute_name const& name, attribute_value_set const& attrs)
|
||||
{
|
||||
value_extractor< T, fallback_to_none > extractor;
|
||||
return extractor(name, attrs);
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
inline typename result_of::extract< T >::type extract(attribute_name const& name, record const& rec)
|
||||
{
|
||||
value_extractor< T, fallback_to_none > extractor;
|
||||
return extractor(name, rec);
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
inline typename result_of::extract< T >::type extract(attribute_name const& name, record_view const& rec)
|
||||
{
|
||||
value_extractor< T, fallback_to_none > extractor;
|
||||
return extractor(name, rec);
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
inline typename result_of::extract< T >::type extract(attribute_value const& value)
|
||||
{
|
||||
value_extractor< T, fallback_to_none > extractor;
|
||||
return extractor(value);
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
inline typename result_of::extract_or_throw< T >::type extract_or_throw(attribute_name const& name, attribute_value_set const& attrs)
|
||||
{
|
||||
value_extractor< T, fallback_to_throw > extractor;
|
||||
return aux::unwrap_value_ref(extractor(name, attrs));
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
inline typename result_of::extract_or_throw< T >::type extract_or_throw(attribute_name const& name, record const& rec)
|
||||
{
|
||||
value_extractor< T, fallback_to_throw > extractor;
|
||||
return aux::unwrap_value_ref(extractor(name, rec));
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
inline typename result_of::extract_or_throw< T >::type extract_or_throw(attribute_name const& name, record_view const& rec)
|
||||
{
|
||||
value_extractor< T, fallback_to_throw > extractor;
|
||||
return aux::unwrap_value_ref(extractor(name, rec));
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
inline typename result_of::extract_or_throw< T >::type extract_or_throw(attribute_value const& value)
|
||||
{
|
||||
value_extractor< T, fallback_to_throw > extractor;
|
||||
return aux::unwrap_value_ref(extractor(value));
|
||||
}
|
||||
|
||||
template< typename T, typename DefaultT >
|
||||
inline typename result_of::extract_or_default< T, DefaultT >::type extract_or_default(
|
||||
attribute_name const& name, attribute_value_set const& attrs, DefaultT const& def_val)
|
||||
{
|
||||
typedef typename result_of::extract_or_default< T, DefaultT >::extracted_type extracted_type;
|
||||
value_extractor< extracted_type, fallback_to_default< DefaultT const& > > extractor(def_val);
|
||||
return aux::unwrap_value_ref(extractor(name, attrs));
|
||||
}
|
||||
|
||||
template< typename T, typename DefaultT >
|
||||
inline typename result_of::extract_or_default< T, DefaultT >::type extract_or_default(
|
||||
attribute_name const& name, record const& rec, DefaultT const& def_val)
|
||||
{
|
||||
typedef typename result_of::extract_or_default< T, DefaultT >::extracted_type extracted_type;
|
||||
value_extractor< extracted_type, fallback_to_default< DefaultT const& > > extractor(def_val);
|
||||
return aux::unwrap_value_ref(extractor(name, rec));
|
||||
}
|
||||
|
||||
template< typename T, typename DefaultT >
|
||||
inline typename result_of::extract_or_default< T, DefaultT >::type extract_or_default(
|
||||
attribute_name const& name, record_view const& rec, DefaultT const& def_val)
|
||||
{
|
||||
typedef typename result_of::extract_or_default< T, DefaultT >::extracted_type extracted_type;
|
||||
value_extractor< extracted_type, fallback_to_default< DefaultT const& > > extractor(def_val);
|
||||
return aux::unwrap_value_ref(extractor(name, rec));
|
||||
}
|
||||
|
||||
template< typename T, typename DefaultT >
|
||||
inline typename result_of::extract_or_default< T, DefaultT >::type extract_or_default(attribute_value const& value, DefaultT const& def_val)
|
||||
{
|
||||
typedef typename result_of::extract_or_default< T, DefaultT >::extracted_type extracted_type;
|
||||
value_extractor< extracted_type, fallback_to_default< DefaultT const& > > extractor(def_val);
|
||||
return aux::unwrap_value_ref(extractor(value));
|
||||
}
|
||||
|
||||
#endif // defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
|
||||
|
||||
/*!
|
||||
* The function extracts an attribute value from the view. The user has to explicitly specify the
|
||||
* type or set of possible types of the attribute value to be extracted.
|
||||
*
|
||||
* \param keyword The keyword of the attribute value to extract.
|
||||
* \param attrs A set of attribute values in which to look for the specified attribute value.
|
||||
* \return A \c value_ref that refers to the extracted value, if found. An empty value otherwise.
|
||||
*/
|
||||
template< typename DescriptorT, template< typename > class ActorT >
|
||||
inline typename result_of::extract< typename DescriptorT::value_type, DescriptorT >::type
|
||||
extract(expressions::attribute_keyword< DescriptorT, ActorT > const& keyword, attribute_value_set const& attrs)
|
||||
{
|
||||
value_extractor< typename DescriptorT::value_type, fallback_to_none, DescriptorT > extractor;
|
||||
return extractor(keyword.get_name(), attrs);
|
||||
}
|
||||
|
||||
/*!
|
||||
* The function extracts an attribute value from the view. The user has to explicitly specify the
|
||||
* type or set of possible types of the attribute value to be extracted.
|
||||
*
|
||||
* \param keyword The keyword of the attribute value to extract.
|
||||
* \param rec A log record. The attribute value will be sought among those associated with the record.
|
||||
* \return A \c value_ref that refers to the extracted value, if found. An empty value otherwise.
|
||||
*/
|
||||
template< typename DescriptorT, template< typename > class ActorT >
|
||||
inline typename result_of::extract< typename DescriptorT::value_type, DescriptorT >::type
|
||||
extract(expressions::attribute_keyword< DescriptorT, ActorT > const& keyword, record const& rec)
|
||||
{
|
||||
value_extractor< typename DescriptorT::value_type, fallback_to_none, DescriptorT > extractor;
|
||||
return extractor(keyword.get_name(), rec);
|
||||
}
|
||||
|
||||
/*!
|
||||
* The function extracts an attribute value from the view. The user has to explicitly specify the
|
||||
* type or set of possible types of the attribute value to be extracted.
|
||||
*
|
||||
* \param keyword The keyword of the attribute value to extract.
|
||||
* \param rec A log record view. The attribute value will be sought among those associated with the record.
|
||||
* \return A \c value_ref that refers to the extracted value, if found. An empty value otherwise.
|
||||
*/
|
||||
template< typename DescriptorT, template< typename > class ActorT >
|
||||
inline typename result_of::extract< typename DescriptorT::value_type, DescriptorT >::type
|
||||
extract(expressions::attribute_keyword< DescriptorT, ActorT > const& keyword, record_view const& rec)
|
||||
{
|
||||
value_extractor< typename DescriptorT::value_type, fallback_to_none, DescriptorT > extractor;
|
||||
return extractor(keyword.get_name(), rec);
|
||||
}
|
||||
|
||||
/*!
|
||||
* The function extracts an attribute value from the view. The user has to explicitly specify the
|
||||
* type or set of possible types of the attribute value to be extracted.
|
||||
*
|
||||
* \param keyword The keyword of the attribute value to extract.
|
||||
* \param attrs A set of attribute values in which to look for the specified attribute value.
|
||||
* \return The extracted value or a non-empty \c value_ref that refers to the value.
|
||||
* \throws An exception is thrown if the requested value cannot be extracted.
|
||||
*/
|
||||
template< typename DescriptorT, template< typename > class ActorT >
|
||||
inline typename result_of::extract_or_throw< typename DescriptorT::value_type, DescriptorT >::type
|
||||
extract_or_throw(expressions::attribute_keyword< DescriptorT, ActorT > const& keyword, attribute_value_set const& attrs)
|
||||
{
|
||||
value_extractor< typename DescriptorT::value_type, fallback_to_throw, DescriptorT > extractor;
|
||||
return aux::unwrap_value_ref(extractor(keyword.get_name(), attrs));
|
||||
}
|
||||
|
||||
/*!
|
||||
* The function extracts an attribute value from the view. The user has to explicitly specify the
|
||||
* type or set of possible types of the attribute value to be extracted.
|
||||
*
|
||||
* \param keyword The keyword of the attribute value to extract.
|
||||
* \param rec A log record. The attribute value will be sought among those associated with the record.
|
||||
* \return The extracted value or a non-empty \c value_ref that refers to the value.
|
||||
* \throws An exception is thrown if the requested value cannot be extracted.
|
||||
*/
|
||||
template< typename DescriptorT, template< typename > class ActorT >
|
||||
inline typename result_of::extract_or_throw< typename DescriptorT::value_type, DescriptorT >::type
|
||||
extract_or_throw(expressions::attribute_keyword< DescriptorT, ActorT > const& keyword, record const& rec)
|
||||
{
|
||||
value_extractor< typename DescriptorT::value_type, fallback_to_throw, DescriptorT > extractor;
|
||||
return aux::unwrap_value_ref(extractor(keyword.get_name(), rec));
|
||||
}
|
||||
|
||||
/*!
|
||||
* The function extracts an attribute value from the view. The user has to explicitly specify the
|
||||
* type or set of possible types of the attribute value to be extracted.
|
||||
*
|
||||
* \param keyword The keyword of the attribute value to extract.
|
||||
* \param rec A log record view. The attribute value will be sought among those associated with the record.
|
||||
* \return The extracted value or a non-empty \c value_ref that refers to the value.
|
||||
* \throws An exception is thrown if the requested value cannot be extracted.
|
||||
*/
|
||||
template< typename DescriptorT, template< typename > class ActorT >
|
||||
inline typename result_of::extract_or_throw< typename DescriptorT::value_type, DescriptorT >::type
|
||||
extract_or_throw(expressions::attribute_keyword< DescriptorT, ActorT > const& keyword, record_view const& rec)
|
||||
{
|
||||
value_extractor< typename DescriptorT::value_type, fallback_to_throw, DescriptorT > extractor;
|
||||
return aux::unwrap_value_ref(extractor(keyword.get_name(), rec));
|
||||
}
|
||||
|
||||
/*!
|
||||
* The function extracts an attribute value from the view. The user has to explicitly specify the
|
||||
* type or set of possible types of the attribute value to be extracted.
|
||||
*
|
||||
* \note Caution must be exercised if the default value is a temporary object. Because the function returns
|
||||
* a reference, if the temporary object is destroyed, the reference may become dangling.
|
||||
*
|
||||
* \param keyword The keyword of the attribute value to extract.
|
||||
* \param attrs A set of attribute values in which to look for the specified attribute value.
|
||||
* \param def_val The default value
|
||||
* \return The extracted value, if found. The default value otherwise.
|
||||
*/
|
||||
template< typename DescriptorT, template< typename > class ActorT, typename DefaultT >
|
||||
inline typename result_of::extract_or_default< typename DescriptorT::value_type, DefaultT, DescriptorT >::type
|
||||
extract_or_default(expressions::attribute_keyword< DescriptorT, ActorT > const& keyword, attribute_value_set const& attrs, DefaultT const& def_val)
|
||||
{
|
||||
typedef typename result_of::extract_or_default< typename DescriptorT::value_type, DefaultT, DescriptorT >::extracted_type extracted_type;
|
||||
value_extractor< extracted_type, fallback_to_default< DefaultT const& >, DescriptorT > extractor(def_val);
|
||||
return aux::unwrap_value_ref(extractor(keyword.get_name(), attrs));
|
||||
}
|
||||
|
||||
/*!
|
||||
* The function extracts an attribute value from the view. The user has to explicitly specify the
|
||||
* type or set of possible types of the attribute value to be visited.
|
||||
*
|
||||
* \note Caution must be exercised if the default value is a temporary object. Because the function returns
|
||||
* a reference, if the temporary object is destroyed, the reference may become dangling.
|
||||
*
|
||||
* \param keyword The keyword of the attribute value to extract.
|
||||
* \param rec A log record. The attribute value will be sought among those associated with the record.
|
||||
* \param def_val The default value
|
||||
* \return The extracted value, if found. The default value otherwise.
|
||||
*/
|
||||
template< typename DescriptorT, template< typename > class ActorT, typename DefaultT >
|
||||
inline typename result_of::extract_or_default< typename DescriptorT::value_type, DefaultT, DescriptorT >::type
|
||||
extract_or_default(expressions::attribute_keyword< DescriptorT, ActorT > const& keyword, record const& rec, DefaultT const& def_val)
|
||||
{
|
||||
typedef typename result_of::extract_or_default< typename DescriptorT::value_type, DefaultT, DescriptorT >::extracted_type extracted_type;
|
||||
value_extractor< extracted_type, fallback_to_default< DefaultT const& >, DescriptorT > extractor(def_val);
|
||||
return aux::unwrap_value_ref(extractor(keyword.get_name(), rec));
|
||||
}
|
||||
|
||||
/*!
|
||||
* The function extracts an attribute value from the view. The user has to explicitly specify the
|
||||
* type or set of possible types of the attribute value to be visited.
|
||||
*
|
||||
* \note Caution must be exercised if the default value is a temporary object. Because the function returns
|
||||
* a reference, if the temporary object is destroyed, the reference may become dangling.
|
||||
*
|
||||
* \param keyword The keyword of the attribute value to extract.
|
||||
* \param rec A log record view. The attribute value will be sought among those associated with the record.
|
||||
* \param def_val The default value
|
||||
* \return The extracted value, if found. The default value otherwise.
|
||||
*/
|
||||
template< typename DescriptorT, template< typename > class ActorT, typename DefaultT >
|
||||
inline typename result_of::extract_or_default< typename DescriptorT::value_type, DefaultT, DescriptorT >::type
|
||||
extract_or_default(expressions::attribute_keyword< DescriptorT, ActorT > const& keyword, record_view const& rec, DefaultT const& def_val)
|
||||
{
|
||||
typedef typename result_of::extract_or_default< typename DescriptorT::value_type, DefaultT, DescriptorT >::extracted_type extracted_type;
|
||||
value_extractor< extracted_type, fallback_to_default< DefaultT const& >, DescriptorT > extractor(def_val);
|
||||
return aux::unwrap_value_ref(extractor(keyword.get_name(), rec));
|
||||
}
|
||||
|
||||
#if !defined(BOOST_LOG_DOXYGEN_PASS)
|
||||
|
||||
template< typename T, typename TagT >
|
||||
inline typename result_of::extract< T, TagT >::type attribute_value::extract() const
|
||||
{
|
||||
return boost::log::extract< T, TagT >(*this);
|
||||
}
|
||||
|
||||
template< typename T, typename TagT >
|
||||
inline typename result_of::extract_or_throw< T, TagT >::type attribute_value::extract_or_throw() const
|
||||
{
|
||||
return boost::log::extract_or_throw< T, TagT >(*this);
|
||||
}
|
||||
|
||||
template< typename T, typename TagT >
|
||||
inline typename result_of::extract_or_default< T, T, TagT >::type attribute_value::extract_or_default(T const& def_value) const
|
||||
{
|
||||
return boost::log::extract_or_default< T, TagT >(*this, def_value);
|
||||
}
|
||||
|
||||
template< typename T, typename TagT, typename DefaultT >
|
||||
inline typename result_of::extract_or_default< T, DefaultT, TagT >::type attribute_value::extract_or_default(DefaultT const& def_value) const
|
||||
{
|
||||
return boost::log::extract_or_default< T, TagT >(*this, def_value);
|
||||
}
|
||||
|
||||
#if defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
|
||||
|
||||
template< typename T >
|
||||
inline typename result_of::extract< T >::type attribute_value::extract() const
|
||||
{
|
||||
return boost::log::extract< T >(*this);
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
inline typename result_of::extract_or_throw< T >::type attribute_value::extract_or_throw() const
|
||||
{
|
||||
return boost::log::extract_or_throw< T >(*this);
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
inline typename result_of::extract_or_default< T, T >::type attribute_value::extract_or_default(T const& def_value) const
|
||||
{
|
||||
return boost::log::extract_or_default< T >(*this, def_value);
|
||||
}
|
||||
|
||||
template< typename T, typename DefaultT >
|
||||
inline typename result_of::extract_or_default< T, DefaultT >::type attribute_value::extract_or_default(DefaultT const& def_value) const
|
||||
{
|
||||
return boost::log::extract_or_default< T >(*this, def_value);
|
||||
}
|
||||
|
||||
#endif // defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
|
||||
|
||||
#endif // !defined(BOOST_LOG_DOXYGEN_PASS)
|
||||
|
||||
#undef BOOST_LOG_AUX_VOID_DEFAULT
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_ATTRIBUTES_VALUE_EXTRACTION_HPP_INCLUDED_
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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 value_extraction_fwd.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 01.03.2008
|
||||
*
|
||||
* The header contains forward declaration of tools for extracting attribute values
|
||||
* from the view.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_ATTRIBUTES_VALUE_EXTRACTION_FWD_HPP_INCLUDED_
|
||||
#define BOOST_LOG_ATTRIBUTES_VALUE_EXTRACTION_FWD_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/attributes/fallback_policy_fwd.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace result_of {
|
||||
|
||||
/*!
|
||||
* \brief A metafunction that allows to acquire the result of the value extraction
|
||||
*/
|
||||
template< typename T, typename DefaultT = T, typename TagT = void >
|
||||
struct extract_or_default;
|
||||
|
||||
/*!
|
||||
* \brief A metafunction that allows to acquire the result of the value extraction
|
||||
*/
|
||||
template< typename T, typename TagT = void >
|
||||
struct extract_or_throw;
|
||||
|
||||
/*!
|
||||
* \brief A metafunction that allows to acquire the result of the value extraction
|
||||
*/
|
||||
template< typename T, typename TagT = void >
|
||||
struct extract;
|
||||
|
||||
} // namespace result_of
|
||||
|
||||
/*!
|
||||
* \brief Generic attribute value extractor
|
||||
*/
|
||||
template< typename T, typename FallbackPolicyT = fallback_to_none, typename TagT = void >
|
||||
class value_extractor;
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_LOG_ATTRIBUTES_VALUE_EXTRACTION_FWD_HPP_INCLUDED_
|
||||
@@ -0,0 +1,372 @@
|
||||
/*
|
||||
* 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 value_visitation.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 01.03.2008
|
||||
*
|
||||
* The header contains implementation of convenience tools to apply visitors to an attribute value
|
||||
* in the view.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_ATTRIBUTES_VALUE_VISITATION_HPP_INCLUDED_
|
||||
#define BOOST_LOG_ATTRIBUTES_VALUE_VISITATION_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/exceptions.hpp>
|
||||
#include <boost/log/core/record.hpp>
|
||||
#include <boost/log/attributes/attribute_name.hpp>
|
||||
#include <boost/log/attributes/attribute_value.hpp>
|
||||
#include <boost/log/attributes/attribute.hpp>
|
||||
#include <boost/log/attributes/attribute_value_set.hpp>
|
||||
#include <boost/log/attributes/value_visitation_fwd.hpp>
|
||||
#include <boost/log/attributes/fallback_policy.hpp>
|
||||
#include <boost/log/expressions/keyword_fwd.hpp>
|
||||
#include <boost/utility/explicit_operator_bool.hpp>
|
||||
#include <boost/log/utility/type_dispatch/static_type_dispatcher.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
/*!
|
||||
* \brief The class represents attribute value visitation result
|
||||
*
|
||||
* The main purpose of this class is to provide a convenient interface for checking
|
||||
* whether the attribute value visitation succeeded or not. It also allows to discover
|
||||
* the actual cause of failure, should the operation fail.
|
||||
*/
|
||||
class visitation_result
|
||||
{
|
||||
public:
|
||||
//! Error codes for attribute value visitation
|
||||
enum error_code
|
||||
{
|
||||
ok, //!< The attribute value has been visited successfully
|
||||
value_not_found, //!< The attribute value is not present in the view
|
||||
value_has_invalid_type //!< The attribute value is present in the view, but has an unexpected type
|
||||
};
|
||||
|
||||
private:
|
||||
error_code m_code;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Initializing constructor. Creates the result that is equivalent to the
|
||||
* specified error code.
|
||||
*/
|
||||
BOOST_CONSTEXPR visitation_result(error_code code = ok) BOOST_NOEXCEPT : m_code(code) {}
|
||||
|
||||
/*!
|
||||
* Checks if the visitation was successful.
|
||||
*
|
||||
* \return \c true if the value was visited successfully, \c false otherwise.
|
||||
*/
|
||||
BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
|
||||
/*!
|
||||
* Checks if the visitation was unsuccessful.
|
||||
*
|
||||
* \return \c false if the value was visited successfully, \c true otherwise.
|
||||
*/
|
||||
bool operator! () const BOOST_NOEXCEPT { return (m_code != ok); }
|
||||
|
||||
/*!
|
||||
* \return The actual result code of value visitation
|
||||
*/
|
||||
error_code code() const BOOST_NOEXCEPT { return m_code; }
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Generic attribute value visitor invoker
|
||||
*
|
||||
* Attribute value invoker is a functional object that attempts to find and extract the stored
|
||||
* attribute value from the attribute value view or a log record. The extracted value is passed to
|
||||
* a unary function object (the visitor) provided by user.
|
||||
*
|
||||
* The invoker can be specialized on one or several attribute value types that should be
|
||||
* specified in the second template argument.
|
||||
*/
|
||||
template< typename T, typename FallbackPolicyT >
|
||||
class value_visitor_invoker :
|
||||
private FallbackPolicyT
|
||||
{
|
||||
typedef value_visitor_invoker< T, FallbackPolicyT > this_type;
|
||||
|
||||
public:
|
||||
//! Attribute value types
|
||||
typedef T value_type;
|
||||
|
||||
//! Fallback policy
|
||||
typedef FallbackPolicyT fallback_policy;
|
||||
|
||||
//! Function object result type
|
||||
typedef visitation_result result_type;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Default constructor
|
||||
*/
|
||||
BOOST_DEFAULTED_FUNCTION(value_visitor_invoker(), {})
|
||||
|
||||
/*!
|
||||
* Copy constructor
|
||||
*/
|
||||
value_visitor_invoker(value_visitor_invoker const& that) : fallback_policy(static_cast< fallback_policy const& >(that))
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* Initializing constructor
|
||||
*
|
||||
* \param arg Fallback policy argument
|
||||
*/
|
||||
template< typename U >
|
||||
explicit value_visitor_invoker(U const& arg) : fallback_policy(arg) {}
|
||||
|
||||
/*!
|
||||
* Visitation operator. Attempts to acquire the stored value of one of the supported types. If acquisition succeeds,
|
||||
* the value is passed to \a visitor.
|
||||
*
|
||||
* \param attr An attribute value to apply the visitor to.
|
||||
* \param visitor A receiving function object to pass the attribute value to.
|
||||
* \return The result of visitation.
|
||||
*/
|
||||
template< typename VisitorT >
|
||||
result_type operator() (attribute_value const& attr, VisitorT visitor) const
|
||||
{
|
||||
if (!!attr)
|
||||
{
|
||||
static_type_dispatcher< value_type > disp(visitor);
|
||||
if (attr.dispatch(disp) || fallback_policy::apply_default(visitor))
|
||||
{
|
||||
return visitation_result::ok;
|
||||
}
|
||||
else
|
||||
{
|
||||
fallback_policy::on_invalid_type(attr.get_type());
|
||||
return visitation_result::value_has_invalid_type;
|
||||
}
|
||||
}
|
||||
|
||||
if (fallback_policy::apply_default(visitor))
|
||||
return visitation_result::ok;
|
||||
|
||||
fallback_policy::on_missing_value();
|
||||
return visitation_result::value_not_found;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Visitation operator. Looks for an attribute value with the specified name
|
||||
* and tries to acquire the stored value of one of the supported types. If acquisition succeeds,
|
||||
* the value is passed to \a visitor.
|
||||
*
|
||||
* \param name Attribute value name.
|
||||
* \param attrs A set of attribute values in which to look for the specified attribute value.
|
||||
* \param visitor A receiving function object to pass the attribute value to.
|
||||
* \return The result of visitation.
|
||||
*/
|
||||
template< typename VisitorT >
|
||||
result_type operator() (attribute_name const& name, attribute_value_set const& attrs, VisitorT visitor) const
|
||||
{
|
||||
try
|
||||
{
|
||||
attribute_value_set::const_iterator it = attrs.find(name);
|
||||
if (it != attrs.end())
|
||||
return operator() (it->second, visitor);
|
||||
else
|
||||
return operator() (attribute_value(), visitor);
|
||||
}
|
||||
catch (exception& e)
|
||||
{
|
||||
// Attach the attribute name to the exception
|
||||
boost::log::aux::attach_attribute_name_info(e, name);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Visitation operator. Looks for an attribute value with the specified name
|
||||
* and tries to acquire the stored value of one of the supported types. If acquisition succeeds,
|
||||
* the value is passed to \a visitor.
|
||||
*
|
||||
* \param name Attribute value name.
|
||||
* \param rec A log record. The attribute value will be sought among those associated with the record.
|
||||
* \param visitor A receiving function object to pass the attribute value to.
|
||||
* \return The result of visitation.
|
||||
*/
|
||||
template< typename VisitorT >
|
||||
result_type operator() (attribute_name const& name, record const& rec, VisitorT visitor) const
|
||||
{
|
||||
return operator() (name, rec.attribute_values(), visitor);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Visitation operator. Looks for an attribute value with the specified name
|
||||
* and tries to acquire the stored value of one of the supported types. If acquisition succeeds,
|
||||
* the value is passed to \a visitor.
|
||||
*
|
||||
* \param name Attribute value name.
|
||||
* \param rec A log record view. The attribute value will be sought among those associated with the record.
|
||||
* \param visitor A receiving function object to pass the attribute value to.
|
||||
* \return The result of visitation.
|
||||
*/
|
||||
template< typename VisitorT >
|
||||
result_type operator() (attribute_name const& name, record_view const& rec, VisitorT visitor) const
|
||||
{
|
||||
return operator() (name, rec.attribute_values(), visitor);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \returns Fallback policy
|
||||
*/
|
||||
fallback_policy const& get_fallback_policy() const
|
||||
{
|
||||
return *static_cast< fallback_policy const* >(this);
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* The function applies a visitor to an attribute value from the view. The user has to explicitly specify the
|
||||
* type or set of possible types of the attribute value to be visited.
|
||||
*
|
||||
* \param name The name of the attribute value to visit.
|
||||
* \param attrs A set of attribute values in which to look for the specified attribute value.
|
||||
* \param visitor A receiving function object to pass the attribute value to.
|
||||
* \return The result of visitation.
|
||||
*/
|
||||
template< typename T, typename VisitorT >
|
||||
inline visitation_result
|
||||
visit(attribute_name const& name, attribute_value_set const& attrs, VisitorT visitor)
|
||||
{
|
||||
value_visitor_invoker< T > invoker;
|
||||
return invoker(name, attrs, visitor);
|
||||
}
|
||||
|
||||
/*!
|
||||
* The function applies a visitor to an attribute value from the view. The user has to explicitly specify the
|
||||
* type or set of possible types of the attribute value to be visited.
|
||||
*
|
||||
* \param name The name of the attribute value to visit.
|
||||
* \param rec A log record. The attribute value will be sought among those associated with the record.
|
||||
* \param visitor A receiving function object to pass the attribute value to.
|
||||
* \return The result of visitation.
|
||||
*/
|
||||
template< typename T, typename VisitorT >
|
||||
inline visitation_result
|
||||
visit(attribute_name const& name, record const& rec, VisitorT visitor)
|
||||
{
|
||||
value_visitor_invoker< T > invoker;
|
||||
return invoker(name, rec, visitor);
|
||||
}
|
||||
|
||||
/*!
|
||||
* The function applies a visitor to an attribute value from the view. The user has to explicitly specify the
|
||||
* type or set of possible types of the attribute value to be visited.
|
||||
*
|
||||
* \param name The name of the attribute value to visit.
|
||||
* \param rec A log record view. The attribute value will be sought among those associated with the record.
|
||||
* \param visitor A receiving function object to pass the attribute value to.
|
||||
* \return The result of visitation.
|
||||
*/
|
||||
template< typename T, typename VisitorT >
|
||||
inline visitation_result
|
||||
visit(attribute_name const& name, record_view const& rec, VisitorT visitor)
|
||||
{
|
||||
value_visitor_invoker< T > invoker;
|
||||
return invoker(name, rec, visitor);
|
||||
}
|
||||
|
||||
/*!
|
||||
* The function applies a visitor to an attribute value. The user has to explicitly specify the
|
||||
* type or set of possible types of the attribute value to be visited.
|
||||
*
|
||||
* \param value The attribute value to visit.
|
||||
* \param visitor A receiving function object to pass the attribute value to.
|
||||
* \return The result of visitation.
|
||||
*/
|
||||
template< typename T, typename VisitorT >
|
||||
inline visitation_result
|
||||
visit(attribute_value const& value, VisitorT visitor)
|
||||
{
|
||||
value_visitor_invoker< T > invoker;
|
||||
return invoker(value, visitor);
|
||||
}
|
||||
|
||||
/*!
|
||||
* The function applies a visitor to an attribute value from the view. The user has to explicitly specify the
|
||||
* type or set of possible types of the attribute value to be visited.
|
||||
*
|
||||
* \param keyword The keyword of the attribute value to visit.
|
||||
* \param attrs A set of attribute values in which to look for the specified attribute value.
|
||||
* \param visitor A receiving function object to pass the attribute value to.
|
||||
* \return The result of visitation.
|
||||
*/
|
||||
template< typename DescriptorT, template< typename > class ActorT, typename VisitorT >
|
||||
inline visitation_result
|
||||
visit(expressions::attribute_keyword< DescriptorT, ActorT > const& keyword, attribute_value_set const& attrs, VisitorT visitor)
|
||||
{
|
||||
value_visitor_invoker< typename DescriptorT::value_type > invoker;
|
||||
return invoker(keyword.get_name(), attrs, visitor);
|
||||
}
|
||||
|
||||
/*!
|
||||
* The function applies a visitor to an attribute value from the view. The user has to explicitly specify the
|
||||
* type or set of possible types of the attribute value to be visited.
|
||||
*
|
||||
* \param keyword The keyword of the attribute value to visit.
|
||||
* \param rec A log record. The attribute value will be sought among those associated with the record.
|
||||
* \param visitor A receiving function object to pass the attribute value to.
|
||||
* \return The result of visitation.
|
||||
*/
|
||||
template< typename DescriptorT, template< typename > class ActorT, typename VisitorT >
|
||||
inline visitation_result
|
||||
visit(expressions::attribute_keyword< DescriptorT, ActorT > const& keyword, record const& rec, VisitorT visitor)
|
||||
{
|
||||
value_visitor_invoker< typename DescriptorT::value_type > invoker;
|
||||
return invoker(keyword.get_name(), rec, visitor);
|
||||
}
|
||||
|
||||
/*!
|
||||
* The function applies a visitor to an attribute value from the view. The user has to explicitly specify the
|
||||
* type or set of possible types of the attribute value to be visited.
|
||||
*
|
||||
* \param keyword The keyword of the attribute value to visit.
|
||||
* \param rec A log record view. The attribute value will be sought among those associated with the record.
|
||||
* \param visitor A receiving function object to pass the attribute value to.
|
||||
* \return The result of visitation.
|
||||
*/
|
||||
template< typename DescriptorT, template< typename > class ActorT, typename VisitorT >
|
||||
inline visitation_result
|
||||
visit(expressions::attribute_keyword< DescriptorT, ActorT > const& keyword, record_view const& rec, VisitorT visitor)
|
||||
{
|
||||
value_visitor_invoker< typename DescriptorT::value_type > invoker;
|
||||
return invoker(keyword.get_name(), rec, visitor);
|
||||
}
|
||||
|
||||
|
||||
#if !defined(BOOST_LOG_DOXYGEN_PASS)
|
||||
|
||||
template< typename T, typename VisitorT >
|
||||
inline visitation_result attribute_value::visit(VisitorT visitor) const
|
||||
{
|
||||
return boost::log::visit< T >(*this, visitor);
|
||||
}
|
||||
|
||||
#endif // !defined(BOOST_LOG_DOXYGEN_PASS)
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_ATTRIBUTES_VALUE_VISITATION_HPP_INCLUDED_
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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 value_visitation_fwd.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 01.03.2008
|
||||
*
|
||||
* The header contains forward declaration of convenience tools to apply visitors to an attribute value
|
||||
* in the view.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_ATTRIBUTES_VALUE_VISITATION_FWD_HPP_INCLUDED_
|
||||
#define BOOST_LOG_ATTRIBUTES_VALUE_VISITATION_FWD_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/attributes/fallback_policy_fwd.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
/*!
|
||||
* \brief The class represents attribute value visitation result
|
||||
*/
|
||||
class visitation_result;
|
||||
|
||||
/*!
|
||||
* \brief Generic attribute value visitor invoker
|
||||
*/
|
||||
template< typename T, typename FallbackPolicyT = fallback_to_none >
|
||||
class value_visitor_invoker;
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_LOG_ATTRIBUTES_VALUE_VISITATION_FWD_HPP_INCLUDED_
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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 common.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 14.03.2009
|
||||
*
|
||||
* This header includes other Boost.Log headers that are commonly used in logging applications.
|
||||
* Note that the header does not include any headers required to setup the library, as usually
|
||||
* they aren't needed in more than one translation unit of the application.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_COMMON_HPP_INCLUDED_
|
||||
#define BOOST_LOG_COMMON_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
|
||||
#include <boost/log/core.hpp>
|
||||
|
||||
#include <boost/log/sources/global_logger_storage.hpp>
|
||||
#include <boost/log/sources/record_ostream.hpp>
|
||||
|
||||
#include <boost/log/sources/basic_logger.hpp>
|
||||
#include <boost/log/sources/severity_logger.hpp>
|
||||
#include <boost/log/sources/channel_logger.hpp>
|
||||
#include <boost/log/sources/severity_channel_logger.hpp>
|
||||
#include <boost/log/sources/exception_handler_feature.hpp>
|
||||
|
||||
#include <boost/log/attributes/constant.hpp>
|
||||
#include <boost/log/attributes/named_scope.hpp>
|
||||
#include <boost/log/attributes/scoped_attribute.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#endif // BOOST_LOG_COMMON_HPP_INCLUDED_
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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 log/core.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 19.04.2007
|
||||
*
|
||||
* This header includes Boost.Log headers related to the logging core.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_CORE_HPP_INCLUDED_
|
||||
#define BOOST_LOG_CORE_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
|
||||
#include <boost/log/core/core.hpp>
|
||||
#include <boost/log/core/record.hpp>
|
||||
#include <boost/log/core/record_view.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#endif // BOOST_LOG_CORE_HPP_INCLUDED_
|
||||
@@ -0,0 +1,329 @@
|
||||
/*
|
||||
* 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 core/core.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 19.04.2007
|
||||
*
|
||||
* This header contains logging core class definition.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_CORE_CORE_HPP_INCLUDED_
|
||||
#define BOOST_LOG_CORE_CORE_HPP_INCLUDED_
|
||||
|
||||
#include <utility>
|
||||
#include <boost/smart_ptr/shared_ptr.hpp>
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/light_function.hpp>
|
||||
#include <boost/log/core/record.hpp>
|
||||
#include <boost/log/attributes/attribute_set.hpp>
|
||||
#include <boost/log/attributes/attribute_name.hpp>
|
||||
#include <boost/log/attributes/attribute.hpp>
|
||||
#include <boost/log/attributes/attribute_value_set.hpp>
|
||||
#include <boost/log/expressions/filter.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
namespace sinks {
|
||||
|
||||
class sink;
|
||||
|
||||
} // namespace sinks
|
||||
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
class core;
|
||||
|
||||
typedef shared_ptr< core > core_ptr;
|
||||
|
||||
/*!
|
||||
* \brief Logging library core class
|
||||
*
|
||||
* The logging core is used to interconnect log sources and sinks. It also provides
|
||||
* a number of basic features, like global filtering and global and thread-specific attribute storage.
|
||||
*
|
||||
* The logging core is a singleton. Users can acquire the core instance by calling the static method <tt>get</tt>.
|
||||
*/
|
||||
class core
|
||||
{
|
||||
public:
|
||||
//! Exception handler function type
|
||||
typedef boost::log::aux::light_function< void () > exception_handler_type;
|
||||
|
||||
private:
|
||||
//! Implementation type
|
||||
struct implementation;
|
||||
friend struct implementation;
|
||||
|
||||
private:
|
||||
//! A pointer to the implementation
|
||||
implementation* m_impl;
|
||||
|
||||
private:
|
||||
//! \cond
|
||||
core();
|
||||
//! \endcond
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Destructor. Destroys the core, releases any sinks and attributes that were registered.
|
||||
*/
|
||||
~core();
|
||||
|
||||
/*!
|
||||
* \return The method returns a pointer to the logging core singleton instance.
|
||||
*/
|
||||
BOOST_LOG_API static core_ptr get();
|
||||
|
||||
/*!
|
||||
* The method enables or disables logging.
|
||||
*
|
||||
* Setting this status to \c false allows you to completely wipe out any logging activity, including
|
||||
* filtering and generation of attribute values. It is useful if you want to completely disable logging
|
||||
* in a running application. The state of logging does not alter any other properties of the logging
|
||||
* library, such as filters or sinks, so you can enable logging with the very same settings that you had
|
||||
* when the logging was disabled.
|
||||
* This feature may also be useful if you want to perform major changes to logging configuration and
|
||||
* don't want your application to block on opening or pushing a log record.
|
||||
*
|
||||
* By default logging is enabled.
|
||||
*
|
||||
* \param enabled The actual flag of logging activity.
|
||||
* \return The previous value of enabled/disabled logging flag
|
||||
*/
|
||||
BOOST_LOG_API bool set_logging_enabled(bool enabled = true);
|
||||
/*!
|
||||
* The method allows to detect if logging is enabled. See the comment for \c set_logging_enabled.
|
||||
*/
|
||||
BOOST_LOG_API bool get_logging_enabled() const;
|
||||
|
||||
/*!
|
||||
* The method sets the global logging filter. The filter is applied to every log record that is processed.
|
||||
*
|
||||
* \param filter The filter function object to be installed.
|
||||
*/
|
||||
BOOST_LOG_API void set_filter(filter const& filter);
|
||||
/*!
|
||||
* The method removes the global logging filter. All log records are passed to sinks without global filtering applied.
|
||||
*/
|
||||
BOOST_LOG_API void reset_filter();
|
||||
|
||||
/*!
|
||||
* The method adds a new sink. The sink is included into logging process immediately after being added and until being removed.
|
||||
* No sink can be added more than once at the same time. If the sink is already registered, the call is ignored.
|
||||
*
|
||||
* \param s The sink to be registered.
|
||||
*/
|
||||
BOOST_LOG_API void add_sink(shared_ptr< sinks::sink > const& s);
|
||||
/*!
|
||||
* The method removes the sink from the output. The sink will not receive any log records after removal.
|
||||
* The call has no effect if the sink is not registered.
|
||||
*
|
||||
* \param s The sink to be unregistered.
|
||||
*/
|
||||
BOOST_LOG_API void remove_sink(shared_ptr< sinks::sink > const& s);
|
||||
/*!
|
||||
* The method removes all registered sinks from the output. The sinks will not receive any log records after removal.
|
||||
*/
|
||||
BOOST_LOG_API void remove_all_sinks();
|
||||
|
||||
/*!
|
||||
* The method performs flush on all registered sinks.
|
||||
*
|
||||
* \note This method may take long time to complete as it may block until all sinks manage to process all buffered log records.
|
||||
* The call will also block all logging attempts until the operation completes.
|
||||
*/
|
||||
BOOST_LOG_API void flush();
|
||||
|
||||
/*!
|
||||
* The method adds an attribute to the global attribute set. The attribute will be implicitly added to every log record.
|
||||
*
|
||||
* \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.
|
||||
*/
|
||||
BOOST_LOG_API std::pair< attribute_set::iterator, bool > add_global_attribute(attribute_name const& name, attribute const& attr);
|
||||
/*!
|
||||
* The method removes an attribute from the global attribute set.
|
||||
*
|
||||
* \pre The attribute was added with the \c add_global_attribute call.
|
||||
* \post The attribute is no longer registered as a global attribute. The iterator is invalidated after removal.
|
||||
*
|
||||
* \param it Iterator to the previously added attribute.
|
||||
*/
|
||||
BOOST_LOG_API void remove_global_attribute(attribute_set::iterator it);
|
||||
|
||||
/*!
|
||||
* The method returns a copy of the complete set of currently registered global attributes.
|
||||
*/
|
||||
BOOST_LOG_API attribute_set get_global_attributes() const;
|
||||
/*!
|
||||
* The method replaces the complete set of currently registered global attributes with the provided set.
|
||||
*
|
||||
* \note The method invalidates all iterators and references that may have been returned
|
||||
* from the \c add_global_attribute method.
|
||||
*
|
||||
* \param attrs The set of attributes to be installed.
|
||||
*/
|
||||
BOOST_LOG_API void set_global_attributes(attribute_set const& attrs);
|
||||
|
||||
/*!
|
||||
* The method adds an attribute to the thread-specific attribute set. The attribute will be implicitly added to
|
||||
* every log record made in the current thread.
|
||||
*
|
||||
* \note In single-threaded build the effect is the same as adding the attribute globally. This, however, does
|
||||
* not imply that iterators to thread-specific and global attributes are interchangeable.
|
||||
*
|
||||
* \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.
|
||||
*/
|
||||
BOOST_LOG_API std::pair< attribute_set::iterator, bool > add_thread_attribute(attribute_name const& name, attribute const& attr);
|
||||
/*!
|
||||
* The method removes an attribute from the thread-specific attribute set.
|
||||
*
|
||||
* \pre The attribute was added with the \c add_thread_attribute call.
|
||||
* \post The attribute is no longer registered as a thread-specific attribute. The iterator is invalidated after removal.
|
||||
*
|
||||
* \param it Iterator to the previously added attribute.
|
||||
*/
|
||||
BOOST_LOG_API void remove_thread_attribute(attribute_set::iterator it);
|
||||
|
||||
/*!
|
||||
* The method returns a copy of the complete set of currently registered thread-specific attributes.
|
||||
*/
|
||||
BOOST_LOG_API attribute_set get_thread_attributes() const;
|
||||
/*!
|
||||
* The method replaces the complete set of currently registered thread-specific attributes with the provided set.
|
||||
*
|
||||
* \note The method invalidates all iterators and references that may have been returned
|
||||
* from the \c add_thread_attribute method.
|
||||
*
|
||||
* \param attrs The set of attributes to be installed.
|
||||
*/
|
||||
BOOST_LOG_API void set_thread_attributes(attribute_set const& attrs);
|
||||
|
||||
/*!
|
||||
* 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 See also: <tt>utility/exception_handler.hpp</tt>
|
||||
* \param handler Exception handling function
|
||||
*
|
||||
* \note The exception handler can be invoked in several threads concurrently.
|
||||
* Thread interruptions are not affected by exception handlers.
|
||||
*/
|
||||
BOOST_LOG_API void set_exception_handler(exception_handler_type const& handler);
|
||||
|
||||
/*!
|
||||
* The method attempts to open a new record to be written. While attempting to open a log record all filtering is applied.
|
||||
* A successfully opened record can be pushed further to sinks by calling the \c push_record method or simply destroyed by
|
||||
* destroying the returned object.
|
||||
*
|
||||
* More than one open records are allowed, such records exist independently. All attribute values are acquired during opening
|
||||
* the record and do not interact between records.
|
||||
*
|
||||
* The returned records can be copied, however, they must not be passed between different threads.
|
||||
*
|
||||
* \param source_attributes The set of source-specific attributes to be attached to the record to be opened.
|
||||
* \return A valid log record if the record is opened, an invalid record object if not (e.g. because it didn't pass filtering).
|
||||
*
|
||||
* \b Throws: If an exception handler is installed, only throws if the handler throws. Otherwise may
|
||||
* throw if one of the sinks throws, or some system resource limitation is reached.
|
||||
*/
|
||||
BOOST_LOG_API record open_record(attribute_set const& source_attributes);
|
||||
/*!
|
||||
* The method attempts to open a new record to be written. While attempting to open a log record all filtering is applied.
|
||||
* A successfully opened record can be pushed further to sinks by calling the \c push_record method or simply destroyed by
|
||||
* destroying the returned object.
|
||||
*
|
||||
* More than one open records are allowed, such records exist independently. All attribute values are acquired during opening
|
||||
* the record and do not interact between records.
|
||||
*
|
||||
* The returned records can be copied, however, they must not be passed between different threads.
|
||||
*
|
||||
* \param source_attributes The set of source-specific attribute values to be attached to the record to be opened.
|
||||
* \return A valid log record if the record is opened, an invalid record object if not (e.g. because it didn't pass filtering).
|
||||
*
|
||||
* \b Throws: If an exception handler is installed, only throws if the handler throws. Otherwise may
|
||||
* throw if one of the sinks throws, or some system resource limitation is reached.
|
||||
*/
|
||||
BOOST_LOG_API record open_record(attribute_value_set const& source_attributes);
|
||||
/*!
|
||||
* The method attempts to open a new record to be written. While attempting to open a log record all filtering is applied.
|
||||
* A successfully opened record can be pushed further to sinks by calling the \c push_record method or simply destroyed by
|
||||
* destroying the returned object.
|
||||
*
|
||||
* More than one open records are allowed, such records exist independently. All attribute values are acquired during opening
|
||||
* the record and do not interact between records.
|
||||
*
|
||||
* The returned records can be copied, however, they must not be passed between different threads.
|
||||
*
|
||||
* \param source_attributes The set of source-specific attribute values to be attached to the record to be opened. The contents
|
||||
* of this container are unspecified after this call.
|
||||
* \return A valid log record if the record is opened, an invalid record object if not (e.g. because it didn't pass filtering).
|
||||
*
|
||||
* \b Throws: If an exception handler is installed, only throws if the handler throws. Otherwise may
|
||||
* throw if one of the sinks throws, or some system resource limitation is reached.
|
||||
*/
|
||||
BOOST_FORCEINLINE record open_record(BOOST_RV_REF(attribute_value_set) source_attributes)
|
||||
{
|
||||
return open_record_move(static_cast< attribute_value_set& >(source_attributes));
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method pushes the record to sinks. The record is moved from in the process.
|
||||
*
|
||||
* \pre <tt>!!rec == true</tt>
|
||||
* \post <tt>!rec == true</tt>
|
||||
* \param rec A previously successfully opened log record.
|
||||
*
|
||||
* \b Throws: If an exception handler is installed, only throws if the handler throws. Otherwise may
|
||||
* throw if one of the sinks throws.
|
||||
*/
|
||||
BOOST_FORCEINLINE void push_record(BOOST_RV_REF(record) rec)
|
||||
{
|
||||
push_record_move(static_cast< record& >(rec));
|
||||
}
|
||||
|
||||
BOOST_DELETED_FUNCTION(core(core const&))
|
||||
BOOST_DELETED_FUNCTION(core& operator= (core const&))
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
private:
|
||||
//! Opens log record. This function is mostly needed to maintain ABI stable between C++03 and C++11.
|
||||
BOOST_LOG_API record open_record_move(attribute_value_set& source_attributes);
|
||||
//! The method pushes the record to sinks.
|
||||
BOOST_LOG_API void push_record_move(record& rec);
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
};
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_CORE_CORE_HPP_INCLUDED_
|
||||
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
* 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.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 09.03.2009
|
||||
*
|
||||
* This header contains a logging record class definition.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_CORE_RECORD_HPP_INCLUDED_
|
||||
#define BOOST_LOG_CORE_RECORD_HPP_INCLUDED_
|
||||
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/utility/explicit_operator_bool.hpp>
|
||||
#include <boost/log/attributes/attribute_value_set.hpp>
|
||||
#include <boost/log/expressions/keyword_fwd.hpp>
|
||||
#include <boost/log/core/record_view.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
class core;
|
||||
|
||||
/*!
|
||||
* \brief Logging record class
|
||||
*
|
||||
* The logging record encapsulates all information related to a single logging statement,
|
||||
* in particular, attribute values view and the log message string. The record can be updated before pushing
|
||||
* for further processing to the logging core.
|
||||
*/
|
||||
class record
|
||||
{
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(record)
|
||||
|
||||
friend class core;
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
private:
|
||||
//! Private data
|
||||
typedef record_view::public_data public_data;
|
||||
|
||||
private:
|
||||
//! A pointer to the log record implementation
|
||||
public_data* m_impl;
|
||||
|
||||
private:
|
||||
// A private constructor, accessible from core
|
||||
BOOST_CONSTEXPR explicit record(public_data* impl) BOOST_NOEXCEPT : m_impl(impl) {}
|
||||
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Default constructor. Creates an empty record that is equivalent to the invalid record handle.
|
||||
*
|
||||
* \post <tt>!*this == true</tt>
|
||||
*/
|
||||
BOOST_CONSTEXPR record() BOOST_NOEXCEPT : m_impl(NULL) {}
|
||||
|
||||
/*!
|
||||
* Move constructor. Source record contents unspecified after the operation.
|
||||
*/
|
||||
record(BOOST_RV_REF(record) that) BOOST_NOEXCEPT : m_impl(that.m_impl)
|
||||
{
|
||||
that.m_impl = NULL;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Destructor. Destroys the record, releases any sinks and attribute values that were involved in processing this record.
|
||||
*/
|
||||
~record() BOOST_NOEXCEPT
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Move assignment. Source record contents unspecified after the operation.
|
||||
*/
|
||||
record& operator= (BOOST_RV_REF(record) that) BOOST_NOEXCEPT
|
||||
{
|
||||
swap(static_cast< record& >(that));
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \return A reference to the set of attribute values attached to this record
|
||||
*
|
||||
* \pre <tt>!!*this</tt>
|
||||
*/
|
||||
attribute_value_set& attribute_values() BOOST_NOEXCEPT
|
||||
{
|
||||
return m_impl->m_attribute_values;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \return A reference to the set of attribute values attached to this record
|
||||
*
|
||||
* \pre <tt>!!*this</tt>
|
||||
*/
|
||||
attribute_value_set const& attribute_values() const BOOST_NOEXCEPT
|
||||
{
|
||||
return m_impl->m_attribute_values;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Conversion to an unspecified boolean type
|
||||
*
|
||||
* \return \c true, if the <tt>*this</tt> identifies a log record, \c false, if the <tt>*this</tt> is not valid
|
||||
*/
|
||||
BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
|
||||
|
||||
/*!
|
||||
* Inverted conversion to an unspecified boolean type
|
||||
*
|
||||
* \return \c false, if the <tt>*this</tt> identifies a log record, \c true, if the <tt>*this</tt> is not valid
|
||||
*/
|
||||
bool operator! () const BOOST_NOEXCEPT
|
||||
{
|
||||
return !m_impl;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Swaps two handles
|
||||
*
|
||||
* \param that Another record to swap with
|
||||
* <b>Throws:</b> Nothing
|
||||
*/
|
||||
void swap(record& that) BOOST_NOEXCEPT
|
||||
{
|
||||
public_data* p = m_impl;
|
||||
m_impl = that.m_impl;
|
||||
that.m_impl = p;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Resets the log record handle. If there are no other handles left, the log record is closed
|
||||
* and all resources referenced by the record are released.
|
||||
*
|
||||
* \post <tt>!*this == true</tt>
|
||||
*/
|
||||
void reset() BOOST_NOEXCEPT
|
||||
{
|
||||
if (m_impl)
|
||||
{
|
||||
public_data::destroy(m_impl);
|
||||
m_impl = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Attribute value lookup.
|
||||
*
|
||||
* \param name Attribute name.
|
||||
* \return An \c attribute_value, non-empty if it is found, empty otherwise.
|
||||
*/
|
||||
attribute_value_set::mapped_type operator[] (attribute_value_set::key_type name) const
|
||||
{
|
||||
return m_impl->m_attribute_values[name];
|
||||
}
|
||||
|
||||
/*!
|
||||
* Attribute value lookup.
|
||||
*
|
||||
* \param keyword Attribute keyword.
|
||||
* \return A \c value_ref with extracted attribute value if it is found, empty \c value_ref otherwise.
|
||||
*/
|
||||
template< typename DescriptorT, template< typename > class ActorT >
|
||||
typename result_of::extract< typename expressions::attribute_keyword< DescriptorT, ActorT >::value_type, DescriptorT >::type
|
||||
operator[] (expressions::attribute_keyword< DescriptorT, ActorT > const& keyword) const
|
||||
{
|
||||
return m_impl->m_attribute_values[keyword];
|
||||
}
|
||||
|
||||
/*!
|
||||
* The function ensures that the log record does not depend on any thread-specific data. Then the record contents
|
||||
* are used to construct a \c record_view which is returned from the function. The record is no longer valid after the call.
|
||||
*
|
||||
* \pre <tt>!!*this</tt>
|
||||
* \post <tt>!*this</tt>
|
||||
* \returns The record view that contains all attribute values from the original record.
|
||||
*/
|
||||
BOOST_LOG_API record_view lock();
|
||||
};
|
||||
|
||||
/*!
|
||||
* A free-standing swap function overload for \c record
|
||||
*/
|
||||
inline void swap(record& left, record& right) BOOST_NOEXCEPT
|
||||
{
|
||||
left.swap(right);
|
||||
}
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_CORE_RECORD_HPP_INCLUDED_
|
||||
@@ -0,0 +1,266 @@
|
||||
/*
|
||||
* 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_view.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 09.03.2009
|
||||
*
|
||||
* This header contains a logging record view class definition.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_CORE_RECORD_VIEW_HPP_INCLUDED_
|
||||
#define BOOST_LOG_CORE_RECORD_VIEW_HPP_INCLUDED_
|
||||
|
||||
#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/utility/explicit_operator_bool.hpp>
|
||||
#include <boost/log/attributes/attribute_value_set.hpp>
|
||||
#include <boost/log/expressions/keyword_fwd.hpp>
|
||||
#ifndef BOOST_LOG_NO_THREADS
|
||||
#include <boost/detail/atomic_count.hpp>
|
||||
#endif // BOOST_LOG_NO_THREADS
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
class core;
|
||||
class record;
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
/*!
|
||||
* \brief Logging record view class
|
||||
*
|
||||
* The logging record encapsulates all information related to a single logging statement,
|
||||
* in particular, attribute values view and the log message string. The view is immutable,
|
||||
* it is implemented as a wrapper around a reference-counted implementation.
|
||||
*/
|
||||
class record_view
|
||||
{
|
||||
BOOST_COPYABLE_AND_MOVABLE(record_view)
|
||||
|
||||
friend class core;
|
||||
friend class record;
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
private:
|
||||
//! Private data
|
||||
struct private_data;
|
||||
friend struct private_data;
|
||||
|
||||
//! Publicly available record data
|
||||
struct public_data
|
||||
{
|
||||
//! Reference counter
|
||||
#ifndef BOOST_LOG_NO_THREADS
|
||||
mutable boost::detail::atomic_count m_ref_counter;
|
||||
#else
|
||||
mutable unsigned int m_ref_counter;
|
||||
#endif // BOOST_LOG_NO_THREADS
|
||||
|
||||
//! Attribute values view
|
||||
attribute_value_set m_attribute_values;
|
||||
|
||||
//! Constructor from the attribute value set
|
||||
explicit public_data(BOOST_RV_REF(attribute_value_set) values) BOOST_NOEXCEPT :
|
||||
m_ref_counter(1),
|
||||
m_attribute_values(boost::move(values))
|
||||
{
|
||||
}
|
||||
|
||||
//! Destructor
|
||||
BOOST_LOG_API static void destroy(const public_data* p) BOOST_NOEXCEPT;
|
||||
|
||||
protected:
|
||||
~public_data() {}
|
||||
|
||||
BOOST_DELETED_FUNCTION(public_data(public_data const&))
|
||||
BOOST_DELETED_FUNCTION(public_data& operator= (public_data const&))
|
||||
|
||||
friend void intrusive_ptr_add_ref(const public_data* p) BOOST_NOEXCEPT { ++p->m_ref_counter; }
|
||||
friend void intrusive_ptr_release(const public_data* p) BOOST_NOEXCEPT { if (--p->m_ref_counter == 0) public_data::destroy(p); }
|
||||
};
|
||||
|
||||
private:
|
||||
//! A pointer to the log record implementation
|
||||
intrusive_ptr< public_data > m_impl;
|
||||
|
||||
private:
|
||||
// A private constructor, accessible from record
|
||||
explicit record_view(public_data* impl) BOOST_NOEXCEPT : m_impl(impl, false) {}
|
||||
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Default constructor. Creates an empty record view that is equivalent to the invalid record handle.
|
||||
*
|
||||
* \post <tt>!*this == true</tt>
|
||||
*/
|
||||
BOOST_CONSTEXPR record_view() BOOST_NOEXCEPT
|
||||
#if !defined(BOOST_LOG_NO_CXX11_DEFAULTED_NOEXCEPT_FUNCTIONS)
|
||||
= default;
|
||||
#else
|
||||
{}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Copy constructor
|
||||
*/
|
||||
record_view(record_view const& that) BOOST_NOEXCEPT : m_impl(that.m_impl) {}
|
||||
|
||||
/*!
|
||||
* Move constructor. Source record contents unspecified after the operation.
|
||||
*/
|
||||
record_view(BOOST_RV_REF(record_view) that) BOOST_NOEXCEPT
|
||||
{
|
||||
m_impl.swap(that.m_impl);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Destructor. Destroys the record, releases any sinks and attribute values that were involved in processing this record.
|
||||
*/
|
||||
~record_view() BOOST_NOEXCEPT {}
|
||||
|
||||
/*!
|
||||
* Copy assignment
|
||||
*/
|
||||
record_view& operator= (BOOST_COPY_ASSIGN_REF(record_view) that) BOOST_NOEXCEPT
|
||||
{
|
||||
m_impl = that.m_impl;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Move assignment. Source record contents unspecified after the operation.
|
||||
*/
|
||||
record_view& operator= (BOOST_RV_REF(record_view) that) BOOST_NOEXCEPT
|
||||
{
|
||||
m_impl.swap(that.m_impl);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \return A reference to the set of attribute values attached to this record
|
||||
*
|
||||
* \pre <tt>!!*this</tt>
|
||||
*/
|
||||
attribute_value_set const& attribute_values() const BOOST_NOEXCEPT
|
||||
{
|
||||
return m_impl->m_attribute_values;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Equality comparison
|
||||
*
|
||||
* \param that Comparand
|
||||
* \return \c true if both <tt>*this</tt> and \a that identify the same log record or both do not
|
||||
* identify any record, \c false otherwise.
|
||||
*/
|
||||
bool operator== (record_view const& that) const BOOST_NOEXCEPT
|
||||
{
|
||||
return m_impl == that.m_impl;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Inequality comparison
|
||||
*
|
||||
* \param that Comparand
|
||||
* \return <tt>!(*this == that)</tt>
|
||||
*/
|
||||
bool operator!= (record_view const& that) const BOOST_NOEXCEPT
|
||||
{
|
||||
return !operator== (that);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Conversion to an unspecified boolean type
|
||||
*
|
||||
* \return \c true, if the <tt>*this</tt> identifies a log record, \c false, if the <tt>*this</tt> is not valid
|
||||
*/
|
||||
BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
|
||||
|
||||
/*!
|
||||
* Inverted conversion to an unspecified boolean type
|
||||
*
|
||||
* \return \c false, if the <tt>*this</tt> identifies a log record, \c true, if the <tt>*this</tt> is not valid
|
||||
*/
|
||||
bool operator! () const BOOST_NOEXCEPT
|
||||
{
|
||||
return !m_impl;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Swaps two handles
|
||||
*
|
||||
* \param that Another record to swap with
|
||||
* <b>Throws:</b> Nothing
|
||||
*/
|
||||
void swap(record_view& that) BOOST_NOEXCEPT
|
||||
{
|
||||
m_impl.swap(that.m_impl);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Resets the log record handle. If there are no other handles left, the log record is closed
|
||||
* and all resources referenced by the record are released.
|
||||
*
|
||||
* \post <tt>!*this == true</tt>
|
||||
*/
|
||||
void reset() BOOST_NOEXCEPT
|
||||
{
|
||||
m_impl.reset();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Attribute value lookup.
|
||||
*
|
||||
* \param name Attribute name.
|
||||
* \return An \c attribute_value, non-empty if it is found, empty otherwise.
|
||||
*/
|
||||
attribute_value_set::mapped_type operator[] (attribute_value_set::key_type name) const
|
||||
{
|
||||
return m_impl->m_attribute_values[name];
|
||||
}
|
||||
|
||||
/*!
|
||||
* Attribute value lookup.
|
||||
*
|
||||
* \param keyword Attribute keyword.
|
||||
* \return A \c value_ref with extracted attribute value if it is found, empty \c value_ref otherwise.
|
||||
*/
|
||||
template< typename DescriptorT, template< typename > class ActorT >
|
||||
typename result_of::extract< typename expressions::attribute_keyword< DescriptorT, ActorT >::value_type, DescriptorT >::type
|
||||
operator[] (expressions::attribute_keyword< DescriptorT, ActorT > const& keyword) const
|
||||
{
|
||||
return m_impl->m_attribute_values[keyword];
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* A free-standing swap function overload for \c record_view
|
||||
*/
|
||||
inline void swap(record_view& left, record_view& right) BOOST_NOEXCEPT
|
||||
{
|
||||
left.swap(right);
|
||||
}
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_CORE_RECORD_VIEW_HPP_INCLUDED_
|
||||
@@ -0,0 +1,235 @@
|
||||
/*
|
||||
* 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 adaptive_mutex.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 01.08.2010
|
||||
*
|
||||
* \brief This header is the Boost.Log library implementation, see the library documentation
|
||||
* at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_ADAPTIVE_MUTEX_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_ADAPTIVE_MUTEX_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_LOG_NO_THREADS
|
||||
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/thread/exceptions.hpp>
|
||||
|
||||
#if defined(BOOST_THREAD_POSIX) // This one can be defined by users, so it should go first
|
||||
#define BOOST_LOG_ADAPTIVE_MUTEX_USE_PTHREAD
|
||||
#elif defined(BOOST_WINDOWS)
|
||||
#define BOOST_LOG_ADAPTIVE_MUTEX_USE_WINAPI
|
||||
#elif defined(BOOST_HAS_PTHREADS)
|
||||
#define BOOST_LOG_ADAPTIVE_MUTEX_USE_PTHREAD
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_LOG_ADAPTIVE_MUTEX_USE_WINAPI)
|
||||
|
||||
#include <boost/log/detail/pause.hpp>
|
||||
#include <boost/detail/interlocked.hpp>
|
||||
#include <boost/detail/winapi/thread.hpp>
|
||||
|
||||
#if defined(__INTEL_COMPILER) || defined(_MSC_VER)
|
||||
# if defined(__INTEL_COMPILER)
|
||||
# define BOOST_LOG_COMPILER_BARRIER __memory_barrier()
|
||||
# else
|
||||
extern "C" void _ReadWriteBarrier(void);
|
||||
# if defined(BOOST_MSVC)
|
||||
# pragma intrinsic(_ReadWriteBarrier)
|
||||
# endif
|
||||
# define BOOST_LOG_COMPILER_BARRIER _ReadWriteBarrier()
|
||||
# endif
|
||||
#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
|
||||
# define BOOST_LOG_COMPILER_BARRIER __asm__ __volatile__("" : : : "memory")
|
||||
#endif
|
||||
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace aux {
|
||||
|
||||
//! A mutex that performs spinning or thread yielding in case of contention
|
||||
class adaptive_mutex
|
||||
{
|
||||
private:
|
||||
enum state
|
||||
{
|
||||
initial_pause = 2,
|
||||
max_pause = 16
|
||||
};
|
||||
|
||||
long m_State;
|
||||
|
||||
public:
|
||||
adaptive_mutex() : m_State(0) {}
|
||||
|
||||
bool try_lock()
|
||||
{
|
||||
return (BOOST_INTERLOCKED_COMPARE_EXCHANGE(&m_State, 1L, 0L) == 0L);
|
||||
}
|
||||
|
||||
void lock()
|
||||
{
|
||||
#if defined(BOOST_LOG_AUX_PAUSE)
|
||||
unsigned int pause_count = initial_pause;
|
||||
#endif
|
||||
while (!try_lock())
|
||||
{
|
||||
#if defined(BOOST_LOG_AUX_PAUSE)
|
||||
if (pause_count < max_pause)
|
||||
{
|
||||
for (unsigned int i = 0; i < pause_count; ++i)
|
||||
{
|
||||
BOOST_LOG_AUX_PAUSE;
|
||||
}
|
||||
pause_count += pause_count;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Restart spinning after waking up this thread
|
||||
pause_count = initial_pause;
|
||||
SwitchToThread();
|
||||
}
|
||||
#else
|
||||
SwitchToThread();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
#if (defined(_M_IX86) || defined(_M_AMD64)) && defined(BOOST_LOG_COMPILER_BARRIER)
|
||||
BOOST_LOG_COMPILER_BARRIER;
|
||||
m_State = 0L;
|
||||
BOOST_LOG_COMPILER_BARRIER;
|
||||
#else
|
||||
BOOST_INTERLOCKED_EXCHANGE(&m_State, 0L);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Non-copyable
|
||||
BOOST_DELETED_FUNCTION(adaptive_mutex(adaptive_mutex const&))
|
||||
BOOST_DELETED_FUNCTION(adaptive_mutex& operator= (adaptive_mutex const&))
|
||||
};
|
||||
|
||||
#undef BOOST_LOG_AUX_PAUSE
|
||||
#undef BOOST_LOG_COMPILER_BARRIER
|
||||
|
||||
} // namespace aux
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#elif defined(BOOST_LOG_ADAPTIVE_MUTEX_USE_PTHREAD)
|
||||
|
||||
#include <pthread.h>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#if defined(PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP)
|
||||
#define BOOST_LOG_ADAPTIVE_MUTEX_USE_PTHREAD_MUTEX_ADAPTIVE_NP
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace aux {
|
||||
|
||||
//! A mutex that performs spinning or thread yielding in case of contention
|
||||
class adaptive_mutex
|
||||
{
|
||||
private:
|
||||
pthread_mutex_t m_State;
|
||||
|
||||
public:
|
||||
adaptive_mutex()
|
||||
{
|
||||
#if defined(BOOST_LOG_ADAPTIVE_MUTEX_USE_PTHREAD_MUTEX_ADAPTIVE_NP)
|
||||
pthread_mutexattr_t attrs;
|
||||
pthread_mutexattr_init(&attrs);
|
||||
pthread_mutexattr_settype(&attrs, PTHREAD_MUTEX_ADAPTIVE_NP);
|
||||
|
||||
const int err = pthread_mutex_init(&m_State, &attrs);
|
||||
pthread_mutexattr_destroy(&attrs);
|
||||
#else
|
||||
const int err = pthread_mutex_init(&m_State, NULL);
|
||||
#endif
|
||||
if (BOOST_UNLIKELY(err != 0))
|
||||
throw_exception< thread_resource_error >(err, "Failed to initialize an adaptive mutex", "adaptive_mutex::adaptive_mutex()", __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
~adaptive_mutex()
|
||||
{
|
||||
BOOST_VERIFY(pthread_mutex_destroy(&m_State) == 0);
|
||||
}
|
||||
|
||||
bool try_lock()
|
||||
{
|
||||
const int err = pthread_mutex_trylock(&m_State);
|
||||
if (err == 0)
|
||||
return true;
|
||||
if (BOOST_UNLIKELY(err != EBUSY))
|
||||
throw_exception< lock_error >(err, "Failed to lock an adaptive mutex", "adaptive_mutex::try_lock()", __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
void lock()
|
||||
{
|
||||
const int err = pthread_mutex_lock(&m_State);
|
||||
if (BOOST_UNLIKELY(err != 0))
|
||||
throw_exception< lock_error >(err, "Failed to lock an adaptive mutex", "adaptive_mutex::lock()", __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
BOOST_VERIFY(pthread_mutex_unlock(&m_State) == 0);
|
||||
}
|
||||
|
||||
// Non-copyable
|
||||
BOOST_DELETED_FUNCTION(adaptive_mutex(adaptive_mutex const&))
|
||||
BOOST_DELETED_FUNCTION(adaptive_mutex& operator= (adaptive_mutex const&))
|
||||
|
||||
private:
|
||||
template< typename ExceptionT >
|
||||
static BOOST_NOINLINE BOOST_LOG_NORETURN void throw_exception(int err, const char* descr, const char* func, const char* file, int line)
|
||||
{
|
||||
#if !defined(BOOST_EXCEPTION_DISABLE)
|
||||
boost::exception_detail::throw_exception_(ExceptionT(err, descr), func, file, line);
|
||||
#else
|
||||
boost::throw_exception(ExceptionT(err, descr));
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif
|
||||
|
||||
#endif // BOOST_LOG_NO_THREADS
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_ADAPTIVE_MUTEX_HPP_INCLUDED_
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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 asio_fwd.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 20.04.2008
|
||||
*
|
||||
* \brief This header is the Boost.Log library implementation, see the library documentation
|
||||
* at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
|
||||
*
|
||||
* The header provides forward declarations of Boost.ASIO that are required for the user's
|
||||
* code to compile with Boost.Log. The forward declarations allow to avoid including the major
|
||||
* part of Boost.ASIO and system headers into user's code.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_ASIO_FWD_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_ASIO_FWD_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace asio {
|
||||
|
||||
namespace ip {
|
||||
|
||||
class address;
|
||||
|
||||
} // namespace ip
|
||||
|
||||
} // namespace asio
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_ASIO_FWD_HPP_INCLUDED_
|
||||
@@ -0,0 +1,330 @@
|
||||
/*
|
||||
* Copyright Andrey Semashev 2007 - 2016.
|
||||
* 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 attachable_sstream_buf.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 29.07.2007
|
||||
*
|
||||
* \brief This header is the Boost.Log library implementation, see the library documentation
|
||||
* at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_ATTACHABLE_SSTREAM_BUF_HPP_INCLUDED_
|
||||
#define BOOST_LOG_ATTACHABLE_SSTREAM_BUF_HPP_INCLUDED_
|
||||
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <locale>
|
||||
#include <string>
|
||||
#include <streambuf>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/locale/utf.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace aux {
|
||||
|
||||
//! A streambuf that puts the formatted data to an external string
|
||||
template<
|
||||
typename CharT,
|
||||
typename TraitsT = std::char_traits< CharT >,
|
||||
typename AllocatorT = std::allocator< CharT >
|
||||
>
|
||||
class basic_ostringstreambuf :
|
||||
public std::basic_streambuf< CharT, TraitsT >
|
||||
{
|
||||
//! Self type
|
||||
typedef basic_ostringstreambuf< CharT, TraitsT, AllocatorT > this_type;
|
||||
//! Base type
|
||||
typedef std::basic_streambuf< CharT, TraitsT > base_type;
|
||||
|
||||
//! Buffer size
|
||||
enum { buffer_size = 16 };
|
||||
|
||||
public:
|
||||
//! Character type
|
||||
typedef typename base_type::char_type char_type;
|
||||
//! Traits type
|
||||
typedef typename base_type::traits_type traits_type;
|
||||
//! String type
|
||||
typedef std::basic_string< char_type, traits_type, AllocatorT > string_type;
|
||||
//! Size type
|
||||
typedef typename string_type::size_type size_type;
|
||||
//! Int type
|
||||
typedef typename base_type::int_type int_type;
|
||||
|
||||
struct storage_state
|
||||
{
|
||||
//! A reference to the string that will be filled
|
||||
string_type* storage;
|
||||
//! Max size of the storage, in characters
|
||||
size_type max_size;
|
||||
//! Indicates that storage overflow happened
|
||||
bool overflow;
|
||||
|
||||
BOOST_CONSTEXPR storage_state() BOOST_NOEXCEPT : storage(NULL), max_size(0u), overflow(false)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
//! Buffer storage state
|
||||
storage_state m_storage_state;
|
||||
//! A buffer used to temporarily store output
|
||||
char_type m_buffer[buffer_size];
|
||||
|
||||
public:
|
||||
//! Constructor
|
||||
basic_ostringstreambuf() BOOST_NOEXCEPT
|
||||
{
|
||||
base_type::setp(m_buffer, m_buffer + (sizeof(m_buffer) / sizeof(*m_buffer)));
|
||||
}
|
||||
//! Constructor
|
||||
explicit basic_ostringstreambuf(string_type& storage) BOOST_NOEXCEPT
|
||||
{
|
||||
base_type::setp(m_buffer, m_buffer + (sizeof(m_buffer) / sizeof(*m_buffer)));
|
||||
attach(storage);
|
||||
}
|
||||
|
||||
storage_state const& get_storage_state() const BOOST_NOEXCEPT { return m_storage_state; }
|
||||
void set_storage_state(storage_state const& st) BOOST_NOEXCEPT { m_storage_state = st; }
|
||||
|
||||
//! Detaches the buffer from the string
|
||||
void detach()
|
||||
{
|
||||
if (m_storage_state.storage)
|
||||
{
|
||||
this_type::sync();
|
||||
m_storage_state.storage = NULL;
|
||||
m_storage_state.max_size = 0u;
|
||||
m_storage_state.overflow = false;
|
||||
}
|
||||
}
|
||||
|
||||
//! Attaches the buffer to another string
|
||||
void attach(string_type& storage)
|
||||
{
|
||||
attach(storage, storage.max_size());
|
||||
}
|
||||
|
||||
//! Attaches the buffer to another string
|
||||
void attach(string_type& storage, size_type max_size)
|
||||
{
|
||||
detach();
|
||||
m_storage_state.storage = &storage;
|
||||
this->max_size(max_size);
|
||||
}
|
||||
|
||||
//! Returns a pointer to the attached string
|
||||
string_type* storage() const BOOST_NOEXCEPT { return m_storage_state.storage; }
|
||||
|
||||
//! Returns the maximum size of the storage
|
||||
size_type max_size() const BOOST_NOEXCEPT { return m_storage_state.max_size; }
|
||||
//! Sets the maximum size of the storage
|
||||
void max_size(size_type size)
|
||||
{
|
||||
if (m_storage_state.storage)
|
||||
{
|
||||
const size_type storage_max_size = m_storage_state.storage->max_size();
|
||||
size = size > storage_max_size ? storage_max_size : size;
|
||||
}
|
||||
|
||||
m_storage_state.max_size = size;
|
||||
ensure_max_size();
|
||||
}
|
||||
//! Makes sure the storage does not exceed the max size limit. Should be called after the storage is modified externally.
|
||||
void ensure_max_size()
|
||||
{
|
||||
if (m_storage_state.storage && m_storage_state.storage->size() > m_storage_state.max_size)
|
||||
{
|
||||
const size_type len = length_until_boundary(m_storage_state.storage->c_str(), m_storage_state.storage->size(), m_storage_state.max_size);
|
||||
m_storage_state.storage->resize(len);
|
||||
m_storage_state.overflow = true;
|
||||
}
|
||||
}
|
||||
|
||||
//! Returns true if the max size limit has been exceeded
|
||||
bool storage_overflow() const BOOST_NOEXCEPT { return m_storage_state.overflow; }
|
||||
//! Sets the overflow flag
|
||||
void storage_overflow(bool f) BOOST_NOEXCEPT { m_storage_state.overflow = f; }
|
||||
|
||||
//! Returns the size left in the storage
|
||||
size_type size_left() const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_ASSERT(m_storage_state.storage != NULL);
|
||||
|
||||
const size_type size = m_storage_state.storage->size();
|
||||
return size < m_storage_state.max_size ? m_storage_state.max_size - size : static_cast< size_type >(0u);
|
||||
}
|
||||
|
||||
//! Appends a string to the storage and returns the number of written characters
|
||||
size_type append(const char_type* s, size_type n)
|
||||
{
|
||||
if (!m_storage_state.overflow)
|
||||
{
|
||||
BOOST_ASSERT(m_storage_state.storage != NULL);
|
||||
|
||||
size_type left = size_left();
|
||||
BOOST_LOG_ASSUME(left <= m_storage_state.storage->max_size());
|
||||
if (BOOST_LIKELY(n <= left))
|
||||
{
|
||||
m_storage_state.storage->append(s, n);
|
||||
return n;
|
||||
}
|
||||
else
|
||||
{
|
||||
// We have to find out where the last character that fits before the limit ends
|
||||
left = length_until_boundary(s, n, left);
|
||||
m_storage_state.storage->append(s, left);
|
||||
m_storage_state.overflow = true;
|
||||
return left;
|
||||
}
|
||||
}
|
||||
return 0u;
|
||||
}
|
||||
|
||||
//! Appends the specified number of characters to the storage and returns the number of written characters
|
||||
size_type append(size_type n, char_type c)
|
||||
{
|
||||
if (!m_storage_state.overflow)
|
||||
{
|
||||
BOOST_ASSERT(m_storage_state.storage != NULL);
|
||||
|
||||
const size_type left = size_left();
|
||||
BOOST_LOG_ASSUME(left <= m_storage_state.storage->max_size());
|
||||
if (BOOST_LIKELY(n <= left))
|
||||
{
|
||||
m_storage_state.storage->append(n, c);
|
||||
return n;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_storage_state.storage->append(left, c);
|
||||
m_storage_state.overflow = true;
|
||||
return left;
|
||||
}
|
||||
}
|
||||
return 0u;
|
||||
}
|
||||
|
||||
//! Appends a character to the storage and returns the number of written characters
|
||||
size_type push_back(char_type c)
|
||||
{
|
||||
if (!m_storage_state.overflow)
|
||||
{
|
||||
BOOST_ASSERT(m_storage_state.storage != NULL);
|
||||
|
||||
BOOST_LOG_ASSUME(m_storage_state.max_size <= m_storage_state.storage->max_size());
|
||||
if (BOOST_LIKELY(m_storage_state.storage->size() < m_storage_state.max_size))
|
||||
{
|
||||
m_storage_state.storage->push_back(c);
|
||||
return 1u;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_storage_state.overflow = true;
|
||||
return 0u;
|
||||
}
|
||||
}
|
||||
return 0u;
|
||||
}
|
||||
|
||||
protected:
|
||||
//! Puts all buffered data to the string
|
||||
int sync()
|
||||
{
|
||||
char_type* pBase = this->pbase();
|
||||
char_type* pPtr = this->pptr();
|
||||
if (pBase != pPtr)
|
||||
{
|
||||
this->append(pBase, static_cast< size_type >(pPtr - pBase));
|
||||
this->pbump(static_cast< int >(pBase - pPtr));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
//! Puts an unbuffered character to the string
|
||||
int_type overflow(int_type c)
|
||||
{
|
||||
this_type::sync();
|
||||
if (!traits_type::eq_int_type(c, traits_type::eof()))
|
||||
{
|
||||
this->push_back(traits_type::to_char_type(c));
|
||||
return c;
|
||||
}
|
||||
else
|
||||
return traits_type::not_eof(c);
|
||||
}
|
||||
//! Puts a character sequence to the string
|
||||
std::streamsize xsputn(const char_type* s, std::streamsize n)
|
||||
{
|
||||
this_type::sync();
|
||||
return static_cast< std::streamsize >(this->append(s, static_cast< size_type >(n)));
|
||||
}
|
||||
|
||||
//! Finds the string length so that it includes only complete characters, and does not exceed \a max_size
|
||||
size_type length_until_boundary(const char_type* s, size_type n, size_type max_size) const
|
||||
{
|
||||
return length_until_boundary(s, n, max_size, mpl::bool_< sizeof(char_type) == 1u >());;
|
||||
}
|
||||
|
||||
//! Finds the string length so that it includes only complete characters, and does not exceed \a max_size
|
||||
size_type length_until_boundary(const char_type* s, size_type n, size_type max_size, mpl::true_) const
|
||||
{
|
||||
std::locale loc = this->getloc();
|
||||
std::codecvt< wchar_t, char, std::mbstate_t > const& fac = std::use_facet< std::codecvt< wchar_t, char, std::mbstate_t > >(loc);
|
||||
std::mbstate_t mbs = std::mbstate_t();
|
||||
return static_cast< size_type >(fac.length(mbs, s, s + max_size, ~static_cast< std::size_t >(0u)));
|
||||
}
|
||||
|
||||
//! Finds the string length so that it includes only complete characters, and does not exceed \a max_size
|
||||
static size_type length_until_boundary(const char_type* s, size_type n, size_type max_size, mpl::false_)
|
||||
{
|
||||
// Note: Although it's not required to be true for wchar_t, here we assume that the string has Unicode encoding.
|
||||
// Compilers use some version of Unicode for wchar_t on all tested platforms, and std::locale doesn't offer a way
|
||||
// to find the character boundary for character types other than char anyway.
|
||||
typedef boost::locale::utf::utf_traits< CharT > utf_traits;
|
||||
|
||||
size_type pos = max_size;
|
||||
while (pos > 0u)
|
||||
{
|
||||
--pos;
|
||||
if (utf_traits::is_lead(s[pos]))
|
||||
{
|
||||
const char_type* p = s + pos;
|
||||
boost::locale::utf::code_point cp = utf_traits::decode(p, s + n);
|
||||
if (boost::locale::utf::is_valid_codepoint(cp) && p <= (s + max_size))
|
||||
return static_cast< size_type >(p - s);
|
||||
}
|
||||
}
|
||||
|
||||
return 0u;
|
||||
}
|
||||
|
||||
//! Copy constructor (closed)
|
||||
BOOST_DELETED_FUNCTION(basic_ostringstreambuf(basic_ostringstreambuf const& that))
|
||||
//! Assignment (closed)
|
||||
BOOST_DELETED_FUNCTION(basic_ostringstreambuf& operator= (basic_ostringstreambuf const& that))
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_ATTACHABLE_SSTREAM_BUF_HPP_INCLUDED_
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* 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 attr_output_impl.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 12.08.2012
|
||||
*
|
||||
* \brief This header is the Boost.Log library implementation, see the library documentation
|
||||
* at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_ATTR_OUTPUT_IMPL_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_ATTR_OUTPUT_IMPL_HPP_INCLUDED_
|
||||
|
||||
#include <boost/mpl/is_sequence.hpp>
|
||||
#include <boost/phoenix/core/actor.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/expressions/attr.hpp>
|
||||
#include <boost/log/utility/functional/bind_to_log.hpp>
|
||||
#include <boost/log/detail/attr_output_terminal.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace expressions {
|
||||
|
||||
namespace aux {
|
||||
|
||||
template< typename LeftT, typename T, typename FallbackPolicyT, typename TagT >
|
||||
struct make_output_expression
|
||||
{
|
||||
//! Resulting expression
|
||||
typedef attribute_output_terminal< LeftT, T, FallbackPolicyT, to_log_fun< TagT > > type;
|
||||
|
||||
//! Creates the output expression
|
||||
template< typename RightT >
|
||||
static BOOST_FORCEINLINE type make(LeftT const& left, RightT const& right)
|
||||
{
|
||||
return type(left, right.get_name(), to_log_fun< TagT >(), right.get_fallback_policy());
|
||||
}
|
||||
};
|
||||
|
||||
template< typename LeftT, typename RightT, typename ValueT = typename RightT::value_type, bool IsSequenceV = mpl::is_sequence< ValueT >::value >
|
||||
struct make_output_actor;
|
||||
|
||||
template< template< typename > class ActorT, typename LeftExprT, typename RightT, typename ValueT >
|
||||
struct make_output_actor< ActorT< LeftExprT >, RightT, ValueT, false >
|
||||
{
|
||||
typedef make_output_expression<
|
||||
ActorT< LeftExprT >,
|
||||
ValueT,
|
||||
typename RightT::fallback_policy,
|
||||
typename RightT::tag_type
|
||||
> make_expression;
|
||||
|
||||
typedef ActorT< typename make_expression::type > type;
|
||||
|
||||
static BOOST_FORCEINLINE type make(ActorT< LeftExprT > const& left, RightT const& right)
|
||||
{
|
||||
type res = {{ make_expression::make(left, right) }};
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
template< template< typename > class ActorT, typename LeftExprT, typename RightT, typename ValueT >
|
||||
struct make_output_actor< ActorT< LeftExprT >, RightT, ValueT, true >
|
||||
{
|
||||
typedef attribute_output_terminal< ActorT< LeftExprT >, ValueT, typename RightT::fallback_policy, to_log_fun< typename RightT::tag_type > > expression_type;
|
||||
|
||||
typedef ActorT< expression_type > type;
|
||||
|
||||
static BOOST_FORCEINLINE type make(ActorT< LeftExprT > const& left, RightT const& right)
|
||||
{
|
||||
type res = {{ expression_type(left, right.get_name(), to_log_fun< typename RightT::tag_type >(), right.get_fallback_policy()) }};
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
#define BOOST_LOG_AUX_OVERLOAD(left_ref, right_ref)\
|
||||
template< typename LeftExprT, typename T, typename FallbackPolicyT, typename TagT >\
|
||||
BOOST_FORCEINLINE typename aux::make_output_actor< phoenix::actor< LeftExprT >, attribute_actor< T, FallbackPolicyT, TagT, phoenix::actor > >::type\
|
||||
operator<< (phoenix::actor< LeftExprT > left_ref left, attribute_actor< T, FallbackPolicyT, TagT, phoenix::actor > right_ref right)\
|
||||
{\
|
||||
return aux::make_output_actor< phoenix::actor< LeftExprT >, attribute_actor< T, FallbackPolicyT, TagT, phoenix::actor > >::make(left, right);\
|
||||
}
|
||||
|
||||
#include <boost/log/detail/generate_overloads.hpp>
|
||||
|
||||
#undef BOOST_LOG_AUX_OVERLOAD
|
||||
|
||||
} // namespace expressions
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_ATTR_OUTPUT_IMPL_HPP_INCLUDED_
|
||||
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* 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 attribute_output_terminal.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 06.11.2012
|
||||
*
|
||||
* The header contains implementation of a generic output manipulator in template expressions.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_ATTR_OUTPUT_TERMINAL_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_ATTR_OUTPUT_TERMINAL_HPP_INCLUDED_
|
||||
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/phoenix/core/actor.hpp>
|
||||
#include <boost/phoenix/core/meta_grammar.hpp>
|
||||
#include <boost/phoenix/core/environment.hpp>
|
||||
#include <boost/phoenix/core/terminal_fwd.hpp>
|
||||
#include <boost/phoenix/core/is_nullary.hpp>
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/fusion/sequence/intrinsic/at.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/custom_terminal_spec.hpp>
|
||||
#include <boost/log/attributes/attribute_name.hpp>
|
||||
#include <boost/log/attributes/value_visitation.hpp>
|
||||
#include <boost/log/utility/functional/bind.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace expressions {
|
||||
|
||||
namespace aux {
|
||||
|
||||
//! Attribute stream output expression
|
||||
template< typename LeftT, typename T, typename FallbackPolicyT, typename ImplT >
|
||||
class attribute_output_terminal
|
||||
{
|
||||
private:
|
||||
//! Self type
|
||||
typedef attribute_output_terminal< LeftT, T, FallbackPolicyT, ImplT > this_type;
|
||||
//! Attribute value visitor invoker
|
||||
typedef value_visitor_invoker< T, FallbackPolicyT > visitor_invoker_type;
|
||||
//! Manipulator implementation
|
||||
typedef ImplT impl_type;
|
||||
|
||||
public:
|
||||
//! Internal typedef for type categorization
|
||||
typedef void _is_boost_log_terminal;
|
||||
|
||||
//! Result type definition
|
||||
template< typename >
|
||||
struct result;
|
||||
|
||||
template< typename ThisT, typename ContextT >
|
||||
struct result< ThisT(ContextT) >
|
||||
{
|
||||
typedef typename remove_cv< typename remove_reference< ContextT >::type >::type context_type;
|
||||
typedef typename phoenix::evaluator::impl<
|
||||
typename LeftT::proto_base_expr&,
|
||||
context_type,
|
||||
phoenix::unused
|
||||
>::result_type type;
|
||||
};
|
||||
|
||||
private:
|
||||
//! Left argument actor
|
||||
LeftT m_left;
|
||||
//! Attribute name
|
||||
const attribute_name m_name;
|
||||
//! Attribute value visitor invoker
|
||||
visitor_invoker_type m_visitor_invoker;
|
||||
//! Manipulator implementation
|
||||
impl_type m_impl;
|
||||
|
||||
public:
|
||||
//! Initializing constructor
|
||||
attribute_output_terminal(LeftT const& left, attribute_name const& name) : m_left(left), m_name(name)
|
||||
{
|
||||
}
|
||||
|
||||
//! Initializing constructor
|
||||
attribute_output_terminal(LeftT const& left, attribute_name const& name, impl_type const& impl) : m_left(left), m_name(name), m_impl(impl)
|
||||
{
|
||||
}
|
||||
|
||||
//! Initializing constructor
|
||||
template< typename U >
|
||||
attribute_output_terminal(LeftT const& left, attribute_name const& name, impl_type const& impl, U const& arg) :
|
||||
m_left(left), m_name(name), m_visitor_invoker(arg), m_impl(impl)
|
||||
{
|
||||
}
|
||||
|
||||
//! Copy constructor
|
||||
attribute_output_terminal(attribute_output_terminal const& that) :
|
||||
m_left(that.m_left), m_name(that.m_name), m_visitor_invoker(that.m_visitor_invoker), m_impl(that.m_impl)
|
||||
{
|
||||
}
|
||||
|
||||
//! Invokation operator
|
||||
template< typename ContextT >
|
||||
typename result< this_type(ContextT const&) >::type operator() (ContextT const& ctx)
|
||||
{
|
||||
typedef typename result< this_type(ContextT const&) >::type result_type;
|
||||
result_type strm = phoenix::eval(m_left, ctx);
|
||||
m_visitor_invoker(m_name, fusion::at_c< 0 >(phoenix::env(ctx).args()), binder1st< impl_type&, result_type >(m_impl, strm));
|
||||
return strm;
|
||||
}
|
||||
|
||||
//! Invokation operator
|
||||
template< typename ContextT >
|
||||
typename result< const this_type(ContextT const&) >::type operator() (ContextT const& ctx) const
|
||||
{
|
||||
typedef typename result< const this_type(ContextT const&) >::type result_type;
|
||||
result_type strm = phoenix::eval(m_left, ctx);
|
||||
m_visitor_invoker(m_name, fusion::at_c< 0 >(phoenix::env(ctx).args()), binder1st< impl_type const&, result_type >(m_impl, strm));
|
||||
return strm;
|
||||
}
|
||||
|
||||
BOOST_DELETED_FUNCTION(attribute_output_terminal())
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
} // namespace expressions
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
namespace phoenix {
|
||||
|
||||
namespace result_of {
|
||||
|
||||
template< typename LeftT, typename T, typename FallbackPolicyT, typename ImplT >
|
||||
struct is_nullary< custom_terminal< boost::log::expressions::aux::attribute_output_terminal< LeftT, T, FallbackPolicyT, ImplT > > > :
|
||||
public mpl::false_
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace result_of
|
||||
|
||||
} // namespace phoenix
|
||||
|
||||
#endif // !defined(BOOST_LOG_DOXYGEN_PASS)
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_ATTR_OUTPUT_TERMINAL_HPP_INCLUDED_
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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 attribute_get_value_impl.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 04.08.2012
|
||||
*
|
||||
* \brief This header is the Boost.Log library implementation, see the library documentation
|
||||
* at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_ATTRIBUTE_GET_VALUE_IMPL_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_ATTRIBUTE_GET_VALUE_IMPL_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/attributes/attribute.hpp>
|
||||
#include <boost/log/attributes/attribute_value.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
inline attribute_value attribute::get_value() const
|
||||
{
|
||||
return m_pImpl->get_value();
|
||||
}
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_ATTRIBUTE_GET_VALUE_IMPL_HPP_INCLUDED_
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* 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 attribute_predicate.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 02.09.2012
|
||||
*
|
||||
* The header contains implementation of a generic predicate in template expressions.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_ATTRIBUTE_PREDICATE_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_ATTRIBUTE_PREDICATE_HPP_INCLUDED_
|
||||
|
||||
#include <boost/phoenix/core/actor.hpp>
|
||||
#include <boost/utility/result_of.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/attributes/attribute_name.hpp>
|
||||
#include <boost/log/attributes/value_visitation.hpp>
|
||||
#include <boost/log/attributes/fallback_policy.hpp>
|
||||
#include <boost/log/utility/functional/bind.hpp>
|
||||
#include <boost/log/utility/functional/save_result.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace expressions {
|
||||
|
||||
namespace aux {
|
||||
|
||||
/*!
|
||||
* The predicate checks if the attribute value satisfies a predicate.
|
||||
*/
|
||||
template< typename T, typename ArgT, typename PredicateT, typename FallbackPolicyT = fallback_to_none >
|
||||
class attribute_predicate
|
||||
{
|
||||
public:
|
||||
//! Function result_type
|
||||
typedef bool result_type;
|
||||
//! Expected attribute value type
|
||||
typedef T value_type;
|
||||
//! Predicate type
|
||||
typedef PredicateT predicate_type;
|
||||
//! Argument type for the predicate
|
||||
typedef ArgT argument_type;
|
||||
//! Fallback policy
|
||||
typedef FallbackPolicyT fallback_policy;
|
||||
|
||||
private:
|
||||
//! Argument for the predicate
|
||||
const argument_type m_arg;
|
||||
//! Attribute value name
|
||||
const attribute_name m_name;
|
||||
//! Visitor invoker
|
||||
value_visitor_invoker< value_type, fallback_policy > m_visitor_invoker;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Initializing constructor
|
||||
*
|
||||
* \param name Attribute name
|
||||
* \param pred_arg The predicate argument
|
||||
*/
|
||||
attribute_predicate(attribute_name const& name, argument_type const& pred_arg) : m_arg(pred_arg), m_name(name)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* Initializing constructor
|
||||
*
|
||||
* \param name Attribute name
|
||||
* \param pred_arg The predicate argument
|
||||
* \param arg Additional parameter for the fallback policy
|
||||
*/
|
||||
template< typename U >
|
||||
attribute_predicate(attribute_name const& name, argument_type const& pred_arg, U const& arg) : m_arg(pred_arg), m_name(name), m_visitor_invoker(arg)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* Checking operator
|
||||
*
|
||||
* \param arg A set of attribute values or a log record
|
||||
* \return \c true if the log record contains the sought attribute value, \c false otherwise
|
||||
*/
|
||||
template< typename ArgumentT >
|
||||
result_type operator() (ArgumentT const& arg) const
|
||||
{
|
||||
typedef binder2nd< predicate_type, argument_type const& > visitor_type;
|
||||
|
||||
bool res = false;
|
||||
m_visitor_invoker(m_name, arg, boost::log::save_result(visitor_type(predicate_type(), m_arg), res));
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
} // namespace expressions
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_ATTRIBUTE_PREDICATE_HPP_INCLUDED_
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright Andrey Semashev 2016.
|
||||
* 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 c_str.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 23.02.2016
|
||||
*
|
||||
* This header is the Boost.Log library implementation, see the library documentation
|
||||
* at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_C_STR_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_C_STR_HPP_INCLUDED_
|
||||
|
||||
#include <string>
|
||||
#include <boost/core/enable_if.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/is_character_type.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace aux {
|
||||
|
||||
template< typename T >
|
||||
inline typename boost::enable_if_c< is_character_type< T >::value, const T* >::type c_str(const T* str) BOOST_NOEXCEPT
|
||||
{
|
||||
return str;
|
||||
}
|
||||
|
||||
template< typename T, typename TraitsT, typename AllocatorT >
|
||||
inline typename boost::enable_if_c< is_character_type< T >::value, const T* >::type c_str(std::basic_string< T, TraitsT, AllocatorT > const& str) BOOST_NOEXCEPT
|
||||
{
|
||||
return str.c_str();
|
||||
}
|
||||
|
||||
} // namespace aux
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_C_STR_HPP_INCLUDED_
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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 cleanup_scope_guard.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 11.03.2008
|
||||
*
|
||||
* \brief This header is the Boost.Log library implementation, see the library documentation
|
||||
* at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_CLEANUP_SCOPE_GUARD_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_CLEANUP_SCOPE_GUARD_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace aux {
|
||||
|
||||
//! Cleanup scope guard
|
||||
template< typename T >
|
||||
struct cleanup_guard
|
||||
{
|
||||
explicit cleanup_guard(T& obj) : m_Obj(obj) {}
|
||||
~cleanup_guard() { m_Obj.clear(); }
|
||||
|
||||
// Copying prohibited
|
||||
BOOST_DELETED_FUNCTION(cleanup_guard(cleanup_guard const&))
|
||||
BOOST_DELETED_FUNCTION(cleanup_guard& operator= (cleanup_guard const&))
|
||||
|
||||
private:
|
||||
T& m_Obj;
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_CLEANUP_SCOPE_GUARD_HPP_INCLUDED_
|
||||
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* 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 code_conversion.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 08.11.2008
|
||||
*
|
||||
* \brief This header is the Boost.Log library implementation, see the library documentation
|
||||
* at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_CODE_CONVERSION_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_CODE_CONVERSION_HPP_INCLUDED_
|
||||
|
||||
#include <cstddef>
|
||||
#include <locale>
|
||||
#include <string>
|
||||
#include <boost/core/enable_if.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/is_character_type.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace aux {
|
||||
|
||||
// Implementation note: We have to implement char<->wchar_t conversions even in the absence of the native wchar_t
|
||||
// type. These conversions are used in sinks, e.g. to convert multibyte strings to wide-character filesystem paths.
|
||||
|
||||
//! The function converts one string to the character type of another
|
||||
BOOST_LOG_API bool code_convert_impl(const wchar_t* str1, std::size_t len, std::string& str2, std::size_t max_size, std::locale const& loc = std::locale());
|
||||
//! The function converts one string to the character type of another
|
||||
BOOST_LOG_API bool code_convert_impl(const char* str1, std::size_t len, std::wstring& str2, std::size_t max_size, std::locale const& loc = std::locale());
|
||||
|
||||
#if !defined(BOOST_LOG_NO_CXX11_CODECVT_FACETS)
|
||||
#if !defined(BOOST_NO_CXX11_CHAR16_T)
|
||||
//! The function converts one string to the character type of another
|
||||
BOOST_LOG_API bool code_convert_impl(const char16_t* str1, std::size_t len, std::string& str2, std::size_t max_size, std::locale const& loc = std::locale());
|
||||
//! The function converts one string to the character type of another
|
||||
BOOST_LOG_API bool code_convert_impl(const char* str1, std::size_t len, std::u16string& str2, std::size_t max_size, std::locale const& loc = std::locale());
|
||||
//! The function converts one string to the character type of another
|
||||
BOOST_LOG_API bool code_convert_impl(const char16_t* str1, std::size_t len, std::wstring& str2, std::size_t max_size, std::locale const& loc = std::locale());
|
||||
#endif
|
||||
#if !defined(BOOST_NO_CXX11_CHAR32_T)
|
||||
//! The function converts one string to the character type of another
|
||||
BOOST_LOG_API bool code_convert_impl(const char32_t* str1, std::size_t len, std::string& str2, std::size_t max_size, std::locale const& loc = std::locale());
|
||||
//! The function converts one string to the character type of another
|
||||
BOOST_LOG_API bool code_convert_impl(const char* str1, std::size_t len, std::u32string& str2, std::size_t max_size, std::locale const& loc = std::locale());
|
||||
//! The function converts one string to the character type of another
|
||||
BOOST_LOG_API bool code_convert_impl(const char32_t* str1, std::size_t len, std::wstring& str2, std::size_t max_size, std::locale const& loc = std::locale());
|
||||
#endif
|
||||
#if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_CHAR32_T)
|
||||
//! The function converts one string to the character type of another
|
||||
BOOST_LOG_API bool code_convert_impl(const char16_t* str1, std::size_t len, std::u32string& str2, std::size_t max_size, std::locale const& loc = std::locale());
|
||||
//! The function converts one string to the character type of another
|
||||
BOOST_LOG_API bool code_convert_impl(const char32_t* str1, std::size_t len, std::u16string& str2, std::size_t max_size, std::locale const& loc = std::locale());
|
||||
#endif
|
||||
#endif // !defined(BOOST_LOG_NO_CXX11_CODECVT_FACETS)
|
||||
|
||||
//! The function converts one string to the character type of another
|
||||
template< typename SourceCharT, typename TargetCharT, typename TargetTraitsT, typename TargetAllocatorT >
|
||||
inline typename boost::enable_if_c< is_character_type< SourceCharT >::value && is_character_type< TargetCharT >::value && sizeof(SourceCharT) == sizeof(TargetCharT), bool >::type
|
||||
code_convert(const SourceCharT* str1, std::size_t len, std::basic_string< TargetCharT, TargetTraitsT, TargetAllocatorT >& str2, std::size_t max_size, std::locale const& = std::locale())
|
||||
{
|
||||
std::size_t size_left = str2.size() < max_size ? max_size - str2.size() : static_cast< std::size_t >(0u);
|
||||
const bool overflow = len > size_left;
|
||||
str2.append(reinterpret_cast< const TargetCharT* >(str1), overflow ? size_left : len);
|
||||
return !overflow;
|
||||
}
|
||||
|
||||
//! The function converts one string to the character type of another
|
||||
template< typename SourceCharT, typename SourceTraitsT, typename SourceAllocatorT, typename TargetCharT, typename TargetTraitsT, typename TargetAllocatorT >
|
||||
inline typename boost::enable_if_c< is_character_type< SourceCharT >::value && is_character_type< TargetCharT >::value && sizeof(SourceCharT) == sizeof(TargetCharT), bool >::type
|
||||
code_convert(std::basic_string< SourceCharT, SourceTraitsT, SourceAllocatorT > const& str1, std::basic_string< TargetCharT, TargetTraitsT, TargetAllocatorT >& str2, std::size_t max_size, std::locale const& loc = std::locale())
|
||||
{
|
||||
return aux::code_convert(str1.data(), str1.size(), str2, max_size, loc);
|
||||
}
|
||||
|
||||
//! The function converts one string to the character type of another
|
||||
template< typename SourceCharT, typename SourceTraitsT, typename SourceAllocatorT, typename TargetCharT, typename TargetTraitsT, typename TargetAllocatorT >
|
||||
inline typename boost::enable_if_c< is_character_type< SourceCharT >::value && is_character_type< TargetCharT >::value && sizeof(SourceCharT) == sizeof(TargetCharT), bool >::type
|
||||
code_convert(std::basic_string< SourceCharT, SourceTraitsT, SourceAllocatorT > const& str1, std::basic_string< TargetCharT, TargetTraitsT, TargetAllocatorT >& str2, std::locale const& loc = std::locale())
|
||||
{
|
||||
return aux::code_convert(str1.data(), str1.size(), str2, str2.max_size(), loc);
|
||||
}
|
||||
//! The function converts one string to the character type of another
|
||||
template< typename SourceCharT, typename TargetCharT, typename TargetTraitsT, typename TargetAllocatorT >
|
||||
inline typename boost::enable_if_c< is_character_type< SourceCharT >::value && is_character_type< TargetCharT >::value && sizeof(SourceCharT) == sizeof(TargetCharT), bool >::type
|
||||
code_convert(const SourceCharT* str1, std::size_t len, std::basic_string< TargetCharT, TargetTraitsT, TargetAllocatorT >& str2, std::locale const& loc = std::locale())
|
||||
{
|
||||
return aux::code_convert(str1, len, str2, str2.max_size(), loc);
|
||||
}
|
||||
|
||||
//! The function converts one string to the character type of another
|
||||
template< typename SourceCharT, typename SourceTraitsT, typename SourceAllocatorT, typename TargetCharT, typename TargetTraitsT, typename TargetAllocatorT >
|
||||
inline typename boost::enable_if_c< is_character_type< SourceCharT >::value && is_character_type< TargetCharT >::value && sizeof(SourceCharT) != sizeof(TargetCharT), bool >::type
|
||||
code_convert(std::basic_string< SourceCharT, SourceTraitsT, SourceAllocatorT > const& str1, std::basic_string< TargetCharT, TargetTraitsT, TargetAllocatorT >& str2, std::locale const& loc = std::locale())
|
||||
{
|
||||
return aux::code_convert_impl(str1.c_str(), str1.size(), str2, str2.max_size(), loc);
|
||||
}
|
||||
|
||||
//! The function converts one string to the character type of another
|
||||
template< typename SourceCharT, typename TargetCharT, typename TargetTraitsT, typename TargetAllocatorT >
|
||||
inline typename boost::enable_if_c< is_character_type< SourceCharT >::value && is_character_type< TargetCharT >::value && sizeof(SourceCharT) != sizeof(TargetCharT), bool >::type
|
||||
code_convert(const SourceCharT* str1, std::size_t len, std::basic_string< TargetCharT, TargetTraitsT, TargetAllocatorT >& str2, std::locale const& loc = std::locale())
|
||||
{
|
||||
return aux::code_convert_impl(str1, len, str2, str2.max_size(), loc);
|
||||
}
|
||||
|
||||
//! The function converts one string to the character type of another
|
||||
template< typename SourceCharT, typename SourceTraitsT, typename SourceAllocatorT, typename TargetCharT, typename TargetTraitsT, typename TargetAllocatorT >
|
||||
inline typename boost::enable_if_c< is_character_type< SourceCharT >::value && is_character_type< TargetCharT >::value && sizeof(SourceCharT) != sizeof(TargetCharT), bool >::type
|
||||
code_convert(std::basic_string< SourceCharT, SourceTraitsT, SourceAllocatorT > const& str1, std::basic_string< TargetCharT, TargetTraitsT, TargetAllocatorT >& str2, std::size_t max_size, std::locale const& loc = std::locale())
|
||||
{
|
||||
return aux::code_convert_impl(str1.c_str(), str1.size(), str2, max_size, loc);
|
||||
}
|
||||
|
||||
//! The function converts one string to the character type of another
|
||||
template< typename SourceCharT, typename TargetCharT, typename TargetTraitsT, typename TargetAllocatorT >
|
||||
inline typename boost::enable_if_c< is_character_type< SourceCharT >::value && is_character_type< TargetCharT >::value && sizeof(SourceCharT) != sizeof(TargetCharT), bool >::type
|
||||
code_convert(const SourceCharT* str1, std::size_t len, std::basic_string< TargetCharT, TargetTraitsT, TargetAllocatorT >& str2, std::size_t max_size, std::locale const& loc = std::locale())
|
||||
{
|
||||
return aux::code_convert_impl(str1, len, str2, max_size, loc);
|
||||
}
|
||||
|
||||
//! The function converts the passed string to the narrow-character encoding
|
||||
inline std::string const& to_narrow(std::string const& str)
|
||||
{
|
||||
return str;
|
||||
}
|
||||
|
||||
//! The function converts the passed string to the narrow-character encoding
|
||||
inline std::string const& to_narrow(std::string const& str, std::locale const&)
|
||||
{
|
||||
return str;
|
||||
}
|
||||
|
||||
//! The function converts the passed string to the narrow-character encoding
|
||||
inline std::string to_narrow(std::wstring const& str, std::locale const& loc = std::locale())
|
||||
{
|
||||
std::string res;
|
||||
aux::code_convert_impl(str.c_str(), str.size(), res, res.max_size(), loc);
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_HAS_NRVO)
|
||||
return static_cast< std::string&& >(res);
|
||||
#else
|
||||
return res;
|
||||
#endif
|
||||
}
|
||||
|
||||
//! The function converts the passed string to the wide-character encoding
|
||||
inline std::wstring const& to_wide(std::wstring const& str)
|
||||
{
|
||||
return str;
|
||||
}
|
||||
|
||||
//! The function converts the passed string to the wide-character encoding
|
||||
inline std::wstring const& to_wide(std::wstring const& str, std::locale const&)
|
||||
{
|
||||
return str;
|
||||
}
|
||||
|
||||
//! The function converts the passed string to the wide-character encoding
|
||||
inline std::wstring to_wide(std::string const& str, std::locale const& loc = std::locale())
|
||||
{
|
||||
std::wstring res;
|
||||
aux::code_convert_impl(str.c_str(), str.size(), res, res.max_size(), loc);
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_HAS_NRVO)
|
||||
return static_cast< std::wstring&& >(res);
|
||||
#else
|
||||
return res;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace aux
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_CODE_CONVERSION_HPP_INCLUDED_
|
||||
@@ -0,0 +1,381 @@
|
||||
/*
|
||||
* 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 config.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 08.03.2007
|
||||
*
|
||||
* \brief This header is the Boost.Log library implementation, see the library documentation
|
||||
* at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html. In this file
|
||||
* internal configuration macros are defined.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_CONFIG_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_CONFIG_HPP_INCLUDED_
|
||||
|
||||
// This check must be before any system headers are included, or __MSVCRT_VERSION__ may get defined to 0x0600
|
||||
#if defined(__MINGW32__) && !defined(__MSVCRT_VERSION__)
|
||||
// Target MinGW headers to at least MSVC 7.0 runtime by default. This will enable some useful functions.
|
||||
#define __MSVCRT_VERSION__ 0x0700
|
||||
#endif
|
||||
|
||||
#include <boost/predef/os.h>
|
||||
|
||||
// Try including WinAPI config as soon as possible so that any other headers don't include Windows SDK headers
|
||||
#if defined(BOOST_OS_WINDOWS_AVAILABLE)
|
||||
#include <boost/detail/winapi/config.hpp>
|
||||
#endif
|
||||
|
||||
#include <limits.h> // To bring in libc macros
|
||||
#include <boost/config.hpp>
|
||||
|
||||
// The library requires dynamic_cast in a few places
|
||||
#if defined(BOOST_NO_RTTI)
|
||||
# error Boost.Log: RTTI is required by the library
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1600
|
||||
# define BOOST_LOG_HAS_PRAGMA_DETECT_MISMATCH
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_LOG_HAS_PRAGMA_DETECT_MISMATCH)
|
||||
#include <boost/preprocessor/stringize.hpp>
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_WINDOWS)
|
||||
# ifndef BOOST_LOG_WITHOUT_DEBUG_OUTPUT
|
||||
# define BOOST_LOG_WITHOUT_DEBUG_OUTPUT
|
||||
# endif
|
||||
# ifndef BOOST_LOG_WITHOUT_EVENT_LOG
|
||||
# define BOOST_LOG_WITHOUT_EVENT_LOG
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
// For some reason MSVC 9.0 fails to link the library if static integral constants are defined in cpp
|
||||
# define BOOST_LOG_BROKEN_STATIC_CONSTANTS_LINKAGE
|
||||
# if _MSC_VER <= 1310
|
||||
// MSVC 7.1 sometimes fails to match out-of-class template function definitions with
|
||||
// their declarations if the return type or arguments of the functions involve typename keyword
|
||||
// and depend on the template parameters.
|
||||
# define BOOST_LOG_BROKEN_TEMPLATE_DEFINITION_MATCHING
|
||||
# endif
|
||||
# if _MSC_VER <= 1400
|
||||
// Older MSVC versions reject friend declarations for class template specializations
|
||||
# define BOOST_LOG_BROKEN_FRIEND_TEMPLATE_SPECIALIZATIONS
|
||||
# endif
|
||||
# if _MSC_VER <= 1600
|
||||
// MSVC up to 10.0 attempts to invoke copy constructor when initializing a const reference from rvalue returned from a function.
|
||||
// This fails when the returned value cannot be copied (only moved):
|
||||
//
|
||||
// class base {};
|
||||
// class derived : public base { BOOST_MOVABLE_BUT_NOT_COPYABLE(derived) };
|
||||
// derived foo();
|
||||
// base const& var = foo(); // attempts to call copy constructor of derived
|
||||
# define BOOST_LOG_BROKEN_REFERENCE_FROM_RVALUE_INIT
|
||||
# endif
|
||||
# if !defined(_STLPORT_VERSION)
|
||||
// MSVC 9.0 mandates packaging of STL classes, which apparently affects alignment and
|
||||
// makes alignment_of< T >::value no longer be a power of 2 for types that derive from STL classes.
|
||||
// This breaks type_with_alignment and everything that relies on it.
|
||||
// This doesn't happen with non-native STLs, such as STLPort. Strangely, this doesn't show with
|
||||
// STL classes themselves or most of the user-defined derived classes.
|
||||
// Not sure if that happens with other MSVC versions.
|
||||
// See: http://svn.boost.org/trac/boost/ticket/1946
|
||||
# define BOOST_LOG_BROKEN_STL_ALIGNMENT
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_INTEL) || defined(__SUNPRO_CC)
|
||||
// Intel compiler and Sun Studio 12.3 have problems with friend declarations for nested class templates
|
||||
# define BOOST_LOG_NO_MEMBER_TEMPLATE_FRIENDS
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1600
|
||||
// MSVC cannot interpret constant expressions in certain contexts, such as non-type template parameters
|
||||
# define BOOST_LOG_BROKEN_CONSTANT_EXPRESSIONS
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_NO_CXX11_HDR_CODECVT)
|
||||
// The compiler does not support std::codecvt<char16_t> and std::codecvt<char32_t> specializations.
|
||||
// The BOOST_NO_CXX11_HDR_CODECVT means there's no usable <codecvt>, which is slightly different from this macro.
|
||||
// But in order for <codecvt> to be implemented the std::codecvt specializations have to be implemented as well.
|
||||
# define BOOST_LOG_NO_CXX11_CODECVT_FACETS
|
||||
#endif
|
||||
|
||||
#if defined(__CYGWIN__)
|
||||
// Boost.ASIO is broken on Cygwin
|
||||
# define BOOST_LOG_NO_ASIO
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_LOG_USE_NATIVE_SYSLOG) && defined(BOOST_LOG_NO_ASIO)
|
||||
# ifndef BOOST_LOG_WITHOUT_SYSLOG
|
||||
# define BOOST_LOG_WITHOUT_SYSLOG
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && (__GNUC__ == 4 && __GNUC_MINOR__ <= 2)
|
||||
// GCC 4.1 and 4.2 have buggy anonymous namespaces support, which interferes with symbol linkage
|
||||
# define BOOST_LOG_ANONYMOUS_NAMESPACE namespace anonymous {} using namespace anonymous; namespace anonymous
|
||||
#else
|
||||
# define BOOST_LOG_ANONYMOUS_NAMESPACE namespace
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || (defined(__GNUC__) && (__GNUC__ == 4 && __GNUC_MINOR__ <= 6))
|
||||
// GCC up to 4.6 (inclusively) did not support expanding template argument packs into non-variadic template arguments
|
||||
#define BOOST_LOG_NO_CXX11_ARG_PACKS_TO_NON_VARIADIC_ARGS_EXPANSION
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_NO_CXX11_CONSTEXPR) || (defined(BOOST_GCC) && ((BOOST_GCC+0) / 100) <= 406)
|
||||
// GCC 4.6 does not support in-class brace initializers for static constexpr array members
|
||||
#define BOOST_LOG_NO_CXX11_CONSTEXPR_DATA_MEMBER_BRACE_INITIALIZERS
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || (defined(BOOST_GCC) && ((BOOST_GCC+0) / 100) <= 406)
|
||||
// GCC 4.6 cannot handle a defaulted function with noexcept specifier
|
||||
#define BOOST_LOG_NO_CXX11_DEFAULTED_NOEXCEPT_FUNCTIONS
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# define BOOST_LOG_NO_VTABLE __declspec(novtable)
|
||||
#elif defined(__GNUC__)
|
||||
# define BOOST_LOG_NO_VTABLE
|
||||
#else
|
||||
# define BOOST_LOG_NO_VTABLE
|
||||
#endif
|
||||
|
||||
// An MS-like compilers' extension that allows to optimize away the needless code
|
||||
#if defined(_MSC_VER)
|
||||
# define BOOST_LOG_ASSUME(expr) __assume(expr)
|
||||
#else
|
||||
# define BOOST_LOG_ASSUME(expr)
|
||||
#endif
|
||||
|
||||
// The statement marking unreachable branches of code to avoid warnings
|
||||
#if defined(BOOST_CLANG)
|
||||
# if __has_builtin(__builtin_unreachable)
|
||||
# define BOOST_LOG_UNREACHABLE() __builtin_unreachable()
|
||||
# endif
|
||||
#elif defined(__GNUC__)
|
||||
# if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
|
||||
# define BOOST_LOG_UNREACHABLE() __builtin_unreachable()
|
||||
# endif
|
||||
#elif defined(_MSC_VER)
|
||||
# define BOOST_LOG_UNREACHABLE() __assume(0)
|
||||
#endif
|
||||
#if !defined(BOOST_LOG_UNREACHABLE)
|
||||
# define BOOST_LOG_UNREACHABLE()
|
||||
# define BOOST_LOG_UNREACHABLE_RETURN(r) return r
|
||||
#else
|
||||
# define BOOST_LOG_UNREACHABLE_RETURN(r) BOOST_LOG_UNREACHABLE()
|
||||
#endif
|
||||
|
||||
// The macro efficiently returns a local lvalue from a function.
|
||||
// It employs NRVO, if supported by compiler, or uses a move constructor otherwise.
|
||||
#if defined(BOOST_HAS_NRVO)
|
||||
#define BOOST_LOG_NRVO_RESULT(x) x
|
||||
#else
|
||||
#define BOOST_LOG_NRVO_RESULT(x) boost::move(x)
|
||||
#endif
|
||||
|
||||
// Some compilers support a special attribute that shows that a function won't return
|
||||
#if defined(__GNUC__) || (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x590)
|
||||
// GCC and Sun Studio 12 support attribute syntax
|
||||
# define BOOST_LOG_NORETURN __attribute__((noreturn))
|
||||
#elif defined (_MSC_VER)
|
||||
// Microsoft-compatible compilers go here
|
||||
# define BOOST_LOG_NORETURN __declspec(noreturn)
|
||||
#else
|
||||
// The rest compilers might emit bogus warnings about missing return statements
|
||||
// in functions with non-void return types when throw_exception is used.
|
||||
# define BOOST_LOG_NORETURN
|
||||
#endif
|
||||
|
||||
// GCC and compatible compilers may require marking types that may alias other types
|
||||
#if defined(__GNUC__)
|
||||
# define BOOST_LOG_MAY_ALIAS __attribute__ ((__may_alias__))
|
||||
#else
|
||||
# define BOOST_LOG_MAY_ALIAS
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_LOG_BUILDING_THE_LIB)
|
||||
|
||||
// Detect if we're dealing with dll
|
||||
# if defined(BOOST_LOG_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)
|
||||
# define BOOST_LOG_DLL
|
||||
# endif
|
||||
|
||||
# if defined(BOOST_LOG_DLL)
|
||||
# define BOOST_LOG_API BOOST_SYMBOL_IMPORT
|
||||
# else
|
||||
# define BOOST_LOG_API
|
||||
# endif
|
||||
//
|
||||
// Automatically link to the correct build variant where possible.
|
||||
//
|
||||
# if !defined(BOOST_ALL_NO_LIB)
|
||||
# if !defined(BOOST_LOG_NO_LIB)
|
||||
# define BOOST_LIB_NAME boost_log
|
||||
# if defined(BOOST_LOG_DLL)
|
||||
# define BOOST_DYN_LINK
|
||||
# endif
|
||||
# include <boost/config/auto_link.hpp>
|
||||
# endif
|
||||
// In static-library builds compilers ignore auto-link comments from Boost.Log binary to
|
||||
// other Boost libraries. We explicitly add comments here for other libraries.
|
||||
// In dynamic-library builds this is not needed.
|
||||
# if !defined(BOOST_LOG_DLL)
|
||||
# include <boost/system/config.hpp>
|
||||
# include <boost/filesystem/config.hpp>
|
||||
# if !defined(BOOST_DATE_TIME_NO_LIB) && !defined(BOOST_DATE_TIME_SOURCE)
|
||||
# define BOOST_LIB_NAME boost_date_time
|
||||
# if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_DATE_TIME_DYN_LINK)
|
||||
# define BOOST_DYN_LINK
|
||||
# endif
|
||||
# include <boost/config/auto_link.hpp>
|
||||
# endif
|
||||
// Boost.Thread's config is included below, if needed
|
||||
# endif
|
||||
# endif // auto-linking disabled
|
||||
|
||||
#else // !defined(BOOST_LOG_BUILDING_THE_LIB)
|
||||
|
||||
# if defined(BOOST_LOG_DLL)
|
||||
# define BOOST_LOG_API BOOST_SYMBOL_EXPORT
|
||||
# else
|
||||
# define BOOST_LOG_API BOOST_SYMBOL_VISIBLE
|
||||
# endif
|
||||
|
||||
#endif // !defined(BOOST_LOG_BUILDING_THE_LIB)
|
||||
|
||||
// By default we provide support for both char and wchar_t
|
||||
#if !defined(BOOST_LOG_WITHOUT_CHAR)
|
||||
# define BOOST_LOG_USE_CHAR
|
||||
#endif
|
||||
#if !defined(BOOST_LOG_WITHOUT_WCHAR_T)
|
||||
# define BOOST_LOG_USE_WCHAR_T
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_LOG_DOXYGEN_PASS)
|
||||
// Check if multithreading is supported
|
||||
# if !defined(BOOST_LOG_NO_THREADS) && !defined(BOOST_HAS_THREADS)
|
||||
# define BOOST_LOG_NO_THREADS
|
||||
# endif // !defined(BOOST_LOG_NO_THREADS) && !defined(BOOST_HAS_THREADS)
|
||||
#endif // !defined(BOOST_LOG_DOXYGEN_PASS)
|
||||
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
// We need this header to (i) enable auto-linking with Boost.Thread and
|
||||
// (ii) to bring in configuration macros of Boost.Thread.
|
||||
# include <boost/thread/detail/config.hpp>
|
||||
#endif // !defined(BOOST_LOG_NO_THREADS)
|
||||
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
# define BOOST_LOG_EXPR_IF_MT(expr) expr
|
||||
#else
|
||||
# undef BOOST_LOG_USE_COMPILER_TLS
|
||||
# define BOOST_LOG_EXPR_IF_MT(expr)
|
||||
#endif // !defined(BOOST_LOG_NO_THREADS)
|
||||
|
||||
#if defined(BOOST_LOG_USE_COMPILER_TLS)
|
||||
# if defined(__GNUC__) || defined(__SUNPRO_CC)
|
||||
# define BOOST_LOG_TLS __thread
|
||||
# elif defined(BOOST_MSVC)
|
||||
# define BOOST_LOG_TLS __declspec(thread)
|
||||
# else
|
||||
# undef BOOST_LOG_USE_COMPILER_TLS
|
||||
# endif
|
||||
#endif // defined(BOOST_LOG_USE_COMPILER_TLS)
|
||||
|
||||
#ifndef BOOST_LOG_CPU_CACHE_LINE_SIZE
|
||||
//! The macro defines the CPU cache line size for the target architecture. This is mostly used for optimization.
|
||||
#define BOOST_LOG_CPU_CACHE_LINE_SIZE 64
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
// Setup namespace name
|
||||
#if !defined(BOOST_LOG_DOXYGEN_PASS)
|
||||
# if defined(BOOST_LOG_DLL)
|
||||
# if defined(BOOST_LOG_NO_THREADS)
|
||||
# define BOOST_LOG_VERSION_NAMESPACE v2_st
|
||||
# else
|
||||
# if defined(BOOST_THREAD_PLATFORM_PTHREAD)
|
||||
# define BOOST_LOG_VERSION_NAMESPACE v2_mt_posix
|
||||
# elif defined(BOOST_THREAD_PLATFORM_WIN32)
|
||||
# if BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_WIN6
|
||||
# define BOOST_LOG_VERSION_NAMESPACE v2_mt_nt6
|
||||
# else
|
||||
# define BOOST_LOG_VERSION_NAMESPACE v2_mt_nt5
|
||||
# endif
|
||||
# else
|
||||
# define BOOST_LOG_VERSION_NAMESPACE v2_mt
|
||||
# endif
|
||||
# endif // defined(BOOST_LOG_NO_THREADS)
|
||||
# else
|
||||
# if defined(BOOST_LOG_NO_THREADS)
|
||||
# define BOOST_LOG_VERSION_NAMESPACE v2s_st
|
||||
# else
|
||||
# if defined(BOOST_THREAD_PLATFORM_PTHREAD)
|
||||
# define BOOST_LOG_VERSION_NAMESPACE v2s_mt_posix
|
||||
# elif defined(BOOST_THREAD_PLATFORM_WIN32)
|
||||
# if BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_WIN6
|
||||
# define BOOST_LOG_VERSION_NAMESPACE v2s_mt_nt6
|
||||
# else
|
||||
# define BOOST_LOG_VERSION_NAMESPACE v2s_mt_nt5
|
||||
# endif
|
||||
# else
|
||||
# define BOOST_LOG_VERSION_NAMESPACE v2s_mt
|
||||
# endif
|
||||
# endif // defined(BOOST_LOG_NO_THREADS)
|
||||
# endif // defined(BOOST_LOG_DLL)
|
||||
|
||||
|
||||
namespace log {
|
||||
|
||||
# if !defined(BOOST_NO_CXX11_INLINE_NAMESPACES)
|
||||
|
||||
inline namespace BOOST_LOG_VERSION_NAMESPACE {}
|
||||
}
|
||||
|
||||
# define BOOST_LOG_OPEN_NAMESPACE namespace log { inline namespace BOOST_LOG_VERSION_NAMESPACE {
|
||||
# define BOOST_LOG_CLOSE_NAMESPACE }}
|
||||
|
||||
# else
|
||||
|
||||
namespace BOOST_LOG_VERSION_NAMESPACE {}
|
||||
|
||||
using namespace BOOST_LOG_VERSION_NAMESPACE
|
||||
# if defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) && !defined(__clang__)
|
||||
__attribute__((__strong__))
|
||||
# endif
|
||||
;
|
||||
|
||||
}
|
||||
|
||||
# define BOOST_LOG_OPEN_NAMESPACE namespace log { namespace BOOST_LOG_VERSION_NAMESPACE {
|
||||
# define BOOST_LOG_CLOSE_NAMESPACE }}
|
||||
# endif
|
||||
|
||||
#else // !defined(BOOST_LOG_DOXYGEN_PASS)
|
||||
|
||||
namespace log {}
|
||||
# define BOOST_LOG_OPEN_NAMESPACE namespace log {
|
||||
# define BOOST_LOG_CLOSE_NAMESPACE }
|
||||
|
||||
#endif // !defined(BOOST_LOG_DOXYGEN_PASS)
|
||||
|
||||
#if defined(BOOST_LOG_HAS_PRAGMA_DETECT_MISMATCH)
|
||||
#pragma detect_mismatch("boost_log_abi", BOOST_PP_STRINGIZE(BOOST_LOG_VERSION_NAMESPACE))
|
||||
#endif
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_CONFIG_HPP_INCLUDED_
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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 copy_cv.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 16.03.2014
|
||||
*
|
||||
* The header defines \c copy_cv type trait which copies const/volatile qualifiers from one type to another
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_COPY_CV_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_COPY_CV_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace aux {
|
||||
|
||||
//! The type trait copies top level const/volatile qualifiers from \c FromT to \c ToT
|
||||
template< typename FromT, typename ToT >
|
||||
struct copy_cv
|
||||
{
|
||||
typedef ToT type;
|
||||
};
|
||||
|
||||
template< typename FromT, typename ToT >
|
||||
struct copy_cv< const FromT, ToT >
|
||||
{
|
||||
typedef const ToT type;
|
||||
};
|
||||
|
||||
template< typename FromT, typename ToT >
|
||||
struct copy_cv< volatile FromT, ToT >
|
||||
{
|
||||
typedef volatile ToT type;
|
||||
};
|
||||
|
||||
template< typename FromT, typename ToT >
|
||||
struct copy_cv< const volatile FromT, ToT >
|
||||
{
|
||||
typedef const volatile ToT type;
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_COPY_CV_HPP_INCLUDED_
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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 custom_terminal_spec.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 29.01.2012
|
||||
*
|
||||
* The header contains Boost.Phoenix custom terminal specialization for Boost.Log terminals.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_CUSTOM_TERMINAL_SPEC_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_CUSTOM_TERMINAL_SPEC_HPP_INCLUDED_
|
||||
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/phoenix/core/terminal_fwd.hpp>
|
||||
#include <boost/phoenix/core/is_nullary.hpp>
|
||||
#include <boost/phoenix/core/terminal.hpp> // needed for terminal-related part of the grammar
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/utility/result_of.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace phoenix {
|
||||
|
||||
template< typename T >
|
||||
struct is_custom_terminal< T, typename T::_is_boost_log_terminal > :
|
||||
public mpl::true_
|
||||
{
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
struct custom_terminal< T, typename T::_is_boost_log_terminal >
|
||||
{
|
||||
typedef custom_terminal< T, typename T::_is_boost_log_terminal > this_type;
|
||||
|
||||
template< typename >
|
||||
struct result;
|
||||
|
||||
template< typename ThisT, typename TermT, typename ContextT >
|
||||
struct result< ThisT(TermT, ContextT) >
|
||||
{
|
||||
typedef typename remove_cv< typename remove_reference< TermT >::type >::type term;
|
||||
typedef typename boost::result_of< const term(ContextT) >::type type;
|
||||
};
|
||||
|
||||
template< typename ContextT >
|
||||
typename result< const this_type(T const&, ContextT&) >::type operator() (T const& term, ContextT& ctx) const
|
||||
{
|
||||
return term(ctx);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace phoenix
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_CUSTOM_TERMINAL_SPEC_HPP_INCLUDED_
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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 date_time_fmt_gen_traits_fwd.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 07.11.2012
|
||||
*
|
||||
* \brief This header is the Boost.Log library implementation, see the library documentation
|
||||
* at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_DATE_TIME_FMT_GEN_TRAITS_FWD_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_DATE_TIME_FMT_GEN_TRAITS_FWD_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace expressions {
|
||||
|
||||
namespace aux {
|
||||
|
||||
template< typename T, typename CharT, typename VoidT = void >
|
||||
struct date_time_formatter_generator_traits;
|
||||
|
||||
} // namespace aux
|
||||
|
||||
} // namespace expressions
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_DATE_TIME_FMT_GEN_TRAITS_FWD_HPP_INCLUDED_
|
||||
@@ -0,0 +1,486 @@
|
||||
/*
|
||||
* 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 date_time_format_parser.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 16.09.2012
|
||||
*
|
||||
* The header contains a parser for date and time format strings.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_DATE_TIME_FORMAT_PARSER_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_DATE_TIME_FORMAT_PARSER_HPP_INCLUDED_
|
||||
|
||||
#include <string>
|
||||
#include <boost/range/as_literal.hpp>
|
||||
#include <boost/range/iterator_range_core.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace aux {
|
||||
|
||||
/*!
|
||||
* This is the interface the parser will use to notify the caller about various components of date in the format string.
|
||||
*/
|
||||
template< typename CharT >
|
||||
struct date_format_parser_callback
|
||||
{
|
||||
//! Character type used by the parser
|
||||
typedef CharT char_type;
|
||||
|
||||
//! Destructor
|
||||
virtual ~date_format_parser_callback() {}
|
||||
|
||||
/*!
|
||||
* \brief The function is called when the parser discovers a string literal in the format string
|
||||
*
|
||||
* \param lit The string of characters not interpreted as a placeholder
|
||||
*/
|
||||
virtual void on_literal(iterator_range< const char_type* > const& lit) = 0;
|
||||
|
||||
/*!
|
||||
* \brief The method is called when an unknown placeholder is found in the format string
|
||||
*
|
||||
* \param ph The placeholder with the leading percent sign
|
||||
*/
|
||||
virtual void on_placeholder(iterator_range< const char_type* > const& ph)
|
||||
{
|
||||
// By default interpret all unrecognized placeholders as literals
|
||||
on_literal(ph);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief The function is called when the short year placeholder is found in the format string
|
||||
*/
|
||||
virtual void on_short_year()
|
||||
{
|
||||
const char_type placeholder[3] = { static_cast< char_type >('%'), static_cast< char_type >('y'), static_cast< char_type >('\0') };
|
||||
on_placeholder(boost::as_literal(placeholder));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief The function is called when the full year placeholder is found in the format string
|
||||
*/
|
||||
virtual void on_full_year()
|
||||
{
|
||||
const char_type placeholder[3] = { static_cast< char_type >('%'), static_cast< char_type >('Y'), static_cast< char_type >('\0') };
|
||||
on_placeholder(boost::as_literal(placeholder));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief The function is called when the numeric month placeholder is found in the format string
|
||||
*/
|
||||
virtual void on_numeric_month()
|
||||
{
|
||||
const char_type placeholder[3] = { static_cast< char_type >('%'), static_cast< char_type >('m'), static_cast< char_type >('\0') };
|
||||
on_placeholder(boost::as_literal(placeholder));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief The function is called when the short alphabetic month placeholder is found in the format string
|
||||
*/
|
||||
virtual void on_short_month()
|
||||
{
|
||||
const char_type placeholder[3] = { static_cast< char_type >('%'), static_cast< char_type >('b'), static_cast< char_type >('\0') };
|
||||
on_placeholder(boost::as_literal(placeholder));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief The function is called when the full alphabetic month placeholder is found in the format string
|
||||
*/
|
||||
virtual void on_full_month()
|
||||
{
|
||||
const char_type placeholder[3] = { static_cast< char_type >('%'), static_cast< char_type >('B'), static_cast< char_type >('\0') };
|
||||
on_placeholder(boost::as_literal(placeholder));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief The function is called when the numeric day of month placeholder is found in the format string
|
||||
*
|
||||
* \param leading_zero If \c true, the day should be formatted with leading zero, otherwise with leading space
|
||||
*/
|
||||
virtual void on_month_day(bool leading_zero)
|
||||
{
|
||||
const char_type placeholder[3] = { static_cast< char_type >('%'), (leading_zero ? static_cast< char_type >('d') : static_cast< char_type >('e')), static_cast< char_type >('\0') };
|
||||
on_placeholder(boost::as_literal(placeholder));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief The function is called when the numeric day of week placeholder is found in the format string
|
||||
*/
|
||||
virtual void on_numeric_week_day()
|
||||
{
|
||||
const char_type placeholder[3] = { static_cast< char_type >('%'), static_cast< char_type >('w'), static_cast< char_type >('\0') };
|
||||
on_placeholder(boost::as_literal(placeholder));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief The function is called when the short alphabetic day of week placeholder is found in the format string
|
||||
*/
|
||||
virtual void on_short_week_day()
|
||||
{
|
||||
const char_type placeholder[3] = { static_cast< char_type >('%'), static_cast< char_type >('a'), static_cast< char_type >('\0') };
|
||||
on_placeholder(boost::as_literal(placeholder));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief The function is called when the full alphabetic day of week placeholder is found in the format string
|
||||
*/
|
||||
virtual void on_full_week_day()
|
||||
{
|
||||
const char_type placeholder[3] = { static_cast< char_type >('%'), static_cast< char_type >('A'), static_cast< char_type >('\0') };
|
||||
on_placeholder(boost::as_literal(placeholder));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief The function is called when the ISO-formatted date is found in the format string
|
||||
*/
|
||||
virtual void on_iso_date()
|
||||
{
|
||||
on_full_year();
|
||||
on_numeric_month();
|
||||
on_month_day(true);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief The function is called when the extended ISO-formatted date is found in the format string
|
||||
*/
|
||||
virtual void on_extended_iso_date()
|
||||
{
|
||||
const char_type delimiter[2] = { static_cast< char_type >('-'), static_cast< char_type >('\0') };
|
||||
on_full_year();
|
||||
on_literal(boost::as_literal(delimiter));
|
||||
on_numeric_month();
|
||||
on_literal(boost::as_literal(delimiter));
|
||||
on_month_day(true);
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* This is the interface the parser will use to notify the caller about various components of date in the format string.
|
||||
*/
|
||||
template< typename CharT >
|
||||
struct time_format_parser_callback
|
||||
{
|
||||
//! Character type used by the parser
|
||||
typedef CharT char_type;
|
||||
|
||||
//! Destructor
|
||||
virtual ~time_format_parser_callback() {}
|
||||
|
||||
/*!
|
||||
* \brief The function is called when the parser discovers a string literal in the format string
|
||||
*
|
||||
* \param lit The string of characters not interpreted as a placeholder
|
||||
*/
|
||||
virtual void on_literal(iterator_range< const char_type* > const& lit) = 0;
|
||||
|
||||
/*!
|
||||
* \brief The method is called when an unknown placeholder is found in the format string
|
||||
*
|
||||
* \param ph The placeholder with the leading percent sign
|
||||
*/
|
||||
virtual void on_placeholder(iterator_range< const char_type* > const& ph)
|
||||
{
|
||||
// By default interpret all unrecognized placeholders as literals
|
||||
on_literal(ph);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief The function is called when the hours placeholder is found in the format string
|
||||
*
|
||||
* The placeholder is used for 24-hour clock and duration formatting.
|
||||
*
|
||||
* \param leading_zero If \c true, the one-digit number of hours should be formatted with leading zero, otherwise with leading space
|
||||
*/
|
||||
virtual void on_hours(bool leading_zero)
|
||||
{
|
||||
const char_type placeholder[3] = { static_cast< char_type >('%'), (leading_zero ? static_cast< char_type >('O') : static_cast< char_type >('k')), static_cast< char_type >('\0') };
|
||||
on_placeholder(boost::as_literal(placeholder));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief The function is called when the hours placeholder is found in the format string
|
||||
*
|
||||
* The placeholder is used for 12-hour clock formatting. It should not be used for duration formatting.
|
||||
*
|
||||
* \param leading_zero If \c true, the one-digit number of hours should be formatted with leading zero, otherwise with leading space
|
||||
*/
|
||||
virtual void on_hours_12(bool leading_zero)
|
||||
{
|
||||
const char_type placeholder[3] = { static_cast< char_type >('%'), (leading_zero ? static_cast< char_type >('I') : static_cast< char_type >('l')), static_cast< char_type >('\0') };
|
||||
on_placeholder(boost::as_literal(placeholder));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief The function is called when the minutes placeholder is found in the format string
|
||||
*/
|
||||
virtual void on_minutes()
|
||||
{
|
||||
const char_type placeholder[3] = { static_cast< char_type >('%'), static_cast< char_type >('M'), static_cast< char_type >('\0') };
|
||||
on_placeholder(boost::as_literal(placeholder));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief The function is called when the seconds placeholder is found in the format string
|
||||
*/
|
||||
virtual void on_seconds()
|
||||
{
|
||||
const char_type placeholder[3] = { static_cast< char_type >('%'), static_cast< char_type >('S'), static_cast< char_type >('\0') };
|
||||
on_placeholder(boost::as_literal(placeholder));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief The function is called when the fractional seconds placeholder is found in the format string
|
||||
*/
|
||||
virtual void on_fractional_seconds()
|
||||
{
|
||||
const char_type placeholder[3] = { static_cast< char_type >('%'), static_cast< char_type >('f'), static_cast< char_type >('\0') };
|
||||
on_placeholder(boost::as_literal(placeholder));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief The function is called when the day period (AM/PM) placeholder is found in the format string
|
||||
*
|
||||
* The placeholder is used for 12-hour clock formatting. It should not be used for duration formatting.
|
||||
*
|
||||
* \param upper_case If \c true, the day period will be upper case, and lower case otherwise
|
||||
*/
|
||||
virtual void on_am_pm(bool upper_case)
|
||||
{
|
||||
const char_type placeholder[3] = { static_cast< char_type >('%'), (upper_case ? static_cast< char_type >('p') : static_cast< char_type >('P')), static_cast< char_type >('\0') };
|
||||
on_placeholder(boost::as_literal(placeholder));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief The function is called when the time duration sign placeholder is found in the format string
|
||||
*
|
||||
* The placeholder is used for duration formatting. It should not be used for time point formatting.
|
||||
*
|
||||
* \param display_positive If \c true, the positive sign will be explicitly displayed, otherwise only negative sign will be displayed
|
||||
*/
|
||||
virtual void on_duration_sign(bool display_positive)
|
||||
{
|
||||
const char_type placeholder[3] = { static_cast< char_type >('%'), (display_positive ? static_cast< char_type >('+') : static_cast< char_type >('-')), static_cast< char_type >('\0') };
|
||||
on_placeholder(boost::as_literal(placeholder));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief The function is called when the ISO time zone placeholder is found in the format string
|
||||
*/
|
||||
virtual void on_iso_time_zone()
|
||||
{
|
||||
const char_type placeholder[3] = { static_cast< char_type >('%'), static_cast< char_type >('q'), static_cast< char_type >('\0') };
|
||||
on_placeholder(boost::as_literal(placeholder));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief The function is called when the extended ISO time zone placeholder is found in the format string
|
||||
*/
|
||||
virtual void on_extended_iso_time_zone()
|
||||
{
|
||||
const char_type placeholder[3] = { static_cast< char_type >('%'), static_cast< char_type >('Q'), static_cast< char_type >('\0') };
|
||||
on_placeholder(boost::as_literal(placeholder));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief The function is called when the ISO-formatted time is found in the format string
|
||||
*/
|
||||
virtual void on_iso_time()
|
||||
{
|
||||
on_hours(true);
|
||||
on_minutes();
|
||||
on_seconds();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief The function is called when the extended ISO-formatted time is found in the format string
|
||||
*/
|
||||
virtual void on_extended_iso_time()
|
||||
{
|
||||
const char_type delimiter[2] = { static_cast< char_type >(':'), static_cast< char_type >('\0') };
|
||||
on_hours(true);
|
||||
on_literal(boost::as_literal(delimiter));
|
||||
on_minutes();
|
||||
on_literal(boost::as_literal(delimiter));
|
||||
on_seconds();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief The function is called when the extended ISO-formatted time with fractional seconds is found in the format string
|
||||
*/
|
||||
virtual void on_default_time()
|
||||
{
|
||||
on_extended_iso_time();
|
||||
|
||||
const char_type delimiter[2] = { static_cast< char_type >('.'), static_cast< char_type >('\0') };
|
||||
on_literal(boost::as_literal(delimiter));
|
||||
on_fractional_seconds();
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* This is the interface the parser will use to notify the caller about various components of date in the format string.
|
||||
*/
|
||||
template< typename CharT >
|
||||
struct date_time_format_parser_callback :
|
||||
public date_format_parser_callback< CharT >,
|
||||
public time_format_parser_callback< CharT >
|
||||
{
|
||||
//! Character type used by the parser
|
||||
typedef CharT char_type;
|
||||
|
||||
//! Destructor
|
||||
virtual ~date_time_format_parser_callback() {}
|
||||
|
||||
/*!
|
||||
* \brief The function is called when the parser discovers a string literal in the format string
|
||||
*
|
||||
* \param lit The string of characters not interpreted as a placeholder
|
||||
*/
|
||||
virtual void on_literal(iterator_range< const char_type* > const& lit) = 0;
|
||||
|
||||
/*!
|
||||
* \brief The method is called when an unknown placeholder is found in the format string
|
||||
*
|
||||
* \param ph The placeholder with the leading percent sign
|
||||
*/
|
||||
virtual void on_placeholder(iterator_range< const char_type* > const& ph)
|
||||
{
|
||||
// By default interpret all unrecognized placeholders as literals
|
||||
on_literal(ph);
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Parses the date format string and invokes the callback object
|
||||
*
|
||||
* \pre <tt>begin <= end</tt>, both pointers must not be \c NULL
|
||||
* \param begin Pointer to the first character of the sequence
|
||||
* \param end Pointer to the after-the-last character of the sequence
|
||||
* \param callback Reference to the callback object that will be invoked by the parser as it processes the input
|
||||
*/
|
||||
template< typename CharT >
|
||||
BOOST_LOG_API void parse_date_format(const CharT* begin, const CharT* end, date_format_parser_callback< CharT >& callback);
|
||||
|
||||
/*!
|
||||
* \brief Parses the date format string and invokes the callback object
|
||||
*
|
||||
* \param str The format string to parse
|
||||
* \param callback Reference to the callback object that will be invoked by the parser as it processes the input
|
||||
*/
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT >
|
||||
inline void parse_date_format(std::basic_string< CharT, TraitsT, AllocatorT > const& str, date_format_parser_callback< CharT >& callback)
|
||||
{
|
||||
const CharT* p = str.c_str();
|
||||
return parse_date_format(p, p + str.size(), callback);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Parses the date format string and invokes the callback object
|
||||
*
|
||||
* \pre <tt>str != NULL</tt>, <tt>str</tt> points to a zero-terminated string.
|
||||
* \param str The format string to parse
|
||||
* \param callback Reference to the callback object that will be invoked by the parser as it processes the input
|
||||
*/
|
||||
template< typename CharT >
|
||||
inline void parse_date_format(const CharT* str, date_format_parser_callback< CharT >& callback)
|
||||
{
|
||||
return parse_date_format(str, str + std::char_traits< CharT >::length(str), callback);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Parses the time format string and invokes the callback object
|
||||
*
|
||||
* \pre <tt>begin <= end</tt>, both pointers must not be \c NULL
|
||||
* \param begin Pointer to the first character of the sequence
|
||||
* \param end Pointer to the after-the-last character of the sequence
|
||||
* \param callback Reference to the callback object that will be invoked by the parser as it processes the input
|
||||
*/
|
||||
template< typename CharT >
|
||||
BOOST_LOG_API void parse_time_format(const CharT* begin, const CharT* end, time_format_parser_callback< CharT >& callback);
|
||||
|
||||
/*!
|
||||
* \brief Parses the time format string and invokes the callback object
|
||||
*
|
||||
* \param str The format string to parse
|
||||
* \param callback Reference to the callback object that will be invoked by the parser as it processes the input
|
||||
*/
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT >
|
||||
inline void parse_time_format(std::basic_string< CharT, TraitsT, AllocatorT > const& str, time_format_parser_callback< CharT >& callback)
|
||||
{
|
||||
const CharT* p = str.c_str();
|
||||
return parse_time_format(p, p + str.size(), callback);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Parses the time format string and invokes the callback object
|
||||
*
|
||||
* \pre <tt>str != NULL</tt>, <tt>str</tt> points to a zero-terminated string.
|
||||
* \param str The format string to parse
|
||||
* \param callback Reference to the callback object that will be invoked by the parser as it processes the input
|
||||
*/
|
||||
template< typename CharT >
|
||||
inline void parse_time_format(const CharT* str, time_format_parser_callback< CharT >& callback)
|
||||
{
|
||||
return parse_time_format(str, str + std::char_traits< CharT >::length(str), callback);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Parses the date and time format string and invokes the callback object
|
||||
*
|
||||
* \pre <tt>begin <= end</tt>, both pointers must not be \c NULL
|
||||
* \param begin Pointer to the first character of the sequence
|
||||
* \param end Pointer to the after-the-last character of the sequence
|
||||
* \param callback Reference to the callback object that will be invoked by the parser as it processes the input
|
||||
*/
|
||||
template< typename CharT >
|
||||
BOOST_LOG_API void parse_date_time_format(const CharT* begin, const CharT* end, date_time_format_parser_callback< CharT >& callback);
|
||||
|
||||
/*!
|
||||
* \brief Parses the date and time format string and invokes the callback object
|
||||
*
|
||||
* \param str The format string to parse
|
||||
* \param callback Reference to the callback object that will be invoked by the parser as it processes the input
|
||||
*/
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT >
|
||||
inline void parse_date_time_format(std::basic_string< CharT, TraitsT, AllocatorT > const& str, date_time_format_parser_callback< CharT >& callback)
|
||||
{
|
||||
const CharT* p = str.c_str();
|
||||
return parse_date_time_format(p, p + str.size(), callback);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Parses the date and time format string and invokes the callback object
|
||||
*
|
||||
* \pre <tt>str != NULL</tt>, <tt>str</tt> points to a zero-terminated string.
|
||||
* \param str The format string to parse
|
||||
* \param callback Reference to the callback object that will be invoked by the parser as it processes the input
|
||||
*/
|
||||
template< typename CharT >
|
||||
inline void parse_date_time_format(const CharT* str, date_time_format_parser_callback< CharT >& callback)
|
||||
{
|
||||
return parse_date_time_format(str, str + std::char_traits< CharT >::length(str), callback);
|
||||
}
|
||||
|
||||
} // namespace aux
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_DATE_TIME_FORMAT_PARSER_HPP_INCLUDED_
|
||||
@@ -0,0 +1,439 @@
|
||||
/*
|
||||
* 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 decomposed_time.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 07.11.2012
|
||||
*
|
||||
* \brief This header is the Boost.Log library implementation, see the library documentation
|
||||
* at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_DECOMPOSED_TIME_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_DECOMPOSED_TIME_HPP_INCLUDED_
|
||||
|
||||
#include <ctime>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <locale>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/range/iterator_range_core.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/date_time_format_parser.hpp>
|
||||
#include <boost/log/detail/attachable_sstream_buf.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
|
||||
|
||||
namespace aux {
|
||||
|
||||
//! Date and time suitable for formatting
|
||||
struct decomposed_time
|
||||
{
|
||||
// Subseconds are microseconds
|
||||
enum _
|
||||
{
|
||||
subseconds_per_second = 1000000,
|
||||
subseconds_digits10 = 6
|
||||
};
|
||||
|
||||
uint32_t year, month, day, hours, minutes, seconds, subseconds;
|
||||
bool negative;
|
||||
|
||||
decomposed_time() : year(0), month(1), day(1), hours(0), minutes(0), seconds(0), subseconds(0), negative(false)
|
||||
{
|
||||
}
|
||||
|
||||
decomposed_time(uint32_t y, uint32_t mo, uint32_t d, uint32_t h, uint32_t mi, uint32_t s, uint32_t ss = 0, bool neg = false) :
|
||||
year(y), month(mo), day(d), hours(h), minutes(mi), seconds(s), subseconds(ss), negative(neg)
|
||||
{
|
||||
}
|
||||
|
||||
unsigned int week_day() const
|
||||
{
|
||||
unsigned int a = (14u - month) / 12u;
|
||||
unsigned int y = year - a;
|
||||
unsigned int m = month + 12u * a - 2u;
|
||||
return (day + y + (y / 4u) - (y / 100u) + (y / 400u) + (31u * m) / 12u) % 7u;
|
||||
}
|
||||
|
||||
unsigned int year_day() const
|
||||
{
|
||||
bool is_leap_year = (!(year % 4u)) && ((year % 100u) || (!(year % 400u)));
|
||||
static const unsigned int first_day_offset[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
|
||||
return first_day_offset[month - 1] + day + (month > 2 && is_leap_year);
|
||||
}
|
||||
};
|
||||
|
||||
inline std::tm to_tm(decomposed_time const& t)
|
||||
{
|
||||
std::tm res = {};
|
||||
res.tm_year = static_cast< int >(t.year) - 1900;
|
||||
res.tm_mon = t.month - 1;
|
||||
res.tm_mday = t.day;
|
||||
res.tm_hour = t.hours;
|
||||
res.tm_min = t.minutes;
|
||||
res.tm_sec = t.seconds;
|
||||
res.tm_wday = t.week_day();
|
||||
res.tm_yday = t.year_day();
|
||||
res.tm_isdst = -1;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
struct decomposed_time_wrapper :
|
||||
public boost::log::aux::decomposed_time
|
||||
{
|
||||
typedef boost::log::aux::decomposed_time base_type;
|
||||
typedef T value_type;
|
||||
value_type m_time;
|
||||
|
||||
BOOST_DEFAULTED_FUNCTION(decomposed_time_wrapper(), {})
|
||||
|
||||
explicit decomposed_time_wrapper(value_type const& time) : m_time(time)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template< typename CharT >
|
||||
BOOST_LOG_API void put_integer(boost::log::aux::basic_ostringstreambuf< CharT >& strbuf, uint32_t value, unsigned int width, CharT fill_char);
|
||||
|
||||
template< typename T, typename CharT >
|
||||
class date_time_formatter
|
||||
{
|
||||
BOOST_COPYABLE_AND_MOVABLE_ALT(date_time_formatter)
|
||||
|
||||
protected:
|
||||
// Note: This typedef is needed to work around MSVC 2012 crappy name lookup in the derived classes
|
||||
typedef date_time_formatter date_time_formatter_;
|
||||
|
||||
public:
|
||||
typedef void result_type;
|
||||
typedef T value_type;
|
||||
typedef CharT char_type;
|
||||
typedef std::basic_string< char_type > string_type;
|
||||
typedef basic_formatting_ostream< char_type > stream_type;
|
||||
|
||||
struct context
|
||||
{
|
||||
date_time_formatter const& self;
|
||||
stream_type& strm;
|
||||
value_type const& value;
|
||||
unsigned int literal_index, literal_pos;
|
||||
|
||||
context(date_time_formatter const& self_, stream_type& strm_, value_type const& value_) :
|
||||
self(self_),
|
||||
strm(strm_),
|
||||
value(value_),
|
||||
literal_index(0),
|
||||
literal_pos(0)
|
||||
{
|
||||
}
|
||||
|
||||
BOOST_DELETED_FUNCTION(context(context const&))
|
||||
BOOST_DELETED_FUNCTION(context& operator=(context const&))
|
||||
};
|
||||
|
||||
private:
|
||||
typedef void (*formatter_type)(context&);
|
||||
typedef std::vector< formatter_type > formatters;
|
||||
typedef std::vector< unsigned int > literal_lens;
|
||||
|
||||
protected:
|
||||
formatters m_formatters;
|
||||
literal_lens m_literal_lens;
|
||||
string_type m_literal_chars;
|
||||
|
||||
public:
|
||||
BOOST_DEFAULTED_FUNCTION(date_time_formatter(), {})
|
||||
date_time_formatter(date_time_formatter const& that) :
|
||||
m_formatters(that.m_formatters),
|
||||
m_literal_lens(that.m_literal_lens),
|
||||
m_literal_chars(that.m_literal_chars)
|
||||
{
|
||||
}
|
||||
date_time_formatter(BOOST_RV_REF(date_time_formatter) that) BOOST_NOEXCEPT
|
||||
{
|
||||
this->swap(static_cast< date_time_formatter& >(that));
|
||||
}
|
||||
|
||||
date_time_formatter& operator= (date_time_formatter that) BOOST_NOEXCEPT
|
||||
{
|
||||
this->swap(that);
|
||||
return *this;
|
||||
}
|
||||
|
||||
result_type operator() (stream_type& strm, value_type const& value) const
|
||||
{
|
||||
// Some formatters will put characters directly to the underlying string, so we have to flush stream buffers before formatting
|
||||
strm.flush();
|
||||
context ctx(*this, strm, value);
|
||||
for (typename formatters::const_iterator it = m_formatters.begin(), end = m_formatters.end(); strm.good() && it != end; ++it)
|
||||
{
|
||||
(*it)(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
void add_formatter(formatter_type fun)
|
||||
{
|
||||
m_formatters.push_back(fun);
|
||||
}
|
||||
|
||||
void add_literal(iterator_range< const char_type* > const& lit)
|
||||
{
|
||||
m_literal_chars.append(lit.begin(), lit.end());
|
||||
m_literal_lens.push_back(static_cast< unsigned int >(lit.size()));
|
||||
m_formatters.push_back(&date_time_formatter_::format_literal);
|
||||
}
|
||||
|
||||
void swap(date_time_formatter& that) BOOST_NOEXCEPT
|
||||
{
|
||||
m_formatters.swap(that.m_formatters);
|
||||
m_literal_lens.swap(that.m_literal_lens);
|
||||
m_literal_chars.swap(that.m_literal_chars);
|
||||
}
|
||||
|
||||
public:
|
||||
template< char FormatCharV >
|
||||
static void format_through_locale(context& ctx)
|
||||
{
|
||||
typedef std::time_put< char_type > facet_type;
|
||||
typedef typename facet_type::iter_type iter_type;
|
||||
std::tm t = to_tm(static_cast< decomposed_time const& >(ctx.value));
|
||||
std::use_facet< facet_type >(ctx.strm.getloc()).put(iter_type(ctx.strm.stream()), ctx.strm.stream(), ' ', &t, FormatCharV);
|
||||
ctx.strm.flush();
|
||||
}
|
||||
|
||||
static void format_full_year(context& ctx)
|
||||
{
|
||||
(put_integer)(*ctx.strm.rdbuf(), ctx.value.year, 4, static_cast< char_type >('0'));
|
||||
}
|
||||
|
||||
static void format_short_year(context& ctx)
|
||||
{
|
||||
(put_integer)(*ctx.strm.rdbuf(), ctx.value.year % 100u, 2, static_cast< char_type >('0'));
|
||||
}
|
||||
|
||||
static void format_numeric_month(context& ctx)
|
||||
{
|
||||
(put_integer)(*ctx.strm.rdbuf(), ctx.value.month, 2, static_cast< char_type >('0'));
|
||||
}
|
||||
|
||||
template< char_type FillCharV >
|
||||
static void format_month_day(context& ctx)
|
||||
{
|
||||
(put_integer)(*ctx.strm.rdbuf(), ctx.value.day, 2, static_cast< char_type >(FillCharV));
|
||||
}
|
||||
|
||||
static void format_week_day(context& ctx)
|
||||
{
|
||||
(put_integer)(*ctx.strm.rdbuf(), static_cast< decomposed_time const& >(ctx.value).week_day(), 1, static_cast< char_type >('0'));
|
||||
}
|
||||
|
||||
template< char_type FillCharV >
|
||||
static void format_hours(context& ctx)
|
||||
{
|
||||
(put_integer)(*ctx.strm.rdbuf(), ctx.value.hours, 2, static_cast< char_type >(FillCharV));
|
||||
}
|
||||
|
||||
template< char_type FillCharV >
|
||||
static void format_hours_12(context& ctx)
|
||||
{
|
||||
(put_integer)(*ctx.strm.rdbuf(), ctx.value.hours % 12u + 1u, 2, static_cast< char_type >(FillCharV));
|
||||
}
|
||||
|
||||
static void format_minutes(context& ctx)
|
||||
{
|
||||
(put_integer)(*ctx.strm.rdbuf(), ctx.value.minutes, 2, static_cast< char_type >('0'));
|
||||
}
|
||||
|
||||
static void format_seconds(context& ctx)
|
||||
{
|
||||
(put_integer)(*ctx.strm.rdbuf(), ctx.value.seconds, 2, static_cast< char_type >('0'));
|
||||
}
|
||||
|
||||
static void format_fractional_seconds(context& ctx)
|
||||
{
|
||||
(put_integer)(*ctx.strm.rdbuf(), ctx.value.subseconds, decomposed_time::subseconds_digits10, static_cast< char_type >('0'));
|
||||
}
|
||||
|
||||
template< bool UpperCaseV >
|
||||
static void format_am_pm(context& ctx)
|
||||
{
|
||||
static const char_type am[] = { static_cast< char_type >(UpperCaseV ? 'A' : 'a'), static_cast< char_type >(UpperCaseV ? 'M' : 'm'), static_cast< char_type >(0) };
|
||||
static const char_type pm[] = { static_cast< char_type >(UpperCaseV ? 'P' : 'p'), static_cast< char_type >(UpperCaseV ? 'M' : 'm'), static_cast< char_type >(0) };
|
||||
|
||||
ctx.strm.rdbuf()->append(((static_cast< decomposed_time const& >(ctx.value).hours > 11) ? pm : am), 2u);
|
||||
}
|
||||
|
||||
template< bool DisplayPositiveV >
|
||||
static void format_sign(context& ctx)
|
||||
{
|
||||
if (static_cast< decomposed_time const& >(ctx.value).negative)
|
||||
ctx.strm.rdbuf()->push_back('-');
|
||||
else if (DisplayPositiveV)
|
||||
ctx.strm.rdbuf()->push_back('+');
|
||||
}
|
||||
|
||||
private:
|
||||
static void format_literal(context& ctx)
|
||||
{
|
||||
unsigned int len = ctx.self.m_literal_lens[ctx.literal_index], pos = ctx.literal_pos;
|
||||
++ctx.literal_index;
|
||||
ctx.literal_pos += len;
|
||||
const char_type* lit = ctx.self.m_literal_chars.c_str();
|
||||
ctx.strm.rdbuf()->append(lit + pos, len);
|
||||
}
|
||||
};
|
||||
|
||||
template< typename FormatterT, typename CharT >
|
||||
class decomposed_time_formatter_builder :
|
||||
public date_time_format_parser_callback< CharT >
|
||||
{
|
||||
public:
|
||||
typedef date_time_format_parser_callback< CharT > base_type;
|
||||
typedef typename base_type::char_type char_type;
|
||||
typedef FormatterT formatter_type;
|
||||
typedef typename formatter_type::value_type value_type;
|
||||
typedef typename formatter_type::stream_type stream_type;
|
||||
typedef typename stream_type::string_type string_type;
|
||||
|
||||
protected:
|
||||
formatter_type& m_formatter;
|
||||
|
||||
public:
|
||||
explicit decomposed_time_formatter_builder(formatter_type& fmt) : m_formatter(fmt)
|
||||
{
|
||||
}
|
||||
|
||||
void on_literal(iterator_range< const char_type* > const& lit)
|
||||
{
|
||||
m_formatter.add_literal(lit);
|
||||
}
|
||||
|
||||
void on_short_year()
|
||||
{
|
||||
m_formatter.add_formatter(&formatter_type::format_short_year);
|
||||
}
|
||||
|
||||
void on_full_year()
|
||||
{
|
||||
m_formatter.add_formatter(&formatter_type::format_full_year);
|
||||
}
|
||||
|
||||
void on_numeric_month()
|
||||
{
|
||||
m_formatter.add_formatter(&formatter_type::format_numeric_month);
|
||||
}
|
||||
|
||||
void on_short_month()
|
||||
{
|
||||
m_formatter.add_formatter(&formatter_type::BOOST_NESTED_TEMPLATE format_through_locale< 'b' >);
|
||||
}
|
||||
|
||||
void on_full_month()
|
||||
{
|
||||
m_formatter.add_formatter(&formatter_type::BOOST_NESTED_TEMPLATE format_through_locale< 'B' >);
|
||||
}
|
||||
|
||||
void on_month_day(bool leading_zero)
|
||||
{
|
||||
if (leading_zero)
|
||||
m_formatter.add_formatter(&formatter_type::BOOST_NESTED_TEMPLATE format_month_day< '0' >);
|
||||
else
|
||||
m_formatter.add_formatter(&formatter_type::BOOST_NESTED_TEMPLATE format_month_day< ' ' >);
|
||||
}
|
||||
|
||||
void on_numeric_week_day()
|
||||
{
|
||||
m_formatter.add_formatter(&formatter_type::format_week_day);
|
||||
}
|
||||
|
||||
void on_short_week_day()
|
||||
{
|
||||
m_formatter.add_formatter(&formatter_type::BOOST_NESTED_TEMPLATE format_through_locale< 'a' >);
|
||||
}
|
||||
|
||||
void on_full_week_day()
|
||||
{
|
||||
m_formatter.add_formatter(&formatter_type::BOOST_NESTED_TEMPLATE format_through_locale< 'A' >);
|
||||
}
|
||||
|
||||
void on_hours(bool leading_zero)
|
||||
{
|
||||
if (leading_zero)
|
||||
m_formatter.add_formatter(&formatter_type::BOOST_NESTED_TEMPLATE format_hours< '0' >);
|
||||
else
|
||||
m_formatter.add_formatter(&formatter_type::BOOST_NESTED_TEMPLATE format_hours< ' ' >);
|
||||
}
|
||||
|
||||
void on_hours_12(bool leading_zero)
|
||||
{
|
||||
if (leading_zero)
|
||||
m_formatter.add_formatter(&formatter_type::BOOST_NESTED_TEMPLATE format_hours_12< '0' >);
|
||||
else
|
||||
m_formatter.add_formatter(&formatter_type::BOOST_NESTED_TEMPLATE format_hours_12< ' ' >);
|
||||
}
|
||||
|
||||
void on_minutes()
|
||||
{
|
||||
m_formatter.add_formatter(&formatter_type::format_minutes);
|
||||
}
|
||||
|
||||
void on_seconds()
|
||||
{
|
||||
m_formatter.add_formatter(&formatter_type::format_seconds);
|
||||
}
|
||||
|
||||
void on_fractional_seconds()
|
||||
{
|
||||
m_formatter.add_formatter(&formatter_type::format_fractional_seconds);
|
||||
}
|
||||
|
||||
void on_am_pm(bool upper_case)
|
||||
{
|
||||
if (upper_case)
|
||||
m_formatter.add_formatter(&formatter_type::BOOST_NESTED_TEMPLATE format_am_pm< true >);
|
||||
else
|
||||
m_formatter.add_formatter(&formatter_type::BOOST_NESTED_TEMPLATE format_am_pm< false >);
|
||||
}
|
||||
|
||||
void on_duration_sign(bool display_positive)
|
||||
{
|
||||
if (display_positive)
|
||||
m_formatter.add_formatter(&formatter_type::BOOST_NESTED_TEMPLATE format_sign< true >);
|
||||
else
|
||||
m_formatter.add_formatter(&formatter_type::BOOST_NESTED_TEMPLATE format_sign< false >);
|
||||
}
|
||||
|
||||
void on_iso_time_zone()
|
||||
{
|
||||
}
|
||||
|
||||
void on_extended_iso_time_zone()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_DECOMPOSED_TIME_HPP_INCLUDED_
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* 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 deduce_char_type.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 17.11.2012
|
||||
*
|
||||
* \brief This header is the Boost.Log library implementation, see the library documentation
|
||||
* at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_DEDUCE_CHAR_TYPE_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_DEDUCE_CHAR_TYPE_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace aux {
|
||||
|
||||
template< typename T >
|
||||
struct deduced_char_type;
|
||||
|
||||
template< >
|
||||
struct deduced_char_type< char >
|
||||
{
|
||||
typedef char type;
|
||||
};
|
||||
|
||||
template< >
|
||||
struct deduced_char_type< const char >
|
||||
{
|
||||
typedef char type;
|
||||
};
|
||||
|
||||
template< >
|
||||
struct deduced_char_type< wchar_t >
|
||||
{
|
||||
typedef wchar_t type;
|
||||
};
|
||||
|
||||
template< >
|
||||
struct deduced_char_type< const wchar_t >
|
||||
{
|
||||
typedef wchar_t type;
|
||||
};
|
||||
|
||||
//! Auxiliary traits to detect character type from a string
|
||||
template< typename RangeT >
|
||||
struct deduce_char_type :
|
||||
public deduced_char_type< typename RangeT::value_type >
|
||||
{
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
struct deduce_char_type< T* > :
|
||||
public deduced_char_type< T >
|
||||
{
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
struct deduce_char_type< T* const > :
|
||||
public deduced_char_type< T >
|
||||
{
|
||||
};
|
||||
|
||||
template< typename T, unsigned int CountV >
|
||||
struct deduce_char_type< T[CountV] > :
|
||||
public deduced_char_type< T >
|
||||
{
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
struct deduce_char_type< T& > :
|
||||
public deduce_char_type< T >
|
||||
{
|
||||
};
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
|
||||
template< typename T >
|
||||
struct deduce_char_type< T&& > :
|
||||
public deduce_char_type< T >
|
||||
{
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace aux
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_DEDUCE_CHAR_TYPE_HPP_INCLUDED_
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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 default_attribute_names.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 15.01.2012
|
||||
*
|
||||
* \brief This header is the Boost.Log library implementation, see the library documentation
|
||||
* at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_DEFAULT_ATTRIBUTE_NAMES_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_DEFAULT_ATTRIBUTE_NAMES_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/attributes/attribute_name.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace aux {
|
||||
|
||||
namespace default_attribute_names {
|
||||
|
||||
BOOST_LOG_API attribute_name severity();
|
||||
BOOST_LOG_API attribute_name channel();
|
||||
BOOST_LOG_API attribute_name message();
|
||||
BOOST_LOG_API attribute_name line_id();
|
||||
BOOST_LOG_API attribute_name timestamp();
|
||||
BOOST_LOG_API attribute_name process_id();
|
||||
BOOST_LOG_API attribute_name thread_id();
|
||||
|
||||
} // namespace default_attribute_names
|
||||
|
||||
} // namespace aux
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_DEFAULT_ATTRIBUTE_NAMES_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 embedded_string_type.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 16.08.2009
|
||||
*
|
||||
* This header is the Boost.Log library implementation, see the library documentation
|
||||
* at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_EMBEDDED_STRING_TYPE_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_EMBEDDED_STRING_TYPE_HPP_INCLUDED_
|
||||
|
||||
#include <string>
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace aux {
|
||||
|
||||
template< typename T, typename ArgT >
|
||||
struct make_embedded_string_type_impl
|
||||
{
|
||||
typedef ArgT type;
|
||||
};
|
||||
|
||||
template< typename ArgT >
|
||||
struct make_embedded_string_type_impl< char, ArgT >
|
||||
{
|
||||
typedef std::basic_string< char > type;
|
||||
};
|
||||
|
||||
template< typename ArgT >
|
||||
struct make_embedded_string_type_impl< const char, ArgT >
|
||||
{
|
||||
typedef std::basic_string< char > type;
|
||||
};
|
||||
|
||||
template< typename ArgT >
|
||||
struct make_embedded_string_type_impl< wchar_t, ArgT >
|
||||
{
|
||||
typedef std::basic_string< wchar_t > type;
|
||||
};
|
||||
|
||||
template< typename ArgT >
|
||||
struct make_embedded_string_type_impl< const wchar_t, ArgT >
|
||||
{
|
||||
typedef std::basic_string< wchar_t > type;
|
||||
};
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_CHAR16_T)
|
||||
template< typename ArgT >
|
||||
struct make_embedded_string_type_impl< char16_t, ArgT >
|
||||
{
|
||||
typedef std::basic_string< char16_t > type;
|
||||
};
|
||||
|
||||
template< typename ArgT >
|
||||
struct make_embedded_string_type_impl< const char16_t, ArgT >
|
||||
{
|
||||
typedef std::basic_string< char16_t > type;
|
||||
};
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_CHAR32_T)
|
||||
template< typename ArgT >
|
||||
struct make_embedded_string_type_impl< char32_t, ArgT >
|
||||
{
|
||||
typedef std::basic_string< char32_t > type;
|
||||
};
|
||||
|
||||
template< typename ArgT >
|
||||
struct make_embedded_string_type_impl< const char32_t, ArgT >
|
||||
{
|
||||
typedef std::basic_string< char32_t > type;
|
||||
};
|
||||
#endif
|
||||
|
||||
//! An auxiliary type translator to store strings by value in function objects and attribute values
|
||||
template< typename ArgT >
|
||||
struct make_embedded_string_type :
|
||||
public remove_cv< ArgT >
|
||||
{
|
||||
};
|
||||
|
||||
template< typename ArgT >
|
||||
struct make_embedded_string_type< ArgT* > :
|
||||
public make_embedded_string_type_impl< ArgT, ArgT* >
|
||||
{
|
||||
};
|
||||
|
||||
template< typename ArgT, unsigned int CountV >
|
||||
struct make_embedded_string_type< ArgT[CountV] > :
|
||||
public make_embedded_string_type_impl< ArgT, ArgT[CountV] >
|
||||
{
|
||||
};
|
||||
|
||||
template< typename ArgT, unsigned int CountV >
|
||||
struct make_embedded_string_type< ArgT(&)[CountV] > :
|
||||
public make_embedded_string_type_impl< ArgT, ArgT(&)[CountV] >
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_EMBEDDED_STRING_TYPE_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 enqueued_record.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 01.04.2014
|
||||
*
|
||||
* \brief This header is the Boost.Log library implementation, see the library documentation
|
||||
* at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html. In this file
|
||||
* internal configuration macros are defined.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_ENQUEUED_RECORD_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_ENQUEUED_RECORD_HPP_INCLUDED_
|
||||
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/timestamp.hpp>
|
||||
#include <boost/log/core/record_view.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace sinks {
|
||||
|
||||
namespace aux {
|
||||
|
||||
//! Log record with enqueueing timestamp
|
||||
class enqueued_record
|
||||
{
|
||||
BOOST_COPYABLE_AND_MOVABLE(enqueued_record)
|
||||
|
||||
public:
|
||||
//! Ordering predicate
|
||||
template< typename OrderT >
|
||||
struct order :
|
||||
public OrderT
|
||||
{
|
||||
typedef typename OrderT::result_type result_type;
|
||||
|
||||
order() {}
|
||||
order(order const& that) : OrderT(static_cast< OrderT const& >(that)) {}
|
||||
order(OrderT const& that) : OrderT(that) {}
|
||||
|
||||
result_type operator() (enqueued_record const& left, enqueued_record const& right) const
|
||||
{
|
||||
// std::priority_queue requires ordering with semantics of std::greater, so we swap arguments
|
||||
return OrderT::operator() (right.m_record, left.m_record);
|
||||
}
|
||||
};
|
||||
|
||||
boost::log::aux::timestamp m_timestamp;
|
||||
record_view m_record;
|
||||
|
||||
enqueued_record(enqueued_record const& that) : m_timestamp(that.m_timestamp), m_record(that.m_record)
|
||||
{
|
||||
}
|
||||
enqueued_record(BOOST_RV_REF(enqueued_record) that) :
|
||||
m_timestamp(that.m_timestamp),
|
||||
m_record(boost::move(that.m_record))
|
||||
{
|
||||
}
|
||||
explicit enqueued_record(record_view const& rec) :
|
||||
m_timestamp(boost::log::aux::get_timestamp()),
|
||||
m_record(rec)
|
||||
{
|
||||
}
|
||||
enqueued_record& operator= (BOOST_COPY_ASSIGN_REF(enqueued_record) that)
|
||||
{
|
||||
m_timestamp = that.m_timestamp;
|
||||
m_record = that.m_record;
|
||||
return *this;
|
||||
}
|
||||
enqueued_record& operator= (BOOST_RV_REF(enqueued_record) that)
|
||||
{
|
||||
m_timestamp = that.m_timestamp;
|
||||
m_record = boost::move(that.m_record);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
} // namespace sinks
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_ENQUEUED_RECORD_HPP_INCLUDED_
|
||||
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* 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 detail/event.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 24.07.2011
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_EVENT_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_EVENT_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_LOG_NO_THREADS
|
||||
|
||||
#if defined(BOOST_THREAD_PLATFORM_PTHREAD)
|
||||
# include <boost/atomic/capabilities.hpp>
|
||||
# if (defined(linux) || defined(__linux) || defined(__linux__)) && BOOST_ATOMIC_INT_LOCK_FREE == 2
|
||||
# include <boost/atomic/atomic.hpp>
|
||||
# define BOOST_LOG_EVENT_USE_FUTEX
|
||||
# elif defined(_POSIX_SEMAPHORES) && (_POSIX_SEMAPHORES + 0) > 0 && BOOST_ATOMIC_FLAG_LOCK_FREE == 2
|
||||
# include <semaphore.h>
|
||||
# include <boost/cstdint.hpp>
|
||||
# include <boost/atomic/atomic_flag.hpp>
|
||||
# define BOOST_LOG_EVENT_USE_POSIX_SEMAPHORE
|
||||
# endif
|
||||
#elif defined(BOOST_THREAD_PLATFORM_WIN32)
|
||||
# include <boost/cstdint.hpp>
|
||||
# define BOOST_LOG_EVENT_USE_WINAPI
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_LOG_EVENT_USE_POSIX_SEMAPHORE) && !defined(BOOST_LOG_EVENT_USE_WINAPI)
|
||||
# include <boost/thread/mutex.hpp>
|
||||
# include <boost/thread/condition_variable.hpp>
|
||||
# define BOOST_LOG_EVENT_USE_BOOST_CONDITION
|
||||
#endif
|
||||
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace aux {
|
||||
|
||||
#if defined(BOOST_LOG_EVENT_USE_FUTEX)
|
||||
|
||||
class futex_based_event
|
||||
{
|
||||
private:
|
||||
boost::atomic< int > m_state;
|
||||
|
||||
public:
|
||||
//! Default constructor
|
||||
BOOST_LOG_API futex_based_event();
|
||||
//! Destructor
|
||||
BOOST_LOG_API ~futex_based_event();
|
||||
|
||||
//! Waits for the object to become signalled
|
||||
BOOST_LOG_API void wait();
|
||||
//! Sets the object to a signalled state
|
||||
BOOST_LOG_API void set_signalled();
|
||||
|
||||
// Copying prohibited
|
||||
BOOST_DELETED_FUNCTION(futex_based_event(futex_based_event const&))
|
||||
BOOST_DELETED_FUNCTION(futex_based_event& operator= (futex_based_event const&))
|
||||
};
|
||||
|
||||
typedef futex_based_event event;
|
||||
|
||||
#elif defined(BOOST_LOG_EVENT_USE_POSIX_SEMAPHORE)
|
||||
|
||||
class sem_based_event
|
||||
{
|
||||
private:
|
||||
boost::atomic_flag m_state;
|
||||
sem_t m_semaphore;
|
||||
|
||||
public:
|
||||
//! Default constructor
|
||||
BOOST_LOG_API sem_based_event();
|
||||
//! Destructor
|
||||
BOOST_LOG_API ~sem_based_event();
|
||||
|
||||
//! Waits for the object to become signalled
|
||||
BOOST_LOG_API void wait();
|
||||
//! Sets the object to a signalled state
|
||||
BOOST_LOG_API void set_signalled();
|
||||
|
||||
// Copying prohibited
|
||||
BOOST_DELETED_FUNCTION(sem_based_event(sem_based_event const&))
|
||||
BOOST_DELETED_FUNCTION(sem_based_event& operator= (sem_based_event const&))
|
||||
};
|
||||
|
||||
typedef sem_based_event event;
|
||||
|
||||
#elif defined(BOOST_LOG_EVENT_USE_WINAPI)
|
||||
|
||||
class winapi_based_event
|
||||
{
|
||||
private:
|
||||
boost::uint32_t m_state;
|
||||
void* m_event;
|
||||
|
||||
public:
|
||||
//! Default constructor
|
||||
BOOST_LOG_API winapi_based_event();
|
||||
//! Destructor
|
||||
BOOST_LOG_API ~winapi_based_event();
|
||||
|
||||
//! Waits for the object to become signalled
|
||||
BOOST_LOG_API void wait();
|
||||
//! Sets the object to a signalled state
|
||||
BOOST_LOG_API void set_signalled();
|
||||
|
||||
// Copying prohibited
|
||||
BOOST_DELETED_FUNCTION(winapi_based_event(winapi_based_event const&))
|
||||
BOOST_DELETED_FUNCTION(winapi_based_event& operator= (winapi_based_event const&))
|
||||
};
|
||||
|
||||
typedef winapi_based_event event;
|
||||
|
||||
#else
|
||||
|
||||
class generic_event
|
||||
{
|
||||
private:
|
||||
boost::mutex m_mutex;
|
||||
boost::condition_variable m_cond;
|
||||
bool m_state;
|
||||
|
||||
public:
|
||||
//! Default constructor
|
||||
BOOST_LOG_API generic_event();
|
||||
//! Destructor
|
||||
BOOST_LOG_API ~generic_event();
|
||||
|
||||
//! Waits for the object to become signalled
|
||||
BOOST_LOG_API void wait();
|
||||
//! Sets the object to a signalled state
|
||||
BOOST_LOG_API void set_signalled();
|
||||
|
||||
// Copying prohibited
|
||||
BOOST_DELETED_FUNCTION(generic_event(generic_event const&))
|
||||
BOOST_DELETED_FUNCTION(generic_event& operator= (generic_event const&))
|
||||
};
|
||||
|
||||
typedef generic_event event;
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace aux
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_NO_THREADS
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_EVENT_HPP_INCLUDED_
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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 fake_mutex.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 31.07.2011
|
||||
*
|
||||
* \brief This header is the Boost.Log library implementation, see the library documentation
|
||||
* at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_FAKE_MUTEX_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_FAKE_MUTEX_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace aux {
|
||||
|
||||
//! Fake mutex that doesn't do anything. Note: we're not using \c null_mutex from Boost.Thread in order not to introduce false dependencies on Boost.Thread and Boost.Chrono.
|
||||
class fake_mutex
|
||||
{
|
||||
public:
|
||||
BOOST_DEFAULTED_FUNCTION(fake_mutex(), {})
|
||||
void lock() {}
|
||||
bool try_lock() { return true; }
|
||||
template< typename T >
|
||||
bool timed_lock(T const&) { return true; }
|
||||
void unlock() {}
|
||||
|
||||
// Copying prohibited
|
||||
BOOST_DELETED_FUNCTION(fake_mutex(fake_mutex const&))
|
||||
BOOST_DELETED_FUNCTION(fake_mutex& operator=(fake_mutex const&))
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_FAKE_MUTEX_HPP_INCLUDED_
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* 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)
|
||||
*/
|
||||
|
||||
#if !defined(BOOST_LOG_ENABLE_WARNINGS)
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
#pragma warning(pop)
|
||||
|
||||
#elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 406
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
#endif
|
||||
|
||||
#endif // !defined(BOOST_LOG_ENABLE_WARNINGS)
|
||||
|
||||
#include <boost/config/abi_suffix.hpp>
|
||||
@@ -0,0 +1,340 @@
|
||||
/*
|
||||
* 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 format.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 15.11.2012
|
||||
*
|
||||
* \brief This header is the Boost.Log library implementation, see the library documentation
|
||||
* at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_FORMAT_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_FORMAT_HPP_INCLUDED_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <iosfwd>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/unhandled_exception_count.hpp>
|
||||
#include <boost/log/detail/cleanup_scope_guard.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
|
||||
|
||||
namespace aux {
|
||||
|
||||
//! An element (either literal or placeholder) of the format string
|
||||
struct format_element
|
||||
{
|
||||
//! Argument placeholder number or -1 if it's not a placeholder (i.e. a literal)
|
||||
int arg_number;
|
||||
//! If the element describes a constant literal, the starting character and length of the literal
|
||||
unsigned int literal_start_pos, literal_len;
|
||||
|
||||
format_element() : arg_number(0), literal_start_pos(0), literal_len(0)
|
||||
{
|
||||
}
|
||||
|
||||
static format_element literal(unsigned int start_pos, unsigned int len)
|
||||
{
|
||||
format_element el;
|
||||
el.arg_number = -1;
|
||||
el.literal_start_pos = start_pos;
|
||||
el.literal_len = len;
|
||||
return el;
|
||||
}
|
||||
|
||||
static format_element positional_argument(unsigned int arg_n)
|
||||
{
|
||||
format_element el;
|
||||
el.arg_number = arg_n;
|
||||
return el;
|
||||
}
|
||||
};
|
||||
|
||||
//! Parsed format string description
|
||||
template< typename CharT >
|
||||
struct format_description
|
||||
{
|
||||
BOOST_COPYABLE_AND_MOVABLE_ALT(format_description)
|
||||
|
||||
public:
|
||||
//! Character type
|
||||
typedef CharT char_type;
|
||||
//! String type
|
||||
typedef std::basic_string< char_type > string_type;
|
||||
|
||||
//! Array of format element descriptors
|
||||
typedef std::vector< format_element > format_element_list;
|
||||
|
||||
//! Characters of all literal parts of the format string
|
||||
string_type literal_chars;
|
||||
//! Format element descriptors
|
||||
format_element_list format_elements;
|
||||
|
||||
BOOST_DEFAULTED_FUNCTION(format_description(), {})
|
||||
|
||||
format_description(format_description const& that) : literal_chars(that.literal_chars), format_elements(that.format_elements)
|
||||
{
|
||||
}
|
||||
|
||||
format_description(BOOST_RV_REF(format_description) that)
|
||||
{
|
||||
literal_chars.swap(that.literal_chars);
|
||||
format_elements.swap(that.format_elements);
|
||||
}
|
||||
|
||||
format_description& operator= (format_description that)
|
||||
{
|
||||
literal_chars.swap(that.literal_chars);
|
||||
format_elements.swap(that.format_elements);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
//! Parses format string
|
||||
template< typename CharT >
|
||||
BOOST_LOG_API format_description< CharT > parse_format(const CharT* begin, const CharT* end);
|
||||
|
||||
//! Parses format string
|
||||
template< typename CharT >
|
||||
BOOST_FORCEINLINE format_description< CharT > parse_format(const CharT* begin)
|
||||
{
|
||||
return parse_format(begin, begin + std::char_traits< CharT >::length(begin));
|
||||
}
|
||||
|
||||
//! Parses format string
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT >
|
||||
BOOST_FORCEINLINE format_description< CharT > parse_format(std::basic_string< CharT, TraitsT, AllocatorT > const& fmt)
|
||||
{
|
||||
const CharT* begin = fmt.c_str();
|
||||
return parse_format(begin, begin + fmt.size());
|
||||
}
|
||||
|
||||
//! Formatter object
|
||||
template< typename CharT >
|
||||
class basic_format
|
||||
{
|
||||
public:
|
||||
//! Character type
|
||||
typedef CharT char_type;
|
||||
//! String type
|
||||
typedef std::basic_string< char_type > string_type;
|
||||
//! Stream type
|
||||
typedef basic_formatting_ostream< char_type > stream_type;
|
||||
//! Format description type
|
||||
typedef format_description< char_type > format_description_type;
|
||||
|
||||
//! The pump receives arguments and formats them into strings. At destruction the pump composes the final string in the attached stream.
|
||||
class pump;
|
||||
friend class pump;
|
||||
|
||||
private:
|
||||
//! Formatting params for a single placeholder in the format string
|
||||
struct formatting_params
|
||||
{
|
||||
//! Formatting element index in the format description
|
||||
unsigned int element_idx;
|
||||
//! Formatting result
|
||||
string_type target;
|
||||
|
||||
formatting_params() : element_idx(~0u) {}
|
||||
};
|
||||
typedef std::vector< formatting_params > formatting_params_list;
|
||||
|
||||
private:
|
||||
//! Format string description
|
||||
format_description_type m_format;
|
||||
//! Formatting parameters for all placeholders
|
||||
formatting_params_list m_formatting_params;
|
||||
//! Current formatting position
|
||||
unsigned int m_current_idx;
|
||||
|
||||
public:
|
||||
//! Initializing constructor
|
||||
explicit basic_format(string_type const& fmt) : m_format(aux::parse_format(fmt)), m_current_idx(0)
|
||||
{
|
||||
init_params();
|
||||
}
|
||||
//! Initializing constructor
|
||||
explicit basic_format(const char_type* fmt) : m_format(aux::parse_format(fmt)), m_current_idx(0)
|
||||
{
|
||||
init_params();
|
||||
}
|
||||
|
||||
//! Clears all formatted strings and resets the current formatting position
|
||||
void clear() BOOST_NOEXCEPT
|
||||
{
|
||||
for (typename formatting_params_list::iterator it = m_formatting_params.begin(), end = m_formatting_params.end(); it != end; ++it)
|
||||
{
|
||||
it->target.clear();
|
||||
}
|
||||
m_current_idx = 0;
|
||||
}
|
||||
|
||||
//! Creates a pump that will receive all format arguments and put the formatted string into the stream
|
||||
pump make_pump(stream_type& strm)
|
||||
{
|
||||
// Flush the stream beforehand so that the pump can safely switch the stream storage string
|
||||
strm.flush();
|
||||
return pump(*this, strm);
|
||||
}
|
||||
|
||||
//! Composes the final string from the formatted pieces
|
||||
string_type str() const
|
||||
{
|
||||
string_type result;
|
||||
compose(result);
|
||||
return BOOST_LOG_NRVO_RESULT(result);
|
||||
}
|
||||
|
||||
private:
|
||||
//! Initializes the formatting params
|
||||
void init_params()
|
||||
{
|
||||
typename format_description_type::format_element_list::const_iterator it = m_format.format_elements.begin(), end = m_format.format_elements.end();
|
||||
for (; it != end; ++it)
|
||||
{
|
||||
if (it->arg_number >= 0)
|
||||
{
|
||||
if (static_cast< unsigned int >(it->arg_number) >= m_formatting_params.size())
|
||||
m_formatting_params.resize(it->arg_number + 1);
|
||||
m_formatting_params[it->arg_number].element_idx = static_cast< unsigned int >(it - m_format.format_elements.begin());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//! Composes the final string from the formatted pieces
|
||||
template< typename T >
|
||||
void compose(T& str) const
|
||||
{
|
||||
typename format_description_type::format_element_list::const_iterator it = m_format.format_elements.begin(), end = m_format.format_elements.end();
|
||||
for (; it != end; ++it)
|
||||
{
|
||||
if (it->arg_number >= 0)
|
||||
{
|
||||
// This is a placeholder
|
||||
string_type const& target = m_formatting_params[it->arg_number].target;
|
||||
str.append(target.data(), target.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is a literal
|
||||
const char_type* p = m_format.literal_chars.c_str() + it->literal_start_pos;
|
||||
str.append(p, it->literal_len);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//! The pump receives arguments and formats them into strings. At destruction the pump composes the final string in the attached stream.
|
||||
template< typename CharT >
|
||||
class basic_format< CharT >::pump
|
||||
{
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(pump)
|
||||
|
||||
private:
|
||||
//! The guard temporarily replaces storage string in the specified stream
|
||||
struct scoped_storage
|
||||
{
|
||||
scoped_storage(stream_type& strm, string_type& storage) : m_stream(strm), m_storage_state_backup(strm.rdbuf()->get_storage_state())
|
||||
{
|
||||
strm.attach(storage);
|
||||
}
|
||||
~scoped_storage()
|
||||
{
|
||||
m_stream.rdbuf()->set_storage_state(m_storage_state_backup);
|
||||
}
|
||||
|
||||
private:
|
||||
stream_type& m_stream;
|
||||
typename stream_type::streambuf_type::storage_state m_storage_state_backup;
|
||||
};
|
||||
|
||||
private:
|
||||
//! Reference to the owner
|
||||
basic_format* m_owner;
|
||||
//! Reference to the stream
|
||||
stream_type* m_stream;
|
||||
//! Unhandled exception count
|
||||
const unsigned int m_exception_count;
|
||||
|
||||
public:
|
||||
//! Initializing constructor
|
||||
pump(basic_format& owner, stream_type& strm) BOOST_NOEXCEPT : m_owner(&owner), m_stream(&strm), m_exception_count(unhandled_exception_count())
|
||||
{
|
||||
}
|
||||
|
||||
//! Move constructor
|
||||
pump(BOOST_RV_REF(pump) that) BOOST_NOEXCEPT : m_owner(that.m_owner), m_stream(that.m_stream), m_exception_count(that.m_exception_count)
|
||||
{
|
||||
that.m_owner = NULL;
|
||||
that.m_stream = NULL;
|
||||
}
|
||||
|
||||
//! Destructor
|
||||
~pump() BOOST_NOEXCEPT_IF(false)
|
||||
{
|
||||
if (m_owner)
|
||||
{
|
||||
// Whether or not the destructor is called because of an exception, the format object has to be cleared
|
||||
boost::log::aux::cleanup_guard< basic_format< char_type > > cleanup1(*m_owner);
|
||||
|
||||
BOOST_ASSERT(m_stream != NULL);
|
||||
if (m_exception_count >= unhandled_exception_count())
|
||||
{
|
||||
// Compose the final string in the stream buffer
|
||||
m_stream->flush();
|
||||
m_owner->compose(*m_stream->rdbuf());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Puts an argument to the formatter. Note the pump has to be returned by value and not by reference in order this to
|
||||
* work with Boost.Phoenix expressions. Otherwise the pump that is returned from \c basic_format::make_pump is
|
||||
* destroyed after the first call to \c operator%, and the returned reference becomes dangling.
|
||||
*/
|
||||
template< typename T >
|
||||
pump operator% (T const& val)
|
||||
{
|
||||
BOOST_ASSERT_MSG(m_owner != NULL && m_stream != NULL, "Boost.Log: This basic_format::pump has already been moved from");
|
||||
|
||||
if (m_owner->m_current_idx < m_owner->m_formatting_params.size())
|
||||
{
|
||||
scoped_storage storage_guard(*m_stream, m_owner->m_formatting_params[m_owner->m_current_idx].target);
|
||||
|
||||
*m_stream << val;
|
||||
m_stream->flush();
|
||||
|
||||
++m_owner->m_current_idx;
|
||||
}
|
||||
|
||||
return boost::move(*this);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_FORMAT_HPP_INCLUDED_
|
||||
@@ -0,0 +1,236 @@
|
||||
/*
|
||||
* 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 function_traits.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 30.08.2009
|
||||
*
|
||||
* \brief This header is the Boost.Log library implementation, see the library documentation
|
||||
* at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_FUNCTION_TRAITS_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_FUNCTION_TRAITS_HPP_INCLUDED_
|
||||
|
||||
#include <boost/mpl/has_xxx.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
|
||||
#if defined(BOOST_NO_SFINAE) || defined(BOOST_MPL_CFG_NO_HAS_XXX)
|
||||
# if !defined(BOOST_LOG_NO_FUNCTION_TRAITS)
|
||||
# define BOOST_LOG_NO_FUNCTION_TRAITS
|
||||
# endif
|
||||
#else
|
||||
|
||||
#include <boost/mpl/int.hpp>
|
||||
#include <boost/mpl/front.hpp>
|
||||
#include <boost/mpl/pop_front.hpp>
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/function_types/function_arity.hpp>
|
||||
#include <boost/function_types/parameter_types.hpp>
|
||||
#include <boost/function_types/is_nonmember_callable_builtin.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace aux {
|
||||
|
||||
// A number of traits to deal with functors
|
||||
BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_argument_type, argument_type, false)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_first_argument_type, first_argument_type, false)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_second_argument_type, second_argument_type, false)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_arg1_type, arg1_type, false)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_arg2_type, arg2_type, false)
|
||||
|
||||
namespace has_arity_no_adl {
|
||||
|
||||
typedef char yes_type;
|
||||
struct no_type
|
||||
{
|
||||
char dummy[2];
|
||||
};
|
||||
|
||||
template< typename FunT, int ArityV = FunT::arity >
|
||||
struct checker
|
||||
{
|
||||
};
|
||||
|
||||
template< typename FunT >
|
||||
yes_type has_arity_impl(FunT const&, checker< FunT >*);
|
||||
template< typename FunT >
|
||||
no_type has_arity_impl(FunT const&, ...);
|
||||
|
||||
} // namespace has_arity_no_adl
|
||||
|
||||
//! The metafunction detects if the type has an arity static constant member
|
||||
template< typename FunT >
|
||||
struct has_arity
|
||||
{
|
||||
static FunT const& get_FunT();
|
||||
|
||||
enum value_t { value = (sizeof(has_arity_no_adl::has_arity_impl(get_FunT(), 0)) == sizeof(has_arity_no_adl::yes_type)) };
|
||||
typedef mpl::bool_< value > type;
|
||||
};
|
||||
|
||||
//! The metafunction results in an unqualified type with removed reference
|
||||
template< typename T >
|
||||
struct root_type :
|
||||
public remove_cv<
|
||||
typename remove_reference<
|
||||
T
|
||||
>::type
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
template<
|
||||
typename FunT,
|
||||
bool = function_types::is_nonmember_callable_builtin< FunT >::value,
|
||||
bool = has_argument_type< FunT >::value,
|
||||
bool = has_first_argument_type< FunT >::value,
|
||||
bool = has_arg1_type< FunT >::value
|
||||
>
|
||||
struct first_argument_type_of_impl
|
||||
{
|
||||
};
|
||||
template< typename FunT >
|
||||
struct first_argument_type_of_impl< FunT, true, false, false, false >
|
||||
{
|
||||
typedef typename root_type<
|
||||
typename mpl::front<
|
||||
typename function_types::parameter_types< FunT >::type
|
||||
>::type
|
||||
>::type type;
|
||||
};
|
||||
template< typename FunT, bool HasFirstArgumentV, bool HasArg1V >
|
||||
struct first_argument_type_of_impl< FunT, false, true, HasFirstArgumentV, HasArg1V >
|
||||
{
|
||||
typedef typename root_type<
|
||||
typename FunT::argument_type
|
||||
>::type type;
|
||||
};
|
||||
template< typename FunT, bool HasArg1V >
|
||||
struct first_argument_type_of_impl< FunT, false, false, true, HasArg1V >
|
||||
{
|
||||
typedef typename root_type<
|
||||
typename FunT::first_argument_type
|
||||
>::type type;
|
||||
};
|
||||
template< typename FunT >
|
||||
struct first_argument_type_of_impl< FunT, false, false, false, true >
|
||||
{
|
||||
typedef typename root_type<
|
||||
typename FunT::arg1_type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
//! The metafunction returns the first argument type of a function
|
||||
template< typename FunT >
|
||||
struct first_argument_type_of :
|
||||
public first_argument_type_of_impl< FunT >
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
template<
|
||||
typename FunT,
|
||||
bool = function_types::is_nonmember_callable_builtin< FunT >::value,
|
||||
bool = has_second_argument_type< FunT >::value,
|
||||
bool = has_arg2_type< FunT >::value
|
||||
>
|
||||
struct second_argument_type_of_impl
|
||||
{
|
||||
};
|
||||
template< typename FunT >
|
||||
struct second_argument_type_of_impl< FunT, true, false, false >
|
||||
{
|
||||
typedef typename root_type<
|
||||
typename mpl::front<
|
||||
typename mpl::pop_front<
|
||||
typename function_types::parameter_types< FunT >::type
|
||||
>::type
|
||||
>::type
|
||||
>::type type;
|
||||
};
|
||||
template< typename FunT, bool HasArg2V >
|
||||
struct second_argument_type_of_impl< FunT, false, true, HasArg2V >
|
||||
{
|
||||
typedef typename root_type<
|
||||
typename FunT::second_argument_type
|
||||
>::type type;
|
||||
};
|
||||
template< typename FunT >
|
||||
struct second_argument_type_of_impl< FunT, false, false, true >
|
||||
{
|
||||
typedef typename root_type<
|
||||
typename FunT::arg2_type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
//! The metafunction returns the second argument type of a function
|
||||
template< typename FunT >
|
||||
struct second_argument_type_of :
|
||||
public second_argument_type_of_impl< FunT >
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
template<
|
||||
typename FunT,
|
||||
bool = function_types::is_nonmember_callable_builtin< FunT >::value,
|
||||
bool = has_arity< FunT >::value,
|
||||
bool = has_argument_type< FunT >::value,
|
||||
bool = has_second_argument_type< FunT >::value
|
||||
>
|
||||
struct arity_of_impl
|
||||
{
|
||||
};
|
||||
template< typename FunT >
|
||||
struct arity_of_impl< FunT, true, false, false, false > :
|
||||
public function_types::function_arity< FunT >
|
||||
{
|
||||
};
|
||||
template< typename FunT, bool HasArgumentTypeV, bool HasSecondArgumentTypeV >
|
||||
struct arity_of_impl< FunT, false, true, HasArgumentTypeV, HasSecondArgumentTypeV > :
|
||||
public mpl::int_< FunT::arity >
|
||||
{
|
||||
};
|
||||
template< typename FunT, bool HasArgumentTypeV >
|
||||
struct arity_of_impl< FunT, false, false, HasArgumentTypeV, true > :
|
||||
public mpl::int_< 2 >
|
||||
{
|
||||
};
|
||||
template< typename FunT >
|
||||
struct arity_of_impl< FunT, false, false, true, false > :
|
||||
public mpl::int_< 1 >
|
||||
{
|
||||
};
|
||||
|
||||
//! The metafunction returns the arity of a function
|
||||
template< typename FunT >
|
||||
struct arity_of :
|
||||
public arity_of_impl< FunT >
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // defined(BOOST_NO_SFINAE) || defined(BOOST_MPL_CFG_NO_HAS_XXX)
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_FUNCTION_TRAITS_HPP_INCLUDED_
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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)
|
||||
*/
|
||||
|
||||
BOOST_LOG_AUX_OVERLOAD(const&, const&)
|
||||
BOOST_LOG_AUX_OVERLOAD(&, const&)
|
||||
BOOST_LOG_AUX_OVERLOAD(const&, &)
|
||||
BOOST_LOG_AUX_OVERLOAD(&, &)
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
|
||||
BOOST_LOG_AUX_OVERLOAD(const&&, const&&)
|
||||
BOOST_LOG_AUX_OVERLOAD(&&, const&&)
|
||||
BOOST_LOG_AUX_OVERLOAD(const&&, &&)
|
||||
BOOST_LOG_AUX_OVERLOAD(&&, &&)
|
||||
|
||||
BOOST_LOG_AUX_OVERLOAD(const&&, const&)
|
||||
BOOST_LOG_AUX_OVERLOAD(&&, const&)
|
||||
BOOST_LOG_AUX_OVERLOAD(const&&, &)
|
||||
BOOST_LOG_AUX_OVERLOAD(&&, &)
|
||||
|
||||
BOOST_LOG_AUX_OVERLOAD(const&, const&&)
|
||||
BOOST_LOG_AUX_OVERLOAD(&, const&&)
|
||||
BOOST_LOG_AUX_OVERLOAD(const&, &&)
|
||||
BOOST_LOG_AUX_OVERLOAD(&, &&)
|
||||
|
||||
#endif // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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)
|
||||
*/
|
||||
|
||||
#include <boost/config/abi_prefix.hpp>
|
||||
|
||||
#if !defined(BOOST_LOG_ENABLE_WARNINGS)
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
#pragma warning(push, 3)
|
||||
// 'm_A' : class 'A' needs to have dll-interface to be used by clients of class 'B'
|
||||
#pragma warning(disable: 4251)
|
||||
// non dll-interface class 'A' used as base for dll-interface class 'B'
|
||||
#pragma warning(disable: 4275)
|
||||
// switch statement contains 'default' but no 'case' labels
|
||||
#pragma warning(disable: 4065)
|
||||
// 'this' : used in base member initializer list
|
||||
#pragma warning(disable: 4355)
|
||||
// 'int' : forcing value to bool 'true' or 'false' (performance warning)
|
||||
#pragma warning(disable: 4800)
|
||||
// unreferenced formal parameter
|
||||
#pragma warning(disable: 4100)
|
||||
// conditional expression is constant
|
||||
#pragma warning(disable: 4127)
|
||||
// default constructor could not be generated
|
||||
#pragma warning(disable: 4510)
|
||||
// copy constructor could not be generated
|
||||
#pragma warning(disable: 4511)
|
||||
// assignment operator could not be generated
|
||||
#pragma warning(disable: 4512)
|
||||
// struct 'A' can never be instantiated - user defined constructor required
|
||||
#pragma warning(disable: 4610)
|
||||
// function marked as __forceinline not inlined
|
||||
#pragma warning(disable: 4714)
|
||||
// decorated name length exceeded, name was truncated
|
||||
#pragma warning(disable: 4503)
|
||||
// declaration of 'A' hides previous local declaration
|
||||
#pragma warning(disable: 4456)
|
||||
// declaration of 'A' hides global declaration
|
||||
#pragma warning(disable: 4459)
|
||||
// 'X': This function or variable may be unsafe. Consider using Y instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
|
||||
#pragma warning(disable: 4996)
|
||||
|
||||
#elif defined(__GNUC__) && !(defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC)) \
|
||||
&& (__GNUC__ * 100 + __GNUC_MINOR__) >= 406
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
// 'var' defined but not used
|
||||
#pragma GCC diagnostic ignored "-Wunused-variable"
|
||||
// unused parameter 'arg'
|
||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
// missing initializer for member var
|
||||
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
|
||||
|
||||
#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 407
|
||||
// typedef 'foo' locally defined but not used
|
||||
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif // !defined(BOOST_LOG_ENABLE_WARNINGS)
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* 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 id.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 08.01.2012
|
||||
*
|
||||
* \brief This header is the Boost.Log library implementation, see the library documentation
|
||||
* at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_ID_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_ID_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace aux {
|
||||
|
||||
//! Generic identifier class
|
||||
template< typename DescriptorT >
|
||||
class id
|
||||
{
|
||||
public:
|
||||
//! Native type of the process id
|
||||
typedef typename DescriptorT::native_type native_type;
|
||||
|
||||
private:
|
||||
native_type m_NativeID;
|
||||
|
||||
public:
|
||||
BOOST_CONSTEXPR id() BOOST_NOEXCEPT : m_NativeID(0) {}
|
||||
|
||||
explicit id(native_type native) BOOST_NOEXCEPT : m_NativeID(native) {}
|
||||
|
||||
native_type native_id() const BOOST_NOEXCEPT { return m_NativeID; }
|
||||
|
||||
bool operator== (id const& that) const BOOST_NOEXCEPT
|
||||
{
|
||||
return (m_NativeID == that.m_NativeID);
|
||||
}
|
||||
bool operator!= (id const& that) const BOOST_NOEXCEPT
|
||||
{
|
||||
return (m_NativeID != that.m_NativeID);
|
||||
}
|
||||
bool operator< (id const& that) const BOOST_NOEXCEPT
|
||||
{
|
||||
return (m_NativeID < that.m_NativeID);
|
||||
}
|
||||
bool operator> (id const& that) const BOOST_NOEXCEPT
|
||||
{
|
||||
return (m_NativeID > that.m_NativeID);
|
||||
}
|
||||
bool operator<= (id const& that) const BOOST_NOEXCEPT
|
||||
{
|
||||
return (m_NativeID <= that.m_NativeID);
|
||||
}
|
||||
bool operator>= (id const& that) const BOOST_NOEXCEPT
|
||||
{
|
||||
return (m_NativeID >= that.m_NativeID);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_ID_HPP_INCLUDED_
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* 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 is_character_type.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 25.07.2015
|
||||
*
|
||||
* The header defines \c is_character_type trait which checks if the type is one of the character types
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_IS_CHARACTER_TYPE_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_IS_CHARACTER_TYPE_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace aux {
|
||||
|
||||
template< typename T >
|
||||
struct is_character_type
|
||||
{
|
||||
static BOOST_CONSTEXPR_OR_CONST bool value = false;
|
||||
};
|
||||
|
||||
template< >
|
||||
struct is_character_type< char >
|
||||
{
|
||||
static BOOST_CONSTEXPR_OR_CONST bool value = true;
|
||||
};
|
||||
|
||||
template< >
|
||||
struct is_character_type< wchar_t >
|
||||
{
|
||||
static BOOST_CONSTEXPR_OR_CONST bool value = true;
|
||||
};
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_CHAR16_T)
|
||||
template< >
|
||||
struct is_character_type< char16_t >
|
||||
{
|
||||
static BOOST_CONSTEXPR_OR_CONST bool value = true;
|
||||
};
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_CHAR32_T)
|
||||
template< >
|
||||
struct is_character_type< char32_t >
|
||||
{
|
||||
static BOOST_CONSTEXPR_OR_CONST bool value = true;
|
||||
};
|
||||
#endif
|
||||
|
||||
} // namespace aux
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_IS_CHARACTER_TYPE_HPP_INCLUDED_
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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 is_ostream.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 05.07.2015
|
||||
*
|
||||
* \brief This header is the Boost.Log library implementation, see the library documentation
|
||||
* at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html. In this file
|
||||
* internal configuration macros are defined.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_IS_OSTREAM_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_IS_OSTREAM_HPP_INCLUDED_
|
||||
|
||||
#include <iosfwd>
|
||||
#include <boost/type_traits/is_base_of.hpp>
|
||||
#include <boost/type_traits/has_left_shift.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/utility/formatting_ostream_fwd.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace aux {
|
||||
|
||||
template< typename T >
|
||||
struct is_ostream
|
||||
{
|
||||
static BOOST_CONSTEXPR_OR_CONST bool value = is_base_of< std::ios_base, T >::value && has_left_shift< T, int >::value;
|
||||
};
|
||||
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT >
|
||||
struct is_ostream< basic_formatting_ostream< CharT, TraitsT, AllocatorT > >
|
||||
{
|
||||
static BOOST_CONSTEXPR_OR_CONST bool value = true;
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_IS_OSTREAM_HPP_INCLUDED_
|
||||
@@ -0,0 +1,521 @@
|
||||
/*
|
||||
* 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 light_function.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 20.06.2010
|
||||
*
|
||||
* \brief This header is the Boost.Log library impl, see the library documentation
|
||||
* at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
|
||||
*
|
||||
* The file contains a lightweight alternative of Boost.Function. It does not provide all
|
||||
* features of Boost.Function but doesn't introduce dependency on Boost.Bind.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_LIGHT_FUNCTION_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_LIGHT_FUNCTION_HPP_INCLUDED_
|
||||
|
||||
#include <cstddef>
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/utility/explicit_operator_bool.hpp>
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
#include <boost/preprocessor/iteration/iterate.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
|
||||
#endif
|
||||
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
#include <boost/log/detail/sfinae_tools.hpp>
|
||||
#else
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#endif
|
||||
#if defined(BOOST_NO_CXX11_NULLPTR)
|
||||
#include <boost/assert.hpp>
|
||||
#endif
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_LOG_LIGHT_FUNCTION_LIMIT
|
||||
#define BOOST_LOG_LIGHT_FUNCTION_LIMIT 2
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace aux {
|
||||
|
||||
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
|
||||
template< typename T, typename ThisT >
|
||||
struct is_cv_same { enum _ { value = false }; };
|
||||
template< typename T >
|
||||
struct is_cv_same< T, T > { enum _ { value = true }; };
|
||||
template< typename T >
|
||||
struct is_cv_same< T, const T > { enum _ { value = true }; };
|
||||
template< typename T >
|
||||
struct is_cv_same< T, volatile T > { enum _ { value = true }; };
|
||||
template< typename T >
|
||||
struct is_cv_same< T, const volatile T > { enum _ { value = true }; };
|
||||
|
||||
template< typename T, typename ThisT >
|
||||
struct is_rv_or_same { enum _ { value = false }; };
|
||||
template< typename T >
|
||||
struct is_rv_or_same< T, T > { enum _ { value = true }; };
|
||||
template< typename T, typename ThisT >
|
||||
struct is_rv_or_same< boost::rv< T >, ThisT > { enum _ { value = true }; };
|
||||
|
||||
#endif
|
||||
|
||||
template< typename SignatureT >
|
||||
class light_function;
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
template< typename ResultT, typename... ArgsT >
|
||||
class light_function< ResultT (ArgsT...) >
|
||||
{
|
||||
typedef light_function this_type;
|
||||
BOOST_COPYABLE_AND_MOVABLE(this_type)
|
||||
|
||||
public:
|
||||
typedef ResultT result_type;
|
||||
|
||||
private:
|
||||
struct impl_base
|
||||
{
|
||||
typedef result_type (*invoke_type)(void*, ArgsT...);
|
||||
const invoke_type invoke;
|
||||
|
||||
typedef impl_base* (*clone_type)(const void*);
|
||||
const clone_type clone;
|
||||
|
||||
typedef void (*destroy_type)(void*);
|
||||
const destroy_type destroy;
|
||||
|
||||
impl_base(invoke_type inv, clone_type cl, destroy_type dstr) : invoke(inv), clone(cl), destroy(dstr)
|
||||
{
|
||||
}
|
||||
|
||||
BOOST_DELETED_FUNCTION(impl_base(impl_base const&))
|
||||
BOOST_DELETED_FUNCTION(impl_base& operator= (impl_base const&))
|
||||
};
|
||||
|
||||
#if !defined(BOOST_LOG_NO_MEMBER_TEMPLATE_FRIENDS)
|
||||
template< typename FunT >
|
||||
class impl;
|
||||
template< typename FunT >
|
||||
friend class impl;
|
||||
#endif
|
||||
|
||||
template< typename FunT >
|
||||
class impl :
|
||||
public impl_base
|
||||
{
|
||||
typedef impl< FunT > this_type;
|
||||
|
||||
FunT m_Function;
|
||||
|
||||
public:
|
||||
explicit impl(FunT const& fun) :
|
||||
impl_base(&this_type::invoke_impl, &this_type::clone_impl, &this_type::destroy_impl),
|
||||
m_Function(fun)
|
||||
{
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
explicit impl(FunT&& fun) :
|
||||
impl_base(&this_type::invoke_impl, &this_type::clone_impl, &this_type::destroy_impl),
|
||||
m_Function(boost::move(fun))
|
||||
{
|
||||
}
|
||||
#endif // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
|
||||
static void destroy_impl(void* self)
|
||||
{
|
||||
delete static_cast< impl* >(static_cast< impl_base* >(self));
|
||||
}
|
||||
static impl_base* clone_impl(const void* self)
|
||||
{
|
||||
return new impl(static_cast< const impl* >(static_cast< const impl_base* >(self))->m_Function);
|
||||
}
|
||||
static result_type invoke_impl(void* self, ArgsT... args)
|
||||
{
|
||||
return static_cast< impl* >(static_cast< impl_base* >(self))->m_Function(args...);
|
||||
}
|
||||
|
||||
BOOST_DELETED_FUNCTION(impl(impl const&))
|
||||
BOOST_DELETED_FUNCTION(impl& operator= (impl const&))
|
||||
};
|
||||
|
||||
private:
|
||||
impl_base* m_pImpl;
|
||||
|
||||
public:
|
||||
BOOST_CONSTEXPR light_function() BOOST_NOEXCEPT : m_pImpl(NULL)
|
||||
{
|
||||
}
|
||||
light_function(this_type const& that)
|
||||
{
|
||||
if (that.m_pImpl)
|
||||
m_pImpl = that.m_pImpl->clone(that.m_pImpl);
|
||||
else
|
||||
m_pImpl = NULL;
|
||||
}
|
||||
|
||||
light_function(BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT
|
||||
{
|
||||
m_pImpl = that.m_pImpl;
|
||||
that.m_pImpl = NULL;
|
||||
}
|
||||
|
||||
light_function(BOOST_RV_REF(const this_type) that) BOOST_NOEXCEPT
|
||||
{
|
||||
m_pImpl = that.m_pImpl;
|
||||
((this_type&)that).m_pImpl = NULL;
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
template< typename FunT >
|
||||
light_function(FunT&& fun) :
|
||||
m_pImpl(new impl< typename remove_cv< typename remove_reference< FunT >::type >::type >(boost::forward< FunT >(fun)))
|
||||
{
|
||||
}
|
||||
#else
|
||||
template< typename FunT >
|
||||
light_function(FunT const& fun, typename boost::disable_if_c< is_rv_or_same< FunT, this_type >::value, boost::log::aux::sfinae_dummy >::type = boost::log::aux::sfinae_dummy()) :
|
||||
m_pImpl(new impl< FunT >(fun))
|
||||
{
|
||||
}
|
||||
template< typename FunT >
|
||||
light_function(BOOST_RV_REF(FunT) fun, typename boost::disable_if_c< is_cv_same< FunT, this_type >::value, boost::log::aux::sfinae_dummy >::type = boost::log::aux::sfinae_dummy()) :
|
||||
m_pImpl(new impl< typename remove_cv< FunT >::type >(fun))
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
//! Constructor from NULL
|
||||
#if !defined(BOOST_NO_CXX11_NULLPTR)
|
||||
BOOST_CONSTEXPR light_function(std::nullptr_t) BOOST_NOEXCEPT
|
||||
#else
|
||||
BOOST_CONSTEXPR light_function(int p) BOOST_NOEXCEPT
|
||||
#endif
|
||||
: m_pImpl(NULL)
|
||||
{
|
||||
#if defined(BOOST_NO_CXX11_NULLPTR)
|
||||
BOOST_ASSERT(p == 0);
|
||||
#endif
|
||||
}
|
||||
~light_function()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
light_function& operator= (BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT
|
||||
{
|
||||
this->swap(that);
|
||||
return *this;
|
||||
}
|
||||
light_function& operator= (BOOST_COPY_ASSIGN_REF(this_type) that)
|
||||
{
|
||||
light_function tmp = static_cast< this_type const& >(that);
|
||||
this->swap(tmp);
|
||||
return *this;
|
||||
}
|
||||
//! Assignment of NULL
|
||||
#if !defined(BOOST_NO_CXX11_NULLPTR)
|
||||
light_function& operator= (std::nullptr_t)
|
||||
#else
|
||||
light_function& operator= (int p)
|
||||
#endif
|
||||
{
|
||||
#if defined(BOOST_NO_CXX11_NULLPTR)
|
||||
BOOST_ASSERT(p == 0);
|
||||
#endif
|
||||
clear();
|
||||
return *this;
|
||||
}
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
template< typename FunT >
|
||||
light_function& operator= (FunT&& fun)
|
||||
{
|
||||
light_function tmp(boost::forward< FunT >(fun));
|
||||
this->swap(tmp);
|
||||
return *this;
|
||||
}
|
||||
#else
|
||||
template< typename FunT >
|
||||
typename boost::disable_if_c< is_rv_or_same< FunT, this_type >::value, this_type& >::type
|
||||
operator= (FunT const& fun)
|
||||
{
|
||||
light_function tmp(fun);
|
||||
this->swap(tmp);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
result_type operator() (ArgsT... args) const
|
||||
{
|
||||
return m_pImpl->invoke(m_pImpl, args...);
|
||||
}
|
||||
|
||||
BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
|
||||
bool operator! () const BOOST_NOEXCEPT { return (m_pImpl == NULL); }
|
||||
bool empty() const BOOST_NOEXCEPT { return (m_pImpl == NULL); }
|
||||
void clear() BOOST_NOEXCEPT
|
||||
{
|
||||
if (m_pImpl)
|
||||
{
|
||||
m_pImpl->destroy(m_pImpl);
|
||||
m_pImpl = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void swap(this_type& that) BOOST_NOEXCEPT
|
||||
{
|
||||
impl_base* p = m_pImpl;
|
||||
m_pImpl = that.m_pImpl;
|
||||
that.m_pImpl = p;
|
||||
}
|
||||
};
|
||||
|
||||
template< typename... ArgsT >
|
||||
class light_function< void (ArgsT...) >
|
||||
{
|
||||
typedef light_function this_type;
|
||||
BOOST_COPYABLE_AND_MOVABLE(this_type)
|
||||
|
||||
public:
|
||||
typedef void result_type;
|
||||
|
||||
private:
|
||||
struct impl_base
|
||||
{
|
||||
typedef void (*invoke_type)(void*, ArgsT...);
|
||||
const invoke_type invoke;
|
||||
|
||||
typedef impl_base* (*clone_type)(const void*);
|
||||
const clone_type clone;
|
||||
|
||||
typedef void (*destroy_type)(void*);
|
||||
const destroy_type destroy;
|
||||
|
||||
impl_base(invoke_type inv, clone_type cl, destroy_type dstr) : invoke(inv), clone(cl), destroy(dstr)
|
||||
{
|
||||
}
|
||||
|
||||
BOOST_DELETED_FUNCTION(impl_base(impl_base const&))
|
||||
BOOST_DELETED_FUNCTION(impl_base& operator= (impl_base const&))
|
||||
};
|
||||
|
||||
#if !defined(BOOST_LOG_NO_MEMBER_TEMPLATE_FRIENDS)
|
||||
template< typename FunT >
|
||||
class impl;
|
||||
template< typename FunT >
|
||||
friend class impl;
|
||||
#endif
|
||||
|
||||
template< typename FunT >
|
||||
class impl :
|
||||
public impl_base
|
||||
{
|
||||
typedef impl< FunT > this_type;
|
||||
|
||||
FunT m_Function;
|
||||
|
||||
public:
|
||||
explicit impl(FunT const& fun) :
|
||||
impl_base(&this_type::invoke_impl, &this_type::clone_impl, &this_type::destroy_impl),
|
||||
m_Function(fun)
|
||||
{
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
explicit impl(FunT&& fun) :
|
||||
impl_base(&this_type::invoke_impl, &this_type::clone_impl, &this_type::destroy_impl),
|
||||
m_Function(boost::move(fun))
|
||||
{
|
||||
}
|
||||
#endif // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
|
||||
static void destroy_impl(void* self)
|
||||
{
|
||||
delete static_cast< impl* >(static_cast< impl_base* >(self));
|
||||
}
|
||||
static impl_base* clone_impl(const void* self)
|
||||
{
|
||||
return new impl(static_cast< const impl* >(static_cast< const impl_base* >(self))->m_Function);
|
||||
}
|
||||
static result_type invoke_impl(void* self, ArgsT... args)
|
||||
{
|
||||
static_cast< impl* >(static_cast< impl_base* >(self))->m_Function(args...);
|
||||
}
|
||||
|
||||
BOOST_DELETED_FUNCTION(impl(impl const&))
|
||||
BOOST_DELETED_FUNCTION(impl& operator= (impl const&))
|
||||
};
|
||||
|
||||
private:
|
||||
impl_base* m_pImpl;
|
||||
|
||||
public:
|
||||
BOOST_CONSTEXPR light_function() BOOST_NOEXCEPT : m_pImpl(NULL)
|
||||
{
|
||||
}
|
||||
light_function(this_type const& that)
|
||||
{
|
||||
if (that.m_pImpl)
|
||||
m_pImpl = that.m_pImpl->clone(that.m_pImpl);
|
||||
else
|
||||
m_pImpl = NULL;
|
||||
}
|
||||
light_function(BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT
|
||||
{
|
||||
m_pImpl = that.m_pImpl;
|
||||
that.m_pImpl = NULL;
|
||||
}
|
||||
|
||||
light_function(BOOST_RV_REF(const this_type) that) BOOST_NOEXCEPT
|
||||
{
|
||||
m_pImpl = that.m_pImpl;
|
||||
((this_type&)that).m_pImpl = NULL;
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
template< typename FunT >
|
||||
light_function(FunT&& fun) :
|
||||
m_pImpl(new impl< typename remove_cv< typename remove_reference< FunT >::type >::type >(boost::forward< FunT >(fun)))
|
||||
{
|
||||
}
|
||||
#else
|
||||
template< typename FunT >
|
||||
light_function(FunT const& fun, typename boost::disable_if_c< is_rv_or_same< FunT, this_type >::value, boost::log::aux::sfinae_dummy >::type = boost::log::aux::sfinae_dummy()) :
|
||||
m_pImpl(new impl< FunT >(fun))
|
||||
{
|
||||
}
|
||||
template< typename FunT >
|
||||
light_function(BOOST_RV_REF(FunT) fun, typename boost::disable_if_c< is_cv_same< FunT, this_type >::value, boost::log::aux::sfinae_dummy >::type = boost::log::aux::sfinae_dummy()) :
|
||||
m_pImpl(new impl< typename remove_cv< FunT >::type >(fun))
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
//! Constructor from NULL
|
||||
#if !defined(BOOST_NO_CXX11_NULLPTR)
|
||||
BOOST_CONSTEXPR light_function(std::nullptr_t) BOOST_NOEXCEPT
|
||||
#else
|
||||
BOOST_CONSTEXPR light_function(int p) BOOST_NOEXCEPT
|
||||
#endif
|
||||
: m_pImpl(NULL)
|
||||
{
|
||||
#if defined(BOOST_NO_CXX11_NULLPTR)
|
||||
BOOST_ASSERT(p == 0);
|
||||
#endif
|
||||
}
|
||||
~light_function()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
light_function& operator= (BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT
|
||||
{
|
||||
this->swap(that);
|
||||
return *this;
|
||||
}
|
||||
light_function& operator= (BOOST_COPY_ASSIGN_REF(this_type) that)
|
||||
{
|
||||
light_function tmp = static_cast< this_type const& >(that);
|
||||
this->swap(tmp);
|
||||
return *this;
|
||||
}
|
||||
//! Assignment of NULL
|
||||
#if !defined(BOOST_NO_CXX11_NULLPTR)
|
||||
light_function& operator= (std::nullptr_t)
|
||||
#else
|
||||
light_function& operator= (int p)
|
||||
#endif
|
||||
{
|
||||
#if defined(BOOST_NO_CXX11_NULLPTR)
|
||||
BOOST_ASSERT(p == 0);
|
||||
#endif
|
||||
clear();
|
||||
return *this;
|
||||
}
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
template< typename FunT >
|
||||
light_function& operator= (FunT&& fun)
|
||||
{
|
||||
light_function tmp(boost::forward< FunT >(fun));
|
||||
this->swap(tmp);
|
||||
return *this;
|
||||
}
|
||||
#else
|
||||
template< typename FunT >
|
||||
typename boost::disable_if_c< is_rv_or_same< FunT, this_type >::value, this_type& >::type
|
||||
operator= (FunT const& fun)
|
||||
{
|
||||
light_function tmp(fun);
|
||||
this->swap(tmp);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
result_type operator() (ArgsT... args) const
|
||||
{
|
||||
m_pImpl->invoke(m_pImpl, args...);
|
||||
}
|
||||
|
||||
BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
|
||||
bool operator! () const BOOST_NOEXCEPT { return (m_pImpl == NULL); }
|
||||
bool empty() const BOOST_NOEXCEPT { return (m_pImpl == NULL); }
|
||||
void clear() BOOST_NOEXCEPT
|
||||
{
|
||||
if (m_pImpl)
|
||||
{
|
||||
m_pImpl->destroy(m_pImpl);
|
||||
m_pImpl = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void swap(this_type& that) BOOST_NOEXCEPT
|
||||
{
|
||||
impl_base* p = m_pImpl;
|
||||
m_pImpl = that.m_pImpl;
|
||||
that.m_pImpl = p;
|
||||
}
|
||||
};
|
||||
|
||||
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
#define BOOST_PP_FILENAME_1 <boost/log/detail/light_function_pp.hpp>
|
||||
#define BOOST_PP_ITERATION_LIMITS (0, BOOST_LOG_LIGHT_FUNCTION_LIMIT)
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
template< typename SignatureT >
|
||||
inline void swap(light_function< SignatureT >& left, light_function< SignatureT >& right)
|
||||
{
|
||||
left.swap(right);
|
||||
}
|
||||
|
||||
} // namespace aux
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_LIGHT_FUNCTION_HPP_INCLUDED_
|
||||
@@ -0,0 +1,424 @@
|
||||
/*
|
||||
* 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)
|
||||
*/
|
||||
|
||||
template<
|
||||
typename ResultT
|
||||
BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), typename ArgT)
|
||||
>
|
||||
class light_function< ResultT (BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), ArgT)) >
|
||||
{
|
||||
typedef light_function this_type;
|
||||
BOOST_COPYABLE_AND_MOVABLE(this_type)
|
||||
|
||||
public:
|
||||
typedef ResultT result_type;
|
||||
|
||||
private:
|
||||
struct impl_base
|
||||
{
|
||||
typedef result_type (*invoke_type)(void* BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), ArgT));
|
||||
const invoke_type invoke;
|
||||
|
||||
typedef impl_base* (*clone_type)(const void*);
|
||||
const clone_type clone;
|
||||
|
||||
typedef void (*destroy_type)(void*);
|
||||
const destroy_type destroy;
|
||||
|
||||
impl_base(invoke_type inv, clone_type cl, destroy_type dstr) : invoke(inv), clone(cl), destroy(dstr)
|
||||
{
|
||||
}
|
||||
|
||||
BOOST_DELETED_FUNCTION(impl_base(impl_base const&))
|
||||
BOOST_DELETED_FUNCTION(impl_base& operator= (impl_base const&))
|
||||
};
|
||||
|
||||
#if !defined(BOOST_LOG_NO_MEMBER_TEMPLATE_FRIENDS)
|
||||
template< typename FunT >
|
||||
class impl;
|
||||
template< typename FunT >
|
||||
friend class impl;
|
||||
#endif
|
||||
|
||||
template< typename FunT >
|
||||
class impl :
|
||||
public impl_base
|
||||
{
|
||||
typedef impl< FunT > this_type;
|
||||
|
||||
FunT m_Function;
|
||||
|
||||
public:
|
||||
explicit impl(FunT const& fun) :
|
||||
impl_base(&this_type::invoke_impl, &this_type::clone_impl, &this_type::destroy_impl),
|
||||
m_Function(fun)
|
||||
{
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
explicit impl(FunT&& fun) :
|
||||
impl_base(&this_type::invoke_impl, &this_type::clone_impl, &this_type::destroy_impl),
|
||||
m_Function(boost::move(fun))
|
||||
{
|
||||
}
|
||||
#endif // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
|
||||
static void destroy_impl(void* self)
|
||||
{
|
||||
delete static_cast< impl* >(static_cast< impl_base* >(self));
|
||||
}
|
||||
static impl_base* clone_impl(const void* self)
|
||||
{
|
||||
return new impl(static_cast< const impl* >(static_cast< const impl_base* >(self))->m_Function);
|
||||
}
|
||||
static result_type invoke_impl(void* self BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(BOOST_PP_ITERATION(), ArgT, arg))
|
||||
{
|
||||
return static_cast< impl* >(static_cast< impl_base* >(self))->m_Function(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), arg));
|
||||
}
|
||||
|
||||
BOOST_DELETED_FUNCTION(impl(impl const&))
|
||||
BOOST_DELETED_FUNCTION(impl& operator= (impl const&))
|
||||
};
|
||||
|
||||
private:
|
||||
impl_base* m_pImpl;
|
||||
|
||||
public:
|
||||
BOOST_CONSTEXPR light_function() BOOST_NOEXCEPT : m_pImpl(NULL)
|
||||
{
|
||||
}
|
||||
light_function(this_type const& that)
|
||||
{
|
||||
if (that.m_pImpl)
|
||||
m_pImpl = that.m_pImpl->clone(that.m_pImpl);
|
||||
else
|
||||
m_pImpl = NULL;
|
||||
}
|
||||
|
||||
light_function(BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT
|
||||
{
|
||||
m_pImpl = that.m_pImpl;
|
||||
that.m_pImpl = NULL;
|
||||
}
|
||||
|
||||
light_function(BOOST_RV_REF(const this_type) that) BOOST_NOEXCEPT
|
||||
{
|
||||
m_pImpl = that.m_pImpl;
|
||||
((this_type&)that).m_pImpl = NULL;
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
template< typename FunT >
|
||||
light_function(FunT&& fun) :
|
||||
m_pImpl(new impl< typename remove_cv< typename remove_reference< FunT >::type >::type >(boost::forward< FunT >(fun)))
|
||||
{
|
||||
}
|
||||
#else
|
||||
template< typename FunT >
|
||||
light_function(FunT const& fun, typename boost::disable_if_c< is_rv_or_same< FunT, this_type >::value, boost::log::aux::sfinae_dummy >::type = boost::log::aux::sfinae_dummy()) :
|
||||
m_pImpl(new impl< FunT >(fun))
|
||||
{
|
||||
}
|
||||
template< typename FunT >
|
||||
light_function(BOOST_RV_REF(FunT) fun, typename boost::disable_if_c< is_cv_same< FunT, this_type >::value, boost::log::aux::sfinae_dummy >::type = boost::log::aux::sfinae_dummy()) :
|
||||
m_pImpl(new impl< typename remove_cv< FunT >::type >(fun))
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
//! Constructor from NULL
|
||||
#if !defined(BOOST_NO_CXX11_NULLPTR)
|
||||
BOOST_CONSTEXPR light_function(std::nullptr_t) BOOST_NOEXCEPT
|
||||
#else
|
||||
BOOST_CONSTEXPR light_function(int p) BOOST_NOEXCEPT
|
||||
#endif
|
||||
: m_pImpl(NULL)
|
||||
{
|
||||
#if defined(BOOST_NO_CXX11_NULLPTR)
|
||||
BOOST_ASSERT(p == 0);
|
||||
#endif
|
||||
}
|
||||
~light_function()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
light_function& operator= (BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT
|
||||
{
|
||||
this->swap(that);
|
||||
return *this;
|
||||
}
|
||||
light_function& operator= (BOOST_COPY_ASSIGN_REF(this_type) that)
|
||||
{
|
||||
light_function tmp = static_cast< this_type const& >(that);
|
||||
this->swap(tmp);
|
||||
return *this;
|
||||
}
|
||||
//! Assignment of NULL
|
||||
#if !defined(BOOST_NO_CXX11_NULLPTR)
|
||||
light_function& operator= (std::nullptr_t)
|
||||
#else
|
||||
light_function& operator= (int p)
|
||||
#endif
|
||||
{
|
||||
#if defined(BOOST_NO_CXX11_NULLPTR)
|
||||
BOOST_ASSERT(p == 0);
|
||||
#endif
|
||||
clear();
|
||||
return *this;
|
||||
}
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
template< typename FunT >
|
||||
light_function& operator= (FunT&& fun)
|
||||
{
|
||||
light_function tmp(boost::forward< FunT >(fun));
|
||||
this->swap(tmp);
|
||||
return *this;
|
||||
}
|
||||
#else
|
||||
template< typename FunT >
|
||||
typename boost::disable_if_c< is_rv_or_same< FunT, this_type >::value, this_type& >::type
|
||||
operator= (FunT const& fun)
|
||||
{
|
||||
light_function tmp(fun);
|
||||
this->swap(tmp);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
result_type operator() (BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), ArgT, arg)) const
|
||||
{
|
||||
return m_pImpl->invoke(m_pImpl BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), arg));
|
||||
}
|
||||
|
||||
BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
|
||||
bool operator! () const BOOST_NOEXCEPT { return (m_pImpl == NULL); }
|
||||
bool empty() const BOOST_NOEXCEPT { return (m_pImpl == NULL); }
|
||||
void clear() BOOST_NOEXCEPT
|
||||
{
|
||||
if (m_pImpl)
|
||||
{
|
||||
m_pImpl->destroy(m_pImpl);
|
||||
m_pImpl = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void swap(this_type& that) BOOST_NOEXCEPT
|
||||
{
|
||||
impl_base* p = m_pImpl;
|
||||
m_pImpl = that.m_pImpl;
|
||||
that.m_pImpl = p;
|
||||
}
|
||||
};
|
||||
|
||||
template<
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), typename ArgT)
|
||||
>
|
||||
class light_function< void (BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), ArgT)) >
|
||||
{
|
||||
typedef light_function this_type;
|
||||
BOOST_COPYABLE_AND_MOVABLE(this_type)
|
||||
|
||||
public:
|
||||
typedef void result_type;
|
||||
|
||||
private:
|
||||
struct impl_base
|
||||
{
|
||||
typedef void (*invoke_type)(void* BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), ArgT));
|
||||
const invoke_type invoke;
|
||||
|
||||
typedef impl_base* (*clone_type)(const void*);
|
||||
const clone_type clone;
|
||||
|
||||
typedef void (*destroy_type)(void*);
|
||||
const destroy_type destroy;
|
||||
|
||||
impl_base(invoke_type inv, clone_type cl, destroy_type dstr) : invoke(inv), clone(cl), destroy(dstr)
|
||||
{
|
||||
}
|
||||
|
||||
BOOST_DELETED_FUNCTION(impl_base(impl_base const&))
|
||||
BOOST_DELETED_FUNCTION(impl_base& operator= (impl_base const&))
|
||||
};
|
||||
|
||||
#if !defined(BOOST_LOG_NO_MEMBER_TEMPLATE_FRIENDS)
|
||||
template< typename FunT >
|
||||
class impl;
|
||||
template< typename FunT >
|
||||
friend class impl;
|
||||
#endif
|
||||
|
||||
template< typename FunT >
|
||||
class impl :
|
||||
public impl_base
|
||||
{
|
||||
typedef impl< FunT > this_type;
|
||||
|
||||
FunT m_Function;
|
||||
|
||||
public:
|
||||
explicit impl(FunT const& fun) :
|
||||
impl_base(&this_type::invoke_impl, &this_type::clone_impl, &this_type::destroy_impl),
|
||||
m_Function(fun)
|
||||
{
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
explicit impl(FunT&& fun) :
|
||||
impl_base(&this_type::invoke_impl, &this_type::clone_impl, &this_type::destroy_impl),
|
||||
m_Function(boost::move(fun))
|
||||
{
|
||||
}
|
||||
#endif // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
|
||||
static void destroy_impl(void* self)
|
||||
{
|
||||
delete static_cast< impl* >(static_cast< impl_base* >(self));
|
||||
}
|
||||
static impl_base* clone_impl(const void* self)
|
||||
{
|
||||
return new impl(static_cast< const impl* >(static_cast< const impl_base* >(self))->m_Function);
|
||||
}
|
||||
static result_type invoke_impl(void* self BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(BOOST_PP_ITERATION(), ArgT, arg))
|
||||
{
|
||||
static_cast< impl* >(static_cast< impl_base* >(self))->m_Function(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), arg));
|
||||
}
|
||||
|
||||
BOOST_DELETED_FUNCTION(impl(impl const&))
|
||||
BOOST_DELETED_FUNCTION(impl& operator= (impl const&))
|
||||
};
|
||||
|
||||
private:
|
||||
impl_base* m_pImpl;
|
||||
|
||||
public:
|
||||
BOOST_CONSTEXPR light_function() BOOST_NOEXCEPT : m_pImpl(NULL)
|
||||
{
|
||||
}
|
||||
light_function(this_type const& that)
|
||||
{
|
||||
if (that.m_pImpl)
|
||||
m_pImpl = that.m_pImpl->clone(that.m_pImpl);
|
||||
else
|
||||
m_pImpl = NULL;
|
||||
}
|
||||
light_function(BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT
|
||||
{
|
||||
m_pImpl = that.m_pImpl;
|
||||
that.m_pImpl = NULL;
|
||||
}
|
||||
|
||||
light_function(BOOST_RV_REF(const this_type) that) BOOST_NOEXCEPT
|
||||
{
|
||||
m_pImpl = that.m_pImpl;
|
||||
((this_type&)that).m_pImpl = NULL;
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
template< typename FunT >
|
||||
light_function(FunT&& fun) :
|
||||
m_pImpl(new impl< typename remove_cv< typename remove_reference< FunT >::type >::type >(boost::forward< FunT >(fun)))
|
||||
{
|
||||
}
|
||||
#else
|
||||
template< typename FunT >
|
||||
light_function(FunT const& fun, typename boost::disable_if_c< is_rv_or_same< FunT, this_type >::value, boost::log::aux::sfinae_dummy >::type = boost::log::aux::sfinae_dummy()) :
|
||||
m_pImpl(new impl< FunT >(fun))
|
||||
{
|
||||
}
|
||||
template< typename FunT >
|
||||
light_function(BOOST_RV_REF(FunT) fun, typename boost::disable_if_c< is_cv_same< FunT, this_type >::value, boost::log::aux::sfinae_dummy >::type = boost::log::aux::sfinae_dummy()) :
|
||||
m_pImpl(new impl< typename remove_cv< FunT >::type >(fun))
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
//! Constructor from NULL
|
||||
#if !defined(BOOST_NO_CXX11_NULLPTR)
|
||||
BOOST_CONSTEXPR light_function(std::nullptr_t) BOOST_NOEXCEPT
|
||||
#else
|
||||
BOOST_CONSTEXPR light_function(int p) BOOST_NOEXCEPT
|
||||
#endif
|
||||
: m_pImpl(NULL)
|
||||
{
|
||||
#if defined(BOOST_NO_CXX11_NULLPTR)
|
||||
BOOST_ASSERT(p == 0);
|
||||
#endif
|
||||
}
|
||||
~light_function()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
light_function& operator= (BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT
|
||||
{
|
||||
this->swap(that);
|
||||
return *this;
|
||||
}
|
||||
light_function& operator= (BOOST_COPY_ASSIGN_REF(this_type) that)
|
||||
{
|
||||
light_function tmp = static_cast< this_type const& >(that);
|
||||
this->swap(tmp);
|
||||
return *this;
|
||||
}
|
||||
//! Assignment of NULL
|
||||
#if !defined(BOOST_NO_CXX11_NULLPTR)
|
||||
light_function& operator= (std::nullptr_t)
|
||||
#else
|
||||
light_function& operator= (int p)
|
||||
#endif
|
||||
{
|
||||
#if defined(BOOST_NO_CXX11_NULLPTR)
|
||||
BOOST_ASSERT(p == 0);
|
||||
#endif
|
||||
clear();
|
||||
return *this;
|
||||
}
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
template< typename FunT >
|
||||
light_function& operator= (FunT&& fun)
|
||||
{
|
||||
light_function tmp(boost::forward< FunT >(fun));
|
||||
this->swap(tmp);
|
||||
return *this;
|
||||
}
|
||||
#else
|
||||
template< typename FunT >
|
||||
typename boost::disable_if_c< is_rv_or_same< FunT, this_type >::value, this_type& >::type
|
||||
operator= (FunT const& fun)
|
||||
{
|
||||
light_function tmp(fun);
|
||||
this->swap(tmp);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
result_type operator() (BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), ArgT, arg)) const
|
||||
{
|
||||
m_pImpl->invoke(m_pImpl BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), arg));
|
||||
}
|
||||
|
||||
BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
|
||||
bool operator! () const BOOST_NOEXCEPT { return (m_pImpl == NULL); }
|
||||
bool empty() const BOOST_NOEXCEPT { return (m_pImpl == NULL); }
|
||||
void clear() BOOST_NOEXCEPT
|
||||
{
|
||||
if (m_pImpl)
|
||||
{
|
||||
m_pImpl->destroy(m_pImpl);
|
||||
m_pImpl = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void swap(this_type& that) BOOST_NOEXCEPT
|
||||
{
|
||||
impl_base* p = m_pImpl;
|
||||
m_pImpl = that.m_pImpl;
|
||||
that.m_pImpl = p;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* 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 light_rw_mutex.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 24.03.2009
|
||||
*
|
||||
* \brief This header is the Boost.Log library implementation, see the library documentation
|
||||
* at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_LIGHT_RW_MUTEX_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_LIGHT_RW_MUTEX_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_LOG_NO_THREADS
|
||||
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#if defined(BOOST_THREAD_POSIX) // This one can be defined by users, so it should go first
|
||||
#define BOOST_LOG_LWRWMUTEX_USE_PTHREAD
|
||||
#elif defined(BOOST_WINDOWS) && (BOOST_USE_WINAPI_VERSION+0) >= (BOOST_WINAPI_VERSION_WIN6+0)
|
||||
#define BOOST_LOG_LWRWMUTEX_USE_SRWLOCK
|
||||
#elif defined(BOOST_HAS_PTHREADS)
|
||||
#define BOOST_LOG_LWRWMUTEX_USE_PTHREAD
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_LOG_LWRWMUTEX_USE_SRWLOCK)
|
||||
|
||||
#include <boost/detail/winapi/srw_lock.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace aux {
|
||||
|
||||
//! A light read/write mutex that uses WinNT 6 and later APIs
|
||||
class light_rw_mutex
|
||||
{
|
||||
boost::detail::winapi::SRWLOCK_ m_Mutex;
|
||||
|
||||
public:
|
||||
light_rw_mutex()
|
||||
{
|
||||
boost::detail::winapi::InitializeSRWLock(&m_Mutex);
|
||||
}
|
||||
void lock_shared()
|
||||
{
|
||||
boost::detail::winapi::AcquireSRWLockShared(&m_Mutex);
|
||||
}
|
||||
void unlock_shared()
|
||||
{
|
||||
boost::detail::winapi::ReleaseSRWLockShared(&m_Mutex);
|
||||
}
|
||||
void lock()
|
||||
{
|
||||
boost::detail::winapi::AcquireSRWLockExclusive(&m_Mutex);
|
||||
}
|
||||
void unlock()
|
||||
{
|
||||
boost::detail::winapi::ReleaseSRWLockExclusive(&m_Mutex);
|
||||
}
|
||||
|
||||
// Noncopyable
|
||||
BOOST_DELETED_FUNCTION(light_rw_mutex(light_rw_mutex const&))
|
||||
BOOST_DELETED_FUNCTION(light_rw_mutex& operator= (light_rw_mutex const&))
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#elif defined(BOOST_LOG_LWRWMUTEX_USE_PTHREAD)
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace aux {
|
||||
|
||||
//! A light read/write mutex that maps directly onto POSIX threading library
|
||||
class light_rw_mutex
|
||||
{
|
||||
pthread_rwlock_t m_Mutex;
|
||||
|
||||
public:
|
||||
light_rw_mutex()
|
||||
{
|
||||
pthread_rwlock_init(&m_Mutex, NULL);
|
||||
}
|
||||
~light_rw_mutex()
|
||||
{
|
||||
pthread_rwlock_destroy(&m_Mutex);
|
||||
}
|
||||
void lock_shared()
|
||||
{
|
||||
pthread_rwlock_rdlock(&m_Mutex);
|
||||
}
|
||||
void unlock_shared()
|
||||
{
|
||||
pthread_rwlock_unlock(&m_Mutex);
|
||||
}
|
||||
void lock()
|
||||
{
|
||||
pthread_rwlock_wrlock(&m_Mutex);
|
||||
}
|
||||
void unlock()
|
||||
{
|
||||
pthread_rwlock_unlock(&m_Mutex);
|
||||
}
|
||||
|
||||
// Noncopyable
|
||||
BOOST_DELETED_FUNCTION(light_rw_mutex(light_rw_mutex const&))
|
||||
BOOST_DELETED_FUNCTION(light_rw_mutex& operator= (light_rw_mutex const&))
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#else
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace aux {
|
||||
|
||||
//! A light read/write mutex
|
||||
class light_rw_mutex
|
||||
{
|
||||
struct BOOST_LOG_MAY_ALIAS mutex_state { void* p; } m_Mutex;
|
||||
|
||||
public:
|
||||
BOOST_LOG_API light_rw_mutex();
|
||||
BOOST_LOG_API ~light_rw_mutex();
|
||||
BOOST_LOG_API void lock_shared();
|
||||
BOOST_LOG_API void unlock_shared();
|
||||
BOOST_LOG_API void lock();
|
||||
BOOST_LOG_API void unlock();
|
||||
|
||||
// Noncopyable
|
||||
BOOST_DELETED_FUNCTION(light_rw_mutex(light_rw_mutex const&))
|
||||
BOOST_DELETED_FUNCTION(light_rw_mutex& operator= (light_rw_mutex const&))
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_NO_THREADS
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_LIGHT_RW_MUTEX_HPP_INCLUDED_
|
||||
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* 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 locking_ptr.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 15.07.2009
|
||||
*
|
||||
* This header is the Boost.Log library implementation, see the library documentation
|
||||
* at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_LOCKING_PTR_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_LOCKING_PTR_HPP_INCLUDED_
|
||||
|
||||
#include <cstddef>
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/smart_ptr/shared_ptr.hpp>
|
||||
#include <boost/thread/lock_options.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/utility/explicit_operator_bool.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace aux {
|
||||
|
||||
//! A pointer type that locks the backend until it's destroyed
|
||||
template< typename T, typename LockableT >
|
||||
class locking_ptr
|
||||
{
|
||||
typedef locking_ptr this_type;
|
||||
BOOST_COPYABLE_AND_MOVABLE_ALT(this_type)
|
||||
|
||||
public:
|
||||
//! Pointed type
|
||||
typedef T element_type;
|
||||
|
||||
private:
|
||||
//! Lockable type
|
||||
typedef LockableT lockable_type;
|
||||
|
||||
private:
|
||||
//! The pointer to the backend
|
||||
shared_ptr< element_type > m_pElement;
|
||||
//! Reference to the shared lock control object
|
||||
lockable_type* m_pLock;
|
||||
|
||||
public:
|
||||
//! Default constructor
|
||||
locking_ptr() BOOST_NOEXCEPT : m_pLock(NULL)
|
||||
{
|
||||
}
|
||||
//! Constructor
|
||||
locking_ptr(shared_ptr< element_type > const& p, lockable_type& l) : m_pElement(p), m_pLock(&l)
|
||||
{
|
||||
m_pLock->lock();
|
||||
}
|
||||
//! Constructor
|
||||
locking_ptr(shared_ptr< element_type > const& p, lockable_type& l, try_to_lock_t const&) : m_pElement(p), m_pLock(&l)
|
||||
{
|
||||
if (!m_pLock->try_lock())
|
||||
{
|
||||
m_pElement.reset();
|
||||
m_pLock = NULL;
|
||||
}
|
||||
}
|
||||
//! Copy constructor
|
||||
locking_ptr(locking_ptr const& that) : m_pElement(that.m_pElement), m_pLock(that.m_pLock)
|
||||
{
|
||||
if (m_pLock)
|
||||
m_pLock->lock();
|
||||
}
|
||||
//! Move constructor
|
||||
locking_ptr(BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT : m_pLock(that.m_pLock)
|
||||
{
|
||||
m_pElement.swap(that.m_pElement);
|
||||
that.m_pLock = NULL;
|
||||
}
|
||||
|
||||
//! Destructor
|
||||
~locking_ptr()
|
||||
{
|
||||
if (m_pLock)
|
||||
m_pLock->unlock();
|
||||
}
|
||||
|
||||
//! Assignment
|
||||
locking_ptr& operator= (locking_ptr that) BOOST_NOEXCEPT
|
||||
{
|
||||
this->swap(that);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Indirection
|
||||
element_type* operator-> () const BOOST_NOEXCEPT { return m_pElement.get(); }
|
||||
//! Dereferencing
|
||||
element_type& operator* () const BOOST_NOEXCEPT { return *m_pElement; }
|
||||
|
||||
//! Accessor to the raw pointer
|
||||
element_type* get() const BOOST_NOEXCEPT { return m_pElement.get(); }
|
||||
|
||||
//! Checks for null pointer
|
||||
BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
|
||||
//! Checks for null pointer
|
||||
bool operator! () const BOOST_NOEXCEPT { return !m_pElement; }
|
||||
|
||||
//! Swaps two pointers
|
||||
void swap(locking_ptr& that) BOOST_NOEXCEPT
|
||||
{
|
||||
m_pElement.swap(that.m_pElement);
|
||||
lockable_type* p = m_pLock;
|
||||
m_pLock = that.m_pLock;
|
||||
that.m_pLock = p;
|
||||
}
|
||||
};
|
||||
|
||||
//! Free raw pointer getter to assist generic programming
|
||||
template< typename T, typename LockableT >
|
||||
inline T* get_pointer(locking_ptr< T, LockableT > const& p) BOOST_NOEXCEPT
|
||||
{
|
||||
return p.get();
|
||||
}
|
||||
//! Free swap operation
|
||||
template< typename T, typename LockableT >
|
||||
inline void swap(locking_ptr< T, LockableT >& left, locking_ptr< T, LockableT >& right) BOOST_NOEXCEPT
|
||||
{
|
||||
left.swap(right);
|
||||
}
|
||||
|
||||
} // namespace aux
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_LOCKING_PTR_HPP_INCLUDED_
|
||||
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
* 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 locks.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 30.05.2010
|
||||
*
|
||||
* \brief This header is the Boost.Log library implementation, see the library documentation
|
||||
* at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_LOCKS_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_LOCKS_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
#ifndef BOOST_LOG_NO_THREADS
|
||||
|
||||
// Forward declaration of Boost.Thread locks. Specified here to avoid including Boost.Thread,
|
||||
// which would bring in many dependent headers, including a great deal of Boost.DateTime.
|
||||
template< typename >
|
||||
class lock_guard;
|
||||
template< typename >
|
||||
class shared_lock_guard;
|
||||
template< typename >
|
||||
class shared_lock;
|
||||
template< typename >
|
||||
class upgrade_lock;
|
||||
template< typename >
|
||||
class unique_lock;
|
||||
|
||||
template< typename >
|
||||
struct is_mutex_type;
|
||||
|
||||
#endif // BOOST_LOG_NO_THREADS
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
//! An auxiliary pseudo-lock to express no locking requirements in logger features
|
||||
template< typename MutexT >
|
||||
class no_lock
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* Constructs the pseudo-lock. The mutex is not affected during the construction.
|
||||
*/
|
||||
explicit no_lock(MutexT&) {}
|
||||
|
||||
private:
|
||||
no_lock(no_lock const&);
|
||||
no_lock& operator= (no_lock const&);
|
||||
};
|
||||
|
||||
namespace aux {
|
||||
|
||||
#ifndef BOOST_LOG_NO_THREADS
|
||||
|
||||
//! A trait to detect if the mutex supports exclusive locking
|
||||
template< typename MutexT >
|
||||
struct is_exclusively_lockable
|
||||
{
|
||||
typedef char true_type;
|
||||
struct false_type { char t[2]; };
|
||||
|
||||
template< typename T >
|
||||
static true_type check_lockable(T*, void (T::*)() = &T::lock, void (T::*)() = &T::unlock);
|
||||
static false_type check_lockable(void*);
|
||||
|
||||
enum value_t { value = sizeof(check_lockable((MutexT*)NULL)) == sizeof(true_type) };
|
||||
};
|
||||
|
||||
//! A trait to detect if the mutex supports shared locking
|
||||
template< typename MutexT >
|
||||
struct is_shared_lockable
|
||||
{
|
||||
typedef char true_type;
|
||||
struct false_type { char t[2]; };
|
||||
|
||||
template< typename T >
|
||||
static true_type check_shared_lockable(T*, void (T::*)() = &T::lock_shared, void (T::*)() = &T::unlock_shared);
|
||||
static false_type check_shared_lockable(void*);
|
||||
|
||||
enum value_t { value = sizeof(check_shared_lockable((MutexT*)NULL)) == sizeof(true_type) };
|
||||
};
|
||||
|
||||
//! A scope guard that automatically unlocks the mutex on destruction
|
||||
template< typename MutexT >
|
||||
struct exclusive_auto_unlocker
|
||||
{
|
||||
explicit exclusive_auto_unlocker(MutexT& m) BOOST_NOEXCEPT : m_Mutex(m)
|
||||
{
|
||||
}
|
||||
~exclusive_auto_unlocker()
|
||||
{
|
||||
m_Mutex.unlock();
|
||||
}
|
||||
|
||||
BOOST_DELETED_FUNCTION(exclusive_auto_unlocker(exclusive_auto_unlocker const&))
|
||||
BOOST_DELETED_FUNCTION(exclusive_auto_unlocker& operator= (exclusive_auto_unlocker const&))
|
||||
|
||||
protected:
|
||||
MutexT& m_Mutex;
|
||||
};
|
||||
|
||||
//! An analogue to the minimalistic \c lock_guard template. Defined here to avoid including Boost.Thread.
|
||||
template< typename MutexT >
|
||||
struct exclusive_lock_guard
|
||||
{
|
||||
explicit exclusive_lock_guard(MutexT& m) : m_Mutex(m)
|
||||
{
|
||||
m.lock();
|
||||
}
|
||||
~exclusive_lock_guard()
|
||||
{
|
||||
m_Mutex.unlock();
|
||||
}
|
||||
|
||||
BOOST_DELETED_FUNCTION(exclusive_lock_guard(exclusive_lock_guard const&))
|
||||
BOOST_DELETED_FUNCTION(exclusive_lock_guard& operator= (exclusive_lock_guard const&))
|
||||
|
||||
private:
|
||||
MutexT& m_Mutex;
|
||||
};
|
||||
|
||||
//! An analogue to the minimalistic \c lock_guard template that locks \c shared_mutex with shared ownership.
|
||||
template< typename MutexT >
|
||||
struct shared_lock_guard
|
||||
{
|
||||
explicit shared_lock_guard(MutexT& m) : m_Mutex(m)
|
||||
{
|
||||
m.lock_shared();
|
||||
}
|
||||
~shared_lock_guard()
|
||||
{
|
||||
m_Mutex.unlock_shared();
|
||||
}
|
||||
|
||||
BOOST_DELETED_FUNCTION(shared_lock_guard(shared_lock_guard const&))
|
||||
BOOST_DELETED_FUNCTION(shared_lock_guard& operator= (shared_lock_guard const&))
|
||||
|
||||
private:
|
||||
MutexT& m_Mutex;
|
||||
};
|
||||
|
||||
//! A deadlock-safe lock type that exclusively locks two mutexes
|
||||
template< typename MutexT1, typename MutexT2 >
|
||||
class multiple_unique_lock2
|
||||
{
|
||||
public:
|
||||
multiple_unique_lock2(MutexT1& m1, MutexT2& m2) :
|
||||
m_p1(&m1),
|
||||
m_p2(&m2)
|
||||
{
|
||||
// Yes, it's not conforming, but it works
|
||||
// and it doesn't require to #include <functional>
|
||||
if (static_cast< void* >(m_p1) < static_cast< void* >(m_p2))
|
||||
{
|
||||
m_p1->lock();
|
||||
m_p2->lock();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_p2->lock();
|
||||
m_p1->lock();
|
||||
}
|
||||
}
|
||||
~multiple_unique_lock2()
|
||||
{
|
||||
m_p2->unlock();
|
||||
m_p1->unlock();
|
||||
}
|
||||
|
||||
private:
|
||||
MutexT1* m_p1;
|
||||
MutexT2* m_p2;
|
||||
};
|
||||
|
||||
#endif // BOOST_LOG_NO_THREADS
|
||||
|
||||
} // namespace aux
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_LOCKS_HPP_INCLUDED_
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* 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)
|
||||
*/
|
||||
|
||||
template< BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), typename ArgT) >
|
||||
BOOST_FORCEINLINE format_named_scope_actor<
|
||||
fallback_to_none,
|
||||
typename boost::log::aux::deduce_char_type<
|
||||
typename parameter::binding<
|
||||
typename boost::log::aux::make_arg_list< BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), ArgT) >::type,
|
||||
keywords::tag::format,
|
||||
void
|
||||
>::type
|
||||
>::type
|
||||
> format_named_scope(attribute_name const& name, BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), ArgT, const& arg))
|
||||
{
|
||||
typedef typename boost::log::aux::deduce_char_type<
|
||||
typename parameter::binding<
|
||||
typename boost::log::aux::make_arg_list< BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), ArgT) >::type,
|
||||
keywords::tag::format,
|
||||
void
|
||||
>::type
|
||||
>::type char_type;
|
||||
return aux::format_named_scope< char_type, phoenix::actor >(name, fallback_to_none(), (BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), arg)));
|
||||
}
|
||||
|
||||
template< typename DescriptorT, template< typename > class ActorT, BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), typename ArgT) >
|
||||
BOOST_FORCEINLINE format_named_scope_actor<
|
||||
fallback_to_none,
|
||||
typename boost::log::aux::deduce_char_type<
|
||||
typename parameter::binding<
|
||||
typename boost::log::aux::make_arg_list< BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), ArgT) >::type,
|
||||
keywords::tag::format,
|
||||
void
|
||||
>::type
|
||||
>::type,
|
||||
ActorT
|
||||
>
|
||||
format_named_scope(attribute_keyword< DescriptorT, ActorT > const& keyword, BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), ArgT, const& arg))
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG((is_same< typename DescriptorT::value_type, attributes::named_scope::value_type >::value),\
|
||||
"Boost.Log: Named scope formatter only accepts attribute values of type attributes::named_scope::value_type.");
|
||||
|
||||
typedef typename boost::log::aux::deduce_char_type<
|
||||
typename parameter::binding<
|
||||
typename boost::log::aux::make_arg_list< BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), ArgT) >::type,
|
||||
keywords::tag::format,
|
||||
void
|
||||
>::type
|
||||
>::type char_type;
|
||||
return aux::format_named_scope< char_type, ActorT >(keyword.get_name(), fallback_to_none(), (BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), arg)));
|
||||
}
|
||||
|
||||
template< typename T, typename FallbackPolicyT, typename TagT, template< typename > class ActorT, BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), typename ArgT) >
|
||||
BOOST_FORCEINLINE format_named_scope_actor<
|
||||
FallbackPolicyT,
|
||||
typename boost::log::aux::deduce_char_type<
|
||||
typename parameter::binding<
|
||||
typename boost::log::aux::make_arg_list< BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), ArgT) >::type,
|
||||
keywords::tag::format,
|
||||
void
|
||||
>::type
|
||||
>::type,
|
||||
ActorT
|
||||
>
|
||||
format_named_scope(attribute_actor< T, FallbackPolicyT, TagT, ActorT > const& placeholder, BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), ArgT, const& arg))
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG((is_same< T, attributes::named_scope::value_type >::value),\
|
||||
"Boost.Log: Named scope formatter only accepts attribute values of type attributes::named_scope::value_type.");
|
||||
|
||||
typedef typename boost::log::aux::deduce_char_type<
|
||||
typename parameter::binding<
|
||||
typename boost::log::aux::make_arg_list< BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), ArgT) >::type,
|
||||
keywords::tag::format,
|
||||
void
|
||||
>::type
|
||||
>::type char_type;
|
||||
return aux::format_named_scope< char_type, ActorT >(placeholder.get_name(), placeholder.get_fallback_policy(), (BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), arg)));
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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 native_typeof.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 08.03.2009
|
||||
*
|
||||
* This header is the Boost.Log library implementation, see the library documentation
|
||||
* at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_NATIVE_TYPEOF_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_NATIVE_TYPEOF_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_DECLTYPE)
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace aux {
|
||||
|
||||
template< typename T >
|
||||
T get_root_type(T const&);
|
||||
|
||||
} // namespace aux
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#define BOOST_LOG_TYPEOF(x) decltype(::boost::log::aux::get_root_type(x))
|
||||
|
||||
#elif defined(__COMO__) && defined(__GNUG__)
|
||||
|
||||
#define BOOST_LOG_TYPEOF(x) typeof(x)
|
||||
|
||||
#elif defined(__GNUC__) || defined(__MWERKS__)
|
||||
|
||||
#define BOOST_LOG_TYPEOF(x) __typeof__(x)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_AUTO_DECLARATIONS)
|
||||
#define BOOST_LOG_AUTO(var, expr) auto var = (expr)
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_LOG_AUTO) && defined(BOOST_LOG_TYPEOF)
|
||||
#define BOOST_LOG_AUTO(var, expr) BOOST_LOG_TYPEOF((expr)) var = (expr)
|
||||
#endif
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_NATIVE_TYPEOF_HPP_INCLUDED_
|
||||
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* 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 parameter_tools.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 28.06.2009
|
||||
*
|
||||
* \brief This header is the Boost.Log library implementation, see the library documentation
|
||||
* at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_PARAMETER_TOOLS_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_PARAMETER_TOOLS_HPP_INCLUDED_
|
||||
|
||||
#include <boost/parameter/keyword.hpp>
|
||||
#include <boost/preprocessor/control/if.hpp>
|
||||
#include <boost/preprocessor/comparison/equal.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/facilities/intercept.hpp>
|
||||
#include <boost/preprocessor/arithmetic/dec.hpp>
|
||||
#include <boost/preprocessor/tuple/elem.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/sfinae_tools.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_LOG_MAX_PARAMETER_ARGS
|
||||
//! The maximum number of named arguments that are accepted by constructors and functions
|
||||
#define BOOST_LOG_MAX_PARAMETER_ARGS 16
|
||||
#endif
|
||||
|
||||
// The macro applies the passed macro with the specified arguments BOOST_LOG_MAX_PARAMETER_ARGS times
|
||||
#define BOOST_LOG_PARAMETRIZED_CONSTRUCTORS_GEN(macro, args)\
|
||||
public:\
|
||||
BOOST_PP_REPEAT_FROM_TO(1, BOOST_LOG_MAX_PARAMETER_ARGS, macro, args)
|
||||
|
||||
#define BOOST_LOG_CTOR_FORWARD_1(n, types)\
|
||||
template< typename T0 >\
|
||||
explicit BOOST_PP_TUPLE_ELEM(2, 0, types)(T0 const& arg0, typename boost::log::aux::enable_if_named_parameters< T0, boost::log::aux::sfinae_dummy >::type = boost::log::aux::sfinae_dummy()) :\
|
||||
BOOST_PP_TUPLE_ELEM(2, 1, types)((BOOST_PP_ENUM_PARAMS(n, arg))) {}
|
||||
|
||||
#define BOOST_LOG_CTOR_FORWARD_N(n, types)\
|
||||
template< BOOST_PP_ENUM_PARAMS(n, typename T) >\
|
||||
explicit BOOST_PP_TUPLE_ELEM(2, 0, types)(BOOST_PP_ENUM_BINARY_PARAMS(n, T, const& arg)) :\
|
||||
BOOST_PP_TUPLE_ELEM(2, 1, types)((BOOST_PP_ENUM_PARAMS(n, arg))) {}
|
||||
|
||||
#define BOOST_LOG_CTOR_FORWARD(z, n, types)\
|
||||
BOOST_PP_IF(BOOST_PP_EQUAL(n, 1), BOOST_LOG_CTOR_FORWARD_1, BOOST_LOG_CTOR_FORWARD_N)(n, types)
|
||||
|
||||
// The macro expands to a number of templated constructors that aggregate their named arguments
|
||||
// into an ArgumentsPack and pass it to the base class constructor.
|
||||
#define BOOST_LOG_PARAMETRIZED_CONSTRUCTORS_FORWARD(class_type, base_type)\
|
||||
BOOST_LOG_PARAMETRIZED_CONSTRUCTORS_GEN(BOOST_LOG_CTOR_FORWARD, (class_type, base_type))
|
||||
|
||||
#define BOOST_LOG_CTOR_CALL_1(n, types)\
|
||||
template< typename T0 >\
|
||||
explicit BOOST_PP_TUPLE_ELEM(2, 0, types)(T0 const& arg0, typename boost::log::aux::enable_if_named_parameters< T0, boost::log::aux::sfinae_dummy >::type = boost::log::aux::sfinae_dummy())\
|
||||
{ BOOST_PP_TUPLE_ELEM(2, 1, types)((BOOST_PP_ENUM_PARAMS(n, arg))); }
|
||||
|
||||
#define BOOST_LOG_CTOR_CALL_N(n, types)\
|
||||
template< BOOST_PP_ENUM_PARAMS(n, typename T) >\
|
||||
explicit BOOST_PP_TUPLE_ELEM(2, 0, types)(BOOST_PP_ENUM_BINARY_PARAMS(n, T, const& arg))\
|
||||
{ BOOST_PP_TUPLE_ELEM(2, 1, types)((BOOST_PP_ENUM_PARAMS(n, arg))); }
|
||||
|
||||
#define BOOST_LOG_CTOR_CALL(z, n, types)\
|
||||
BOOST_PP_IF(BOOST_PP_EQUAL(n, 1), BOOST_LOG_CTOR_CALL_1, BOOST_LOG_CTOR_CALL_N)(n, types)
|
||||
|
||||
// The macro expands to a number of templated constructors that aggregate their named arguments
|
||||
// into an ArgumentsPack and pass it to a function call.
|
||||
#define BOOST_LOG_PARAMETRIZED_CONSTRUCTORS_CALL(class_type, fun)\
|
||||
BOOST_LOG_PARAMETRIZED_CONSTRUCTORS_GEN(BOOST_LOG_CTOR_CALL, (class_type, fun))
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace aux {
|
||||
|
||||
// Yeah, not too cute. The empty_arg_list class should really be public.
|
||||
// https://svn.boost.org/trac/boost/ticket/7247
|
||||
typedef boost::parameter::aux::empty_arg_list empty_arg_list;
|
||||
|
||||
#if !(defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_LOG_NO_CXX11_ARG_PACKS_TO_NON_VARIADIC_ARGS_EXPANSION))
|
||||
|
||||
//! The metafunction generates argument pack
|
||||
template< typename ArgT0, typename... ArgsT >
|
||||
struct make_arg_list
|
||||
{
|
||||
typedef boost::parameter::aux::arg_list< ArgT0, typename make_arg_list< ArgsT... >::type > type;
|
||||
};
|
||||
|
||||
template< typename ArgT0 >
|
||||
struct make_arg_list< ArgT0 >
|
||||
{
|
||||
typedef boost::parameter::aux::arg_list< ArgT0 > type;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
//! The metafunction generates argument pack
|
||||
template< typename ArgT0, BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_DEC(BOOST_LOG_MAX_PARAMETER_ARGS), typename T, = void BOOST_PP_INTERCEPT) >
|
||||
struct make_arg_list
|
||||
{
|
||||
typedef boost::parameter::aux::arg_list< ArgT0, typename make_arg_list< BOOST_PP_ENUM_PARAMS(BOOST_PP_DEC(BOOST_LOG_MAX_PARAMETER_ARGS), T) >::type > type;
|
||||
};
|
||||
|
||||
template< typename ArgT0 >
|
||||
struct make_arg_list< ArgT0, BOOST_PP_ENUM_PARAMS(BOOST_PP_DEC(BOOST_LOG_MAX_PARAMETER_ARGS), void BOOST_PP_INTERCEPT) >
|
||||
{
|
||||
typedef boost::parameter::aux::arg_list< ArgT0 > type;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
template< typename T, typename R >
|
||||
struct enable_if_named_parameters {};
|
||||
|
||||
template< typename R >
|
||||
struct enable_if_named_parameters< empty_arg_list, R >
|
||||
{
|
||||
typedef R type;
|
||||
};
|
||||
|
||||
template< typename Keyword, typename Arg, typename R >
|
||||
struct enable_if_named_parameters< boost::parameter::aux::tagged_argument< Keyword, Arg >, R >
|
||||
{
|
||||
typedef R type;
|
||||
};
|
||||
|
||||
template< typename TaggedArg, typename Next, typename R >
|
||||
struct enable_if_named_parameters< boost::parameter::aux::arg_list< TaggedArg, Next >, R >
|
||||
{
|
||||
typedef R type;
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_PARAMETER_TOOLS_HPP_INCLUDED_
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright Andrey Semashev 2016.
|
||||
* 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 pause.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 06.01.2016
|
||||
*
|
||||
* \brief This header is the Boost.Log library implementation, see the library documentation
|
||||
* at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_PAUSE_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_PAUSE_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#if defined(__INTEL_COMPILER) || defined(_MSC_VER)
|
||||
# if defined(_M_IX86)
|
||||
# define BOOST_LOG_AUX_PAUSE __asm { pause }
|
||||
# elif defined(_M_AMD64)
|
||||
extern "C" void _mm_pause(void);
|
||||
# if defined(BOOST_MSVC)
|
||||
# pragma intrinsic(_mm_pause)
|
||||
# endif
|
||||
# define BOOST_LOG_AUX_PAUSE _mm_pause()
|
||||
# endif
|
||||
#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
|
||||
# define BOOST_LOG_AUX_PAUSE __asm__ __volatile__("pause;")
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace aux {
|
||||
|
||||
BOOST_FORCEINLINE void pause() BOOST_NOEXCEPT
|
||||
{
|
||||
#if defined(BOOST_LOG_AUX_PAUSE)
|
||||
BOOST_LOG_AUX_PAUSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace aux
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_PAUSE_HPP_INCLUDED_
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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 pp_identity.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 12.02.2011
|
||||
*
|
||||
* This header is the Boost.Log library implementation, see the library documentation
|
||||
* at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_PP_IDENTITY_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_PP_IDENTITY_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#define BOOST_LOG_PP_IDENTITY(z, n, data) data
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_PP_IDENTITY_HPP_INCLUDED_
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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 process_id.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 12.09.2009
|
||||
*
|
||||
* \brief This header is the Boost.Log library implementation, see the library documentation
|
||||
* at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_PROCESS_ID_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_PROCESS_ID_HPP_INCLUDED_
|
||||
|
||||
#include <iosfwd>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/id.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace aux {
|
||||
|
||||
//! The process id descriptor
|
||||
struct process
|
||||
{
|
||||
typedef unsigned long native_type;
|
||||
typedef boost::log::aux::id< process > id;
|
||||
};
|
||||
|
||||
namespace this_process {
|
||||
|
||||
//! The function returns current process identifier
|
||||
BOOST_LOG_API process::id get_id();
|
||||
|
||||
} // namespace this_process
|
||||
|
||||
template< typename CharT, typename TraitsT >
|
||||
BOOST_LOG_API std::basic_ostream< CharT, TraitsT >&
|
||||
operator<< (std::basic_ostream< CharT, TraitsT >& strm, process::id const& pid);
|
||||
|
||||
} // namespace aux
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_PROCESS_ID_HPP_INCLUDED_
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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 setup_config.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 14.09.2009
|
||||
*
|
||||
* \brief This header is the Boost.Log library implementation, see the library documentation
|
||||
* at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html. In this file
|
||||
* internal configuration macros are defined.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_SETUP_CONFIG_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_SETUP_CONFIG_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_LOG_SETUP_BUILDING_THE_LIB)
|
||||
|
||||
// Detect if we're dealing with dll
|
||||
# if defined(BOOST_LOG_SETUP_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)
|
||||
# define BOOST_LOG_SETUP_DLL
|
||||
# endif
|
||||
|
||||
# if defined(BOOST_LOG_SETUP_DLL)
|
||||
# define BOOST_LOG_SETUP_API BOOST_SYMBOL_IMPORT
|
||||
# else
|
||||
# define BOOST_LOG_SETUP_API
|
||||
# endif
|
||||
|
||||
//
|
||||
// Automatically link to the correct build variant where possible.
|
||||
//
|
||||
# if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_LOG_SETUP_NO_LIB)
|
||||
# define BOOST_LIB_NAME boost_log_setup
|
||||
# if defined(BOOST_LOG_SETUP_DLL)
|
||||
# define BOOST_DYN_LINK
|
||||
# endif
|
||||
# include <boost/config/auto_link.hpp>
|
||||
# endif // auto-linking disabled
|
||||
|
||||
#else // !defined(BOOST_LOG_SETUP_BUILDING_THE_LIB)
|
||||
|
||||
# if defined(BOOST_LOG_SETUP_DLL)
|
||||
# define BOOST_LOG_SETUP_API BOOST_SYMBOL_EXPORT
|
||||
# else
|
||||
# define BOOST_LOG_SETUP_API BOOST_SYMBOL_VISIBLE
|
||||
# endif
|
||||
|
||||
#endif // !defined(BOOST_LOG_SETUP_BUILDING_THE_LIB)
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_SETUP_CONFIG_HPP_INCLUDED_
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright Andrey Semashev 2016.
|
||||
* 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 sfinae_tools.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 23.02.2016
|
||||
*
|
||||
* \brief This header is the Boost.Log library implementation, see the library documentation
|
||||
* at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_SFINAE_TOOLS_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_SFINAE_TOOLS_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/core/enable_if.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace aux {
|
||||
|
||||
//! A distinct type that can be used as a fake argument type in constructors filtered by SFINAE
|
||||
struct sfinae_dummy {};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_SFINAE_TOOLS_HPP_INCLUDED_
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* 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 singleton.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 20.04.2008
|
||||
*
|
||||
* \brief This header is the Boost.Log library implementation, see the library documentation
|
||||
* at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_SINGLETON_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_SINGLETON_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/utility/once_block.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace aux {
|
||||
|
||||
//! A base class for singletons, constructed on-demand
|
||||
template< typename DerivedT, typename StorageT = DerivedT >
|
||||
class lazy_singleton
|
||||
{
|
||||
public:
|
||||
BOOST_DEFAULTED_FUNCTION(lazy_singleton(), {})
|
||||
|
||||
//! Returns the singleton instance
|
||||
static StorageT& get()
|
||||
{
|
||||
BOOST_LOG_ONCE_BLOCK()
|
||||
{
|
||||
DerivedT::init_instance();
|
||||
}
|
||||
return get_instance();
|
||||
}
|
||||
|
||||
//! Initializes the singleton instance
|
||||
static void init_instance()
|
||||
{
|
||||
get_instance();
|
||||
}
|
||||
|
||||
BOOST_DELETED_FUNCTION(lazy_singleton(lazy_singleton const&))
|
||||
BOOST_DELETED_FUNCTION(lazy_singleton& operator= (lazy_singleton const&))
|
||||
|
||||
protected:
|
||||
//! Returns the singleton instance (not thread-safe)
|
||||
static StorageT& get_instance()
|
||||
{
|
||||
static StorageT instance;
|
||||
return instance;
|
||||
}
|
||||
};
|
||||
|
||||
//! A base class for singletons, constructed on namespace scope initialization stage
|
||||
template< typename DerivedT, typename StorageT = DerivedT >
|
||||
class singleton :
|
||||
public lazy_singleton< DerivedT, StorageT >
|
||||
{
|
||||
public:
|
||||
static StorageT& instance;
|
||||
};
|
||||
|
||||
template< typename DerivedT, typename StorageT >
|
||||
StorageT& singleton< DerivedT, StorageT >::instance =
|
||||
lazy_singleton< DerivedT, StorageT >::get();
|
||||
|
||||
} // namespace aux
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_SINGLETON_HPP_INCLUDED_
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* 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 sink_init_helpers.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 14.03.2009
|
||||
*
|
||||
* \brief This header is the Boost.Log library implementation, see the library documentation
|
||||
* at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_SINK_INIT_HELPERS_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_SINK_INIT_HELPERS_HPP_INCLUDED_
|
||||
|
||||
#include <string>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/parameter/binding.hpp>
|
||||
#include <boost/type_traits/is_void.hpp>
|
||||
#include <boost/core/enable_if.hpp>
|
||||
#include <boost/phoenix/core/is_actor.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/core/core.hpp>
|
||||
#include <boost/log/expressions/filter.hpp>
|
||||
#include <boost/log/expressions/formatter.hpp>
|
||||
#include <boost/log/utility/setup/filter_parser.hpp>
|
||||
#include <boost/log/utility/setup/formatter_parser.hpp>
|
||||
#include <boost/log/keywords/filter.hpp>
|
||||
#include <boost/log/keywords/format.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace aux {
|
||||
|
||||
// The function creates a filter functional object from the provided argument
|
||||
template< typename CharT >
|
||||
inline filter acquire_filter(const CharT* filter)
|
||||
{
|
||||
return boost::log::parse_filter(filter);
|
||||
}
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT >
|
||||
inline filter acquire_filter(std::basic_string< CharT, TraitsT, AllocatorT > const& filter)
|
||||
{
|
||||
return boost::log::parse_filter(filter);
|
||||
}
|
||||
template< typename FilterT >
|
||||
inline typename boost::enable_if_c<
|
||||
phoenix::is_actor< FilterT >::value,
|
||||
FilterT const&
|
||||
>::type acquire_filter(FilterT const& filter)
|
||||
{
|
||||
return filter;
|
||||
}
|
||||
|
||||
// The function installs filter into the sink, if provided in the arguments pack
|
||||
template< typename SinkT, typename ArgsT >
|
||||
inline void setup_filter(SinkT&, ArgsT const&, mpl::true_)
|
||||
{
|
||||
}
|
||||
|
||||
template< typename SinkT, typename ArgsT >
|
||||
inline void setup_filter(SinkT& s, ArgsT const& args, mpl::false_)
|
||||
{
|
||||
s.set_filter(aux::acquire_filter(args[keywords::filter]));
|
||||
}
|
||||
|
||||
|
||||
// The function creates a filter functional object from the provided argument
|
||||
template< typename CharT >
|
||||
inline basic_formatter< CharT > acquire_formatter(const CharT* formatter)
|
||||
{
|
||||
return boost::log::parse_formatter(formatter);
|
||||
}
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT >
|
||||
inline basic_formatter< CharT > acquire_formatter(std::basic_string< CharT, TraitsT, AllocatorT > const& formatter)
|
||||
{
|
||||
return boost::log::parse_formatter(formatter);
|
||||
}
|
||||
template< typename FormatterT >
|
||||
inline typename boost::enable_if_c<
|
||||
phoenix::is_actor< FormatterT >::value,
|
||||
FormatterT const&
|
||||
>::type acquire_formatter(FormatterT const& formatter)
|
||||
{
|
||||
return formatter;
|
||||
}
|
||||
|
||||
// The function installs filter into the sink, if provided in the arguments pack
|
||||
template< typename SinkT, typename ArgsT >
|
||||
inline void setup_formatter(SinkT&, ArgsT const&, mpl::true_)
|
||||
{
|
||||
}
|
||||
|
||||
template< typename SinkT, typename ArgsT >
|
||||
inline void setup_formatter(SinkT& s, ArgsT const& args, mpl::false_)
|
||||
{
|
||||
s.set_formatter(aux::acquire_formatter(args[keywords::format]));
|
||||
}
|
||||
|
||||
} // namespace aux
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_SINK_INIT_HELPERS_HPP_INCLUDED_
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* 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 snprintf.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 20.02.2009
|
||||
*
|
||||
* \brief This header is the Boost.Log library implementation, see the library documentation
|
||||
* at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_SNPRINTF_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_SNPRINTF_HPP_INCLUDED_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <cstddef>
|
||||
#include <cstdarg>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#ifdef BOOST_LOG_USE_WCHAR_T
|
||||
#include <wchar.h>
|
||||
#endif // BOOST_LOG_USE_WCHAR_T
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace aux {
|
||||
|
||||
#if defined(_MSC_VER) || (defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR))
|
||||
|
||||
// MSVC snprintfs are not conforming but they are good enough for our cases.
|
||||
// MinGW32, at least the older versions up until gcc 4.7, also provide the non-conforming interface.
|
||||
inline int vsnprintf(char* buf, std::size_t size, const char* format, std::va_list args)
|
||||
{
|
||||
int n = _vsnprintf(buf, size, format, args);
|
||||
if (static_cast< unsigned int >(n) >= size)
|
||||
{
|
||||
n = static_cast< int >(size);
|
||||
buf[size - 1] = '\0';
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
# ifdef BOOST_LOG_USE_WCHAR_T
|
||||
inline int vswprintf(wchar_t* buf, std::size_t size, const wchar_t* format, std::va_list args)
|
||||
{
|
||||
int n = _vsnwprintf(buf, size, format, args);
|
||||
if (static_cast< unsigned int >(n) >= size)
|
||||
{
|
||||
n = static_cast< int >(size);
|
||||
buf[size - 1] = L'\0';
|
||||
}
|
||||
return n;
|
||||
}
|
||||
# endif // BOOST_LOG_USE_WCHAR_T
|
||||
|
||||
inline int snprintf(char* buf, std::size_t size, const char* format, ...)
|
||||
{
|
||||
std::va_list args;
|
||||
va_start(args, format);
|
||||
int n = vsnprintf(buf, size, format, args);
|
||||
va_end(args);
|
||||
return n;
|
||||
}
|
||||
|
||||
# ifdef BOOST_LOG_USE_WCHAR_T
|
||||
inline int swprintf(wchar_t* buf, std::size_t size, const wchar_t* format, ...)
|
||||
{
|
||||
std::va_list args;
|
||||
va_start(args, format);
|
||||
int n = vswprintf(buf, size, format, args);
|
||||
va_end(args);
|
||||
return n;
|
||||
}
|
||||
# endif // BOOST_LOG_USE_WCHAR_T
|
||||
|
||||
#else
|
||||
|
||||
// Standard-conforming compilers already have the correct snprintfs
|
||||
using ::snprintf;
|
||||
using ::vsnprintf;
|
||||
|
||||
# ifdef BOOST_LOG_USE_WCHAR_T
|
||||
using ::swprintf;
|
||||
using ::vswprintf;
|
||||
# endif // BOOST_LOG_USE_WCHAR_T
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace aux
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_SNPRINTF_HPP_INCLUDED_
|
||||
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* 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 tagged_integer.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 11.01.2008
|
||||
*
|
||||
* \brief This header is the Boost.Log library implementation, see the library documentation
|
||||
* at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_TAGGED_INTEGER_HPP_INCLUDED_
|
||||
#define BOOST_LOG_TAGGED_INTEGER_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace aux {
|
||||
|
||||
//! A tagged integer wrapper for type safety
|
||||
template< typename IntT, typename TagT >
|
||||
struct tagged_integer
|
||||
{
|
||||
//! Contained value type
|
||||
typedef IntT integer_type;
|
||||
//! Tag
|
||||
typedef TagT tag;
|
||||
|
||||
//! Contained value
|
||||
integer_type value;
|
||||
|
||||
//! Conversion operator
|
||||
BOOST_CONSTEXPR operator integer_type() const BOOST_NOEXCEPT { return value; }
|
||||
|
||||
// Increment
|
||||
tagged_integer& operator++ () BOOST_NOEXCEPT { ++value; return *this; }
|
||||
tagged_integer operator++ (int) BOOST_NOEXCEPT { tagged_integer temp = *this; ++value; return temp; }
|
||||
// Decrement
|
||||
tagged_integer& operator-- () BOOST_NOEXCEPT { --value; return *this; }
|
||||
tagged_integer operator-- (int) BOOST_NOEXCEPT { tagged_integer temp = *this; --value; return temp; }
|
||||
|
||||
#define BOOST_LOG_TAGGED_INTEGER_OP(op)\
|
||||
tagged_integer& operator op (tagged_integer const& that) BOOST_NOEXCEPT { value op that.value; return *this; }
|
||||
|
||||
BOOST_LOG_TAGGED_INTEGER_OP(|=)
|
||||
BOOST_LOG_TAGGED_INTEGER_OP(&=)
|
||||
BOOST_LOG_TAGGED_INTEGER_OP(^=)
|
||||
BOOST_LOG_TAGGED_INTEGER_OP(+=)
|
||||
BOOST_LOG_TAGGED_INTEGER_OP(-=)
|
||||
BOOST_LOG_TAGGED_INTEGER_OP(*=)
|
||||
BOOST_LOG_TAGGED_INTEGER_OP(/=)
|
||||
BOOST_LOG_TAGGED_INTEGER_OP(%=)
|
||||
|
||||
#undef BOOST_LOG_TAGGED_INTEGER_OP
|
||||
|
||||
//! Inversion operator
|
||||
tagged_integer& operator~ () BOOST_NOEXCEPT { ~value; return *this; }
|
||||
|
||||
// Shift operators
|
||||
template< typename T >
|
||||
tagged_integer& operator<<= (T const& that) BOOST_NOEXCEPT { value <<= that; return *this; }
|
||||
template< typename T >
|
||||
tagged_integer& operator>>= (T const& that) BOOST_NOEXCEPT { value >>= that; return *this; }
|
||||
|
||||
private:
|
||||
// Protection against improper usage
|
||||
template< typename T1, typename T2 >
|
||||
tagged_integer& operator<<= (tagged_integer< T1, T2 > const&);
|
||||
template< typename T1, typename T2 >
|
||||
tagged_integer& operator>>= (tagged_integer< T1, T2 > const&);
|
||||
};
|
||||
|
||||
// Relational operators
|
||||
#define BOOST_LOG_TAGGED_INTEGER_OP(op)\
|
||||
template< typename IntT, typename TagT >\
|
||||
inline bool operator op (\
|
||||
tagged_integer< IntT, TagT > const& left, tagged_integer< IntT, TagT > const& right) BOOST_NOEXCEPT\
|
||||
{\
|
||||
return (left.value op right.value);\
|
||||
}
|
||||
|
||||
BOOST_LOG_TAGGED_INTEGER_OP(==)
|
||||
BOOST_LOG_TAGGED_INTEGER_OP(!=)
|
||||
BOOST_LOG_TAGGED_INTEGER_OP(<)
|
||||
BOOST_LOG_TAGGED_INTEGER_OP(>)
|
||||
BOOST_LOG_TAGGED_INTEGER_OP(<=)
|
||||
BOOST_LOG_TAGGED_INTEGER_OP(>=)
|
||||
|
||||
#undef BOOST_LOG_TAGGED_INTEGER_OP
|
||||
|
||||
#define BOOST_LOG_TAGGED_INTEGER_OP(op)\
|
||||
template< typename IntT, typename TagT >\
|
||||
inline tagged_integer< IntT, TagT > operator op (\
|
||||
tagged_integer< IntT, TagT > const& left, tagged_integer< IntT, TagT > const& right) BOOST_NOEXCEPT\
|
||||
{\
|
||||
tagged_integer< IntT, TagT > temp = left;\
|
||||
temp op##= right;\
|
||||
return temp;\
|
||||
}
|
||||
|
||||
BOOST_LOG_TAGGED_INTEGER_OP(|)
|
||||
BOOST_LOG_TAGGED_INTEGER_OP(&)
|
||||
BOOST_LOG_TAGGED_INTEGER_OP(^)
|
||||
BOOST_LOG_TAGGED_INTEGER_OP(+)
|
||||
BOOST_LOG_TAGGED_INTEGER_OP(-)
|
||||
BOOST_LOG_TAGGED_INTEGER_OP(*)
|
||||
BOOST_LOG_TAGGED_INTEGER_OP(/)
|
||||
BOOST_LOG_TAGGED_INTEGER_OP(%)
|
||||
|
||||
#undef BOOST_LOG_TAGGED_INTEGER_OP
|
||||
|
||||
#define BOOST_LOG_TAGGED_INTEGER_OP(op)\
|
||||
template< typename IntT, typename TagT, typename T >\
|
||||
inline tagged_integer< IntT, TagT > operator op (\
|
||||
tagged_integer< IntT, TagT > const& left, T const& right) BOOST_NOEXCEPT\
|
||||
{\
|
||||
tagged_integer< IntT, TagT > temp = left;\
|
||||
temp op##= right;\
|
||||
return temp;\
|
||||
}
|
||||
|
||||
BOOST_LOG_TAGGED_INTEGER_OP(<<)
|
||||
BOOST_LOG_TAGGED_INTEGER_OP(>>)
|
||||
|
||||
#undef BOOST_LOG_TAGGED_INTEGER_OP
|
||||
|
||||
} // namespace aux
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_TAGGED_INTEGER_HPP_INCLUDED_
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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 thread_id.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 08.01.2012
|
||||
*
|
||||
* \brief This header is the Boost.Log library implementation, see the library documentation
|
||||
* at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_THREAD_ID_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_THREAD_ID_HPP_INCLUDED_
|
||||
|
||||
#include <iosfwd>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/id.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace aux {
|
||||
|
||||
//! The thread id descriptor
|
||||
struct thread
|
||||
{
|
||||
#if defined(BOOST_WINDOWS)
|
||||
typedef uint32_t native_type;
|
||||
#else
|
||||
typedef uintmax_t native_type;
|
||||
#endif
|
||||
typedef boost::log::aux::id< thread > id;
|
||||
};
|
||||
|
||||
namespace this_thread {
|
||||
|
||||
//! The function returns current thread identifier
|
||||
BOOST_LOG_API thread::id const& get_id();
|
||||
|
||||
} // namespace this_thread
|
||||
|
||||
template< typename CharT, typename TraitsT >
|
||||
BOOST_LOG_API std::basic_ostream< CharT, TraitsT >&
|
||||
operator<< (std::basic_ostream< CharT, TraitsT >& strm, thread::id const& tid);
|
||||
|
||||
} // namespace aux
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_THREAD_ID_HPP_INCLUDED_
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* 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 thread_specific.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 01.03.2008
|
||||
*
|
||||
* \brief This header is the Boost.Log library implementation, see the library documentation
|
||||
* at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_THREAD_SPECIFIC_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_THREAD_SPECIFIC_HPP_INCLUDED_
|
||||
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits/is_pod.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace aux {
|
||||
|
||||
//! Base class for TLS to hide platform-specific storage management
|
||||
class thread_specific_base
|
||||
{
|
||||
private:
|
||||
#if defined(BOOST_THREAD_PLATFORM_WIN32)
|
||||
typedef unsigned long key_storage;
|
||||
#else
|
||||
typedef void* key_storage;
|
||||
#endif
|
||||
|
||||
key_storage m_Key;
|
||||
|
||||
protected:
|
||||
BOOST_LOG_API thread_specific_base();
|
||||
BOOST_LOG_API ~thread_specific_base();
|
||||
BOOST_LOG_API void* get_content() const;
|
||||
BOOST_LOG_API void set_content(void* value) const;
|
||||
|
||||
// Copying prohibited
|
||||
BOOST_DELETED_FUNCTION(thread_specific_base(thread_specific_base const&))
|
||||
BOOST_DELETED_FUNCTION(thread_specific_base& operator= (thread_specific_base const&))
|
||||
};
|
||||
|
||||
//! A TLS wrapper for small POD types with least possible overhead
|
||||
template< typename T >
|
||||
class thread_specific :
|
||||
public thread_specific_base
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(sizeof(T) <= sizeof(void*) && is_pod< T >::value, "Boost.Log: Thread-specific values must be PODs and must not exceed the size of a pointer");
|
||||
|
||||
//! Union to perform type casting
|
||||
union value_storage
|
||||
{
|
||||
void* as_pointer;
|
||||
T as_value;
|
||||
};
|
||||
|
||||
public:
|
||||
//! Default constructor
|
||||
BOOST_DEFAULTED_FUNCTION(thread_specific(), {})
|
||||
//! Initializing constructor
|
||||
thread_specific(T const& value)
|
||||
{
|
||||
set(value);
|
||||
}
|
||||
//! Assignment
|
||||
thread_specific& operator= (T const& value)
|
||||
{
|
||||
set(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Accessor
|
||||
T get() const
|
||||
{
|
||||
value_storage cast = {};
|
||||
cast.as_pointer = thread_specific_base::get_content();
|
||||
return cast.as_value;
|
||||
}
|
||||
|
||||
//! Setter
|
||||
void set(T const& value)
|
||||
{
|
||||
value_storage cast = {};
|
||||
cast.as_value = value;
|
||||
thread_specific_base::set_content(cast.as_pointer);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // !defined(BOOST_LOG_NO_THREADS)
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_THREAD_SPECIFIC_HPP_INCLUDED_
|
||||
@@ -0,0 +1,272 @@
|
||||
/*
|
||||
* 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 threadsafe_queue.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 05.11.2010
|
||||
*
|
||||
* \brief This header is the Boost.Log library implementation, see the library documentation
|
||||
* at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_THREADSAFE_QUEUE_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_THREADSAFE_QUEUE_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_LOG_NO_THREADS
|
||||
|
||||
#include <new>
|
||||
#include <memory>
|
||||
#include <cstddef>
|
||||
#include <boost/aligned_storage.hpp>
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include <boost/type_traits/alignment_of.hpp>
|
||||
#include <boost/type_traits/type_with_alignment.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace aux {
|
||||
|
||||
//! Base class for the thread-safe queue implementation
|
||||
struct threadsafe_queue_impl
|
||||
{
|
||||
struct BOOST_LOG_MAY_ALIAS pointer_storage
|
||||
{
|
||||
union
|
||||
{
|
||||
void* data[2];
|
||||
type_with_alignment< 2 * sizeof(void*) >::type alignment;
|
||||
};
|
||||
};
|
||||
|
||||
struct node_base
|
||||
{
|
||||
pointer_storage next;
|
||||
};
|
||||
|
||||
static BOOST_LOG_API threadsafe_queue_impl* create(node_base* first_node);
|
||||
|
||||
static BOOST_LOG_API void* operator new (std::size_t size);
|
||||
static BOOST_LOG_API void operator delete (void* p, std::size_t);
|
||||
|
||||
virtual ~threadsafe_queue_impl() {}
|
||||
virtual node_base* reset_last_node() = 0;
|
||||
virtual bool unsafe_empty() = 0;
|
||||
virtual void push(node_base* p) = 0;
|
||||
virtual bool try_pop(node_base*& node_to_free, node_base*& node_with_value) = 0;
|
||||
};
|
||||
|
||||
//! A helper class to compose some of the types used by the queue
|
||||
template< typename T, typename AllocatorT >
|
||||
struct threadsafe_queue_types
|
||||
{
|
||||
struct node :
|
||||
public threadsafe_queue_impl::node_base
|
||||
{
|
||||
typedef typename aligned_storage< sizeof(T), alignment_of< T >::value >::type storage_type;
|
||||
storage_type storage;
|
||||
|
||||
node() {}
|
||||
explicit node(T const& val) { new (storage.address()) T(val); }
|
||||
T& value() { return *static_cast< T* >(storage.address()); }
|
||||
void destroy() { static_cast< T* >(storage.address())->~T(); }
|
||||
};
|
||||
|
||||
typedef typename AllocatorT::BOOST_NESTED_TEMPLATE rebind< node >::other allocator_type;
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief An unbounded thread-safe queue
|
||||
*
|
||||
* The implementation is based on algorithms published in the "Simple, Fast,
|
||||
* and Practical Non-Blocking and Blocking Concurrent Queue Algorithms" article
|
||||
* in PODC96 by Maged M. Michael and Michael L. Scott. Pseudocode is available here:
|
||||
* http://www.cs.rochester.edu/research/synchronization/pseudocode/queues.html
|
||||
*
|
||||
* The implementation provides thread-safe \c push and \c try_pop operations, as well as
|
||||
* a thread-unsafe \c empty operation. The queue imposes the following requirements
|
||||
* on the element type:
|
||||
*
|
||||
* \li Default constructible, the default constructor must not throw.
|
||||
* \li Copy constructible.
|
||||
* \li Movable (i.e. there should be an efficient move assignment for this type).
|
||||
*
|
||||
* The last requirement is not mandatory but is crucial for decent performance.
|
||||
*/
|
||||
template< typename T, typename AllocatorT = std::allocator< void > >
|
||||
class threadsafe_queue :
|
||||
private threadsafe_queue_types< T, AllocatorT >::allocator_type
|
||||
{
|
||||
private:
|
||||
typedef typename threadsafe_queue_types< T, AllocatorT >::allocator_type base_type;
|
||||
typedef typename threadsafe_queue_types< T, AllocatorT >::node node;
|
||||
|
||||
//! A simple scope guard to automate memory reclaiming
|
||||
struct auto_deallocate;
|
||||
friend struct auto_deallocate;
|
||||
struct auto_deallocate
|
||||
{
|
||||
auto_deallocate(base_type* alloc, node* dealloc, node* destr) :
|
||||
m_pAllocator(alloc),
|
||||
m_pDeallocate(dealloc),
|
||||
m_pDestroy(destr)
|
||||
{
|
||||
}
|
||||
~auto_deallocate()
|
||||
{
|
||||
m_pAllocator->deallocate(m_pDeallocate, 1);
|
||||
m_pDestroy->destroy();
|
||||
}
|
||||
|
||||
private:
|
||||
base_type* m_pAllocator;
|
||||
node* m_pDeallocate;
|
||||
node* m_pDestroy;
|
||||
};
|
||||
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T& reference;
|
||||
typedef T const& const_reference;
|
||||
typedef T* pointer;
|
||||
typedef T const* const_pointer;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef std::size_t size_type;
|
||||
typedef AllocatorT allocator_type;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Default constructor, creates an empty queue. Unlike most containers,
|
||||
* the constructor requires memory allocation.
|
||||
*
|
||||
* \throw std::bad_alloc if there is not sufficient memory
|
||||
*/
|
||||
threadsafe_queue(base_type const& alloc = base_type()) :
|
||||
base_type(alloc)
|
||||
{
|
||||
node* p = base_type::allocate(1);
|
||||
if (p)
|
||||
{
|
||||
try
|
||||
{
|
||||
new (p) node();
|
||||
try
|
||||
{
|
||||
m_pImpl = threadsafe_queue_impl::create(p);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
p->~node();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
base_type::deallocate(p, 1);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
else
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
/*!
|
||||
* Destructor
|
||||
*/
|
||||
~threadsafe_queue()
|
||||
{
|
||||
// Clear the queue
|
||||
if (!unsafe_empty())
|
||||
{
|
||||
value_type value;
|
||||
while (try_pop(value));
|
||||
}
|
||||
|
||||
// Remove the last dummy node
|
||||
node* p = static_cast< node* >(m_pImpl->reset_last_node());
|
||||
p->~node();
|
||||
base_type::deallocate(p, 1);
|
||||
|
||||
delete m_pImpl;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Checks if the queue is empty. Not thread-safe, the returned result may not be actual.
|
||||
*/
|
||||
bool unsafe_empty() const { return m_pImpl->unsafe_empty(); }
|
||||
|
||||
/*!
|
||||
* Puts a new element to the end of the queue. Thread-safe, can be called
|
||||
* concurrently by several threads, and concurrently with the \c pop operation.
|
||||
*/
|
||||
void push(const_reference value)
|
||||
{
|
||||
node* p = base_type::allocate(1);
|
||||
if (p)
|
||||
{
|
||||
try
|
||||
{
|
||||
new (p) node(value);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
base_type::deallocate(p, 1);
|
||||
throw;
|
||||
}
|
||||
m_pImpl->push(p);
|
||||
}
|
||||
else
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Attempts to pop an element from the beginning of the queue. Thread-safe, can
|
||||
* be called concurrently with the \c push operation. Should not be called by
|
||||
* several threads concurrently.
|
||||
*/
|
||||
bool try_pop(reference value)
|
||||
{
|
||||
threadsafe_queue_impl::node_base *dealloc, *destr;
|
||||
if (m_pImpl->try_pop(dealloc, destr))
|
||||
{
|
||||
node* p = static_cast< node* >(destr);
|
||||
auto_deallocate guard(static_cast< base_type* >(this), static_cast< node* >(dealloc), p);
|
||||
value = boost::move(p->value());
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
// Copying and assignment is prohibited
|
||||
BOOST_DELETED_FUNCTION(threadsafe_queue(threadsafe_queue const&))
|
||||
BOOST_DELETED_FUNCTION(threadsafe_queue& operator= (threadsafe_queue const&))
|
||||
|
||||
private:
|
||||
//! Pointer to the implementation
|
||||
threadsafe_queue_impl* m_pImpl;
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_NO_THREADS
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_THREADSAFE_QUEUE_HPP_INCLUDED_
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* 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 timestamp.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 31.07.2011
|
||||
*
|
||||
* \brief This header is the Boost.Log library implementation, see the library documentation
|
||||
* at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_TIMESTAMP_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_TIMESTAMP_HPP_INCLUDED_
|
||||
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#if defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
|
||||
#include <boost/detail/winapi/basic_types.hpp>
|
||||
#endif
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace aux {
|
||||
|
||||
/*!
|
||||
* Duration between two timestamps
|
||||
*/
|
||||
class duration
|
||||
{
|
||||
int64_t m_ticks;
|
||||
|
||||
public:
|
||||
explicit duration(int64_t ticks = 0) : m_ticks(ticks) {}
|
||||
|
||||
#if defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
|
||||
int64_t milliseconds() const { return m_ticks; }
|
||||
#else
|
||||
BOOST_LOG_API int64_t milliseconds() const;
|
||||
#endif
|
||||
};
|
||||
|
||||
/*!
|
||||
* Opaque timestamp class
|
||||
*/
|
||||
class timestamp
|
||||
{
|
||||
uint64_t m_ticks;
|
||||
|
||||
public:
|
||||
explicit timestamp(uint64_t ticks = 0) : m_ticks(ticks) {}
|
||||
|
||||
duration operator- (timestamp that) const
|
||||
{
|
||||
return duration(m_ticks - that.m_ticks);
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* \fn get_timestamp
|
||||
*
|
||||
* The function returns a timestamp, in opaque units since an unspecified
|
||||
* time point. This timer is guaranteed to be monotonic, it should not
|
||||
* be affected by clock changes, either manual or seasonal. Also, it
|
||||
* should be as fast as possible.
|
||||
*/
|
||||
#if defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
|
||||
|
||||
typedef uint64_t (WINAPI* get_tick_count_t)();
|
||||
extern BOOST_LOG_API get_tick_count_t get_tick_count;
|
||||
|
||||
inline timestamp get_timestamp()
|
||||
{
|
||||
return timestamp(get_tick_count());
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
typedef timestamp (*get_timestamp_t)();
|
||||
extern BOOST_LOG_API get_timestamp_t get_timestamp;
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace aux
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_TIMESTAMP_HPP_INCLUDED_
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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 trivial_keyword.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 02.12.2012
|
||||
*
|
||||
* \brief This header is the Boost.Log library implementation, see the library documentation
|
||||
* at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_TRIVIAL_KEYWORD_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_TRIVIAL_KEYWORD_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace trivial {
|
||||
|
||||
//! Trivial severity keyword
|
||||
BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", severity_level)
|
||||
|
||||
} // namespace trivial
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_TRIVIAL_KEYWORD_HPP_INCLUDED_
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* 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 unary_function_terminal.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 21.07.2012
|
||||
*
|
||||
* The header contains attribute value extractor adapter for constructing expression template terminals.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_UNARY_FUNCTION_TERMINAL_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_UNARY_FUNCTION_TERMINAL_HPP_INCLUDED_
|
||||
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/utility/result_of.hpp>
|
||||
#include <boost/fusion/sequence/intrinsic/at_c.hpp>
|
||||
#include <boost/phoenix/core/is_nullary.hpp>
|
||||
#include <boost/phoenix/core/environment.hpp>
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/copy_cv.hpp>
|
||||
#include <boost/log/detail/custom_terminal_spec.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace expressions {
|
||||
|
||||
namespace aux {
|
||||
|
||||
/*!
|
||||
* \brief An adapter for a unary function to be used as a terminal in a Boost.Phoenix expression
|
||||
*
|
||||
* This class is an adapter between Boost.Phoenix expression invocation protocol and
|
||||
* a unary function. It forwards the call to the base function, passing only the first argument
|
||||
* from the original call. This allows to embed value extractors in template expressions.
|
||||
*/
|
||||
template< typename FunT >
|
||||
class unary_function_terminal
|
||||
{
|
||||
private:
|
||||
//! Adopted function type
|
||||
typedef FunT function_type;
|
||||
//! Self type
|
||||
typedef unary_function_terminal< function_type > this_type;
|
||||
|
||||
public:
|
||||
//! Internal typedef for type categorization
|
||||
typedef void _is_boost_log_terminal;
|
||||
|
||||
//! Function result type
|
||||
template< typename >
|
||||
struct result;
|
||||
|
||||
template< typename ThisT, typename ContextT >
|
||||
struct result< ThisT(ContextT) >
|
||||
{
|
||||
typedef typename remove_cv<
|
||||
typename remove_reference< typename phoenix::result_of::env< ContextT >::type >::type
|
||||
>::type env_type;
|
||||
typedef typename env_type::args_type args_type;
|
||||
typedef typename boost::log::aux::copy_cv< ThisT, function_type >::type cv_function_type;
|
||||
|
||||
typedef typename boost::result_of< cv_function_type(typename fusion::result_of::at_c< args_type, 0 >::type) >::type type;
|
||||
};
|
||||
|
||||
private:
|
||||
//! Adopted function
|
||||
function_type m_fun;
|
||||
|
||||
public:
|
||||
//! Default constructor
|
||||
BOOST_DEFAULTED_FUNCTION(unary_function_terminal(), {})
|
||||
//! Copy constructor
|
||||
unary_function_terminal(unary_function_terminal const& that) : m_fun(that.m_fun) {}
|
||||
//! Initializing constructor
|
||||
template< typename ArgT1 >
|
||||
explicit unary_function_terminal(ArgT1 const& arg1) : m_fun(arg1) {}
|
||||
//! Initializing constructor
|
||||
template< typename ArgT1, typename ArgT2 >
|
||||
unary_function_terminal(ArgT1 const& arg1, ArgT2 const& arg2) : m_fun(arg1, arg2) {}
|
||||
//! Initializing constructor
|
||||
template< typename ArgT1, typename ArgT2, typename ArgT3 >
|
||||
unary_function_terminal(ArgT1 const& arg1, ArgT2 const& arg2, ArgT3 const& arg3) : m_fun(arg1, arg2, arg3) {}
|
||||
|
||||
//! The operator forwards the call to the base function
|
||||
template< typename ContextT >
|
||||
typename result< this_type(ContextT const&) >::type
|
||||
operator() (ContextT const& ctx)
|
||||
{
|
||||
return m_fun(fusion::at_c< 0 >(phoenix::env(ctx).args()));
|
||||
}
|
||||
|
||||
//! The operator forwards the call to the base function
|
||||
template< typename ContextT >
|
||||
typename result< const this_type(ContextT const&) >::type
|
||||
operator() (ContextT const& ctx) const
|
||||
{
|
||||
return m_fun(fusion::at_c< 0 >(phoenix::env(ctx).args()));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
} // namespace expressions
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
namespace phoenix {
|
||||
|
||||
namespace result_of {
|
||||
|
||||
template< typename FunT >
|
||||
struct is_nullary< custom_terminal< boost::log::expressions::aux::unary_function_terminal< FunT > > > :
|
||||
public mpl::false_
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace result_of
|
||||
|
||||
} // namespace phoenix
|
||||
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_UNARY_FUNCTION_TERMINAL_HPP_INCLUDED_
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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 unhandled_exception_count.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 05.11.2012
|
||||
*
|
||||
* \brief This header is the Boost.Log library implementation, see the library documentation
|
||||
* at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_UNHANDLED_EXCEPTION_COUNT_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_UNHANDLED_EXCEPTION_COUNT_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace aux {
|
||||
|
||||
//! Returns the number of currently pending exceptions
|
||||
BOOST_LOG_API unsigned int unhandled_exception_count() BOOST_NOEXCEPT;
|
||||
|
||||
} // namespace aux
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_UNHANDLED_EXCEPTION_COUNT_HPP_INCLUDED_
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* 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 value_ref_visitation.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 28.07.2012
|
||||
*
|
||||
* \brief This header is the Boost.Log library implementation, see the library documentation
|
||||
* at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html. In this file
|
||||
* internal configuration macros are defined.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DETAIL_VALUE_REF_VISITATION_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DETAIL_VALUE_REF_VISITATION_HPP_INCLUDED_
|
||||
|
||||
#include <boost/mpl/at.hpp>
|
||||
#include <boost/mpl/begin.hpp>
|
||||
#include <boost/mpl/end.hpp>
|
||||
#include <boost/mpl/advance.hpp>
|
||||
#include <boost/mpl/erase.hpp>
|
||||
#include <boost/mpl/size.hpp>
|
||||
#include <boost/preprocessor/arithmetic/inc.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
|
||||
#include <boost/preprocessor/iteration/iterate.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifndef BOOST_LOG_VALUE_REF_VISITATION_UNROLL_COUNT
|
||||
#define BOOST_LOG_VALUE_REF_VISITATION_UNROLL_COUNT 8
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace aux {
|
||||
|
||||
template< typename SequenceT, typename VisitorT, unsigned int SizeV = mpl::size< SequenceT >::value >
|
||||
struct apply_visitor_dispatch
|
||||
{
|
||||
typedef typename VisitorT::result_type result_type;
|
||||
|
||||
static BOOST_FORCEINLINE result_type call(const void* p, unsigned int type_index, VisitorT& visitor)
|
||||
{
|
||||
typedef typename mpl::begin< SequenceT >::type begin_type;
|
||||
typedef typename mpl::advance_c< begin_type, SizeV / 2u >::type middle_type;
|
||||
if (type_index < (SizeV / 2u))
|
||||
{
|
||||
typedef typename mpl::erase< SequenceT, middle_type, typename mpl::end< SequenceT >::type >::type new_sequence;
|
||||
typedef apply_visitor_dispatch< new_sequence, VisitorT > new_dispatch;
|
||||
return new_dispatch::call(p, type_index, visitor);
|
||||
}
|
||||
else
|
||||
{
|
||||
typedef typename mpl::erase< SequenceT, begin_type, middle_type >::type new_sequence;
|
||||
typedef apply_visitor_dispatch< new_sequence, VisitorT > new_dispatch;
|
||||
return new_dispatch::call(p, type_index - (SizeV / 2u), visitor);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#define BOOST_LOG_AUX_CASE_ENTRY(z, i, data)\
|
||||
case i: return visitor(*static_cast< typename mpl::at_c< SequenceT, i >::type const* >(p));
|
||||
|
||||
#define BOOST_PP_FILENAME_1 <boost/log/detail/value_ref_visitation.hpp>
|
||||
#define BOOST_PP_ITERATION_LIMITS (1, BOOST_PP_INC(BOOST_LOG_VALUE_REF_VISITATION_VTABLE_SIZE))
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
#undef BOOST_LOG_AUX_CASE_ENTRY
|
||||
|
||||
} // namespace aux
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_DETAIL_VALUE_REF_VISITATION_HPP_INCLUDED_
|
||||
|
||||
#ifdef BOOST_PP_IS_ITERATING
|
||||
|
||||
#define BOOST_LOG_AUX_SWITCH_SIZE BOOST_PP_ITERATION()
|
||||
|
||||
template< typename SequenceT, typename VisitorT >
|
||||
struct apply_visitor_dispatch< SequenceT, VisitorT, BOOST_LOG_AUX_SWITCH_SIZE >
|
||||
{
|
||||
typedef typename VisitorT::result_type result_type;
|
||||
|
||||
static BOOST_FORCEINLINE result_type call(const void* p, unsigned int type_index, VisitorT& visitor)
|
||||
{
|
||||
switch (type_index)
|
||||
{
|
||||
BOOST_PP_REPEAT_FROM_TO(1, BOOST_LOG_AUX_SWITCH_SIZE, BOOST_LOG_AUX_CASE_ENTRY, ~)
|
||||
default:
|
||||
return visitor(*static_cast< typename mpl::at_c< SequenceT, 0 >::type const* >(p));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#undef BOOST_LOG_AUX_SWITCH_SIZE
|
||||
|
||||
#endif // BOOST_PP_IS_ITERATING
|
||||
@@ -0,0 +1,469 @@
|
||||
/*
|
||||
* 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
|
||||
* \author Andrey Semashev
|
||||
* \date 31.10.2009
|
||||
*
|
||||
* The header contains exception classes declarations.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_EXCEPTIONS_HPP_INCLUDED_
|
||||
#define BOOST_LOG_EXCEPTIONS_HPP_INCLUDED_
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <boost/type_index.hpp>
|
||||
#include <boost/preprocessor/seq/enum.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
#include <boost/system/system_error.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/attributes/attribute_name.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
// Forward-declaration of an exception base class from Boost.Exception
|
||||
#if defined(__GNUC__)
|
||||
# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)
|
||||
# pragma GCC visibility push (default)
|
||||
|
||||
class exception;
|
||||
|
||||
# pragma GCC visibility pop
|
||||
# else
|
||||
|
||||
class exception;
|
||||
|
||||
# endif
|
||||
#else
|
||||
|
||||
class BOOST_SYMBOL_VISIBLE exception;
|
||||
|
||||
#endif
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace aux {
|
||||
|
||||
//! Attaches attribute name exception information
|
||||
BOOST_LOG_API void attach_attribute_name_info(exception& e, attribute_name const& name);
|
||||
|
||||
} // namespace aux
|
||||
|
||||
/*!
|
||||
* \brief Base class for memory allocation errors
|
||||
*
|
||||
* Exceptions derived from this class indicate problems with memory allocation.
|
||||
*/
|
||||
class BOOST_LOG_API bad_alloc :
|
||||
public std::bad_alloc
|
||||
{
|
||||
private:
|
||||
std::string m_message;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Initializing constructor. Creates an exception with the specified error message.
|
||||
*/
|
||||
explicit bad_alloc(const char* descr);
|
||||
/*!
|
||||
* Initializing constructor. Creates an exception with the specified error message.
|
||||
*/
|
||||
explicit bad_alloc(std::string const& descr);
|
||||
/*!
|
||||
* Destructor
|
||||
*/
|
||||
~bad_alloc() throw();
|
||||
|
||||
/*!
|
||||
* Error message accessor.
|
||||
*/
|
||||
const char* what() const throw();
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, const char* descr);
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, std::string const& descr);
|
||||
#endif
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief The exception is used to indicate reaching a storage capacity limit
|
||||
*/
|
||||
class BOOST_LOG_API capacity_limit_reached :
|
||||
public bad_alloc
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* Initializing constructor. Creates an exception with the specified error message.
|
||||
*/
|
||||
explicit capacity_limit_reached(const char* descr);
|
||||
/*!
|
||||
* Initializing constructor. Creates an exception with the specified error message.
|
||||
*/
|
||||
explicit capacity_limit_reached(std::string const& descr);
|
||||
/*!
|
||||
* Destructor
|
||||
*/
|
||||
~capacity_limit_reached() throw();
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, const char* descr);
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, std::string const& descr);
|
||||
#endif
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Base class for runtime exceptions from the logging library
|
||||
*
|
||||
* Exceptions derived from this class indicate a problem that may not directly
|
||||
* be caused by the user's code that interacts with the library, such as
|
||||
* errors caused by input data.
|
||||
*/
|
||||
class BOOST_LOG_API runtime_error :
|
||||
public std::runtime_error
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* Initializing constructor. Creates an exception with the specified error message.
|
||||
*/
|
||||
explicit runtime_error(std::string const& descr);
|
||||
/*!
|
||||
* Destructor
|
||||
*/
|
||||
~runtime_error() throw();
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Exception class that is used to indicate errors of missing values
|
||||
*/
|
||||
class BOOST_LOG_API missing_value :
|
||||
public runtime_error
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* Default constructor. Creates an exception with the default error message.
|
||||
*/
|
||||
missing_value();
|
||||
/*!
|
||||
* Initializing constructor. Creates an exception with the specified error message.
|
||||
*/
|
||||
explicit missing_value(std::string const& descr);
|
||||
/*!
|
||||
* Destructor
|
||||
*/
|
||||
~missing_value() throw();
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line);
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, const char* descr);
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, std::string const& descr);
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, const char* descr, attribute_name const& name);
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, std::string const& descr, attribute_name const& name);
|
||||
#endif
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Exception class that is used to indicate errors of incorrect type of an object
|
||||
*/
|
||||
class BOOST_LOG_API invalid_type :
|
||||
public runtime_error
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* Default constructor. Creates an exception with the default error message.
|
||||
*/
|
||||
invalid_type();
|
||||
/*!
|
||||
* Initializing constructor. Creates an exception with the specified error message.
|
||||
*/
|
||||
explicit invalid_type(std::string const& descr);
|
||||
/*!
|
||||
* Destructor
|
||||
*/
|
||||
~invalid_type() throw();
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line);
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, const char* descr);
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, std::string const& descr);
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, const char* descr, attribute_name const& name);
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, std::string const& descr, attribute_name const& name);
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, const char* descr, typeindex::type_index const& type);
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, std::string const& descr, typeindex::type_index const& type);
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, const char* descr, attribute_name const& name, typeindex::type_index const& type);
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, std::string const& descr, attribute_name const& name, typeindex::type_index const& type);
|
||||
#endif
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Exception class that is used to indicate errors of incorrect value of an object
|
||||
*/
|
||||
class BOOST_LOG_API invalid_value :
|
||||
public runtime_error
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* Default constructor. Creates an exception with the default error message.
|
||||
*/
|
||||
invalid_value();
|
||||
/*!
|
||||
* Initializing constructor. Creates an exception with the specified error message.
|
||||
*/
|
||||
explicit invalid_value(std::string const& descr);
|
||||
/*!
|
||||
* Destructor
|
||||
*/
|
||||
~invalid_value() throw();
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line);
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, const char* descr);
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, std::string const& descr);
|
||||
#endif
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Exception class that is used to indicate parsing errors
|
||||
*/
|
||||
class BOOST_LOG_API parse_error :
|
||||
public runtime_error
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* Default constructor. Creates an exception with the default error message.
|
||||
*/
|
||||
parse_error();
|
||||
/*!
|
||||
* Initializing constructor. Creates an exception with the specified error message.
|
||||
*/
|
||||
explicit parse_error(std::string const& descr);
|
||||
/*!
|
||||
* Destructor
|
||||
*/
|
||||
~parse_error() throw();
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line);
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, const char* descr);
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, std::string const& descr);
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, const char* descr, std::size_t content_line);
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, std::string const& descr, std::size_t content_line);
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, const char* descr, attribute_name const& name);
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, std::string const& descr, attribute_name const& name);
|
||||
#endif
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Exception class that is used to indicate conversion errors
|
||||
*/
|
||||
class BOOST_LOG_API conversion_error :
|
||||
public runtime_error
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* Default constructor. Creates an exception with the default error message.
|
||||
*/
|
||||
conversion_error();
|
||||
/*!
|
||||
* Initializing constructor. Creates an exception with the specified error message.
|
||||
*/
|
||||
explicit conversion_error(std::string const& descr);
|
||||
/*!
|
||||
* Destructor
|
||||
*/
|
||||
~conversion_error() throw();
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line);
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, const char* descr);
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, std::string const& descr);
|
||||
#endif
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Exception class that is used to indicate underlying OS API errors
|
||||
*/
|
||||
class BOOST_LOG_API system_error :
|
||||
public boost::system::system_error
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* Initializing constructor. Creates an exception with the specified error message.
|
||||
*/
|
||||
system_error(boost::system::error_code code, std::string const& descr);
|
||||
/*!
|
||||
* Destructor
|
||||
*/
|
||||
~system_error() throw();
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, const char* descr, int system_error_code);
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, std::string const& descr, int system_error_code);
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, const char* descr, boost::system::error_code code);
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, std::string const& descr, boost::system::error_code code);
|
||||
#endif
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Base class for logic exceptions from the logging library
|
||||
*
|
||||
* Exceptions derived from this class usually indicate errors on the user's side, such as
|
||||
* incorrect library usage.
|
||||
*/
|
||||
class BOOST_LOG_API logic_error :
|
||||
public std::logic_error
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* Initializing constructor. Creates an exception with the specified error message.
|
||||
*/
|
||||
explicit logic_error(std::string const& descr);
|
||||
/*!
|
||||
* Destructor
|
||||
*/
|
||||
~logic_error() throw();
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, const char* descr);
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, std::string const& descr);
|
||||
#endif
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Exception class that is used to indicate ODR violation
|
||||
*/
|
||||
class BOOST_LOG_API odr_violation :
|
||||
public logic_error
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* Default constructor. Creates an exception with the default error message.
|
||||
*/
|
||||
odr_violation();
|
||||
/*!
|
||||
* Initializing constructor. Creates an exception with the specified error message.
|
||||
*/
|
||||
explicit odr_violation(std::string const& descr);
|
||||
/*!
|
||||
* Destructor
|
||||
*/
|
||||
~odr_violation() throw();
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line);
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, const char* descr);
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, std::string const& descr);
|
||||
#endif
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Exception class that is used to indicate invalid call sequence
|
||||
*/
|
||||
class BOOST_LOG_API unexpected_call :
|
||||
public logic_error
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* Default constructor. Creates an exception with the default error message.
|
||||
*/
|
||||
unexpected_call();
|
||||
/*!
|
||||
* Initializing constructor. Creates an exception with the specified error message.
|
||||
*/
|
||||
explicit unexpected_call(std::string const& descr);
|
||||
/*!
|
||||
* Destructor
|
||||
*/
|
||||
~unexpected_call() throw();
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line);
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, const char* descr);
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, std::string const& descr);
|
||||
#endif
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Exception class that is used to indicate invalid library setup
|
||||
*/
|
||||
class BOOST_LOG_API setup_error :
|
||||
public logic_error
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* Default constructor. Creates an exception with the default error message.
|
||||
*/
|
||||
setup_error();
|
||||
/*!
|
||||
* Initializing constructor. Creates an exception with the specified error message.
|
||||
*/
|
||||
explicit setup_error(std::string const& descr);
|
||||
/*!
|
||||
* Destructor
|
||||
*/
|
||||
~setup_error() throw();
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line);
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, const char* descr);
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, std::string const& descr);
|
||||
#endif
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Exception class that is used to indicate library limitation
|
||||
*/
|
||||
class BOOST_LOG_API limitation_error :
|
||||
public logic_error
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* Default constructor. Creates an exception with the default error message.
|
||||
*/
|
||||
limitation_error();
|
||||
/*!
|
||||
* Initializing constructor. Creates an exception with the specified error message.
|
||||
*/
|
||||
explicit limitation_error(std::string const& descr);
|
||||
/*!
|
||||
* Destructor
|
||||
*/
|
||||
~limitation_error() throw();
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line);
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, const char* descr);
|
||||
static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, std::string const& descr);
|
||||
#endif
|
||||
};
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
#define BOOST_LOG_THROW(ex)\
|
||||
ex::throw_(__FILE__, static_cast< std::size_t >(__LINE__))
|
||||
|
||||
#define BOOST_LOG_THROW_DESCR(ex, descr)\
|
||||
ex::throw_(__FILE__, static_cast< std::size_t >(__LINE__), descr)
|
||||
|
||||
#define BOOST_LOG_THROW_DESCR_PARAMS(ex, descr, params)\
|
||||
ex::throw_(__FILE__, static_cast< std::size_t >(__LINE__), descr, BOOST_PP_SEQ_ENUM(params))
|
||||
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_EXCEPTIONS_HPP_INCLUDED_
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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 expressions.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 10.11.2012
|
||||
*
|
||||
* This header includes other Boost.Log headers with all template expression tools.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_EXPRESSIONS_HPP_INCLUDED_
|
||||
#define BOOST_LOG_EXPRESSIONS_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
|
||||
#include <boost/log/expressions/attr.hpp>
|
||||
#include <boost/log/expressions/keyword.hpp>
|
||||
#include <boost/log/expressions/message.hpp>
|
||||
#include <boost/log/expressions/record.hpp>
|
||||
|
||||
#include <boost/log/expressions/predicates.hpp>
|
||||
#include <boost/log/expressions/formatters.hpp>
|
||||
|
||||
#include <boost/log/expressions/filter.hpp>
|
||||
#include <boost/log/expressions/formatter.hpp>
|
||||
|
||||
// Boost.Phoenix operators are likely to be used with Boost.Log expression nodes anyway
|
||||
#include <boost/phoenix/operator.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#endif // BOOST_LOG_EXPRESSIONS_HPP_INCLUDED_
|
||||
@@ -0,0 +1,278 @@
|
||||
/*
|
||||
* 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 attr.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 21.07.2012
|
||||
*
|
||||
* The header contains implementation of a generic attribute placeholder in template expressions.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_EXPRESSIONS_ATTR_HPP_INCLUDED_
|
||||
#define BOOST_LOG_EXPRESSIONS_ATTR_HPP_INCLUDED_
|
||||
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/utility/result_of.hpp>
|
||||
#include <boost/phoenix/core/actor.hpp>
|
||||
#include <boost/phoenix/core/terminal_fwd.hpp>
|
||||
#include <boost/phoenix/core/is_nullary.hpp>
|
||||
#include <boost/phoenix/core/environment.hpp>
|
||||
#include <boost/fusion/sequence/intrinsic/at_c.hpp>
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/copy_cv.hpp>
|
||||
#include <boost/log/detail/custom_terminal_spec.hpp>
|
||||
#include <boost/log/attributes/attribute_name.hpp>
|
||||
#include <boost/log/attributes/value_extraction.hpp>
|
||||
#include <boost/log/attributes/fallback_policy.hpp>
|
||||
#include <boost/log/expressions/attr_fwd.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace expressions {
|
||||
|
||||
/*!
|
||||
* An attribute value extraction terminal
|
||||
*/
|
||||
template< typename T, typename FallbackPolicyT, typename TagT >
|
||||
class attribute_terminal
|
||||
{
|
||||
private:
|
||||
//! Value extractor type
|
||||
typedef value_extractor< T, FallbackPolicyT, TagT > value_extractor_type;
|
||||
//! Self type
|
||||
typedef attribute_terminal< T, FallbackPolicyT, TagT > this_type;
|
||||
|
||||
public:
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
//! Internal typedef for type categorization
|
||||
typedef void _is_boost_log_terminal;
|
||||
#endif
|
||||
|
||||
//! Attribute tag type
|
||||
typedef TagT tag_type;
|
||||
//! Attribute value type
|
||||
typedef typename value_extractor_type::value_type value_type;
|
||||
//! Fallback policy type
|
||||
typedef typename value_extractor_type::fallback_policy fallback_policy;
|
||||
|
||||
//! Function result type
|
||||
template< typename >
|
||||
struct result;
|
||||
|
||||
template< typename ThisT, typename ContextT >
|
||||
struct result< ThisT(ContextT) >
|
||||
{
|
||||
typedef typename remove_cv<
|
||||
typename remove_reference< typename phoenix::result_of::env< ContextT >::type >::type
|
||||
>::type env_type;
|
||||
typedef typename env_type::args_type args_type;
|
||||
typedef typename boost::log::aux::copy_cv< ThisT, value_extractor_type >::type cv_value_extractor_type;
|
||||
|
||||
typedef typename boost::result_of< cv_value_extractor_type(attribute_name const&, typename fusion::result_of::at_c< args_type, 0 >::type) >::type type;
|
||||
};
|
||||
|
||||
private:
|
||||
//! Attribute value name
|
||||
const attribute_name m_name;
|
||||
//! Attribute value extractor
|
||||
value_extractor_type m_value_extractor;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Initializing constructor
|
||||
*/
|
||||
explicit attribute_terminal(attribute_name const& name) : m_name(name)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* Initializing constructor
|
||||
*/
|
||||
template< typename U >
|
||||
attribute_terminal(attribute_name const& name, U const& arg) : m_name(name), m_value_extractor(arg)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* \returns Attribute value name
|
||||
*/
|
||||
attribute_name get_name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \returns Fallback policy
|
||||
*/
|
||||
fallback_policy const& get_fallback_policy() const
|
||||
{
|
||||
return m_value_extractor.get_fallback_policy();
|
||||
}
|
||||
|
||||
/*!
|
||||
* The operator extracts attribute value
|
||||
*/
|
||||
template< typename ContextT >
|
||||
typename result< this_type(ContextT const&) >::type
|
||||
operator() (ContextT const& ctx)
|
||||
{
|
||||
return m_value_extractor(m_name, fusion::at_c< 0 >(phoenix::env(ctx).args()));
|
||||
}
|
||||
|
||||
/*!
|
||||
* The operator extracts attribute value
|
||||
*/
|
||||
template< typename ContextT >
|
||||
typename result< const this_type(ContextT const&) >::type
|
||||
operator() (ContextT const& ctx) const
|
||||
{
|
||||
return m_value_extractor(m_name, fusion::at_c< 0 >(phoenix::env(ctx).args()));
|
||||
}
|
||||
|
||||
BOOST_DELETED_FUNCTION(attribute_terminal())
|
||||
};
|
||||
|
||||
/*!
|
||||
* An attribute value extraction terminal actor
|
||||
*/
|
||||
template< typename T, typename FallbackPolicyT, typename TagT, template< typename > class ActorT >
|
||||
class attribute_actor :
|
||||
public ActorT< attribute_terminal< T, FallbackPolicyT, TagT > >
|
||||
{
|
||||
public:
|
||||
//! Attribute tag type
|
||||
typedef TagT tag_type;
|
||||
//! Fallback policy
|
||||
typedef FallbackPolicyT fallback_policy;
|
||||
//! Base terminal type
|
||||
typedef attribute_terminal< T, fallback_policy, tag_type > terminal_type;
|
||||
//! Attribute value type
|
||||
typedef typename terminal_type::value_type value_type;
|
||||
|
||||
//! Base actor type
|
||||
typedef ActorT< terminal_type > base_type;
|
||||
|
||||
public:
|
||||
//! Initializing constructor
|
||||
explicit attribute_actor(base_type const& act) : base_type(act)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* \returns The attribute name
|
||||
*/
|
||||
attribute_name get_name() const
|
||||
{
|
||||
return this->proto_expr_.child0.get_name();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \returns Fallback policy
|
||||
*/
|
||||
fallback_policy const& get_fallback_policy() const
|
||||
{
|
||||
return this->proto_expr_.child0.get_fallback_policy();
|
||||
}
|
||||
|
||||
//! Expression with cached attribute name
|
||||
typedef attribute_actor< value_type, fallback_to_none, tag_type, ActorT > or_none_result_type;
|
||||
|
||||
//! Generates an expression that extracts the attribute value or a default value
|
||||
or_none_result_type or_none() const
|
||||
{
|
||||
typedef typename or_none_result_type::terminal_type result_terminal;
|
||||
typename or_none_result_type::base_type act = {{ result_terminal(get_name()) }};
|
||||
return or_none_result_type(act);
|
||||
}
|
||||
|
||||
//! Expression with cached attribute name
|
||||
typedef attribute_actor< value_type, fallback_to_throw, tag_type, ActorT > or_throw_result_type;
|
||||
|
||||
//! Generates an expression that extracts the attribute value or throws an exception
|
||||
or_throw_result_type or_throw() const
|
||||
{
|
||||
typedef typename or_throw_result_type::terminal_type result_terminal;
|
||||
typename or_throw_result_type::base_type act = {{ result_terminal(get_name()) }};
|
||||
return or_throw_result_type(act);
|
||||
}
|
||||
|
||||
//! Generates an expression that extracts the attribute value or a default value
|
||||
template< typename DefaultT >
|
||||
attribute_actor< value_type, fallback_to_default< DefaultT >, tag_type, ActorT > or_default(DefaultT const& def_val) const
|
||||
{
|
||||
typedef attribute_actor< value_type, fallback_to_default< DefaultT >, tag_type, ActorT > or_default_result_type;
|
||||
typedef typename or_default_result_type::terminal_type result_terminal;
|
||||
typename or_default_result_type::base_type act = {{ result_terminal(get_name(), def_val) }};
|
||||
return or_default_result_type(act);
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* The function generates a terminal node in a template expression. The node will extract the value of the attribute
|
||||
* with the specified name and type.
|
||||
*/
|
||||
template< typename AttributeValueT >
|
||||
BOOST_FORCEINLINE attribute_actor< AttributeValueT > attr(attribute_name const& name)
|
||||
{
|
||||
typedef attribute_actor< AttributeValueT > result_type;
|
||||
typedef typename result_type::terminal_type result_terminal;
|
||||
typename result_type::base_type act = {{ result_terminal(name) }};
|
||||
return result_type(act);
|
||||
}
|
||||
|
||||
/*!
|
||||
* The function generates a terminal node in a template expression. The node will extract the value of the attribute
|
||||
* with the specified name and type.
|
||||
*/
|
||||
template< typename AttributeValueT, typename TagT >
|
||||
BOOST_FORCEINLINE attribute_actor< AttributeValueT, fallback_to_none, TagT > attr(attribute_name const& name)
|
||||
{
|
||||
typedef attribute_actor< AttributeValueT, fallback_to_none, TagT > result_type;
|
||||
typedef typename result_type::terminal_type result_terminal;
|
||||
typename result_type::base_type act = {{ result_terminal(name) }};
|
||||
return result_type(act);
|
||||
}
|
||||
|
||||
} // namespace expressions
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
namespace phoenix {
|
||||
|
||||
namespace result_of {
|
||||
|
||||
template< typename T, typename FallbackPolicyT, typename TagT >
|
||||
struct is_nullary< custom_terminal< boost::log::expressions::attribute_terminal< T, FallbackPolicyT, TagT > > > :
|
||||
public mpl::false_
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace result_of
|
||||
|
||||
} // namespace phoenix
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
#if defined(BOOST_LOG_EXPRESSIONS_FORMATTERS_STREAM_HPP_INCLUDED_)
|
||||
#include <boost/log/detail/attr_output_impl.hpp>
|
||||
#endif
|
||||
|
||||
#endif // BOOST_LOG_EXPRESSIONS_ATTR_HPP_INCLUDED_
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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 attr_fwd.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 21.07.2012
|
||||
*
|
||||
* The header contains forward declaration of a generic attribute placeholder in template expressions.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_EXPRESSIONS_ATTR_FWD_HPP_INCLUDED_
|
||||
#define BOOST_LOG_EXPRESSIONS_ATTR_FWD_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/attributes/fallback_policy_fwd.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
namespace phoenix {
|
||||
|
||||
template< typename >
|
||||
struct actor;
|
||||
|
||||
} // namespace phoenix
|
||||
|
||||
#endif
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace expressions {
|
||||
|
||||
/*!
|
||||
* An attribute value extraction terminal
|
||||
*/
|
||||
template<
|
||||
typename T,
|
||||
typename FallbackPolicyT = fallback_to_none,
|
||||
typename TagT = void
|
||||
>
|
||||
class attribute_terminal;
|
||||
|
||||
/*!
|
||||
* An attribute value extraction terminal actor
|
||||
*/
|
||||
template<
|
||||
typename T,
|
||||
typename FallbackPolicyT = fallback_to_none,
|
||||
typename TagT = void,
|
||||
template< typename > class ActorT = phoenix::actor
|
||||
>
|
||||
class attribute_actor;
|
||||
|
||||
} // namespace expressions
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_LOG_EXPRESSIONS_ATTR_FWD_HPP_INCLUDED_
|
||||
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
* 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 filter.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 13.07.2012
|
||||
*
|
||||
* The header contains a filter function object definition.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_EXPRESSIONS_FILTER_HPP_INCLUDED_
|
||||
#define BOOST_LOG_EXPRESSIONS_FILTER_HPP_INCLUDED_
|
||||
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
#include <boost/log/detail/sfinae_tools.hpp>
|
||||
#endif
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/attributes/attribute_value_set.hpp>
|
||||
#include <boost/log/detail/light_function.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
/*!
|
||||
* Log record filter function wrapper.
|
||||
*/
|
||||
class filter
|
||||
{
|
||||
BOOST_COPYABLE_AND_MOVABLE(filter)
|
||||
|
||||
public:
|
||||
//! Result type
|
||||
typedef bool result_type;
|
||||
|
||||
private:
|
||||
//! Filter function type
|
||||
typedef boost::log::aux::light_function< bool (attribute_value_set const&) > filter_type;
|
||||
|
||||
//! Default filter, always returns \c true
|
||||
struct default_filter
|
||||
{
|
||||
typedef bool result_type;
|
||||
result_type operator() (attribute_value_set const&) const { return true; }
|
||||
};
|
||||
|
||||
private:
|
||||
//! Filter function
|
||||
filter_type m_Filter;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Default constructor. Creates a filter that always returns \c true.
|
||||
*/
|
||||
filter() : m_Filter(default_filter())
|
||||
{
|
||||
}
|
||||
/*!
|
||||
* Copy constructor
|
||||
*/
|
||||
filter(filter const& that) : m_Filter(that.m_Filter)
|
||||
{
|
||||
}
|
||||
/*!
|
||||
* Move constructor. The moved-from filter is left in an unspecified state.
|
||||
*/
|
||||
filter(BOOST_RV_REF(filter) that) BOOST_NOEXCEPT : m_Filter(boost::move(that.m_Filter))
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* Initializing constructor. Creates a filter which will invoke the specified function object.
|
||||
*/
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
template< typename FunT >
|
||||
filter(FunT&& fun) : m_Filter(boost::forward< FunT >(fun))
|
||||
{
|
||||
}
|
||||
#elif !defined(BOOST_MSVC) || BOOST_MSVC >= 1600
|
||||
template< typename FunT >
|
||||
filter(FunT const& fun, typename boost::disable_if_c< move_detail::is_rv< FunT >::value, boost::log::aux::sfinae_dummy >::type = boost::log::aux::sfinae_dummy()) : m_Filter(fun)
|
||||
{
|
||||
}
|
||||
#else
|
||||
// MSVC 9 and older blows up in unexpected ways if we use SFINAE to disable constructor instantiation
|
||||
template< typename FunT >
|
||||
filter(FunT const& fun) : m_Filter(fun)
|
||||
{
|
||||
}
|
||||
template< typename FunT >
|
||||
filter(rv< FunT >& fun) : m_Filter(fun)
|
||||
{
|
||||
}
|
||||
template< typename FunT >
|
||||
filter(rv< FunT > const& fun) : m_Filter(static_cast< FunT const& >(fun))
|
||||
{
|
||||
}
|
||||
filter(rv< filter > const& that) : m_Filter(that.m_Filter)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Move assignment. The moved-from filter is left in an unspecified state.
|
||||
*/
|
||||
filter& operator= (BOOST_RV_REF(filter) that) BOOST_NOEXCEPT
|
||||
{
|
||||
m_Filter.swap(that.m_Filter);
|
||||
return *this;
|
||||
}
|
||||
/*!
|
||||
* Copy assignment.
|
||||
*/
|
||||
filter& operator= (BOOST_COPY_ASSIGN_REF(filter) that)
|
||||
{
|
||||
m_Filter = that.m_Filter;
|
||||
return *this;
|
||||
}
|
||||
/*!
|
||||
* Initializing assignment. Sets the specified function object to the filter.
|
||||
*/
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
template< typename FunT >
|
||||
filter& operator= (FunT const& fun)
|
||||
#else
|
||||
template< typename FunT >
|
||||
typename boost::disable_if_c< is_same< typename remove_cv< FunT >::type, filter >::value, filter& >::type
|
||||
operator= (FunT const& fun)
|
||||
#endif
|
||||
{
|
||||
filter(fun).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Filtering operator.
|
||||
*
|
||||
* \param values Attribute values of the log record.
|
||||
* \return \c true if the log record passes the filter, \c false otherwise.
|
||||
*/
|
||||
result_type operator() (attribute_value_set const& values) const
|
||||
{
|
||||
return m_Filter(values);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Resets the filter to the default. The default filter always returns \c true.
|
||||
*/
|
||||
void reset()
|
||||
{
|
||||
m_Filter = default_filter();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Swaps two filters
|
||||
*/
|
||||
void swap(filter& that) BOOST_NOEXCEPT
|
||||
{
|
||||
m_Filter.swap(that.m_Filter);
|
||||
}
|
||||
};
|
||||
|
||||
inline void swap(filter& left, filter& right) BOOST_NOEXCEPT
|
||||
{
|
||||
left.swap(right);
|
||||
}
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_EXPRESSIONS_FILTER_HPP_INCLUDED_
|
||||
@@ -0,0 +1,484 @@
|
||||
/*
|
||||
* 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 formatter.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 13.07.2012
|
||||
*
|
||||
* The header contains a formatter function object definition.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_EXPRESSIONS_FORMATTER_HPP_INCLUDED_
|
||||
#define BOOST_LOG_EXPRESSIONS_FORMATTER_HPP_INCLUDED_
|
||||
|
||||
#include <locale>
|
||||
#include <ostream>
|
||||
#include <boost/ref.hpp>
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
#include <boost/log/detail/sfinae_tools.hpp>
|
||||
#endif
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/light_function.hpp>
|
||||
#include <boost/log/attributes/attribute_value_set.hpp>
|
||||
#include <boost/log/attributes/value_visitation.hpp>
|
||||
#include <boost/log/core/record_view.hpp>
|
||||
#include <boost/log/utility/formatting_ostream.hpp>
|
||||
#include <boost/log/utility/functional/bind_output.hpp>
|
||||
#include <boost/log/expressions/message.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace expressions {
|
||||
|
||||
namespace aux {
|
||||
|
||||
// This reference class is a workaround for a Boost.Phoenix bug: https://svn.boost.org/trac/boost/ticket/9363
|
||||
// It is needed to pass output streams by non-const reference to function objects wrapped in phoenix::bind and phoenix::function.
|
||||
// It's an implementation detail and will be removed when Boost.Phoenix is fixed.
|
||||
template< typename StreamT >
|
||||
class stream_ref :
|
||||
public reference_wrapper< StreamT >
|
||||
{
|
||||
public:
|
||||
typedef typename StreamT::char_type char_type;
|
||||
typedef typename StreamT::traits_type traits_type;
|
||||
typedef typename StreamT::allocator_type allocator_type;
|
||||
typedef typename StreamT::streambuf_type streambuf_type;
|
||||
typedef typename StreamT::string_type string_type;
|
||||
typedef typename StreamT::ostream_type ostream_type;
|
||||
typedef typename StreamT::pos_type pos_type;
|
||||
typedef typename StreamT::off_type off_type;
|
||||
typedef typename StreamT::int_type int_type;
|
||||
|
||||
typedef typename StreamT::failure failure;
|
||||
typedef typename StreamT::fmtflags fmtflags;
|
||||
typedef typename StreamT::iostate iostate;
|
||||
typedef typename StreamT::openmode openmode;
|
||||
typedef typename StreamT::seekdir seekdir;
|
||||
typedef typename StreamT::Init Init;
|
||||
|
||||
typedef typename StreamT::event event;
|
||||
typedef typename StreamT::event_callback event_callback;
|
||||
|
||||
typedef typename StreamT::sentry sentry;
|
||||
|
||||
static BOOST_CONSTEXPR_OR_CONST fmtflags boolalpha = StreamT::boolalpha;
|
||||
static BOOST_CONSTEXPR_OR_CONST fmtflags dec = StreamT::dec;
|
||||
static BOOST_CONSTEXPR_OR_CONST fmtflags fixed = StreamT::fixed;
|
||||
static BOOST_CONSTEXPR_OR_CONST fmtflags hex = StreamT::hex;
|
||||
static BOOST_CONSTEXPR_OR_CONST fmtflags internal = StreamT::internal;
|
||||
static BOOST_CONSTEXPR_OR_CONST fmtflags left = StreamT::left;
|
||||
static BOOST_CONSTEXPR_OR_CONST fmtflags oct = StreamT::oct;
|
||||
static BOOST_CONSTEXPR_OR_CONST fmtflags right = StreamT::right;
|
||||
static BOOST_CONSTEXPR_OR_CONST fmtflags scientific = StreamT::scientific;
|
||||
static BOOST_CONSTEXPR_OR_CONST fmtflags showbase = StreamT::showbase;
|
||||
static BOOST_CONSTEXPR_OR_CONST fmtflags showpoint = StreamT::showpoint;
|
||||
static BOOST_CONSTEXPR_OR_CONST fmtflags skipws = StreamT::skipws;
|
||||
static BOOST_CONSTEXPR_OR_CONST fmtflags unitbuf = StreamT::unitbuf;
|
||||
static BOOST_CONSTEXPR_OR_CONST fmtflags uppercase = StreamT::uppercase;
|
||||
static BOOST_CONSTEXPR_OR_CONST fmtflags adjustfield = StreamT::adjustfield;
|
||||
static BOOST_CONSTEXPR_OR_CONST fmtflags basefield = StreamT::basefield;
|
||||
static BOOST_CONSTEXPR_OR_CONST fmtflags floatfield = StreamT::floatfield;
|
||||
|
||||
static BOOST_CONSTEXPR_OR_CONST iostate badbit = StreamT::badbit;
|
||||
static BOOST_CONSTEXPR_OR_CONST iostate eofbit = StreamT::eofbit;
|
||||
static BOOST_CONSTEXPR_OR_CONST iostate failbit = StreamT::failbit;
|
||||
static BOOST_CONSTEXPR_OR_CONST iostate goodbit = StreamT::goodbit;
|
||||
|
||||
static BOOST_CONSTEXPR_OR_CONST openmode app = StreamT::app;
|
||||
static BOOST_CONSTEXPR_OR_CONST openmode ate = StreamT::ate;
|
||||
static BOOST_CONSTEXPR_OR_CONST openmode binary = StreamT::binary;
|
||||
static BOOST_CONSTEXPR_OR_CONST openmode in = StreamT::in;
|
||||
static BOOST_CONSTEXPR_OR_CONST openmode out = StreamT::out;
|
||||
static BOOST_CONSTEXPR_OR_CONST openmode trunc = StreamT::trunc;
|
||||
|
||||
static BOOST_CONSTEXPR_OR_CONST seekdir beg = StreamT::beg;
|
||||
static BOOST_CONSTEXPR_OR_CONST seekdir cur = StreamT::cur;
|
||||
static BOOST_CONSTEXPR_OR_CONST seekdir end = StreamT::end;
|
||||
|
||||
static BOOST_CONSTEXPR_OR_CONST event erase_event = StreamT::erase_event;
|
||||
static BOOST_CONSTEXPR_OR_CONST event imbue_event = StreamT::imbue_event;
|
||||
static BOOST_CONSTEXPR_OR_CONST event copyfmt_event = StreamT::copyfmt_event;
|
||||
|
||||
|
||||
BOOST_FORCEINLINE explicit stream_ref(StreamT& strm) : reference_wrapper< StreamT >(strm)
|
||||
{
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
template< typename T >
|
||||
BOOST_FORCEINLINE StreamT& operator<< (T&& val) const
|
||||
{
|
||||
StreamT& strm = this->get();
|
||||
strm << static_cast< T&& >(val);
|
||||
return strm;
|
||||
}
|
||||
#if defined(BOOST_MSVC) && BOOST_MSVC < 1800
|
||||
// MSVC 10 and 11 generate broken code for the perfect forwarding version above if T is an array type (e.g. a string literal)
|
||||
template< typename T, unsigned int N >
|
||||
BOOST_FORCEINLINE StreamT& operator<< (T (&val)[N]) const
|
||||
{
|
||||
StreamT& strm = this->get();
|
||||
strm << val;
|
||||
return strm;
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
template< typename T >
|
||||
BOOST_FORCEINLINE StreamT& operator<< (T& val) const
|
||||
{
|
||||
StreamT& strm = this->get();
|
||||
strm << val;
|
||||
return strm;
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
BOOST_FORCEINLINE StreamT& operator<< (T const& val) const
|
||||
{
|
||||
StreamT& strm = this->get();
|
||||
strm << val;
|
||||
return strm;
|
||||
}
|
||||
#endif
|
||||
|
||||
BOOST_FORCEINLINE void attach(string_type& str) const { this->get().attach(str); }
|
||||
BOOST_FORCEINLINE void detach() const { this->get().detach(); }
|
||||
BOOST_FORCEINLINE string_type const& str() const { return this->get().str(); }
|
||||
BOOST_FORCEINLINE ostream_type& stream() const { return this->get().stream(); }
|
||||
BOOST_FORCEINLINE fmtflags flags() const { return this->get().flags(); }
|
||||
BOOST_FORCEINLINE fmtflags flags(fmtflags f) const { return this->get().flags(f); }
|
||||
BOOST_FORCEINLINE fmtflags setf(fmtflags f) const { return this->get().setf(f); }
|
||||
BOOST_FORCEINLINE fmtflags setf(fmtflags f, fmtflags mask) const { return this->get().setf(f, mask); }
|
||||
BOOST_FORCEINLINE void unsetf(fmtflags f) const { this->get().unsetf(f); }
|
||||
|
||||
BOOST_FORCEINLINE std::streamsize precision() const { return this->get().precision(); }
|
||||
BOOST_FORCEINLINE std::streamsize precision(std::streamsize p) const { return this->get().precision(p); }
|
||||
|
||||
BOOST_FORCEINLINE std::streamsize width() const { return this->get().width(); }
|
||||
BOOST_FORCEINLINE std::streamsize width(std::streamsize w) const { return this->get().width(w); }
|
||||
|
||||
BOOST_FORCEINLINE std::locale getloc() const { return this->get().getloc(); }
|
||||
BOOST_FORCEINLINE std::locale imbue(std::locale const& loc) const { return this->get().imbue(loc); }
|
||||
|
||||
static BOOST_FORCEINLINE int xalloc() { return StreamT::xalloc(); }
|
||||
BOOST_FORCEINLINE long& iword(int index) const { return this->get().iword(index); }
|
||||
BOOST_FORCEINLINE void*& pword(int index) const { return this->get().pword(index); }
|
||||
|
||||
BOOST_FORCEINLINE void register_callback(event_callback fn, int index) const { this->get().register_callback(fn, index); }
|
||||
|
||||
static BOOST_FORCEINLINE bool sync_with_stdio(bool sync = true) { return StreamT::sync_with_stdio(sync); }
|
||||
|
||||
BOOST_EXPLICIT_OPERATOR_BOOL()
|
||||
BOOST_FORCEINLINE bool operator! () const { return !this->get(); }
|
||||
|
||||
BOOST_FORCEINLINE iostate rdstate() const { return this->get().rdstate(); }
|
||||
BOOST_FORCEINLINE void clear(iostate state = goodbit) const { this->get().clear(state); }
|
||||
BOOST_FORCEINLINE void setstate(iostate state) const { this->get().setstate(state); }
|
||||
BOOST_FORCEINLINE bool good() const { return this->get().good(); }
|
||||
BOOST_FORCEINLINE bool eof() const { return this->get().eof(); }
|
||||
BOOST_FORCEINLINE bool fail() const { return this->get().fail(); }
|
||||
BOOST_FORCEINLINE bool bad() const { return this->get().bad(); }
|
||||
|
||||
BOOST_FORCEINLINE iostate exceptions() const { return this->get().exceptions(); }
|
||||
BOOST_FORCEINLINE void exceptions(iostate s) const { this->get().exceptions(s); }
|
||||
|
||||
BOOST_FORCEINLINE ostream_type* tie() const { return this->get().tie(); }
|
||||
BOOST_FORCEINLINE ostream_type* tie(ostream_type* strm) const { return this->get().tie(strm); }
|
||||
|
||||
BOOST_FORCEINLINE streambuf_type* rdbuf() const { return this->get().rdbuf(); }
|
||||
|
||||
BOOST_FORCEINLINE StreamT& copyfmt(std::basic_ios< char_type, traits_type >& rhs) const { return this->get().copyfmt(rhs); }
|
||||
BOOST_FORCEINLINE StreamT& copyfmt(StreamT& rhs) const { return this->get().copyfmt(rhs); }
|
||||
|
||||
BOOST_FORCEINLINE char_type fill() const { return this->get().fill(); }
|
||||
BOOST_FORCEINLINE char_type fill(char_type ch) const { return this->get().fill(ch); }
|
||||
|
||||
BOOST_FORCEINLINE char narrow(char_type ch, char def) const { return this->get().narrow(ch, def); }
|
||||
BOOST_FORCEINLINE char_type widen(char ch) const { return this->get().widen(ch); }
|
||||
|
||||
BOOST_FORCEINLINE StreamT& flush() const { return this->get().flush(); }
|
||||
|
||||
BOOST_FORCEINLINE pos_type tellp() const { return this->get().tellp(); }
|
||||
BOOST_FORCEINLINE StreamT& seekp(pos_type pos) const { return this->get().seekp(pos); }
|
||||
BOOST_FORCEINLINE StreamT& seekp(off_type off, std::ios_base::seekdir dir) const { return this->get().seekp(off, dir); }
|
||||
|
||||
template< typename CharT >
|
||||
BOOST_FORCEINLINE typename boost::log::aux::enable_if_streamable_char_type< CharT, StreamT& >::type
|
||||
put(CharT c) const { return this->get().put(c); }
|
||||
|
||||
template< typename CharT >
|
||||
BOOST_FORCEINLINE typename boost::log::aux::enable_if_streamable_char_type< CharT, StreamT& >::type
|
||||
write(const CharT* p, std::streamsize size) const { return this->get().write(p, size); }
|
||||
};
|
||||
|
||||
template< typename StreamT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::fmtflags stream_ref< StreamT >::boolalpha;
|
||||
template< typename StreamT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::fmtflags stream_ref< StreamT >::dec;
|
||||
template< typename StreamT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::fmtflags stream_ref< StreamT >::fixed;
|
||||
template< typename StreamT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::fmtflags stream_ref< StreamT >::hex;
|
||||
template< typename StreamT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::fmtflags stream_ref< StreamT >::internal;
|
||||
template< typename StreamT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::fmtflags stream_ref< StreamT >::left;
|
||||
template< typename StreamT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::fmtflags stream_ref< StreamT >::oct;
|
||||
template< typename StreamT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::fmtflags stream_ref< StreamT >::right;
|
||||
template< typename StreamT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::fmtflags stream_ref< StreamT >::scientific;
|
||||
template< typename StreamT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::fmtflags stream_ref< StreamT >::showbase;
|
||||
template< typename StreamT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::fmtflags stream_ref< StreamT >::showpoint;
|
||||
template< typename StreamT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::fmtflags stream_ref< StreamT >::skipws;
|
||||
template< typename StreamT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::fmtflags stream_ref< StreamT >::unitbuf;
|
||||
template< typename StreamT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::fmtflags stream_ref< StreamT >::uppercase;
|
||||
template< typename StreamT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::fmtflags stream_ref< StreamT >::adjustfield;
|
||||
template< typename StreamT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::fmtflags stream_ref< StreamT >::basefield;
|
||||
template< typename StreamT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::fmtflags stream_ref< StreamT >::floatfield;
|
||||
|
||||
template< typename StreamT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::iostate stream_ref< StreamT >::badbit;
|
||||
template< typename StreamT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::iostate stream_ref< StreamT >::eofbit;
|
||||
template< typename StreamT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::iostate stream_ref< StreamT >::failbit;
|
||||
template< typename StreamT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::iostate stream_ref< StreamT >::goodbit;
|
||||
|
||||
template< typename StreamT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::openmode stream_ref< StreamT >::app;
|
||||
template< typename StreamT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::openmode stream_ref< StreamT >::ate;
|
||||
template< typename StreamT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::openmode stream_ref< StreamT >::binary;
|
||||
template< typename StreamT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::openmode stream_ref< StreamT >::in;
|
||||
template< typename StreamT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::openmode stream_ref< StreamT >::out;
|
||||
template< typename StreamT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::openmode stream_ref< StreamT >::trunc;
|
||||
|
||||
template< typename StreamT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::seekdir stream_ref< StreamT >::beg;
|
||||
template< typename StreamT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::seekdir stream_ref< StreamT >::cur;
|
||||
template< typename StreamT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::seekdir stream_ref< StreamT >::end;
|
||||
|
||||
template< typename StreamT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::event stream_ref< StreamT >::erase_event;
|
||||
template< typename StreamT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::event stream_ref< StreamT >::imbue_event;
|
||||
template< typename StreamT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename stream_ref< StreamT >::event stream_ref< StreamT >::copyfmt_event;
|
||||
|
||||
//! Default log record message formatter
|
||||
struct message_formatter
|
||||
{
|
||||
typedef void result_type;
|
||||
|
||||
message_formatter() : m_MessageName(expressions::tag::message::get_name())
|
||||
{
|
||||
}
|
||||
|
||||
template< typename StreamT >
|
||||
BOOST_FORCEINLINE result_type operator() (record_view const& rec, StreamT& strm) const
|
||||
{
|
||||
boost::log::visit< expressions::tag::message::value_type >(m_MessageName, rec, boost::log::bind_output(strm));
|
||||
}
|
||||
|
||||
private:
|
||||
const attribute_name m_MessageName;
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
} // namespace expressions
|
||||
|
||||
/*!
|
||||
* Log record formatter function wrapper.
|
||||
*/
|
||||
template< typename CharT >
|
||||
class basic_formatter
|
||||
{
|
||||
typedef basic_formatter this_type;
|
||||
BOOST_COPYABLE_AND_MOVABLE(this_type)
|
||||
|
||||
public:
|
||||
//! Result type
|
||||
typedef void result_type;
|
||||
|
||||
//! Character type
|
||||
typedef CharT char_type;
|
||||
//! Output stream type
|
||||
typedef basic_formatting_ostream< char_type > stream_type;
|
||||
|
||||
private:
|
||||
//! Filter function type
|
||||
typedef boost::log::aux::light_function< void (record_view const&, expressions::aux::stream_ref< stream_type >) > formatter_type;
|
||||
|
||||
private:
|
||||
//! Formatter function
|
||||
formatter_type m_Formatter;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Default constructor. Creates a formatter that only outputs log message.
|
||||
*/
|
||||
basic_formatter() : m_Formatter(expressions::aux::message_formatter())
|
||||
{
|
||||
}
|
||||
/*!
|
||||
* Copy constructor
|
||||
*/
|
||||
basic_formatter(basic_formatter const& that) : m_Formatter(that.m_Formatter)
|
||||
{
|
||||
}
|
||||
/*!
|
||||
* Move constructor. The moved-from formatter is left in an unspecified state.
|
||||
*/
|
||||
basic_formatter(BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT : m_Formatter(boost::move(that.m_Formatter))
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* Initializing constructor. Creates a formatter which will invoke the specified function object.
|
||||
*/
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
template< typename FunT >
|
||||
basic_formatter(FunT&& fun) : m_Formatter(boost::forward< FunT >(fun))
|
||||
{
|
||||
}
|
||||
#elif !defined(BOOST_MSVC) || BOOST_MSVC >= 1600
|
||||
template< typename FunT >
|
||||
basic_formatter(FunT const& fun, typename boost::disable_if_c< move_detail::is_rv< FunT >::value, boost::log::aux::sfinae_dummy >::type = boost::log::aux::sfinae_dummy()) : m_Formatter(fun)
|
||||
{
|
||||
}
|
||||
#else
|
||||
// MSVC 9 and older blows up in unexpected ways if we use SFINAE to disable constructor instantiation
|
||||
template< typename FunT >
|
||||
basic_formatter(FunT const& fun) : m_Formatter(fun)
|
||||
{
|
||||
}
|
||||
template< typename FunT >
|
||||
basic_formatter(rv< FunT >& fun) : m_Formatter(fun)
|
||||
{
|
||||
}
|
||||
template< typename FunT >
|
||||
basic_formatter(rv< FunT > const& fun) : m_Formatter(static_cast< FunT const& >(fun))
|
||||
{
|
||||
}
|
||||
basic_formatter(rv< this_type > const& that) : m_Formatter(that.m_Formatter)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Move assignment. The moved-from formatter is left in an unspecified state.
|
||||
*/
|
||||
basic_formatter& operator= (BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT
|
||||
{
|
||||
m_Formatter.swap(that.m_Formatter);
|
||||
return *this;
|
||||
}
|
||||
/*!
|
||||
* Copy assignment.
|
||||
*/
|
||||
basic_formatter& operator= (BOOST_COPY_ASSIGN_REF(this_type) that)
|
||||
{
|
||||
m_Formatter = that.m_Formatter;
|
||||
return *this;
|
||||
}
|
||||
/*!
|
||||
* Initializing assignment. Sets the specified function object to the formatter.
|
||||
*/
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
template< typename FunT >
|
||||
basic_formatter& operator= (FunT&& fun)
|
||||
{
|
||||
this_type(boost::forward< FunT >(fun)).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
#else
|
||||
template< typename FunT >
|
||||
typename boost::disable_if_c< is_same< typename remove_cv< FunT >::type, this_type >::value, this_type& >::type
|
||||
operator= (FunT const& fun)
|
||||
{
|
||||
this_type(fun).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Formatting operator.
|
||||
*
|
||||
* \param rec A log record to format.
|
||||
* \param strm A stream to put the formatted characters to.
|
||||
*/
|
||||
result_type operator() (record_view const& rec, stream_type& strm) const
|
||||
{
|
||||
m_Formatter(rec, expressions::aux::stream_ref< stream_type >(strm));
|
||||
}
|
||||
|
||||
/*!
|
||||
* Resets the formatter to the default. The default formatter only outputs message text.
|
||||
*/
|
||||
void reset()
|
||||
{
|
||||
m_Formatter = expressions::aux::message_formatter();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Swaps two formatters
|
||||
*/
|
||||
void swap(basic_formatter& that) BOOST_NOEXCEPT
|
||||
{
|
||||
m_Formatter.swap(that.m_Formatter);
|
||||
}
|
||||
};
|
||||
|
||||
template< typename CharT >
|
||||
inline void swap(basic_formatter< CharT >& left, basic_formatter< CharT >& right) BOOST_NOEXCEPT
|
||||
{
|
||||
left.swap(right);
|
||||
}
|
||||
|
||||
#ifdef BOOST_LOG_USE_CHAR
|
||||
typedef basic_formatter< char > formatter;
|
||||
#endif
|
||||
#ifdef BOOST_LOG_USE_WCHAR_T
|
||||
typedef basic_formatter< wchar_t > wformatter;
|
||||
#endif
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_EXPRESSIONS_FORMATTER_HPP_INCLUDED_
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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 formatters.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 10.11.2012
|
||||
*
|
||||
* The header includes all template expression formatters.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_EXPRESSIONS_FORMATTERS_HPP_INCLUDED_
|
||||
#define BOOST_LOG_EXPRESSIONS_FORMATTERS_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
|
||||
#include <boost/log/expressions/formatters/stream.hpp>
|
||||
#include <boost/log/expressions/formatters/format.hpp>
|
||||
|
||||
#include <boost/log/expressions/formatters/date_time.hpp>
|
||||
#include <boost/log/expressions/formatters/named_scope.hpp>
|
||||
|
||||
#include <boost/log/expressions/formatters/char_decorator.hpp>
|
||||
#include <boost/log/expressions/formatters/xml_decorator.hpp>
|
||||
#include <boost/log/expressions/formatters/csv_decorator.hpp>
|
||||
#include <boost/log/expressions/formatters/c_decorator.hpp>
|
||||
#include <boost/log/expressions/formatters/max_size_decorator.hpp>
|
||||
|
||||
#include <boost/log/expressions/formatters/if.hpp>
|
||||
#include <boost/log/expressions/formatters/wrap_formatter.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#endif // BOOST_LOG_EXPRESSIONS_FORMATTERS_HPP_INCLUDED_
|
||||
@@ -0,0 +1,280 @@
|
||||
/*
|
||||
* 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 formatters/c_decorator.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 18.11.2012
|
||||
*
|
||||
* The header contains implementation of C-style character decorators.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_EXPRESSIONS_FORMATTERS_C_DECORATOR_HPP_INCLUDED_
|
||||
#define BOOST_LOG_EXPRESSIONS_FORMATTERS_C_DECORATOR_HPP_INCLUDED_
|
||||
|
||||
#include <limits>
|
||||
#include <boost/range/iterator_range_core.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/snprintf.hpp>
|
||||
#include <boost/log/expressions/formatters/char_decorator.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace expressions {
|
||||
|
||||
namespace aux {
|
||||
|
||||
template< typename >
|
||||
struct c_decorator_traits;
|
||||
|
||||
#ifdef BOOST_LOG_USE_CHAR
|
||||
template< >
|
||||
struct c_decorator_traits< char >
|
||||
{
|
||||
static boost::iterator_range< const char* const* > get_patterns()
|
||||
{
|
||||
static const char* const patterns[] =
|
||||
{
|
||||
"\\", "\a", "\b", "\f", "\n", "\r", "\t", "\v", "'", "\"", "?"
|
||||
};
|
||||
return boost::make_iterator_range(patterns);
|
||||
}
|
||||
static boost::iterator_range< const char* const* > get_replacements()
|
||||
{
|
||||
static const char* const replacements[] =
|
||||
{
|
||||
"\\\\", "\\a", "\\b", "\\f", "\\n", "\\r", "\\t", "\\v", "\\'", "\\\"", "\\?"
|
||||
};
|
||||
return boost::make_iterator_range(replacements);
|
||||
}
|
||||
template< unsigned int N >
|
||||
static std::size_t print_escaped(char (&buf)[N], char c)
|
||||
{
|
||||
int n = boost::log::aux::snprintf(buf, N, "\\x%.2X", static_cast< unsigned int >(static_cast< uint8_t >(c)));
|
||||
if (n < 0)
|
||||
{
|
||||
n = 0;
|
||||
buf[0] = '\0';
|
||||
}
|
||||
return static_cast< unsigned int >(n) >= N ? N - 1 : static_cast< unsigned int >(n);
|
||||
}
|
||||
};
|
||||
#endif // BOOST_LOG_USE_CHAR
|
||||
|
||||
#ifdef BOOST_LOG_USE_WCHAR_T
|
||||
template< >
|
||||
struct c_decorator_traits< wchar_t >
|
||||
{
|
||||
static boost::iterator_range< const wchar_t* const* > get_patterns()
|
||||
{
|
||||
static const wchar_t* const patterns[] =
|
||||
{
|
||||
L"\\", L"\a", L"\b", L"\f", L"\n", L"\r", L"\t", L"\v", L"'", L"\"", L"?"
|
||||
};
|
||||
return boost::make_iterator_range(patterns);
|
||||
}
|
||||
static boost::iterator_range< const wchar_t* const* > get_replacements()
|
||||
{
|
||||
static const wchar_t* const replacements[] =
|
||||
{
|
||||
L"\\\\", L"\\a", L"\\b", L"\\f", L"\\n", L"\\r", L"\\t", L"\\v", L"\\'", L"\\\"", L"\\?"
|
||||
};
|
||||
return boost::make_iterator_range(replacements);
|
||||
}
|
||||
template< unsigned int N >
|
||||
static std::size_t print_escaped(wchar_t (&buf)[N], wchar_t c)
|
||||
{
|
||||
const wchar_t* format;
|
||||
unsigned int val;
|
||||
if (sizeof(wchar_t) == 1)
|
||||
{
|
||||
format = L"\\x%.2X";
|
||||
val = static_cast< uint8_t >(c);
|
||||
}
|
||||
else if (sizeof(wchar_t) == 2)
|
||||
{
|
||||
format = L"\\x%.4X";
|
||||
val = static_cast< uint16_t >(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
format = L"\\x%.8X";
|
||||
val = static_cast< uint32_t >(c);
|
||||
}
|
||||
|
||||
int n = boost::log::aux::swprintf(buf, N, format, val);
|
||||
if (n < 0)
|
||||
{
|
||||
n = 0;
|
||||
buf[0] = L'\0';
|
||||
}
|
||||
return static_cast< unsigned int >(n) >= N ? N - 1 : static_cast< unsigned int >(n);
|
||||
}
|
||||
};
|
||||
#endif // BOOST_LOG_USE_WCHAR_T
|
||||
|
||||
template< typename CharT >
|
||||
struct c_decorator_gen
|
||||
{
|
||||
typedef CharT char_type;
|
||||
|
||||
template< typename SubactorT >
|
||||
BOOST_FORCEINLINE char_decorator_actor< SubactorT, pattern_replacer< char_type > > operator[] (SubactorT const& subactor) const
|
||||
{
|
||||
typedef c_decorator_traits< char_type > traits_type;
|
||||
typedef pattern_replacer< char_type > replacer_type;
|
||||
typedef char_decorator_actor< SubactorT, replacer_type > result_type;
|
||||
typedef typename result_type::terminal_type terminal_type;
|
||||
typename result_type::base_type act = {{ terminal_type(subactor, replacer_type(traits_type::get_patterns(), traits_type::get_replacements())) }};
|
||||
return result_type(act);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
/*!
|
||||
* C-style decorator generator object. The decorator replaces characters with specific meaning in C
|
||||
* language with the corresponding escape sequences. The generator provides <tt>operator[]</tt> that
|
||||
* can be used to construct the actual decorator. For example:
|
||||
*
|
||||
* <code>
|
||||
* c_decor[ stream << attr< std::string >("MyAttr") ]
|
||||
* </code>
|
||||
*
|
||||
* For wide-character formatting there is the similar \c wc_decor decorator generator object.
|
||||
*/
|
||||
#ifdef BOOST_LOG_USE_CHAR
|
||||
const aux::c_decorator_gen< char > c_decor = {};
|
||||
#endif
|
||||
#ifdef BOOST_LOG_USE_WCHAR_T
|
||||
const aux::c_decorator_gen< wchar_t > wc_decor = {};
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* The function creates a C-style decorator generator for arbitrary character type.
|
||||
*/
|
||||
template< typename CharT >
|
||||
BOOST_FORCEINLINE aux::c_decorator_gen< CharT > make_c_decor()
|
||||
{
|
||||
return aux::c_decorator_gen< CharT >();
|
||||
}
|
||||
|
||||
/*!
|
||||
* A character decorator implementation that escapes all non-prontable and non-ASCII characters
|
||||
* in the output with C-style escape sequences.
|
||||
*/
|
||||
template< typename CharT >
|
||||
class c_ascii_pattern_replacer :
|
||||
public pattern_replacer< CharT >
|
||||
{
|
||||
private:
|
||||
//! Base type
|
||||
typedef pattern_replacer< CharT > base_type;
|
||||
|
||||
public:
|
||||
//! Result type
|
||||
typedef typename base_type::result_type result_type;
|
||||
//! Character type
|
||||
typedef typename base_type::char_type char_type;
|
||||
//! String type
|
||||
typedef typename base_type::string_type string_type;
|
||||
|
||||
private:
|
||||
//! Traits type
|
||||
typedef aux::c_decorator_traits< char_type > traits_type;
|
||||
|
||||
public:
|
||||
//! Default constructor
|
||||
c_ascii_pattern_replacer() : base_type(traits_type::get_patterns(), traits_type::get_replacements())
|
||||
{
|
||||
}
|
||||
|
||||
//! Applies string replacements starting from the specified position
|
||||
result_type operator() (string_type& str, typename string_type::size_type start_pos = 0) const
|
||||
{
|
||||
base_type::operator() (str, start_pos);
|
||||
|
||||
typedef typename string_type::iterator string_iterator;
|
||||
for (string_iterator it = str.begin() + start_pos, end = str.end(); it != end; ++it)
|
||||
{
|
||||
char_type c = *it;
|
||||
if (c < 0x20 || c > 0x7e)
|
||||
{
|
||||
char_type buf[(std::numeric_limits< char_type >::digits + 3) / 4 + 3];
|
||||
std::size_t n = traits_type::print_escaped(buf, c);
|
||||
std::size_t pos = it - str.begin();
|
||||
str.replace(pos, 1, buf, n);
|
||||
it = str.begin() + n - 1;
|
||||
end = str.end();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
namespace aux {
|
||||
|
||||
template< typename CharT >
|
||||
struct c_ascii_decorator_gen
|
||||
{
|
||||
typedef CharT char_type;
|
||||
|
||||
template< typename SubactorT >
|
||||
BOOST_FORCEINLINE char_decorator_actor< SubactorT, c_ascii_pattern_replacer< char_type > > operator[] (SubactorT const& subactor) const
|
||||
{
|
||||
typedef c_ascii_pattern_replacer< char_type > replacer_type;
|
||||
typedef char_decorator_actor< SubactorT, replacer_type > result_type;
|
||||
typedef typename result_type::terminal_type terminal_type;
|
||||
typename result_type::base_type act = {{ terminal_type(subactor, replacer_type()) }};
|
||||
return result_type(act);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
/*!
|
||||
* C-style decorator generator object. Acts similarly to \c c_decor, except that \c c_ascii_decor also
|
||||
* converts all non-ASCII and non-printable ASCII characters, except for space character, into
|
||||
* C-style hexadecimal escape sequences. The generator provides <tt>operator[]</tt> that
|
||||
* can be used to construct the actual decorator. For example:
|
||||
*
|
||||
* <code>
|
||||
* c_ascii_decor[ stream << attr< std::string >("MyAttr") ]
|
||||
* </code>
|
||||
*
|
||||
* For wide-character formatting there is the similar \c wc_ascii_decor decorator generator object.
|
||||
*/
|
||||
#ifdef BOOST_LOG_USE_CHAR
|
||||
const aux::c_ascii_decorator_gen< char > c_ascii_decor = {};
|
||||
#endif
|
||||
#ifdef BOOST_LOG_USE_WCHAR_T
|
||||
const aux::c_ascii_decorator_gen< wchar_t > wc_ascii_decor = {};
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* The function creates a C-style decorator generator for arbitrary character type.
|
||||
*/
|
||||
template< typename CharT >
|
||||
BOOST_FORCEINLINE aux::c_ascii_decorator_gen< CharT > make_c_ascii_decor()
|
||||
{
|
||||
return aux::c_ascii_decorator_gen< CharT >();
|
||||
}
|
||||
|
||||
} // namespace expressions
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_EXPRESSIONS_FORMATTERS_C_DECORATOR_HPP_INCLUDED_
|
||||
+645
@@ -0,0 +1,645 @@
|
||||
/*
|
||||
* 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 formatters/char_decorator.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 17.11.2012
|
||||
*
|
||||
* The header contains implementation of a character decorator.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_EXPRESSIONS_FORMATTERS_CHAR_DECORATOR_HPP_INCLUDED_
|
||||
#define BOOST_LOG_EXPRESSIONS_FORMATTERS_CHAR_DECORATOR_HPP_INCLUDED_
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <iterator>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
#include <boost/range/size.hpp>
|
||||
#include <boost/range/const_iterator.hpp>
|
||||
#include <boost/range/value_type.hpp>
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include <boost/core/addressof.hpp>
|
||||
#include <boost/phoenix/core/actor.hpp>
|
||||
#include <boost/phoenix/core/meta_grammar.hpp>
|
||||
#include <boost/phoenix/core/terminal_fwd.hpp>
|
||||
#include <boost/phoenix/core/is_nullary.hpp>
|
||||
#include <boost/phoenix/core/environment.hpp>
|
||||
#include <boost/phoenix/support/vector.hpp>
|
||||
#include <boost/fusion/sequence/intrinsic/at_c.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/custom_terminal_spec.hpp>
|
||||
#include <boost/log/detail/deduce_char_type.hpp>
|
||||
#include <boost/log/detail/sfinae_tools.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
|
||||
|
||||
namespace expressions {
|
||||
|
||||
namespace aux {
|
||||
|
||||
template< typename RangeT >
|
||||
struct string_const_iterator : range_const_iterator< RangeT > {};
|
||||
template< >
|
||||
struct string_const_iterator< char* > { typedef char* type; };
|
||||
template< >
|
||||
struct string_const_iterator< const char* > { typedef const char* type; };
|
||||
template< >
|
||||
struct string_const_iterator< wchar_t* > { typedef wchar_t* type; };
|
||||
template< >
|
||||
struct string_const_iterator< const wchar_t* > { typedef const wchar_t* type; };
|
||||
|
||||
} // namespace aux
|
||||
|
||||
/*!
|
||||
* A simple character decorator implementation. This implementation replaces string patterns in the source string with
|
||||
* the fixed replacements. Source patterns and replacements can be specified at the object construction.
|
||||
*/
|
||||
template< typename CharT >
|
||||
class pattern_replacer
|
||||
{
|
||||
public:
|
||||
//! Result type
|
||||
typedef void result_type;
|
||||
|
||||
//! Character type
|
||||
typedef CharT char_type;
|
||||
//! String type
|
||||
typedef std::basic_string< char_type > string_type;
|
||||
|
||||
private:
|
||||
//! Lengths of source pattern and replacement
|
||||
struct string_lengths
|
||||
{
|
||||
unsigned int from_len, to_len;
|
||||
};
|
||||
|
||||
//! List of the decorations to apply
|
||||
typedef std::vector< string_lengths > string_lengths_list;
|
||||
|
||||
private:
|
||||
//! Characters of the interleaved source patterns and replacements
|
||||
string_type m_decoration_chars;
|
||||
//! List of the decorations to apply
|
||||
string_lengths_list m_string_lengths;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Initializing constructor. Creates a pattern replacer with the specified \a decorations.
|
||||
* The provided decorations must be a sequence of \c std::pair of strings. The first element
|
||||
* of each pair is the source pattern, and the second one is the corresponding replacement.
|
||||
*/
|
||||
template< typename RangeT >
|
||||
explicit pattern_replacer(RangeT const& decorations
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
// This is needed for a workaround against an MSVC-10 and older bug in constructor overload resolution
|
||||
, typename boost::enable_if_has_type< typename range_const_iterator< RangeT >::type, boost::log::aux::sfinae_dummy >::type = boost::log::aux::sfinae_dummy()
|
||||
#endif
|
||||
)
|
||||
{
|
||||
typedef typename range_const_iterator< RangeT >::type iterator;
|
||||
for (iterator it = boost::begin(decorations), end_ = boost::end(decorations); it != end_; ++it)
|
||||
{
|
||||
string_lengths lens;
|
||||
{
|
||||
typedef typename aux::string_const_iterator< typename range_value< RangeT >::type::first_type >::type first_iterator;
|
||||
first_iterator b = string_begin(it->first), e = string_end(it->first);
|
||||
lens.from_len = static_cast< unsigned int >(std::distance(b, e));
|
||||
m_decoration_chars.append(b, e);
|
||||
}
|
||||
{
|
||||
typedef typename aux::string_const_iterator< typename range_value< RangeT >::type::second_type >::type second_iterator;
|
||||
second_iterator b = string_begin(it->second), e = string_end(it->second);
|
||||
lens.to_len = static_cast< unsigned int >(std::distance(b, e));
|
||||
m_decoration_chars.append(b, e);
|
||||
}
|
||||
m_string_lengths.push_back(lens);
|
||||
}
|
||||
}
|
||||
/*!
|
||||
* Initializing constructor. Creates a pattern replacer with decorations specified
|
||||
* in form of two same-sized string sequences. Each <tt>i</tt>'th decoration will be
|
||||
* <tt>from[i]</tt> -> <tt>to[i]</tt>.
|
||||
*/
|
||||
template< typename FromRangeT, typename ToRangeT >
|
||||
pattern_replacer(FromRangeT const& from, ToRangeT const& to)
|
||||
{
|
||||
typedef typename range_const_iterator< FromRangeT >::type iterator1;
|
||||
typedef typename range_const_iterator< ToRangeT >::type iterator2;
|
||||
iterator1 it1 = boost::begin(from), end1 = boost::end(from);
|
||||
iterator2 it2 = boost::begin(to), end2 = boost::end(to);
|
||||
for (; it1 != end1 && it2 != end2; ++it1, ++it2)
|
||||
{
|
||||
string_lengths lens;
|
||||
{
|
||||
typedef typename aux::string_const_iterator< typename range_value< FromRangeT >::type >::type from_iterator;
|
||||
from_iterator b = string_begin(*it1), e = string_end(*it1);
|
||||
lens.from_len = static_cast< unsigned int >(std::distance(b, e));
|
||||
m_decoration_chars.append(b, e);
|
||||
}
|
||||
{
|
||||
typedef typename aux::string_const_iterator< typename range_value< ToRangeT >::type >::type to_iterator;
|
||||
to_iterator b = string_begin(*it2), e = string_end(*it2);
|
||||
lens.to_len = static_cast< unsigned int >(std::distance(b, e));
|
||||
m_decoration_chars.append(b, e);
|
||||
}
|
||||
m_string_lengths.push_back(lens);
|
||||
}
|
||||
|
||||
// Both sequences should be of the same size
|
||||
BOOST_ASSERT(it1 == end1);
|
||||
BOOST_ASSERT(it2 == end2);
|
||||
}
|
||||
//! Copy constructor
|
||||
pattern_replacer(pattern_replacer const& that) : m_decoration_chars(that.m_decoration_chars), m_string_lengths(that.m_string_lengths)
|
||||
{
|
||||
}
|
||||
|
||||
//! Applies string replacements starting from the specified position
|
||||
result_type operator() (string_type& str, typename string_type::size_type start_pos = 0) const
|
||||
{
|
||||
typedef typename string_type::size_type size_type;
|
||||
|
||||
const char_type* from_chars = m_decoration_chars.c_str();
|
||||
for (typename string_lengths_list::const_iterator it = m_string_lengths.begin(), end = m_string_lengths.end(); it != end; ++it)
|
||||
{
|
||||
const unsigned int from_len = it->from_len, to_len = it->to_len;
|
||||
const char_type* const to_chars = from_chars + from_len;
|
||||
for (size_type pos = str.find(from_chars, start_pos, from_len); pos != string_type::npos; pos = str.find(from_chars, pos, from_len))
|
||||
{
|
||||
str.replace(pos, from_len, to_chars, to_len);
|
||||
pos += to_len;
|
||||
}
|
||||
from_chars = to_chars + to_len;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
static char_type* string_begin(char_type* p)
|
||||
{
|
||||
return p;
|
||||
}
|
||||
static const char_type* string_begin(const char_type* p)
|
||||
{
|
||||
return p;
|
||||
}
|
||||
template< typename RangeT >
|
||||
static typename range_const_iterator< RangeT >::type string_begin(RangeT const& r)
|
||||
{
|
||||
return boost::begin(r);
|
||||
}
|
||||
|
||||
static char_type* string_end(char_type* p)
|
||||
{
|
||||
return p + std::char_traits< char_type >::length(p);
|
||||
}
|
||||
static const char_type* string_end(const char_type* p)
|
||||
{
|
||||
return p + std::char_traits< char_type >::length(p);
|
||||
}
|
||||
template< typename RangeT >
|
||||
static typename range_const_iterator< RangeT >::type string_end(RangeT const& r)
|
||||
{
|
||||
return boost::end(r);
|
||||
}
|
||||
};
|
||||
|
||||
namespace aux {
|
||||
|
||||
//! Character decorator stream output terminal
|
||||
template< typename LeftT, typename SubactorT, typename ImplT >
|
||||
class char_decorator_output_terminal
|
||||
{
|
||||
private:
|
||||
//! Self type
|
||||
typedef char_decorator_output_terminal< LeftT, SubactorT, ImplT > this_type;
|
||||
|
||||
public:
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
//! Internal typedef for type categorization
|
||||
typedef void _is_boost_log_terminal;
|
||||
#endif
|
||||
|
||||
//! Implementation type
|
||||
typedef ImplT impl_type;
|
||||
|
||||
//! Character type
|
||||
typedef typename impl_type::char_type char_type;
|
||||
//! String type
|
||||
typedef typename impl_type::string_type string_type;
|
||||
//! Adopted actor type
|
||||
typedef SubactorT subactor_type;
|
||||
|
||||
//! Result type definition
|
||||
template< typename >
|
||||
struct result;
|
||||
|
||||
template< typename ThisT, typename ContextT >
|
||||
struct result< ThisT(ContextT) >
|
||||
{
|
||||
typedef typename remove_cv< typename remove_reference< ContextT >::type >::type context_type;
|
||||
typedef typename phoenix::evaluator::impl<
|
||||
typename LeftT::proto_base_expr&,
|
||||
context_type,
|
||||
phoenix::unused
|
||||
>::result_type type;
|
||||
};
|
||||
|
||||
private:
|
||||
//! Left argument actor
|
||||
LeftT m_left;
|
||||
//! Adopted formatter actor
|
||||
subactor_type m_subactor;
|
||||
//! Implementation type
|
||||
impl_type m_impl;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Initializing constructor. Creates decorator of the \a fmt formatter with the specified \a decorations.
|
||||
*/
|
||||
char_decorator_output_terminal(LeftT const& left, subactor_type const& sub, impl_type const& impl) :
|
||||
m_left(left), m_subactor(sub), m_impl(impl)
|
||||
{
|
||||
}
|
||||
/*!
|
||||
* Copy constructor
|
||||
*/
|
||||
char_decorator_output_terminal(char_decorator_output_terminal const& that) :
|
||||
m_left(that.m_left), m_subactor(that.m_subactor), m_impl(that.m_impl)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* Invokation operator
|
||||
*/
|
||||
template< typename ContextT >
|
||||
typename result< this_type(ContextT const&) >::type operator() (ContextT const& ctx)
|
||||
{
|
||||
// Flush the stream and keep the current write position in the target string
|
||||
typedef typename result< this_type(ContextT const&) >::type result_type;
|
||||
result_type strm = phoenix::eval(m_left, ctx);
|
||||
strm.flush();
|
||||
typename string_type::size_type const start_pos = strm.rdbuf()->storage()->size();
|
||||
|
||||
// Invoke the adopted formatter
|
||||
phoenix::eval(m_subactor, ctx);
|
||||
|
||||
// Flush the buffered characters and apply decorations
|
||||
strm.flush();
|
||||
m_impl(*strm.rdbuf()->storage(), start_pos);
|
||||
strm.rdbuf()->ensure_max_size();
|
||||
|
||||
return strm;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Invokation operator
|
||||
*/
|
||||
template< typename ContextT >
|
||||
typename result< const this_type(ContextT const&) >::type operator() (ContextT const& ctx) const
|
||||
{
|
||||
// Flush the stream and keep the current write position in the target string
|
||||
typedef typename result< const this_type(ContextT const&) >::type result_type;
|
||||
result_type strm = phoenix::eval(m_left, ctx);
|
||||
strm.flush();
|
||||
typename string_type::size_type const start_pos = strm.rdbuf()->storage()->size();
|
||||
|
||||
// Invoke the adopted formatter
|
||||
phoenix::eval(m_subactor, ctx);
|
||||
|
||||
// Flush the buffered characters and apply decorations
|
||||
strm.flush();
|
||||
m_impl(*strm.rdbuf()->storage(), start_pos);
|
||||
strm.rdbuf()->ensure_max_size();
|
||||
|
||||
return strm;
|
||||
}
|
||||
|
||||
BOOST_DELETED_FUNCTION(char_decorator_output_terminal())
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
/*!
|
||||
* Character decorator terminal class. This formatter allows to modify strings generated by other
|
||||
* formatters on character level. The most obvious application of decorators is replacing
|
||||
* a certain set of characters with decorated equivalents to satisfy requirements of
|
||||
* text-based sinks.
|
||||
*
|
||||
* The \c char_decorator_terminal class aggregates the formatter being decorated, and a set
|
||||
* of string pairs that are used as decorations. All decorations are applied sequentially.
|
||||
* The \c char_decorator_terminal class is a formatter itself, so it can be used to construct
|
||||
* more complex formatters, including nesting decorators.
|
||||
*/
|
||||
template< typename SubactorT, typename ImplT >
|
||||
class char_decorator_terminal
|
||||
{
|
||||
private:
|
||||
//! Self type
|
||||
typedef char_decorator_terminal< SubactorT, ImplT > this_type;
|
||||
|
||||
public:
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
//! Internal typedef for type categorization
|
||||
typedef void _is_boost_log_terminal;
|
||||
#endif
|
||||
|
||||
//! Implementation type
|
||||
typedef ImplT impl_type;
|
||||
//! Character type
|
||||
typedef typename impl_type::char_type char_type;
|
||||
//! String type
|
||||
typedef typename impl_type::string_type string_type;
|
||||
//! Stream type
|
||||
typedef basic_formatting_ostream< char_type > stream_type;
|
||||
//! Adopted actor type
|
||||
typedef SubactorT subactor_type;
|
||||
|
||||
//! Result type definition
|
||||
typedef string_type result_type;
|
||||
|
||||
private:
|
||||
//! Adopted formatter actor
|
||||
subactor_type m_subactor;
|
||||
//! Implementation
|
||||
impl_type m_impl;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Initializing constructor.
|
||||
*/
|
||||
char_decorator_terminal(subactor_type const& sub, impl_type const& impl) : m_subactor(sub), m_impl(impl)
|
||||
{
|
||||
}
|
||||
/*!
|
||||
* Copy constructor
|
||||
*/
|
||||
char_decorator_terminal(char_decorator_terminal const& that) : m_subactor(that.m_subactor), m_impl(that.m_impl)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* \returns Adopted subactor
|
||||
*/
|
||||
subactor_type const& get_subactor() const
|
||||
{
|
||||
return m_subactor;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \returns Implementation
|
||||
*/
|
||||
impl_type const& get_impl() const
|
||||
{
|
||||
return m_impl;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Invokation operator
|
||||
*/
|
||||
template< typename ContextT >
|
||||
result_type operator() (ContextT const& ctx)
|
||||
{
|
||||
string_type str;
|
||||
stream_type strm(str);
|
||||
|
||||
// Invoke the adopted formatter
|
||||
typedef phoenix::vector3<
|
||||
subactor_type*,
|
||||
typename fusion::result_of::at_c<
|
||||
typename remove_cv<
|
||||
typename remove_reference<
|
||||
typename phoenix::result_of::env< ContextT const& >::type
|
||||
>::type
|
||||
>::type::args_type,
|
||||
0
|
||||
>::type,
|
||||
stream_type&
|
||||
> env_type;
|
||||
env_type env = { boost::addressof(m_subactor), fusion::at_c< 0 >(phoenix::env(ctx).args()), strm };
|
||||
phoenix::eval(m_subactor, phoenix::make_context(env, phoenix::actions(ctx)));
|
||||
|
||||
// Flush the buffered characters and apply decorations
|
||||
strm.flush();
|
||||
m_impl(*strm.rdbuf()->storage());
|
||||
|
||||
return BOOST_LOG_NRVO_RESULT(str);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Invokation operator
|
||||
*/
|
||||
template< typename ContextT >
|
||||
result_type operator() (ContextT const& ctx) const
|
||||
{
|
||||
string_type str;
|
||||
stream_type strm(str);
|
||||
|
||||
// Invoke the adopted formatter
|
||||
typedef phoenix::vector3<
|
||||
const subactor_type*,
|
||||
typename fusion::result_of::at_c<
|
||||
typename remove_cv<
|
||||
typename remove_reference<
|
||||
typename phoenix::result_of::env< ContextT const& >::type
|
||||
>::type
|
||||
>::type::args_type,
|
||||
0
|
||||
>::type,
|
||||
stream_type&
|
||||
> env_type;
|
||||
env_type env = { boost::addressof(m_subactor), fusion::at_c< 0 >(phoenix::env(ctx).args()), strm };
|
||||
phoenix::eval(m_subactor, phoenix::make_context(env, phoenix::actions(ctx)));
|
||||
|
||||
// Flush the buffered characters and apply decorations
|
||||
strm.flush();
|
||||
m_impl(*strm.rdbuf()->storage());
|
||||
|
||||
return BOOST_LOG_NRVO_RESULT(str);
|
||||
}
|
||||
|
||||
BOOST_DELETED_FUNCTION(char_decorator_terminal())
|
||||
};
|
||||
|
||||
/*!
|
||||
* Character decorator actor
|
||||
*/
|
||||
template< typename SubactorT, typename ImplT, template< typename > class ActorT = phoenix::actor >
|
||||
class char_decorator_actor :
|
||||
public ActorT< char_decorator_terminal< SubactorT, ImplT > >
|
||||
{
|
||||
public:
|
||||
//! Base terminal type
|
||||
typedef char_decorator_terminal< SubactorT, ImplT > terminal_type;
|
||||
//! Character type
|
||||
typedef typename terminal_type::char_type char_type;
|
||||
|
||||
//! Base actor type
|
||||
typedef ActorT< terminal_type > base_type;
|
||||
|
||||
public:
|
||||
//! Initializing constructor
|
||||
explicit char_decorator_actor(base_type const& act) : base_type(act)
|
||||
{
|
||||
}
|
||||
|
||||
//! Returns reference to the terminal
|
||||
terminal_type const& get_terminal() const
|
||||
{
|
||||
return this->proto_expr_.child0;
|
||||
}
|
||||
};
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
#define BOOST_LOG_AUX_OVERLOAD(left_ref, right_ref)\
|
||||
template< typename LeftExprT, typename SubactorT, typename ImplT, template< typename > class ActorT >\
|
||||
BOOST_FORCEINLINE phoenix::actor< aux::char_decorator_output_terminal< phoenix::actor< LeftExprT >, SubactorT, ImplT > >\
|
||||
operator<< (phoenix::actor< LeftExprT > left_ref left, char_decorator_actor< SubactorT, ImplT, ActorT > right_ref right)\
|
||||
{\
|
||||
typedef aux::char_decorator_output_terminal< phoenix::actor< LeftExprT >, SubactorT, ImplT > terminal_type;\
|
||||
phoenix::actor< terminal_type > actor = {{ terminal_type(left, right.get_terminal().get_subactor(), right.get_terminal().get_impl()) }};\
|
||||
return actor;\
|
||||
}
|
||||
|
||||
#include <boost/log/detail/generate_overloads.hpp>
|
||||
|
||||
#undef BOOST_LOG_AUX_OVERLOAD
|
||||
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
namespace aux {
|
||||
|
||||
template< typename RangeT >
|
||||
class char_decorator_gen1
|
||||
{
|
||||
RangeT const& m_decorations;
|
||||
|
||||
typedef typename boost::log::aux::deduce_char_type< typename range_value< RangeT >::type::first_type >::type char_type;
|
||||
|
||||
public:
|
||||
explicit char_decorator_gen1(RangeT const& decorations) : m_decorations(decorations)
|
||||
{
|
||||
}
|
||||
|
||||
template< typename SubactorT >
|
||||
BOOST_FORCEINLINE char_decorator_actor< SubactorT, pattern_replacer< char_type > > operator[] (SubactorT const& subactor) const
|
||||
{
|
||||
typedef pattern_replacer< char_type > replacer_type;
|
||||
typedef char_decorator_actor< SubactorT, replacer_type > result_type;
|
||||
typedef typename result_type::terminal_type terminal_type;
|
||||
typename result_type::base_type act = {{ terminal_type(subactor, replacer_type(m_decorations)) }};
|
||||
return result_type(act);
|
||||
}
|
||||
};
|
||||
|
||||
template< typename FromRangeT, typename ToRangeT >
|
||||
class char_decorator_gen2
|
||||
{
|
||||
FromRangeT const& m_from;
|
||||
ToRangeT const& m_to;
|
||||
|
||||
typedef typename boost::log::aux::deduce_char_type< typename range_value< FromRangeT >::type >::type from_char_type;
|
||||
typedef typename boost::log::aux::deduce_char_type< typename range_value< ToRangeT >::type >::type to_char_type;
|
||||
BOOST_STATIC_ASSERT_MSG((is_same< from_char_type, to_char_type >::value), "Boost.Log: character decorator cannot be instantiated with different character types for source and replacement strings");
|
||||
|
||||
public:
|
||||
char_decorator_gen2(FromRangeT const& from, ToRangeT const& to) : m_from(from), m_to(to)
|
||||
{
|
||||
}
|
||||
|
||||
template< typename SubactorT >
|
||||
BOOST_FORCEINLINE char_decorator_actor< SubactorT, pattern_replacer< from_char_type > > operator[] (SubactorT const& subactor) const
|
||||
{
|
||||
typedef pattern_replacer< from_char_type > replacer_type;
|
||||
typedef char_decorator_actor< SubactorT, replacer_type > result_type;
|
||||
typedef typename result_type::terminal_type terminal_type;
|
||||
typename result_type::base_type act = {{ terminal_type(subactor, replacer_type(m_from, m_to)) }};
|
||||
return result_type(act);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
/*!
|
||||
* The function returns a decorator generator object. The generator provides <tt>operator[]</tt> that can be used
|
||||
* to construct the actual decorator.
|
||||
*
|
||||
* \param decorations A sequence of string pairs that will be used as decorations. Every <tt>decorations[i].first</tt>
|
||||
* substring occurrence in the output will be replaced with <tt>decorations[i].second</tt>.
|
||||
*/
|
||||
template< typename RangeT >
|
||||
BOOST_FORCEINLINE aux::char_decorator_gen1< RangeT > char_decor(RangeT const& decorations)
|
||||
{
|
||||
return aux::char_decorator_gen1< RangeT >(decorations);
|
||||
}
|
||||
|
||||
/*!
|
||||
* The function returns a decorator generator object. The generator provides <tt>operator[]</tt> that can be used
|
||||
* to construct the actual decorator.
|
||||
*
|
||||
* \param from A sequence of strings that will be sought in the output.
|
||||
* \param to A sequence of strings that will be used as replacements.
|
||||
*
|
||||
* \note The \a from and \a to sequences mush be of the same size. Every <tt>from[i]</tt>
|
||||
* substring occurrence in the output will be replaced with <tt>to[i]</tt>.
|
||||
*/
|
||||
template< typename FromRangeT, typename ToRangeT >
|
||||
BOOST_FORCEINLINE aux::char_decorator_gen2< FromRangeT, ToRangeT > char_decor(FromRangeT const& from, ToRangeT const& to)
|
||||
{
|
||||
return aux::char_decorator_gen2< FromRangeT, ToRangeT >(from, to);
|
||||
}
|
||||
|
||||
} // namespace expressions
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
namespace phoenix {
|
||||
|
||||
namespace result_of {
|
||||
|
||||
template< typename SubactorT, typename ImplT >
|
||||
struct is_nullary< custom_terminal< boost::log::expressions::char_decorator_terminal< SubactorT, ImplT > > > :
|
||||
public mpl::false_
|
||||
{
|
||||
};
|
||||
|
||||
template< typename LeftT, typename SubactorT, typename ImplT >
|
||||
struct is_nullary< custom_terminal< boost::log::expressions::aux::char_decorator_output_terminal< LeftT, SubactorT, ImplT > > > :
|
||||
public mpl::false_
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace result_of
|
||||
|
||||
} // namespace phoenix
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_EXPRESSIONS_FORMATTERS_CHAR_DECORATOR_HPP_INCLUDED_
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* 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 formatters/csv_decorator.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 18.11.2012
|
||||
*
|
||||
* The header contains implementation of a CSV-style character decorator.
|
||||
* See: http://en.wikipedia.org/wiki/Comma-separated_values
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_EXPRESSIONS_FORMATTERS_CSV_DECORATOR_HPP_INCLUDED_
|
||||
#define BOOST_LOG_EXPRESSIONS_FORMATTERS_CSV_DECORATOR_HPP_INCLUDED_
|
||||
|
||||
#include <boost/range/iterator_range_core.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/expressions/formatters/char_decorator.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace expressions {
|
||||
|
||||
namespace aux {
|
||||
|
||||
template< typename >
|
||||
struct csv_decorator_traits;
|
||||
|
||||
#ifdef BOOST_LOG_USE_CHAR
|
||||
template< >
|
||||
struct csv_decorator_traits< char >
|
||||
{
|
||||
static boost::iterator_range< const char* const* > get_patterns()
|
||||
{
|
||||
static const char* const patterns[] =
|
||||
{
|
||||
"\""
|
||||
};
|
||||
return boost::make_iterator_range(patterns);
|
||||
}
|
||||
static boost::iterator_range< const char* const* > get_replacements()
|
||||
{
|
||||
static const char* const replacements[] =
|
||||
{
|
||||
"\"\""
|
||||
};
|
||||
return boost::make_iterator_range(replacements);
|
||||
}
|
||||
};
|
||||
#endif // BOOST_LOG_USE_CHAR
|
||||
|
||||
#ifdef BOOST_LOG_USE_WCHAR_T
|
||||
template< >
|
||||
struct csv_decorator_traits< wchar_t >
|
||||
{
|
||||
static boost::iterator_range< const wchar_t* const* > get_patterns()
|
||||
{
|
||||
static const wchar_t* const patterns[] =
|
||||
{
|
||||
L"\""
|
||||
};
|
||||
return boost::make_iterator_range(patterns);
|
||||
}
|
||||
static boost::iterator_range< const wchar_t* const* > get_replacements()
|
||||
{
|
||||
static const wchar_t* const replacements[] =
|
||||
{
|
||||
L"\"\""
|
||||
};
|
||||
return boost::make_iterator_range(replacements);
|
||||
}
|
||||
};
|
||||
#endif // BOOST_LOG_USE_WCHAR_T
|
||||
|
||||
template< typename CharT >
|
||||
struct csv_decorator_gen
|
||||
{
|
||||
typedef CharT char_type;
|
||||
|
||||
template< typename SubactorT >
|
||||
BOOST_FORCEINLINE char_decorator_actor< SubactorT, pattern_replacer< char_type > > operator[] (SubactorT const& subactor) const
|
||||
{
|
||||
typedef csv_decorator_traits< char_type > traits_type;
|
||||
typedef pattern_replacer< char_type > replacer_type;
|
||||
typedef char_decorator_actor< SubactorT, replacer_type > result_type;
|
||||
typedef typename result_type::terminal_type terminal_type;
|
||||
typename result_type::base_type act = {{ terminal_type(subactor, replacer_type(traits_type::get_patterns(), traits_type::get_replacements())) }};
|
||||
return result_type(act);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
/*!
|
||||
* CSV-style decorator generator object. The decorator doubles double quotes that may be found
|
||||
* in the output. See http://en.wikipedia.org/wiki/Comma-separated_values for more information on
|
||||
* the CSV format. The generator provides <tt>operator[]</tt> that can be used to construct
|
||||
* the actual decorator. For example:
|
||||
*
|
||||
* <code>
|
||||
* csv_decor[ stream << attr< std::string >("MyAttr") ]
|
||||
* </code>
|
||||
*
|
||||
* For wide-character formatting there is the similar \c wcsv_decor decorator generator object.
|
||||
*/
|
||||
#ifdef BOOST_LOG_USE_CHAR
|
||||
const aux::csv_decorator_gen< char > csv_decor = {};
|
||||
#endif
|
||||
#ifdef BOOST_LOG_USE_WCHAR_T
|
||||
const aux::csv_decorator_gen< wchar_t > wcsv_decor = {};
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* The function creates an CSV-style decorator generator for arbitrary character type.
|
||||
*/
|
||||
template< typename CharT >
|
||||
BOOST_FORCEINLINE aux::csv_decorator_gen< CharT > make_csv_decor()
|
||||
{
|
||||
return aux::csv_decorator_gen< CharT >();
|
||||
}
|
||||
|
||||
} // namespace expressions
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_EXPRESSIONS_FORMATTERS_CSV_DECORATOR_HPP_INCLUDED_
|
||||
@@ -0,0 +1,345 @@
|
||||
/*
|
||||
* 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 formatters/date_time.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 16.09.2012
|
||||
*
|
||||
* The header contains a formatter function for date and time attribute values.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_EXPRESSIONS_FORMATTERS_DATE_TIME_HPP_INCLUDED_
|
||||
#define BOOST_LOG_EXPRESSIONS_FORMATTERS_DATE_TIME_HPP_INCLUDED_
|
||||
|
||||
#include <string>
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include <boost/phoenix/core/actor.hpp>
|
||||
#include <boost/phoenix/core/terminal_fwd.hpp>
|
||||
#include <boost/phoenix/core/is_nullary.hpp>
|
||||
#include <boost/phoenix/core/environment.hpp>
|
||||
#include <boost/fusion/sequence/intrinsic/at_c.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/attributes/attribute_name.hpp>
|
||||
#include <boost/log/attributes/fallback_policy.hpp>
|
||||
#include <boost/log/attributes/value_visitation.hpp>
|
||||
#include <boost/log/detail/light_function.hpp>
|
||||
#include <boost/log/detail/date_time_fmt_gen_traits_fwd.hpp>
|
||||
#include <boost/log/detail/custom_terminal_spec.hpp>
|
||||
#include <boost/log/detail/attr_output_terminal.hpp>
|
||||
#include <boost/log/expressions/attr_fwd.hpp>
|
||||
#include <boost/log/expressions/keyword_fwd.hpp>
|
||||
#include <boost/log/utility/formatting_ostream.hpp>
|
||||
#include <boost/log/utility/functional/bind.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace expressions {
|
||||
|
||||
/*!
|
||||
* Date and time formatter terminal.
|
||||
*/
|
||||
template< typename T, typename FallbackPolicyT, typename CharT >
|
||||
class format_date_time_terminal
|
||||
{
|
||||
public:
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
//! Internal typedef for type categorization
|
||||
typedef void _is_boost_log_terminal;
|
||||
#endif
|
||||
|
||||
//! Attribute value type
|
||||
typedef T value_type;
|
||||
//! Fallback policy
|
||||
typedef FallbackPolicyT fallback_policy;
|
||||
//! Character type
|
||||
typedef CharT char_type;
|
||||
//! String type
|
||||
typedef std::basic_string< char_type > string_type;
|
||||
//! Formatting stream type
|
||||
typedef basic_formatting_ostream< char_type > stream_type;
|
||||
|
||||
//! Formatter function
|
||||
typedef boost::log::aux::light_function< void (stream_type&, value_type const&) > formatter_function_type;
|
||||
|
||||
//! Function result type
|
||||
typedef string_type result_type;
|
||||
|
||||
private:
|
||||
//! Formatter generator traits
|
||||
typedef aux::date_time_formatter_generator_traits< value_type, char_type > formatter_generator;
|
||||
//! Attribute value visitor invoker
|
||||
typedef value_visitor_invoker< value_type, fallback_policy > visitor_invoker_type;
|
||||
|
||||
private:
|
||||
//! Attribute name
|
||||
attribute_name m_name;
|
||||
//! Formattr function
|
||||
formatter_function_type m_formatter;
|
||||
//! Attribute value visitor invoker
|
||||
visitor_invoker_type m_visitor_invoker;
|
||||
|
||||
public:
|
||||
//! Initializing constructor
|
||||
format_date_time_terminal(attribute_name const& name, fallback_policy const& fallback, string_type const& format) :
|
||||
m_name(name), m_formatter(formatter_generator::parse(format)), m_visitor_invoker(fallback)
|
||||
{
|
||||
}
|
||||
//! Copy constructor
|
||||
format_date_time_terminal(format_date_time_terminal const& that) :
|
||||
m_name(that.m_name), m_formatter(that.m_formatter), m_visitor_invoker(that.m_visitor_invoker)
|
||||
{
|
||||
}
|
||||
|
||||
//! Returns attribute name
|
||||
attribute_name get_name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
//! Returns fallback policy
|
||||
fallback_policy const& get_fallback_policy() const
|
||||
{
|
||||
return m_visitor_invoker.get_fallback_policy();
|
||||
}
|
||||
|
||||
//! Retruns formatter function
|
||||
formatter_function_type const& get_formatter_function() const
|
||||
{
|
||||
return m_formatter;
|
||||
}
|
||||
|
||||
//! Invokation operator
|
||||
template< typename ContextT >
|
||||
result_type operator() (ContextT const& ctx)
|
||||
{
|
||||
string_type str;
|
||||
stream_type strm(str);
|
||||
m_visitor_invoker(m_name, fusion::at_c< 0 >(phoenix::env(ctx).args()), binder1st< formatter_function_type&, stream_type& >(m_formatter, strm));
|
||||
strm.flush();
|
||||
return BOOST_LOG_NRVO_RESULT(str);
|
||||
}
|
||||
|
||||
//! Invokation operator
|
||||
template< typename ContextT >
|
||||
result_type operator() (ContextT const& ctx) const
|
||||
{
|
||||
string_type str;
|
||||
stream_type strm(str);
|
||||
m_visitor_invoker(m_name, fusion::at_c< 0 >(phoenix::env(ctx).args()), binder1st< formatter_function_type const&, stream_type& >(m_formatter, strm));
|
||||
strm.flush();
|
||||
return BOOST_LOG_NRVO_RESULT(str);
|
||||
}
|
||||
|
||||
BOOST_DELETED_FUNCTION(format_date_time_terminal())
|
||||
};
|
||||
|
||||
/*!
|
||||
* Date and time formatter actor.
|
||||
*/
|
||||
template< typename T, typename FallbackPolicyT, typename CharT, template< typename > class ActorT = phoenix::actor >
|
||||
class format_date_time_actor :
|
||||
public ActorT< format_date_time_terminal< T, FallbackPolicyT, CharT > >
|
||||
{
|
||||
public:
|
||||
//! Attribute value type
|
||||
typedef T value_type;
|
||||
//! Character type
|
||||
typedef CharT char_type;
|
||||
//! Fallback policy
|
||||
typedef FallbackPolicyT fallback_policy;
|
||||
//! Base terminal type
|
||||
typedef format_date_time_terminal< value_type, fallback_policy, char_type > terminal_type;
|
||||
//! Formatter function
|
||||
typedef typename terminal_type::formatter_function_type formatter_function_type;
|
||||
|
||||
//! Base actor type
|
||||
typedef ActorT< terminal_type > base_type;
|
||||
|
||||
public:
|
||||
//! Initializing constructor
|
||||
explicit format_date_time_actor(base_type const& act) : base_type(act)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* \returns The attribute name
|
||||
*/
|
||||
attribute_name get_name() const
|
||||
{
|
||||
return this->proto_expr_.child0.get_name();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \returns Fallback policy
|
||||
*/
|
||||
fallback_policy const& get_fallback_policy() const
|
||||
{
|
||||
return this->proto_expr_.child0.get_fallback_policy();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \returns Formatter function
|
||||
*/
|
||||
formatter_function_type const& get_formatter_function() const
|
||||
{
|
||||
return this->proto_expr_.child0.get_formatter_function();
|
||||
}
|
||||
};
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
#define BOOST_LOG_AUX_OVERLOAD(left_ref, right_ref)\
|
||||
template< typename LeftExprT, typename T, typename FallbackPolicyT, typename CharT >\
|
||||
BOOST_FORCEINLINE phoenix::actor< aux::attribute_output_terminal< phoenix::actor< LeftExprT >, T, FallbackPolicyT, typename format_date_time_actor< T, FallbackPolicyT, CharT >::formatter_function_type > >\
|
||||
operator<< (phoenix::actor< LeftExprT > left_ref left, format_date_time_actor< T, FallbackPolicyT, CharT > right_ref right)\
|
||||
{\
|
||||
typedef aux::attribute_output_terminal< phoenix::actor< LeftExprT >, T, FallbackPolicyT, typename format_date_time_actor< T, FallbackPolicyT, CharT >::formatter_function_type > terminal_type;\
|
||||
phoenix::actor< terminal_type > actor = {{ terminal_type(left, right.get_name(), right.get_formatter_function(), right.get_fallback_policy()) }};\
|
||||
return actor;\
|
||||
}
|
||||
|
||||
#include <boost/log/detail/generate_overloads.hpp>
|
||||
|
||||
#undef BOOST_LOG_AUX_OVERLOAD
|
||||
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
/*!
|
||||
* The function generates a manipulator node in a template expression. The manipulator must participate in a formatting
|
||||
* expression (stream output or \c format placeholder filler).
|
||||
*
|
||||
* \param name Attribute name
|
||||
* \param format Format string
|
||||
*/
|
||||
template< typename AttributeValueT, typename CharT >
|
||||
BOOST_FORCEINLINE format_date_time_actor< AttributeValueT, fallback_to_none, CharT > format_date_time(attribute_name const& name, const CharT* format)
|
||||
{
|
||||
typedef format_date_time_actor< AttributeValueT, fallback_to_none, CharT > actor_type;
|
||||
typedef typename actor_type::terminal_type terminal_type;
|
||||
typename actor_type::base_type act = {{ terminal_type(name, fallback_to_none(), format) }};
|
||||
return actor_type(act);
|
||||
}
|
||||
|
||||
/*!
|
||||
* The function generates a manipulator node in a template expression. The manipulator must participate in a formatting
|
||||
* expression (stream output or \c format placeholder filler).
|
||||
*
|
||||
* \param name Attribute name
|
||||
* \param format Format string
|
||||
*/
|
||||
template< typename AttributeValueT, typename CharT >
|
||||
BOOST_FORCEINLINE format_date_time_actor< AttributeValueT, fallback_to_none, CharT > format_date_time(attribute_name const& name, std::basic_string< CharT > const& format)
|
||||
{
|
||||
typedef format_date_time_actor< AttributeValueT, fallback_to_none, CharT > actor_type;
|
||||
typedef typename actor_type::terminal_type terminal_type;
|
||||
typename actor_type::base_type act = {{ terminal_type(name, fallback_to_none(), format) }};
|
||||
return actor_type(act);
|
||||
}
|
||||
|
||||
/*!
|
||||
* The function generates a manipulator node in a template expression. The manipulator must participate in a formatting
|
||||
* expression (stream output or \c format placeholder filler).
|
||||
*
|
||||
* \param keyword Attribute keyword
|
||||
* \param format Format string
|
||||
*/
|
||||
template< typename DescriptorT, template< typename > class ActorT, typename CharT >
|
||||
BOOST_FORCEINLINE format_date_time_actor< typename DescriptorT::value_type, fallback_to_none, CharT, ActorT >
|
||||
format_date_time(attribute_keyword< DescriptorT, ActorT > const& keyword, const CharT* format)
|
||||
{
|
||||
typedef format_date_time_actor< typename DescriptorT::value_type, fallback_to_none, CharT, ActorT > actor_type;
|
||||
typedef typename actor_type::terminal_type terminal_type;
|
||||
typename actor_type::base_type act = {{ terminal_type(keyword.get_name(), fallback_to_none(), format) }};
|
||||
return actor_type(act);
|
||||
}
|
||||
|
||||
/*!
|
||||
* The function generates a manipulator node in a template expression. The manipulator must participate in a formatting
|
||||
* expression (stream output or \c format placeholder filler).
|
||||
*
|
||||
* \param keyword Attribute keyword
|
||||
* \param format Format string
|
||||
*/
|
||||
template< typename DescriptorT, template< typename > class ActorT, typename CharT >
|
||||
BOOST_FORCEINLINE format_date_time_actor< typename DescriptorT::value_type, fallback_to_none, CharT, ActorT >
|
||||
format_date_time(attribute_keyword< DescriptorT, ActorT > const& keyword, std::basic_string< CharT > const& format)
|
||||
{
|
||||
typedef format_date_time_actor< typename DescriptorT::value_type, fallback_to_none, CharT, ActorT > actor_type;
|
||||
typedef typename actor_type::terminal_type terminal_type;
|
||||
typename actor_type::base_type act = {{ terminal_type(keyword.get_name(), fallback_to_none(), format) }};
|
||||
return actor_type(act);
|
||||
}
|
||||
|
||||
/*!
|
||||
* The function generates a manipulator node in a template expression. The manipulator must participate in a formatting
|
||||
* expression (stream output or \c format placeholder filler).
|
||||
*
|
||||
* \param placeholder Attribute placeholder
|
||||
* \param format Format string
|
||||
*/
|
||||
template< typename T, typename FallbackPolicyT, typename TagT, template< typename > class ActorT, typename CharT >
|
||||
BOOST_FORCEINLINE format_date_time_actor< T, FallbackPolicyT, CharT, ActorT >
|
||||
format_date_time(attribute_actor< T, FallbackPolicyT, TagT, ActorT > const& placeholder, const CharT* format)
|
||||
{
|
||||
typedef format_date_time_actor< T, FallbackPolicyT, CharT, ActorT > actor_type;
|
||||
typedef typename actor_type::terminal_type terminal_type;
|
||||
typename actor_type::base_type act = {{ terminal_type(placeholder.get_name(), placeholder.get_fallback_policy(), format) }};
|
||||
return actor_type(act);
|
||||
}
|
||||
|
||||
/*!
|
||||
* The function generates a manipulator node in a template expression. The manipulator must participate in a formatting
|
||||
* expression (stream output or \c format placeholder filler).
|
||||
*
|
||||
* \param placeholder Attribute placeholder
|
||||
* \param format Format string
|
||||
*/
|
||||
template< typename T, typename FallbackPolicyT, typename TagT, template< typename > class ActorT, typename CharT >
|
||||
BOOST_FORCEINLINE format_date_time_actor< T, FallbackPolicyT, CharT, ActorT >
|
||||
format_date_time(attribute_actor< T, FallbackPolicyT, TagT, ActorT > const& placeholder, std::basic_string< CharT > const& format)
|
||||
{
|
||||
typedef format_date_time_actor< T, FallbackPolicyT, CharT, ActorT > actor_type;
|
||||
typedef typename actor_type::terminal_type terminal_type;
|
||||
typename actor_type::base_type act = {{ terminal_type(placeholder.get_name(), placeholder.get_fallback_policy(), format) }};
|
||||
return actor_type(act);
|
||||
}
|
||||
|
||||
} // namespace expressions
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
namespace phoenix {
|
||||
|
||||
namespace result_of {
|
||||
|
||||
template< typename T, typename FallbackPolicyT, typename CharT >
|
||||
struct is_nullary< custom_terminal< boost::log::expressions::format_date_time_terminal< T, FallbackPolicyT, CharT > > > :
|
||||
public mpl::false_
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace result_of
|
||||
|
||||
} // namespace phoenix
|
||||
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_EXPRESSIONS_FORMATTERS_DATE_TIME_HPP_INCLUDED_
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* 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 formatters/format.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 15.11.2012
|
||||
*
|
||||
* The header contains a generic log record formatter function.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_EXPRESSIONS_FORMATTERS_FORMAT_HPP_INCLUDED_
|
||||
#define BOOST_LOG_EXPRESSIONS_FORMATTERS_FORMAT_HPP_INCLUDED_
|
||||
|
||||
#include <string>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/phoenix/core/actor.hpp>
|
||||
#include <boost/phoenix/core/terminal_fwd.hpp>
|
||||
#include <boost/phoenix/core/is_nullary.hpp>
|
||||
#include <boost/phoenix/core/environment.hpp>
|
||||
#include <boost/fusion/sequence/intrinsic/at_c.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/format.hpp>
|
||||
#include <boost/log/detail/custom_terminal_spec.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace expressions {
|
||||
|
||||
/*!
|
||||
* \brief Template expressions terminal node with Boost.Format-like formatter
|
||||
*/
|
||||
template< typename CharT >
|
||||
class format_terminal
|
||||
{
|
||||
public:
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
//! Internal typedef for type categorization
|
||||
typedef void _is_boost_log_terminal;
|
||||
#endif
|
||||
|
||||
//! Character type
|
||||
typedef CharT char_type;
|
||||
//! Boost.Format formatter type
|
||||
typedef boost::log::aux::basic_format< char_type > format_type;
|
||||
//! String type
|
||||
typedef std::basic_string< char_type > string_type;
|
||||
|
||||
//! Terminal result type
|
||||
typedef typename format_type::pump result_type;
|
||||
|
||||
private:
|
||||
//! Formatter object
|
||||
mutable format_type m_format;
|
||||
|
||||
public:
|
||||
//! Initializing constructor
|
||||
explicit format_terminal(const char_type* format) : m_format(format) {}
|
||||
|
||||
//! Invokation operator
|
||||
template< typename ContextT >
|
||||
result_type operator() (ContextT const& ctx) const
|
||||
{
|
||||
return m_format.make_pump(fusion::at_c< 1 >(phoenix::env(ctx).args()));
|
||||
}
|
||||
|
||||
BOOST_DELETED_FUNCTION(format_terminal())
|
||||
};
|
||||
|
||||
/*!
|
||||
* The function generates a terminal node in a template expression. The node will perform log record formatting
|
||||
* according to the provided format string.
|
||||
*/
|
||||
template< typename CharT >
|
||||
BOOST_FORCEINLINE phoenix::actor< format_terminal< CharT > > format(const CharT* fmt)
|
||||
{
|
||||
typedef format_terminal< CharT > terminal_type;
|
||||
phoenix::actor< terminal_type > act = {{ terminal_type(fmt) }};
|
||||
return act;
|
||||
}
|
||||
|
||||
/*!
|
||||
* The function generates a terminal node in a template expression. The node will perform log record formatting
|
||||
* according to the provided format string.
|
||||
*/
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT >
|
||||
BOOST_FORCEINLINE phoenix::actor< format_terminal< CharT > > format(std::basic_string< CharT, TraitsT, AllocatorT > const& fmt)
|
||||
{
|
||||
typedef format_terminal< CharT > terminal_type;
|
||||
phoenix::actor< terminal_type > act = {{ terminal_type(fmt.c_str()) }};
|
||||
return act;
|
||||
}
|
||||
|
||||
} // namespace expressions
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
namespace phoenix {
|
||||
|
||||
namespace result_of {
|
||||
|
||||
template< typename CharT >
|
||||
struct is_nullary< custom_terminal< boost::log::expressions::format_terminal< CharT > > > :
|
||||
public mpl::false_
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace result_of
|
||||
|
||||
} // namespace phoenix
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_EXPRESSIONS_FORMATTERS_FORMAT_HPP_INCLUDED_
|
||||
@@ -0,0 +1,319 @@
|
||||
/*
|
||||
* 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 formatters/if.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 17.11.2012
|
||||
*
|
||||
* The header contains implementation of a conditional formatter.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_EXPRESSIONS_FORMATTERS_IF_HPP_INCLUDED_
|
||||
#define BOOST_LOG_EXPRESSIONS_FORMATTERS_IF_HPP_INCLUDED_
|
||||
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/phoenix/core/actor.hpp>
|
||||
#include <boost/phoenix/core/meta_grammar.hpp>
|
||||
#include <boost/phoenix/core/terminal_fwd.hpp>
|
||||
#include <boost/phoenix/core/is_nullary.hpp>
|
||||
#include <boost/phoenix/core/environment.hpp>
|
||||
#include <boost/fusion/sequence/intrinsic/at_c.hpp>
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/custom_terminal_spec.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace expressions {
|
||||
|
||||
namespace aux {
|
||||
|
||||
template< typename LeftT, typename CondT, typename ThenT >
|
||||
class if_output_terminal
|
||||
{
|
||||
private:
|
||||
//! Self type
|
||||
typedef if_output_terminal this_type;
|
||||
|
||||
public:
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
//! Internal typedef for type categorization
|
||||
typedef void _is_boost_log_terminal;
|
||||
#endif
|
||||
|
||||
//! Result type definition
|
||||
template< typename >
|
||||
struct result;
|
||||
|
||||
template< typename ThisT, typename ContextT >
|
||||
struct result< ThisT(ContextT) >
|
||||
{
|
||||
typedef typename remove_cv< typename remove_reference< ContextT >::type >::type context_type;
|
||||
typedef typename phoenix::evaluator::impl<
|
||||
typename LeftT::proto_base_expr&,
|
||||
context_type,
|
||||
phoenix::unused
|
||||
>::result_type type;
|
||||
};
|
||||
|
||||
private:
|
||||
//! Left argument actor
|
||||
LeftT m_left;
|
||||
//! Condition expression
|
||||
CondT m_cond;
|
||||
//! Positive branch
|
||||
ThenT m_then;
|
||||
|
||||
public:
|
||||
//! Initializing constructor
|
||||
if_output_terminal(LeftT const& left, CondT const& cond, ThenT const& then_) : m_left(left), m_cond(cond), m_then(then_)
|
||||
{
|
||||
}
|
||||
|
||||
//! Invokation operator
|
||||
template< typename ContextT >
|
||||
typename result< this_type(ContextT const&) >::type operator() (ContextT const& ctx)
|
||||
{
|
||||
typedef typename result< this_type(ContextT const&) >::type result_type;
|
||||
result_type strm = phoenix::eval(m_left, ctx);
|
||||
if (phoenix::eval(m_cond, ctx))
|
||||
phoenix::eval(m_then, ctx);
|
||||
return strm;
|
||||
}
|
||||
|
||||
//! Invokation operator
|
||||
template< typename ContextT >
|
||||
typename result< const this_type(ContextT const&) >::type operator() (ContextT const& ctx) const
|
||||
{
|
||||
typedef typename result< const this_type(ContextT const&) >::type result_type;
|
||||
result_type strm = phoenix::eval(m_left, ctx);
|
||||
if (phoenix::eval(m_cond, ctx))
|
||||
phoenix::eval(m_then, ctx);
|
||||
return strm;
|
||||
}
|
||||
|
||||
BOOST_DELETED_FUNCTION(if_output_terminal())
|
||||
};
|
||||
|
||||
template< typename LeftT, typename CondT, typename ThenT, typename ElseT >
|
||||
class if_else_output_terminal
|
||||
{
|
||||
private:
|
||||
//! Self type
|
||||
typedef if_else_output_terminal this_type;
|
||||
|
||||
public:
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
//! Internal typedef for type categorization
|
||||
typedef void _is_boost_log_terminal;
|
||||
#endif
|
||||
|
||||
//! Result type definition
|
||||
template< typename >
|
||||
struct result;
|
||||
|
||||
template< typename ThisT, typename ContextT >
|
||||
struct result< ThisT(ContextT) >
|
||||
{
|
||||
typedef typename remove_cv< typename remove_reference< ContextT >::type >::type context_type;
|
||||
typedef typename phoenix::evaluator::impl<
|
||||
typename LeftT::proto_base_expr&,
|
||||
context_type,
|
||||
phoenix::unused
|
||||
>::result_type type;
|
||||
};
|
||||
|
||||
private:
|
||||
//! Left argument actor
|
||||
LeftT m_left;
|
||||
//! Condition expression
|
||||
CondT m_cond;
|
||||
//! Positive branch
|
||||
ThenT m_then;
|
||||
//! Negative branch
|
||||
ElseT m_else;
|
||||
|
||||
public:
|
||||
//! Initializing constructor
|
||||
if_else_output_terminal(LeftT const& left, CondT const& cond, ThenT const& then_, ElseT const& else_) : m_left(left), m_cond(cond), m_then(then_), m_else(else_)
|
||||
{
|
||||
}
|
||||
|
||||
//! Invokation operator
|
||||
template< typename ContextT >
|
||||
typename result< this_type(ContextT const&) >::type operator() (ContextT const& ctx)
|
||||
{
|
||||
typedef typename result< this_type(ContextT const&) >::type result_type;
|
||||
result_type strm = phoenix::eval(m_left, ctx);
|
||||
if (phoenix::eval(m_cond, ctx))
|
||||
phoenix::eval(m_then, ctx);
|
||||
else
|
||||
phoenix::eval(m_else, ctx);
|
||||
return strm;
|
||||
}
|
||||
|
||||
//! Invokation operator
|
||||
template< typename ContextT >
|
||||
typename result< const this_type(ContextT const&) >::type operator() (ContextT const& ctx) const
|
||||
{
|
||||
typedef typename result< const this_type(ContextT const&) >::type result_type;
|
||||
result_type strm = phoenix::eval(m_left, ctx);
|
||||
if (phoenix::eval(m_cond, ctx))
|
||||
phoenix::eval(m_then, ctx);
|
||||
else
|
||||
phoenix::eval(m_else, ctx);
|
||||
return strm;
|
||||
}
|
||||
|
||||
BOOST_DELETED_FUNCTION(if_else_output_terminal())
|
||||
};
|
||||
|
||||
|
||||
template< typename CondT, typename ThenT, typename ElseT >
|
||||
struct if_then_else_gen
|
||||
{
|
||||
CondT m_cond;
|
||||
ThenT m_then;
|
||||
ElseT m_else;
|
||||
|
||||
if_then_else_gen(CondT const& cond, ThenT const& then_, ElseT const& else_) : m_cond(cond), m_then(then_), m_else(else_)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
#define BOOST_LOG_AUX_OVERLOAD(left_ref, right_ref)\
|
||||
template< typename LeftExprT, typename CondT, typename ThenT, typename ElseT >\
|
||||
BOOST_FORCEINLINE phoenix::actor< if_else_output_terminal< phoenix::actor< LeftExprT >, CondT, ThenT, ElseT > >\
|
||||
operator<< (phoenix::actor< LeftExprT > left_ref left, if_then_else_gen< CondT, ThenT, ElseT > right_ref right)\
|
||||
{\
|
||||
typedef if_else_output_terminal< phoenix::actor< LeftExprT >, CondT, ThenT, ElseT > terminal_type;\
|
||||
phoenix::actor< terminal_type > actor = {{ terminal_type(left, right.m_cond, right.m_then, right.m_else) }};\
|
||||
return actor;\
|
||||
}
|
||||
|
||||
#include <boost/log/detail/generate_overloads.hpp>
|
||||
|
||||
#undef BOOST_LOG_AUX_OVERLOAD
|
||||
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
template< typename CondT, typename ThenT >
|
||||
struct if_then_gen
|
||||
{
|
||||
struct else_gen
|
||||
{
|
||||
CondT m_cond;
|
||||
ThenT m_then;
|
||||
|
||||
else_gen(CondT const& cond, ThenT const& then_) : m_cond(cond), m_then(then_)
|
||||
{
|
||||
}
|
||||
|
||||
template< typename ElseT >
|
||||
BOOST_FORCEINLINE if_then_else_gen< CondT, ThenT, ElseT > operator[] (ElseT const& el)
|
||||
{
|
||||
return if_then_else_gen< CondT, ThenT, ElseT >(m_cond, m_then, el);
|
||||
}
|
||||
}
|
||||
else_;
|
||||
|
||||
if_then_gen(CondT const& cond, ThenT const& then_) : else_(cond, then_) {}
|
||||
};
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
#define BOOST_LOG_AUX_OVERLOAD(left_ref, right_ref)\
|
||||
template< typename LeftExprT, typename CondT, typename ThenT >\
|
||||
BOOST_FORCEINLINE phoenix::actor< if_output_terminal< phoenix::actor< LeftExprT >, CondT, ThenT > >\
|
||||
operator<< (phoenix::actor< LeftExprT > left_ref left, if_then_gen< CondT, ThenT > right_ref right)\
|
||||
{\
|
||||
typedef if_output_terminal< phoenix::actor< LeftExprT >, CondT, ThenT > terminal_type;\
|
||||
phoenix::actor< terminal_type > actor = {{ terminal_type(left, right.else_.m_cond, right.else_.m_then) }};\
|
||||
return actor;\
|
||||
}
|
||||
|
||||
#include <boost/log/detail/generate_overloads.hpp>
|
||||
|
||||
#undef BOOST_LOG_AUX_OVERLOAD
|
||||
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
template< typename CondT >
|
||||
class if_gen
|
||||
{
|
||||
private:
|
||||
CondT const& m_cond;
|
||||
|
||||
public:
|
||||
explicit if_gen(CondT const& cond) : m_cond(cond)
|
||||
{
|
||||
}
|
||||
|
||||
template< typename ThenT >
|
||||
BOOST_FORCEINLINE if_then_gen< CondT, ThenT > operator[] (ThenT const& then_) const
|
||||
{
|
||||
return if_then_gen< CondT, ThenT >(m_cond, then_);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
/*!
|
||||
* The function returns a conditional formatter generator object. The generator provides <tt>operator[]</tt> that can be used
|
||||
* to construct the actual formatter. The formatter must participate in a streaming expression.
|
||||
*
|
||||
* \param cond A filter expression that will be used as the condition
|
||||
*/
|
||||
template< typename CondT >
|
||||
BOOST_FORCEINLINE aux::if_gen< CondT > if_(CondT const& cond)
|
||||
{
|
||||
return aux::if_gen< CondT >(cond);
|
||||
}
|
||||
|
||||
} // namespace expressions
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
namespace phoenix {
|
||||
|
||||
namespace result_of {
|
||||
|
||||
template< typename LeftT, typename CondT, typename ThenT >
|
||||
struct is_nullary< custom_terminal< boost::log::expressions::aux::if_output_terminal< LeftT, CondT, ThenT > > > :
|
||||
public mpl::false_
|
||||
{
|
||||
};
|
||||
|
||||
template< typename LeftT, typename CondT, typename ThenT, typename ElseT >
|
||||
struct is_nullary< custom_terminal< boost::log::expressions::aux::if_else_output_terminal< LeftT, CondT, ThenT, ElseT > > > :
|
||||
public mpl::false_
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace result_of
|
||||
|
||||
} // namespace phoenix
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_EXPRESSIONS_FORMATTERS_IF_HPP_INCLUDED_
|
||||
+561
@@ -0,0 +1,561 @@
|
||||
/*
|
||||
* Copyright Andrey Semashev 2016.
|
||||
* 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 formatters/max_size_decorator.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 06.07.2016
|
||||
*
|
||||
* The header contains implementation of a string length limiting decorator.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_EXPRESSIONS_FORMATTERS_MAX_SIZE_DECORATOR_HPP_INCLUDED_
|
||||
#define BOOST_LOG_EXPRESSIONS_FORMATTERS_MAX_SIZE_DECORATOR_HPP_INCLUDED_
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include <boost/core/addressof.hpp>
|
||||
#include <boost/phoenix/core/actor.hpp>
|
||||
#include <boost/phoenix/core/meta_grammar.hpp>
|
||||
#include <boost/phoenix/core/terminal_fwd.hpp>
|
||||
#include <boost/phoenix/core/is_nullary.hpp>
|
||||
#include <boost/phoenix/core/environment.hpp>
|
||||
#include <boost/phoenix/support/vector.hpp>
|
||||
#include <boost/fusion/sequence/intrinsic/at_c.hpp>
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/custom_terminal_spec.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
|
||||
|
||||
namespace expressions {
|
||||
|
||||
namespace aux {
|
||||
|
||||
//! String size limiting decorator stream output terminal
|
||||
template< typename LeftT, typename SubactorT, typename CharT >
|
||||
class max_size_decorator_output_terminal
|
||||
{
|
||||
private:
|
||||
//! Self type
|
||||
typedef max_size_decorator_output_terminal< LeftT, SubactorT, CharT > this_type;
|
||||
|
||||
public:
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
//! Internal typedef for type categorization
|
||||
typedef void _is_boost_log_terminal;
|
||||
#endif
|
||||
|
||||
//! Character type
|
||||
typedef CharT char_type;
|
||||
//! String type
|
||||
typedef std::basic_string< char_type > string_type;
|
||||
//! String size type
|
||||
typedef std::size_t size_type;
|
||||
//! Adopted actor type
|
||||
typedef SubactorT subactor_type;
|
||||
|
||||
//! Result type definition
|
||||
template< typename >
|
||||
struct result;
|
||||
|
||||
template< typename ThisT, typename ContextT >
|
||||
struct result< ThisT(ContextT) >
|
||||
{
|
||||
typedef typename remove_cv< typename remove_reference< ContextT >::type >::type context_type;
|
||||
typedef typename phoenix::evaluator::impl<
|
||||
typename LeftT::proto_base_expr&,
|
||||
context_type,
|
||||
phoenix::unused
|
||||
>::result_type type;
|
||||
};
|
||||
|
||||
private:
|
||||
//! Left argument actor
|
||||
LeftT m_left;
|
||||
//! Adopted formatter actor
|
||||
subactor_type m_subactor;
|
||||
//! Max size of the formatted string produced by the adopted formatter
|
||||
size_type m_max_size;
|
||||
//! Overflow marker
|
||||
string_type m_overflow_marker;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Initializing constructor. Creates decorator of the \a fmt formatter with the specified \a decorations.
|
||||
*/
|
||||
max_size_decorator_output_terminal(LeftT const& left, subactor_type const& sub, size_type max_size, string_type const& overflow_marker = string_type()) :
|
||||
m_left(left), m_subactor(sub), m_max_size(max_size), m_overflow_marker(overflow_marker)
|
||||
{
|
||||
BOOST_ASSERT(overflow_marker.size() <= max_size);
|
||||
}
|
||||
/*!
|
||||
* Copy constructor
|
||||
*/
|
||||
max_size_decorator_output_terminal(max_size_decorator_output_terminal const& that) :
|
||||
m_left(that.m_left), m_subactor(that.m_subactor), m_max_size(that.m_max_size), m_overflow_marker(that.m_overflow_marker)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* Invokation operator
|
||||
*/
|
||||
template< typename ContextT >
|
||||
typename result< this_type(ContextT const&) >::type operator() (ContextT const& ctx)
|
||||
{
|
||||
// Flush the stream and keep the current write position in the target string
|
||||
typedef typename result< this_type(ContextT const&) >::type result_type;
|
||||
result_type strm = phoenix::eval(m_left, ctx);
|
||||
strm.flush();
|
||||
|
||||
if (!strm.rdbuf()->storage_overflow())
|
||||
{
|
||||
const size_type old_max_size = strm.rdbuf()->max_size();
|
||||
const size_type start_pos = strm.rdbuf()->storage()->size(), max_size_left = strm.rdbuf()->storage()->max_size() - start_pos;
|
||||
strm.rdbuf()->max_size(start_pos + (m_max_size <= max_size_left ? m_max_size : max_size_left));
|
||||
|
||||
try
|
||||
{
|
||||
// Invoke the adopted formatter
|
||||
phoenix::eval(m_subactor, ctx);
|
||||
|
||||
// Flush the buffered characters and apply decorations
|
||||
strm.flush();
|
||||
|
||||
if (strm.rdbuf()->storage_overflow())
|
||||
{
|
||||
if (!m_overflow_marker.empty())
|
||||
{
|
||||
// Free up space for the overflow marker
|
||||
strm.rdbuf()->max_size(strm.rdbuf()->max_size() - m_overflow_marker.size());
|
||||
|
||||
// Append the marker
|
||||
strm.rdbuf()->max_size(strm.rdbuf()->storage()->max_size());
|
||||
strm.rdbuf()->storage_overflow(false);
|
||||
strm.rdbuf()->append(m_overflow_marker.data(), m_overflow_marker.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
strm.rdbuf()->storage_overflow(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Restore the original size limit
|
||||
strm.rdbuf()->max_size(old_max_size);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
strm.rdbuf()->storage_overflow(false);
|
||||
strm.rdbuf()->max_size(old_max_size);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
return strm;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Invokation operator
|
||||
*/
|
||||
template< typename ContextT >
|
||||
typename result< const this_type(ContextT const&) >::type operator() (ContextT const& ctx) const
|
||||
{
|
||||
// Flush the stream and keep the current write position in the target string
|
||||
typedef typename result< const this_type(ContextT const&) >::type result_type;
|
||||
result_type strm = phoenix::eval(m_left, ctx);
|
||||
strm.flush();
|
||||
|
||||
if (!strm.rdbuf()->storage_overflow())
|
||||
{
|
||||
const size_type old_max_size = strm.rdbuf()->max_size();
|
||||
const size_type start_pos = strm.rdbuf()->storage()->size(), max_size_left = strm.rdbuf()->storage()->max_size() - start_pos;
|
||||
strm.rdbuf()->max_size(start_pos + (m_max_size <= max_size_left ? m_max_size : max_size_left));
|
||||
|
||||
try
|
||||
{
|
||||
// Invoke the adopted formatter
|
||||
phoenix::eval(m_subactor, ctx);
|
||||
|
||||
// Flush the buffered characters and apply decorations
|
||||
strm.flush();
|
||||
|
||||
if (strm.rdbuf()->storage_overflow())
|
||||
{
|
||||
if (!m_overflow_marker.empty())
|
||||
{
|
||||
// Free up space for the overflow marker
|
||||
strm.rdbuf()->max_size(strm.rdbuf()->max_size() - m_overflow_marker.size());
|
||||
|
||||
// Append the marker
|
||||
strm.rdbuf()->max_size(strm.rdbuf()->storage()->max_size());
|
||||
strm.rdbuf()->storage_overflow(false);
|
||||
strm.rdbuf()->append(m_overflow_marker.data(), m_overflow_marker.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
strm.rdbuf()->storage_overflow(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Restore the original size limit
|
||||
strm.rdbuf()->max_size(old_max_size);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
strm.rdbuf()->storage_overflow(false);
|
||||
strm.rdbuf()->max_size(old_max_size);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
return strm;
|
||||
}
|
||||
|
||||
BOOST_DELETED_FUNCTION(max_size_decorator_output_terminal())
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
/*!
|
||||
* String size limiting decorator terminal class. This formatter allows to limit the maximum total length
|
||||
* of the strings generated by other formatters.
|
||||
*
|
||||
* The \c max_size_decorator_terminal class aggregates the formatter being decorated, the maximum string length
|
||||
* it can produce and an optional truncation marker string, which will be put at the end of the output if the limit is exceeded. Note that
|
||||
* the marker length is included in the limit and as such must not exceed it.
|
||||
* The \c max_size_decorator_terminal class is a formatter itself, so it can be used to construct
|
||||
* more complex formatters, including nesting decorators.
|
||||
*/
|
||||
template< typename SubactorT, typename CharT >
|
||||
class max_size_decorator_terminal
|
||||
{
|
||||
private:
|
||||
//! Self type
|
||||
typedef max_size_decorator_terminal< SubactorT, CharT > this_type;
|
||||
|
||||
public:
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
//! Internal typedef for type categorization
|
||||
typedef void _is_boost_log_terminal;
|
||||
#endif
|
||||
|
||||
//! Character type
|
||||
typedef CharT char_type;
|
||||
//! String type
|
||||
typedef std::basic_string< char_type > string_type;
|
||||
//! String size type
|
||||
typedef std::size_t size_type;
|
||||
//! Stream type
|
||||
typedef basic_formatting_ostream< char_type > stream_type;
|
||||
//! Adopted actor type
|
||||
typedef SubactorT subactor_type;
|
||||
|
||||
//! Result type definition
|
||||
typedef string_type result_type;
|
||||
|
||||
private:
|
||||
//! Adopted formatter actor
|
||||
subactor_type m_subactor;
|
||||
//! Max size of the formatted string produced by the adopted formatter
|
||||
size_type m_max_size;
|
||||
//! Overflow marker
|
||||
string_type m_overflow_marker;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Initializing constructor.
|
||||
*/
|
||||
max_size_decorator_terminal(subactor_type const& sub, size_type max_size, string_type const& overflow_marker = string_type()) :
|
||||
m_subactor(sub), m_max_size(max_size), m_overflow_marker(overflow_marker)
|
||||
{
|
||||
BOOST_ASSERT(overflow_marker.size() <= max_size);
|
||||
}
|
||||
/*!
|
||||
* Copy constructor
|
||||
*/
|
||||
max_size_decorator_terminal(max_size_decorator_terminal const& that) :
|
||||
m_subactor(that.m_subactor), m_max_size(that.m_max_size), m_overflow_marker(that.m_overflow_marker)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* \returns Adopted subactor
|
||||
*/
|
||||
subactor_type const& get_subactor() const
|
||||
{
|
||||
return m_subactor;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \returns Max string size limit
|
||||
*/
|
||||
size_type get_max_size() const
|
||||
{
|
||||
return m_max_size;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \returns Max string size limit
|
||||
*/
|
||||
string_type const& get_overflow_marker() const
|
||||
{
|
||||
return m_overflow_marker;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Invokation operator
|
||||
*/
|
||||
template< typename ContextT >
|
||||
result_type operator() (ContextT const& ctx)
|
||||
{
|
||||
string_type str;
|
||||
stream_type strm(str);
|
||||
strm.rdbuf()->max_size(m_max_size);
|
||||
|
||||
// Invoke the adopted formatter
|
||||
typedef phoenix::vector3<
|
||||
subactor_type*,
|
||||
typename fusion::result_of::at_c<
|
||||
typename remove_cv<
|
||||
typename remove_reference<
|
||||
typename phoenix::result_of::env< ContextT const& >::type
|
||||
>::type
|
||||
>::type::args_type,
|
||||
0
|
||||
>::type,
|
||||
stream_type&
|
||||
> env_type;
|
||||
env_type env = { boost::addressof(m_subactor), fusion::at_c< 0 >(phoenix::env(ctx).args()), strm };
|
||||
phoenix::eval(m_subactor, phoenix::make_context(env, phoenix::actions(ctx)));
|
||||
|
||||
// Flush the buffered characters and see of overflow happened
|
||||
strm.flush();
|
||||
|
||||
if (strm.rdbuf()->storage_overflow() && !m_overflow_marker.empty())
|
||||
{
|
||||
strm.rdbuf()->max_size(strm.rdbuf()->max_size() - m_overflow_marker.size());
|
||||
strm.rdbuf()->max_size(str.max_size());
|
||||
strm.rdbuf()->storage_overflow(false);
|
||||
strm.rdbuf()->append(m_overflow_marker.data(), m_overflow_marker.size());
|
||||
strm.flush();
|
||||
}
|
||||
|
||||
return BOOST_LOG_NRVO_RESULT(str);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Invokation operator
|
||||
*/
|
||||
template< typename ContextT >
|
||||
result_type operator() (ContextT const& ctx) const
|
||||
{
|
||||
string_type str;
|
||||
stream_type strm(str);
|
||||
strm.rdbuf()->max_size(m_max_size);
|
||||
|
||||
// Invoke the adopted formatter
|
||||
typedef phoenix::vector3<
|
||||
const subactor_type*,
|
||||
typename fusion::result_of::at_c<
|
||||
typename remove_cv<
|
||||
typename remove_reference<
|
||||
typename phoenix::result_of::env< ContextT const& >::type
|
||||
>::type
|
||||
>::type::args_type,
|
||||
0
|
||||
>::type,
|
||||
stream_type&
|
||||
> env_type;
|
||||
env_type env = { boost::addressof(m_subactor), fusion::at_c< 0 >(phoenix::env(ctx).args()), strm };
|
||||
phoenix::eval(m_subactor, phoenix::make_context(env, phoenix::actions(ctx)));
|
||||
|
||||
// Flush the buffered characters and see of overflow happened
|
||||
strm.flush();
|
||||
|
||||
if (strm.rdbuf()->storage_overflow())
|
||||
{
|
||||
strm.rdbuf()->max_size(strm.rdbuf()->max_size() - m_overflow_marker.size());
|
||||
strm.rdbuf()->max_size(str.max_size());
|
||||
strm.rdbuf()->storage_overflow(false);
|
||||
strm.rdbuf()->append(m_overflow_marker.data(), m_overflow_marker.size());
|
||||
strm.flush();
|
||||
}
|
||||
|
||||
return BOOST_LOG_NRVO_RESULT(str);
|
||||
}
|
||||
|
||||
BOOST_DELETED_FUNCTION(max_size_decorator_terminal())
|
||||
};
|
||||
|
||||
/*!
|
||||
* Character decorator actor
|
||||
*/
|
||||
template< typename SubactorT, typename CharT, template< typename > class ActorT = phoenix::actor >
|
||||
class max_size_decorator_actor :
|
||||
public ActorT< max_size_decorator_terminal< SubactorT, CharT > >
|
||||
{
|
||||
public:
|
||||
//! Base terminal type
|
||||
typedef max_size_decorator_terminal< SubactorT, CharT > terminal_type;
|
||||
//! Character type
|
||||
typedef typename terminal_type::char_type char_type;
|
||||
|
||||
//! Base actor type
|
||||
typedef ActorT< terminal_type > base_type;
|
||||
|
||||
public:
|
||||
//! Initializing constructor
|
||||
explicit max_size_decorator_actor(base_type const& act) : base_type(act)
|
||||
{
|
||||
}
|
||||
|
||||
//! Returns reference to the terminal
|
||||
terminal_type const& get_terminal() const
|
||||
{
|
||||
return this->proto_expr_.child0;
|
||||
}
|
||||
};
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
#define BOOST_LOG_AUX_OVERLOAD(left_ref, right_ref)\
|
||||
template< typename LeftExprT, typename SubactorT, typename CharT, template< typename > class ActorT >\
|
||||
BOOST_FORCEINLINE phoenix::actor< aux::max_size_decorator_output_terminal< phoenix::actor< LeftExprT >, SubactorT, CharT > >\
|
||||
operator<< (phoenix::actor< LeftExprT > left_ref left, max_size_decorator_actor< SubactorT, CharT, ActorT > right_ref right)\
|
||||
{\
|
||||
typedef aux::max_size_decorator_output_terminal< phoenix::actor< LeftExprT >, SubactorT, CharT > terminal_type;\
|
||||
phoenix::actor< terminal_type > actor = {{ terminal_type(left, right.get_terminal().get_subactor(), right.get_terminal().get_max_size(), right.get_terminal().get_overflow_marker()) }};\
|
||||
return actor;\
|
||||
}
|
||||
|
||||
#include <boost/log/detail/generate_overloads.hpp>
|
||||
|
||||
#undef BOOST_LOG_AUX_OVERLOAD
|
||||
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
namespace aux {
|
||||
|
||||
template< typename CharT >
|
||||
class max_size_decorator_gen
|
||||
{
|
||||
private:
|
||||
typedef CharT char_type;
|
||||
typedef std::basic_string< char_type > string_type;
|
||||
typedef std::size_t size_type;
|
||||
|
||||
private:
|
||||
size_type m_max_size;
|
||||
string_type m_overflow_marker;
|
||||
|
||||
public:
|
||||
explicit max_size_decorator_gen(size_type max_size, string_type const& overflow_marker = string_type()) :
|
||||
m_max_size(max_size), m_overflow_marker(overflow_marker)
|
||||
{
|
||||
BOOST_ASSERT(overflow_marker.size() <= max_size);
|
||||
}
|
||||
|
||||
template< typename SubactorT >
|
||||
BOOST_FORCEINLINE max_size_decorator_actor< SubactorT, char_type > operator[] (SubactorT const& subactor) const
|
||||
{
|
||||
typedef max_size_decorator_actor< SubactorT, char_type > result_type;
|
||||
typedef typename result_type::terminal_type terminal_type;
|
||||
typename result_type::base_type act = {{ terminal_type(subactor, m_max_size, m_overflow_marker) }};
|
||||
return result_type(act);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
/*!
|
||||
* The function returns a decorator generator object. The generator provides <tt>operator[]</tt> that can be used
|
||||
* to construct the actual decorator.
|
||||
*
|
||||
* \param max_size The maximum number of characters (i.e. string element objects) that the decorated formatter can produce.
|
||||
*/
|
||||
template< typename CharT >
|
||||
BOOST_FORCEINLINE aux::max_size_decorator_gen< CharT > max_size_decor(std::size_t max_size)
|
||||
{
|
||||
return aux::max_size_decorator_gen< CharT >(max_size);
|
||||
}
|
||||
|
||||
/*!
|
||||
* The function returns a decorator generator object. The generator provides <tt>operator[]</tt> that can be used
|
||||
* to construct the actual decorator.
|
||||
*
|
||||
* \param max_size The maximum number of characters (i.e. string element objects) that the decorated formatter can produce.
|
||||
* \param overflow_marker The marker string which is appended to the output if the \a max_size limit is exceeded. Must be
|
||||
* a non-null pointer to a zero-terminated string.
|
||||
*
|
||||
* \pre The \a overflow_marker length must not exceed the \a max_size limit.
|
||||
*/
|
||||
template< typename CharT >
|
||||
BOOST_FORCEINLINE aux::max_size_decorator_gen< CharT > max_size_decor(std::size_t max_size, const CharT* overflow_marker)
|
||||
{
|
||||
return aux::max_size_decorator_gen< CharT >(max_size, overflow_marker);
|
||||
}
|
||||
|
||||
/*!
|
||||
* The function returns a decorator generator object. The generator provides <tt>operator[]</tt> that can be used
|
||||
* to construct the actual decorator.
|
||||
*
|
||||
* \param max_size The maximum number of characters (i.e. string element objects) that the decorated formatter can produce.
|
||||
* \param overflow_marker The marker string which is appended to the output if the \a max_size limit is exceeded.
|
||||
*
|
||||
* \pre The \a overflow_marker length must not exceed the \a max_size limit.
|
||||
*/
|
||||
template< typename CharT >
|
||||
BOOST_FORCEINLINE aux::max_size_decorator_gen< CharT > max_size_decor(std::size_t max_size, std::basic_string< CharT > const& overflow_marker)
|
||||
{
|
||||
return aux::max_size_decorator_gen< CharT >(max_size, overflow_marker);
|
||||
}
|
||||
|
||||
} // namespace expressions
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
namespace phoenix {
|
||||
|
||||
namespace result_of {
|
||||
|
||||
template< typename SubactorT, typename CharT >
|
||||
struct is_nullary< custom_terminal< boost::log::expressions::max_size_decorator_terminal< SubactorT, CharT > > > :
|
||||
public mpl::false_
|
||||
{
|
||||
};
|
||||
|
||||
template< typename LeftT, typename SubactorT, typename CharT >
|
||||
struct is_nullary< custom_terminal< boost::log::expressions::aux::max_size_decorator_output_terminal< LeftT, SubactorT, CharT > > > :
|
||||
public mpl::false_
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace result_of
|
||||
|
||||
} // namespace phoenix
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_EXPRESSIONS_FORMATTERS_MAX_SIZE_DECORATOR_HPP_INCLUDED_
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user