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

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