diff options
Diffstat (limited to 'boost/log')
-rw-r--r-- | boost/log/detail/allocator_traits.hpp | 77 | ||||
-rw-r--r-- | boost/log/detail/attachable_sstream_buf.hpp | 10 | ||||
-rw-r--r-- | boost/log/detail/config.hpp | 13 | ||||
-rw-r--r-- | boost/log/detail/threadsafe_queue.hpp | 95 | ||||
-rw-r--r-- | boost/log/expressions/predicates/channel_severity_filter.hpp | 3 | ||||
-rw-r--r-- | boost/log/utility/ipc/reliable_message_queue.hpp | 4 | ||||
-rw-r--r-- | boost/log/utility/permissions.hpp | 4 |
7 files changed, 149 insertions, 57 deletions
diff --git a/boost/log/detail/allocator_traits.hpp b/boost/log/detail/allocator_traits.hpp new file mode 100644 index 0000000000..3f9501c655 --- /dev/null +++ b/boost/log/detail/allocator_traits.hpp @@ -0,0 +1,77 @@ +/* + * Copyright Andrey Semashev 2018. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + */ +/*! + * \file allocator_traits.hpp + * \author Andrey Semashev + * \date 03.01.2018 + * + * \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_ALLOCATOR_TRAITS_HPP_INCLUDED_ +#define BOOST_LOG_ALLOCATOR_TRAITS_HPP_INCLUDED_ + +#include <memory> +#include <boost/log/detail/config.hpp> +#if defined(BOOST_NO_CXX11_ALLOCATOR) +#include <boost/container/allocator_traits.hpp> +#endif +#include <boost/log/detail/header.hpp> + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +namespace boost { + +BOOST_LOG_OPEN_NAMESPACE + +namespace aux { + +// A portable name for allocator traits +#if !defined(BOOST_NO_CXX11_ALLOCATOR) +using std::allocator_traits; +#else +using boost::container::allocator_traits; +#endif + +/*! + * \brief A standalone trait to rebind an allocator to another type. + * + * The important difference from <tt>std::allocator_traits<Alloc>::rebind_alloc<U></tt> is that this + * trait does not require template aliases and thus is compatible with C++03. There is + * <tt>boost::container::allocator_traits<Alloc>::portable_rebind_alloc<U></tt>, but it is not present in <tt>std::allocator_traits</tt>. + * It will also attempt to instantiate the allocator type to test if it provides the nested <tt>rebind</tt> template. We don't want + * that to happen because it prohibits using <tt>std::allocator<void></tt> in C++17 and later, which deprecated + * this allocator specialization. This standalone trait does not use the nested <tt>rebind</tt> template in this case. + */ +template< typename Allocator, typename U > +struct rebind_alloc +{ +#if !defined(BOOST_NO_CXX11_ALLOCATOR) + typedef typename std::allocator_traits< Allocator >::BOOST_NESTED_TEMPLATE rebind_alloc< U > type; +#else + typedef typename boost::container::allocator_traits< Allocator >::BOOST_NESTED_TEMPLATE portable_rebind_alloc< U >::type type; +#endif +}; + +template< typename U > +struct rebind_alloc< std::allocator< void >, U > +{ + typedef std::allocator< U > type; +}; + +} // namespace aux + +BOOST_LOG_CLOSE_NAMESPACE // namespace log + +} // namespace boost + +#include <boost/log/detail/footer.hpp> + +#endif // BOOST_LOG_ALLOCATOR_TRAITS_HPP_INCLUDED_ diff --git a/boost/log/detail/attachable_sstream_buf.hpp b/boost/log/detail/attachable_sstream_buf.hpp index 7bcb3a4307..e196689c80 100644 --- a/boost/log/detail/attachable_sstream_buf.hpp +++ b/boost/log/detail/attachable_sstream_buf.hpp @@ -22,7 +22,7 @@ #include <string> #include <streambuf> #include <boost/assert.hpp> -#include <boost/mpl/bool.hpp> +#include <boost/type_traits/integral_constant.hpp> #include <boost/locale/utf.hpp> #include <boost/log/detail/config.hpp> #include <boost/log/detail/header.hpp> @@ -277,11 +277,13 @@ protected: //! Finds the string length so that it includes only complete characters, and does not exceed \a max_size size_type length_until_boundary(const char_type* s, size_type n, size_type max_size) const { - return length_until_boundary(s, n, max_size, mpl::bool_< sizeof(char_type) == 1u >()); + BOOST_ASSERT(max_size <= n); + return length_until_boundary(s, n, max_size, boost::integral_constant< bool, sizeof(char_type) == 1u >()); } +private: //! Finds the string length so that it includes only complete characters, and does not exceed \a max_size - size_type length_until_boundary(const char_type* s, size_type n, size_type max_size, mpl::true_) const + size_type length_until_boundary(const char_type* s, size_type, size_type max_size, boost::true_type) const { std::locale loc = this->getloc(); std::codecvt< wchar_t, char, std::mbstate_t > const& fac = std::use_facet< std::codecvt< wchar_t, char, std::mbstate_t > >(loc); @@ -290,7 +292,7 @@ protected: } //! Finds the string length so that it includes only complete characters, and does not exceed \a max_size - static size_type length_until_boundary(const char_type* s, size_type n, size_type max_size, mpl::false_) + static size_type length_until_boundary(const char_type* s, size_type n, size_type max_size, boost::false_type) { // Note: Although it's not required to be true for wchar_t, here we assume that the string has Unicode encoding. // Compilers use some version of Unicode for wchar_t on all tested platforms, and std::locale doesn't offer a way diff --git a/boost/log/detail/config.hpp b/boost/log/detail/config.hpp index 5f43443e42..8db321baad 100644 --- a/boost/log/detail/config.hpp +++ b/boost/log/detail/config.hpp @@ -344,11 +344,18 @@ 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 }} +# elif defined(BOOST_GCC) && (BOOST_GCC+0) >= 40400 + +// GCC 7 deprecated strong using directives but allows inline namespaces in C++03 mode since GCC 4.4. +__extension__ inline namespace BOOST_LOG_VERSION_NAMESPACE {} + +# define BOOST_LOG_OPEN_NAMESPACE namespace log { __extension__ inline namespace BOOST_LOG_VERSION_NAMESPACE { +# define BOOST_LOG_CLOSE_NAMESPACE }} + # else namespace BOOST_LOG_VERSION_NAMESPACE {} @@ -359,12 +366,12 @@ __attribute__((__strong__)) # endif ; -} - # define BOOST_LOG_OPEN_NAMESPACE namespace log { namespace BOOST_LOG_VERSION_NAMESPACE { # define BOOST_LOG_CLOSE_NAMESPACE }} # endif +} // namespace log + #else // !defined(BOOST_LOG_DOXYGEN_PASS) namespace log {} diff --git a/boost/log/detail/threadsafe_queue.hpp b/boost/log/detail/threadsafe_queue.hpp index b8b3dbe60a..b747ed4c5d 100644 --- a/boost/log/detail/threadsafe_queue.hpp +++ b/boost/log/detail/threadsafe_queue.hpp @@ -32,6 +32,7 @@ #include <boost/move/utility_core.hpp> #include <boost/type_traits/alignment_of.hpp> #include <boost/type_traits/type_with_alignment.hpp> +#include <boost/log/detail/allocator_traits.hpp> #include <boost/log/detail/header.hpp> namespace boost { @@ -69,23 +70,22 @@ struct threadsafe_queue_impl 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 +//! Thread-safe queue node type +template< typename T > +struct threadsafe_queue_node : + public threadsafe_queue_impl::node_base { - struct node : - public threadsafe_queue_impl::node_base - { - typedef typename aligned_storage< sizeof(T), alignment_of< T >::value >::type storage_type; - storage_type storage; + 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(); } - }; + BOOST_DEFAULTED_FUNCTION(threadsafe_queue_node(), {}) + explicit threadsafe_queue_node(T const& val) { new (storage.address()) T(val); } + T& value() BOOST_NOEXCEPT { return *static_cast< T* >(storage.address()); } + void destroy() BOOST_NOEXCEPT { static_cast< T* >(storage.address())->~T(); } - typedef typename AllocatorT::BOOST_NESTED_TEMPLATE rebind< node >::other allocator_type; + // Copying and assignment is prohibited + BOOST_DELETED_FUNCTION(threadsafe_queue_node(threadsafe_queue_node const&)) + BOOST_DELETED_FUNCTION(threadsafe_queue_node& operator= (threadsafe_queue_node const&)) }; /*! @@ -108,74 +108,77 @@ struct threadsafe_queue_types */ template< typename T, typename AllocatorT = std::allocator< void > > class threadsafe_queue : - private threadsafe_queue_types< T, AllocatorT >::allocator_type + private boost::log::aux::rebind_alloc< AllocatorT, threadsafe_queue_node< T > >::type { private: - typedef typename threadsafe_queue_types< T, AllocatorT >::allocator_type base_type; - typedef typename threadsafe_queue_types< T, AllocatorT >::node node; + typedef threadsafe_queue_node< T > node; + +public: + typedef typename boost::log::aux::rebind_alloc< AllocatorT, node >::type allocator_type; + 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; + +private: + typedef boost::log::aux::allocator_traits< allocator_type > alloc_traits; //! 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) : + auto_deallocate(allocator_type* alloc, node* dealloc, node* destr) BOOST_NOEXCEPT : m_pAllocator(alloc), m_pDeallocate(dealloc), m_pDestroy(destr) { } - ~auto_deallocate() + ~auto_deallocate() BOOST_NOEXCEPT { - m_pAllocator->deallocate(m_pDeallocate, 1); + alloc_traits::destroy(*m_pAllocator, m_pDeallocate); + alloc_traits::deallocate(*m_pAllocator, m_pDeallocate, 1); m_pDestroy->destroy(); } private: - base_type* m_pAllocator; + allocator_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) + threadsafe_queue(allocator_type const& alloc = allocator_type()) : + allocator_type(alloc) { - node* p = base_type::allocate(1); + node* p = alloc_traits::allocate(get_allocator(), 1); if (p) { try { - new (p) node(); + alloc_traits::construct(get_allocator(), p); try { m_pImpl = threadsafe_queue_impl::create(p); } catch (...) { - p->~node(); + alloc_traits::destroy(get_allocator(), p); throw; } } catch (...) { - base_type::deallocate(p, 1); + alloc_traits::deallocate(get_allocator(), p, 1); throw; } } @@ -185,7 +188,7 @@ public: /*! * Destructor */ - ~threadsafe_queue() + ~threadsafe_queue() BOOST_NOEXCEPT { // Clear the queue if (!unsafe_empty()) @@ -196,8 +199,8 @@ public: // Remove the last dummy node node* p = static_cast< node* >(m_pImpl->reset_last_node()); - p->~node(); - base_type::deallocate(p, 1); + alloc_traits::destroy(get_allocator(), p); + alloc_traits::deallocate(get_allocator(), p, 1); delete m_pImpl; } @@ -213,16 +216,16 @@ public: */ void push(const_reference value) { - node* p = base_type::allocate(1); + node* p = alloc_traits::allocate(get_allocator(), 1); if (p) { try { - new (p) node(value); + alloc_traits::construct(get_allocator(), p, value); } catch (...) { - base_type::deallocate(p, 1); + alloc_traits::deallocate(get_allocator(), p, 1); throw; } m_pImpl->push(p); @@ -242,7 +245,7 @@ public: 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); + auto_deallocate guard(static_cast< allocator_type* >(this), static_cast< node* >(dealloc), p); value = boost::move(p->value()); return true; } @@ -255,6 +258,10 @@ public: BOOST_DELETED_FUNCTION(threadsafe_queue& operator= (threadsafe_queue const&)) private: + //! Returns the allocator instance + allocator_type& get_allocator() BOOST_NOEXCEPT { return *static_cast< allocator_type* >(this); } + +private: //! Pointer to the implementation threadsafe_queue_impl* m_pImpl; }; diff --git a/boost/log/expressions/predicates/channel_severity_filter.hpp b/boost/log/expressions/predicates/channel_severity_filter.hpp index c7430a1bd7..e8562e2a81 100644 --- a/boost/log/expressions/predicates/channel_severity_filter.hpp +++ b/boost/log/expressions/predicates/channel_severity_filter.hpp @@ -26,6 +26,7 @@ #include <boost/type_traits/remove_cv.hpp> #include <boost/type_traits/remove_reference.hpp> #include <boost/log/detail/config.hpp> +#include <boost/log/detail/allocator_traits.hpp> #include <boost/log/detail/custom_terminal_spec.hpp> #include <boost/log/attributes/attribute_name.hpp> #include <boost/log/attributes/fallback_policy.hpp> @@ -80,7 +81,7 @@ private: channel_value_type, severity_value_type, ChannelOrderT, - typename AllocatorT::BOOST_NESTED_TEMPLATE rebind< std::pair< const channel_value_type, severity_value_type > >::other + typename boost::log::aux::rebind_alloc< AllocatorT, std::pair< const channel_value_type, severity_value_type > >::type > mapping_type; //! Attribute value visitor invoker for channel typedef value_visitor_invoker< channel_value_type, channel_fallback_policy > channel_visitor_invoker_type; diff --git a/boost/log/utility/ipc/reliable_message_queue.hpp b/boost/log/utility/ipc/reliable_message_queue.hpp index 934d6ab299..5159d72ef6 100644 --- a/boost/log/utility/ipc/reliable_message_queue.hpp +++ b/boost/log/utility/ipc/reliable_message_queue.hpp @@ -429,7 +429,7 @@ public: /*! * The method wakes up all threads that are blocked in calls to <tt>send()</tt> or - * <tt>receive()</tt>. Those calls would then return \c false with \c errno \c EINTR. + * <tt>receive()</tt>. Those calls would then return <tt>operation_result::aborted</tt>. * Note that, the method does not block until the woken-up threads have actually * returned from <tt>send()</tt> or <tt>receive()</tt>. Other means is needed to ensure * that calls to <tt>send()</tt> or <tt>receive()</tt> have returned, e.g., joining the @@ -437,7 +437,7 @@ public: * * The method also puts the object in stopped state. When in stopped state, calls to * <tt>send()</tt> or <tt>receive()</tt> will return immediately with return value - * \c false and \c errno \c EINTR when they would otherwise block in running state. + * <tt>operation_result::aborted</tt> when they would otherwise block in running state. * * Concurrent calls to this method, <tt>send()</tt>, <tt>try_send()</tt>, <tt>receive()</tt>, * <tt>try_receive()</tt>, and <tt>clear()</tt> are allowed. diff --git a/boost/log/utility/permissions.hpp b/boost/log/utility/permissions.hpp index e35649a185..8562f7fe73 100644 --- a/boost/log/utility/permissions.hpp +++ b/boost/log/utility/permissions.hpp @@ -33,11 +33,9 @@ struct _SECURITY_ATTRIBUTES; namespace boost { #ifdef BOOST_WINDOWS -namespace detail { namespace winapi { struct BOOST_LOG_MAY_ALIAS _SECURITY_ATTRIBUTES; } -} #endif namespace interprocess { @@ -108,7 +106,7 @@ public: } #ifdef BOOST_WINDOWS - permissions(boost::detail::winapi::_SECURITY_ATTRIBUTES* perms) BOOST_NOEXCEPT : m_perms(reinterpret_cast< native_type >(perms)) + permissions(boost::winapi::_SECURITY_ATTRIBUTES* perms) BOOST_NOEXCEPT : m_perms(reinterpret_cast< native_type >(perms)) { } #endif |