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
diff --git a/include/unordered_map b/include/unordered_map
index 15243f6..cb2ab42 100644
--- a/include/unordered_map
+++ b/include/unordered_map
@@ -786,42 +786,15 @@
     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 @@
 
 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 @@
 #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 @@
     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 @@
     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 @@
     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 @@
 #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 @@
     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;