From 9a22431578339e72d0b32e1304be769da120a0de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Thu, 14 Jun 2018 13:17:55 +0200 Subject: [PATCH] * Clean up constructor template auto deduction guides to use Boost.Container traits * GitHub #73: '"triviality of pair". * Fixed race condition bug in unsynchronized_pool_resource --- doc/container.qbk | 7 +- include/boost/container/deque.hpp | 4 +- include/boost/container/detail/pair.hpp | 8 + .../boost/container/detail/thread_mutex.hpp | 179 ++++++++++++++++++ include/boost/container/flat_map.hpp | 102 ++++++++-- include/boost/container/flat_set.hpp | 70 +++++-- include/boost/container/list.hpp | 7 +- include/boost/container/map.hpp | 102 ++++++++-- .../pmr/synchronized_pool_resource.hpp | 5 +- include/boost/container/set.hpp | 70 +++++-- include/boost/container/slist.hpp | 9 +- include/boost/container/stable_vector.hpp | 9 +- include/boost/container/string.hpp | 9 +- include/boost/container/vector.hpp | 9 +- proj/vc7ide/container.vcproj | 3 + src/synchronized_pool_resource.cpp | 48 ++--- 16 files changed, 532 insertions(+), 109 deletions(-) create mode 100644 include/boost/container/detail/thread_mutex.hpp diff --git a/doc/container.qbk b/doc/container.qbk index e7a4f19..bfcaa54 100644 --- a/doc/container.qbk +++ b/doc/container.qbk @@ -1247,12 +1247,17 @@ use [*Boost.Container]? There are several reasons for that: * Implemented C++14's heterogeneous lookup functions for `[multi]map/[multi]set/flat_[multi]map/flat_[multi]set`. +* Added [@https://github.com/boostorg/container/pull/71 GitHub #71: ['"Constructor Template Auto Deduction guides "]]. + * Fixed bugs: * [@https://svn.boost.org/trac/boost/ticket/13533 Trac #13533: ['"Boost vector resize causes assert(false)"]]. + * [@https://github.com/boostorg/container/issues/73 GitHub #73: ['"triviality of pair"]]. + * Fixed race condition bug in [classref boost::container::pmr::unsynchronized_pool_resource unsynchronized_pool_resource] + found by Arthur O'Dowyer in his blog post + [@https://quuxplusone.github.io/blog/2018/06/05/libcpp-memory-resource/ for libc++] [endsect] - [section:release_notes_boost_1_67_00 Boost 1.67 Release] * ['vector] can now have options, using [classref boost::container::vector_options vector_options]. diff --git a/include/boost/container/deque.hpp b/include/boost/container/deque.hpp index fe05120..f04ba49 100644 --- a/include/boost/container/deque.hpp +++ b/include/boost/container/deque.hpp @@ -2240,9 +2240,9 @@ class deque : protected deque_base #if __cplusplus >= 201703L template -deque(InputIterator, InputIterator) -> deque::value_type>; +deque(InputIterator, InputIterator) -> deque::value_type>; template -deque(InputIterator, InputIterator, Allocator const&) -> deque::value_type, Allocator>; +deque(InputIterator, InputIterator, Allocator const&) -> deque::value_type, Allocator>; #endif }} diff --git a/include/boost/container/detail/pair.hpp b/include/boost/container/detail/pair.hpp index 6b00db1..e1df18c 100644 --- a/include/boost/container/detail/pair.hpp +++ b/include/boost/container/detail/pair.hpp @@ -550,6 +550,14 @@ struct is_class< std::pair > static const bool value = true; }; +template +struct is_trivially_copy_assignable + > +{ + static const bool value = boost::move_detail::is_trivially_copy_assignable::value && + boost::move_detail::is_trivially_copy_assignable::value ; +}; + } //namespace move_detail{ } //namespace boost { diff --git a/include/boost/container/detail/thread_mutex.hpp b/include/boost/container/detail/thread_mutex.hpp new file mode 100644 index 0000000..628f28b --- /dev/null +++ b/include/boost/container/detail/thread_mutex.hpp @@ -0,0 +1,179 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2018-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) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +// +// This code is partially based on the lightweight mutex implemented +// by Boost.SmartPtr: +// +// Copyright (c) 2002, 2003 Peter Dimov +// Copyright (c) Microsoft Corporation 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) +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONFIG_HPP +# include +#endif +# +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#ifndef BOOST_CONTAINER_DETAIL_THREAD_MUTEX_HPP +#define BOOST_CONTAINER_DETAIL_THREAD_MUTEX_HPP + +#include +#include + +#if defined(BOOST_HAS_PTHREADS) + +#include +#include + +namespace boost{ +namespace container { +namespace dtl { + +class thread_mutex +{ + public: + thread_mutex() + { + BOOST_VERIFY(pthread_mutex_init(&m_mut, 0) == 0); + } + + ~thread_mutex() + { + BOOST_VERIFY(pthread_mutex_destroy(&m_mut) == 0); + } + + void lock() + { + BOOST_VERIFY(pthread_mutex_lock( &m_mut) == 0); + } + + void unlock() + { + BOOST_VERIFY(pthread_mutex_unlock(&m_mut) == 0); + } + + private: + thread_mutex(thread_mutex const &); + thread_mutex & operator=(thread_mutex const &); + + pthread_mutex_t m_mut; +}; + +} // namespace dtl { +} // namespace container { +} // namespace boost { + +#else //!BOOST_HAS_PTHREADS (Windows implementation) + +#ifdef BOOST_USE_WINDOWS_H + +#include + +namespace boost{ +namespace container { +namespace dtl { + +typedef ::CRITICAL_SECTION win_critical_section; + +} // namespace dtl { +} // namespace container { +} // namespace boost { + +#else //! BOOST_USE_WINDOWS_H + +struct _RTL_CRITICAL_SECTION_DEBUG; +struct _RTL_CRITICAL_SECTION; + +namespace boost{ +namespace container { +namespace dtl { + +#ifdef BOOST_PLAT_WINDOWS_UWP +extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSectionEx(::_RTL_CRITICAL_SECTION *, unsigned long, unsigned long); +#else +extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSection(::_RTL_CRITICAL_SECTION *); +#endif +extern "C" __declspec(dllimport) void __stdcall EnterCriticalSection(::_RTL_CRITICAL_SECTION *); +extern "C" __declspec(dllimport) void __stdcall LeaveCriticalSection(::_RTL_CRITICAL_SECTION *); +extern "C" __declspec(dllimport) void __stdcall DeleteCriticalSection(::_RTL_CRITICAL_SECTION *); + +struct win_critical_section +{ + struct _RTL_CRITICAL_SECTION_DEBUG * DebugInfo; + long LockCount; + long RecursionCount; + void * OwningThread; + void * LockSemaphore; + #if defined(_WIN64) + unsigned __int64 SpinCount; + #else + unsigned long SpinCount; + #endif +}; + +} // namespace dtl { +} // namespace container { +} // namespace boost { + +#endif //BOOST_USE_WINDOWS_H + +namespace boost{ +namespace container { +namespace dtl { + +class thread_mutex +{ + public: + thread_mutex() + { + #ifdef BOOST_PLAT_WINDOWS_UWP + InitializeCriticalSectionEx(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&m_crit_sect), 4000, 0); + #else + InitializeCriticalSection(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&m_crit_sect)); + #endif + } + + void lock() + { + EnterCriticalSection(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&m_crit_sect)); + } + + void unlock() + { + LeaveCriticalSection(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&m_crit_sect)); + } + + ~thread_mutex() + { + DeleteCriticalSection(reinterpret_cast< ::_RTL_CRITICAL_SECTION* >(&m_crit_sect)); + } + + private: + thread_mutex(thread_mutex const &); + thread_mutex & operator=(thread_mutex const &); + + win_critical_section m_crit_sect; +}; + +} // namespace dtl { +} // namespace container { +} // namespace boost { + +#endif //BOOST_HAS_PTHREADS + +#endif // #ifndef BOOST_CONTAINER_DETAIL_THREAD_MUTEX_HPP diff --git a/include/boost/container/flat_map.hpp b/include/boost/container/flat_map.hpp index 0e24493..9679946 100644 --- a/include/boost/container/flat_map.hpp +++ b/include/boost/container/flat_map.hpp @@ -1546,22 +1546,57 @@ class flat_map }; #if __cplusplus >= 201703L + template -flat_map(InputIterator, InputIterator) -> flat_map::value_type::first_type>, typename std::iterator_traits::value_type::second_type>; +flat_map(InputIterator, InputIterator) -> + flat_map< typename dtl::remove_const< typename iterator_traits::value_type::first_type>::type + , typename iterator_traits::value_type::second_type>; + template -flat_map(InputIterator, InputIterator, Allocator const&) -> flat_map::value_type::first_type>, typename std::iterator_traits::value_type::second_type, std::less::value_type::first_type>>, Allocator>; +flat_map(InputIterator, InputIterator, Allocator const&) -> + flat_map< typename dtl::remove_const< typename iterator_traits::value_type::first_type>::type + , typename iterator_traits::value_type::second_type + , std::less::value_type::first_type>::type> + , Allocator>; + template -flat_map(InputIterator, InputIterator, Compare const&) -> flat_map::value_type::first_type>, typename std::iterator_traits::value_type::second_type, Compare>; +flat_map(InputIterator, InputIterator, Compare const&) -> + flat_map< typename dtl::remove_const::value_type::first_type>::type + , typename iterator_traits::value_type::second_type + , Compare>; + template -flat_map(InputIterator, InputIterator, Compare const&, Allocator const&) -> flat_map::value_type::first_type>, typename std::iterator_traits::value_type::second_type, Compare, Allocator>; +flat_map(InputIterator, InputIterator, Compare const&, Allocator const&) -> + flat_map< typename dtl::remove_const::value_type::first_type>::type + , typename iterator_traits::value_type::second_type + , Compare + , Allocator>; + template -flat_map(ordered_unique_range_t, InputIterator, InputIterator) -> flat_map::value_type::first_type>, typename std::iterator_traits::value_type::second_type>; +flat_map(ordered_unique_range_t, InputIterator, InputIterator) -> + flat_map< typename dtl::remove_const::value_type::first_type>::type + , typename iterator_traits::value_type::second_type>; + template -flat_map(ordered_unique_range_t, InputIterator, InputIterator, Allocator const&) -> flat_map::value_type::first_type>, typename std::iterator_traits::value_type::second_type, std::less::value_type::first_type>>, Allocator>; +flat_map(ordered_unique_range_t, InputIterator, InputIterator, Allocator const&) -> + flat_map< typename dtl::remove_const::value_type::first_type>::type + , typename iterator_traits::value_type::second_type + , std::less::value_type::first_type>::type> + , Allocator>; + template -flat_map(ordered_unique_range_t, InputIterator, InputIterator, Compare const&) -> flat_map::value_type::first_type>, typename std::iterator_traits::value_type::second_type, Compare>; +flat_map(ordered_unique_range_t, InputIterator, InputIterator, Compare const&) -> + flat_map< typename dtl::remove_const::value_type::first_type>::type + , typename iterator_traits::value_type::second_type + , Compare>; + template -flat_map(ordered_unique_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) -> flat_map::value_type::first_type>, typename std::iterator_traits::value_type::second_type, Compare, Allocator>; +flat_map(ordered_unique_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) -> + flat_map< typename dtl::remove_const::value_type::first_type>::type + , typename iterator_traits::value_type::second_type + , Compare + , Allocator>; + #endif #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED @@ -2776,22 +2811,57 @@ class flat_multimap }; #if __cplusplus >= 201703L + template -flat_multimap(InputIterator, InputIterator) -> flat_multimap::value_type::first_type>, typename std::iterator_traits::value_type::second_type>; +flat_multimap(InputIterator, InputIterator) -> + flat_multimap::value_type::first_type>::type + , typename iterator_traits::value_type::second_type>; + template -flat_multimap(InputIterator, InputIterator, Allocator const&) -> flat_multimap::value_type::first_type>, typename std::iterator_traits::value_type::second_type, std::less::value_type::first_type>>, Allocator>; +flat_multimap(InputIterator, InputIterator, Allocator const&) -> + flat_multimap::value_type::first_type>::type + , typename iterator_traits::value_type::second_type + , std::less::value_type::first_type>::type> + , Allocator>; + template -flat_multimap(InputIterator, InputIterator, Compare const&) -> flat_multimap::value_type::first_type>, typename std::iterator_traits::value_type::second_type, Compare>; +flat_multimap(InputIterator, InputIterator, Compare const&) -> + flat_multimap< typename dtl::remove_const::value_type::first_type>::type + , typename iterator_traits::value_type::second_type + , Compare>; + template -flat_multimap(InputIterator, InputIterator, Compare const&, Allocator const&) -> flat_multimap::value_type::first_type>, typename std::iterator_traits::value_type::second_type, Compare, Allocator>; +flat_multimap(InputIterator, InputIterator, Compare const&, Allocator const&) -> + flat_multimap< typename dtl::remove_const::value_type::first_type>::type + , typename iterator_traits::value_type::second_type + , Compare + , Allocator>; + template -flat_multimap(ordered_range_t, InputIterator, InputIterator) -> flat_multimap::value_type::first_type>, typename std::iterator_traits::value_type::second_type>; +flat_multimap(ordered_range_t, InputIterator, InputIterator) -> + flat_multimap< typename dtl::remove_const::value_type::first_type>::type + , typename iterator_traits::value_type::second_type>; + template -flat_multimap(ordered_range_t, InputIterator, InputIterator, Allocator const&) -> flat_multimap::value_type::first_type>, typename std::iterator_traits::value_type::second_type, std::less::value_type::first_type>>, Allocator>; +flat_multimap(ordered_range_t, InputIterator, InputIterator, Allocator const&) -> + flat_multimap< typename dtl::remove_const::value_type::first_type>::type + , typename iterator_traits::value_type::second_type + , std::less::value_type::first_type>::type> + , Allocator>; + template -flat_multimap(ordered_range_t, InputIterator, InputIterator, Compare const&) -> flat_multimap::value_type::first_type>, typename std::iterator_traits::value_type::second_type, Compare>; +flat_multimap(ordered_range_t, InputIterator, InputIterator, Compare const&) -> + flat_multimap< typename dtl::remove_const::value_type::first_type>::type + , typename iterator_traits::value_type::second_type + , Compare>; + template -flat_multimap(ordered_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) -> flat_multimap::value_type::first_type>, typename std::iterator_traits::value_type::second_type, Compare, Allocator>; +flat_multimap(ordered_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) -> + flat_multimap< typename dtl::remove_const::value_type::first_type>::type + , typename iterator_traits::value_type::second_type + , Compare + , Allocator>; + #endif }} diff --git a/include/boost/container/flat_set.hpp b/include/boost/container/flat_set.hpp index 3dda0ca..cfea7c8 100644 --- a/include/boost/container/flat_set.hpp +++ b/include/boost/container/flat_set.hpp @@ -1092,22 +1092,39 @@ class flat_set }; #if __cplusplus >= 201703L + template -flat_set(InputIterator, InputIterator) -> flat_set::value_type>; +flat_set(InputIterator, InputIterator) -> + flat_set::value_type>; + template -flat_set(InputIterator, InputIterator, Allocator const&) -> flat_set::value_type, std::less::value_type>, Allocator>; +flat_set(InputIterator, InputIterator, Allocator const&) -> + flat_set::value_type, std::less::value_type>, Allocator>; + template -flat_set(InputIterator, InputIterator, Compare const&) -> flat_set::value_type, Compare>; +flat_set(InputIterator, InputIterator, Compare const&) -> + flat_set::value_type, Compare>; + template -flat_set(InputIterator, InputIterator, Compare const&, Allocator const&) -> flat_set::value_type, Compare, Allocator>; +flat_set(InputIterator, InputIterator, Compare const&, Allocator const&) -> + flat_set::value_type, Compare, Allocator>; + template -flat_set(ordered_unique_range_t, InputIterator, InputIterator) -> flat_set::value_type>; +flat_set(ordered_unique_range_t, InputIterator, InputIterator) -> + flat_set::value_type>; + template -flat_set(ordered_unique_range_t, InputIterator, InputIterator, Allocator const&) -> flat_set::value_type, std::less::value_type>, Allocator>; +flat_set(ordered_unique_range_t, InputIterator, InputIterator, Allocator const&) -> + flat_set::value_type, std::less::value_type>, Allocator>; + template -flat_set(ordered_unique_range_t, InputIterator, InputIterator, Compare const&) -> flat_set::value_type, Compare>; +flat_set(ordered_unique_range_t, InputIterator, InputIterator, Compare const&) -> + flat_set::value_type, Compare>; + template -flat_set(ordered_unique_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) -> flat_set::value_type, Compare, Allocator>; +flat_set(ordered_unique_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) -> + flat_set::value_type, Compare, Allocator>; + #endif #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED @@ -1765,22 +1782,43 @@ class flat_multiset }; #if __cplusplus >= 201703L + template -flat_multiset(InputIterator, InputIterator) -> flat_multiset::value_type>; +flat_multiset(InputIterator, InputIterator) -> + flat_multiset::value_type>; + template -flat_multiset(InputIterator, InputIterator, Allocator const&) -> flat_multiset::value_type, std::less::value_type>, Allocator>; +flat_multiset(InputIterator, InputIterator, Allocator const&) -> + flat_multiset< typename iterator_traits::value_type + , std::less::value_type> + , Allocator>; + template -flat_multiset(InputIterator, InputIterator, Compare const&) -> flat_multiset::value_type, Compare>; +flat_multiset(InputIterator, InputIterator, Compare const&) -> + flat_multiset::value_type, Compare>; + template -flat_multiset(InputIterator, InputIterator, Compare const&, Allocator const&) -> flat_multiset::value_type, Compare, Allocator>; +flat_multiset(InputIterator, InputIterator, Compare const&, Allocator const&) -> + flat_multiset::value_type, Compare, Allocator>; + template -flat_multiset(ordered_range_t, InputIterator, InputIterator) -> flat_multiset::value_type>; +flat_multiset(ordered_range_t, InputIterator, InputIterator) -> + flat_multiset::value_type>; + template -flat_multiset(ordered_range_t, InputIterator, InputIterator, Allocator const&) -> flat_multiset::value_type, std::less::value_type>, Allocator>; +flat_multiset(ordered_range_t, InputIterator, InputIterator, Allocator const&) -> + flat_multiset< typename iterator_traits::value_type + , std::less::value_type> + , Allocator>; + template -flat_multiset(ordered_range_t, InputIterator, InputIterator, Compare const&) -> flat_multiset::value_type, Compare>; +flat_multiset(ordered_range_t, InputIterator, InputIterator, Compare const&) -> + flat_multiset< typename iterator_traits::value_type, Compare>; + template -flat_multiset(ordered_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) -> flat_multiset::value_type, Compare, Allocator>; +flat_multiset(ordered_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) -> + flat_multiset::value_type, Compare, Allocator>; + #endif #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED diff --git a/include/boost/container/list.hpp b/include/boost/container/list.hpp index 3cafd4c..68892bc 100644 --- a/include/boost/container/list.hpp +++ b/include/boost/container/list.hpp @@ -1466,9 +1466,12 @@ class list #if __cplusplus >= 201703L template -list(InputIterator, InputIterator) -> list::value_type>; +list(InputIterator, InputIterator) -> + list::value_type>; + template -list(InputIterator, InputIterator, Allocator const&) -> list::value_type, Allocator>; +list(InputIterator, InputIterator, Allocator const&) -> + list::value_type, Allocator>; #endif #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED diff --git a/include/boost/container/map.hpp b/include/boost/container/map.hpp index 8fe50d5..a88b6a5 100644 --- a/include/boost/container/map.hpp +++ b/include/boost/container/map.hpp @@ -1264,22 +1264,57 @@ class map }; #if __cplusplus >= 201703L + template -map(InputIterator, InputIterator) -> map::value_type::first_type>, typename std::iterator_traits::value_type::second_type>; +map(InputIterator, InputIterator) -> + map< typename dtl::remove_const< typename iterator_traits::value_type::first_type>::type + , typename iterator_traits::value_type::second_type>; + template -map(InputIterator, InputIterator, Allocator const&) -> map::value_type::first_type>, typename std::iterator_traits::value_type::second_type, std::less::value_type::first_type>>, Allocator>; +map(InputIterator, InputIterator, Allocator const&) -> + map< typename dtl::remove_const< typename iterator_traits::value_type::first_type>::type + , typename iterator_traits::value_type::second_type + , std::less::value_type::first_type>::type> + , Allocator>; + template -map(InputIterator, InputIterator, Compare const&) -> map::value_type::first_type>, typename std::iterator_traits::value_type::second_type, Compare>; +map(InputIterator, InputIterator, Compare const&) -> + map< typename dtl::remove_const::value_type::first_type>::type + , typename iterator_traits::value_type::second_type + , Compare>; + template -map(InputIterator, InputIterator, Compare const&, Allocator const&) -> map::value_type::first_type>, typename std::iterator_traits::value_type::second_type, Compare, Allocator>; +map(InputIterator, InputIterator, Compare const&, Allocator const&) -> + map< typename dtl::remove_const::value_type::first_type>::type + , typename iterator_traits::value_type::second_type + , Compare + , Allocator>; + template -map(ordered_unique_range_t, InputIterator, InputIterator) -> map::value_type::first_type>, typename std::iterator_traits::value_type::second_type>; +map(ordered_unique_range_t, InputIterator, InputIterator) -> + map< typename dtl::remove_const::value_type::first_type>::type + , typename iterator_traits::value_type::second_type>; + template -map(ordered_unique_range_t, InputIterator, InputIterator, Allocator const&) -> map::value_type::first_type>, typename std::iterator_traits::value_type::second_type, std::less::value_type::first_type>>, Allocator>; +map(ordered_unique_range_t, InputIterator, InputIterator, Allocator const&) -> + map< typename dtl::remove_const::value_type::first_type>::type + , typename iterator_traits::value_type::second_type + , std::less::value_type::first_type>::type> + , Allocator>; + template -map(ordered_unique_range_t, InputIterator, InputIterator, Compare const&) -> map::value_type::first_type>, typename std::iterator_traits::value_type::second_type, Compare>; +map(ordered_unique_range_t, InputIterator, InputIterator, Compare const&) -> + map< typename dtl::remove_const::value_type::first_type>::type + , typename iterator_traits::value_type::second_type + , Compare>; + template -map(ordered_unique_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) -> map::value_type::first_type>, typename std::iterator_traits::value_type::second_type, Compare, Allocator>; +map(ordered_unique_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) -> + map< typename dtl::remove_const::value_type::first_type>::type + , typename iterator_traits::value_type::second_type + , Compare + , Allocator>; + #endif @@ -2118,22 +2153,57 @@ class multimap }; #if __cplusplus >= 201703L + template -multimap(InputIterator, InputIterator) -> multimap::value_type::first_type>, typename std::iterator_traits::value_type::second_type>; +multimap(InputIterator, InputIterator) -> + multimap::value_type::first_type>::type + , typename iterator_traits::value_type::second_type>; + template -multimap(InputIterator, InputIterator, Allocator const&) -> multimap::value_type::first_type>, typename std::iterator_traits::value_type::second_type, std::less::value_type::first_type>>, Allocator>; +multimap(InputIterator, InputIterator, Allocator const&) -> + multimap::value_type::first_type>::type + , typename iterator_traits::value_type::second_type + , std::less::value_type::first_type>::type> + , Allocator>; + template -multimap(InputIterator, InputIterator, Compare const&) -> multimap::value_type::first_type>, typename std::iterator_traits::value_type::second_type, Compare>; +multimap(InputIterator, InputIterator, Compare const&) -> + multimap< typename dtl::remove_const::value_type::first_type>::type + , typename iterator_traits::value_type::second_type + , Compare>; + template -multimap(InputIterator, InputIterator, Compare const&, Allocator const&) -> multimap::value_type::first_type>, typename std::iterator_traits::value_type::second_type, Compare, Allocator>; +multimap(InputIterator, InputIterator, Compare const&, Allocator const&) -> + multimap< typename dtl::remove_const::value_type::first_type>::type + , typename iterator_traits::value_type::second_type + , Compare + , Allocator>; + template -multimap(ordered_range_t, InputIterator, InputIterator) -> multimap::value_type::first_type>, typename std::iterator_traits::value_type::second_type>; +multimap(ordered_range_t, InputIterator, InputIterator) -> + multimap< typename dtl::remove_const::value_type::first_type>::type + , typename iterator_traits::value_type::second_type>; + template -multimap(ordered_range_t, InputIterator, InputIterator, Allocator const&) -> multimap::value_type::first_type>, typename std::iterator_traits::value_type::second_type, std::less::value_type::first_type>>, Allocator>; +multimap(ordered_range_t, InputIterator, InputIterator, Allocator const&) -> + multimap< typename dtl::remove_const::value_type::first_type>::type + , typename iterator_traits::value_type::second_type + , std::less::value_type::first_type>::type> + , Allocator>; + template -multimap(ordered_range_t, InputIterator, InputIterator, Compare const&) -> multimap::value_type::first_type>, typename std::iterator_traits::value_type::second_type, Compare>; +multimap(ordered_range_t, InputIterator, InputIterator, Compare const&) -> + multimap< typename dtl::remove_const::value_type::first_type>::type + , typename iterator_traits::value_type::second_type + , Compare>; + template -multimap(ordered_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) -> multimap::value_type::first_type>, typename std::iterator_traits::value_type::second_type, Compare, Allocator>; +multimap(ordered_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) -> + multimap< typename dtl::remove_const::value_type::first_type>::type + , typename iterator_traits::value_type::second_type + , Compare + , Allocator>; + #endif #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED diff --git a/include/boost/container/pmr/synchronized_pool_resource.hpp b/include/boost/container/pmr/synchronized_pool_resource.hpp index e4d4dd5..516e6d2 100644 --- a/include/boost/container/pmr/synchronized_pool_resource.hpp +++ b/include/boost/container/pmr/synchronized_pool_resource.hpp @@ -20,6 +20,7 @@ #include #include #include +#include #include @@ -60,8 +61,8 @@ namespace pmr { class BOOST_CONTAINER_DECL synchronized_pool_resource : public memory_resource { - pool_resource m_pool_resource; - void *m_opaque_sync; + dtl::thread_mutex m_mut; + pool_resource m_pool_resource; public: diff --git a/include/boost/container/set.hpp b/include/boost/container/set.hpp index 5eda825..e300898 100644 --- a/include/boost/container/set.hpp +++ b/include/boost/container/set.hpp @@ -935,22 +935,39 @@ class set }; #if __cplusplus >= 201703L + template -set(InputIterator, InputIterator) -> set::value_type>; +set(InputIterator, InputIterator) -> + set::value_type>; + template -set(InputIterator, InputIterator, Allocator const&) -> set::value_type, std::less::value_type>, Allocator>; +set(InputIterator, InputIterator, Allocator const&) -> + set::value_type, std::less::value_type>, Allocator>; + template -set(InputIterator, InputIterator, Compare const&) -> set::value_type, Compare>; +set(InputIterator, InputIterator, Compare const&) -> + set::value_type, Compare>; + template -set(InputIterator, InputIterator, Compare const&, Allocator const&) -> set::value_type, Compare, Allocator>; +set(InputIterator, InputIterator, Compare const&, Allocator const&) -> + set::value_type, Compare, Allocator>; + template -set(ordered_unique_range_t, InputIterator, InputIterator) -> set::value_type>; +set(ordered_unique_range_t, InputIterator, InputIterator) -> + set::value_type>; + template -set(ordered_unique_range_t, InputIterator, InputIterator, Allocator const&) -> set::value_type, std::less::value_type>, Allocator>; +set(ordered_unique_range_t, InputIterator, InputIterator, Allocator const&) -> + set::value_type, std::less::value_type>, Allocator>; + template -set(ordered_unique_range_t, InputIterator, InputIterator, Compare const&) -> set::value_type, Compare>; +set(ordered_unique_range_t, InputIterator, InputIterator, Compare const&) -> + set::value_type, Compare>; + template -set(ordered_unique_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) -> set::value_type, Compare, Allocator>; +set(ordered_unique_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) -> + set::value_type, Compare, Allocator>; + #endif #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED @@ -1540,22 +1557,43 @@ class multiset }; #if __cplusplus >= 201703L + template -multiset(InputIterator, InputIterator) -> multiset::value_type>; +multiset(InputIterator, InputIterator) -> + multiset::value_type>; + template -multiset(InputIterator, InputIterator, Allocator const&) -> multiset::value_type, std::less::value_type>, Allocator>; +multiset(InputIterator, InputIterator, Allocator const&) -> + multiset< typename iterator_traits::value_type + , std::less::value_type> + , Allocator>; + template -multiset(InputIterator, InputIterator, Compare const&) -> multiset::value_type, Compare>; +multiset(InputIterator, InputIterator, Compare const&) -> + multiset::value_type, Compare>; + template -multiset(InputIterator, InputIterator, Compare const&, Allocator const&) -> multiset::value_type, Compare, Allocator>; +multiset(InputIterator, InputIterator, Compare const&, Allocator const&) -> + multiset::value_type, Compare, Allocator>; + template -multiset(ordered_range_t, InputIterator, InputIterator) -> multiset::value_type>; +multiset(ordered_range_t, InputIterator, InputIterator) -> + multiset::value_type>; + template -multiset(ordered_range_t, InputIterator, InputIterator, Allocator const&) -> multiset::value_type, std::less::value_type>, Allocator>; +multiset(ordered_range_t, InputIterator, InputIterator, Allocator const&) -> + multiset< typename iterator_traits::value_type + , std::less::value_type> + , Allocator>; + template -multiset(ordered_range_t, InputIterator, InputIterator, Compare const&) -> multiset::value_type, Compare>; +multiset(ordered_range_t, InputIterator, InputIterator, Compare const&) -> + multiset< typename iterator_traits::value_type, Compare>; + template -multiset(ordered_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) -> multiset::value_type, Compare, Allocator>; +multiset(ordered_range_t, InputIterator, InputIterator, Compare const&, Allocator const&) -> + multiset::value_type, Compare, Allocator>; + #endif #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED diff --git a/include/boost/container/slist.hpp b/include/boost/container/slist.hpp index be80939..2769070 100644 --- a/include/boost/container/slist.hpp +++ b/include/boost/container/slist.hpp @@ -1633,10 +1633,15 @@ class slist }; #if __cplusplus >= 201703L + template -slist(InpIt, InpIt) -> slist::value_type>; +slist(InpIt, InpIt) -> + slist::value_type>; + template -slist(InpIt, InpIt, Allocator const&) -> slist::value_type, Allocator>; +slist(InpIt, InpIt, Allocator const&) -> + slist::value_type, Allocator>; + #endif }} diff --git a/include/boost/container/stable_vector.hpp b/include/boost/container/stable_vector.hpp index 612b911..41f45df 100644 --- a/include/boost/container/stable_vector.hpp +++ b/include/boost/container/stable_vector.hpp @@ -2086,10 +2086,15 @@ class stable_vector }; #if __cplusplus >= 201703L + template -stable_vector(InputIterator, InputIterator) -> stable_vector::value_type>; +stable_vector(InputIterator, InputIterator) -> + stable_vector::value_type>; + template -stable_vector(InputIterator, InputIterator, Allocator const&) -> stable_vector::value_type, Allocator>; +stable_vector(InputIterator, InputIterator, Allocator const&) -> + stable_vector::value_type, Allocator>; + #endif #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED diff --git a/include/boost/container/string.hpp b/include/boost/container/string.hpp index a3db188..6c0cc96 100644 --- a/include/boost/container/string.hpp +++ b/include/boost/container/string.hpp @@ -2934,10 +2934,15 @@ class basic_string }; #if __cplusplus >= 201703L + template -basic_string(InputIterator, InputIterator) -> basic_string::value_type>; +basic_string(InputIterator, InputIterator) -> + basic_string::value_type>; + template -basic_string(InputIterator, InputIterator, Allocator const&) -> basic_string::value_type, Allocator>; +basic_string(InputIterator, InputIterator, Allocator const&) -> + basic_string::value_type, Allocator>; + #endif #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED diff --git a/include/boost/container/vector.hpp b/include/boost/container/vector.hpp index 5a14b73..ff9977a 100644 --- a/include/boost/container/vector.hpp +++ b/include/boost/container/vector.hpp @@ -3365,10 +3365,15 @@ class vector }; #if __cplusplus >= 201703L + template -vector(InputIterator, InputIterator) -> vector::value_type>; +vector(InputIterator, InputIterator) -> + vector::value_type>; + template -vector(InputIterator, InputIterator, Allocator const&) -> vector::value_type, Allocator>; +vector(InputIterator, InputIterator, Allocator const&) -> + vector::value_type, Allocator>; + #endif diff --git a/proj/vc7ide/container.vcproj b/proj/vc7ide/container.vcproj index de0ddfb..28db9cd 100644 --- a/proj/vc7ide/container.vcproj +++ b/proj/vc7ide/container.vcproj @@ -314,6 +314,9 @@ + + diff --git a/src/synchronized_pool_resource.cpp b/src/synchronized_pool_resource.cpp index b98bed4..0a725e9 100644 --- a/src/synchronized_pool_resource.cpp +++ b/src/synchronized_pool_resource.cpp @@ -11,31 +11,29 @@ #define BOOST_CONTAINER_SOURCE #include #include -#include +#include #include #include namespace { -using namespace boost::container; +using namespace boost::container::dtl; -class dlmalloc_sync_scoped_lock +class thread_mutex_lock { - void *m_sync; + thread_mutex &m_mut; public: - explicit dlmalloc_sync_scoped_lock(void *sync) - : m_sync(sync) + explicit thread_mutex_lock(thread_mutex &m) + : m_mut(m) { - if(!dlmalloc_sync_lock(m_sync)){ - throw_bad_alloc(); - } + m_mut.lock(); } - ~dlmalloc_sync_scoped_lock() + ~thread_mutex_lock() { - dlmalloc_sync_unlock(m_sync); + m_mut.unlock(); } }; @@ -46,32 +44,28 @@ namespace container { namespace pmr { synchronized_pool_resource::synchronized_pool_resource(const pool_options& opts, memory_resource* upstream) BOOST_NOEXCEPT - : m_pool_resource(opts, upstream), m_opaque_sync() + : m_mut(), m_pool_resource(opts, upstream) {} synchronized_pool_resource::synchronized_pool_resource() BOOST_NOEXCEPT - : m_pool_resource(), m_opaque_sync() + : m_mut(), m_pool_resource() {} synchronized_pool_resource::synchronized_pool_resource(memory_resource* upstream) BOOST_NOEXCEPT - : m_pool_resource(upstream), m_opaque_sync() + : m_mut(), m_pool_resource(upstream) {} synchronized_pool_resource::synchronized_pool_resource(const pool_options& opts) BOOST_NOEXCEPT - : m_pool_resource(opts), m_opaque_sync() + : m_mut(), m_pool_resource(opts) {} synchronized_pool_resource::~synchronized_pool_resource() //virtual -{ - if(m_opaque_sync) - dlmalloc_sync_destroy(m_opaque_sync); -} +{} void synchronized_pool_resource::release() { - if(m_opaque_sync){ //If there is no mutex, no allocation could be done - m_pool_resource.release(); - } + thread_mutex_lock lck(m_mut); (void)lck; + m_pool_resource.release(); } memory_resource* synchronized_pool_resource::upstream_resource() const @@ -82,19 +76,13 @@ pool_options synchronized_pool_resource::options() const void* synchronized_pool_resource::do_allocate(std::size_t bytes, std::size_t alignment) //virtual { - if(!m_opaque_sync){ //If there is no mutex, no allocation could be done - m_opaque_sync = dlmalloc_sync_create(); - if(!m_opaque_sync){ - throw_bad_alloc(); - } - } - dlmalloc_sync_scoped_lock lock(m_opaque_sync); (void)lock; + thread_mutex_lock lck(m_mut); (void)lck; return m_pool_resource.do_allocate(bytes, alignment); } void synchronized_pool_resource::do_deallocate(void* p, std::size_t bytes, std::size_t alignment) //virtual { - dlmalloc_sync_scoped_lock lock(m_opaque_sync); (void)lock; + thread_mutex_lock lck(m_mut); (void)lck; return m_pool_resource.do_deallocate(p, bytes, alignment); }