The rules for emplace in map, multimap, unordered_map and unordered_multimap changed a while back and I'm just now updating to these new rules. In a nutshell, you've got to know you're emplacing to a pair and use one of pair's constructors. I made one extension: If you want to emplace the key and default construct the mapped_type, you can just emplace(key), as opposed to emplace(piecewise_construct, forward_as_tuple(key), forward_as_tuple()).

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@157503 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Howard Hinnant
2012-05-25 22:04:21 +00:00
parent 3e3e5ebc72
commit 635ce1d127
11 changed files with 291 additions and 264 deletions

View File

@@ -786,42 +786,15 @@ public:
const_iterator cend() const _NOEXCEPT {return __table_.end();}
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
_LIBCPP_INLINE_VISIBILITY
pair<iterator, bool> emplace()
{return __table_.__emplace_unique();}
template <class _A0,
class = typename enable_if<is_constructible<value_type, _A0>::value>::type>
_LIBCPP_INLINE_VISIBILITY
pair<iterator, bool> emplace(_A0&& __a0)
{return __table_.__emplace_unique(_VSTD::forward<_A0>(__a0));}
#ifndef _LIBCPP_HAS_NO_VARIADICS
template <class _A0, class... _Args,
class = typename enable_if<is_constructible<key_type, _A0>::value>::type>
pair<iterator, bool> emplace(_A0&& __a0, _Args&&... __args);
template <class... _Args>
pair<iterator, bool> emplace(_Args&&... __args);
#endif // _LIBCPP_HAS_NO_VARIADICS
_LIBCPP_INLINE_VISIBILITY
iterator emplace_hint(const_iterator)
{return __table_.__emplace_unique().first;}
template <class _A0,
class = typename enable_if<is_constructible<value_type, _A0>::value>::type>
template <class... _Args>
_LIBCPP_INLINE_VISIBILITY
iterator emplace_hint(const_iterator, _A0&& __a0)
{return __table_.__emplace_unique(_VSTD::forward<_A0>(__a0)).first;}
#ifndef _LIBCPP_HAS_NO_VARIADICS
template <class _A0, class... _Args,
class = typename enable_if<is_constructible<key_type, _A0>::value>::type>
_LIBCPP_INLINE_VISIBILITY
iterator emplace_hint(const_iterator, _A0&& __a0, _Args&&... __args)
{return emplace(_VSTD::forward<_A0>(__a0),
_VSTD::forward<_Args>(__args)...).first;}
iterator emplace_hint(const_iterator, _Args&&... __args)
{return emplace(_VSTD::forward<_Args>(__args)...).first;}
#endif // _LIBCPP_HAS_NO_VARIADICS
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
_LIBCPP_INLINE_VISIBILITY
@@ -932,14 +905,25 @@ public:
private:
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
__node_holder __construct_node();
template <class _A0>
typename enable_if
<
is_constructible<value_type, _A0>::value,
__node_holder
>::type
__construct_node(_A0&& __a0);
template <class _A0>
typename enable_if
<
is_constructible<key_type, _A0>::value,
__node_holder
>::type
__construct_node(_A0&& __a0);
#ifndef _LIBCPP_HAS_NO_VARIADICS
template <class _A0, class... _Args,
class = typename enable_if<is_constructible<key_type, _A0>::value>::type>
__node_holder __construct_node(_A0&& __a0, _Args&&... __args);
template <class _A0, class _A1, class ..._Args>
__node_holder __construct_node(_A0&& __a0, _A1&& __a1, _Args&& ...__args);
#endif // _LIBCPP_HAS_NO_VARIADICS
template <class _A0,
class = typename enable_if<is_constructible<value_type, _A0>::value>::type>
__node_holder __construct_node(_A0&& __a0);
#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
__node_holder __construct_node(const key_type& __k);
#endif
@@ -1106,34 +1090,26 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=(
#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
#ifndef _LIBCPP_HAS_NO_VARIADICS
template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
template <class _A0, class... _Args,
class // = typename enable_if<is_constructible<key_type, _A0>::value>::type
>
typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder
unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(_A0&& __a0,
_Args&&... __args)
unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node()
{
__node_allocator& __na = __table_.__node_alloc();
__node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
__node_traits::construct(__na, _VSTD::addressof(__h->__value_.first),
_VSTD::forward<_A0>(__a0));
__node_traits::construct(__na, _VSTD::addressof(__h->__value_));
__h.get_deleter().__first_constructed = true;
__node_traits::construct(__na, _VSTD::addressof(__h->__value_.second),
_VSTD::forward<_Args>(__args)...);
__h.get_deleter().__second_constructed = true;
return __h;
}
#endif // _LIBCPP_HAS_NO_VARIADICS
template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
template <class _A0,
class // = typename enable_if<is_constructible<value_type, _A0>::value>::type
>
typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder
template <class _A0>
typename enable_if
<
is_constructible<pair<const _Key, _Tp>, _A0>::value,
typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder
>::type
unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(_A0&& __a0)
{
__node_allocator& __na = __table_.__node_alloc();
@@ -1145,17 +1121,50 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(_A0&& __a0)
return __h;
}
template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
template <class _A0>
typename enable_if
<
is_constructible<_Key, _A0>::value,
typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder
>::type
unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(_A0&& __a0)
{
__node_allocator& __na = __table_.__node_alloc();
__node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
__node_traits::construct(__na, _VSTD::addressof(__h->__value_.first),
_VSTD::forward<_A0>(__a0));
__h.get_deleter().__first_constructed = true;
__node_traits::construct(__na, _VSTD::addressof(__h->__value_.second));
__h.get_deleter().__second_constructed = true;
return __h;
}
#ifndef _LIBCPP_HAS_NO_VARIADICS
template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
template <class _A0, class... _Args,
class // = typename enable_if<is_constructible<key_type, _A0>::value>::type
>
pair<typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::iterator, bool>
unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::emplace(_A0&& __a0, _Args&&... __args)
template <class _A0, class _A1, class ..._Args>
typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder
unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(_A0&& __a0,
_A1&& __a1,
_Args&&... __args)
{
__node_holder __h = __construct_node(_VSTD::forward<_A0>(__a0),
_VSTD::forward<_Args>(__args)...);
__node_allocator& __na = __table_.__node_alloc();
__node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
__node_traits::construct(__na, _VSTD::addressof(__h->__value_),
_VSTD::forward<_A0>(__a0), _VSTD::forward<_A1>(__a1),
_VSTD::forward<_Args>(__args)...);
__h.get_deleter().__first_constructed = true;
__h.get_deleter().__second_constructed = true;
return __h;
}
template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
template <class... _Args>
pair<typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::iterator, bool>
unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::emplace(_Args&&... __args)
{
__node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
pair<iterator, bool> __r = __table_.__node_insert_unique(__h.get());
if (__r.second)
__h.release();
@@ -1409,39 +1418,13 @@ public:
const_iterator cend() const _NOEXCEPT {return __table_.end();}
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
_LIBCPP_INLINE_VISIBILITY
iterator emplace()
{return __table_.__emplace_multi();}
template <class _A0,
class = typename enable_if<is_constructible<value_type, _A0>::value>::type>
_LIBCPP_INLINE_VISIBILITY
iterator emplace(_A0&& __a0)
{return __table_.__emplace_multi(_VSTD::forward<_A0>(__a0));}
#ifndef _LIBCPP_HAS_NO_VARIADICS
template <class _A0, class... _Args,
class = typename enable_if<is_constructible<key_type, _A0>::value>::type>
iterator emplace(_A0&& __a0, _Args&&... __args);
template <class... _Args>
iterator emplace(_Args&&... __args);
#endif // _LIBCPP_HAS_NO_VARIADICS
_LIBCPP_INLINE_VISIBILITY
iterator emplace_hint(const_iterator __p)
{return __table_.__emplace_hint_multi(__p.__i_);}
template <class _A0,
class = typename enable_if<is_constructible<value_type, _A0>::value>::type>
_LIBCPP_INLINE_VISIBILITY
iterator emplace_hint(const_iterator __p, _A0&& __a0)
{return __table_.__emplace_hint_multi(__p.__i_, _VSTD::forward<_A0>(__a0));}
#ifndef _LIBCPP_HAS_NO_VARIADICS
template <class _A0, class... _Args,
class = typename enable_if<is_constructible<key_type, _A0>::value>::type>
iterator emplace_hint(const_iterator __p, _A0&& __a0, _Args&&... __args);
template <class... _Args>
iterator emplace_hint(const_iterator __p, _Args&&... __args);
#endif // _LIBCPP_HAS_NO_VARIADICS
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
_LIBCPP_INLINE_VISIBILITY
@@ -1543,14 +1526,27 @@ public:
void reserve(size_type __n) {__table_.reserve(__n);}
private:
#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
template <class _A0, class... _Args,
class = typename enable_if<is_constructible<key_type, _A0>::value>::type>
__node_holder __construct_node(_A0&& __a0, _Args&&... __args);
template <class _A0,
class = typename enable_if<is_constructible<value_type, _A0>::value>::type>
__node_holder __construct_node(_A0&& __a0);
#endif // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
__node_holder __construct_node();
template <class _A0>
typename enable_if
<
is_constructible<value_type, _A0>::value,
__node_holder
>::type
__construct_node(_A0&& __a0);
template <class _A0>
typename enable_if
<
is_constructible<key_type, _A0>::value,
__node_holder
>::type
__construct_node(_A0&& __a0);
#ifndef _LIBCPP_HAS_NO_VARIADICS
template <class _A0, class _A1, class ..._Args>
__node_holder __construct_node(_A0&& __a0, _A1&& __a1, _Args&& ...__args);
#endif // _LIBCPP_HAS_NO_VARIADICS
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
};
template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
@@ -1716,34 +1712,26 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=(
#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
#ifndef _LIBCPP_HAS_NO_VARIADICS
template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
template <class _A0, class... _Args,
class // = typename enable_if<is_constructible<key_type, _A0>::value>::type
>
typename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder
unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(
_A0&& __a0, _Args&&... __args)
unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node()
{
__node_allocator& __na = __table_.__node_alloc();
__node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
__node_traits::construct(__na, _VSTD::addressof(__h->__value_.first),
_VSTD::forward<_A0>(__a0));
__node_traits::construct(__na, _VSTD::addressof(__h->__value_));
__h.get_deleter().__first_constructed = true;
__node_traits::construct(__na, _VSTD::addressof(__h->__value_.second),
_VSTD::forward<_Args>(__args)...);
__h.get_deleter().__second_constructed = true;
return __h;
}
#endif // _LIBCPP_HAS_NO_VARIADICS
template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
template <class _A0,
class // = typename enable_if<is_constructible<value_type, _A0>::value>::type
>
typename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder
template <class _A0>
typename enable_if
<
is_constructible<pair<const _Key, _Tp>, _A0>::value,
typename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder
>::type
unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(_A0&& __a0)
{
__node_allocator& __na = __table_.__node_alloc();
@@ -1755,32 +1743,61 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(_A0&& __a0
return __h;
}
template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
template <class _A0>
typename enable_if
<
is_constructible<_Key, _A0>::value,
typename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder
>::type
unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(_A0&& __a0)
{
__node_allocator& __na = __table_.__node_alloc();
__node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
__node_traits::construct(__na, _VSTD::addressof(__h->__value_.first),
_VSTD::forward<_A0>(__a0));
__h.get_deleter().__first_constructed = true;
__node_traits::construct(__na, _VSTD::addressof(__h->__value_.second));
__h.get_deleter().__second_constructed = true;
return __h;
}
#ifndef _LIBCPP_HAS_NO_VARIADICS
template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
template <class _A0, class... _Args,
class // = typename enable_if<is_constructible<key_type, _A0>::value>::type
>
typename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::iterator
unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::emplace(_A0&& __a0, _Args&&... __args)
template <class _A0, class _A1, class ..._Args>
typename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder
unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(
_A0&& __a0, _A1&& __a1, _Args&&... __args)
{
__node_holder __h = __construct_node(_VSTD::forward<_A0>(__a0),
_VSTD::forward<_Args>(__args)...);
__node_allocator& __na = __table_.__node_alloc();
__node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
__node_traits::construct(__na, _VSTD::addressof(__h->__value_),
_VSTD::forward<_A0>(__a0), _VSTD::forward<_A1>(__a1),
_VSTD::forward<_Args>(__args)...);
__h.get_deleter().__first_constructed = true;
__h.get_deleter().__second_constructed = true;
return __h;
}
template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
template <class... _Args>
typename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::iterator
unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::emplace(_Args&&... __args)
{
__node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
iterator __r = __table_.__node_insert_multi(__h.get());
__h.release();
return __r;
}
template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
template <class _A0, class... _Args,
class // = typename enable_if<is_constructible<key_type, _A0>::value>::type
>
template <class... _Args>
typename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::iterator
unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::emplace_hint(
const_iterator __p, _A0&& __a0, _Args&&... __args)
const_iterator __p, _Args&&... __args)
{
__node_holder __h = __construct_node(_VSTD::forward<_A0>(__a0),
_VSTD::forward<_Args>(__args)...);
__node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
iterator __r = __table_.__node_insert_multi(__p.__i_, __h.get());
__h.release();
return __r;