[libcxx] r258575 - unordered_map: Reuse insert logic in emplace when possible, NFC

Duncan P. N. Exon Smith via cfe-commits cfe-commits at lists.llvm.org
Fri Jan 22 14:48:02 PST 2016


Author: dexonsmith
Date: Fri Jan 22 16:48:02 2016
New Revision: 258575

URL: http://llvm.org/viewvc/llvm-project?rev=258575&view=rev
Log:
unordered_map: Reuse insert logic in emplace when possible, NFC

An upcoming commit will add an optimization to insert() that avoids
unnecessary mallocs when we can safely extract the key type.  This
commit shares code between emplace() and insert():
- if emplace() is given a single argument, and
- value_type is constructible from that argument
so that we have a single code path for the two.

I also updated the debug version of emplace_hint() to defer to
emplace(), like the non-debug version does.

In both cases, there should be NFC here.

Modified:
    libcxx/trunk/include/unordered_map

Modified: libcxx/trunk/include/unordered_map
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/unordered_map?rev=258575&r1=258574&r2=258575&view=diff
==============================================================================
--- libcxx/trunk/include/unordered_map (original)
+++ libcxx/trunk/include/unordered_map Fri Jan 22 16:48:02 2016
@@ -922,8 +922,32 @@ public:
 #ifndef _LIBCPP_HAS_NO_VARIADICS
 
     template <class... _Args>
-        pair<iterator, bool> emplace(_Args&&... __args);
+    pair<iterator, bool> emplace(_Args&&... __args)
+        {return __emplace_dispatch(std::forward<_Args>(__args)...);}
 
+private:
+    template <class _Arg>
+    pair<iterator, bool> __emplace_dispatch(_Arg&& __arg)
+        {
+            typedef is_constructible<value_type, _Arg> __constructible;
+            return __emplace_insert_if_constructible(std::forward<_Arg>(__arg),
+                                                     __constructible());
+        }
+    template <class _Arg1, class... _Args>
+    pair<iterator, bool> __emplace_dispatch(_Arg1&& __arg1, _Args&&... __args)
+        {return __emplace_impl(std::forward<_Arg1>(__arg1), std::forward<_Args>(__args)...);}
+
+    template <class _Arg>
+    pair<iterator, bool> __emplace_insert_if_constructible(_Arg&& __arg, false_type)
+        {return __emplace_impl(std::forward<_Arg>(__arg));}
+    template <class _Arg>
+    pair<iterator, bool> __emplace_insert_if_constructible(_Arg&& __arg, true_type)
+        {return insert(std::forward<_Arg>(__arg));}
+
+    template <class... _Args>
+    pair<iterator, bool> __emplace_impl(_Args&&... __args);
+
+public:
     template <class... _Args>
         _LIBCPP_INLINE_VISIBILITY
 #if _LIBCPP_DEBUG_LEVEL >= 2
@@ -932,7 +956,7 @@ public:
             _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
                 "unordered_map::emplace_hint(const_iterator, args...) called with an iterator not"
                 " referring to this unordered_map");
-            return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...).first;
+            return emplace(_VSTD::forward<_Args>(__args)...).first;
         }
 #else
         iterator emplace_hint(const_iterator, _Args&&... __args)
@@ -1477,7 +1501,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _
 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)
+unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__emplace_impl(_Args&&... __args)
 {
     __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
     pair<iterator, bool> __r = __table_.__node_insert_unique(__h.get());




More information about the cfe-commits mailing list