mirror of
https://github.com/boostorg/container.git
synced 2025-07-31 13:07:17 +02:00
FIxes #297 ("flat_map::try_emplace does not compile if allocator has construct")
This commit is contained in:
@@ -1421,6 +1421,13 @@ use [*Boost.Container]? There are several reasons for that:
|
||||
|
||||
[section:release_notes Release Notes]
|
||||
|
||||
[section:release_notes_boost_1_88_00 Boost 1.88 Release]
|
||||
|
||||
* Fixed bugs/issues:
|
||||
* [@https://github.com/boostorg/container/issues/297 GitHub #297: ['"flat_map::try_emplace does not compile if allocator has construct"]].
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:release_notes_boost_1_87_00 Boost 1.87 Release]
|
||||
|
||||
* Added [classref boost::container::stored_size stored_size] option to
|
||||
|
@@ -94,23 +94,6 @@ BOOST_CONTAINER_FORCEINLINE void construct_type(T *p, BOOST_FWD_REF(Args) ...arg
|
||||
::new((void*)p, boost_container_new_t()) T(::boost::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template < class Pair, class KeyType, class ... Args>
|
||||
typename dtl::enable_if< dtl::is_pair<Pair>, void >::type
|
||||
construct_type
|
||||
(Pair* p, try_emplace_t, BOOST_FWD_REF(KeyType) k, BOOST_FWD_REF(Args) ...args)
|
||||
{
|
||||
construct_type(dtl::addressof(p->first), ::boost::forward<KeyType>(k));
|
||||
BOOST_CONTAINER_TRY{
|
||||
construct_type(dtl::addressof(p->second), ::boost::forward<Args>(args)...);
|
||||
}
|
||||
BOOST_CONTAINER_CATCH(...) {
|
||||
typedef typename Pair::first_type first_type;
|
||||
dtl::addressof(p->first)->~first_type();
|
||||
BOOST_CONTAINER_RETHROW
|
||||
}
|
||||
BOOST_CONTAINER_CATCH_END
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define BOOST_CONTAINER_ALLOCATOR_TRAITS_CONSTRUCT_TYPEJ(N) \
|
||||
@@ -125,32 +108,12 @@ construct_type(T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
|
||||
BOOST_MOVE_ITERATE_0TO8(BOOST_CONTAINER_ALLOCATOR_TRAITS_CONSTRUCT_TYPEJ)
|
||||
#undef BOOST_CONTAINER_ALLOCATOR_TRAITS_CONSTRUCT_TYPEJ
|
||||
|
||||
#define BOOST_CONTAINER_ALLOCATOR_TRAITS_CONSTRUCT_TYPE(N) \
|
||||
template < class Pair, class KeyType BOOST_MOVE_I##N BOOST_MOVE_CLASS##N>\
|
||||
typename dtl::enable_if< dtl::is_pair<Pair>, void >::type construct_type\
|
||||
(Pair* p, try_emplace_t, BOOST_FWD_REF(KeyType) k BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
|
||||
{\
|
||||
construct_type(dtl::addressof(p->first), ::boost::forward<KeyType>(k));\
|
||||
BOOST_CONTAINER_TRY{\
|
||||
construct_type(dtl::addressof(p->second) BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
|
||||
}\
|
||||
BOOST_CONTAINER_CATCH(...) {\
|
||||
typedef typename Pair::first_type first_type;\
|
||||
dtl::addressof(p->first)->~first_type();\
|
||||
BOOST_CONTAINER_RETHROW\
|
||||
}\
|
||||
BOOST_CONTAINER_CATCH_END\
|
||||
}\
|
||||
//
|
||||
BOOST_MOVE_ITERATE_0TO8(BOOST_CONTAINER_ALLOCATOR_TRAITS_CONSTRUCT_TYPE)
|
||||
#undef BOOST_CONTAINER_ALLOCATOR_TRAITS_CONSTRUCT_TYPE
|
||||
|
||||
#endif
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
typename dtl::enable_if<dtl::is_pair<T>, void >::type
|
||||
construct_type(T* p)
|
||||
construct_type(T* p)
|
||||
{
|
||||
dtl::construct_type(dtl::addressof(p->first));
|
||||
BOOST_CONTAINER_TRY{
|
||||
@@ -164,7 +127,6 @@ construct_type(T* p)
|
||||
BOOST_CONTAINER_CATCH_END
|
||||
}
|
||||
|
||||
|
||||
template<class T, class U>
|
||||
inline
|
||||
typename dtl::enable_if_c
|
||||
@@ -509,6 +471,25 @@ struct allocator_traits
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
|
||||
template < class Pair, class KeyType, class ... Args>
|
||||
static typename dtl::enable_if< dtl::is_pair<Pair>, void >::type construct
|
||||
(Allocator & a, Pair* p, try_emplace_t, BOOST_FWD_REF(KeyType) k, BOOST_FWD_REF(Args) ...args)
|
||||
{
|
||||
allocator_traits::construct(a, dtl::addressof(p->first), ::boost::forward<KeyType>(k));
|
||||
BOOST_CONTAINER_TRY{
|
||||
allocator_traits::construct(a, dtl::addressof(p->second), ::boost::forward<Args>(args)...);
|
||||
}
|
||||
BOOST_CONTAINER_CATCH(...) {
|
||||
typedef typename Pair::first_type first_type;
|
||||
dtl::addressof(p->first)->~first_type();
|
||||
BOOST_CONTAINER_RETHROW
|
||||
}
|
||||
BOOST_CONTAINER_CATCH_END
|
||||
}
|
||||
#endif
|
||||
|
||||
//! <b>Returns</b>: <code>a.storage_is_unpropagable(p)</code> if is_partially_propagable::value is true; otherwise,
|
||||
//! <code>false</code>.
|
||||
inline static bool storage_is_unpropagable(const Allocator &a, pointer p) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
@@ -582,6 +563,22 @@ struct allocator_traits
|
||||
inline static void priv_construct(dtl::true_type, Allocator &a, T *p, BOOST_FWD_REF(Args) ...args)
|
||||
{ a.construct( p, ::boost::forward<Args>(args)...); }
|
||||
|
||||
template<class T, class KeyType, class ...Args>
|
||||
inline static typename dtl::enable_if< dtl::is_pair<T>, void >::type
|
||||
priv_construct(dtl::true_type, Allocator &a, T *p, try_emplace_t, BOOST_FWD_REF(KeyType) k, BOOST_FWD_REF(Args) ...args)
|
||||
{
|
||||
a.construct(dtl::addressof(p->first), ::boost::forward<KeyType>(k));
|
||||
BOOST_CONTAINER_TRY{
|
||||
a.construct(dtl::addressof(p->second), ::boost::forward<Args>(args)...);
|
||||
}
|
||||
BOOST_CONTAINER_CATCH(...) {
|
||||
typedef typename T::first_type first_type;
|
||||
dtl::addressof(p->first)->~first_type();
|
||||
BOOST_CONTAINER_RETHROW
|
||||
}
|
||||
BOOST_CONTAINER_CATCH_END
|
||||
}
|
||||
|
||||
template<class T, class ...Args>
|
||||
inline static void priv_construct(dtl::false_type, Allocator &, T *p, BOOST_FWD_REF(Args) ...args)
|
||||
{ dtl::construct_type(p, ::boost::forward<Args>(args)...); }
|
||||
@@ -600,6 +597,28 @@ struct allocator_traits
|
||||
dtl::bool_<value> flag;\
|
||||
(priv_construct)(flag, a, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
|
||||
}\
|
||||
\
|
||||
//
|
||||
BOOST_MOVE_ITERATE_0TO8(BOOST_CONTAINER_ALLOCATOR_TRAITS_CONSTRUCT_IMPL)
|
||||
#undef BOOST_CONTAINER_ALLOCATOR_TRAITS_CONSTRUCT_IMPL
|
||||
|
||||
#define BOOST_CONTAINER_ALLOCATOR_TRAITS_CONSTRUCT_IMPL(N) \
|
||||
template<class T, class KeyType BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
|
||||
inline static typename dtl::enable_if< dtl::is_pair<T>, void >::type\
|
||||
construct(Allocator &a, T *p, try_emplace_t, BOOST_FWD_REF(KeyType) k BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
|
||||
{\
|
||||
allocator_traits::construct(a, dtl::addressof(p->first), ::boost::forward<KeyType>(k));\
|
||||
BOOST_CONTAINER_TRY{\
|
||||
allocator_traits::construct(a, dtl::addressof(p->second) BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
|
||||
}\
|
||||
BOOST_CONTAINER_CATCH(...) {\
|
||||
typedef typename T::first_type first_type;\
|
||||
dtl::addressof(p->first)->~first_type();\
|
||||
BOOST_CONTAINER_RETHROW\
|
||||
}\
|
||||
BOOST_CONTAINER_CATCH_END\
|
||||
}\
|
||||
\
|
||||
//
|
||||
BOOST_MOVE_ITERATE_0TO8(BOOST_CONTAINER_ALLOCATOR_TRAITS_CONSTRUCT_IMPL)
|
||||
#undef BOOST_CONTAINER_ALLOCATOR_TRAITS_CONSTRUCT_IMPL
|
||||
|
@@ -11,6 +11,7 @@
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
#include <boost/container/detail/type_traits.hpp>
|
||||
#include <boost/container/detail/function_detector.hpp>
|
||||
#include <boost/container/detail/pair.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include <memory>
|
||||
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
@@ -420,6 +421,20 @@ int main()
|
||||
SAllocTraits::construct(s_alloc, &c, 0, 1, 2);
|
||||
BOOST_TEST(!c.copymoveconstructed() && !c.moved());
|
||||
}
|
||||
|
||||
{
|
||||
boost::container::dtl::pair<copymovable, copymovable> cp;
|
||||
copymovable k(99, 100, 101);
|
||||
SAllocTraits::construct(s_alloc, &cp, boost::container::try_emplace_t(), boost::move(k), 1, 2, 3);
|
||||
BOOST_TEST(cp.first.moved() && !cp.second.copymoveconstructed() && !cp.second.moved());
|
||||
}
|
||||
{
|
||||
boost::container::dtl::pair<copymovable, copymovable> cp;
|
||||
copymovable k(99, 100, 101);
|
||||
CAllocTraits::construct(c_alloc, &cp, boost::container::try_emplace_t(), boost::move(k), 1, 2, 3);
|
||||
BOOST_TEST(cp.first.moved() && !cp.second.copymoveconstructed() && !cp.second.moved());
|
||||
}
|
||||
|
||||
//storage_is_unpropagable
|
||||
{
|
||||
SAlloc s_alloc2;
|
||||
|
Reference in New Issue
Block a user