summaryrefslogtreecommitdiff
path: root/boost/log
diff options
context:
space:
mode:
authorChanho Park <chanho61.park@samsung.com>2014-12-11 09:55:56 (GMT)
committerChanho Park <chanho61.park@samsung.com>2014-12-11 09:55:56 (GMT)
commit08c1e93fa36a49f49325a07fe91ff92c964c2b6c (patch)
tree7a7053ceb8874b28ec4b868d4c49b500008a102e /boost/log
parentbb4dd8289b351fae6b55e303f189127a394a1edd (diff)
downloadboost-08c1e93fa36a49f49325a07fe91ff92c964c2b6c.zip
boost-08c1e93fa36a49f49325a07fe91ff92c964c2b6c.tar.gz
boost-08c1e93fa36a49f49325a07fe91ff92c964c2b6c.tar.bz2
Imported Upstream version 1.57.0upstream/1.57.0
Diffstat (limited to 'boost/log')
-rw-r--r--boost/log/attributes.hpp38
-rw-r--r--boost/log/attributes/attribute.hpp191
-rw-r--r--boost/log/attributes/attribute_cast.hpp74
-rw-r--r--boost/log/attributes/attribute_name.hpp185
-rw-r--r--boost/log/attributes/attribute_set.hpp507
-rw-r--r--boost/log/attributes/attribute_value.hpp380
-rw-r--r--boost/log/attributes/attribute_value_impl.hpp136
-rw-r--r--boost/log/attributes/attribute_value_set.hpp480
-rw-r--r--boost/log/attributes/clock.hpp95
-rw-r--r--boost/log/attributes/constant.hpp122
-rw-r--r--boost/log/attributes/counter.hpp218
-rw-r--r--boost/log/attributes/current_process_id.hpp67
-rw-r--r--boost/log/attributes/current_process_name.hpp71
-rw-r--r--boost/log/attributes/current_thread_id.hpp109
-rw-r--r--boost/log/attributes/fallback_policy.hpp186
-rw-r--r--boost/log/attributes/fallback_policy_fwd.hpp48
-rw-r--r--boost/log/attributes/function.hpp170
-rw-r--r--boost/log/attributes/mutable_constant.hpp332
-rw-r--r--boost/log/attributes/named_scope.hpp474
-rw-r--r--boost/log/attributes/scoped_attribute.hpp253
-rw-r--r--boost/log/attributes/time_traits.hpp81
-rw-r--r--boost/log/attributes/timer.hpp83
-rw-r--r--boost/log/attributes/value_extraction.hpp816
-rw-r--r--boost/log/attributes/value_extraction_fwd.hpp62
-rw-r--r--boost/log/attributes/value_visitation.hpp372
-rw-r--r--boost/log/attributes/value_visitation_fwd.hpp45
-rw-r--r--boost/log/common.hpp41
-rw-r--r--boost/log/core.hpp28
-rw-r--r--boost/log/core/core.hpp329
-rw-r--r--boost/log/core/record.hpp207
-rw-r--r--boost/log/core/record_view.hpp260
-rw-r--r--boost/log/detail/asio_fwd.hpp43
-rw-r--r--boost/log/detail/attachable_sstream_buf.hpp172
-rw-r--r--boost/log/detail/attr_output_impl.hpp111
-rw-r--r--boost/log/detail/attr_output_terminal.hpp162
-rw-r--r--boost/log/detail/attribute_get_value_impl.hpp43
-rw-r--r--boost/log/detail/attribute_predicate.hpp116
-rw-r--r--boost/log/detail/cleanup_scope_guard.hpp55
-rw-r--r--boost/log/detail/code_conversion.hpp119
-rw-r--r--boost/log/detail/config.hpp351
-rw-r--r--boost/log/detail/copy_cv.hpp64
-rw-r--r--boost/log/detail/custom_terminal_spec.hpp70
-rw-r--r--boost/log/detail/date_time_fmt_gen_traits_fwd.hpp44
-rw-r--r--boost/log/detail/date_time_format_parser.hpp486
-rw-r--r--boost/log/detail/decomposed_time.hpp440
-rw-r--r--boost/log/detail/deduce_char_type.hpp108
-rw-r--r--boost/log/detail/default_attribute_names.hpp53
-rw-r--r--boost/log/detail/embedded_string_type.hpp125
-rw-r--r--boost/log/detail/enqueued_record.hpp103
-rw-r--r--boost/log/detail/event.hpp142
-rw-r--r--boost/log/detail/fake_mutex.hpp56
-rw-r--r--boost/log/detail/footer.hpp22
-rw-r--r--boost/log/detail/format.hpp336
-rw-r--r--boost/log/detail/function_traits.hpp236
-rw-r--r--boost/log/detail/generate_overloads.hpp30
-rw-r--r--boost/log/detail/header.hpp64
-rw-r--r--boost/log/detail/id.hpp84
-rw-r--r--boost/log/detail/light_function.hpp521
-rw-r--r--boost/log/detail/light_function_pp.hpp424
-rw-r--r--boost/log/detail/light_rw_mutex.hpp208
-rw-r--r--boost/log/detail/locking_ptr.hpp148
-rw-r--r--boost/log/detail/locks.hpp180
-rw-r--r--boost/log/detail/named_scope_fmt_pp.hpp82
-rw-r--r--boost/log/detail/native_typeof.hpp63
-rw-r--r--boost/log/detail/parameter_tools.hpp114
-rw-r--r--boost/log/detail/pp_identity.hpp27
-rw-r--r--boost/log/detail/process_id.hpp60
-rw-r--r--boost/log/detail/setup_config.hpp61
-rw-r--r--boost/log/detail/singleton.hpp89
-rw-r--r--boost/log/detail/sink_init_helpers.hpp118
-rw-r--r--boost/log/detail/snprintf.hpp106
-rw-r--r--boost/log/detail/spin_mutex.hpp319
-rw-r--r--boost/log/detail/tagged_integer.hpp147
-rw-r--r--boost/log/detail/thread_id.hpp65
-rw-r--r--boost/log/detail/thread_specific.hpp116
-rw-r--r--boost/log/detail/threadsafe_queue.hpp277
-rw-r--r--boost/log/detail/timestamp.hpp99
-rw-r--r--boost/log/detail/trivial_keyword.hpp43
-rw-r--r--boost/log/detail/unary_function_terminal.hpp142
-rw-r--r--boost/log/detail/unhandled_exception_count.hpp40
-rw-r--r--boost/log/detail/value_ref_visitation.hpp107
-rw-r--r--boost/log/detail/visible_type.hpp48
-rw-r--r--boost/log/exceptions.hpp387
-rw-r--r--boost/log/expressions.hpp38
-rw-r--r--boost/log/expressions/attr.hpp276
-rw-r--r--boost/log/expressions/attr_fwd.hpp69
-rw-r--r--boost/log/expressions/filter.hpp183
-rw-r--r--boost/log/expressions/formatter.hpp257
-rw-r--r--boost/log/expressions/formatters.hpp38
-rw-r--r--boost/log/expressions/formatters/c_decorator.hpp281
-rw-r--r--boost/log/expressions/formatters/char_decorator.hpp639
-rw-r--r--boost/log/expressions/formatters/csv_decorator.hpp140
-rw-r--r--boost/log/expressions/formatters/date_time.hpp343
-rw-r--r--boost/log/expressions/formatters/format.hpp128
-rw-r--r--boost/log/expressions/formatters/if.hpp315
-rw-r--r--boost/log/expressions/formatters/named_scope.hpp653
-rw-r--r--boost/log/expressions/formatters/stream.hpp53
-rw-r--r--boost/log/expressions/formatters/wrap_formatter.hpp338
-rw-r--r--boost/log/expressions/formatters/xml_decorator.hpp138
-rw-r--r--boost/log/expressions/is_keyword_descriptor.hpp67
-rw-r--r--boost/log/expressions/keyword.hpp258
-rw-r--r--boost/log/expressions/keyword_fwd.hpp53
-rw-r--r--boost/log/expressions/message.hpp130
-rw-r--r--boost/log/expressions/predicates.hpp34
-rw-r--r--boost/log/expressions/predicates/begins_with.hpp129
-rw-r--r--boost/log/expressions/predicates/channel_severity_filter.hpp572
-rw-r--r--boost/log/expressions/predicates/contains.hpp129
-rw-r--r--boost/log/expressions/predicates/ends_with.hpp129
-rw-r--r--boost/log/expressions/predicates/has_attr.hpp172
-rw-r--r--boost/log/expressions/predicates/is_debugger_present.hpp107
-rw-r--r--boost/log/expressions/predicates/is_in_range.hpp133
-rw-r--r--boost/log/expressions/predicates/matches.hpp119
-rw-r--r--boost/log/expressions/record.hpp50
-rw-r--r--boost/log/keywords/auto_flush.hpp40
-rw-r--r--boost/log/keywords/channel.hpp40
-rw-r--r--boost/log/keywords/delimiter.hpp40
-rw-r--r--boost/log/keywords/depth.hpp40
-rw-r--r--boost/log/keywords/empty_marker.hpp40
-rw-r--r--boost/log/keywords/facility.hpp40
-rw-r--r--boost/log/keywords/file_name.hpp40
-rw-r--r--boost/log/keywords/filter.hpp40
-rw-r--r--boost/log/keywords/format.hpp40
-rw-r--r--boost/log/keywords/ident.hpp40
-rw-r--r--boost/log/keywords/incomplete_marker.hpp40
-rw-r--r--boost/log/keywords/ip_version.hpp40
-rw-r--r--boost/log/keywords/iteration.hpp40
-rw-r--r--boost/log/keywords/log_name.hpp40
-rw-r--r--boost/log/keywords/log_source.hpp40
-rw-r--r--boost/log/keywords/max_size.hpp40
-rw-r--r--boost/log/keywords/message_file.hpp40
-rw-r--r--boost/log/keywords/min_free_space.hpp40
-rw-r--r--boost/log/keywords/open_mode.hpp40
-rw-r--r--boost/log/keywords/order.hpp40
-rw-r--r--boost/log/keywords/ordering_window.hpp40
-rw-r--r--boost/log/keywords/registration.hpp40
-rw-r--r--boost/log/keywords/rotation_size.hpp40
-rw-r--r--boost/log/keywords/scan_method.hpp40
-rw-r--r--boost/log/keywords/severity.hpp40
-rw-r--r--boost/log/keywords/start_thread.hpp40
-rw-r--r--boost/log/keywords/target.hpp40
-rw-r--r--boost/log/keywords/time_based_rotation.hpp40
-rw-r--r--boost/log/keywords/use_impl.hpp40
-rw-r--r--boost/log/sinks.hpp47
-rw-r--r--boost/log/sinks/async_frontend.hpp462
-rw-r--r--boost/log/sinks/attribute_mapping.hpp290
-rw-r--r--boost/log/sinks/basic_sink_backend.hpp97
-rw-r--r--boost/log/sinks/basic_sink_frontend.hpp524
-rw-r--r--boost/log/sinks/block_on_overflow.hpp147
-rw-r--r--boost/log/sinks/bounded_fifo_queue.hpp192
-rw-r--r--boost/log/sinks/bounded_ordering_queue.hpp262
-rw-r--r--boost/log/sinks/debug_output_backend.hpp93
-rw-r--r--boost/log/sinks/drop_on_overflow.hpp80
-rw-r--r--boost/log/sinks/event_log_backend.hpp662
-rw-r--r--boost/log/sinks/event_log_constants.hpp88
-rw-r--r--boost/log/sinks/frontend_requirements.hpp119
-rw-r--r--boost/log/sinks/sink.hpp115
-rw-r--r--boost/log/sinks/sync_frontend.hpp166
-rw-r--r--boost/log/sinks/syslog_backend.hpp288
-rw-r--r--boost/log/sinks/syslog_constants.hpp101
-rw-r--r--boost/log/sinks/text_file_backend.hpp539
-rw-r--r--boost/log/sinks/text_multifile_backend.hpp201
-rw-r--r--boost/log/sinks/text_ostream_backend.hpp124
-rw-r--r--boost/log/sinks/unbounded_fifo_queue.hpp142
-rw-r--r--boost/log/sinks/unbounded_ordering_queue.hpp245
-rw-r--r--boost/log/sinks/unlocked_frontend.hpp142
-rw-r--r--boost/log/sources/basic_logger.hpp742
-rw-r--r--boost/log/sources/channel_feature.hpp242
-rw-r--r--boost/log/sources/channel_logger.hpp325
-rw-r--r--boost/log/sources/exception_handler_feature.hpp253
-rw-r--r--boost/log/sources/features.hpp150
-rw-r--r--boost/log/sources/global_logger_storage.hpp206
-rw-r--r--boost/log/sources/logger.hpp103
-rw-r--r--boost/log/sources/record_ostream.hpp335
-rw-r--r--boost/log/sources/severity_channel_logger.hpp309
-rw-r--r--boost/log/sources/severity_feature.hpp310
-rw-r--r--boost/log/sources/severity_logger.hpp325
-rw-r--r--boost/log/sources/threading_models.hpp125
-rw-r--r--boost/log/support/date_time.hpp548
-rw-r--r--boost/log/support/exception.hpp72
-rw-r--r--boost/log/support/regex.hpp76
-rw-r--r--boost/log/support/spirit_classic.hpp112
-rw-r--r--boost/log/support/spirit_qi.hpp92
-rw-r--r--boost/log/support/std_regex.hpp86
-rw-r--r--boost/log/support/xpressive.hpp75
-rw-r--r--boost/log/trivial.hpp127
-rw-r--r--boost/log/utility/empty_deleter.hpp42
-rw-r--r--boost/log/utility/exception_handler.hpp354
-rw-r--r--boost/log/utility/explicit_operator_bool.hpp42
-rw-r--r--boost/log/utility/formatting_ostream.hpp748
-rw-r--r--boost/log/utility/formatting_ostream_fwd.hpp51
-rw-r--r--boost/log/utility/functional.hpp40
-rw-r--r--boost/log/utility/functional/as_action.hpp60
-rw-r--r--boost/log/utility/functional/begins_with.hpp57
-rw-r--r--boost/log/utility/functional/bind.hpp237
-rw-r--r--boost/log/utility/functional/bind_assign.hpp55
-rw-r--r--boost/log/utility/functional/bind_output.hpp55
-rw-r--r--boost/log/utility/functional/bind_to_log.hpp76
-rw-r--r--boost/log/utility/functional/contains.hpp69
-rw-r--r--boost/log/utility/functional/ends_with.hpp57
-rw-r--r--boost/log/utility/functional/fun_ref.hpp79
-rw-r--r--boost/log/utility/functional/in_range.hpp63
-rw-r--r--boost/log/utility/functional/logical.hpp225
-rw-r--r--boost/log/utility/functional/matches.hpp66
-rw-r--r--boost/log/utility/functional/nop.hpp55
-rw-r--r--boost/log/utility/functional/save_result.hpp60
-rw-r--r--boost/log/utility/intrusive_ref_counter.hpp55
-rw-r--r--boost/log/utility/manipulators.hpp28
-rw-r--r--boost/log/utility/manipulators/add_value.hpp165
-rw-r--r--boost/log/utility/manipulators/dump.hpp231
-rw-r--r--boost/log/utility/manipulators/to_log.hpp87
-rw-r--r--boost/log/utility/once_block.hpp196
-rw-r--r--boost/log/utility/record_ordering.hpp229
-rw-r--r--boost/log/utility/setup.hpp37
-rw-r--r--boost/log/utility/setup/common_attributes.hpp76
-rw-r--r--boost/log/utility/setup/console.hpp243
-rw-r--r--boost/log/utility/setup/file.hpp166
-rw-r--r--boost/log/utility/setup/filter_parser.hpp346
-rw-r--r--boost/log/utility/setup/formatter_parser.hpp216
-rw-r--r--boost/log/utility/setup/from_settings.hpp164
-rw-r--r--boost/log/utility/setup/from_stream.hpp47
-rw-r--r--boost/log/utility/setup/settings.hpp643
-rw-r--r--boost/log/utility/setup/settings_parser.hpp47
-rw-r--r--boost/log/utility/strictest_lock.hpp214
-rw-r--r--boost/log/utility/string_literal.hpp617
-rw-r--r--boost/log/utility/string_literal_fwd.hpp55
-rw-r--r--boost/log/utility/type_dispatch/date_time_types.hpp138
-rw-r--r--boost/log/utility/type_dispatch/dynamic_type_dispatcher.hpp154
-rw-r--r--boost/log/utility/type_dispatch/standard_types.hpp105
-rw-r--r--boost/log/utility/type_dispatch/static_type_dispatcher.hpp319
-rw-r--r--boost/log/utility/type_dispatch/type_dispatcher.hpp189
-rw-r--r--boost/log/utility/type_info_wrapper.hpp188
-rw-r--r--boost/log/utility/unique_identifier_name.hpp51
-rw-r--r--boost/log/utility/unused_variable.hpp51
-rw-r--r--boost/log/utility/value_ref.hpp630
-rw-r--r--boost/log/utility/value_ref_fwd.hpp38
235 files changed, 39172 insertions, 0 deletions
diff --git a/boost/log/attributes.hpp b/boost/log/attributes.hpp
new file mode 100644
index 0000000..92b9c25
--- /dev/null
+++ b/boost/log/attributes.hpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file attributes.hpp
+ * \author Andrey Semashev
+ * \date 13.07.2009
+ *
+ * This header includes other Boost.Log headers with all attributes.
+ */
+
+#ifndef BOOST_LOG_ATTRIBUTES_HPP_INCLUDED_
+#define BOOST_LOG_ATTRIBUTES_HPP_INCLUDED_
+
+#include <boost/log/detail/config.hpp>
+
+#include <boost/log/attributes/attribute.hpp>
+#include <boost/log/attributes/clock.hpp>
+#include <boost/log/attributes/constant.hpp>
+#include <boost/log/attributes/counter.hpp>
+#include <boost/log/attributes/function.hpp>
+#include <boost/log/attributes/mutable_constant.hpp>
+#include <boost/log/attributes/named_scope.hpp>
+#include <boost/log/attributes/timer.hpp>
+#include <boost/log/attributes/current_process_name.hpp>
+#include <boost/log/attributes/current_process_id.hpp>
+#if !defined(BOOST_LOG_NO_THREADS)
+#include <boost/log/attributes/current_thread_id.hpp>
+#endif
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#endif // BOOST_LOG_ATTRIBUTES_HPP_INCLUDED_
diff --git a/boost/log/attributes/attribute.hpp b/boost/log/attributes/attribute.hpp
new file mode 100644
index 0000000..0d6ba64
--- /dev/null
+++ b/boost/log/attributes/attribute.hpp
@@ -0,0 +1,191 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file attribute.hpp
+ * \author Andrey Semashev
+ * \date 15.04.2007
+ *
+ * The header contains attribute interface definition.
+ */
+
+#ifndef BOOST_LOG_ATTRIBUTES_ATTRIBUTE_HPP_INCLUDED_
+#define BOOST_LOG_ATTRIBUTES_ATTRIBUTE_HPP_INCLUDED_
+
+#include <new>
+#include <boost/move/core.hpp>
+#include <boost/smart_ptr/intrusive_ptr.hpp>
+#include <boost/smart_ptr/intrusive_ref_counter.hpp>
+#include <boost/log/detail/config.hpp>
+#include <boost/utility/explicit_operator_bool.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+#ifndef BOOST_LOG_DOXYGEN_PASS
+
+class attribute_value;
+
+namespace aux {
+
+//! Reference proxy object to implement \c operator[]
+class attribute_set_reference_proxy;
+
+} // namespace aux
+
+#endif // BOOST_LOG_DOXYGEN_PASS
+
+/*!
+ * \brief A base class for an attribute value factory
+ *
+ * Every attribute is represented with a factory that is basically an attribute value generator.
+ * The sole purpose of an attribute is to return an actual value when requested. A simplest attribute
+ * can always return the same value that it stores internally, but more complex ones can
+ * perform a considerable amount of work to return a value, and the returned values may differ
+ * each time requested.
+ *
+ * A word about thread safety. An attribute should be prepared to be requested a value from
+ * multiple threads concurrently.
+ */
+class attribute
+{
+ BOOST_COPYABLE_AND_MOVABLE(attribute)
+
+public:
+ /*!
+ * \brief A base class for an attribute value factory
+ *
+ * All attributes must derive their implementation from this class.
+ */
+ struct BOOST_LOG_NO_VTABLE BOOST_SYMBOL_VISIBLE impl :
+ public boost::intrusive_ref_counter< impl >
+ {
+ /*!
+ * \brief Virtual destructor
+ */
+ virtual ~impl() {}
+
+ /*!
+ * \return The actual attribute value. It shall not return empty values (exceptions
+ * shall be used to indicate errors).
+ */
+ virtual attribute_value get_value() = 0;
+
+ BOOST_LOG_API static void* operator new (std::size_t size);
+ BOOST_LOG_API static void operator delete (void* p, std::size_t size) BOOST_NOEXCEPT;
+ };
+
+private:
+ //! Pointer to the attribute factory implementation
+ intrusive_ptr< impl > m_pImpl;
+
+public:
+ /*!
+ * Default constructor. Creates an empty attribute value factory, which is not usable until
+ * \c set_impl is called.
+ */
+ BOOST_DEFAULTED_FUNCTION(attribute(), {})
+
+ /*!
+ * Copy constructor
+ */
+ attribute(attribute const& that) BOOST_NOEXCEPT : m_pImpl(that.m_pImpl) {}
+
+ /*!
+ * Move constructor
+ */
+ attribute(BOOST_RV_REF(attribute) that) BOOST_NOEXCEPT { m_pImpl.swap(that.m_pImpl); }
+
+ /*!
+ * Initializing constructor
+ *
+ * \param p Pointer to the implementation. Must not be \c NULL.
+ */
+ explicit attribute(intrusive_ptr< impl > p) BOOST_NOEXCEPT { m_pImpl.swap(p); }
+
+ /*!
+ * Copy assignment
+ */
+ attribute& operator= (BOOST_COPY_ASSIGN_REF(attribute) that) BOOST_NOEXCEPT
+ {
+ m_pImpl = that.m_pImpl;
+ return *this;
+ }
+
+ /*!
+ * Move assignment
+ */
+ attribute& operator= (BOOST_RV_REF(attribute) that) BOOST_NOEXCEPT
+ {
+ m_pImpl.swap(that.m_pImpl);
+ return *this;
+ }
+
+#ifndef BOOST_LOG_DOXYGEN_PASS
+ attribute& operator= (aux::attribute_set_reference_proxy const& that) BOOST_NOEXCEPT;
+#endif
+
+ /*!
+ * Verifies that the factory is not in empty state
+ */
+ BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
+
+ /*!
+ * Verifies that the factory is in empty state
+ */
+ bool operator! () const BOOST_NOEXCEPT { return !m_pImpl; }
+
+ /*!
+ * \return The actual attribute value. It shall not return empty values (exceptions
+ * shall be used to indicate errors).
+ */
+ attribute_value get_value() const;
+
+ /*!
+ * The method swaps two factories (i.e. their implementations).
+ */
+ void swap(attribute& that) BOOST_NOEXCEPT { m_pImpl.swap(that.m_pImpl); }
+
+protected:
+ /*!
+ * \returns The pointer to the implementation
+ */
+ impl* get_impl() const BOOST_NOEXCEPT { return m_pImpl.get(); }
+ /*!
+ * Sets the pointer to the factory implementation.
+ *
+ * \param p Pointer to the implementation. Must not be \c NULL.
+ */
+ void set_impl(intrusive_ptr< impl > p) BOOST_NOEXCEPT { m_pImpl.swap(p); }
+
+ template< typename T >
+ friend T attribute_cast(attribute const&);
+};
+
+/*!
+ * The function swaps two attribute value factories
+ */
+inline void swap(attribute& left, attribute& right) BOOST_NOEXCEPT
+{
+ left.swap(right);
+}
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+#if defined(BOOST_LOG_ATTRIBUTES_ATTRIBUTE_VALUE_HPP_INCLUDED_)
+#include <boost/log/detail/attribute_get_value_impl.hpp>
+#endif
+
+#endif // BOOST_LOG_ATTRIBUTES_ATTRIBUTE_HPP_INCLUDED_
diff --git a/boost/log/attributes/attribute_cast.hpp b/boost/log/attributes/attribute_cast.hpp
new file mode 100644
index 0000000..7ae1c92
--- /dev/null
+++ b/boost/log/attributes/attribute_cast.hpp
@@ -0,0 +1,74 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file attribute_cast.hpp
+ * \author Andrey Semashev
+ * \date 06.08.2010
+ *
+ * The header contains utilities for casting between attribute factories.
+ */
+
+#ifndef BOOST_LOG_ATTRIBUTES_ATTRIBUTE_CAST_HPP_INCLUDED_
+#define BOOST_LOG_ATTRIBUTES_ATTRIBUTE_CAST_HPP_INCLUDED_
+
+#include <boost/log/detail/config.hpp>
+#include <boost/log/attributes/attribute.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace attributes {
+
+/*!
+ * The class holds a reference to the attribute factory implementation being casted
+ */
+class cast_source
+{
+private:
+ attribute::impl* m_pImpl;
+
+public:
+ /*!
+ * Initializing constructor. Creates a source that refers to the specified factory implementation.
+ */
+ explicit cast_source(attribute::impl* p) : m_pImpl(p)
+ {
+ }
+
+ /*!
+ * The function attempts to cast the aggregated pointer to the implementation to the specified type.
+ *
+ * \return The converted pointer or \c NULL, if the conversion fails.
+ */
+ template< typename T >
+ T* as() const { return dynamic_cast< T* >(m_pImpl); }
+};
+
+} // namespace attributes
+
+/*!
+ * The function casts one attribute factory to another
+ */
+template< typename T >
+inline T attribute_cast(attribute const& attr)
+{
+ return T(attributes::cast_source(attr.get_impl()));
+}
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_ATTRIBUTES_ATTRIBUTE_CAST_HPP_INCLUDED_
diff --git a/boost/log/attributes/attribute_name.hpp b/boost/log/attributes/attribute_name.hpp
new file mode 100644
index 0000000..4e283e6
--- /dev/null
+++ b/boost/log/attributes/attribute_name.hpp
@@ -0,0 +1,185 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file attribute_name.hpp
+ * \author Andrey Semashev
+ * \date 28.06.2010
+ *
+ * The header contains attribute name interface definition.
+ */
+
+#ifndef BOOST_LOG_ATTRIBUTE_NAME_HPP_INCLUDED_
+#define BOOST_LOG_ATTRIBUTE_NAME_HPP_INCLUDED_
+
+#include <iosfwd>
+#include <string>
+#include <boost/assert.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/log/detail/config.hpp>
+#include <boost/utility/explicit_operator_bool.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+/*!
+ * \brief The class represents an attribute name in containers used by the library
+ *
+ * The class mostly serves for optimization purposes. Each attribute name that is used
+ * with the library is automatically associated with a unique identifier, which is much
+ * lighter in terms of memory footprint and operations complexity. This is done
+ * transparently by this class, on object construction. Passing objects of this class
+ * to other library methods, such as attribute lookup functions, will not require
+ * this translation and/or string copying and thus will result in a more efficient code.
+ */
+class attribute_name
+{
+public:
+ //! String type
+ typedef std::string string_type;
+#ifdef BOOST_LOG_DOXYGEN_PASS
+ //! Associated identifier
+ typedef unspecified id_type;
+#else
+ typedef uint32_t id_type;
+
+private:
+ enum { uninitialized = 0xFFFFFFFFu };
+
+ class repository;
+ friend class repository;
+
+private:
+ //! Associated identifier
+ id_type m_id;
+#endif
+
+public:
+ /*!
+ * Default constructor. Creates an object that does not refer to any attribute name.
+ */
+ BOOST_CONSTEXPR attribute_name() BOOST_NOEXCEPT : m_id(static_cast< id_type >(uninitialized))
+ {
+ }
+ /*!
+ * Constructs an attribute name from the specified string
+ *
+ * \param name An attribute name
+ * \pre \a name is not NULL and points to a zero-terminated string
+ */
+ attribute_name(const char* name) :
+ m_id(get_id_from_string(name))
+ {
+ }
+ /*!
+ * Constructs an attribute name from the specified string
+ *
+ * \param name An attribute name
+ */
+ attribute_name(string_type const& name) :
+ m_id(get_id_from_string(name.c_str()))
+ {
+ }
+
+ /*!
+ * Compares the attribute names
+ *
+ * \return \c true if <tt>*this</tt> and \c that refer to the same attribute name,
+ * and \c false otherwise.
+ */
+ bool operator== (attribute_name const& that) const BOOST_NOEXCEPT { return m_id == that.m_id; }
+ /*!
+ * Compares the attribute names
+ *
+ * \return \c true if <tt>*this</tt> and \c that refer to different attribute names,
+ * and \c false otherwise.
+ */
+ bool operator!= (attribute_name const& that) const BOOST_NOEXCEPT { return m_id != that.m_id; }
+
+ /*!
+ * Compares the attribute names
+ *
+ * \return \c true if <tt>*this</tt> and \c that refer to the same attribute name,
+ * and \c false otherwise.
+ */
+ bool operator== (const char* that) const { return (m_id != static_cast< id_type >(uninitialized)) && (this->string() == that); }
+ /*!
+ * Compares the attribute names
+ *
+ * \return \c true if <tt>*this</tt> and \c that refer to different attribute names,
+ * and \c false otherwise.
+ */
+ bool operator!= (const char* that) const { return !operator== (that); }
+
+ /*!
+ * Compares the attribute names
+ *
+ * \return \c true if <tt>*this</tt> and \c that refer to the same attribute name,
+ * and \c false otherwise.
+ */
+ bool operator== (string_type const& that) const { return (m_id != static_cast< id_type >(uninitialized)) && (this->string() == that); }
+ /*!
+ * Compares the attribute names
+ *
+ * \return \c true if <tt>*this</tt> and \c that refer to different attribute names,
+ * and \c false otherwise.
+ */
+ bool operator!= (string_type const& that) const { return !operator== (that); }
+
+ /*!
+ * Checks if the object was default-constructed
+ *
+ * \return \c true if <tt>*this</tt> was constructed with an attribute name, \c false otherwise
+ */
+ BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
+ /*!
+ * Checks if the object was default-constructed
+ *
+ * \return \c true if <tt>*this</tt> was default-constructed and does not refer to any attribute name,
+ * \c false otherwise
+ */
+ bool operator! () const BOOST_NOEXCEPT { return (m_id == static_cast< id_type >(uninitialized)); }
+
+ /*!
+ * \return The associated id value
+ * \pre <tt>(!*this) == false</tt>
+ */
+ id_type id() const BOOST_NOEXCEPT
+ {
+ BOOST_ASSERT(m_id != static_cast< id_type >(uninitialized));
+ return m_id;
+ }
+ /*!
+ * \return The attribute name string that was used during the object construction
+ * \pre <tt>(!*this) == false</tt>
+ */
+ string_type const& string() const { return get_string_from_id(m_id); }
+
+private:
+#ifndef BOOST_LOG_DOXYGEN_PASS
+ static BOOST_LOG_API id_type get_id_from_string(const char* name);
+ static BOOST_LOG_API string_type const& get_string_from_id(id_type id);
+#endif
+};
+
+template< typename CharT, typename TraitsT >
+BOOST_LOG_API std::basic_ostream< CharT, TraitsT >& operator<< (
+ std::basic_ostream< CharT, TraitsT >& strm,
+ attribute_name const& name);
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_ATTRIBUTE_NAME_HPP_INCLUDED_
diff --git a/boost/log/attributes/attribute_set.hpp b/boost/log/attributes/attribute_set.hpp
new file mode 100644
index 0000000..5481c09
--- /dev/null
+++ b/boost/log/attributes/attribute_set.hpp
@@ -0,0 +1,507 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file attribute_set.hpp
+ * \author Andrey Semashev
+ * \date 08.03.2007
+ *
+ * This header contains definition of the attribute set container.
+ */
+
+#ifndef BOOST_LOG_ATTRIBUTE_SET_HPP_INCLUDED_
+#define BOOST_LOG_ATTRIBUTE_SET_HPP_INCLUDED_
+
+#include <cstddef>
+#include <utility>
+#include <iterator>
+#include <boost/mpl/if.hpp>
+#include <boost/move/core.hpp>
+#include <boost/log/detail/config.hpp>
+#include <boost/log/attributes/attribute_name.hpp>
+#include <boost/log/attributes/attribute.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+class attribute_set;
+class attribute_value_set;
+
+namespace aux {
+
+//! Reference proxy object to implement \c operator[]
+class attribute_set_reference_proxy
+{
+private:
+ //! Key type
+ typedef attribute_name key_type;
+ //! Mapped attribute type
+ typedef attribute mapped_type;
+
+private:
+ attribute_set* const m_pContainer;
+ const key_type m_key;
+
+public:
+ //! Constructor
+ explicit attribute_set_reference_proxy(attribute_set* pContainer, key_type const& key) BOOST_NOEXCEPT :
+ m_pContainer(pContainer),
+ m_key(key)
+ {
+ }
+
+ //! Conversion operator (would be invoked in case of reading from the container)
+ operator mapped_type() const BOOST_NOEXCEPT;
+ //! Assignment operator (would be invoked in case of writing to the container)
+ mapped_type& operator= (mapped_type const& val) const;
+};
+
+} // namespace aux
+
+/*!
+ * \brief An attribute set class.
+ *
+ * An attribute set is an associative container with attribute name as a key and
+ * pointer to the attribute as a mapped value. The container allows storing only one element for each distinct
+ * key value. In most regards attribute set container provides interface similar to \c std::unordered_map.
+ * However, there are differences in \c operator[] semantics and a number of optimizations with regard to iteration.
+ * Besides, attribute names are stored as a read-only <tt>attribute_name</tt>'s instead of \c std::string,
+ * which saves memory and CPU time.
+ */
+class attribute_set
+{
+ BOOST_COPYABLE_AND_MOVABLE_ALT(attribute_set)
+
+ friend class attribute_value_set;
+ friend class aux::attribute_set_reference_proxy;
+
+public:
+ //! Key type
+ typedef attribute_name key_type;
+ //! Mapped attribute type
+ typedef attribute mapped_type;
+
+ //! Value type
+ typedef std::pair< const key_type, mapped_type > value_type;
+ //! Reference type
+ typedef value_type& reference;
+ //! Const reference type
+ typedef value_type const& const_reference;
+ //! Pointer type
+ typedef value_type* pointer;
+ //! Const pointer type
+ typedef value_type const* const_pointer;
+ //! Size type
+ typedef std::size_t size_type;
+ //! Difference type
+ typedef std::ptrdiff_t difference_type;
+
+private:
+ //! \cond
+
+ //! Implementation
+ struct implementation;
+ friend struct implementation;
+
+ //! A base class for the container nodes
+ struct node_base
+ {
+ node_base* m_pPrev;
+ node_base* m_pNext;
+
+ node_base();
+
+ BOOST_DELETED_FUNCTION(node_base(node_base const&))
+ BOOST_DELETED_FUNCTION(node_base& operator= (node_base const&))
+ };
+
+ //! Container elements
+ struct node;
+ friend struct node;
+ struct node :
+ public node_base
+ {
+ value_type m_Value;
+
+ node(key_type const& key, mapped_type const& data);
+ };
+
+ //! Iterator class
+#ifndef BOOST_LOG_NO_MEMBER_TEMPLATE_FRIENDS
+ template< bool fConstV > class iter;
+ template< bool fConstV > friend class iter;
+#endif
+ template< bool fConstV >
+ class iter
+ {
+ friend class iter< !fConstV >;
+ friend class attribute_set;
+
+ public:
+ // Standard typedefs
+ typedef attribute_set::difference_type difference_type;
+ typedef attribute_set::value_type value_type;
+ typedef typename mpl::if_c<
+ fConstV,
+ attribute_set::const_reference,
+ attribute_set::reference
+ >::type reference;
+ typedef typename mpl::if_c<
+ fConstV,
+ attribute_set::const_pointer,
+ attribute_set::pointer
+ >::type pointer;
+ typedef std::bidirectional_iterator_tag iterator_category;
+
+ public:
+ // Constructors
+ BOOST_CONSTEXPR iter() : m_pNode(NULL) {}
+ explicit iter(node_base* pNode) BOOST_NOEXCEPT : m_pNode(pNode) {}
+ iter(iter< false > const& that) BOOST_NOEXCEPT : m_pNode(that.m_pNode) {}
+
+ //! Assignment
+ template< bool f >
+ iter& operator= (iter< f > const& that) BOOST_NOEXCEPT
+ {
+ m_pNode = that.m_pNode;
+ return *this;
+ }
+
+ // Comparison
+ template< bool f >
+ bool operator== (iter< f > const& that) const BOOST_NOEXCEPT { return (m_pNode == that.m_pNode); }
+ template< bool f >
+ bool operator!= (iter< f > const& that) const BOOST_NOEXCEPT { return (m_pNode != that.m_pNode); }
+
+ // Modification
+ iter& operator++ () BOOST_NOEXCEPT
+ {
+ m_pNode = m_pNode->m_pNext;
+ return *this;
+ }
+ iter& operator-- () BOOST_NOEXCEPT
+ {
+ m_pNode = m_pNode->m_pPrev;
+ return *this;
+ }
+ iter operator++ (int) BOOST_NOEXCEPT
+ {
+ iter tmp(*this);
+ m_pNode = m_pNode->m_pNext;
+ return tmp;
+ }
+ iter operator-- (int) BOOST_NOEXCEPT
+ {
+ iter tmp(*this);
+ m_pNode = m_pNode->m_pPrev;
+ return tmp;
+ }
+
+ // Dereferencing
+ pointer operator-> () const BOOST_NOEXCEPT { return &(static_cast< node* >(m_pNode)->m_Value); }
+ reference operator* () const BOOST_NOEXCEPT { return static_cast< node* >(m_pNode)->m_Value; }
+
+ node_base* base() const BOOST_NOEXCEPT { return m_pNode; }
+
+ private:
+ node_base* m_pNode;
+ };
+
+ //! \endcond
+
+public:
+#ifndef BOOST_LOG_DOXYGEN_PASS
+ //! Iterator type
+ typedef iter< false > iterator;
+ //! Const iterator type
+ typedef iter< true > const_iterator;
+#else
+ /*!
+ * Iterator type. The iterator complies to the bidirectional iterator requirements.
+ */
+ typedef implementation_defined iterator;
+ /*!
+ * Constant iterator type. The iterator complies to the bidirectional iterator requirements with read-only capabilities.
+ */
+ typedef implementation_defined const_iterator;
+#endif // BOOST_LOG_DOXYGEN_PASS
+
+private:
+ //! Pointer to implementation
+ implementation* m_pImpl;
+
+public:
+ /*!
+ * Default constructor.
+ *
+ * \post <tt>empty() == true</tt>
+ */
+ BOOST_LOG_API attribute_set();
+
+ /*!
+ * Copy constructor.
+ *
+ * \post <tt>size() == that.size() && std::equal(begin(), end(), that.begin()) == true</tt>
+ */
+ BOOST_LOG_API attribute_set(attribute_set const& that);
+
+ /*!
+ * Move constructor
+ */
+ attribute_set(BOOST_RV_REF(attribute_set) that) BOOST_NOEXCEPT : m_pImpl(that.m_pImpl)
+ {
+ that.m_pImpl = NULL;
+ }
+
+ /*!
+ * Destructor. All stored references to attributes are released.
+ */
+ BOOST_LOG_API ~attribute_set() BOOST_NOEXCEPT;
+
+ /*!
+ * Copy assignment operator.
+ *
+ * \post <tt>size() == that.size() && std::equal(begin(), end(), that.begin()) == true</tt>
+ */
+ attribute_set& operator= (attribute_set that) BOOST_NOEXCEPT
+ {
+ this->swap(that);
+ return *this;
+ }
+
+ /*!
+ * Swaps two instances of the container.
+ *
+ * \b Throws: Nothing.
+ */
+ void swap(attribute_set& that) BOOST_NOEXCEPT
+ {
+ implementation* const p = m_pImpl;
+ m_pImpl = that.m_pImpl;
+ that.m_pImpl = p;
+ }
+
+ /*!
+ * \return Iterator to the first element of the container.
+ */
+ BOOST_LOG_API iterator begin() BOOST_NOEXCEPT;
+ /*!
+ * \return Iterator to the after-the-last element of the container.
+ */
+ BOOST_LOG_API iterator end() BOOST_NOEXCEPT;
+ /*!
+ * \return Constant iterator to the first element of the container.
+ */
+ BOOST_LOG_API const_iterator begin() const BOOST_NOEXCEPT;
+ /*!
+ * \return Constant iterator to the after-the-last element of the container.
+ */
+ BOOST_LOG_API const_iterator end() const BOOST_NOEXCEPT;
+
+ /*!
+ * \return Number of elements in the container.
+ */
+ BOOST_LOG_API size_type size() const BOOST_NOEXCEPT;
+ /*!
+ * \return true if there are no elements in the container, false otherwise.
+ */
+ bool empty() const BOOST_NOEXCEPT { return (this->size() == 0); }
+
+ /*!
+ * The method finds the attribute by name.
+ *
+ * \param key Attribute name.
+ * \return Iterator to the found element or end() if the attribute with such name is not found.
+ */
+ BOOST_LOG_API iterator find(key_type key) BOOST_NOEXCEPT;
+ /*!
+ * The method finds the attribute by name.
+ *
+ * \param key Attribute name.
+ * \return Iterator to the found element or \c end() if the attribute with such name is not found.
+ */
+ const_iterator find(key_type key) const BOOST_NOEXCEPT
+ {
+ return const_iterator(const_cast< attribute_set* >(this)->find(key));
+ }
+ /*!
+ * The method counts the number of the attribute occurrences in the container. Since there can be only one
+ * attribute with a particular key, the method always return 0 or 1.
+ *
+ * \param key Attribute name.
+ * \return The number of times the attribute is found in the container.
+ */
+ size_type count(key_type key) const BOOST_NOEXCEPT { return size_type(this->find(key) != this->end()); }
+
+ /*!
+ * Combined lookup/insertion operator. The operator semantics depends on the further usage of the returned reference.
+ * \li If the reference is used as an assignment target, the assignment expression is equivalent to element insertion,
+ * where the element is composed of the second argument of the \c operator[] as a key and the second argument of assignment
+ * as a mapped value.
+ * \li If the returned reference is used in context where a conversion to the mapped type is required,
+ * the result of the conversion is equivalent to the mapped value found with the second argument of the \c operator[] as a key,
+ * if such an element exists in the container, or a default-constructed mapped value, if an element does not exist in the
+ * container.
+ *
+ * \param key Attribute name.
+ * \return A smart reference object of unspecified type.
+ */
+ aux::attribute_set_reference_proxy operator[] (key_type key) BOOST_NOEXCEPT
+ {
+ return aux::attribute_set_reference_proxy(this, key);
+ }
+ /*!
+ * Lookup operator
+ *
+ * \param key Attribute name.
+ * \return If an element with the corresponding attribute name is found in the container, its mapped value
+ * is returned. Otherwise a default-constructed mapped value is returned.
+ */
+ mapped_type operator[] (key_type key) const BOOST_NOEXCEPT
+ {
+ const_iterator it = this->find(key);
+ if (it != end())
+ return it->second;
+ else
+ return mapped_type();
+ }
+
+ /*!
+ * Insertion method
+ *
+ * \param key Attribute name.
+ * \param data Pointer to the attribute. Must not be NULL.
+ * \returns A pair of values. If second is true, the insertion succeeded and the first component points to the
+ * inserted element. Otherwise the first component points to the element that prevents insertion.
+ */
+ BOOST_LOG_API std::pair< iterator, bool > insert(key_type key, mapped_type const& data);
+
+ /*!
+ * Insertion method
+ *
+ * \param value An element to be inserted.
+ * \returns A pair of values. If second is true, the insertion succeeded and the first component points to the
+ * inserted element. Otherwise the first component points to the element that prevents insertion.
+ */
+ std::pair< iterator, bool > insert(const_reference value)
+ {
+ return this->insert(value.first, value.second);
+ }
+
+ /*!
+ * Mass insertion method.
+ *
+ * \param begin A forward iterator that points to the first element to be inserted.
+ * \param end A forward iterator that points to the after-the-last element to be inserted.
+ */
+ template< typename FwdIteratorT >
+ void insert(FwdIteratorT begin, FwdIteratorT end)
+ {
+ for (; begin != end; ++begin)
+ this->insert(*begin);
+ }
+
+ /*!
+ * Mass insertion method with ability to acquire iterators to the inserted elements.
+ *
+ * \param begin A forward iterator that points to the first element to be inserted.
+ * \param end A forward iterator that points to the after-the-last element to be inserted.
+ * \param out An output iterator that receives results of insertion of the elements
+ */
+ template< typename FwdIteratorT, typename OutputIteratorT >
+ void insert(FwdIteratorT begin, FwdIteratorT end, OutputIteratorT out)
+ {
+ for (; begin != end; ++begin, ++out)
+ *out = this->insert(*begin);
+ }
+
+ /*!
+ * The method erases all attributes with the specified name
+ *
+ * \post All iterators to the erased elements become invalid.
+ * \param key Attribute name.
+ * \return Tne number of erased elements
+ */
+ BOOST_LOG_API size_type erase(key_type key) BOOST_NOEXCEPT;
+ /*!
+ * The method erases the specified attribute
+ *
+ * \post All iterators to the erased element become invalid.
+ * \param it A valid iterator to the element to be erased.
+ * \return Tne number of erased elements
+ */
+ BOOST_LOG_API void erase(iterator it) BOOST_NOEXCEPT;
+ /*!
+ * The method erases all attributes within the specified range
+ *
+ * \pre \a end is reachable from \a begin with a finite number of increments.
+ * \post All iterators to the erased elements become invalid.
+ * \param begin An iterator that points to the first element to be erased.
+ * \param end An iterator that points to the after-the-last element to be erased.
+ */
+ BOOST_LOG_API void erase(iterator begin, iterator end) BOOST_NOEXCEPT;
+
+ /*!
+ * The method removes all elements from the container
+ *
+ * \post <tt>empty() == true</tt>
+ */
+ BOOST_LOG_API void clear() BOOST_NOEXCEPT;
+};
+
+/*!
+ * Free swap overload
+ */
+inline void swap(attribute_set& left, attribute_set& right) BOOST_NOEXCEPT
+{
+ left.swap(right);
+}
+
+namespace aux {
+
+//! Conversion operator (would be invoked in case of reading from the container)
+inline attribute_set_reference_proxy::operator mapped_type() const BOOST_NOEXCEPT
+{
+ attribute_set::iterator it = m_pContainer->find(m_key);
+ if (it != m_pContainer->end())
+ return it->second;
+ else
+ return mapped_type();
+}
+
+//! Assignment operator (would be invoked in case of writing to the container)
+inline attribute_set_reference_proxy::mapped_type& attribute_set_reference_proxy::operator= (mapped_type const& val) const
+{
+ std::pair< attribute_set::iterator, bool > res = m_pContainer->insert(m_key, val);
+ if (!res.second)
+ res.first->second = val;
+ return res.first->second;
+}
+
+} // namespace aux
+
+#ifndef BOOST_LOG_DOXYGEN_PASS
+inline attribute& attribute::operator= (aux::attribute_set_reference_proxy const& that) BOOST_NOEXCEPT
+{
+ attribute attr = that;
+ this->swap(attr);
+ return *this;
+}
+#endif
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_ATTRIBUTE_SET_HPP_INCLUDED_
diff --git a/boost/log/attributes/attribute_value.hpp b/boost/log/attributes/attribute_value.hpp
new file mode 100644
index 0000000..972093d
--- /dev/null
+++ b/boost/log/attributes/attribute_value.hpp
@@ -0,0 +1,380 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file attribute_value.hpp
+ * \author Andrey Semashev
+ * \date 21.05.2010
+ *
+ * The header contains \c attribute_value class definition.
+ */
+
+#ifndef BOOST_LOG_ATTRIBUTE_VALUE_HPP_INCLUDED_
+#define BOOST_LOG_ATTRIBUTE_VALUE_HPP_INCLUDED_
+
+#include <boost/move/core.hpp>
+#include <boost/smart_ptr/intrusive_ptr.hpp>
+#include <boost/log/detail/config.hpp>
+#include <boost/utility/explicit_operator_bool.hpp>
+#include <boost/log/utility/type_info_wrapper.hpp>
+#include <boost/log/utility/type_dispatch/type_dispatcher.hpp>
+#include <boost/log/attributes/attribute.hpp>
+#include <boost/log/attributes/value_extraction_fwd.hpp>
+#include <boost/log/attributes/value_visitation_fwd.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+/*!
+ * \brief An attribute value class
+ *
+ * An attribute value is an object that contains a piece of data that represents an attribute state
+ * at the point of the value acquisition. All major operations with log records, such as filtering and
+ * formatting, involve attribute values contained in a single view. Most likely an attribute value is
+ * implemented as a simple holder of some typed value. This holder implements the
+ * \c attribute_value::implementation interface and acts as a pimpl for the \c attribute_value
+ * object. The \c attribute_value class provides type dispatching support in order to allow
+ * to extract the value from the holder.
+ *
+ * Normally, attributes and their values shall be designed in order to exclude as much interference as
+ * reasonable. Such approach allows to have more than one attribute value simultaneously, which improves
+ * scalability and allows to implement generating attributes.
+ *
+ * However, there are cases when this approach does not help to achieve the required level of independency
+ * of attribute values and attribute itself from each other at a reasonable performance tradeoff.
+ * For example, an attribute or its values may use thread-specific data, which is global and shared
+ * between all the instances of the attribute/value. Passing such an attribute value to another thread
+ * would be a disaster. To solve this the library defines an additional method for attribute values,
+ * namely \c detach_from_thread. The \c attribute_value class forwards the call to its pimpl,
+ * which is supposed to ensure that it no longer refers to any thread-specific data after the call.
+ * The pimpl can create a new holder as a result of this method and return it to the \c attribute_value
+ * wrapper, which will keep the returned reference for any further calls.
+ * This method is called for all attribute values that are passed to another thread.
+ */
+class attribute_value
+{
+ BOOST_COPYABLE_AND_MOVABLE(attribute_value)
+
+public:
+ /*!
+ * \brief A base class for an attribute value implementation
+ *
+ * All attribute value holders should derive from this interface.
+ */
+ struct BOOST_LOG_NO_VTABLE impl :
+ public attribute::impl
+ {
+ public:
+ /*!
+ * The method dispatches the value to the given object.
+ *
+ * \param dispatcher The object that attempts to dispatch the stored value.
+ * \return true if \a dispatcher was capable to consume the real attribute value type and false otherwise.
+ */
+ virtual bool dispatch(type_dispatcher& dispatcher) = 0;
+
+ /*!
+ * The method is called when the attribute value is passed to another thread (e.g.
+ * in case of asynchronous logging). The value should ensure it properly owns all thread-specific data.
+ *
+ * \return An actual pointer to the attribute value. It may either point to this object or another.
+ * In the latter case the returned pointer replaces the pointer used by caller to invoke this
+ * method and is considered to be a functional equivalent to the previous pointer.
+ */
+ virtual intrusive_ptr< impl > detach_from_thread()
+ {
+ return this;
+ }
+
+ /*!
+ * \return The attribute value that refers to self implementation.
+ */
+ virtual attribute_value get_value() { return attribute_value(this); }
+
+ /*!
+ * \return The attribute value type
+ */
+ virtual type_info_wrapper get_type() const { return type_info_wrapper(); }
+ };
+
+private:
+ //! Pointer to the value implementation
+ intrusive_ptr< impl > m_pImpl;
+
+public:
+ /*!
+ * Default constructor. Creates an empty (absent) attribute value.
+ */
+ BOOST_DEFAULTED_FUNCTION(attribute_value(), {})
+
+ /*!
+ * Copy constructor
+ */
+ attribute_value(attribute_value const& that) BOOST_NOEXCEPT : m_pImpl(that.m_pImpl) {}
+
+ /*!
+ * Move constructor
+ */
+ attribute_value(BOOST_RV_REF(attribute_value) that) BOOST_NOEXCEPT { m_pImpl.swap(that.m_pImpl); }
+
+ /*!
+ * Initializing constructor. Creates an attribute value that refers to the specified holder.
+ *
+ * \param p A pointer to the attribute value holder.
+ */
+ explicit attribute_value(intrusive_ptr< impl > p) BOOST_NOEXCEPT { m_pImpl.swap(p); }
+
+ /*!
+ * Copy assignment
+ */
+ attribute_value& operator= (BOOST_COPY_ASSIGN_REF(attribute_value) that) BOOST_NOEXCEPT
+ {
+ m_pImpl = that.m_pImpl;
+ return *this;
+ }
+
+ /*!
+ * Move assignment
+ */
+ attribute_value& operator= (BOOST_RV_REF(attribute_value) that) BOOST_NOEXCEPT
+ {
+ m_pImpl.swap(that.m_pImpl);
+ return *this;
+ }
+
+ /*!
+ * The operator checks if the attribute value is empty
+ */
+ BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
+ /*!
+ * The operator checks if the attribute value is empty
+ */
+ bool operator! () const BOOST_NOEXCEPT { return !m_pImpl; }
+
+ /*!
+ * The method returns the type information of the stored value of the attribute.
+ * The returned type info wrapper may be empty if the attribute value is empty or
+ * the information cannot be provided. If the returned value is not empty, the type
+ * can be used for value extraction.
+ */
+ type_info_wrapper get_type() const
+ {
+ if (m_pImpl.get())
+ return m_pImpl->get_type();
+ else
+ return type_info_wrapper();
+ }
+
+ /*!
+ * The method is called when the attribute value is passed to another thread (e.g.
+ * in case of asynchronous logging). The value should ensure it properly owns all thread-specific data.
+ *
+ * \post The attribute value no longer refers to any thread-specific resources.
+ */
+ void detach_from_thread()
+ {
+ if (m_pImpl.get())
+ m_pImpl->detach_from_thread().swap(m_pImpl);
+ }
+
+ /*!
+ * The method dispatches the value to the given object. This method is a low level interface for
+ * attribute value visitation and extraction. For typical usage these interfaces may be more convenient.
+ *
+ * \param dispatcher The object that attempts to dispatch the stored value.
+ * \return \c true if the value is not empty and the \a dispatcher was capable to consume
+ * the real attribute value type and \c false otherwise.
+ */
+ bool dispatch(type_dispatcher& dispatcher) const
+ {
+ if (m_pImpl.get())
+ return m_pImpl->dispatch(dispatcher);
+ else
+ return false;
+ }
+
+#if !defined(BOOST_LOG_DOXYGEN_PASS)
+#if !defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
+#define BOOST_LOG_AUX_VOID_DEFAULT = void
+#else
+#define BOOST_LOG_AUX_VOID_DEFAULT
+#endif
+#endif // !defined(BOOST_LOG_DOXYGEN_PASS)
+
+ /*!
+ * The method attempts to extract the stored value, assuming the value has the specified type.
+ * One can specify either a single type or an MPL type sequence, in which case the stored value
+ * is checked against every type in the sequence.
+ *
+ * \note Include <tt>value_extraction.hpp</tt> prior to using this method.
+ *
+ * \return The extracted value, if the attribute value is not empty and the value is the same
+ * as specified. Otherwise returns an empty value. See description of the \c result_of::extract
+ * metafunction for information on the nature of the result value.
+ */
+ template< typename T, typename TagT BOOST_LOG_AUX_VOID_DEFAULT >
+ typename result_of::extract< T, TagT >::type extract() const;
+
+ /*!
+ * The method attempts to extract the stored value, assuming the value has the specified type.
+ * One can specify either a single type or an MPL type sequence, in which case the stored value
+ * is checked against every type in the sequence.
+ *
+ * \note Include <tt>value_extraction.hpp</tt> prior to using this method.
+ *
+ * \return The extracted value, if the attribute value is not empty and the value is the same
+ * as specified. Otherwise an exception is thrown. See description of the \c result_of::extract_or_throw
+ * metafunction for information on the nature of the result value.
+ */
+ template< typename T, typename TagT BOOST_LOG_AUX_VOID_DEFAULT >
+ typename result_of::extract_or_throw< T, TagT >::type extract_or_throw() const;
+
+ /*!
+ * The method attempts to extract the stored value, assuming the value has the specified type.
+ * One can specify either a single type or an MPL type sequence, in which case the stored value
+ * is checked against every type in the sequence. If extraction fails, the default value is returned.
+ *
+ * \note Include <tt>value_extraction.hpp</tt> prior to using this method.
+ *
+ * \param def_value Default value.
+ *
+ * \return The extracted value, if the attribute value is not empty and the value is the same
+ * as specified. Otherwise returns the default value. See description of the \c result_of::extract_or_default
+ * metafunction for information on the nature of the result value.
+ */
+ template< typename T, typename TagT BOOST_LOG_AUX_VOID_DEFAULT >
+ typename result_of::extract_or_default< T, T, TagT >::type extract_or_default(T const& def_value) const;
+
+ /*!
+ * The method attempts to extract the stored value, assuming the value has the specified type.
+ * One can specify either a single type or an MPL type sequence, in which case the stored value
+ * is checked against every type in the sequence. If extraction fails, the default value is returned.
+ *
+ * \note Include <tt>value_extraction.hpp</tt> prior to using this method.
+ *
+ * \param def_value Default value.
+ *
+ * \return The extracted value, if the attribute value is not empty and the value is the same
+ * as specified. Otherwise returns the default value. See description of the \c result_of::extract_or_default
+ * metafunction for information on the nature of the result value.
+ */
+ template< typename T, typename TagT BOOST_LOG_AUX_VOID_DEFAULT, typename DefaultT >
+ typename result_of::extract_or_default< T, DefaultT, TagT >::type extract_or_default(DefaultT const& def_value) const;
+
+#if defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
+ /*!
+ * The method attempts to extract the stored value, assuming the value has the specified type.
+ * One can specify either a single type or an MPL type sequence, in which case the stored value
+ * is checked against every type in the sequence.
+ *
+ * \note Include <tt>value_extraction.hpp</tt> prior to using this method.
+ *
+ * \return The extracted value, if the attribute value is not empty and the value is the same
+ * as specified. Otherwise returns an empty value. See description of the \c result_of::extract
+ * metafunction for information on the nature of the result value.
+ */
+ template< typename T >
+ typename result_of::extract< T >::type extract() const;
+
+ /*!
+ * The method attempts to extract the stored value, assuming the value has the specified type.
+ * One can specify either a single type or an MPL type sequence, in which case the stored value
+ * is checked against every type in the sequence.
+ *
+ * \note Include <tt>value_extraction.hpp</tt> prior to using this method.
+ *
+ * \return The extracted value, if the attribute value is not empty and the value is the same
+ * as specified. Otherwise an exception is thrown. See description of the \c result_of::extract_or_throw
+ * metafunction for information on the nature of the result value.
+ */
+ template< typename T >
+ typename result_of::extract_or_throw< T >::type extract_or_throw() const;
+
+ /*!
+ * The method attempts to extract the stored value, assuming the value has the specified type.
+ * One can specify either a single type or an MPL type sequence, in which case the stored value
+ * is checked against every type in the sequence. If extraction fails, the default value is returned.
+ *
+ * \note Include <tt>value_extraction.hpp</tt> prior to using this method.
+ *
+ * \param def_value Default value.
+ *
+ * \return The extracted value, if the attribute value is not empty and the value is the same
+ * as specified. Otherwise returns the default value. See description of the \c result_of::extract_or_default
+ * metafunction for information on the nature of the result value.
+ */
+ template< typename T >
+ typename result_of::extract_or_default< T, T >::type extract_or_default(T const& def_value) const;
+
+ /*!
+ * The method attempts to extract the stored value, assuming the value has the specified type.
+ * One can specify either a single type or an MPL type sequence, in which case the stored value
+ * is checked against every type in the sequence. If extraction fails, the default value is returned.
+ *
+ * \note Include <tt>value_extraction.hpp</tt> prior to using this method.
+ *
+ * \param def_value Default value.
+ *
+ * \return The extracted value, if the attribute value is not empty and the value is the same
+ * as specified. Otherwise returns the default value. See description of the \c result_of::extract_or_default
+ * metafunction for information on the nature of the result value.
+ */
+ template< typename T, typename DefaultT >
+ typename result_of::extract_or_default< T, DefaultT >::type extract_or_default(DefaultT const& def_value) const;
+#endif // defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
+
+#undef BOOST_LOG_AUX_VOID_DEFAULT
+
+ /*!
+ * The method attempts to extract the stored value, assuming the value has the specified type,
+ * and pass it to the \a visitor function object.
+ * One can specify either a single type or an MPL type sequence, in which case the stored value
+ * is checked against every type in the sequence.
+ *
+ * \note Include <tt>value_visitation.hpp</tt> prior to using this method.
+ *
+ * \param visitor A function object that will be invoked on the extracted attribute value.
+ * The visitor should be capable to be called with a single argument of
+ * any type of the specified types in \c T.
+ *
+ * \return The result of visitation.
+ */
+ template< typename T, typename VisitorT >
+ visitation_result visit(VisitorT visitor) const;
+
+ /*!
+ * The method swaps two attribute values
+ */
+ void swap(attribute_value& that) BOOST_NOEXCEPT
+ {
+ m_pImpl.swap(that.m_pImpl);
+ }
+};
+
+/*!
+ * The function swaps two attribute values
+ */
+inline void swap(attribute_value& left, attribute_value& right) BOOST_NOEXCEPT
+{
+ left.swap(right);
+}
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+#if defined(BOOST_LOG_ATTRIBUTES_ATTRIBUTE_HPP_INCLUDED_)
+#include <boost/log/detail/attribute_get_value_impl.hpp>
+#endif
+
+#endif // BOOST_LOG_ATTRIBUTE_VALUE_HPP_INCLUDED_
diff --git a/boost/log/attributes/attribute_value_impl.hpp b/boost/log/attributes/attribute_value_impl.hpp
new file mode 100644
index 0000000..405c346
--- /dev/null
+++ b/boost/log/attributes/attribute_value_impl.hpp
@@ -0,0 +1,136 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file attribute_value_impl.hpp
+ * \author Andrey Semashev
+ * \date 24.06.2007
+ *
+ * The header contains an implementation of a basic attribute value implementation class.
+ */
+
+#ifndef BOOST_LOG_ATTRIBUTES_ATTRIBUTE_VALUE_IMPL_HPP_INCLUDED_
+#define BOOST_LOG_ATTRIBUTES_ATTRIBUTE_VALUE_IMPL_HPP_INCLUDED_
+
+#include <boost/move/core.hpp>
+#include <boost/move/utility.hpp>
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/log/detail/config.hpp>
+#include <boost/log/attributes/attribute_value.hpp>
+#include <boost/log/utility/type_dispatch/type_dispatcher.hpp>
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+#include <boost/type_traits/remove_reference.hpp>
+#endif
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace attributes {
+
+/*!
+ * \brief Basic attribute value implementation class
+ *
+ * This class can be used as a boilerplate for simple attribute values. The class implements all needed
+ * interfaces of attribute values and allows to store a single value of the type specified as a template parameter.
+ * The stored value can be dispatched with type dispatching mechanism.
+ */
+template< typename T >
+class attribute_value_impl :
+ public attribute_value::impl
+{
+public:
+ //! Value type
+ typedef T value_type;
+
+private:
+ //! Attribute value
+ const value_type m_value;
+
+public:
+ /*!
+ * Constructor with initialization of the stored value
+ */
+ explicit attribute_value_impl(value_type const& v) : m_value(v) {}
+ /*!
+ * Constructor with initialization of the stored value
+ */
+ explicit attribute_value_impl(BOOST_RV_REF(value_type) v) : m_value(v) {}
+
+ /*!
+ * Attribute value dispatching method.
+ *
+ * \param dispatcher The dispatcher that receives the stored value
+ *
+ * \return \c true if the value has been dispatched, \c false otherwise
+ */
+ virtual bool dispatch(type_dispatcher& dispatcher)
+ {
+ type_dispatcher::callback< value_type > callback = dispatcher.get_callback< value_type >();
+ if (callback)
+ {
+ callback(m_value);
+ return true;
+ }
+ else
+ return false;
+ }
+
+ /*!
+ * \return The attribute value type
+ */
+ type_info_wrapper get_type() const { return type_info_wrapper(typeid(value_type)); }
+
+ /*!
+ * \return Reference to the contained value.
+ */
+ value_type const& get() const { return m_value; }
+};
+
+/*!
+ * The function creates an attribute value from the specified object.
+ */
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+
+template< typename T >
+inline attribute_value make_attribute_value(T&& v)
+{
+ typedef typename remove_cv< typename remove_reference< T >::type >::type value_type;
+ return attribute_value(new attribute_value_impl< value_type >(boost::forward< T >(v)));
+}
+
+#else // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+
+template< typename T >
+inline attribute_value make_attribute_value(T const& v)
+{
+ typedef typename remove_cv< T >::type value_type;
+ return attribute_value(new attribute_value_impl< value_type >(v));
+}
+
+template< typename T >
+inline attribute_value make_attribute_value(rv< T > const& v)
+{
+ typedef typename remove_cv< T >::type value_type;
+ return attribute_value(new attribute_value_impl< value_type >(v));
+}
+
+#endif // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+
+} // namespace attributes
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_ATTRIBUTES_ATTRIBUTE_VALUE_IMPL_HPP_INCLUDED_
diff --git a/boost/log/attributes/attribute_value_set.hpp b/boost/log/attributes/attribute_value_set.hpp
new file mode 100644
index 0000000..0ca6359
--- /dev/null
+++ b/boost/log/attributes/attribute_value_set.hpp
@@ -0,0 +1,480 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file attribute_value_set.hpp
+ * \author Andrey Semashev
+ * \date 21.04.2007
+ *
+ * This header file contains definition of attribute value set. The set is constructed from
+ * three attribute sets (global, thread-specific and source-specific) and contains attribute
+ * values.
+ */
+
+#ifndef BOOST_LOG_ATTRIBUTE_VALUE_SET_HPP_INCLUDED_
+#define BOOST_LOG_ATTRIBUTE_VALUE_SET_HPP_INCLUDED_
+
+#include <cstddef>
+#include <utility>
+#include <iterator>
+#include <boost/move/core.hpp>
+#include <boost/log/detail/config.hpp>
+#include <boost/log/attributes/attribute_name.hpp>
+#include <boost/log/attributes/attribute.hpp>
+#include <boost/log/attributes/attribute_value.hpp>
+#include <boost/log/attributes/attribute_set.hpp>
+#include <boost/log/expressions/keyword_fwd.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+/*!
+ * \brief A set of attribute values
+ *
+ * The set of attribute values is an associative container with attribute name as a key and
+ * a pointer to attribute value object as a mapped type. This is a collection of elements with unique
+ * keys, that is, there can be only one attribute value with a given name in the set. With respect to
+ * read-only capabilities, the set interface is close to \c std::unordered_map.
+ *
+ * The set is designed to be only capable of adding elements to it. Once added, the attribute value
+ * cannot be removed from the set.
+ *
+ * An instance of attribute value set can be constructed from three attribute sets. The constructor attempts to
+ * accommodate values of all attributes from the sets. The situation when a same-named attribute is found
+ * in more than one attribute set is possible. This problem is solved on construction of the value set: the three
+ * attribute sets have different priorities when it comes to solving conflicts.
+ *
+ * From the library perspective the three source attribute sets are global, thread-specific and source-specific
+ * attributes, with the latter having the highest priority. This feature allows to override attributes of wider scopes
+ * with the more specific ones.
+ *
+ * For sake of performance, the attribute values are not immediately acquired from attribute sets at construction.
+ * Instead, on-demand acquisition is performed either on iterator dereferencing or on call to the \c freeze method.
+ * Once acquired, the attribute value stays within the set until its destruction. This nuance does not affect
+ * other set properties, such as size or lookup ability. The logging core automatically freezes the set
+ * at the right point, so users should not be bothered unless they manually create attribute value sets.
+ *
+ * \note The attribute sets that were used for the value set construction must not be modified or destroyed
+ * until the value set is frozen. Otherwise the behavior is undefined.
+ */
+class attribute_value_set
+{
+ BOOST_COPYABLE_AND_MOVABLE_ALT(attribute_value_set)
+
+public:
+ //! Key type
+ typedef attribute_name key_type;
+ //! Mapped attribute type
+ typedef attribute_value mapped_type;
+
+ //! Value type
+ typedef std::pair< const key_type, mapped_type > value_type;
+ //! Reference type
+ typedef value_type& reference;
+ //! Const reference type
+ typedef value_type const& const_reference;
+ //! Pointer type
+ typedef value_type* pointer;
+ //! Const pointer type
+ typedef value_type const* const_pointer;
+ //! Size type
+ typedef std::size_t size_type;
+ //! Pointer difference type
+ typedef std::ptrdiff_t difference_type;
+
+#ifndef BOOST_LOG_DOXYGEN_PASS
+
+private:
+ struct implementation;
+ friend struct implementation;
+
+ //! A base class for the container nodes
+ struct node_base
+ {
+ node_base* m_pPrev;
+ node_base* m_pNext;
+
+ node_base();
+
+ BOOST_DELETED_FUNCTION(node_base(node_base const&))
+ BOOST_DELETED_FUNCTION(node_base& operator= (node_base const&))
+ };
+
+ //! Container elements
+ struct node;
+ friend struct node;
+ struct node :
+ public node_base
+ {
+ value_type m_Value;
+ bool m_DynamicallyAllocated;
+
+ node(key_type const& key, mapped_type& data, bool dynamic);
+ };
+
+public:
+ class const_iterator;
+ friend class const_iterator;
+ class const_iterator
+ {
+ public:
+ // Standard typedefs
+ typedef attribute_value_set::difference_type difference_type;
+ typedef attribute_value_set::value_type value_type;
+ typedef attribute_value_set::const_reference reference;
+ typedef attribute_value_set::const_pointer pointer;
+ typedef std::bidirectional_iterator_tag iterator_category;
+
+ public:
+ // Constructors
+ BOOST_CONSTEXPR const_iterator() : m_pNode(NULL), m_pContainer(NULL) {}
+ explicit const_iterator(node_base* n, attribute_value_set* cont) BOOST_NOEXCEPT :
+ m_pNode(n),
+ m_pContainer(cont)
+ {
+ }
+
+ // Comparison
+ bool operator== (const_iterator const& that) const BOOST_NOEXCEPT
+ {
+ return (m_pNode == that.m_pNode);
+ }
+ bool operator!= (const_iterator const& that) const BOOST_NOEXCEPT
+ {
+ return (m_pNode != that.m_pNode);
+ }
+
+ // Modification
+ const_iterator& operator++ ()
+ {
+ m_pContainer->freeze();
+ m_pNode = m_pNode->m_pNext;
+ return *this;
+ }
+ const_iterator& operator-- ()
+ {
+ m_pContainer->freeze();
+ m_pNode = m_pNode->m_pPrev;
+ return *this;
+ }
+ const_iterator operator++ (int)
+ {
+ const_iterator tmp(*this);
+ m_pContainer->freeze();
+ m_pNode = m_pNode->m_pNext;
+ return tmp;
+ }
+ const_iterator operator-- (int)
+ {
+ const_iterator tmp(*this);
+ m_pContainer->freeze();
+ m_pNode = m_pNode->m_pPrev;
+ return tmp;
+ }
+
+ // Dereferencing
+ pointer operator-> () const BOOST_NOEXCEPT { return &(static_cast< node* >(m_pNode)->m_Value); }
+ reference operator* () const BOOST_NOEXCEPT { return static_cast< node* >(m_pNode)->m_Value; }
+
+ private:
+ node_base* m_pNode;
+ attribute_value_set* m_pContainer;
+ };
+
+#else
+
+ /*!
+ * Constant iterator type with bidirectional capabilities.
+ */
+ typedef implementation_defined const_iterator;
+
+#endif // BOOST_LOG_DOXYGEN_PASS
+
+private:
+ //! Pointer to the container implementation
+ implementation* m_pImpl;
+
+public:
+ /*!
+ * Default constructor
+ *
+ * The constructor creates an empty set which can be filled later by subsequent
+ * calls of \c insert method. Optionally, the amount of storage reserved for elements
+ * to be inserted may be passed to the constructor.
+ * The constructed set is frozen.
+ *
+ * \param reserve_count Number of elements to reserve space for.
+ */
+ BOOST_LOG_API explicit attribute_value_set(size_type reserve_count = 8);
+
+ /*!
+ * Move constructor
+ */
+ attribute_value_set(BOOST_RV_REF(attribute_value_set) that) BOOST_NOEXCEPT : m_pImpl(that.m_pImpl)
+ {
+ that.m_pImpl = NULL;
+ }
+
+ /*!
+ * The constructor adopts three attribute sets into the value set.
+ * The \a source_attrs attributes have the greatest preference when a same-named
+ * attribute is found in several sets, \a global_attrs has the least.
+ * The constructed set is not frozen.
+ *
+ * \param source_attrs A set of source-specific attributes.
+ * \param thread_attrs A set of thread-specific attributes.
+ * \param global_attrs A set of global attributes.
+ * \param reserve_count Amount of elements to reserve space for, in addition to the elements in the three attribute sets provided.
+ */
+ BOOST_LOG_API attribute_value_set(
+ attribute_set const& source_attrs,
+ attribute_set const& thread_attrs,
+ attribute_set const& global_attrs,
+ size_type reserve_count = 8);
+
+ /*!
+ * The constructor adopts three attribute sets into the value set.
+ * The \a source_attrs attributes have the greatest preference when a same-named
+ * attribute is found in several sets, \a global_attrs has the least.
+ * The constructed set is not frozen.
+ *
+ * \pre The \a source_attrs set is frozen.
+ *
+ * \param source_attrs A set of source-specific attributes.
+ * \param thread_attrs A set of thread-specific attributes.
+ * \param global_attrs A set of global attributes.
+ * \param reserve_count Amount of elements to reserve space for, in addition to the elements in the three attribute sets provided.
+ */
+ BOOST_LOG_API attribute_value_set(
+ attribute_value_set const& source_attrs,
+ attribute_set const& thread_attrs,
+ attribute_set const& global_attrs,
+ size_type reserve_count = 8);
+
+ /*!
+ * The constructor adopts three attribute sets into the value set.
+ * The \a source_attrs attributes have the greatest preference when a same-named
+ * attribute is found in several sets, \a global_attrs has the least.
+ * The constructed set is not frozen.
+ *
+ * \pre The \a source_attrs set is frozen.
+ *
+ * \param source_attrs A set of source-specific attributes.
+ * \param thread_attrs A set of thread-specific attributes.
+ * \param global_attrs A set of global attributes.
+ * \param reserve_count Amount of elements to reserve space for, in addition to the elements in the three attribute sets provided.
+ */
+ attribute_value_set(
+ BOOST_RV_REF(attribute_value_set) source_attrs,
+ attribute_set const& thread_attrs,
+ attribute_set const& global_attrs,
+ size_type reserve_count = 8) : m_pImpl(NULL)
+ {
+ construct(static_cast< attribute_value_set& >(source_attrs), thread_attrs, global_attrs, reserve_count);
+ }
+
+ /*!
+ * Copy constructor.
+ *
+ * \pre The original set is frozen.
+ * \post The constructed set is frozen, <tt>std::equal(begin(), end(), that.begin()) == true</tt>
+ */
+ BOOST_LOG_API attribute_value_set(attribute_value_set const& that);
+
+ /*!
+ * Destructor. Releases all referenced attribute values.
+ */
+ BOOST_LOG_API ~attribute_value_set() BOOST_NOEXCEPT;
+
+ /*!
+ * Assignment operator
+ */
+ attribute_value_set& operator= (attribute_value_set that) BOOST_NOEXCEPT
+ {
+ this->swap(that);
+ return *this;
+ }
+
+ /*!
+ * Swaps two sets
+ *
+ * \b Throws: Nothing.
+ */
+ void swap(attribute_value_set& that) BOOST_NOEXCEPT
+ {
+ implementation* const p = m_pImpl;
+ m_pImpl = that.m_pImpl;
+ that.m_pImpl = p;
+ }
+
+ /*!
+ * \return Iterator to the first element of the set.
+ */
+ BOOST_LOG_API const_iterator begin() const;
+ /*!
+ * \return Iterator to the after-the-last element of the set.
+ */
+ BOOST_LOG_API const_iterator end() const;
+
+ /*!
+ * \return Number of elements in the set.
+ */
+ BOOST_LOG_API size_type size() const;
+ /*!
+ * \return true if there are no elements in the container, false otherwise.
+ */
+ bool empty() const { return (this->size() == 0); }
+
+ /*!
+ * The method finds the attribute value by name.
+ *
+ * \param key Attribute name.
+ * \return Iterator to the found element or \c end() if the attribute with such name is not found.
+ */
+ BOOST_LOG_API const_iterator find(key_type key) const;
+
+ /*!
+ * Alternative lookup syntax.
+ *
+ * \param key Attribute name.
+ * \return A pointer to the attribute value if it is found with \a key, default-constructed mapped value otherwise.
+ */
+ mapped_type operator[] (key_type key) const
+ {
+ const_iterator it = this->find(key);
+ if (it != this->end())
+ return it->second;
+ else
+ return mapped_type();
+ }
+
+ /*!
+ * Alternative lookup syntax.
+ *
+ * \param keyword Attribute keyword.
+ * \return A \c value_ref with extracted attribute value if it is found, empty \c value_ref otherwise.
+ */
+ template< typename DescriptorT, template< typename > class ActorT >
+ typename result_of::extract< typename expressions::attribute_keyword< DescriptorT, ActorT >::value_type, DescriptorT >::type
+ operator[] (expressions::attribute_keyword< DescriptorT, ActorT > const& keyword) const
+ {
+ typedef typename expressions::attribute_keyword< DescriptorT, ActorT >::value_type attr_value_type;
+ typedef typename result_of::extract< attr_value_type, DescriptorT >::type result_type;
+ const_iterator it = this->find(keyword.get_name());
+ if (it != this->end())
+ return it->second.extract< attr_value_type, DescriptorT >();
+ else
+ return result_type();
+ }
+
+ /*!
+ * The method counts the number of the attribute value occurrences in the set. Since there can be only one
+ * attribute value with a particular key, the method always return 0 or 1.
+ *
+ * \param key Attribute name.
+ * \return The number of times the attribute value is found in the container.
+ */
+ size_type count(key_type key) const { return size_type(this->find(key) != this->end()); }
+
+ /*!
+ * The method acquires values of all adopted attributes.
+ *
+ * \post The set is frozen.
+ */
+ BOOST_LOG_API void freeze();
+
+ /*!
+ * Inserts an element into the set. The complexity of the operation is amortized constant.
+ *
+ * \pre The set is frozen.
+ *
+ * \param key The attribute name.
+ * \param mapped The attribute value.
+ *
+ * \returns An iterator to the inserted element and \c true if insertion succeeded. Otherwise,
+ * if the set already contains a same-named attribute value, iterator to the
+ * existing element and \c false.
+ */
+ BOOST_LOG_API std::pair< const_iterator, bool > insert(key_type key, mapped_type const& mapped);
+
+ /*!
+ * Inserts an element into the set. The complexity of the operation is amortized constant.
+ *
+ * \pre The set is frozen.
+ *
+ * \param value The attribute name and value.
+ *
+ * \returns An iterator to the inserted element and \c true if insertion succeeded. Otherwise,
+ * if the set already contains a same-named attribute value, iterator to the
+ * existing element and \c false.
+ */
+ std::pair< const_iterator, bool > insert(const_reference value) { return this->insert(value.first, value.second); }
+
+ /*!
+ * Mass insertion method. The complexity of the operation is linear to the number of elements inserted.
+ *
+ * \pre The set is frozen.
+ *
+ * \param begin A forward iterator that points to the first element to be inserted.
+ * \param end A forward iterator that points to the after-the-last element to be inserted.
+ */
+ template< typename FwdIteratorT >
+ void insert(FwdIteratorT begin, FwdIteratorT end)
+ {
+ for (; begin != end; ++begin)
+ this->insert(*begin);
+ }
+
+ /*!
+ * Mass insertion method with ability to acquire iterators to the inserted elements.
+ * The complexity of the operation is linear to the number of elements inserted times the complexity
+ * of filling the \a out iterator.
+ *
+ * \pre The set is frozen.
+ *
+ * \param begin A forward iterator that points to the first element to be inserted.
+ * \param end A forward iterator that points to the after-the-last element to be inserted.
+ * \param out An output iterator that receives results of insertion of the elements.
+ */
+ template< typename FwdIteratorT, typename OutputIteratorT >
+ void insert(FwdIteratorT begin, FwdIteratorT end, OutputIteratorT out)
+ {
+ for (; begin != end; ++begin, ++out)
+ *out = this->insert(*begin);
+ }
+
+#ifndef BOOST_LOG_DOXYGEN_PASS
+private:
+ //! Constructs the object by moving from \a source_attrs. This function is mostly needed to maintain ABI stable between C++03 and C++11.
+ BOOST_LOG_API void construct(
+ attribute_value_set& source_attrs,
+ attribute_set const& thread_attrs,
+ attribute_set const& global_attrs,
+ size_type reserve_count);
+#endif // BOOST_LOG_DOXYGEN_PASS
+};
+
+/*!
+ * Free swap overload
+ */
+inline void swap(attribute_value_set& left, attribute_value_set& right) BOOST_NOEXCEPT
+{
+ left.swap(right);
+}
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_ATTRIBUTE_VALUE_SET_HPP_INCLUDED_
diff --git a/boost/log/attributes/clock.hpp b/boost/log/attributes/clock.hpp
new file mode 100644
index 0000000..c28da5a
--- /dev/null
+++ b/boost/log/attributes/clock.hpp
@@ -0,0 +1,95 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file clock.hpp
+ * \author Andrey Semashev
+ * \date 01.12.2007
+ *
+ * The header contains wall clock attribute implementation and typedefs.
+ */
+
+#ifndef BOOST_LOG_ATTRIBUTES_CLOCK_HPP_INCLUDED_
+#define BOOST_LOG_ATTRIBUTES_CLOCK_HPP_INCLUDED_
+
+#include <boost/log/detail/config.hpp>
+#include <boost/log/attributes/attribute.hpp>
+#include <boost/log/attributes/attribute_value.hpp>
+#include <boost/log/attributes/attribute_cast.hpp>
+#include <boost/log/attributes/attribute_value_impl.hpp>
+#include <boost/log/attributes/time_traits.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace attributes {
+
+/*!
+ * \brief A class of an attribute that makes an attribute value of the current date and time
+ *
+ * The attribute generates current time stamp as a value. The type of the attribute value
+ * is determined with time traits passed to the class template as a template parameter.
+ * The time traits provided by the library use \c boost::posix_time::ptime as the time type.
+ *
+ * Time traits also determine the way time is acquired. There are two types of time traits
+ * provided by the library: \c utc_time_traits and \c local_time_traits. The first returns UTC time,
+ * the second returns local time.
+ */
+template< typename TimeTraitsT >
+class basic_clock :
+ public attribute
+{
+public:
+ //! Generated value type
+ typedef typename TimeTraitsT::time_type value_type;
+
+protected:
+ //! Attribute factory implementation
+ struct BOOST_SYMBOL_VISIBLE impl :
+ public attribute::impl
+ {
+ attribute_value get_value()
+ {
+ typedef attribute_value_impl< value_type > result_value;
+ return attribute_value(new result_value(TimeTraitsT::get_clock()));
+ }
+ };
+
+public:
+ /*!
+ * Default constructor
+ */
+ basic_clock() : attribute(new impl())
+ {
+ }
+ /*!
+ * Constructor for casting support
+ */
+ explicit basic_clock(cast_source const& source) : attribute(source.as< impl >())
+ {
+ }
+};
+
+//! Attribute that returns current UTC time
+typedef basic_clock< utc_time_traits > utc_clock;
+//! Attribute that returns current local time
+typedef basic_clock< local_time_traits > local_clock;
+
+} // namespace attributes
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_ATTRIBUTES_CLOCK_HPP_INCLUDED_
diff --git a/boost/log/attributes/constant.hpp b/boost/log/attributes/constant.hpp
new file mode 100644
index 0000000..f2ae0a7
--- /dev/null
+++ b/boost/log/attributes/constant.hpp
@@ -0,0 +1,122 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file constant.hpp
+ * \author Andrey Semashev
+ * \date 15.04.2007
+ *
+ * The header contains implementation of a constant attribute.
+ */
+
+#ifndef BOOST_LOG_ATTRIBUTES_CONSTANT_HPP_INCLUDED_
+#define BOOST_LOG_ATTRIBUTES_CONSTANT_HPP_INCLUDED_
+
+#include <boost/move/core.hpp>
+#include <boost/move/utility.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/log/detail/config.hpp>
+#include <boost/log/detail/embedded_string_type.hpp>
+#include <boost/log/attributes/attribute.hpp>
+#include <boost/log/attributes/attribute_cast.hpp>
+#include <boost/log/attributes/attribute_value_impl.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace attributes {
+
+/*!
+ * \brief A class of an attribute that holds a single constant value
+ *
+ * The constant is a simplest and one of the most frequently used types of attributes.
+ * It stores a constant value, which it eventually returns as its value each time
+ * requested.
+ */
+template< typename T >
+class constant :
+ public attribute
+{
+public:
+ //! Attribute value type
+ typedef T value_type;
+
+protected:
+ //! Factory implementation
+ class BOOST_SYMBOL_VISIBLE impl :
+ public attribute_value_impl< value_type >
+ {
+ //! Base type
+ typedef attribute_value_impl< value_type > base_type;
+
+ public:
+ /*!
+ * Constructor with the stored value initialization
+ */
+ explicit impl(value_type const& value) : base_type(value) {}
+ /*!
+ * Constructor with the stored value initialization
+ */
+ explicit impl(BOOST_RV_REF(value_type) value) : base_type(boost::move(value)) {}
+ };
+
+public:
+ /*!
+ * Constructor with the stored value initialization
+ */
+ explicit constant(value_type const& value) : attribute(new impl(value)) {}
+ /*!
+ * Constructor with the stored value initialization
+ */
+ explicit constant(BOOST_RV_REF(value_type) value) : attribute(new impl(boost::move(value))) {}
+ /*!
+ * Constructor for casting support
+ */
+ explicit constant(cast_source const& source) : attribute(source.as< impl >())
+ {
+ }
+
+ /*!
+ * \return Reference to the contained value.
+ */
+ value_type const& get() const
+ {
+ return static_cast< impl* >(this->get_impl())->get();
+ }
+};
+
+/*!
+ * The function constructs a \c constant attribute containing the provided value.
+ * The function automatically converts C string arguments to \c std::basic_string objects.
+ */
+template< typename T >
+inline constant<
+ typename boost::log::aux::make_embedded_string_type<
+ typename remove_reference< T >::type
+ >::type
+> make_constant(BOOST_FWD_REF(T) val)
+{
+ typedef typename boost::log::aux::make_embedded_string_type<
+ typename remove_reference< T >::type
+ >::type value_type;
+ return constant< value_type >(boost::forward< T >(val));
+}
+
+} // namespace attributes
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_ATTRIBUTES_CONSTANT_HPP_INCLUDED_
diff --git a/boost/log/attributes/counter.hpp b/boost/log/attributes/counter.hpp
new file mode 100644
index 0000000..a472271
--- /dev/null
+++ b/boost/log/attributes/counter.hpp
@@ -0,0 +1,218 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file counter.hpp
+ * \author Andrey Semashev
+ * \date 01.05.2007
+ *
+ * The header contains implementation of the counter attribute.
+ */
+
+#ifndef BOOST_LOG_ATTRIBUTES_COUNTER_HPP_INCLUDED_
+#define BOOST_LOG_ATTRIBUTES_COUNTER_HPP_INCLUDED_
+
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_integral.hpp>
+#include <boost/log/detail/config.hpp>
+#include <boost/log/attributes/attribute.hpp>
+#include <boost/log/attributes/attribute_cast.hpp>
+#include <boost/log/attributes/attribute_value_impl.hpp>
+#ifndef BOOST_LOG_NO_THREADS
+#include <boost/detail/atomic_count.hpp>
+#endif // BOOST_LOG_NO_THREADS
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace attributes {
+
+/*!
+ * \brief A class of an attribute that counts an integral value
+ *
+ * This type of attribute acts as a counter, that is, it returns a monotonously
+ * changing value each time requested. The attribute value type can be specified
+ * as a template parameter. However, the type must be an integral type of size no
+ * more than <tt>sizeof(long)</tt>.
+ */
+template< typename T >
+class counter :
+ public attribute
+{
+ // For now only integral types up to long are supported
+ BOOST_STATIC_ASSERT_MSG(is_integral< T >::value && sizeof(T) <= sizeof(long), "Boost.Log: Only integral types up to long are supported by counter attribute");
+
+public:
+ //! A counter value type
+ typedef T value_type;
+
+protected:
+ //! Base class for factory implementation
+ class BOOST_LOG_NO_VTABLE BOOST_SYMBOL_VISIBLE impl :
+ public attribute::impl
+ {
+ };
+
+ //! Generic factory implementation
+ class impl_generic;
+#ifndef BOOST_LOG_NO_THREADS
+ //! Increment-by-one factory implementation
+ class impl_inc;
+ //! Decrement-by-one factory implementation
+ class impl_dec;
+#endif
+
+public:
+ /*!
+ * Constructor
+ *
+ * \param initial Initial value of the counter
+ * \param step Changing step of the counter. Each value acquired from the attribute
+ * will be greater than the previous one to this amount.
+ */
+ explicit counter(value_type initial = (value_type)0, long step = 1) :
+#ifndef BOOST_LOG_NO_THREADS
+ attribute()
+ {
+ if (step == 1)
+ this->set_impl(new impl_inc(initial));
+ else if (step == -1)
+ this->set_impl(new impl_dec(initial));
+ else
+ this->set_impl(new impl_generic(initial, step));
+ }
+#else
+ attribute(new impl_generic(initial, step))
+ {
+ }
+#endif
+ /*!
+ * Constructor for casting support
+ */
+ explicit counter(cast_source const& source) :
+ attribute(source.as< impl >())
+ {
+ }
+};
+
+#ifndef BOOST_LOG_NO_THREADS
+
+template< typename T >
+class counter< T >::impl_generic :
+ public impl
+{
+private:
+ //! Initial value
+ const value_type m_Initial;
+ //! Step value
+ const long m_Step;
+ //! The counter
+ boost::detail::atomic_count m_Counter;
+
+public:
+ /*!
+ * Initializing constructor
+ */
+ impl_generic(value_type initial, long step) : m_Initial(initial), m_Step(step), m_Counter(-1)
+ {
+ }
+
+ attribute_value get_value()
+ {
+ const unsigned long next_counter = static_cast< unsigned long >(++m_Counter);
+ value_type next = static_cast< value_type >(m_Initial + (next_counter * m_Step));
+ return make_attribute_value(next);
+ }
+};
+
+template< typename T >
+class counter< T >::impl_inc :
+ public impl
+{
+private:
+ //! The counter
+ boost::detail::atomic_count m_Counter;
+
+public:
+ /*!
+ * Initializing constructor
+ */
+ explicit impl_inc(value_type initial) : m_Counter(initial - 1)
+ {
+ }
+
+ attribute_value get_value()
+ {
+ return make_attribute_value(static_cast< value_type >(++m_Counter));
+ }
+};
+
+template< typename T >
+class counter< T >::impl_dec :
+ public impl
+{
+private:
+ //! The counter
+ boost::detail::atomic_count m_Counter;
+
+public:
+ /*!
+ * Initializing constructor
+ */
+ explicit impl_dec(value_type initial) : m_Counter(initial + 1)
+ {
+ }
+
+ attribute_value get_value()
+ {
+ return make_attribute_value(static_cast< value_type >(--m_Counter));
+ }
+};
+
+#else // BOOST_LOG_NO_THREADS
+
+template< typename T >
+class counter< T >::impl_generic :
+ public impl
+{
+private:
+ //! Step value
+ const long m_Step;
+ //! The counter
+ value_type m_Counter;
+
+public:
+ /*!
+ * Initializing constructor
+ */
+ impl_generic(value_type initial, long step) : m_Step(step), m_Counter(initial - step)
+ {
+ }
+
+ attribute_value get_value()
+ {
+ m_Counter += m_Step;
+ return make_attribute_value(m_Counter);
+ }
+};
+
+#endif // BOOST_LOG_NO_THREADS
+
+} // namespace attributes
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_ATTRIBUTES_COUNTER_HPP_INCLUDED_
diff --git a/boost/log/attributes/current_process_id.hpp b/boost/log/attributes/current_process_id.hpp
new file mode 100644
index 0000000..d528b7d
--- /dev/null
+++ b/boost/log/attributes/current_process_id.hpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file current_process_id.hpp
+ * \author Andrey Semashev
+ * \date 12.09.2009
+ *
+ * The header contains implementation of a current process id attribute
+ */
+
+#ifndef BOOST_LOG_ATTRIBUTES_CURRENT_PROCESS_ID_HPP_INCLUDED_
+#define BOOST_LOG_ATTRIBUTES_CURRENT_PROCESS_ID_HPP_INCLUDED_
+
+#include <boost/log/detail/config.hpp>
+#include <boost/log/detail/process_id.hpp>
+#include <boost/log/attributes/constant.hpp>
+#include <boost/log/attributes/attribute_cast.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+//! Process identifier type used by the library
+typedef boost::log::aux::process::id process_id;
+
+namespace attributes {
+
+/*!
+ * \brief A class of an attribute that holds the current process identifier
+ */
+class current_process_id :
+ public constant< process_id >
+{
+ typedef constant< process_id > base_type;
+
+public:
+ /*!
+ * Constructor. Initializes the attribute with the current process identifier.
+ */
+ current_process_id() : base_type(boost::log::aux::this_process::get_id()) {}
+ /*!
+ * Constructor for casting support
+ */
+ explicit current_process_id(cast_source const& source) :
+ base_type(source)
+ {
+ }
+};
+
+} // namespace attributes
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_ATTRIBUTES_CURRENT_PROCESS_ID_HPP_INCLUDED_
diff --git a/boost/log/attributes/current_process_name.hpp b/boost/log/attributes/current_process_name.hpp
new file mode 100644
index 0000000..92e7859
--- /dev/null
+++ b/boost/log/attributes/current_process_name.hpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file current_process_name.hpp
+ * \author Andrey Semashev
+ * \date 29.07.2012
+ *
+ * The header contains implementation of a current process name attribute
+ */
+
+#ifndef BOOST_LOG_ATTRIBUTES_CURRENT_PROCESS_NAME_HPP_INCLUDED_
+#define BOOST_LOG_ATTRIBUTES_CURRENT_PROCESS_NAME_HPP_INCLUDED_
+
+#include <string>
+#include <boost/log/detail/config.hpp>
+#include <boost/log/attributes/constant.hpp>
+#include <boost/log/attributes/attribute_cast.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace aux {
+
+//! The function returns the current process name
+BOOST_LOG_API std::string get_process_name();
+
+} // namespace aux
+
+namespace attributes {
+
+/*!
+ * \brief A class of an attribute that holds the current process name
+ */
+class current_process_name :
+ public constant< std::string >
+{
+ typedef constant< std::string > base_type;
+
+public:
+ /*!
+ * Constructor. Initializes the attribute with the current process name.
+ */
+ current_process_name() : base_type(boost::log::aux::get_process_name()) {}
+ /*!
+ * Constructor for casting support
+ */
+ explicit current_process_name(cast_source const& source) :
+ base_type(source)
+ {
+ }
+};
+
+} // namespace attributes
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_ATTRIBUTES_CURRENT_PROCESS_NAME_HPP_INCLUDED_
diff --git a/boost/log/attributes/current_thread_id.hpp b/boost/log/attributes/current_thread_id.hpp
new file mode 100644
index 0000000..6b8488f
--- /dev/null
+++ b/boost/log/attributes/current_thread_id.hpp
@@ -0,0 +1,109 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file current_thread_id.hpp
+ * \author Andrey Semashev
+ * \date 12.09.2009
+ *
+ * The header contains implementation of a current thread id attribute
+ */
+
+#ifndef BOOST_LOG_ATTRIBUTES_CURRENT_THREAD_ID_HPP_INCLUDED_
+#define BOOST_LOG_ATTRIBUTES_CURRENT_THREAD_ID_HPP_INCLUDED_
+
+#include <boost/log/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#if defined(BOOST_LOG_NO_THREADS)
+#error Boost.Log: The current_thread_id attribute is only available in multithreaded builds
+#endif
+
+#include <boost/smart_ptr/intrusive_ptr.hpp>
+#include <boost/log/detail/thread_id.hpp>
+#include <boost/log/attributes/attribute.hpp>
+#include <boost/log/attributes/attribute_cast.hpp>
+#include <boost/log/attributes/attribute_value_impl.hpp>
+#include <boost/log/detail/header.hpp>
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+//! Thread identifier type
+typedef boost::log::aux::thread::id thread_id;
+
+namespace attributes {
+
+/*!
+ * \brief A class of an attribute that always returns the current thread identifier
+ *
+ * \note This attribute can be registered globally, it will still return the correct
+ * thread identifier, no matter which thread emits the log record.
+ */
+class current_thread_id :
+ public attribute
+{
+public:
+ //! A held attribute value type
+ typedef thread_id value_type;
+
+protected:
+ //! Factory implementation
+ class BOOST_SYMBOL_VISIBLE impl :
+ public attribute_value::impl
+ {
+ public:
+ bool dispatch(type_dispatcher& dispatcher)
+ {
+ type_dispatcher::callback< value_type > callback =
+ dispatcher.get_callback< value_type >();
+ if (callback)
+ {
+ callback(boost::log::aux::this_thread::get_id());
+ return true;
+ }
+ else
+ return false;
+ }
+
+ intrusive_ptr< attribute_value::impl > detach_from_thread()
+ {
+ typedef attribute_value_impl< value_type > detached_value;
+ return new detached_value(boost::log::aux::this_thread::get_id());
+ }
+
+ type_info_wrapper get_type() const { return type_info_wrapper(typeid(value_type)); }
+ };
+
+public:
+ /*!
+ * Default constructor
+ */
+ current_thread_id() : attribute(new impl())
+ {
+ }
+ /*!
+ * Constructor for casting support
+ */
+ explicit current_thread_id(cast_source const& source) :
+ attribute(source.as< impl >())
+ {
+ }
+};
+
+} // namespace attributes
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_ATTRIBUTES_CURRENT_THREAD_ID_HPP_INCLUDED_
diff --git a/boost/log/attributes/fallback_policy.hpp b/boost/log/attributes/fallback_policy.hpp
new file mode 100644
index 0000000..8a3c648
--- /dev/null
+++ b/boost/log/attributes/fallback_policy.hpp
@@ -0,0 +1,186 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file fallback_policy.hpp
+ * \author Andrey Semashev
+ * \date 18.08.2012
+ *
+ * The header contains definition of fallback policies when attribute value visitation or extraction fails.
+ */
+
+#ifndef BOOST_LOG_ATTRIBUTES_FALLBACK_POLICY_HPP_INCLUDED_
+#define BOOST_LOG_ATTRIBUTES_FALLBACK_POLICY_HPP_INCLUDED_
+
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/log/detail/config.hpp>
+#include <boost/log/exceptions.hpp>
+#include <boost/log/utility/type_info_wrapper.hpp>
+#include <boost/log/attributes/fallback_policy_fwd.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+/*!
+ * The \c fallback_to_none policy results in returning an empty value reference if the attribute value cannot be extracted.
+ */
+struct fallback_to_none
+{
+ enum { guaranteed_result = false };
+
+ /*!
+ * The method is called in order to apply a function object to the default value.
+ */
+ template< typename FunT >
+ static bool apply_default(FunT&)
+ {
+ return false;
+ }
+
+ /*!
+ * The method is called in order to apply a function object to the default value.
+ */
+ template< typename FunT >
+ static bool apply_default(FunT const&)
+ {
+ return false;
+ }
+
+ /*!
+ * The method is called when value extraction failed because the attribute value has different type than requested.
+ */
+ static void on_invalid_type(type_info_wrapper const&)
+ {
+ }
+
+ /*!
+ * The method is called when value extraction failed because the attribute value was not found.
+ */
+ static void on_missing_value()
+ {
+ }
+};
+
+/*!
+ * The \c fallback_to_throw policy results in throwing an exception if the attribute value cannot be extracted.
+ */
+struct fallback_to_throw
+{
+ enum { guaranteed_result = true };
+
+ /*!
+ * The method is called in order to apply a function object to the default value.
+ */
+ template< typename FunT >
+ static bool apply_default(FunT&)
+ {
+ return false;
+ }
+
+ /*!
+ * The method is called in order to apply a function object to the default value.
+ */
+ template< typename FunT >
+ static bool apply_default(FunT const&)
+ {
+ return false;
+ }
+
+ /*!
+ * The method is called when value extraction failed because the attribute value has different type than requested.
+ */
+ static void on_invalid_type(type_info_wrapper const& t)
+ {
+ BOOST_LOG_THROW_DESCR_PARAMS(invalid_type, "Attribute value has incompatible type", (t));
+ }
+
+ /*!
+ * The method is called when value extraction failed because the attribute value was not found.
+ */
+ static void on_missing_value()
+ {
+ BOOST_LOG_THROW_DESCR(missing_value, "Attribute value not found");
+ }
+};
+
+/*!
+ * The \c fallback_to_default policy results in a default value if the attribute value cannot be extracted.
+ */
+template< typename DefaultT >
+struct fallback_to_default
+{
+ enum { guaranteed_result = true };
+
+ //! Default value type
+ typedef typename remove_cv< typename remove_reference< DefaultT >::type >::type default_type;
+
+ /*!
+ * Default constructor.
+ */
+ fallback_to_default() : m_default()
+ {
+ }
+
+ /*!
+ * Initializing constructor.
+ */
+ explicit fallback_to_default(default_type const& def_val) : m_default(def_val)
+ {
+ }
+
+ /*!
+ * The method is called in order to apply a function object to the default value.
+ */
+ template< typename FunT >
+ bool apply_default(FunT& fun) const
+ {
+ fun(m_default);
+ return true;
+ }
+
+ /*!
+ * The method is called in order to apply a function object to the default value.
+ */
+ template< typename FunT >
+ bool apply_default(FunT const& fun) const
+ {
+ fun(m_default);
+ return true;
+ }
+
+ /*!
+ * The method is called when value extraction failed because the attribute value has different type than requested.
+ */
+ static void on_invalid_type(type_info_wrapper const&)
+ {
+ }
+
+ /*!
+ * The method is called when value extraction failed because the attribute value was not found.
+ */
+ static void on_missing_value()
+ {
+ }
+
+private:
+ //! Default value
+ DefaultT m_default;
+};
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_ATTRIBUTES_FALLBACK_POLICY_HPP_INCLUDED_
diff --git a/boost/log/attributes/fallback_policy_fwd.hpp b/boost/log/attributes/fallback_policy_fwd.hpp
new file mode 100644
index 0000000..b6b01e3
--- /dev/null
+++ b/boost/log/attributes/fallback_policy_fwd.hpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file fallback_policy_fwd.hpp
+ * \author Andrey Semashev
+ * \date 18.08.2012
+ *
+ * The header contains forward declaration of fallback policies when attribute value visitation or extraction fails.
+ */
+
+#ifndef BOOST_LOG_ATTRIBUTES_FALLBACK_POLICY_FWD_HPP_INCLUDED_
+#define BOOST_LOG_ATTRIBUTES_FALLBACK_POLICY_FWD_HPP_INCLUDED_
+
+#include <boost/log/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+/*!
+ * The \c fallback_to_none policy results in returning an empty value reference if the attribute value cannot be extracted.
+ */
+struct fallback_to_none;
+
+/*!
+ * The \c fallback_to_throw policy results in throwing an exception if the attribute value cannot be extracted.
+ */
+struct fallback_to_throw;
+
+/*!
+ * The \c fallback_to_default policy results in a default value if the attribute value cannot be extracted.
+ */
+template< typename DefaultT >
+struct fallback_to_default;
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#endif // BOOST_LOG_ATTRIBUTES_FALLBACK_POLICY_FWD_HPP_INCLUDED_
diff --git a/boost/log/attributes/function.hpp b/boost/log/attributes/function.hpp
new file mode 100644
index 0000000..4333e32
--- /dev/null
+++ b/boost/log/attributes/function.hpp
@@ -0,0 +1,170 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file function.hpp
+ * \author Andrey Semashev
+ * \date 24.06.2007
+ *
+ * The header contains implementation of an attribute that calls a third-party function on value acquisition.
+ */
+
+#ifndef BOOST_LOG_ATTRIBUTES_FUNCTION_HPP_INCLUDED_
+#define BOOST_LOG_ATTRIBUTES_FUNCTION_HPP_INCLUDED_
+
+#include <boost/static_assert.hpp>
+#include <boost/utility/result_of.hpp>
+#include <boost/type_traits/is_void.hpp>
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/log/detail/config.hpp>
+#include <boost/log/attributes/attribute.hpp>
+#include <boost/log/attributes/attribute_cast.hpp>
+#include <boost/log/attributes/attribute_value_impl.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace attributes {
+
+/*!
+ * \brief A class of an attribute that acquires its value from a third-party function object
+ *
+ * The attribute calls a stored nullary function object to acquire each value.
+ * The result type of the function object is the attribute value type.
+ *
+ * It is not recommended to use this class directly. Use \c make_function convenience functions
+ * to construct the attribute instead.
+ */
+template< typename R >
+class function :
+ public attribute
+{
+ BOOST_STATIC_ASSERT_MSG(!is_void< R >::value, "Boost.Log: Function object return type must not be void");
+
+public:
+ //! The attribute value type
+ typedef R value_type;
+
+protected:
+ //! Base class for factory implementation
+ class BOOST_LOG_NO_VTABLE BOOST_SYMBOL_VISIBLE impl :
+ public attribute::impl
+ {
+ };
+
+ //! Factory implementation
+ template< typename T >
+ class impl_template :
+ public impl
+ {
+ private:
+ //! Functor that returns attribute values
+ /*!
+ * \note The constness signifies that the function object should avoid
+ * modifying its state since it's not protected against concurrent calls.
+ */
+ const T m_Functor;
+
+ public:
+ /*!
+ * Constructor with the stored delegate initialization
+ */
+ explicit impl_template(T const& fun) : m_Functor(fun) {}
+
+ attribute_value get_value()
+ {
+ return attributes::make_attribute_value(m_Functor());
+ }
+ };
+
+public:
+ /*!
+ * Initializing constructor
+ */
+ template< typename T >
+ explicit function(T const& fun) : attribute(new impl_template< T >(fun))
+ {
+ }
+ /*!
+ * Constructor for casting support
+ */
+ explicit function(cast_source const& source) :
+ attribute(source.as< impl >())
+ {
+ }
+};
+
+#ifndef BOOST_NO_RESULT_OF
+
+/*!
+ * The function constructs \c function attribute instance with the provided function object.
+ *
+ * \param fun Nullary functional object that returns an actual stored value for an attribute value.
+ * \return Pointer to the attribute instance
+ */
+template< typename T >
+inline function<
+ typename remove_cv<
+ typename remove_reference<
+ typename boost::result_of< T() >::type
+ >::type
+ >::type
+> make_function(T const& fun)
+{
+ typedef typename remove_cv<
+ typename remove_reference<
+ typename boost::result_of< T() >::type
+ >::type
+ >::type result_type;
+
+ typedef function< result_type > function_type;
+ return function_type(fun);
+}
+
+#endif // BOOST_NO_RESULT_OF
+
+#ifndef BOOST_LOG_DOXYGEN_PASS
+
+/*!
+ * The function constructs \c function attribute instance with the provided function object.
+ * Use this version if your compiler fails to determine the result type of the function object.
+ *
+ * \param fun Nullary functional object that returns an actual stored value for an attribute value.
+ * \return Pointer to the attribute instance
+ */
+template< typename R, typename T >
+inline function<
+ typename remove_cv<
+ typename remove_reference< R >::type
+ >::type
+> make_function(T const& fun)
+{
+ typedef typename remove_cv<
+ typename remove_reference< R >::type
+ >::type result_type;
+
+ typedef function< result_type > function_type;
+ return function_type(fun);
+}
+
+#endif // BOOST_LOG_DOXYGEN_PASS
+
+} // namespace attributes
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_ATTRIBUTES_FUNCTOR_HPP_INCLUDED_
diff --git a/boost/log/attributes/mutable_constant.hpp b/boost/log/attributes/mutable_constant.hpp
new file mode 100644
index 0000000..a668256
--- /dev/null
+++ b/boost/log/attributes/mutable_constant.hpp
@@ -0,0 +1,332 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file mutable_constant.hpp
+ * \author Andrey Semashev
+ * \date 06.11.2007
+ *
+ * The header contains implementation of a mutable constant attribute.
+ */
+
+#ifndef BOOST_LOG_ATTRIBUTES_MUTABLE_CONSTANT_HPP_INCLUDED_
+#define BOOST_LOG_ATTRIBUTES_MUTABLE_CONSTANT_HPP_INCLUDED_
+
+#include <boost/static_assert.hpp>
+#include <boost/smart_ptr/intrusive_ptr.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/move/core.hpp>
+#include <boost/move/utility.hpp>
+#include <boost/type_traits/is_void.hpp>
+#include <boost/log/detail/config.hpp>
+#include <boost/log/detail/locks.hpp>
+#include <boost/log/attributes/attribute.hpp>
+#include <boost/log/attributes/attribute_cast.hpp>
+#include <boost/log/attributes/attribute_value_impl.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace attributes {
+
+/*!
+ * \brief A class of an attribute that holds a single constant value with ability to change it
+ *
+ * The mutable_constant attribute stores a single value of type, specified as the first template argument.
+ * This value is returned on each attribute value acquisition.
+ *
+ * The attribute also allows to modify the stored value, even if the attribute is registered in an attribute set.
+ * In order to ensure thread safety of such modifications the \c mutable_constant class is also parametrized
+ * with three additional template arguments: mutex type, scoped write and scoped read lock types. If not specified,
+ * the lock types are automatically deduced based on the mutex type.
+ *
+ * The implementation may avoid using these types to actually create and use the mutex, if a more efficient synchronization method is
+ * available (such as atomic operations on the value type). By default no synchronization is done.
+ */
+#ifdef BOOST_LOG_DOXYGEN_PASS
+template< typename T, typename MutexT = void, typename ScopedWriteLockT = auto, typename ScopedReadLockT = auto >
+#else // BOOST_LOG_DOXYGEN_PASS
+template<
+ typename T,
+ typename MutexT = void,
+ typename ScopedWriteLockT =
+#ifndef BOOST_LOG_NO_THREADS
+ typename mpl::if_c<
+ boost::log::aux::is_exclusively_lockable< MutexT >::value,
+ boost::log::aux::exclusive_lock_guard< MutexT >,
+ void
+ >::type,
+#else
+ void,
+#endif // BOOST_LOG_NO_THREADS
+ typename ScopedReadLockT =
+#ifndef BOOST_LOG_NO_THREADS
+ typename mpl::if_c<
+ boost::log::aux::is_shared_lockable< MutexT >::value,
+ boost::log::aux::shared_lock_guard< MutexT >,
+ ScopedWriteLockT
+ >::type
+#else
+ ScopedWriteLockT
+#endif // BOOST_LOG_NO_THREADS
+#endif // BOOST_LOG_DOXYGEN_PASS
+>
+class mutable_constant :
+ public attribute
+{
+public:
+ //! The attribute value type
+ typedef T value_type;
+
+protected:
+ //! Factory implementation
+ class BOOST_SYMBOL_VISIBLE impl :
+ public attribute::impl
+ {
+ private:
+ //! Mutex type
+ typedef MutexT mutex_type;
+ //! Shared lock type
+ typedef ScopedReadLockT scoped_read_lock;
+ //! Exclusive lock type
+ typedef ScopedWriteLockT scoped_write_lock;
+ BOOST_STATIC_ASSERT_MSG(!(is_void< mutex_type >::value || is_void< scoped_read_lock >::value || is_void< scoped_write_lock >::value), "Boost.Log: Mutex and both lock types either must not be void or must all be void");
+ //! Attribute value wrapper
+ typedef attribute_value_impl< value_type > attr_value;
+
+ private:
+ //! Thread protection mutex
+ mutable mutex_type m_Mutex;
+ //! Pointer to the actual attribute value
+ intrusive_ptr< attr_value > m_Value;
+
+ public:
+ /*!
+ * Initializing constructor
+ */
+ explicit impl(value_type const& value) : m_Value(new attr_value(value))
+ {
+ }
+ /*!
+ * Initializing constructor
+ */
+ explicit impl(BOOST_RV_REF(value_type) value) : m_Value(new attr_value(boost::move(value)))
+ {
+ }
+
+ attribute_value get_value()
+ {
+ scoped_read_lock lock(m_Mutex);
+ return attribute_value(m_Value);
+ }
+
+ void set(value_type const& value)
+ {
+ intrusive_ptr< attr_value > p = new attr_value(value);
+ scoped_write_lock lock(m_Mutex);
+ m_Value.swap(p);
+ }
+
+ void set(BOOST_RV_REF(value_type) value)
+ {
+ intrusive_ptr< attr_value > p = new attr_value(boost::move(value));
+ scoped_write_lock lock(m_Mutex);
+ m_Value.swap(p);
+ }
+
+ value_type get() const
+ {
+ scoped_read_lock lock(m_Mutex);
+ return m_Value->get();
+ }
+ };
+
+public:
+ /*!
+ * Constructor with the stored value initialization
+ */
+ explicit mutable_constant(value_type const& value) : attribute(new impl(value))
+ {
+ }
+ /*!
+ * Constructor with the stored value initialization
+ */
+ explicit mutable_constant(BOOST_RV_REF(value_type) value) : attribute(new impl(boost::move(value)))
+ {
+ }
+ /*!
+ * Constructor for casting support
+ */
+ explicit mutable_constant(cast_source const& source) : attribute(source.as< impl >())
+ {
+ }
+
+ /*!
+ * The method sets a new attribute value. The implementation exclusively locks the mutex in order
+ * to protect the value assignment.
+ */
+ void set(value_type const& value)
+ {
+ get_impl()->set(value);
+ }
+
+ /*!
+ * The method sets a new attribute value.
+ */
+ void set(BOOST_RV_REF(value_type) value)
+ {
+ get_impl()->set(boost::move(value));
+ }
+
+ /*!
+ * The method acquires the current attribute value. The implementation non-exclusively locks the mutex in order
+ * to protect the value acquisition.
+ */
+ value_type get() const
+ {
+ return get_impl()->get();
+ }
+
+protected:
+ /*!
+ * \returns Pointer to the factory implementation
+ */
+ impl* get_impl() const
+ {
+ return static_cast< impl* >(attribute::get_impl());
+ }
+};
+
+
+/*!
+ * \brief Specialization for unlocked case
+ *
+ * This version of attribute does not perform thread synchronization to access the stored value.
+ */
+template< typename T >
+class mutable_constant< T, void, void, void > :
+ public attribute
+{
+public:
+ //! The attribute value type
+ typedef T value_type;
+
+protected:
+ //! Factory implementation
+ class BOOST_SYMBOL_VISIBLE impl :
+ public attribute::impl
+ {
+ private:
+ //! Attribute value wrapper
+ typedef attribute_value_impl< value_type > attr_value;
+
+ private:
+ //! The actual value
+ intrusive_ptr< attr_value > m_Value;
+
+ public:
+ /*!
+ * Initializing constructor
+ */
+ explicit impl(value_type const& value) : m_Value(new attr_value(value))
+ {
+ }
+ /*!
+ * Initializing constructor
+ */
+ explicit impl(BOOST_RV_REF(value_type) value) : m_Value(new attr_value(boost::move(value)))
+ {
+ }
+
+ attribute_value get_value()
+ {
+ return attribute_value(m_Value);
+ }
+
+ void set(value_type const& value)
+ {
+ m_Value = new attr_value(value);
+ }
+ void set(BOOST_RV_REF(value_type) value)
+ {
+ m_Value = new attr_value(boost::move(value));
+ }
+
+ value_type get() const
+ {
+ return m_Value->get();
+ }
+ };
+
+public:
+ /*!
+ * Constructor with the stored value initialization
+ */
+ explicit mutable_constant(value_type const& value) : attribute(new impl(value))
+ {
+ }
+ /*!
+ * Constructor with the stored value initialization
+ */
+ explicit mutable_constant(BOOST_RV_REF(value_type) value) : attribute(new impl(boost::move(value)))
+ {
+ }
+ /*!
+ * Constructor for casting support
+ */
+ explicit mutable_constant(cast_source const& source) : attribute(source.as< impl >())
+ {
+ }
+
+ /*!
+ * The method sets a new attribute value.
+ */
+ void set(value_type const& value)
+ {
+ get_impl()->set(value);
+ }
+
+ /*!
+ * The method sets a new attribute value.
+ */
+ void set(BOOST_RV_REF(value_type) value)
+ {
+ get_impl()->set(boost::move(value));
+ }
+
+ /*!
+ * The method acquires the current attribute value.
+ */
+ value_type get() const
+ {
+ return get_impl()->get();
+ }
+
+protected:
+ /*!
+ * \returns Pointer to the factory implementation
+ */
+ impl* get_impl() const
+ {
+ return static_cast< impl* >(attribute::get_impl());
+ }
+};
+
+} // namespace attributes
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_ATTRIBUTES_MUTABLE_CONSTANT_HPP_INCLUDED_
diff --git a/boost/log/attributes/named_scope.hpp b/boost/log/attributes/named_scope.hpp
new file mode 100644
index 0000000..7b75c3d
--- /dev/null
+++ b/boost/log/attributes/named_scope.hpp
@@ -0,0 +1,474 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file
+ * \author Andrey Semashev
+ * \date 24.06.2007
+ *
+ * The header contains implementation of named scope container and an attribute that allows to
+ * put the named scope to log. A number of convenience macros are also provided.
+ */
+
+#ifndef BOOST_LOG_ATTRIBUTES_NAMED_SCOPE_HPP_INCLUDED_
+#define BOOST_LOG_ATTRIBUTES_NAMED_SCOPE_HPP_INCLUDED_
+
+#include <ostream>
+#include <memory>
+#include <iterator>
+#include <cstddef>
+#include <boost/log/detail/config.hpp>
+#include <boost/current_function.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/log/utility/string_literal.hpp>
+#include <boost/log/utility/unique_identifier_name.hpp>
+#include <boost/log/utility/unused_variable.hpp>
+#include <boost/log/attributes/attribute.hpp>
+#include <boost/log/attributes/attribute_cast.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace attributes {
+
+namespace aux {
+
+ //! Double-linked list node
+ struct named_scope_list_node
+ {
+ mutable named_scope_list_node* _m_pPrev;
+ mutable named_scope_list_node* _m_pNext;
+
+ named_scope_list_node() BOOST_NOEXCEPT { _m_pPrev = _m_pNext = this; }
+ };
+
+} // namespace aux
+
+/*!
+ * \brief The structure contains all information about a named scope
+ *
+ * The named scope entries are stored as elements of \c basic_named_scope_list container, which
+ * in turn can be acquired either from the \c basic_named_scope attribute value or from a thread-local
+ * instance.
+ */
+struct named_scope_entry
+ //! \cond
+ : public aux::named_scope_list_node
+ //! \endcond
+{
+ /*!
+ * \brief Scope entry type
+ *
+ * Describes scope name specifics
+ */
+ enum scope_name_type
+ {
+ general, //!< The scope name contains some unstructured string that should not be interpreted by the library
+ function //!< The scope name contains a function signature
+ };
+
+ /*!
+ * The scope name (e.g. a function signature)
+ */
+ string_literal scope_name;
+ /*!
+ * The source file name
+ */
+ string_literal file_name;
+ /*!
+ * The line number in the source file
+ */
+ unsigned int line;
+ /*!
+ * The scope name type
+ */
+ scope_name_type type;
+
+ /*!
+ * Initializing constructor
+ *
+ * \post <tt>scope_name == sn && file_name == fn && line == ln</tt>
+ *
+ * \b Throws: Nothing.
+ */
+ named_scope_entry(string_literal const& sn, string_literal const& fn, unsigned int ln, scope_name_type t = general) BOOST_NOEXCEPT :
+ scope_name(sn),
+ file_name(fn),
+ line(ln),
+ type(t)
+ {
+ }
+};
+
+/*!
+ * \brief The class implements the list of scopes
+ *
+ * The scope list provides a read-only access to a doubly-linked list of scopes.
+ */
+class named_scope_list
+ //! \cond
+ : protected std::allocator< named_scope_entry >
+ //! \endcond
+{
+public:
+ //! Allocator type
+ typedef std::allocator< named_scope_entry > allocator_type;
+
+ // Standard types
+ typedef allocator_type::value_type value_type;
+ typedef allocator_type::reference reference;
+ typedef allocator_type::const_reference const_reference;
+ typedef allocator_type::pointer pointer;
+ typedef allocator_type::const_pointer const_pointer;
+ typedef allocator_type::size_type size_type;
+ typedef allocator_type::difference_type difference_type;
+
+#ifndef BOOST_LOG_DOXYGEN_PASS
+
+protected:
+ //! Iterator class
+#ifndef BOOST_LOG_NO_MEMBER_TEMPLATE_FRIENDS
+ template< bool fConstV > class iter;
+ template< bool fConstV > friend class iter;
+#endif
+ template< bool fConstV >
+ class iter
+ {
+ friend class iter< !fConstV >;
+
+ public:
+ // Standard typedefs
+ typedef named_scope_list::difference_type difference_type;
+ typedef named_scope_list::value_type value_type;
+ typedef typename mpl::if_c<
+ fConstV,
+ named_scope_list::const_reference,
+ named_scope_list::reference
+ >::type reference;
+ typedef typename mpl::if_c<
+ fConstV,
+ named_scope_list::const_pointer,
+ named_scope_list::pointer
+ >::type pointer;
+ typedef std::bidirectional_iterator_tag iterator_category;
+
+ public:
+ // Constructors
+ iter() : m_pNode(NULL) {}
+ explicit iter(aux::named_scope_list_node* pNode) : m_pNode(pNode) {}
+ iter(iter< false > const& that) : m_pNode(that.m_pNode) {}
+
+ //! Assignment
+ template< bool f >
+ iter& operator= (iter< f > const& that)
+ {
+ m_pNode = that.m_pNode;
+ return *this;
+ }
+
+ // Comparison
+ template< bool f >
+ bool operator== (iter< f > const& that) const { return (m_pNode == that.m_pNode); }
+ template< bool f >
+ bool operator!= (iter< f > const& that) const { return (m_pNode != that.m_pNode); }
+
+ // Modification
+ iter& operator++ ()
+ {
+ m_pNode = m_pNode->_m_pNext;
+ return *this;
+ }
+ iter& operator-- ()
+ {
+ m_pNode = m_pNode->_m_pPrev;
+ return *this;
+ }
+ iter operator++ (int)
+ {
+ iter tmp(*this);
+ m_pNode = m_pNode->_m_pNext;
+ return tmp;
+ }
+ iter operator-- (int)
+ {
+ iter tmp(*this);
+ m_pNode = m_pNode->_m_pPrev;
+ return tmp;
+ }
+
+ // Dereferencing
+ pointer operator-> () const { return static_cast< pointer >(m_pNode); }
+ reference operator* () const { return *static_cast< pointer >(m_pNode); }
+
+ private:
+ aux::named_scope_list_node* m_pNode;
+ };
+
+public:
+ typedef iter< true > const_iterator;
+ typedef iter< false > iterator;
+ typedef std::reverse_iterator< const_iterator > const_reverse_iterator;
+ typedef std::reverse_iterator< iterator > reverse_iterator;
+
+protected:
+ //! The root node of the container
+ aux::named_scope_list_node m_RootNode;
+ //! The size of the container
+ size_type m_Size;
+ //! The flag shows if the contained elements are dynamically allocated
+ bool m_fNeedToDeallocate;
+
+#else // BOOST_LOG_DOXYGEN_PASS
+
+ /*!
+ * A constant iterator to the sequence of scopes. Complies to bidirectional iterator requirements.
+ */
+ typedef implementation_defined const_iterator;
+ /*!
+ * An iterator to the sequence of scopes. Complies to bidirectional iterator requirements.
+ */
+ typedef implementation_defined iterator;
+ /*!
+ * A constant reverse iterator to the sequence of scopes. Complies to bidirectional iterator requirements.
+ */
+ typedef implementation_defined const_reverse_iterator;
+ /*!
+ * A reverse iterator to the sequence of scopes. Complies to bidirectional iterator requirements.
+ */
+ typedef implementation_defined reverse_iterator;
+
+#endif // BOOST_LOG_DOXYGEN_PASS
+
+public:
+ /*!
+ * Default constructor
+ *
+ * \post <tt>empty() == true</tt>
+ */
+ named_scope_list() : m_Size(0), m_fNeedToDeallocate(false) {}
+ /*!
+ * Copy constructor
+ *
+ * \post <tt>std::equal(begin(), end(), that.begin()) == true</tt>
+ */
+ BOOST_LOG_API named_scope_list(named_scope_list const& that);
+ /*!
+ * Destructor. Destroys the stored entries.
+ */
+ BOOST_LOG_API ~named_scope_list();
+
+ /*!
+ * Assignment operator
+ *
+ * \post <tt>std::equal(begin(), end(), that.begin()) == true</tt>
+ */
+ named_scope_list& operator= (named_scope_list const& that)
+ {
+ if (this != &that)
+ {
+ named_scope_list tmp(that);
+ swap(tmp);
+ }
+ return *this;
+ }
+
+ /*!
+ * \return Constant iterator to the first element of the container.
+ */
+ const_iterator begin() const { return const_iterator(m_RootNode._m_pNext); }
+ /*!
+ * \return Constant iterator to the after-the-last element of the container.
+ */
+ const_iterator end() const { return const_iterator(const_cast< aux::named_scope_list_node* >(&m_RootNode)); }
+ /*!
+ * \return Constant iterator to the last element of the container.
+ */
+ const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
+ /*!
+ * \return Constant iterator to the before-the-first element of the container.
+ */
+ const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
+
+ /*!
+ * \return The number of elements in the container
+ */
+ size_type size() const { return m_Size; }
+ /*!
+ * \return true if the container is empty and false otherwise
+ */
+ bool empty() const { return (m_Size == 0); }
+
+ /*!
+ * Swaps two instances of the container
+ */
+ BOOST_LOG_API void swap(named_scope_list& that);
+
+ /*!
+ * \return Last pushed scope entry
+ */
+ const_reference back() const { return *rbegin(); }
+ /*!
+ * \return First pushed scope entry
+ */
+ const_reference front() const { return *begin(); }
+};
+
+//! Stream output operator
+template< typename CharT, typename TraitsT >
+inline std::basic_ostream< CharT, TraitsT >& operator<< (std::basic_ostream< CharT, TraitsT >& strm, named_scope_list const& sl)
+{
+ if (strm.good())
+ {
+ named_scope_list::const_iterator it = sl.begin(), end = sl.end();
+ if (it != end)
+ {
+ strm << it->scope_name.c_str();
+ for (++it; it != end; ++it)
+ strm << "->" << it->scope_name.c_str();
+ }
+ }
+ return strm;
+}
+
+/*!
+ * \brief A class of an attribute that holds stack of named scopes of the current thread
+ *
+ * The basic_named_scope attribute is essentially a hook to the thread-specific instance of
+ * scope list. This means that the attribute will generate different values if get_value is
+ * called in different threads. The attribute generates value with stored type
+ * <tt>basic_named_scope_list< CharT ></tt>.
+ *
+ * The attribute class can also be used to gain access to the scope stack instance, e.g. to
+ * get its copy or to push or pop a scope entry. However, it is highly not recommended to
+ * maintain scope list manually. Use \c BOOST_LOG_NAMED_SCOPE or \c BOOST_LOG_FUNCTION macros instead.
+ */
+class BOOST_LOG_API named_scope :
+ public attribute
+{
+public:
+ //! Scope names stack (the attribute value type)
+ typedef named_scope_list value_type;
+ //! Scope entry
+ typedef value_type::value_type scope_entry;
+
+ //! Sentry object class to automatically push and pop scopes
+ struct sentry
+ {
+ /*!
+ * Constructor. Pushes the specified scope to the end of the thread-local list of scopes.
+ *
+ * \param sn Scope name.
+ * \param fn File name, in which the scope is located.
+ * \param ln Line number in the file.
+ */
+ sentry(string_literal const& sn, string_literal const& fn, unsigned int ln, scope_entry::scope_name_type t = scope_entry::general) BOOST_NOEXCEPT :
+ m_Entry(sn, fn, ln, t)
+ {
+ named_scope::push_scope(m_Entry);
+ }
+
+ /*!
+ * Destructor. Removes the last pushed scope from the thread-local list of scopes.
+ */
+ ~sentry() BOOST_NOEXCEPT
+ {
+ named_scope::pop_scope();
+ }
+
+ BOOST_DELETED_FUNCTION(sentry(sentry const&))
+ BOOST_DELETED_FUNCTION(sentry& operator= (sentry const&))
+
+ private:
+ scope_entry m_Entry;
+ };
+
+private:
+ //! Attribute implementation class
+ struct BOOST_SYMBOL_VISIBLE impl;
+
+public:
+ /*!
+ * Constructor. Creates an attribute.
+ */
+ named_scope();
+ /*!
+ * Constructor for casting support
+ */
+ explicit named_scope(cast_source const& source);
+
+ /*!
+ * The method pushes the scope to the back of the current thread's scope list
+ *
+ * \b Throws: Nothing.
+ */
+ static void push_scope(scope_entry const& entry) BOOST_NOEXCEPT;
+ /*!
+ * The method pops the last pushed scope from the current thread's scope list
+ *
+ * \b Throws: Nothing.
+ */
+ static void pop_scope() BOOST_NOEXCEPT;
+
+ /*!
+ * \return The current thread's list of scopes
+ *
+ * \note The returned reference is only valid until the current thread ends. The scopes in the
+ * returned container may change if the execution scope is changed (i.e. either \c push_scope
+ * or \c pop_scope is called). User has to copy the stack if he wants to keep it intact regardless
+ * of the execution scope.
+ */
+ static value_type const& get_scopes();
+};
+
+} // namespace attributes
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#ifndef BOOST_LOG_DOXYGEN_PASS
+
+#define BOOST_LOG_NAMED_SCOPE_INTERNAL(var, name, file, line, type)\
+ BOOST_LOG_UNUSED_VARIABLE(::boost::log::attributes::named_scope::sentry, var, (name, file, line, type));
+
+#endif // BOOST_LOG_DOXYGEN_PASS
+
+/*!
+ * Macro for scope markup. The specified scope name is pushed to the end of the current thread scope list.
+ */
+#define BOOST_LOG_NAMED_SCOPE(name)\
+ BOOST_LOG_NAMED_SCOPE_INTERNAL(BOOST_LOG_UNIQUE_IDENTIFIER_NAME(_boost_log_named_scope_sentry_), name, __FILE__, __LINE__, ::boost::log::attributes::named_scope_entry::general)
+
+/*!
+ * Macro for function scope markup. The scope name is constructed with help of compiler and contains the current function signature.
+ * The scope name is pushed to the end of the current thread scope list.
+ *
+ * Not all compilers have support for this macro. The exact form of the scope name may vary from one compiler to another.
+ */
+#define BOOST_LOG_FUNCTION()\
+ BOOST_LOG_NAMED_SCOPE_INTERNAL(BOOST_LOG_UNIQUE_IDENTIFIER_NAME(_boost_log_named_scope_sentry_), BOOST_CURRENT_FUNCTION, __FILE__, __LINE__, ::boost::log::attributes::named_scope_entry::function)
+
+/*!
+ * Macro for function scope markup. The scope name is constructed with help of compiler and contains the current function name. It may be shorter than what \c BOOST_LOG_FUNCTION macro produces.
+ * The scope name is pushed to the end of the current thread scope list.
+ *
+ * Not all compilers have support for this macro. The exact form of the scope name may vary from one compiler to another.
+ */
+#if defined(_MSC_VER) || defined(__GNUC__)
+#define BOOST_LOG_FUNC() BOOST_LOG_NAMED_SCOPE(__FUNCTION__)
+#else
+#define BOOST_LOG_FUNC() BOOST_LOG_FUNCTION()
+#endif
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_ATTRIBUTES_NAMED_SCOPE_HPP_INCLUDED_
diff --git a/boost/log/attributes/scoped_attribute.hpp b/boost/log/attributes/scoped_attribute.hpp
new file mode 100644
index 0000000..33b1c39
--- /dev/null
+++ b/boost/log/attributes/scoped_attribute.hpp
@@ -0,0 +1,253 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file scoped_attribute.hpp
+ * \author Andrey Semashev
+ * \date 13.05.2007
+ *
+ * The header contains definition of facilities to define scoped attributes.
+ */
+
+#ifndef BOOST_LOG_ATTRIBUTES_SCOPED_ATTRIBUTE_HPP_INCLUDED_
+#define BOOST_LOG_ATTRIBUTES_SCOPED_ATTRIBUTE_HPP_INCLUDED_
+
+#include <utility>
+#include <boost/move/core.hpp>
+#include <boost/move/utility.hpp>
+#include <boost/utility/addressof.hpp>
+#include <boost/log/detail/config.hpp>
+#include <boost/log/core/core.hpp>
+#include <boost/log/sources/basic_logger.hpp>
+#include <boost/log/attributes/attribute.hpp>
+#include <boost/log/attributes/attribute_set.hpp>
+#include <boost/log/attributes/attribute_name.hpp>
+#include <boost/log/attributes/constant.hpp>
+#include <boost/log/utility/unused_variable.hpp>
+#include <boost/log/utility/unique_identifier_name.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace aux {
+
+//! A base class for all scoped attribute guards
+class attribute_scope_guard
+{
+};
+
+} // namespace aux
+
+//! Scoped attribute guard type
+typedef aux::attribute_scope_guard const& scoped_attribute;
+
+namespace aux {
+
+//! A scoped logger attribute guard
+template< typename LoggerT >
+class scoped_logger_attribute :
+ public attribute_scope_guard
+{
+ BOOST_COPYABLE_AND_MOVABLE_ALT(scoped_logger_attribute)
+
+private:
+ //! Logger type
+ typedef LoggerT logger_type;
+
+private:
+ //! A reference to the logger
+ logger_type* m_pLogger;
+ //! An iterator to the added attribute
+ attribute_set::iterator m_itAttribute;
+
+public:
+ //! Constructor
+ scoped_logger_attribute(logger_type& l, attribute_name const& name, attribute const& attr) :
+ m_pLogger(boost::addressof(l))
+ {
+ std::pair<
+ attribute_set::iterator,
+ bool
+ > res = l.add_attribute(name, attr);
+ if (res.second)
+ m_itAttribute = res.first;
+ else
+ m_pLogger = 0; // if there already is a same-named attribute, don't register anything
+ }
+ //! Move constructor
+ scoped_logger_attribute(BOOST_RV_REF(scoped_logger_attribute) that) :
+ m_pLogger(that.m_pLogger),
+ m_itAttribute(that.m_itAttribute)
+ {
+ that.m_pLogger = 0;
+ }
+
+ //! Destructor
+ ~scoped_logger_attribute()
+ {
+ if (m_pLogger)
+ m_pLogger->remove_attribute(m_itAttribute);
+ }
+
+#ifndef BOOST_LOG_BROKEN_REFERENCE_FROM_RVALUE_INIT
+ BOOST_DELETED_FUNCTION(scoped_logger_attribute(scoped_logger_attribute const&))
+#else // BOOST_LOG_BROKEN_REFERENCE_FROM_RVALUE_INIT
+ scoped_logger_attribute(scoped_logger_attribute const& that) : m_pLogger(that.m_pLogger), m_itAttribute(that.m_itAttribute)
+ {
+ const_cast< scoped_logger_attribute& >(that).m_pLogger = 0;
+ }
+#endif // BOOST_LOG_BROKEN_REFERENCE_FROM_RVALUE_INIT
+
+ BOOST_DELETED_FUNCTION(scoped_logger_attribute& operator= (scoped_logger_attribute const&))
+};
+
+} // namespace aux
+
+// Generator helper functions
+/*!
+ * Registers an attribute in the logger
+ *
+ * \param l Logger to register the attribute in
+ * \param name Attribute name
+ * \param attr The attribute. Must not be NULL.
+ * \return An unspecified guard object which may be used to initialize a \c scoped_attribute variable.
+ */
+template< typename LoggerT >
+BOOST_FORCEINLINE aux::scoped_logger_attribute< LoggerT > add_scoped_logger_attribute(LoggerT& l, attribute_name const& name, attribute const& attr)
+{
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ return aux::scoped_logger_attribute< LoggerT >(l, name, attr);
+#else
+ aux::scoped_logger_attribute< LoggerT > guard(l, name, attr);
+ return boost::move(guard);
+#endif
+}
+
+#ifndef BOOST_LOG_DOXYGEN_PASS
+
+#define BOOST_LOG_SCOPED_LOGGER_ATTR_INTERNAL(logger, attr_name, attr, sentry_var_name)\
+ BOOST_LOG_UNUSED_VARIABLE(::boost::log::scoped_attribute, sentry_var_name,\
+ = ::boost::log::add_scoped_logger_attribute(logger, attr_name, (attr)));
+
+#endif // BOOST_LOG_DOXYGEN_PASS
+
+//! The macro sets a scoped logger-wide attribute in a more compact way
+#define BOOST_LOG_SCOPED_LOGGER_ATTR(logger, attr_name, attr)\
+ BOOST_LOG_SCOPED_LOGGER_ATTR_INTERNAL(\
+ logger,\
+ attr_name,\
+ attr,\
+ BOOST_LOG_UNIQUE_IDENTIFIER_NAME(_boost_log_scoped_logger_attr_sentry_))
+
+//! The macro sets a scoped logger-wide tag in a more compact way
+#define BOOST_LOG_SCOPED_LOGGER_TAG(logger, attr_name, attr_value)\
+ BOOST_LOG_SCOPED_LOGGER_ATTR(logger, attr_name, ::boost::log::attributes::make_constant(attr_value))
+
+namespace aux {
+
+//! A scoped thread-specific attribute guard
+class scoped_thread_attribute :
+ public attribute_scope_guard
+{
+ BOOST_COPYABLE_AND_MOVABLE_ALT(scoped_thread_attribute)
+
+private:
+ //! A pointer to the logging core
+ core_ptr m_pCore;
+ //! An iterator to the added attribute
+ attribute_set::iterator m_itAttribute;
+
+public:
+ //! Constructor
+ scoped_thread_attribute(attribute_name const& name, attribute const& attr) :
+ m_pCore(core::get())
+ {
+ std::pair<
+ attribute_set::iterator,
+ bool
+ > res = m_pCore->add_thread_attribute(name, attr);
+ if (res.second)
+ m_itAttribute = res.first;
+ else
+ m_pCore.reset(); // if there already is a same-named attribute, don't register anything
+ }
+ //! Move constructor
+ scoped_thread_attribute(BOOST_RV_REF(scoped_thread_attribute) that) : m_itAttribute(that.m_itAttribute)
+ {
+ m_pCore.swap(that.m_pCore);
+ }
+
+ //! Destructor
+ ~scoped_thread_attribute()
+ {
+ if (!!m_pCore)
+ m_pCore->remove_thread_attribute(m_itAttribute);
+ }
+
+#ifndef BOOST_LOG_BROKEN_REFERENCE_FROM_RVALUE_INIT
+ BOOST_DELETED_FUNCTION(scoped_thread_attribute(scoped_thread_attribute const&))
+#else // BOOST_LOG_BROKEN_REFERENCE_FROM_RVALUE_INIT
+ scoped_thread_attribute(scoped_thread_attribute const& that) : m_itAttribute(that.m_itAttribute)
+ {
+ m_pCore.swap(const_cast< scoped_thread_attribute& >(that).m_pCore);
+ }
+#endif // BOOST_LOG_BROKEN_REFERENCE_FROM_RVALUE_INIT
+
+ BOOST_DELETED_FUNCTION(scoped_thread_attribute& operator= (scoped_thread_attribute const&))
+};
+
+} // namespace aux
+
+// Generator helper functions
+/*!
+ * Registers a thread-specific attribute
+ *
+ * \param name Attribute name
+ * \param attr The attribute. Must not be NULL.
+ * \return An unspecified guard object which may be used to initialize a \c scoped_attribute variable.
+ */
+BOOST_FORCEINLINE aux::scoped_thread_attribute add_scoped_thread_attribute(attribute_name const& name, attribute const& attr)
+{
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ return aux::scoped_thread_attribute(name, attr);
+#else
+ aux::scoped_thread_attribute guard(name, attr);
+ return boost::move(guard);
+#endif
+}
+
+#ifndef BOOST_LOG_DOXYGEN_PASS
+
+#define BOOST_LOG_SCOPED_THREAD_ATTR_INTERNAL(attr_name, attr, sentry_var_name)\
+ BOOST_LOG_UNUSED_VARIABLE(::boost::log::scoped_attribute, sentry_var_name,\
+ = ::boost::log::add_scoped_thread_attribute(attr_name, (attr)));
+
+#endif // BOOST_LOG_DOXYGEN_PASS
+
+//! The macro sets a scoped thread-wide attribute in a more compact way
+#define BOOST_LOG_SCOPED_THREAD_ATTR(attr_name, attr)\
+ BOOST_LOG_SCOPED_THREAD_ATTR_INTERNAL(\
+ attr_name,\
+ attr,\
+ BOOST_LOG_UNIQUE_IDENTIFIER_NAME(_boost_log_scoped_thread_attr_sentry_))
+
+//! The macro sets a scoped thread-wide tag in a more compact way
+#define BOOST_LOG_SCOPED_THREAD_TAG(attr_name, attr_value)\
+ BOOST_LOG_SCOPED_THREAD_ATTR(attr_name, ::boost::log::attributes::make_constant(attr_value))
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_ATTRIBUTES_SCOPED_ATTRIBUTE_HPP_INCLUDED_
diff --git a/boost/log/attributes/time_traits.hpp b/boost/log/attributes/time_traits.hpp
new file mode 100644
index 0000000..9a967f8
--- /dev/null
+++ b/boost/log/attributes/time_traits.hpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file time_traits.hpp
+ * \author Andrey Semashev
+ * \date 01.12.2007
+ *
+ * The header contains implementation of time traits that are used in various parts of the
+ * library to acquire current time.
+ */
+
+#ifndef BOOST_LOG_ATTRIBUTES_TIME_TRAITS_HPP_INCLUDED_
+#define BOOST_LOG_ATTRIBUTES_TIME_TRAITS_HPP_INCLUDED_
+
+#include <boost/date_time/posix_time/posix_time_types.hpp>
+#include <boost/log/detail/config.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace attributes {
+
+//! Base class for time traits involving Boost.DateTime.
+struct basic_time_traits
+{
+ //! Time type
+ typedef posix_time::ptime time_type;
+
+ //! Current time source
+#if defined(BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK)
+ typedef posix_time::microsec_clock clock_source;
+#else
+ typedef posix_time::second_clock clock_source;
+#endif // defined(BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK)
+};
+
+//! Time traits that describes UTC time acquirement via Boost.DateTime facilities
+struct utc_time_traits :
+ public basic_time_traits
+{
+ /*!
+ * \return Current time stamp
+ */
+ static time_type get_clock()
+ {
+ return clock_source::universal_time();
+ }
+};
+
+//! Time traits that describes local time acquirement via Boost.DateTime facilities
+struct local_time_traits :
+ public basic_time_traits
+{
+ /*!
+ * \return Current time stamp
+ */
+ static time_type get_clock()
+ {
+ return clock_source::local_time();
+ }
+};
+
+} // namespace attributes
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_ATTRIBUTES_TIME_TRAITS_HPP_INCLUDED_
diff --git a/boost/log/attributes/timer.hpp b/boost/log/attributes/timer.hpp
new file mode 100644
index 0000000..ae7d65e
--- /dev/null
+++ b/boost/log/attributes/timer.hpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file timer.hpp
+ * \author Andrey Semashev
+ * \date 02.12.2007
+ *
+ * The header contains implementation of a stop watch attribute.
+ */
+
+#ifndef BOOST_LOG_ATTRIBUTES_TIMER_HPP_INCLUDED_
+#define BOOST_LOG_ATTRIBUTES_TIMER_HPP_INCLUDED_
+
+#include <boost/log/detail/config.hpp>
+#include <boost/log/attributes/attribute.hpp>
+#include <boost/log/attributes/attribute_cast.hpp>
+#include <boost/log/attributes/time_traits.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace attributes {
+
+/*!
+ * \brief A class of an attribute that makes an attribute value of the time interval since construction
+ *
+ * The timer attribute calculates the time passed since its construction and returns it on value acquisition.
+ * The attribute value type is <tt>boost::posix_time::time_duration</tt>.
+ *
+ * On Windows platform there are two implementations of the attribute. The default one is more precise but
+ * a bit slower. This version uses <tt>QueryPerformanceFrequence</tt>/<tt>QueryPerformanceCounter</tt> API
+ * to calculate elapsed time.
+ *
+ * There are known problems with these functions when used with some CPUs, notably AMD Athlon with
+ * Cool'n'Quiet technology enabled. See the following links for more information and possible resolutions:
+ *
+ * http://support.microsoft.com/?scid=kb;en-us;895980
+ * http://support.microsoft.com/?id=896256
+ *
+ * In case if none of these solutions apply, you are free to define <tt>BOOST_LOG_NO_QUERY_PERFORMANCE_COUNTER</tt> macro to
+ * fall back to another implementation based on Boost.DateTime.
+ */
+class BOOST_LOG_API timer :
+ public attribute
+{
+public:
+ //! Attribute value type
+ typedef utc_time_traits::time_type::time_duration_type value_type;
+
+private:
+ //! Factory implementation
+ class BOOST_SYMBOL_VISIBLE impl;
+
+public:
+ /*!
+ * Constructor. Starts time counting.
+ */
+ timer();
+ /*!
+ * Constructor for casting support
+ */
+ explicit timer(cast_source const& source);
+};
+
+} // namespace attributes
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_ATTRIBUTES_TIMER_HPP_INCLUDED_
diff --git a/boost/log/attributes/value_extraction.hpp b/boost/log/attributes/value_extraction.hpp
new file mode 100644
index 0000000..84ee3dd
--- /dev/null
+++ b/boost/log/attributes/value_extraction.hpp
@@ -0,0 +1,816 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file value_extraction.hpp
+ * \author Andrey Semashev
+ * \date 01.03.2008
+ *
+ * The header contains implementation of tools for extracting an attribute value
+ * from the view.
+ */
+
+#ifndef BOOST_LOG_ATTRIBUTES_VALUE_EXTRACTION_HPP_INCLUDED_
+#define BOOST_LOG_ATTRIBUTES_VALUE_EXTRACTION_HPP_INCLUDED_
+
+#include <boost/mpl/vector.hpp>
+#include <boost/mpl/joint_view.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/mpl/is_sequence.hpp>
+#include <boost/mpl/contains.hpp>
+#include <boost/mpl/push_back.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/log/detail/config.hpp>
+#include <boost/log/exceptions.hpp>
+#include <boost/log/core/record.hpp>
+#include <boost/log/attributes/attribute_name.hpp>
+#include <boost/log/attributes/attribute_value.hpp>
+#include <boost/log/attributes/attribute.hpp>
+#include <boost/log/attributes/attribute_value_set.hpp>
+#include <boost/log/attributes/value_extraction_fwd.hpp>
+#include <boost/log/attributes/fallback_policy.hpp>
+#include <boost/log/expressions/keyword_fwd.hpp>
+#include <boost/log/utility/value_ref.hpp>
+#include <boost/log/utility/type_dispatch/static_type_dispatcher.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace result_of {
+
+/*!
+ * \brief A metafunction that allows to acquire the result of the value extraction
+ *
+ * The metafunction results in a type that is in form of <tt>T const&</tt>, if \c T is
+ * not an MPL type sequence and <tt>DefaultT</tt> is the same as <tt>T</tt>,
+ * or <tt>value_ref< TypesT, TagT ></tt> otherwise, with
+ * \c TypesT being a type sequence comprising the types from sequence \c T and \c DefaultT,
+ * if it is not present in \c T already.
+ */
+template< typename T, typename DefaultT, typename TagT >
+struct extract_or_default
+{
+ typedef typename mpl::eval_if<
+ mpl::is_sequence< T >,
+ mpl::eval_if<
+ mpl::contains< T, DefaultT >,
+ mpl::identity< T >,
+ mpl::push_back< T, DefaultT >
+ >,
+ mpl::if_<
+ is_same< T, DefaultT >,
+ T,
+ mpl::vector2< T, DefaultT >
+ >
+ >::type extracted_type;
+
+ typedef typename mpl::if_<
+ mpl::is_sequence< extracted_type >,
+ value_ref< extracted_type, TagT >,
+ extracted_type const&
+ >::type type;
+};
+
+/*!
+ * \brief A metafunction that allows to acquire the result of the value extraction
+ *
+ * The metafunction results in a type that is in form of <tt>T const&</tt>, if \c T is
+ * not an MPL type sequence, or <tt>value_ref< T, TagT ></tt> otherwise. In the latter
+ * case the value reference shall never be empty.
+ */
+template< typename T, typename TagT >
+struct extract_or_throw
+{
+ typedef typename mpl::if_<
+ mpl::is_sequence< T >,
+ value_ref< T, TagT >,
+ T const&
+ >::type type;
+};
+
+/*!
+ * \brief A metafunction that allows to acquire the result of the value extraction
+ *
+ * The metafunction results in a type that is in form of <tt>value_ref< T, TagT ></tt>.
+ */
+template< typename T, typename TagT >
+struct extract
+{
+ typedef value_ref< T, TagT > type;
+};
+
+} // namespace result_of
+
+namespace aux {
+
+//! The function object initializes the value reference
+template< typename RefT >
+struct value_ref_initializer
+{
+ typedef void result_type;
+
+ value_ref_initializer(RefT& ref) : m_ref(ref)
+ {
+ }
+
+ template< typename ArgT >
+ result_type operator() (ArgT const& arg) const
+ {
+ m_ref = RefT(arg);
+ }
+
+private:
+ RefT& m_ref;
+};
+
+//! The function unwraps \c value_ref, if possible
+template< typename T, typename TagT >
+BOOST_FORCEINLINE typename enable_if< mpl::is_sequence< T >, value_ref< T, TagT > >::type
+unwrap_value_ref(value_ref< T, TagT > const& r)
+{
+ return r;
+}
+
+template< typename T, typename TagT >
+BOOST_FORCEINLINE typename disable_if< mpl::is_sequence< T >, T const& >::type
+unwrap_value_ref(value_ref< T, TagT > const& r)
+{
+ return r.get();
+}
+
+} // namespace aux
+
+/*!
+ * \brief Generic attribute value extractor
+ *
+ * Attribute value extractor is a functional object that attempts to find and extract the stored
+ * attribute value from the attribute values view or a log record. The extracted value is returned
+ * from the extractor.
+ */
+template< typename T, typename FallbackPolicyT, typename TagT >
+class value_extractor :
+ private FallbackPolicyT
+{
+public:
+ //! Fallback policy
+ typedef FallbackPolicyT fallback_policy;
+ //! Attribute value types
+ typedef T value_type;
+ //! Function object result type
+ typedef value_ref< value_type, TagT > result_type;
+
+public:
+ /*!
+ * Default constructor
+ */
+ BOOST_DEFAULTED_FUNCTION(value_extractor(), {})
+
+ /*!
+ * Copy constructor
+ */
+ value_extractor(value_extractor const& that) : fallback_policy(static_cast< fallback_policy const& >(that))
+ {
+ }
+
+ /*!
+ * Constructor
+ *
+ * \param arg Fallback policy constructor argument
+ */
+ template< typename U >
+ explicit value_extractor(U const& arg) : fallback_policy(arg) {}
+
+ /*!
+ * Extraction operator. Attempts to acquire the stored value of one of the supported types. If extraction succeeds,
+ * the extracted value is returned.
+ *
+ * \param attr The attribute value to extract from.
+ * \return The extracted value, if extraction succeeded, an empty value otherwise.
+ */
+ result_type operator() (attribute_value const& attr) const
+ {
+ result_type res;
+ aux::value_ref_initializer< result_type > initializer(res);
+ if (!!attr)
+ {
+ static_type_dispatcher< value_type > disp(initializer);
+ if (!attr.dispatch(disp) && !fallback_policy::apply_default(initializer))
+ fallback_policy::on_invalid_type(attr.get_type());
+ }
+ else if (!fallback_policy::apply_default(initializer))
+ {
+ fallback_policy::on_missing_value();
+ }
+ return res;
+ }
+
+ /*!
+ * Extraction operator. Looks for an attribute value with the specified name
+ * and tries to acquire the stored value of one of the supported types. If extraction succeeds,
+ * the extracted value is returned.
+ *
+ * \param name Attribute value name.
+ * \param attrs A set of attribute values in which to look for the specified attribute value.
+ * \return The extracted value, if extraction succeeded, an empty value otherwise.
+ */
+ result_type operator() (attribute_name const& name, attribute_value_set const& attrs) const
+ {
+ try
+ {
+ attribute_value_set::const_iterator it = attrs.find(name);
+ if (it != attrs.end())
+ return operator() (it->second);
+ else
+ return operator() (attribute_value());
+ }
+ catch (exception& e)
+ {
+ // Attach the attribute name to the exception
+ boost::log::aux::attach_attribute_name_info(e, name);
+ throw;
+ }
+ }
+
+ /*!
+ * Extraction operator. Looks for an attribute value with the specified name
+ * and tries to acquire the stored value of one of the supported types. If extraction succeeds,
+ * the extracted value is returned.
+ *
+ * \param name Attribute value name.
+ * \param rec A log record. The attribute value will be sought among those associated with the record.
+ * \return The extracted value, if extraction succeeded, an empty value otherwise.
+ */
+ result_type operator() (attribute_name const& name, record const& rec) const
+ {
+ return operator() (name, rec.attribute_values());
+ }
+
+ /*!
+ * Extraction operator. Looks for an attribute value with the specified name
+ * and tries to acquire the stored value of one of the supported types. If extraction succeeds,
+ * the extracted value is returned.
+ *
+ * \param name Attribute value name.
+ * \param rec A log record view. The attribute value will be sought among those associated with the record.
+ * \return The extracted value, if extraction succeeded, an empty value otherwise.
+ */
+ result_type operator() (attribute_name const& name, record_view const& rec) const
+ {
+ return operator() (name, rec.attribute_values());
+ }
+
+ /*!
+ * \returns Fallback policy
+ */
+ fallback_policy const& get_fallback_policy() const
+ {
+ return *static_cast< fallback_policy const* >(this);
+ }
+};
+
+#if !defined(BOOST_LOG_DOXYGEN_PASS)
+#if !defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
+#define BOOST_LOG_AUX_VOID_DEFAULT = void
+#else
+#define BOOST_LOG_AUX_VOID_DEFAULT
+#endif
+#endif // !defined(BOOST_LOG_DOXYGEN_PASS)
+
+/*!
+ * The function extracts an attribute value from the view. The user has to explicitly specify the
+ * type or set of possible types of the attribute value to be extracted.
+ *
+ * \param name The name of the attribute value to extract.
+ * \param attrs A set of attribute values in which to look for the specified attribute value.
+ * \return A \c value_ref that refers to the extracted value, if found. An empty value otherwise.
+ */
+template< typename T, typename TagT BOOST_LOG_AUX_VOID_DEFAULT >
+inline typename result_of::extract< T, TagT >::type extract(attribute_name const& name, attribute_value_set const& attrs)
+{
+ value_extractor< T, fallback_to_none, TagT > extractor;
+ return extractor(name, attrs);
+}
+
+/*!
+ * The function extracts an attribute value from the view. The user has to explicitly specify the
+ * type or set of possible types of the attribute value to be extracted.
+ *
+ * \param name The name of the attribute value to extract.
+ * \param rec A log record. The attribute value will be sought among those associated with the record.
+ * \return A \c value_ref that refers to the extracted value, if found. An empty value otherwise.
+ */
+template< typename T, typename TagT BOOST_LOG_AUX_VOID_DEFAULT >
+inline typename result_of::extract< T, TagT >::type extract(attribute_name const& name, record const& rec)
+{
+ value_extractor< T, fallback_to_none, TagT > extractor;
+ return extractor(name, rec);
+}
+
+/*!
+ * The function extracts an attribute value from the view. The user has to explicitly specify the
+ * type or set of possible types of the attribute value to be extracted.
+ *
+ * \param name The name of the attribute value to extract.
+ * \param rec A log record view. The attribute value will be sought among those associated with the record.
+ * \return A \c value_ref that refers to the extracted value, if found. An empty value otherwise.
+ */
+template< typename T, typename TagT BOOST_LOG_AUX_VOID_DEFAULT >
+inline typename result_of::extract< T, TagT >::type extract(attribute_name const& name, record_view const& rec)
+{
+ value_extractor< T, fallback_to_none, TagT > extractor;
+ return extractor(name, rec);
+}
+
+/*!
+ * The function extracts an attribute value from the view. The user has to explicitly specify the
+ * type or set of possible types of the attribute value to be extracted.
+ *
+ * \param value Attribute value.
+ * \return A \c value_ref that refers to the extracted value, if found. An empty value otherwise.
+ */
+template< typename T, typename TagT BOOST_LOG_AUX_VOID_DEFAULT >
+inline typename result_of::extract< T, TagT >::type extract(attribute_value const& value)
+{
+ value_extractor< T, fallback_to_none, TagT > extractor;
+ return extractor(value);
+}
+
+/*!
+ * The function extracts an attribute value from the view. The user has to explicitly specify the
+ * type or set of possible types of the attribute value to be extracted.
+ *
+ * \param name The name of the attribute value to extract.
+ * \param attrs A set of attribute values in which to look for the specified attribute value.
+ * \return The extracted value or a non-empty \c value_ref that refers to the value.
+ * \throws An exception is thrown if the requested value cannot be extracted.
+ */
+template< typename T, typename TagT BOOST_LOG_AUX_VOID_DEFAULT >
+inline typename result_of::extract_or_throw< T, TagT >::type extract_or_throw(attribute_name const& name, attribute_value_set const& attrs)
+{
+ value_extractor< T, fallback_to_throw, TagT > extractor;
+ return aux::unwrap_value_ref(extractor(name, attrs));
+}
+
+/*!
+ * The function extracts an attribute value from the view. The user has to explicitly specify the
+ * type or set of possible types of the attribute value to be extracted.
+ *
+ * \param name The name of the attribute value to extract.
+ * \param rec A log record. The attribute value will be sought among those associated with the record.
+ * \return The extracted value or a non-empty \c value_ref that refers to the value.
+ * \throws An exception is thrown if the requested value cannot be extracted.
+ */
+template< typename T, typename TagT BOOST_LOG_AUX_VOID_DEFAULT >
+inline typename result_of::extract_or_throw< T, TagT >::type extract_or_throw(attribute_name const& name, record const& rec)
+{
+ value_extractor< T, fallback_to_throw, TagT > extractor;
+ return aux::unwrap_value_ref(extractor(name, rec));
+}
+
+/*!
+ * The function extracts an attribute value from the view. The user has to explicitly specify the
+ * type or set of possible types of the attribute value to be extracted.
+ *
+ * \param name The name of the attribute value to extract.
+ * \param rec A log record view. The attribute value will be sought among those associated with the record.
+ * \return The extracted value or a non-empty \c value_ref that refers to the value.
+ * \throws An exception is thrown if the requested value cannot be extracted.
+ */
+template< typename T, typename TagT BOOST_LOG_AUX_VOID_DEFAULT >
+inline typename result_of::extract_or_throw< T, TagT >::type extract_or_throw(attribute_name const& name, record_view const& rec)
+{
+ value_extractor< T, fallback_to_throw, TagT > extractor;
+ return aux::unwrap_value_ref(extractor(name, rec));
+}
+
+/*!
+ * The function extracts an attribute value from the view. The user has to explicitly specify the
+ * type or set of possible types of the attribute value to be extracted.
+ *
+ * \param value Attribute value.
+ * \return The extracted value or a non-empty \c value_ref that refers to the value.
+ * \throws An exception is thrown if the requested value cannot be extracted.
+ */
+template< typename T, typename TagT BOOST_LOG_AUX_VOID_DEFAULT >
+inline typename result_of::extract_or_throw< T, TagT >::type extract_or_throw(attribute_value const& value)
+{
+ value_extractor< T, fallback_to_throw, TagT > extractor;
+ return aux::unwrap_value_ref(extractor(value));
+}
+
+/*!
+ * The function extracts an attribute value from the view. The user has to explicitly specify the
+ * type or set of possible types of the attribute value to be extracted.
+ *
+ * \note Caution must be exercised if the default value is a temporary object. Because the function returns
+ * a reference, if the temporary object is destroyed, the reference may become dangling.
+ *
+ * \param name The name of the attribute value to extract.
+ * \param attrs A set of attribute values in which to look for the specified attribute value.
+ * \param def_val The default value
+ * \return The extracted value, if found. The default value otherwise.
+ */
+template< typename T, typename TagT BOOST_LOG_AUX_VOID_DEFAULT, typename DefaultT >
+inline typename result_of::extract_or_default< T, DefaultT, TagT >::type
+extract_or_default(attribute_name const& name, attribute_value_set const& attrs, DefaultT const& def_val)
+{
+ typedef typename result_of::extract_or_default< T, DefaultT, TagT >::extracted_type extracted_type;
+ value_extractor< extracted_type, fallback_to_default< DefaultT const& >, TagT > extractor(def_val);
+ return aux::unwrap_value_ref(extractor(name, attrs));
+}
+
+/*!
+ * The function extracts an attribute value from the view. The user has to explicitly specify the
+ * type or set of possible types of the attribute value to be visited.
+ *
+ * \note Caution must be exercised if the default value is a temporary object. Because the function returns
+ * a reference, if the temporary object is destroyed, the reference may become dangling.
+ *
+ * \param name The name of the attribute value to extract.
+ * \param rec A log record. The attribute value will be sought among those associated with the record.
+ * \param def_val The default value
+ * \return The extracted value, if found. The default value otherwise.
+ */
+template< typename T, typename TagT BOOST_LOG_AUX_VOID_DEFAULT, typename DefaultT >
+inline typename result_of::extract_or_default< T, DefaultT, TagT >::type
+extract_or_default(attribute_name const& name, record const& rec, DefaultT const& def_val)
+{
+ typedef typename result_of::extract_or_default< T, DefaultT, TagT >::extracted_type extracted_type;
+ value_extractor< extracted_type, fallback_to_default< DefaultT const& >, TagT > extractor(def_val);
+ return aux::unwrap_value_ref(extractor(name, rec));
+}
+
+/*!
+ * The function extracts an attribute value from the view. The user has to explicitly specify the
+ * type or set of possible types of the attribute value to be visited.
+ *
+ * \note Caution must be exercised if the default value is a temporary object. Because the function returns
+ * a reference, if the temporary object is destroyed, the reference may become dangling.
+ *
+ * \param name The name of the attribute value to extract.
+ * \param rec A log record view. The attribute value will be sought among those associated with the record.
+ * \param def_val The default value
+ * \return The extracted value, if found. The default value otherwise.
+ */
+template< typename T, typename TagT BOOST_LOG_AUX_VOID_DEFAULT, typename DefaultT >
+inline typename result_of::extract_or_default< T, DefaultT, TagT >::type
+extract_or_default(attribute_name const& name, record_view const& rec, DefaultT const& def_val)
+{
+ typedef typename result_of::extract_or_default< T, DefaultT, TagT >::extracted_type extracted_type;
+ value_extractor< extracted_type, fallback_to_default< DefaultT const& >, TagT > extractor(def_val);
+ return aux::unwrap_value_ref(extractor(name, rec));
+}
+
+/*!
+ * The function extracts an attribute value from the view. The user has to explicitly specify the
+ * type or set of possible types of the attribute value to be visited.
+ *
+ * \note Caution must be exercised if the default value is a temporary object. Because the function returns
+ * a reference, if the temporary object is destroyed, the reference may become dangling.
+ *
+ * \param value Attribute value.
+ * \param def_val The default value
+ * \return The extracted value, if found. The default value otherwise.
+ */
+template< typename T, typename TagT BOOST_LOG_AUX_VOID_DEFAULT, typename DefaultT >
+inline typename result_of::extract_or_default< T, DefaultT, TagT >::type extract_or_default(attribute_value const& value, DefaultT const& def_val)
+{
+ typedef typename result_of::extract_or_default< T, DefaultT, TagT >::extracted_type extracted_type;
+ value_extractor< extracted_type, fallback_to_default< DefaultT const& >, TagT > extractor(def_val);
+ return aux::unwrap_value_ref(extractor(value));
+}
+
+#if defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
+
+template< typename T >
+inline typename result_of::extract< T >::type extract(attribute_name const& name, attribute_value_set const& attrs)
+{
+ value_extractor< T, fallback_to_none > extractor;
+ return extractor(name, attrs);
+}
+
+template< typename T >
+inline typename result_of::extract< T >::type extract(attribute_name const& name, record const& rec)
+{
+ value_extractor< T, fallback_to_none > extractor;
+ return extractor(name, rec);
+}
+
+template< typename T >
+inline typename result_of::extract< T >::type extract(attribute_name const& name, record_view const& rec)
+{
+ value_extractor< T, fallback_to_none > extractor;
+ return extractor(name, rec);
+}
+
+template< typename T >
+inline typename result_of::extract< T >::type extract(attribute_value const& value)
+{
+ value_extractor< T, fallback_to_none > extractor;
+ return extractor(value);
+}
+
+template< typename T >
+inline typename result_of::extract_or_throw< T >::type extract_or_throw(attribute_name const& name, attribute_value_set const& attrs)
+{
+ value_extractor< T, fallback_to_throw > extractor;
+ return aux::unwrap_value_ref(extractor(name, attrs));
+}
+
+template< typename T >
+inline typename result_of::extract_or_throw< T >::type extract_or_throw(attribute_name const& name, record const& rec)
+{
+ value_extractor< T, fallback_to_throw > extractor;
+ return aux::unwrap_value_ref(extractor(name, rec));
+}
+
+template< typename T >
+inline typename result_of::extract_or_throw< T >::type extract_or_throw(attribute_name const& name, record_view const& rec)
+{
+ value_extractor< T, fallback_to_throw > extractor;
+ return aux::unwrap_value_ref(extractor(name, rec));
+}
+
+template< typename T >
+inline typename result_of::extract_or_throw< T >::type extract_or_throw(attribute_value const& value)
+{
+ value_extractor< T, fallback_to_throw > extractor;
+ return aux::unwrap_value_ref(extractor(value));
+}
+
+template< typename T, typename DefaultT >
+inline typename result_of::extract_or_default< T, DefaultT >::type extract_or_default(
+ attribute_name const& name, attribute_value_set const& attrs, DefaultT const& def_val)
+{
+ typedef typename result_of::extract_or_default< T, DefaultT >::extracted_type extracted_type;
+ value_extractor< extracted_type, fallback_to_default< DefaultT const& > > extractor(def_val);
+ return aux::unwrap_value_ref(extractor(name, attrs));
+}
+
+template< typename T, typename DefaultT >
+inline typename result_of::extract_or_default< T, DefaultT >::type extract_or_default(
+ attribute_name const& name, record const& rec, DefaultT const& def_val)
+{
+ typedef typename result_of::extract_or_default< T, DefaultT >::extracted_type extracted_type;
+ value_extractor< extracted_type, fallback_to_default< DefaultT const& > > extractor(def_val);
+ return aux::unwrap_value_ref(extractor(name, rec));
+}
+
+template< typename T, typename DefaultT >
+inline typename result_of::extract_or_default< T, DefaultT >::type extract_or_default(
+ attribute_name const& name, record_view const& rec, DefaultT const& def_val)
+{
+ typedef typename result_of::extract_or_default< T, DefaultT >::extracted_type extracted_type;
+ value_extractor< extracted_type, fallback_to_default< DefaultT const& > > extractor(def_val);
+ return aux::unwrap_value_ref(extractor(name, rec));
+}
+
+template< typename T, typename DefaultT >
+inline typename result_of::extract_or_default< T, DefaultT >::type extract_or_default(attribute_value const& value, DefaultT const& def_val)
+{
+ typedef typename result_of::extract_or_default< T, DefaultT >::extracted_type extracted_type;
+ value_extractor< extracted_type, fallback_to_default< DefaultT const& > > extractor(def_val);
+ return aux::unwrap_value_ref(extractor(value));
+}
+
+#endif // defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
+
+/*!
+ * The function extracts an attribute value from the view. The user has to explicitly specify the
+ * type or set of possible types of the attribute value to be extracted.
+ *
+ * \param keyword The keyword of the attribute value to extract.
+ * \param attrs A set of attribute values in which to look for the specified attribute value.
+ * \return A \c value_ref that refers to the extracted value, if found. An empty value otherwise.
+ */
+template< typename DescriptorT, template< typename > class ActorT >
+inline typename result_of::extract< typename DescriptorT::value_type, DescriptorT >::type
+extract(expressions::attribute_keyword< DescriptorT, ActorT > const& keyword, attribute_value_set const& attrs)
+{
+ value_extractor< typename DescriptorT::value_type, fallback_to_none, DescriptorT > extractor;
+ return extractor(keyword.get_name(), attrs);
+}
+
+/*!
+ * The function extracts an attribute value from the view. The user has to explicitly specify the
+ * type or set of possible types of the attribute value to be extracted.
+ *
+ * \param keyword The keyword of the attribute value to extract.
+ * \param rec A log record. The attribute value will be sought among those associated with the record.
+ * \return A \c value_ref that refers to the extracted value, if found. An empty value otherwise.
+ */
+template< typename DescriptorT, template< typename > class ActorT >
+inline typename result_of::extract< typename DescriptorT::value_type, DescriptorT >::type
+extract(expressions::attribute_keyword< DescriptorT, ActorT > const& keyword, record const& rec)
+{
+ value_extractor< typename DescriptorT::value_type, fallback_to_none, DescriptorT > extractor;
+ return extractor(keyword.get_name(), rec);
+}
+
+/*!
+ * The function extracts an attribute value from the view. The user has to explicitly specify the
+ * type or set of possible types of the attribute value to be extracted.
+ *
+ * \param keyword The keyword of the attribute value to extract.
+ * \param rec A log record view. The attribute value will be sought among those associated with the record.
+ * \return A \c value_ref that refers to the extracted value, if found. An empty value otherwise.
+ */
+template< typename DescriptorT, template< typename > class ActorT >
+inline typename result_of::extract< typename DescriptorT::value_type, DescriptorT >::type
+extract(expressions::attribute_keyword< DescriptorT, ActorT > const& keyword, record_view const& rec)
+{
+ value_extractor< typename DescriptorT::value_type, fallback_to_none, DescriptorT > extractor;
+ return extractor(keyword.get_name(), rec);
+}
+
+/*!
+ * The function extracts an attribute value from the view. The user has to explicitly specify the
+ * type or set of possible types of the attribute value to be extracted.
+ *
+ * \param keyword The keyword of the attribute value to extract.
+ * \param attrs A set of attribute values in which to look for the specified attribute value.
+ * \return The extracted value or a non-empty \c value_ref that refers to the value.
+ * \throws An exception is thrown if the requested value cannot be extracted.
+ */
+template< typename DescriptorT, template< typename > class ActorT >
+inline typename result_of::extract_or_throw< typename DescriptorT::value_type, DescriptorT >::type
+extract_or_throw(expressions::attribute_keyword< DescriptorT, ActorT > const& keyword, attribute_value_set const& attrs)
+{
+ value_extractor< typename DescriptorT::value_type, fallback_to_throw, DescriptorT > extractor;
+ return aux::unwrap_value_ref(extractor(keyword.get_name(), attrs));
+}
+
+/*!
+ * The function extracts an attribute value from the view. The user has to explicitly specify the
+ * type or set of possible types of the attribute value to be extracted.
+ *
+ * \param keyword The keyword of the attribute value to extract.
+ * \param rec A log record. The attribute value will be sought among those associated with the record.
+ * \return The extracted value or a non-empty \c value_ref that refers to the value.
+ * \throws An exception is thrown if the requested value cannot be extracted.
+ */
+template< typename DescriptorT, template< typename > class ActorT >
+inline typename result_of::extract_or_throw< typename DescriptorT::value_type, DescriptorT >::type
+extract_or_throw(expressions::attribute_keyword< DescriptorT, ActorT > const& keyword, record const& rec)
+{
+ value_extractor< typename DescriptorT::value_type, fallback_to_throw, DescriptorT > extractor;
+ return aux::unwrap_value_ref(extractor(keyword.get_name(), rec));
+}
+
+/*!
+ * The function extracts an attribute value from the view. The user has to explicitly specify the
+ * type or set of possible types of the attribute value to be extracted.
+ *
+ * \param keyword The keyword of the attribute value to extract.
+ * \param rec A log record view. The attribute value will be sought among those associated with the record.
+ * \return The extracted value or a non-empty \c value_ref that refers to the value.
+ * \throws An exception is thrown if the requested value cannot be extracted.
+ */
+template< typename DescriptorT, template< typename > class ActorT >
+inline typename result_of::extract_or_throw< typename DescriptorT::value_type, DescriptorT >::type
+extract_or_throw(expressions::attribute_keyword< DescriptorT, ActorT > const& keyword, record_view const& rec)
+{
+ value_extractor< typename DescriptorT::value_type, fallback_to_throw, DescriptorT > extractor;
+ return aux::unwrap_value_ref(extractor(keyword.get_name(), rec));
+}
+
+/*!
+ * The function extracts an attribute value from the view. The user has to explicitly specify the
+ * type or set of possible types of the attribute value to be extracted.
+ *
+ * \note Caution must be exercised if the default value is a temporary object. Because the function returns
+ * a reference, if the temporary object is destroyed, the reference may become dangling.
+ *
+ * \param keyword The keyword of the attribute value to extract.
+ * \param attrs A set of attribute values in which to look for the specified attribute value.
+ * \param def_val The default value
+ * \return The extracted value, if found. The default value otherwise.
+ */
+template< typename DescriptorT, template< typename > class ActorT, typename DefaultT >
+inline typename result_of::extract_or_default< typename DescriptorT::value_type, DefaultT, DescriptorT >::type
+extract_or_default(expressions::attribute_keyword< DescriptorT, ActorT > const& keyword, attribute_value_set const& attrs, DefaultT const& def_val)
+{
+ typedef typename result_of::extract_or_default< typename DescriptorT::value_type, DefaultT, DescriptorT >::extracted_type extracted_type;
+ value_extractor< extracted_type, fallback_to_default< DefaultT const& >, DescriptorT > extractor(def_val);
+ return aux::unwrap_value_ref(extractor(keyword.get_name(), attrs));
+}
+
+/*!
+ * The function extracts an attribute value from the view. The user has to explicitly specify the
+ * type or set of possible types of the attribute value to be visited.
+ *
+ * \note Caution must be exercised if the default value is a temporary object. Because the function returns
+ * a reference, if the temporary object is destroyed, the reference may become dangling.
+ *
+ * \param keyword The keyword of the attribute value to extract.
+ * \param rec A log record. The attribute value will be sought among those associated with the record.
+ * \param def_val The default value
+ * \return The extracted value, if found. The default value otherwise.
+ */
+template< typename DescriptorT, template< typename > class ActorT, typename DefaultT >
+inline typename result_of::extract_or_default< typename DescriptorT::value_type, DefaultT, DescriptorT >::type
+extract_or_default(expressions::attribute_keyword< DescriptorT, ActorT > const& keyword, record const& rec, DefaultT const& def_val)
+{
+ typedef typename result_of::extract_or_default< typename DescriptorT::value_type, DefaultT, DescriptorT >::extracted_type extracted_type;
+ value_extractor< extracted_type, fallback_to_default< DefaultT const& >, DescriptorT > extractor(def_val);
+ return aux::unwrap_value_ref(extractor(keyword.get_name(), rec));
+}
+
+/*!
+ * The function extracts an attribute value from the view. The user has to explicitly specify the
+ * type or set of possible types of the attribute value to be visited.
+ *
+ * \note Caution must be exercised if the default value is a temporary object. Because the function returns
+ * a reference, if the temporary object is destroyed, the reference may become dangling.
+ *
+ * \param keyword The keyword of the attribute value to extract.
+ * \param rec A log record view. The attribute value will be sought among those associated with the record.
+ * \param def_val The default value
+ * \return The extracted value, if found. The default value otherwise.
+ */
+template< typename DescriptorT, template< typename > class ActorT, typename DefaultT >
+inline typename result_of::extract_or_default< typename DescriptorT::value_type, DefaultT, DescriptorT >::type
+extract_or_default(expressions::attribute_keyword< DescriptorT, ActorT > const& keyword, record_view const& rec, DefaultT const& def_val)
+{
+ typedef typename result_of::extract_or_default< typename DescriptorT::value_type, DefaultT, DescriptorT >::extracted_type extracted_type;
+ value_extractor< extracted_type, fallback_to_default< DefaultT const& >, DescriptorT > extractor(def_val);
+ return aux::unwrap_value_ref(extractor(keyword.get_name(), rec));
+}
+
+#if !defined(BOOST_LOG_DOXYGEN_PASS)
+
+template< typename T, typename TagT >
+inline typename result_of::extract< T, TagT >::type attribute_value::extract() const
+{
+ return boost::log::extract< T, TagT >(*this);
+}
+
+template< typename T, typename TagT >
+inline typename result_of::extract_or_throw< T, TagT >::type attribute_value::extract_or_throw() const
+{
+ return boost::log::extract_or_throw< T, TagT >(*this);
+}
+
+template< typename T, typename TagT >
+inline typename result_of::extract_or_default< T, T, TagT >::type attribute_value::extract_or_default(T const& def_value) const
+{
+ return boost::log::extract_or_default< T, TagT >(*this, def_value);
+}
+
+template< typename T, typename TagT, typename DefaultT >
+inline typename result_of::extract_or_default< T, DefaultT, TagT >::type attribute_value::extract_or_default(DefaultT const& def_value) const
+{
+ return boost::log::extract_or_default< T, TagT >(*this, def_value);
+}
+
+#if defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
+
+template< typename T >
+inline typename result_of::extract< T >::type attribute_value::extract() const
+{
+ return boost::log::extract< T >(*this);
+}
+
+template< typename T >
+inline typename result_of::extract_or_throw< T >::type attribute_value::extract_or_throw() const
+{
+ return boost::log::extract_or_throw< T >(*this);
+}
+
+template< typename T >
+inline typename result_of::extract_or_default< T, T >::type attribute_value::extract_or_default(T const& def_value) const
+{
+ return boost::log::extract_or_default< T >(*this, def_value);
+}
+
+template< typename T, typename DefaultT >
+inline typename result_of::extract_or_default< T, DefaultT >::type attribute_value::extract_or_default(DefaultT const& def_value) const
+{
+ return boost::log::extract_or_default< T >(*this, def_value);
+}
+
+#endif // defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
+
+#endif // !defined(BOOST_LOG_DOXYGEN_PASS)
+
+#undef BOOST_LOG_AUX_VOID_DEFAULT
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_ATTRIBUTES_VALUE_EXTRACTION_HPP_INCLUDED_
diff --git a/boost/log/attributes/value_extraction_fwd.hpp b/boost/log/attributes/value_extraction_fwd.hpp
new file mode 100644
index 0000000..2cc5583
--- /dev/null
+++ b/boost/log/attributes/value_extraction_fwd.hpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file value_extraction_fwd.hpp
+ * \author Andrey Semashev
+ * \date 01.03.2008
+ *
+ * The header contains forward declaration of tools for extracting attribute values
+ * from the view.
+ */
+
+#ifndef BOOST_LOG_ATTRIBUTES_VALUE_EXTRACTION_FWD_HPP_INCLUDED_
+#define BOOST_LOG_ATTRIBUTES_VALUE_EXTRACTION_FWD_HPP_INCLUDED_
+
+#include <boost/log/detail/config.hpp>
+#include <boost/log/attributes/fallback_policy_fwd.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace result_of {
+
+/*!
+ * \brief A metafunction that allows to acquire the result of the value extraction
+ */
+template< typename T, typename DefaultT = T, typename TagT = void >
+struct extract_or_default;
+
+/*!
+ * \brief A metafunction that allows to acquire the result of the value extraction
+ */
+template< typename T, typename TagT = void >
+struct extract_or_throw;
+
+/*!
+ * \brief A metafunction that allows to acquire the result of the value extraction
+ */
+template< typename T, typename TagT = void >
+struct extract;
+
+} // namespace result_of
+
+/*!
+ * \brief Generic attribute value extractor
+ */
+template< typename T, typename FallbackPolicyT = fallback_to_none, typename TagT = void >
+class value_extractor;
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#endif // BOOST_LOG_ATTRIBUTES_VALUE_EXTRACTION_FWD_HPP_INCLUDED_
diff --git a/boost/log/attributes/value_visitation.hpp b/boost/log/attributes/value_visitation.hpp
new file mode 100644
index 0000000..6a8205f
--- /dev/null
+++ b/boost/log/attributes/value_visitation.hpp
@@ -0,0 +1,372 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file value_visitation.hpp
+ * \author Andrey Semashev
+ * \date 01.03.2008
+ *
+ * The header contains implementation of convenience tools to apply visitors to an attribute value
+ * in the view.
+ */
+
+#ifndef BOOST_LOG_ATTRIBUTES_VALUE_VISITATION_HPP_INCLUDED_
+#define BOOST_LOG_ATTRIBUTES_VALUE_VISITATION_HPP_INCLUDED_
+
+#include <boost/log/detail/config.hpp>
+#include <boost/log/exceptions.hpp>
+#include <boost/log/core/record.hpp>
+#include <boost/log/attributes/attribute_name.hpp>
+#include <boost/log/attributes/attribute_value.hpp>
+#include <boost/log/attributes/attribute.hpp>
+#include <boost/log/attributes/attribute_value_set.hpp>
+#include <boost/log/attributes/value_visitation_fwd.hpp>
+#include <boost/log/attributes/fallback_policy.hpp>
+#include <boost/log/expressions/keyword_fwd.hpp>
+#include <boost/utility/explicit_operator_bool.hpp>
+#include <boost/log/utility/type_dispatch/static_type_dispatcher.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+/*!
+ * \brief The class represents attribute value visitation result
+ *
+ * The main purpose of this class is to provide a convenient interface for checking
+ * whether the attribute value visitation succeeded or not. It also allows to discover
+ * the actual cause of failure, should the operation fail.
+ */
+class visitation_result
+{
+public:
+ //! Error codes for attribute value visitation
+ enum error_code
+ {
+ ok, //!< The attribute value has been visited successfully
+ value_not_found, //!< The attribute value is not present in the view
+ value_has_invalid_type //!< The attribute value is present in the view, but has an unexpected type
+ };
+
+private:
+ error_code m_code;
+
+public:
+ /*!
+ * Initializing constructor. Creates the result that is equivalent to the
+ * specified error code.
+ */
+ BOOST_CONSTEXPR visitation_result(error_code code = ok) BOOST_NOEXCEPT : m_code(code) {}
+
+ /*!
+ * Checks if the visitation was successful.
+ *
+ * \return \c true if the value was visited successfully, \c false otherwise.
+ */
+ BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
+ /*!
+ * Checks if the visitation was unsuccessful.
+ *
+ * \return \c false if the value was visited successfully, \c true otherwise.
+ */
+ bool operator! () const BOOST_NOEXCEPT { return (m_code != ok); }
+
+ /*!
+ * \return The actual result code of value visitation
+ */
+ error_code code() const BOOST_NOEXCEPT { return m_code; }
+};
+
+/*!
+ * \brief Generic attribute value visitor invoker
+ *
+ * Attribute value invoker is a functional object that attempts to find and extract the stored
+ * attribute value from the attribute value view or a log record. The extracted value is passed to
+ * a unary function object (the visitor) provided by user.
+ *
+ * The invoker can be specialized on one or several attribute value types that should be
+ * specified in the second template argument.
+ */
+template< typename T, typename FallbackPolicyT >
+class value_visitor_invoker :
+ private FallbackPolicyT
+{
+ typedef value_visitor_invoker< T, FallbackPolicyT > this_type;
+
+public:
+ //! Attribute value types
+ typedef T value_type;
+
+ //! Fallback policy
+ typedef FallbackPolicyT fallback_policy;
+
+ //! Function object result type
+ typedef visitation_result result_type;
+
+public:
+ /*!
+ * Default constructor
+ */
+ BOOST_DEFAULTED_FUNCTION(value_visitor_invoker(), {})
+
+ /*!
+ * Copy constructor
+ */
+ value_visitor_invoker(value_visitor_invoker const& that) : fallback_policy(static_cast< fallback_policy const& >(that))
+ {
+ }
+
+ /*!
+ * Initializing constructor
+ *
+ * \param arg Fallback policy argument
+ */
+ template< typename U >
+ explicit value_visitor_invoker(U const& arg) : fallback_policy(arg) {}
+
+ /*!
+ * Visitation operator. Attempts to acquire the stored value of one of the supported types. If acquisition succeeds,
+ * the value is passed to \a visitor.
+ *
+ * \param attr An attribute value to apply the visitor to.
+ * \param visitor A receiving function object to pass the attribute value to.
+ * \return The result of visitation.
+ */
+ template< typename VisitorT >
+ result_type operator() (attribute_value const& attr, VisitorT visitor) const
+ {
+ if (!!attr)
+ {
+ static_type_dispatcher< value_type > disp(visitor);
+ if (attr.dispatch(disp) || fallback_policy::apply_default(visitor))
+ {
+ return visitation_result::ok;
+ }
+ else
+ {
+ fallback_policy::on_invalid_type(attr.get_type());
+ return visitation_result::value_has_invalid_type;
+ }
+ }
+
+ if (fallback_policy::apply_default(visitor))
+ return visitation_result::ok;
+
+ fallback_policy::on_missing_value();
+ return visitation_result::value_not_found;
+ }
+
+ /*!
+ * Visitation operator. Looks for an attribute value with the specified name
+ * and tries to acquire the stored value of one of the supported types. If acquisition succeeds,
+ * the value is passed to \a visitor.
+ *
+ * \param name Attribute value name.
+ * \param attrs A set of attribute values in which to look for the specified attribute value.
+ * \param visitor A receiving function object to pass the attribute value to.
+ * \return The result of visitation.
+ */
+ template< typename VisitorT >
+ result_type operator() (attribute_name const& name, attribute_value_set const& attrs, VisitorT visitor) const
+ {
+ try
+ {
+ attribute_value_set::const_iterator it = attrs.find(name);
+ if (it != attrs.end())
+ return operator() (it->second, visitor);
+ else
+ return operator() (attribute_value(), visitor);
+ }
+ catch (exception& e)
+ {
+ // Attach the attribute name to the exception
+ boost::log::aux::attach_attribute_name_info(e, name);
+ throw;
+ }
+ }
+
+ /*!
+ * Visitation operator. Looks for an attribute value with the specified name
+ * and tries to acquire the stored value of one of the supported types. If acquisition succeeds,
+ * the value is passed to \a visitor.
+ *
+ * \param name Attribute value name.
+ * \param rec A log record. The attribute value will be sought among those associated with the record.
+ * \param visitor A receiving function object to pass the attribute value to.
+ * \return The result of visitation.
+ */
+ template< typename VisitorT >
+ result_type operator() (attribute_name const& name, record const& rec, VisitorT visitor) const
+ {
+ return operator() (name, rec.attribute_values(), visitor);
+ }
+
+ /*!
+ * Visitation operator. Looks for an attribute value with the specified name
+ * and tries to acquire the stored value of one of the supported types. If acquisition succeeds,
+ * the value is passed to \a visitor.
+ *
+ * \param name Attribute value name.
+ * \param rec A log record view. The attribute value will be sought among those associated with the record.
+ * \param visitor A receiving function object to pass the attribute value to.
+ * \return The result of visitation.
+ */
+ template< typename VisitorT >
+ result_type operator() (attribute_name const& name, record_view const& rec, VisitorT visitor) const
+ {
+ return operator() (name, rec.attribute_values(), visitor);
+ }
+
+ /*!
+ * \returns Fallback policy
+ */
+ fallback_policy const& get_fallback_policy() const
+ {
+ return *static_cast< fallback_policy const* >(this);
+ }
+};
+
+/*!
+ * The function applies a visitor to an attribute value from the view. The user has to explicitly specify the
+ * type or set of possible types of the attribute value to be visited.
+ *
+ * \param name The name of the attribute value to visit.
+ * \param attrs A set of attribute values in which to look for the specified attribute value.
+ * \param visitor A receiving function object to pass the attribute value to.
+ * \return The result of visitation.
+ */
+template< typename T, typename VisitorT >
+inline visitation_result
+visit(attribute_name const& name, attribute_value_set const& attrs, VisitorT visitor)
+{
+ value_visitor_invoker< T > invoker;
+ return invoker(name, attrs, visitor);
+}
+
+/*!
+ * The function applies a visitor to an attribute value from the view. The user has to explicitly specify the
+ * type or set of possible types of the attribute value to be visited.
+ *
+ * \param name The name of the attribute value to visit.
+ * \param rec A log record. The attribute value will be sought among those associated with the record.
+ * \param visitor A receiving function object to pass the attribute value to.
+ * \return The result of visitation.
+ */
+template< typename T, typename VisitorT >
+inline visitation_result
+visit(attribute_name const& name, record const& rec, VisitorT visitor)
+{
+ value_visitor_invoker< T > invoker;
+ return invoker(name, rec, visitor);
+}
+
+/*!
+ * The function applies a visitor to an attribute value from the view. The user has to explicitly specify the
+ * type or set of possible types of the attribute value to be visited.
+ *
+ * \param name The name of the attribute value to visit.
+ * \param rec A log record view. The attribute value will be sought among those associated with the record.
+ * \param visitor A receiving function object to pass the attribute value to.
+ * \return The result of visitation.
+ */
+template< typename T, typename VisitorT >
+inline visitation_result
+visit(attribute_name const& name, record_view const& rec, VisitorT visitor)
+{
+ value_visitor_invoker< T > invoker;
+ return invoker(name, rec, visitor);
+}
+
+/*!
+ * The function applies a visitor to an attribute value. The user has to explicitly specify the
+ * type or set of possible types of the attribute value to be visited.
+ *
+ * \param value The attribute value to visit.
+ * \param visitor A receiving function object to pass the attribute value to.
+ * \return The result of visitation.
+ */
+template< typename T, typename VisitorT >
+inline visitation_result
+visit(attribute_value const& value, VisitorT visitor)
+{
+ value_visitor_invoker< T > invoker;
+ return invoker(value, visitor);
+}
+
+/*!
+ * The function applies a visitor to an attribute value from the view. The user has to explicitly specify the
+ * type or set of possible types of the attribute value to be visited.
+ *
+ * \param keyword The keyword of the attribute value to visit.
+ * \param attrs A set of attribute values in which to look for the specified attribute value.
+ * \param visitor A receiving function object to pass the attribute value to.
+ * \return The result of visitation.
+ */
+template< typename DescriptorT, template< typename > class ActorT, typename VisitorT >
+inline visitation_result
+visit(expressions::attribute_keyword< DescriptorT, ActorT > const& keyword, attribute_value_set const& attrs, VisitorT visitor)
+{
+ value_visitor_invoker< typename DescriptorT::value_type > invoker;
+ return invoker(keyword.get_name(), attrs, visitor);
+}
+
+/*!
+ * The function applies a visitor to an attribute value from the view. The user has to explicitly specify the
+ * type or set of possible types of the attribute value to be visited.
+ *
+ * \param keyword The keyword of the attribute value to visit.
+ * \param rec A log record. The attribute value will be sought among those associated with the record.
+ * \param visitor A receiving function object to pass the attribute value to.
+ * \return The result of visitation.
+ */
+template< typename DescriptorT, template< typename > class ActorT, typename VisitorT >
+inline visitation_result
+visit(expressions::attribute_keyword< DescriptorT, ActorT > const& keyword, record const& rec, VisitorT visitor)
+{
+ value_visitor_invoker< typename DescriptorT::value_type > invoker;
+ return invoker(keyword.get_name(), rec, visitor);
+}
+
+/*!
+ * The function applies a visitor to an attribute value from the view. The user has to explicitly specify the
+ * type or set of possible types of the attribute value to be visited.
+ *
+ * \param keyword The keyword of the attribute value to visit.
+ * \param rec A log record view. The attribute value will be sought among those associated with the record.
+ * \param visitor A receiving function object to pass the attribute value to.
+ * \return The result of visitation.
+ */
+template< typename DescriptorT, template< typename > class ActorT, typename VisitorT >
+inline visitation_result
+visit(expressions::attribute_keyword< DescriptorT, ActorT > const& keyword, record_view const& rec, VisitorT visitor)
+{
+ value_visitor_invoker< typename DescriptorT::value_type > invoker;
+ return invoker(keyword.get_name(), rec, visitor);
+}
+
+
+#if !defined(BOOST_LOG_DOXYGEN_PASS)
+
+template< typename T, typename VisitorT >
+inline visitation_result attribute_value::visit(VisitorT visitor) const
+{
+ return boost::log::visit< T >(*this, visitor);
+}
+
+#endif // !defined(BOOST_LOG_DOXYGEN_PASS)
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_ATTRIBUTES_VALUE_VISITATION_HPP_INCLUDED_
diff --git a/boost/log/attributes/value_visitation_fwd.hpp b/boost/log/attributes/value_visitation_fwd.hpp
new file mode 100644
index 0000000..5917c22
--- /dev/null
+++ b/boost/log/attributes/value_visitation_fwd.hpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file value_visitation_fwd.hpp
+ * \author Andrey Semashev
+ * \date 01.03.2008
+ *
+ * The header contains forward declaration of convenience tools to apply visitors to an attribute value
+ * in the view.
+ */
+
+#ifndef BOOST_LOG_ATTRIBUTES_VALUE_VISITATION_FWD_HPP_INCLUDED_
+#define BOOST_LOG_ATTRIBUTES_VALUE_VISITATION_FWD_HPP_INCLUDED_
+
+#include <boost/log/detail/config.hpp>
+#include <boost/log/attributes/fallback_policy_fwd.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+/*!
+ * \brief The class represents attribute value visitation result
+ */
+class visitation_result;
+
+/*!
+ * \brief Generic attribute value visitor invoker
+ */
+template< typename T, typename FallbackPolicyT = fallback_to_none >
+class value_visitor_invoker;
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#endif // BOOST_LOG_ATTRIBUTES_VALUE_VISITATION_FWD_HPP_INCLUDED_
diff --git a/boost/log/common.hpp b/boost/log/common.hpp
new file mode 100644
index 0000000..bc62893
--- /dev/null
+++ b/boost/log/common.hpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file common.hpp
+ * \author Andrey Semashev
+ * \date 14.03.2009
+ *
+ * This header includes other Boost.Log headers that are commonly used in logging applications.
+ * Note that the header does not include any headers required to setup the library, as usually
+ * they aren't needed in more than one translation unit of the application.
+ */
+
+#ifndef BOOST_LOG_COMMON_HPP_INCLUDED_
+#define BOOST_LOG_COMMON_HPP_INCLUDED_
+
+#include <boost/log/detail/config.hpp>
+
+#include <boost/log/core.hpp>
+
+#include <boost/log/sources/global_logger_storage.hpp>
+#include <boost/log/sources/record_ostream.hpp>
+
+#include <boost/log/sources/basic_logger.hpp>
+#include <boost/log/sources/severity_logger.hpp>
+#include <boost/log/sources/channel_logger.hpp>
+#include <boost/log/sources/severity_channel_logger.hpp>
+#include <boost/log/sources/exception_handler_feature.hpp>
+
+#include <boost/log/attributes/constant.hpp>
+#include <boost/log/attributes/named_scope.hpp>
+#include <boost/log/attributes/scoped_attribute.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#endif // BOOST_LOG_COMMON_HPP_INCLUDED_
diff --git a/boost/log/core.hpp b/boost/log/core.hpp
new file mode 100644
index 0000000..159e5b9
--- /dev/null
+++ b/boost/log/core.hpp
@@ -0,0 +1,28 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file log/core.hpp
+ * \author Andrey Semashev
+ * \date 19.04.2007
+ *
+ * This header includes Boost.Log headers related to the logging core.
+ */
+
+#ifndef BOOST_LOG_CORE_HPP_INCLUDED_
+#define BOOST_LOG_CORE_HPP_INCLUDED_
+
+#include <boost/log/detail/config.hpp>
+
+#include <boost/log/core/core.hpp>
+#include <boost/log/core/record.hpp>
+#include <boost/log/core/record_view.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#endif // BOOST_LOG_CORE_HPP_INCLUDED_
diff --git a/boost/log/core/core.hpp b/boost/log/core/core.hpp
new file mode 100644
index 0000000..e347529
--- /dev/null
+++ b/boost/log/core/core.hpp
@@ -0,0 +1,329 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file core/core.hpp
+ * \author Andrey Semashev
+ * \date 19.04.2007
+ *
+ * This header contains logging core class definition.
+ */
+
+#ifndef BOOST_LOG_CORE_CORE_HPP_INCLUDED_
+#define BOOST_LOG_CORE_CORE_HPP_INCLUDED_
+
+#include <utility>
+#include <boost/smart_ptr/shared_ptr.hpp>
+#include <boost/move/core.hpp>
+#include <boost/log/detail/config.hpp>
+#include <boost/log/detail/light_function.hpp>
+#include <boost/log/core/record.hpp>
+#include <boost/log/attributes/attribute_set.hpp>
+#include <boost/log/attributes/attribute_name.hpp>
+#include <boost/log/attributes/attribute.hpp>
+#include <boost/log/attributes/attribute_value_set.hpp>
+#include <boost/log/expressions/filter.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+#ifndef BOOST_LOG_DOXYGEN_PASS
+
+namespace sinks {
+
+class sink;
+
+} // namespace sinks
+
+#endif // BOOST_LOG_DOXYGEN_PASS
+
+class core;
+
+typedef shared_ptr< core > core_ptr;
+
+/*!
+ * \brief Logging library core class
+ *
+ * The logging core is used to interconnect log sources and sinks. It also provides
+ * a number of basic features, like global filtering and global and thread-specific attribute storage.
+ *
+ * The logging core is a singleton. Users can acquire the core instance by calling the static method <tt>get</tt>.
+ */
+class core
+{
+public:
+ //! Exception handler function type
+ typedef boost::log::aux::light_function< void () > exception_handler_type;
+
+private:
+ //! Implementation type
+ struct implementation;
+ friend struct implementation;
+
+private:
+ //! A pointer to the implementation
+ implementation* m_impl;
+
+private:
+ //! \cond
+ core();
+ //! \endcond
+
+public:
+ /*!
+ * Destructor. Destroys the core, releases any sinks and attributes that were registered.
+ */
+ ~core();
+
+ /*!
+ * \return The method returns a pointer to the logging core singleton instance.
+ */
+ BOOST_LOG_API static core_ptr get();
+
+ /*!
+ * The method enables or disables logging.
+ *
+ * Setting this status to \c false allows you to completely wipe out any logging activity, including
+ * filtering and generation of attribute values. It is useful if you want to completely disable logging
+ * in a running application. The state of logging does not alter any other properties of the logging
+ * library, such as filters or sinks, so you can enable logging with the very same settings that you had
+ * when the logging was disabled.
+ * This feature may also be useful if you want to perform major changes to logging configuration and
+ * don't want your application to block on opening or pushing a log record.
+ *
+ * By default logging is enabled.
+ *
+ * \param enabled The actual flag of logging activity.
+ * \return The previous value of enabled/disabled logging flag
+ */
+ BOOST_LOG_API bool set_logging_enabled(bool enabled = true);
+ /*!
+ * The method allows to detect if logging is enabled. See the comment for \c set_logging_enabled.
+ */
+ BOOST_LOG_API bool get_logging_enabled() const;
+
+ /*!
+ * The method sets the global logging filter. The filter is applied to every log record that is processed.
+ *
+ * \param filter The filter function object to be installed.
+ */
+ BOOST_LOG_API void set_filter(filter const& filter);
+ /*!
+ * The method removes the global logging filter. All log records are passed to sinks without global filtering applied.
+ */
+ BOOST_LOG_API void reset_filter();
+
+ /*!
+ * The method adds a new sink. The sink is included into logging process immediately after being added and until being removed.
+ * No sink can be added more than once at the same time. If the sink is already registered, the call is ignored.
+ *
+ * \param s The sink to be registered.
+ */
+ BOOST_LOG_API void add_sink(shared_ptr< sinks::sink > const& s);
+ /*!
+ * The method removes the sink from the output. The sink will not receive any log records after removal.
+ * The call has no effect if the sink is not registered.
+ *
+ * \param s The sink to be unregistered.
+ */
+ BOOST_LOG_API void remove_sink(shared_ptr< sinks::sink > const& s);
+ /*!
+ * The method removes all registered sinks from the output. The sinks will not receive any log records after removal.
+ */
+ BOOST_LOG_API void remove_all_sinks();
+
+ /*!
+ * The method performs flush on all registered sinks.
+ *
+ * \note This method may take long time to complete as it may block until all sinks manage to process all buffered log records.
+ * The call will also block all logging attempts until the operation completes.
+ */
+ BOOST_LOG_API void flush();
+
+ /*!
+ * The method adds an attribute to the global attribute set. The attribute will be implicitly added to every log record.
+ *
+ * \param name The attribute name.
+ * \param attr The attribute factory.
+ * \return A pair of values. If the second member is \c true, then the attribute is added and the first member points to the
+ * attribute. Otherwise the attribute was not added and the first member points to the attribute that prevents
+ * addition.
+ */
+ BOOST_LOG_API std::pair< attribute_set::iterator, bool > add_global_attribute(attribute_name const& name, attribute const& attr);
+ /*!
+ * The method removes an attribute from the global attribute set.
+ *
+ * \pre The attribute was added with the \c add_global_attribute call.
+ * \post The attribute is no longer registered as a global attribute. The iterator is invalidated after removal.
+ *
+ * \param it Iterator to the previously added attribute.
+ */
+ BOOST_LOG_API void remove_global_attribute(attribute_set::iterator it);
+
+ /*!
+ * The method returns a copy of the complete set of currently registered global attributes.
+ */
+ BOOST_LOG_API attribute_set get_global_attributes() const;
+ /*!
+ * The method replaces the complete set of currently registered global attributes with the provided set.
+ *
+ * \note The method invalidates all iterators and references that may have been returned
+ * from the \c add_global_attribute method.
+ *
+ * \param attrs The set of attributes to be installed.
+ */
+ BOOST_LOG_API void set_global_attributes(attribute_set const& attrs);
+
+ /*!
+ * The method adds an attribute to the thread-specific attribute set. The attribute will be implicitly added to
+ * every log record made in the current thread.
+ *
+ * \note In single-threaded build the effect is the same as adding the attribute globally. This, however, does
+ * not imply that iterators to thread-specific and global attributes are interchangeable.
+ *
+ * \param name The attribute name.
+ * \param attr The attribute factory.
+ * \return A pair of values. If the second member is \c true, then the attribute is added and the first member points to the
+ * attribute. Otherwise the attribute was not added and the first member points to the attribute that prevents
+ * addition.
+ */
+ BOOST_LOG_API std::pair< attribute_set::iterator, bool > add_thread_attribute(attribute_name const& name, attribute const& attr);
+ /*!
+ * The method removes an attribute from the thread-specific attribute set.
+ *
+ * \pre The attribute was added with the \c add_thread_attribute call.
+ * \post The attribute is no longer registered as a thread-specific attribute. The iterator is invalidated after removal.
+ *
+ * \param it Iterator to the previously added attribute.
+ */
+ BOOST_LOG_API void remove_thread_attribute(attribute_set::iterator it);
+
+ /*!
+ * The method returns a copy of the complete set of currently registered thread-specific attributes.
+ */
+ BOOST_LOG_API attribute_set get_thread_attributes() const;
+ /*!
+ * The method replaces the complete set of currently registered thread-specific attributes with the provided set.
+ *
+ * \note The method invalidates all iterators and references that may have been returned
+ * from the \c add_thread_attribute method.
+ *
+ * \param attrs The set of attributes to be installed.
+ */
+ BOOST_LOG_API void set_thread_attributes(attribute_set const& attrs);
+
+ /*!
+ * The method sets exception handler function. The function will be called with no arguments
+ * in case if an exception occurs during either \c open_record or \c push_record method
+ * execution. Since exception handler is called from a \c catch statement, the exception
+ * can be rethrown in order to determine its type.
+ *
+ * By default no handler is installed, thus any exception is propagated as usual.
+ *
+ * \sa See also: <tt>utility/exception_handler.hpp</tt>
+ * \param handler Exception handling function
+ *
+ * \note The exception handler can be invoked in several threads concurrently.
+ * Thread interruptions are not affected by exception handlers.
+ */
+ BOOST_LOG_API void set_exception_handler(exception_handler_type const& handler);
+
+ /*!
+ * The method attempts to open a new record to be written. While attempting to open a log record all filtering is applied.
+ * A successfully opened record can be pushed further to sinks by calling the \c push_record method or simply destroyed by
+ * destroying the returned object.
+ *
+ * More than one open records are allowed, such records exist independently. All attribute values are acquired during opening
+ * the record and do not interact between records.
+ *
+ * The returned records can be copied, however, they must not be passed between different threads.
+ *
+ * \param source_attributes The set of source-specific attributes to be attached to the record to be opened.
+ * \return A valid log record if the record is opened, an invalid record object if not (e.g. because it didn't pass filtering).
+ *
+ * \b Throws: If an exception handler is installed, only throws if the handler throws. Otherwise may
+ * throw if one of the sinks throws, or some system resource limitation is reached.
+ */
+ BOOST_LOG_API record open_record(attribute_set const& source_attributes);
+ /*!
+ * The method attempts to open a new record to be written. While attempting to open a log record all filtering is applied.
+ * A successfully opened record can be pushed further to sinks by calling the \c push_record method or simply destroyed by
+ * destroying the returned object.
+ *
+ * More than one open records are allowed, such records exist independently. All attribute values are acquired during opening
+ * the record and do not interact between records.
+ *
+ * The returned records can be copied, however, they must not be passed between different threads.
+ *
+ * \param source_attributes The set of source-specific attribute values to be attached to the record to be opened.
+ * \return A valid log record if the record is opened, an invalid record object if not (e.g. because it didn't pass filtering).
+ *
+ * \b Throws: If an exception handler is installed, only throws if the handler throws. Otherwise may
+ * throw if one of the sinks throws, or some system resource limitation is reached.
+ */
+ BOOST_LOG_API record open_record(attribute_value_set const& source_attributes);
+ /*!
+ * The method attempts to open a new record to be written. While attempting to open a log record all filtering is applied.
+ * A successfully opened record can be pushed further to sinks by calling the \c push_record method or simply destroyed by
+ * destroying the returned object.
+ *
+ * More than one open records are allowed, such records exist independently. All attribute values are acquired during opening
+ * the record and do not interact between records.
+ *
+ * The returned records can be copied, however, they must not be passed between different threads.
+ *
+ * \param source_attributes The set of source-specific attribute values to be attached to the record to be opened. The contents
+ * of this container are unspecified after this call.
+ * \return A valid log record if the record is opened, an invalid record object if not (e.g. because it didn't pass filtering).
+ *
+ * \b Throws: If an exception handler is installed, only throws if the handler throws. Otherwise may
+ * throw if one of the sinks throws, or some system resource limitation is reached.
+ */
+ BOOST_FORCEINLINE record open_record(BOOST_RV_REF(attribute_value_set) source_attributes)
+ {
+ return open_record_move(static_cast< attribute_value_set& >(source_attributes));
+ }
+
+ /*!
+ * The method pushes the record to sinks. The record is moved from in the process.
+ *
+ * \pre <tt>!!rec == true</tt>
+ * \post <tt>!rec == true</tt>
+ * \param rec A previously successfully opened log record.
+ *
+ * \b Throws: If an exception handler is installed, only throws if the handler throws. Otherwise may
+ * throw if one of the sinks throws.
+ */
+ BOOST_FORCEINLINE void push_record(BOOST_RV_REF(record) rec)
+ {
+ push_record_move(static_cast< record& >(rec));
+ }
+
+ BOOST_DELETED_FUNCTION(core(core const&))
+ BOOST_DELETED_FUNCTION(core& operator= (core const&))
+
+#ifndef BOOST_LOG_DOXYGEN_PASS
+private:
+ //! Opens log record. This function is mostly needed to maintain ABI stable between C++03 and C++11.
+ BOOST_LOG_API record open_record_move(attribute_value_set& source_attributes);
+ //! The method pushes the record to sinks.
+ BOOST_LOG_API void push_record_move(record& rec);
+#endif // BOOST_LOG_DOXYGEN_PASS
+};
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_CORE_CORE_HPP_INCLUDED_
diff --git a/boost/log/core/record.hpp b/boost/log/core/record.hpp
new file mode 100644
index 0000000..758e44a
--- /dev/null
+++ b/boost/log/core/record.hpp
@@ -0,0 +1,207 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file record.hpp
+ * \author Andrey Semashev
+ * \date 09.03.2009
+ *
+ * This header contains a logging record class definition.
+ */
+
+#ifndef BOOST_LOG_CORE_RECORD_HPP_INCLUDED_
+#define BOOST_LOG_CORE_RECORD_HPP_INCLUDED_
+
+#include <boost/move/core.hpp>
+#include <boost/log/detail/config.hpp>
+#include <boost/utility/explicit_operator_bool.hpp>
+#include <boost/log/attributes/attribute_value_set.hpp>
+#include <boost/log/expressions/keyword_fwd.hpp>
+#include <boost/log/core/record_view.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+class core;
+
+/*!
+ * \brief Logging record class
+ *
+ * The logging record encapsulates all information related to a single logging statement,
+ * in particular, attribute values view and the log message string. The record can be updated before pushing
+ * for further processing to the logging core.
+ */
+class record
+{
+ BOOST_MOVABLE_BUT_NOT_COPYABLE(record)
+
+ friend class core;
+
+#ifndef BOOST_LOG_DOXYGEN_PASS
+private:
+ //! Private data
+ typedef record_view::public_data public_data;
+
+private:
+ //! A pointer to the log record implementation
+ public_data* m_impl;
+
+#endif // BOOST_LOG_DOXYGEN_PASS
+
+public:
+ /*!
+ * Default constructor. Creates an empty record that is equivalent to the invalid record handle.
+ *
+ * \post <tt>!*this == true</tt>
+ */
+ record() : m_impl(NULL) {}
+
+ /*!
+ * Move constructor. Source record contents unspecified after the operation.
+ */
+ record(BOOST_RV_REF(record) that) BOOST_NOEXCEPT : m_impl(that.m_impl)
+ {
+ that.m_impl = NULL;
+ }
+
+ /*!
+ * Destructor. Destroys the record, releases any sinks and attribute values that were involved in processing this record.
+ */
+ ~record() BOOST_NOEXCEPT
+ {
+ reset();
+ }
+
+ /*!
+ * Move assignment. Source record contents unspecified after the operation.
+ */
+ record& operator= (BOOST_RV_REF(record) that) BOOST_NOEXCEPT
+ {
+ swap(static_cast< record& >(that));
+ return *this;
+ }
+
+ /*!
+ * \return A reference to the set of attribute values attached to this record
+ *
+ * \pre <tt>!!*this</tt>
+ */
+ attribute_value_set& attribute_values() BOOST_NOEXCEPT
+ {
+ return m_impl->m_attribute_values;
+ }
+
+ /*!
+ * \return A reference to the set of attribute values attached to this record
+ *
+ * \pre <tt>!!*this</tt>
+ */
+ attribute_value_set const& attribute_values() const BOOST_NOEXCEPT
+ {
+ return m_impl->m_attribute_values;
+ }
+
+ /*!
+ * Conversion to an unspecified boolean type
+ *
+ * \return \c true, if the <tt>*this</tt> identifies a log record, \c false, if the <tt>*this</tt> is not valid
+ */
+ BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
+
+ /*!
+ * Inverted conversion to an unspecified boolean type
+ *
+ * \return \c false, if the <tt>*this</tt> identifies a log record, \c true, if the <tt>*this</tt> is not valid
+ */
+ bool operator! () const BOOST_NOEXCEPT
+ {
+ return !m_impl;
+ }
+
+ /*!
+ * Swaps two handles
+ *
+ * \param that Another record to swap with
+ * <b>Throws:</b> Nothing
+ */
+ void swap(record& that) BOOST_NOEXCEPT
+ {
+ public_data* p = m_impl;
+ m_impl = that.m_impl;
+ that.m_impl = p;
+ }
+
+ /*!
+ * Resets the log record handle. If there are no other handles left, the log record is closed
+ * and all resources referenced by the record are released.
+ *
+ * \post <tt>!*this == true</tt>
+ */
+ void reset() BOOST_NOEXCEPT
+ {
+ if (m_impl)
+ {
+ public_data::destroy(m_impl);
+ m_impl = NULL;
+ }
+ }
+
+ /*!
+ * Attribute value lookup.
+ *
+ * \param name Attribute name.
+ * \return An \c attribute_value, non-empty if it is found, empty otherwise.
+ */
+ attribute_value_set::mapped_type operator[] (attribute_value_set::key_type name) const
+ {
+ return m_impl->m_attribute_values[name];
+ }
+
+ /*!
+ * Attribute value lookup.
+ *
+ * \param keyword Attribute keyword.
+ * \return A \c value_ref with extracted attribute value if it is found, empty \c value_ref otherwise.
+ */
+ template< typename DescriptorT, template< typename > class ActorT >
+ typename result_of::extract< typename expressions::attribute_keyword< DescriptorT, ActorT >::value_type, DescriptorT >::type
+ operator[] (expressions::attribute_keyword< DescriptorT, ActorT > const& keyword) const
+ {
+ return m_impl->m_attribute_values[keyword];
+ }
+
+ /*!
+ * The function ensures that the log record does not depend on any thread-specific data. Then the record contents
+ * are used to construct a \c record_view which is returned from the function. The record is no longer valid after the call.
+ *
+ * \pre <tt>!!*this</tt>
+ * \post <tt>!*this</tt>
+ * \returns The record view that contains all attribute values from the original record.
+ */
+ BOOST_LOG_API record_view lock();
+};
+
+/*!
+ * A free-standing swap function overload for \c record
+ */
+inline void swap(record& left, record& right) BOOST_NOEXCEPT
+{
+ left.swap(right);
+}
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_CORE_RECORD_HPP_INCLUDED_
diff --git a/boost/log/core/record_view.hpp b/boost/log/core/record_view.hpp
new file mode 100644
index 0000000..58f2a1b
--- /dev/null
+++ b/boost/log/core/record_view.hpp
@@ -0,0 +1,260 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file record_view.hpp
+ * \author Andrey Semashev
+ * \date 09.03.2009
+ *
+ * This header contains a logging record view class definition.
+ */
+
+#ifndef BOOST_LOG_CORE_RECORD_VIEW_HPP_INCLUDED_
+#define BOOST_LOG_CORE_RECORD_VIEW_HPP_INCLUDED_
+
+#include <boost/smart_ptr/intrusive_ptr.hpp>
+#include <boost/move/core.hpp>
+#include <boost/log/detail/config.hpp>
+#include <boost/utility/explicit_operator_bool.hpp>
+#include <boost/log/attributes/attribute_value_set.hpp>
+#include <boost/log/expressions/keyword_fwd.hpp>
+#ifndef BOOST_LOG_NO_THREADS
+#include <boost/detail/atomic_count.hpp>
+#endif // BOOST_LOG_NO_THREADS
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+#ifndef BOOST_LOG_DOXYGEN_PASS
+class core;
+class record;
+#endif // BOOST_LOG_DOXYGEN_PASS
+
+/*!
+ * \brief Logging record view class
+ *
+ * The logging record encapsulates all information related to a single logging statement,
+ * in particular, attribute values view and the log message string. The view is immutable,
+ * it is implemented as a wrapper around a reference-counted implementation.
+ */
+class record_view
+{
+ BOOST_COPYABLE_AND_MOVABLE(record_view)
+
+ friend class core;
+ friend class record;
+
+#ifndef BOOST_LOG_DOXYGEN_PASS
+private:
+ //! Private data
+ struct private_data;
+ friend struct private_data;
+
+ //! Publicly available record data
+ struct public_data
+ {
+ //! Reference counter
+#ifndef BOOST_LOG_NO_THREADS
+ mutable boost::detail::atomic_count m_ref_counter;
+#else
+ mutable unsigned int m_ref_counter;
+#endif // BOOST_LOG_NO_THREADS
+
+ //! Attribute values view
+ attribute_value_set m_attribute_values;
+
+ //! Constructor from the attribute sets
+ explicit public_data(BOOST_RV_REF(attribute_value_set) values) :
+ m_ref_counter(1),
+ m_attribute_values(values)
+ {
+ }
+
+ //! Destructor
+ BOOST_LOG_API static void destroy(const public_data* p) BOOST_NOEXCEPT;
+
+ protected:
+ ~public_data() {}
+
+ BOOST_DELETED_FUNCTION(public_data(public_data const&))
+ BOOST_DELETED_FUNCTION(public_data& operator= (public_data const&))
+
+ friend void intrusive_ptr_add_ref(const public_data* p) { ++p->m_ref_counter; }
+ friend void intrusive_ptr_release(const public_data* p) { if (--p->m_ref_counter == 0) public_data::destroy(p); }
+ };
+
+private:
+ //! A pointer to the log record implementation
+ intrusive_ptr< public_data > m_impl;
+
+private:
+ // A private constructor, accessible from record
+ explicit record_view(public_data* impl) : m_impl(impl, false) {}
+
+#endif // BOOST_LOG_DOXYGEN_PASS
+
+public:
+ /*!
+ * Default constructor. Creates an empty record view that is equivalent to the invalid record handle.
+ *
+ * \post <tt>!*this == true</tt>
+ */
+ BOOST_DEFAULTED_FUNCTION(record_view(), {})
+
+ /*!
+ * Copy constructor
+ */
+ record_view(record_view const& that) BOOST_NOEXCEPT : m_impl(that.m_impl) {}
+
+ /*!
+ * Move constructor. Source record contents unspecified after the operation.
+ */
+ record_view(BOOST_RV_REF(record_view) that) BOOST_NOEXCEPT
+ {
+ m_impl.swap(that.m_impl);
+ }
+
+ /*!
+ * Destructor. Destroys the record, releases any sinks and attribute values that were involved in processing this record.
+ */
+ ~record_view() BOOST_NOEXCEPT {}
+
+ /*!
+ * Copy assignment
+ */
+ record_view& operator= (BOOST_COPY_ASSIGN_REF(record_view) that) BOOST_NOEXCEPT
+ {
+ m_impl = that.m_impl;
+ return *this;
+ }
+
+ /*!
+ * Move assignment. Source record contents unspecified after the operation.
+ */
+ record_view& operator= (BOOST_RV_REF(record_view) that) BOOST_NOEXCEPT
+ {
+ m_impl.swap(that.m_impl);
+ return *this;
+ }
+
+ /*!
+ * \return A reference to the set of attribute values attached to this record
+ *
+ * \pre <tt>!!*this</tt>
+ */
+ attribute_value_set const& attribute_values() const BOOST_NOEXCEPT
+ {
+ return m_impl->m_attribute_values;
+ }
+
+ /*!
+ * Equality comparison
+ *
+ * \param that Comparand
+ * \return \c true if both <tt>*this</tt> and \a that identify the same log record or both do not
+ * identify any record, \c false otherwise.
+ */
+ bool operator== (record_view const& that) const BOOST_NOEXCEPT
+ {
+ return m_impl == that.m_impl;
+ }
+
+ /*!
+ * Inequality comparison
+ *
+ * \param that Comparand
+ * \return <tt>!(*this == that)</tt>
+ */
+ bool operator!= (record_view const& that) const BOOST_NOEXCEPT
+ {
+ return !operator== (that);
+ }
+
+ /*!
+ * Conversion to an unspecified boolean type
+ *
+ * \return \c true, if the <tt>*this</tt> identifies a log record, \c false, if the <tt>*this</tt> is not valid
+ */
+ BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
+
+ /*!
+ * Inverted conversion to an unspecified boolean type
+ *
+ * \return \c false, if the <tt>*this</tt> identifies a log record, \c true, if the <tt>*this</tt> is not valid
+ */
+ bool operator! () const BOOST_NOEXCEPT
+ {
+ return !m_impl;
+ }
+
+ /*!
+ * Swaps two handles
+ *
+ * \param that Another record to swap with
+ * <b>Throws:</b> Nothing
+ */
+ void swap(record_view& that) BOOST_NOEXCEPT
+ {
+ m_impl.swap(that.m_impl);
+ }
+
+ /*!
+ * Resets the log record handle. If there are no other handles left, the log record is closed
+ * and all resources referenced by the record are released.
+ *
+ * \post <tt>!*this == true</tt>
+ */
+ void reset() BOOST_NOEXCEPT
+ {
+ m_impl.reset();
+ }
+
+ /*!
+ * Attribute value lookup.
+ *
+ * \param name Attribute name.
+ * \return An \c attribute_value, non-empty if it is found, empty otherwise.
+ */
+ attribute_value_set::mapped_type operator[] (attribute_value_set::key_type name) const
+ {
+ return m_impl->m_attribute_values[name];
+ }
+
+ /*!
+ * Attribute value lookup.
+ *
+ * \param keyword Attribute keyword.
+ * \return A \c value_ref with extracted attribute value if it is found, empty \c value_ref otherwise.
+ */
+ template< typename DescriptorT, template< typename > class ActorT >
+ typename result_of::extract< typename expressions::attribute_keyword< DescriptorT, ActorT >::value_type, DescriptorT >::type
+ operator[] (expressions::attribute_keyword< DescriptorT, ActorT > const& keyword) const
+ {
+ return m_impl->m_attribute_values[keyword];
+ }
+};
+
+/*!
+ * A free-standing swap function overload for \c record_view
+ */
+inline void swap(record_view& left, record_view& right) BOOST_NOEXCEPT
+{
+ left.swap(right);
+}
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_CORE_RECORD_VIEW_HPP_INCLUDED_
diff --git a/boost/log/detail/asio_fwd.hpp b/boost/log/detail/asio_fwd.hpp
new file mode 100644
index 0000000..e284c24
--- /dev/null
+++ b/boost/log/detail/asio_fwd.hpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file asio_fwd.hpp
+ * \author Andrey Semashev
+ * \date 20.04.2008
+ *
+ * \brief This header is the Boost.Log library implementation, see the library documentation
+ * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
+ *
+ * The header provides forward declarations of Boost.ASIO that are required for the user's
+ * code to compile with Boost.Log. The forward declarations allow to avoid including the major
+ * part of Boost.ASIO and system headers into user's code.
+ */
+
+#ifndef BOOST_LOG_DETAIL_ASIO_FWD_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_ASIO_FWD_HPP_INCLUDED_
+
+#include <boost/log/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+namespace asio {
+
+namespace ip {
+
+class address;
+
+} // namespace ip
+
+} // namespace asio
+
+} // namespace boost
+
+#endif // BOOST_LOG_DETAIL_ASIO_FWD_HPP_INCLUDED_
diff --git a/boost/log/detail/attachable_sstream_buf.hpp b/boost/log/detail/attachable_sstream_buf.hpp
new file mode 100644
index 0000000..9b0a053
--- /dev/null
+++ b/boost/log/detail/attachable_sstream_buf.hpp
@@ -0,0 +1,172 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file attachable_sstream_buf.hpp
+ * \author Andrey Semashev
+ * \date 29.07.2007
+ *
+ * \brief This header is the Boost.Log library implementation, see the library documentation
+ * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
+ */
+
+#ifndef BOOST_LOG_ATTACHABLE_SSTREAM_BUF_HPP_INCLUDED_
+#define BOOST_LOG_ATTACHABLE_SSTREAM_BUF_HPP_INCLUDED_
+
+#include <memory>
+#include <string>
+#include <streambuf>
+#include <boost/assert.hpp>
+#include <boost/utility/addressof.hpp>
+#include <boost/log/detail/config.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace aux {
+
+//! A streambuf that puts the formatted data to an external string
+template<
+ typename CharT,
+ typename TraitsT = std::char_traits< CharT >,
+ typename AllocatorT = std::allocator< CharT >
+>
+class basic_ostringstreambuf :
+ public std::basic_streambuf< CharT, TraitsT >
+{
+ //! Self type
+ typedef basic_ostringstreambuf< CharT, TraitsT, AllocatorT > this_type;
+ //! Base type
+ typedef std::basic_streambuf< CharT, TraitsT > base_type;
+
+ //! Buffer size
+ enum { buffer_size = 16 };
+
+public:
+ //! Character type
+ typedef typename base_type::char_type char_type;
+ //! Traits type
+ typedef typename base_type::traits_type traits_type;
+ //! String type
+ typedef std::basic_string< char_type, traits_type, AllocatorT > string_type;
+ //! Int type
+ typedef typename base_type::int_type int_type;
+
+private:
+ //! A reference to the string that will be filled
+ string_type* m_Storage;
+ //! A buffer used to temporarily store output
+ char_type m_Buffer[buffer_size];
+
+public:
+ //! Constructor
+ explicit basic_ostringstreambuf() : m_Storage(0)
+ {
+ base_type::setp(m_Buffer, m_Buffer + (sizeof(m_Buffer) / sizeof(*m_Buffer)));
+ }
+ //! Constructor
+ explicit basic_ostringstreambuf(string_type& storage) : m_Storage(boost::addressof(storage))
+ {
+ base_type::setp(m_Buffer, m_Buffer + (sizeof(m_Buffer) / sizeof(*m_Buffer)));
+ }
+
+ //! Clears the buffer to the initial state
+ void clear()
+ {
+ char_type* pBase = this->pbase();
+ char_type* pPtr = this->pptr();
+ if (pBase != pPtr)
+ this->pbump(static_cast< int >(pBase - pPtr));
+ }
+
+ //! Detaches the buffer from the string
+ void detach()
+ {
+ if (m_Storage)
+ {
+ this_type::sync();
+ m_Storage = 0;
+ }
+ }
+
+ //! Attaches the buffer to another string
+ void attach(string_type& storage)
+ {
+ detach();
+ m_Storage = boost::addressof(storage);
+ }
+
+ //! Returns a pointer to the attached string
+ string_type* storage() const { return m_Storage; }
+
+protected:
+ //! Puts all buffered data to the string
+ int sync()
+ {
+ BOOST_ASSERT(m_Storage != 0);
+ char_type* pBase = this->pbase();
+ char_type* pPtr = this->pptr();
+ if (pBase != pPtr)
+ {
+ m_Storage->append(pBase, pPtr);
+ this->pbump(static_cast< int >(pBase - pPtr));
+ }
+ return 0;
+ }
+ //! Puts an unbuffered character to the string
+ int_type overflow(int_type c)
+ {
+ BOOST_ASSERT(m_Storage != 0);
+ basic_ostringstreambuf::sync();
+ if (!traits_type::eq_int_type(c, traits_type::eof()))
+ {
+ m_Storage->push_back(traits_type::to_char_type(c));
+ return c;
+ }
+ else
+ return traits_type::not_eof(c);
+ }
+ //! Puts a character sequence to the string
+ std::streamsize xsputn(const char_type* s, std::streamsize n)
+ {
+ BOOST_ASSERT(m_Storage != 0);
+ basic_ostringstreambuf::sync();
+ typedef typename string_type::size_type string_size_type;
+ const string_size_type max_storage_left =
+ m_Storage->max_size() - m_Storage->size();
+ if (static_cast< string_size_type >(n) < max_storage_left)
+ {
+ m_Storage->append(s, static_cast< string_size_type >(n));
+ return n;
+ }
+ else
+ {
+ m_Storage->append(s, max_storage_left);
+ return static_cast< std::streamsize >(max_storage_left);
+ }
+ }
+
+ //! Copy constructor (closed)
+ BOOST_DELETED_FUNCTION(basic_ostringstreambuf(basic_ostringstreambuf const& that))
+ //! Assignment (closed)
+ BOOST_DELETED_FUNCTION(basic_ostringstreambuf& operator= (basic_ostringstreambuf const& that))
+};
+
+} // namespace aux
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_ATTACHABLE_SSTREAM_BUF_HPP_INCLUDED_
diff --git a/boost/log/detail/attr_output_impl.hpp b/boost/log/detail/attr_output_impl.hpp
new file mode 100644
index 0000000..8f00736
--- /dev/null
+++ b/boost/log/detail/attr_output_impl.hpp
@@ -0,0 +1,111 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file attr_output_impl.hpp
+ * \author Andrey Semashev
+ * \date 12.08.2012
+ *
+ * \brief This header is the Boost.Log library implementation, see the library documentation
+ * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
+ */
+
+#ifndef BOOST_LOG_DETAIL_ATTR_OUTPUT_IMPL_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_ATTR_OUTPUT_IMPL_HPP_INCLUDED_
+
+#include <boost/mpl/is_sequence.hpp>
+#include <boost/phoenix/core/actor.hpp>
+#include <boost/log/detail/config.hpp>
+#include <boost/log/expressions/attr.hpp>
+#include <boost/log/utility/functional/bind_to_log.hpp>
+#include <boost/log/detail/attr_output_terminal.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace expressions {
+
+namespace aux {
+
+template< typename LeftT, typename T, typename FallbackPolicyT, typename TagT >
+struct make_output_expression
+{
+ //! Resulting expression
+ typedef attribute_output_terminal< LeftT, T, FallbackPolicyT, to_log_fun< TagT > > type;
+
+ //! Creates the output expression
+ template< typename RightT >
+ static BOOST_FORCEINLINE type make(LeftT const& left, RightT const& right)
+ {
+ return type(left, right.get_name(), to_log_fun< TagT >(), right.get_fallback_policy());
+ }
+};
+
+template< typename LeftT, typename RightT, typename ValueT = typename RightT::value_type, bool IsSequenceV = mpl::is_sequence< ValueT >::value >
+struct make_output_actor;
+
+template< template< typename > class ActorT, typename LeftExprT, typename RightT, typename ValueT >
+struct make_output_actor< ActorT< LeftExprT >, RightT, ValueT, false >
+{
+ typedef make_output_expression<
+ ActorT< LeftExprT >,
+ ValueT,
+ typename RightT::fallback_policy,
+ typename RightT::tag_type
+ > make_expression;
+
+ typedef ActorT< typename make_expression::type > type;
+
+ static BOOST_FORCEINLINE type make(ActorT< LeftExprT > const& left, RightT const& right)
+ {
+ type res = {{ make_expression::make(left, right) }};
+ return res;
+ }
+};
+
+template< template< typename > class ActorT, typename LeftExprT, typename RightT, typename ValueT >
+struct make_output_actor< ActorT< LeftExprT >, RightT, ValueT, true >
+{
+ typedef attribute_output_terminal< ActorT< LeftExprT >, ValueT, typename RightT::fallback_policy, to_log_fun< typename RightT::tag_type > > expression_type;
+
+ typedef ActorT< expression_type > type;
+
+ static BOOST_FORCEINLINE type make(ActorT< LeftExprT > const& left, RightT const& right)
+ {
+ type res = {{ expression_type(left, right.get_name(), to_log_fun< typename RightT::tag_type >(), right.get_fallback_policy()) }};
+ return res;
+ }
+};
+
+} // namespace aux
+
+#define BOOST_LOG_AUX_OVERLOAD(left_ref, right_ref)\
+ template< typename LeftExprT, typename T, typename FallbackPolicyT, typename TagT >\
+ BOOST_FORCEINLINE typename aux::make_output_actor< phoenix::actor< LeftExprT >, attribute_actor< T, FallbackPolicyT, TagT, phoenix::actor > >::type\
+ operator<< (phoenix::actor< LeftExprT > left_ref left, attribute_actor< T, FallbackPolicyT, TagT, phoenix::actor > right_ref right)\
+ {\
+ return aux::make_output_actor< phoenix::actor< LeftExprT >, attribute_actor< T, FallbackPolicyT, TagT, phoenix::actor > >::make(left, right);\
+ }
+
+#include <boost/log/detail/generate_overloads.hpp>
+
+#undef BOOST_LOG_AUX_OVERLOAD
+
+} // namespace expressions
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_DETAIL_ATTR_OUTPUT_IMPL_HPP_INCLUDED_
diff --git a/boost/log/detail/attr_output_terminal.hpp b/boost/log/detail/attr_output_terminal.hpp
new file mode 100644
index 0000000..574993a
--- /dev/null
+++ b/boost/log/detail/attr_output_terminal.hpp
@@ -0,0 +1,162 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file attribute_output_terminal.hpp
+ * \author Andrey Semashev
+ * \date 06.11.2012
+ *
+ * The header contains implementation of a generic output manipulator in template expressions.
+ */
+
+#ifndef BOOST_LOG_DETAIL_ATTR_OUTPUT_TERMINAL_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_ATTR_OUTPUT_TERMINAL_HPP_INCLUDED_
+
+#include <boost/mpl/bool.hpp>
+#include <boost/phoenix/core/actor.hpp>
+#include <boost/phoenix/core/meta_grammar.hpp>
+#include <boost/phoenix/core/environment.hpp>
+#include <boost/phoenix/core/terminal_fwd.hpp>
+#include <boost/phoenix/core/is_nullary.hpp>
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/fusion/sequence/intrinsic/at.hpp>
+#include <boost/log/detail/config.hpp>
+#include <boost/log/detail/custom_terminal_spec.hpp>
+#include <boost/log/attributes/attribute_name.hpp>
+#include <boost/log/attributes/value_visitation.hpp>
+#include <boost/log/utility/functional/bind.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace expressions {
+
+namespace aux {
+
+//! Attribute stream output expression
+template< typename LeftT, typename T, typename FallbackPolicyT, typename ImplT >
+class attribute_output_terminal
+{
+private:
+ //! Self type
+ typedef attribute_output_terminal< LeftT, T, FallbackPolicyT, ImplT > this_type;
+ //! Attribute value visitor invoker
+ typedef value_visitor_invoker< T, FallbackPolicyT > visitor_invoker_type;
+ //! Manipulator implementation
+ typedef ImplT impl_type;
+
+public:
+ //! Internal typedef for type categorization
+ typedef void _is_boost_log_terminal;
+
+ //! Result type definition
+ template< typename >
+ struct result;
+
+ template< typename ThisT, typename ContextT >
+ struct result< ThisT(ContextT) >
+ {
+ typedef typename remove_cv< typename remove_reference< ContextT >::type >::type context_type;
+ typedef typename phoenix::evaluator::impl<
+ typename LeftT::proto_base_expr&,
+ context_type,
+ phoenix::unused
+ >::result_type type;
+ };
+
+private:
+ //! Left argument actor
+ LeftT m_left;
+ //! Attribute name
+ const attribute_name m_name;
+ //! Attribute value visitor invoker
+ visitor_invoker_type m_visitor_invoker;
+ //! Manipulator implementation
+ impl_type m_impl;
+
+public:
+ //! Initializing constructor
+ attribute_output_terminal(LeftT const& left, attribute_name const& name) : m_left(left), m_name(name)
+ {
+ }
+
+ //! Initializing constructor
+ attribute_output_terminal(LeftT const& left, attribute_name const& name, impl_type const& impl) : m_left(left), m_name(name), m_impl(impl)
+ {
+ }
+
+ //! Initializing constructor
+ template< typename U >
+ attribute_output_terminal(LeftT const& left, attribute_name const& name, impl_type const& impl, U const& arg) :
+ m_left(left), m_name(name), m_visitor_invoker(arg), m_impl(impl)
+ {
+ }
+
+ //! Copy constructor
+ attribute_output_terminal(attribute_output_terminal const& that) :
+ m_left(that.m_left), m_name(that.m_name), m_visitor_invoker(that.m_visitor_invoker), m_impl(that.m_impl)
+ {
+ }
+
+ //! Invokation operator
+ template< typename ContextT >
+ typename result< this_type(ContextT const&) >::type operator() (ContextT const& ctx)
+ {
+ typedef typename result< this_type(ContextT const&) >::type result_type;
+ result_type strm = phoenix::eval(m_left, ctx);
+ m_visitor_invoker(m_name, fusion::at_c< 0 >(phoenix::env(ctx).args()), binder1st< impl_type&, result_type >(m_impl, strm));
+ return strm;
+ }
+
+ //! Invokation operator
+ template< typename ContextT >
+ typename result< const this_type(ContextT const&) >::type operator() (ContextT const& ctx) const
+ {
+ typedef typename result< const this_type(ContextT const&) >::type result_type;
+ result_type strm = phoenix::eval(m_left, ctx);
+ m_visitor_invoker(m_name, fusion::at_c< 0 >(phoenix::env(ctx).args()), binder1st< impl_type const&, result_type >(m_impl, strm));
+ return strm;
+ }
+
+ BOOST_DELETED_FUNCTION(attribute_output_terminal())
+};
+
+} // namespace aux
+
+} // namespace expressions
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+#ifndef BOOST_LOG_DOXYGEN_PASS
+
+namespace phoenix {
+
+namespace result_of {
+
+template< typename LeftT, typename T, typename FallbackPolicyT, typename ImplT >
+struct is_nullary< custom_terminal< boost::log::expressions::aux::attribute_output_terminal< LeftT, T, FallbackPolicyT, ImplT > > > :
+ public mpl::false_
+{
+};
+
+} // namespace result_of
+
+} // namespace phoenix
+
+#endif // !defined(BOOST_LOG_DOXYGEN_PASS)
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_DETAIL_ATTR_OUTPUT_TERMINAL_HPP_INCLUDED_
diff --git a/boost/log/detail/attribute_get_value_impl.hpp b/boost/log/detail/attribute_get_value_impl.hpp
new file mode 100644
index 0000000..2058d65
--- /dev/null
+++ b/boost/log/detail/attribute_get_value_impl.hpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file attribute_get_value_impl.hpp
+ * \author Andrey Semashev
+ * \date 04.08.2012
+ *
+ * \brief This header is the Boost.Log library implementation, see the library documentation
+ * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
+ */
+
+#ifndef BOOST_LOG_DETAIL_ATTRIBUTE_GET_VALUE_IMPL_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_ATTRIBUTE_GET_VALUE_IMPL_HPP_INCLUDED_
+
+#include <boost/log/detail/config.hpp>
+#include <boost/log/attributes/attribute.hpp>
+#include <boost/log/attributes/attribute_value.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+inline attribute_value attribute::get_value() const
+{
+ return m_pImpl->get_value();
+}
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_DETAIL_ATTRIBUTE_GET_VALUE_IMPL_HPP_INCLUDED_
diff --git a/boost/log/detail/attribute_predicate.hpp b/boost/log/detail/attribute_predicate.hpp
new file mode 100644
index 0000000..a097863
--- /dev/null
+++ b/boost/log/detail/attribute_predicate.hpp
@@ -0,0 +1,116 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file attribute_predicate.hpp
+ * \author Andrey Semashev
+ * \date 02.09.2012
+ *
+ * The header contains implementation of a generic predicate in template expressions.
+ */
+
+#ifndef BOOST_LOG_DETAIL_ATTRIBUTE_PREDICATE_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_ATTRIBUTE_PREDICATE_HPP_INCLUDED_
+
+#include <boost/phoenix/core/actor.hpp>
+#include <boost/utility/result_of.hpp>
+#include <boost/log/detail/config.hpp>
+#include <boost/log/attributes/attribute_name.hpp>
+#include <boost/log/attributes/value_visitation.hpp>
+#include <boost/log/attributes/fallback_policy.hpp>
+#include <boost/log/utility/functional/bind.hpp>
+#include <boost/log/utility/functional/save_result.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace expressions {
+
+namespace aux {
+
+/*!
+ * The predicate checks if the attribute value satisfies a predicate.
+ */
+template< typename T, typename ArgT, typename PredicateT, typename FallbackPolicyT = fallback_to_none >
+class attribute_predicate
+{
+public:
+ //! Function result_type
+ typedef bool result_type;
+ //! Expected attribute value type
+ typedef T value_type;
+ //! Predicate type
+ typedef PredicateT predicate_type;
+ //! Argument type for the predicate
+ typedef ArgT argument_type;
+ //! Fallback policy
+ typedef FallbackPolicyT fallback_policy;
+
+private:
+ //! Argument for the predicate
+ const argument_type m_arg;
+ //! Attribute value name
+ const attribute_name m_name;
+ //! Visitor invoker
+ value_visitor_invoker< value_type, fallback_policy > m_visitor_invoker;
+
+public:
+ /*!
+ * Initializing constructor
+ *
+ * \param name Attribute name
+ * \param pred_arg The predicate argument
+ */
+ attribute_predicate(attribute_name const& name, argument_type const& pred_arg) : m_arg(pred_arg), m_name(name)
+ {
+ }
+
+ /*!
+ * Initializing constructor
+ *
+ * \param name Attribute name
+ * \param pred_arg The predicate argument
+ * \param arg Additional parameter for the fallback policy
+ */
+ template< typename U >
+ attribute_predicate(attribute_name const& name, argument_type const& pred_arg, U const& arg) : m_arg(pred_arg), m_name(name), m_visitor_invoker(arg)
+ {
+ }
+
+ /*!
+ * Checking operator
+ *
+ * \param arg A set of attribute values or a log record
+ * \return \c true if the log record contains the sought attribute value, \c false otherwise
+ */
+ template< typename ArgumentT >
+ result_type operator() (ArgumentT const& arg) const
+ {
+ typedef binder2nd< predicate_type, argument_type const& > visitor_type;
+
+ bool res = false;
+ m_visitor_invoker(m_name, arg, boost::log::save_result(visitor_type(predicate_type(), m_arg), res));
+ return res;
+ }
+};
+
+} // namespace aux
+
+} // namespace expressions
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_DETAIL_ATTRIBUTE_PREDICATE_HPP_INCLUDED_
diff --git a/boost/log/detail/cleanup_scope_guard.hpp b/boost/log/detail/cleanup_scope_guard.hpp
new file mode 100644
index 0000000..dd2c0e1
--- /dev/null
+++ b/boost/log/detail/cleanup_scope_guard.hpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file cleanup_scope_guard.hpp
+ * \author Andrey Semashev
+ * \date 11.03.2008
+ *
+ * \brief This header is the Boost.Log library implementation, see the library documentation
+ * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
+ */
+
+#ifndef BOOST_LOG_DETAIL_CLEANUP_SCOPE_GUARD_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_CLEANUP_SCOPE_GUARD_HPP_INCLUDED_
+
+#include <boost/log/detail/config.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace aux {
+
+//! Cleanup scope guard
+template< typename T >
+struct cleanup_guard
+{
+ explicit cleanup_guard(T& obj) : m_Obj(obj) {}
+ ~cleanup_guard() { m_Obj.clear(); }
+
+ // Copying prohibited
+ BOOST_DELETED_FUNCTION(cleanup_guard(cleanup_guard const&))
+ BOOST_DELETED_FUNCTION(cleanup_guard& operator= (cleanup_guard const&))
+
+private:
+ T& m_Obj;
+};
+
+} // namespace aux
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_DETAIL_CLEANUP_SCOPE_GUARD_HPP_INCLUDED_
diff --git a/boost/log/detail/code_conversion.hpp b/boost/log/detail/code_conversion.hpp
new file mode 100644
index 0000000..d49988b
--- /dev/null
+++ b/boost/log/detail/code_conversion.hpp
@@ -0,0 +1,119 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file code_conversion.hpp
+ * \author Andrey Semashev
+ * \date 08.11.2008
+ *
+ * \brief This header is the Boost.Log library implementation, see the library documentation
+ * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
+ */
+
+#ifndef BOOST_LOG_DETAIL_CODE_CONVERSION_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_CODE_CONVERSION_HPP_INCLUDED_
+
+#include <locale>
+#include <string>
+#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 function converts one string to the character type of another
+BOOST_LOG_API void code_convert(const wchar_t* str1, std::size_t len, std::string& str2, std::locale const& loc = std::locale());
+//! The function converts one string to the character type of another
+BOOST_LOG_API void code_convert(const char* str1, std::size_t len, std::wstring& str2, std::locale const& loc = std::locale());
+#if !defined(BOOST_NO_CXX11_CHAR16_T)
+//! The function converts one string to the character type of another
+BOOST_LOG_API void code_convert(const char16_t* str1, std::size_t len, std::string& str2, std::locale const& loc = std::locale());
+//! The function converts one string to the character type of another
+BOOST_LOG_API void code_convert(const char* str1, std::size_t len, std::u16string& str2, std::locale const& loc = std::locale());
+#endif
+#if !defined(BOOST_NO_CXX11_CHAR32_T)
+//! The function converts one string to the character type of another
+BOOST_LOG_API void code_convert(const char32_t* str1, std::size_t len, std::string& str2, std::locale const& loc = std::locale());
+//! The function converts one string to the character type of another
+BOOST_LOG_API void code_convert(const char* str1, std::size_t len, std::u32string& str2, std::locale const& loc = std::locale());
+#endif
+
+//! The function converts one string to the character type of another
+template< typename CharT, typename SourceTraitsT, typename SourceAllocatorT, typename TargetTraitsT, typename TargetAllocatorT >
+inline void code_convert(std::basic_string< CharT, SourceTraitsT, SourceAllocatorT > const& str1, std::basic_string< CharT, TargetTraitsT, TargetAllocatorT >& str2, std::locale const& = std::locale())
+{
+ str2.append(str1.c_str(), str1.size());
+}
+//! The function converts one string to the character type of another
+template< typename CharT, typename TargetTraitsT, typename TargetAllocatorT >
+inline void code_convert(const CharT* str1, std::size_t len, std::basic_string< CharT, TargetTraitsT, TargetAllocatorT >& str2, std::locale const& = std::locale())
+{
+ str2.append(str1, len);
+}
+
+//! The function converts one string to the character type of another
+template< typename SourceCharT, typename SourceTraitsT, typename SourceAllocatorT, typename TargetCharT, typename TargetTraitsT, typename TargetAllocatorT >
+inline void code_convert(std::basic_string< SourceCharT, SourceTraitsT, SourceAllocatorT > const& str1, std::basic_string< TargetCharT, TargetTraitsT, TargetAllocatorT >& str2, std::locale const& loc = std::locale())
+{
+ aux::code_convert(str1.c_str(), str1.size(), str2, loc);
+}
+
+//! The function converts the passed string to the narrow-character encoding
+inline std::string const& to_narrow(std::string const& str)
+{
+ return str;
+}
+
+//! The function converts the passed string to the narrow-character encoding
+inline std::string const& to_narrow(std::string const& str, std::locale const&)
+{
+ return str;
+}
+
+//! The function converts the passed string to the narrow-character encoding
+inline std::string to_narrow(std::wstring const& str, std::locale const& loc = std::locale())
+{
+ std::string res;
+ aux::code_convert(str, res, loc);
+ return res;
+}
+
+//! The function converts the passed string to the wide-character encoding
+inline std::wstring const& to_wide(std::wstring const& str)
+{
+ return str;
+}
+
+//! The function converts the passed string to the wide-character encoding
+inline std::wstring const& to_wide(std::wstring const& str, std::locale const&)
+{
+ return str;
+}
+
+//! The function converts the passed string to the wide-character encoding
+inline std::wstring to_wide(std::string const& str, std::locale const& loc = std::locale())
+{
+ std::wstring res;
+ aux::code_convert(str, res, loc);
+ return res;
+}
+
+} // namespace aux
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_DETAIL_CODE_CONVERSION_HPP_INCLUDED_
diff --git a/boost/log/detail/config.hpp b/boost/log/detail/config.hpp
new file mode 100644
index 0000000..4d1e66b
--- /dev/null
+++ b/boost/log/detail/config.hpp
@@ -0,0 +1,351 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file config.hpp
+ * \author Andrey Semashev
+ * \date 08.03.2007
+ *
+ * \brief This header is the Boost.Log library implementation, see the library documentation
+ * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html. In this file
+ * internal configuration macros are defined.
+ */
+
+#ifndef BOOST_LOG_DETAIL_CONFIG_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_CONFIG_HPP_INCLUDED_
+
+// This check must be before any system headers are included, or __MSVCRT_VERSION__ may get defined to 0x0600
+#if defined(__MINGW32__) && !defined(__MSVCRT_VERSION__)
+// Target MinGW headers to at least MSVC 7.0 runtime by default. This will enable some useful functions.
+#define __MSVCRT_VERSION__ 0x0700
+#endif
+
+#include <limits.h> // To bring in libc macros
+#include <boost/config.hpp>
+
+#if defined(BOOST_NO_RTTI)
+# error Boost.Log: RTTI is required by the library
+#endif
+
+#if defined(_MSC_VER) && _MSC_VER >= 1600
+# define BOOST_LOG_HAS_PRAGMA_DETECT_MISMATCH
+#endif
+
+#if defined(BOOST_LOG_HAS_PRAGMA_DETECT_MISMATCH)
+#include <boost/preprocessor/stringize.hpp>
+#endif
+
+#if !defined(BOOST_WINDOWS)
+# ifndef BOOST_LOG_WITHOUT_DEBUG_OUTPUT
+# define BOOST_LOG_WITHOUT_DEBUG_OUTPUT
+# endif
+# ifndef BOOST_LOG_WITHOUT_EVENT_LOG
+# define BOOST_LOG_WITHOUT_EVENT_LOG
+# endif
+#endif
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#if defined(BOOST_MSVC)
+ // For some reason MSVC 9.0 fails to link the library if static integral constants are defined in cpp
+# define BOOST_LOG_BROKEN_STATIC_CONSTANTS_LINKAGE
+# if _MSC_VER <= 1310
+ // MSVC 7.1 sometimes fails to match out-of-class template function definitions with
+ // their declarations if the return type or arguments of the functions involve typename keyword
+ // and depend on the template parameters.
+# define BOOST_LOG_BROKEN_TEMPLATE_DEFINITION_MATCHING
+# endif
+# if _MSC_VER <= 1400
+ // Older MSVC versions reject friend declarations for class template specializations
+# define BOOST_LOG_BROKEN_FRIEND_TEMPLATE_SPECIALIZATIONS
+# endif
+# if _MSC_VER <= 1600
+ // MSVC up to 10.0 attempts to invoke copy constructor when initializing a const reference from rvalue returned from a function.
+ // This fails when the returned value cannot be copied (only moved):
+ //
+ // class base {};
+ // class derived : public base { BOOST_MOVABLE_BUT_NOT_COPYABLE(derived) };
+ // derived foo();
+ // base const& var = foo(); // attempts to call copy constructor of derived
+# define BOOST_LOG_BROKEN_REFERENCE_FROM_RVALUE_INIT
+# endif
+# if !defined(_STLPORT_VERSION)
+ // MSVC 9.0 mandates packaging of STL classes, which apparently affects alignment and
+ // makes alignment_of< T >::value no longer be a power of 2 for types that derive from STL classes.
+ // This breaks type_with_alignment and everything that relies on it.
+ // This doesn't happen with non-native STLs, such as STLPort. Strangely, this doesn't show with
+ // STL classes themselves or most of the user-defined derived classes.
+ // Not sure if that happens with other MSVC versions.
+ // See: http://svn.boost.org/trac/boost/ticket/1946
+# define BOOST_LOG_BROKEN_STL_ALIGNMENT
+# endif
+#endif
+
+#if defined(BOOST_INTEL) || defined(__SUNPRO_CC)
+ // Intel compiler and Sun Studio 12.3 have problems with friend declarations for nested class templates
+# define BOOST_LOG_NO_MEMBER_TEMPLATE_FRIENDS
+#endif
+
+#if defined(BOOST_MSVC) && BOOST_MSVC <= 1600
+ // MSVC cannot interpret constant expressions in certain contexts, such as non-type template parameters
+# define BOOST_LOG_BROKEN_CONSTANT_EXPRESSIONS
+#endif
+
+#if defined(__CYGWIN__)
+ // Boost.ASIO is broken on Cygwin
+# define BOOST_LOG_NO_ASIO
+#endif
+
+#if !defined(BOOST_LOG_USE_NATIVE_SYSLOG) && defined(BOOST_LOG_NO_ASIO)
+# ifndef BOOST_LOG_WITHOUT_SYSLOG
+# define BOOST_LOG_WITHOUT_SYSLOG
+# endif
+#endif
+
+#if defined(__GNUC__) && (__GNUC__ == 4 && __GNUC_MINOR__ <= 2)
+ // GCC 4.1 and 4.2 have buggy anonymous namespaces support, which interferes with symbol linkage
+# define BOOST_LOG_ANONYMOUS_NAMESPACE namespace anonymous {} using namespace anonymous; namespace anonymous
+#else
+# define BOOST_LOG_ANONYMOUS_NAMESPACE namespace
+#endif
+
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || (defined(__GNUC__) && (__GNUC__ == 4 && __GNUC_MINOR__ <= 6))
+// GCC up to 4.6 (inclusively) did not support expanding template argument packs into non-variadic template arguments
+#define BOOST_LOG_NO_CXX11_ARG_PACKS_TO_NON_VARIADIC_ARGS_EXPANSION
+#endif
+
+#if defined(_MSC_VER)
+# define BOOST_LOG_NO_VTABLE __declspec(novtable)
+#elif defined(__GNUC__)
+# define BOOST_LOG_NO_VTABLE
+#else
+# define BOOST_LOG_NO_VTABLE
+#endif
+
+// An MS-like compilers' extension that allows to optimize away the needless code
+#if defined(_MSC_VER)
+# define BOOST_LOG_ASSUME(expr) __assume(expr)
+#else
+# define BOOST_LOG_ASSUME(expr)
+#endif
+
+// The statement marking unreachable branches of code to avoid warnings
+#if defined(BOOST_CLANG)
+# if __has_builtin(__builtin_unreachable)
+# define BOOST_LOG_UNREACHABLE() __builtin_unreachable()
+# endif
+#elif defined(__GNUC__)
+# if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
+# define BOOST_LOG_UNREACHABLE() __builtin_unreachable()
+# endif
+#elif defined(_MSC_VER)
+# define BOOST_LOG_UNREACHABLE() __assume(0)
+#endif
+#if !defined(BOOST_LOG_UNREACHABLE)
+# define BOOST_LOG_UNREACHABLE()
+# define BOOST_LOG_UNREACHABLE_RETURN(r) return r
+#else
+# define BOOST_LOG_UNREACHABLE_RETURN(r) BOOST_LOG_UNREACHABLE()
+#endif
+
+// Some compilers support a special attribute that shows that a function won't return
+#if defined(__GNUC__) || (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x590)
+ // GCC and Sun Studio 12 support attribute syntax
+# define BOOST_LOG_NORETURN __attribute__((noreturn))
+#elif defined (_MSC_VER)
+ // Microsoft-compatible compilers go here
+# define BOOST_LOG_NORETURN __declspec(noreturn)
+#else
+ // The rest compilers might emit bogus warnings about missing return statements
+ // in functions with non-void return types when throw_exception is used.
+# define BOOST_LOG_NORETURN
+#endif
+
+#if !defined(BOOST_LOG_BUILDING_THE_LIB)
+
+// Detect if we're dealing with dll
+# if defined(BOOST_LOG_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)
+# define BOOST_LOG_DLL
+# endif
+
+# if defined(BOOST_LOG_DLL)
+# if defined(BOOST_SYMBOL_IMPORT)
+# define BOOST_LOG_API BOOST_SYMBOL_IMPORT
+# elif defined(BOOST_HAS_DECLSPEC)
+# define BOOST_LOG_API __declspec(dllimport)
+# endif
+# endif
+# ifndef BOOST_LOG_API
+# define BOOST_LOG_API
+# endif
+//
+// Automatically link to the correct build variant where possible.
+//
+# if !defined(BOOST_ALL_NO_LIB)
+# if !defined(BOOST_LOG_NO_LIB)
+# define BOOST_LIB_NAME boost_log
+# if defined(BOOST_LOG_DLL)
+# define BOOST_DYN_LINK
+# endif
+# include <boost/config/auto_link.hpp>
+# endif
+ // In static-library builds compilers ignore auto-link comments from Boost.Log binary to
+ // other Boost libraries. We explicitly add comments here for other libraries.
+ // In dynamic-library builds this is not needed.
+# if !defined(BOOST_LOG_DLL)
+# include <boost/system/config.hpp>
+# include <boost/filesystem/config.hpp>
+# if !defined(BOOST_DATE_TIME_NO_LIB) && !defined(BOOST_DATE_TIME_SOURCE)
+# define BOOST_LIB_NAME boost_date_time
+# if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_DATE_TIME_DYN_LINK)
+# define BOOST_DYN_LINK
+# endif
+# include <boost/config/auto_link.hpp>
+# endif
+ // Boost.Thread's config is included below, if needed
+# endif
+# endif // auto-linking disabled
+
+#else // !defined(BOOST_LOG_BUILDING_THE_LIB)
+
+# if defined(BOOST_LOG_DLL)
+# if defined(BOOST_SYMBOL_EXPORT)
+# define BOOST_LOG_API BOOST_SYMBOL_EXPORT
+# elif defined(BOOST_HAS_DECLSPEC)
+# define BOOST_LOG_API __declspec(dllexport)
+# endif
+# endif
+# ifndef BOOST_LOG_API
+# define BOOST_LOG_API BOOST_SYMBOL_VISIBLE
+# endif
+
+#endif // !defined(BOOST_LOG_BUILDING_THE_LIB)
+
+// By default we provide support for both char and wchar_t
+#if !defined(BOOST_LOG_WITHOUT_CHAR)
+# define BOOST_LOG_USE_CHAR
+#endif
+#if !defined(BOOST_LOG_WITHOUT_WCHAR_T)
+# define BOOST_LOG_USE_WCHAR_T
+#endif
+
+#if !defined(BOOST_LOG_DOXYGEN_PASS)
+ // Check if multithreading is supported
+# if !defined(BOOST_LOG_NO_THREADS) && !defined(BOOST_HAS_THREADS)
+# define BOOST_LOG_NO_THREADS
+# endif // !defined(BOOST_LOG_NO_THREADS) && !defined(BOOST_HAS_THREADS)
+#endif // !defined(BOOST_LOG_DOXYGEN_PASS)
+
+#if !defined(BOOST_LOG_NO_THREADS)
+ // We need this header to (i) enable auto-linking with Boost.Thread and
+ // (ii) to bring in configuration macros of Boost.Thread.
+# include <boost/thread/detail/config.hpp>
+#endif // !defined(BOOST_LOG_NO_THREADS)
+
+#if !defined(BOOST_LOG_NO_THREADS)
+# define BOOST_LOG_EXPR_IF_MT(expr) expr
+#else
+# undef BOOST_LOG_USE_COMPILER_TLS
+# define BOOST_LOG_EXPR_IF_MT(expr)
+#endif // !defined(BOOST_LOG_NO_THREADS)
+
+#if defined(BOOST_LOG_USE_COMPILER_TLS)
+# if defined(__GNUC__) || defined(__SUNPRO_CC)
+# define BOOST_LOG_TLS __thread
+# elif defined(BOOST_MSVC)
+# define BOOST_LOG_TLS __declspec(thread)
+# else
+# undef BOOST_LOG_USE_COMPILER_TLS
+# endif
+#endif // defined(BOOST_LOG_USE_COMPILER_TLS)
+
+#ifndef BOOST_LOG_CPU_CACHE_LINE_SIZE
+//! The macro defines the CPU cache line size for the target architecture. This is mostly used for optimization.
+#define BOOST_LOG_CPU_CACHE_LINE_SIZE 64
+#endif
+
+namespace boost {
+
+// Setup namespace name
+#if !defined(BOOST_LOG_DOXYGEN_PASS)
+# if defined(BOOST_LOG_DLL)
+# if defined(BOOST_LOG_NO_THREADS)
+# define BOOST_LOG_VERSION_NAMESPACE v2_st
+# else
+# if defined(BOOST_THREAD_PLATFORM_PTHREAD)
+# define BOOST_LOG_VERSION_NAMESPACE v2_mt_posix
+# elif defined(BOOST_THREAD_PLATFORM_WIN32)
+# if defined(BOOST_LOG_USE_WINNT6_API)
+# define BOOST_LOG_VERSION_NAMESPACE v2_mt_nt6
+# else
+# define BOOST_LOG_VERSION_NAMESPACE v2_mt_nt5
+# endif // defined(BOOST_LOG_USE_WINNT6_API)
+# else
+# define BOOST_LOG_VERSION_NAMESPACE v2_mt
+# endif
+# endif // defined(BOOST_LOG_NO_THREADS)
+# else
+# if defined(BOOST_LOG_NO_THREADS)
+# define BOOST_LOG_VERSION_NAMESPACE v2s_st
+# else
+# if defined(BOOST_THREAD_PLATFORM_PTHREAD)
+# define BOOST_LOG_VERSION_NAMESPACE v2s_mt_posix
+# elif defined(BOOST_THREAD_PLATFORM_WIN32)
+# if defined(BOOST_LOG_USE_WINNT6_API)
+# define BOOST_LOG_VERSION_NAMESPACE v2s_mt_nt6
+# else
+# define BOOST_LOG_VERSION_NAMESPACE v2s_mt_nt5
+# endif // defined(BOOST_LOG_USE_WINNT6_API)
+# else
+# define BOOST_LOG_VERSION_NAMESPACE v2s_mt
+# endif
+# endif // defined(BOOST_LOG_NO_THREADS)
+# endif // defined(BOOST_LOG_DLL)
+
+
+namespace log {
+
+# if !defined(BOOST_NO_CXX11_INLINE_NAMESPACES)
+
+inline namespace BOOST_LOG_VERSION_NAMESPACE {}
+}
+
+# define BOOST_LOG_OPEN_NAMESPACE namespace log { inline namespace BOOST_LOG_VERSION_NAMESPACE {
+# define BOOST_LOG_CLOSE_NAMESPACE }}
+
+# else
+
+namespace BOOST_LOG_VERSION_NAMESPACE {}
+
+using namespace BOOST_LOG_VERSION_NAMESPACE
+# if defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) && !defined(__clang__)
+__attribute__((__strong__))
+# endif
+;
+
+}
+
+# define BOOST_LOG_OPEN_NAMESPACE namespace log { namespace BOOST_LOG_VERSION_NAMESPACE {
+# define BOOST_LOG_CLOSE_NAMESPACE }}
+# endif
+
+#else // !defined(BOOST_LOG_DOXYGEN_PASS)
+
+namespace log {}
+# define BOOST_LOG_OPEN_NAMESPACE namespace log {
+# define BOOST_LOG_CLOSE_NAMESPACE }
+
+#endif // !defined(BOOST_LOG_DOXYGEN_PASS)
+
+#if defined(BOOST_LOG_HAS_PRAGMA_DETECT_MISMATCH)
+#pragma detect_mismatch("boost_log_abi", BOOST_PP_STRINGIZE(BOOST_LOG_VERSION_NAMESPACE))
+#endif
+
+} // namespace boost
+
+#endif // BOOST_LOG_DETAIL_CONFIG_HPP_INCLUDED_
diff --git a/boost/log/detail/copy_cv.hpp b/boost/log/detail/copy_cv.hpp
new file mode 100644
index 0000000..a6a4eba
--- /dev/null
+++ b/boost/log/detail/copy_cv.hpp
@@ -0,0 +1,64 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file copy_cv.hpp
+ * \author Andrey Semashev
+ * \date 16.03.2014
+ *
+ * The header defines \c copy_cv type trait which copies const/volatile qualifiers from one type to another
+ */
+
+#ifndef BOOST_LOG_DETAIL_COPY_CV_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_COPY_CV_HPP_INCLUDED_
+
+#include <boost/log/detail/config.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace aux {
+
+//! The type trait copies top level const/volatile qualifiers from \c FromT to \c ToT
+template< typename FromT, typename ToT >
+struct copy_cv
+{
+ typedef ToT type;
+};
+
+template< typename FromT, typename ToT >
+struct copy_cv< const FromT, ToT >
+{
+ typedef const ToT type;
+};
+
+template< typename FromT, typename ToT >
+struct copy_cv< volatile FromT, ToT >
+{
+ typedef volatile ToT type;
+};
+
+template< typename FromT, typename ToT >
+struct copy_cv< const volatile FromT, ToT >
+{
+ typedef const volatile ToT type;
+};
+
+} // namespace aux
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_DETAIL_COPY_CV_HPP_INCLUDED_
diff --git a/boost/log/detail/custom_terminal_spec.hpp b/boost/log/detail/custom_terminal_spec.hpp
new file mode 100644
index 0000000..fb43357
--- /dev/null
+++ b/boost/log/detail/custom_terminal_spec.hpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file custom_terminal_spec.hpp
+ * \author Andrey Semashev
+ * \date 29.01.2012
+ *
+ * The header contains Boost.Phoenix custom terminal specialization for Boost.Log terminals.
+ */
+
+#ifndef BOOST_LOG_DETAIL_CUSTOM_TERMINAL_SPEC_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_CUSTOM_TERMINAL_SPEC_HPP_INCLUDED_
+
+#include <boost/mpl/bool.hpp>
+#include <boost/phoenix/core/terminal_fwd.hpp>
+#include <boost/phoenix/core/is_nullary.hpp>
+#include <boost/phoenix/core/terminal.hpp> // needed for terminal-related part of the grammar
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/utility/result_of.hpp>
+#include <boost/log/detail/config.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+namespace phoenix {
+
+template< typename T >
+struct is_custom_terminal< T, typename T::_is_boost_log_terminal > :
+ public mpl::true_
+{
+};
+
+template< typename T >
+struct custom_terminal< T, typename T::_is_boost_log_terminal >
+{
+ typedef custom_terminal< T, typename T::_is_boost_log_terminal > this_type;
+
+ template< typename >
+ struct result;
+
+ template< typename ThisT, typename TermT, typename ContextT >
+ struct result< ThisT(TermT, ContextT) >
+ {
+ typedef typename remove_cv< typename remove_reference< TermT >::type >::type term;
+ typedef typename boost::result_of< const term(ContextT) >::type type;
+ };
+
+ template< typename ContextT >
+ typename result< const this_type(T const&, ContextT&) >::type operator() (T const& term, ContextT& ctx) const
+ {
+ return term(ctx);
+ }
+};
+
+} // namespace phoenix
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_DETAIL_CUSTOM_TERMINAL_SPEC_HPP_INCLUDED_
diff --git a/boost/log/detail/date_time_fmt_gen_traits_fwd.hpp b/boost/log/detail/date_time_fmt_gen_traits_fwd.hpp
new file mode 100644
index 0000000..a80930b
--- /dev/null
+++ b/boost/log/detail/date_time_fmt_gen_traits_fwd.hpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file date_time_fmt_gen_traits_fwd.hpp
+ * \author Andrey Semashev
+ * \date 07.11.2012
+ *
+ * \brief This header is the Boost.Log library implementation, see the library documentation
+ * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
+ */
+
+#ifndef BOOST_LOG_DETAIL_DATE_TIME_FMT_GEN_TRAITS_FWD_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_DATE_TIME_FMT_GEN_TRAITS_FWD_HPP_INCLUDED_
+
+#include <boost/log/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace expressions {
+
+namespace aux {
+
+template< typename T, typename CharT, typename VoidT = void >
+struct date_time_formatter_generator_traits;
+
+} // namespace aux
+
+} // namespace expressions
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#endif // BOOST_LOG_DETAIL_DATE_TIME_FMT_GEN_TRAITS_FWD_HPP_INCLUDED_
diff --git a/boost/log/detail/date_time_format_parser.hpp b/boost/log/detail/date_time_format_parser.hpp
new file mode 100644
index 0000000..7b82d55
--- /dev/null
+++ b/boost/log/detail/date_time_format_parser.hpp
@@ -0,0 +1,486 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file date_time_format_parser.hpp
+ * \author Andrey Semashev
+ * \date 16.09.2012
+ *
+ * The header contains a parser for date and time format strings.
+ */
+
+#ifndef BOOST_LOG_DETAIL_DATE_TIME_FORMAT_PARSER_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_DATE_TIME_FORMAT_PARSER_HPP_INCLUDED_
+
+#include <string>
+#include <boost/range/as_literal.hpp>
+#include <boost/range/iterator_range_core.hpp>
+#include <boost/log/detail/config.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace aux {
+
+/*!
+ * This is the interface the parser will use to notify the caller about various components of date in the format string.
+ */
+template< typename CharT >
+struct date_format_parser_callback
+{
+ //! Character type used by the parser
+ typedef CharT char_type;
+
+ //! Destructor
+ virtual ~date_format_parser_callback() {}
+
+ /*!
+ * \brief The function is called when the parser discovers a string literal in the format string
+ *
+ * \param lit The string of characters not interpreted as a placeholder
+ */
+ virtual void on_literal(iterator_range< const char_type* > const& lit) = 0;
+
+ /*!
+ * \brief The method is called when an unknown placeholder is found in the format string
+ *
+ * \param ph The placeholder with the leading percent sign
+ */
+ virtual void on_placeholder(iterator_range< const char_type* > const& ph)
+ {
+ // By default interpret all unrecognized placeholders as literals
+ on_literal(ph);
+ }
+
+ /*!
+ * \brief The function is called when the short year placeholder is found in the format string
+ */
+ virtual void on_short_year()
+ {
+ const char_type placeholder[3] = { static_cast< char_type >('%'), static_cast< char_type >('y'), static_cast< char_type >('\0') };
+ on_placeholder(boost::as_literal(placeholder));
+ }
+
+ /*!
+ * \brief The function is called when the full year placeholder is found in the format string
+ */
+ virtual void on_full_year()
+ {
+ const char_type placeholder[3] = { static_cast< char_type >('%'), static_cast< char_type >('Y'), static_cast< char_type >('\0') };
+ on_placeholder(boost::as_literal(placeholder));
+ }
+
+ /*!
+ * \brief The function is called when the numeric month placeholder is found in the format string
+ */
+ virtual void on_numeric_month()
+ {
+ const char_type placeholder[3] = { static_cast< char_type >('%'), static_cast< char_type >('m'), static_cast< char_type >('\0') };
+ on_placeholder(boost::as_literal(placeholder));
+ }
+
+ /*!
+ * \brief The function is called when the short alphabetic month placeholder is found in the format string
+ */
+ virtual void on_short_month()
+ {
+ const char_type placeholder[3] = { static_cast< char_type >('%'), static_cast< char_type >('b'), static_cast< char_type >('\0') };
+ on_placeholder(boost::as_literal(placeholder));
+ }
+
+ /*!
+ * \brief The function is called when the full alphabetic month placeholder is found in the format string
+ */
+ virtual void on_full_month()
+ {
+ const char_type placeholder[3] = { static_cast< char_type >('%'), static_cast< char_type >('B'), static_cast< char_type >('\0') };
+ on_placeholder(boost::as_literal(placeholder));
+ }
+
+ /*!
+ * \brief The function is called when the numeric day of month placeholder is found in the format string
+ *
+ * \param leading_zero If \c true, the day should be formatted with leading zero, otherwise with leading space
+ */
+ virtual void on_month_day(bool leading_zero)
+ {
+ const char_type placeholder[3] = { static_cast< char_type >('%'), (leading_zero ? static_cast< char_type >('d') : static_cast< char_type >('e')), static_cast< char_type >('\0') };
+ on_placeholder(boost::as_literal(placeholder));
+ }
+
+ /*!
+ * \brief The function is called when the numeric day of week placeholder is found in the format string
+ */
+ virtual void on_numeric_week_day()
+ {
+ const char_type placeholder[3] = { static_cast< char_type >('%'), static_cast< char_type >('w'), static_cast< char_type >('\0') };
+ on_placeholder(boost::as_literal(placeholder));
+ }
+
+ /*!
+ * \brief The function is called when the short alphabetic day of week placeholder is found in the format string
+ */
+ virtual void on_short_week_day()
+ {
+ const char_type placeholder[3] = { static_cast< char_type >('%'), static_cast< char_type >('a'), static_cast< char_type >('\0') };
+ on_placeholder(boost::as_literal(placeholder));
+ }
+
+ /*!
+ * \brief The function is called when the full alphabetic day of week placeholder is found in the format string
+ */
+ virtual void on_full_week_day()
+ {
+ const char_type placeholder[3] = { static_cast< char_type >('%'), static_cast< char_type >('A'), static_cast< char_type >('\0') };
+ on_placeholder(boost::as_literal(placeholder));
+ }
+
+ /*!
+ * \brief The function is called when the ISO-formatted date is found in the format string
+ */
+ virtual void on_iso_date()
+ {
+ on_full_year();
+ on_numeric_month();
+ on_month_day(true);
+ }
+
+ /*!
+ * \brief The function is called when the extended ISO-formatted date is found in the format string
+ */
+ virtual void on_extended_iso_date()
+ {
+ const char_type delimiter[2] = { static_cast< char_type >('-'), static_cast< char_type >('\0') };
+ on_full_year();
+ on_literal(boost::as_literal(delimiter));
+ on_numeric_month();
+ on_literal(boost::as_literal(delimiter));
+ on_month_day(true);
+ }
+};
+
+/*!
+ * This is the interface the parser will use to notify the caller about various components of date in the format string.
+ */
+template< typename CharT >
+struct time_format_parser_callback
+{
+ //! Character type used by the parser
+ typedef CharT char_type;
+
+ //! Destructor
+ virtual ~time_format_parser_callback() {}
+
+ /*!
+ * \brief The function is called when the parser discovers a string literal in the format string
+ *
+ * \param lit The string of characters not interpreted as a placeholder
+ */
+ virtual void on_literal(iterator_range< const char_type* > const& lit) = 0;
+
+ /*!
+ * \brief The method is called when an unknown placeholder is found in the format string
+ *
+ * \param ph The placeholder with the leading percent sign
+ */
+ virtual void on_placeholder(iterator_range< const char_type* > const& ph)
+ {
+ // By default interpret all unrecognized placeholders as literals
+ on_literal(ph);
+ }
+
+ /*!
+ * \brief The function is called when the hours placeholder is found in the format string
+ *
+ * The placeholder is used for 24-hour clock and duration formatting.
+ *
+ * \param leading_zero If \c true, the one-digit number of hours should be formatted with leading zero, otherwise with leading space
+ */
+ virtual void on_hours(bool leading_zero)
+ {
+ const char_type placeholder[3] = { static_cast< char_type >('%'), (leading_zero ? static_cast< char_type >('O') : static_cast< char_type >('k')), static_cast< char_type >('\0') };
+ on_placeholder(boost::as_literal(placeholder));
+ }
+
+ /*!
+ * \brief The function is called when the hours placeholder is found in the format string
+ *
+ * The placeholder is used for 12-hour clock formatting. It should not be used for duration formatting.
+ *
+ * \param leading_zero If \c true, the one-digit number of hours should be formatted with leading zero, otherwise with leading space
+ */
+ virtual void on_hours_12(bool leading_zero)
+ {
+ const char_type placeholder[3] = { static_cast< char_type >('%'), (leading_zero ? static_cast< char_type >('I') : static_cast< char_type >('l')), static_cast< char_type >('\0') };
+ on_placeholder(boost::as_literal(placeholder));
+ }
+
+ /*!
+ * \brief The function is called when the minutes placeholder is found in the format string
+ */
+ virtual void on_minutes()
+ {
+ const char_type placeholder[3] = { static_cast< char_type >('%'), static_cast< char_type >('M'), static_cast< char_type >('\0') };
+ on_placeholder(boost::as_literal(placeholder));
+ }
+
+ /*!
+ * \brief The function is called when the seconds placeholder is found in the format string
+ */
+ virtual void on_seconds()
+ {
+ const char_type placeholder[3] = { static_cast< char_type >('%'), static_cast< char_type >('S'), static_cast< char_type >('\0') };
+ on_placeholder(boost::as_literal(placeholder));
+ }
+
+ /*!
+ * \brief The function is called when the fractional seconds placeholder is found in the format string
+ */
+ virtual void on_fractional_seconds()
+ {
+ const char_type placeholder[3] = { static_cast< char_type >('%'), static_cast< char_type >('f'), static_cast< char_type >('\0') };
+ on_placeholder(boost::as_literal(placeholder));
+ }
+
+ /*!
+ * \brief The function is called when the day period (AM/PM) placeholder is found in the format string
+ *
+ * The placeholder is used for 12-hour clock formatting. It should not be used for duration formatting.
+ *
+ * \param upper_case If \c true, the day period will be upper case, and lower case otherwise
+ */
+ virtual void on_am_pm(bool upper_case)
+ {
+ const char_type placeholder[3] = { static_cast< char_type >('%'), (upper_case ? static_cast< char_type >('p') : static_cast< char_type >('P')), static_cast< char_type >('\0') };
+ on_placeholder(boost::as_literal(placeholder));
+ }
+
+ /*!
+ * \brief The function is called when the time duration sign placeholder is found in the format string
+ *
+ * The placeholder is used for duration formatting. It should not be used for time point formatting.
+ *
+ * \param display_positive If \c true, the positive sign will be explicitly displayed, otherwise only negative sign will be displayed
+ */
+ virtual void on_duration_sign(bool display_positive)
+ {
+ const char_type placeholder[3] = { static_cast< char_type >('%'), (display_positive ? static_cast< char_type >('+') : static_cast< char_type >('-')), static_cast< char_type >('\0') };
+ on_placeholder(boost::as_literal(placeholder));
+ }
+
+ /*!
+ * \brief The function is called when the ISO time zone placeholder is found in the format string
+ */
+ virtual void on_iso_time_zone()
+ {
+ const char_type placeholder[3] = { static_cast< char_type >('%'), static_cast< char_type >('q'), static_cast< char_type >('\0') };
+ on_placeholder(boost::as_literal(placeholder));
+ }
+
+ /*!
+ * \brief The function is called when the extended ISO time zone placeholder is found in the format string
+ */
+ virtual void on_extended_iso_time_zone()
+ {
+ const char_type placeholder[3] = { static_cast< char_type >('%'), static_cast< char_type >('Q'), static_cast< char_type >('\0') };
+ on_placeholder(boost::as_literal(placeholder));
+ }
+
+ /*!
+ * \brief The function is called when the ISO-formatted time is found in the format string
+ */
+ virtual void on_iso_time()
+ {
+ on_hours(true);
+ on_minutes();
+ on_seconds();
+ }
+
+ /*!
+ * \brief The function is called when the extended ISO-formatted time is found in the format string
+ */
+ virtual void on_extended_iso_time()
+ {
+ const char_type delimiter[2] = { static_cast< char_type >(':'), static_cast< char_type >('\0') };
+ on_hours(true);
+ on_literal(boost::as_literal(delimiter));
+ on_minutes();
+ on_literal(boost::as_literal(delimiter));
+ on_seconds();
+ }
+
+ /*!
+ * \brief The function is called when the extended ISO-formatted time with fractional seconds is found in the format string
+ */
+ virtual void on_default_time()
+ {
+ on_extended_iso_time();
+
+ const char_type delimiter[2] = { static_cast< char_type >('.'), static_cast< char_type >('\0') };
+ on_literal(boost::as_literal(delimiter));
+ on_fractional_seconds();
+ }
+};
+
+/*!
+ * This is the interface the parser will use to notify the caller about various components of date in the format string.
+ */
+template< typename CharT >
+struct date_time_format_parser_callback :
+ public date_format_parser_callback< CharT >,
+ public time_format_parser_callback< CharT >
+{
+ //! Character type used by the parser
+ typedef CharT char_type;
+
+ //! Destructor
+ virtual ~date_time_format_parser_callback() {}
+
+ /*!
+ * \brief The function is called when the parser discovers a string literal in the format string
+ *
+ * \param lit The string of characters not interpreted as a placeholder
+ */
+ virtual void on_literal(iterator_range< const char_type* > const& lit) = 0;
+
+ /*!
+ * \brief The method is called when an unknown placeholder is found in the format string
+ *
+ * \param ph The placeholder with the leading percent sign
+ */
+ virtual void on_placeholder(iterator_range< const char_type* > const& ph)
+ {
+ // By default interpret all unrecognized placeholders as literals
+ on_literal(ph);
+ }
+};
+
+/*!
+ * \brief Parses the date format string and invokes the callback object
+ *
+ * \pre <tt>begin <= end</tt>, both pointers must not be \c NULL
+ * \param begin Pointer to the first character of the sequence
+ * \param end Pointer to the after-the-last character of the sequence
+ * \param callback Reference to the callback object that will be invoked by the parser as it processes the input
+ */
+template< typename CharT >
+BOOST_LOG_API void parse_date_format(const CharT* begin, const CharT* end, date_format_parser_callback< CharT >& callback);
+
+/*!
+ * \brief Parses the date format string and invokes the callback object
+ *
+ * \param str The format string to parse
+ * \param callback Reference to the callback object that will be invoked by the parser as it processes the input
+ */
+template< typename CharT, typename TraitsT, typename AllocatorT >
+inline void parse_date_format(std::basic_string< CharT, TraitsT, AllocatorT > const& str, date_format_parser_callback< CharT >& callback)
+{
+ const CharT* p = str.c_str();
+ return parse_date_format(p, p + str.size(), callback);
+}
+
+/*!
+ * \brief Parses the date format string and invokes the callback object
+ *
+ * \pre <tt>str != NULL</tt>, <tt>str</tt> points to a zero-terminated string.
+ * \param str The format string to parse
+ * \param callback Reference to the callback object that will be invoked by the parser as it processes the input
+ */
+template< typename CharT >
+inline void parse_date_format(const CharT* str, date_format_parser_callback< CharT >& callback)
+{
+ return parse_date_format(str, str + std::char_traits< CharT >::length(str), callback);
+}
+
+/*!
+ * \brief Parses the time format string and invokes the callback object
+ *
+ * \pre <tt>begin <= end</tt>, both pointers must not be \c NULL
+ * \param begin Pointer to the first character of the sequence
+ * \param end Pointer to the after-the-last character of the sequence
+ * \param callback Reference to the callback object that will be invoked by the parser as it processes the input
+ */
+template< typename CharT >
+BOOST_LOG_API void parse_time_format(const CharT* begin, const CharT* end, time_format_parser_callback< CharT >& callback);
+
+/*!
+ * \brief Parses the time format string and invokes the callback object
+ *
+ * \param str The format string to parse
+ * \param callback Reference to the callback object that will be invoked by the parser as it processes the input
+ */
+template< typename CharT, typename TraitsT, typename AllocatorT >
+inline void parse_time_format(std::basic_string< CharT, TraitsT, AllocatorT > const& str, time_format_parser_callback< CharT >& callback)
+{
+ const CharT* p = str.c_str();
+ return parse_time_format(p, p + str.size(), callback);
+}
+
+/*!
+ * \brief Parses the time format string and invokes the callback object
+ *
+ * \pre <tt>str != NULL</tt>, <tt>str</tt> points to a zero-terminated string.
+ * \param str The format string to parse
+ * \param callback Reference to the callback object that will be invoked by the parser as it processes the input
+ */
+template< typename CharT >
+inline void parse_time_format(const CharT* str, time_format_parser_callback< CharT >& callback)
+{
+ return parse_time_format(str, str + std::char_traits< CharT >::length(str), callback);
+}
+
+/*!
+ * \brief Parses the date and time format string and invokes the callback object
+ *
+ * \pre <tt>begin <= end</tt>, both pointers must not be \c NULL
+ * \param begin Pointer to the first character of the sequence
+ * \param end Pointer to the after-the-last character of the sequence
+ * \param callback Reference to the callback object that will be invoked by the parser as it processes the input
+ */
+template< typename CharT >
+BOOST_LOG_API void parse_date_time_format(const CharT* begin, const CharT* end, date_time_format_parser_callback< CharT >& callback);
+
+/*!
+ * \brief Parses the date and time format string and invokes the callback object
+ *
+ * \param str The format string to parse
+ * \param callback Reference to the callback object that will be invoked by the parser as it processes the input
+ */
+template< typename CharT, typename TraitsT, typename AllocatorT >
+inline void parse_date_time_format(std::basic_string< CharT, TraitsT, AllocatorT > const& str, date_time_format_parser_callback< CharT >& callback)
+{
+ const CharT* p = str.c_str();
+ return parse_date_time_format(p, p + str.size(), callback);
+}
+
+/*!
+ * \brief Parses the date and time format string and invokes the callback object
+ *
+ * \pre <tt>str != NULL</tt>, <tt>str</tt> points to a zero-terminated string.
+ * \param str The format string to parse
+ * \param callback Reference to the callback object that will be invoked by the parser as it processes the input
+ */
+template< typename CharT >
+inline void parse_date_time_format(const CharT* str, date_time_format_parser_callback< CharT >& callback)
+{
+ return parse_date_time_format(str, str + std::char_traits< CharT >::length(str), callback);
+}
+
+} // namespace aux
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_DETAIL_DATE_TIME_FORMAT_PARSER_HPP_INCLUDED_
diff --git a/boost/log/detail/decomposed_time.hpp b/boost/log/detail/decomposed_time.hpp
new file mode 100644
index 0000000..24f7546
--- /dev/null
+++ b/boost/log/detail/decomposed_time.hpp
@@ -0,0 +1,440 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file decomposed_time.hpp
+ * \author Andrey Semashev
+ * \date 07.11.2012
+ *
+ * \brief This header is the Boost.Log library implementation, see the library documentation
+ * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
+ */
+
+#ifndef BOOST_LOG_DETAIL_DECOMPOSED_TIME_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_DECOMPOSED_TIME_HPP_INCLUDED_
+
+#include <ctime>
+#include <string>
+#include <vector>
+#include <locale>
+#include <boost/cstdint.hpp>
+#include <boost/move/core.hpp>
+#include <boost/range/iterator_range_core.hpp>
+#include <boost/log/detail/config.hpp>
+#include <boost/log/detail/date_time_format_parser.hpp>
+#include <boost/log/utility/formatting_ostream.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace aux {
+
+//! Date and time suitable for formatting
+struct decomposed_time
+{
+ // Subseconds are microseconds
+ enum _
+ {
+ subseconds_per_second = 1000000,
+ subseconds_digits10 = 6
+ };
+
+ uint32_t year, month, day, hours, minutes, seconds, subseconds;
+ bool negative;
+
+ decomposed_time() : year(0), month(1), day(1), hours(0), minutes(0), seconds(0), subseconds(0), negative(false)
+ {
+ }
+
+ decomposed_time(uint32_t y, uint32_t mo, uint32_t d, uint32_t h, uint32_t mi, uint32_t s, uint32_t ss = 0, bool neg = false) :
+ year(y), month(mo), day(d), hours(h), minutes(mi), seconds(s), subseconds(ss), negative(neg)
+ {
+ }
+
+ unsigned int week_day() const
+ {
+ unsigned int a = (14u - month) / 12u;
+ unsigned int y = year - a;
+ unsigned int m = month + 12u * a - 2u;
+ return (day + y + (y / 4u) - (y / 100u) + (y / 400u) + (31u * m) / 12u) % 7u;
+ }
+
+ unsigned int year_day() const
+ {
+ bool is_leap_year = (!(year % 4u)) && ((year % 100u) || (!(year % 400u)));
+ static const unsigned int first_day_offset[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
+ return first_day_offset[month - 1] + day + (month > 2 && is_leap_year);
+ }
+};
+
+inline std::tm to_tm(decomposed_time const& t)
+{
+ std::tm res = {};
+ res.tm_year = static_cast< int >(t.year) - 1900;
+ res.tm_mon = t.month - 1;
+ res.tm_mday = t.day;
+ res.tm_hour = t.hours;
+ res.tm_min = t.minutes;
+ res.tm_sec = t.seconds;
+ res.tm_wday = t.week_day();
+ res.tm_yday = t.year_day();
+ res.tm_isdst = -1;
+
+ return res;
+}
+
+template< typename T >
+struct decomposed_time_wrapper :
+ public boost::log::aux::decomposed_time
+{
+ typedef boost::log::aux::decomposed_time base_type;
+ typedef T value_type;
+ value_type m_time;
+
+ BOOST_DEFAULTED_FUNCTION(decomposed_time_wrapper(), {})
+
+ explicit decomposed_time_wrapper(value_type const& time) : m_time(time)
+ {
+ }
+};
+
+template< typename CharT >
+BOOST_LOG_API void put_integer(std::basic_string< CharT >& str, uint32_t value, unsigned int width, CharT fill_char);
+
+template< typename T, typename CharT >
+class date_time_formatter
+{
+ BOOST_COPYABLE_AND_MOVABLE_ALT(date_time_formatter)
+
+protected:
+ // Note: This typedef is needed to work around MSVC 2012 crappy name lookup in the derived classes
+ typedef date_time_formatter date_time_formatter_;
+
+public:
+ typedef void result_type;
+ typedef T value_type;
+ typedef CharT char_type;
+ typedef std::basic_string< char_type > string_type;
+ typedef basic_formatting_ostream< char_type > stream_type;
+
+ struct context
+ {
+ date_time_formatter const& self;
+ stream_type& strm;
+ string_type& str;
+ value_type const& value;
+ unsigned int literal_index, literal_pos;
+
+ context(date_time_formatter const& self_, stream_type& strm_, value_type const& value_) :
+ self(self_),
+ strm(strm_),
+ str(*strm_.rdbuf()->storage()),
+ value(value_),
+ literal_index(0),
+ literal_pos(0)
+ {
+ }
+
+ BOOST_DELETED_FUNCTION(context(context const&))
+ BOOST_DELETED_FUNCTION(context& operator=(context const&))
+ };
+
+private:
+ typedef void (*formatter_type)(context&);
+ typedef std::vector< formatter_type > formatters;
+ typedef std::vector< unsigned int > literal_lens;
+
+protected:
+ formatters m_formatters;
+ literal_lens m_literal_lens;
+ string_type m_literal_chars;
+
+public:
+ BOOST_DEFAULTED_FUNCTION(date_time_formatter(), {})
+ date_time_formatter(date_time_formatter const& that) :
+ m_formatters(that.m_formatters),
+ m_literal_lens(that.m_literal_lens),
+ m_literal_chars(that.m_literal_chars)
+ {
+ }
+ date_time_formatter(BOOST_RV_REF(date_time_formatter) that)
+ {
+ this->swap(static_cast< date_time_formatter& >(that));
+ }
+
+ date_time_formatter& operator= (date_time_formatter that)
+ {
+ this->swap(that);
+ return *this;
+ }
+
+ result_type operator() (stream_type& strm, value_type const& value) const
+ {
+ // Some formatters will put characters directly to the underlying string, so we have to flush stream buffers before formatting
+ strm.flush();
+ context ctx(*this, strm, value);
+ for (typename formatters::const_iterator it = m_formatters.begin(), end = m_formatters.end(); strm.good() && it != end; ++it)
+ {
+ (*it)(ctx);
+ }
+ }
+
+ void add_formatter(formatter_type fun)
+ {
+ m_formatters.push_back(fun);
+ }
+
+ void add_literal(iterator_range< const char_type* > const& lit)
+ {
+ m_literal_chars.append(lit.begin(), lit.end());
+ m_literal_lens.push_back(static_cast< unsigned int >(lit.size()));
+ m_formatters.push_back(&date_time_formatter_::format_literal);
+ }
+
+ void swap(date_time_formatter& that)
+ {
+ m_formatters.swap(that.m_formatters);
+ m_literal_lens.swap(that.m_literal_lens);
+ m_literal_chars.swap(that.m_literal_chars);
+ }
+
+public:
+ template< char FormatCharV >
+ static void format_through_locale(context& ctx)
+ {
+ typedef std::time_put< char_type > facet_type;
+ typedef typename facet_type::iter_type iter_type;
+ std::tm t = to_tm(static_cast< decomposed_time const& >(ctx.value));
+ std::use_facet< facet_type >(ctx.strm.getloc()).put(iter_type(ctx.strm.stream()), ctx.strm.stream(), ' ', &t, FormatCharV);
+ ctx.strm.flush();
+ }
+
+ static void format_full_year(context& ctx)
+ {
+ (put_integer)(ctx.str, ctx.value.year, 4, static_cast< char_type >('0'));
+ }
+
+ static void format_short_year(context& ctx)
+ {
+ (put_integer)(ctx.str, ctx.value.year % 100u, 2, static_cast< char_type >('0'));
+ }
+
+ static void format_numeric_month(context& ctx)
+ {
+ (put_integer)(ctx.str, ctx.value.month, 2, static_cast< char_type >('0'));
+ }
+
+ template< char_type FillCharV >
+ static void format_month_day(context& ctx)
+ {
+ (put_integer)(ctx.str, ctx.value.day, 2, static_cast< char_type >(FillCharV));
+ }
+
+ static void format_week_day(context& ctx)
+ {
+ (put_integer)(ctx.str, static_cast< decomposed_time const& >(ctx.value).week_day(), 1, static_cast< char_type >('0'));
+ }
+
+ template< char_type FillCharV >
+ static void format_hours(context& ctx)
+ {
+ (put_integer)(ctx.str, ctx.value.hours, 2, static_cast< char_type >(FillCharV));
+ }
+
+ template< char_type FillCharV >
+ static void format_hours_12(context& ctx)
+ {
+ (put_integer)(ctx.str, ctx.value.hours % 12u + 1u, 2, static_cast< char_type >(FillCharV));
+ }
+
+ static void format_minutes(context& ctx)
+ {
+ (put_integer)(ctx.str, ctx.value.minutes, 2, static_cast< char_type >('0'));
+ }
+
+ static void format_seconds(context& ctx)
+ {
+ (put_integer)(ctx.str, ctx.value.seconds, 2, static_cast< char_type >('0'));
+ }
+
+ static void format_fractional_seconds(context& ctx)
+ {
+ (put_integer)(ctx.str, ctx.value.subseconds, decomposed_time::subseconds_digits10, static_cast< char_type >('0'));
+ }
+
+ template< bool UpperCaseV >
+ static void format_am_pm(context& ctx)
+ {
+ static const char_type am[] = { static_cast< char_type >(UpperCaseV ? 'A' : 'a'), static_cast< char_type >(UpperCaseV ? 'M' : 'm'), static_cast< char_type >(0) };
+ static const char_type pm[] = { static_cast< char_type >(UpperCaseV ? 'P' : 'p'), static_cast< char_type >(UpperCaseV ? 'M' : 'm'), static_cast< char_type >(0) };
+
+ ctx.str.append(((static_cast< decomposed_time const& >(ctx.value).hours > 11) ? pm : am), 2u);
+ }
+
+ template< bool DisplayPositiveV >
+ static void format_sign(context& ctx)
+ {
+ if (static_cast< decomposed_time const& >(ctx.value).negative)
+ ctx.str.push_back('-');
+ else if (DisplayPositiveV)
+ ctx.str.push_back('+');
+ }
+
+private:
+ static void format_literal(context& ctx)
+ {
+ unsigned int len = ctx.self.m_literal_lens[ctx.literal_index], pos = ctx.literal_pos;
+ ++ctx.literal_index;
+ ctx.literal_pos += len;
+ const char_type* lit = ctx.self.m_literal_chars.c_str();
+ ctx.str.append(lit + pos, len);
+ }
+};
+
+template< typename FormatterT, typename CharT >
+class decomposed_time_formatter_builder :
+ public date_time_format_parser_callback< CharT >
+{
+public:
+ typedef date_time_format_parser_callback< CharT > base_type;
+ typedef typename base_type::char_type char_type;
+ typedef FormatterT formatter_type;
+ typedef typename formatter_type::value_type value_type;
+ typedef typename formatter_type::stream_type stream_type;
+ typedef typename stream_type::string_type string_type;
+
+protected:
+ formatter_type& m_formatter;
+
+public:
+ explicit decomposed_time_formatter_builder(formatter_type& fmt) : m_formatter(fmt)
+ {
+ }
+
+ void on_literal(iterator_range< const char_type* > const& lit)
+ {
+ m_formatter.add_literal(lit);
+ }
+
+ void on_short_year()
+ {
+ m_formatter.add_formatter(&formatter_type::format_short_year);
+ }
+
+ void on_full_year()
+ {
+ m_formatter.add_formatter(&formatter_type::format_full_year);
+ }
+
+ void on_numeric_month()
+ {
+ m_formatter.add_formatter(&formatter_type::format_numeric_month);
+ }
+
+ void on_short_month()
+ {
+ m_formatter.add_formatter(&formatter_type::BOOST_NESTED_TEMPLATE format_through_locale< 'b' >);
+ }
+
+ void on_full_month()
+ {
+ m_formatter.add_formatter(&formatter_type::BOOST_NESTED_TEMPLATE format_through_locale< 'B' >);
+ }
+
+ void on_month_day(bool leading_zero)
+ {
+ if (leading_zero)
+ m_formatter.add_formatter(&formatter_type::BOOST_NESTED_TEMPLATE format_month_day< '0' >);
+ else
+ m_formatter.add_formatter(&formatter_type::BOOST_NESTED_TEMPLATE format_month_day< ' ' >);
+ }
+
+ void on_numeric_week_day()
+ {
+ m_formatter.add_formatter(&formatter_type::format_week_day);
+ }
+
+ void on_short_week_day()
+ {
+ m_formatter.add_formatter(&formatter_type::BOOST_NESTED_TEMPLATE format_through_locale< 'a' >);
+ }
+
+ void on_full_week_day()
+ {
+ m_formatter.add_formatter(&formatter_type::BOOST_NESTED_TEMPLATE format_through_locale< 'A' >);
+ }
+
+ void on_hours(bool leading_zero)
+ {
+ if (leading_zero)
+ m_formatter.add_formatter(&formatter_type::BOOST_NESTED_TEMPLATE format_hours< '0' >);
+ else
+ m_formatter.add_formatter(&formatter_type::BOOST_NESTED_TEMPLATE format_hours< ' ' >);
+ }
+
+ void on_hours_12(bool leading_zero)
+ {
+ if (leading_zero)
+ m_formatter.add_formatter(&formatter_type::BOOST_NESTED_TEMPLATE format_hours_12< '0' >);
+ else
+ m_formatter.add_formatter(&formatter_type::BOOST_NESTED_TEMPLATE format_hours_12< ' ' >);
+ }
+
+ void on_minutes()
+ {
+ m_formatter.add_formatter(&formatter_type::format_minutes);
+ }
+
+ void on_seconds()
+ {
+ m_formatter.add_formatter(&formatter_type::format_seconds);
+ }
+
+ void on_fractional_seconds()
+ {
+ m_formatter.add_formatter(&formatter_type::format_fractional_seconds);
+ }
+
+ void on_am_pm(bool upper_case)
+ {
+ if (upper_case)
+ m_formatter.add_formatter(&formatter_type::BOOST_NESTED_TEMPLATE format_am_pm< true >);
+ else
+ m_formatter.add_formatter(&formatter_type::BOOST_NESTED_TEMPLATE format_am_pm< false >);
+ }
+
+ void on_duration_sign(bool display_positive)
+ {
+ if (display_positive)
+ m_formatter.add_formatter(&formatter_type::BOOST_NESTED_TEMPLATE format_sign< true >);
+ else
+ m_formatter.add_formatter(&formatter_type::BOOST_NESTED_TEMPLATE format_sign< false >);
+ }
+
+ void on_iso_time_zone()
+ {
+ }
+
+ void on_extended_iso_time_zone()
+ {
+ }
+};
+
+} // namespace aux
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_DETAIL_DECOMPOSED_TIME_HPP_INCLUDED_
diff --git a/boost/log/detail/deduce_char_type.hpp b/boost/log/detail/deduce_char_type.hpp
new file mode 100644
index 0000000..cb02460
--- /dev/null
+++ b/boost/log/detail/deduce_char_type.hpp
@@ -0,0 +1,108 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file deduce_char_type.hpp
+ * \author Andrey Semashev
+ * \date 17.11.2012
+ *
+ * \brief This header is the Boost.Log library implementation, see the library documentation
+ * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
+ */
+
+#ifndef BOOST_LOG_DETAIL_DEDUCE_CHAR_TYPE_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_DEDUCE_CHAR_TYPE_HPP_INCLUDED_
+
+#include <boost/log/detail/config.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace aux {
+
+template< typename T >
+struct deduced_char_type;
+
+template< >
+struct deduced_char_type< char >
+{
+ typedef char type;
+};
+
+template< >
+struct deduced_char_type< const char >
+{
+ typedef char type;
+};
+
+template< >
+struct deduced_char_type< wchar_t >
+{
+ typedef wchar_t type;
+};
+
+template< >
+struct deduced_char_type< const wchar_t >
+{
+ typedef wchar_t type;
+};
+
+//! Auxiliary traits to detect character type from a string
+template< typename RangeT >
+struct deduce_char_type :
+ public deduced_char_type< typename RangeT::value_type >
+{
+};
+
+template< typename T >
+struct deduce_char_type< T* > :
+ public deduced_char_type< T >
+{
+};
+
+template< typename T >
+struct deduce_char_type< T* const > :
+ public deduced_char_type< T >
+{
+};
+
+template< typename T, unsigned int CountV >
+struct deduce_char_type< T[CountV] > :
+ public deduced_char_type< T >
+{
+};
+
+template< typename T >
+struct deduce_char_type< T& > :
+ public deduce_char_type< T >
+{
+};
+
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+
+template< typename T >
+struct deduce_char_type< T&& > :
+ public deduce_char_type< T >
+{
+};
+
+#endif
+
+} // namespace aux
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_DETAIL_DEDUCE_CHAR_TYPE_HPP_INCLUDED_
diff --git a/boost/log/detail/default_attribute_names.hpp b/boost/log/detail/default_attribute_names.hpp
new file mode 100644
index 0000000..c1fddd3
--- /dev/null
+++ b/boost/log/detail/default_attribute_names.hpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file default_attribute_names.hpp
+ * \author Andrey Semashev
+ * \date 15.01.2012
+ *
+ * \brief This header is the Boost.Log library implementation, see the library documentation
+ * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
+ */
+
+#ifndef BOOST_LOG_DETAIL_DEFAULT_ATTRIBUTE_NAMES_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_DEFAULT_ATTRIBUTE_NAMES_HPP_INCLUDED_
+
+#include <boost/log/detail/config.hpp>
+#include <boost/log/attributes/attribute_name.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace aux {
+
+namespace default_attribute_names {
+
+BOOST_LOG_API attribute_name severity();
+BOOST_LOG_API attribute_name channel();
+BOOST_LOG_API attribute_name message();
+BOOST_LOG_API attribute_name line_id();
+BOOST_LOG_API attribute_name timestamp();
+BOOST_LOG_API attribute_name process_id();
+BOOST_LOG_API attribute_name thread_id();
+
+} // namespace default_attribute_names
+
+} // namespace aux
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_DETAIL_DEFAULT_ATTRIBUTE_NAMES_HPP_INCLUDED_
diff --git a/boost/log/detail/embedded_string_type.hpp b/boost/log/detail/embedded_string_type.hpp
new file mode 100644
index 0000000..091dce2
--- /dev/null
+++ b/boost/log/detail/embedded_string_type.hpp
@@ -0,0 +1,125 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file embedded_string_type.hpp
+ * \author Andrey Semashev
+ * \date 16.08.2009
+ *
+ * This header is the Boost.Log library implementation, see the library documentation
+ * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
+ */
+
+#ifndef BOOST_LOG_DETAIL_EMBEDDED_STRING_TYPE_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_EMBEDDED_STRING_TYPE_HPP_INCLUDED_
+
+#include <string>
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/log/detail/config.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace aux {
+
+template< typename T, typename ArgT >
+struct make_embedded_string_type_impl
+{
+ typedef ArgT type;
+};
+
+template< typename ArgT >
+struct make_embedded_string_type_impl< char, ArgT >
+{
+ typedef std::basic_string< char > type;
+};
+
+template< typename ArgT >
+struct make_embedded_string_type_impl< const char, ArgT >
+{
+ typedef std::basic_string< char > type;
+};
+
+template< typename ArgT >
+struct make_embedded_string_type_impl< wchar_t, ArgT >
+{
+ typedef std::basic_string< wchar_t > type;
+};
+
+template< typename ArgT >
+struct make_embedded_string_type_impl< const wchar_t, ArgT >
+{
+ typedef std::basic_string< wchar_t > type;
+};
+
+#if !defined(BOOST_NO_CXX11_CHAR16_T)
+template< typename ArgT >
+struct make_embedded_string_type_impl< char16_t, ArgT >
+{
+ typedef std::basic_string< char16_t > type;
+};
+
+template< typename ArgT >
+struct make_embedded_string_type_impl< const char16_t, ArgT >
+{
+ typedef std::basic_string< char16_t > type;
+};
+#endif
+
+#if !defined(BOOST_NO_CXX11_CHAR32_T)
+template< typename ArgT >
+struct make_embedded_string_type_impl< char32_t, ArgT >
+{
+ typedef std::basic_string< char32_t > type;
+};
+
+template< typename ArgT >
+struct make_embedded_string_type_impl< const char32_t, ArgT >
+{
+ typedef std::basic_string< char32_t > type;
+};
+#endif
+
+//! An auxiliary type translator to store strings by value in function objects and attribute values
+template< typename ArgT >
+struct make_embedded_string_type :
+ public remove_cv< ArgT >
+{
+};
+
+template< typename ArgT >
+struct make_embedded_string_type< ArgT* > :
+ public make_embedded_string_type_impl< ArgT, ArgT* >
+{
+};
+
+template< typename ArgT, unsigned int CountV >
+struct make_embedded_string_type< ArgT[CountV] > :
+ public make_embedded_string_type_impl< ArgT, ArgT[CountV] >
+{
+};
+
+template< typename ArgT, unsigned int CountV >
+struct make_embedded_string_type< ArgT(&)[CountV] > :
+ public make_embedded_string_type_impl< ArgT, ArgT(&)[CountV] >
+{
+};
+
+} // namespace aux
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_DETAIL_EMBEDDED_STRING_TYPE_HPP_INCLUDED_
diff --git a/boost/log/detail/enqueued_record.hpp b/boost/log/detail/enqueued_record.hpp
new file mode 100644
index 0000000..11aaf18
--- /dev/null
+++ b/boost/log/detail/enqueued_record.hpp
@@ -0,0 +1,103 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file enqueued_record.hpp
+ * \author Andrey Semashev
+ * \date 01.04.2014
+ *
+ * \brief This header is the Boost.Log library implementation, see the library documentation
+ * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html. In this file
+ * internal configuration macros are defined.
+ */
+
+#ifndef BOOST_LOG_DETAIL_ENQUEUED_RECORD_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_ENQUEUED_RECORD_HPP_INCLUDED_
+
+#include <boost/move/core.hpp>
+#include <boost/move/utility.hpp>
+#include <boost/log/detail/config.hpp>
+#include <boost/log/detail/timestamp.hpp>
+#include <boost/log/core/record_view.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace sinks {
+
+namespace aux {
+
+//! Log record with enqueueing timestamp
+class enqueued_record
+{
+ BOOST_COPYABLE_AND_MOVABLE(enqueued_record)
+
+public:
+ //! Ordering predicate
+ template< typename OrderT >
+ struct order :
+ public OrderT
+ {
+ typedef typename OrderT::result_type result_type;
+
+ order() {}
+ order(order const& that) : OrderT(static_cast< OrderT const& >(that)) {}
+ order(OrderT const& that) : OrderT(that) {}
+
+ result_type operator() (enqueued_record const& left, enqueued_record const& right) const
+ {
+ // std::priority_queue requires ordering with semantics of std::greater, so we swap arguments
+ return OrderT::operator() (right.m_record, left.m_record);
+ }
+ };
+
+ boost::log::aux::timestamp m_timestamp;
+ record_view m_record;
+
+ enqueued_record(enqueued_record const& that) : m_timestamp(that.m_timestamp), m_record(that.m_record)
+ {
+ }
+ enqueued_record(BOOST_RV_REF(enqueued_record) that) :
+ m_timestamp(that.m_timestamp),
+ m_record(boost::move(that.m_record))
+ {
+ }
+ explicit enqueued_record(record_view const& rec) :
+ m_timestamp(boost::log::aux::get_timestamp()),
+ m_record(rec)
+ {
+ }
+ enqueued_record& operator= (BOOST_COPY_ASSIGN_REF(enqueued_record) that)
+ {
+ m_timestamp = that.m_timestamp;
+ m_record = that.m_record;
+ return *this;
+ }
+ enqueued_record& operator= (BOOST_RV_REF(enqueued_record) that)
+ {
+ m_timestamp = that.m_timestamp;
+ m_record = boost::move(that.m_record);
+ return *this;
+ }
+};
+
+} // namespace aux
+
+} // namespace sinks
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_DETAIL_ENQUEUED_RECORD_HPP_INCLUDED_
diff --git a/boost/log/detail/event.hpp b/boost/log/detail/event.hpp
new file mode 100644
index 0000000..741ab3c
--- /dev/null
+++ b/boost/log/detail/event.hpp
@@ -0,0 +1,142 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file detail/event.hpp
+ * \author Andrey Semashev
+ * \date 24.07.2011
+ */
+
+#ifndef BOOST_LOG_DETAIL_EVENT_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_EVENT_HPP_INCLUDED_
+
+#include <boost/log/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#ifndef BOOST_LOG_NO_THREADS
+
+#if defined(BOOST_THREAD_PLATFORM_PTHREAD)
+# if defined(_POSIX_SEMAPHORES) && (_POSIX_SEMAPHORES + 0) > 0
+# if defined(__GNUC__) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
+# include <semaphore.h>
+# include <boost/cstdint.hpp>
+# define BOOST_LOG_EVENT_USE_POSIX_SEMAPHORE
+# endif
+# endif
+#elif defined(BOOST_THREAD_PLATFORM_WIN32)
+# include <boost/cstdint.hpp>
+# define BOOST_LOG_EVENT_USE_WINAPI
+#endif
+
+#if !defined(BOOST_LOG_EVENT_USE_POSIX_SEMAPHORE) && !defined(BOOST_LOG_EVENT_USE_WINAPI)
+# include <boost/thread/mutex.hpp>
+# include <boost/thread/condition_variable.hpp>
+# define BOOST_LOG_EVENT_USE_BOOST_CONDITION
+#endif
+
+#include <boost/log/detail/header.hpp>
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace aux {
+
+#if defined(BOOST_LOG_EVENT_USE_POSIX_SEMAPHORE)
+
+class sem_based_event
+{
+private:
+ boost::uint32_t m_state;
+ sem_t m_semaphore;
+
+public:
+ //! Default constructor
+ BOOST_LOG_API sem_based_event();
+ //! Destructor
+ BOOST_LOG_API ~sem_based_event();
+
+ //! Waits for the object to become signalled
+ BOOST_LOG_API void wait();
+ //! Sets the object to a signalled state
+ BOOST_LOG_API void set_signalled();
+
+ // Copying prohibited
+ BOOST_DELETED_FUNCTION(sem_based_event(sem_based_event const&))
+ BOOST_DELETED_FUNCTION(sem_based_event& operator= (sem_based_event const&))
+};
+
+typedef sem_based_event event;
+
+#elif defined(BOOST_LOG_EVENT_USE_WINAPI)
+
+class winapi_based_event
+{
+private:
+ boost::uint32_t m_state;
+ void* m_event;
+
+public:
+ //! Default constructor
+ BOOST_LOG_API winapi_based_event();
+ //! Destructor
+ BOOST_LOG_API ~winapi_based_event();
+
+ //! Waits for the object to become signalled
+ BOOST_LOG_API void wait();
+ //! Sets the object to a signalled state
+ BOOST_LOG_API void set_signalled();
+
+ // Copying prohibited
+ BOOST_DELETED_FUNCTION(winapi_based_event(winapi_based_event const&))
+ BOOST_DELETED_FUNCTION(winapi_based_event& operator= (winapi_based_event const&))
+};
+
+typedef winapi_based_event event;
+
+#else
+
+class generic_event
+{
+private:
+ boost::mutex m_mutex;
+ boost::condition_variable m_cond;
+ bool m_state;
+
+public:
+ //! Default constructor
+ BOOST_LOG_API generic_event();
+ //! Destructor
+ BOOST_LOG_API ~generic_event();
+
+ //! Waits for the object to become signalled
+ BOOST_LOG_API void wait();
+ //! Sets the object to a signalled state
+ BOOST_LOG_API void set_signalled();
+
+ // Copying prohibited
+ BOOST_DELETED_FUNCTION(generic_event(generic_event const&))
+ BOOST_DELETED_FUNCTION(generic_event& operator= (generic_event const&))
+};
+
+typedef generic_event event;
+
+#endif
+
+} // namespace aux
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_NO_THREADS
+
+#endif // BOOST_LOG_DETAIL_EVENT_HPP_INCLUDED_
diff --git a/boost/log/detail/fake_mutex.hpp b/boost/log/detail/fake_mutex.hpp
new file mode 100644
index 0000000..f21f961
--- /dev/null
+++ b/boost/log/detail/fake_mutex.hpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file fake_mutex.hpp
+ * \author Andrey Semashev
+ * \date 31.07.2011
+ *
+ * \brief This header is the Boost.Log library implementation, see the library documentation
+ * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
+ */
+
+#ifndef BOOST_LOG_DETAIL_FAKE_MUTEX_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_FAKE_MUTEX_HPP_INCLUDED_
+
+#include <boost/log/detail/config.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace aux {
+
+//! Fake mutex that doesn't do anything. Note: we're not using \c null_mutex from Boost.Thread in order not to introduce false dependencies on Boost.Thread and Boost.Chrono.
+class fake_mutex
+{
+public:
+ BOOST_DEFAULTED_FUNCTION(fake_mutex(), {})
+ void lock() {}
+ bool try_lock() { return true; }
+ template< typename T >
+ bool timed_lock(T const&) { return true; }
+ void unlock() {}
+
+ // Copying prohibited
+ BOOST_DELETED_FUNCTION(fake_mutex(fake_mutex const&))
+ BOOST_DELETED_FUNCTION(fake_mutex& operator=(fake_mutex const&))
+};
+
+} // namespace aux
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_DETAIL_FAKE_MUTEX_HPP_INCLUDED_
diff --git a/boost/log/detail/footer.hpp b/boost/log/detail/footer.hpp
new file mode 100644
index 0000000..8208ebd
--- /dev/null
+++ b/boost/log/detail/footer.hpp
@@ -0,0 +1,22 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+#if !defined(BOOST_LOG_ENABLE_WARNINGS)
+
+#if defined(_MSC_VER)
+
+#pragma warning(pop)
+
+#elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 406
+
+#pragma GCC diagnostic pop
+
+#endif
+
+#endif // !defined(BOOST_LOG_ENABLE_WARNINGS)
+
+#include <boost/config/abi_suffix.hpp>
diff --git a/boost/log/detail/format.hpp b/boost/log/detail/format.hpp
new file mode 100644
index 0000000..d383aba
--- /dev/null
+++ b/boost/log/detail/format.hpp
@@ -0,0 +1,336 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file format.hpp
+ * \author Andrey Semashev
+ * \date 15.11.2012
+ *
+ * \brief This header is the Boost.Log library implementation, see the library documentation
+ * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
+ */
+
+#ifndef BOOST_LOG_DETAIL_FORMAT_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_FORMAT_HPP_INCLUDED_
+
+#include <string>
+#include <vector>
+#include <iosfwd>
+#include <boost/assert.hpp>
+#include <boost/move/core.hpp>
+#include <boost/move/utility.hpp>
+#include <boost/log/detail/config.hpp>
+#include <boost/log/detail/unhandled_exception_count.hpp>
+#include <boost/log/detail/cleanup_scope_guard.hpp>
+#include <boost/log/utility/formatting_ostream.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace aux {
+
+//! An element (either literal or placeholder) of the format string
+struct format_element
+{
+ //! Argument placeholder number or -1 if it's not a placeholder (i.e. a literal)
+ int arg_number;
+ //! If the element describes a constant literal, the starting character and length of the literal
+ unsigned int literal_start_pos, literal_len;
+
+ format_element() : arg_number(0), literal_start_pos(0), literal_len(0)
+ {
+ }
+
+ static format_element literal(unsigned int start_pos, unsigned int len)
+ {
+ format_element el;
+ el.arg_number = -1;
+ el.literal_start_pos = start_pos;
+ el.literal_len = len;
+ return el;
+ }
+
+ static format_element positional_argument(unsigned int arg_n)
+ {
+ format_element el;
+ el.arg_number = arg_n;
+ return el;
+ }
+};
+
+//! Parsed format string description
+template< typename CharT >
+struct format_description
+{
+ BOOST_COPYABLE_AND_MOVABLE_ALT(format_description)
+
+public:
+ //! Character type
+ typedef CharT char_type;
+ //! String type
+ typedef std::basic_string< char_type > string_type;
+
+ //! Array of format element descriptors
+ typedef std::vector< format_element > format_element_list;
+
+ //! Characters of all literal parts of the format string
+ string_type literal_chars;
+ //! Format element descriptors
+ format_element_list format_elements;
+
+ BOOST_DEFAULTED_FUNCTION(format_description(), {})
+
+ format_description(format_description const& that) : literal_chars(that.literal_chars), format_elements(that.format_elements)
+ {
+ }
+
+ format_description(BOOST_RV_REF(format_description) that)
+ {
+ literal_chars.swap(that.literal_chars);
+ format_elements.swap(that.format_elements);
+ }
+
+ format_description& operator= (format_description that)
+ {
+ literal_chars.swap(that.literal_chars);
+ format_elements.swap(that.format_elements);
+ return *this;
+ }
+};
+
+//! Parses format string
+template< typename CharT >
+BOOST_LOG_API format_description< CharT > parse_format(const CharT* begin, const CharT* end);
+
+//! Parses format string
+template< typename CharT >
+BOOST_FORCEINLINE format_description< CharT > parse_format(const CharT* begin)
+{
+ return parse_format(begin, begin + std::char_traits< CharT >::length(begin));
+}
+
+//! Parses format string
+template< typename CharT, typename TraitsT, typename AllocatorT >
+BOOST_FORCEINLINE format_description< CharT > parse_format(std::basic_string< CharT, TraitsT, AllocatorT > const& fmt)
+{
+ const CharT* begin = fmt.c_str();
+ return parse_format(begin, begin + fmt.size());
+}
+
+//! Formatter object
+template< typename CharT >
+class basic_format
+{
+public:
+ //! Character type
+ typedef CharT char_type;
+ //! String type
+ typedef std::basic_string< char_type > string_type;
+ //! Stream type
+ typedef basic_formatting_ostream< char_type > stream_type;
+ //! Format description type
+ typedef format_description< char_type > format_description_type;
+
+ //! The pump receives arguments and formats them into strings. At destruction the pump composes the final string in the attached stream.
+ class pump;
+ friend class pump;
+
+private:
+ //! Formatting params for a single placeholder in the format string
+ struct formatting_params
+ {
+ //! Formatting element index in the format description
+ unsigned int element_idx;
+ //! Formatting result
+ string_type target;
+
+ formatting_params() : element_idx(~0u) {}
+ };
+ typedef std::vector< formatting_params > formatting_params_list;
+
+private:
+ //! Format string description
+ format_description_type m_format;
+ //! Formatting parameters for all placeholders
+ formatting_params_list m_formatting_params;
+ //! Current formatting position
+ unsigned int m_current_idx;
+
+public:
+ //! Initializing constructor
+ explicit basic_format(string_type const& fmt) : m_format(aux::parse_format(fmt)), m_current_idx(0)
+ {
+ init_params();
+ }
+ //! Initializing constructor
+ explicit basic_format(const char_type* fmt) : m_format(aux::parse_format(fmt)), m_current_idx(0)
+ {
+ init_params();
+ }
+
+ //! Clears all formatted strings and resets the current formatting position
+ void clear() BOOST_NOEXCEPT
+ {
+ for (typename formatting_params_list::iterator it = m_formatting_params.begin(), end = m_formatting_params.end(); it != end; ++it)
+ {
+ it->target.clear();
+ }
+ m_current_idx = 0;
+ }
+
+ //! Creates a pump that will receive all format arguments and put the formatted string into the stream
+ pump make_pump(stream_type& strm) BOOST_NOEXCEPT
+ {
+ return pump(*this, strm);
+ }
+
+ //! Composes the final string from the formatted pieces
+ void compose(string_type& str) const
+ {
+ typename format_description_type::format_element_list::const_iterator it = m_format.format_elements.begin(), end = m_format.format_elements.end();
+ for (; it != end; ++it)
+ {
+ if (it->arg_number >= 0)
+ {
+ // This is a placeholder
+ str.append(m_formatting_params[it->arg_number].target);
+ }
+ else
+ {
+ // This is a literal
+ const char_type* p = m_format.literal_chars.c_str() + it->literal_start_pos;
+ str.append(p, it->literal_len);
+ }
+ }
+ }
+
+ //! Composes the final string from the formatted pieces
+ string_type str() const
+ {
+ string_type result;
+ compose(result);
+ return boost::move(result);
+ }
+
+private:
+ //! Initializes the formatting params
+ void init_params()
+ {
+ typename format_description_type::format_element_list::const_iterator it = m_format.format_elements.begin(), end = m_format.format_elements.end();
+ for (; it != end; ++it)
+ {
+ if (it->arg_number >= 0)
+ {
+ if (static_cast< unsigned int >(it->arg_number) >= m_formatting_params.size())
+ m_formatting_params.resize(it->arg_number + 1);
+ m_formatting_params[it->arg_number].element_idx = static_cast< unsigned int >(it - m_format.format_elements.begin());
+ }
+ }
+ }
+};
+
+//! The pump receives arguments and formats them into strings. At destruction the pump composes the final string in the attached stream.
+template< typename CharT >
+class basic_format< CharT >::pump
+{
+ BOOST_MOVABLE_BUT_NOT_COPYABLE(pump)
+
+private:
+ //! The guard temporarily replaces storage string in the specified stream
+ struct scoped_storage
+ {
+ scoped_storage(stream_type& strm, string_type& storage) : m_stream(strm), m_storage_backup(*strm.rdbuf()->storage())
+ {
+ strm.attach(storage);
+ }
+ ~scoped_storage()
+ {
+ m_stream.attach(m_storage_backup);
+ }
+
+ private:
+ stream_type& m_stream;
+ string_type& m_storage_backup;
+ };
+
+private:
+ //! Reference to the owner
+ basic_format* m_owner;
+ //! Reference to the stream
+ stream_type* m_stream;
+ //! Unhandled exception count
+ const unsigned int m_exception_count;
+
+public:
+ //! Initializing constructor
+ pump(basic_format& owner, stream_type& strm) BOOST_NOEXCEPT : m_owner(&owner), m_stream(&strm), m_exception_count(unhandled_exception_count())
+ {
+ }
+
+ //! Move constructor
+ pump(BOOST_RV_REF(pump) that) BOOST_NOEXCEPT : m_owner(that.m_owner), m_stream(that.m_stream), m_exception_count(that.m_exception_count)
+ {
+ that.m_owner = NULL;
+ that.m_stream = NULL;
+ }
+
+ //! Destructor
+ ~pump() BOOST_NOEXCEPT_IF(false)
+ {
+ if (m_owner)
+ {
+ // Whether or not the destructor is called because of an exception, the format object has to be cleared
+ boost::log::aux::cleanup_guard< basic_format< char_type > > cleanup1(*m_owner);
+
+ BOOST_ASSERT(m_stream != NULL);
+ if (m_exception_count >= unhandled_exception_count())
+ {
+ // Compose the final string in the stream buffer
+ m_stream->flush();
+ m_owner->compose(*m_stream->rdbuf()->storage());
+ }
+ }
+ }
+
+ /*!
+ * Puts an argument to the formatter. Note the pump has to be returned by value and not by reference in order this to
+ * work with Boost.Phoenix expressions. Otherwise the pump that is returned from \c basic_format::make_pump is
+ * destroyed after the first call to \c operator%, and the returned reference becomes dangling.
+ */
+ template< typename T >
+ pump operator% (T const& val)
+ {
+ BOOST_ASSERT_MSG(m_owner != NULL && m_stream != NULL, "Boost.Log: This basic_format::pump has already been moved from");
+
+ if (m_owner->m_current_idx < m_owner->m_formatting_params.size())
+ {
+ scoped_storage storage_guard(*m_stream, m_owner->m_formatting_params[m_owner->m_current_idx].target);
+
+ *m_stream << val;
+ m_stream->flush();
+
+ ++m_owner->m_current_idx;
+ }
+
+ return boost::move(*this);
+ }
+};
+
+} // namespace aux
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_DETAIL_FORMAT_HPP_INCLUDED_
diff --git a/boost/log/detail/function_traits.hpp b/boost/log/detail/function_traits.hpp
new file mode 100644
index 0000000..bd298fc
--- /dev/null
+++ b/boost/log/detail/function_traits.hpp
@@ -0,0 +1,236 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file function_traits.hpp
+ * \author Andrey Semashev
+ * \date 30.08.2009
+ *
+ * \brief This header is the Boost.Log library implementation, see the library documentation
+ * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
+ */
+
+#ifndef BOOST_LOG_DETAIL_FUNCTION_TRAITS_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_FUNCTION_TRAITS_HPP_INCLUDED_
+
+#include <boost/mpl/has_xxx.hpp>
+#include <boost/log/detail/config.hpp>
+
+#if defined(BOOST_NO_SFINAE) || defined(BOOST_MPL_CFG_NO_HAS_XXX)
+# if !defined(BOOST_LOG_NO_FUNCTION_TRAITS)
+# define BOOST_LOG_NO_FUNCTION_TRAITS
+# endif
+#else
+
+#include <boost/mpl/int.hpp>
+#include <boost/mpl/front.hpp>
+#include <boost/mpl/pop_front.hpp>
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/function_types/function_arity.hpp>
+#include <boost/function_types/parameter_types.hpp>
+#include <boost/function_types/is_nonmember_callable_builtin.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace aux {
+
+ // A number of traits to deal with functors
+ BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_argument_type, argument_type, false)
+ BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_first_argument_type, first_argument_type, false)
+ BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_second_argument_type, second_argument_type, false)
+ BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_arg1_type, arg1_type, false)
+ BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_arg2_type, arg2_type, false)
+
+ namespace has_arity_no_adl {
+
+ typedef char yes_type;
+ struct no_type
+ {
+ char dummy[2];
+ };
+
+ template< typename FunT, int ArityV = FunT::arity >
+ struct checker
+ {
+ };
+
+ template< typename FunT >
+ yes_type has_arity_impl(FunT const&, checker< FunT >*);
+ template< typename FunT >
+ no_type has_arity_impl(FunT const&, ...);
+
+ } // namespace has_arity_no_adl
+
+ //! The metafunction detects if the type has an arity static constant member
+ template< typename FunT >
+ struct has_arity
+ {
+ static FunT const& get_FunT();
+
+ enum value_t { value = (sizeof(has_arity_no_adl::has_arity_impl(get_FunT(), 0)) == sizeof(has_arity_no_adl::yes_type)) };
+ typedef mpl::bool_< value > type;
+ };
+
+ //! The metafunction results in an unqualified type with removed reference
+ template< typename T >
+ struct root_type :
+ public remove_cv<
+ typename remove_reference<
+ T
+ >::type
+ >
+ {
+ };
+
+ template<
+ typename FunT,
+ bool = function_types::is_nonmember_callable_builtin< FunT >::value,
+ bool = has_argument_type< FunT >::value,
+ bool = has_first_argument_type< FunT >::value,
+ bool = has_arg1_type< FunT >::value
+ >
+ struct first_argument_type_of_impl
+ {
+ };
+ template< typename FunT >
+ struct first_argument_type_of_impl< FunT, true, false, false, false >
+ {
+ typedef typename root_type<
+ typename mpl::front<
+ typename function_types::parameter_types< FunT >::type
+ >::type
+ >::type type;
+ };
+ template< typename FunT, bool HasFirstArgumentV, bool HasArg1V >
+ struct first_argument_type_of_impl< FunT, false, true, HasFirstArgumentV, HasArg1V >
+ {
+ typedef typename root_type<
+ typename FunT::argument_type
+ >::type type;
+ };
+ template< typename FunT, bool HasArg1V >
+ struct first_argument_type_of_impl< FunT, false, false, true, HasArg1V >
+ {
+ typedef typename root_type<
+ typename FunT::first_argument_type
+ >::type type;
+ };
+ template< typename FunT >
+ struct first_argument_type_of_impl< FunT, false, false, false, true >
+ {
+ typedef typename root_type<
+ typename FunT::arg1_type
+ >::type type;
+ };
+
+ //! The metafunction returns the first argument type of a function
+ template< typename FunT >
+ struct first_argument_type_of :
+ public first_argument_type_of_impl< FunT >
+ {
+ };
+
+
+ template<
+ typename FunT,
+ bool = function_types::is_nonmember_callable_builtin< FunT >::value,
+ bool = has_second_argument_type< FunT >::value,
+ bool = has_arg2_type< FunT >::value
+ >
+ struct second_argument_type_of_impl
+ {
+ };
+ template< typename FunT >
+ struct second_argument_type_of_impl< FunT, true, false, false >
+ {
+ typedef typename root_type<
+ typename mpl::front<
+ typename mpl::pop_front<
+ typename function_types::parameter_types< FunT >::type
+ >::type
+ >::type
+ >::type type;
+ };
+ template< typename FunT, bool HasArg2V >
+ struct second_argument_type_of_impl< FunT, false, true, HasArg2V >
+ {
+ typedef typename root_type<
+ typename FunT::second_argument_type
+ >::type type;
+ };
+ template< typename FunT >
+ struct second_argument_type_of_impl< FunT, false, false, true >
+ {
+ typedef typename root_type<
+ typename FunT::arg2_type
+ >::type type;
+ };
+
+ //! The metafunction returns the second argument type of a function
+ template< typename FunT >
+ struct second_argument_type_of :
+ public second_argument_type_of_impl< FunT >
+ {
+ };
+
+
+ template<
+ typename FunT,
+ bool = function_types::is_nonmember_callable_builtin< FunT >::value,
+ bool = has_arity< FunT >::value,
+ bool = has_argument_type< FunT >::value,
+ bool = has_second_argument_type< FunT >::value
+ >
+ struct arity_of_impl
+ {
+ };
+ template< typename FunT >
+ struct arity_of_impl< FunT, true, false, false, false > :
+ public function_types::function_arity< FunT >
+ {
+ };
+ template< typename FunT, bool HasArgumentTypeV, bool HasSecondArgumentTypeV >
+ struct arity_of_impl< FunT, false, true, HasArgumentTypeV, HasSecondArgumentTypeV > :
+ public mpl::int_< FunT::arity >
+ {
+ };
+ template< typename FunT, bool HasArgumentTypeV >
+ struct arity_of_impl< FunT, false, false, HasArgumentTypeV, true > :
+ public mpl::int_< 2 >
+ {
+ };
+ template< typename FunT >
+ struct arity_of_impl< FunT, false, false, true, false > :
+ public mpl::int_< 1 >
+ {
+ };
+
+ //! The metafunction returns the arity of a function
+ template< typename FunT >
+ struct arity_of :
+ public arity_of_impl< FunT >
+ {
+ };
+
+} // namespace aux
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // defined(BOOST_NO_SFINAE) || defined(BOOST_MPL_CFG_NO_HAS_XXX)
+
+#endif // BOOST_LOG_DETAIL_FUNCTION_TRAITS_HPP_INCLUDED_
diff --git a/boost/log/detail/generate_overloads.hpp b/boost/log/detail/generate_overloads.hpp
new file mode 100644
index 0000000..63b9edf
--- /dev/null
+++ b/boost/log/detail/generate_overloads.hpp
@@ -0,0 +1,30 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+BOOST_LOG_AUX_OVERLOAD(const&, const&)
+BOOST_LOG_AUX_OVERLOAD(&, const&)
+BOOST_LOG_AUX_OVERLOAD(const&, &)
+BOOST_LOG_AUX_OVERLOAD(&, &)
+
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+
+BOOST_LOG_AUX_OVERLOAD(const&&, const&&)
+BOOST_LOG_AUX_OVERLOAD(&&, const&&)
+BOOST_LOG_AUX_OVERLOAD(const&&, &&)
+BOOST_LOG_AUX_OVERLOAD(&&, &&)
+
+BOOST_LOG_AUX_OVERLOAD(const&&, const&)
+BOOST_LOG_AUX_OVERLOAD(&&, const&)
+BOOST_LOG_AUX_OVERLOAD(const&&, &)
+BOOST_LOG_AUX_OVERLOAD(&&, &)
+
+BOOST_LOG_AUX_OVERLOAD(const&, const&&)
+BOOST_LOG_AUX_OVERLOAD(&, const&&)
+BOOST_LOG_AUX_OVERLOAD(const&, &&)
+BOOST_LOG_AUX_OVERLOAD(&, &&)
+
+#endif // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
diff --git a/boost/log/detail/header.hpp b/boost/log/detail/header.hpp
new file mode 100644
index 0000000..f7cf75d
--- /dev/null
+++ b/boost/log/detail/header.hpp
@@ -0,0 +1,64 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+#include <boost/config/abi_prefix.hpp>
+
+#if !defined(BOOST_LOG_ENABLE_WARNINGS)
+
+#if defined(_MSC_VER)
+
+#pragma warning(push, 3)
+// 'm_A' : class 'A' needs to have dll-interface to be used by clients of class 'B'
+#pragma warning(disable: 4251)
+// non dll-interface class 'A' used as base for dll-interface class 'B'
+#pragma warning(disable: 4275)
+// switch statement contains 'default' but no 'case' labels
+#pragma warning(disable: 4065)
+// 'this' : used in base member initializer list
+#pragma warning(disable: 4355)
+// 'int' : forcing value to bool 'true' or 'false' (performance warning)
+#pragma warning(disable: 4800)
+// unreferenced formal parameter
+#pragma warning(disable: 4100)
+// conditional expression is constant
+#pragma warning(disable: 4127)
+// default constructor could not be generated
+#pragma warning(disable: 4510)
+// copy constructor could not be generated
+#pragma warning(disable: 4511)
+// assignment operator could not be generated
+#pragma warning(disable: 4512)
+// struct 'A' can never be instantiated - user defined constructor required
+#pragma warning(disable: 4610)
+// function marked as __forceinline not inlined
+#pragma warning(disable: 4714)
+// decorated name length exceeded, name was truncated
+#pragma warning(disable: 4503)
+// declaration of 'A' hides previous local declaration
+#pragma warning(disable: 4456)
+// declaration of 'A' hides global declaration
+#pragma warning(disable: 4459)
+
+#elif defined(__GNUC__) && !(defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC)) \
+ && (__GNUC__ * 100 + __GNUC_MINOR__) >= 406
+
+#pragma GCC diagnostic push
+// 'var' defined but not used
+#pragma GCC diagnostic ignored "-Wunused-variable"
+// unused parameter 'arg'
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+// missing initializer for member var
+#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
+
+#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 407
+// typedef 'foo' locally defined but not used
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#endif
+
+#endif
+
+#endif // !defined(BOOST_LOG_ENABLE_WARNINGS)
diff --git a/boost/log/detail/id.hpp b/boost/log/detail/id.hpp
new file mode 100644
index 0000000..2ca1e1e
--- /dev/null
+++ b/boost/log/detail/id.hpp
@@ -0,0 +1,84 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file id.hpp
+ * \author Andrey Semashev
+ * \date 08.01.2012
+ *
+ * \brief This header is the Boost.Log library implementation, see the library documentation
+ * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
+ */
+
+#ifndef BOOST_LOG_DETAIL_ID_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_ID_HPP_INCLUDED_
+
+#include <boost/log/detail/config.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace aux {
+
+//! Generic identifier class
+template< typename DescriptorT >
+class id
+{
+public:
+ //! Native type of the process id
+ typedef typename DescriptorT::native_type native_type;
+
+private:
+ native_type m_NativeID;
+
+public:
+ BOOST_CONSTEXPR id() BOOST_NOEXCEPT : m_NativeID(0) {}
+
+ explicit id(native_type native) BOOST_NOEXCEPT : m_NativeID(native) {}
+
+ native_type native_id() const BOOST_NOEXCEPT { return m_NativeID; }
+
+ bool operator== (id const& that) const BOOST_NOEXCEPT
+ {
+ return (m_NativeID == that.m_NativeID);
+ }
+ bool operator!= (id const& that) const BOOST_NOEXCEPT
+ {
+ return (m_NativeID != that.m_NativeID);
+ }
+ bool operator< (id const& that) const BOOST_NOEXCEPT
+ {
+ return (m_NativeID < that.m_NativeID);
+ }
+ bool operator> (id const& that) const BOOST_NOEXCEPT
+ {
+ return (m_NativeID > that.m_NativeID);
+ }
+ bool operator<= (id const& that) const BOOST_NOEXCEPT
+ {
+ return (m_NativeID <= that.m_NativeID);
+ }
+ bool operator>= (id const& that) const BOOST_NOEXCEPT
+ {
+ return (m_NativeID >= that.m_NativeID);
+ }
+};
+
+} // namespace aux
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_DETAIL_ID_HPP_INCLUDED_
diff --git a/boost/log/detail/light_function.hpp b/boost/log/detail/light_function.hpp
new file mode 100644
index 0000000..b673359
--- /dev/null
+++ b/boost/log/detail/light_function.hpp
@@ -0,0 +1,521 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file light_function.hpp
+ * \author Andrey Semashev
+ * \date 20.06.2010
+ *
+ * \brief This header is the Boost.Log library impl, see the library documentation
+ * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
+ *
+ * The file contains a lightweight alternative of Boost.Function. It does not provide all
+ * features of Boost.Function but doesn't introduce dependency on Boost.Bind.
+ */
+
+#ifndef BOOST_LOG_DETAIL_LIGHT_FUNCTION_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_LIGHT_FUNCTION_HPP_INCLUDED_
+
+#include <cstddef>
+#include <boost/move/core.hpp>
+#include <boost/move/utility.hpp>
+#include <boost/log/detail/config.hpp>
+#include <boost/utility/explicit_operator_bool.hpp>
+#include <boost/type_traits/remove_cv.hpp>
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#include <boost/preprocessor/iteration/iterate.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
+#include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
+#endif
+#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+#include <boost/utility/enable_if.hpp>
+#else
+#include <boost/type_traits/remove_reference.hpp>
+#endif
+#if defined(BOOST_NO_CXX11_NULLPTR)
+#include <boost/assert.hpp>
+#endif
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#ifndef BOOST_LOG_LIGHT_FUNCTION_LIMIT
+#define BOOST_LOG_LIGHT_FUNCTION_LIMIT 2
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace aux {
+
+#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+
+template< typename T, typename ThisT >
+struct is_cv_same { enum _ { value = false }; };
+template< typename T >
+struct is_cv_same< T, T > { enum _ { value = true }; };
+template< typename T >
+struct is_cv_same< T, const T > { enum _ { value = true }; };
+template< typename T >
+struct is_cv_same< T, volatile T > { enum _ { value = true }; };
+template< typename T >
+struct is_cv_same< T, const volatile T > { enum _ { value = true }; };
+
+template< typename T, typename ThisT >
+struct is_rv_or_same { enum _ { value = false }; };
+template< typename T >
+struct is_rv_or_same< T, T > { enum _ { value = true }; };
+template< typename T, typename ThisT >
+struct is_rv_or_same< boost::rv< T >, ThisT > { enum _ { value = true }; };
+
+#endif
+
+template< typename SignatureT >
+class light_function;
+
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+template< typename ResultT, typename... ArgsT >
+class light_function< ResultT (ArgsT...) >
+{
+ typedef light_function this_type;
+ BOOST_COPYABLE_AND_MOVABLE(this_type)
+
+public:
+ typedef ResultT result_type;
+
+private:
+ struct impl_base
+ {
+ typedef result_type (*invoke_type)(void*, ArgsT...);
+ const invoke_type invoke;
+
+ typedef impl_base* (*clone_type)(const void*);
+ const clone_type clone;
+
+ typedef void (*destroy_type)(void*);
+ const destroy_type destroy;
+
+ impl_base(invoke_type inv, clone_type cl, destroy_type dstr) : invoke(inv), clone(cl), destroy(dstr)
+ {
+ }
+
+ BOOST_DELETED_FUNCTION(impl_base(impl_base const&))
+ BOOST_DELETED_FUNCTION(impl_base& operator= (impl_base const&))
+ };
+
+#if !defined(BOOST_LOG_NO_MEMBER_TEMPLATE_FRIENDS)
+ template< typename FunT >
+ class impl;
+ template< typename FunT >
+ friend class impl;
+#endif
+
+ template< typename FunT >
+ class impl :
+ public impl_base
+ {
+ typedef impl< FunT > this_type;
+
+ FunT m_Function;
+
+ public:
+ explicit impl(FunT const& fun) :
+ impl_base(&this_type::invoke_impl, &this_type::clone_impl, &this_type::destroy_impl),
+ m_Function(fun)
+ {
+ }
+
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ explicit impl(FunT&& fun) :
+ impl_base(&this_type::invoke_impl, &this_type::clone_impl, &this_type::destroy_impl),
+ m_Function(boost::move(fun))
+ {
+ }
+#endif // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+
+ static void destroy_impl(void* self)
+ {
+ delete static_cast< impl* >(static_cast< impl_base* >(self));
+ }
+ static impl_base* clone_impl(const void* self)
+ {
+ return new impl(static_cast< const impl* >(static_cast< const impl_base* >(self))->m_Function);
+ }
+ static result_type invoke_impl(void* self, ArgsT... args)
+ {
+ return static_cast< impl* >(static_cast< impl_base* >(self))->m_Function(args...);
+ }
+
+ BOOST_DELETED_FUNCTION(impl(impl const&))
+ BOOST_DELETED_FUNCTION(impl& operator= (impl const&))
+ };
+
+private:
+ impl_base* m_pImpl;
+
+public:
+ BOOST_CONSTEXPR light_function() BOOST_NOEXCEPT : m_pImpl(NULL)
+ {
+ }
+ light_function(this_type const& that)
+ {
+ if (that.m_pImpl)
+ m_pImpl = that.m_pImpl->clone(that.m_pImpl);
+ else
+ m_pImpl = NULL;
+ }
+
+ light_function(BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT
+ {
+ m_pImpl = that.m_pImpl;
+ that.m_pImpl = NULL;
+ }
+
+ light_function(BOOST_RV_REF(const this_type) that) BOOST_NOEXCEPT
+ {
+ m_pImpl = that.m_pImpl;
+ ((this_type&)that).m_pImpl = NULL;
+ }
+
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ template< typename FunT >
+ light_function(FunT&& fun) :
+ m_pImpl(new impl< typename remove_cv< typename remove_reference< FunT >::type >::type >(boost::forward< FunT >(fun)))
+ {
+ }
+#else
+ template< typename FunT >
+ light_function(FunT const& fun, typename disable_if_c< is_rv_or_same< FunT, this_type >::value, int >::type = 0) :
+ m_pImpl(new impl< FunT >(fun))
+ {
+ }
+ template< typename FunT >
+ light_function(BOOST_RV_REF(FunT) fun, typename disable_if_c< is_cv_same< FunT, this_type >::value, int >::type = 0) :
+ m_pImpl(new impl< typename remove_cv< FunT >::type >(fun))
+ {
+ }
+#endif
+
+ //! Constructor from NULL
+#if !defined(BOOST_NO_CXX11_NULLPTR)
+ BOOST_CONSTEXPR light_function(std::nullptr_t) BOOST_NOEXCEPT
+#else
+ BOOST_CONSTEXPR light_function(int p) BOOST_NOEXCEPT
+#endif
+ : m_pImpl(NULL)
+ {
+#if defined(BOOST_NO_CXX11_NULLPTR)
+ BOOST_ASSERT(p == 0);
+#endif
+ }
+ ~light_function()
+ {
+ clear();
+ }
+
+ light_function& operator= (BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT
+ {
+ this->swap(that);
+ return *this;
+ }
+ light_function& operator= (BOOST_COPY_ASSIGN_REF(this_type) that)
+ {
+ light_function tmp = static_cast< this_type const& >(that);
+ this->swap(tmp);
+ return *this;
+ }
+ //! Assignment of NULL
+#if !defined(BOOST_NO_CXX11_NULLPTR)
+ light_function& operator= (std::nullptr_t)
+#else
+ light_function& operator= (int p)
+#endif
+ {
+#if defined(BOOST_NO_CXX11_NULLPTR)
+ BOOST_ASSERT(p == 0);
+#endif
+ clear();
+ return *this;
+ }
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ template< typename FunT >
+ light_function& operator= (FunT&& fun)
+ {
+ light_function tmp(boost::forward< FunT >(fun));
+ this->swap(tmp);
+ return *this;
+ }
+#else
+ template< typename FunT >
+ typename disable_if_c< is_rv_or_same< FunT, this_type >::value, this_type& >::type
+ operator= (FunT const& fun)
+ {
+ light_function tmp(fun);
+ this->swap(tmp);
+ return *this;
+ }
+#endif
+
+ result_type operator() (ArgsT... args) const
+ {
+ return m_pImpl->invoke(m_pImpl, args...);
+ }
+
+ BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
+ bool operator! () const BOOST_NOEXCEPT { return (m_pImpl == NULL); }
+ bool empty() const BOOST_NOEXCEPT { return (m_pImpl == NULL); }
+ void clear() BOOST_NOEXCEPT
+ {
+ if (m_pImpl)
+ {
+ m_pImpl->destroy(m_pImpl);
+ m_pImpl = NULL;
+ }
+ }
+
+ void swap(this_type& that) BOOST_NOEXCEPT
+ {
+ impl_base* p = m_pImpl;
+ m_pImpl = that.m_pImpl;
+ that.m_pImpl = p;
+ }
+};
+
+template< typename... ArgsT >
+class light_function< void (ArgsT...) >
+{
+ typedef light_function this_type;
+ BOOST_COPYABLE_AND_MOVABLE(this_type)
+
+public:
+ typedef void result_type;
+
+private:
+ struct impl_base
+ {
+ typedef void (*invoke_type)(void*, ArgsT...);
+ const invoke_type invoke;
+
+ typedef impl_base* (*clone_type)(const void*);
+ const clone_type clone;
+
+ typedef void (*destroy_type)(void*);
+ const destroy_type destroy;
+
+ impl_base(invoke_type inv, clone_type cl, destroy_type dstr) : invoke(inv), clone(cl), destroy(dstr)
+ {
+ }
+
+ BOOST_DELETED_FUNCTION(impl_base(impl_base const&))
+ BOOST_DELETED_FUNCTION(impl_base& operator= (impl_base const&))
+ };
+
+#if !defined(BOOST_LOG_NO_MEMBER_TEMPLATE_FRIENDS)
+ template< typename FunT >
+ class impl;
+ template< typename FunT >
+ friend class impl;
+#endif
+
+ template< typename FunT >
+ class impl :
+ public impl_base
+ {
+ typedef impl< FunT > this_type;
+
+ FunT m_Function;
+
+ public:
+ explicit impl(FunT const& fun) :
+ impl_base(&this_type::invoke_impl, &this_type::clone_impl, &this_type::destroy_impl),
+ m_Function(fun)
+ {
+ }
+
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ explicit impl(FunT&& fun) :
+ impl_base(&this_type::invoke_impl, &this_type::clone_impl, &this_type::destroy_impl),
+ m_Function(boost::move(fun))
+ {
+ }
+#endif // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+
+ static void destroy_impl(void* self)
+ {
+ delete static_cast< impl* >(static_cast< impl_base* >(self));
+ }
+ static impl_base* clone_impl(const void* self)
+ {
+ return new impl(static_cast< const impl* >(static_cast< const impl_base* >(self))->m_Function);
+ }
+ static result_type invoke_impl(void* self, ArgsT... args)
+ {
+ static_cast< impl* >(static_cast< impl_base* >(self))->m_Function(args...);
+ }
+
+ BOOST_DELETED_FUNCTION(impl(impl const&))
+ BOOST_DELETED_FUNCTION(impl& operator= (impl const&))
+ };
+
+private:
+ impl_base* m_pImpl;
+
+public:
+ BOOST_CONSTEXPR light_function() BOOST_NOEXCEPT : m_pImpl(NULL)
+ {
+ }
+ light_function(this_type const& that)
+ {
+ if (that.m_pImpl)
+ m_pImpl = that.m_pImpl->clone(that.m_pImpl);
+ else
+ m_pImpl = NULL;
+ }
+ light_function(BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT
+ {
+ m_pImpl = that.m_pImpl;
+ that.m_pImpl = NULL;
+ }
+
+ light_function(BOOST_RV_REF(const this_type) that) BOOST_NOEXCEPT
+ {
+ m_pImpl = that.m_pImpl;
+ ((this_type&)that).m_pImpl = NULL;
+ }
+
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ template< typename FunT >
+ light_function(FunT&& fun) :
+ m_pImpl(new impl< typename remove_cv< typename remove_reference< FunT >::type >::type >(boost::forward< FunT >(fun)))
+ {
+ }
+#else
+ template< typename FunT >
+ light_function(FunT const& fun, typename disable_if_c< is_rv_or_same< FunT, this_type >::value, int >::type = 0) :
+ m_pImpl(new impl< FunT >(fun))
+ {
+ }
+ template< typename FunT >
+ light_function(BOOST_RV_REF(FunT) fun, typename disable_if_c< is_cv_same< FunT, this_type >::value, int >::type = 0) :
+ m_pImpl(new impl< typename remove_cv< FunT >::type >(fun))
+ {
+ }
+#endif
+
+ //! Constructor from NULL
+#if !defined(BOOST_NO_CXX11_NULLPTR)
+ BOOST_CONSTEXPR light_function(std::nullptr_t) BOOST_NOEXCEPT
+#else
+ BOOST_CONSTEXPR light_function(int p) BOOST_NOEXCEPT
+#endif
+ : m_pImpl(NULL)
+ {
+#if defined(BOOST_NO_CXX11_NULLPTR)
+ BOOST_ASSERT(p == 0);
+#endif
+ }
+ ~light_function()
+ {
+ clear();
+ }
+
+ light_function& operator= (BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT
+ {
+ this->swap(that);
+ return *this;
+ }
+ light_function& operator= (BOOST_COPY_ASSIGN_REF(this_type) that)
+ {
+ light_function tmp = static_cast< this_type const& >(that);
+ this->swap(tmp);
+ return *this;
+ }
+ //! Assignment of NULL
+#if !defined(BOOST_NO_CXX11_NULLPTR)
+ light_function& operator= (std::nullptr_t)
+#else
+ light_function& operator= (int p)
+#endif
+ {
+#if defined(BOOST_NO_CXX11_NULLPTR)
+ BOOST_ASSERT(p == 0);
+#endif
+ clear();
+ return *this;
+ }
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ template< typename FunT >
+ light_function& operator= (FunT&& fun)
+ {
+ light_function tmp(boost::forward< FunT >(fun));
+ this->swap(tmp);
+ return *this;
+ }
+#else
+ template< typename FunT >
+ typename disable_if_c< is_rv_or_same< FunT, this_type >::value, this_type& >::type
+ operator= (FunT const& fun)
+ {
+ light_function tmp(fun);
+ this->swap(tmp);
+ return *this;
+ }
+#endif
+
+ result_type operator() (ArgsT... args) const
+ {
+ m_pImpl->invoke(m_pImpl, args...);
+ }
+
+ BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
+ bool operator! () const BOOST_NOEXCEPT { return (m_pImpl == NULL); }
+ bool empty() const BOOST_NOEXCEPT { return (m_pImpl == NULL); }
+ void clear() BOOST_NOEXCEPT
+ {
+ if (m_pImpl)
+ {
+ m_pImpl->destroy(m_pImpl);
+ m_pImpl = NULL;
+ }
+ }
+
+ void swap(this_type& that) BOOST_NOEXCEPT
+ {
+ impl_base* p = m_pImpl;
+ m_pImpl = that.m_pImpl;
+ that.m_pImpl = p;
+ }
+};
+
+#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+#define BOOST_PP_FILENAME_1 <boost/log/detail/light_function_pp.hpp>
+#define BOOST_PP_ITERATION_LIMITS (0, BOOST_LOG_LIGHT_FUNCTION_LIMIT)
+#include BOOST_PP_ITERATE()
+
+#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+template< typename SignatureT >
+inline void swap(light_function< SignatureT >& left, light_function< SignatureT >& right)
+{
+ left.swap(right);
+}
+
+} // namespace aux
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_DETAIL_LIGHT_FUNCTION_HPP_INCLUDED_
diff --git a/boost/log/detail/light_function_pp.hpp b/boost/log/detail/light_function_pp.hpp
new file mode 100644
index 0000000..55eca7c
--- /dev/null
+++ b/boost/log/detail/light_function_pp.hpp
@@ -0,0 +1,424 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+template<
+ typename ResultT
+ BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), typename ArgT)
+>
+class light_function< ResultT (BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), ArgT)) >
+{
+ typedef light_function this_type;
+ BOOST_COPYABLE_AND_MOVABLE(this_type)
+
+public:
+ typedef ResultT result_type;
+
+private:
+ struct impl_base
+ {
+ typedef result_type (*invoke_type)(void* BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), ArgT));
+ const invoke_type invoke;
+
+ typedef impl_base* (*clone_type)(const void*);
+ const clone_type clone;
+
+ typedef void (*destroy_type)(void*);
+ const destroy_type destroy;
+
+ impl_base(invoke_type inv, clone_type cl, destroy_type dstr) : invoke(inv), clone(cl), destroy(dstr)
+ {
+ }
+
+ BOOST_DELETED_FUNCTION(impl_base(impl_base const&))
+ BOOST_DELETED_FUNCTION(impl_base& operator= (impl_base const&))
+ };
+
+#if !defined(BOOST_LOG_NO_MEMBER_TEMPLATE_FRIENDS)
+ template< typename FunT >
+ class impl;
+ template< typename FunT >
+ friend class impl;
+#endif
+
+ template< typename FunT >
+ class impl :
+ public impl_base
+ {
+ typedef impl< FunT > this_type;
+
+ FunT m_Function;
+
+ public:
+ explicit impl(FunT const& fun) :
+ impl_base(&this_type::invoke_impl, &this_type::clone_impl, &this_type::destroy_impl),
+ m_Function(fun)
+ {
+ }
+
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ explicit impl(FunT&& fun) :
+ impl_base(&this_type::invoke_impl, &this_type::clone_impl, &this_type::destroy_impl),
+ m_Function(boost::move(fun))
+ {
+ }
+#endif // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+
+ static void destroy_impl(void* self)
+ {
+ delete static_cast< impl* >(static_cast< impl_base* >(self));
+ }
+ static impl_base* clone_impl(const void* self)
+ {
+ return new impl(static_cast< const impl* >(static_cast< const impl_base* >(self))->m_Function);
+ }
+ static result_type invoke_impl(void* self BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(BOOST_PP_ITERATION(), ArgT, arg))
+ {
+ return static_cast< impl* >(static_cast< impl_base* >(self))->m_Function(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), arg));
+ }
+
+ BOOST_DELETED_FUNCTION(impl(impl const&))
+ BOOST_DELETED_FUNCTION(impl& operator= (impl const&))
+ };
+
+private:
+ impl_base* m_pImpl;
+
+public:
+ BOOST_CONSTEXPR light_function() BOOST_NOEXCEPT : m_pImpl(NULL)
+ {
+ }
+ light_function(this_type const& that)
+ {
+ if (that.m_pImpl)
+ m_pImpl = that.m_pImpl->clone(that.m_pImpl);
+ else
+ m_pImpl = NULL;
+ }
+
+ light_function(BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT
+ {
+ m_pImpl = that.m_pImpl;
+ that.m_pImpl = NULL;
+ }
+
+ light_function(BOOST_RV_REF(const this_type) that) BOOST_NOEXCEPT
+ {
+ m_pImpl = that.m_pImpl;
+ ((this_type&)that).m_pImpl = NULL;
+ }
+
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ template< typename FunT >
+ light_function(FunT&& fun) :
+ m_pImpl(new impl< typename remove_cv< typename remove_reference< FunT >::type >::type >(boost::forward< FunT >(fun)))
+ {
+ }
+#else
+ template< typename FunT >
+ light_function(FunT const& fun, typename disable_if_c< is_rv_or_same< FunT, this_type >::value, int >::type = 0) :
+ m_pImpl(new impl< FunT >(fun))
+ {
+ }
+ template< typename FunT >
+ light_function(BOOST_RV_REF(FunT) fun, typename disable_if_c< is_cv_same< FunT, this_type >::value, int >::type = 0) :
+ m_pImpl(new impl< typename remove_cv< FunT >::type >(fun))
+ {
+ }
+#endif
+
+ //! Constructor from NULL
+#if !defined(BOOST_NO_CXX11_NULLPTR)
+ BOOST_CONSTEXPR light_function(std::nullptr_t) BOOST_NOEXCEPT
+#else
+ BOOST_CONSTEXPR light_function(int p) BOOST_NOEXCEPT
+#endif
+ : m_pImpl(NULL)
+ {
+#if defined(BOOST_NO_CXX11_NULLPTR)
+ BOOST_ASSERT(p == 0);
+#endif
+ }
+ ~light_function()
+ {
+ clear();
+ }
+
+ light_function& operator= (BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT
+ {
+ this->swap(that);
+ return *this;
+ }
+ light_function& operator= (BOOST_COPY_ASSIGN_REF(this_type) that)
+ {
+ light_function tmp = static_cast< this_type const& >(that);
+ this->swap(tmp);
+ return *this;
+ }
+ //! Assignment of NULL
+#if !defined(BOOST_NO_CXX11_NULLPTR)
+ light_function& operator= (std::nullptr_t)
+#else
+ light_function& operator= (int p)
+#endif
+ {
+#if defined(BOOST_NO_CXX11_NULLPTR)
+ BOOST_ASSERT(p == 0);
+#endif
+ clear();
+ return *this;
+ }
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ template< typename FunT >
+ light_function& operator= (FunT&& fun)
+ {
+ light_function tmp(boost::forward< FunT >(fun));
+ this->swap(tmp);
+ return *this;
+ }
+#else
+ template< typename FunT >
+ typename disable_if_c< is_rv_or_same< FunT, this_type >::value, this_type& >::type
+ operator= (FunT const& fun)
+ {
+ light_function tmp(fun);
+ this->swap(tmp);
+ return *this;
+ }
+#endif
+
+ result_type operator() (BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), ArgT, arg)) const
+ {
+ return m_pImpl->invoke(m_pImpl BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), arg));
+ }
+
+ BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
+ bool operator! () const BOOST_NOEXCEPT { return (m_pImpl == NULL); }
+ bool empty() const BOOST_NOEXCEPT { return (m_pImpl == NULL); }
+ void clear() BOOST_NOEXCEPT
+ {
+ if (m_pImpl)
+ {
+ m_pImpl->destroy(m_pImpl);
+ m_pImpl = NULL;
+ }
+ }
+
+ void swap(this_type& that) BOOST_NOEXCEPT
+ {
+ impl_base* p = m_pImpl;
+ m_pImpl = that.m_pImpl;
+ that.m_pImpl = p;
+ }
+};
+
+template<
+ BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), typename ArgT)
+>
+class light_function< void (BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), ArgT)) >
+{
+ typedef light_function this_type;
+ BOOST_COPYABLE_AND_MOVABLE(this_type)
+
+public:
+ typedef void result_type;
+
+private:
+ struct impl_base
+ {
+ typedef void (*invoke_type)(void* BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), ArgT));
+ const invoke_type invoke;
+
+ typedef impl_base* (*clone_type)(const void*);
+ const clone_type clone;
+
+ typedef void (*destroy_type)(void*);
+ const destroy_type destroy;
+
+ impl_base(invoke_type inv, clone_type cl, destroy_type dstr) : invoke(inv), clone(cl), destroy(dstr)
+ {
+ }
+
+ BOOST_DELETED_FUNCTION(impl_base(impl_base const&))
+ BOOST_DELETED_FUNCTION(impl_base& operator= (impl_base const&))
+ };
+
+#if !defined(BOOST_LOG_NO_MEMBER_TEMPLATE_FRIENDS)
+ template< typename FunT >
+ class impl;
+ template< typename FunT >
+ friend class impl;
+#endif
+
+ template< typename FunT >
+ class impl :
+ public impl_base
+ {
+ typedef impl< FunT > this_type;
+
+ FunT m_Function;
+
+ public:
+ explicit impl(FunT const& fun) :
+ impl_base(&this_type::invoke_impl, &this_type::clone_impl, &this_type::destroy_impl),
+ m_Function(fun)
+ {
+ }
+
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ explicit impl(FunT&& fun) :
+ impl_base(&this_type::invoke_impl, &this_type::clone_impl, &this_type::destroy_impl),
+ m_Function(boost::move(fun))
+ {
+ }
+#endif // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+
+ static void destroy_impl(void* self)
+ {
+ delete static_cast< impl* >(static_cast< impl_base* >(self));
+ }
+ static impl_base* clone_impl(const void* self)
+ {
+ return new impl(static_cast< const impl* >(static_cast< const impl_base* >(self))->m_Function);
+ }
+ static result_type invoke_impl(void* self BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(BOOST_PP_ITERATION(), ArgT, arg))
+ {
+ static_cast< impl* >(static_cast< impl_base* >(self))->m_Function(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), arg));
+ }
+
+ BOOST_DELETED_FUNCTION(impl(impl const&))
+ BOOST_DELETED_FUNCTION(impl& operator= (impl const&))
+ };
+
+private:
+ impl_base* m_pImpl;
+
+public:
+ BOOST_CONSTEXPR light_function() BOOST_NOEXCEPT : m_pImpl(NULL)
+ {
+ }
+ light_function(this_type const& that)
+ {
+ if (that.m_pImpl)
+ m_pImpl = that.m_pImpl->clone(that.m_pImpl);
+ else
+ m_pImpl = NULL;
+ }
+ light_function(BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT
+ {
+ m_pImpl = that.m_pImpl;
+ that.m_pImpl = NULL;
+ }
+
+ light_function(BOOST_RV_REF(const this_type) that) BOOST_NOEXCEPT
+ {
+ m_pImpl = that.m_pImpl;
+ ((this_type&)that).m_pImpl = NULL;
+ }
+
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ template< typename FunT >
+ light_function(FunT&& fun) :
+ m_pImpl(new impl< typename remove_cv< typename remove_reference< FunT >::type >::type >(boost::forward< FunT >(fun)))
+ {
+ }
+#else
+ template< typename FunT >
+ light_function(FunT const& fun, typename disable_if_c< is_rv_or_same< FunT, this_type >::value, int >::type = 0) :
+ m_pImpl(new impl< FunT >(fun))
+ {
+ }
+ template< typename FunT >
+ light_function(BOOST_RV_REF(FunT) fun, typename disable_if_c< is_cv_same< FunT, this_type >::value, int >::type = 0) :
+ m_pImpl(new impl< typename remove_cv< FunT >::type >(fun))
+ {
+ }
+#endif
+
+ //! Constructor from NULL
+#if !defined(BOOST_NO_CXX11_NULLPTR)
+ BOOST_CONSTEXPR light_function(std::nullptr_t) BOOST_NOEXCEPT
+#else
+ BOOST_CONSTEXPR light_function(int p) BOOST_NOEXCEPT
+#endif
+ : m_pImpl(NULL)
+ {
+#if defined(BOOST_NO_CXX11_NULLPTR)
+ BOOST_ASSERT(p == 0);
+#endif
+ }
+ ~light_function()
+ {
+ clear();
+ }
+
+ light_function& operator= (BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT
+ {
+ this->swap(that);
+ return *this;
+ }
+ light_function& operator= (BOOST_COPY_ASSIGN_REF(this_type) that)
+ {
+ light_function tmp = static_cast< this_type const& >(that);
+ this->swap(tmp);
+ return *this;
+ }
+ //! Assignment of NULL
+#if !defined(BOOST_NO_CXX11_NULLPTR)
+ light_function& operator= (std::nullptr_t)
+#else
+ light_function& operator= (int p)
+#endif
+ {
+#if defined(BOOST_NO_CXX11_NULLPTR)
+ BOOST_ASSERT(p == 0);
+#endif
+ clear();
+ return *this;
+ }
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ template< typename FunT >
+ light_function& operator= (FunT&& fun)
+ {
+ light_function tmp(boost::forward< FunT >(fun));
+ this->swap(tmp);
+ return *this;
+ }
+#else
+ template< typename FunT >
+ typename disable_if_c< is_rv_or_same< FunT, this_type >::value, this_type& >::type
+ operator= (FunT const& fun)
+ {
+ light_function tmp(fun);
+ this->swap(tmp);
+ return *this;
+ }
+#endif
+
+ result_type operator() (BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), ArgT, arg)) const
+ {
+ m_pImpl->invoke(m_pImpl BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), arg));
+ }
+
+ BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
+ bool operator! () const BOOST_NOEXCEPT { return (m_pImpl == NULL); }
+ bool empty() const BOOST_NOEXCEPT { return (m_pImpl == NULL); }
+ void clear() BOOST_NOEXCEPT
+ {
+ if (m_pImpl)
+ {
+ m_pImpl->destroy(m_pImpl);
+ m_pImpl = NULL;
+ }
+ }
+
+ void swap(this_type& that) BOOST_NOEXCEPT
+ {
+ impl_base* p = m_pImpl;
+ m_pImpl = that.m_pImpl;
+ that.m_pImpl = p;
+ }
+};
diff --git a/boost/log/detail/light_rw_mutex.hpp b/boost/log/detail/light_rw_mutex.hpp
new file mode 100644
index 0000000..abfef13
--- /dev/null
+++ b/boost/log/detail/light_rw_mutex.hpp
@@ -0,0 +1,208 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file light_rw_mutex.hpp
+ * \author Andrey Semashev
+ * \date 24.03.2009
+ *
+ * \brief This header is the Boost.Log library implementation, see the library documentation
+ * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
+ */
+
+#ifndef BOOST_LOG_DETAIL_LIGHT_RW_MUTEX_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_LIGHT_RW_MUTEX_HPP_INCLUDED_
+
+#include <boost/log/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#ifndef BOOST_LOG_NO_THREADS
+
+#include <boost/log/detail/header.hpp>
+
+#if defined(BOOST_THREAD_POSIX) // This one can be defined by users, so it should go first
+#define BOOST_LOG_LWRWMUTEX_USE_PTHREAD
+#elif defined(BOOST_WINDOWS) && defined(BOOST_LOG_USE_WINNT6_API)
+#define BOOST_LOG_LWRWMUTEX_USE_SRWLOCK
+#elif defined(BOOST_HAS_PTHREADS)
+#define BOOST_LOG_LWRWMUTEX_USE_PTHREAD
+#endif
+
+#if defined(BOOST_LOG_LWRWMUTEX_USE_SRWLOCK)
+
+#if defined(BOOST_USE_WINDOWS_H)
+
+#ifndef _WIN32_WINNT
+#define _WIN32_WINNT 0x0600 // _WIN32_WINNT_LONGHORN
+#endif
+
+#include <windows.h>
+
+#else // defined(BOOST_USE_WINDOWS_H)
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace aux {
+
+extern "C" {
+
+struct SRWLOCK { void* p; };
+__declspec(dllimport) void __stdcall InitializeSRWLock(SRWLOCK*);
+__declspec(dllimport) void __stdcall ReleaseSRWLockExclusive(SRWLOCK*);
+__declspec(dllimport) void __stdcall ReleaseSRWLockShared(SRWLOCK*);
+__declspec(dllimport) void __stdcall AcquireSRWLockExclusive(SRWLOCK*);
+__declspec(dllimport) void __stdcall AcquireSRWLockShared(SRWLOCK*);
+
+} // extern "C"
+
+} // namespace aux
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#endif // BOOST_USE_WINDOWS_H
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace aux {
+
+//! A light read/write mutex that uses WinNT 6 and later APIs
+class light_rw_mutex
+{
+ SRWLOCK m_Mutex;
+
+public:
+ light_rw_mutex()
+ {
+ InitializeSRWLock(&m_Mutex);
+ }
+ void lock_shared()
+ {
+ AcquireSRWLockShared(&m_Mutex);
+ }
+ void unlock_shared()
+ {
+ ReleaseSRWLockShared(&m_Mutex);
+ }
+ void lock()
+ {
+ AcquireSRWLockExclusive(&m_Mutex);
+ }
+ void unlock()
+ {
+ ReleaseSRWLockExclusive(&m_Mutex);
+ }
+
+ // Noncopyable
+ BOOST_DELETED_FUNCTION(light_rw_mutex(light_rw_mutex const&))
+ BOOST_DELETED_FUNCTION(light_rw_mutex& operator= (light_rw_mutex const&))
+};
+
+} // namespace aux
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#elif defined(BOOST_LOG_LWRWMUTEX_USE_PTHREAD)
+
+#include <pthread.h>
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace aux {
+
+//! A light read/write mutex that maps directly onto POSIX threading library
+class light_rw_mutex
+{
+ pthread_rwlock_t m_Mutex;
+
+public:
+ light_rw_mutex()
+ {
+ pthread_rwlock_init(&m_Mutex, NULL);
+ }
+ ~light_rw_mutex()
+ {
+ pthread_rwlock_destroy(&m_Mutex);
+ }
+ void lock_shared()
+ {
+ pthread_rwlock_rdlock(&m_Mutex);
+ }
+ void unlock_shared()
+ {
+ pthread_rwlock_unlock(&m_Mutex);
+ }
+ void lock()
+ {
+ pthread_rwlock_wrlock(&m_Mutex);
+ }
+ void unlock()
+ {
+ pthread_rwlock_unlock(&m_Mutex);
+ }
+
+ // Noncopyable
+ BOOST_DELETED_FUNCTION(light_rw_mutex(light_rw_mutex const&))
+ BOOST_DELETED_FUNCTION(light_rw_mutex& operator= (light_rw_mutex const&))
+};
+
+} // namespace aux
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#else
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace aux {
+
+//! A light read/write mutex
+class light_rw_mutex
+{
+ struct { void* p; } m_Mutex;
+
+public:
+ BOOST_LOG_API light_rw_mutex();
+ BOOST_LOG_API ~light_rw_mutex();
+ BOOST_LOG_API void lock_shared();
+ BOOST_LOG_API void unlock_shared();
+ BOOST_LOG_API void lock();
+ BOOST_LOG_API void unlock();
+
+ // Noncopyable
+ BOOST_DELETED_FUNCTION(light_rw_mutex(light_rw_mutex const&))
+ BOOST_DELETED_FUNCTION(light_rw_mutex& operator= (light_rw_mutex const&))
+};
+
+} // namespace aux
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#endif
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_NO_THREADS
+
+#endif // BOOST_LOG_DETAIL_LIGHT_RW_MUTEX_HPP_INCLUDED_
diff --git a/boost/log/detail/locking_ptr.hpp b/boost/log/detail/locking_ptr.hpp
new file mode 100644
index 0000000..913780e
--- /dev/null
+++ b/boost/log/detail/locking_ptr.hpp
@@ -0,0 +1,148 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file locking_ptr.hpp
+ * \author Andrey Semashev
+ * \date 15.07.2009
+ *
+ * This header is the Boost.Log library implementation, see the library documentation
+ * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
+ */
+
+#ifndef BOOST_LOG_DETAIL_LOCKING_PTR_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_LOCKING_PTR_HPP_INCLUDED_
+
+#include <cstddef>
+#include <boost/move/core.hpp>
+#include <boost/smart_ptr/shared_ptr.hpp>
+#include <boost/thread/lock_options.hpp>
+#include <boost/log/detail/config.hpp>
+#include <boost/utility/explicit_operator_bool.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace aux {
+
+//! A pointer type that locks the backend until it's destroyed
+template< typename T, typename LockableT >
+class locking_ptr
+{
+ typedef locking_ptr this_type;
+ BOOST_COPYABLE_AND_MOVABLE_ALT(this_type)
+
+public:
+ //! Pointed type
+ typedef T element_type;
+
+private:
+ //! Lockable type
+ typedef LockableT lockable_type;
+
+private:
+ //! The pointer to the backend
+ shared_ptr< element_type > m_pElement;
+ //! Reference to the shared lock control object
+ lockable_type* m_pLock;
+
+public:
+ //! Default constructor
+ locking_ptr() BOOST_NOEXCEPT : m_pLock(NULL)
+ {
+ }
+ //! Constructor
+ locking_ptr(shared_ptr< element_type > const& p, lockable_type& l) : m_pElement(p), m_pLock(&l)
+ {
+ m_pLock->lock();
+ }
+ //! Constructor
+ locking_ptr(shared_ptr< element_type > const& p, lockable_type& l, try_to_lock_t const&) : m_pElement(p), m_pLock(&l)
+ {
+ if (!m_pLock->try_lock())
+ {
+ m_pElement.reset();
+ m_pLock = NULL;
+ }
+ }
+ //! Copy constructor
+ locking_ptr(locking_ptr const& that) : m_pElement(that.m_pElement), m_pLock(that.m_pLock)
+ {
+ if (m_pLock)
+ m_pLock->lock();
+ }
+ //! Move constructor
+ locking_ptr(BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT : m_pLock(that.m_pLock)
+ {
+ m_pElement.swap(that.m_pElement);
+ that.m_pLock = NULL;
+ }
+
+ //! Destructor
+ ~locking_ptr()
+ {
+ if (m_pLock)
+ m_pLock->unlock();
+ }
+
+ //! Assignment
+ locking_ptr& operator= (locking_ptr that) BOOST_NOEXCEPT
+ {
+ this->swap(that);
+ return *this;
+ }
+
+ //! Indirection
+ element_type* operator-> () const BOOST_NOEXCEPT { return m_pElement.get(); }
+ //! Dereferencing
+ element_type& operator* () const BOOST_NOEXCEPT { return *m_pElement; }
+
+ //! Accessor to the raw pointer
+ element_type* get() const BOOST_NOEXCEPT { return m_pElement.get(); }
+
+ //! Checks for null pointer
+ BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
+ //! Checks for null pointer
+ bool operator! () const BOOST_NOEXCEPT { return !m_pElement; }
+
+ //! Swaps two pointers
+ void swap(locking_ptr& that) BOOST_NOEXCEPT
+ {
+ m_pElement.swap(that.m_pElement);
+ lockable_type* p = m_pLock;
+ m_pLock = that.m_pLock;
+ that.m_pLock = p;
+ }
+};
+
+//! Free raw pointer getter to assist generic programming
+template< typename T, typename LockableT >
+inline T* get_pointer(locking_ptr< T, LockableT > const& p) BOOST_NOEXCEPT
+{
+ return p.get();
+}
+//! Free swap operation
+template< typename T, typename LockableT >
+inline void swap(locking_ptr< T, LockableT >& left, locking_ptr< T, LockableT >& right) BOOST_NOEXCEPT
+{
+ left.swap(right);
+}
+
+} // namespace aux
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_DETAIL_LOCKING_PTR_HPP_INCLUDED_
diff --git a/boost/log/detail/locks.hpp b/boost/log/detail/locks.hpp
new file mode 100644
index 0000000..72b8945
--- /dev/null
+++ b/boost/log/detail/locks.hpp
@@ -0,0 +1,180 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file locks.hpp
+ * \author Andrey Semashev
+ * \date 30.05.2010
+ *
+ * \brief This header is the Boost.Log library implementation, see the library documentation
+ * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
+ */
+
+#ifndef BOOST_LOG_DETAIL_LOCKS_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_LOCKS_HPP_INCLUDED_
+
+#include <boost/log/detail/config.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+#ifndef BOOST_LOG_NO_THREADS
+
+// Forward declaration of Boost.Thread locks. Specified here to avoid including Boost.Thread,
+// which would bring in many dependent headers, including a great deal of Boost.DateTime.
+template< typename >
+class lock_guard;
+template< typename >
+class shared_lock;
+template< typename >
+class upgrade_lock;
+template< typename >
+class unique_lock;
+
+template< typename >
+struct is_mutex_type;
+
+#endif // BOOST_LOG_NO_THREADS
+
+BOOST_LOG_OPEN_NAMESPACE
+
+//! An auxiliary pseudo-lock to express no locking requirements in logger features
+template< typename MutexT >
+class no_lock
+{
+public:
+ /*!
+ * Constructs the pseudo-lock. The mutex is not affected during the construction.
+ */
+ explicit no_lock(MutexT&) {}
+
+private:
+ no_lock(no_lock const&);
+ no_lock& operator= (no_lock const&);
+};
+
+namespace aux {
+
+#ifndef BOOST_LOG_NO_THREADS
+
+//! A trait to detect if the mutex supports exclusive locking
+template< typename MutexT >
+struct is_exclusively_lockable
+{
+ typedef char true_type;
+ struct false_type { char t[2]; };
+
+ template< typename T >
+ static true_type check_lockable(T*, void (T::*)() = &T::lock, void (T::*)() = &T::unlock);
+ static false_type check_lockable(void*);
+
+ enum value_t { value = sizeof(check_lockable((MutexT*)NULL)) == sizeof(true_type) };
+};
+
+//! A trait to detect if the mutex supports shared locking
+template< typename MutexT >
+struct is_shared_lockable
+{
+ typedef char true_type;
+ struct false_type { char t[2]; };
+
+ template< typename T >
+ static true_type check_shared_lockable(T*, void (T::*)() = &T::lock_shared, void (T::*)() = &T::unlock_shared);
+ static false_type check_shared_lockable(void*);
+
+ enum value_t { value = sizeof(check_shared_lockable((MutexT*)NULL)) == sizeof(true_type) };
+};
+
+//! An analogue to the minimalistic \c lock_guard template. Defined here to avoid including Boost.Thread.
+template< typename MutexT >
+struct exclusive_lock_guard
+{
+ explicit exclusive_lock_guard(MutexT& m) : m_Mutex(m)
+ {
+ m.lock();
+ }
+ ~exclusive_lock_guard()
+ {
+ m_Mutex.unlock();
+ }
+
+private:
+ exclusive_lock_guard(exclusive_lock_guard const&);
+ exclusive_lock_guard& operator= (exclusive_lock_guard const&);
+
+private:
+ MutexT& m_Mutex;
+};
+
+//! An analogue to the minimalistic \c lock_guard template that locks \c shared_mutex with shared ownership.
+template< typename MutexT >
+struct shared_lock_guard
+{
+ explicit shared_lock_guard(MutexT& m) : m_Mutex(m)
+ {
+ m.lock_shared();
+ }
+ ~shared_lock_guard()
+ {
+ m_Mutex.unlock_shared();
+ }
+
+private:
+ shared_lock_guard(shared_lock_guard const&);
+ shared_lock_guard& operator= (shared_lock_guard const&);
+
+private:
+ MutexT& m_Mutex;
+};
+
+//! A deadlock-safe lock type that exclusively locks two mutexes
+template< typename MutexT1, typename MutexT2 >
+class multiple_unique_lock2
+{
+public:
+ multiple_unique_lock2(MutexT1& m1, MutexT2& m2) :
+ m_p1(&m1),
+ m_p2(&m2)
+ {
+ // Yes, it's not conforming, but it works
+ // and it doesn't require to #include <functional>
+ if (static_cast< void* >(m_p1) < static_cast< void* >(m_p2))
+ {
+ m_p1->lock();
+ m_p2->lock();
+ }
+ else
+ {
+ m_p2->lock();
+ m_p1->lock();
+ }
+ }
+ ~multiple_unique_lock2()
+ {
+ m_p2->unlock();
+ m_p1->unlock();
+ }
+
+private:
+ MutexT1* m_p1;
+ MutexT2* m_p2;
+};
+
+#endif // BOOST_LOG_NO_THREADS
+
+} // namespace aux
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_DETAIL_LOCKS_HPP_INCLUDED_
diff --git a/boost/log/detail/named_scope_fmt_pp.hpp b/boost/log/detail/named_scope_fmt_pp.hpp
new file mode 100644
index 0000000..d9f0027
--- /dev/null
+++ b/boost/log/detail/named_scope_fmt_pp.hpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+template< BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), typename ArgT) >
+BOOST_FORCEINLINE format_named_scope_actor<
+ fallback_to_none,
+ typename boost::log::aux::deduce_char_type<
+ typename parameter::binding<
+ typename boost::log::aux::make_arg_list< BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), ArgT) >::type,
+ keywords::tag::format,
+ void
+ >::type
+ >::type
+> format_named_scope(attribute_name const& name, BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), ArgT, const& arg))
+{
+ typedef typename boost::log::aux::deduce_char_type<
+ typename parameter::binding<
+ typename boost::log::aux::make_arg_list< BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), ArgT) >::type,
+ keywords::tag::format,
+ void
+ >::type
+ >::type char_type;
+ return aux::format_named_scope< char_type, phoenix::actor >(name, fallback_to_none(), (BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), arg)));
+}
+
+template< typename DescriptorT, template< typename > class ActorT, BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), typename ArgT) >
+BOOST_FORCEINLINE format_named_scope_actor<
+ fallback_to_none,
+ typename boost::log::aux::deduce_char_type<
+ typename parameter::binding<
+ typename boost::log::aux::make_arg_list< BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), ArgT) >::type,
+ keywords::tag::format,
+ void
+ >::type
+ >::type,
+ ActorT
+>
+format_named_scope(attribute_keyword< DescriptorT, ActorT > const& keyword, BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), ArgT, const& arg))
+{
+ BOOST_STATIC_ASSERT_MSG((is_same< typename DescriptorT::value_type, attributes::named_scope::value_type >::value),\
+ "Boost.Log: Named scope formatter only accepts attribute values of type attributes::named_scope::value_type.");
+
+ typedef typename boost::log::aux::deduce_char_type<
+ typename parameter::binding<
+ typename boost::log::aux::make_arg_list< BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), ArgT) >::type,
+ keywords::tag::format,
+ void
+ >::type
+ >::type char_type;
+ return aux::format_named_scope< char_type, ActorT >(keyword.get_name(), fallback_to_none(), (BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), arg)));
+}
+
+template< typename T, typename FallbackPolicyT, typename TagT, template< typename > class ActorT, BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), typename ArgT) >
+BOOST_FORCEINLINE format_named_scope_actor<
+ FallbackPolicyT,
+ typename boost::log::aux::deduce_char_type<
+ typename parameter::binding<
+ typename boost::log::aux::make_arg_list< BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), ArgT) >::type,
+ keywords::tag::format,
+ void
+ >::type
+ >::type,
+ ActorT
+>
+format_named_scope(attribute_actor< T, FallbackPolicyT, TagT, ActorT > const& placeholder, BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), ArgT, const& arg))
+{
+ BOOST_STATIC_ASSERT_MSG((is_same< T, attributes::named_scope::value_type >::value),\
+ "Boost.Log: Named scope formatter only accepts attribute values of type attributes::named_scope::value_type.");
+
+ typedef typename boost::log::aux::deduce_char_type<
+ typename parameter::binding<
+ typename boost::log::aux::make_arg_list< BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), ArgT) >::type,
+ keywords::tag::format,
+ void
+ >::type
+ >::type char_type;
+ return aux::format_named_scope< char_type, ActorT >(placeholder.get_name(), placeholder.get_fallback_policy(), (BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), arg)));
+}
diff --git a/boost/log/detail/native_typeof.hpp b/boost/log/detail/native_typeof.hpp
new file mode 100644
index 0000000..276b294
--- /dev/null
+++ b/boost/log/detail/native_typeof.hpp
@@ -0,0 +1,63 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file native_typeof.hpp
+ * \author Andrey Semashev
+ * \date 08.03.2009
+ *
+ * This header is the Boost.Log library implementation, see the library documentation
+ * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
+ */
+
+#ifndef BOOST_LOG_DETAIL_NATIVE_TYPEOF_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_NATIVE_TYPEOF_HPP_INCLUDED_
+
+#include <boost/log/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#if !defined(BOOST_NO_CXX11_DECLTYPE)
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace aux {
+
+template< typename T >
+T get_root_type(T const&);
+
+} // namespace aux
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#define BOOST_LOG_TYPEOF(x) decltype(::boost::log::aux::get_root_type(x))
+
+#elif defined(__COMO__) && defined(__GNUG__)
+
+#define BOOST_LOG_TYPEOF(x) typeof(x)
+
+#elif defined(__GNUC__) || defined(__MWERKS__)
+
+#define BOOST_LOG_TYPEOF(x) __typeof__(x)
+
+#endif
+
+
+#if !defined(BOOST_NO_CXX11_AUTO_DECLARATIONS)
+#define BOOST_LOG_AUTO(var, expr) auto var = (expr)
+#endif
+
+#if !defined(BOOST_LOG_AUTO) && defined(BOOST_LOG_TYPEOF)
+#define BOOST_LOG_AUTO(var, expr) BOOST_LOG_TYPEOF((expr)) var = (expr)
+#endif
+
+#endif // BOOST_LOG_DETAIL_NATIVE_TYPEOF_HPP_INCLUDED_
diff --git a/boost/log/detail/parameter_tools.hpp b/boost/log/detail/parameter_tools.hpp
new file mode 100644
index 0000000..692a337
--- /dev/null
+++ b/boost/log/detail/parameter_tools.hpp
@@ -0,0 +1,114 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file parameter_tools.hpp
+ * \author Andrey Semashev
+ * \date 28.06.2009
+ *
+ * \brief This header is the Boost.Log library implementation, see the library documentation
+ * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
+ */
+
+#ifndef BOOST_LOG_DETAIL_PARAMETER_TOOLS_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_PARAMETER_TOOLS_HPP_INCLUDED_
+
+#include <boost/parameter/keyword.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/repetition/repeat_from_to.hpp>
+#include <boost/preprocessor/facilities/intercept.hpp>
+#include <boost/preprocessor/arithmetic/dec.hpp>
+#include <boost/preprocessor/tuple/elem.hpp>
+#include <boost/log/detail/config.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#ifndef BOOST_LOG_MAX_PARAMETER_ARGS
+//! The maximum number of named arguments that are accepted by constructors and functions
+#define BOOST_LOG_MAX_PARAMETER_ARGS 16
+#endif
+
+// The macro applies the passed macro with the specified arguments BOOST_LOG_MAX_PARAMETER_ARGS times
+#define BOOST_LOG_PARAMETRIZED_CONSTRUCTORS_GEN(macro, args)\
+ public:\
+ BOOST_PP_REPEAT_FROM_TO(1, BOOST_LOG_MAX_PARAMETER_ARGS, macro, args)
+
+
+#define BOOST_LOG_CTOR_FORWARD(z, n, types)\
+ template< BOOST_PP_ENUM_PARAMS(n, typename T) >\
+ explicit BOOST_PP_TUPLE_ELEM(2, 0, types)(BOOST_PP_ENUM_BINARY_PARAMS(n, T, const& arg)) :\
+ BOOST_PP_TUPLE_ELEM(2, 1, types)((BOOST_PP_ENUM_PARAMS(n, arg))) {}
+
+// The macro expands to a number of templated constructors that aggregate their named arguments
+// into an ArgumentsPack and pass it to the base class constructor.
+#define BOOST_LOG_PARAMETRIZED_CONSTRUCTORS_FORWARD(class_type, base_type)\
+ BOOST_LOG_PARAMETRIZED_CONSTRUCTORS_GEN(BOOST_LOG_CTOR_FORWARD, (class_type, base_type))
+
+
+#define BOOST_LOG_CTOR_CALL(z, n, types)\
+ template< BOOST_PP_ENUM_PARAMS(n, typename T) >\
+ explicit BOOST_PP_TUPLE_ELEM(2, 0, types)(BOOST_PP_ENUM_BINARY_PARAMS(n, T, const& arg))\
+ { BOOST_PP_TUPLE_ELEM(2, 1, types)((BOOST_PP_ENUM_PARAMS(n, arg))); }
+
+// The macro expands to a number of templated constructors that aggregate their named arguments
+// into an ArgumentsPack and pass it to a function call.
+#define BOOST_LOG_PARAMETRIZED_CONSTRUCTORS_CALL(class_type, fun)\
+ BOOST_LOG_PARAMETRIZED_CONSTRUCTORS_GEN(BOOST_LOG_CTOR_CALL, (class_type, fun))
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace aux {
+
+// Yeah, not too cute. The empty_arg_list class should really be public.
+typedef boost::parameter::aux::empty_arg_list empty_arg_list;
+
+#if !(defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_LOG_NO_CXX11_ARG_PACKS_TO_NON_VARIADIC_ARGS_EXPANSION))
+
+//! The metafunction generates argument pack
+template< typename ArgT0, typename... ArgsT >
+struct make_arg_list
+{
+ typedef boost::parameter::aux::arg_list< ArgT0, typename make_arg_list< ArgsT... >::type > type;
+};
+
+template< typename ArgT0 >
+struct make_arg_list< ArgT0 >
+{
+ typedef boost::parameter::aux::arg_list< ArgT0 > type;
+};
+
+#else
+
+//! The metafunction generates argument pack
+template< typename ArgT0, BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_DEC(BOOST_LOG_MAX_PARAMETER_ARGS), typename T, = void BOOST_PP_INTERCEPT) >
+struct make_arg_list
+{
+ typedef boost::parameter::aux::arg_list< ArgT0, typename make_arg_list< BOOST_PP_ENUM_PARAMS(BOOST_PP_DEC(BOOST_LOG_MAX_PARAMETER_ARGS), T) >::type > type;
+};
+
+template< typename ArgT0 >
+struct make_arg_list< ArgT0, BOOST_PP_ENUM_PARAMS(BOOST_PP_DEC(BOOST_LOG_MAX_PARAMETER_ARGS), void BOOST_PP_INTERCEPT) >
+{
+ typedef boost::parameter::aux::arg_list< ArgT0 > type;
+};
+
+#endif
+
+} // namespace aux
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_DETAIL_PARAMETER_TOOLS_HPP_INCLUDED_
diff --git a/boost/log/detail/pp_identity.hpp b/boost/log/detail/pp_identity.hpp
new file mode 100644
index 0000000..8daaf95
--- /dev/null
+++ b/boost/log/detail/pp_identity.hpp
@@ -0,0 +1,27 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file pp_identity.hpp
+ * \author Andrey Semashev
+ * \date 12.02.2011
+ *
+ * This header is the Boost.Log library implementation, see the library documentation
+ * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
+ */
+
+#ifndef BOOST_LOG_DETAIL_PP_IDENTITY_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_PP_IDENTITY_HPP_INCLUDED_
+
+#include <boost/log/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#define BOOST_LOG_PP_IDENTITY(z, n, data) data
+
+#endif // BOOST_LOG_DETAIL_PP_IDENTITY_HPP_INCLUDED_
diff --git a/boost/log/detail/process_id.hpp b/boost/log/detail/process_id.hpp
new file mode 100644
index 0000000..3532506
--- /dev/null
+++ b/boost/log/detail/process_id.hpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file process_id.hpp
+ * \author Andrey Semashev
+ * \date 12.09.2009
+ *
+ * \brief This header is the Boost.Log library implementation, see the library documentation
+ * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
+ */
+
+#ifndef BOOST_LOG_DETAIL_PROCESS_ID_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_PROCESS_ID_HPP_INCLUDED_
+
+#include <iosfwd>
+#include <boost/log/detail/config.hpp>
+#include <boost/log/detail/id.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace aux {
+
+//! The process id descriptor
+struct process
+{
+ typedef unsigned long native_type;
+ typedef boost::log::aux::id< process > id;
+};
+
+namespace this_process {
+
+//! The function returns current process identifier
+BOOST_LOG_API process::id get_id();
+
+} // namespace this_process
+
+template< typename CharT, typename TraitsT >
+BOOST_LOG_API std::basic_ostream< CharT, TraitsT >&
+operator<< (std::basic_ostream< CharT, TraitsT >& strm, process::id const& pid);
+
+} // namespace aux
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_DETAIL_PROCESS_ID_HPP_INCLUDED_
diff --git a/boost/log/detail/setup_config.hpp b/boost/log/detail/setup_config.hpp
new file mode 100644
index 0000000..1123959
--- /dev/null
+++ b/boost/log/detail/setup_config.hpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file setup_config.hpp
+ * \author Andrey Semashev
+ * \date 14.09.2009
+ *
+ * \brief This header is the Boost.Log library implementation, see the library documentation
+ * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html. In this file
+ * internal configuration macros are defined.
+ */
+
+#ifndef BOOST_LOG_DETAIL_SETUP_CONFIG_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_SETUP_CONFIG_HPP_INCLUDED_
+
+#include <boost/log/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#if !defined(BOOST_LOG_SETUP_BUILDING_THE_LIB)
+
+// Detect if we're dealing with dll
+# if defined(BOOST_LOG_SETUP_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)
+# define BOOST_LOG_SETUP_DLL
+# endif
+
+# if defined(BOOST_HAS_DECLSPEC) && defined(BOOST_LOG_SETUP_DLL)
+# define BOOST_LOG_SETUP_API __declspec(dllimport)
+# else
+# define BOOST_LOG_SETUP_API
+# endif // defined(BOOST_HAS_DECLSPEC)
+//
+// Automatically link to the correct build variant where possible.
+//
+# if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_LOG_SETUP_NO_LIB)
+# define BOOST_LIB_NAME boost_log_setup
+# if defined(BOOST_LOG_SETUP_DLL)
+# define BOOST_DYN_LINK
+# endif
+# include <boost/config/auto_link.hpp>
+# endif // auto-linking disabled
+
+#else // !defined(BOOST_LOG_SETUP_BUILDING_THE_LIB)
+
+# if defined(BOOST_HAS_DECLSPEC) && defined(BOOST_LOG_SETUP_DLL)
+# define BOOST_LOG_SETUP_API __declspec(dllexport)
+# elif defined(__GNUC__) && __GNUC__ >= 4 && (defined(linux) || defined(__linux) || defined(__linux__))
+# define BOOST_LOG_SETUP_API __attribute__((visibility("default")))
+# else
+# define BOOST_LOG_SETUP_API
+# endif
+
+#endif // !defined(BOOST_LOG_SETUP_BUILDING_THE_LIB)
+
+#endif // BOOST_LOG_DETAIL_SETUP_CONFIG_HPP_INCLUDED_
diff --git a/boost/log/detail/singleton.hpp b/boost/log/detail/singleton.hpp
new file mode 100644
index 0000000..ac1ac1a
--- /dev/null
+++ b/boost/log/detail/singleton.hpp
@@ -0,0 +1,89 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file singleton.hpp
+ * \author Andrey Semashev
+ * \date 20.04.2008
+ *
+ * \brief This header is the Boost.Log library implementation, see the library documentation
+ * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
+ */
+
+#ifndef BOOST_LOG_DETAIL_SINGLETON_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_SINGLETON_HPP_INCLUDED_
+
+#include <boost/log/detail/config.hpp>
+#include <boost/log/utility/once_block.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace aux {
+
+//! A base class for singletons, constructed on-demand
+template< typename DerivedT, typename StorageT = DerivedT >
+class lazy_singleton
+{
+public:
+ BOOST_DEFAULTED_FUNCTION(lazy_singleton(), {})
+
+ //! Returns the singleton instance
+ static StorageT& get()
+ {
+ BOOST_LOG_ONCE_BLOCK()
+ {
+ DerivedT::init_instance();
+ }
+ return get_instance();
+ }
+
+ //! Initializes the singleton instance
+ static void init_instance()
+ {
+ get_instance();
+ }
+
+ BOOST_DELETED_FUNCTION(lazy_singleton(lazy_singleton const&))
+ BOOST_DELETED_FUNCTION(lazy_singleton& operator= (lazy_singleton const&))
+
+protected:
+ //! Returns the singleton instance (not thread-safe)
+ static StorageT& get_instance()
+ {
+ static StorageT instance;
+ return instance;
+ }
+};
+
+//! A base class for singletons, constructed on namespace scope initialization stage
+template< typename DerivedT, typename StorageT = DerivedT >
+class singleton :
+ public lazy_singleton< DerivedT, StorageT >
+{
+public:
+ static StorageT& instance;
+};
+
+template< typename DerivedT, typename StorageT >
+StorageT& singleton< DerivedT, StorageT >::instance =
+ lazy_singleton< DerivedT, StorageT >::get();
+
+} // namespace aux
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_DETAIL_SINGLETON_HPP_INCLUDED_
diff --git a/boost/log/detail/sink_init_helpers.hpp b/boost/log/detail/sink_init_helpers.hpp
new file mode 100644
index 0000000..060aab7
--- /dev/null
+++ b/boost/log/detail/sink_init_helpers.hpp
@@ -0,0 +1,118 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file sink_init_helpers.hpp
+ * \author Andrey Semashev
+ * \date 14.03.2009
+ *
+ * \brief This header is the Boost.Log library implementation, see the library documentation
+ * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
+ */
+
+#ifndef BOOST_LOG_DETAIL_SINK_INIT_HELPERS_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_SINK_INIT_HELPERS_HPP_INCLUDED_
+
+#include <string>
+#include <boost/mpl/bool.hpp>
+#include <boost/parameter/binding.hpp>
+#include <boost/type_traits/is_void.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/phoenix/core/is_actor.hpp>
+#include <boost/log/detail/config.hpp>
+#include <boost/log/core/core.hpp>
+#include <boost/log/expressions/filter.hpp>
+#include <boost/log/expressions/formatter.hpp>
+#include <boost/log/utility/setup/filter_parser.hpp>
+#include <boost/log/utility/setup/formatter_parser.hpp>
+#include <boost/log/keywords/filter.hpp>
+#include <boost/log/keywords/format.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace aux {
+
+// The function creates a filter functional object from the provided argument
+template< typename CharT >
+inline filter acquire_filter(const CharT* filter)
+{
+ return boost::log::parse_filter(filter);
+}
+template< typename CharT, typename TraitsT, typename AllocatorT >
+inline filter acquire_filter(std::basic_string< CharT, TraitsT, AllocatorT > const& filter)
+{
+ return boost::log::parse_filter(filter);
+}
+template< typename FilterT >
+inline typename enable_if<
+ phoenix::is_actor< FilterT >,
+ FilterT const&
+>::type acquire_filter(FilterT const& filter)
+{
+ return filter;
+}
+
+// The function installs filter into the sink, if provided in the arguments pack
+template< typename SinkT, typename ArgsT >
+inline void setup_filter(SinkT&, ArgsT const&, mpl::true_)
+{
+}
+
+template< typename SinkT, typename ArgsT >
+inline void setup_filter(SinkT& s, ArgsT const& args, mpl::false_)
+{
+ s.set_filter(aux::acquire_filter(args[keywords::filter]));
+}
+
+
+// The function creates a filter functional object from the provided argument
+template< typename CharT >
+inline basic_formatter< CharT > acquire_formatter(const CharT* formatter)
+{
+ return boost::log::parse_formatter(formatter);
+}
+template< typename CharT, typename TraitsT, typename AllocatorT >
+inline basic_formatter< CharT > acquire_formatter(std::basic_string< CharT, TraitsT, AllocatorT > const& formatter)
+{
+ return boost::log::parse_formatter(formatter);
+}
+template< typename FormatterT >
+inline typename enable_if<
+ phoenix::is_actor< FormatterT >,
+ FormatterT const&
+>::type acquire_formatter(FormatterT const& formatter)
+{
+ return formatter;
+}
+
+// The function installs filter into the sink, if provided in the arguments pack
+template< typename SinkT, typename ArgsT >
+inline void setup_formatter(SinkT&, ArgsT const&, mpl::true_)
+{
+}
+
+template< typename SinkT, typename ArgsT >
+inline void setup_formatter(SinkT& s, ArgsT const& args, mpl::false_)
+{
+ s.set_formatter(aux::acquire_formatter(args[keywords::format]));
+}
+
+} // namespace aux
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_DETAIL_SINK_INIT_HELPERS_HPP_INCLUDED_
diff --git a/boost/log/detail/snprintf.hpp b/boost/log/detail/snprintf.hpp
new file mode 100644
index 0000000..ced0cd5
--- /dev/null
+++ b/boost/log/detail/snprintf.hpp
@@ -0,0 +1,106 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file snprintf.hpp
+ * \author Andrey Semashev
+ * \date 20.02.2009
+ *
+ * \brief This header is the Boost.Log library implementation, see the library documentation
+ * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
+ */
+
+#ifndef BOOST_LOG_DETAIL_SNPRINTF_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_SNPRINTF_HPP_INCLUDED_
+
+#include <stdio.h>
+#include <cstddef>
+#include <cstdarg>
+#include <boost/log/detail/config.hpp>
+#ifdef BOOST_LOG_USE_WCHAR_T
+#include <wchar.h>
+#endif // BOOST_LOG_USE_WCHAR_T
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace aux {
+
+#if !defined(_MSC_VER)
+
+// Standard-conforming compilers already have the correct snprintfs
+using ::snprintf;
+using ::vsnprintf;
+
+# ifdef BOOST_LOG_USE_WCHAR_T
+using ::swprintf;
+using ::vswprintf;
+# endif // BOOST_LOG_USE_WCHAR_T
+
+#else // !defined(_MSC_VER)
+
+// MSVC snprintfs are not conforming but they are good enough for our cases
+inline int vsnprintf(char* buf, std::size_t size, const char* format, std::va_list args)
+{
+ int n = _vsnprintf(buf, size, format, args);
+ if (static_cast< unsigned int >(n) >= size)
+ {
+ n = static_cast< int >(size);
+ buf[size - 1] = '\0';
+ }
+ return n;
+}
+
+# ifdef BOOST_LOG_USE_WCHAR_T
+inline int vswprintf(wchar_t* buf, std::size_t size, const wchar_t* format, std::va_list args)
+{
+ int n = _vsnwprintf(buf, size, format, args);
+ if (static_cast< unsigned int >(n) >= size)
+ {
+ n = static_cast< int >(size);
+ buf[size - 1] = L'\0';
+ }
+ return n;
+}
+# endif // BOOST_LOG_USE_WCHAR_T
+
+inline int snprintf(char* buf, std::size_t size, const char* format, ...)
+{
+ std::va_list args;
+ va_start(args, format);
+ int n = vsnprintf(buf, size, format, args);
+ va_end(args);
+ return n;
+}
+
+# ifdef BOOST_LOG_USE_WCHAR_T
+inline int swprintf(wchar_t* buf, std::size_t size, const wchar_t* format, ...)
+{
+ std::va_list args;
+ va_start(args, format);
+ int n = vswprintf(buf, size, format, args);
+ va_end(args);
+ return n;
+}
+# endif // BOOST_LOG_USE_WCHAR_T
+
+#endif // !defined(_MSC_VER)
+
+} // namespace aux
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_DETAIL_SNPRINTF_HPP_INCLUDED_
diff --git a/boost/log/detail/spin_mutex.hpp b/boost/log/detail/spin_mutex.hpp
new file mode 100644
index 0000000..727d6d1
--- /dev/null
+++ b/boost/log/detail/spin_mutex.hpp
@@ -0,0 +1,319 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * 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 spin_mutex.hpp
+ * \author Andrey Semashev
+ * \date 01.08.2010
+ *
+ * \brief This header is the Boost.Log library implementation, see the library documentation
+ * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
+ */
+
+#ifndef BOOST_LOG_DETAIL_SPIN_MUTEX_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_SPIN_MUTEX_HPP_INCLUDED_
+
+#include <boost/log/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#ifndef BOOST_LOG_NO_THREADS
+
+#include <boost/throw_exception.hpp>
+#include <boost/thread/exceptions.hpp>
+
+#if defined(BOOST_THREAD_POSIX) // This one can be defined by users, so it should go first
+#define BOOST_LOG_SPIN_MUTEX_USE_PTHREAD
+#elif defined(BOOST_WINDOWS)
+#define BOOST_LOG_SPIN_MUTEX_USE_WINAPI
+#elif defined(BOOST_HAS_PTHREADS)
+#define BOOST_LOG_SPIN_MUTEX_USE_PTHREAD
+#endif
+
+#if defined(BOOST_LOG_SPIN_MUTEX_USE_WINAPI)
+
+#include <boost/detail/interlocked.hpp>
+
+#if defined(BOOST_USE_WINDOWS_H)
+
+#ifndef _WIN32_WINNT
+#define _WIN32_WINNT 0x0500
+#endif
+
+#include <windows.h>
+
+#else // defined(BOOST_USE_WINDOWS_H)
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace aux {
+
+extern "C" {
+
+__declspec(dllimport) int __stdcall SwitchToThread();
+
+} // extern "C"
+
+} // namespace aux
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#endif // BOOST_USE_WINDOWS_H
+
+#if defined(__INTEL_COMPILER) || defined(_MSC_VER)
+# if defined(_M_IX86)
+# define BOOST_LOG_PAUSE_OP __asm { pause }
+# elif defined(_M_AMD64)
+extern "C" void _mm_pause(void);
+#pragma intrinsic(_mm_pause)
+# define BOOST_LOG_PAUSE_OP _mm_pause()
+# endif
+# if defined(__INTEL_COMPILER)
+# define BOOST_LOG_COMPILER_BARRIER __memory_barrier()
+# else
+extern "C" void _ReadWriteBarrier(void);
+#pragma intrinsic(_ReadWriteBarrier)
+# define BOOST_LOG_COMPILER_BARRIER _ReadWriteBarrier()
+# endif
+#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
+# define BOOST_LOG_PAUSE_OP __asm__ __volatile__("pause;")
+# define BOOST_LOG_COMPILER_BARRIER __asm__ __volatile__("" : : : "memory")
+#endif
+
+#include <boost/log/detail/header.hpp>
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace aux {
+
+//! A simple spinning mutex
+class spin_mutex
+{
+private:
+ enum state
+ {
+ initial_pause = 2,
+ max_pause = 16
+ };
+
+ long m_State;
+
+public:
+ spin_mutex() : m_State(0) {}
+
+ bool try_lock()
+ {
+ return (BOOST_INTERLOCKED_COMPARE_EXCHANGE(&m_State, 1L, 0L) == 0L);
+ }
+
+ void lock()
+ {
+#if defined(BOOST_LOG_PAUSE_OP)
+ unsigned int pause_count = initial_pause;
+#endif
+ while (!try_lock())
+ {
+#if defined(BOOST_LOG_PAUSE_OP)
+ if (pause_count < max_pause)
+ {
+ for (unsigned int i = 0; i < pause_count; ++i)
+ {
+ BOOST_LOG_PAUSE_OP;
+ }
+ pause_count += pause_count;
+ }
+ else
+ {
+ // Restart spinning after waking up this thread
+ pause_count = initial_pause;
+ SwitchToThread();
+ }
+#else
+ SwitchToThread();
+#endif
+ }
+ }
+
+ void unlock()
+ {
+#if (defined(_M_IX86) || defined(_M_AMD64)) && defined(BOOST_LOG_COMPILER_BARRIER)
+ BOOST_LOG_COMPILER_BARRIER;
+ m_State = 0L;
+ BOOST_LOG_COMPILER_BARRIER;
+#else
+ BOOST_INTERLOCKED_EXCHANGE(&m_State, 0L);
+#endif
+ }
+
+ // Non-copyable
+ BOOST_DELETED_FUNCTION(spin_mutex(spin_mutex const&))
+ BOOST_DELETED_FUNCTION(spin_mutex& operator= (spin_mutex const&))
+};
+
+#undef BOOST_LOG_PAUSE_OP
+#undef BOOST_LOG_COMPILER_BARRIER
+
+} // namespace aux
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#elif defined(BOOST_LOG_SPIN_MUTEX_USE_PTHREAD)
+
+#include <pthread.h>
+#include <boost/assert.hpp>
+#include <boost/log/detail/header.hpp>
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace aux {
+
+#if defined(_POSIX_SPIN_LOCKS) && _POSIX_SPIN_LOCKS > 0
+
+//! A simple spinning mutex
+class spin_mutex
+{
+private:
+ pthread_spinlock_t m_State;
+
+public:
+ spin_mutex()
+ {
+ const int err = pthread_spin_init(&m_State, PTHREAD_PROCESS_PRIVATE);
+ if (err != 0)
+ throw_exception< thread_resource_error >(err, "failed to initialize a spin mutex", "spin_mutex::spin_mutex()", __FILE__, __LINE__);
+ }
+
+ ~spin_mutex()
+ {
+ BOOST_VERIFY(pthread_spin_destroy(&m_State) == 0);
+ }
+
+ bool try_lock()
+ {
+ const int err = pthread_spin_trylock(&m_State);
+ if (err == 0)
+ return true;
+ if (err != EBUSY)
+ throw_exception< lock_error >(err, "failed to lock a spin mutex", "spin_mutex::try_lock()", __FILE__, __LINE__);
+ return false;
+ }
+
+ void lock()
+ {
+ const int err = pthread_spin_lock(&m_State);
+ if (err != 0)
+ throw_exception< lock_error >(err, "failed to lock a spin mutex", "spin_mutex::lock()", __FILE__, __LINE__);
+ }
+
+ void unlock()
+ {
+ BOOST_VERIFY(pthread_spin_unlock(&m_State) == 0);
+ }
+
+ // Non-copyable
+ BOOST_DELETED_FUNCTION(spin_mutex(spin_mutex const&))
+ BOOST_DELETED_FUNCTION(spin_mutex& operator= (spin_mutex const&))
+
+private:
+ template< typename ExceptionT >
+ static BOOST_NOINLINE BOOST_LOG_NORETURN void throw_exception(int err, const char* descr, const char* func, const char* file, int line)
+ {
+#if !defined(BOOST_EXCEPTION_DISABLE)
+ boost::exception_detail::throw_exception_(ExceptionT(err, descr), func, file, line);
+#else
+ boost::throw_exception(ExceptionT(err, descr));
+#endif
+ }
+};
+
+#else // defined(_POSIX_SPIN_LOCKS)
+
+//! Backup implementation in case if pthreads don't support spin locks
+class spin_mutex
+{
+private:
+ pthread_mutex_t m_State;
+
+public:
+ spin_mutex()
+ {
+ const int err = pthread_mutex_init(&m_State, NULL);
+ if (err != 0)
+ throw_exception< thread_resource_error >(err, "failed to initialize a spin mutex", "spin_mutex::spin_mutex()", __FILE__, __LINE__);
+ }
+
+ ~spin_mutex()
+ {
+ BOOST_VERIFY(pthread_mutex_destroy(&m_State) == 0);
+ }
+
+ bool try_lock()
+ {
+ const int err = pthread_mutex_trylock(&m_State);
+ if (err == 0)
+ return true;
+ if (err != EBUSY)
+ throw_exception< lock_error >(err, "failed to lock a spin mutex", "spin_mutex::try_lock()", __FILE__, __LINE__);
+ return false;
+ }
+
+ void lock()
+ {
+ const int err = pthread_mutex_lock(&m_State);
+ if (err != 0)
+ throw_exception< lock_error >(err, "failed to lock a spin mutex", "spin_mutex::lock()", __FILE__, __LINE__);
+ }
+
+ void unlock()
+ {
+ BOOST_VERIFY(pthread_mutex_unlock(&m_State) == 0);
+ }
+
+ // Non-copyable
+ BOOST_DELETED_FUNCTION(spin_mutex(spin_mutex const&))
+ BOOST_DELETED_FUNCTION(spin_mutex& operator= (spin_mutex const&))
+
+private:
+ template< typename ExceptionT >
+ static BOOST_NOINLINE BOOST_LOG_NORETURN void throw_exception(int err, const char* descr, const char* func, const char* file, int line)
+ {
+#if !defined(BOOST_EXCEPTION_DISABLE)
+ boost::exception_detail::throw_exception_(ExceptionT(err, descr), func, file, line);
+#else
+ boost::throw_exception(ExceptionT(err, descr));
+#endif
+ }
+};
+
+#endif // defined(_POSIX_SPIN_LOCKS)
+
+} // namespace aux
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif
+
+#endif // BOOST_LOG_NO_THREADS
+
+#endif // BOOST_LOG_DETAIL_SPIN_MUTEX_HPP_INCLUDED_
diff --git a/boost/log/detail/tagged_integer.hpp b/boost/log/detail/tagged_integer.hpp
new file mode 100644
index 0000000..5aef5bb
--- /dev/null
+++ b/boost/log/detail/tagged_integer.hpp
@@ -0,0 +1,147 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file tagged_integer.hpp
+ * \author Andrey Semashev
+ * \date 11.01.2008
+ *
+ * \brief This header is the Boost.Log library implementation, see the library documentation
+ * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
+ */
+
+#ifndef BOOST_LOG_TAGGED_INTEGER_HPP_INCLUDED_
+#define BOOST_LOG_TAGGED_INTEGER_HPP_INCLUDED_
+
+#include <boost/log/detail/config.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace aux {
+
+//! A tagged integer wrapper for type safety
+template< typename IntT, typename TagT >
+struct tagged_integer
+{
+ //! Contained value type
+ typedef IntT integer_type;
+ //! Tag
+ typedef TagT tag;
+
+ //! Contained value
+ integer_type value;
+
+ //! Conversion operator
+ operator integer_type() const { return value; }
+
+ // Increment
+ tagged_integer& operator++ () { ++value; return *this; }
+ tagged_integer operator++ (int) { tagged_integer temp = *this; ++value; return temp; }
+ // Decrement
+ tagged_integer& operator-- () { --value; return *this; }
+ tagged_integer operator-- (int) { tagged_integer temp = *this; --value; return temp; }
+
+#define BOOST_LOG_TAGGED_INTEGER_OP(op)\
+ tagged_integer& operator op (tagged_integer const& that) { value op that.value; return *this; }
+
+ BOOST_LOG_TAGGED_INTEGER_OP(|=)
+ BOOST_LOG_TAGGED_INTEGER_OP(&=)
+ BOOST_LOG_TAGGED_INTEGER_OP(^=)
+ BOOST_LOG_TAGGED_INTEGER_OP(+=)
+ BOOST_LOG_TAGGED_INTEGER_OP(-=)
+ BOOST_LOG_TAGGED_INTEGER_OP(*=)
+ BOOST_LOG_TAGGED_INTEGER_OP(/=)
+ BOOST_LOG_TAGGED_INTEGER_OP(%=)
+
+#undef BOOST_LOG_TAGGED_INTEGER_OP
+
+ //! Inversion operator
+ tagged_integer& operator~ () { ~value; return *this; }
+
+ // Shift operators
+ template< typename T >
+ tagged_integer& operator<<= (T const& that) { value <<= that; return *this; }
+ template< typename T >
+ tagged_integer& operator>>= (T const& that) { value >>= that; return *this; }
+
+private:
+ // Protection against improper usage
+ template< typename T1, typename T2 >
+ tagged_integer& operator<<= (tagged_integer< T1, T2 > const&);
+ template< typename T1, typename T2 >
+ tagged_integer& operator>>= (tagged_integer< T1, T2 > const&);
+};
+
+ // Relational operators
+#define BOOST_LOG_TAGGED_INTEGER_OP(op)\
+ template< typename IntT, typename TagT >\
+ inline bool operator op (\
+ tagged_integer< IntT, TagT > const& left, tagged_integer< IntT, TagT > const& right)\
+ {\
+ return (left.value op right.value);\
+ }
+
+BOOST_LOG_TAGGED_INTEGER_OP(==)
+BOOST_LOG_TAGGED_INTEGER_OP(!=)
+BOOST_LOG_TAGGED_INTEGER_OP(<)
+BOOST_LOG_TAGGED_INTEGER_OP(>)
+BOOST_LOG_TAGGED_INTEGER_OP(<=)
+BOOST_LOG_TAGGED_INTEGER_OP(>=)
+
+#undef BOOST_LOG_TAGGED_INTEGER_OP
+
+#define BOOST_LOG_TAGGED_INTEGER_OP(op)\
+ template< typename IntT, typename TagT >\
+ inline tagged_integer< IntT, TagT > operator op (\
+ tagged_integer< IntT, TagT > const& left, tagged_integer< IntT, TagT > const& right)\
+ {\
+ tagged_integer< IntT, TagT > temp = left;\
+ temp op##= right;\
+ return temp;\
+ }
+
+BOOST_LOG_TAGGED_INTEGER_OP(|)
+BOOST_LOG_TAGGED_INTEGER_OP(&)
+BOOST_LOG_TAGGED_INTEGER_OP(^)
+BOOST_LOG_TAGGED_INTEGER_OP(+)
+BOOST_LOG_TAGGED_INTEGER_OP(-)
+BOOST_LOG_TAGGED_INTEGER_OP(*)
+BOOST_LOG_TAGGED_INTEGER_OP(/)
+BOOST_LOG_TAGGED_INTEGER_OP(%)
+
+#undef BOOST_LOG_TAGGED_INTEGER_OP
+
+#define BOOST_LOG_TAGGED_INTEGER_OP(op)\
+ template< typename IntT, typename TagT, typename T >\
+ inline tagged_integer< IntT, TagT > operator op (\
+ tagged_integer< IntT, TagT > const& left, T const& right)\
+ {\
+ tagged_integer< IntT, TagT > temp = left;\
+ temp op##= right;\
+ return temp;\
+ }
+
+BOOST_LOG_TAGGED_INTEGER_OP(<<)
+BOOST_LOG_TAGGED_INTEGER_OP(>>)
+
+#undef BOOST_LOG_TAGGED_INTEGER_OP
+
+} // namespace aux
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_TAGGED_INTEGER_HPP_INCLUDED_
diff --git a/boost/log/detail/thread_id.hpp b/boost/log/detail/thread_id.hpp
new file mode 100644
index 0000000..3b592c2
--- /dev/null
+++ b/boost/log/detail/thread_id.hpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file thread_id.hpp
+ * \author Andrey Semashev
+ * \date 08.01.2012
+ *
+ * \brief This header is the Boost.Log library implementation, see the library documentation
+ * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
+ */
+
+#ifndef BOOST_LOG_DETAIL_THREAD_ID_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_THREAD_ID_HPP_INCLUDED_
+
+#include <iosfwd>
+#include <boost/cstdint.hpp>
+#include <boost/log/detail/config.hpp>
+#include <boost/log/detail/id.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace aux {
+
+//! The thread id descriptor
+struct thread
+{
+#if defined(BOOST_WINDOWS)
+ typedef uint32_t native_type;
+#else
+ typedef uintmax_t native_type;
+#endif
+ typedef boost::log::aux::id< thread > id;
+};
+
+namespace this_thread {
+
+//! The function returns current thread identifier
+BOOST_LOG_API thread::id const& get_id();
+
+} // namespace this_thread
+
+template< typename CharT, typename TraitsT >
+BOOST_LOG_API std::basic_ostream< CharT, TraitsT >&
+operator<< (std::basic_ostream< CharT, TraitsT >& strm, thread::id const& tid);
+
+} // namespace aux
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_DETAIL_THREAD_ID_HPP_INCLUDED_
diff --git a/boost/log/detail/thread_specific.hpp b/boost/log/detail/thread_specific.hpp
new file mode 100644
index 0000000..72d2a3b
--- /dev/null
+++ b/boost/log/detail/thread_specific.hpp
@@ -0,0 +1,116 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file thread_specific.hpp
+ * \author Andrey Semashev
+ * \date 01.03.2008
+ *
+ * \brief This header is the Boost.Log library implementation, see the library documentation
+ * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
+ */
+
+#ifndef BOOST_LOG_DETAIL_THREAD_SPECIFIC_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_THREAD_SPECIFIC_HPP_INCLUDED_
+
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_pod.hpp>
+#include <boost/log/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#if !defined(BOOST_LOG_NO_THREADS)
+
+#include <boost/log/detail/header.hpp>
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace aux {
+
+//! Base class for TLS to hide platform-specific storage management
+class thread_specific_base
+{
+private:
+ union key_storage
+ {
+ void* as_pointer;
+ unsigned int as_dword;
+ };
+
+ key_storage m_Key;
+
+protected:
+ BOOST_LOG_API thread_specific_base();
+ BOOST_LOG_API ~thread_specific_base();
+ BOOST_LOG_API void* get_content() const;
+ BOOST_LOG_API void set_content(void* value) const;
+
+ // Copying prohibited
+ BOOST_DELETED_FUNCTION(thread_specific_base(thread_specific_base const&))
+ BOOST_DELETED_FUNCTION(thread_specific_base& operator= (thread_specific_base const&))
+};
+
+//! A TLS wrapper for small POD types with least possible overhead
+template< typename T >
+class thread_specific :
+ public thread_specific_base
+{
+ BOOST_STATIC_ASSERT_MSG(sizeof(T) <= sizeof(void*) && is_pod< T >::value, "Boost.Log: Thread-specific values must be PODs and must not exceed the size of a pointer");
+
+ //! Union to perform type casting
+ union value_storage
+ {
+ void* as_pointer;
+ T as_value;
+ };
+
+public:
+ //! Default constructor
+ BOOST_DEFAULTED_FUNCTION(thread_specific(), {})
+ //! Initializing constructor
+ thread_specific(T const& value)
+ {
+ set(value);
+ }
+ //! Assignment
+ thread_specific& operator= (T const& value)
+ {
+ set(value);
+ return *this;
+ }
+
+ //! Accessor
+ T get() const
+ {
+ value_storage cast = {};
+ cast.as_pointer = thread_specific_base::get_content();
+ return cast.as_value;
+ }
+
+ //! Setter
+ void set(T const& value)
+ {
+ value_storage cast = {};
+ cast.as_value = value;
+ thread_specific_base::set_content(cast.as_pointer);
+ }
+};
+
+} // namespace aux
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // !defined(BOOST_LOG_NO_THREADS)
+
+#endif // BOOST_LOG_DETAIL_THREAD_SPECIFIC_HPP_INCLUDED_
diff --git a/boost/log/detail/threadsafe_queue.hpp b/boost/log/detail/threadsafe_queue.hpp
new file mode 100644
index 0000000..a1e7824
--- /dev/null
+++ b/boost/log/detail/threadsafe_queue.hpp
@@ -0,0 +1,277 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file threadsafe_queue.hpp
+ * \author Andrey Semashev
+ * \date 05.11.2010
+ *
+ * \brief This header is the Boost.Log library implementation, see the library documentation
+ * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
+ */
+
+#ifndef BOOST_LOG_DETAIL_THREADSAFE_QUEUE_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_THREADSAFE_QUEUE_HPP_INCLUDED_
+
+#include <boost/log/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#ifndef BOOST_LOG_NO_THREADS
+
+#include <new>
+#include <memory>
+#include <cstddef>
+#include <boost/aligned_storage.hpp>
+#include <boost/move/core.hpp>
+#include <boost/move/utility.hpp>
+#include <boost/type_traits/alignment_of.hpp>
+#include <boost/type_traits/type_with_alignment.hpp>
+#include <boost/log/detail/header.hpp>
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace aux {
+
+//! Base class for the thread-safe queue implementation
+struct threadsafe_queue_impl
+{
+ struct
+#if defined(__GNUC__)
+ // Explicitly mark the type so that it may alias other types
+ __attribute__ ((__may_alias__))
+#endif
+ pointer_storage
+ {
+ union
+ {
+ void* data[2];
+ type_with_alignment< 2 * sizeof(void*) >::type alignment;
+ };
+ };
+
+ struct node_base
+ {
+ pointer_storage next;
+ };
+
+ static BOOST_LOG_API threadsafe_queue_impl* create(node_base* first_node);
+
+ static BOOST_LOG_API void* operator new (std::size_t size);
+ static BOOST_LOG_API void operator delete (void* p, std::size_t);
+
+ virtual ~threadsafe_queue_impl() {}
+ virtual node_base* reset_last_node() = 0;
+ virtual bool unsafe_empty() = 0;
+ virtual void push(node_base* p) = 0;
+ virtual bool try_pop(node_base*& node_to_free, node_base*& node_with_value) = 0;
+};
+
+//! A helper class to compose some of the types used by the queue
+template< typename T, typename AllocatorT >
+struct threadsafe_queue_types
+{
+ struct node :
+ public threadsafe_queue_impl::node_base
+ {
+ typedef typename aligned_storage< sizeof(T), alignment_of< T >::value >::type storage_type;
+ storage_type storage;
+
+ node() {}
+ explicit node(T const& val) { new (storage.address()) T(val); }
+ T& value() { return *static_cast< T* >(storage.address()); }
+ void destroy() { static_cast< T* >(storage.address())->~T(); }
+ };
+
+ typedef typename AllocatorT::BOOST_NESTED_TEMPLATE rebind< node >::other allocator_type;
+};
+
+/*!
+ * \brief An unbounded thread-safe queue
+ *
+ * The implementation is based on algorithms published in the "Simple, Fast,
+ * and Practical Non-Blocking and Blocking Concurrent Queue Algorithms" article
+ * in PODC96 by Maged M. Michael and Michael L. Scott. Pseudocode is available here:
+ * http://www.cs.rochester.edu/research/synchronization/pseudocode/queues.html
+ *
+ * The implementation provides thread-safe \c push and \c try_pop operations, as well as
+ * a thread-unsafe \c empty operation. The queue imposes the following requirements
+ * on the element type:
+ *
+ * \li Default constructible, the default constructor must not throw.
+ * \li Copy constructible.
+ * \li Movable (i.e. there should be an efficient move assignment for this type).
+ *
+ * The last requirement is not mandatory but is crucial for decent performance.
+ */
+template< typename T, typename AllocatorT = std::allocator< void > >
+class threadsafe_queue :
+ private threadsafe_queue_types< T, AllocatorT >::allocator_type
+{
+private:
+ typedef typename threadsafe_queue_types< T, AllocatorT >::allocator_type base_type;
+ typedef typename threadsafe_queue_types< T, AllocatorT >::node node;
+
+ //! A simple scope guard to automate memory reclaiming
+ struct auto_deallocate;
+ friend struct auto_deallocate;
+ struct auto_deallocate
+ {
+ auto_deallocate(base_type* alloc, node* dealloc, node* destr) :
+ m_pAllocator(alloc),
+ m_pDeallocate(dealloc),
+ m_pDestroy(destr)
+ {
+ }
+ ~auto_deallocate()
+ {
+ m_pAllocator->deallocate(m_pDeallocate, 1);
+ m_pDestroy->destroy();
+ }
+
+ private:
+ base_type* m_pAllocator;
+ node* m_pDeallocate;
+ node* m_pDestroy;
+ };
+
+public:
+ typedef T value_type;
+ typedef T& reference;
+ typedef T const& const_reference;
+ typedef T* pointer;
+ typedef T const* const_pointer;
+ typedef std::ptrdiff_t difference_type;
+ typedef std::size_t size_type;
+ typedef AllocatorT allocator_type;
+
+public:
+ /*!
+ * Default constructor, creates an empty queue. Unlike most containers,
+ * the constructor requires memory allocation.
+ *
+ * \throw std::bad_alloc if there is not sufficient memory
+ */
+ threadsafe_queue(base_type const& alloc = base_type()) :
+ base_type(alloc)
+ {
+ node* p = base_type::allocate(1);
+ if (p)
+ {
+ try
+ {
+ new (p) node();
+ try
+ {
+ m_pImpl = threadsafe_queue_impl::create(p);
+ }
+ catch (...)
+ {
+ p->~node();
+ throw;
+ }
+ }
+ catch (...)
+ {
+ base_type::deallocate(p, 1);
+ throw;
+ }
+ }
+ else
+ throw std::bad_alloc();
+ }
+ /*!
+ * Destructor
+ */
+ ~threadsafe_queue()
+ {
+ // Clear the queue
+ if (!unsafe_empty())
+ {
+ value_type value;
+ while (try_pop(value));
+ }
+
+ // Remove the last dummy node
+ node* p = static_cast< node* >(m_pImpl->reset_last_node());
+ p->~node();
+ base_type::deallocate(p, 1);
+
+ delete m_pImpl;
+ }
+
+ /*!
+ * Checks if the queue is empty. Not thread-safe, the returned result may not be actual.
+ */
+ bool unsafe_empty() const { return m_pImpl->unsafe_empty(); }
+
+ /*!
+ * Puts a new element to the end of the queue. Thread-safe, can be called
+ * concurrently by several threads, and concurrently with the \c pop operation.
+ */
+ void push(const_reference value)
+ {
+ node* p = base_type::allocate(1);
+ if (p)
+ {
+ try
+ {
+ new (p) node(value);
+ }
+ catch (...)
+ {
+ base_type::deallocate(p, 1);
+ throw;
+ }
+ m_pImpl->push(p);
+ }
+ else
+ throw std::bad_alloc();
+ }
+
+ /*!
+ * Attempts to pop an element from the beginning of the queue. Thread-safe, can
+ * be called concurrently with the \c push operation. Should not be called by
+ * several threads concurrently.
+ */
+ bool try_pop(reference value)
+ {
+ threadsafe_queue_impl::node_base *dealloc, *destr;
+ if (m_pImpl->try_pop(dealloc, destr))
+ {
+ node* p = static_cast< node* >(destr);
+ auto_deallocate guard(static_cast< base_type* >(this), static_cast< node* >(dealloc), p);
+ value = boost::move(p->value());
+ return true;
+ }
+ else
+ return false;
+ }
+
+ // Copying and assignment is prohibited
+ BOOST_DELETED_FUNCTION(threadsafe_queue(threadsafe_queue const&))
+ BOOST_DELETED_FUNCTION(threadsafe_queue& operator= (threadsafe_queue const&))
+
+private:
+ //! Pointer to the implementation
+ threadsafe_queue_impl* m_pImpl;
+};
+
+} // namespace aux
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_NO_THREADS
+
+#endif // BOOST_LOG_DETAIL_THREADSAFE_QUEUE_HPP_INCLUDED_
diff --git a/boost/log/detail/timestamp.hpp b/boost/log/detail/timestamp.hpp
new file mode 100644
index 0000000..719061f
--- /dev/null
+++ b/boost/log/detail/timestamp.hpp
@@ -0,0 +1,99 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file timestamp.hpp
+ * \author Andrey Semashev
+ * \date 31.07.2011
+ *
+ * \brief This header is the Boost.Log library implementation, see the library documentation
+ * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
+ */
+
+#ifndef BOOST_LOG_DETAIL_TIMESTAMP_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_TIMESTAMP_HPP_INCLUDED_
+
+#include <boost/cstdint.hpp>
+#include <boost/log/detail/config.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace aux {
+
+/*!
+ * Duration between two timestamps
+ */
+class duration
+{
+ int64_t m_ticks;
+
+public:
+ explicit duration(int64_t ticks = 0) : m_ticks(ticks) {}
+
+#if defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
+ int64_t milliseconds() const { return m_ticks; }
+#else
+ BOOST_LOG_API int64_t milliseconds() const;
+#endif
+};
+
+/*!
+ * Opaque timestamp class
+ */
+class timestamp
+{
+ uint64_t m_ticks;
+
+public:
+ explicit timestamp(uint64_t ticks = 0) : m_ticks(ticks) {}
+
+ duration operator- (timestamp that) const
+ {
+ return duration(m_ticks - that.m_ticks);
+ }
+};
+
+/*!
+ * \fn get_timestamp
+ *
+ * The function returns a timestamp, in opaque units since an unspecified
+ * time point. This timer is guaranteed to be monotonic, it should not
+ * be affected by clock changes, either manual or seasonal. Also, it
+ * should be as fast as possible.
+ */
+#if defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
+
+typedef uint64_t (__stdcall* get_tick_count_t)();
+extern BOOST_LOG_API get_tick_count_t get_tick_count;
+
+inline timestamp get_timestamp()
+{
+ return timestamp(get_tick_count());
+}
+
+#else
+
+typedef timestamp (*get_timestamp_t)();
+extern BOOST_LOG_API get_timestamp_t get_timestamp;
+
+#endif
+
+} // namespace aux
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_DETAIL_TIMESTAMP_HPP_INCLUDED_
diff --git a/boost/log/detail/trivial_keyword.hpp b/boost/log/detail/trivial_keyword.hpp
new file mode 100644
index 0000000..d0e4f60
--- /dev/null
+++ b/boost/log/detail/trivial_keyword.hpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file trivial_keyword.hpp
+ * \author Andrey Semashev
+ * \date 02.12.2012
+ *
+ * \brief This header is the Boost.Log library implementation, see the library documentation
+ * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
+ */
+
+#ifndef BOOST_LOG_DETAIL_TRIVIAL_KEYWORD_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_TRIVIAL_KEYWORD_HPP_INCLUDED_
+
+#include <boost/log/detail/config.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace trivial {
+
+//! Trivial severity keyword
+BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", severity_level)
+
+} // namespace trivial
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_DETAIL_TRIVIAL_KEYWORD_HPP_INCLUDED_
diff --git a/boost/log/detail/unary_function_terminal.hpp b/boost/log/detail/unary_function_terminal.hpp
new file mode 100644
index 0000000..f9a3412
--- /dev/null
+++ b/boost/log/detail/unary_function_terminal.hpp
@@ -0,0 +1,142 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file unary_function_terminal.hpp
+ * \author Andrey Semashev
+ * \date 21.07.2012
+ *
+ * The header contains attribute value extractor adapter for constructing expression template terminals.
+ */
+
+#ifndef BOOST_LOG_DETAIL_UNARY_FUNCTION_TERMINAL_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_UNARY_FUNCTION_TERMINAL_HPP_INCLUDED_
+
+#include <boost/mpl/bool.hpp>
+#include <boost/utility/result_of.hpp>
+#include <boost/fusion/sequence/intrinsic/at_c.hpp>
+#include <boost/phoenix/core/is_nullary.hpp>
+#include <boost/phoenix/core/environment.hpp>
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/log/detail/config.hpp>
+#include <boost/log/detail/copy_cv.hpp>
+#include <boost/log/detail/custom_terminal_spec.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace expressions {
+
+namespace aux {
+
+/*!
+ * \brief An adapter for a unary function to be used as a terminal in a Boost.Phoenix expression
+ *
+ * This class is an adapter between Boost.Phoenix expression invocation protocol and
+ * a unary function. It forwards the call to the base function, passing only the first argument
+ * from the original call. This allows to embed value extractors in template expressions.
+ */
+template< typename FunT >
+class unary_function_terminal
+{
+private:
+ //! Adopted function type
+ typedef FunT function_type;
+ //! Self type
+ typedef unary_function_terminal< function_type > this_type;
+
+public:
+ //! Internal typedef for type categorization
+ typedef void _is_boost_log_terminal;
+
+ //! Function result type
+ template< typename >
+ struct result;
+
+ template< typename ThisT, typename ContextT >
+ struct result< ThisT(ContextT) >
+ {
+ typedef typename remove_cv<
+ typename remove_reference< typename phoenix::result_of::env< ContextT >::type >::type
+ >::type env_type;
+ typedef typename env_type::args_type args_type;
+ typedef typename boost::log::aux::copy_cv< ThisT, function_type >::type cv_function_type;
+
+ typedef typename boost::result_of< cv_function_type(typename fusion::result_of::at_c< args_type, 0 >::type) >::type type;
+ };
+
+private:
+ //! Adopted function
+ function_type m_fun;
+
+public:
+ //! Default constructor
+ BOOST_DEFAULTED_FUNCTION(unary_function_terminal(), {})
+ //! Copy constructor
+ unary_function_terminal(unary_function_terminal const& that) : m_fun(that.m_fun) {}
+ //! Initializing constructor
+ template< typename ArgT1 >
+ explicit unary_function_terminal(ArgT1 const& arg1) : m_fun(arg1) {}
+ //! Initializing constructor
+ template< typename ArgT1, typename ArgT2 >
+ unary_function_terminal(ArgT1 const& arg1, ArgT2 const& arg2) : m_fun(arg1, arg2) {}
+ //! Initializing constructor
+ template< typename ArgT1, typename ArgT2, typename ArgT3 >
+ unary_function_terminal(ArgT1 const& arg1, ArgT2 const& arg2, ArgT3 const& arg3) : m_fun(arg1, arg2, arg3) {}
+
+ //! The operator forwards the call to the base function
+ template< typename ContextT >
+ typename result< this_type(ContextT const&) >::type
+ operator() (ContextT const& ctx)
+ {
+ return m_fun(fusion::at_c< 0 >(phoenix::env(ctx).args()));
+ }
+
+ //! The operator forwards the call to the base function
+ template< typename ContextT >
+ typename result< const this_type(ContextT const&) >::type
+ operator() (ContextT const& ctx) const
+ {
+ return m_fun(fusion::at_c< 0 >(phoenix::env(ctx).args()));
+ }
+};
+
+} // namespace aux
+
+} // namespace expressions
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+#ifndef BOOST_LOG_DOXYGEN_PASS
+
+namespace phoenix {
+
+namespace result_of {
+
+template< typename FunT >
+struct is_nullary< custom_terminal< boost::log::expressions::aux::unary_function_terminal< FunT > > > :
+ public mpl::false_
+{
+};
+
+} // namespace result_of
+
+} // namespace phoenix
+
+#endif // BOOST_LOG_DOXYGEN_PASS
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_DETAIL_UNARY_FUNCTION_TERMINAL_HPP_INCLUDED_
diff --git a/boost/log/detail/unhandled_exception_count.hpp b/boost/log/detail/unhandled_exception_count.hpp
new file mode 100644
index 0000000..17866c3
--- /dev/null
+++ b/boost/log/detail/unhandled_exception_count.hpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file unhandled_exception_count.hpp
+ * \author Andrey Semashev
+ * \date 05.11.2012
+ *
+ * \brief This header is the Boost.Log library implementation, see the library documentation
+ * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
+ */
+
+#ifndef BOOST_LOG_DETAIL_UNHANDLED_EXCEPTION_COUNT_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_UNHANDLED_EXCEPTION_COUNT_HPP_INCLUDED_
+
+#include <boost/log/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace aux {
+
+//! Returns the number of currently pending exceptions
+BOOST_LOG_API unsigned int unhandled_exception_count() BOOST_NOEXCEPT;
+
+} // namespace aux
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#endif // BOOST_LOG_DETAIL_UNHANDLED_EXCEPTION_COUNT_HPP_INCLUDED_
diff --git a/boost/log/detail/value_ref_visitation.hpp b/boost/log/detail/value_ref_visitation.hpp
new file mode 100644
index 0000000..795069d
--- /dev/null
+++ b/boost/log/detail/value_ref_visitation.hpp
@@ -0,0 +1,107 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file value_ref_visitation.hpp
+ * \author Andrey Semashev
+ * \date 28.07.2012
+ *
+ * \brief This header is the Boost.Log library implementation, see the library documentation
+ * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html. In this file
+ * internal configuration macros are defined.
+ */
+
+#ifndef BOOST_LOG_DETAIL_VALUE_REF_VISITATION_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_VALUE_REF_VISITATION_HPP_INCLUDED_
+
+#include <boost/mpl/at.hpp>
+#include <boost/mpl/begin.hpp>
+#include <boost/mpl/end.hpp>
+#include <boost/mpl/advance.hpp>
+#include <boost/mpl/erase.hpp>
+#include <boost/mpl/size.hpp>
+#include <boost/preprocessor/arithmetic/inc.hpp>
+#include <boost/preprocessor/repetition/repeat_from_to.hpp>
+#include <boost/preprocessor/iteration/iterate.hpp>
+#include <boost/log/detail/config.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifndef BOOST_LOG_VALUE_REF_VISITATION_UNROLL_COUNT
+#define BOOST_LOG_VALUE_REF_VISITATION_UNROLL_COUNT 8
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace aux {
+
+template< typename SequenceT, typename VisitorT, unsigned int SizeV = mpl::size< SequenceT >::value >
+struct apply_visitor_dispatch
+{
+ typedef typename VisitorT::result_type result_type;
+
+ static BOOST_FORCEINLINE result_type call(const void* p, unsigned int type_index, VisitorT& visitor)
+ {
+ typedef typename mpl::begin< SequenceT >::type begin_type;
+ typedef typename mpl::advance_c< begin_type, SizeV / 2u >::type middle_type;
+ if (type_index < (SizeV / 2u))
+ {
+ typedef typename mpl::erase< SequenceT, middle_type, typename mpl::end< SequenceT >::type >::type new_sequence;
+ typedef apply_visitor_dispatch< new_sequence, VisitorT > new_dispatch;
+ return new_dispatch::call(p, type_index, visitor);
+ }
+ else
+ {
+ typedef typename mpl::erase< SequenceT, begin_type, middle_type >::type new_sequence;
+ typedef apply_visitor_dispatch< new_sequence, VisitorT > new_dispatch;
+ return new_dispatch::call(p, type_index - (SizeV / 2u), visitor);
+ }
+ }
+};
+
+#define BOOST_LOG_AUX_CASE_ENTRY(z, i, data)\
+ case i: return visitor(*static_cast< typename mpl::at_c< SequenceT, i >::type const* >(p));
+
+#define BOOST_PP_FILENAME_1 <boost/log/detail/value_ref_visitation.hpp>
+#define BOOST_PP_ITERATION_LIMITS (1, BOOST_PP_INC(BOOST_LOG_VALUE_REF_VISITATION_VTABLE_SIZE))
+#include BOOST_PP_ITERATE()
+
+#undef BOOST_LOG_AUX_CASE_ENTRY
+
+} // namespace aux
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_DETAIL_VALUE_REF_VISITATION_HPP_INCLUDED_
+
+#ifdef BOOST_PP_IS_ITERATING
+
+#define BOOST_LOG_AUX_SWITCH_SIZE BOOST_PP_ITERATION()
+
+template< typename SequenceT, typename VisitorT >
+struct apply_visitor_dispatch< SequenceT, VisitorT, BOOST_LOG_AUX_SWITCH_SIZE >
+{
+ typedef typename VisitorT::result_type result_type;
+
+ static BOOST_FORCEINLINE result_type call(const void* p, unsigned int type_index, VisitorT& visitor)
+ {
+ switch (type_index)
+ {
+ BOOST_PP_REPEAT_FROM_TO(1, BOOST_LOG_AUX_SWITCH_SIZE, BOOST_LOG_AUX_CASE_ENTRY, ~)
+ default:
+ return visitor(*static_cast< typename mpl::at_c< SequenceT, 0 >::type const* >(p));
+ }
+ }
+};
+
+#undef BOOST_LOG_AUX_SWITCH_SIZE
+
+#endif // BOOST_PP_IS_ITERATING
diff --git a/boost/log/detail/visible_type.hpp b/boost/log/detail/visible_type.hpp
new file mode 100644
index 0000000..2086278
--- /dev/null
+++ b/boost/log/detail/visible_type.hpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * 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 visible_type.hpp
+ * \author Andrey Semashev
+ * \date 08.03.2007
+ *
+ * \brief This header is the Boost.Log library implementation, see the library documentation
+ * at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html. In this file
+ * internal configuration macros are defined.
+ */
+
+#ifndef BOOST_LOG_DETAIL_VISIBLE_TYPE_HPP_INCLUDED_
+#define BOOST_LOG_DETAIL_VISIBLE_TYPE_HPP_INCLUDED_
+
+#include <boost/log/detail/config.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace aux {
+
+//! The wrapper type whose type_info is always visible
+template< typename T >
+struct BOOST_SYMBOL_VISIBLE visible_type
+{
+ typedef T wrapped_type;
+};
+
+} // namespace aux
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_DETAIL_VISIBLE_TYPE_HPP_INCLUDED_
diff --git a/boost/log/exceptions.hpp b/boost/log/exceptions.hpp
new file mode 100644
index 0000000..8171d0a
--- /dev/null
+++ b/boost/log/exceptions.hpp
@@ -0,0 +1,387 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file
+ * \author Andrey Semashev
+ * \date 31.10.2009
+ *
+ * The header contains exception classes declarations.
+ */
+
+#ifndef BOOST_LOG_EXCEPTIONS_HPP_INCLUDED_
+#define BOOST_LOG_EXCEPTIONS_HPP_INCLUDED_
+
+#include <cstddef>
+#include <string>
+#include <stdexcept>
+#include <boost/preprocessor/seq/enum.hpp>
+#include <boost/log/detail/config.hpp>
+#include <boost/log/attributes/attribute_name.hpp>
+#include <boost/log/utility/type_info_wrapper.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+// Forward-declaration of an exception base class from Boost.Exception
+#if defined(__GNUC__)
+# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)
+# pragma GCC visibility push (default)
+
+class exception;
+
+# pragma GCC visibility pop
+# else
+
+class exception;
+
+# endif
+#else
+
+class BOOST_SYMBOL_VISIBLE exception;
+
+#endif
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace aux {
+
+//! Attaches attribute name exception information
+BOOST_LOG_API void attach_attribute_name_info(exception& e, attribute_name const& name);
+
+} // namespace aux
+
+/*!
+ * \brief Base class for runtime exceptions from the logging library
+ *
+ * Exceptions derived from this class indicate a problem that may not directly
+ * be caused by the user's code that interacts with the library, such as
+ * errors caused by input data.
+ */
+class BOOST_LOG_API runtime_error :
+ public std::runtime_error
+{
+protected:
+ /*!
+ * Initializing constructor. Creates an exception with the specified error message.
+ */
+ explicit runtime_error(std::string const& descr);
+ /*!
+ * Destructor
+ */
+ ~runtime_error() throw();
+};
+
+/*!
+ * \brief Exception class that is used to indicate errors of missing values
+ */
+class BOOST_LOG_API missing_value :
+ public runtime_error
+{
+public:
+ /*!
+ * Default constructor. Creates an exception with the default error message.
+ */
+ missing_value();
+ /*!
+ * Initializing constructor. Creates an exception with the specified error message.
+ */
+ explicit missing_value(std::string const& descr);
+ /*!
+ * Destructor
+ */
+ ~missing_value() throw();
+
+#ifndef BOOST_LOG_DOXYGEN_PASS
+ static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line);
+ static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, std::string const& descr);
+ static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, std::string const& descr, attribute_name const& name);
+#endif
+};
+
+/*!
+ * \brief Exception class that is used to indicate errors of incorrect type of an object
+ */
+class BOOST_LOG_API invalid_type :
+ public runtime_error
+{
+public:
+ /*!
+ * Default constructor. Creates an exception with the default error message.
+ */
+ invalid_type();
+ /*!
+ * Initializing constructor. Creates an exception with the specified error message.
+ */
+ explicit invalid_type(std::string const& descr);
+ /*!
+ * Destructor
+ */
+ ~invalid_type() throw();
+
+#ifndef BOOST_LOG_DOXYGEN_PASS
+ static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line);
+ static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, std::string const& descr);
+ static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, std::string const& descr, attribute_name const& name);
+ static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, std::string const& descr, type_info_wrapper const& type);
+ static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, std::string const& descr, attribute_name const& name, type_info_wrapper const& type);
+#endif
+};
+
+/*!
+ * \brief Exception class that is used to indicate errors of incorrect value of an object
+ */
+class BOOST_LOG_API invalid_value :
+ public runtime_error
+{
+public:
+ /*!
+ * Default constructor. Creates an exception with the default error message.
+ */
+ invalid_value();
+ /*!
+ * Initializing constructor. Creates an exception with the specified error message.
+ */
+ explicit invalid_value(std::string const& descr);
+ /*!
+ * Destructor
+ */
+ ~invalid_value() throw();
+
+#ifndef BOOST_LOG_DOXYGEN_PASS
+ static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line);
+ static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, std::string const& descr);
+#endif
+};
+
+/*!
+ * \brief Exception class that is used to indicate parsing errors
+ */
+class BOOST_LOG_API parse_error :
+ public runtime_error
+{
+public:
+ /*!
+ * Default constructor. Creates an exception with the default error message.
+ */
+ parse_error();
+ /*!
+ * Initializing constructor. Creates an exception with the specified error message.
+ */
+ explicit parse_error(std::string const& descr);
+ /*!
+ * Destructor
+ */
+ ~parse_error() throw();
+
+#ifndef BOOST_LOG_DOXYGEN_PASS
+ static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line);
+ static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, std::string const& descr);
+ static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, std::string const& descr, std::size_t content_line);
+ static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, std::string const& descr, attribute_name const& name);
+#endif
+};
+
+/*!
+ * \brief Exception class that is used to indicate conversion errors
+ */
+class BOOST_LOG_API conversion_error :
+ public runtime_error
+{
+public:
+ /*!
+ * Default constructor. Creates an exception with the default error message.
+ */
+ conversion_error();
+ /*!
+ * Initializing constructor. Creates an exception with the specified error message.
+ */
+ explicit conversion_error(std::string const& descr);
+ /*!
+ * Destructor
+ */
+ ~conversion_error() throw();
+
+#ifndef BOOST_LOG_DOXYGEN_PASS
+ static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line);
+ static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, std::string const& descr);
+#endif
+};
+
+/*!
+ * \brief Exception class that is used to indicate underlying OS API errors
+ */
+class BOOST_LOG_API system_error :
+ public runtime_error
+{
+public:
+ /*!
+ * Default constructor. Creates an exception with the default error message.
+ */
+ system_error();
+ /*!
+ * Initializing constructor. Creates an exception with the specified error message.
+ */
+ explicit system_error(std::string const& descr);
+ /*!
+ * Destructor
+ */
+ ~system_error() throw();
+
+#ifndef BOOST_LOG_DOXYGEN_PASS
+ static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line);
+ static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, std::string const& descr);
+#endif
+};
+
+/*!
+ * \brief Base class for logic exceptions from the logging library
+ *
+ * Exceptions derived from this class usually indicate errors on the user's side, such as
+ * incorrect library usage.
+ */
+class BOOST_LOG_API logic_error :
+ public std::logic_error
+{
+protected:
+ /*!
+ * Initializing constructor. Creates an exception with the specified error message.
+ */
+ explicit logic_error(std::string const& descr);
+ /*!
+ * Destructor
+ */
+ ~logic_error() throw();
+};
+
+/*!
+ * \brief Exception class that is used to indicate ODR violation
+ */
+class BOOST_LOG_API odr_violation :
+ public logic_error
+{
+public:
+ /*!
+ * Default constructor. Creates an exception with the default error message.
+ */
+ odr_violation();
+ /*!
+ * Initializing constructor. Creates an exception with the specified error message.
+ */
+ explicit odr_violation(std::string const& descr);
+ /*!
+ * Destructor
+ */
+ ~odr_violation() throw();
+
+#ifndef BOOST_LOG_DOXYGEN_PASS
+ static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line);
+ static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, std::string const& descr);
+#endif
+};
+
+/*!
+ * \brief Exception class that is used to indicate invalid call sequence
+ */
+class BOOST_LOG_API unexpected_call :
+ public logic_error
+{
+public:
+ /*!
+ * Default constructor. Creates an exception with the default error message.
+ */
+ unexpected_call();
+ /*!
+ * Initializing constructor. Creates an exception with the specified error message.
+ */
+ explicit unexpected_call(std::string const& descr);
+ /*!
+ * Destructor
+ */
+ ~unexpected_call() throw();
+
+#ifndef BOOST_LOG_DOXYGEN_PASS
+ static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line);
+ static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, std::string const& descr);
+#endif
+};
+
+/*!
+ * \brief Exception class that is used to indicate invalid library setup
+ */
+class BOOST_LOG_API setup_error :
+ public logic_error
+{
+public:
+ /*!
+ * Default constructor. Creates an exception with the default error message.
+ */
+ setup_error();
+ /*!
+ * Initializing constructor. Creates an exception with the specified error message.
+ */
+ explicit setup_error(std::string const& descr);
+ /*!
+ * Destructor
+ */
+ ~setup_error() throw();
+
+#ifndef BOOST_LOG_DOXYGEN_PASS
+ static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line);
+ static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, std::string const& descr);
+#endif
+};
+
+/*!
+ * \brief Exception class that is used to indicate library limitation
+ */
+class BOOST_LOG_API limitation_error :
+ public logic_error
+{
+public:
+ /*!
+ * Default constructor. Creates an exception with the default error message.
+ */
+ limitation_error();
+ /*!
+ * Initializing constructor. Creates an exception with the specified error message.
+ */
+ explicit limitation_error(std::string const& descr);
+ /*!
+ * Destructor
+ */
+ ~limitation_error() throw();
+
+#ifndef BOOST_LOG_DOXYGEN_PASS
+ static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line);
+ static BOOST_LOG_NORETURN void throw_(const char* file, std::size_t line, std::string const& descr);
+#endif
+};
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#ifndef BOOST_LOG_DOXYGEN_PASS
+
+#define BOOST_LOG_THROW(ex)\
+ ex::throw_(__FILE__, static_cast< std::size_t >(__LINE__))
+
+#define BOOST_LOG_THROW_DESCR(ex, descr)\
+ ex::throw_(__FILE__, static_cast< std::size_t >(__LINE__), descr)
+
+#define BOOST_LOG_THROW_DESCR_PARAMS(ex, descr, params)\
+ ex::throw_(__FILE__, static_cast< std::size_t >(__LINE__), descr, BOOST_PP_SEQ_ENUM(params))
+
+#endif // BOOST_LOG_DOXYGEN_PASS
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_EXCEPTIONS_HPP_INCLUDED_
diff --git a/boost/log/expressions.hpp b/boost/log/expressions.hpp
new file mode 100644
index 0000000..990981a
--- /dev/null
+++ b/boost/log/expressions.hpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file expressions.hpp
+ * \author Andrey Semashev
+ * \date 10.11.2012
+ *
+ * This header includes other Boost.Log headers with all template expression tools.
+ */
+
+#ifndef BOOST_LOG_EXPRESSIONS_HPP_INCLUDED_
+#define BOOST_LOG_EXPRESSIONS_HPP_INCLUDED_
+
+#include <boost/log/detail/config.hpp>
+
+#include <boost/log/expressions/attr.hpp>
+#include <boost/log/expressions/keyword.hpp>
+#include <boost/log/expressions/message.hpp>
+#include <boost/log/expressions/record.hpp>
+
+#include <boost/log/expressions/predicates.hpp>
+#include <boost/log/expressions/formatters.hpp>
+
+#include <boost/log/expressions/filter.hpp>
+#include <boost/log/expressions/formatter.hpp>
+
+// Boost.Phoenix operators are likely to be used with Boost.Log expression nodes anyway
+#include <boost/phoenix/operator.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#endif // BOOST_LOG_EXPRESSIONS_HPP_INCLUDED_
diff --git a/boost/log/expressions/attr.hpp b/boost/log/expressions/attr.hpp
new file mode 100644
index 0000000..31deefc
--- /dev/null
+++ b/boost/log/expressions/attr.hpp
@@ -0,0 +1,276 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file attr.hpp
+ * \author Andrey Semashev
+ * \date 21.07.2012
+ *
+ * The header contains implementation of a generic attribute placeholder in template expressions.
+ */
+
+#ifndef BOOST_LOG_EXPRESSIONS_ATTR_HPP_INCLUDED_
+#define BOOST_LOG_EXPRESSIONS_ATTR_HPP_INCLUDED_
+
+#include <boost/mpl/bool.hpp>
+#include <boost/utility/result_of.hpp>
+#include <boost/phoenix/core/actor.hpp>
+#include <boost/phoenix/core/terminal_fwd.hpp>
+#include <boost/phoenix/core/is_nullary.hpp>
+#include <boost/phoenix/core/environment.hpp>
+#include <boost/fusion/sequence/intrinsic/at_c.hpp>
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/log/detail/config.hpp>
+#include <boost/log/detail/copy_cv.hpp>
+#include <boost/log/detail/custom_terminal_spec.hpp>
+#include <boost/log/attributes/attribute_name.hpp>
+#include <boost/log/attributes/value_extraction.hpp>
+#include <boost/log/attributes/fallback_policy.hpp>
+#include <boost/log/expressions/attr_fwd.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace expressions {
+
+/*!
+ * An attribute value extraction terminal
+ */
+template< typename T, typename FallbackPolicyT, typename TagT >
+class attribute_terminal
+{
+private:
+ //! Value extractor type
+ typedef value_extractor< T, FallbackPolicyT, TagT > value_extractor_type;
+ //! Self type
+ typedef attribute_terminal< T, FallbackPolicyT, TagT > this_type;
+
+public:
+ //! Internal typedef for type categorization
+ typedef void _is_boost_log_terminal;
+
+ //! Attribute tag type
+ typedef TagT tag_type;
+ //! Attribute value type
+ typedef typename value_extractor_type::value_type value_type;
+ //! Fallback policy type
+ typedef typename value_extractor_type::fallback_policy fallback_policy;
+
+ //! Function result type
+ template< typename >
+ struct result;
+
+ template< typename ThisT, typename ContextT >
+ struct result< ThisT(ContextT) >
+ {
+ typedef typename remove_cv<
+ typename remove_reference< typename phoenix::result_of::env< ContextT >::type >::type
+ >::type env_type;
+ typedef typename env_type::args_type args_type;
+ typedef typename boost::log::aux::copy_cv< ThisT, value_extractor_type >::type cv_value_extractor_type;
+
+ typedef typename boost::result_of< cv_value_extractor_type(attribute_name const&, typename fusion::result_of::at_c< args_type, 0 >::type) >::type type;
+ };
+
+private:
+ //! Attribute value name
+ const attribute_name m_name;
+ //! Attribute value extractor
+ value_extractor_type m_value_extractor;
+
+public:
+ /*!
+ * Initializing constructor
+ */
+ explicit attribute_terminal(attribute_name const& name) : m_name(name)
+ {
+ }
+
+ /*!
+ * Initializing constructor
+ */
+ template< typename U >
+ attribute_terminal(attribute_name const& name, U const& arg) : m_name(name), m_value_extractor(arg)
+ {
+ }
+
+ /*!
+ * \returns Attribute value name
+ */
+ attribute_name get_name() const
+ {
+ return m_name;
+ }
+
+ /*!
+ * \returns Fallback policy
+ */
+ fallback_policy const& get_fallback_policy() const
+ {
+ return m_value_extractor.get_fallback_policy();
+ }
+
+ /*!
+ * The operator extracts attribute value
+ */
+ template< typename ContextT >
+ typename result< this_type(ContextT const&) >::type
+ operator() (ContextT const& ctx)
+ {
+ return m_value_extractor(m_name, fusion::at_c< 0 >(phoenix::env(ctx).args()));
+ }
+
+ /*!
+ * The operator extracts attribute value
+ */
+ template< typename ContextT >
+ typename result< const this_type(ContextT const&) >::type
+ operator() (ContextT const& ctx) const
+ {
+ return m_value_extractor(m_name, fusion::at_c< 0 >(phoenix::env(ctx).args()));
+ }
+
+ BOOST_DELETED_FUNCTION(attribute_terminal())
+};
+
+/*!
+ * An attribute value extraction terminal actor
+ */
+template< typename T, typename FallbackPolicyT, typename TagT, template< typename > class ActorT >
+class attribute_actor :
+ public ActorT< attribute_terminal< T, FallbackPolicyT, TagT > >
+{
+public:
+ //! Attribute tag type
+ typedef TagT tag_type;
+ //! Fallback policy
+ typedef FallbackPolicyT fallback_policy;
+ //! Base terminal type
+ typedef attribute_terminal< T, fallback_policy, tag_type > terminal_type;
+ //! Attribute value type
+ typedef typename terminal_type::value_type value_type;
+
+ //! Base actor type
+ typedef ActorT< terminal_type > base_type;
+
+public:
+ //! Initializing constructor
+ explicit attribute_actor(base_type const& act) : base_type(act)
+ {
+ }
+
+ /*!
+ * \returns The attribute name
+ */
+ attribute_name get_name() const
+ {
+ return this->proto_expr_.child0.get_name();
+ }
+
+ /*!
+ * \returns Fallback policy
+ */
+ fallback_policy const& get_fallback_policy() const
+ {
+ return this->proto_expr_.child0.get_fallback_policy();
+ }
+
+ //! Expression with cached attribute name
+ typedef attribute_actor< value_type, fallback_to_none, tag_type, ActorT > or_none_result_type;
+
+ //! Generates an expression that extracts the attribute value or a default value
+ or_none_result_type or_none() const
+ {
+ typedef typename or_none_result_type::terminal_type result_terminal;
+ typename or_none_result_type::base_type act = {{ result_terminal(get_name()) }};
+ return or_none_result_type(act);
+ }
+
+ //! Expression with cached attribute name
+ typedef attribute_actor< value_type, fallback_to_throw, tag_type, ActorT > or_throw_result_type;
+
+ //! Generates an expression that extracts the attribute value or throws an exception
+ or_throw_result_type or_throw() const
+ {
+ typedef typename or_throw_result_type::terminal_type result_terminal;
+ typename or_throw_result_type::base_type act = {{ result_terminal(get_name()) }};
+ return or_throw_result_type(act);
+ }
+
+ //! Generates an expression that extracts the attribute value or a default value
+ template< typename DefaultT >
+ attribute_actor< value_type, fallback_to_default< DefaultT >, tag_type, ActorT > or_default(DefaultT const& def_val) const
+ {
+ typedef attribute_actor< value_type, fallback_to_default< DefaultT >, tag_type, ActorT > or_default_result_type;
+ typedef typename or_default_result_type::terminal_type result_terminal;
+ typename or_default_result_type::base_type act = {{ result_terminal(get_name(), def_val) }};
+ return or_default_result_type(act);
+ }
+};
+
+/*!
+ * The function generates a terminal node in a template expression. The node will extract the value of the attribute
+ * with the specified name and type.
+ */
+template< typename AttributeValueT >
+BOOST_FORCEINLINE attribute_actor< AttributeValueT > attr(attribute_name const& name)
+{
+ typedef attribute_actor< AttributeValueT > result_type;
+ typedef typename result_type::terminal_type result_terminal;
+ typename result_type::base_type act = {{ result_terminal(name) }};
+ return result_type(act);
+}
+
+/*!
+ * The function generates a terminal node in a template expression. The node will extract the value of the attribute
+ * with the specified name and type.
+ */
+template< typename AttributeValueT, typename TagT >
+BOOST_FORCEINLINE attribute_actor< AttributeValueT, fallback_to_none, TagT > attr(attribute_name const& name)
+{
+ typedef attribute_actor< AttributeValueT, fallback_to_none, TagT > result_type;
+ typedef typename result_type::terminal_type result_terminal;
+ typename result_type::base_type act = {{ result_terminal(name) }};
+ return result_type(act);
+}
+
+} // namespace expressions
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+#ifndef BOOST_LOG_DOXYGEN_PASS
+
+namespace phoenix {
+
+namespace result_of {
+
+template< typename T, typename FallbackPolicyT, typename TagT >
+struct is_nullary< custom_terminal< boost::log::expressions::attribute_terminal< T, FallbackPolicyT, TagT > > > :
+ public mpl::false_
+{
+};
+
+} // namespace result_of
+
+} // namespace phoenix
+
+#endif
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+#if defined(BOOST_LOG_EXPRESSIONS_FORMATTERS_STREAM_HPP_INCLUDED_)
+#include <boost/log/detail/attr_output_impl.hpp>
+#endif
+
+#endif // BOOST_LOG_EXPRESSIONS_ATTR_HPP_INCLUDED_
diff --git a/boost/log/expressions/attr_fwd.hpp b/boost/log/expressions/attr_fwd.hpp
new file mode 100644
index 0000000..a8e7b92
--- /dev/null
+++ b/boost/log/expressions/attr_fwd.hpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file attr_fwd.hpp
+ * \author Andrey Semashev
+ * \date 21.07.2012
+ *
+ * The header contains forward declaration of a generic attribute placeholder in template expressions.
+ */
+
+#ifndef BOOST_LOG_EXPRESSIONS_ATTR_FWD_HPP_INCLUDED_
+#define BOOST_LOG_EXPRESSIONS_ATTR_FWD_HPP_INCLUDED_
+
+#include <boost/log/detail/config.hpp>
+#include <boost/log/attributes/fallback_policy_fwd.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+#ifndef BOOST_LOG_DOXYGEN_PASS
+
+namespace phoenix {
+
+template< typename >
+struct actor;
+
+} // namespace phoenix
+
+#endif
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace expressions {
+
+/*!
+ * An attribute value extraction terminal
+ */
+template<
+ typename T,
+ typename FallbackPolicyT = fallback_to_none,
+ typename TagT = void
+>
+class attribute_terminal;
+
+/*!
+ * An attribute value extraction terminal actor
+ */
+template<
+ typename T,
+ typename FallbackPolicyT = fallback_to_none,
+ typename TagT = void,
+ template< typename > class ActorT = phoenix::actor
+>
+class attribute_actor;
+
+} // namespace expressions
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#endif // BOOST_LOG_EXPRESSIONS_ATTR_FWD_HPP_INCLUDED_
diff --git a/boost/log/expressions/filter.hpp b/boost/log/expressions/filter.hpp
new file mode 100644
index 0000000..dcf7d59
--- /dev/null
+++ b/boost/log/expressions/filter.hpp
@@ -0,0 +1,183 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file filter.hpp
+ * \author Andrey Semashev
+ * \date 13.07.2012
+ *
+ * The header contains a filter function object definition.
+ */
+
+#ifndef BOOST_LOG_EXPRESSIONS_FILTER_HPP_INCLUDED_
+#define BOOST_LOG_EXPRESSIONS_FILTER_HPP_INCLUDED_
+
+#include <boost/move/core.hpp>
+#include <boost/move/utility.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/log/detail/config.hpp>
+#include <boost/log/attributes/attribute_value_set.hpp>
+#include <boost/log/detail/light_function.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+/*!
+ * Log record filter function wrapper.
+ */
+class filter
+{
+ BOOST_COPYABLE_AND_MOVABLE(filter)
+
+public:
+ //! Result type
+ typedef bool result_type;
+
+private:
+ //! Filter function type
+ typedef boost::log::aux::light_function< bool (attribute_value_set const&) > filter_type;
+
+ //! Default filter, always returns \c true
+ struct default_filter
+ {
+ typedef bool result_type;
+ result_type operator() (attribute_value_set const&) const { return true; }
+ };
+
+private:
+ //! Filter function
+ filter_type m_Filter;
+
+public:
+ /*!
+ * Default constructor. Creates a filter that always returns \c true.
+ */
+ filter() : m_Filter(default_filter())
+ {
+ }
+ /*!
+ * Copy constructor
+ */
+ filter(filter const& that) : m_Filter(that.m_Filter)
+ {
+ }
+ /*!
+ * Move constructor. The moved-from filter is left in an unspecified state.
+ */
+ filter(BOOST_RV_REF(filter) that) BOOST_NOEXCEPT : m_Filter(boost::move(that.m_Filter))
+ {
+ }
+
+ /*!
+ * Initializing constructor. Creates a filter which will invoke the specified function object.
+ */
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ template< typename FunT >
+ filter(FunT&& fun) : m_Filter(boost::forward< FunT >(fun))
+ {
+ }
+#elif !defined(BOOST_MSVC) || BOOST_MSVC > 1400
+ template< typename FunT >
+ filter(FunT const& fun, typename disable_if_c< move_detail::is_rv< FunT >::value, int >::type = 0) : m_Filter(fun)
+ {
+ }
+#else
+ // MSVC 8 blows up in unexpected ways if we use SFINAE to disable constructor instantiation
+ template< typename FunT >
+ filter(FunT const& fun) : m_Filter(fun)
+ {
+ }
+ template< typename FunT >
+ filter(rv< FunT >& fun) : m_Filter(fun)
+ {
+ }
+ template< typename FunT >
+ filter(rv< FunT > const& fun) : m_Filter(static_cast< FunT const& >(fun))
+ {
+ }
+ filter(rv< filter > const& that) : m_Filter(that.m_Filter)
+ {
+ }
+#endif
+
+ /*!
+ * Move assignment. The moved-from filter is left in an unspecified state.
+ */
+ filter& operator= (BOOST_RV_REF(filter) that) BOOST_NOEXCEPT
+ {
+ m_Filter.swap(that.m_Filter);
+ return *this;
+ }
+ /*!
+ * Copy assignment.
+ */
+ filter& operator= (BOOST_COPY_ASSIGN_REF(filter) that)
+ {
+ m_Filter = that.m_Filter;
+ return *this;
+ }
+ /*!
+ * Initializing assignment. Sets the specified function object to the filter.
+ */
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ template< typename FunT >
+ filter& operator= (FunT const& fun)
+#else
+ template< typename FunT >
+ typename disable_if< is_same< typename remove_cv< FunT >::type, filter >, filter& >::type
+ operator= (FunT const& fun)
+#endif
+ {
+ filter(fun).swap(*this);
+ return *this;
+ }
+
+ /*!
+ * Filtering operator.
+ *
+ * \param values Attribute values of the log record.
+ * \return \c true if the log record passes the filter, \c false otherwise.
+ */
+ result_type operator() (attribute_value_set const& values) const
+ {
+ return m_Filter(values);
+ }
+
+ /*!
+ * Resets the filter to the default. The default filter always returns \c true.
+ */
+ void reset()
+ {
+ m_Filter = default_filter();
+ }
+
+ /*!
+ * Swaps two filters
+ */
+ void swap(filter& that) BOOST_NOEXCEPT
+ {
+ m_Filter.swap(that.m_Filter);
+ }
+};
+
+inline void swap(filter& left, filter& right) BOOST_NOEXCEPT
+{
+ left.swap(right);
+}
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_EXPRESSIONS_FILTER_HPP_INCLUDED_
diff --git a/boost/log/expressions/formatter.hpp b/boost/log/expressions/formatter.hpp
new file mode 100644
index 0000000..05692ec
--- /dev/null
+++ b/boost/log/expressions/formatter.hpp
@@ -0,0 +1,257 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file formatter.hpp
+ * \author Andrey Semashev
+ * \date 13.07.2012
+ *
+ * The header contains a formatter function object definition.
+ */
+
+#ifndef BOOST_LOG_EXPRESSIONS_FORMATTER_HPP_INCLUDED_
+#define BOOST_LOG_EXPRESSIONS_FORMATTER_HPP_INCLUDED_
+
+#include <boost/ref.hpp>
+#include <boost/move/core.hpp>
+#include <boost/move/utility.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/log/detail/config.hpp>
+#include <boost/log/detail/light_function.hpp>
+#include <boost/log/attributes/attribute_value_set.hpp>
+#include <boost/log/attributes/value_visitation.hpp>
+#include <boost/log/core/record_view.hpp>
+#include <boost/log/utility/formatting_ostream.hpp>
+#include <boost/log/utility/functional/bind_output.hpp>
+#include <boost/log/expressions/message.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace expressions {
+
+namespace aux {
+
+// This reference class is a workaround for a Boost.Phoenix bug: https://svn.boost.org/trac/boost/ticket/9363
+// It is needed to pass output streams by non-const reference to function objects wrapped in phoenix::bind and phoenix::function.
+// It's an implementation detail and will be removed when Boost.Phoenix is fixed.
+template< typename StreamT >
+class stream_ref :
+ public reference_wrapper< StreamT >
+{
+public:
+ BOOST_FORCEINLINE explicit stream_ref(StreamT& strm) : reference_wrapper< StreamT >(strm)
+ {
+ }
+
+ template< typename T >
+ BOOST_FORCEINLINE StreamT& operator<< (T& val) const
+ {
+ StreamT& strm = this->get();
+ strm << val;
+ return strm;
+ }
+
+ template< typename T >
+ BOOST_FORCEINLINE StreamT& operator<< (T const& val) const
+ {
+ StreamT& strm = this->get();
+ strm << val;
+ return strm;
+ }
+};
+
+//! Default log record message formatter
+struct message_formatter
+{
+ typedef void result_type;
+
+ message_formatter() : m_MessageName(expressions::tag::message::get_name())
+ {
+ }
+
+ template< typename StreamT >
+ result_type operator() (record_view const& rec, StreamT& strm) const
+ {
+ boost::log::visit< expressions::tag::message::value_type >(m_MessageName, rec, boost::log::bind_output(strm));
+ }
+
+private:
+ const attribute_name m_MessageName;
+};
+
+} // namespace aux
+
+} // namespace expressions
+
+/*!
+ * Log record formatter function wrapper.
+ */
+template< typename CharT >
+class basic_formatter
+{
+ typedef basic_formatter this_type;
+ BOOST_COPYABLE_AND_MOVABLE(this_type)
+
+public:
+ //! Result type
+ typedef void result_type;
+
+ //! Character type
+ typedef CharT char_type;
+ //! Output stream type
+ typedef basic_formatting_ostream< char_type > stream_type;
+
+private:
+ //! Filter function type
+ typedef boost::log::aux::light_function< void (record_view const&, expressions::aux::stream_ref< stream_type >) > formatter_type;
+
+private:
+ //! Formatter function
+ formatter_type m_Formatter;
+
+public:
+ /*!
+ * Default constructor. Creates a formatter that only outputs log message.
+ */
+ basic_formatter() : m_Formatter(expressions::aux::message_formatter())
+ {
+ }
+ /*!
+ * Copy constructor
+ */
+ basic_formatter(basic_formatter const& that) : m_Formatter(that.m_Formatter)
+ {
+ }
+ /*!
+ * Move constructor. The moved-from formatter is left in an unspecified state.
+ */
+ basic_formatter(BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT : m_Formatter(boost::move(that.m_Formatter))
+ {
+ }
+
+ /*!
+ * Initializing constructor. Creates a formatter which will invoke the specified function object.
+ */
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ template< typename FunT >
+ basic_formatter(FunT&& fun) : m_Formatter(boost::forward< FunT >(fun))
+ {
+ }
+#elif !defined(BOOST_MSVC) || BOOST_MSVC > 1400
+ template< typename FunT >
+ basic_formatter(FunT const& fun, typename disable_if_c< move_detail::is_rv< FunT >::value, int >::type = 0) : m_Formatter(fun)
+ {
+ }
+#else
+ // MSVC 8 blows up in unexpected ways if we use SFINAE to disable constructor instantiation
+ template< typename FunT >
+ basic_formatter(FunT const& fun) : m_Formatter(fun)
+ {
+ }
+ template< typename FunT >
+ basic_formatter(rv< FunT >& fun) : m_Formatter(fun)
+ {
+ }
+ template< typename FunT >
+ basic_formatter(rv< FunT > const& fun) : m_Formatter(static_cast< FunT const& >(fun))
+ {
+ }
+ basic_formatter(rv< this_type > const& that) : m_Formatter(that.m_Formatter)
+ {
+ }
+#endif
+
+ /*!
+ * Move assignment. The moved-from formatter is left in an unspecified state.
+ */
+ basic_formatter& operator= (BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT
+ {
+ m_Formatter.swap(that.m_Formatter);
+ return *this;
+ }
+ /*!
+ * Copy assignment.
+ */
+ basic_formatter& operator= (BOOST_COPY_ASSIGN_REF(this_type) that)
+ {
+ m_Formatter = that.m_Formatter;
+ return *this;
+ }
+ /*!
+ * Initializing assignment. Sets the specified function object to the formatter.
+ */
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ template< typename FunT >
+ basic_formatter& operator= (FunT&& fun)
+ {
+ this_type(boost::forward< FunT >(fun)).swap(*this);
+ return *this;
+ }
+#else
+ template< typename FunT >
+ typename disable_if< is_same< typename remove_cv< FunT >::type, this_type >, this_type& >::type
+ operator= (FunT const& fun)
+ {
+ this_type(fun).swap(*this);
+ return *this;
+ }
+#endif
+
+ /*!
+ * Formatting operator.
+ *
+ * \param rec A log record to format.
+ * \param strm A stream to put the formatted characters to.
+ */
+ result_type operator() (record_view const& rec, stream_type& strm) const
+ {
+ m_Formatter(rec, expressions::aux::stream_ref< stream_type >(strm));
+ }
+
+ /*!
+ * Resets the formatter to the default. The default formatter only outputs message text.
+ */
+ void reset()
+ {
+ m_Formatter = expressions::aux::message_formatter();
+ }
+
+ /*!
+ * Swaps two formatters
+ */
+ void swap(basic_formatter& that) BOOST_NOEXCEPT
+ {
+ m_Formatter.swap(that.m_Formatter);
+ }
+};
+
+template< typename CharT >
+inline void swap(basic_formatter< CharT >& left, basic_formatter< CharT >& right) BOOST_NOEXCEPT
+{
+ left.swap(right);
+}
+
+#ifdef BOOST_LOG_USE_CHAR
+typedef basic_formatter< char > formatter;
+#endif
+#ifdef BOOST_LOG_USE_WCHAR_T
+typedef basic_formatter< wchar_t > wformatter;
+#endif
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_EXPRESSIONS_FORMATTER_HPP_INCLUDED_
diff --git a/boost/log/expressions/formatters.hpp b/boost/log/expressions/formatters.hpp
new file mode 100644
index 0000000..47f84a5
--- /dev/null
+++ b/boost/log/expressions/formatters.hpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file formatters.hpp
+ * \author Andrey Semashev
+ * \date 10.11.2012
+ *
+ * The header includes all template expression formatters.
+ */
+
+#ifndef BOOST_LOG_EXPRESSIONS_FORMATTERS_HPP_INCLUDED_
+#define BOOST_LOG_EXPRESSIONS_FORMATTERS_HPP_INCLUDED_
+
+#include <boost/log/detail/config.hpp>
+
+#include <boost/log/expressions/formatters/stream.hpp>
+#include <boost/log/expressions/formatters/format.hpp>
+
+#include <boost/log/expressions/formatters/date_time.hpp>
+#include <boost/log/expressions/formatters/named_scope.hpp>
+
+#include <boost/log/expressions/formatters/char_decorator.hpp>
+#include <boost/log/expressions/formatters/xml_decorator.hpp>
+#include <boost/log/expressions/formatters/csv_decorator.hpp>
+#include <boost/log/expressions/formatters/c_decorator.hpp>
+
+#include <boost/log/expressions/formatters/if.hpp>
+#include <boost/log/expressions/formatters/wrap_formatter.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#endif // BOOST_LOG_EXPRESSIONS_FORMATTERS_HPP_INCLUDED_
diff --git a/boost/log/expressions/formatters/c_decorator.hpp b/boost/log/expressions/formatters/c_decorator.hpp
new file mode 100644
index 0000000..a793b52
--- /dev/null
+++ b/boost/log/expressions/formatters/c_decorator.hpp
@@ -0,0 +1,281 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file formatters/c_decorator.hpp
+ * \author Andrey Semashev
+ * \date 18.11.2012
+ *
+ * The header contains implementation of C-style character decorators.
+ */
+
+#ifndef BOOST_LOG_EXPRESSIONS_FORMATTERS_C_DECORATOR_HPP_INCLUDED_
+#define BOOST_LOG_EXPRESSIONS_FORMATTERS_C_DECORATOR_HPP_INCLUDED_
+
+#include <limits>
+#include <boost/range/iterator_range_core.hpp>
+#include <boost/log/detail/config.hpp>
+#include <boost/log/detail/snprintf.hpp>
+#include <boost/log/expressions/formatters/char_decorator.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace expressions {
+
+namespace aux {
+
+template< typename >
+struct c_decorator_traits;
+
+#ifdef BOOST_LOG_USE_CHAR
+template< >
+struct c_decorator_traits< char >
+{
+ static boost::iterator_range< const char* const* > get_patterns()
+ {
+ static const char* const patterns[] =
+ {
+ "\\", "\a", "\b", "\f", "\n", "\r", "\t", "\v", "'", "\"", "?"
+ };
+ return boost::make_iterator_range(patterns);
+ }
+ static boost::iterator_range< const char* const* > get_replacements()
+ {
+ static const char* const replacements[] =
+ {
+ "\\\\", "\\a", "\\b", "\\f", "\\n", "\\r", "\\t", "\\v", "\\'", "\\\"", "\\?"
+ };
+ return boost::make_iterator_range(replacements);
+ }
+ template< unsigned int N >
+ static std::size_t print_escaped(char (&buf)[N], char c)
+ {
+ int n = boost::log::aux::snprintf(buf, N, "\\x%0.2X", static_cast< unsigned int >(static_cast< uint8_t >(c)));
+ if (n < 0)
+ {
+ n = 0;
+ buf[0] = '\0';
+ }
+ return static_cast< unsigned int >(n) >= N ? N - 1 : static_cast< unsigned int >(n);
+ }
+};
+#endif // BOOST_LOG_USE_CHAR
+
+#ifdef BOOST_LOG_USE_WCHAR_T
+template< >
+struct c_decorator_traits< wchar_t >
+{
+ static boost::iterator_range< const wchar_t* const* > get_patterns()
+ {
+ static const wchar_t* const patterns[] =
+ {
+ L"\\", L"\a", L"\b", L"\f", L"\n", L"\r", L"\t", L"\v", L"'", L"\"", L"?"
+ };
+ return boost::make_iterator_range(patterns);
+ }
+ static boost::iterator_range< const wchar_t* const* > get_replacements()
+ {
+ static const wchar_t* const replacements[] =
+ {
+ L"\\\\", L"\\a", L"\\b", L"\\f", L"\\n", L"\\r", L"\\t", L"\\v", L"\\'", L"\\\"", L"\\?"
+ };
+ return boost::make_iterator_range(replacements);
+ }
+ template< unsigned int N >
+ static std::size_t print_escaped(wchar_t (&buf)[N], wchar_t c)
+ {
+ const wchar_t* format;
+ unsigned int val;
+ if (sizeof(wchar_t) == 1)
+ {
+ format = L"\\x%0.2X";
+ val = static_cast< uint8_t >(c);
+ }
+ else if (sizeof(wchar_t) == 2)
+ {
+ format = L"\\x%0.4X";
+ val = static_cast< uint16_t >(c);
+ }
+ else
+ {
+ format = L"\\x%0.8X";
+ val = static_cast< uint32_t >(c);
+ }
+
+ int n = boost::log::aux::swprintf(buf, N, format, val);
+ if (n < 0)
+ {
+ n = 0;
+ buf[0] = L'\0';
+ }
+ return static_cast< unsigned int >(n) >= N ? N - 1 : static_cast< unsigned int >(n);
+ }
+};
+#endif // BOOST_LOG_USE_WCHAR_T
+
+template< typename CharT >
+struct c_decorator_gen
+{
+ typedef CharT char_type;
+
+ template< typename SubactorT >
+ BOOST_FORCEINLINE char_decorator_actor< SubactorT, pattern_replacer< char_type > > operator[] (SubactorT const& subactor) const
+ {
+ typedef c_decorator_traits< char_type > traits_type;
+ typedef pattern_replacer< char_type > replacer_type;
+ typedef char_decorator_actor< SubactorT, replacer_type > result_type;
+ typedef typename result_type::terminal_type terminal_type;
+ typename result_type::base_type act = {{ terminal_type(subactor, replacer_type(traits_type::get_patterns(), traits_type::get_replacements())) }};
+ return result_type(act);
+ }
+};
+
+} // namespace aux
+
+/*!
+ * C-style decorator generator object. The decorator replaces characters with specific meaning in C
+ * language with the corresponding escape sequences. The generator provides <tt>operator[]</tt> that
+ * can be used to construct the actual decorator. For example:
+ *
+ * <code>
+ * c_decor[ attr< std::string >("MyAttr") ]
+ * </code>
+ *
+ * For wide-character formatting there is the similar \c wc_decor decorator generator object.
+ */
+#ifdef BOOST_LOG_USE_CHAR
+const aux::c_decorator_gen< char > c_decor = {};
+#endif
+#ifdef BOOST_LOG_USE_WCHAR_T
+const aux::c_decorator_gen< wchar_t > wc_decor = {};
+#endif
+
+/*!
+ * The function creates a C-style decorator generator for arbitrary character type.
+ */
+template< typename CharT >
+BOOST_FORCEINLINE aux::c_decorator_gen< CharT > make_c_decor()
+{
+ return aux::c_decorator_gen< CharT >();
+}
+
+/*!
+ * A character decorator implementation that escapes all non-prontable and non-ASCII characters
+ * in the output with C-style escape sequences.
+ */
+template< typename CharT >
+class c_ascii_pattern_replacer :
+ public pattern_replacer< CharT >
+{
+private:
+ //! Base type
+ typedef pattern_replacer< CharT > base_type;
+
+public:
+ //! Result type
+ typedef typename base_type::result_type result_type;
+ //! Character type
+ typedef typename base_type::char_type char_type;
+ //! String type
+ typedef typename base_type::string_type string_type;
+
+private:
+ //! Traits type
+ typedef aux::c_decorator_traits< char_type > traits_type;
+
+public:
+ //! Default constructor
+ c_ascii_pattern_replacer() : base_type(traits_type::get_patterns(), traits_type::get_replacements())
+ {
+ }
+
+ //! Applies string replacements starting from the specified position
+ result_type operator() (string_type& str, typename string_type::size_type start_pos = 0) const
+ {
+ base_type::operator() (str, start_pos);
+
+ typedef typename string_type::iterator string_iterator;
+ for (string_iterator it = str.begin() + start_pos, end = str.end(); it != end; ++it)
+ {
+ char_type c = *it;
+ if (c < 0x20 || c > 0x7e)
+ {
+ char_type buf[(std::numeric_limits< char_type >::digits + 3) / 4 + 3];
+ std::size_t n = traits_type::print_escaped(buf, c);
+ std::size_t pos = it - str.begin();
+ str.replace(pos, 1, buf, n);
+ it = str.begin() + n - 1;
+ end = str.end();
+ }
+ }
+ }
+};
+
+namespace aux {
+
+template< typename CharT >
+struct c_ascii_decorator_gen
+{
+ typedef CharT char_type;
+
+ template< typename SubactorT >
+ BOOST_FORCEINLINE char_decorator_actor< SubactorT, c_ascii_pattern_replacer< char_type > > operator[] (SubactorT const& subactor) const
+ {
+ typedef c_decorator_traits< char_type > traits_type;
+ typedef c_ascii_pattern_replacer< char_type > replacer_type;
+ typedef char_decorator_actor< SubactorT, replacer_type > result_type;
+ typedef typename result_type::terminal_type terminal_type;
+ typename result_type::base_type act = {{ terminal_type(subactor, replacer_type()) }};
+ return result_type(act);
+ }
+};
+
+} // namespace aux
+
+/*!
+ * C-style decorator generator object. Acts similarly to \c c_decor, except that \c c_ascii_decor also
+ * converts all non-ASCII and non-printable ASCII characters, except for space character, into
+ * C-style hexadecimal escape sequences. The generator provides <tt>operator[]</tt> that
+ * can be used to construct the actual decorator. For example:
+ *
+ * <code>
+ * c_ascii_decor[ attr< std::string >("MyAttr") ]
+ * </code>
+ *
+ * For wide-character formatting there is the similar \c wc_ascii_decor decorator generator object.
+ */
+#ifdef BOOST_LOG_USE_CHAR
+const aux::c_ascii_decorator_gen< char > c_ascii_decor = {};
+#endif
+#ifdef BOOST_LOG_USE_WCHAR_T
+const aux::c_ascii_decorator_gen< wchar_t > wc_ascii_decor = {};
+#endif
+
+/*!
+ * The function creates a C-style decorator generator for arbitrary character type.
+ */
+template< typename CharT >
+BOOST_FORCEINLINE aux::c_ascii_decorator_gen< CharT > make_c_ascii_decor()
+{
+ return aux::c_ascii_decorator_gen< CharT >();
+}
+
+} // namespace expressions
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_EXPRESSIONS_FORMATTERS_C_DECORATOR_HPP_INCLUDED_
diff --git a/boost/log/expressions/formatters/char_decorator.hpp b/boost/log/expressions/formatters/char_decorator.hpp
new file mode 100644
index 0000000..ca24c0d
--- /dev/null
+++ b/boost/log/expressions/formatters/char_decorator.hpp
@@ -0,0 +1,639 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file formatters/char_decorator.hpp
+ * \author Andrey Semashev
+ * \date 17.11.2012
+ *
+ * The header contains implementation of a character decorator.
+ */
+
+#ifndef BOOST_LOG_EXPRESSIONS_FORMATTERS_CHAR_DECORATOR_HPP_INCLUDED_
+#define BOOST_LOG_EXPRESSIONS_FORMATTERS_CHAR_DECORATOR_HPP_INCLUDED_
+
+#include <vector>
+#include <string>
+#include <iterator>
+#include <boost/assert.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/size.hpp>
+#include <boost/range/const_iterator.hpp>
+#include <boost/range/value_type.hpp>
+#include <boost/move/core.hpp>
+#include <boost/move/utility.hpp>
+#include <boost/utility/addressof.hpp>
+#include <boost/phoenix/core/actor.hpp>
+#include <boost/phoenix/core/meta_grammar.hpp>
+#include <boost/phoenix/core/terminal_fwd.hpp>
+#include <boost/phoenix/core/is_nullary.hpp>
+#include <boost/phoenix/core/environment.hpp>
+#include <boost/phoenix/support/vector.hpp>
+#include <boost/fusion/sequence/intrinsic/at_c.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/log/detail/config.hpp>
+#include <boost/log/detail/custom_terminal_spec.hpp>
+#include <boost/log/detail/deduce_char_type.hpp>
+#include <boost/log/utility/formatting_ostream.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace expressions {
+
+namespace aux {
+
+template< typename RangeT >
+struct string_const_iterator : range_const_iterator< RangeT > {};
+template< >
+struct string_const_iterator< char* > { typedef char* type; };
+template< >
+struct string_const_iterator< const char* > { typedef const char* type; };
+template< >
+struct string_const_iterator< wchar_t* > { typedef wchar_t* type; };
+template< >
+struct string_const_iterator< const wchar_t* > { typedef const wchar_t* type; };
+
+} // namespace aux
+
+/*!
+ * A simple character decorator implementation. This implementation replaces string patterns in the source string with
+ * the fixed replacements. Source patterns and replacements can be specified at the object construction.
+ */
+template< typename CharT >
+class pattern_replacer
+{
+public:
+ //! Result type
+ typedef void result_type;
+
+ //! Character type
+ typedef CharT char_type;
+ //! String type
+ typedef std::basic_string< char_type > string_type;
+
+private:
+ //! Lengths of source pattern and replacement
+ struct string_lengths
+ {
+ unsigned int from_len, to_len;
+ };
+
+ //! List of the decorations to apply
+ typedef std::vector< string_lengths > string_lengths_list;
+
+private:
+ //! Characters of the interleaved source patterns and replacements
+ string_type m_decoration_chars;
+ //! List of the decorations to apply
+ string_lengths_list m_string_lengths;
+
+public:
+ /*!
+ * Initializing constructor. Creates a pattern replacer with the specified \a decorations.
+ * The provided decorations must be a sequence of \c std::pair of strings. The first element
+ * of each pair is the source pattern, and the second one is the corresponding replacement.
+ */
+ template< typename RangeT >
+ explicit pattern_replacer(RangeT const& decorations)
+ {
+ typedef typename range_const_iterator< RangeT >::type iterator;
+ for (iterator it = begin(decorations), end_ = end(decorations); it != end_; ++it)
+ {
+ string_lengths lens;
+ {
+ typedef typename aux::string_const_iterator< typename range_value< RangeT >::type::first_type >::type first_iterator;
+ first_iterator b = string_begin(it->first), e = string_end(it->first);
+ lens.from_len = static_cast< unsigned int >(std::distance(b, e));
+ m_decoration_chars.append(b, e);
+ }
+ {
+ typedef typename aux::string_const_iterator< typename range_value< RangeT >::type::second_type >::type second_iterator;
+ second_iterator b = string_begin(it->second), e = string_end(it->second);
+ lens.to_len = static_cast< unsigned int >(std::distance(b, e));
+ m_decoration_chars.append(b, e);
+ }
+ m_string_lengths.push_back(lens);
+ }
+ }
+ /*!
+ * Initializing constructor. Creates a pattern replacer with decorations specified
+ * in form of two same-sized string sequences. Each <tt>i</tt>'th decoration will be
+ * <tt>from[i]</tt> -> <tt>to[i]</tt>.
+ */
+ template< typename FromRangeT, typename ToRangeT >
+ pattern_replacer(FromRangeT const& from, ToRangeT const& to)
+ {
+ typedef typename range_const_iterator< FromRangeT >::type iterator1;
+ typedef typename range_const_iterator< ToRangeT >::type iterator2;
+ iterator1 it1 = begin(from), end1 = end(from);
+ iterator2 it2 = begin(to), end2 = end(to);
+ for (; it1 != end1 && it2 != end2; ++it1, ++it2)
+ {
+ string_lengths lens;
+ {
+ typedef typename aux::string_const_iterator< typename range_value< FromRangeT >::type >::type from_iterator;
+ from_iterator b = string_begin(*it1), e = string_end(*it1);
+ lens.from_len = static_cast< unsigned int >(std::distance(b, e));
+ m_decoration_chars.append(b, e);
+ }
+ {
+ typedef typename aux::string_const_iterator< typename range_value< ToRangeT >::type >::type to_iterator;
+ to_iterator b = string_begin(*it2), e = string_end(*it2);
+ lens.to_len = static_cast< unsigned int >(std::distance(b, e));
+ m_decoration_chars.append(b, e);
+ }
+ m_string_lengths.push_back(lens);
+ }
+
+ // Both sequences should be of the same size
+ BOOST_ASSERT(it1 == end1);
+ BOOST_ASSERT(it2 == end2);
+ }
+ //! Copy constructor
+ pattern_replacer(pattern_replacer const& that) : m_decoration_chars(that.m_decoration_chars), m_string_lengths(that.m_string_lengths)
+ {
+ }
+
+ //! Applies string replacements starting from the specified position
+ result_type operator() (string_type& str, typename string_type::size_type start_pos = 0) const
+ {
+ typedef typename string_type::size_type size_type;
+
+ const char_type* from_chars = m_decoration_chars.c_str();
+ for (typename string_lengths_list::const_iterator it = m_string_lengths.begin(), end = m_string_lengths.end(); it != end; ++it)
+ {
+ const unsigned int from_len = it->from_len, to_len = it->to_len;
+ const char_type* const to_chars = from_chars + from_len;
+ for (size_type pos = str.find(from_chars, start_pos, from_len); pos != string_type::npos; pos = str.find(from_chars, pos, from_len))
+ {
+ str.replace(pos, from_len, to_chars, to_len);
+ pos += to_len;
+ }
+ from_chars = to_chars + to_len;
+ }
+ }
+
+private:
+ static char_type* string_begin(char_type* p)
+ {
+ return p;
+ }
+ static const char_type* string_begin(const char_type* p)
+ {
+ return p;
+ }
+ template< typename RangeT >
+ static typename range_const_iterator< RangeT >::type string_begin(RangeT const& r)
+ {
+ return begin(r);
+ }
+
+ static char_type* string_end(char_type* p)
+ {
+ while (*p)
+ ++p;
+ return p;
+ }
+ static const char_type* string_end(const char_type* p)
+ {
+ while (*p)
+ ++p;
+ return p;
+ }
+ template< typename RangeT >
+ static typename range_const_iterator< RangeT >::type string_end(RangeT const& r)
+ {
+ return end(r);
+ }
+};
+
+namespace aux {
+
+//! Character decorator stream output terminal
+template< typename LeftT, typename SubactorT, typename ImplT >
+class char_decorator_output_terminal
+{
+private:
+ //! Self type
+ typedef char_decorator_output_terminal< LeftT, SubactorT, ImplT > this_type;
+
+public:
+ //! Internal typedef for type categorization
+ typedef void _is_boost_log_terminal;
+
+ //! Implementation type
+ typedef ImplT impl_type;
+
+ //! Character type
+ typedef typename impl_type::char_type char_type;
+ //! String type
+ typedef typename impl_type::string_type string_type;
+ //! Adopted actor type
+ typedef SubactorT subactor_type;
+
+ //! Result type definition
+ template< typename >
+ struct result;
+
+ template< typename ThisT, typename ContextT >
+ struct result< ThisT(ContextT) >
+ {
+ typedef typename remove_cv< typename remove_reference< ContextT >::type >::type context_type;
+ typedef typename phoenix::evaluator::impl<
+ typename LeftT::proto_base_expr&,
+ context_type,
+ phoenix::unused
+ >::result_type type;
+ };
+
+private:
+ //! Left argument actor
+ LeftT m_left;
+ //! Adopted formatter actor
+ subactor_type m_subactor;
+ //! Implementation type
+ impl_type m_impl;
+
+public:
+ /*!
+ * Initializing constructor. Creates decorator of the \a fmt formatter with the specified \a decorations.
+ */
+ char_decorator_output_terminal(LeftT const& left, subactor_type const& sub, impl_type const& impl) :
+ m_left(left), m_subactor(sub), m_impl(impl)
+ {
+ }
+ /*!
+ * Copy constructor
+ */
+ char_decorator_output_terminal(char_decorator_output_terminal const& that) :
+ m_left(that.m_left), m_subactor(that.m_subactor), m_impl(that.m_impl)
+ {
+ }
+
+ /*!
+ * Invokation operator
+ */
+ template< typename ContextT >
+ typename result< this_type(ContextT const&) >::type operator() (ContextT const& ctx)
+ {
+ // Flush the stream and keep the current write position in the target string
+ typedef typename result< this_type(ContextT const&) >::type result_type;
+ result_type strm = phoenix::eval(m_left, ctx);
+ strm.flush();
+ typename string_type::size_type const start_pos = strm.rdbuf()->storage()->size();
+
+ // Invoke the adopted formatter
+ typedef typename result< this_type(ContextT const&) >::type result_type;
+ phoenix::eval(m_subactor, ctx);
+
+ // Flush the buffered characters and apply decorations
+ strm.flush();
+ m_impl(*strm.rdbuf()->storage(), start_pos);
+
+ return strm;
+ }
+
+ /*!
+ * Invokation operator
+ */
+ template< typename ContextT >
+ typename result< const this_type(ContextT const&) >::type operator() (ContextT const& ctx) const
+ {
+ // Flush the stream and keep the current write position in the target string
+ typedef typename result< const this_type(ContextT const&) >::type result_type;
+ result_type strm = phoenix::eval(m_left, ctx);
+ strm.flush();
+ typename string_type::size_type const start_pos = strm.rdbuf()->storage()->size();
+
+ // Invoke the adopted formatter
+ typedef typename result< const this_type(ContextT const&) >::type result_type;
+ phoenix::eval(m_subactor, ctx);
+
+ // Flush the buffered characters and apply decorations
+ strm.flush();
+ m_impl(*strm.rdbuf()->storage(), start_pos);
+
+ return strm;
+ }
+
+ BOOST_DELETED_FUNCTION(char_decorator_output_terminal())
+};
+
+} // namespace aux
+
+/*!
+ * Character decorator terminal class. This formatter allows to modify strings generated by other
+ * formatters on character level. The most obvious application of decorators is replacing
+ * a certain set of characters with decorated equivalents to satisfy requirements of
+ * text-based sinks.
+ *
+ * The \c char_decorator_terminal class aggregates the formatter being decorated, and a set
+ * of string pairs that are used as decorations. All decorations are applied sequentially.
+ * The \c char_decorator_terminal class is a formatter itself, so it can be used to construct
+ * more complex formatters, including nesting decorators.
+ */
+template< typename SubactorT, typename ImplT >
+class char_decorator_terminal
+{
+private:
+ //! Self type
+ typedef char_decorator_terminal< SubactorT, ImplT > this_type;
+
+public:
+ //! Internal typedef for type categorization
+ typedef void _is_boost_log_terminal;
+
+ //! Implementation type
+ typedef ImplT impl_type;
+ //! Character type
+ typedef typename impl_type::char_type char_type;
+ //! String type
+ typedef typename impl_type::string_type string_type;
+ //! Stream type
+ typedef basic_formatting_ostream< char_type > stream_type;
+ //! Adopted actor type
+ typedef SubactorT subactor_type;
+
+ //! Result type definition
+ typedef string_type result_type;
+
+private:
+ //! Adopted formatter actor
+ subactor_type m_subactor;
+ //! Implementation
+ impl_type m_impl;
+
+public:
+ /*!
+ * Initializing constructor.
+ */
+ char_decorator_terminal(subactor_type const& sub, impl_type const& impl) : m_subactor(sub), m_impl(impl)
+ {
+ }
+ /*!
+ * Copy constructor
+ */
+ char_decorator_terminal(char_decorator_terminal const& that) : m_subactor(that.m_subactor), m_impl(that.m_impl)
+ {
+ }
+
+ /*!
+ * \returns Adopted subactor
+ */
+ subactor_type const& get_subactor() const
+ {
+ return m_subactor;
+ }
+
+ /*!
+ * \returns Implementation
+ */
+ impl_type const& get_impl() const
+ {
+ return m_impl;
+ }
+
+ /*!
+ * Invokation operator
+ */
+ template< typename ContextT >
+ result_type operator() (ContextT const& ctx)
+ {
+ string_type str;
+ stream_type strm(str);
+
+ // Invoke the adopted formatter
+ typedef phoenix::vector3<
+ subactor_type*,
+ typename fusion::result_of::at_c<
+ typename remove_cv<
+ typename remove_reference<
+ typename phoenix::result_of::env< ContextT const& >::type
+ >::type
+ >::type::args_type,
+ 0
+ >::type,
+ stream_type&
+ > env_type;
+ env_type env = { boost::addressof(m_subactor), fusion::at_c< 0 >(phoenix::env(ctx).args()), strm };
+ phoenix::eval(m_subactor, phoenix::make_context(env, phoenix::actions(ctx)));
+
+ // Flush the buffered characters and apply decorations
+ strm.flush();
+ m_impl(*strm.rdbuf()->storage());
+
+ return boost::move(str);
+ }
+
+ /*!
+ * Invokation operator
+ */
+ template< typename ContextT >
+ result_type operator() (ContextT const& ctx) const
+ {
+ string_type str;
+ stream_type strm(str);
+
+ // Invoke the adopted formatter
+ typedef phoenix::vector3<
+ const subactor_type*,
+ typename fusion::result_of::at_c<
+ typename remove_cv<
+ typename remove_reference<
+ typename phoenix::result_of::env< ContextT const& >::type
+ >::type
+ >::type::args_type,
+ 0
+ >::type,
+ stream_type&
+ > env_type;
+ env_type env = { boost::addressof(m_subactor), fusion::at_c< 0 >(phoenix::env(ctx).args()), strm };
+ phoenix::eval(m_subactor, phoenix::make_context(env, phoenix::actions(ctx)));
+
+ // Flush the buffered characters and apply decorations
+ strm.flush();
+ m_impl(*strm.rdbuf()->storage());
+
+ return boost::move(str);
+ }
+
+ BOOST_DELETED_FUNCTION(char_decorator_terminal())
+};
+
+/*!
+ * Character decorator actor
+ */
+template< typename SubactorT, typename ImplT, template< typename > class ActorT = phoenix::actor >
+class char_decorator_actor :
+ public ActorT< char_decorator_terminal< SubactorT, ImplT > >
+{
+public:
+ //! Base terminal type
+ typedef char_decorator_terminal< SubactorT, ImplT > terminal_type;
+ //! Character type
+ typedef typename terminal_type::char_type char_type;
+
+ //! Base actor type
+ typedef ActorT< terminal_type > base_type;
+
+public:
+ //! Initializing constructor
+ explicit char_decorator_actor(base_type const& act) : base_type(act)
+ {
+ }
+
+ //! Returns reference to the terminal
+ terminal_type const& get_terminal() const
+ {
+ return this->proto_expr_.child0;
+ }
+};
+
+#ifndef BOOST_LOG_DOXYGEN_PASS
+
+#define BOOST_LOG_AUX_OVERLOAD(left_ref, right_ref)\
+ template< typename LeftExprT, typename SubactorT, typename ImplT, template< typename > class ActorT >\
+ BOOST_FORCEINLINE phoenix::actor< aux::char_decorator_output_terminal< phoenix::actor< LeftExprT >, SubactorT, ImplT > >\
+ operator<< (phoenix::actor< LeftExprT > left_ref left, char_decorator_actor< SubactorT, ImplT, ActorT > right_ref right)\
+ {\
+ typedef aux::char_decorator_output_terminal< phoenix::actor< LeftExprT >, SubactorT, ImplT > terminal_type;\
+ phoenix::actor< terminal_type > actor = {{ terminal_type(left, right.get_terminal().get_subactor(), right.get_terminal().get_impl()) }};\
+ return actor;\
+ }
+
+#include <boost/log/detail/generate_overloads.hpp>
+
+#undef BOOST_LOG_AUX_OVERLOAD
+
+#endif // BOOST_LOG_DOXYGEN_PASS
+
+namespace aux {
+
+template< typename RangeT >
+class char_decorator_gen1
+{
+ RangeT const& m_decorations;
+
+ typedef typename boost::log::aux::deduce_char_type< typename range_value< RangeT >::type::first_type >::type char_type;
+
+public:
+ explicit char_decorator_gen1(RangeT const& decorations) : m_decorations(decorations)
+ {
+ }
+
+ template< typename SubactorT >
+ BOOST_FORCEINLINE char_decorator_actor< SubactorT, pattern_replacer< char_type > > operator[] (SubactorT const& subactor) const
+ {
+ typedef pattern_replacer< char_type > replacer_type;
+ typedef char_decorator_actor< SubactorT, replacer_type > result_type;
+ typedef typename result_type::terminal_type terminal_type;
+ typename result_type::base_type act = {{ terminal_type(subactor, replacer_type(m_decorations)) }};
+ return result_type(act);
+ }
+};
+
+template< typename FromRangeT, typename ToRangeT >
+class char_decorator_gen2
+{
+ FromRangeT const& m_from;
+ ToRangeT const& m_to;
+
+ typedef typename boost::log::aux::deduce_char_type< typename range_value< FromRangeT >::type >::type from_char_type;
+ typedef typename boost::log::aux::deduce_char_type< typename range_value< ToRangeT >::type >::type to_char_type;
+ BOOST_STATIC_ASSERT_MSG((is_same< from_char_type, to_char_type >::value), "Boost.Log: character decorator cannot be instantiated with different character types for source and replacement strings");
+
+public:
+ char_decorator_gen2(FromRangeT const& from, ToRangeT const& to) : m_from(from), m_to(to)
+ {
+ }
+
+ template< typename SubactorT >
+ BOOST_FORCEINLINE char_decorator_actor< SubactorT, pattern_replacer< from_char_type > > operator[] (SubactorT const& subactor) const
+ {
+ typedef pattern_replacer< from_char_type > replacer_type;
+ typedef char_decorator_actor< SubactorT, replacer_type > result_type;
+ typedef typename result_type::terminal_type terminal_type;
+ typename result_type::base_type act = {{ terminal_type(subactor, replacer_type(m_from, m_to)) }};
+ return result_type(act);
+ }
+};
+
+} // namespace aux
+
+/*!
+ * The function returns a decorator generator object. The generator provides <tt>operator[]</tt> that can be used
+ * to construct the actual decorator.
+ *
+ * \param decorations A sequence of string pairs that will be used as decorations. Every <tt>decorations[i].first</tt>
+ * substring occurrence in the output will be replaced with <tt>decorations[i].second</tt>.
+ */
+template< typename RangeT >
+BOOST_FORCEINLINE aux::char_decorator_gen1< RangeT > char_decor(RangeT const& decorations)
+{
+ return aux::char_decorator_gen1< RangeT >(decorations);
+}
+
+/*!
+ * The function returns a decorator generator object. The generator provides <tt>operator[]</tt> that can be used
+ * to construct the actual decorator.
+ *
+ * \param from A sequence of strings that will be sought in the output.
+ * \param to A sequence of strings that will be used as replacements.
+ *
+ * \note The \a from and \a to sequences mush be of the same size. Every <tt>from[i]</tt>
+ * substring occurrence in the output will be replaced with <tt>to[i]</tt>.
+ */
+template< typename FromRangeT, typename ToRangeT >
+BOOST_FORCEINLINE aux::char_decorator_gen2< FromRangeT, ToRangeT > char_decor(FromRangeT const& from, ToRangeT const& to)
+{
+ return aux::char_decorator_gen2< FromRangeT, ToRangeT >(from, to);
+}
+
+} // namespace expressions
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+#ifndef BOOST_LOG_DOXYGEN_PASS
+
+namespace phoenix {
+
+namespace result_of {
+
+template< typename SubactorT, typename ImplT >
+struct is_nullary< custom_terminal< boost::log::expressions::char_decorator_terminal< SubactorT, ImplT > > > :
+ public mpl::false_
+{
+};
+
+template< typename LeftT, typename SubactorT, typename ImplT >
+struct is_nullary< custom_terminal< boost::log::expressions::aux::char_decorator_output_terminal< LeftT, SubactorT, ImplT > > > :
+ public mpl::false_
+{
+};
+
+} // namespace result_of
+
+} // namespace phoenix
+
+#endif
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_EXPRESSIONS_FORMATTERS_CHAR_DECORATOR_HPP_INCLUDED_
diff --git a/boost/log/expressions/formatters/csv_decorator.hpp b/boost/log/expressions/formatters/csv_decorator.hpp
new file mode 100644
index 0000000..8c964a0
--- /dev/null
+++ b/boost/log/expressions/formatters/csv_decorator.hpp
@@ -0,0 +1,140 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file formatters/csv_decorator.hpp
+ * \author Andrey Semashev
+ * \date 18.11.2012
+ *
+ * The header contains implementation of a CSV-style character decorator.
+ * See: http://en.wikipedia.org/wiki/Comma-separated_values
+ */
+
+#ifndef BOOST_LOG_EXPRESSIONS_FORMATTERS_CSV_DECORATOR_HPP_INCLUDED_
+#define BOOST_LOG_EXPRESSIONS_FORMATTERS_CSV_DECORATOR_HPP_INCLUDED_
+
+#include <boost/range/iterator_range_core.hpp>
+#include <boost/log/detail/config.hpp>
+#include <boost/log/expressions/formatters/char_decorator.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace expressions {
+
+namespace aux {
+
+template< typename >
+struct csv_decorator_traits;
+
+#ifdef BOOST_LOG_USE_CHAR
+template< >
+struct csv_decorator_traits< char >
+{
+ static boost::iterator_range< const char* const* > get_patterns()
+ {
+ static const char* const patterns[] =
+ {
+ "\""
+ };
+ return boost::make_iterator_range(patterns);
+ }
+ static boost::iterator_range< const char* const* > get_replacements()
+ {
+ static const char* const replacements[] =
+ {
+ "\"\""
+ };
+ return boost::make_iterator_range(replacements);
+ }
+};
+#endif // BOOST_LOG_USE_CHAR
+
+#ifdef BOOST_LOG_USE_WCHAR_T
+template< >
+struct csv_decorator_traits< wchar_t >
+{
+ static boost::iterator_range< const wchar_t* const* > get_patterns()
+ {
+ static const wchar_t* const patterns[] =
+ {
+ L"\""
+ };
+ return boost::make_iterator_range(patterns);
+ }
+ static boost::iterator_range< const wchar_t* const* > get_replacements()
+ {
+ static const wchar_t* const replacements[] =
+ {
+ L"\"\""
+ };
+ return boost::make_iterator_range(replacements);
+ }
+};
+#endif // BOOST_LOG_USE_WCHAR_T
+
+template< typename CharT >
+struct csv_decorator_gen
+{
+ typedef CharT char_type;
+
+ template< typename SubactorT >
+ BOOST_FORCEINLINE char_decorator_actor< SubactorT, pattern_replacer< char_type > > operator[] (SubactorT const& subactor) const
+ {
+ typedef csv_decorator_traits< char_type > traits_type;
+ typedef pattern_replacer< char_type > replacer_type;
+ typedef char_decorator_actor< SubactorT, replacer_type > result_type;
+ typedef typename result_type::terminal_type terminal_type;
+ typename result_type::base_type act = {{ terminal_type(subactor, replacer_type(traits_type::get_patterns(), traits_type::get_replacements())) }};
+ return result_type(act);
+ }
+};
+
+} // namespace aux
+
+/*!
+ * CSV-style decorator generator object. The decorator doubles double quotes that may be found
+ * in the output. See http://en.wikipedia.org/wiki/Comma-separated_values for more information on
+ * the CSV format. The generator provides <tt>operator[]</tt> that can be used to construct
+ * the actual decorator. For example:
+ *
+ * <code>
+ * csv_decor[ attr< std::string >("MyAttr") ]
+ * </code>
+ *
+ * For wide-character formatting there is the similar \c wcsv_decor decorator generator object.
+ */
+#ifdef BOOST_LOG_USE_CHAR
+const aux::csv_decorator_gen< char > csv_decor = {};
+#endif
+#ifdef BOOST_LOG_USE_WCHAR_T
+const aux::csv_decorator_gen< wchar_t > wcsv_decor = {};
+#endif
+
+/*!
+ * The function creates an CSV-style decorator generator for arbitrary character type.
+ */
+template< typename CharT >
+BOOST_FORCEINLINE aux::csv_decorator_gen< CharT > make_csv_decor()
+{
+ return aux::csv_decorator_gen< CharT >();
+}
+
+} // namespace expressions
+
+BOOST_LOG_CLOSE_NAMESPACE // namespace log
+
+} // namespace boost
+
+#include <boost/log/detail/footer.hpp>
+
+#endif // BOOST_LOG_EXPRESSIONS_FORMATTERS_CSV_DECORATOR_HPP_INCLUDED_
diff --git a/boost/log/expressions/formatters/date_time.hpp b/boost/log/expressions/formatters/date_time.hpp
new file mode 100644
index 0000000..0ff6b68
--- /dev/null
+++ b/boost/log/expressions/formatters/date_time.hpp
@@ -0,0 +1,343 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2014.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file formatters/date_time.hpp
+ * \author Andrey Semashev
+ * \date 16.09.2012
+ *
+ * The header contains a formatter function for date and time attribute values.
+ */
+
+#ifndef BOOST_LOG_EXPRESSIONS_FORMATTERS_DATE_TIME_HPP_INCLUDED_
+#define BOOST_LOG_EXPRESSIONS_FORMATTERS_DATE_TIME_HPP_INCLUDED_
+
+#include <string>
+#include <boost/move/core.hpp>
+#include <boost/move/utility.hpp>
+#include <boost/phoenix/core/actor.hpp>
+#include <boost/phoenix/core/terminal_fwd.hpp>
+#include <boost/phoenix/core/is_nullary.hpp>
+#include <boost/phoenix/core/environment.hpp>
+#include <boost/fusion/sequence/intrinsic/at_c.hpp>
+#include <boost/log/detail/config.hpp>
+#include <boost/log/attributes/attribute_name.hpp>
+#include <boost/log/attributes/fallback_policy.hpp>
+#include <boost/log/attributes/value_visitation.hpp>
+#include <boost/log/detail/light_function.hpp>
+#include <boost/log/detail/date_time_fmt_gen_traits_fwd.hpp>
+#include <boost/log/detail/custom_terminal_spec.hpp>
+#include <boost/log/detail/attr_output_terminal.hpp>
+#include <boost/log/expressions/attr_fwd.hpp>
+#include <boost/log/expressions/keyword_fwd.hpp>
+#include <boost/log/utility/formatting_ostream.hpp>
+#include <boost/log/utility/functional/bind.hpp>
+#include <boost/log/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+BOOST_LOG_OPEN_NAMESPACE
+
+namespace expressions {
+
+/*!
+ * Date and time formatter terminal.
+ */
+template< typename T, typename FallbackPolicyT, typename CharT >
+class format_date_time_terminal
+{
+public:
+ //! Internal typedef for type categorization
+ typedef void _is_boost_log_terminal;
+
+ //! Attribute value type
+ typedef T value_type;
+ //! Fallback policy
+ typedef FallbackPolicyT fallback_policy;
+ //! Character type
+ typedef CharT char_type;
+ //! String type
+ typedef std::basic_string< char_type > string_type;
+ //! Formatting stream type
+ typedef basic_formatting_ostream< char_type > stream_type;
+
+ //! Formatter function
+ typedef boost::log::aux::light_function< void (stream_type&, value_type const&) > formatter_function_type;
+
+ //! Function result type
+ typedef string_type result_type;
+
+private:
+ //! Formatter generator traits
+ typedef aux::date_time_formatter_generator_traits< value_type, char_type > formatter_generator;
+ //! Attribute value visitor invoker
+ typedef value_visitor_invoker< value_type, fallback_policy > visitor_invoker_type;
+
+private:
+ //! Attribute name
+ attribute_name m_name;
+ //! Formattr function
+ formatter_function_type m_formatter;
+ //! Attribute value visitor invoker
+ visitor_invoker_type m_visitor_invoker;
+
+public:
+ //! Initializing constructor
+ format_date_time_terminal(attribute_name const& name, fallback_policy const& fallback, string_type const& format) :
+ m_name(name), m_formatter(formatter_generator::parse(format)), m_visitor_invoker(fallback)
+ {
+ }
+ //! Copy constructor
+ format_date_time_terminal(format_date_time_terminal const& that) :
+ m_name(that.m_name), m_formatter(that.m_formatter), m_visitor_invoker(that.m_visitor_invoker)
+ {
+ }
+
+ //! Returns attribute name
+ attribute_name get_name() const
+ {
+ return m_name;
+ }
+
+ //! Returns fallback policy
+ fallback_policy const& get_fallback_policy() const
+ {
+ return m_visitor_invoker.get_fallback_policy();
+ }
+
+ //! Retruns formatter function
+ formatter_function_type const& get_formatter_function() const
+ {
+ return m_formatter;
+ }
+
+ //! Invokation operator
+ template< typename ContextT >
+ result_type operator() (ContextT const& ctx)
+ {
+ string_type str;
+ stream_type strm(str);
+ m_visitor_invoker(m_name, fusion::at_c< 0 >(phoenix::env(ctx).args()), binder1st< formatter_function_type&, stream_type& >(m_formatter, strm));
+ strm.flush();
+ return boost::move(str);
+ }
+
+ //! Invokation operator
+ template< typename ContextT >
+ result_type operator() (ContextT const& ctx) const
+ {
+ string_type str;
+ stream_type strm(str);
+ m_visitor_invoker(m_name, fusion::at_c< 0 >(phoenix::env(ctx).args()), binder1st< formatter_function_type const&, stream_type& >(m_formatter, strm));
+ strm.flush();
+ return boost::move(str);
+ }
+
+ BOOST_DELETED_FUNCTION(format_date_time_terminal())
+};
+
+/*!
+ * Date and time formatter actor.
+ */
+template< typename T, typename FallbackPolicyT, typename CharT, template< typename > class ActorT = phoenix::actor >
+class format_date_time_actor :
+ public ActorT< format_date_time_terminal< T, FallbackPolicyT, CharT > >
+{
+public:
+ //! Attribute value type
+ typedef T value_type;
+ //! Character type
+ typedef CharT char_type;
+ //! Fallback policy
+ typedef FallbackPolicyT fallback_policy;
+ //! Base terminal type
+ typedef format_date_time_terminal< value_type, fallback_policy, char_type > terminal_type;
+ //! Formatter function
+ typedef typename terminal_type::formatter_function_type formatter_function_type;
+
+ //! Base actor type
+ typedef ActorT< terminal_type > base_type;
+
+public:
+ //! Initializing constructor
+ explicit format_date_time_actor(base_type const& act) : base_type(act)
+ {
+ }
+
+ /*!
+ * \returns The attribute name
+ */
+ attribute_name get_name() const
+ {
+ return this->proto_expr_.child0.get_name();
+ }
+
+ /*!
+ * \returns Fallback policy
+ */
+ fallback_policy const& get_fallback_policy() const
+ {
+ return this->proto_expr_.child0.get_fallback_policy();
+ }
+
+ /*!
+ * \returns Formatter function
+ */
+ formatter_function_type const& get_formatter_function() const
+ {
+ return this->proto_expr_.child0.get_formatter_function();
+ }
+};
+
+#ifndef BOOST_LOG_DOXYGEN_PASS
+
+#define BOOST_LOG_AUX_OVERLOAD(left_ref, right_ref)\
+ template< typename LeftExprT, typename T, typename FallbackPolicyT, typename CharT >\
+ BOOST_FORCEINLINE phoenix::actor< aux::attribute_output_terminal< phoenix::actor< LeftExprT >, T, FallbackPolicyT, typename format_date_time_actor< T, FallbackPolicyT, CharT >::formatter_function_type > >\
+ operator<< (phoenix::actor< LeftExprT > left_ref left, format_date_time_actor< T, FallbackPolicyT, CharT > right_ref right)\
+ {\
+ typedef aux::attribute_output_terminal< phoenix::actor< LeftExprT >, T, FallbackPolicyT, typename format_date_time_actor< T, FallbackPolicyT, CharT >::formatter_function_type > terminal_type;\
+ phoenix::actor< terminal_type > actor = {{ terminal_type(left, right.get_name(), right.get_formatter_function(), right.get_fallback_policy()) }};\
+ return actor;\
+ }
+
+#include <boost/log/detail/generate_overloads.hpp>
+
+#undef BOOST_LOG_AUX_OVERLOAD
+
+#endif // BOOST_LOG_DOXYGEN_PASS
+