stabilize build system: depends, installer, boost/bdb fixes, cross targets groundwork
This commit is contained in:
@@ -0,0 +1,354 @@
|
||||
/*
|
||||
* Copyright Andrey Semashev 2007 - 2015.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
/*!
|
||||
* \file exception_handler.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 12.07.2009
|
||||
*
|
||||
* This header contains tools for exception handlers support in different parts of the library.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_UTILITY_EXCEPTION_HANDLER_HPP_INCLUDED_
|
||||
#define BOOST_LOG_UTILITY_EXCEPTION_HANDLER_HPP_INCLUDED_
|
||||
|
||||
#include <new> // std::nothrow_t
|
||||
#include <boost/mpl/bind.hpp>
|
||||
#include <boost/mpl/quote.hpp>
|
||||
#include <boost/mpl/fold.hpp>
|
||||
#include <boost/mpl/placeholders.hpp>
|
||||
#include <boost/mpl/has_xxx.hpp>
|
||||
#include <boost/mpl/vector.hpp>
|
||||
#include <boost/core/enable_if.hpp>
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/utility/functional/nop.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_LOG_MAX_EXCEPTION_TYPES
|
||||
//! Maximum number of exception types that can be specified for exception handlers
|
||||
#define BOOST_LOG_MAX_EXCEPTION_TYPES 10
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace aux {
|
||||
|
||||
BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_exception_types, exception_types, false)
|
||||
|
||||
//! Root class for the exception handler class hierarchy
|
||||
template< typename HandlerT >
|
||||
class eh_root
|
||||
{
|
||||
public:
|
||||
//! The exception handler type
|
||||
typedef HandlerT handler_type;
|
||||
//! The handler result type
|
||||
typedef void result_type;
|
||||
|
||||
protected:
|
||||
//! Exception handler
|
||||
handler_type m_Handler;
|
||||
|
||||
public:
|
||||
//! Initializing constructor
|
||||
explicit eh_root(handler_type const& handler) : m_Handler(handler)
|
||||
{
|
||||
}
|
||||
|
||||
//! Exception launcher
|
||||
void operator()() const
|
||||
{
|
||||
throw;
|
||||
}
|
||||
};
|
||||
|
||||
//! A cons-list element of the exception handler class hierarchy
|
||||
template< typename ExceptionT, typename BaseT >
|
||||
class eh_cons :
|
||||
public BaseT
|
||||
{
|
||||
//! Base type
|
||||
typedef BaseT base_type;
|
||||
|
||||
public:
|
||||
//! The exception handler type
|
||||
typedef typename base_type::handler_type handler_type;
|
||||
|
||||
public:
|
||||
//! Initializing constructor
|
||||
explicit eh_cons(handler_type const& handler) : base_type(handler)
|
||||
{
|
||||
}
|
||||
|
||||
//! Exception launcher
|
||||
void operator()() const
|
||||
{
|
||||
try
|
||||
{
|
||||
base_type::operator()();
|
||||
}
|
||||
catch (ExceptionT& e)
|
||||
{
|
||||
this->m_Handler(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template< template< typename, typename > class EHT, typename HandlerT >
|
||||
struct make_self_contained_exception_handler
|
||||
{
|
||||
typedef EHT< typename HandlerT::exception_types, HandlerT > type;
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
/*!
|
||||
* An exception handler functional object. The handler aggregates a user-defined
|
||||
* functional object that will be called when one of the specified exception types
|
||||
* is caught.
|
||||
*/
|
||||
template< typename SequenceT, typename HandlerT >
|
||||
class exception_handler :
|
||||
public mpl::fold<
|
||||
SequenceT,
|
||||
aux::eh_root< HandlerT >,
|
||||
mpl::bind< mpl::quote2< aux::eh_cons >, mpl::_2, mpl::_1 >
|
||||
>::type
|
||||
{
|
||||
//! Base type
|
||||
typedef typename mpl::fold<
|
||||
SequenceT,
|
||||
aux::eh_root< HandlerT >,
|
||||
mpl::bind< mpl::quote2< aux::eh_cons >, mpl::_2, mpl::_1 >
|
||||
>::type base_type;
|
||||
|
||||
public:
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
typedef typename base_type::handler_type handler_type;
|
||||
#else
|
||||
//! The exception handler type
|
||||
typedef HandlerT handler_type;
|
||||
//! The handler result type
|
||||
typedef void result_type;
|
||||
#endif
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Initializing constructor. Creates an exception handler with the specified
|
||||
* function object that will receive the exception.
|
||||
*/
|
||||
explicit exception_handler(handler_type const& handler) : base_type(handler)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* Exception launcher. Rethrows the current exception in order to detect its type
|
||||
* and pass it to the aggregated function object.
|
||||
*
|
||||
* \note Must be called from within a \c catch statement.
|
||||
*/
|
||||
void operator()() const
|
||||
{
|
||||
base_type::operator()();
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* A no-throw exception handler functional object. Acts similar to \c exception_handler,
|
||||
* but in case if the exception cannot be handled the exception is not propagated
|
||||
* from the handler. Instead the user-defined functional object is called with
|
||||
* no parameters.
|
||||
*/
|
||||
template< typename SequenceT, typename HandlerT >
|
||||
class nothrow_exception_handler :
|
||||
public exception_handler< SequenceT, HandlerT >
|
||||
{
|
||||
//! Base type
|
||||
typedef exception_handler< SequenceT, HandlerT > base_type;
|
||||
|
||||
public:
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
typedef typename base_type::handler_type handler_type;
|
||||
#else
|
||||
//! The exception handler type
|
||||
typedef HandlerT handler_type;
|
||||
//! The handler result type
|
||||
typedef void result_type;
|
||||
#endif
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Initializing constructor. Creates an exception handler with the specified
|
||||
* function object that will receive the exception.
|
||||
*/
|
||||
explicit nothrow_exception_handler(handler_type const& handler) : base_type(handler)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* Exception launcher. Rethrows the current exception in order to detect its type
|
||||
* and pass it to the aggregated function object. If the type of the exception
|
||||
* could not be detected, the user-defined handler is called with no arguments.
|
||||
*
|
||||
* \note Must be called from within a \c catch statement.
|
||||
*/
|
||||
void operator()() const
|
||||
{
|
||||
try
|
||||
{
|
||||
base_type::operator()();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
this->m_Handler();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* The function creates an empty exception handler that effectively suppresses any exception
|
||||
*/
|
||||
inline nop make_exception_suppressor()
|
||||
{
|
||||
return nop();
|
||||
}
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
template< typename HandlerT >
|
||||
inline typename boost::lazy_enable_if_c<
|
||||
aux::has_exception_types< HandlerT >::value,
|
||||
aux::make_self_contained_exception_handler< exception_handler, HandlerT >
|
||||
>::type make_exception_handler(HandlerT const& handler)
|
||||
{
|
||||
typedef typename aux::make_self_contained_exception_handler< exception_handler, HandlerT >::type eh_t;
|
||||
return eh_t(handler);
|
||||
}
|
||||
|
||||
template< typename HandlerT >
|
||||
inline typename boost::lazy_enable_if_c<
|
||||
aux::has_exception_types< HandlerT >::value,
|
||||
aux::make_self_contained_exception_handler< nothrow_exception_handler, HandlerT >
|
||||
>::type make_exception_handler(HandlerT const& handler, std::nothrow_t const&)
|
||||
{
|
||||
typedef typename aux::make_self_contained_exception_handler< nothrow_exception_handler, HandlerT >::type eh_t;
|
||||
return eh_t(handler);
|
||||
}
|
||||
|
||||
#define BOOST_LOG_MAKE_EXCEPTION_HANDLER_INTERNAL(z, n, data)\
|
||||
template< BOOST_PP_ENUM_PARAMS(n, typename T), typename HandlerT >\
|
||||
inline exception_handler<\
|
||||
BOOST_PP_CAT(mpl::vector, n)< BOOST_PP_ENUM_PARAMS(n, T) >,\
|
||||
HandlerT\
|
||||
> make_exception_handler(HandlerT const& handler)\
|
||||
{\
|
||||
typedef exception_handler<\
|
||||
BOOST_PP_CAT(mpl::vector, n)< BOOST_PP_ENUM_PARAMS(n, T) >,\
|
||||
HandlerT\
|
||||
> eh_t;\
|
||||
return eh_t(handler);\
|
||||
}\
|
||||
template< BOOST_PP_ENUM_PARAMS(n, typename T), typename HandlerT >\
|
||||
inline nothrow_exception_handler<\
|
||||
BOOST_PP_CAT(mpl::vector, n)< BOOST_PP_ENUM_PARAMS(n, T) >,\
|
||||
HandlerT\
|
||||
> make_exception_handler(HandlerT const& handler, std::nothrow_t const&)\
|
||||
{\
|
||||
typedef nothrow_exception_handler<\
|
||||
BOOST_PP_CAT(mpl::vector, n)< BOOST_PP_ENUM_PARAMS(n, T) >,\
|
||||
HandlerT\
|
||||
> eh_t;\
|
||||
return eh_t(handler);\
|
||||
}
|
||||
|
||||
BOOST_PP_REPEAT_FROM_TO(1, BOOST_LOG_MAX_EXCEPTION_TYPES, BOOST_LOG_MAKE_EXCEPTION_HANDLER_INTERNAL, ~)
|
||||
|
||||
#undef BOOST_LOG_MAKE_EXCEPTION_HANDLER_INTERNAL
|
||||
|
||||
#else // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
/*!
|
||||
* The function creates an exception handler functional object. The handler will call to the
|
||||
* user-specified functional object with an exception as its argument.
|
||||
*
|
||||
* \param handler User-defined functional object that will receive exceptions.
|
||||
* \return A nullary functional object that should be called from within a \c catch statement.
|
||||
*
|
||||
* \note This form requires the user-defined functional object to have an \c exception_types
|
||||
* nested type. This type should be an MPL sequence of all expected exception types.
|
||||
*/
|
||||
template< typename HandlerT >
|
||||
exception_handler< typename HandlerT::exception_types, HandlerT >
|
||||
make_exception_handler(HandlerT const& handler);
|
||||
|
||||
/*!
|
||||
* The function creates an exception handler functional object. The handler will call to the
|
||||
* user-specified functional object with an exception as its argument. If the exception type
|
||||
* cannot be identified, the handler will call the user-defined functor with no arguments,
|
||||
* instead of propagating exception to the caller.
|
||||
*
|
||||
* \overload
|
||||
*
|
||||
* \param handler User-defined functional object that will receive exceptions.
|
||||
* \return A nullary functional object that should be called from within a \c catch statement.
|
||||
*
|
||||
* \note This form requires the user-defined functional object to have an \c exception_types
|
||||
* nested type. This type should be an MPL sequence of all expected exception types.
|
||||
*/
|
||||
template< typename HandlerT >
|
||||
nothrow_exception_handler< typename HandlerT::exception_types, HandlerT >
|
||||
make_exception_handler(HandlerT const& handler, std::nothrow_t const&);
|
||||
|
||||
/*!
|
||||
* The function creates an exception handler functional object. The handler will call to the
|
||||
* user-specified functional object with an exception as its argument. All expected exception
|
||||
* types should be specified as first template parameters explicitly, in the order they would
|
||||
* be specified in a corresponding <tt>try/catch</tt> statement.
|
||||
*
|
||||
* \overload
|
||||
*
|
||||
* \param handler User-defined functional object that will receive exceptions.
|
||||
* \return A nullary functional object that should be called from within a \c catch statement.
|
||||
*/
|
||||
template< typename... ExceptionsT, typename HandlerT >
|
||||
exception_handler< MPL_sequence_of_ExceptionsT, HandlerT >
|
||||
make_exception_handler(HandlerT const& handler);
|
||||
|
||||
/*!
|
||||
* The function creates an exception handler functional object. The handler will call to the
|
||||
* user-specified functional object with an exception as its argument. If the exception type
|
||||
* cannot be identified, the handler will call the user-defined functor with no arguments,
|
||||
* instead of propagating exception to the caller. All expected exception types should be
|
||||
* specified as first template parameters explicitly, in the order they would be specified in
|
||||
* a corresponding <tt>try/catch</tt> statement.
|
||||
*
|
||||
* \overload
|
||||
*
|
||||
* \param handler User-defined functional object that will receive exceptions.
|
||||
* \return A nullary functional object that should be called from within a \c catch statement.
|
||||
*/
|
||||
template< typename... ExceptionsT, typename HandlerT >
|
||||
nothrow_exception_handler< MPL_sequence_of_ExceptionsT, HandlerT >
|
||||
make_exception_handler(HandlerT const& handler, std::nothrow_t const&);
|
||||
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_UTILITY_EXCEPTION_HANDLER_HPP_INCLUDED_
|
||||
@@ -0,0 +1,916 @@
|
||||
/*
|
||||
* 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 formatting_ostream.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 11.07.2012
|
||||
*
|
||||
* The header contains implementation of a string stream used for log record formatting.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_UTILITY_FORMATTING_OSTREAM_HPP_INCLUDED_
|
||||
#define BOOST_LOG_UTILITY_FORMATTING_OSTREAM_HPP_INCLUDED_
|
||||
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <locale>
|
||||
#include <boost/core/enable_if.hpp>
|
||||
#include <boost/core/explicit_operator_bool.hpp>
|
||||
#include <boost/utility/string_ref_fwd.hpp>
|
||||
#include <boost/utility/string_view_fwd.hpp>
|
||||
#include <boost/type_traits/is_enum.hpp>
|
||||
#include <boost/type_traits/is_scalar.hpp>
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/attachable_sstream_buf.hpp>
|
||||
#include <boost/log/detail/code_conversion.hpp>
|
||||
#include <boost/log/utility/string_literal_fwd.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, typename R >
|
||||
struct enable_if_streamable_char_type {};
|
||||
template< typename R >
|
||||
struct enable_if_streamable_char_type< char, R > { typedef R type; };
|
||||
template< typename R >
|
||||
struct enable_if_streamable_char_type< wchar_t, R > { typedef R type; };
|
||||
#if !defined(BOOST_LOG_NO_CXX11_CODECVT_FACETS)
|
||||
#if !defined(BOOST_NO_CXX11_CHAR16_T)
|
||||
template< typename R >
|
||||
struct enable_if_streamable_char_type< char16_t, R > { typedef R type; };
|
||||
#endif
|
||||
#if !defined(BOOST_NO_CXX11_CHAR32_T)
|
||||
template< typename R >
|
||||
struct enable_if_streamable_char_type< char32_t, R > { typedef R type; };
|
||||
#endif
|
||||
#endif
|
||||
|
||||
template< typename StreamT, typename T, bool ByValueV, typename R >
|
||||
struct enable_formatting_ostream_generic_operator {};
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT, typename T, typename R >
|
||||
struct enable_formatting_ostream_generic_operator< basic_formatting_ostream< CharT, TraitsT, AllocatorT >, T, false, R > :
|
||||
public boost::disable_if_c< boost::is_scalar< typename boost::remove_cv< T >::type >::value, R >
|
||||
{
|
||||
};
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT, typename T, typename R >
|
||||
struct enable_formatting_ostream_generic_operator< basic_formatting_ostream< CharT, TraitsT, AllocatorT >, T, true, R > :
|
||||
public boost::enable_if_c< boost::is_enum< typename boost::remove_cv< T >::type >::value, R >
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
/*!
|
||||
* \brief Stream wrapper for log records formatting.
|
||||
*
|
||||
* This stream wrapper is used by the library for log record formatting. It implements the standard string stream interface
|
||||
* with a few differences:
|
||||
*
|
||||
* \li It does not derive from standard types <tt>std::basic_ostream</tt>, <tt>std::basic_ios</tt> and <tt>std::ios_base</tt>,
|
||||
* although it tries to implement their interfaces closely. There are a few small differences, mostly regarding <tt>rdbuf</tt>
|
||||
* and <tt>str</tt> signatures, as well as the supported insertion operator overloads. The actual wrapped stream can be accessed
|
||||
* through the <tt>stream</tt> methods.
|
||||
* \li By default, \c bool values are formatted using alphabetical representation rather than numeric.
|
||||
* \li The stream supports writing strings of character types different from the stream character type. The stream will perform
|
||||
* character code conversion as needed using the imbued locale.
|
||||
* \li The stream operates on an external string object rather than on the embedded one. The string can be attached or detached
|
||||
* from the stream dynamically.
|
||||
*
|
||||
* Although <tt>basic_formatting_ostream</tt> does not derive from <tt>std::basic_ostream</tt>, users are not required to add
|
||||
* special overloads of \c operator<< for it since the stream will by default reuse the operators for <tt>std::basic_ostream</tt>.
|
||||
* However, one can define special overloads of \c operator<< for <tt>basic_formatting_ostream</tt> if a certain type needs
|
||||
* special formatting when output to log.
|
||||
*/
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT >
|
||||
class basic_formatting_ostream
|
||||
{
|
||||
public:
|
||||
//! Character type
|
||||
typedef CharT char_type;
|
||||
//! Character traits
|
||||
typedef TraitsT traits_type;
|
||||
//! Memory allocator
|
||||
typedef AllocatorT allocator_type;
|
||||
//! Stream buffer type
|
||||
typedef boost::log::aux::basic_ostringstreambuf< char_type, traits_type, allocator_type > streambuf_type;
|
||||
//! Target string type
|
||||
typedef typename streambuf_type::string_type string_type;
|
||||
|
||||
//! Stream type
|
||||
typedef std::basic_ostream< char_type, traits_type > ostream_type;
|
||||
//! Stream position type
|
||||
typedef typename ostream_type::pos_type pos_type;
|
||||
//! Stream offset type
|
||||
typedef typename ostream_type::off_type off_type;
|
||||
//! Integer type for characters
|
||||
typedef typename ostream_type::int_type int_type;
|
||||
|
||||
typedef typename ostream_type::failure failure;
|
||||
typedef typename ostream_type::fmtflags fmtflags;
|
||||
typedef typename ostream_type::iostate iostate;
|
||||
typedef typename ostream_type::openmode openmode;
|
||||
typedef typename ostream_type::seekdir seekdir;
|
||||
typedef typename ostream_type::Init Init;
|
||||
|
||||
typedef typename ostream_type::event event;
|
||||
typedef typename ostream_type::event_callback event_callback;
|
||||
|
||||
class sentry :
|
||||
public ostream_type::sentry
|
||||
{
|
||||
typedef typename ostream_type::sentry base_type;
|
||||
|
||||
public:
|
||||
explicit sentry(basic_formatting_ostream& strm) : base_type(strm.stream())
|
||||
{
|
||||
}
|
||||
|
||||
// A workaround for Solaris Studio 12.4 compiler, see: https://svn.boost.org/trac/boost/ticket/11545
|
||||
BOOST_EXPLICIT_OPERATOR_BOOL()
|
||||
bool operator! () const { return !static_cast< base_type const& >(*this); }
|
||||
|
||||
BOOST_DELETED_FUNCTION(sentry(sentry const&))
|
||||
BOOST_DELETED_FUNCTION(sentry& operator= (sentry const&))
|
||||
};
|
||||
|
||||
protected:
|
||||
// Function types
|
||||
typedef std::ios_base& (*ios_base_manip)(std::ios_base&);
|
||||
typedef std::basic_ios< char_type, traits_type >& (*basic_ios_manip)(std::basic_ios< char_type, traits_type >&);
|
||||
typedef ostream_type& (*stream_manip)(ostream_type&);
|
||||
|
||||
public:
|
||||
static BOOST_CONSTEXPR_OR_CONST fmtflags boolalpha = ostream_type::boolalpha;
|
||||
static BOOST_CONSTEXPR_OR_CONST fmtflags dec = ostream_type::dec;
|
||||
static BOOST_CONSTEXPR_OR_CONST fmtflags fixed = ostream_type::fixed;
|
||||
static BOOST_CONSTEXPR_OR_CONST fmtflags hex = ostream_type::hex;
|
||||
static BOOST_CONSTEXPR_OR_CONST fmtflags internal = ostream_type::internal;
|
||||
static BOOST_CONSTEXPR_OR_CONST fmtflags left = ostream_type::left;
|
||||
static BOOST_CONSTEXPR_OR_CONST fmtflags oct = ostream_type::oct;
|
||||
static BOOST_CONSTEXPR_OR_CONST fmtflags right = ostream_type::right;
|
||||
static BOOST_CONSTEXPR_OR_CONST fmtflags scientific = ostream_type::scientific;
|
||||
static BOOST_CONSTEXPR_OR_CONST fmtflags showbase = ostream_type::showbase;
|
||||
static BOOST_CONSTEXPR_OR_CONST fmtflags showpoint = ostream_type::showpoint;
|
||||
static BOOST_CONSTEXPR_OR_CONST fmtflags skipws = ostream_type::skipws;
|
||||
static BOOST_CONSTEXPR_OR_CONST fmtflags unitbuf = ostream_type::unitbuf;
|
||||
static BOOST_CONSTEXPR_OR_CONST fmtflags uppercase = ostream_type::uppercase;
|
||||
static BOOST_CONSTEXPR_OR_CONST fmtflags adjustfield = ostream_type::adjustfield;
|
||||
static BOOST_CONSTEXPR_OR_CONST fmtflags basefield = ostream_type::basefield;
|
||||
static BOOST_CONSTEXPR_OR_CONST fmtflags floatfield = ostream_type::floatfield;
|
||||
|
||||
static BOOST_CONSTEXPR_OR_CONST iostate badbit = ostream_type::badbit;
|
||||
static BOOST_CONSTEXPR_OR_CONST iostate eofbit = ostream_type::eofbit;
|
||||
static BOOST_CONSTEXPR_OR_CONST iostate failbit = ostream_type::failbit;
|
||||
static BOOST_CONSTEXPR_OR_CONST iostate goodbit = ostream_type::goodbit;
|
||||
|
||||
static BOOST_CONSTEXPR_OR_CONST openmode app = ostream_type::app;
|
||||
static BOOST_CONSTEXPR_OR_CONST openmode ate = ostream_type::ate;
|
||||
static BOOST_CONSTEXPR_OR_CONST openmode binary = ostream_type::binary;
|
||||
static BOOST_CONSTEXPR_OR_CONST openmode in = ostream_type::in;
|
||||
static BOOST_CONSTEXPR_OR_CONST openmode out = ostream_type::out;
|
||||
static BOOST_CONSTEXPR_OR_CONST openmode trunc = ostream_type::trunc;
|
||||
|
||||
static BOOST_CONSTEXPR_OR_CONST seekdir beg = ostream_type::beg;
|
||||
static BOOST_CONSTEXPR_OR_CONST seekdir cur = ostream_type::cur;
|
||||
static BOOST_CONSTEXPR_OR_CONST seekdir end = ostream_type::end;
|
||||
|
||||
static BOOST_CONSTEXPR_OR_CONST event erase_event = ostream_type::erase_event;
|
||||
static BOOST_CONSTEXPR_OR_CONST event imbue_event = ostream_type::imbue_event;
|
||||
static BOOST_CONSTEXPR_OR_CONST event copyfmt_event = ostream_type::copyfmt_event;
|
||||
|
||||
private:
|
||||
mutable streambuf_type m_streambuf;
|
||||
ostream_type m_stream;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Default constructor. Creates an empty record that is equivalent to the invalid record handle.
|
||||
* The stream capability is not available after construction.
|
||||
*
|
||||
* \post <tt>!*this == true</tt>
|
||||
*/
|
||||
basic_formatting_ostream() : m_stream(&m_streambuf)
|
||||
{
|
||||
init_stream();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Initializing constructor. Attaches the string to the constructed stream.
|
||||
* The string will be used to store the formatted characters.
|
||||
*
|
||||
* \post <tt>!*this == false</tt>
|
||||
* \param str The string buffer to attach.
|
||||
*/
|
||||
explicit basic_formatting_ostream(string_type& str) :
|
||||
m_streambuf(str),
|
||||
m_stream(&m_streambuf)
|
||||
{
|
||||
init_stream();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Destructor. Destroys the record, releases any sinks and attribute values that were involved in processing this record.
|
||||
*/
|
||||
~basic_formatting_ostream()
|
||||
{
|
||||
if (m_streambuf.storage())
|
||||
flush();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Attaches the stream to the string. The string will be used to store the formatted characters.
|
||||
*
|
||||
* \param str The string buffer to attach.
|
||||
*/
|
||||
void attach(string_type& str)
|
||||
{
|
||||
m_streambuf.attach(str);
|
||||
m_stream.clear(ostream_type::goodbit);
|
||||
}
|
||||
/*!
|
||||
* Detaches the stream from the string. Any buffered data is flushed to the string.
|
||||
*/
|
||||
void detach()
|
||||
{
|
||||
m_streambuf.detach();
|
||||
m_stream.clear(ostream_type::badbit);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \returns Reference to the attached string. The string must be attached before calling this method.
|
||||
*/
|
||||
string_type const& str() const
|
||||
{
|
||||
string_type* const storage = m_streambuf.storage();
|
||||
BOOST_ASSERT(storage != NULL);
|
||||
|
||||
m_streambuf.pubsync();
|
||||
|
||||
return *storage;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \returns Reference to the wrapped stream
|
||||
*/
|
||||
ostream_type& stream() { return m_stream; }
|
||||
|
||||
/*!
|
||||
* \returns Reference to the wrapped stream
|
||||
*/
|
||||
ostream_type const& stream() const { return m_stream; }
|
||||
|
||||
// std::ios_base method forwarders
|
||||
fmtflags flags() const { return m_stream.flags(); }
|
||||
fmtflags flags(fmtflags f) { return m_stream.flags(f); }
|
||||
fmtflags setf(fmtflags f) { return m_stream.setf(f); }
|
||||
fmtflags setf(fmtflags f, fmtflags mask) { return m_stream.setf(f, mask); }
|
||||
void unsetf(fmtflags f) { m_stream.unsetf(f); }
|
||||
|
||||
std::streamsize precision() const { return m_stream.precision(); }
|
||||
std::streamsize precision(std::streamsize p) { return m_stream.precision(p); }
|
||||
|
||||
std::streamsize width() const { return m_stream.width(); }
|
||||
std::streamsize width(std::streamsize w) { return m_stream.width(w); }
|
||||
|
||||
std::locale getloc() const { return m_stream.getloc(); }
|
||||
std::locale imbue(std::locale const& loc) { return m_stream.imbue(loc); }
|
||||
|
||||
static int xalloc() { return ostream_type::xalloc(); }
|
||||
long& iword(int index) { return m_stream.iword(index); }
|
||||
void*& pword(int index) { return m_stream.pword(index); }
|
||||
|
||||
void register_callback(event_callback fn, int index) { m_stream.register_callback(fn, index); }
|
||||
|
||||
static bool sync_with_stdio(bool sync = true) { return ostream_type::sync_with_stdio(sync); }
|
||||
|
||||
// std::basic_ios method forwarders
|
||||
BOOST_EXPLICIT_OPERATOR_BOOL()
|
||||
bool operator! () const { return !m_stream; }
|
||||
|
||||
iostate rdstate() const { return m_stream.rdstate(); }
|
||||
void clear(iostate state = goodbit) { m_stream.clear(state); }
|
||||
void setstate(iostate state) { m_stream.setstate(state); }
|
||||
bool good() const { return m_stream.good(); }
|
||||
bool eof() const { return m_stream.eof(); }
|
||||
bool fail() const { return m_stream.fail(); }
|
||||
bool bad() const { return m_stream.bad(); }
|
||||
|
||||
iostate exceptions() const { return m_stream.exceptions(); }
|
||||
void exceptions(iostate s) { m_stream.exceptions(s); }
|
||||
|
||||
ostream_type* tie() const { return m_stream.tie(); }
|
||||
ostream_type* tie(ostream_type* strm) { return m_stream.tie(strm); }
|
||||
|
||||
streambuf_type* rdbuf() const { return &m_streambuf; }
|
||||
|
||||
basic_formatting_ostream& copyfmt(std::basic_ios< char_type, traits_type >& rhs)
|
||||
{
|
||||
m_stream.copyfmt(rhs);
|
||||
return *this;
|
||||
}
|
||||
basic_formatting_ostream& copyfmt(basic_formatting_ostream& rhs)
|
||||
{
|
||||
m_stream.copyfmt(rhs.stream());
|
||||
return *this;
|
||||
}
|
||||
|
||||
char_type fill() const { return m_stream.fill(); }
|
||||
char_type fill(char_type ch) { return m_stream.fill(ch); }
|
||||
|
||||
char narrow(char_type ch, char def) const { return m_stream.narrow(ch, def); }
|
||||
char_type widen(char ch) const { return m_stream.widen(ch); }
|
||||
|
||||
// std::basic_ostream method forwarders
|
||||
basic_formatting_ostream& flush()
|
||||
{
|
||||
m_stream.flush();
|
||||
return *this;
|
||||
}
|
||||
|
||||
pos_type tellp() { return m_stream.tellp(); }
|
||||
basic_formatting_ostream& seekp(pos_type pos)
|
||||
{
|
||||
m_stream.seekp(pos);
|
||||
return *this;
|
||||
}
|
||||
basic_formatting_ostream& seekp(off_type off, std::ios_base::seekdir dir)
|
||||
{
|
||||
m_stream.seekp(off, dir);
|
||||
return *this;
|
||||
}
|
||||
|
||||
basic_formatting_ostream& put(char_type c)
|
||||
{
|
||||
m_stream.put(c);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template< typename OtherCharT >
|
||||
typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
|
||||
put(OtherCharT c)
|
||||
{
|
||||
write(&c, 1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
basic_formatting_ostream& write(const char_type* p, std::streamsize size)
|
||||
{
|
||||
m_stream.write(p, size);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template< typename OtherCharT >
|
||||
typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
|
||||
write(const OtherCharT* p, std::streamsize size)
|
||||
{
|
||||
sentry guard(*this);
|
||||
if (!!guard)
|
||||
{
|
||||
m_stream.flush();
|
||||
|
||||
if (!m_streambuf.storage_overflow())
|
||||
{
|
||||
string_type* storage = m_streambuf.storage();
|
||||
if (!aux::code_convert(p, static_cast< std::size_t >(size), *storage, m_streambuf.max_size(), m_stream.getloc()))
|
||||
m_streambuf.storage_overflow(true);
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
basic_formatting_ostream& operator<< (ios_base_manip manip)
|
||||
{
|
||||
m_stream << manip;
|
||||
return *this;
|
||||
}
|
||||
basic_formatting_ostream& operator<< (basic_ios_manip manip)
|
||||
{
|
||||
m_stream << manip;
|
||||
return *this;
|
||||
}
|
||||
basic_formatting_ostream& operator<< (stream_manip manip)
|
||||
{
|
||||
m_stream << manip;
|
||||
return *this;
|
||||
}
|
||||
|
||||
basic_formatting_ostream& operator<< (char c)
|
||||
{
|
||||
return this->formatted_write(&c, 1);
|
||||
}
|
||||
basic_formatting_ostream& operator<< (const char* p)
|
||||
{
|
||||
return this->formatted_write(p, static_cast< std::streamsize >(std::char_traits< char >::length(p)));
|
||||
}
|
||||
|
||||
// When no native character type is supported, the following overloads are disabled as they have ambiguous meaning.
|
||||
// Use basic_string_view or basic_string to explicitly indicate that the data is a string.
|
||||
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
|
||||
basic_formatting_ostream& operator<< (wchar_t c)
|
||||
{
|
||||
return this->formatted_write(&c, 1);
|
||||
}
|
||||
basic_formatting_ostream& operator<< (const wchar_t* p)
|
||||
{
|
||||
return this->formatted_write(p, static_cast< std::streamsize >(std::char_traits< wchar_t >::length(p)));
|
||||
}
|
||||
#endif
|
||||
#if !defined(BOOST_LOG_NO_CXX11_CODECVT_FACETS)
|
||||
#if !defined(BOOST_NO_CXX11_CHAR16_T)
|
||||
basic_formatting_ostream& operator<< (char16_t c)
|
||||
{
|
||||
return this->formatted_write(&c, 1);
|
||||
}
|
||||
basic_formatting_ostream& operator<< (const char16_t* p)
|
||||
{
|
||||
return this->formatted_write(p, static_cast< std::streamsize >(std::char_traits< char16_t >::length(p)));
|
||||
}
|
||||
#endif
|
||||
#if !defined(BOOST_NO_CXX11_CHAR32_T)
|
||||
basic_formatting_ostream& operator<< (char32_t c)
|
||||
{
|
||||
return this->formatted_write(&c, 1);
|
||||
}
|
||||
basic_formatting_ostream& operator<< (const char32_t* p)
|
||||
{
|
||||
return this->formatted_write(p, static_cast< std::streamsize >(std::char_traits< char32_t >::length(p)));
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
basic_formatting_ostream& operator<< (bool value)
|
||||
{
|
||||
m_stream << value;
|
||||
return *this;
|
||||
}
|
||||
basic_formatting_ostream& operator<< (signed char value)
|
||||
{
|
||||
m_stream << value;
|
||||
return *this;
|
||||
}
|
||||
basic_formatting_ostream& operator<< (unsigned char value)
|
||||
{
|
||||
m_stream << value;
|
||||
return *this;
|
||||
}
|
||||
basic_formatting_ostream& operator<< (short value)
|
||||
{
|
||||
m_stream << value;
|
||||
return *this;
|
||||
}
|
||||
basic_formatting_ostream& operator<< (unsigned short value)
|
||||
{
|
||||
m_stream << value;
|
||||
return *this;
|
||||
}
|
||||
basic_formatting_ostream& operator<< (int value)
|
||||
{
|
||||
m_stream << value;
|
||||
return *this;
|
||||
}
|
||||
basic_formatting_ostream& operator<< (unsigned int value)
|
||||
{
|
||||
m_stream << value;
|
||||
return *this;
|
||||
}
|
||||
basic_formatting_ostream& operator<< (long value)
|
||||
{
|
||||
m_stream << value;
|
||||
return *this;
|
||||
}
|
||||
basic_formatting_ostream& operator<< (unsigned long value)
|
||||
{
|
||||
m_stream << value;
|
||||
return *this;
|
||||
}
|
||||
#if !defined(BOOST_NO_LONG_LONG)
|
||||
basic_formatting_ostream& operator<< (long long value)
|
||||
{
|
||||
m_stream << value;
|
||||
return *this;
|
||||
}
|
||||
basic_formatting_ostream& operator<< (unsigned long long value)
|
||||
{
|
||||
m_stream << value;
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
basic_formatting_ostream& operator<< (float value)
|
||||
{
|
||||
m_stream << value;
|
||||
return *this;
|
||||
}
|
||||
basic_formatting_ostream& operator<< (double value)
|
||||
{
|
||||
m_stream << value;
|
||||
return *this;
|
||||
}
|
||||
basic_formatting_ostream& operator<< (long double value)
|
||||
{
|
||||
m_stream << value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
basic_formatting_ostream& operator<< (const void* value)
|
||||
{
|
||||
m_stream << value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
basic_formatting_ostream& operator<< (std::basic_streambuf< char_type, traits_type >* buf)
|
||||
{
|
||||
m_stream << buf;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template< typename OtherCharT, typename OtherTraitsT, typename OtherAllocatorT >
|
||||
friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
|
||||
operator<< (basic_formatting_ostream& strm, std::basic_string< OtherCharT, OtherTraitsT, OtherAllocatorT > const& str)
|
||||
{
|
||||
return strm.formatted_write(str.c_str(), static_cast< std::streamsize >(str.size()));
|
||||
}
|
||||
|
||||
template< typename OtherCharT, typename OtherTraitsT >
|
||||
friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
|
||||
operator<< (basic_formatting_ostream& strm, basic_string_literal< OtherCharT, OtherTraitsT > const& str)
|
||||
{
|
||||
return strm.formatted_write(str.c_str(), static_cast< std::streamsize >(str.size()));
|
||||
}
|
||||
|
||||
template< typename OtherCharT, typename OtherTraitsT >
|
||||
friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
|
||||
operator<< (basic_formatting_ostream& strm, basic_string_view< OtherCharT, OtherTraitsT > const& str)
|
||||
{
|
||||
return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
|
||||
}
|
||||
|
||||
// Deprecated overload
|
||||
template< typename OtherCharT, typename OtherTraitsT >
|
||||
friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
|
||||
operator<< (basic_formatting_ostream& strm, basic_string_ref< OtherCharT, OtherTraitsT > const& str)
|
||||
{
|
||||
return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
|
||||
}
|
||||
|
||||
template< typename OtherCharT, typename OtherTraitsT, typename OtherAllocatorT >
|
||||
friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
|
||||
operator<< (basic_formatting_ostream& strm, std::basic_string< OtherCharT, OtherTraitsT, OtherAllocatorT >& str)
|
||||
{
|
||||
return strm.formatted_write(str.c_str(), static_cast< std::streamsize >(str.size()));
|
||||
}
|
||||
|
||||
template< typename OtherCharT, typename OtherTraitsT >
|
||||
friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
|
||||
operator<< (basic_formatting_ostream& strm, basic_string_literal< OtherCharT, OtherTraitsT >& str)
|
||||
{
|
||||
return strm.formatted_write(str.c_str(), static_cast< std::streamsize >(str.size()));
|
||||
}
|
||||
|
||||
template< typename OtherCharT, typename OtherTraitsT >
|
||||
friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
|
||||
operator<< (basic_formatting_ostream& strm, basic_string_view< OtherCharT, OtherTraitsT >& str)
|
||||
{
|
||||
return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
|
||||
}
|
||||
|
||||
// Deprecated overload
|
||||
template< typename OtherCharT, typename OtherTraitsT >
|
||||
friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
|
||||
operator<< (basic_formatting_ostream& strm, basic_string_ref< OtherCharT, OtherTraitsT >& str)
|
||||
{
|
||||
return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
template< typename OtherCharT, typename OtherTraitsT, typename OtherAllocatorT >
|
||||
friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
|
||||
operator<< (basic_formatting_ostream&& strm, std::basic_string< OtherCharT, OtherTraitsT, OtherAllocatorT > const& str)
|
||||
{
|
||||
return strm.formatted_write(str.c_str(), static_cast< std::streamsize >(str.size()));
|
||||
}
|
||||
|
||||
template< typename OtherCharT, typename OtherTraitsT >
|
||||
friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
|
||||
operator<< (basic_formatting_ostream&& strm, basic_string_literal< OtherCharT, OtherTraitsT > const& str)
|
||||
{
|
||||
return strm.formatted_write(str.c_str(), static_cast< std::streamsize >(str.size()));
|
||||
}
|
||||
|
||||
template< typename OtherCharT, typename OtherTraitsT >
|
||||
friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
|
||||
operator<< (basic_formatting_ostream&& strm, basic_string_view< OtherCharT, OtherTraitsT > const& str)
|
||||
{
|
||||
return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
|
||||
}
|
||||
|
||||
// Deprecated overload
|
||||
template< typename OtherCharT, typename OtherTraitsT >
|
||||
friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
|
||||
operator<< (basic_formatting_ostream&& strm, basic_string_ref< OtherCharT, OtherTraitsT > const& str)
|
||||
{
|
||||
return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
|
||||
}
|
||||
|
||||
template< typename OtherCharT, typename OtherTraitsT, typename OtherAllocatorT >
|
||||
friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
|
||||
operator<< (basic_formatting_ostream&& strm, std::basic_string< OtherCharT, OtherTraitsT, OtherAllocatorT >& str)
|
||||
{
|
||||
return strm.formatted_write(str.c_str(), static_cast< std::streamsize >(str.size()));
|
||||
}
|
||||
|
||||
template< typename OtherCharT, typename OtherTraitsT >
|
||||
friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
|
||||
operator<< (basic_formatting_ostream&& strm, basic_string_literal< OtherCharT, OtherTraitsT >& str)
|
||||
{
|
||||
return strm.formatted_write(str.c_str(), static_cast< std::streamsize >(str.size()));
|
||||
}
|
||||
|
||||
template< typename OtherCharT, typename OtherTraitsT >
|
||||
friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
|
||||
operator<< (basic_formatting_ostream&& strm, basic_string_view< OtherCharT, OtherTraitsT >& str)
|
||||
{
|
||||
return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
|
||||
}
|
||||
|
||||
// Deprecated overload
|
||||
template< typename OtherCharT, typename OtherTraitsT >
|
||||
friend typename aux::enable_if_streamable_char_type< OtherCharT, basic_formatting_ostream& >::type
|
||||
operator<< (basic_formatting_ostream&& strm, basic_string_ref< OtherCharT, OtherTraitsT >& str)
|
||||
{
|
||||
return strm.formatted_write(str.data(), static_cast< std::streamsize >(str.size()));
|
||||
}
|
||||
#endif
|
||||
|
||||
protected:
|
||||
void init_stream()
|
||||
{
|
||||
m_stream.exceptions(ostream_type::goodbit);
|
||||
m_stream.clear(m_streambuf.storage() ? ostream_type::goodbit : ostream_type::badbit);
|
||||
m_stream.flags
|
||||
(
|
||||
ostream_type::dec |
|
||||
ostream_type::skipws |
|
||||
ostream_type::boolalpha // this differs from the default stream flags but makes logs look better
|
||||
);
|
||||
m_stream.width(0);
|
||||
m_stream.precision(6);
|
||||
m_stream.fill(static_cast< char_type >(' '));
|
||||
}
|
||||
|
||||
private:
|
||||
basic_formatting_ostream& formatted_write(const char_type* p, std::streamsize size)
|
||||
{
|
||||
sentry guard(*this);
|
||||
if (!!guard)
|
||||
{
|
||||
m_stream.flush();
|
||||
|
||||
if (m_stream.width() <= size)
|
||||
m_streambuf.append(p, static_cast< std::size_t >(size));
|
||||
else
|
||||
this->aligned_write(p, size);
|
||||
|
||||
m_stream.width(0);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template< typename OtherCharT >
|
||||
basic_formatting_ostream& formatted_write(const OtherCharT* p, std::streamsize size)
|
||||
{
|
||||
sentry guard(*this);
|
||||
if (!!guard)
|
||||
{
|
||||
m_stream.flush();
|
||||
|
||||
if (m_stream.width() <= size)
|
||||
{
|
||||
if (!m_streambuf.storage_overflow())
|
||||
{
|
||||
if (!aux::code_convert(p, static_cast< std::size_t >(size), *m_streambuf.storage(), m_streambuf.max_size(), m_stream.getloc()))
|
||||
m_streambuf.storage_overflow(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
this->aligned_write(p, size);
|
||||
|
||||
m_stream.width(0);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void aligned_write(const char_type* p, std::streamsize size);
|
||||
|
||||
template< typename OtherCharT >
|
||||
void aligned_write(const OtherCharT* p, std::streamsize size);
|
||||
|
||||
//! Copy constructor (closed)
|
||||
BOOST_DELETED_FUNCTION(basic_formatting_ostream(basic_formatting_ostream const& that))
|
||||
//! Assignment (closed)
|
||||
BOOST_DELETED_FUNCTION(basic_formatting_ostream& operator= (basic_formatting_ostream const& that))
|
||||
};
|
||||
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::boolalpha;
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::dec;
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fixed;
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::hex;
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::internal;
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::left;
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::oct;
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::right;
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::scientific;
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::showbase;
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::showpoint;
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::skipws;
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::unitbuf;
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::uppercase;
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::adjustfield;
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::basefield;
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::fmtflags basic_formatting_ostream< CharT, TraitsT, AllocatorT >::floatfield;
|
||||
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::iostate basic_formatting_ostream< CharT, TraitsT, AllocatorT >::badbit;
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::iostate basic_formatting_ostream< CharT, TraitsT, AllocatorT >::eofbit;
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::iostate basic_formatting_ostream< CharT, TraitsT, AllocatorT >::failbit;
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::iostate basic_formatting_ostream< CharT, TraitsT, AllocatorT >::goodbit;
|
||||
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::openmode basic_formatting_ostream< CharT, TraitsT, AllocatorT >::app;
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::openmode basic_formatting_ostream< CharT, TraitsT, AllocatorT >::ate;
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::openmode basic_formatting_ostream< CharT, TraitsT, AllocatorT >::binary;
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::openmode basic_formatting_ostream< CharT, TraitsT, AllocatorT >::in;
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::openmode basic_formatting_ostream< CharT, TraitsT, AllocatorT >::out;
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::openmode basic_formatting_ostream< CharT, TraitsT, AllocatorT >::trunc;
|
||||
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::seekdir basic_formatting_ostream< CharT, TraitsT, AllocatorT >::beg;
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::seekdir basic_formatting_ostream< CharT, TraitsT, AllocatorT >::cur;
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::seekdir basic_formatting_ostream< CharT, TraitsT, AllocatorT >::end;
|
||||
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::event basic_formatting_ostream< CharT, TraitsT, AllocatorT >::erase_event;
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::event basic_formatting_ostream< CharT, TraitsT, AllocatorT >::imbue_event;
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT >
|
||||
BOOST_CONSTEXPR_OR_CONST typename basic_formatting_ostream< CharT, TraitsT, AllocatorT >::event basic_formatting_ostream< CharT, TraitsT, AllocatorT >::copyfmt_event;
|
||||
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT >
|
||||
void basic_formatting_ostream< CharT, TraitsT, AllocatorT >::aligned_write(const char_type* p, std::streamsize size)
|
||||
{
|
||||
typename string_type::size_type const alignment_size =
|
||||
static_cast< typename string_type::size_type >(m_stream.width() - size);
|
||||
const bool align_left = (m_stream.flags() & ostream_type::adjustfield) == ostream_type::left;
|
||||
if (align_left)
|
||||
{
|
||||
m_streambuf.append(p, static_cast< std::size_t >(size));
|
||||
m_streambuf.append(alignment_size, m_stream.fill());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_streambuf.append(alignment_size, m_stream.fill());
|
||||
m_streambuf.append(p, static_cast< std::size_t >(size));
|
||||
}
|
||||
}
|
||||
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT >
|
||||
template< typename OtherCharT >
|
||||
void basic_formatting_ostream< CharT, TraitsT, AllocatorT >::aligned_write(const OtherCharT* p, std::streamsize size)
|
||||
{
|
||||
string_type* const storage = m_streambuf.storage();
|
||||
typename string_type::size_type const alignment_size =
|
||||
static_cast< typename string_type::size_type >(m_stream.width() - size);
|
||||
const bool align_left = (m_stream.flags() & ostream_type::adjustfield) == ostream_type::left;
|
||||
if (align_left)
|
||||
{
|
||||
if (!m_streambuf.storage_overflow())
|
||||
{
|
||||
if (!aux::code_convert(p, static_cast< std::size_t >(size), *storage, m_streambuf.max_size(), m_stream.getloc()))
|
||||
m_streambuf.storage_overflow(true);
|
||||
}
|
||||
m_streambuf.append(alignment_size, m_stream.fill());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_streambuf.append(alignment_size, m_stream.fill());
|
||||
if (!m_streambuf.storage_overflow())
|
||||
{
|
||||
if (!aux::code_convert(p, static_cast< std::size_t >(size), *storage, m_streambuf.max_size(), m_stream.getloc()))
|
||||
m_streambuf.storage_overflow(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Implementation note: these operators below should be the least attractive for the compiler
|
||||
// so that user's overloads are chosen, when present. We use function template partial ordering for this purpose.
|
||||
// We also don't use perfect forwarding for the right hand argument because in this case the generic overload
|
||||
// would be more preferred than the typical one written by users:
|
||||
//
|
||||
// formatting_ostream& operator<< (formatting_ostream& strm, my_type const& arg);
|
||||
//
|
||||
// This is because my_type rvalues require adding const to the type, which counts as a conversion that is not required
|
||||
// if there is a perfect forwarding overload.
|
||||
template< typename StreamT, typename T >
|
||||
inline typename boost::log::aux::enable_formatting_ostream_generic_operator< StreamT, T, true, StreamT& >::type
|
||||
operator<< (StreamT& strm, T value)
|
||||
{
|
||||
strm.stream() << value;
|
||||
return strm;
|
||||
}
|
||||
|
||||
template< typename StreamT, typename T >
|
||||
inline typename boost::log::aux::enable_formatting_ostream_generic_operator< StreamT, T, false, StreamT& >::type
|
||||
operator<< (StreamT& strm, T const& value)
|
||||
{
|
||||
strm.stream() << value;
|
||||
return strm;
|
||||
}
|
||||
|
||||
template< typename StreamT, typename T >
|
||||
inline typename boost::log::aux::enable_formatting_ostream_generic_operator< StreamT, T, false, StreamT& >::type
|
||||
operator<< (StreamT& strm, T& value)
|
||||
{
|
||||
strm.stream() << value;
|
||||
return strm;
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
|
||||
template< typename StreamT, typename T >
|
||||
inline typename boost::log::aux::enable_formatting_ostream_generic_operator< StreamT, T, true, StreamT& >::type
|
||||
operator<< (StreamT&& strm, T value)
|
||||
{
|
||||
strm.stream() << value;
|
||||
return strm;
|
||||
}
|
||||
|
||||
template< typename StreamT, typename T >
|
||||
inline typename boost::log::aux::enable_formatting_ostream_generic_operator< StreamT, T, false, StreamT& >::type
|
||||
operator<< (StreamT&& strm, T const& value)
|
||||
{
|
||||
strm.stream() << value;
|
||||
return strm;
|
||||
}
|
||||
|
||||
template< typename StreamT, typename T >
|
||||
inline typename boost::log::aux::enable_formatting_ostream_generic_operator< StreamT, T, false, StreamT& >::type
|
||||
operator<< (StreamT&& strm, T& value)
|
||||
{
|
||||
strm.stream() << value;
|
||||
return strm;
|
||||
}
|
||||
|
||||
#endif // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_UTILITY_FORMATTING_OSTREAM_HPP_INCLUDED_
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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 formatting_ostream_fwd.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 11.07.2012
|
||||
*
|
||||
* The header contains forward declaration of a string stream used for log record formatting.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_UTILITY_FORMATTING_OSTREAM_FWD_HPP_INCLUDED_
|
||||
#define BOOST_LOG_UTILITY_FORMATTING_OSTREAM_FWD_HPP_INCLUDED_
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
/*!
|
||||
* \brief Stream for log records formatting
|
||||
*/
|
||||
template<
|
||||
typename CharT,
|
||||
typename TraitsT = std::char_traits< CharT >,
|
||||
typename AllocatorT = std::allocator< CharT >
|
||||
>
|
||||
class basic_formatting_ostream;
|
||||
|
||||
#ifdef BOOST_LOG_USE_CHAR
|
||||
typedef basic_formatting_ostream< char > formatting_ostream;
|
||||
#endif
|
||||
#ifdef BOOST_LOG_USE_WCHAR_T
|
||||
typedef basic_formatting_ostream< wchar_t > wformatting_ostream;
|
||||
#endif
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_LOG_UTILITY_FORMATTING_OSTREAM_FWD_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 functional.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 30.03.2008
|
||||
*
|
||||
* This header includes all functional helpers.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_UTILITY_FUNCTIONAL_HPP_INCLUDED_
|
||||
#define BOOST_LOG_UTILITY_FUNCTIONAL_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
|
||||
#include <boost/log/utility/functional/logical.hpp>
|
||||
#include <boost/log/utility/functional/in_range.hpp>
|
||||
#include <boost/log/utility/functional/begins_with.hpp>
|
||||
#include <boost/log/utility/functional/ends_with.hpp>
|
||||
#include <boost/log/utility/functional/contains.hpp>
|
||||
#include <boost/log/utility/functional/matches.hpp>
|
||||
|
||||
#include <boost/log/utility/functional/nop.hpp>
|
||||
#include <boost/log/utility/functional/bind_assign.hpp>
|
||||
#include <boost/log/utility/functional/bind_output.hpp>
|
||||
#include <boost/log/utility/functional/bind_to_log.hpp>
|
||||
#include <boost/log/utility/functional/bind.hpp>
|
||||
#include <boost/log/utility/functional/fun_ref.hpp>
|
||||
#include <boost/log/utility/functional/as_action.hpp>
|
||||
#include <boost/log/utility/functional/save_result.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#endif // BOOST_LOG_UTILITY_FUNCTIONAL_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 as_action.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 30.03.2008
|
||||
*
|
||||
* This header contains function object adapter for compatibility with Boost.Spirit actions interface requirements.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_UTILITY_FUNCTIONAL_AS_ACTION_HPP_INCLUDED_
|
||||
#define BOOST_LOG_UTILITY_FUNCTIONAL_AS_ACTION_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
|
||||
|
||||
//! Function object adapter for Boost.Spirit actions
|
||||
template< typename FunT >
|
||||
struct as_action_adapter
|
||||
{
|
||||
typedef typename FunT::result_type result_type;
|
||||
|
||||
BOOST_DEFAULTED_FUNCTION(as_action_adapter(), {})
|
||||
explicit as_action_adapter(FunT const& fun) : m_fun(fun) {}
|
||||
|
||||
template< typename AttributeT, typename ContextT >
|
||||
result_type operator() (AttributeT const& attr, ContextT const& ctx, bool& pass) const
|
||||
{
|
||||
return m_fun(attr);
|
||||
}
|
||||
|
||||
private:
|
||||
FunT m_fun;
|
||||
};
|
||||
|
||||
template< typename FunT >
|
||||
BOOST_FORCEINLINE as_action_adapter< FunT > as_action(FunT const& fun)
|
||||
{
|
||||
return as_action_adapter< FunT >(fun);
|
||||
}
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_UTILITY_FUNCTIONAL_AS_ACTION_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 begins_with.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 30.03.2008
|
||||
*
|
||||
* This header contains a predicate for checking if the provided string begins with a substring.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_UTILITY_FUNCTIONAL_BEGINS_WITH_HPP_INCLUDED_
|
||||
#define BOOST_LOG_UTILITY_FUNCTIONAL_BEGINS_WITH_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
|
||||
|
||||
//! The \c begins_with functor
|
||||
struct begins_with_fun
|
||||
{
|
||||
typedef bool result_type;
|
||||
|
||||
template< typename T, typename U >
|
||||
bool operator() (T const& left, U const& right) const
|
||||
{
|
||||
typedef typename T::const_iterator left_iterator;
|
||||
typedef typename U::const_iterator right_iterator;
|
||||
|
||||
left_iterator left_it = left.begin(), left_end = left.end();
|
||||
right_iterator right_it = right.begin(), right_end = right.end();
|
||||
for (; left_it != left_end && right_it != right_end; ++left_it, ++right_it)
|
||||
{
|
||||
if (*left_it != *right_it)
|
||||
break;
|
||||
}
|
||||
return right_it == right_end;
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_UTILITY_FUNCTIONAL_BEGINS_WITH_HPP_INCLUDED_
|
||||
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
* 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 bind.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 30.03.2008
|
||||
*
|
||||
* This header contains function object adapters.
|
||||
* This is a lightweight alternative to what Boost.Phoenix and Boost.Bind provides.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_UTILITY_FUNCTIONAL_BIND_HPP_INCLUDED_
|
||||
#define BOOST_LOG_UTILITY_FUNCTIONAL_BIND_HPP_INCLUDED_
|
||||
|
||||
#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 >
|
||||
struct make_arg_type
|
||||
{
|
||||
typedef T const& type;
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
struct make_arg_type< T& >
|
||||
{
|
||||
typedef T& type;
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
//! First argument binder
|
||||
template< typename FunT, typename FirstArgT >
|
||||
struct binder1st :
|
||||
private FunT
|
||||
{
|
||||
typedef typename FunT::result_type result_type;
|
||||
|
||||
binder1st(FunT const& fun, typename aux::make_arg_type< FirstArgT >::type arg) : FunT(fun), m_arg(arg) {}
|
||||
|
||||
result_type operator() () const
|
||||
{
|
||||
return FunT::operator()(m_arg);
|
||||
}
|
||||
|
||||
template< typename T0 >
|
||||
result_type operator() (T0 const& arg0) const
|
||||
{
|
||||
return FunT::operator()(m_arg, arg0);
|
||||
}
|
||||
|
||||
template< typename T0, typename T1 >
|
||||
result_type operator() (T0 const& arg0, T1 const& arg1) const
|
||||
{
|
||||
return FunT::operator()(m_arg, arg0, arg1);
|
||||
}
|
||||
|
||||
private:
|
||||
FirstArgT m_arg;
|
||||
};
|
||||
|
||||
//! First argument binder
|
||||
template< typename FunT, typename FirstArgT >
|
||||
struct binder1st< FunT&, FirstArgT >
|
||||
{
|
||||
typedef typename remove_cv< FunT >::type::result_type result_type;
|
||||
|
||||
binder1st(FunT& fun, typename aux::make_arg_type< FirstArgT >::type arg) : m_fun(fun), m_arg(arg) {}
|
||||
|
||||
result_type operator() () const
|
||||
{
|
||||
return m_fun(m_arg);
|
||||
}
|
||||
|
||||
template< typename T0 >
|
||||
result_type operator() (T0 const& arg0) const
|
||||
{
|
||||
return m_fun(m_arg, arg0);
|
||||
}
|
||||
|
||||
template< typename T0, typename T1 >
|
||||
result_type operator() (T0 const& arg0, T1 const& arg1) const
|
||||
{
|
||||
return m_fun(m_arg, arg0, arg1);
|
||||
}
|
||||
|
||||
private:
|
||||
FunT& m_fun;
|
||||
FirstArgT m_arg;
|
||||
};
|
||||
|
||||
template< typename FunT, typename FirstArgT >
|
||||
BOOST_FORCEINLINE binder1st< FunT, FirstArgT > bind1st(FunT fun, FirstArgT const& arg)
|
||||
{
|
||||
return binder1st< FunT, FirstArgT >(fun, arg);
|
||||
}
|
||||
|
||||
template< typename FunT, typename FirstArgT >
|
||||
BOOST_FORCEINLINE binder1st< FunT, FirstArgT > bind1st(FunT fun, FirstArgT& arg)
|
||||
{
|
||||
return binder1st< FunT, FirstArgT >(fun, arg);
|
||||
}
|
||||
|
||||
//! Second argument binder
|
||||
template< typename FunT, typename SecondArgT >
|
||||
struct binder2nd :
|
||||
private FunT
|
||||
{
|
||||
typedef typename FunT::result_type result_type;
|
||||
|
||||
binder2nd(FunT const& fun, typename aux::make_arg_type< SecondArgT >::type arg) : FunT(fun), m_arg(arg) {}
|
||||
|
||||
template< typename T >
|
||||
result_type operator() (T const& arg) const
|
||||
{
|
||||
return FunT::operator()(arg, m_arg);
|
||||
}
|
||||
|
||||
template< typename T0, typename T1 >
|
||||
result_type operator() (T0 const& arg0, T1 const& arg1) const
|
||||
{
|
||||
return FunT::operator()(arg0, m_arg, arg1);
|
||||
}
|
||||
|
||||
private:
|
||||
SecondArgT m_arg;
|
||||
};
|
||||
|
||||
//! Second argument binder
|
||||
template< typename FunT, typename SecondArgT >
|
||||
struct binder2nd< FunT&, SecondArgT >
|
||||
{
|
||||
typedef typename remove_cv< FunT >::type::result_type result_type;
|
||||
|
||||
binder2nd(FunT& fun, typename aux::make_arg_type< SecondArgT >::type arg) : m_fun(fun), m_arg(arg) {}
|
||||
|
||||
template< typename T >
|
||||
result_type operator() (T const& arg) const
|
||||
{
|
||||
return m_fun(arg, m_arg);
|
||||
}
|
||||
|
||||
template< typename T0, typename T1 >
|
||||
result_type operator() (T0 const& arg0, T1 const& arg1) const
|
||||
{
|
||||
return m_fun(arg0, m_arg, arg1);
|
||||
}
|
||||
|
||||
private:
|
||||
FunT& m_fun;
|
||||
SecondArgT m_arg;
|
||||
};
|
||||
|
||||
template< typename FunT, typename SecondArgT >
|
||||
BOOST_FORCEINLINE binder2nd< FunT, SecondArgT > bind2nd(FunT fun, SecondArgT const& arg)
|
||||
{
|
||||
return binder2nd< FunT, SecondArgT >(fun, arg);
|
||||
}
|
||||
|
||||
template< typename FunT, typename SecondArgT >
|
||||
BOOST_FORCEINLINE binder2nd< FunT, SecondArgT > bind2nd(FunT fun, SecondArgT& arg)
|
||||
{
|
||||
return binder2nd< FunT, SecondArgT >(fun, arg);
|
||||
}
|
||||
|
||||
//! Third argument binder
|
||||
template< typename FunT, typename ThirdArgT >
|
||||
struct binder3rd :
|
||||
private FunT
|
||||
{
|
||||
typedef typename FunT::result_type result_type;
|
||||
|
||||
binder3rd(FunT const& fun, typename aux::make_arg_type< ThirdArgT >::type arg) : FunT(fun), m_arg(arg) {}
|
||||
|
||||
template< typename T0, typename T1 >
|
||||
result_type operator() (T0 const& arg0, T1 const& arg1) const
|
||||
{
|
||||
return FunT::operator()(arg0, arg1, m_arg);
|
||||
}
|
||||
|
||||
private:
|
||||
ThirdArgT m_arg;
|
||||
};
|
||||
|
||||
//! Third argument binder
|
||||
template< typename FunT, typename ThirdArgT >
|
||||
struct binder3rd< FunT&, ThirdArgT >
|
||||
{
|
||||
typedef typename remove_cv< FunT >::type::result_type result_type;
|
||||
|
||||
binder3rd(FunT& fun, typename aux::make_arg_type< ThirdArgT >::type arg) : m_fun(fun), m_arg(arg) {}
|
||||
|
||||
template< typename T0, typename T1 >
|
||||
result_type operator() (T0 const& arg0, T1 const& arg1) const
|
||||
{
|
||||
return m_fun(arg0, arg1, m_arg);
|
||||
}
|
||||
|
||||
private:
|
||||
FunT& m_fun;
|
||||
ThirdArgT m_arg;
|
||||
};
|
||||
|
||||
template< typename FunT, typename ThirdArgT >
|
||||
BOOST_FORCEINLINE binder3rd< FunT, ThirdArgT > bind3rd(FunT fun, ThirdArgT const& arg)
|
||||
{
|
||||
return binder3rd< FunT, ThirdArgT >(fun, arg);
|
||||
}
|
||||
|
||||
template< typename FunT, typename ThirdArgT >
|
||||
BOOST_FORCEINLINE binder3rd< FunT, ThirdArgT > bind3rd(FunT fun, ThirdArgT& arg)
|
||||
{
|
||||
return binder3rd< FunT, ThirdArgT >(fun, arg);
|
||||
}
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_UTILITY_FUNCTIONAL_BIND_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 bind_assign.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 30.03.2008
|
||||
*
|
||||
* This header contains a function object that assigns the received value to the bound object.
|
||||
* This is a lightweight alternative to what Boost.Phoenix and Boost.Lambda provides.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_UTILITY_FUNCTIONAL_BIND_ASSIGN_HPP_INCLUDED_
|
||||
#define BOOST_LOG_UTILITY_FUNCTIONAL_BIND_ASSIGN_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.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
|
||||
|
||||
//! The function object that assigns its second operand to the first one
|
||||
struct assign_fun
|
||||
{
|
||||
typedef void result_type;
|
||||
|
||||
template< typename LeftT, typename RightT >
|
||||
void operator() (LeftT& assignee, RightT const& val) const
|
||||
{
|
||||
assignee = val;
|
||||
}
|
||||
};
|
||||
|
||||
template< typename AssigneeT >
|
||||
BOOST_FORCEINLINE binder1st< assign_fun, AssigneeT& > bind_assign(AssigneeT& assignee)
|
||||
{
|
||||
return binder1st< assign_fun, AssigneeT& >(assign_fun(), assignee);
|
||||
}
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_UTILITY_FUNCTIONAL_BIND_ASSIGN_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 bind_output.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 30.03.2008
|
||||
*
|
||||
* This header contains a function object that puts the received value to the bound stream.
|
||||
* This is a lightweight alternative to what Boost.Phoenix and Boost.Lambda provides.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_UTILITY_FUNCTIONAL_BIND_OUTPUT_HPP_INCLUDED_
|
||||
#define BOOST_LOG_UTILITY_FUNCTIONAL_BIND_OUTPUT_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.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
|
||||
|
||||
//! The function object that outputs its second operand to the first one
|
||||
struct output_fun
|
||||
{
|
||||
typedef void result_type;
|
||||
|
||||
template< typename StreamT, typename T >
|
||||
void operator() (StreamT& strm, T const& val) const
|
||||
{
|
||||
strm << val;
|
||||
}
|
||||
};
|
||||
|
||||
template< typename StreamT >
|
||||
BOOST_FORCEINLINE binder1st< output_fun, StreamT& > bind_output(StreamT& strm)
|
||||
{
|
||||
return binder1st< output_fun, StreamT& >(output_fun(), strm);
|
||||
}
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_UTILITY_FUNCTIONAL_BIND_OUTPUT_HPP_INCLUDED_
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* 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 bind_to_log.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 06.11.2012
|
||||
*
|
||||
* This header contains a function object that puts the received value to the bound stream using the \c to_log manipulator.
|
||||
* This is a lightweight alternative to what Boost.Phoenix and Boost.Lambda provides.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_UTILITY_FUNCTIONAL_BIND_TO_LOG_HPP_INCLUDED_
|
||||
#define BOOST_LOG_UTILITY_FUNCTIONAL_BIND_TO_LOG_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/utility/functional/bind.hpp>
|
||||
#include <boost/log/utility/manipulators/to_log.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
//! The function object that outputs its second operand to the first one
|
||||
template< typename TagT = void >
|
||||
struct to_log_fun
|
||||
{
|
||||
typedef void result_type;
|
||||
|
||||
template< typename StreamT, typename T >
|
||||
void operator() (StreamT& strm, T const& val) const
|
||||
{
|
||||
strm << boost::log::to_log< TagT >(val);
|
||||
}
|
||||
};
|
||||
|
||||
//! The function object that outputs its second operand to the first one
|
||||
template< >
|
||||
struct to_log_fun< void >
|
||||
{
|
||||
typedef void result_type;
|
||||
|
||||
template< typename StreamT, typename T >
|
||||
void operator() (StreamT& strm, T const& val) const
|
||||
{
|
||||
strm << boost::log::to_log(val);
|
||||
}
|
||||
};
|
||||
|
||||
template< typename StreamT >
|
||||
BOOST_FORCEINLINE binder1st< to_log_fun< >, StreamT& > bind_to_log(StreamT& strm)
|
||||
{
|
||||
return binder1st< to_log_fun< >, StreamT& >(to_log_fun< >(), strm);
|
||||
}
|
||||
|
||||
template< typename TagT, typename StreamT >
|
||||
BOOST_FORCEINLINE binder1st< to_log_fun< TagT >, StreamT& > bind_to_log(StreamT& strm)
|
||||
{
|
||||
return binder1st< to_log_fun< TagT >, StreamT& >(to_log_fun< TagT >(), strm);
|
||||
}
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_UTILITY_FUNCTIONAL_BIND_TO_LOG_HPP_INCLUDED_
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright Andrey Semashev 2007 - 2015.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
/*!
|
||||
* \file contains.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 30.03.2008
|
||||
*
|
||||
* This header contains a predicate for checking if the provided string contains a substring.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_UTILITY_FUNCTIONAL_CONTAINS_HPP_INCLUDED_
|
||||
#define BOOST_LOG_UTILITY_FUNCTIONAL_CONTAINS_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
|
||||
|
||||
//! The \c contains functor
|
||||
struct contains_fun
|
||||
{
|
||||
typedef bool result_type;
|
||||
|
||||
template< typename T, typename U >
|
||||
bool operator() (T const& left, U const& right) const
|
||||
{
|
||||
typedef typename T::const_iterator left_iterator;
|
||||
typedef typename U::const_iterator right_iterator;
|
||||
|
||||
typename U::size_type const right_size = right.size();
|
||||
if (left.size() >= right_size)
|
||||
{
|
||||
const left_iterator search_end = left.end() - right_size + 1;
|
||||
const right_iterator right_end = right.end();
|
||||
for (left_iterator it = left.begin(); it != search_end; ++it)
|
||||
{
|
||||
left_iterator left_it = it;
|
||||
right_iterator right_it = right.begin();
|
||||
for (; right_it != right_end; ++left_it, ++right_it)
|
||||
{
|
||||
if (*left_it != *right_it)
|
||||
break;
|
||||
}
|
||||
if (right_it == right_end)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_UTILITY_FUNCTIONAL_CONTAINS_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 ends_with.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 30.03.2008
|
||||
*
|
||||
* This header contains a predicate for checking if the provided string ends with a substring.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_UTILITY_FUNCTIONAL_ENDS_WITH_HPP_INCLUDED_
|
||||
#define BOOST_LOG_UTILITY_FUNCTIONAL_ENDS_WITH_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
|
||||
|
||||
//! The \c ends_with functor
|
||||
struct ends_with_fun
|
||||
{
|
||||
typedef bool result_type;
|
||||
|
||||
template< typename T, typename U >
|
||||
bool operator() (T const& left, U const& right) const
|
||||
{
|
||||
typedef typename T::const_reverse_iterator left_iterator;
|
||||
typedef typename U::const_reverse_iterator right_iterator;
|
||||
|
||||
left_iterator left_it = left.rbegin(), left_end = left.rend();
|
||||
right_iterator right_it = right.rbegin(), right_end = right.rend();
|
||||
for (; left_it != left_end && right_it != right_end; ++left_it, ++right_it)
|
||||
{
|
||||
if (*left_it != *right_it)
|
||||
break;
|
||||
}
|
||||
return right_it == right_end;
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_UTILITY_FUNCTIONAL_ENDS_WITH_HPP_INCLUDED_
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* 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 fun_ref.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 30.03.2008
|
||||
*
|
||||
* This header contains function object reference adapter. The adapter stores a reference to external
|
||||
* function object and forwards all calls to the referred function.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_UTILITY_FUNCTIONAL_FUN_REF_HPP_INCLUDED_
|
||||
#define BOOST_LOG_UTILITY_FUNCTIONAL_FUN_REF_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
|
||||
|
||||
//! Reference wrapper for function objects
|
||||
template< typename FunT >
|
||||
struct function_reference_wrapper
|
||||
{
|
||||
typedef typename FunT::result_type result_type;
|
||||
|
||||
explicit function_reference_wrapper(FunT& fun) : m_Fun(fun) {}
|
||||
|
||||
result_type operator() () const
|
||||
{
|
||||
return m_Fun();
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template< typename... ArgsT >
|
||||
result_type operator() (ArgsT const&... args) const
|
||||
{
|
||||
return m_Fun(args...);
|
||||
}
|
||||
#else
|
||||
template< typename T >
|
||||
result_type operator() (T const& arg) const
|
||||
{
|
||||
return m_Fun(arg);
|
||||
}
|
||||
|
||||
template< typename T1, typename T2 >
|
||||
result_type operator() (T1 const& arg1, T2 const& arg2) const
|
||||
{
|
||||
return m_Fun(arg1, arg2);
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
FunT& m_Fun;
|
||||
};
|
||||
|
||||
template< typename FunT >
|
||||
BOOST_FORCEINLINE function_reference_wrapper< FunT > fun_ref(FunT& fun)
|
||||
{
|
||||
return function_reference_wrapper< FunT >(fun);
|
||||
}
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_UTILITY_FUNCTIONAL_FUN_REF_HPP_INCLUDED_
|
||||
@@ -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 in_range.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 30.03.2008
|
||||
*
|
||||
* This header contains a predicate for checking if the provided value is within a half-open range.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_UTILITY_FUNCTIONAL_IN_RANGE_HPP_INCLUDED_
|
||||
#define BOOST_LOG_UTILITY_FUNCTIONAL_IN_RANGE_HPP_INCLUDED_
|
||||
|
||||
#include <utility>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/utility/functional/logical.hpp> // make_common_integral_type
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
//! The in_range functor
|
||||
struct in_range_fun
|
||||
{
|
||||
typedef bool result_type;
|
||||
|
||||
template< typename T, typename U >
|
||||
bool operator() (T const& value, std::pair< U, U > const& rng) const
|
||||
{
|
||||
return op(value, rng, typename mpl::and_< is_integral< T >, is_integral< U > >::type());
|
||||
}
|
||||
|
||||
private:
|
||||
template< typename T, typename U >
|
||||
static bool op(T const& value, std::pair< U, U > const& rng, mpl::false_ const&)
|
||||
{
|
||||
return (value >= rng.first && value < rng.second);
|
||||
}
|
||||
template< typename T, typename U >
|
||||
static bool op(T const& value, std::pair< U, U > const& rng, mpl::true_ const&)
|
||||
{
|
||||
typedef typename aux::make_common_integral_type< T, U >::type common_integral_type;
|
||||
return (static_cast< common_integral_type >(value) >= static_cast< common_integral_type >(rng.first))
|
||||
&& (static_cast< common_integral_type >(value) < static_cast< common_integral_type >(rng.second));
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_UTILITY_FUNCTIONAL_IN_RANGE_HPP_INCLUDED_
|
||||
@@ -0,0 +1,225 @@
|
||||
/*
|
||||
* 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 logical.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 30.03.2008
|
||||
*
|
||||
* This header contains logical predicates for value comparison, analogous to \c std::less, \c std::greater
|
||||
* and others. The main difference from the standard equivalents is that the predicates defined in this
|
||||
* header are not templates and therefore do not require a fixed argument type. Furthermore, both arguments
|
||||
* may have different types, in which case the comparison is performed without type conversion.
|
||||
*
|
||||
* \note In case if arguments are integral, the conversion is performed according to the standard C++ rules
|
||||
* in order to avoid warnings from the compiler.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_UTILITY_FUNCTIONAL_LOGICAL_HPP_INCLUDED_
|
||||
#define BOOST_LOG_UTILITY_FUNCTIONAL_LOGICAL_HPP_INCLUDED_
|
||||
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
#include <boost/type_traits/is_unsigned.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 {
|
||||
|
||||
//! The trait creates a common integral type suitable for comparison. This is mostly to silence compiler warnings like 'signed/unsigned mismatch'.
|
||||
template< typename T, typename U, unsigned int TSizeV = sizeof(T), unsigned int USizeV = sizeof(U), bool TSmallerThanU = (sizeof(T) < sizeof(U)) >
|
||||
struct make_common_integral_type
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
//! Specialization for case when \c T is smaller than \c U
|
||||
template< typename T, typename U, unsigned int TSizeV, unsigned int USizeV >
|
||||
struct make_common_integral_type< T, U, TSizeV, USizeV, true >
|
||||
{
|
||||
typedef U type;
|
||||
};
|
||||
|
||||
//! Specialization for the case when both types have the same size
|
||||
template< typename T, typename U, unsigned int SizeV >
|
||||
struct make_common_integral_type< T, U, SizeV, SizeV, false > :
|
||||
public mpl::if_<
|
||||
is_unsigned< T >,
|
||||
T,
|
||||
U
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
//! Equality predicate
|
||||
struct equal_to
|
||||
{
|
||||
typedef bool result_type;
|
||||
|
||||
template< typename T, typename U >
|
||||
bool operator() (T const& left, U const& right) const
|
||||
{
|
||||
return op(left, right, typename mpl::and_< is_integral< T >, is_integral< U > >::type());
|
||||
}
|
||||
|
||||
private:
|
||||
template< typename T, typename U >
|
||||
static bool op(T const& left, U const& right, mpl::false_ const&)
|
||||
{
|
||||
return (left == right);
|
||||
}
|
||||
template< typename T, typename U >
|
||||
static bool op(T const& left, U const& right, mpl::true_ const&)
|
||||
{
|
||||
typedef typename aux::make_common_integral_type< T, U >::type common_integral_type;
|
||||
return static_cast< common_integral_type >(left) == static_cast< common_integral_type >(right);
|
||||
}
|
||||
};
|
||||
|
||||
//! Inequality predicate
|
||||
struct not_equal_to
|
||||
{
|
||||
typedef bool result_type;
|
||||
|
||||
template< typename T, typename U >
|
||||
bool operator() (T const& left, U const& right) const
|
||||
{
|
||||
return op(left, right, typename mpl::and_< is_integral< T >, is_integral< U > >::type());
|
||||
}
|
||||
|
||||
private:
|
||||
template< typename T, typename U >
|
||||
static bool op(T const& left, U const& right, mpl::false_ const&)
|
||||
{
|
||||
return (left != right);
|
||||
}
|
||||
template< typename T, typename U >
|
||||
static bool op(T const& left, U const& right, mpl::true_ const&)
|
||||
{
|
||||
typedef typename aux::make_common_integral_type< T, U >::type common_integral_type;
|
||||
return static_cast< common_integral_type >(left) != static_cast< common_integral_type >(right);
|
||||
}
|
||||
};
|
||||
|
||||
//! Less predicate
|
||||
struct less
|
||||
{
|
||||
typedef bool result_type;
|
||||
|
||||
template< typename T, typename U >
|
||||
bool operator() (T const& left, U const& right) const
|
||||
{
|
||||
return op(left, right, typename mpl::and_< is_integral< T >, is_integral< U > >::type());
|
||||
}
|
||||
|
||||
private:
|
||||
template< typename T, typename U >
|
||||
static bool op(T const& left, U const& right, mpl::false_ const&)
|
||||
{
|
||||
return (left < right);
|
||||
}
|
||||
template< typename T, typename U >
|
||||
static bool op(T const& left, U const& right, mpl::true_ const&)
|
||||
{
|
||||
typedef typename aux::make_common_integral_type< T, U >::type common_integral_type;
|
||||
return static_cast< common_integral_type >(left) < static_cast< common_integral_type >(right);
|
||||
}
|
||||
};
|
||||
|
||||
//! Greater predicate
|
||||
struct greater
|
||||
{
|
||||
typedef bool result_type;
|
||||
|
||||
template< typename T, typename U >
|
||||
bool operator() (T const& left, U const& right) const
|
||||
{
|
||||
return op(left, right, typename mpl::and_< is_integral< T >, is_integral< U > >::type());
|
||||
}
|
||||
|
||||
private:
|
||||
template< typename T, typename U >
|
||||
static bool op(T const& left, U const& right, mpl::false_ const&)
|
||||
{
|
||||
return (left > right);
|
||||
}
|
||||
template< typename T, typename U >
|
||||
static bool op(T const& left, U const& right, mpl::true_ const&)
|
||||
{
|
||||
typedef typename aux::make_common_integral_type< T, U >::type common_integral_type;
|
||||
return static_cast< common_integral_type >(left) > static_cast< common_integral_type >(right);
|
||||
}
|
||||
};
|
||||
|
||||
//! Less or equal predicate
|
||||
struct less_equal
|
||||
{
|
||||
typedef bool result_type;
|
||||
|
||||
template< typename T, typename U >
|
||||
bool operator() (T const& left, U const& right) const
|
||||
{
|
||||
return op(left, right, typename mpl::and_< is_integral< T >, is_integral< U > >::type());
|
||||
}
|
||||
|
||||
private:
|
||||
template< typename T, typename U >
|
||||
static bool op(T const& left, U const& right, mpl::false_ const&)
|
||||
{
|
||||
return (left <= right);
|
||||
}
|
||||
template< typename T, typename U >
|
||||
static bool op(T const& left, U const& right, mpl::true_ const&)
|
||||
{
|
||||
typedef typename aux::make_common_integral_type< T, U >::type common_integral_type;
|
||||
return static_cast< common_integral_type >(left) <= static_cast< common_integral_type >(right);
|
||||
}
|
||||
};
|
||||
|
||||
//! Greater or equal predicate
|
||||
struct greater_equal
|
||||
{
|
||||
typedef bool result_type;
|
||||
|
||||
template< typename T, typename U >
|
||||
bool operator() (T const& left, U const& right) const
|
||||
{
|
||||
return op(left, right, typename mpl::and_< is_integral< T >, is_integral< U > >::type());
|
||||
}
|
||||
|
||||
private:
|
||||
template< typename T, typename U >
|
||||
static bool op(T const& left, U const& right, mpl::false_ const&)
|
||||
{
|
||||
return (left >= right);
|
||||
}
|
||||
template< typename T, typename U >
|
||||
static bool op(T const& left, U const& right, mpl::true_ const&)
|
||||
{
|
||||
typedef typename aux::make_common_integral_type< T, U >::type common_integral_type;
|
||||
return static_cast< common_integral_type >(left) >= static_cast< common_integral_type >(right);
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_UTILITY_FUNCTIONAL_LOGICAL_HPP_INCLUDED_
|
||||
@@ -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)
|
||||
*/
|
||||
/*!
|
||||
* \file matches.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 30.03.2008
|
||||
*
|
||||
* This header contains a predicate for checking if the provided string matches a regular expression.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_UTILITY_FUNCTIONAL_MATCHES_HPP_INCLUDED_
|
||||
#define BOOST_LOG_UTILITY_FUNCTIONAL_MATCHES_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 metafunction detects the matching expression kind and returns a tag that is used to specialize \c match_traits
|
||||
template< typename ExpressionT, typename = void >
|
||||
struct matching_expression_kind;
|
||||
|
||||
//! The matching function implementation
|
||||
template< typename ExpressionT, typename TagT = typename matching_expression_kind< ExpressionT >::type >
|
||||
struct match_traits;
|
||||
|
||||
} // namespace aux
|
||||
|
||||
//! The regex matching functor
|
||||
struct matches_fun
|
||||
{
|
||||
typedef bool result_type;
|
||||
|
||||
template< typename StringT, typename ExpressionT >
|
||||
bool operator() (StringT const& str, ExpressionT const& expr) const
|
||||
{
|
||||
typedef aux::match_traits< ExpressionT > impl;
|
||||
return impl::matches(str, expr);
|
||||
}
|
||||
template< typename StringT, typename ExpressionT, typename ArgT >
|
||||
bool operator() (StringT const& str, ExpressionT const& expr, ArgT const& arg) const
|
||||
{
|
||||
typedef aux::match_traits< ExpressionT > impl;
|
||||
return impl::matches(str, expr, arg);
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_UTILITY_FUNCTIONAL_MATCHES_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 nop.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 30.03.2008
|
||||
*
|
||||
* This header contains a function object that does nothing.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_UTILITY_FUNCTIONAL_NOP_HPP_INCLUDED_
|
||||
#define BOOST_LOG_UTILITY_FUNCTIONAL_NOP_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
|
||||
|
||||
//! The function object that does nothing
|
||||
struct nop
|
||||
{
|
||||
typedef void result_type;
|
||||
|
||||
void operator() () const BOOST_NOEXCEPT {}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template< typename... ArgsT >
|
||||
void operator() (ArgsT const&...) const BOOST_NOEXCEPT {}
|
||||
#else
|
||||
template< typename T >
|
||||
void operator() (T const&) const BOOST_NOEXCEPT {}
|
||||
template< typename T1, typename T2 >
|
||||
void operator() (T1 const&, T2 const&) const BOOST_NOEXCEPT {}
|
||||
template< typename T1, typename T2, typename T3 >
|
||||
void operator() (T1 const&, T2 const&, T3 const&) const BOOST_NOEXCEPT {}
|
||||
#endif
|
||||
};
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_UTILITY_FUNCTIONAL_NOP_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 save_result.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 19.01.2013
|
||||
*
|
||||
* This header contains function object adapter that saves the result of the adopted function to an external variable.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_UTILITY_FUNCTIONAL_SAVE_RESULT_HPP_INCLUDED_
|
||||
#define BOOST_LOG_UTILITY_FUNCTIONAL_SAVE_RESULT_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
|
||||
|
||||
//! Function object wrapper for saving the adopted function object result
|
||||
template< typename FunT, typename AssigneeT >
|
||||
struct save_result_wrapper
|
||||
{
|
||||
typedef void result_type;
|
||||
|
||||
save_result_wrapper(FunT fun, AssigneeT& assignee) : m_fun(fun), m_assignee(assignee) {}
|
||||
|
||||
template< typename ArgT >
|
||||
result_type operator() (ArgT const& arg) const
|
||||
{
|
||||
m_assignee = m_fun(arg);
|
||||
}
|
||||
|
||||
private:
|
||||
FunT m_fun;
|
||||
AssigneeT& m_assignee;
|
||||
};
|
||||
|
||||
template< typename FunT, typename AssigneeT >
|
||||
BOOST_FORCEINLINE save_result_wrapper< FunT, AssigneeT > save_result(FunT const& fun, AssigneeT& assignee)
|
||||
{
|
||||
return save_result_wrapper< FunT, AssigneeT >(fun, assignee);
|
||||
}
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_UTILITY_FUNCTIONAL_SAVE_RESULT_HPP_INCLUDED_
|
||||
@@ -0,0 +1,271 @@
|
||||
/*
|
||||
* 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 utility/ipc/object_name.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 05.03.2016
|
||||
*
|
||||
* The header contains declaration of a system object name wrapper.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_UTILITY_IPC_OBJECT_NAME_HPP_INCLUDED_
|
||||
#define BOOST_LOG_UTILITY_IPC_OBJECT_NAME_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <cstddef>
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace ipc {
|
||||
|
||||
/*!
|
||||
* \brief A system object name class
|
||||
*
|
||||
* In order to identify a system-wide object such as a shared memory segment or a named synchronization primitive the object has to be given a name.
|
||||
* The format of the name is specific to the operating system and the \c object_name class provides an abstraction for names of objects. It also
|
||||
* provides means for scoping, which allows to avoid name clashes between different processes.
|
||||
*
|
||||
* The object name is a UTF-8 encoded string. The portable object name should consist of the following characters:
|
||||
*
|
||||
* <pre>
|
||||
* A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
|
||||
* a b c d e f g h i j k l m n o p q r s t u v w x y z
|
||||
* 0 1 2 3 4 5 6 7 8 9 . _ -
|
||||
* </pre>
|
||||
*
|
||||
* \note The character set corresponds to the POSIX Portable Filename Character Set (http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_278).
|
||||
*
|
||||
* Use of other characters may result in non-portable system-specific behavior.
|
||||
*
|
||||
* The name can have one of the following scopes:
|
||||
*
|
||||
* \li \c global - objects within this scope are visible to any process on the system. In order to use this scope the process may need to have
|
||||
* extended privileges. This scope is not available for Windows Store applications.
|
||||
* \li \c user - objects within this scope can be opened by processes running under the same user as the current process.
|
||||
* \li \c session - objects within this scope are visible to processes within the session of the current process. The definition of a session may vary between
|
||||
* operating systems. On POSIX, a session is typically a group of processes attached to a single virtual terminal device. On Windows a session is
|
||||
* started when a user logs into the system. There is also a separate session for Windows services.
|
||||
* \li \c process_group - objects within this scope are visible to processes within the process group of the current process. Currently, on Windows all processes
|
||||
* running in the current session are considered members of the same process group. This may change in future.
|
||||
*
|
||||
* The scopes are not overlapping. For instance, if an object is created in the global scope, the object cannot be opened with the same name but in user's scope.
|
||||
*
|
||||
* Note that name scoping is not a security feature. On some systems any process on the system has technical capability to open objects within any scope.
|
||||
* The scope is only used to help avoid name clashes between processes using \c object_name to identify objects.
|
||||
*/
|
||||
class object_name
|
||||
{
|
||||
public:
|
||||
//! Name scopes
|
||||
enum scope
|
||||
{
|
||||
global, //!< The name has global scope; any process in the system has the potential to open the resource identified by the name
|
||||
user, //!< The name is limited to processes running under the current user
|
||||
session, //!< The name is limited to processes running in the current login session
|
||||
process_group //!< The name is limited to processes running in the current process group
|
||||
};
|
||||
|
||||
#if !defined(BOOST_LOG_DOXYGEN_PASS)
|
||||
|
||||
BOOST_COPYABLE_AND_MOVABLE(object_name)
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
|
||||
#endif // !defined(BOOST_LOG_DOXYGEN_PASS)
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Default constructor. The method creates an empty object name.
|
||||
*
|
||||
* \post <tt>empty() == true</tt>
|
||||
*/
|
||||
object_name() BOOST_NOEXCEPT
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* Move constructor.
|
||||
*/
|
||||
object_name(BOOST_RV_REF(object_name) that) BOOST_NOEXCEPT
|
||||
{
|
||||
m_name.swap(that.m_name);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Copy constructor.
|
||||
*/
|
||||
object_name(object_name const& that) : m_name(that.m_name)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* Constructor from the native string.
|
||||
*
|
||||
* \param str The object name string, must not be \c NULL. The string format is specific to the operating system.
|
||||
*/
|
||||
static object_name from_native(const char* str)
|
||||
{
|
||||
object_name name;
|
||||
name.m_name = str;
|
||||
return name;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Constructor from the native string.
|
||||
*
|
||||
* \param str The object name string. The string format is specific to the operating system.
|
||||
*/
|
||||
static object_name from_native(std::string const& str)
|
||||
{
|
||||
object_name name;
|
||||
name.m_name = str;
|
||||
return name;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Constructor from the object name
|
||||
* \param ns The scope of the object name
|
||||
* \param str The object name, must not be NULL.
|
||||
*/
|
||||
BOOST_LOG_API object_name(scope ns, const char* str);
|
||||
|
||||
/*!
|
||||
* Constructor from the object name
|
||||
* \param ns The scope of the object name
|
||||
* \param str The object name
|
||||
*/
|
||||
BOOST_LOG_API object_name(scope ns, std::string const& str);
|
||||
|
||||
/*!
|
||||
* Move assignment
|
||||
*/
|
||||
object_name& operator= (BOOST_RV_REF(object_name) that) BOOST_NOEXCEPT
|
||||
{
|
||||
m_name.clear();
|
||||
m_name.swap(that.m_name);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Copy assignment
|
||||
*/
|
||||
object_name& operator= (BOOST_COPY_ASSIGN_REF(object_name) that)
|
||||
{
|
||||
m_name = that.m_name;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns \c true if the object name is empty
|
||||
*/
|
||||
bool empty() const BOOST_NOEXCEPT { return m_name.empty(); }
|
||||
|
||||
/*!
|
||||
* Returns length of the name, in bytes
|
||||
*/
|
||||
std::size_t size() const BOOST_NOEXCEPT { return m_name.size(); }
|
||||
|
||||
/*!
|
||||
* Returns the name string
|
||||
*/
|
||||
const char* c_str() const BOOST_NOEXCEPT { return m_name.c_str(); }
|
||||
|
||||
/*!
|
||||
* Swaps the object name with another object name
|
||||
*/
|
||||
void swap(object_name& that) BOOST_NOEXCEPT { m_name.swap(that.m_name); }
|
||||
|
||||
/*!
|
||||
* Swaps two object names
|
||||
*/
|
||||
friend void swap(object_name& left, object_name& right) BOOST_NOEXCEPT
|
||||
{
|
||||
left.swap(right);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns string representation of the object name
|
||||
*/
|
||||
friend std::string to_string(object_name const& name)
|
||||
{
|
||||
return name.m_name;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Equality operator
|
||||
*/
|
||||
friend bool operator== (object_name const& left, object_name const& right) BOOST_NOEXCEPT
|
||||
{
|
||||
return left.m_name == right.m_name;
|
||||
}
|
||||
/*!
|
||||
* Inequality operator
|
||||
*/
|
||||
friend bool operator!= (object_name const& left, object_name const& right) BOOST_NOEXCEPT
|
||||
{
|
||||
return left.m_name != right.m_name;
|
||||
}
|
||||
/*!
|
||||
* Less operator
|
||||
*/
|
||||
friend bool operator< (object_name const& left, object_name const& right) BOOST_NOEXCEPT
|
||||
{
|
||||
return left.m_name < right.m_name;
|
||||
}
|
||||
/*!
|
||||
* Greater operator
|
||||
*/
|
||||
friend bool operator> (object_name const& left, object_name const& right) BOOST_NOEXCEPT
|
||||
{
|
||||
return left.m_name > right.m_name;
|
||||
}
|
||||
/*!
|
||||
* Less or equal operator
|
||||
*/
|
||||
friend bool operator<= (object_name const& left, object_name const& right) BOOST_NOEXCEPT
|
||||
{
|
||||
return left.m_name <= right.m_name;
|
||||
}
|
||||
/*!
|
||||
* Greater or equal operator
|
||||
*/
|
||||
friend bool operator>= (object_name const& left, object_name const& right) BOOST_NOEXCEPT
|
||||
{
|
||||
return left.m_name >= right.m_name;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Stream ouput operator
|
||||
*/
|
||||
template< typename CharT, typename TraitsT >
|
||||
friend std::basic_ostream< CharT, TraitsT >& operator<< (std::basic_ostream< CharT, TraitsT >& strm, object_name const& name)
|
||||
{
|
||||
strm << name.c_str();
|
||||
return strm;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace ipc
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_UTILITY_IPC_OBJECT_NAME_HPP_INCLUDED_
|
||||
@@ -0,0 +1,776 @@
|
||||
/*
|
||||
* Copyright Lingxi Li 2015.
|
||||
* 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 utility/ipc/reliable_message_queue.hpp
|
||||
* \author Lingxi Li
|
||||
* \author Andrey Semashev
|
||||
* \date 01.01.2016
|
||||
*
|
||||
* The header contains declaration of a reliable interprocess message queue.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_UTILITY_IPC_RELIABLE_MESSAGE_QUEUE_HPP_INCLUDED_
|
||||
#define BOOST_LOG_UTILITY_IPC_RELIABLE_MESSAGE_QUEUE_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <cstddef>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/log/keywords/open_mode.hpp>
|
||||
#include <boost/log/keywords/name.hpp>
|
||||
#include <boost/log/keywords/capacity.hpp>
|
||||
#include <boost/log/keywords/block_size.hpp>
|
||||
#include <boost/log/keywords/overflow_policy.hpp>
|
||||
#include <boost/log/keywords/permissions.hpp>
|
||||
#include <boost/log/utility/open_mode.hpp>
|
||||
#include <boost/log/utility/permissions.hpp>
|
||||
#include <boost/log/utility/ipc/object_name.hpp>
|
||||
#include <boost/log/detail/parameter_tools.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace ipc {
|
||||
|
||||
namespace aux {
|
||||
|
||||
template< typename T, typename R >
|
||||
struct enable_if_byte {};
|
||||
template< typename R >
|
||||
struct enable_if_byte< char, R > { typedef R type; };
|
||||
template< typename R >
|
||||
struct enable_if_byte< signed char, R > { typedef R type; };
|
||||
template< typename R >
|
||||
struct enable_if_byte< unsigned char, R > { typedef R type; };
|
||||
|
||||
} // namespace aux
|
||||
|
||||
/*!
|
||||
* \brief A reliable interprocess message queue
|
||||
*
|
||||
* The queue implements a reliable one-way channel of passing messages from one or multiple writers to a single reader.
|
||||
* The format of the messages is user-defined and must be consistent across all writers and the reader. The queue does
|
||||
* not enforce any specific format of the messages, other than they should be supplied as a contiguous array of bytes.
|
||||
*
|
||||
* The queue internally uses a process-shared storage identified by an \c object_name (the queue name). Refer to \c object_name
|
||||
* documentation for details on restrictions imposed on object names.
|
||||
*
|
||||
* The queue storage is organized as a fixed number of blocks of a fixed size. The block size must be an integer power of 2 and
|
||||
* is expressed in bytes. Each written message, together with some metadata added by the queue, consumes an integer number
|
||||
* of blocks. Each read message received by the reader releases the blocks allocated for that message. As such the maximum size
|
||||
* of a message is slightly less than block size times capacity of the queue. For efficiency, it is recommended to choose
|
||||
* block size large enough to accommodate most of the messages to be passed through the queue.
|
||||
*
|
||||
* The queue is considered empty when no messages are enqueued (all blocks are free). The queue is considered full at the point
|
||||
* of enqueueing a message when there is not enough free blocks to accommodate the message.
|
||||
*
|
||||
* The queue is reliable in that it will not drop successfully sent messages that are not received by the reader, other than the
|
||||
* case when a non-empty queue is destroyed by the last user. If a message cannot be enqueued by the writer because the queue is
|
||||
* full, the queue can either block the writer or return an error or throw an exception, depending on the policy specified at
|
||||
* the queue creation. The policy is object local, i.e. different writers and the reader can have different overflow policies.
|
||||
*
|
||||
* If the queue is empty and the reader attempts to dequeue a message, it will block until a message is enqueued by a writer.
|
||||
*
|
||||
* A blocked reader or writer can be unblocked by calling \c stop_local. After this method is called, all threads blocked on
|
||||
* this particular object are released and return \c operation_result::aborted. The other instances of the queue (in the current
|
||||
* or other processes) are unaffected. In order to restore the normal functioning of the queue instance after the \c stop_local
|
||||
* call the user has to invoke \c reset_local.
|
||||
*
|
||||
* The queue does not guarantee any particular order of received messages from different writer threads. Messages sent by a
|
||||
* particular writer thread will be received in the order of sending.
|
||||
*
|
||||
* Methods of this class are not thread-safe, unless otherwise specified.
|
||||
*/
|
||||
class reliable_message_queue
|
||||
{
|
||||
public:
|
||||
//! Result codes for various operations on the queue
|
||||
enum operation_result
|
||||
{
|
||||
succeeded, //!< The operation has completed successfully
|
||||
no_space, //!< The message could not be sent because the queue is full
|
||||
aborted //!< The operation has been aborted because the queue method <tt>stop_local()</tt> has been called
|
||||
};
|
||||
|
||||
//! Interprocess queue overflow policies
|
||||
enum overflow_policy
|
||||
{
|
||||
//! Block the send operation when the queue is full
|
||||
block_on_overflow,
|
||||
//! Return \c operation_result::no_space when the queue is full
|
||||
fail_on_overflow,
|
||||
//! Throw \c capacity_limit_reached exception when the queue is full
|
||||
throw_on_overflow
|
||||
};
|
||||
|
||||
//! Queue message size type
|
||||
typedef uint32_t size_type;
|
||||
|
||||
#if !defined(BOOST_LOG_DOXYGEN_PASS)
|
||||
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(reliable_message_queue)
|
||||
|
||||
private:
|
||||
typedef void (*receive_handler)(void* state, const void* data, size_type size);
|
||||
|
||||
struct fixed_buffer_state
|
||||
{
|
||||
uint8_t* data;
|
||||
size_type size;
|
||||
};
|
||||
|
||||
struct implementation;
|
||||
implementation* m_impl;
|
||||
|
||||
#endif // !defined(BOOST_LOG_DOXYGEN_PASS)
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Default constructor. The method constructs an object that is not associated with any
|
||||
* message queue.
|
||||
*
|
||||
* \post <tt>is_open() == false</tt>
|
||||
*/
|
||||
BOOST_CONSTEXPR reliable_message_queue() BOOST_NOEXCEPT : m_impl(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* Constructor. The method is used to construct an object and create the associated
|
||||
* message queue. The constructed object will be in running state if the message queue is
|
||||
* successfully created.
|
||||
*
|
||||
* \post <tt>is_open() == true</tt>
|
||||
*
|
||||
* \param name Name of the message queue to be associated with.
|
||||
* \param capacity Maximum number of allocation blocks the queue can hold.
|
||||
* \param block_size Size in bytes of allocation block. Must be a power of 2.
|
||||
* \param oflow_policy Queue behavior policy in case of overflow.
|
||||
* \param perms Access permissions for the associated message queue.
|
||||
*/
|
||||
reliable_message_queue
|
||||
(
|
||||
open_mode::create_only_tag,
|
||||
object_name const& name,
|
||||
uint32_t capacity,
|
||||
size_type block_size,
|
||||
overflow_policy oflow_policy = block_on_overflow,
|
||||
permissions const& perms = permissions()
|
||||
) :
|
||||
m_impl(NULL)
|
||||
{
|
||||
this->create(name, capacity, block_size, oflow_policy, perms);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Constructor. The method is used to construct an object and create or open the associated
|
||||
* message queue. The constructed object will be in running state if the message queue is
|
||||
* successfully created or opened. If the message queue that is identified by the name already
|
||||
* exists then the other queue parameters are ignored. The actual queue parameters can be obtained
|
||||
* with accessors from the constructed object.
|
||||
*
|
||||
* \post <tt>is_open() == true</tt>
|
||||
*
|
||||
* \param name Name of the message queue to be associated with.
|
||||
* \param capacity Maximum number of allocation blocks the queue can hold.
|
||||
* \param block_size Size in bytes of allocation block. Must be a power of 2.
|
||||
* \param oflow_policy Queue behavior policy in case of overflow.
|
||||
* \param perms Access permissions for the associated message queue.
|
||||
*/
|
||||
reliable_message_queue
|
||||
(
|
||||
open_mode::open_or_create_tag,
|
||||
object_name const& name,
|
||||
uint32_t capacity,
|
||||
size_type block_size,
|
||||
overflow_policy oflow_policy = block_on_overflow,
|
||||
permissions const& perms = permissions()
|
||||
) :
|
||||
m_impl(NULL)
|
||||
{
|
||||
this->open_or_create(name, capacity, block_size, oflow_policy, perms);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Constructor. The method is used to construct an object and open the existing
|
||||
* message queue. The constructed object will be in running state if the message queue is
|
||||
* successfully opened.
|
||||
*
|
||||
* \post <tt>is_open() == true</tt>
|
||||
*
|
||||
* \param name Name of the message queue to be associated with.
|
||||
* \param oflow_policy Queue behavior policy in case of overflow.
|
||||
* \param perms Access permissions for the associated message queue. The permissions will only be used
|
||||
* if the queue implementation has to create system objects while operating.
|
||||
* This parameter is currently not used on POSIX systems.
|
||||
*/
|
||||
reliable_message_queue
|
||||
(
|
||||
open_mode::open_only_tag,
|
||||
object_name const& name,
|
||||
overflow_policy oflow_policy = block_on_overflow,
|
||||
permissions const& perms = permissions()
|
||||
) :
|
||||
m_impl(NULL)
|
||||
{
|
||||
this->open(name, oflow_policy, perms);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Constructor with named parameters. The method is used to construct an object and create or open
|
||||
* the associated message queue. The constructed object will be in running state if the message queue is
|
||||
* successfully created.
|
||||
*
|
||||
* The following named parameters are accepted:
|
||||
*
|
||||
* * open_mode - One of the open mode tags: \c open_mode::create_only, \c open_mode::open_only or
|
||||
* \c open_mode::open_or_create.
|
||||
* * name - Name of the message queue to be associated with.
|
||||
* * capacity - Maximum number of allocation blocks the queue can hold. Used only if the queue is created.
|
||||
* * block_size - Size in bytes of allocation block. Must be a power of 2. Used only if the queue is created.
|
||||
* * overflow_policy - Queue behavior policy in case of overflow, see \c overflow_policy.
|
||||
* * permissions - Access permissions for the associated message queue.
|
||||
*
|
||||
* \post <tt>is_open() == true</tt>
|
||||
*/
|
||||
#if !defined(BOOST_LOG_DOXYGEN_PASS)
|
||||
BOOST_LOG_PARAMETRIZED_CONSTRUCTORS_CALL(reliable_message_queue, construct)
|
||||
#else
|
||||
template< typename... Args >
|
||||
explicit reliable_message_queue(Args const&... args);
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Destructor. Calls <tt>close()</tt>.
|
||||
*/
|
||||
~reliable_message_queue() BOOST_NOEXCEPT
|
||||
{
|
||||
this->close();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Move constructor. The method move-constructs an object from \c other. After
|
||||
* the call, the constructed object becomes \c other, while \c other is left in
|
||||
* default constructed state.
|
||||
*
|
||||
* \param that The object to be moved.
|
||||
*/
|
||||
reliable_message_queue(BOOST_RV_REF(reliable_message_queue) that) BOOST_NOEXCEPT :
|
||||
m_impl(that.m_impl)
|
||||
{
|
||||
that.m_impl = NULL;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Move assignment operator. If the object is associated with a message queue,
|
||||
* <tt>close()</tt> is first called and the precondition to calling <tt>close()</tt>
|
||||
* applies. After the call, the object becomes \a that while \a that is left
|
||||
* in default constructed state.
|
||||
*
|
||||
* \param that The object to be moved.
|
||||
*
|
||||
* \return A reference to the assigned object.
|
||||
*/
|
||||
reliable_message_queue& operator= (BOOST_RV_REF(reliable_message_queue) that) BOOST_NOEXCEPT
|
||||
{
|
||||
reliable_message_queue other(static_cast< BOOST_RV_REF(reliable_message_queue) >(that));
|
||||
this->swap(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method swaps the object with \a that.
|
||||
*
|
||||
* \param that The other object to swap with.
|
||||
*/
|
||||
void swap(reliable_message_queue& that) BOOST_NOEXCEPT
|
||||
{
|
||||
implementation* p = m_impl;
|
||||
m_impl = that.m_impl;
|
||||
that.m_impl = p;
|
||||
}
|
||||
|
||||
//! Swaps the two \c reliable_message_queue objects.
|
||||
friend void swap(reliable_message_queue& a, reliable_message_queue& b) BOOST_NOEXCEPT
|
||||
{
|
||||
a.swap(b);
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method creates the message queue to be associated with the object. After the call,
|
||||
* the object will be in running state if a message queue is successfully created.
|
||||
*
|
||||
* \pre <tt>is_open() == false</tt>
|
||||
* \post <tt>is_open() == true</tt>
|
||||
*
|
||||
* \param name Name of the message queue to be associated with.
|
||||
* \param capacity Maximum number of allocation blocks the queue can hold.
|
||||
* \param block_size Size in bytes of allocation block. Must be a power of 2.
|
||||
* \param oflow_policy Queue behavior policy in case of overflow.
|
||||
* \param perms Access permissions for the associated message queue.
|
||||
*/
|
||||
BOOST_LOG_API void create
|
||||
(
|
||||
object_name const& name,
|
||||
uint32_t capacity,
|
||||
size_type block_size,
|
||||
overflow_policy oflow_policy = block_on_overflow,
|
||||
permissions const& perms = permissions()
|
||||
);
|
||||
|
||||
/*!
|
||||
* The method creates or opens the message queue to be associated with the object.
|
||||
* After the call, the object will be in running state if a message queue is successfully
|
||||
* created or opened. If the message queue that is identified by the name already exists then
|
||||
* the other queue parameters are ignored. The actual queue parameters can be obtained
|
||||
* with accessors from this object after this method returns.
|
||||
*
|
||||
* \pre <tt>is_open() == false</tt>
|
||||
* \post <tt>is_open() == true</tt>
|
||||
*
|
||||
* \param name Name of the message queue to be associated with.
|
||||
* \param capacity Maximum number of allocation blocks the queue can hold.
|
||||
* \param block_size Size in bytes of allocation block. Must be a power of 2.
|
||||
* \param oflow_policy Queue behavior policy in case of overflow.
|
||||
* \param perms Access permissions for the associated message queue.
|
||||
*/
|
||||
BOOST_LOG_API void open_or_create
|
||||
(
|
||||
object_name const& name,
|
||||
uint32_t capacity,
|
||||
size_type block_size,
|
||||
overflow_policy oflow_policy = block_on_overflow,
|
||||
permissions const& perms = permissions()
|
||||
);
|
||||
|
||||
/*!
|
||||
* The method opens the existing message queue to be associated with the object.
|
||||
* After the call, the object will be in running state if a message queue is successfully
|
||||
* opened.
|
||||
*
|
||||
* \pre <tt>is_open() == false</tt>
|
||||
* \post <tt>is_open() == true</tt>
|
||||
*
|
||||
* \param name Name of the message queue to be associated with.
|
||||
* \param oflow_policy Queue behavior policy in case of overflow.
|
||||
* \param perms Access permissions for the associated message queue. The permissions will only be used
|
||||
* if the queue implementation has to create system objects while operating.
|
||||
* This parameter is currently not used on POSIX systems.
|
||||
*/
|
||||
BOOST_LOG_API void open
|
||||
(
|
||||
object_name const& name,
|
||||
overflow_policy oflow_policy = block_on_overflow,
|
||||
permissions const& perms = permissions()
|
||||
);
|
||||
|
||||
/*!
|
||||
* Tests whether the object is associated with any message queue.
|
||||
*
|
||||
* \return \c true if the object is associated with a message queue, and \c false otherwise.
|
||||
*/
|
||||
bool is_open() const BOOST_NOEXCEPT
|
||||
{
|
||||
return m_impl != NULL;
|
||||
}
|
||||
|
||||
/*!
|
||||
* This method empties the associated message queue. Concurrent calls to this method, <tt>send()</tt>,
|
||||
* <tt>try_send()</tt>, <tt>receive()</tt>, <tt>try_receive()</tt>, and <tt>stop_local()</tt> are allowed.
|
||||
*
|
||||
* \pre <tt>is_open() == true</tt>
|
||||
*/
|
||||
BOOST_LOG_API void clear();
|
||||
|
||||
/*!
|
||||
* The method returns the name of the associated message queue.
|
||||
*
|
||||
* \pre <tt>is_open() == true</tt>
|
||||
*
|
||||
* \return Name of the associated message queue
|
||||
*/
|
||||
BOOST_LOG_API object_name const& name() const;
|
||||
|
||||
/*!
|
||||
* The method returns the maximum number of allocation blocks the associated message queue
|
||||
* can hold. Note that the returned value may be different from the corresponding
|
||||
* value passed to the constructor or <tt>open_or_create()</tt>, for the message queue may
|
||||
* not have been created by this object.
|
||||
*
|
||||
* \pre <tt>is_open() == true</tt>
|
||||
*
|
||||
* \return Maximum number of allocation blocks the associated message queue can hold.
|
||||
*/
|
||||
BOOST_LOG_API uint32_t capacity() const;
|
||||
|
||||
/*!
|
||||
* The method returns the allocation block size, in bytes. Each message in the
|
||||
* associated message queue consumes an integer number of allocation blocks.
|
||||
* Note that the returned value may be different from the corresponding value passed
|
||||
* to the constructor or <tt>open_or_create()</tt>, for the message queue may not
|
||||
* have been created by this object.
|
||||
*
|
||||
* \pre <tt>is_open() == true</tt>
|
||||
*
|
||||
* \return Allocation block size, in bytes.
|
||||
*/
|
||||
BOOST_LOG_API size_type block_size() const;
|
||||
|
||||
/*!
|
||||
* The method wakes up all threads that are blocked in calls to <tt>send()</tt> or
|
||||
* <tt>receive()</tt>. Those calls would then return \c false with \c errno \c EINTR.
|
||||
* Note that, the method does not block until the woken-up threads have actually
|
||||
* returned from <tt>send()</tt> or <tt>receive()</tt>. Other means is needed to ensure
|
||||
* that calls to <tt>send()</tt> or <tt>receive()</tt> have returned, e.g., joining the
|
||||
* threads that might be blocking on the calls.
|
||||
*
|
||||
* The method also puts the object in stopped state. When in stopped state, calls to
|
||||
* <tt>send()</tt> or <tt>receive()</tt> will return immediately with return value
|
||||
* \c false and \c errno \c EINTR when they would otherwise block in running state.
|
||||
*
|
||||
* Concurrent calls to this method, <tt>send()</tt>, <tt>try_send()</tt>, <tt>receive()</tt>,
|
||||
* <tt>try_receive()</tt>, and <tt>clear()</tt> are allowed.
|
||||
*
|
||||
* \pre <tt>is_open() == true</tt>
|
||||
*/
|
||||
BOOST_LOG_API void stop_local();
|
||||
|
||||
/*!
|
||||
* The method puts the object in running state where calls to <tt>send()</tt> or
|
||||
* <tt>receive()</tt> may block. This method is not thread-safe.
|
||||
*
|
||||
* \pre <tt>is_open() == true</tt>
|
||||
*/
|
||||
BOOST_LOG_API void reset_local();
|
||||
|
||||
/*!
|
||||
* The method disassociates the associated message queue, if any. No other threads
|
||||
* should be using this object before calling this method. The <tt>stop_local()</tt> method
|
||||
* can be used to have any threads currently blocked in <tt>send()</tt> or
|
||||
* <tt>receive()</tt> return, and prevent further calls to them from blocking. Typically,
|
||||
* before calling this method, one would first call <tt>stop_local()</tt> and then join all
|
||||
* threads that might be blocking on <tt>send()</tt> or <tt>receive()</tt> to ensure that
|
||||
* they have returned from the calls. The associated message queue is destroyed if the
|
||||
* object represents the last outstanding reference to it.
|
||||
*
|
||||
* \post <tt>is_open() == false</tt>
|
||||
*/
|
||||
void close() BOOST_NOEXCEPT
|
||||
{
|
||||
if (is_open())
|
||||
do_close();
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method sends a message to the associated message queue. When the object is in
|
||||
* running state and the queue has no free space for the message, the method either blocks
|
||||
* or throws an exception, depending on the overflow policy that was specified on the queue
|
||||
* opening/creation. If blocking policy is in effect, the blocking can be interrupted by
|
||||
* calling <tt>stop_local()</tt>, in which case the method returns \c operation_result::aborted.
|
||||
* When the object is already in the stopped state, the method does not block but returns
|
||||
* immediately with return value \c operation_result::aborted.
|
||||
*
|
||||
* It is possible to send an empty message by passing \c 0 to the parameter \c message_size.
|
||||
*
|
||||
* Concurrent calls to <tt>send()</tt>, <tt>try_send()</tt>, <tt>receive()</tt>, <tt>try_receive()</tt>,
|
||||
* <tt>stop_local()</tt>, and <tt>clear()</tt> are allowed.
|
||||
*
|
||||
* \pre <tt>is_open() == true</tt>
|
||||
*
|
||||
* \param message_data The message data to send. Ignored when \c message_size is \c 0.
|
||||
* \param message_size Size of the message data in bytes. If the size is larger than
|
||||
* the associated message queue capacity, an <tt>std::logic_error</tt> exception is thrown.
|
||||
*
|
||||
* \retval operation_result::succeeded if the operation is successful
|
||||
* \retval operation_result::no_space if \c overflow_policy::fail_on_overflow is in effect and the queue is full
|
||||
* \retval operation_result::aborted if the call was interrupted by <tt>stop_local()</tt>
|
||||
*
|
||||
* <b>Throws:</b> <tt>std::logic_error</tt> in case if the message size exceeds the queue
|
||||
* capacity, <tt>system_error</tt> in case if a native OS method fails.
|
||||
*/
|
||||
BOOST_LOG_API operation_result send(void const* message_data, size_type message_size);
|
||||
|
||||
/*!
|
||||
* The method performs an attempt to send a message to the associated message queue.
|
||||
* The method is non-blocking, and always returns immediately.
|
||||
* <tt>boost::system::system_error</tt> is thrown for errors resulting from native
|
||||
* operating system calls. Note that it is possible to send an empty message by passing
|
||||
* \c 0 to the parameter \c message_size. Concurrent calls to <tt>send()</tt>,
|
||||
* <tt>try_send()</tt>, <tt>receive()</tt>, <tt>try_receive()</tt>, <tt>stop_local()</tt>,
|
||||
* and <tt>clear()</tt> are allowed.
|
||||
*
|
||||
* \pre <tt>is_open() == true</tt>
|
||||
*
|
||||
* \param message_data The message data to send. Ignored when \c message_size is \c 0.
|
||||
* \param message_size Size of the message data in bytes. If the size is larger than the
|
||||
* maximum size allowed by the associated message queue, an
|
||||
* <tt>std::logic_error</tt> exception is thrown.
|
||||
*
|
||||
* \return \c true if the message is successfully sent, and \c false otherwise (e.g.,
|
||||
* when the queue is full).
|
||||
*
|
||||
* <b>Throws:</b> <tt>std::logic_error</tt> in case if the message size exceeds the queue
|
||||
* capacity, <tt>system_error</tt> in case if a native OS method fails.
|
||||
*/
|
||||
BOOST_LOG_API bool try_send(void const* message_data, size_type message_size);
|
||||
|
||||
/*!
|
||||
* The method takes a message from the associated message queue. When the object is in
|
||||
* running state and the queue is empty, the method blocks. The blocking is interrupted
|
||||
* when <tt>stop_local()</tt> is called, in which case the method returns \c operation_result::aborted.
|
||||
* When the object is already in the stopped state and the queue is empty, the method
|
||||
* does not block but returns immediately with return value \c operation_result::aborted.
|
||||
*
|
||||
* Concurrent calls to <tt>send()</tt>, <tt>try_send()</tt>, <tt>receive()</tt>,
|
||||
* <tt>try_receive()</tt>, <tt>stop_local()</tt>, and <tt>clear()</tt> are allowed.
|
||||
*
|
||||
* \pre <tt>is_open() == true</tt>
|
||||
*
|
||||
* \param buffer The memory buffer to store the received message in.
|
||||
* \param buffer_size The size of the buffer, in bytes.
|
||||
* \param message_size Receives the size of the received message, in bytes.
|
||||
*
|
||||
* \retval operation_result::succeeded if the operation is successful
|
||||
* \retval operation_result::aborted if the call was interrupted by <tt>stop_local()</tt>
|
||||
*/
|
||||
operation_result receive(void* buffer, size_type buffer_size, size_type& message_size)
|
||||
{
|
||||
fixed_buffer_state state = { static_cast< uint8_t* >(buffer), buffer_size };
|
||||
operation_result result = do_receive(&reliable_message_queue::fixed_buffer_receive_handler, &state);
|
||||
message_size = buffer_size - state.size;
|
||||
return result;
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method takes a message from the associated message queue. When the object is in
|
||||
* running state and the queue is empty, the method blocks. The blocking is interrupted
|
||||
* when <tt>stop_local()</tt> is called, in which case the method returns \c operation_result::aborted.
|
||||
* When the object is already in the stopped state and the queue is empty, the method
|
||||
* does not block but returns immediately with return value \c operation_result::aborted.
|
||||
*
|
||||
* Concurrent calls to <tt>send()</tt>, <tt>try_send()</tt>, <tt>receive()</tt>,
|
||||
* <tt>try_receive()</tt>, <tt>stop_local()</tt>, and <tt>clear()</tt> are allowed.
|
||||
*
|
||||
* \pre <tt>is_open() == true</tt>
|
||||
*
|
||||
* \param buffer The memory buffer to store the received message in.
|
||||
* \param message_size Receives the size of the received message, in bytes.
|
||||
*
|
||||
* \retval operation_result::succeeded if the operation is successful
|
||||
* \retval operation_result::aborted if the call was interrupted by <tt>stop_local()</tt>
|
||||
*/
|
||||
template< typename ElementT, size_type SizeV >
|
||||
#if !defined(BOOST_LOG_DOXYGEN_PASS)
|
||||
typename aux::enable_if_byte< ElementT, operation_result >::type
|
||||
#else
|
||||
operation_result
|
||||
#endif
|
||||
receive(ElementT (&buffer)[SizeV], size_type& message_size)
|
||||
{
|
||||
return receive(buffer, SizeV, message_size);
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method takes a message from the associated message queue. When the object is in
|
||||
* running state and the queue is empty, the method blocks. The blocking is interrupted
|
||||
* when <tt>stop_local()</tt> is called, in which case the method returns \c operation_result::aborted.
|
||||
* When the object is already in the stopped state and the queue is empty, the method
|
||||
* does not block but returns immediately with return value \c operation_result::aborted.
|
||||
*
|
||||
* Concurrent calls to <tt>send()</tt>, <tt>try_send()</tt>, <tt>receive()</tt>,
|
||||
* <tt>try_receive()</tt>, <tt>stop_local()</tt>, and <tt>clear()</tt> are allowed.
|
||||
*
|
||||
* \pre <tt>is_open() == true</tt>
|
||||
*
|
||||
* \param container The container to store the received message in. The container should have
|
||||
* value type of <tt>char</tt>, <tt>signed char</tt> or <tt>unsigned char</tt>
|
||||
* and support inserting elements at the end.
|
||||
*
|
||||
* \retval operation_result::succeeded if the operation is successful
|
||||
* \retval operation_result::aborted if the call was interrupted by <tt>stop_local()</tt>
|
||||
*/
|
||||
template< typename ContainerT >
|
||||
#if !defined(BOOST_LOG_DOXYGEN_PASS)
|
||||
typename aux::enable_if_byte< typename ContainerT::value_type, operation_result >::type
|
||||
#else
|
||||
operation_result
|
||||
#endif
|
||||
receive(ContainerT& container)
|
||||
{
|
||||
return do_receive(&reliable_message_queue::container_receive_handler< ContainerT >, &container);
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method performs an attempt to take a message from the associated message queue. The
|
||||
* method is non-blocking, and always returns immediately.
|
||||
*
|
||||
* Concurrent calls to <tt>send()</tt>, <tt>try_send()</tt>, <tt>receive()</tt>,
|
||||
* <tt>try_receive()</tt>, <tt>stop_local()</tt>, and <tt>clear()</tt> are allowed.
|
||||
*
|
||||
* \pre <tt>is_open() == true</tt>
|
||||
*
|
||||
* \param buffer The memory buffer to store the received message in.
|
||||
* \param buffer_size The size of the buffer, in bytes.
|
||||
* \param message_size Receives the size of the received message, in bytes.
|
||||
*
|
||||
* \return \c true if a message is successfully received, and \c false otherwise (e.g.,
|
||||
* when the queue is empty).
|
||||
*/
|
||||
bool try_receive(void* buffer, size_type buffer_size, size_type& message_size)
|
||||
{
|
||||
fixed_buffer_state state = { static_cast< uint8_t* >(buffer), buffer_size };
|
||||
bool result = do_try_receive(&reliable_message_queue::fixed_buffer_receive_handler, &state);
|
||||
message_size = buffer_size - state.size;
|
||||
return result;
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method performs an attempt to take a message from the associated message queue. The
|
||||
* method is non-blocking, and always returns immediately.
|
||||
*
|
||||
* Concurrent calls to <tt>send()</tt>, <tt>try_send()</tt>, <tt>receive()</tt>,
|
||||
* <tt>try_receive()</tt>, <tt>stop_local()</tt>, and <tt>clear()</tt> are allowed.
|
||||
*
|
||||
* \pre <tt>is_open() == true</tt>
|
||||
*
|
||||
* \param buffer The memory buffer to store the received message in.
|
||||
* \param message_size Receives the size of the received message, in bytes.
|
||||
*
|
||||
* \return \c true if a message is successfully received, and \c false otherwise (e.g.,
|
||||
* when the queue is empty).
|
||||
*/
|
||||
template< typename ElementT, size_type SizeV >
|
||||
#if !defined(BOOST_LOG_DOXYGEN_PASS)
|
||||
typename aux::enable_if_byte< ElementT, bool >::type
|
||||
#else
|
||||
bool
|
||||
#endif
|
||||
try_receive(ElementT (&buffer)[SizeV], size_type& message_size)
|
||||
{
|
||||
return try_receive(buffer, SizeV, message_size);
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method performs an attempt to take a message from the associated message queue. The
|
||||
* method is non-blocking, and always returns immediately.
|
||||
*
|
||||
* Concurrent calls to <tt>send()</tt>, <tt>try_send()</tt>, <tt>receive()</tt>,
|
||||
* <tt>try_receive()</tt>, <tt>stop_local()</tt>, and <tt>clear()</tt> are allowed.
|
||||
*
|
||||
* \pre <tt>is_open() == true</tt>
|
||||
*
|
||||
* \param container The container to store the received message in. The container should have
|
||||
* value type of <tt>char</tt>, <tt>signed char</tt> or <tt>unsigned char</tt>
|
||||
* and support inserting elements at the end.
|
||||
*
|
||||
* \return \c true if a message is successfully received, and \c false otherwise (e.g.,
|
||||
* when the queue is empty).
|
||||
*/
|
||||
template< typename ContainerT >
|
||||
#if !defined(BOOST_LOG_DOXYGEN_PASS)
|
||||
typename aux::enable_if_byte< typename ContainerT::value_type, bool >::type
|
||||
#else
|
||||
bool
|
||||
#endif
|
||||
try_receive(ContainerT& container)
|
||||
{
|
||||
return do_try_receive(&reliable_message_queue::container_receive_handler< ContainerT >, &container);
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method frees system-wide resources, associated with the interprocess queue with the supplied name.
|
||||
* The queue referred to by the specified name must not be opened in any process at the point of this call.
|
||||
* After this call succeeds a new queue with the specified name can be created.
|
||||
*
|
||||
* This call can be useful to recover from an earlier process misbehavior (e.g. a crash without properly
|
||||
* closing the message queue). In this case resources allocated for the interprocess queue may remain
|
||||
* allocated after the last process closed the queue, which in turn may prevent creating a new queue with
|
||||
* the same name. By calling this method before creating a queue the application can attempt to ensure
|
||||
* it starts with a clean slate.
|
||||
*
|
||||
* On some platforms resources associated with the queue are automatically reclaimed by the operating system
|
||||
* when the last process using those resources terminates (even if it terminates abnormally). On these
|
||||
* platforms this call may be a no-op. However, portable code should still call this method at appropriate
|
||||
* places to ensure compatibility with other platforms and future library versions, which may change implementation
|
||||
* of the queue.
|
||||
*
|
||||
* \param name Name of the message queue to be removed.
|
||||
*/
|
||||
static BOOST_LOG_API void remove(object_name const& name);
|
||||
|
||||
#if !defined(BOOST_LOG_DOXYGEN_PASS)
|
||||
private:
|
||||
//! Implementation of the constructor with named arguments
|
||||
template< typename ArgsT >
|
||||
void construct(ArgsT const& args)
|
||||
{
|
||||
m_impl = NULL;
|
||||
construct_dispatch(args[keywords::open_mode], args);
|
||||
}
|
||||
|
||||
//! Implementation of the constructor with named arguments
|
||||
template< typename ArgsT >
|
||||
void construct_dispatch(open_mode::create_only_tag, ArgsT const& args)
|
||||
{
|
||||
this->create(args[keywords::name], args[keywords::capacity], args[keywords::block_size], args[keywords::overflow_policy | block_on_overflow], args[keywords::permissions | permissions()]);
|
||||
}
|
||||
|
||||
//! Implementation of the constructor with named arguments
|
||||
template< typename ArgsT >
|
||||
void construct_dispatch(open_mode::open_or_create_tag, ArgsT const& args)
|
||||
{
|
||||
this->open_or_create(args[keywords::name], args[keywords::capacity], args[keywords::block_size], args[keywords::overflow_policy | block_on_overflow], args[keywords::permissions | permissions()]);
|
||||
}
|
||||
|
||||
//! Implementation of the constructor with named arguments
|
||||
template< typename ArgsT >
|
||||
void construct_dispatch(open_mode::open_only_tag, ArgsT const& args)
|
||||
{
|
||||
this->open(args[keywords::name], args[keywords::overflow_policy | block_on_overflow], args[keywords::permissions | permissions()]);
|
||||
}
|
||||
|
||||
//! Closes the message queue, if it's open
|
||||
BOOST_LOG_API void do_close() BOOST_NOEXCEPT;
|
||||
|
||||
//! Receives the message from the queue and calls the handler to place the data in the user's storage
|
||||
BOOST_LOG_API operation_result do_receive(receive_handler handler, void* state);
|
||||
//! Attempts to receives the message from the queue and calls the handler to place the data in the user's storage
|
||||
BOOST_LOG_API bool do_try_receive(receive_handler handler, void* state);
|
||||
|
||||
//! Fixed buffer receive handler
|
||||
static BOOST_LOG_API void fixed_buffer_receive_handler(void* state, const void* data, size_type size);
|
||||
//! Receive handler for a container
|
||||
template< typename ContainerT >
|
||||
static void container_receive_handler(void* state, const void* data, size_type size)
|
||||
{
|
||||
ContainerT* const container = static_cast< ContainerT* >(state);
|
||||
container->insert
|
||||
(
|
||||
container->end(),
|
||||
static_cast< typename ContainerT::value_type const* >(data),
|
||||
static_cast< typename ContainerT::value_type const* >(data) + size
|
||||
);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace ipc
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_UTILITY_IPC_RELIABLE_MESSAGE_QUEUE_HPP_INCLUDED_
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright Andrey Semashev 2007 - 2015.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
/*!
|
||||
* \file manipulators.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 06.11.2012
|
||||
*
|
||||
* This header includes all manipulators.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_UTILITY_MANIPULATORS_HPP_INCLUDED_
|
||||
#define BOOST_LOG_UTILITY_MANIPULATORS_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
|
||||
#include <boost/log/utility/manipulators/add_value.hpp>
|
||||
#include <boost/log/utility/manipulators/to_log.hpp>
|
||||
#include <boost/log/utility/manipulators/dump.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#endif // BOOST_LOG_UTILITY_MANIPULATORS_HPP_INCLUDED_
|
||||
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* 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 add_value.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 26.11.2012
|
||||
*
|
||||
* This header contains the \c add_value manipulator.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_UTILITY_MANIPULATORS_ADD_VALUE_HPP_INCLUDED_
|
||||
#define BOOST_LOG_UTILITY_MANIPULATORS_ADD_VALUE_HPP_INCLUDED_
|
||||
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/type_traits/is_scalar.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/embedded_string_type.hpp>
|
||||
#include <boost/log/attributes/attribute_name.hpp>
|
||||
#include <boost/log/attributes/attribute_value_impl.hpp>
|
||||
#include <boost/log/expressions/keyword_fwd.hpp>
|
||||
#include <boost/log/sources/record_ostream.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
// 'boost::log::v2s_mt_nt6::add_value_manip<RefT>::m_value' : reference member is initialized to a temporary that doesn't persist after the constructor exits
|
||||
// This is intentional since the manipulator can be used with a temporary, which will be used before the streaming expression ends and it is destroyed.
|
||||
#pragma warning(disable: 4413)
|
||||
// returning address of local variable or temporary
|
||||
// This warning refers to add_value_manip<RefT>::get_value() when RefT is an rvalue reference. We store the reference in the manipulator and we intend to return it as is.
|
||||
#pragma warning(disable: 4172)
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
//! Attribute value manipulator
|
||||
template< typename RefT >
|
||||
class add_value_manip
|
||||
{
|
||||
public:
|
||||
//! Stored reference type
|
||||
typedef RefT reference_type;
|
||||
//! Attribute value type
|
||||
typedef typename remove_cv< typename remove_reference< reference_type >::type >::type value_type;
|
||||
|
||||
private:
|
||||
// The stored reference type is an lvalue reference since apparently different compilers (GCC and MSVC) have different quirks when rvalue references are stored as members.
|
||||
// Additionally, MSVC (at least 11.0) has a bug which causes a dangling reference to be stored in the manipulator, if a scalar rvalue is passed to the add_value generator.
|
||||
// To work around this problem we save the value inside the manipulator in this case.
|
||||
typedef typename remove_reference< reference_type >::type& lvalue_reference_type;
|
||||
|
||||
typedef typename mpl::if_<
|
||||
is_scalar< value_type >,
|
||||
value_type,
|
||||
lvalue_reference_type
|
||||
>::type stored_type;
|
||||
|
||||
typedef typename mpl::if_<
|
||||
is_scalar< value_type >,
|
||||
value_type,
|
||||
reference_type
|
||||
>::type get_value_result_type;
|
||||
|
||||
private:
|
||||
//! Attribute value
|
||||
stored_type m_value;
|
||||
//! Attribute name
|
||||
attribute_name m_name;
|
||||
|
||||
public:
|
||||
//! Initializing constructor
|
||||
add_value_manip(attribute_name const& name, reference_type value) : m_value(static_cast< lvalue_reference_type >(value)), m_name(name)
|
||||
{
|
||||
}
|
||||
|
||||
//! Returns attribute name
|
||||
attribute_name get_name() const { return m_name; }
|
||||
//! Returns attribute value
|
||||
get_value_result_type get_value() const { return static_cast< get_value_result_type >(m_value); }
|
||||
};
|
||||
|
||||
//! The operator attaches an attribute value to the log record
|
||||
template< typename CharT, typename RefT >
|
||||
inline basic_record_ostream< CharT >& operator<< (basic_record_ostream< CharT >& strm, add_value_manip< RefT > const& manip)
|
||||
{
|
||||
typedef typename aux::make_embedded_string_type< typename add_value_manip< RefT >::value_type >::type value_type;
|
||||
attribute_value value(new attributes::attribute_value_impl< value_type >(manip.get_value()));
|
||||
strm.get_record().attribute_values().insert(manip.get_name(), value);
|
||||
return strm;
|
||||
}
|
||||
|
||||
//! The function creates a manipulator that attaches an attribute value to a log record
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
|
||||
template< typename T >
|
||||
inline add_value_manip< T&& > add_value(attribute_name const& name, T&& value)
|
||||
{
|
||||
return add_value_manip< T&& >(name, static_cast< T&& >(value));
|
||||
}
|
||||
|
||||
//! \overload
|
||||
template< typename DescriptorT, template< typename > class ActorT >
|
||||
inline add_value_manip< typename DescriptorT::value_type&& >
|
||||
add_value(expressions::attribute_keyword< DescriptorT, ActorT > const&, typename DescriptorT::value_type&& value)
|
||||
{
|
||||
typedef typename DescriptorT::value_type value_type;
|
||||
return add_value_manip< value_type&& >(DescriptorT::get_name(), static_cast< value_type&& >(value));
|
||||
}
|
||||
|
||||
//! \overload
|
||||
template< typename DescriptorT, template< typename > class ActorT >
|
||||
inline add_value_manip< typename DescriptorT::value_type& >
|
||||
add_value(expressions::attribute_keyword< DescriptorT, ActorT > const&, typename DescriptorT::value_type& value)
|
||||
{
|
||||
return add_value_manip< typename DescriptorT::value_type& >(DescriptorT::get_name(), value);
|
||||
}
|
||||
|
||||
//! \overload
|
||||
template< typename DescriptorT, template< typename > class ActorT >
|
||||
inline add_value_manip< typename DescriptorT::value_type const& >
|
||||
add_value(expressions::attribute_keyword< DescriptorT, ActorT > const&, typename DescriptorT::value_type const& value)
|
||||
{
|
||||
return add_value_manip< typename DescriptorT::value_type const& >(DescriptorT::get_name(), value);
|
||||
}
|
||||
|
||||
#else // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
|
||||
template< typename T >
|
||||
inline add_value_manip< T const& > add_value(attribute_name const& name, T const& value)
|
||||
{
|
||||
return add_value_manip< T const& >(name, value);
|
||||
}
|
||||
|
||||
template< typename DescriptorT, template< typename > class ActorT >
|
||||
inline add_value_manip< typename DescriptorT::value_type const& >
|
||||
add_value(expressions::attribute_keyword< DescriptorT, ActorT > const&, typename DescriptorT::value_type const& value)
|
||||
{
|
||||
return add_value_manip< typename DescriptorT::value_type const& >(DescriptorT::get_name(), value);
|
||||
}
|
||||
|
||||
#endif // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_UTILITY_MANIPULATORS_ADD_VALUE_HPP_INCLUDED_
|
||||
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
* 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 dump.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 03.05.2013
|
||||
*
|
||||
* This header contains the \c dump output manipulator.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_UTILITY_MANIPULATORS_DUMP_HPP_INCLUDED_
|
||||
#define BOOST_LOG_UTILITY_MANIPULATORS_DUMP_HPP_INCLUDED_
|
||||
|
||||
#include <cstddef>
|
||||
#include <iosfwd>
|
||||
#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 {
|
||||
|
||||
typedef void dump_data_char_t(const void* data, std::size_t size, std::basic_ostream< char >& strm);
|
||||
extern BOOST_LOG_API dump_data_char_t* dump_data_char;
|
||||
BOOST_FORCEINLINE void dump_data(const void* data, std::size_t size, std::basic_ostream< char >& strm)
|
||||
{
|
||||
(dump_data_char)(data, size, strm);
|
||||
}
|
||||
|
||||
typedef void dump_data_wchar_t(const void* data, std::size_t size, std::basic_ostream< wchar_t >& strm);
|
||||
extern BOOST_LOG_API dump_data_wchar_t* dump_data_wchar;
|
||||
BOOST_FORCEINLINE void dump_data(const void* data, std::size_t size, std::basic_ostream< wchar_t >& strm)
|
||||
{
|
||||
(dump_data_wchar)(data, size, strm);
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_CHAR16_T)
|
||||
typedef void dump_data_char16_t(const void* data, std::size_t size, std::basic_ostream< char16_t >& strm);
|
||||
extern BOOST_LOG_API dump_data_char16_t* dump_data_char16;
|
||||
BOOST_FORCEINLINE void dump_data(const void* data, std::size_t size, std::basic_ostream< char16_t >& strm)
|
||||
{
|
||||
(dump_data_char16)(data, size, strm);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_CHAR32_T)
|
||||
typedef void dump_data_char32_t(const void* data, std::size_t size, std::basic_ostream< char32_t >& strm);
|
||||
extern BOOST_LOG_API dump_data_char32_t* dump_data_char32;
|
||||
BOOST_FORCEINLINE void dump_data(const void* data, std::size_t size, std::basic_ostream< char32_t >& strm)
|
||||
{
|
||||
(dump_data_char32)(data, size, strm);
|
||||
}
|
||||
#endif
|
||||
|
||||
template< std::size_t SizeV, typename R >
|
||||
struct enable_dump_size_based
|
||||
{
|
||||
};
|
||||
|
||||
template< typename R >
|
||||
struct enable_dump_size_based< 1u, R >
|
||||
{
|
||||
typedef R type;
|
||||
};
|
||||
|
||||
template< typename T, typename R >
|
||||
struct enable_dump :
|
||||
public enable_dump_size_based< sizeof(T), R >
|
||||
{
|
||||
};
|
||||
|
||||
template< typename R >
|
||||
struct enable_dump< void, R >
|
||||
{
|
||||
typedef R type;
|
||||
};
|
||||
|
||||
template< typename R >
|
||||
struct enable_dump< const void, R >
|
||||
{
|
||||
typedef R type;
|
||||
};
|
||||
|
||||
template< typename R >
|
||||
struct enable_dump< volatile void, R >
|
||||
{
|
||||
typedef R type;
|
||||
};
|
||||
|
||||
template< typename R >
|
||||
struct enable_dump< const volatile void, R >
|
||||
{
|
||||
typedef R type;
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
/*!
|
||||
* \brief Manipulator for printing binary representation of the data
|
||||
*/
|
||||
class dump_manip
|
||||
{
|
||||
private:
|
||||
//! Beginning of the data
|
||||
const void* m_data;
|
||||
//! Size of the data, in bytes
|
||||
std::size_t m_size;
|
||||
|
||||
public:
|
||||
dump_manip(const void* data, std::size_t size) BOOST_NOEXCEPT : m_data(data), m_size(size) {}
|
||||
dump_manip(dump_manip const& that) BOOST_NOEXCEPT : m_data(that.m_data), m_size(that.m_size) {}
|
||||
|
||||
const void* get_data() const BOOST_NOEXCEPT { return m_data; }
|
||||
std::size_t get_size() const BOOST_NOEXCEPT { return m_size; }
|
||||
};
|
||||
|
||||
//! The operator outputs binary data to a stream
|
||||
template< typename CharT, typename TraitsT >
|
||||
inline std::basic_ostream< CharT, TraitsT >& operator<< (std::basic_ostream< CharT, TraitsT >& strm, dump_manip const& manip)
|
||||
{
|
||||
if (strm.good())
|
||||
aux::dump_data(manip.get_data(), manip.get_size(), strm);
|
||||
|
||||
return strm;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Manipulator for printing binary representation of the data with a size limit
|
||||
*/
|
||||
class bounded_dump_manip :
|
||||
public dump_manip
|
||||
{
|
||||
private:
|
||||
//! Maximum size to output, in bytes
|
||||
std::size_t m_max_size;
|
||||
|
||||
public:
|
||||
bounded_dump_manip(const void* data, std::size_t size, std::size_t max_size) BOOST_NOEXCEPT : dump_manip(data, size), m_max_size(max_size) {}
|
||||
bounded_dump_manip(bounded_dump_manip const& that) BOOST_NOEXCEPT : dump_manip(static_cast< dump_manip const& >(that)), m_max_size(that.m_max_size) {}
|
||||
|
||||
std::size_t get_max_size() const BOOST_NOEXCEPT { return m_max_size; }
|
||||
};
|
||||
|
||||
//! The operator outputs binary data to a stream
|
||||
template< typename CharT, typename TraitsT >
|
||||
inline std::basic_ostream< CharT, TraitsT >& operator<< (std::basic_ostream< CharT, TraitsT >& strm, bounded_dump_manip const& manip)
|
||||
{
|
||||
if (strm.good())
|
||||
{
|
||||
const std::size_t size = manip.get_size(), max_size = manip.get_max_size();
|
||||
if (max_size >= size)
|
||||
{
|
||||
aux::dump_data(manip.get_data(), size, strm);
|
||||
}
|
||||
else
|
||||
{
|
||||
aux::dump_data(manip.get_data(), max_size, strm);
|
||||
strm << " and " << (size - max_size) << " bytes more";
|
||||
}
|
||||
}
|
||||
|
||||
return strm;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Creates a stream manipulator that will output contents of a memory region in hexadecimal form
|
||||
* \param data The pointer to the beginning of the region
|
||||
* \param size The size of the region, in bytes
|
||||
* \return The manipulator that is to be put to a stream
|
||||
*/
|
||||
template< typename T >
|
||||
inline typename aux::enable_dump< T, dump_manip >::type dump(T* data, std::size_t size) BOOST_NOEXCEPT
|
||||
{
|
||||
return dump_manip((const void*)data, size);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Creates a stream manipulator that will dump elements of an array in hexadecimal form
|
||||
* \param data The pointer to the beginning of the array
|
||||
* \param count The size of the region, in number of \c T elements
|
||||
* \return The manipulator that is to be put to a stream
|
||||
*/
|
||||
template< typename T >
|
||||
inline dump_manip dump_elements(T* data, std::size_t count) BOOST_NOEXCEPT
|
||||
{
|
||||
return dump_manip((const void*)data, count * sizeof(T));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Creates a stream manipulator that will output contents of a memory region in hexadecimal form
|
||||
* \param data The pointer to the beginning of the region
|
||||
* \param size The size of the region, in bytes
|
||||
* \param max_size The maximum number of bytes of the region to output
|
||||
* \return The manipulator that is to be put to a stream
|
||||
*/
|
||||
template< typename T >
|
||||
inline typename aux::enable_dump< T, bounded_dump_manip >::type dump(T* data, std::size_t size, std::size_t max_size) BOOST_NOEXCEPT
|
||||
{
|
||||
return bounded_dump_manip((const void*)data, size, max_size);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Creates a stream manipulator that will dump elements of an array in hexadecimal form
|
||||
* \param data The pointer to the beginning of the array
|
||||
* \param count The size of the region, in number of \c T elements
|
||||
* \param max_count The maximum number of elements to output
|
||||
* \return The manipulator that is to be put to a stream
|
||||
*/
|
||||
template< typename T >
|
||||
inline bounded_dump_manip dump_elements(T* data, std::size_t count, std::size_t max_count) BOOST_NOEXCEPT
|
||||
{
|
||||
return bounded_dump_manip((const void*)data, count * sizeof(T), max_count * sizeof(T));
|
||||
}
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_UTILITY_MANIPULATORS_DUMP_HPP_INCLUDED_
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright Andrey Semashev 2007 - 2015.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
/*!
|
||||
* \file to_log.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 06.11.2012
|
||||
*
|
||||
* This header contains the \c to_log output manipulator.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_UTILITY_MANIPULATORS_TO_LOG_HPP_INCLUDED_
|
||||
#define BOOST_LOG_UTILITY_MANIPULATORS_TO_LOG_HPP_INCLUDED_
|
||||
|
||||
#include <iosfwd>
|
||||
#include <boost/core/enable_if.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/is_ostream.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
|
||||
|
||||
/*!
|
||||
* \brief Generic manipulator for customizing output to log
|
||||
*/
|
||||
template< typename T, typename TagT = void >
|
||||
class to_log_manip
|
||||
{
|
||||
public:
|
||||
//! Output value type
|
||||
typedef T value_type;
|
||||
//! Value tag type
|
||||
typedef TagT tag_type;
|
||||
|
||||
private:
|
||||
//! Reference to the value
|
||||
value_type const& m_value;
|
||||
|
||||
public:
|
||||
explicit to_log_manip(value_type const& value) BOOST_NOEXCEPT : m_value(value) {}
|
||||
to_log_manip(to_log_manip const& that) BOOST_NOEXCEPT : m_value(that.m_value) {}
|
||||
|
||||
value_type const& get() const BOOST_NOEXCEPT { return m_value; }
|
||||
};
|
||||
|
||||
template< typename StreamT, typename T, typename TagT >
|
||||
inline typename enable_if_c< log::aux::is_ostream< StreamT >::value, StreamT& >::type operator<< (StreamT& strm, to_log_manip< T, TagT > manip)
|
||||
{
|
||||
strm << manip.get();
|
||||
return strm;
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
inline to_log_manip< T > to_log(T const& value) BOOST_NOEXCEPT
|
||||
{
|
||||
return to_log_manip< T >(value);
|
||||
}
|
||||
|
||||
template< typename TagT, typename T >
|
||||
inline to_log_manip< T, TagT > to_log(T const& value) BOOST_NOEXCEPT
|
||||
{
|
||||
return to_log_manip< T, TagT >(value);
|
||||
}
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_UTILITY_MANIPULATORS_TO_LOG_HPP_INCLUDED_
|
||||
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* 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 once_block.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 23.06.2010
|
||||
*
|
||||
* \brief The header defines classes and macros for once-blocks.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_UTILITY_ONCE_BLOCK_HPP_INCLUDED_
|
||||
#define BOOST_LOG_UTILITY_ONCE_BLOCK_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/utility/unique_identifier_name.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_LOG_NO_THREADS
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
/*!
|
||||
* \brief A flag to detect if a code block has already been executed.
|
||||
*
|
||||
* This structure should be used in conjunction with the \c BOOST_LOG_ONCE_BLOCK_FLAG
|
||||
* macro. Usage example:
|
||||
*
|
||||
* <code>
|
||||
* once_block_flag flag = BOOST_LOG_ONCE_BLOCK_INIT;
|
||||
*
|
||||
* void foo()
|
||||
* {
|
||||
* BOOST_LOG_ONCE_BLOCK_FLAG(flag)
|
||||
* {
|
||||
* puts("Hello, world once!");
|
||||
* }
|
||||
* }
|
||||
* </code>
|
||||
*/
|
||||
struct once_block_flag
|
||||
{
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
// Do not use, implementation detail
|
||||
enum
|
||||
{
|
||||
uninitialized = 0, // this must be zero, so that zero-initialized once_block_flag is equivalent to the one initialized with uninitialized
|
||||
being_initialized,
|
||||
initialized
|
||||
};
|
||||
unsigned char status;
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
};
|
||||
|
||||
/*!
|
||||
* \def BOOST_LOG_ONCE_BLOCK_INIT
|
||||
*
|
||||
* The static initializer for \c once_block_flag.
|
||||
*/
|
||||
#define BOOST_LOG_ONCE_BLOCK_INIT { boost::log::once_block_flag::uninitialized }
|
||||
|
||||
namespace aux {
|
||||
|
||||
class once_block_sentry
|
||||
{
|
||||
private:
|
||||
once_block_flag& m_flag;
|
||||
|
||||
public:
|
||||
explicit once_block_sentry(once_block_flag& f) BOOST_NOEXCEPT : m_flag(f)
|
||||
{
|
||||
}
|
||||
|
||||
~once_block_sentry() BOOST_NOEXCEPT
|
||||
{
|
||||
if (BOOST_UNLIKELY(m_flag.status != once_block_flag::initialized))
|
||||
rollback();
|
||||
}
|
||||
|
||||
bool executed() const BOOST_NOEXCEPT
|
||||
{
|
||||
return (m_flag.status == once_block_flag::initialized || enter_once_block());
|
||||
}
|
||||
|
||||
BOOST_LOG_API void commit() BOOST_NOEXCEPT;
|
||||
|
||||
private:
|
||||
BOOST_LOG_API bool enter_once_block() const BOOST_NOEXCEPT;
|
||||
BOOST_LOG_API void rollback() BOOST_NOEXCEPT;
|
||||
|
||||
// Non-copyable, non-assignable
|
||||
BOOST_DELETED_FUNCTION(once_block_sentry(once_block_sentry const&))
|
||||
BOOST_DELETED_FUNCTION(once_block_sentry& operator= (once_block_sentry const&))
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#else // BOOST_LOG_NO_THREADS
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
struct once_block_flag
|
||||
{
|
||||
bool status;
|
||||
};
|
||||
|
||||
#define BOOST_LOG_ONCE_BLOCK_INIT { false }
|
||||
|
||||
namespace aux {
|
||||
|
||||
class once_block_sentry
|
||||
{
|
||||
private:
|
||||
once_block_flag& m_flag;
|
||||
|
||||
public:
|
||||
explicit once_block_sentry(once_block_flag& f) BOOST_NOEXCEPT : m_flag(f)
|
||||
{
|
||||
}
|
||||
|
||||
bool executed() const BOOST_NOEXCEPT
|
||||
{
|
||||
return m_flag.status;
|
||||
}
|
||||
|
||||
void commit() BOOST_NOEXCEPT
|
||||
{
|
||||
m_flag.status = true;
|
||||
}
|
||||
|
||||
// Non-copyable, non-assignable
|
||||
BOOST_DELETED_FUNCTION(once_block_sentry(once_block_sentry const&))
|
||||
BOOST_DELETED_FUNCTION(once_block_sentry& operator= (once_block_sentry const&))
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_LOG_NO_THREADS
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
#define BOOST_LOG_ONCE_BLOCK_FLAG_INTERNAL(flag_var, sentry_var)\
|
||||
for (boost::log::aux::once_block_sentry sentry_var((flag_var));\
|
||||
BOOST_UNLIKELY(!sentry_var.executed()); sentry_var.commit())
|
||||
|
||||
// NOTE: flag_var deliberately doesn't have an initializer so that it is zero-initialized at the static initialization stage
|
||||
#define BOOST_LOG_ONCE_BLOCK_INTERNAL(flag_var, sentry_var)\
|
||||
static boost::log::once_block_flag flag_var;\
|
||||
BOOST_LOG_ONCE_BLOCK_FLAG_INTERNAL(flag_var, sentry_var)
|
||||
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
/*!
|
||||
* \def BOOST_LOG_ONCE_BLOCK_FLAG(flag_var)
|
||||
*
|
||||
* Begins a code block to be executed only once, with protection against thread concurrency.
|
||||
* User has to provide the flag variable that controls whether the block has already
|
||||
* been executed.
|
||||
*/
|
||||
#define BOOST_LOG_ONCE_BLOCK_FLAG(flag_var)\
|
||||
BOOST_LOG_ONCE_BLOCK_FLAG_INTERNAL(\
|
||||
flag_var,\
|
||||
BOOST_LOG_UNIQUE_IDENTIFIER_NAME(_boost_log_once_block_sentry_))
|
||||
|
||||
/*!
|
||||
* \def BOOST_LOG_ONCE_BLOCK()
|
||||
*
|
||||
* Begins a code block to be executed only once, with protection against thread concurrency.
|
||||
*/
|
||||
#define BOOST_LOG_ONCE_BLOCK()\
|
||||
BOOST_LOG_ONCE_BLOCK_INTERNAL(\
|
||||
BOOST_LOG_UNIQUE_IDENTIFIER_NAME(_boost_log_once_block_flag_),\
|
||||
BOOST_LOG_UNIQUE_IDENTIFIER_NAME(_boost_log_once_block_sentry_))
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_UTILITY_ONCE_BLOCK_HPP_INCLUDED_
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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 open_mode.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 01.01.2016
|
||||
*
|
||||
* The header defines resource opening modes.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_UTILITY_OPEN_MODE_HPP_INCLUDED_
|
||||
#define BOOST_LOG_UTILITY_OPEN_MODE_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 open_mode {
|
||||
|
||||
//! Create a new resource; fail if exists already
|
||||
struct create_only_tag {} const create_only = create_only_tag();
|
||||
//! Opens an existing resource; fail if not exist
|
||||
struct open_only_tag {} const open_only = open_only_tag();
|
||||
//! Creates a new resource or opens an existing one
|
||||
struct open_or_create_tag {} const open_or_create = open_or_create_tag();
|
||||
|
||||
} // namespace open_mode
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_UTILITY_OPEN_MODE_HPP_INCLUDED_
|
||||
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
* Copyright Lingxi Li 2015.
|
||||
* Copyright Andrey Semashev 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 permissions.hpp
|
||||
* \author Lingxi Li
|
||||
* \author Andrey Semashev
|
||||
* \date 14.10.2015
|
||||
*
|
||||
* The header contains an abstraction wrapper for security permissions.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_UTILITY_PERMISSIONS_HPP_INCLUDED_
|
||||
#define BOOST_LOG_UTILITY_PERMISSIONS_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_WINDOWS
|
||||
extern "C" {
|
||||
struct _SECURITY_ATTRIBUTES;
|
||||
}
|
||||
#endif // BOOST_WINDOWS
|
||||
|
||||
namespace boost {
|
||||
|
||||
#ifdef BOOST_WINDOWS
|
||||
namespace detail {
|
||||
namespace winapi {
|
||||
struct BOOST_LOG_MAY_ALIAS _SECURITY_ATTRIBUTES;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace interprocess {
|
||||
class permissions;
|
||||
} // namespace interprocess
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
/*!
|
||||
* \brief Access permissions wrapper.
|
||||
*
|
||||
* On Windows platforms, it represents a pointer to \c SECURITY_ATTRIBUTES. The user is responsible
|
||||
* for allocating and reclaiming resources associated with the pointer, \c permissions instance does
|
||||
* not own them.
|
||||
*
|
||||
* On POSIX platforms, it represents a \c mode_t value.
|
||||
*/
|
||||
class permissions
|
||||
{
|
||||
public:
|
||||
#if defined(BOOST_LOG_DOXYGEN_PASS)
|
||||
//! The type of security permissions, specific to the operating system
|
||||
typedef implementation_defined native_type;
|
||||
#elif defined(BOOST_WINDOWS)
|
||||
typedef ::_SECURITY_ATTRIBUTES* native_type;
|
||||
#else
|
||||
// Equivalent to POSIX mode_t
|
||||
typedef unsigned int native_type;
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_LOG_DOXYGEN_PASS)
|
||||
private:
|
||||
native_type m_perms;
|
||||
#endif
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Default constructor. The method constructs an object that represents
|
||||
* a null \c SECURITY_ATTRIBUTES pointer on Windows platforms, and a
|
||||
* \c mode_t value \c 0644 on POSIX platforms.
|
||||
*/
|
||||
permissions() BOOST_NOEXCEPT
|
||||
{
|
||||
set_default();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Copy constructor.
|
||||
*/
|
||||
permissions(permissions const& that) BOOST_NOEXCEPT : m_perms(that.m_perms)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* Copy assignment.
|
||||
*/
|
||||
permissions& operator=(permissions const& that) BOOST_NOEXCEPT
|
||||
{
|
||||
m_perms = that.m_perms;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Initializing constructor.
|
||||
*/
|
||||
permissions(native_type perms) BOOST_NOEXCEPT : m_perms(perms)
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef BOOST_WINDOWS
|
||||
permissions(boost::detail::winapi::_SECURITY_ATTRIBUTES* perms) BOOST_NOEXCEPT : m_perms(reinterpret_cast< native_type >(perms))
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Initializing constructor.
|
||||
*/
|
||||
BOOST_LOG_API permissions(boost::interprocess::permissions const& perms) BOOST_NOEXCEPT;
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
/*!
|
||||
* Move constructor.
|
||||
*/
|
||||
permissions(permissions&& that) BOOST_NOEXCEPT : m_perms(that.m_perms)
|
||||
{
|
||||
that.set_default();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Move assignment.
|
||||
*/
|
||||
permissions& operator=(permissions&& that) BOOST_NOEXCEPT
|
||||
{
|
||||
m_perms = that.m_perms;
|
||||
that.set_default();
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Sets permissions from the OS-specific permissions.
|
||||
*/
|
||||
void set_native(native_type perms) BOOST_NOEXCEPT
|
||||
{
|
||||
m_perms = perms;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the underlying OS-specific permissions.
|
||||
*/
|
||||
native_type get_native() const BOOST_NOEXCEPT
|
||||
{
|
||||
return m_perms;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Sets the default permissions, which are equivalent to \c NULL \c SECURITY_ATTRIBUTES
|
||||
* on Windows and \c 0644 on POSIX platforms.
|
||||
*/
|
||||
void set_default() BOOST_NOEXCEPT
|
||||
{
|
||||
#if defined(BOOST_WINDOWS)
|
||||
m_perms = 0;
|
||||
#else
|
||||
m_perms = 0644;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* Sets unrestricted permissions, which are equivalent to \c SECURITY_ATTRIBUTES with \c NULL DACL
|
||||
* on Windows and \c 0666 on POSIX platforms.
|
||||
*/
|
||||
void set_unrestricted()
|
||||
{
|
||||
#if defined(BOOST_WINDOWS)
|
||||
m_perms = get_unrestricted_security_attributes();
|
||||
#else
|
||||
m_perms = 0666;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method swaps the object with \a that.
|
||||
*
|
||||
* \param that The other object to swap with.
|
||||
*/
|
||||
void swap(permissions& that) BOOST_NOEXCEPT
|
||||
{
|
||||
native_type perms = m_perms;
|
||||
m_perms = that.m_perms;
|
||||
that.m_perms = perms;
|
||||
}
|
||||
|
||||
//! Swaps the two \c permissions objects.
|
||||
friend void swap(permissions& a, permissions& b) BOOST_NOEXCEPT
|
||||
{
|
||||
a.swap(b);
|
||||
}
|
||||
|
||||
#if !defined(BOOST_LOG_DOXYGEN_PASS) && defined(BOOST_WINDOWS)
|
||||
private:
|
||||
static BOOST_LOG_API native_type get_unrestricted_security_attributes();
|
||||
#endif
|
||||
};
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_UTILITY_PERMISSIONS_HPP_INCLUDED_
|
||||
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
* Copyright Andrey Semashev 2007 - 2015.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
/*!
|
||||
* \file record_ordering.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 23.08.2009
|
||||
*
|
||||
* This header contains ordering predicates for logging records.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_UTILITY_RECORD_ORDERING_HPP_INCLUDED_
|
||||
#define BOOST_LOG_UTILITY_RECORD_ORDERING_HPP_INCLUDED_
|
||||
|
||||
#include <boost/core/enable_if.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/function_traits.hpp>
|
||||
#include <boost/log/core/record_view.hpp>
|
||||
#include <boost/log/attributes/attribute_name.hpp>
|
||||
#include <boost/log/attributes/attribute_value.hpp>
|
||||
#include <boost/log/attributes/value_visitation.hpp>
|
||||
#include <boost/log/utility/functional/logical.hpp>
|
||||
#include <boost/log/utility/functional/nop.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
/*!
|
||||
* \brief Ordering predicate, based on opaque pointers to the record view implementation data
|
||||
*
|
||||
* Since record views only refer to a shared implementation data, this predicate is able to order the views
|
||||
* by comparing the pointers to the data. Therefore two views are considered to be equivalent if they
|
||||
* refer to the same implementation data. Otherwise it is not specified whether one record is ordered before
|
||||
* the other until the predicate is applied. Note that the ordering may change every time the application runs.
|
||||
*
|
||||
* This kind of ordering may be useful if log records are to be stored in an associative
|
||||
* container with as least performance overhead as possible, when the particular order is not important.
|
||||
*
|
||||
* The \c FunT template argument is the predicate that is used to actually compare pointers. It should be
|
||||
* able to compare <tt>const void*</tt> pointers. The compared pointers may refer to distinct memory regions,
|
||||
* the pointers must not be interpreted in any way.
|
||||
*/
|
||||
template< typename FunT = less >
|
||||
class abstract_ordering :
|
||||
private FunT
|
||||
{
|
||||
public:
|
||||
//! Result type
|
||||
typedef bool result_type;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Default constructor. Requires \c FunT to be default constructible.
|
||||
*/
|
||||
abstract_ordering() : FunT()
|
||||
{
|
||||
}
|
||||
/*!
|
||||
* Initializing constructor. Constructs \c FunT instance as a copy of the \a fun argument.
|
||||
*/
|
||||
explicit abstract_ordering(FunT const& fun) : FunT(fun)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* Ordering operator
|
||||
*/
|
||||
result_type operator() (record_view const& left, record_view const& right) const
|
||||
{
|
||||
// We rely on the fact that the attribute_values() method returns a reference to the object in the record implementation,
|
||||
// so we can compare pointers.
|
||||
return FunT::operator() (static_cast< const void* >(&left.attribute_values()), static_cast< const void* >(&right.attribute_values()));
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Ordering predicate, based on attribute values associated with records
|
||||
*
|
||||
* This predicate allows to order log records based on values of a specifically named attribute
|
||||
* associated with them. Two given log records being compared should both have the specified
|
||||
* attribute value of the specified type to be able to be ordered properly. As a special case,
|
||||
* if neither of the records have the value, these records are considered equivalent. Otherwise,
|
||||
* the ordering results are unspecified.
|
||||
*/
|
||||
template< typename ValueT, typename FunT = less >
|
||||
class attribute_value_ordering :
|
||||
private FunT
|
||||
{
|
||||
public:
|
||||
//! Result type
|
||||
typedef bool result_type;
|
||||
//! Compared attribute value type
|
||||
typedef ValueT value_type;
|
||||
|
||||
private:
|
||||
template< typename LeftT >
|
||||
struct l2_visitor
|
||||
{
|
||||
typedef void result_type;
|
||||
|
||||
l2_visitor(FunT const& fun, LeftT const& left, bool& result) :
|
||||
m_fun(fun), m_left(left), m_result(result)
|
||||
{
|
||||
}
|
||||
|
||||
template< typename RightT >
|
||||
result_type operator() (RightT const& right) const
|
||||
{
|
||||
m_result = m_fun(m_left, right);
|
||||
}
|
||||
|
||||
private:
|
||||
FunT const& m_fun;
|
||||
LeftT const& m_left;
|
||||
bool& m_result;
|
||||
};
|
||||
|
||||
struct l1_visitor;
|
||||
friend struct l1_visitor;
|
||||
struct l1_visitor
|
||||
{
|
||||
typedef void result_type;
|
||||
|
||||
l1_visitor(attribute_value_ordering const& owner, record_view const& right, bool& result) :
|
||||
m_owner(owner), m_right(right), m_result(result)
|
||||
{
|
||||
}
|
||||
|
||||
template< typename LeftT >
|
||||
result_type operator() (LeftT const& left) const
|
||||
{
|
||||
boost::log::visit< value_type >(m_owner.m_name, m_right, l2_visitor< LeftT >(static_cast< FunT const& >(m_owner), left, m_result));
|
||||
}
|
||||
|
||||
private:
|
||||
attribute_value_ordering const& m_owner;
|
||||
record_view const& m_right;
|
||||
bool& m_result;
|
||||
};
|
||||
|
||||
private:
|
||||
//! Attribute value name
|
||||
const attribute_name m_name;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Initializing constructor.
|
||||
*
|
||||
* \param name The attribute value name to be compared
|
||||
* \param fun The ordering functor
|
||||
*/
|
||||
explicit attribute_value_ordering(attribute_name const& name, FunT const& fun = FunT()) :
|
||||
FunT(fun),
|
||||
m_name(name)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* Ordering operator
|
||||
*/
|
||||
result_type operator() (record_view const& left, record_view const& right) const
|
||||
{
|
||||
bool result = false;
|
||||
if (!boost::log::visit< value_type >(m_name, left, l1_visitor(*this, right, result)))
|
||||
{
|
||||
return !boost::log::visit< value_type >(m_name, right, nop());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* The function constructs a log record ordering predicate
|
||||
*/
|
||||
template< typename ValueT, typename FunT >
|
||||
inline attribute_value_ordering< ValueT, FunT > make_attr_ordering(attribute_name const& name, FunT const& fun)
|
||||
{
|
||||
typedef attribute_value_ordering< ValueT, FunT > ordering_t;
|
||||
return ordering_t(name, fun);
|
||||
}
|
||||
|
||||
#if !defined(BOOST_LOG_NO_FUNCTION_TRAITS)
|
||||
|
||||
namespace aux {
|
||||
|
||||
//! An ordering predicate constructor that uses SFINAE to disable invalid instantiations
|
||||
template<
|
||||
typename FunT,
|
||||
typename ArityCheckT = typename boost::enable_if_c< aux::arity_of< FunT >::value == 2 >::type,
|
||||
typename Arg1T = typename aux::first_argument_type_of< FunT >::type,
|
||||
typename Arg2T = typename aux::second_argument_type_of< FunT >::type,
|
||||
typename ArgsCheckT = typename boost::enable_if_c< is_same< Arg1T, Arg2T >::value >::type
|
||||
>
|
||||
struct make_attr_ordering_type
|
||||
{
|
||||
typedef attribute_value_ordering< Arg1T, FunT > type;
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
/*!
|
||||
* The function constructs a log record ordering predicate
|
||||
*/
|
||||
template< typename FunT >
|
||||
inline typename aux::make_attr_ordering_type< FunT >::type make_attr_ordering(attribute_name const& name, FunT const& fun)
|
||||
{
|
||||
typedef typename aux::make_attr_ordering_type< FunT >::type ordering_t;
|
||||
return ordering_t(name, fun);
|
||||
}
|
||||
|
||||
#endif // BOOST_LOG_NO_FUNCTION_TRAITS
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_UTILITY_RECORD_ORDERING_HPP_INCLUDED_
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 16.02.2013
|
||||
*
|
||||
* This header includes all library setup helpers.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_UTILITY_SETUP_HPP_INCLUDED_
|
||||
#define BOOST_LOG_UTILITY_SETUP_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/setup_config.hpp>
|
||||
|
||||
#include <boost/log/utility/setup/common_attributes.hpp>
|
||||
|
||||
#include <boost/log/utility/setup/console.hpp>
|
||||
#include <boost/log/utility/setup/file.hpp>
|
||||
|
||||
#include <boost/log/utility/setup/from_settings.hpp>
|
||||
#include <boost/log/utility/setup/from_stream.hpp>
|
||||
|
||||
#include <boost/log/utility/setup/settings.hpp>
|
||||
#include <boost/log/utility/setup/settings_parser.hpp>
|
||||
#include <boost/log/utility/setup/filter_parser.hpp>
|
||||
#include <boost/log/utility/setup/formatter_parser.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#endif // BOOST_LOG_UTILITY_SETUP_HPP_INCLUDED_
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright Andrey Semashev 2007 - 2015.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
/*!
|
||||
* \file common_attributes.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 16.05.2008
|
||||
*
|
||||
* The header contains implementation of convenience functions for registering commonly used attributes.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_UTILITY_SETUP_COMMON_ATTRIBUTES_HPP_INCLUDED_
|
||||
#define BOOST_LOG_UTILITY_SETUP_COMMON_ATTRIBUTES_HPP_INCLUDED_
|
||||
|
||||
#include <iostream>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/core/core.hpp>
|
||||
#include <boost/log/attributes/clock.hpp>
|
||||
#include <boost/log/attributes/counter.hpp>
|
||||
#include <boost/log/attributes/current_process_id.hpp>
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
#include <boost/log/attributes/current_thread_id.hpp>
|
||||
#endif
|
||||
#include <boost/log/detail/default_attribute_names.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
/*!
|
||||
* \brief Simple attribute initialization routine
|
||||
*
|
||||
* The function adds commonly used attributes to the logging system. Specifically, the following
|
||||
* attributes are registered globally:
|
||||
*
|
||||
* \li LineID - logging records counter with value type <tt>unsigned int</tt>
|
||||
* \li TimeStamp - local time generator with value type <tt>boost::posix_time::ptime</tt>
|
||||
* \li ProcessID - current process identifier with value type
|
||||
* <tt>attributes::current_process_id::value_type</tt>
|
||||
* \li ThreadID - in multithreaded builds, current thread identifier with
|
||||
* value type <tt>attributes::current_thread_id::value_type</tt>
|
||||
*/
|
||||
inline void add_common_attributes()
|
||||
{
|
||||
shared_ptr< core > pCore = core::get();
|
||||
pCore->add_global_attribute(
|
||||
aux::default_attribute_names::line_id(),
|
||||
attributes::counter< unsigned int >(1));
|
||||
pCore->add_global_attribute(
|
||||
aux::default_attribute_names::timestamp(),
|
||||
attributes::local_clock());
|
||||
pCore->add_global_attribute(
|
||||
aux::default_attribute_names::process_id(),
|
||||
attributes::current_process_id());
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
pCore->add_global_attribute(
|
||||
aux::default_attribute_names::thread_id(),
|
||||
attributes::current_thread_id());
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_UTILITY_SETUP_COMMON_ATTRIBUTES_HPP_INCLUDED_
|
||||
@@ -0,0 +1,243 @@
|
||||
/*
|
||||
* 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 console.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 16.05.2008
|
||||
*
|
||||
* The header contains implementation of convenience functions for enabling logging to console.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_UTILITY_SETUP_CONSOLE_HPP_INCLUDED_
|
||||
#define BOOST_LOG_UTILITY_SETUP_CONSOLE_HPP_INCLUDED_
|
||||
|
||||
#include <iostream>
|
||||
#include <boost/smart_ptr/shared_ptr.hpp>
|
||||
#include <boost/smart_ptr/make_shared_object.hpp>
|
||||
#include <boost/core/null_deleter.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/sink_init_helpers.hpp>
|
||||
#ifndef BOOST_LOG_NO_THREADS
|
||||
#include <boost/log/sinks/sync_frontend.hpp>
|
||||
#else
|
||||
#include <boost/log/sinks/unlocked_frontend.hpp>
|
||||
#endif
|
||||
#include <boost/log/sinks/text_ostream_backend.hpp>
|
||||
#include <boost/log/keywords/format.hpp>
|
||||
#include <boost/log/keywords/filter.hpp>
|
||||
#include <boost/log/keywords/auto_flush.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
#ifndef BOOST_LOG_NO_THREADS
|
||||
#define BOOST_LOG_CONSOLE_SINK_FRONTEND_INTERNAL sinks::synchronous_sink
|
||||
#else
|
||||
#define BOOST_LOG_CONSOLE_SINK_FRONTEND_INTERNAL sinks::unlocked_sink
|
||||
#endif
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace aux {
|
||||
|
||||
// The function creates and initializes the sink
|
||||
template< typename CharT, typename ArgsT >
|
||||
shared_ptr<
|
||||
BOOST_LOG_CONSOLE_SINK_FRONTEND_INTERNAL<
|
||||
sinks::basic_text_ostream_backend< CharT >
|
||||
>
|
||||
> add_console_log(std::basic_ostream< CharT >& strm, ArgsT const& args)
|
||||
{
|
||||
shared_ptr< std::basic_ostream< CharT > > pStream(&strm, boost::null_deleter());
|
||||
|
||||
typedef sinks::basic_text_ostream_backend< CharT > backend_t;
|
||||
shared_ptr< backend_t > pBackend = boost::make_shared< backend_t >();
|
||||
|
||||
pBackend->add_stream(pStream);
|
||||
pBackend->auto_flush(args[keywords::auto_flush | false]);
|
||||
|
||||
typedef BOOST_LOG_CONSOLE_SINK_FRONTEND_INTERNAL< backend_t > sink_t;
|
||||
shared_ptr< sink_t > pSink = boost::make_shared< sink_t >(pBackend);
|
||||
|
||||
aux::setup_filter(*pSink, args,
|
||||
typename is_void< typename parameter::binding< ArgsT, keywords::tag::filter, void >::type >::type());
|
||||
|
||||
aux::setup_formatter(*pSink, args,
|
||||
typename is_void< typename parameter::binding< ArgsT, keywords::tag::format, void >::type >::type());
|
||||
|
||||
core::get()->add_sink(pSink);
|
||||
|
||||
return pSink;
|
||||
}
|
||||
|
||||
template< typename CharT >
|
||||
struct default_console_stream;
|
||||
|
||||
#ifdef BOOST_LOG_USE_CHAR
|
||||
template< >
|
||||
struct default_console_stream< char >
|
||||
{
|
||||
static std::ostream& get() { return std::clog; }
|
||||
};
|
||||
#endif // BOOST_LOG_USE_CHAR
|
||||
|
||||
#ifdef BOOST_LOG_USE_WCHAR_T
|
||||
template< >
|
||||
struct default_console_stream< wchar_t >
|
||||
{
|
||||
static std::wostream& get() { return std::wclog; }
|
||||
};
|
||||
#endif // BOOST_LOG_USE_WCHAR_T
|
||||
|
||||
} // namespace aux
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
template< typename CharT >
|
||||
inline shared_ptr<
|
||||
BOOST_LOG_CONSOLE_SINK_FRONTEND_INTERNAL<
|
||||
sinks::basic_text_ostream_backend< CharT >
|
||||
>
|
||||
> add_console_log()
|
||||
{
|
||||
return aux::add_console_log(
|
||||
aux::default_console_stream< CharT >::get(), keywords::auto_flush = false);
|
||||
}
|
||||
|
||||
|
||||
template< typename CharT >
|
||||
inline shared_ptr<
|
||||
BOOST_LOG_CONSOLE_SINK_FRONTEND_INTERNAL<
|
||||
sinks::basic_text_ostream_backend< CharT >
|
||||
>
|
||||
> add_console_log(std::basic_ostream< CharT >& strm)
|
||||
{
|
||||
return aux::add_console_log(strm, keywords::auto_flush = false);
|
||||
}
|
||||
|
||||
template< typename CharT, typename ArgT1 >
|
||||
inline shared_ptr<
|
||||
BOOST_LOG_CONSOLE_SINK_FRONTEND_INTERNAL<
|
||||
sinks::basic_text_ostream_backend< CharT >
|
||||
>
|
||||
> add_console_log(std::basic_ostream< CharT >& strm, ArgT1 const& arg1)
|
||||
{
|
||||
return aux::add_console_log(strm, arg1);
|
||||
}
|
||||
|
||||
template< typename CharT, typename ArgT1, typename ArgT2 >
|
||||
inline shared_ptr<
|
||||
BOOST_LOG_CONSOLE_SINK_FRONTEND_INTERNAL<
|
||||
sinks::basic_text_ostream_backend< CharT >
|
||||
>
|
||||
> add_console_log(std::basic_ostream< CharT >& strm, ArgT1 const& arg1, ArgT2 const& arg2)
|
||||
{
|
||||
return aux::add_console_log(strm, (arg1, arg2));
|
||||
}
|
||||
|
||||
template< typename CharT, typename ArgT1, typename ArgT2, typename ArgT3 >
|
||||
inline shared_ptr<
|
||||
BOOST_LOG_CONSOLE_SINK_FRONTEND_INTERNAL<
|
||||
sinks::basic_text_ostream_backend< CharT >
|
||||
>
|
||||
> add_console_log(std::basic_ostream< CharT >& strm, ArgT1 const& arg1, ArgT2 const& arg2, ArgT3 const& arg3)
|
||||
{
|
||||
return aux::add_console_log(strm, (arg1, arg2, arg3));
|
||||
}
|
||||
|
||||
#else // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
/*!
|
||||
* The function constructs sink for the specified console stream and adds it to the core
|
||||
*
|
||||
* \param strm One of the standard console streams: <tt>std::cout</tt>, <tt>std::cerr</tt> or <tt>std::clog</tt>
|
||||
* (or the corresponding wide-character analogues).
|
||||
* \param args Optional additional named arguments for the sink initialization. The following arguments are supported:
|
||||
* \li \c filter Specifies a filter to install into the sink. May be a string that represents a filter,
|
||||
* or a filter lambda expression.
|
||||
* \li \c format Specifies a formatter to install into the sink. May be a string that represents a formatter,
|
||||
* or a formatter lambda expression (either streaming or Boost.Format-like notation).
|
||||
* \li \c auto_flush A boolean flag that shows whether the sink should automatically flush the stream
|
||||
* after each written record.
|
||||
* \return Pointer to the constructed sink.
|
||||
*/
|
||||
template< typename CharT, typename... ArgsT >
|
||||
shared_ptr<
|
||||
BOOST_LOG_CONSOLE_SINK_FRONTEND_INTERNAL<
|
||||
sinks::basic_text_ostream_backend< CharT >
|
||||
>
|
||||
> add_console_log(std::basic_ostream< CharT >& strm, ArgsT... const& args);
|
||||
|
||||
/*!
|
||||
* Equivalent to: <tt>add_console_log(std::clog);</tt> or <tt>add_console_log(std::wclog);</tt>,
|
||||
* depending on the \c CharT type.
|
||||
*
|
||||
* \overload
|
||||
*/
|
||||
template< typename CharT, typename... ArgsT >
|
||||
shared_ptr<
|
||||
BOOST_LOG_CONSOLE_SINK_FRONTEND_INTERNAL<
|
||||
sinks::basic_text_ostream_backend< CharT >
|
||||
>
|
||||
> add_console_log(ArgsT... const& args);
|
||||
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
#ifdef BOOST_LOG_USE_CHAR
|
||||
|
||||
/*!
|
||||
* The function constructs sink for the <tt>std::clog</tt> stream and adds it to the core
|
||||
*
|
||||
* \overload
|
||||
*
|
||||
* \return Pointer to the constructed sink.
|
||||
*/
|
||||
inline shared_ptr<
|
||||
BOOST_LOG_CONSOLE_SINK_FRONTEND_INTERNAL<
|
||||
sinks::text_ostream_backend
|
||||
>
|
||||
> add_console_log()
|
||||
{
|
||||
return add_console_log(std::clog);
|
||||
}
|
||||
|
||||
#endif // BOOST_LOG_USE_CHAR
|
||||
|
||||
#ifdef BOOST_LOG_USE_WCHAR_T
|
||||
|
||||
/*!
|
||||
* The function constructs sink for the <tt>std::wclog</tt> stream and adds it to the core
|
||||
*
|
||||
* \return Pointer to the constructed sink.
|
||||
*/
|
||||
inline shared_ptr<
|
||||
BOOST_LOG_CONSOLE_SINK_FRONTEND_INTERNAL<
|
||||
sinks::wtext_ostream_backend
|
||||
>
|
||||
> wadd_console_log()
|
||||
{
|
||||
return add_console_log(std::wclog);
|
||||
}
|
||||
|
||||
#endif // BOOST_LOG_USE_WCHAR_T
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#undef BOOST_LOG_CONSOLE_SINK_FRONTEND_INTERNAL
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_UTILITY_SETUP_CONSOLE_HPP_INCLUDED_
|
||||
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* 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 file.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 16.05.2008
|
||||
*
|
||||
* The header contains implementation of convenience functions for enabling logging to a file.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_UTILITY_SETUP_FILE_HPP_INCLUDED_
|
||||
#define BOOST_LOG_UTILITY_SETUP_FILE_HPP_INCLUDED_
|
||||
|
||||
#include <boost/smart_ptr/shared_ptr.hpp>
|
||||
#include <boost/smart_ptr/make_shared_object.hpp>
|
||||
#include <boost/parameter/parameters.hpp> // for is_named_argument
|
||||
#include <boost/preprocessor/comparison/greater.hpp>
|
||||
#include <boost/preprocessor/punctuation/comma_if.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_shifted_params.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/sink_init_helpers.hpp>
|
||||
#include <boost/log/detail/parameter_tools.hpp>
|
||||
#include <boost/log/core/core.hpp>
|
||||
#ifndef BOOST_LOG_NO_THREADS
|
||||
#include <boost/log/sinks/sync_frontend.hpp>
|
||||
#else
|
||||
#include <boost/log/sinks/unlocked_frontend.hpp>
|
||||
#endif
|
||||
#include <boost/log/sinks/text_file_backend.hpp>
|
||||
#include <boost/log/keywords/scan_method.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
#ifndef BOOST_LOG_NO_THREADS
|
||||
#define BOOST_LOG_FILE_SINK_FRONTEND_INTERNAL sinks::synchronous_sink
|
||||
#else
|
||||
#define BOOST_LOG_FILE_SINK_FRONTEND_INTERNAL sinks::unlocked_sink
|
||||
#endif
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace aux {
|
||||
|
||||
//! The function creates a file collector according to the specified arguments
|
||||
template< typename ArgsT >
|
||||
inline shared_ptr< sinks::file::collector > setup_file_collector(ArgsT const&, mpl::true_ const&)
|
||||
{
|
||||
return shared_ptr< sinks::file::collector >();
|
||||
}
|
||||
template< typename ArgsT >
|
||||
inline shared_ptr< sinks::file::collector > setup_file_collector(ArgsT const& args, mpl::false_ const&)
|
||||
{
|
||||
return sinks::file::make_collector(args);
|
||||
}
|
||||
|
||||
//! The function constructs the sink and adds it to the core
|
||||
template< typename ArgsT >
|
||||
shared_ptr< BOOST_LOG_FILE_SINK_FRONTEND_INTERNAL< sinks::text_file_backend > > add_file_log(ArgsT const& args)
|
||||
{
|
||||
typedef sinks::text_file_backend backend_t;
|
||||
shared_ptr< backend_t > pBackend = boost::make_shared< backend_t >(args);
|
||||
|
||||
shared_ptr< sinks::file::collector > pCollector = aux::setup_file_collector(args,
|
||||
typename is_void< typename parameter::binding< ArgsT, keywords::tag::target, void >::type >::type());
|
||||
if (pCollector)
|
||||
{
|
||||
pBackend->set_file_collector(pCollector);
|
||||
pBackend->scan_for_files(args[keywords::scan_method | sinks::file::scan_matching]);
|
||||
}
|
||||
|
||||
shared_ptr< BOOST_LOG_FILE_SINK_FRONTEND_INTERNAL< backend_t > > pSink =
|
||||
boost::make_shared< BOOST_LOG_FILE_SINK_FRONTEND_INTERNAL< backend_t > >(pBackend);
|
||||
|
||||
aux::setup_filter(*pSink, args,
|
||||
typename is_void< typename parameter::binding< ArgsT, keywords::tag::filter, void >::type >::type());
|
||||
|
||||
aux::setup_formatter(*pSink, args,
|
||||
typename is_void< typename parameter::binding< ArgsT, keywords::tag::format, void >::type >::type());
|
||||
|
||||
core::get()->add_sink(pSink);
|
||||
|
||||
return pSink;
|
||||
}
|
||||
|
||||
//! The function wraps the argument into a file_name named argument, if needed
|
||||
template< typename T >
|
||||
inline T const& wrap_file_name(T const& arg, mpl::true_)
|
||||
{
|
||||
return arg;
|
||||
}
|
||||
template< typename T >
|
||||
inline typename parameter::aux::tag< keywords::tag::file_name, T const >::type
|
||||
wrap_file_name(T const& arg, mpl::false_)
|
||||
{
|
||||
return keywords::file_name = arg;
|
||||
}
|
||||
|
||||
} // namespace aux
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
#define BOOST_LOG_INIT_LOG_TO_FILE_INTERNAL(z, n, data)\
|
||||
template< BOOST_PP_ENUM_PARAMS(n, typename T) >\
|
||||
inline shared_ptr< BOOST_LOG_FILE_SINK_FRONTEND_INTERNAL< sinks::text_file_backend > > add_file_log(BOOST_PP_ENUM_BINARY_PARAMS(n, T, const& arg))\
|
||||
{\
|
||||
return aux::add_file_log((\
|
||||
aux::wrap_file_name(arg0, typename parameter::aux::is_named_argument< T0 >::type())\
|
||||
BOOST_PP_COMMA_IF(BOOST_PP_GREATER(n, 1))\
|
||||
BOOST_PP_ENUM_SHIFTED_PARAMS(n, arg)\
|
||||
));\
|
||||
}
|
||||
|
||||
BOOST_PP_REPEAT_FROM_TO(1, BOOST_LOG_MAX_PARAMETER_ARGS, BOOST_LOG_INIT_LOG_TO_FILE_INTERNAL, ~)
|
||||
|
||||
#undef BOOST_LOG_INIT_LOG_TO_FILE_INTERNAL
|
||||
|
||||
#else // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
/*!
|
||||
* The function initializes the logging library to write logs to a file stream.
|
||||
*
|
||||
* \param args A number of named arguments. The following parameters are supported:
|
||||
* \li \c file_name The file name or its pattern. This parameter is mandatory.
|
||||
* \li \c open_mode The mask that describes the open mode for the file. See <tt>std::ios_base::openmode</tt>.
|
||||
* \li \c rotation_size The size of the file at which rotation should occur. See <tt>basic_text_file_backend</tt>.
|
||||
* \li \c time_based_rotation The predicate for time-based file rotations. See <tt>basic_text_file_backend</tt>.
|
||||
* \li \c auto_flush A boolean flag that shows whether the sink should automatically flush the file
|
||||
* after each written record.
|
||||
* \li \c target The target directory to store rotated files in. See <tt>sinks::file::make_collector</tt>.
|
||||
* \li \c max_size The maximum total size of rotated files in the target directory. See <tt>sinks::file::make_collector</tt>.
|
||||
* \li \c min_free_space Minimum free space in the target directory. See <tt>sinks::file::make_collector</tt>.
|
||||
* \li \c max_files The maximum total number of rotated files in the target directory. See <tt>sinks::file::make_collector</tt>.
|
||||
* \li \c scan_method The method of scanning the target directory for log files. See <tt>sinks::file::scan_method</tt>.
|
||||
* \li \c filter Specifies a filter to install into the sink. May be a string that represents a filter,
|
||||
* or a filter lambda expression.
|
||||
* \li \c format Specifies a formatter to install into the sink. May be a string that represents a formatter,
|
||||
* or a formatter lambda expression (either streaming or Boost.Format-like notation).
|
||||
* \return Pointer to the constructed sink.
|
||||
*/
|
||||
template< typename... ArgsT >
|
||||
shared_ptr< BOOST_LOG_FILE_SINK_FRONTEND_INTERNAL< sinks::text_file_backend > > add_file_log(ArgsT... const& args);
|
||||
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#undef BOOST_LOG_FILE_SINK_FRONTEND_INTERNAL
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_UTILITY_SETUP_FILE_HPP_INCLUDED_
|
||||
@@ -0,0 +1,346 @@
|
||||
/*
|
||||
* Copyright Andrey Semashev 2007 - 2015.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
/*!
|
||||
* \file filter_parser.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 31.03.2008
|
||||
*
|
||||
* The header contains definition of a filter parser function.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_UTILITY_SETUP_FILTER_PARSER_HPP_INCLUDED_
|
||||
#define BOOST_LOG_UTILITY_SETUP_FILTER_PARSER_HPP_INCLUDED_
|
||||
|
||||
#include <string>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/smart_ptr/shared_ptr.hpp>
|
||||
#include <boost/smart_ptr/make_shared_object.hpp>
|
||||
#include <boost/phoenix/operator/comparison.hpp>
|
||||
#include <boost/type_traits/is_base_and_derived.hpp>
|
||||
#include <boost/core/enable_if.hpp>
|
||||
#include <boost/log/detail/setup_config.hpp>
|
||||
#include <boost/log/detail/code_conversion.hpp>
|
||||
#include <boost/log/exceptions.hpp>
|
||||
#include <boost/log/attributes/attribute_name.hpp>
|
||||
#include <boost/log/attributes/attribute_value_set.hpp>
|
||||
#include <boost/log/expressions/filter.hpp>
|
||||
#include <boost/log/expressions/keyword_fwd.hpp>
|
||||
#include <boost/log/expressions/attr.hpp>
|
||||
#include <boost/log/expressions/predicates/has_attr.hpp>
|
||||
#include <boost/log/core/core.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
/*!
|
||||
* The interface class for all filter factories.
|
||||
*/
|
||||
template< typename CharT >
|
||||
struct filter_factory
|
||||
{
|
||||
//! Character type
|
||||
typedef CharT char_type;
|
||||
//! String type
|
||||
typedef std::basic_string< char_type > string_type;
|
||||
|
||||
/*!
|
||||
* Default constructor
|
||||
*/
|
||||
BOOST_DEFAULTED_FUNCTION(filter_factory(), {})
|
||||
|
||||
/*!
|
||||
* Virtual destructor
|
||||
*/
|
||||
virtual ~filter_factory() {}
|
||||
|
||||
/*!
|
||||
* The callback for filter for the attribute existence test
|
||||
*/
|
||||
virtual filter on_exists_test(attribute_name const& name)
|
||||
{
|
||||
return filter(expressions::has_attr(name));
|
||||
}
|
||||
|
||||
/*!
|
||||
* The callback for equality relation filter
|
||||
*/
|
||||
virtual filter on_equality_relation(attribute_name const& name, string_type const& arg)
|
||||
{
|
||||
BOOST_LOG_THROW_DESCR_PARAMS(parse_error, "The equality attribute value relation is not supported", (name));
|
||||
BOOST_LOG_UNREACHABLE_RETURN(filter());
|
||||
}
|
||||
/*!
|
||||
* The callback for inequality relation filter
|
||||
*/
|
||||
virtual filter on_inequality_relation(attribute_name const& name, string_type const& arg)
|
||||
{
|
||||
BOOST_LOG_THROW_DESCR_PARAMS(parse_error, "The inequality attribute value relation is not supported", (name));
|
||||
BOOST_LOG_UNREACHABLE_RETURN(filter());
|
||||
}
|
||||
/*!
|
||||
* The callback for less relation filter
|
||||
*/
|
||||
virtual filter on_less_relation(attribute_name const& name, string_type const& arg)
|
||||
{
|
||||
BOOST_LOG_THROW_DESCR_PARAMS(parse_error, "The less attribute value relation is not supported", (name));
|
||||
BOOST_LOG_UNREACHABLE_RETURN(filter());
|
||||
}
|
||||
/*!
|
||||
* The callback for greater relation filter
|
||||
*/
|
||||
virtual filter on_greater_relation(attribute_name const& name, string_type const& arg)
|
||||
{
|
||||
BOOST_LOG_THROW_DESCR_PARAMS(parse_error, "The greater attribute value relation is not supported", (name));
|
||||
BOOST_LOG_UNREACHABLE_RETURN(filter());
|
||||
}
|
||||
/*!
|
||||
* The callback for less or equal relation filter
|
||||
*/
|
||||
virtual filter on_less_or_equal_relation(attribute_name const& name, string_type const& arg)
|
||||
{
|
||||
BOOST_LOG_THROW_DESCR_PARAMS(parse_error, "The less-or-equal attribute value relation is not supported", (name));
|
||||
BOOST_LOG_UNREACHABLE_RETURN(filter());
|
||||
}
|
||||
/*!
|
||||
* The callback for greater or equal relation filter
|
||||
*/
|
||||
virtual filter on_greater_or_equal_relation(attribute_name const& name, string_type const& arg)
|
||||
{
|
||||
BOOST_LOG_THROW_DESCR_PARAMS(parse_error, "The greater-or-equal attribute value relation is not supported", (name));
|
||||
BOOST_LOG_UNREACHABLE_RETURN(filter());
|
||||
}
|
||||
|
||||
/*!
|
||||
* The callback for custom relation filter
|
||||
*/
|
||||
virtual filter on_custom_relation(attribute_name const& name, string_type const& rel, string_type const& arg)
|
||||
{
|
||||
BOOST_LOG_THROW_DESCR_PARAMS(parse_error, "The custom attribute value relation \"" + boost::log::aux::to_narrow(rel) + "\" is not supported", (name));
|
||||
BOOST_LOG_UNREACHABLE_RETURN(filter());
|
||||
}
|
||||
|
||||
BOOST_DELETED_FUNCTION(filter_factory(filter_factory const&))
|
||||
BOOST_DELETED_FUNCTION(filter_factory& operator= (filter_factory const&))
|
||||
};
|
||||
|
||||
/*!
|
||||
* The base class for filter factories. The class defines default implementations for most
|
||||
* filter expressions. In order to be able to construct filters, the attribute value type must
|
||||
* support reading from a stream. Also, the default filters will rely on relational operators for
|
||||
* the type, so these operators must also be defined.
|
||||
*/
|
||||
template< typename CharT, typename AttributeValueT >
|
||||
class basic_filter_factory :
|
||||
public filter_factory< CharT >
|
||||
{
|
||||
//! Base type
|
||||
typedef filter_factory< CharT > base_type;
|
||||
|
||||
public:
|
||||
//! The type(s) of the attribute value expected
|
||||
typedef AttributeValueT value_type;
|
||||
// Type imports
|
||||
typedef typename base_type::string_type string_type;
|
||||
|
||||
/*!
|
||||
* The callback for filter for the attribute existence test
|
||||
*/
|
||||
virtual filter on_exists_test(attribute_name const& name)
|
||||
{
|
||||
return filter(expressions::has_attr< value_type >(name));
|
||||
}
|
||||
|
||||
/*!
|
||||
* The callback for equality relation filter
|
||||
*/
|
||||
virtual filter on_equality_relation(attribute_name const& name, string_type const& arg)
|
||||
{
|
||||
return filter(expressions::attr< value_type >(name) == parse_argument(arg));
|
||||
}
|
||||
/*!
|
||||
* The callback for inequality relation filter
|
||||
*/
|
||||
virtual filter on_inequality_relation(attribute_name const& name, string_type const& arg)
|
||||
{
|
||||
return filter(expressions::attr< value_type >(name) != parse_argument(arg));
|
||||
}
|
||||
/*!
|
||||
* The callback for less relation filter
|
||||
*/
|
||||
virtual filter on_less_relation(attribute_name const& name, string_type const& arg)
|
||||
{
|
||||
return filter(expressions::attr< value_type >(name) < parse_argument(arg));
|
||||
}
|
||||
/*!
|
||||
* The callback for greater relation filter
|
||||
*/
|
||||
virtual filter on_greater_relation(attribute_name const& name, string_type const& arg)
|
||||
{
|
||||
return filter(expressions::attr< value_type >(name) > parse_argument(arg));
|
||||
}
|
||||
/*!
|
||||
* The callback for less or equal relation filter
|
||||
*/
|
||||
virtual filter on_less_or_equal_relation(attribute_name const& name, string_type const& arg)
|
||||
{
|
||||
return filter(expressions::attr< value_type >(name) <= parse_argument(arg));
|
||||
}
|
||||
/*!
|
||||
* The callback for greater or equal relation filter
|
||||
*/
|
||||
virtual filter on_greater_or_equal_relation(attribute_name const& name, string_type const& arg)
|
||||
{
|
||||
return filter(expressions::attr< value_type >(name) >= parse_argument(arg));
|
||||
}
|
||||
|
||||
/*!
|
||||
* The callback for custom relation filter
|
||||
*/
|
||||
virtual filter on_custom_relation(attribute_name const& name, string_type const& rel, string_type const& arg)
|
||||
{
|
||||
BOOST_LOG_THROW_DESCR_PARAMS(parse_error, "The custom attribute value relation \"" + boost::log::aux::to_narrow(rel) + "\" is not supported", (name));
|
||||
BOOST_LOG_UNREACHABLE_RETURN(filter());
|
||||
}
|
||||
|
||||
/*!
|
||||
* The function parses the argument value for a binary relation
|
||||
*/
|
||||
virtual value_type parse_argument(string_type const& arg)
|
||||
{
|
||||
return boost::lexical_cast< value_type >(arg);
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* The function registers a filter factory object for the specified attribute name. The factory will be
|
||||
* used to construct a filter during parsing the filter string.
|
||||
*
|
||||
* \pre <tt>name != NULL && factory != NULL</tt>, <tt>name</tt> points to a zero-terminated string
|
||||
* \param name Attribute name to associate the factory with
|
||||
* \param factory The filter factory
|
||||
*/
|
||||
template< typename CharT >
|
||||
BOOST_LOG_SETUP_API void register_filter_factory(
|
||||
attribute_name const& name, shared_ptr< filter_factory< CharT > > const& factory);
|
||||
|
||||
/*!
|
||||
* The function registers a filter factory object for the specified attribute name. The factory will be
|
||||
* used to construct a filter during parsing the filter string.
|
||||
*
|
||||
* \pre <tt>name != NULL && factory != NULL</tt>, <tt>name</tt> points to a zero-terminated string
|
||||
* \param name Attribute name to associate the factory with
|
||||
* \param factory The filter factory
|
||||
*/
|
||||
template< typename FactoryT >
|
||||
inline typename boost::enable_if_c<
|
||||
is_base_and_derived< filter_factory< typename FactoryT::char_type >, FactoryT >::value
|
||||
>::type register_filter_factory(attribute_name const& name, shared_ptr< FactoryT > const& factory)
|
||||
{
|
||||
typedef filter_factory< typename FactoryT::char_type > factory_base;
|
||||
register_filter_factory(name, boost::static_pointer_cast< factory_base >(factory));
|
||||
}
|
||||
|
||||
/*!
|
||||
* The function registers a simple filter factory object for the specified attribute name. The factory will
|
||||
* support attribute values of type \c AttributeValueT, which must support all relation operations, such as
|
||||
* equality comparison and less/greater ordering, and also extraction from stream.
|
||||
*
|
||||
* \pre <tt>name != NULL</tt>, <tt>name</tt> points to a zero-terminated string
|
||||
* \param name Attribute name to associate the factory with
|
||||
*/
|
||||
template< typename AttributeValueT, typename CharT >
|
||||
inline void register_simple_filter_factory(attribute_name const& name)
|
||||
{
|
||||
shared_ptr< filter_factory< CharT > > factory =
|
||||
boost::make_shared< basic_filter_factory< CharT, AttributeValueT > >();
|
||||
register_filter_factory(name, factory);
|
||||
}
|
||||
|
||||
/*!
|
||||
* The function registers a simple filter factory object for the specified attribute name. The factory will
|
||||
* support attribute values of type \c AttributeValueT, which must support all relation operations, such as
|
||||
* equality comparison and less/greater ordering, and also extraction from stream.
|
||||
*
|
||||
* \pre <tt>name != NULL</tt>, <tt>name</tt> points to a zero-terminated string
|
||||
* \param name Attribute name to associate the factory with
|
||||
*/
|
||||
template< typename AttributeValueT >
|
||||
inline void register_simple_filter_factory(attribute_name const& name)
|
||||
{
|
||||
register_simple_filter_factory< AttributeValueT, char >(name);
|
||||
}
|
||||
|
||||
/*!
|
||||
* The function registers a simple filter factory object for the specified attribute keyword. The factory will
|
||||
* support attribute values described by the keyword. The values must support all relation operations, such as
|
||||
* equality comparison and less/greater ordering, and also extraction from stream.
|
||||
*
|
||||
* \pre <tt>name != NULL</tt>, <tt>name</tt> points to a zero-terminated string
|
||||
* \param keyword Attribute keyword to associate the factory with
|
||||
*/
|
||||
template< typename CharT, typename DescriptorT, template< typename > class ActorT >
|
||||
inline void register_simple_filter_factory(expressions::attribute_keyword< DescriptorT, ActorT > const& keyword)
|
||||
{
|
||||
register_simple_filter_factory< typename DescriptorT::value_type, CharT >(keyword.get_name());
|
||||
}
|
||||
|
||||
/*!
|
||||
* The function parses a filter from the sequence of characters
|
||||
*
|
||||
* \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
|
||||
* \return A function object that can be used as a filter.
|
||||
*
|
||||
* \b Throws: An <tt>std::exception</tt>-based exception, if a filter cannot be recognized in the character sequence.
|
||||
*/
|
||||
template< typename CharT >
|
||||
BOOST_LOG_SETUP_API filter parse_filter(const CharT* begin, const CharT* end);
|
||||
|
||||
/*!
|
||||
* The function parses a filter from the string
|
||||
*
|
||||
* \param str A string that contains filter description
|
||||
* \return A function object that can be used as a filter.
|
||||
*
|
||||
* \b Throws: An <tt>std::exception</tt>-based exception, if a filter cannot be recognized in the character sequence.
|
||||
*/
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT >
|
||||
inline filter parse_filter(std::basic_string< CharT, TraitsT, AllocatorT > const& str)
|
||||
{
|
||||
const CharT* p = str.c_str();
|
||||
return parse_filter(p, p + str.size());
|
||||
}
|
||||
|
||||
/*!
|
||||
* The function parses a filter from the string
|
||||
*
|
||||
* \pre <tt>str != NULL</tt>, <tt>str</tt> points to a zero-terminated string.
|
||||
* \param str A string that contains filter description.
|
||||
* \return A function object that can be used as a filter.
|
||||
*
|
||||
* \b Throws: An <tt>std::exception</tt>-based exception, if a filter cannot be recognized in the character sequence.
|
||||
*/
|
||||
template< typename CharT >
|
||||
inline filter parse_filter(const CharT* str)
|
||||
{
|
||||
return parse_filter(str, str + std::char_traits< CharT >::length(str));
|
||||
}
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_UTILITY_SETUP_FILTER_PARSER_HPP_INCLUDED_
|
||||
@@ -0,0 +1,216 @@
|
||||
/*
|
||||
* Copyright Andrey Semashev 2007 - 2015.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
/*!
|
||||
* \file formatter_parser.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 07.04.2008
|
||||
*
|
||||
* The header contains definition of a formatter parser function, along with facilities to
|
||||
* add support for custom formatters.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_UTILITY_SETUP_FORMATTER_PARSER_HPP_INCLUDED_
|
||||
#define BOOST_LOG_UTILITY_SETUP_FORMATTER_PARSER_HPP_INCLUDED_
|
||||
|
||||
#include <iosfwd>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <boost/smart_ptr/shared_ptr.hpp>
|
||||
#include <boost/smart_ptr/make_shared_object.hpp>
|
||||
#include <boost/core/enable_if.hpp>
|
||||
#include <boost/type_traits/is_base_and_derived.hpp>
|
||||
#include <boost/log/detail/setup_config.hpp>
|
||||
#include <boost/log/attributes/attribute_name.hpp>
|
||||
#include <boost/log/core/record.hpp>
|
||||
#include <boost/log/expressions/formatter.hpp>
|
||||
#include <boost/log/expressions/attr.hpp>
|
||||
#include <boost/log/expressions/formatters/stream.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
/*!
|
||||
* Formatter factory base interface.
|
||||
*/
|
||||
template< typename CharT >
|
||||
struct formatter_factory
|
||||
{
|
||||
//! Character type
|
||||
typedef CharT char_type;
|
||||
//! String type
|
||||
typedef std::basic_string< char_type > string_type;
|
||||
//! The formatter function object
|
||||
typedef basic_formatter< char_type > formatter_type;
|
||||
/*!
|
||||
* Type of the map of formatter factory arguments [argument name -> argument value].
|
||||
* This type of maps will be passed to formatter factories on attempt to create a formatter.
|
||||
*/
|
||||
typedef std::map< string_type, string_type > args_map;
|
||||
|
||||
/*!
|
||||
* Default constructor
|
||||
*/
|
||||
BOOST_DEFAULTED_FUNCTION(formatter_factory(), {})
|
||||
|
||||
/*!
|
||||
* Virtual destructor
|
||||
*/
|
||||
virtual ~formatter_factory() {}
|
||||
|
||||
/*!
|
||||
* The function creates a formatter for the specified attribute.
|
||||
*
|
||||
* \param name Attribute name
|
||||
* \param args Formatter arguments
|
||||
*/
|
||||
virtual formatter_type create_formatter(attribute_name const& name, args_map const& args) = 0;
|
||||
|
||||
BOOST_DELETED_FUNCTION(formatter_factory(formatter_factory const&))
|
||||
BOOST_DELETED_FUNCTION(formatter_factory& operator= (formatter_factory const&))
|
||||
};
|
||||
|
||||
/*!
|
||||
* Base class for formatter factories. This class provides default implementation of formatter expressions for
|
||||
* types supporting stream output. The factory does not take into account any additional parameters that may be specified.
|
||||
*/
|
||||
template< typename CharT, typename AttributeValueT >
|
||||
class basic_formatter_factory :
|
||||
public formatter_factory< CharT >
|
||||
{
|
||||
private:
|
||||
typedef formatter_factory< CharT > base_type;
|
||||
|
||||
public:
|
||||
//! Attribute value type
|
||||
typedef AttributeValueT value_type;
|
||||
// Type imports from the base class
|
||||
typedef typename base_type::formatter_type formatter_type;
|
||||
typedef typename base_type::args_map args_map;
|
||||
|
||||
/*!
|
||||
* The function creates a formatter for the specified attribute.
|
||||
*
|
||||
* \param name Attribute name
|
||||
* \param args Formatter arguments
|
||||
*/
|
||||
formatter_type create_formatter(attribute_name const& name, args_map const& args)
|
||||
{
|
||||
return formatter_type(expressions::stream << expressions::attr< value_type >(name));
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief The function registers a user-defined formatter factory
|
||||
*
|
||||
* The function registers a user-defined formatter factory. The registered factory function will be
|
||||
* called when the formatter parser detects the specified attribute name in the formatter string.
|
||||
*
|
||||
* \pre <tt>!!attr_name && !!factory</tt>.
|
||||
*
|
||||
* \param attr_name Attribute name
|
||||
* \param factory Pointer to the formatter factory
|
||||
*/
|
||||
template< typename CharT >
|
||||
BOOST_LOG_SETUP_API void register_formatter_factory(
|
||||
attribute_name const& attr_name, shared_ptr< formatter_factory< CharT > > const& factory);
|
||||
|
||||
/*!
|
||||
* \brief The function registers a user-defined formatter factory
|
||||
*
|
||||
* The function registers a user-defined formatter factory. The registered factory function will be
|
||||
* called when the formatter parser detects the specified attribute name in the formatter string.
|
||||
*
|
||||
* \pre <tt>!!attr_name && !!factory</tt>.
|
||||
*
|
||||
* \param attr_name Attribute name
|
||||
* \param factory Pointer to the formatter factory
|
||||
*/
|
||||
template< typename FactoryT >
|
||||
inline typename boost::enable_if_c<
|
||||
is_base_and_derived< formatter_factory< typename FactoryT::char_type >, FactoryT >::value
|
||||
>::type register_formatter_factory(attribute_name const& attr_name, shared_ptr< FactoryT > const& factory)
|
||||
{
|
||||
typedef formatter_factory< typename FactoryT::char_type > factory_base;
|
||||
register_formatter_factory(attr_name, boost::static_pointer_cast< factory_base >(factory));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief The function registers a simple formatter factory
|
||||
*
|
||||
* The function registers a simple formatter factory. The registered factory will generate formatters
|
||||
* that will be equivalent to the <tt>log::expressions::attr</tt> formatter (i.e. that will use the
|
||||
* native \c operator<< to format the attribute value). The factory does not use any arguments from the format string,
|
||||
* if specified.
|
||||
*
|
||||
* \pre <tt>!!attr_name</tt>.
|
||||
*
|
||||
* \param attr_name Attribute name
|
||||
*/
|
||||
template< typename AttributeValueT, typename CharT >
|
||||
inline void register_simple_formatter_factory(attribute_name const& attr_name)
|
||||
{
|
||||
shared_ptr< formatter_factory< CharT > > factory =
|
||||
boost::make_shared< basic_formatter_factory< CharT, AttributeValueT > >();
|
||||
register_formatter_factory(attr_name, factory);
|
||||
}
|
||||
|
||||
/*!
|
||||
* The function parses a formatter from the sequence of characters
|
||||
*
|
||||
* \pre <tt>begin <= end</tt>, both pointers must not be NULL
|
||||
* \param begin Pointer to the first character of the sequence
|
||||
* \param end Pointer to the after-the-last character of the sequence
|
||||
* \return The parsed formatter.
|
||||
*
|
||||
* \b Throws: An <tt>std::exception</tt>-based exception, if a formatter cannot be recognized in the character sequence.
|
||||
*/
|
||||
template< typename CharT >
|
||||
BOOST_LOG_SETUP_API basic_formatter< CharT > parse_formatter(const CharT* begin, const CharT* end);
|
||||
|
||||
/*!
|
||||
* The function parses a formatter from the string
|
||||
*
|
||||
* \param str A string that contains format description
|
||||
* \return The parsed formatter.
|
||||
*
|
||||
* \b Throws: An <tt>std::exception</tt>-based exception, if a formatter cannot be recognized in the character sequence.
|
||||
*/
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT >
|
||||
inline basic_formatter< CharT > parse_formatter(std::basic_string< CharT, TraitsT, AllocatorT > const& str)
|
||||
{
|
||||
const CharT* p = str.c_str();
|
||||
return parse_formatter(p, p + str.size());
|
||||
}
|
||||
|
||||
/*!
|
||||
* The function parses a formatter from the string
|
||||
*
|
||||
* \pre <tt>str != NULL</tt>, <tt>str</tt> points to a zero-terminated string
|
||||
* \param str A string that contains format description.
|
||||
* \return The parsed formatter.
|
||||
*
|
||||
* \b Throws: An <tt>std::exception</tt>-based exception, if a formatter cannot be recognized in the character sequence.
|
||||
*/
|
||||
template< typename CharT >
|
||||
inline basic_formatter< CharT > parse_formatter(const CharT* str)
|
||||
{
|
||||
return parse_formatter(str, str + std::char_traits< CharT >::length(str));
|
||||
}
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_UTILITY_SETUP_FORMATTER_PARSER_HPP_INCLUDED_
|
||||
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* 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 from_settings.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 11.10.2009
|
||||
*
|
||||
* The header contains definition of facilities that allows to initialize the library from
|
||||
* settings.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_UTILITY_SETUP_FROM_SETTINGS_HPP_INCLUDED_
|
||||
#define BOOST_LOG_UTILITY_SETUP_FROM_SETTINGS_HPP_INCLUDED_
|
||||
|
||||
#include <string>
|
||||
#include <boost/smart_ptr/shared_ptr.hpp>
|
||||
#include <boost/core/enable_if.hpp>
|
||||
#include <boost/type_traits/is_base_and_derived.hpp>
|
||||
#include <boost/log/detail/setup_config.hpp>
|
||||
#include <boost/log/sinks/sink.hpp>
|
||||
#include <boost/log/utility/setup/settings.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
/*!
|
||||
* The function initializes the logging library from a settings container
|
||||
*
|
||||
* \param setts Library settings container
|
||||
*
|
||||
* \b Throws: An <tt>std::exception</tt>-based exception if the provided settings are not valid.
|
||||
*/
|
||||
template< typename CharT >
|
||||
BOOST_LOG_SETUP_API void init_from_settings(basic_settings_section< CharT > const& setts);
|
||||
|
||||
|
||||
/*!
|
||||
* Sink factory base interface
|
||||
*/
|
||||
template< typename CharT >
|
||||
struct sink_factory
|
||||
{
|
||||
//! Character type
|
||||
typedef CharT char_type;
|
||||
//! String type
|
||||
typedef std::basic_string< char_type > string_type;
|
||||
//! Settings section type
|
||||
typedef basic_settings_section< char_type > settings_section;
|
||||
|
||||
/*!
|
||||
* Default constructor
|
||||
*/
|
||||
BOOST_DEFAULTED_FUNCTION(sink_factory(), {})
|
||||
|
||||
/*!
|
||||
* Virtual destructor
|
||||
*/
|
||||
virtual ~sink_factory() {}
|
||||
|
||||
/*!
|
||||
* The function creates a formatter for the specified attribute.
|
||||
*
|
||||
* \param settings Sink parameters
|
||||
*/
|
||||
virtual shared_ptr< sinks::sink > create_sink(settings_section const& settings) = 0;
|
||||
|
||||
BOOST_DELETED_FUNCTION(sink_factory(sink_factory const&))
|
||||
BOOST_DELETED_FUNCTION(sink_factory& operator= (sink_factory const&))
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief The function registers a factory for a custom sink
|
||||
*
|
||||
* The function registers a factory for a sink. The factory will be called to create sink
|
||||
* instance when the parser discovers the specified sink type in the settings file. The
|
||||
* factory must accept a map of parameters [parameter name -> parameter value] that it
|
||||
* may use to initialize the sink. The factory must return a non-NULL pointer to the
|
||||
* constructed sink instance.
|
||||
*
|
||||
* \param sink_name The custom sink name. Must point to a zero-terminated sequence of characters,
|
||||
* must not be NULL.
|
||||
* \param factory Pointer to the custom sink factory. Must not be NULL.
|
||||
*/
|
||||
template< typename CharT >
|
||||
BOOST_LOG_SETUP_API void register_sink_factory(const char* sink_name, shared_ptr< sink_factory< CharT > > const& factory);
|
||||
|
||||
/*!
|
||||
* \brief The function registers a factory for a custom sink
|
||||
*
|
||||
* The function registers a factory for a sink. The factory will be called to create sink
|
||||
* instance when the parser discovers the specified sink type in the settings file. The
|
||||
* factory must accept a map of parameters [parameter name -> parameter value] that it
|
||||
* may use to initialize the sink. The factory must return a non-NULL pointer to the
|
||||
* constructed sink instance.
|
||||
*
|
||||
* \param sink_name The custom sink name
|
||||
* \param factory Pointer to the custom sink factory. Must not be NULL.
|
||||
*/
|
||||
template< typename CharT >
|
||||
inline void register_sink_factory(std::string const& sink_name, shared_ptr< sink_factory< CharT > > const& factory)
|
||||
{
|
||||
register_sink_factory(sink_name.c_str(), factory);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief The function registers a factory for a custom sink
|
||||
*
|
||||
* The function registers a factory for a sink. The factory will be called to create sink
|
||||
* instance when the parser discovers the specified sink type in the settings file. The
|
||||
* factory must accept a map of parameters [parameter name -> parameter value] that it
|
||||
* may use to initialize the sink. The factory must return a non-NULL pointer to the
|
||||
* constructed sink instance.
|
||||
*
|
||||
* \param sink_name The custom sink name. Must point to a zero-terminated sequence of characters,
|
||||
* must not be NULL.
|
||||
* \param factory Pointer to the custom sink factory. Must not be NULL.
|
||||
*/
|
||||
template< typename FactoryT >
|
||||
inline typename boost::enable_if_c<
|
||||
is_base_and_derived< sink_factory< typename FactoryT::char_type >, FactoryT >::value
|
||||
>::type register_sink_factory(const char* sink_name, shared_ptr< FactoryT > const& factory)
|
||||
{
|
||||
typedef sink_factory< typename FactoryT::char_type > factory_base;
|
||||
register_sink_factory(sink_name, boost::static_pointer_cast< factory_base >(factory));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief The function registers a factory for a custom sink
|
||||
*
|
||||
* The function registers a factory for a sink. The factory will be called to create sink
|
||||
* instance when the parser discovers the specified sink type in the settings file. The
|
||||
* factory must accept a map of parameters [parameter name -> parameter value] that it
|
||||
* may use to initialize the sink. The factory must return a non-NULL pointer to the
|
||||
* constructed sink instance.
|
||||
*
|
||||
* \param sink_name The custom sink name
|
||||
* \param factory Pointer to the custom sink factory. Must not be NULL.
|
||||
*/
|
||||
template< typename FactoryT >
|
||||
inline typename boost::enable_if_c<
|
||||
is_base_and_derived< sink_factory< typename FactoryT::char_type >, FactoryT >::value
|
||||
>::type register_sink_factory(std::string const& sink_name, shared_ptr< FactoryT > const& factory)
|
||||
{
|
||||
typedef sink_factory< typename FactoryT::char_type > factory_base;
|
||||
register_sink_factory(sink_name.c_str(), boost::static_pointer_cast< factory_base >(factory));
|
||||
}
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_UTILITY_SETUP_FROM_SETTINGS_HPP_INCLUDED_
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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 from_stream.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 22.03.2008
|
||||
*
|
||||
* The header contains definition of facilities that allows to initialize the library from a
|
||||
* settings file.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_UTILITY_SETUP_FROM_STREAM_HPP_INCLUDED_
|
||||
#define BOOST_LOG_UTILITY_SETUP_FROM_STREAM_HPP_INCLUDED_
|
||||
|
||||
#include <iosfwd>
|
||||
#include <boost/log/detail/setup_config.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
/*!
|
||||
* The function initializes the logging library from a stream containing logging settings
|
||||
*
|
||||
* \param strm Stream, that provides library settings
|
||||
*
|
||||
* \b Throws: An <tt>std::exception</tt>-based exception if the read data cannot be interpreted as the library settings
|
||||
*/
|
||||
template< typename CharT >
|
||||
BOOST_LOG_SETUP_API void init_from_stream(std::basic_istream< CharT >& strm);
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_UTILITY_SETUP_FROM_STREAM_HPP_INCLUDED_
|
||||
@@ -0,0 +1,643 @@
|
||||
/*
|
||||
* 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 settings.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 11.10.2009
|
||||
*
|
||||
* The header contains definition of the library settings container.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_UTILITY_SETUP_SETTINGS_HPP_INCLUDED_
|
||||
#define BOOST_LOG_UTILITY_SETUP_SETTINGS_HPP_INCLUDED_
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <iterator>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/iterator/iterator_adaptor.hpp>
|
||||
#include <boost/optional/optional.hpp>
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include <boost/log/detail/setup_config.hpp>
|
||||
#include <boost/log/detail/native_typeof.hpp>
|
||||
#include <boost/utility/explicit_operator_bool.hpp>
|
||||
#if !defined(BOOST_LOG_TYPEOF)
|
||||
#include <boost/core/enable_if.hpp>
|
||||
#endif
|
||||
#if defined(BOOST_LOG_TYPEOF) && defined(BOOST_NO_CXX11_TRAILING_RESULT_TYPES)
|
||||
#include <boost/utility/declval.hpp>
|
||||
#endif
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace aux {
|
||||
|
||||
// This workaround is needed for MSVC 10 to work around ICE caused by stack overflow
|
||||
template< typename SectionT, bool IsConstV >
|
||||
struct basic_settings_section_iterator_base;
|
||||
|
||||
template< typename SectionT >
|
||||
struct basic_settings_section_iterator_base< SectionT, true >
|
||||
{
|
||||
typedef typename SectionT::BOOST_NESTED_TEMPLATE iter< true > iterator_type;
|
||||
typedef typename SectionT::property_tree_type::const_iterator base_iterator_type;
|
||||
typedef iterator_adaptor<
|
||||
iterator_type,
|
||||
base_iterator_type,
|
||||
SectionT,
|
||||
use_default,
|
||||
const SectionT
|
||||
> type;
|
||||
};
|
||||
|
||||
template< typename SectionT >
|
||||
struct basic_settings_section_iterator_base< SectionT, false >
|
||||
{
|
||||
typedef typename SectionT::BOOST_NESTED_TEMPLATE iter< false > iterator_type;
|
||||
typedef typename SectionT::property_tree_type::iterator base_iterator_type;
|
||||
typedef iterator_adaptor<
|
||||
iterator_type,
|
||||
base_iterator_type,
|
||||
SectionT,
|
||||
use_default,
|
||||
SectionT
|
||||
> type;
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
/*!
|
||||
* \brief The class represents a reference to the settings container section
|
||||
*
|
||||
* The section refers to a sub-tree of the library settings container. It does not
|
||||
* own the referred sub-tree but allows for convenient access to parameters within the subsection.
|
||||
*/
|
||||
template< typename CharT >
|
||||
class basic_settings_section
|
||||
{
|
||||
template< typename SectionT, bool IsConstV >
|
||||
friend struct aux::basic_settings_section_iterator_base;
|
||||
|
||||
public:
|
||||
//! Character type
|
||||
typedef CharT char_type;
|
||||
//! String type
|
||||
typedef std::basic_string< char_type > string_type;
|
||||
//! Property tree type
|
||||
typedef property_tree::basic_ptree< std::string, string_type > property_tree_type;
|
||||
//! Property tree path type
|
||||
typedef typename property_tree_type::path_type path_type;
|
||||
|
||||
private:
|
||||
#if !defined(BOOST_LOG_DOXYGEN_PASS)
|
||||
|
||||
//! A reference proxy object
|
||||
#ifndef BOOST_LOG_NO_MEMBER_TEMPLATE_FRIENDS
|
||||
template< bool IsConstV >
|
||||
class ref;
|
||||
template< bool IsConstV >
|
||||
friend class ref;
|
||||
#endif
|
||||
template< bool IsConstV >
|
||||
class ref
|
||||
{
|
||||
private:
|
||||
typedef typename mpl::if_c<
|
||||
IsConstV,
|
||||
basic_settings_section< char_type > const,
|
||||
basic_settings_section< char_type >
|
||||
>::type section_type;
|
||||
|
||||
private:
|
||||
section_type& m_section;
|
||||
path_type m_path;
|
||||
|
||||
public:
|
||||
ref(section_type& section, std::string const& section_name) :
|
||||
m_section(section),
|
||||
m_path(section_name)
|
||||
{
|
||||
}
|
||||
ref(section_type& section, const char* section_name) :
|
||||
m_section(section),
|
||||
m_path(section_name)
|
||||
{
|
||||
}
|
||||
|
||||
ref& operator[] (std::string const& param_name)
|
||||
{
|
||||
m_path /= param_name;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ref& operator= (string_type const& value)
|
||||
{
|
||||
BOOST_ASSERT(m_section.m_ptree != NULL);
|
||||
m_section.m_ptree->put(m_path, value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template< bool V >
|
||||
ref& operator= (ref< V > const& value)
|
||||
{
|
||||
BOOST_ASSERT(m_section.m_ptree != NULL);
|
||||
optional< string_type > val = value.get();
|
||||
if (!!val)
|
||||
{
|
||||
m_section.m_ptree->put(m_path, val);
|
||||
}
|
||||
else if (optional< property_tree_type& > node = m_section.m_ptree->get_child_optional(m_path))
|
||||
{
|
||||
node.put_value(string_type());
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
ref& operator= (T const& value)
|
||||
{
|
||||
BOOST_ASSERT(m_section.m_ptree != NULL);
|
||||
m_section.m_ptree->put(m_path, value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
BOOST_EXPLICIT_OPERATOR_BOOL()
|
||||
|
||||
bool operator! () const
|
||||
{
|
||||
return !m_section.m_ptree || !m_section.m_ptree->get_child_optional(m_path);
|
||||
}
|
||||
|
||||
std::string get_name() const
|
||||
{
|
||||
return m_path.dump();
|
||||
}
|
||||
|
||||
operator optional< string_type > () const
|
||||
{
|
||||
return get();
|
||||
}
|
||||
|
||||
optional< string_type > get() const
|
||||
{
|
||||
if (m_section.m_ptree)
|
||||
return m_section.m_ptree->template get_optional< string_type >(m_path);
|
||||
else
|
||||
return optional< string_type >();
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
optional< T > get() const
|
||||
{
|
||||
if (m_section.m_ptree)
|
||||
return m_section.m_ptree->template get_optional< T >(m_path);
|
||||
else
|
||||
return optional< T >();
|
||||
}
|
||||
|
||||
operator section_type () const
|
||||
{
|
||||
return get_section();
|
||||
}
|
||||
|
||||
section_type get_section() const
|
||||
{
|
||||
if (m_section.m_ptree)
|
||||
return section_type(m_section.m_ptree->get_child_optional(m_path).get_ptr());
|
||||
else
|
||||
return section_type();
|
||||
}
|
||||
|
||||
#if defined(BOOST_LOG_TYPEOF) && !(defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(__clang__) && !defined(__PATHSCALE__) && !defined(__GXX_EXPERIMENTAL_CXX0X__) && (__GNUC__ == 4 && __GNUC_MINOR__ <= 5))
|
||||
#if !defined(BOOST_NO_CXX11_TRAILING_RESULT_TYPES)
|
||||
template< typename T >
|
||||
auto or_default(T const& def_value) const -> BOOST_LOG_TYPEOF(property_tree_type().get(typename property_tree_type::path_type(), def_value))
|
||||
{
|
||||
if (m_section.m_ptree)
|
||||
return m_section.m_ptree->get(m_path, def_value);
|
||||
else
|
||||
return def_value;
|
||||
}
|
||||
#else
|
||||
// GCC up to 4.5 (inclusively) segfaults on the following code, if C++11 mode is not enabled
|
||||
template< typename T >
|
||||
BOOST_LOG_TYPEOF(property_tree_type().get(typename property_tree_type::path_type(), boost::declval< T >())) or_default(T const& def_value) const
|
||||
{
|
||||
if (m_section.m_ptree)
|
||||
return m_section.m_ptree->get(m_path, def_value);
|
||||
else
|
||||
return def_value;
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
template< typename T >
|
||||
T or_default(T const& def_value) const
|
||||
{
|
||||
if (m_section.m_ptree)
|
||||
return m_section.m_ptree->get(m_path, def_value);
|
||||
else
|
||||
return def_value;
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
typename boost::enable_if_c< boost::property_tree::detail::is_character< T >::value, std::basic_string< T > >::type
|
||||
or_default(const T* def_value) const
|
||||
{
|
||||
if (m_section.m_ptree)
|
||||
return m_section.m_ptree->get(m_path, def_value);
|
||||
else
|
||||
return def_value;
|
||||
}
|
||||
#endif
|
||||
string_type or_default(string_type const& def_value) const
|
||||
{
|
||||
return get().get_value_or(def_value);
|
||||
}
|
||||
string_type or_default(typename string_type::value_type const* def_value) const
|
||||
{
|
||||
if (optional< string_type > val = get())
|
||||
return val.get();
|
||||
else
|
||||
return def_value;
|
||||
}
|
||||
};
|
||||
|
||||
//! An iterator over subsections and parameters
|
||||
#ifndef BOOST_LOG_NO_MEMBER_TEMPLATE_FRIENDS
|
||||
template< bool IsConstV >
|
||||
class iter;
|
||||
template< bool IsConstV >
|
||||
friend class iter;
|
||||
#endif
|
||||
template< bool IsConstV >
|
||||
class iter :
|
||||
public aux::basic_settings_section_iterator_base< basic_settings_section< char_type >, IsConstV >::type
|
||||
{
|
||||
friend class boost::iterator_core_access;
|
||||
|
||||
typedef typename iter::iterator_adaptor_ iterator_adaptor_;
|
||||
// NOTE: This typedef must not come from iterator_adaptor_::base_type in order to work around MSVC 10 ICE
|
||||
typedef typename aux::basic_settings_section_iterator_base< basic_settings_section< char_type >, IsConstV >::base_iterator_type base_iterator_type;
|
||||
|
||||
public:
|
||||
typedef typename iterator_adaptor_::reference reference;
|
||||
|
||||
public:
|
||||
BOOST_DEFAULTED_FUNCTION(iter(), {})
|
||||
template< bool OtherIsConstV >
|
||||
iter(iter< OtherIsConstV > const& that) : iterator_adaptor_(that.base()) {}
|
||||
explicit iter(base_iterator_type const& it) : iterator_adaptor_(it) {}
|
||||
|
||||
//! Returns the section name
|
||||
std::string const& get_name() const
|
||||
{
|
||||
return this->base()->first;
|
||||
}
|
||||
|
||||
private:
|
||||
reference dereference() const
|
||||
{
|
||||
return reference(const_cast< property_tree_type* >(&this->base()->second));
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
typedef ref< true > const_reference;
|
||||
typedef ref< false > reference;
|
||||
typedef iter< true > const_iterator;
|
||||
typedef iter< false > iterator;
|
||||
typedef std::reverse_iterator< const_iterator > const_reverse_iterator;
|
||||
typedef std::reverse_iterator< iterator > reverse_iterator;
|
||||
|
||||
#else
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Constant reference to the parameter value
|
||||
*/
|
||||
typedef implementation_defined const_reference;
|
||||
/*!
|
||||
* Mutable reference to the parameter value
|
||||
*/
|
||||
typedef implementation_defined reference;
|
||||
|
||||
/*!
|
||||
* Constant iterator over nested parameters and subsections
|
||||
*/
|
||||
typedef implementation_defined const_iterator;
|
||||
/*!
|
||||
* Mutable iterator over nested parameters and subsections
|
||||
*/
|
||||
typedef implementation_defined iterator;
|
||||
|
||||
#endif // !defined(BOOST_LOG_DOXYGEN_PASS)
|
||||
|
||||
protected:
|
||||
//! Parameters
|
||||
property_tree_type* m_ptree;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Default constructor. Creates an empty settings container.
|
||||
*/
|
||||
basic_settings_section() : m_ptree(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* Copy constructor.
|
||||
*/
|
||||
basic_settings_section(basic_settings_section const& that) : m_ptree(that.m_ptree)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* Checks if the section refers to the container.
|
||||
*/
|
||||
BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
|
||||
|
||||
/*!
|
||||
* Checks if the section refers to the container.
|
||||
*/
|
||||
bool operator! () const BOOST_NOEXCEPT { return !m_ptree; }
|
||||
|
||||
/*!
|
||||
* Returns an iterator over the nested subsections and parameters.
|
||||
*/
|
||||
iterator begin()
|
||||
{
|
||||
if (m_ptree)
|
||||
return iterator(m_ptree->begin());
|
||||
else
|
||||
return iterator();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns an iterator over the nested subsections and parameters.
|
||||
*/
|
||||
iterator end()
|
||||
{
|
||||
if (m_ptree)
|
||||
return iterator(m_ptree->end());
|
||||
else
|
||||
return iterator();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns an iterator over the nested subsections and parameters.
|
||||
*/
|
||||
const_iterator begin() const
|
||||
{
|
||||
if (m_ptree)
|
||||
return const_iterator(m_ptree->begin());
|
||||
else
|
||||
return const_iterator();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns an iterator over the nested subsections and parameters.
|
||||
*/
|
||||
const_iterator end() const
|
||||
{
|
||||
if (m_ptree)
|
||||
return const_iterator(m_ptree->end());
|
||||
else
|
||||
return const_iterator();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns a reverse iterator over the nested subsections and parameters.
|
||||
*/
|
||||
reverse_iterator rbegin() { return reverse_iterator(begin()); }
|
||||
|
||||
/*!
|
||||
* Returns a reverse iterator over the nested subsections and parameters.
|
||||
*/
|
||||
reverse_iterator rend() { return reverse_iterator(end()); }
|
||||
|
||||
/*!
|
||||
* Returns a reverse iterator over the nested subsections and parameters.
|
||||
*/
|
||||
const_reverse_iterator rbegin() const { return const_reverse_iterator(begin()); }
|
||||
|
||||
/*!
|
||||
* Returns a reverse iterator over the nested subsections and parameters.
|
||||
*/
|
||||
const_reverse_iterator rend() const { return const_reverse_iterator(end()); }
|
||||
|
||||
/*!
|
||||
* Checks if the container is empty (i.e. contains no sections and parameters).
|
||||
*/
|
||||
bool empty() const { return m_ptree == NULL || m_ptree->empty(); }
|
||||
|
||||
/*!
|
||||
* Accessor to a single parameter. This operator should be used in conjunction
|
||||
* with the subsequent subscript operator that designates the parameter name.
|
||||
*
|
||||
* \param section_name The name of the section in which the parameter resides
|
||||
* \return An unspecified reference type that can be used for parameter name specifying
|
||||
*/
|
||||
reference operator[] (std::string const& section_name) { return reference(*this, section_name); }
|
||||
/*!
|
||||
* Accessor to a single parameter. This operator should be used in conjunction
|
||||
* with the subsequent subscript operator that designates the parameter name.
|
||||
*
|
||||
* \param section_name The name of the section in which the parameter resides
|
||||
* \return An unspecified reference type that can be used for parameter name specifying
|
||||
*/
|
||||
const_reference operator[] (std::string const& section_name) const { return const_reference(*this, section_name); }
|
||||
|
||||
/*!
|
||||
* Accessor to a single parameter. This operator should be used in conjunction
|
||||
* with the subsequent subscript operator that designates the parameter name.
|
||||
*
|
||||
* \param section_name The name of the section in which the parameter resides
|
||||
* \return An unspecified reference type that can be used for parameter name specifying
|
||||
*/
|
||||
reference operator[] (const char* section_name) { return reference(*this, section_name); }
|
||||
/*!
|
||||
* Accessor to a single parameter. This operator should be used in conjunction
|
||||
* with the subsequent subscript operator that designates the parameter name.
|
||||
*
|
||||
* \param section_name The name of the section in which the parameter resides
|
||||
* \return An unspecified reference type that can be used for parameter name specifying
|
||||
*/
|
||||
const_reference operator[] (const char* section_name) const { return const_reference(*this, section_name); }
|
||||
|
||||
/*!
|
||||
* Accessor for the embedded property tree
|
||||
*/
|
||||
property_tree_type const& property_tree() const { return *m_ptree; }
|
||||
/*!
|
||||
* Accessor for the embedded property tree
|
||||
*/
|
||||
property_tree_type& property_tree() { return *m_ptree; }
|
||||
|
||||
/*!
|
||||
* Checks if the specified section is present in the container.
|
||||
*
|
||||
* \param section_name The name of the section
|
||||
*/
|
||||
bool has_section(string_type const& section_name) const
|
||||
{
|
||||
return m_ptree != NULL && !!m_ptree->get_child_optional(section_name);
|
||||
}
|
||||
/*!
|
||||
* Checks if the specified parameter is present in the container.
|
||||
*
|
||||
* \param section_name The name of the section in which the parameter resides
|
||||
* \param param_name The name of the parameter
|
||||
*/
|
||||
bool has_parameter(string_type const& section_name, string_type const& param_name) const
|
||||
{
|
||||
if (m_ptree)
|
||||
{
|
||||
optional< property_tree_type& > section = m_ptree->get_child_optional(section_name);
|
||||
if (!!section)
|
||||
return (section->find(param_name) != section->not_found());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Swaps two references to settings sections.
|
||||
*/
|
||||
void swap(basic_settings_section& that)
|
||||
{
|
||||
property_tree_type* const p = m_ptree;
|
||||
m_ptree = that.m_ptree;
|
||||
that.m_ptree = p;
|
||||
}
|
||||
|
||||
protected:
|
||||
explicit basic_settings_section(property_tree_type* tree) : m_ptree(tree)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template< typename CharT >
|
||||
inline void swap(basic_settings_section< CharT >& left, basic_settings_section< CharT >& right)
|
||||
{
|
||||
left.swap(right);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* \brief The class represents settings container
|
||||
*
|
||||
* All settings are presented as a number of named parameters divided into named sections.
|
||||
* The parameters values are stored as strings. Individual parameters may be queried via subscript operators, like this:
|
||||
*
|
||||
* <code><pre>
|
||||
* optional< string > param = settings["Section1"]["Param1"]; // reads parameter "Param1" in section "Section1"
|
||||
* // returns an empty value if no such parameter exists
|
||||
* settings["Section2"]["Param2"] = 10; // sets the parameter "Param2" in section "Section2"
|
||||
* // to value "10"
|
||||
* </pre></code>
|
||||
*
|
||||
* There are also other methods to work with parameters.
|
||||
*/
|
||||
template< typename CharT >
|
||||
class basic_settings :
|
||||
public basic_settings_section< CharT >
|
||||
{
|
||||
typedef basic_settings this_type;
|
||||
BOOST_COPYABLE_AND_MOVABLE(this_type)
|
||||
|
||||
public:
|
||||
//! Section type
|
||||
typedef basic_settings_section< CharT > section;
|
||||
//! Property tree type
|
||||
typedef typename section::property_tree_type property_tree_type;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Default constructor. Creates an empty settings container.
|
||||
*/
|
||||
basic_settings() : section(new property_tree_type())
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* Copy constructor.
|
||||
*/
|
||||
basic_settings(basic_settings const& that) :
|
||||
section(that.m_ptree ? new property_tree_type(*that.m_ptree) : static_cast< property_tree_type* >(NULL))
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* Move constructor.
|
||||
*/
|
||||
basic_settings(BOOST_RV_REF(this_type) that)
|
||||
{
|
||||
this->swap(that);
|
||||
}
|
||||
/*!
|
||||
* Initializing constructor. Creates a settings container with the copy of the specified property tree.
|
||||
*/
|
||||
explicit basic_settings(property_tree_type const& tree) : section(new property_tree_type(tree))
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* Destructor
|
||||
*/
|
||||
~basic_settings()
|
||||
{
|
||||
delete this->m_ptree;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Copy assignment operator.
|
||||
*/
|
||||
basic_settings& operator= (BOOST_COPY_ASSIGN_REF(basic_settings) that)
|
||||
{
|
||||
if (this != &that)
|
||||
{
|
||||
basic_settings tmp = that;
|
||||
this->swap(tmp);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
/*!
|
||||
* Move assignment operator.
|
||||
*/
|
||||
basic_settings& operator= (BOOST_RV_REF(basic_settings) that)
|
||||
{
|
||||
this->swap(that);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef BOOST_LOG_USE_CHAR
|
||||
typedef basic_settings< char > settings; //!< Convenience typedef for narrow-character logging
|
||||
typedef basic_settings_section< char > settings_section; //!< Convenience typedef for narrow-character logging
|
||||
#endif
|
||||
#ifdef BOOST_LOG_USE_WCHAR_T
|
||||
typedef basic_settings< wchar_t > wsettings; //!< Convenience typedef for wide-character logging
|
||||
typedef basic_settings_section< wchar_t > wsettings_section; //!< Convenience typedef for wide-character logging
|
||||
#endif
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_UTILITY_SETUP_SETTINGS_HPP_INCLUDED_
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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 settings_parser.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 20.07.2012
|
||||
*
|
||||
* The header contains definition of a settings parser function.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_UTILITY_SETUP_SETTINGS_PARSER_HPP_INCLUDED_
|
||||
#define BOOST_LOG_UTILITY_SETUP_SETTINGS_PARSER_HPP_INCLUDED_
|
||||
|
||||
#include <iosfwd>
|
||||
#include <boost/log/detail/setup_config.hpp>
|
||||
#include <boost/log/utility/setup/settings.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
/*!
|
||||
* The function parses library settings from an input stream
|
||||
*
|
||||
* \param strm Stream, that provides library settings
|
||||
*
|
||||
* \b Throws: An <tt>std::exception</tt>-based exception if the read data cannot be interpreted as the library settings
|
||||
*/
|
||||
template< typename CharT >
|
||||
BOOST_LOG_SETUP_API basic_settings< CharT > parse_settings(std::basic_istream< CharT >& strm);
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_UTILITY_SETUP_SETTINGS_PARSER_HPP_INCLUDED_
|
||||
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
* Copyright Andrey Semashev 2007 - 2015.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
/*!
|
||||
* \file utility/strictest_lock.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 30.05.2010
|
||||
*
|
||||
* The header contains definition of the \c strictest_lock metafunction that
|
||||
* allows to select a lock with the strictest access requirements.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_UTILITY_STRICTEST_LOCK_HPP_INCLUDED_
|
||||
#define BOOST_LOG_UTILITY_STRICTEST_LOCK_HPP_INCLUDED_
|
||||
|
||||
#include <boost/mpl/integral_c.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/locks.hpp>
|
||||
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/preprocessor/arithmetic/sub.hpp>
|
||||
#include <boost/preprocessor/arithmetic/inc.hpp>
|
||||
#include <boost/preprocessor/arithmetic/dec.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_trailing.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
|
||||
#include <boost/log/detail/pp_identity.hpp>
|
||||
#endif
|
||||
#if defined(BOOST_LOG_BROKEN_CONSTANT_EXPRESSIONS)
|
||||
#include <boost/mpl/less.hpp>
|
||||
#endif
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_LOG_STRICTEST_LOCK_LIMIT)
|
||||
/*!
|
||||
* The macro defines the maximum number of template arguments that the \c strictest_lock
|
||||
* metafunction accepts. Should not be less than 2.
|
||||
*/
|
||||
#define BOOST_LOG_STRICTEST_LOCK_LIMIT 10
|
||||
#endif // BOOST_LOG_STRICTEST_LOCK_LIMIT
|
||||
#if BOOST_LOG_STRICTEST_LOCK_LIMIT < 2
|
||||
#error The BOOST_LOG_STRICTEST_LOCK_LIMIT macro should not be less than 2
|
||||
#endif
|
||||
#endif // defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
//! Access modes for different types of locks
|
||||
enum lock_access_mode
|
||||
{
|
||||
unlocked_access, //!< A thread that owns this kind of lock doesn't restrict other threads in any way
|
||||
shared_access, //!< A thread that owns this kind of lock requires that no other thread modify the locked data
|
||||
exclusive_access //!< A thread that owns this kind of lock requires that no other thread has access to the locked data
|
||||
};
|
||||
|
||||
//! The trait allows to select an access mode by the lock type
|
||||
template< typename LockT >
|
||||
struct thread_access_mode_of;
|
||||
|
||||
template< typename MutexT >
|
||||
struct thread_access_mode_of< no_lock< MutexT > > : mpl::integral_c< lock_access_mode, unlocked_access >
|
||||
{
|
||||
};
|
||||
|
||||
#if !defined(BOOST_LOG_NO_THREADS)
|
||||
|
||||
template< typename MutexT >
|
||||
struct thread_access_mode_of< lock_guard< MutexT > > : mpl::integral_c< lock_access_mode, exclusive_access >
|
||||
{
|
||||
};
|
||||
|
||||
template< typename MutexT >
|
||||
struct thread_access_mode_of< shared_lock_guard< MutexT > > : mpl::integral_c< lock_access_mode, shared_access >
|
||||
{
|
||||
};
|
||||
|
||||
template< typename MutexT >
|
||||
struct thread_access_mode_of< unique_lock< MutexT > > : mpl::integral_c< lock_access_mode, exclusive_access >
|
||||
{
|
||||
};
|
||||
|
||||
template< typename MutexT >
|
||||
struct thread_access_mode_of< shared_lock< MutexT > > : mpl::integral_c< lock_access_mode, shared_access >
|
||||
{
|
||||
};
|
||||
|
||||
template< typename MutexT >
|
||||
struct thread_access_mode_of< upgrade_lock< MutexT > > : mpl::integral_c< lock_access_mode, shared_access >
|
||||
{
|
||||
};
|
||||
|
||||
template< typename MutexT >
|
||||
struct thread_access_mode_of< boost::log::aux::exclusive_lock_guard< MutexT > > : mpl::integral_c< lock_access_mode, exclusive_access >
|
||||
{
|
||||
};
|
||||
|
||||
template< typename MutexT >
|
||||
struct thread_access_mode_of< boost::log::aux::shared_lock_guard< MutexT > > : mpl::integral_c< lock_access_mode, shared_access >
|
||||
{
|
||||
};
|
||||
|
||||
#endif // !defined(BOOST_LOG_NO_THREADS)
|
||||
|
||||
namespace aux {
|
||||
|
||||
//! The metafunction selects the most strict lock type of the two
|
||||
template<
|
||||
typename LeftLockT,
|
||||
typename RightLockT,
|
||||
#if !defined(BOOST_LOG_BROKEN_CONSTANT_EXPRESSIONS)
|
||||
bool CondV = (thread_access_mode_of< LeftLockT >::value < thread_access_mode_of< RightLockT >::value)
|
||||
#else
|
||||
bool CondV = mpl::less< thread_access_mode_of< LeftLockT >, thread_access_mode_of< RightLockT > >::value
|
||||
#endif
|
||||
>
|
||||
struct strictest_lock_impl
|
||||
{
|
||||
typedef RightLockT type;
|
||||
};
|
||||
template< typename LeftLockT, typename RightLockT >
|
||||
struct strictest_lock_impl< LeftLockT, RightLockT, false >
|
||||
{
|
||||
typedef LeftLockT type;
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
#if defined(BOOST_LOG_DOXYGEN_PASS)
|
||||
|
||||
/*!
|
||||
* \brief The metafunction selects the most strict lock type of the specified.
|
||||
*
|
||||
* The template supports all lock types provided by the Boost.Thread
|
||||
* library (except for \c upgrade_to_unique_lock), plus additional
|
||||
* pseudo-lock \c no_lock that indicates no locking at all.
|
||||
* Exclusive locks are considered the strictest, shared locks are weaker,
|
||||
* and \c no_lock is the weakest.
|
||||
*/
|
||||
template< typename... LocksT >
|
||||
struct strictest_lock
|
||||
{
|
||||
typedef implementation_defined type;
|
||||
};
|
||||
|
||||
#else // defined(BOOST_LOG_DOXYGEN_PASS)
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
template< typename LockT, typename... LocksT >
|
||||
struct strictest_lock;
|
||||
|
||||
template< typename LockT >
|
||||
struct strictest_lock< LockT >
|
||||
{
|
||||
typedef LockT type;
|
||||
};
|
||||
|
||||
template< typename LeftLockT, typename RightLockT >
|
||||
struct strictest_lock< LeftLockT, RightLockT >
|
||||
{
|
||||
typedef typename aux::strictest_lock_impl< LeftLockT, RightLockT >::type type;
|
||||
};
|
||||
|
||||
template< typename LeftLockT, typename RightLockT, typename... LocksT >
|
||||
struct strictest_lock< LeftLockT, RightLockT, LocksT... >
|
||||
{
|
||||
typedef typename strictest_lock<
|
||||
typename aux::strictest_lock_impl< LeftLockT, RightLockT >::type,
|
||||
LocksT...
|
||||
>::type type;
|
||||
};
|
||||
|
||||
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
# define BOOST_LOG_TYPE_INTERNAL(z, i, data) BOOST_PP_CAT(T, BOOST_PP_INC(i))
|
||||
|
||||
template<
|
||||
typename T,
|
||||
BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PP_DEC(BOOST_LOG_STRICTEST_LOCK_LIMIT), typename T, void)
|
||||
>
|
||||
struct strictest_lock
|
||||
{
|
||||
typedef typename strictest_lock<
|
||||
typename boost::log::aux::strictest_lock_impl< T, T0 >::type
|
||||
BOOST_PP_ENUM_TRAILING(BOOST_PP_SUB(BOOST_LOG_STRICTEST_LOCK_LIMIT, 2), BOOST_LOG_TYPE_INTERNAL, ~)
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
struct strictest_lock<
|
||||
T
|
||||
BOOST_PP_ENUM_TRAILING(BOOST_PP_DEC(BOOST_LOG_STRICTEST_LOCK_LIMIT), BOOST_LOG_PP_IDENTITY, void)
|
||||
>
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
# undef BOOST_LOG_TYPE_INTERNAL
|
||||
|
||||
#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
#endif // defined(BOOST_LOG_DOXYGEN_PASS)
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_UTILITY_STRICTEST_LOCK_HPP_INCLUDED_
|
||||
@@ -0,0 +1,711 @@
|
||||
/*
|
||||
* 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 string_literal.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 24.06.2007
|
||||
*
|
||||
* The header contains implementation of a constant string literal wrapper.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_UTILITY_STRING_LITERAL_HPP_INCLUDED_
|
||||
#define BOOST_LOG_UTILITY_STRING_LITERAL_HPP_INCLUDED_
|
||||
|
||||
#include <cstddef>
|
||||
#include <stdexcept>
|
||||
#include <iosfwd>
|
||||
#include <ios> // std::streamsize
|
||||
#include <string>
|
||||
#include <iterator>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/utility/string_literal_fwd.hpp>
|
||||
#include <boost/log/detail/sfinae_tools.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
/*!
|
||||
* \brief String literal wrapper
|
||||
*
|
||||
* The \c basic_string_literal is a thin wrapper around a constant string literal.
|
||||
* It provides interface similar to STL strings, but because of read-only nature
|
||||
* of string literals, lacks ability to modify string contents. However,
|
||||
* \c basic_string_literal objects can be assigned to and cleared.
|
||||
*
|
||||
* The main advantage of this class comparing to other string classes is that
|
||||
* it doesn't dynamically allocate memory and therefore is fast, thin and exception safe.
|
||||
*/
|
||||
template< typename CharT, typename TraitsT >
|
||||
class basic_string_literal
|
||||
{
|
||||
//! Self type
|
||||
typedef basic_string_literal< CharT, TraitsT > this_type;
|
||||
|
||||
public:
|
||||
typedef CharT value_type;
|
||||
typedef TraitsT traits_type;
|
||||
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef const value_type* const_pointer;
|
||||
typedef value_type const& const_reference;
|
||||
typedef const value_type* const_iterator;
|
||||
typedef std::reverse_iterator< const_iterator > const_reverse_iterator;
|
||||
|
||||
//! Corresponding STL string type
|
||||
typedef std::basic_string< value_type, traits_type > string_type;
|
||||
|
||||
private:
|
||||
//! Pointer to the beginning of the literal
|
||||
const_pointer m_pStart;
|
||||
//! Length
|
||||
size_type m_Len;
|
||||
|
||||
//! Empty string literal to support \c clear
|
||||
#if !defined(BOOST_LOG_NO_CXX11_CONSTEXPR_DATA_MEMBER_BRACE_INITIALIZERS)
|
||||
static constexpr value_type g_EmptyString[1] = { 0 };
|
||||
#else
|
||||
static const value_type g_EmptyString[1];
|
||||
#endif
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Constructor
|
||||
*
|
||||
* \post <tt>empty() == true</tt>
|
||||
*/
|
||||
BOOST_CONSTEXPR basic_string_literal() BOOST_NOEXCEPT : m_pStart(g_EmptyString), m_Len(0) { }
|
||||
|
||||
/*!
|
||||
* Constructor from a string literal
|
||||
*
|
||||
* \post <tt>*this == p</tt>
|
||||
* \param p A zero-terminated constant sequence of characters
|
||||
*/
|
||||
template< typename T, size_type LenV >
|
||||
BOOST_CONSTEXPR basic_string_literal(T(&p)[LenV]
|
||||
//! \cond
|
||||
, typename boost::enable_if_c< is_same< T, const value_type >::value, boost::log::aux::sfinae_dummy >::type = boost::log::aux::sfinae_dummy()
|
||||
//! \endcond
|
||||
) BOOST_NOEXCEPT
|
||||
: m_pStart(p), m_Len(LenV - 1)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* Copy constructor
|
||||
*
|
||||
* \post <tt>*this == that</tt>
|
||||
* \param that Source literal to copy string from
|
||||
*/
|
||||
BOOST_CONSTEXPR basic_string_literal(basic_string_literal const& that) BOOST_NOEXCEPT : m_pStart(that.m_pStart), m_Len(that.m_Len) {}
|
||||
|
||||
/*!
|
||||
* Assignment operator
|
||||
*
|
||||
* \post <tt>*this == that</tt>
|
||||
* \param that Source literal to copy string from
|
||||
*/
|
||||
BOOST_CXX14_CONSTEXPR this_type& operator= (this_type const& that) BOOST_NOEXCEPT
|
||||
{
|
||||
return assign(that);
|
||||
}
|
||||
/*!
|
||||
* Assignment from a string literal
|
||||
*
|
||||
* \post <tt>*this == p</tt>
|
||||
* \param p A zero-terminated constant sequence of characters
|
||||
*/
|
||||
template< typename T, size_type LenV >
|
||||
BOOST_CXX14_CONSTEXPR
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
typename boost::enable_if_c<
|
||||
is_same< T, const value_type >::value,
|
||||
this_type&
|
||||
>::type
|
||||
#else
|
||||
this_type&
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
operator= (T(&p)[LenV]) BOOST_NOEXCEPT
|
||||
{
|
||||
return assign(p);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Lexicographical comparison (equality)
|
||||
*
|
||||
* \param that Comparand
|
||||
* \return \c true if the comparand string equals to this string, \c false otherwise
|
||||
*/
|
||||
bool operator== (this_type const& that) const BOOST_NOEXCEPT
|
||||
{
|
||||
return (compare_internal(m_pStart, m_Len, that.m_pStart, that.m_Len) == 0);
|
||||
}
|
||||
/*!
|
||||
* Lexicographical comparison (equality)
|
||||
*
|
||||
* \param str Comparand. Must point to a zero-terminated sequence of characters, must not be NULL.
|
||||
* \return \c true if the comparand string equals to this string, \c false otherwise
|
||||
*/
|
||||
bool operator== (const_pointer str) const BOOST_NOEXCEPT
|
||||
{
|
||||
return (compare_internal(m_pStart, m_Len, str, traits_type::length(str)) == 0);
|
||||
}
|
||||
/*!
|
||||
* Lexicographical comparison (equality)
|
||||
*
|
||||
* \param that Comparand
|
||||
* \return \c true if the comparand string equals to this string, \c false otherwise
|
||||
*/
|
||||
bool operator== (string_type const& that) const BOOST_NOEXCEPT
|
||||
{
|
||||
return (compare_internal(m_pStart, m_Len, that.c_str(), that.size()) == 0);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Lexicographical comparison (inequality)
|
||||
*
|
||||
* \param that Comparand
|
||||
* \return \c true if the comparand string is not equal to this string, \c false otherwise
|
||||
*/
|
||||
bool operator!= (this_type const& that) const BOOST_NOEXCEPT
|
||||
{
|
||||
return (compare_internal(m_pStart, m_Len, that.m_pStart, that.m_Len) != 0);
|
||||
}
|
||||
/*!
|
||||
* Lexicographical comparison (inequality)
|
||||
*
|
||||
* \param str Comparand. Must point to a zero-terminated sequence of characters, must not be NULL.
|
||||
* \return \c true if the comparand string is not equal to this string, \c false otherwise
|
||||
*/
|
||||
bool operator!= (const_pointer str) const BOOST_NOEXCEPT
|
||||
{
|
||||
return (compare_internal(m_pStart, m_Len, str, traits_type::length(str)) != 0);
|
||||
}
|
||||
/*!
|
||||
* Lexicographical comparison (inequality)
|
||||
*
|
||||
* \param that Comparand
|
||||
* \return \c true if the comparand string is not equal to this string, \c false otherwise
|
||||
*/
|
||||
bool operator!= (string_type const& that) const BOOST_NOEXCEPT
|
||||
{
|
||||
return (compare_internal(m_pStart, m_Len, that.c_str(), that.size()) != 0);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Lexicographical comparison (less ordering)
|
||||
*
|
||||
* \param that Comparand
|
||||
* \return \c true if this string is less than the comparand, \c false otherwise
|
||||
*/
|
||||
bool operator< (this_type const& that) const BOOST_NOEXCEPT
|
||||
{
|
||||
return (compare_internal(m_pStart, m_Len, that.m_pStart, that.m_Len) < 0);
|
||||
}
|
||||
/*!
|
||||
* Lexicographical comparison (less ordering)
|
||||
*
|
||||
* \param str Comparand. Must point to a zero-terminated sequence of characters, must not be NULL.
|
||||
* \return \c true if this string is less than the comparand, \c false otherwise
|
||||
*/
|
||||
bool operator< (const_pointer str) const BOOST_NOEXCEPT
|
||||
{
|
||||
return (compare_internal(m_pStart, m_Len, str, traits_type::length(str)) < 0);
|
||||
}
|
||||
/*!
|
||||
* Lexicographical comparison (less ordering)
|
||||
*
|
||||
* \param that Comparand
|
||||
* \return \c true if this string is less than the comparand, \c false otherwise
|
||||
*/
|
||||
bool operator< (string_type const& that) const BOOST_NOEXCEPT
|
||||
{
|
||||
return (compare_internal(m_pStart, m_Len, that.c_str(), that.size()) < 0);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Lexicographical comparison (less or equal ordering)
|
||||
*
|
||||
* \param that Comparand
|
||||
* \return \c true if this string is less or equal to the comparand, \c false otherwise
|
||||
*/
|
||||
bool operator<= (this_type const& that) const BOOST_NOEXCEPT
|
||||
{
|
||||
return (compare_internal(m_pStart, m_Len, that.m_pStart, that.m_Len) <= 0);
|
||||
}
|
||||
/*!
|
||||
* Lexicographical comparison (less or equal ordering)
|
||||
*
|
||||
* \param str Comparand. Must point to a zero-terminated sequence of characters, must not be NULL.
|
||||
* \return \c true if this string is less or equal to the comparand, \c false otherwise
|
||||
*/
|
||||
bool operator<= (const_pointer str) const BOOST_NOEXCEPT
|
||||
{
|
||||
return (compare_internal(m_pStart, m_Len, str, traits_type::length(str)) <= 0);
|
||||
}
|
||||
/*!
|
||||
* Lexicographical comparison (less or equal ordering)
|
||||
*
|
||||
* \param that Comparand
|
||||
* \return \c true if this string is less or equal to the comparand, \c false otherwise
|
||||
*/
|
||||
bool operator<= (string_type const& that) const BOOST_NOEXCEPT
|
||||
{
|
||||
return (compare_internal(m_pStart, m_Len, that.c_str(), that.size()) <= 0);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Lexicographical comparison (greater ordering)
|
||||
*
|
||||
* \param that Comparand
|
||||
* \return \c true if this string is greater than the comparand, \c false otherwise
|
||||
*/
|
||||
bool operator> (this_type const& that) const BOOST_NOEXCEPT
|
||||
{
|
||||
return (compare_internal(m_pStart, m_Len, that.m_pStart, that.m_Len) > 0);
|
||||
}
|
||||
/*!
|
||||
* Lexicographical comparison (greater ordering)
|
||||
*
|
||||
* \param str Comparand. Must point to a zero-terminated sequence of characters, must not be NULL.
|
||||
* \return \c true if this string is greater than the comparand, \c false otherwise
|
||||
*/
|
||||
bool operator> (const_pointer str) const BOOST_NOEXCEPT
|
||||
{
|
||||
return (compare_internal(m_pStart, m_Len, str, traits_type::length(str)) > 0);
|
||||
}
|
||||
/*!
|
||||
* Lexicographical comparison (greater ordering)
|
||||
*
|
||||
* \param that Comparand
|
||||
* \return \c true if this string is greater than the comparand, \c false otherwise
|
||||
*/
|
||||
bool operator> (string_type const& that) const BOOST_NOEXCEPT
|
||||
{
|
||||
return (compare_internal(m_pStart, m_Len, that.c_str(), that.size()) > 0);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Lexicographical comparison (greater or equal ordering)
|
||||
*
|
||||
* \param that Comparand
|
||||
* \return \c true if this string is greater or equal to the comparand, \c false otherwise
|
||||
*/
|
||||
bool operator>= (this_type const& that) const BOOST_NOEXCEPT
|
||||
{
|
||||
return (compare_internal(m_pStart, m_Len, that.m_pStart, that.m_Len) >= 0);
|
||||
}
|
||||
/*!
|
||||
* Lexicographical comparison (greater or qual ordering)
|
||||
*
|
||||
* \param str Comparand. Must point to a zero-terminated sequence of characters, must not be NULL.
|
||||
* \return \c true if this string is greater or equal to the comparand, \c false otherwise
|
||||
*/
|
||||
bool operator>= (const_pointer str) const BOOST_NOEXCEPT
|
||||
{
|
||||
return (compare_internal(m_pStart, m_Len, str, traits_type::length(str)) >= 0);
|
||||
}
|
||||
/*!
|
||||
* Lexicographical comparison (greater or equal ordering)
|
||||
*
|
||||
* \param that Comparand
|
||||
* \return \c true if this string is greater or equal to the comparand, \c false otherwise
|
||||
*/
|
||||
bool operator>= (string_type const& that) const BOOST_NOEXCEPT
|
||||
{
|
||||
return (compare_internal(m_pStart, m_Len, that.c_str(), that.size()) >= 0);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Subscript operator
|
||||
*
|
||||
* \pre <tt>i < size()</tt>
|
||||
* \param i Requested character index
|
||||
* \return Constant reference to the requested character
|
||||
*/
|
||||
BOOST_CONSTEXPR const_reference operator[] (size_type i) const BOOST_NOEXCEPT
|
||||
{
|
||||
return m_pStart[i];
|
||||
}
|
||||
/*!
|
||||
* Checked subscript
|
||||
*
|
||||
* \param i Requested character index
|
||||
* \return Constant reference to the requested character
|
||||
*
|
||||
* \b Throws: An <tt>std::exception</tt>-based exception if index \a i is out of string boundaries
|
||||
*/
|
||||
const_reference at(size_type i) const
|
||||
{
|
||||
if (BOOST_UNLIKELY(i >= m_Len))
|
||||
BOOST_THROW_EXCEPTION(std::out_of_range("basic_string_literal::at: the index value is out of range"));
|
||||
return m_pStart[i];
|
||||
}
|
||||
|
||||
/*!
|
||||
* \return Pointer to the beginning of the literal
|
||||
*/
|
||||
BOOST_CONSTEXPR const_pointer c_str() const BOOST_NOEXCEPT { return m_pStart; }
|
||||
/*!
|
||||
* \return Pointer to the beginning of the literal
|
||||
*/
|
||||
BOOST_CONSTEXPR const_pointer data() const BOOST_NOEXCEPT { return m_pStart; }
|
||||
/*!
|
||||
* \return Length of the literal
|
||||
*/
|
||||
BOOST_CONSTEXPR size_type size() const BOOST_NOEXCEPT { return m_Len; }
|
||||
/*!
|
||||
* \return Length of the literal
|
||||
*/
|
||||
BOOST_CONSTEXPR size_type length() const BOOST_NOEXCEPT { return m_Len; }
|
||||
|
||||
/*!
|
||||
* \return \c true if the literal is an empty string, \c false otherwise
|
||||
*/
|
||||
BOOST_CONSTEXPR bool empty() const BOOST_NOEXCEPT
|
||||
{
|
||||
return (m_Len == 0);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \return Iterator that points to the first character of the literal
|
||||
*/
|
||||
BOOST_CONSTEXPR const_iterator begin() const BOOST_NOEXCEPT { return m_pStart; }
|
||||
/*!
|
||||
* \return Iterator that points after the last character of the literal
|
||||
*/
|
||||
BOOST_CONSTEXPR const_iterator end() const BOOST_NOEXCEPT { return m_pStart + m_Len; }
|
||||
/*!
|
||||
* \return Reverse iterator that points to the last character of the literal
|
||||
*/
|
||||
const_reverse_iterator rbegin() const BOOST_NOEXCEPT { return const_reverse_iterator(end()); }
|
||||
/*!
|
||||
* \return Reverse iterator that points before the first character of the literal
|
||||
*/
|
||||
const_reverse_iterator rend() const BOOST_NOEXCEPT { return const_reverse_iterator(begin()); }
|
||||
|
||||
/*!
|
||||
* \return STL string constructed from the literal
|
||||
*/
|
||||
string_type str() const
|
||||
{
|
||||
return string_type(m_pStart, m_Len);
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method clears the literal
|
||||
*
|
||||
* \post <tt>empty() == true</tt>
|
||||
*/
|
||||
BOOST_CXX14_CONSTEXPR void clear() BOOST_NOEXCEPT
|
||||
{
|
||||
m_pStart = g_EmptyString;
|
||||
m_Len = 0;
|
||||
}
|
||||
/*!
|
||||
* The method swaps two literals
|
||||
*/
|
||||
BOOST_CXX14_CONSTEXPR void swap(this_type& that) BOOST_NOEXCEPT
|
||||
{
|
||||
const_pointer p = m_pStart;
|
||||
m_pStart = that.m_pStart;
|
||||
that.m_pStart = p;
|
||||
|
||||
size_type l = m_Len;
|
||||
m_Len = that.m_Len;
|
||||
that.m_Len = l;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Assignment from another literal
|
||||
*
|
||||
* \post <tt>*this == that</tt>
|
||||
* \param that Source literal to copy string from
|
||||
*/
|
||||
BOOST_CXX14_CONSTEXPR this_type& assign(this_type const& that) BOOST_NOEXCEPT
|
||||
{
|
||||
m_pStart = that.m_pStart;
|
||||
m_Len = that.m_Len;
|
||||
return *this;
|
||||
}
|
||||
/*!
|
||||
* Assignment from another literal
|
||||
*
|
||||
* \post <tt>*this == p</tt>
|
||||
* \param p A zero-terminated constant sequence of characters
|
||||
*/
|
||||
template< typename T, size_type LenV >
|
||||
BOOST_CXX14_CONSTEXPR
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
typename boost::enable_if_c<
|
||||
is_same< T, const value_type >::value,
|
||||
this_type&
|
||||
>::type
|
||||
#else
|
||||
this_type&
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
assign(T(&p)[LenV]) BOOST_NOEXCEPT
|
||||
{
|
||||
m_pStart = p;
|
||||
m_Len = LenV - 1;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method copies the literal or its portion to an external buffer
|
||||
*
|
||||
* \pre <tt>pos <= size()</tt>
|
||||
* \param str Pointer to the external buffer beginning. Must not be NULL.
|
||||
* The buffer must have enough capacity to accommodate the requested number of characters.
|
||||
* \param n Maximum number of characters to copy
|
||||
* \param pos Starting position to start copying from
|
||||
* \return Number of characters copied
|
||||
*
|
||||
* \b Throws: An <tt>std::exception</tt>-based exception if \a pos is out of range.
|
||||
*/
|
||||
size_type copy(value_type* str, size_type n, size_type pos = 0) const
|
||||
{
|
||||
if (BOOST_UNLIKELY(pos > m_Len))
|
||||
BOOST_THROW_EXCEPTION(std::out_of_range("basic_string_literal::copy: the position is out of range"));
|
||||
|
||||
size_type len = m_Len - pos;
|
||||
if (len > n)
|
||||
len = n;
|
||||
traits_type::copy(str, m_pStart + pos, len);
|
||||
return len;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Lexicographically compares the argument string to a part of this string
|
||||
*
|
||||
* \pre <tt>pos <= size()</tt>
|
||||
* \param pos Starting position within this string to perform comparison to
|
||||
* \param n Length of the substring of this string to perform comparison to
|
||||
* \param str Comparand. Must point to a sequence of characters, must not be NULL.
|
||||
* \param len Number of characters in the sequence \a str.
|
||||
* \return Zero if the comparand equals this string, a negative value if this string is less than the comparand,
|
||||
* a positive value if this string is greater than the comparand.
|
||||
*
|
||||
* \b Throws: An <tt>std::exception</tt>-based exception if \a pos is out of range.
|
||||
*/
|
||||
int compare(size_type pos, size_type n, const_pointer str, size_type len) const
|
||||
{
|
||||
if (BOOST_UNLIKELY(pos > m_Len))
|
||||
BOOST_THROW_EXCEPTION(std::out_of_range("basic_string_literal::compare: the position is out of range"));
|
||||
|
||||
size_type compare_size = m_Len - pos;
|
||||
if (compare_size > len)
|
||||
compare_size = len;
|
||||
if (compare_size > n)
|
||||
compare_size = n;
|
||||
return compare_internal(m_pStart + pos, compare_size, str, compare_size);
|
||||
}
|
||||
/*!
|
||||
* Lexicographically compares the argument string to a part of this string
|
||||
*
|
||||
* \pre <tt>pos <= size()</tt>
|
||||
* \param pos Starting position within this string to perform comparison to
|
||||
* \param n Length of the substring of this string to perform comparison to
|
||||
* \param str Comparand. Must point to a zero-terminated sequence of characters, must not be NULL.
|
||||
* \return Zero if the comparand equals this string, a negative value if this string is less than the comparand,
|
||||
* a positive value if this string is greater than the comparand.
|
||||
*
|
||||
* \b Throws: An <tt>std::exception</tt>-based exception if \a pos is out of range.
|
||||
*/
|
||||
int compare(size_type pos, size_type n, const_pointer str) const BOOST_NOEXCEPT
|
||||
{
|
||||
return compare(pos, n, str, traits_type::length(str));
|
||||
}
|
||||
/*!
|
||||
* Lexicographically compares the argument string literal to a part of this string
|
||||
*
|
||||
* \pre <tt>pos <= size()</tt>
|
||||
* \param pos Starting position within this string to perform comparison to
|
||||
* \param n Length of the substring of this string to perform comparison to
|
||||
* \param that Comparand
|
||||
* \return Zero if the comparand equals this string, a negative value if this string is less than the comparand,
|
||||
* a positive value if this string is greater than the comparand.
|
||||
*
|
||||
* \b Throws: An <tt>std::exception</tt>-based exception if \a pos is out of range.
|
||||
*/
|
||||
int compare(size_type pos, size_type n, this_type const& that) const BOOST_NOEXCEPT
|
||||
{
|
||||
return compare(pos, n, that.c_str(), that.size());
|
||||
}
|
||||
/*!
|
||||
* Lexicographically compares the argument string to this string
|
||||
*
|
||||
* \param str Comparand. Must point to a sequence of characters, must not be NULL.
|
||||
* \param len Number of characters in the sequence \a str.
|
||||
* \return Zero if the comparand equals this string, a negative value if this string is less than the comparand,
|
||||
* a positive value if this string is greater than the comparand.
|
||||
*/
|
||||
int compare(const_pointer str, size_type len) const BOOST_NOEXCEPT
|
||||
{
|
||||
return compare(0, m_Len, str, len);
|
||||
}
|
||||
/*!
|
||||
* Lexicographically compares the argument string to this string
|
||||
*
|
||||
* \param str Comparand. Must point to a zero-terminated sequence of characters, must not be NULL.
|
||||
* \return Zero if the comparand equals this string, a negative value if this string is less than the comparand,
|
||||
* a positive value if this string is greater than the comparand.
|
||||
*/
|
||||
int compare(const_pointer str) const BOOST_NOEXCEPT
|
||||
{
|
||||
return compare(0, m_Len, str, traits_type::length(str));
|
||||
}
|
||||
/*!
|
||||
* Lexicographically compares the argument string to this string
|
||||
*
|
||||
* \param that Comparand
|
||||
* \return Zero if the comparand equals this string, a negative value if this string is less than the comparand,
|
||||
* a positive value if this string is greater than the comparand.
|
||||
*/
|
||||
int compare(this_type const& that) const BOOST_NOEXCEPT
|
||||
{
|
||||
return compare(0, m_Len, that.c_str(), that.size());
|
||||
}
|
||||
|
||||
private:
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
//! Internal comparison implementation
|
||||
static int compare_internal(const_pointer pLeft, size_type LeftLen, const_pointer pRight, size_type RightLen) BOOST_NOEXCEPT
|
||||
{
|
||||
if (pLeft != pRight)
|
||||
{
|
||||
const int result = traits_type::compare(pLeft, pRight, (LeftLen < RightLen ? LeftLen : RightLen));
|
||||
if (result != 0)
|
||||
return result;
|
||||
}
|
||||
return LeftLen < RightLen ? -1 : (LeftLen > RightLen ? 1 : 0);
|
||||
}
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
};
|
||||
|
||||
#if !defined(BOOST_LOG_NO_CXX11_CONSTEXPR_DATA_MEMBER_BRACE_INITIALIZERS)
|
||||
template< typename CharT, typename TraitsT >
|
||||
constexpr typename basic_string_literal< CharT, TraitsT >::value_type
|
||||
basic_string_literal< CharT, TraitsT >::g_EmptyString[1];
|
||||
#else
|
||||
template< typename CharT, typename TraitsT >
|
||||
const typename basic_string_literal< CharT, TraitsT >::value_type
|
||||
basic_string_literal< CharT, TraitsT >::g_EmptyString[1] = { 0 };
|
||||
#endif
|
||||
|
||||
namespace aux {
|
||||
|
||||
template< typename CharT, typename TraitsT >
|
||||
inline void insert_fill_chars(std::basic_ostream< CharT, TraitsT >& strm, std::size_t n)
|
||||
{
|
||||
enum { chunk_size = 8 };
|
||||
CharT fill_chars[chunk_size];
|
||||
const CharT filler = strm.fill();
|
||||
for (unsigned int i = 0; i < chunk_size; ++i)
|
||||
fill_chars[i] = filler;
|
||||
for (; n >= chunk_size && strm.good(); n -= chunk_size)
|
||||
strm.write(fill_chars, static_cast< std::size_t >(chunk_size));
|
||||
if (n > 0 && strm.good())
|
||||
strm.write(fill_chars, n);
|
||||
}
|
||||
|
||||
template< typename CharT, typename TraitsT >
|
||||
void insert_aligned(std::basic_ostream< CharT, TraitsT >& strm, const CharT* p, std::size_t size)
|
||||
{
|
||||
const std::size_t alignment_size = static_cast< std::size_t >(strm.width()) - size;
|
||||
const bool align_left = (strm.flags() & std::basic_ostream< CharT, TraitsT >::adjustfield) == std::basic_ostream< CharT, TraitsT >::left;
|
||||
if (align_left)
|
||||
{
|
||||
strm.write(p, size);
|
||||
if (strm.good())
|
||||
aux::insert_fill_chars(strm, alignment_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
aux::insert_fill_chars(strm, alignment_size);
|
||||
if (strm.good())
|
||||
strm.write(p, size);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace aux
|
||||
|
||||
//! Output operator
|
||||
template< typename CharT, typename StrmTraitsT, typename LitTraitsT >
|
||||
inline std::basic_ostream< CharT, StrmTraitsT >& operator<< (
|
||||
std::basic_ostream< CharT, StrmTraitsT >& strm, basic_string_literal< CharT, LitTraitsT > const& lit)
|
||||
{
|
||||
if (strm.good())
|
||||
{
|
||||
const std::size_t size = lit.size();
|
||||
const std::size_t w = static_cast< std::size_t >(strm.width());
|
||||
if (w <= size)
|
||||
strm.write(lit.c_str(), static_cast< std::streamsize >(size));
|
||||
else
|
||||
aux::insert_aligned(strm, lit.c_str(), lit.size());
|
||||
strm.width(0);
|
||||
}
|
||||
return strm;
|
||||
}
|
||||
|
||||
//! External swap
|
||||
template< typename CharT, typename TraitsT >
|
||||
inline BOOST_CXX14_CONSTEXPR void swap(basic_string_literal< CharT, TraitsT >& left, basic_string_literal< CharT, TraitsT >& right) BOOST_NOEXCEPT
|
||||
{
|
||||
left.swap(right);
|
||||
}
|
||||
|
||||
//! Creates a string literal wrapper from a constant string literal
|
||||
#ifdef BOOST_LOG_USE_CHAR
|
||||
template< typename T, std::size_t LenV >
|
||||
inline BOOST_CONSTEXPR
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
typename boost::enable_if_c<
|
||||
is_same< T, const char >::value,
|
||||
string_literal
|
||||
>::type
|
||||
#else
|
||||
basic_string_literal< T >
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
str_literal(T(&p)[LenV]) BOOST_NOEXCEPT
|
||||
{
|
||||
return string_literal(p);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
#ifdef BOOST_LOG_USE_WCHAR_T
|
||||
template< typename T, std::size_t LenV >
|
||||
inline BOOST_CONSTEXPR typename boost::enable_if_c<
|
||||
is_same< T, const wchar_t >::value,
|
||||
wstring_literal
|
||||
>::type
|
||||
str_literal(T(&p)[LenV]) BOOST_NOEXCEPT
|
||||
{
|
||||
return wstring_literal(p);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_UTILITY_STRING_LITERAL_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 string_literal_fwd.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 24.06.2007
|
||||
*
|
||||
* The header contains forward declaration of a constant string literal wrapper.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_UTILITY_STRING_LITERAL_FWD_HPP_INCLUDED_
|
||||
#define BOOST_LOG_UTILITY_STRING_LITERAL_FWD_HPP_INCLUDED_
|
||||
|
||||
#include <string>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
/*!
|
||||
* \brief String literal wrapper
|
||||
*
|
||||
* The \c basic_string_literal is a thin wrapper around a constant string literal.
|
||||
* It provides interface similar to STL strings, but because of read-only nature
|
||||
* of string literals, lacks ability to modify string contents. However,
|
||||
* \c basic_string_literal objects can be assigned to and cleared.
|
||||
*
|
||||
* The main advantage of this class comparing to other string classes is that
|
||||
* it doesn't dynamically allocate memory and therefore is fast, thin and exception safe.
|
||||
*/
|
||||
template< typename CharT, typename TraitsT = std::char_traits< CharT > >
|
||||
class basic_string_literal;
|
||||
|
||||
// Convenience typedefs
|
||||
#ifdef BOOST_LOG_USE_CHAR
|
||||
typedef basic_string_literal< char > string_literal; //!< String literal type for narrow characters
|
||||
#endif
|
||||
#ifdef BOOST_LOG_USE_WCHAR_T
|
||||
typedef basic_string_literal< wchar_t > wstring_literal; //!< String literal type for wide characters
|
||||
#endif
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_LOG_UTILITY_STRING_LITERAL_FWD_HPP_INCLUDED_
|
||||
+174
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
* 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_types.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 13.03.2008
|
||||
*
|
||||
* The header contains definition of date and time-related types supported by the library by default.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DATE_TIME_TYPES_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DATE_TIME_TYPES_HPP_INCLUDED_
|
||||
|
||||
#include <ctime>
|
||||
#include <boost/mpl/vector.hpp>
|
||||
#include <boost/preprocessor/seq/enum.hpp>
|
||||
#include <boost/date_time/gregorian/gregorian_types.hpp>
|
||||
#include <boost/date_time/local_time/local_time_types.hpp>
|
||||
#include <boost/date_time/posix_time/posix_time_types.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
//! Boost.Preprocessor sequence of the standard C date/time types
|
||||
#define BOOST_LOG_NATIVE_DATE_TIME_TYPES()\
|
||||
(std::time_t)(std::tm)
|
||||
|
||||
//! Boost.Preprocessor sequence of the standard C date types
|
||||
#define BOOST_LOG_NATIVE_DATE_TYPES()\
|
||||
BOOST_LOG_NATIVE_DATE_TIME_TYPES()
|
||||
|
||||
//! Boost.Preprocessor sequence of the Boost date/time types
|
||||
#define BOOST_LOG_BOOST_DATE_TIME_TYPES()\
|
||||
(boost::posix_time::ptime)(boost::local_time::local_date_time)
|
||||
|
||||
//! Boost.Preprocessor sequence of date/time types
|
||||
#define BOOST_LOG_DATE_TIME_TYPES()\
|
||||
BOOST_LOG_NATIVE_DATE_TIME_TYPES()BOOST_LOG_BOOST_DATE_TIME_TYPES()\
|
||||
|
||||
//! Boost.Preprocessor sequence of the Boost date types
|
||||
#define BOOST_LOG_BOOST_DATE_TYPES()\
|
||||
BOOST_LOG_BOOST_DATE_TIME_TYPES()(boost::gregorian::date)
|
||||
|
||||
//! Boost.Preprocessor sequence of date types
|
||||
#define BOOST_LOG_DATE_TYPES()\
|
||||
BOOST_LOG_NATIVE_DATE_TYPES()BOOST_LOG_BOOST_DATE_TYPES()
|
||||
|
||||
|
||||
//! Boost.Preprocessor sequence of the standard time duration types
|
||||
#define BOOST_LOG_NATIVE_TIME_DURATION_TYPES()\
|
||||
(double) /* result of difftime() */
|
||||
|
||||
//! Boost.Preprocessor sequence of the Boost time duration types
|
||||
#define BOOST_LOG_BOOST_TIME_DURATION_TYPES()\
|
||||
(boost::posix_time::time_duration)(boost::gregorian::date_duration)
|
||||
|
||||
//! Boost.Preprocessor sequence of time duration types
|
||||
#define BOOST_LOG_TIME_DURATION_TYPES()\
|
||||
BOOST_LOG_NATIVE_TIME_DURATION_TYPES()BOOST_LOG_BOOST_TIME_DURATION_TYPES()
|
||||
|
||||
|
||||
//! Boost.Preprocessor sequence of the Boost time period types
|
||||
#define BOOST_LOG_BOOST_TIME_PERIOD_TYPES()\
|
||||
(boost::posix_time::time_period)(boost::local_time::local_time_period)(boost::gregorian::date_period)
|
||||
|
||||
//! Boost.Preprocessor sequence of time period types
|
||||
#define BOOST_LOG_TIME_PERIOD_TYPES()\
|
||||
BOOST_LOG_BOOST_TIME_PERIOD_TYPES()
|
||||
|
||||
|
||||
/*!
|
||||
* An MPL-sequence of natively supported date and time types of attributes
|
||||
*/
|
||||
typedef mpl::vector<
|
||||
BOOST_PP_SEQ_ENUM(BOOST_LOG_NATIVE_DATE_TIME_TYPES())
|
||||
> native_date_time_types;
|
||||
|
||||
/*!
|
||||
* An MPL-sequence of Boost date and time types of attributes
|
||||
*/
|
||||
typedef mpl::vector<
|
||||
BOOST_PP_SEQ_ENUM(BOOST_LOG_BOOST_DATE_TIME_TYPES())
|
||||
> boost_date_time_types;
|
||||
|
||||
/*!
|
||||
* An MPL-sequence with the complete list of the supported date and time types
|
||||
*/
|
||||
typedef mpl::vector<
|
||||
BOOST_PP_SEQ_ENUM(BOOST_LOG_DATE_TIME_TYPES())
|
||||
> date_time_types;
|
||||
|
||||
/*!
|
||||
* An MPL-sequence of natively supported date types of attributes
|
||||
*/
|
||||
typedef native_date_time_types native_date_types;
|
||||
|
||||
/*!
|
||||
* An MPL-sequence of Boost date types of attributes
|
||||
*/
|
||||
typedef mpl::vector<
|
||||
BOOST_PP_SEQ_ENUM(BOOST_LOG_BOOST_DATE_TYPES())
|
||||
> boost_date_types;
|
||||
|
||||
/*!
|
||||
* An MPL-sequence with the complete list of the supported date types
|
||||
*/
|
||||
typedef mpl::vector<
|
||||
BOOST_PP_SEQ_ENUM(BOOST_LOG_DATE_TYPES())
|
||||
> date_types;
|
||||
|
||||
/*!
|
||||
* An MPL-sequence of natively supported time types
|
||||
*/
|
||||
typedef native_date_time_types native_time_types;
|
||||
|
||||
//! An MPL-sequence of Boost time types
|
||||
typedef boost_date_time_types boost_time_types;
|
||||
|
||||
/*!
|
||||
* An MPL-sequence with the complete list of the supported time types
|
||||
*/
|
||||
typedef date_time_types time_types;
|
||||
|
||||
/*!
|
||||
* An MPL-sequence of natively supported time duration types of attributes
|
||||
*/
|
||||
typedef mpl::vector<
|
||||
BOOST_PP_SEQ_ENUM(BOOST_LOG_NATIVE_TIME_DURATION_TYPES())
|
||||
> native_time_duration_types;
|
||||
|
||||
/*!
|
||||
* An MPL-sequence of Boost time duration types of attributes
|
||||
*/
|
||||
typedef mpl::vector<
|
||||
BOOST_PP_SEQ_ENUM(BOOST_LOG_BOOST_TIME_DURATION_TYPES())
|
||||
> boost_time_duration_types;
|
||||
|
||||
/*!
|
||||
* An MPL-sequence with the complete list of the supported time duration types
|
||||
*/
|
||||
typedef mpl::vector<
|
||||
BOOST_PP_SEQ_ENUM(BOOST_LOG_TIME_DURATION_TYPES())
|
||||
> time_duration_types;
|
||||
|
||||
/*!
|
||||
* An MPL-sequence of Boost time duration types of attributes
|
||||
*/
|
||||
typedef mpl::vector<
|
||||
BOOST_PP_SEQ_ENUM(BOOST_LOG_BOOST_TIME_PERIOD_TYPES())
|
||||
> boost_time_period_types;
|
||||
|
||||
/*!
|
||||
* An MPL-sequence with the complete list of the supported time period types
|
||||
*/
|
||||
typedef boost_time_period_types time_period_types;
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_DATE_TIME_TYPES_HPP_INCLUDED_
|
||||
+152
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* 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 dynamic_type_dispatcher.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 15.04.2007
|
||||
*
|
||||
* The header contains implementation of the run-time type dispatcher.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_DYNAMIC_TYPE_DISPATCHER_HPP_INCLUDED_
|
||||
#define BOOST_LOG_DYNAMIC_TYPE_DISPATCHER_HPP_INCLUDED_
|
||||
|
||||
#include <new>
|
||||
#include <memory>
|
||||
#include <map>
|
||||
#include <boost/ref.hpp>
|
||||
#include <boost/type_index.hpp>
|
||||
#include <boost/smart_ptr/shared_ptr.hpp>
|
||||
#include <boost/smart_ptr/make_shared_object.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/utility/type_dispatch/type_dispatcher.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
/*!
|
||||
* \brief A dynamic type dispatcher
|
||||
*
|
||||
* The type dispatcher can be used to pass objects of arbitrary types from one
|
||||
* component to another. With regard to the library, the type dispatcher
|
||||
* can be used to extract attribute values.
|
||||
*
|
||||
* The dynamic type dispatcher can be initialized in run time and, therefore,
|
||||
* can support different types, depending on runtime conditions. Each
|
||||
* supported type is associated with a functional object that will be called
|
||||
* when an object of the type is dispatched.
|
||||
*/
|
||||
class dynamic_type_dispatcher :
|
||||
public type_dispatcher
|
||||
{
|
||||
private:
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
template< typename T, typename VisitorT >
|
||||
class callback_impl :
|
||||
public callback_base
|
||||
{
|
||||
private:
|
||||
VisitorT m_Visitor;
|
||||
|
||||
public:
|
||||
explicit callback_impl(VisitorT const& visitor) : m_Visitor(visitor)
|
||||
{
|
||||
this->m_pVisitor = (void*)boost::addressof(m_Visitor);
|
||||
typedef void (*trampoline_t)(void*, T const&);
|
||||
BOOST_STATIC_ASSERT_MSG(sizeof(trampoline_t) == sizeof(void*), "Boost.Log: Unsupported platform, the size of a function pointer differs from the size of a pointer");
|
||||
union
|
||||
{
|
||||
void* as_pvoid;
|
||||
trampoline_t as_trampoline;
|
||||
}
|
||||
caster;
|
||||
caster.as_trampoline = (trampoline_t)&callback_base::trampoline< VisitorT, T >;
|
||||
this->m_pTrampoline = caster.as_pvoid;
|
||||
}
|
||||
};
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
//! The dispatching map
|
||||
typedef std::map< typeindex::type_index, shared_ptr< callback_base > > dispatching_map;
|
||||
dispatching_map m_DispatchingMap;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Default constructor
|
||||
*/
|
||||
dynamic_type_dispatcher() : type_dispatcher(&dynamic_type_dispatcher::get_callback)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* Copy constructor
|
||||
*/
|
||||
dynamic_type_dispatcher(dynamic_type_dispatcher const& that) :
|
||||
type_dispatcher(static_cast< type_dispatcher const& >(that)),
|
||||
m_DispatchingMap(that.m_DispatchingMap)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* Copy assignment
|
||||
*/
|
||||
dynamic_type_dispatcher& operator= (dynamic_type_dispatcher const& that)
|
||||
{
|
||||
m_DispatchingMap = that.m_DispatchingMap;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method registers a new type
|
||||
*
|
||||
* \param visitor Function object that will be associated with the type \c T
|
||||
*/
|
||||
template< typename T, typename VisitorT >
|
||||
void register_type(VisitorT const& visitor)
|
||||
{
|
||||
boost::shared_ptr< callback_base > p(
|
||||
boost::make_shared< callback_impl< T, VisitorT > >(boost::cref(visitor)));
|
||||
|
||||
typeindex::type_index wrapper(typeindex::type_id< T >());
|
||||
m_DispatchingMap[wrapper].swap(p);
|
||||
}
|
||||
|
||||
/*!
|
||||
* The method returns the number of registered types
|
||||
*/
|
||||
dispatching_map::size_type registered_types_count() const
|
||||
{
|
||||
return m_DispatchingMap.size();
|
||||
}
|
||||
|
||||
private:
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
static callback_base get_callback(type_dispatcher* p, typeindex::type_index type)
|
||||
{
|
||||
dynamic_type_dispatcher* const self = static_cast< dynamic_type_dispatcher* >(p);
|
||||
dispatching_map::iterator it = self->m_DispatchingMap.find(type);
|
||||
if (it != self->m_DispatchingMap.end())
|
||||
return *it->second;
|
||||
else
|
||||
return callback_base();
|
||||
}
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
};
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_DYNAMIC_TYPE_DISPATCHER_HPP_INCLUDED_
|
||||
+145
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* 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 standard_types.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 19.05.2007
|
||||
*
|
||||
* The header contains definition of standard types supported by the library by default.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_STANDARD_TYPES_HPP_INCLUDED_
|
||||
#define BOOST_LOG_STANDARD_TYPES_HPP_INCLUDED_
|
||||
|
||||
#include <string>
|
||||
#include <boost/mpl/vector.hpp>
|
||||
#include <boost/mpl/vector/vector30.hpp> // needed to use mpl::vector sizes greater than 20 even when the default BOOST_MPL_LIMIT_VECTOR_SIZE is not set
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/preprocessor/seq/enum.hpp>
|
||||
#include <boost/preprocessor/seq/size.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/utility/string_literal_fwd.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
|
||||
#define BOOST_LOG_AUX_STANDARD_TYPE_WCHAR_T() (wchar_t)
|
||||
#else
|
||||
#define BOOST_LOG_AUX_STANDARD_TYPE_WCHAR_T()
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_LOG_NO_CXX11_CODECVT_FACETS)
|
||||
#define BOOST_LOG_AUX_STANDARD_TYPE_CHAR16_T() (char16_t)
|
||||
#else
|
||||
#define BOOST_LOG_AUX_STANDARD_TYPE_CHAR16_T()
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_LOG_NO_CXX11_CODECVT_FACETS)
|
||||
#define BOOST_LOG_AUX_STANDARD_TYPE_CHAR32_T() (char32_t)
|
||||
#else
|
||||
#define BOOST_LOG_AUX_STANDARD_TYPE_CHAR32_T()
|
||||
#endif
|
||||
|
||||
//! Boost.Preprocessor sequence of character types
|
||||
#define BOOST_LOG_STANDARD_CHAR_TYPES()\
|
||||
(char)BOOST_LOG_AUX_STANDARD_TYPE_WCHAR_T()BOOST_LOG_AUX_STANDARD_TYPE_CHAR16_T()BOOST_LOG_AUX_STANDARD_TYPE_CHAR32_T()
|
||||
|
||||
#if defined(BOOST_HAS_LONG_LONG)
|
||||
#define BOOST_LOG_AUX_STANDARD_LONG_LONG_TYPES() (long long)(unsigned long long)
|
||||
#else
|
||||
#define BOOST_LOG_AUX_STANDARD_LONG_LONG_TYPES()
|
||||
#endif
|
||||
|
||||
//! Boost.Preprocessor sequence of integral types
|
||||
#define BOOST_LOG_STANDARD_INTEGRAL_TYPES()\
|
||||
(bool)(signed char)(unsigned char)(short)(unsigned short)(int)(unsigned int)(long)(unsigned long)BOOST_LOG_AUX_STANDARD_LONG_LONG_TYPES()\
|
||||
BOOST_LOG_STANDARD_CHAR_TYPES()
|
||||
|
||||
//! Boost.Preprocessor sequence of floating point types
|
||||
#define BOOST_LOG_STANDARD_FLOATING_POINT_TYPES()\
|
||||
(float)(double)(long double)
|
||||
|
||||
//! Boost.Preprocessor sequence of arithmetic types
|
||||
#define BOOST_LOG_STANDARD_ARITHMETIC_TYPES()\
|
||||
BOOST_LOG_STANDARD_INTEGRAL_TYPES()BOOST_LOG_STANDARD_FLOATING_POINT_TYPES()
|
||||
|
||||
#if defined(BOOST_LOG_USE_CHAR)
|
||||
#define BOOST_LOG_AUX_STANDARD_STRING_TYPES() (std::string)(boost::log::string_literal)
|
||||
#else
|
||||
#define BOOST_LOG_AUX_STANDARD_STRING_TYPES()
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_LOG_USE_WCHAR_T)
|
||||
#define BOOST_LOG_AUX_STANDARD_WSTRING_TYPES() (std::wstring)(boost::log::wstring_literal)
|
||||
#else
|
||||
#define BOOST_LOG_AUX_STANDARD_WSTRING_TYPES()
|
||||
#endif
|
||||
|
||||
//! Boost.Preprocessor sequence of string types
|
||||
#define BOOST_LOG_STANDARD_STRING_TYPES()\
|
||||
BOOST_LOG_AUX_STANDARD_STRING_TYPES()BOOST_LOG_AUX_STANDARD_WSTRING_TYPES()
|
||||
|
||||
//! Boost.Preprocessor sequence of the default attribute value types supported by the library
|
||||
#define BOOST_LOG_DEFAULT_ATTRIBUTE_VALUE_TYPES()\
|
||||
BOOST_LOG_STANDARD_ARITHMETIC_TYPES()BOOST_LOG_STANDARD_STRING_TYPES()
|
||||
|
||||
|
||||
/*!
|
||||
* An MPL-sequence of integral types of attributes, supported by default
|
||||
*/
|
||||
typedef mpl::vector<
|
||||
BOOST_PP_SEQ_ENUM(BOOST_LOG_STANDARD_INTEGRAL_TYPES())
|
||||
> integral_types;
|
||||
|
||||
/*!
|
||||
* An MPL-sequence of FP types of attributes, supported by default
|
||||
*/
|
||||
typedef mpl::vector<
|
||||
BOOST_PP_SEQ_ENUM(BOOST_LOG_STANDARD_FLOATING_POINT_TYPES())
|
||||
> floating_point_types;
|
||||
|
||||
/*!
|
||||
* An MPL-sequence of all numeric types of attributes, supported by default
|
||||
*/
|
||||
typedef mpl::vector<
|
||||
BOOST_PP_SEQ_ENUM(BOOST_LOG_STANDARD_ARITHMETIC_TYPES())
|
||||
> arithmetic_types;
|
||||
|
||||
//! Deprecated alias
|
||||
typedef arithmetic_types numeric_types;
|
||||
|
||||
/*!
|
||||
* An MPL-sequence of string types of attributes, supported by default
|
||||
*/
|
||||
typedef mpl::vector<
|
||||
BOOST_PP_SEQ_ENUM(BOOST_LOG_STANDARD_STRING_TYPES())
|
||||
> string_types;
|
||||
|
||||
/*!
|
||||
* An MPL-sequence of all attribute value types that are supported by the library by default.
|
||||
*/
|
||||
typedef BOOST_PP_CAT(mpl::vector, BOOST_PP_SEQ_SIZE(BOOST_LOG_DEFAULT_ATTRIBUTE_VALUE_TYPES()))<
|
||||
BOOST_PP_SEQ_ENUM(BOOST_LOG_DEFAULT_ATTRIBUTE_VALUE_TYPES())
|
||||
> default_attribute_value_types;
|
||||
|
||||
//! Deprecated alias
|
||||
typedef default_attribute_value_types default_attribute_types;
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_STANDARD_TYPES_HPP_INCLUDED_
|
||||
+320
@@ -0,0 +1,320 @@
|
||||
/*
|
||||
* 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 static_type_dispatcher.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 15.04.2007
|
||||
*
|
||||
* The header contains implementation of a compile-time type dispatcher.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_STATIC_TYPE_DISPATCHER_HPP_INCLUDED_
|
||||
#define BOOST_LOG_STATIC_TYPE_DISPATCHER_HPP_INCLUDED_
|
||||
|
||||
#include <cstddef>
|
||||
#include <utility>
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
#include <boost/array.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_index.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/size.hpp>
|
||||
#include <boost/mpl/begin.hpp>
|
||||
#include <boost/mpl/end.hpp>
|
||||
#include <boost/mpl/deref.hpp>
|
||||
#include <boost/mpl/next.hpp>
|
||||
#include <boost/mpl/is_sequence.hpp>
|
||||
#include <boost/core/addressof.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/utility/once_block.hpp>
|
||||
#include <boost/log/utility/type_dispatch/type_dispatcher.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace aux {
|
||||
|
||||
//! Ordering predicate for type dispatching map
|
||||
struct dispatching_map_order
|
||||
{
|
||||
typedef bool result_type;
|
||||
typedef std::pair< typeindex::type_index, void* > first_argument_type, second_argument_type;
|
||||
result_type operator() (first_argument_type const& left, second_argument_type const& right) const
|
||||
{
|
||||
return (left.first < right.first);
|
||||
}
|
||||
};
|
||||
|
||||
//! Dispatching map filler
|
||||
template< typename VisitorT >
|
||||
struct dispatching_map_initializer
|
||||
{
|
||||
template< typename IteratorT >
|
||||
static BOOST_FORCEINLINE void init(IteratorT*, IteratorT*, std::pair< typeindex::type_index, void* >*)
|
||||
{
|
||||
}
|
||||
|
||||
template< typename BeginIteratorT, typename EndIteratorT >
|
||||
static BOOST_FORCEINLINE void init(BeginIteratorT*, EndIteratorT* end, std::pair< typeindex::type_index, void* >* p)
|
||||
{
|
||||
typedef typename mpl::deref< BeginIteratorT >::type type;
|
||||
do_init(static_cast< type* >(0), p);
|
||||
|
||||
typedef typename mpl::next< BeginIteratorT >::type next_iterator_type;
|
||||
init(static_cast< next_iterator_type* >(0), end, p + 1);
|
||||
}
|
||||
|
||||
private:
|
||||
template< typename T >
|
||||
static BOOST_FORCEINLINE void do_init(T*, std::pair< typeindex::type_index, void* >* p)
|
||||
{
|
||||
p->first = typeindex::type_id< T >();
|
||||
|
||||
typedef void (*trampoline_t)(void*, T const&);
|
||||
BOOST_STATIC_ASSERT_MSG(sizeof(trampoline_t) == sizeof(void*), "Boost.Log: Unsupported platform, the size of a function pointer differs from the size of a pointer");
|
||||
union
|
||||
{
|
||||
void* as_pvoid;
|
||||
trampoline_t as_trampoline;
|
||||
}
|
||||
caster;
|
||||
caster.as_trampoline = (trampoline_t)&type_dispatcher::callback_base::trampoline< VisitorT, T >;
|
||||
p->second = caster.as_pvoid;
|
||||
}
|
||||
};
|
||||
|
||||
//! A base class for a dispatcher that supports a sequence of types
|
||||
class type_sequence_dispatcher_base :
|
||||
public type_dispatcher
|
||||
{
|
||||
private:
|
||||
//! Dispatching map element type
|
||||
typedef std::pair< typeindex::type_index, void* > dispatching_map_element_type;
|
||||
|
||||
private:
|
||||
//! Dispatching map
|
||||
const dispatching_map_element_type* m_dispatching_map_begin;
|
||||
//! Dispatching map size
|
||||
std::size_t m_dispatching_map_size;
|
||||
//! Pointer to the receiver function
|
||||
void* m_visitor;
|
||||
|
||||
protected:
|
||||
//! Initializing constructor
|
||||
type_sequence_dispatcher_base(const dispatching_map_element_type* disp_map, std::size_t disp_map_size, void* visitor) BOOST_NOEXCEPT :
|
||||
type_dispatcher(&type_sequence_dispatcher_base::get_callback),
|
||||
m_dispatching_map_begin(disp_map),
|
||||
m_dispatching_map_size(disp_map_size),
|
||||
m_visitor(visitor)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
//! The get_callback method implementation
|
||||
static callback_base get_callback(type_dispatcher* p, typeindex::type_index type)
|
||||
{
|
||||
type_sequence_dispatcher_base* const self = static_cast< type_sequence_dispatcher_base* >(p);
|
||||
const dispatching_map_element_type* begin = self->m_dispatching_map_begin;
|
||||
const dispatching_map_element_type* end = begin + self->m_dispatching_map_size;
|
||||
const dispatching_map_element_type* it = std::lower_bound
|
||||
(
|
||||
begin,
|
||||
end,
|
||||
dispatching_map_element_type(type, (void*)0),
|
||||
dispatching_map_order()
|
||||
);
|
||||
|
||||
if (it != end && it->first == type)
|
||||
return callback_base(self->m_visitor, it->second);
|
||||
else
|
||||
return callback_base();
|
||||
}
|
||||
|
||||
// Copying and assignment closed
|
||||
BOOST_DELETED_FUNCTION(type_sequence_dispatcher_base(type_sequence_dispatcher_base const&))
|
||||
BOOST_DELETED_FUNCTION(type_sequence_dispatcher_base& operator= (type_sequence_dispatcher_base const&))
|
||||
};
|
||||
|
||||
//! A dispatcher that supports a sequence of types
|
||||
template< typename TypeSequenceT >
|
||||
class type_sequence_dispatcher :
|
||||
public type_sequence_dispatcher_base
|
||||
{
|
||||
public:
|
||||
//! Type sequence of the supported types
|
||||
typedef TypeSequenceT supported_types;
|
||||
|
||||
private:
|
||||
//! The dispatching map
|
||||
typedef array<
|
||||
std::pair< typeindex::type_index, void* >,
|
||||
mpl::size< supported_types >::value
|
||||
> dispatching_map;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Constructor. Initializes the dispatcher internals.
|
||||
*/
|
||||
template< typename VisitorT >
|
||||
explicit type_sequence_dispatcher(VisitorT& visitor) :
|
||||
type_sequence_dispatcher_base(get_dispatching_map< VisitorT >().data(), dispatching_map::static_size, (void*)boost::addressof(visitor))
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
//! The method returns the dispatching map instance
|
||||
template< typename VisitorT >
|
||||
static dispatching_map const& get_dispatching_map()
|
||||
{
|
||||
static const dispatching_map* pinstance = NULL;
|
||||
|
||||
BOOST_LOG_ONCE_BLOCK()
|
||||
{
|
||||
static dispatching_map instance;
|
||||
typename dispatching_map::value_type* p = &*instance.begin();
|
||||
|
||||
typedef typename mpl::begin< supported_types >::type begin_iterator_type;
|
||||
typedef typename mpl::end< supported_types >::type end_iterator_type;
|
||||
typedef dispatching_map_initializer< VisitorT > initializer;
|
||||
initializer::init(static_cast< begin_iterator_type* >(0), static_cast< end_iterator_type* >(0), p);
|
||||
|
||||
std::sort(instance.begin(), instance.end(), dispatching_map_order());
|
||||
|
||||
pinstance = &instance;
|
||||
}
|
||||
|
||||
return *pinstance;
|
||||
}
|
||||
|
||||
// Copying and assignment closed
|
||||
BOOST_DELETED_FUNCTION(type_sequence_dispatcher(type_sequence_dispatcher const&))
|
||||
BOOST_DELETED_FUNCTION(type_sequence_dispatcher& operator= (type_sequence_dispatcher const&))
|
||||
};
|
||||
|
||||
//! A base class for a single-type dispatcher
|
||||
class single_type_dispatcher_base :
|
||||
public type_dispatcher
|
||||
{
|
||||
private:
|
||||
//! The type to match against
|
||||
typeindex::type_index m_type;
|
||||
//! A callback for the supported type
|
||||
callback_base m_callback;
|
||||
|
||||
protected:
|
||||
//! Initializing constructor
|
||||
single_type_dispatcher_base(typeindex::type_index type, callback_base const& cb) BOOST_NOEXCEPT :
|
||||
type_dispatcher(&single_type_dispatcher_base::get_callback),
|
||||
m_type(type),
|
||||
m_callback(cb)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
//! The get_callback method implementation
|
||||
static callback_base get_callback(type_dispatcher* p, typeindex::type_index type)
|
||||
{
|
||||
single_type_dispatcher_base* const self = static_cast< single_type_dispatcher_base* >(p);
|
||||
if (type == self->m_type)
|
||||
return self->m_callback;
|
||||
else
|
||||
return callback_base();
|
||||
}
|
||||
|
||||
// Copying and assignment closed
|
||||
BOOST_DELETED_FUNCTION(single_type_dispatcher_base(single_type_dispatcher_base const&))
|
||||
BOOST_DELETED_FUNCTION(single_type_dispatcher_base& operator= (single_type_dispatcher_base const&))
|
||||
};
|
||||
|
||||
//! A simple dispatcher that only supports one type
|
||||
template< typename T >
|
||||
class single_type_dispatcher :
|
||||
public single_type_dispatcher_base
|
||||
{
|
||||
private:
|
||||
typedef void (*trampoline_t)(void*, T const&);
|
||||
|
||||
public:
|
||||
//! Constructor
|
||||
template< typename VisitorT >
|
||||
explicit single_type_dispatcher(VisitorT& visitor) BOOST_NOEXCEPT :
|
||||
single_type_dispatcher_base(typeindex::type_id< T >(), callback_base((void*)boost::addressof(visitor), (trampoline_t)&callback_base::trampoline< VisitorT, T >))
|
||||
{
|
||||
}
|
||||
|
||||
// Copying and assignment closed
|
||||
BOOST_DELETED_FUNCTION(single_type_dispatcher(single_type_dispatcher const&))
|
||||
BOOST_DELETED_FUNCTION(single_type_dispatcher& operator= (single_type_dispatcher const&))
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
/*!
|
||||
* \brief A static type dispatcher class
|
||||
*
|
||||
* The type dispatcher can be used to pass objects of arbitrary types from one
|
||||
* component to another. With regard to the library, the type dispatcher
|
||||
* can be used to extract attribute values.
|
||||
*
|
||||
* Static type dispatchers allow to specify one or several supported types at compile
|
||||
* time.
|
||||
*/
|
||||
template< typename T >
|
||||
class static_type_dispatcher
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
:
|
||||
public mpl::if_<
|
||||
mpl::is_sequence< T >,
|
||||
boost::log::aux::type_sequence_dispatcher< T >,
|
||||
boost::log::aux::single_type_dispatcher< T >
|
||||
>::type
|
||||
#endif
|
||||
{
|
||||
private:
|
||||
//! Base type
|
||||
typedef typename mpl::if_<
|
||||
mpl::is_sequence< T >,
|
||||
boost::log::aux::type_sequence_dispatcher< T >,
|
||||
boost::log::aux::single_type_dispatcher< T >
|
||||
>::type base_type;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Constructor. Initializes the dispatcher internals.
|
||||
*
|
||||
* The \a receiver object is not copied inside the dispatcher, but references to
|
||||
* it may be kept by the dispatcher after construction. The receiver object must remain
|
||||
* valid until the dispatcher is destroyed.
|
||||
*
|
||||
* \param receiver Unary function object that will be called on a dispatched value. The receiver
|
||||
* must be callable with an argument of any of the supported types of the dispatcher.
|
||||
*/
|
||||
template< typename ReceiverT >
|
||||
explicit static_type_dispatcher(ReceiverT& receiver) :
|
||||
base_type(receiver)
|
||||
{
|
||||
}
|
||||
|
||||
// Copying and assignment prohibited
|
||||
BOOST_DELETED_FUNCTION(static_type_dispatcher(static_type_dispatcher const&))
|
||||
BOOST_DELETED_FUNCTION(static_type_dispatcher& operator= (static_type_dispatcher const&))
|
||||
};
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_STATIC_TYPE_DISPATCHER_HPP_INCLUDED_
|
||||
+188
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* 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 type_dispatcher.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 15.04.2007
|
||||
*
|
||||
* The header contains definition of generic type dispatcher interfaces.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_TYPE_DISPATCHER_HPP_INCLUDED_
|
||||
#define BOOST_LOG_TYPE_DISPATCHER_HPP_INCLUDED_
|
||||
|
||||
#include <boost/type_index.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/utility/explicit_operator_bool.hpp>
|
||||
#include <boost/log/detail/header.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
/*!
|
||||
* \brief A type dispatcher interface
|
||||
*
|
||||
* All type dispatchers support this interface. It is used to acquire the
|
||||
* visitor interface for the requested type.
|
||||
*/
|
||||
class type_dispatcher
|
||||
{
|
||||
public:
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
//! The base class for type dispatcher callbacks
|
||||
class callback_base
|
||||
{
|
||||
protected:
|
||||
void* m_pVisitor;
|
||||
void* m_pTrampoline;
|
||||
|
||||
public:
|
||||
explicit callback_base(void* visitor = 0, void* tramp = 0) BOOST_NOEXCEPT :
|
||||
m_pVisitor(visitor),
|
||||
m_pTrampoline(tramp)
|
||||
{
|
||||
}
|
||||
template< typename ValueT >
|
||||
explicit callback_base(void* visitor, void (*tramp)(void*, ValueT const&)) BOOST_NOEXCEPT :
|
||||
m_pVisitor(visitor)
|
||||
{
|
||||
typedef void (*trampoline_t)(void*, ValueT const&);
|
||||
BOOST_STATIC_ASSERT_MSG(sizeof(trampoline_t) == sizeof(void*), "Boost.Log: Unsupported platform, the size of a function pointer differs from the size of a pointer");
|
||||
union
|
||||
{
|
||||
void* as_pvoid;
|
||||
trampoline_t as_trampoline;
|
||||
}
|
||||
caster;
|
||||
caster.as_trampoline = tramp;
|
||||
m_pTrampoline = caster.as_pvoid;
|
||||
}
|
||||
|
||||
template< typename VisitorT, typename T >
|
||||
static void trampoline(void* visitor, T const& value)
|
||||
{
|
||||
(*static_cast< VisitorT* >(visitor))(value);
|
||||
}
|
||||
};
|
||||
|
||||
//! An interface to the callback for the concrete type visitor
|
||||
template< typename T >
|
||||
class callback :
|
||||
private callback_base
|
||||
{
|
||||
private:
|
||||
//! Type of the trampoline method
|
||||
typedef void (*trampoline_t)(void*, T const&);
|
||||
|
||||
public:
|
||||
//! The type, which the visitor is able to consume
|
||||
typedef T supported_type;
|
||||
|
||||
public:
|
||||
callback() BOOST_NOEXCEPT : callback_base()
|
||||
{
|
||||
}
|
||||
explicit callback(callback_base const& base) BOOST_NOEXCEPT : callback_base(base)
|
||||
{
|
||||
}
|
||||
|
||||
void operator() (T const& value) const
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(sizeof(trampoline_t) == sizeof(void*), "Boost.Log: Unsupported platform, the size of a function pointer differs from the size of a pointer");
|
||||
union
|
||||
{
|
||||
void* as_pvoid;
|
||||
trampoline_t as_trampoline;
|
||||
}
|
||||
caster;
|
||||
caster.as_pvoid = this->m_pTrampoline;
|
||||
(caster.as_trampoline)(this->m_pVisitor, value);
|
||||
}
|
||||
|
||||
BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
|
||||
|
||||
bool operator! () const BOOST_NOEXCEPT { return (this->m_pVisitor == 0); }
|
||||
};
|
||||
|
||||
#else // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
/*!
|
||||
* This interface is used by type dispatchers to consume the dispatched value.
|
||||
*/
|
||||
template< typename T >
|
||||
class callback
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* The operator invokes the visitor-specific logic with the given value
|
||||
*
|
||||
* \param value The dispatched value
|
||||
*/
|
||||
void operator() (T const& value) const;
|
||||
|
||||
/*!
|
||||
* The operator checks if the visitor is attached to a receiver
|
||||
*/
|
||||
BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
|
||||
|
||||
/*!
|
||||
* The operator checks if the visitor is not attached to a receiver
|
||||
*/
|
||||
bool operator! () const BOOST_NOEXCEPT;
|
||||
};
|
||||
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
protected:
|
||||
//! Pointer to the callback acquisition method
|
||||
typedef callback_base (*get_callback_impl_type)(type_dispatcher*, typeindex::type_index);
|
||||
|
||||
private:
|
||||
//! Pointer to the callback acquisition method
|
||||
get_callback_impl_type m_get_callback_impl;
|
||||
|
||||
protected:
|
||||
/*!
|
||||
* Initializing constructor
|
||||
*/
|
||||
explicit type_dispatcher(get_callback_impl_type get_callback_impl) BOOST_NOEXCEPT : m_get_callback_impl(get_callback_impl)
|
||||
{
|
||||
}
|
||||
|
||||
// Destructor and copying can only be called from the derived classes
|
||||
BOOST_DEFAULTED_FUNCTION(~type_dispatcher(), {})
|
||||
BOOST_DEFAULTED_FUNCTION(type_dispatcher(type_dispatcher const& that), : m_get_callback_impl(that.m_get_callback_impl) {})
|
||||
BOOST_DEFAULTED_FUNCTION(type_dispatcher& operator= (type_dispatcher const& that), { m_get_callback_impl = that.m_get_callback_impl; return *this; })
|
||||
|
||||
public:
|
||||
/*!
|
||||
* The method requests a callback for the value of type \c T
|
||||
*
|
||||
* \return The type-specific callback or an empty value, if the type is not supported
|
||||
*/
|
||||
template< typename T >
|
||||
callback< T > get_callback()
|
||||
{
|
||||
return callback< T >((this->m_get_callback_impl)(this, typeindex::type_id< T >()));
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_TYPE_DISPATCHER_HPP_INCLUDED_
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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 unique_identifier_name.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 30.04.2008
|
||||
*
|
||||
* The header contains \c BOOST_LOG_UNIQUE_IDENTIFIER_NAME macro definition.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_UTILITY_UNIQUE_IDENTIFIER_NAME_HPP_INCLUDED_
|
||||
#define BOOST_LOG_UTILITY_UNIQUE_IDENTIFIER_NAME_HPP_INCLUDED_
|
||||
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
#define BOOST_LOG_UNIQUE_IDENTIFIER_NAME_INTERNAL_(prefix, postfix)\
|
||||
BOOST_PP_CAT(prefix, postfix)
|
||||
#define BOOST_LOG_UNIQUE_IDENTIFIER_NAME_INTERNAL(prefix, postfix)\
|
||||
BOOST_LOG_UNIQUE_IDENTIFIER_NAME_INTERNAL_(prefix, postfix)
|
||||
|
||||
#endif // BOOST_LOG_DOXYGEN_PASS
|
||||
|
||||
/*!
|
||||
* \def BOOST_LOG_UNIQUE_IDENTIFIER_NAME(prefix)
|
||||
*
|
||||
* Constructs a unique (in the current file scope) token that can be used as a variable name.
|
||||
* The name will contain a prefix passed in the \a prefix argument. This allows to use the
|
||||
* macro multiple times on a single line.
|
||||
*/
|
||||
|
||||
// In VC 7.0 and later when compiling with /ZI option __LINE__ macro is corrupted
|
||||
#ifdef BOOST_MSVC
|
||||
# define BOOST_LOG_UNIQUE_IDENTIFIER_NAME(prefix)\
|
||||
BOOST_LOG_UNIQUE_IDENTIFIER_NAME_INTERNAL(prefix, __COUNTER__)
|
||||
#else
|
||||
# define BOOST_LOG_UNIQUE_IDENTIFIER_NAME(prefix)\
|
||||
BOOST_LOG_UNIQUE_IDENTIFIER_NAME_INTERNAL(prefix, __LINE__)
|
||||
#endif // BOOST_MSVC
|
||||
|
||||
#endif // BOOST_LOG_UTILITY_UNIQUE_IDENTIFIER_NAME_HPP_INCLUDED_
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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 unused_variable.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 10.05.2008
|
||||
*
|
||||
* The header contains definition of a macro to suppress compiler warnings about unused variables.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_UTILITY_UNUSED_VARIABLE_HPP_INCLUDED_
|
||||
#define BOOST_LOG_UTILITY_UNUSED_VARIABLE_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
|
||||
//! The macro suppresses compiler warnings for \c var being unused
|
||||
#define BOOST_LOG_UNUSED_VARIABLE(type, var, initializer) __attribute__((unused)) type var initializer
|
||||
|
||||
#else
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
namespace aux {
|
||||
|
||||
template< typename T >
|
||||
BOOST_FORCEINLINE void no_unused_warnings(T const&) BOOST_NOEXCEPT {}
|
||||
|
||||
} // namespace aux
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
//! The macro suppresses compiler warnings for \c var being unused
|
||||
#define BOOST_LOG_UNUSED_VARIABLE(type, var, initializer) type var initializer; ::boost::log::aux::no_unused_warnings(var)
|
||||
|
||||
#endif
|
||||
|
||||
#endif // BOOST_LOG_UTILITY_UNUSED_VARIABLE_HPP_INCLUDED_
|
||||
@@ -0,0 +1,656 @@
|
||||
/*
|
||||
* 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.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 27.07.2012
|
||||
*
|
||||
* The header contains implementation of a value reference wrapper.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_UTILITY_VALUE_REF_HPP_INCLUDED_
|
||||
#define BOOST_LOG_UTILITY_VALUE_REF_HPP_INCLUDED_
|
||||
|
||||
#include <cstddef>
|
||||
#include <iosfwd>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/eval_if.hpp>
|
||||
#include <boost/mpl/is_sequence.hpp>
|
||||
#include <boost/mpl/front.hpp>
|
||||
#include <boost/mpl/size.hpp>
|
||||
#include <boost/mpl/int.hpp>
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/mpl/identity.hpp>
|
||||
#include <boost/mpl/equal_to.hpp>
|
||||
#include <boost/mpl/contains.hpp>
|
||||
#include <boost/mpl/index_of.hpp>
|
||||
#include <boost/core/explicit_operator_bool.hpp>
|
||||
#include <boost/core/addressof.hpp>
|
||||
#include <boost/optional/optional_fwd.hpp>
|
||||
#include <boost/type_traits/is_void.hpp>
|
||||
#include <boost/log/detail/config.hpp>
|
||||
#include <boost/log/detail/parameter_tools.hpp>
|
||||
#include <boost/log/detail/value_ref_visitation.hpp>
|
||||
#include <boost/log/detail/sfinae_tools.hpp>
|
||||
#include <boost/log/utility/formatting_ostream_fwd.hpp>
|
||||
#include <boost/log/utility/functional/logical.hpp>
|
||||
#include <boost/log/utility/functional/bind.hpp>
|
||||
#include <boost/log/utility/functional/bind_output.hpp>
|
||||
#include <boost/log/utility/functional/bind_to_log.hpp>
|
||||
#include <boost/log/utility/manipulators/to_log.hpp>
|
||||
#include <boost/log/utility/value_ref_fwd.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 object applies the function object to the bound visitable object and argument
|
||||
template< typename VisitableT, typename FunT >
|
||||
struct vistation_invoker
|
||||
{
|
||||
typedef typename FunT::result_type result_type;
|
||||
|
||||
vistation_invoker(VisitableT& visitable, result_type const& def_val) : m_visitable(visitable), m_def_val(def_val)
|
||||
{
|
||||
}
|
||||
|
||||
template< typename ArgT >
|
||||
result_type operator() (ArgT const& arg) const
|
||||
{
|
||||
return m_visitable.apply_visitor_or_default(binder1st< FunT, ArgT const& >(FunT(), arg), m_def_val);
|
||||
}
|
||||
|
||||
private:
|
||||
VisitableT& m_visitable;
|
||||
result_type m_def_val;
|
||||
};
|
||||
|
||||
//! Traits for testing type compatibility with the reference wrapper
|
||||
struct singular_ref_compatibility_traits
|
||||
{
|
||||
template< typename T, typename U >
|
||||
struct is_compatible
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = false);
|
||||
};
|
||||
template< typename T >
|
||||
struct is_compatible< T, T >
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
};
|
||||
|
||||
//! Attribute value reference implementation for a single type case
|
||||
template< typename T, typename TagT >
|
||||
class singular_ref
|
||||
{
|
||||
public:
|
||||
//! Referenced value type
|
||||
typedef T value_type;
|
||||
//! Tag type
|
||||
typedef TagT tag_type;
|
||||
|
||||
protected:
|
||||
//! Traits for testing type compatibility with the reference wrapper
|
||||
typedef singular_ref_compatibility_traits compatibility_traits;
|
||||
|
||||
protected:
|
||||
//! Pointer to the value
|
||||
const value_type* m_ptr;
|
||||
|
||||
protected:
|
||||
//! Default constructor
|
||||
singular_ref() BOOST_NOEXCEPT : m_ptr(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
//! Initializing constructor
|
||||
explicit singular_ref(const value_type* p) BOOST_NOEXCEPT : m_ptr(p)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
//! Returns a pointer to the referred value
|
||||
const value_type* operator-> () const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_ASSERT(m_ptr != NULL);
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
//! Returns a pointer to the referred value
|
||||
const value_type* get_ptr() const BOOST_NOEXCEPT
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
//! Returns a pointer to the referred value
|
||||
template< typename U >
|
||||
typename boost::enable_if_c< compatibility_traits::is_compatible< value_type, U >::value, const U* >::type get_ptr() const BOOST_NOEXCEPT
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
//! Returns a reference to the value
|
||||
value_type const& operator* () const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_ASSERT(m_ptr != NULL);
|
||||
return *m_ptr;
|
||||
}
|
||||
|
||||
//! Returns a reference to the value
|
||||
value_type const& get() const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_ASSERT(m_ptr != NULL);
|
||||
return *m_ptr;
|
||||
}
|
||||
|
||||
//! Returns a reference to the value
|
||||
template< typename U >
|
||||
typename boost::enable_if_c< compatibility_traits::is_compatible< value_type, U >::value, U const& >::type get() const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_ASSERT(m_ptr != NULL);
|
||||
return *m_ptr;
|
||||
}
|
||||
|
||||
|
||||
//! Resets the reference
|
||||
void reset() BOOST_NOEXCEPT
|
||||
{
|
||||
m_ptr = NULL;
|
||||
}
|
||||
|
||||
//! Returns the stored type index
|
||||
static BOOST_CONSTEXPR unsigned int which()
|
||||
{
|
||||
return 0u;
|
||||
}
|
||||
|
||||
//! Swaps two reference wrappers
|
||||
void swap(singular_ref& that) BOOST_NOEXCEPT
|
||||
{
|
||||
const void* p = m_ptr;
|
||||
m_ptr = that.m_ptr;
|
||||
that.m_ptr = p;
|
||||
}
|
||||
|
||||
//! Applies a visitor function object to the referred value
|
||||
template< typename VisitorT >
|
||||
typename VisitorT::result_type apply_visitor(VisitorT visitor) const
|
||||
{
|
||||
BOOST_ASSERT(m_ptr != NULL);
|
||||
return visitor(*m_ptr);
|
||||
}
|
||||
|
||||
//! Applies a visitor function object to the referred value
|
||||
template< typename VisitorT >
|
||||
typename boost::enable_if_c< is_void< typename VisitorT::result_type >::value, bool >::type apply_visitor_optional(VisitorT visitor) const
|
||||
{
|
||||
if (m_ptr)
|
||||
{
|
||||
visitor(*m_ptr);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
//! Applies a visitor function object to the referred value
|
||||
template< typename VisitorT >
|
||||
typename boost::disable_if_c< is_void< typename VisitorT::result_type >::value, optional< typename VisitorT::result_type > >::type apply_visitor_optional(VisitorT visitor) const
|
||||
{
|
||||
typedef optional< typename VisitorT::result_type > result_type;
|
||||
if (m_ptr)
|
||||
return result_type(visitor(*m_ptr));
|
||||
else
|
||||
return result_type();
|
||||
}
|
||||
|
||||
//! Applies a visitor function object to the referred value or returns a default value
|
||||
template< typename VisitorT, typename DefaultT >
|
||||
typename VisitorT::result_type apply_visitor_or_default(VisitorT visitor, DefaultT& def_val) const
|
||||
{
|
||||
if (m_ptr)
|
||||
return visitor(*m_ptr);
|
||||
else
|
||||
return def_val;
|
||||
}
|
||||
|
||||
//! Applies a visitor function object to the referred value or returns a default value
|
||||
template< typename VisitorT, typename DefaultT >
|
||||
typename VisitorT::result_type apply_visitor_or_default(VisitorT visitor, DefaultT const& def_val) const
|
||||
{
|
||||
if (m_ptr)
|
||||
return visitor(*m_ptr);
|
||||
else
|
||||
return def_val;
|
||||
}
|
||||
};
|
||||
|
||||
//! Traits for testing type compatibility with the reference wrapper
|
||||
struct variant_ref_compatibility_traits
|
||||
{
|
||||
template< typename T, typename U >
|
||||
struct is_compatible
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = (mpl::contains< T, U >::type::value));
|
||||
};
|
||||
};
|
||||
|
||||
//! Attribute value reference implementation for multiple types case
|
||||
template< typename T, typename TagT >
|
||||
class variant_ref
|
||||
{
|
||||
public:
|
||||
//! Referenced value type
|
||||
typedef T value_type;
|
||||
//! Tag type
|
||||
typedef TagT tag_type;
|
||||
|
||||
protected:
|
||||
//! Traits for testing type compatibility with the reference wrapper
|
||||
typedef variant_ref_compatibility_traits compatibility_traits;
|
||||
|
||||
protected:
|
||||
//! Pointer to the value
|
||||
const void* m_ptr;
|
||||
//! Type index
|
||||
unsigned int m_type_idx;
|
||||
|
||||
protected:
|
||||
//! Default constructor
|
||||
variant_ref() BOOST_NOEXCEPT : m_ptr(NULL), m_type_idx(0)
|
||||
{
|
||||
}
|
||||
|
||||
//! Initializing constructor
|
||||
template< typename U >
|
||||
explicit variant_ref(const U* p) BOOST_NOEXCEPT : m_ptr(p), m_type_idx(mpl::index_of< value_type, U >::type::value)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
//! Resets the reference
|
||||
void reset() BOOST_NOEXCEPT
|
||||
{
|
||||
m_ptr = NULL;
|
||||
m_type_idx = 0;
|
||||
}
|
||||
|
||||
//! Returns a pointer to the referred value
|
||||
template< typename U >
|
||||
typename boost::enable_if_c< compatibility_traits::is_compatible< value_type, U >::value, const U* >::type get_ptr() const BOOST_NOEXCEPT
|
||||
{
|
||||
if (m_type_idx == static_cast< unsigned int >(mpl::index_of< value_type, U >::type::value))
|
||||
return static_cast< const U* >(m_ptr);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//! Returns a reference to the value
|
||||
template< typename U >
|
||||
typename boost::enable_if_c< compatibility_traits::is_compatible< value_type, U >::value, U const& >::type get() const BOOST_NOEXCEPT
|
||||
{
|
||||
const U* const p = get_ptr< U >();
|
||||
BOOST_ASSERT(p != NULL);
|
||||
return *p;
|
||||
}
|
||||
|
||||
//! Returns the stored type index
|
||||
unsigned int which() const BOOST_NOEXCEPT
|
||||
{
|
||||
return m_type_idx;
|
||||
}
|
||||
|
||||
//! Swaps two reference wrappers
|
||||
void swap(variant_ref& that) BOOST_NOEXCEPT
|
||||
{
|
||||
const void* p = m_ptr;
|
||||
m_ptr = that.m_ptr;
|
||||
that.m_ptr = p;
|
||||
unsigned int type_idx = m_type_idx;
|
||||
m_type_idx = that.m_type_idx;
|
||||
that.m_type_idx = type_idx;
|
||||
}
|
||||
|
||||
//! Applies a visitor function object to the referred value
|
||||
template< typename VisitorT >
|
||||
typename VisitorT::result_type apply_visitor(VisitorT visitor) const
|
||||
{
|
||||
BOOST_ASSERT(m_ptr != NULL);
|
||||
return do_apply_visitor(visitor);
|
||||
}
|
||||
|
||||
//! Applies a visitor function object to the referred value
|
||||
template< typename VisitorT >
|
||||
typename boost::enable_if_c< is_void< typename VisitorT::result_type >::value, bool >::type apply_visitor_optional(VisitorT visitor) const
|
||||
{
|
||||
if (m_ptr)
|
||||
{
|
||||
do_apply_visitor(visitor);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
//! Applies a visitor function object to the referred value
|
||||
template< typename VisitorT >
|
||||
typename boost::disable_if_c< is_void< typename VisitorT::result_type >::value, optional< typename VisitorT::result_type > >::type apply_visitor_optional(VisitorT visitor) const
|
||||
{
|
||||
typedef optional< typename VisitorT::result_type > result_type;
|
||||
if (m_ptr)
|
||||
return result_type(do_apply_visitor(visitor));
|
||||
else
|
||||
return result_type();
|
||||
}
|
||||
|
||||
//! Applies a visitor function object to the referred value or returns a default value
|
||||
template< typename VisitorT, typename DefaultT >
|
||||
typename VisitorT::result_type apply_visitor_or_default(VisitorT visitor, DefaultT& def_val) const
|
||||
{
|
||||
if (m_ptr)
|
||||
return do_apply_visitor(visitor);
|
||||
else
|
||||
return def_val;
|
||||
}
|
||||
|
||||
//! Applies a visitor function object to the referred value or returns a default value
|
||||
template< typename VisitorT, typename DefaultT >
|
||||
typename VisitorT::result_type apply_visitor_or_default(VisitorT visitor, DefaultT const& def_val) const
|
||||
{
|
||||
if (m_ptr)
|
||||
return do_apply_visitor(visitor);
|
||||
else
|
||||
return def_val;
|
||||
}
|
||||
|
||||
private:
|
||||
template< typename VisitorT >
|
||||
typename VisitorT::result_type do_apply_visitor(VisitorT& visitor) const
|
||||
{
|
||||
BOOST_ASSERT(m_type_idx < static_cast< unsigned int >(mpl::size< value_type >::value));
|
||||
return apply_visitor_dispatch< value_type, VisitorT >::call(m_ptr, m_type_idx, visitor);
|
||||
}
|
||||
};
|
||||
|
||||
template< typename T, typename TagT >
|
||||
struct value_ref_base
|
||||
{
|
||||
typedef typename mpl::eval_if<
|
||||
mpl::and_< mpl::is_sequence< T >, mpl::equal_to< mpl::size< T >, mpl::int_< 1 > > >,
|
||||
mpl::front< T >,
|
||||
mpl::identity< T >
|
||||
>::type value_type;
|
||||
|
||||
typedef typename mpl::if_<
|
||||
mpl::is_sequence< value_type >,
|
||||
variant_ref< value_type, TagT >,
|
||||
singular_ref< value_type, TagT >
|
||||
>::type type;
|
||||
};
|
||||
|
||||
} // namespace aux
|
||||
|
||||
/*!
|
||||
* \brief Reference wrapper for a stored attribute value.
|
||||
*
|
||||
* The \c value_ref class template provides access to the stored attribute value. It is not a traditional reference wrapper
|
||||
* since it may be empty (i.e. refer to no value at all) and it can also refer to values of different types. Therefore its
|
||||
* interface and behavior combines features of Boost.Ref, Boost.Optional and Boost.Variant, depending on the use case.
|
||||
*
|
||||
* The template parameter \c T can be a single type or an MPL sequence of possible types being referred. The reference wrapper
|
||||
* will act as either an optional reference or an optional variant of references to the specified types. In any case, the
|
||||
* referred values will not be modifiable (i.e. \c value_ref always models a const reference).
|
||||
*
|
||||
* Template parameter \c TagT is optional. It can be used for customizing the operations on this reference wrapper, such as
|
||||
* putting the referred value to log.
|
||||
*/
|
||||
template< typename T, typename TagT >
|
||||
class value_ref :
|
||||
public aux::value_ref_base< T, TagT >::type
|
||||
{
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
public:
|
||||
typedef void _has_basic_formatting_ostream_insert_operator;
|
||||
#endif
|
||||
|
||||
private:
|
||||
//! Base implementation type
|
||||
typedef typename aux::value_ref_base< T, TagT >::type base_type;
|
||||
//! Traits for testing type compatibility with the reference wrapper
|
||||
typedef typename base_type::compatibility_traits compatibility_traits;
|
||||
|
||||
public:
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
//! Referenced value type
|
||||
typedef typename base_type::value_type value_type;
|
||||
#else
|
||||
//! Referenced value type
|
||||
typedef T value_type;
|
||||
//! Tag type
|
||||
typedef TagT tag_type;
|
||||
#endif
|
||||
|
||||
public:
|
||||
/*!
|
||||
* Default constructor. Creates a reference wrapper that does not refer to a value.
|
||||
*/
|
||||
BOOST_DEFAULTED_FUNCTION(value_ref(), BOOST_NOEXCEPT {})
|
||||
|
||||
/*!
|
||||
* Copy constructor.
|
||||
*/
|
||||
BOOST_DEFAULTED_FUNCTION(value_ref(value_ref const& that), BOOST_NOEXCEPT : base_type(static_cast< base_type const& >(that)) {})
|
||||
|
||||
/*!
|
||||
* Initializing constructor. Creates a reference wrapper that refers to the specified value.
|
||||
*/
|
||||
template< typename U >
|
||||
explicit value_ref(U const& val
|
||||
#ifndef BOOST_LOG_DOXYGEN_PASS
|
||||
// MSVC-8 can't handle SFINAE in this case properly and often wrongly disables this constructor
|
||||
#if !defined(_MSC_VER) || (_MSC_VER + 0) >= 1500
|
||||
, typename boost::enable_if_c< compatibility_traits::BOOST_NESTED_TEMPLATE is_compatible< value_type, U >::value, boost::log::aux::sfinae_dummy >::type = boost::log::aux::sfinae_dummy()
|
||||
#endif
|
||||
#endif
|
||||
) BOOST_NOEXCEPT :
|
||||
base_type(boost::addressof(val))
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* The operator verifies if the wrapper refers to a value.
|
||||
*/
|
||||
BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
|
||||
|
||||
/*!
|
||||
* The operator verifies if the wrapper does not refer to a value.
|
||||
*/
|
||||
bool operator! () const BOOST_NOEXCEPT
|
||||
{
|
||||
return !this->m_ptr;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \return \c true if the wrapper does not refer to a value.
|
||||
*/
|
||||
bool empty() const BOOST_NOEXCEPT
|
||||
{
|
||||
return !this->m_ptr;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Swaps two reference wrappers
|
||||
*/
|
||||
void swap(value_ref& that) BOOST_NOEXCEPT
|
||||
{
|
||||
base_type::swap(that);
|
||||
}
|
||||
};
|
||||
|
||||
//! Free swap function
|
||||
template< typename T, typename TagT >
|
||||
inline void swap(value_ref< T, TagT >& left, value_ref< T, TagT >& right)
|
||||
{
|
||||
left.swap(right);
|
||||
}
|
||||
|
||||
//! Stream output operator
|
||||
template< typename CharT, typename TraitsT, typename T, typename TagT >
|
||||
inline std::basic_ostream< CharT, TraitsT >& operator<< (std::basic_ostream< CharT, TraitsT >& strm, value_ref< T, TagT > const& val)
|
||||
{
|
||||
if (!!val)
|
||||
val.apply_visitor(boost::log::bind_output(strm));
|
||||
return strm;
|
||||
}
|
||||
|
||||
//! Log formatting operator
|
||||
template< typename CharT, typename TraitsT, typename AllocatorT, typename T, typename TagT >
|
||||
inline basic_formatting_ostream< CharT, TraitsT, AllocatorT >& operator<< (basic_formatting_ostream< CharT, TraitsT, AllocatorT >& strm, value_ref< T, TagT > const& val)
|
||||
{
|
||||
if (!!val)
|
||||
val.apply_visitor(boost::log::bind_to_log< TagT >(strm));
|
||||
return strm;
|
||||
}
|
||||
|
||||
// Equality comparison
|
||||
template< typename T, typename TagT, typename U >
|
||||
inline bool operator== (value_ref< T, TagT > const& left, U const& right)
|
||||
{
|
||||
return left.apply_visitor_or_default(binder2nd< equal_to, U const& >(equal_to(), right), false);
|
||||
}
|
||||
|
||||
template< typename U, typename T, typename TagT >
|
||||
inline bool operator== (U const& left, value_ref< T, TagT > const& right)
|
||||
{
|
||||
return right.apply_visitor_or_default(binder1st< equal_to, U const& >(equal_to(), left), false);
|
||||
}
|
||||
|
||||
template< typename T1, typename TagT1, typename T2, typename TagT2 >
|
||||
inline bool operator== (value_ref< T1, TagT1 > const& left, value_ref< T2, TagT2 > const& right)
|
||||
{
|
||||
if (!left && !right)
|
||||
return true;
|
||||
return left.apply_visitor_or_default(aux::vistation_invoker< value_ref< T2, TagT2 >, equal_to >(right, false), false);
|
||||
}
|
||||
|
||||
// Inequality comparison
|
||||
template< typename T, typename TagT, typename U >
|
||||
inline bool operator!= (value_ref< T, TagT > const& left, U const& right)
|
||||
{
|
||||
return left.apply_visitor_or_default(binder2nd< not_equal_to, U const& >(not_equal_to(), right), false);
|
||||
}
|
||||
|
||||
template< typename U, typename T, typename TagT >
|
||||
inline bool operator!= (U const& left, value_ref< T, TagT > const& right)
|
||||
{
|
||||
return right.apply_visitor_or_default(binder1st< not_equal_to, U const& >(not_equal_to(), left), false);
|
||||
}
|
||||
|
||||
template< typename T1, typename TagT1, typename T2, typename TagT2 >
|
||||
inline bool operator!= (value_ref< T1, TagT1 > const& left, value_ref< T2, TagT2 > const& right)
|
||||
{
|
||||
if (!left && !right)
|
||||
return false;
|
||||
return left.apply_visitor_or_default(aux::vistation_invoker< value_ref< T2, TagT2 >, not_equal_to >(right, false), false);
|
||||
}
|
||||
|
||||
// Less than ordering
|
||||
template< typename T, typename TagT, typename U >
|
||||
inline bool operator< (value_ref< T, TagT > const& left, U const& right)
|
||||
{
|
||||
return left.apply_visitor_or_default(binder2nd< less, U const& >(less(), right), false);
|
||||
}
|
||||
|
||||
template< typename U, typename T, typename TagT >
|
||||
inline bool operator< (U const& left, value_ref< T, TagT > const& right)
|
||||
{
|
||||
return right.apply_visitor_or_default(binder1st< less, U const& >(less(), left), false);
|
||||
}
|
||||
|
||||
template< typename T1, typename TagT1, typename T2, typename TagT2 >
|
||||
inline bool operator< (value_ref< T1, TagT1 > const& left, value_ref< T2, TagT2 > const& right)
|
||||
{
|
||||
return left.apply_visitor_or_default(aux::vistation_invoker< value_ref< T2, TagT2 >, less >(right, false), false);
|
||||
}
|
||||
|
||||
// Greater than ordering
|
||||
template< typename T, typename TagT, typename U >
|
||||
inline bool operator> (value_ref< T, TagT > const& left, U const& right)
|
||||
{
|
||||
return left.apply_visitor_or_default(binder2nd< greater, U const& >(greater(), right), false);
|
||||
}
|
||||
|
||||
template< typename U, typename T, typename TagT >
|
||||
inline bool operator> (U const& left, value_ref< T, TagT > const& right)
|
||||
{
|
||||
return right.apply_visitor_or_default(binder1st< greater, U const& >(greater(), left), false);
|
||||
}
|
||||
|
||||
template< typename T1, typename TagT1, typename T2, typename TagT2 >
|
||||
inline bool operator> (value_ref< T1, TagT1 > const& left, value_ref< T2, TagT2 > const& right)
|
||||
{
|
||||
return left.apply_visitor_or_default(aux::vistation_invoker< value_ref< T2, TagT2 >, greater >(right, false), false);
|
||||
}
|
||||
|
||||
// Less or equal ordering
|
||||
template< typename T, typename TagT, typename U >
|
||||
inline bool operator<= (value_ref< T, TagT > const& left, U const& right)
|
||||
{
|
||||
return left.apply_visitor_or_default(binder2nd< less_equal, U const& >(less_equal(), right), false);
|
||||
}
|
||||
|
||||
template< typename U, typename T, typename TagT >
|
||||
inline bool operator<= (U const& left, value_ref< T, TagT > const& right)
|
||||
{
|
||||
return right.apply_visitor_or_default(binder1st< less_equal, U const& >(less_equal(), left), false);
|
||||
}
|
||||
|
||||
template< typename T1, typename TagT1, typename T2, typename TagT2 >
|
||||
inline bool operator<= (value_ref< T1, TagT1 > const& left, value_ref< T2, TagT2 > const& right)
|
||||
{
|
||||
if (!left && !right)
|
||||
return true;
|
||||
return left.apply_visitor_or_default(aux::vistation_invoker< value_ref< T2, TagT2 >, less_equal >(right, false), false);
|
||||
}
|
||||
|
||||
// Greater or equal ordering
|
||||
template< typename T, typename TagT, typename U >
|
||||
inline bool operator>= (value_ref< T, TagT > const& left, U const& right)
|
||||
{
|
||||
return left.apply_visitor_or_default(binder2nd< greater_equal, U const& >(greater_equal(), right), false);
|
||||
}
|
||||
|
||||
template< typename U, typename T, typename TagT >
|
||||
inline bool operator>= (U const& left, value_ref< T, TagT > const& right)
|
||||
{
|
||||
return right.apply_visitor_or_default(binder1st< greater_equal, U const& >(greater_equal(), left), false);
|
||||
}
|
||||
|
||||
template< typename T1, typename TagT1, typename T2, typename TagT2 >
|
||||
inline bool operator>= (value_ref< T1, TagT1 > const& left, value_ref< T2, TagT2 > const& right)
|
||||
{
|
||||
if (!left && !right)
|
||||
return true;
|
||||
return left.apply_visitor_or_default(aux::vistation_invoker< value_ref< T2, TagT2 >, greater_equal >(right, false), false);
|
||||
}
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/log/detail/footer.hpp>
|
||||
|
||||
#endif // BOOST_LOG_UTILITY_VALUE_REF_HPP_INCLUDED_
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright Andrey Semashev 2007 - 2015.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
/*!
|
||||
* \file value_ref_fwd.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 27.07.2012
|
||||
*
|
||||
* The header contains forward declaration of a value reference wrapper.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_LOG_UTILITY_VALUE_REF_FWD_HPP_INCLUDED_
|
||||
#define BOOST_LOG_UTILITY_VALUE_REF_FWD_HPP_INCLUDED_
|
||||
|
||||
#include <boost/log/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
BOOST_LOG_OPEN_NAMESPACE
|
||||
|
||||
/*!
|
||||
* \brief Reference wrapper for a stored attribute value.
|
||||
*/
|
||||
template< typename T, typename TagT = void >
|
||||
class value_ref;
|
||||
|
||||
BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_LOG_UTILITY_VALUE_REF_FWD_HPP_INCLUDED_
|
||||
Reference in New Issue
Block a user