stabilize build system: depends, installer, boost/bdb fixes, cross targets groundwork

This commit is contained in:
2026-02-24 18:38:47 +00:00
parent da8c28aaeb
commit 65cb2619a7
13106 changed files with 2484322 additions and 1804 deletions
@@ -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