diff --git a/doc/container.qbk b/doc/container.qbk index 9fc605e..aa43fe7 100644 --- a/doc/container.qbk +++ b/doc/container.qbk @@ -549,7 +549,7 @@ shortly after new elements are added to the container. [*Boost.Container] offers two new members for `vector`, `static_vector` and `stable_vector`: `explicit container::container(size_type n, default_init_t)` and -`explicit container::resize(size_type n, default_init_t)`, where new elements are constructed +`container::resize(size_type n, default_init_t)`, where new elements are constructed using [@http://en.cppreference.com/w/cpp/language/default_initialization default initialization]. [endsect] @@ -1213,6 +1213,14 @@ use [*Boost.Container]? There are several reasons for that: [section:release_notes Release Notes] + +[section:release_notes_boost_1_64_00 Boost 1.64 Release] + +* Fixed bugs: + * [@https://svn.boost.org/trac/boost/ticket/12749 Trac #12749 : ['"container::pmr::polymorphic_allocator compilation error"]]. + +[endsect] + [section:release_notes_boost_1_63_00 Boost 1.63 Release] * Fixed bugs: diff --git a/include/boost/container/detail/dispatch_uses_allocator.hpp b/include/boost/container/detail/dispatch_uses_allocator.hpp index fdf203c..946fdf6 100644 --- a/include/boost/container/detail/dispatch_uses_allocator.hpp +++ b/include/boost/container/detail/dispatch_uses_allocator.hpp @@ -287,7 +287,7 @@ template< typename ConstructAlloc, typename ArgAlloc, class Pair \ , template class BoostTuple \ BOOST_MOVE_I_IF(BOOST_MOVE_OR(N,M)) BOOST_MOVE_CLASS##N BOOST_MOVE_I_IF(BOOST_MOVE_AND(N,M)) BOOST_MOVE_CLASSQ##M > \ typename container_detail::enable_if< container_detail::is_pair >::type\ - dispatch_uses_allocator( ConstructAlloc & construct_alloc, ArgAlloc & arg_alloc, Pair* pair, piecewise_construct_t\ + dispatch_uses_allocator( ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* pair, piecewise_construct_t\ , BoostTuple p\ , BoostTuple q)\ {\ @@ -313,7 +313,7 @@ BOOST_MOVE_ITER2D_0TOMAX(9, BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_BO template< typename ConstructAlloc, typename ArgAlloc, class Pair , template class Tuple, class... Args1, class... Args2, size_t... Indexes1, size_t... Indexes2> - void dispatch_uses_allocator_index( ConstructAlloc & construct_alloc, ArgAlloc & arg_alloc, Pair* pair + void dispatch_uses_allocator_index( ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* pair , Tuple& t1, Tuple& t2, index_tuple, index_tuple) { (void)t1; (void)t2; @@ -331,7 +331,7 @@ BOOST_MOVE_ITER2D_0TOMAX(9, BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_BO template< typename ConstructAlloc, typename ArgAlloc, class Pair , template class Tuple, class... Args1, class... Args2> typename container_detail::enable_if< container_detail::is_pair >::type - dispatch_uses_allocator( ConstructAlloc & construct_alloc, ArgAlloc & arg_alloc, Pair* pair, piecewise_construct_t + dispatch_uses_allocator( ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* pair, piecewise_construct_t , Tuple t1, Tuple t2) { (dispatch_uses_allocator_index)( construct_alloc, arg_alloc, pair, t1, t2 @@ -347,7 +347,7 @@ BOOST_MOVE_ITER2D_0TOMAX(9, BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_BO , template class StdTuple\ BOOST_MOVE_I_IF(BOOST_MOVE_OR(N,M)) BOOST_MOVE_CLASS##N BOOST_MOVE_I_IF(BOOST_MOVE_AND(N,M)) BOOST_MOVE_CLASSQ##M > \ typename container_detail::enable_if< container_detail::is_pair >::type\ - dispatch_uses_allocator(ConstructAlloc & construct_alloc, ArgAlloc & arg_alloc, Pair* pair, piecewise_construct_t\ + dispatch_uses_allocator(ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* pair, piecewise_construct_t\ , StdTuple p\ , StdTuple q)\ {\ @@ -382,7 +382,7 @@ BOOST_MOVE_ITER2D_0TOMAX(9, BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_BO BOOST_MOVE_I_IF(BOOST_MOVE_OR(N,M)) BOOST_MOVE_CLASS##N BOOST_MOVE_I_IF(BOOST_MOVE_AND(N,M)) BOOST_MOVE_CLASSQ##M > \ typename container_detail::enable_if< container_detail::is_pair >::type\ dispatch_uses_allocator\ - ( ConstructAlloc & construct_alloc, ArgAlloc & arg_alloc, Pair* pair, piecewise_construct_t\ + ( ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* pair, piecewise_construct_t\ , StdTuple p\ , StdTuple q)\ {\ @@ -406,6 +406,52 @@ BOOST_MOVE_ITER2D_0TOMAX(9, BOOST_DISPATCH_USES_ALLOCATOR_PIECEWISE_CONSTRUCT_BO #endif //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +template < typename ConstructAlloc + , typename ArgAlloc + , class Pair, class KeyType, class ... Args> +typename container_detail::enable_if< container_detail::is_pair, void >::type + dispatch_uses_allocator + (ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* p, try_emplace_t, BOOST_FWD_REF(KeyType) k, BOOST_FWD_REF(Args) ...args) +{ + (dispatch_uses_allocator)(construct_alloc, arg_alloc, container_detail::addressof(p->first), ::boost::forward(k)); + BOOST_TRY{ + (dispatch_uses_allocator)(construct_alloc, arg_alloc, container_detail::addressof(p->second), ::boost::forward(args)...); + } + BOOST_CATCH(...) { + allocator_traits::destroy(construct_alloc, container_detail::addressof(p->first)); + BOOST_RETHROW + } + BOOST_CATCH_END +} + +#else + +#define BOOST_CONTAINER_DISPATCH_USES_ALLOCATOR_PAIR_TRY_EMPLACE_CODE(N) \ + template \ + inline typename container_detail::enable_if\ + < container_detail::is_pair, void >::type\ + dispatch_uses_allocator\ + (ConstructAlloc &construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, Pair* p, try_emplace_t, \ + BOOST_FWD_REF(KeyType) k BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ + {\ + (dispatch_uses_allocator)(construct_alloc, arg_alloc, container_detail::addressof(p->first), ::boost::forward(k));\ + BOOST_TRY{\ + (dispatch_uses_allocator)(construct_alloc, arg_alloc, container_detail::addressof(p->second) BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ + }\ + BOOST_CATCH(...) {\ + allocator_traits::destroy(construct_alloc, container_detail::addressof(p->first));\ + BOOST_RETHROW\ + }\ + BOOST_CATCH_END\ + }\ +// +BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_DISPATCH_USES_ALLOCATOR_PAIR_TRY_EMPLACE_CODE) +#undef BOOST_CONTAINER_DISPATCH_USES_ALLOCATOR_PAIR_TRY_EMPLACE_CODE + +#endif //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + } //namespace container_detail }} // namespace boost { namespace container { diff --git a/test/scoped_allocator_adaptor_test.cpp b/test/scoped_allocator_adaptor_test.cpp index d21afa4..51d6ee1 100644 --- a/test/scoped_allocator_adaptor_test.cpp +++ b/test/scoped_allocator_adaptor_test.cpp @@ -1331,6 +1331,44 @@ int main() dummy.~MarkTypePair(); } #endif //BOOST_CONTAINER_PAIR_TEST_HAS_HEADER_TUPLE + + //Check construction with try_emplace_t 0/1 arguments for each pair + { + typedef ::allocator_argument_tester MarkType; + typedef pair MarkTypePair; + MarkTypePair dummy; + dummy.~MarkTypePair(); + s0i.construct(&dummy, try_emplace_t(), 5, 1); + BOOST_TEST(dummy.first.construction_type == NotUsesAllocator); + BOOST_TEST(dummy.second.construction_type == NotUsesAllocator); + BOOST_TEST(dummy.first.value == 5); + BOOST_TEST(dummy.second.value == 1); + dummy.~MarkTypePair(); + } + { + typedef ::allocator_argument_tester MarkType; + typedef pair MarkTypePair; + MarkTypePair dummy; + dummy.~MarkTypePair(); + s0i.construct(&dummy, try_emplace_t(), 6); + BOOST_TEST(dummy.first.construction_type == ConstructibleSuffix); + BOOST_TEST(dummy.second.construction_type == ConstructibleSuffix); + BOOST_TEST(dummy.first.value == 6); + BOOST_TEST(dummy.second.value == 0); + dummy.~MarkTypePair(); + } + { + typedef ::allocator_argument_tester MarkType; + typedef pair MarkTypePair; + MarkTypePair dummy; + dummy.~MarkTypePair(); + s0i.construct(&dummy, try_emplace_t(), 7, 2); + BOOST_TEST(dummy.first.construction_type == ConstructiblePrefix); + BOOST_TEST(dummy.second.construction_type == ConstructiblePrefix); + BOOST_TEST(dummy.first.value == 7); + BOOST_TEST(dummy.second.value == 2); + dummy.~MarkTypePair(); + } } }