<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[173801] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/173801">173801</a></dd>
<dt>Author</dt> <dd>weinig@apple.com</dd>
<dt>Date</dt> <dd>2014-09-21 17:24:44 -0700 (Sun, 21 Sep 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Make possible HashSet&lt;std::unique_ptr&lt;&gt;&gt;
https://bugs.webkit.org/show_bug.cgi?id=136166

Reviewed by Darin Adler.

Source/WTF:

* wtf/GetPtr.h:
(WTF::getPtr):
(WTF::GetPtrHelper&lt;std::unique_ptr&lt;T&gt;&gt;::getPtr):
Make specializing GetPtrHelper a bit cleaner (you don't have to put 
IsSmartPtr&lt;T&gt;::value everywhere any more) and add specializations for
std::unique_ptr.

* wtf/HashFunctions.h:
(WTF::PtrHash&lt;std::unique_ptr&lt;P&gt;&gt;):
Add specialization for PtrHash for std::unique_ptr and set it as the DefaultHash
for it as well.

* wtf/HashMap.h:    
* wtf/HashSet.h:
Add overloads of find(), contains(), remove(), take() (and get() for HashMap) for &quot;smart pointers&quot; that
take the raw pointer type as the parameter. These use SFINAE to make themselves only available
when the IsSmartPtr&lt;KeyType&gt;::value is true. 

* wtf/HashTraits.h:
Override constructDeletedValue() and isDeletedValue() in the std::unique_ptr specialization
since the default implementation depends on the type having a constructor that takes a HashTableDeletedValue
and function named isHashTableDeletedValue().

* wtf/OwnPtr.h:
(WTF::OwnPtr::OwnPtr):
(WTF::OwnPtr::isHashTableDeletedValue):
(WTF::OwnPtr::hashTableDeletedValue):
Add HashTableDeletedValue constructor/functions to allow the constructDeletedValue() and isDeletedValue()
hash traits to work.

(WTF::PtrHash&lt;OwnPtr&lt;P&gt;&gt;::hash):
(WTF::PtrHash&lt;OwnPtr&lt;P&gt;&gt;::equal):
Add specialization for PtrHash for OwnPtr and set it as the DefaultHash
for it as well.

* wtf/Ref.h:
Update for the less verbose GetPtrHelper specialization.

Tools:

* TestWebKitAPI/Tests/WTF/CopyMoveCounter.h: Removed.
* TestWebKitAPI/Counters.cpp: Added.
* TestWebKitAPI/Counters.h: Copied from Tools/TestWebKitAPI/Tests/WTF/CopyMoveCounter.h.
Move the CopyMoveCounter helper from CopyMoveCounter.h to Counters.h, and add a ConstructorDestructorCounter
helper to the mix as well. Add Counters.cpp to allow for the global variables to be used in more than one
translation unit.
    
* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
Add new files.

* TestWebKitAPI/Tests/WTF/HashMap.cpp:
Add tests for using std::unique_ptr and OwnPtr as the key's of a HashMap.

* TestWebKitAPI/Tests/WTF/HashSet.cpp:
Add tests for using std::unique_ptr and OwnPtr as the values of a HashSet.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWTFChangeLog">trunk/Source/WTF/ChangeLog</a></li>
<li><a href="#trunkSourceWTFwtfGetPtrh">trunk/Source/WTF/wtf/GetPtr.h</a></li>
<li><a href="#trunkSourceWTFwtfHashFunctionsh">trunk/Source/WTF/wtf/HashFunctions.h</a></li>
<li><a href="#trunkSourceWTFwtfHashMaph">trunk/Source/WTF/wtf/HashMap.h</a></li>
<li><a href="#trunkSourceWTFwtfHashSeth">trunk/Source/WTF/wtf/HashSet.h</a></li>
<li><a href="#trunkSourceWTFwtfHashTraitsh">trunk/Source/WTF/wtf/HashTraits.h</a></li>
<li><a href="#trunkSourceWTFwtfOwnPtrh">trunk/Source/WTF/wtf/OwnPtr.h</a></li>
<li><a href="#trunkSourceWTFwtfRefh">trunk/Source/WTF/wtf/Ref.h</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsTestWebKitAPICMakeListstxt">trunk/Tools/TestWebKitAPI/CMakeLists.txt</a></li>
<li><a href="#trunkToolsTestWebKitAPITestWebKitAPIvcxprojTestWebKitAPIvcxproj">trunk/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPI.vcxproj</a></li>
<li><a href="#trunkToolsTestWebKitAPITestWebKitAPIvcxprojTestWebKitAPIvcxprojfilters">trunk/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPI.vcxproj.filters</a></li>
<li><a href="#trunkToolsTestWebKitAPITestWebKitAPIxcodeprojprojectpbxproj">trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkToolsTestWebKitAPITestsWTFHashMapcpp">trunk/Tools/TestWebKitAPI/Tests/WTF/HashMap.cpp</a></li>
<li><a href="#trunkToolsTestWebKitAPITestsWTFHashSetcpp">trunk/Tools/TestWebKitAPI/Tests/WTF/HashSet.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkToolsTestWebKitAPICounterscpp">trunk/Tools/TestWebKitAPI/Counters.cpp</a></li>
<li><a href="#trunkToolsTestWebKitAPICountersh">trunk/Tools/TestWebKitAPI/Counters.h</a></li>
</ul>

<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkToolsTestWebKitAPITestsWTFCopyMoveCounterh">trunk/Tools/TestWebKitAPI/Tests/WTF/CopyMoveCounter.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (173800 => 173801)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/ChangeLog        2014-09-22 00:18:50 UTC (rev 173800)
+++ trunk/Source/WTF/ChangeLog        2014-09-22 00:24:44 UTC (rev 173801)
</span><span class="lines">@@ -1,3 +1,48 @@
</span><ins>+2014-09-20  Sam Weinig  &lt;sam@webkit.org&gt;
+
+        Make possible HashSet&lt;std::unique_ptr&lt;&gt;&gt;
+        https://bugs.webkit.org/show_bug.cgi?id=136166
+
+        Reviewed by Darin Adler.
+
+        * wtf/GetPtr.h:
+        (WTF::getPtr):
+        (WTF::GetPtrHelper&lt;std::unique_ptr&lt;T&gt;&gt;::getPtr):
+        Make specializing GetPtrHelper a bit cleaner (you don't have to put 
+        IsSmartPtr&lt;T&gt;::value everywhere any more) and add specializations for
+        std::unique_ptr.
+
+        * wtf/HashFunctions.h:
+        (WTF::PtrHash&lt;std::unique_ptr&lt;P&gt;&gt;):
+        Add specialization for PtrHash for std::unique_ptr and set it as the DefaultHash
+        for it as well.
+
+        * wtf/HashMap.h:    
+        * wtf/HashSet.h:
+        Add overloads of find(), contains(), remove(), take() (and get() for HashMap) for &quot;smart pointers&quot; that
+        take the raw pointer type as the parameter. These use SFINAE to make themselves only available
+        when the IsSmartPtr&lt;KeyType&gt;::value is true. 
+
+        * wtf/HashTraits.h:
+        Override constructDeletedValue() and isDeletedValue() in the std::unique_ptr specialization
+        since the default implementation depends on the type having a constructor that takes a HashTableDeletedValue
+        and function named isHashTableDeletedValue().
+
+        * wtf/OwnPtr.h:
+        (WTF::OwnPtr::OwnPtr):
+        (WTF::OwnPtr::isHashTableDeletedValue):
+        (WTF::OwnPtr::hashTableDeletedValue):
+        Add HashTableDeletedValue constructor/functions to allow the constructDeletedValue() and isDeletedValue()
+        hash traits to work.
+
+        (WTF::PtrHash&lt;OwnPtr&lt;P&gt;&gt;::hash):
+        (WTF::PtrHash&lt;OwnPtr&lt;P&gt;&gt;::equal):
+        Add specialization for PtrHash for OwnPtr and set it as the DefaultHash
+        for it as well.
+
+        * wtf/Ref.h:
+        Update for the less verbose GetPtrHelper specialization.
+
</ins><span class="cx"> 2014-09-19  Chris Dumez  &lt;cdumez@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Allow DOM methods to return references instead of pointers
</span></span></pre></div>
<a id="trunkSourceWTFwtfGetPtrh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/GetPtr.h (173800 => 173801)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/GetPtr.h        2014-09-22 00:18:50 UTC (rev 173800)
+++ trunk/Source/WTF/wtf/GetPtr.h        2014-09-22 00:24:44 UTC (rev 173801)
</span><span class="lines">@@ -21,6 +21,8 @@
</span><span class="cx"> #ifndef WTF_GetPtr_h
</span><span class="cx"> #define WTF_GetPtr_h
</span><span class="cx"> 
</span><ins>+#include &lt;memory&gt;
+
</ins><span class="cx"> namespace WTF {
</span><span class="cx"> 
</span><span class="cx"> template &lt;typename T&gt; inline T* getPtr(T* p) { return p; }
</span><span class="lines">@@ -30,32 +32,48 @@
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> template &lt;typename T, bool isSmartPtr&gt;
</span><del>-struct GetPtrHelper;
</del><ins>+struct GetPtrHelperBase;
</ins><span class="cx"> 
</span><span class="cx"> template &lt;typename T&gt;
</span><del>-struct GetPtrHelper&lt;T, false /* isSmartPtr */&gt; {
</del><ins>+struct GetPtrHelperBase&lt;T, false /* isSmartPtr */&gt; {
</ins><span class="cx">     typedef T* PtrType;
</span><span class="cx">     static T* getPtr(T&amp; p) { return &amp;p; }
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> template &lt;typename T&gt;
</span><del>-struct GetPtrHelper&lt;T, true /* isSmartPtr */&gt; {
</del><ins>+struct GetPtrHelperBase&lt;T, true /* isSmartPtr */&gt; {
</ins><span class="cx">     typedef typename T::PtrType PtrType;
</span><span class="cx">     static PtrType getPtr(const T&amp; p) { return p.get(); }
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> template &lt;typename T&gt;
</span><del>-inline typename GetPtrHelper&lt;T, IsSmartPtr&lt;T&gt;::value&gt;::PtrType getPtr(T&amp; p)
</del><ins>+struct GetPtrHelper : GetPtrHelperBase&lt;T, IsSmartPtr&lt;T&gt;::value&gt; {
+};
+
+template &lt;typename T&gt;
+inline typename GetPtrHelper&lt;T&gt;::PtrType getPtr(T&amp; p)
</ins><span class="cx"> {
</span><del>-    return GetPtrHelper&lt;T, IsSmartPtr&lt;T&gt;::value&gt;::getPtr(p);
</del><ins>+    return GetPtrHelper&lt;T&gt;::getPtr(p);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template &lt;typename T&gt;
</span><del>-inline typename GetPtrHelper&lt;T, IsSmartPtr&lt;T&gt;::value&gt;::PtrType getPtr(const T&amp; p)
</del><ins>+inline typename GetPtrHelper&lt;T&gt;::PtrType getPtr(const T&amp; p)
</ins><span class="cx"> {
</span><del>-    return GetPtrHelper&lt;T, IsSmartPtr&lt;T&gt;::value&gt;::getPtr(p);
</del><ins>+    return GetPtrHelper&lt;T&gt;::getPtr(p);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+// Explicit specialization for C++ standard library types.
+
+template &lt;typename T, typename Deleter&gt; struct IsSmartPtr&lt;std::unique_ptr&lt;T, Deleter&gt;&gt; {
+    static const bool value = true;
+};
+
+template &lt;typename T, typename Deleter&gt;
+struct GetPtrHelper&lt;std::unique_ptr&lt;T, Deleter&gt;&gt; {
+    typedef T* PtrType;
+    static T* getPtr(const std::unique_ptr&lt;T, Deleter&gt;&amp; p) { return const_cast&lt;T*&gt;(p.get()); }
+};
+
</ins><span class="cx"> } // namespace WTF
</span><span class="cx"> 
</span><span class="cx"> #endif // WTF_GetPtr_h
</span></span></pre></div>
<a id="trunkSourceWTFwtfHashFunctionsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/HashFunctions.h (173800 => 173801)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/HashFunctions.h        2014-09-22 00:18:50 UTC (rev 173800)
+++ trunk/Source/WTF/wtf/HashFunctions.h        2014-09-22 00:24:44 UTC (rev 173801)
</span><span class="lines">@@ -127,6 +127,7 @@
</span><span class="cx">         static bool equal(T a, T b) { return a == b; }
</span><span class="cx">         static const bool safeToCompareToEmptyOrDeleted = true;
</span><span class="cx">     };
</span><ins>+
</ins><span class="cx">     template&lt;typename P&gt; struct PtrHash&lt;RefPtr&lt;P&gt;&gt; : PtrHash&lt;P*&gt; {
</span><span class="cx">         using PtrHash&lt;P*&gt;::hash;
</span><span class="cx">         static unsigned hash(const RefPtr&lt;P&gt;&amp; key) { return hash(key.get()); }
</span><span class="lines">@@ -136,6 +137,15 @@
</span><span class="cx">         static bool equal(const RefPtr&lt;P&gt;&amp; a, P* b) { return a == b; }
</span><span class="cx">     };
</span><span class="cx"> 
</span><ins>+    template&lt;typename P, typename Deleter&gt; struct PtrHash&lt;std::unique_ptr&lt;P, Deleter&gt;&gt; : PtrHash&lt;P*&gt; {
+        using PtrHash&lt;P*&gt;::hash;
+        static unsigned hash(const std::unique_ptr&lt;P, Deleter&gt;&amp; key) { return hash(key.get()); }
+        using PtrHash&lt;P*&gt;::equal;
+        static bool equal(const std::unique_ptr&lt;P, Deleter&gt;&amp; a, const std::unique_ptr&lt;P, Deleter&gt;&amp; b) { return a.get() == b.get(); }
+        static bool equal(P* a, const std::unique_ptr&lt;P, Deleter&gt;&amp; b) { return a == b.get(); }
+        static bool equal(const std::unique_ptr&lt;P, Deleter&gt;&amp; a, P* b) { return a.get() == b; }
+    };
+
</ins><span class="cx">     // default hash function for each type
</span><span class="cx"> 
</span><span class="cx">     template&lt;typename T&gt; struct DefaultHash;
</span><span class="lines">@@ -181,6 +191,7 @@
</span><span class="cx"> 
</span><span class="cx">     template&lt;typename P&gt; struct DefaultHash&lt;P*&gt; { typedef PtrHash&lt;P*&gt; Hash; };
</span><span class="cx">     template&lt;typename P&gt; struct DefaultHash&lt;RefPtr&lt;P&gt;&gt; { typedef PtrHash&lt;RefPtr&lt;P&gt;&gt; Hash; };
</span><ins>+    template&lt;typename P, typename Deleter&gt; struct DefaultHash&lt;std::unique_ptr&lt;P, Deleter&gt;&gt; { typedef PtrHash&lt;std::unique_ptr&lt;P, Deleter&gt;&gt; Hash; };
</ins><span class="cx"> 
</span><span class="cx">     // make IntPairHash the default hash function for pairs of (at most) 32-bit integers.
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWTFwtfHashMaph"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/HashMap.h (173800 => 173801)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/HashMap.h        2014-09-22 00:18:50 UTC (rev 173800)
+++ trunk/Source/WTF/wtf/HashMap.h        2014-09-22 00:24:44 UTC (rev 173801)
</span><span class="lines">@@ -22,6 +22,7 @@
</span><span class="cx"> #define WTF_HashMap_h
</span><span class="cx"> 
</span><span class="cx"> #include &lt;initializer_list&gt;
</span><ins>+#include &lt;wtf/GetPtr.h&gt;
</ins><span class="cx"> #include &lt;wtf/HashTable.h&gt;
</span><span class="cx"> #include &lt;wtf/IteratorRange.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -143,6 +144,14 @@
</span><span class="cx">     //   static translate(ValueType&amp;, const T&amp;, unsigned hashCode);
</span><span class="cx">     template&lt;typename HashTranslator, typename K, typename V&gt; AddResult add(K&amp;&amp;, V&amp;&amp;);
</span><span class="cx"> 
</span><ins>+    // Overloads for smart pointer keys that take the raw pointer type as the parameter.
+    template&lt;typename K = KeyType&gt; typename std::enable_if&lt;IsSmartPtr&lt;K&gt;::value, iterator&gt;::type find(typename GetPtrHelper&lt;K&gt;::PtrType);
+    template&lt;typename K = KeyType&gt; typename std::enable_if&lt;IsSmartPtr&lt;K&gt;::value, const_iterator&gt;::type find(typename GetPtrHelper&lt;K&gt;::PtrType) const;
+    template&lt;typename K = KeyType&gt; typename std::enable_if&lt;IsSmartPtr&lt;K&gt;::value, bool&gt;::type contains(typename GetPtrHelper&lt;K&gt;::PtrType) const;
+    template&lt;typename K = KeyType&gt; typename std::enable_if&lt;IsSmartPtr&lt;K&gt;::value, MappedPeekType&gt;::type get(typename GetPtrHelper&lt;K&gt;::PtrType) const;
+    template&lt;typename K = KeyType&gt; typename std::enable_if&lt;IsSmartPtr&lt;K&gt;::value, bool&gt;::type remove(typename GetPtrHelper&lt;K&gt;::PtrType);
+    template&lt;typename K = KeyType&gt; typename std::enable_if&lt;IsSmartPtr&lt;K&gt;::value, MappedType&gt;::type take(typename GetPtrHelper&lt;K&gt;::PtrType);
+
</ins><span class="cx">     void checkConsistency() const;
</span><span class="cx"> 
</span><span class="cx">     static bool isValidKey(const KeyType&amp;);
</span><span class="lines">@@ -386,6 +395,56 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template&lt;typename T, typename U, typename V, typename W, typename X&gt;
</span><ins>+template&lt;typename K&gt;
+inline auto HashMap&lt;T, U, V, W, X&gt;::find(typename GetPtrHelper&lt;K&gt;::PtrType key) -&gt; typename std::enable_if&lt;IsSmartPtr&lt;K&gt;::value, iterator&gt;::type
+{
+    return m_impl.template find&lt;HashMapTranslator&lt;KeyValuePairTraits, HashFunctions&gt;&gt;(key);
+}
+
+template&lt;typename T, typename U, typename V, typename W, typename X&gt;
+template&lt;typename K&gt;
+inline auto HashMap&lt;T, U, V, W, X&gt;::find(typename GetPtrHelper&lt;K&gt;::PtrType key) const -&gt; typename std::enable_if&lt;IsSmartPtr&lt;K&gt;::value, const_iterator&gt;::type
+{
+    return m_impl.template find&lt;HashMapTranslator&lt;KeyValuePairTraits, HashFunctions&gt;&gt;(key);
+}
+
+template&lt;typename T, typename U, typename V, typename W, typename X&gt;
+template&lt;typename K&gt;
+inline auto HashMap&lt;T, U, V, W, X&gt;::contains(typename GetPtrHelper&lt;K&gt;::PtrType key) const -&gt; typename std::enable_if&lt;IsSmartPtr&lt;K&gt;::value, bool&gt;::type
+{
+    return m_impl.template contains&lt;HashMapTranslator&lt;KeyValuePairTraits, HashFunctions&gt;&gt;(key);
+}
+
+template&lt;typename T, typename U, typename V, typename W, typename X&gt;
+template&lt;typename K&gt;
+inline auto HashMap&lt;T, U, V, W, X&gt;::get(typename GetPtrHelper&lt;K&gt;::PtrType key) const -&gt; typename std::enable_if&lt;IsSmartPtr&lt;K&gt;::value, MappedPeekType&gt;::type
+{
+    KeyValuePairType* entry = const_cast&lt;HashTableType&amp;&gt;(m_impl).template lookup&lt;HashMapTranslator&lt;KeyValuePairTraits, HashFunctions&gt;&gt;(key);
+    if (!entry)
+        return MappedTraits::peek(MappedTraits::emptyValue());
+    return MappedTraits::peek(entry-&gt;value);
+}
+
+template&lt;typename T, typename U, typename V, typename W, typename X&gt;
+template&lt;typename K&gt;
+inline auto HashMap&lt;T, U, V, W, X&gt;::remove(typename GetPtrHelper&lt;K&gt;::PtrType key) -&gt; typename std::enable_if&lt;IsSmartPtr&lt;K&gt;::value, bool&gt;::type
+{
+    return remove(find(key));
+}
+
+template&lt;typename T, typename U, typename V, typename W, typename X&gt;
+template&lt;typename K&gt;
+inline auto HashMap&lt;T, U, V, W, X&gt;::take(typename GetPtrHelper&lt;K&gt;::PtrType key) -&gt; typename std::enable_if&lt;IsSmartPtr&lt;K&gt;::value, MappedType&gt;::type
+{
+    iterator it = find(key);
+    if (it == end())
+        return MappedTraits::emptyValue();
+    MappedType value = WTF::move(it-&gt;value);
+    remove(it);
+    return value;
+}
+
+template&lt;typename T, typename U, typename V, typename W, typename X&gt;
</ins><span class="cx"> inline void HashMap&lt;T, U, V, W, X&gt;::checkConsistency() const
</span><span class="cx"> {
</span><span class="cx">     m_impl.checkTableConsistency();
</span></span></pre></div>
<a id="trunkSourceWTFwtfHashSeth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/HashSet.h (173800 => 173801)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/HashSet.h        2014-09-22 00:18:50 UTC (rev 173800)
+++ trunk/Source/WTF/wtf/HashSet.h        2014-09-22 00:24:44 UTC (rev 173801)
</span><span class="lines">@@ -23,6 +23,7 @@
</span><span class="cx"> 
</span><span class="cx"> #include &lt;initializer_list&gt;
</span><span class="cx"> #include &lt;wtf/FastMalloc.h&gt;
</span><ins>+#include &lt;wtf/GetPtr.h&gt;
</ins><span class="cx"> #include &lt;wtf/HashTable.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace WTF {
</span><span class="lines">@@ -106,6 +107,12 @@
</span><span class="cx">         ValueType take(iterator);
</span><span class="cx">         ValueType takeAny();
</span><span class="cx"> 
</span><ins>+        // Overloads for smart pointer values that take the raw pointer type as the parameter.
+        template&lt;typename V = ValueType&gt; typename std::enable_if&lt;IsSmartPtr&lt;V&gt;::value, iterator&gt;::type find(typename GetPtrHelper&lt;V&gt;::PtrType) const;
+        template&lt;typename V = ValueType&gt; typename std::enable_if&lt;IsSmartPtr&lt;V&gt;::value, bool&gt;::type contains(typename GetPtrHelper&lt;V&gt;::PtrType) const;
+        template&lt;typename V = ValueType&gt; typename std::enable_if&lt;IsSmartPtr&lt;V&gt;::value, bool&gt;::type remove(typename GetPtrHelper&lt;V&gt;::PtrType);
+        template&lt;typename V = ValueType&gt; typename std::enable_if&lt;IsSmartPtr&lt;V&gt;::value, ValueType&gt;::type take(typename GetPtrHelper&lt;V&gt;::PtrType);
+
</ins><span class="cx">         static bool isValidValue(const ValueType&amp;);
</span><span class="cx">         
</span><span class="cx">         bool operator==(const HashSet&amp;) const;
</span><span class="lines">@@ -118,6 +125,13 @@
</span><span class="cx">         template&lt;typename T&gt; static const T&amp; extract(const T&amp; t) { return t; }
</span><span class="cx">     };
</span><span class="cx"> 
</span><ins>+    template&lt;typename HashFunctions&gt;
+    struct HashSetTranslator {
+        template&lt;typename T&gt; static unsigned hash(const T&amp; key) { return HashFunctions::hash(key); }
+        template&lt;typename T, typename U&gt; static bool equal(const T&amp; a, const U&amp; b) { return HashFunctions::equal(a, b); }
+        template&lt;typename T, typename U, typename V&gt; static void translate(T&amp; location, U&amp;&amp;, V&amp;&amp; value) { location = std::forward&lt;V&gt;(value); }
+    };
+
</ins><span class="cx">     template&lt;typename Translator&gt;
</span><span class="cx">     struct HashSetTranslatorAdapter {
</span><span class="cx">         template&lt;typename T&gt; static unsigned hash(const T&amp; key) { return Translator::hash(key); }
</span><span class="lines">@@ -264,6 +278,34 @@
</span><span class="cx">         return take(begin());
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    template&lt;typename Value, typename HashFunctions, typename Traits&gt;
+    template&lt;typename V&gt;
+    inline auto HashSet&lt;Value, HashFunctions, Traits&gt;::find(typename GetPtrHelper&lt;V&gt;::PtrType value) const -&gt; typename std::enable_if&lt;IsSmartPtr&lt;V&gt;::value, iterator&gt;::type
+    {
+        return m_impl.template find&lt;HashSetTranslator&lt;HashFunctions&gt;&gt;(value);
+    }
+
+    template&lt;typename Value, typename HashFunctions, typename Traits&gt;
+    template&lt;typename V&gt;
+    inline auto HashSet&lt;Value, HashFunctions, Traits&gt;::contains(typename GetPtrHelper&lt;V&gt;::PtrType value) const -&gt; typename std::enable_if&lt;IsSmartPtr&lt;V&gt;::value, bool&gt;::type
+    {
+        return m_impl.template contains&lt;HashSetTranslator&lt;HashFunctions&gt;&gt;(value);
+    }
+
+    template&lt;typename Value, typename HashFunctions, typename Traits&gt;
+    template&lt;typename V&gt;
+    inline auto HashSet&lt;Value, HashFunctions, Traits&gt;::remove(typename GetPtrHelper&lt;V&gt;::PtrType value) -&gt; typename std::enable_if&lt;IsSmartPtr&lt;V&gt;::value, bool&gt;::type
+    {
+        return remove(find(value));
+    }
+
+    template&lt;typename Value, typename HashFunctions, typename Traits&gt;
+    template&lt;typename V&gt;
+    inline auto HashSet&lt;Value, HashFunctions, Traits&gt;::take(typename GetPtrHelper&lt;V&gt;::PtrType value) -&gt; typename std::enable_if&lt;IsSmartPtr&lt;V&gt;::value, ValueType&gt;::type
+    {
+        return take(find(value));
+    }
+
</ins><span class="cx">     template&lt;typename T, typename U, typename V&gt;
</span><span class="cx">     inline bool HashSet&lt;T, U, V&gt;::isValidValue(const ValueType&amp; value)
</span><span class="cx">     {
</span></span></pre></div>
<a id="trunkSourceWTFwtfHashTraitsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/HashTraits.h (173800 => 173801)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/HashTraits.h        2014-09-22 00:18:50 UTC (rev 173800)
+++ trunk/Source/WTF/wtf/HashTraits.h        2014-09-22 00:24:44 UTC (rev 173801)
</span><span class="lines">@@ -104,6 +104,9 @@
</span><span class="cx">     typedef std::nullptr_t EmptyValueType;
</span><span class="cx">     static EmptyValueType emptyValue() { return nullptr; }
</span><span class="cx"> 
</span><ins>+    static void constructDeletedValue(std::unique_ptr&lt;T, Deleter&gt;&amp; slot) { new (NotNull, &amp;slot) std::unique_ptr&lt;T, Deleter&gt; { reinterpret_cast&lt;T*&gt;(-1) }; }
+    static bool isDeletedValue(const std::unique_ptr&lt;T, Deleter&gt;&amp; value) { return value.get() == reinterpret_cast&lt;T*&gt;(-1); }
+
</ins><span class="cx">     typedef T* PeekType;
</span><span class="cx">     static T* peek(const std::unique_ptr&lt;T, Deleter&gt;&amp; value) { return value.get(); }
</span><span class="cx">     static T* peek(std::nullptr_t) { return nullptr; }
</span></span></pre></div>
<a id="trunkSourceWTFwtfOwnPtrh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/OwnPtr.h (173800 => 173801)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/OwnPtr.h        2014-09-22 00:18:50 UTC (rev 173800)
+++ trunk/Source/WTF/wtf/OwnPtr.h        2014-09-22 00:24:44 UTC (rev 173801)
</span><span class="lines">@@ -21,14 +21,15 @@
</span><span class="cx"> #ifndef WTF_OwnPtr_h
</span><span class="cx"> #define WTF_OwnPtr_h
</span><span class="cx"> 
</span><ins>+#include &lt;algorithm&gt;
+#include &lt;cstddef&gt;
+#include &lt;memory&gt;
</ins><span class="cx"> #include &lt;wtf/Assertions.h&gt;
</span><span class="cx"> #include &lt;wtf/Atomics.h&gt;
</span><span class="cx"> #include &lt;wtf/GetPtr.h&gt;
</span><ins>+#include &lt;wtf/HashTraits.h&gt;
</ins><span class="cx"> #include &lt;wtf/Noncopyable.h&gt;
</span><span class="cx"> #include &lt;wtf/OwnPtrCommon.h&gt;
</span><del>-#include &lt;algorithm&gt;
-#include &lt;cstddef&gt;
-#include &lt;memory&gt;
</del><span class="cx"> 
</span><span class="cx"> namespace WTF {
</span><span class="cx"> 
</span><span class="lines">@@ -73,6 +74,10 @@
</span><span class="cx">         OwnPtr&amp; operator=(OwnPtr&amp;&amp;);
</span><span class="cx">         template&lt;typename U&gt; OwnPtr&amp; operator=(OwnPtr&lt;U&gt;&amp;&amp;);
</span><span class="cx"> 
</span><ins>+        // Hash table deleted values, which are only constructed and never copied or destroyed.
+        OwnPtr(HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) { }
+        bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue(); }
+
</ins><span class="cx">         void swap(OwnPtr&amp; o) { std::swap(m_ptr, o.m_ptr); }
</span><span class="cx">         
</span><span class="cx">         // Construct an object to store into this OwnPtr, but only so long as this OwnPtr
</span><span class="lines">@@ -89,6 +94,8 @@
</span><span class="cx">     private:
</span><span class="cx">         explicit OwnPtr(PtrType ptr) : m_ptr(ptr) { }
</span><span class="cx"> 
</span><ins>+        static PtrType hashTableDeletedValue() { return reinterpret_cast&lt;PtrType&gt;(-1); }
+
</ins><span class="cx">         // We should never have two OwnPtrs for the same underlying object (otherwise we'll get
</span><span class="cx">         // double-destruction), so these equality operators should never be needed.
</span><span class="cx">         template&lt;typename U&gt; bool operator==(const OwnPtr&lt;U&gt;&amp;) { COMPILE_ASSERT(!sizeof(U*), OwnPtrs_should_never_be_equal); return false; }
</span><span class="lines">@@ -220,6 +227,17 @@
</span><span class="cx"> #endif
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    template&lt;typename P&gt; struct PtrHash&lt;OwnPtr&lt;P&gt;&gt; : PtrHash&lt;P*&gt; {
+        using PtrHash&lt;P*&gt;::hash;
+        static unsigned hash(const OwnPtr&lt;P&gt;&amp; key) { return hash(key.get()); }
+        using PtrHash&lt;P*&gt;::equal;
+        static bool equal(const OwnPtr&lt;P&gt;&amp; a, const OwnPtr&lt;P&gt;&amp; b) { return a.get() == b.get(); }
+        static bool equal(P* a, const OwnPtr&lt;P&gt;&amp; b) { return a == b.get(); }
+        static bool equal(const OwnPtr&lt;P&gt;&amp; a, P* b) { return a.get() == b; }
+    };
+
+    template&lt;typename P&gt; struct DefaultHash&lt;OwnPtr&lt;P&gt;&gt; { typedef PtrHash&lt;OwnPtr&lt;P&gt;&gt; Hash; };
+
</ins><span class="cx"> } // namespace WTF
</span><span class="cx"> 
</span><span class="cx"> using WTF::OwnPtr;
</span></span></pre></div>
<a id="trunkSourceWTFwtfRefh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/Ref.h (173800 => 173801)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/Ref.h        2014-09-22 00:18:50 UTC (rev 173800)
+++ trunk/Source/WTF/wtf/Ref.h        2014-09-22 00:24:44 UTC (rev 173801)
</span><span class="lines">@@ -75,7 +75,7 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template &lt;typename T&gt;
</span><del>-struct GetPtrHelper&lt;Ref&lt;T&gt;, false /* isSmartPtr */&gt; {
</del><ins>+struct GetPtrHelper&lt;Ref&lt;T&gt;&gt; {
</ins><span class="cx">     typedef T* PtrType;
</span><span class="cx">     static T* getPtr(const Ref&lt;T&gt;&amp; p) { return const_cast&lt;T*&gt;(&amp;p.get()); }
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (173800 => 173801)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2014-09-22 00:18:50 UTC (rev 173800)
+++ trunk/Tools/ChangeLog        2014-09-22 00:24:44 UTC (rev 173801)
</span><span class="lines">@@ -1,3 +1,26 @@
</span><ins>+2014-09-20  Sam Weinig  &lt;sam@webkit.org&gt;
+
+        Make possible HashSet&lt;std::unique_ptr&lt;&gt;&gt;
+        https://bugs.webkit.org/show_bug.cgi?id=136166
+
+        Reviewed by Darin Adler.
+
+        * TestWebKitAPI/Tests/WTF/CopyMoveCounter.h: Removed.
+        * TestWebKitAPI/Counters.cpp: Added.
+        * TestWebKitAPI/Counters.h: Copied from Tools/TestWebKitAPI/Tests/WTF/CopyMoveCounter.h.
+        Move the CopyMoveCounter helper from CopyMoveCounter.h to Counters.h, and add a ConstructorDestructorCounter
+        helper to the mix as well. Add Counters.cpp to allow for the global variables to be used in more than one
+        translation unit.
+    
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        Add new files.
+
+        * TestWebKitAPI/Tests/WTF/HashMap.cpp:
+        Add tests for using std::unique_ptr and OwnPtr as the key's of a HashMap.
+
+        * TestWebKitAPI/Tests/WTF/HashSet.cpp:
+        Add tests for using std::unique_ptr and OwnPtr as the values of a HashSet.
+
</ins><span class="cx"> 2014-09-21  Youenn Fablet  &lt;youenn.fablet@crf.canon.fr&gt;
</span><span class="cx"> 
</span><span class="cx">         run-webkit-tests should count tests submitted as absolute paths once
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPICMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/CMakeLists.txt (173800 => 173801)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/CMakeLists.txt        2014-09-22 00:18:50 UTC (rev 173800)
+++ trunk/Tools/TestWebKitAPI/CMakeLists.txt        2014-09-22 00:24:44 UTC (rev 173801)
</span><span class="lines">@@ -65,6 +65,7 @@
</span><span class="cx"> )
</span><span class="cx"> 
</span><span class="cx"> set(TestWTF_SOURCES
</span><ins>+    ${TESTWEBKITAPI_DIR}/Counters.cpp
</ins><span class="cx">     ${TESTWEBKITAPI_DIR}/TestsController.cpp
</span><span class="cx">     ${TESTWEBKITAPI_DIR}/Tests/WTF/AtomicString.cpp
</span><span class="cx">     ${TESTWEBKITAPI_DIR}/Tests/WTF/CString.cpp
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPICounterscpp"></a>
<div class="addfile"><h4>Added: trunk/Tools/TestWebKitAPI/Counters.cpp (0 => 173801)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Counters.cpp                                (rev 0)
+++ trunk/Tools/TestWebKitAPI/Counters.cpp        2014-09-22 00:24:44 UTC (rev 173801)
</span><span class="lines">@@ -0,0 +1,34 @@
</span><ins>+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;Counters.h&quot;
+
+unsigned CopyMoveCounter::constructionCount = 0;
+unsigned CopyMoveCounter::copyCount = 0;
+unsigned CopyMoveCounter::moveCount = 0;
+
+unsigned ConstructorDestructorCounter::constructionCount = 0;
+unsigned ConstructorDestructorCounter::destructionCount = 0;
</ins></span></pre></div>
<a id="trunkToolsTestWebKitAPICountershfromrev173795trunkToolsTestWebKitAPITestsWTFCopyMoveCounterh"></a>
<div class="copfile"><h4>Copied: trunk/Tools/TestWebKitAPI/Counters.h (from rev 173795, trunk/Tools/TestWebKitAPI/Tests/WTF/CopyMoveCounter.h) (0 => 173801)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Counters.h                                (rev 0)
+++ trunk/Tools/TestWebKitAPI/Counters.h        2014-09-22 00:24:44 UTC (rev 173801)
</span><span class="lines">@@ -0,0 +1,88 @@
</span><ins>+/*
+ * Copyright (C) 2014 Igalia S.L.
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef Counters_h
+#define Counters_h
+
+struct CopyMoveCounter {
+    static unsigned constructionCount;
+    static unsigned copyCount;
+    static unsigned moveCount;
+
+    struct TestingScope {
+        TestingScope()
+        {
+            constructionCount = 0;
+            copyCount = 0;
+            moveCount = 0;
+        }
+    };
+
+    CopyMoveCounter() { constructionCount++; }
+    CopyMoveCounter(const CopyMoveCounter&amp;) { copyCount++; }
+    CopyMoveCounter&amp; operator=(const CopyMoveCounter&amp;) { copyCount++; return *this; }
+    CopyMoveCounter(CopyMoveCounter&amp;&amp;) { moveCount++; }
+    CopyMoveCounter&amp; operator=(CopyMoveCounter&amp;&amp;) { moveCount++; return *this; }
+};
+
+
+struct ConstructorDestructorCounter {
+    static unsigned constructionCount;
+    static unsigned destructionCount;
+
+    struct TestingScope {
+        TestingScope()
+        {
+            constructionCount = 0;
+            destructionCount = 0;
+        }
+    };
+
+    ConstructorDestructorCounter() { constructionCount++; }
+    ~ConstructorDestructorCounter() { destructionCount++; }
+};
+
+template&lt;typename T&gt;
+struct DeleterCounter {
+    static unsigned deleterCount;
+
+    struct TestingScope {
+        TestingScope()
+        {
+            deleterCount = 0;
+        }
+    };
+
+    void operator()(T* p) const
+    {
+        deleterCount++;
+        delete p;
+    }
+};
+
+template&lt;class T&gt; unsigned DeleterCounter&lt;T&gt;::deleterCount = 0;
+
+#endif // Counters_h
</ins></span></pre></div>
<a id="trunkToolsTestWebKitAPITestWebKitAPIvcxprojTestWebKitAPIvcxproj"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPI.vcxproj (173800 => 173801)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPI.vcxproj        2014-09-22 00:18:50 UTC (rev 173800)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPI.vcxproj        2014-09-22 00:24:44 UTC (rev 173801)
</span><span class="lines">@@ -280,11 +280,13 @@
</span><span class="cx">   &lt;/ItemDefinitionGroup&gt;
</span><span class="cx">   &lt;ItemGroup&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\config.h&quot; /&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\Counters.h&quot; /&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\Test.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\TestsController.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\win\HostWindow.h&quot; /&gt;
</span><span class="cx">   &lt;/ItemGroup&gt;
</span><span class="cx">   &lt;ItemGroup&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\Counters.cpp&quot; /&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\TestsController.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\Tests\WebCore\LayoutUnit.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\Tests\WebCore\win\BitmapImage.cpp&quot;&gt;
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestWebKitAPIvcxprojTestWebKitAPIvcxprojfilters"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPI.vcxproj.filters (173800 => 173801)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPI.vcxproj.filters        2014-09-22 00:18:50 UTC (rev 173800)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPI.vcxproj.filters        2014-09-22 00:24:44 UTC (rev 173801)
</span><span class="lines">@@ -22,6 +22,7 @@
</span><span class="cx">   &lt;/ItemGroup&gt;
</span><span class="cx">   &lt;ItemGroup&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\config.h&quot; /&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\Counters.h&quot; /&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\Test.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\TestsController.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\win\HostWindow.h&quot;&gt;
</span><span class="lines">@@ -29,6 +30,7 @@
</span><span class="cx">     &lt;/ClInclude&gt;
</span><span class="cx">   &lt;/ItemGroup&gt;
</span><span class="cx">   &lt;ItemGroup&gt;
</span><ins>+    &lt;ClCompile Include=&quot;..\Counters.cpp&quot; /&gt;
</ins><span class="cx">     &lt;ClCompile Include=&quot;..\TestsController.cpp&quot; /&gt;
</span><span class="cx">     &lt;ClCompile Include=&quot;..\win\HostWindow.cpp&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;win&lt;/Filter&gt;
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestWebKitAPIxcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (173800 => 173801)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj        2014-09-22 00:18:50 UTC (rev 173800)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj        2014-09-22 00:24:44 UTC (rev 173801)
</span><span class="lines">@@ -119,6 +119,7 @@
</span><span class="cx">                 76E182DA1547550100F1FADD /* WillSendSubmitEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 76E182D91547550100F1FADD /* WillSendSubmitEvent.cpp */; };
</span><span class="cx">                 76E182DD1547569100F1FADD /* WillSendSubmitEvent_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 76E182DC1547569100F1FADD /* WillSendSubmitEvent_Bundle.cpp */; };
</span><span class="cx">                 76E182DF154767E600F1FADD /* auto-submitting-form.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 76E182DE15475A8300F1FADD /* auto-submitting-form.html */; };
</span><ins>+                7C6BBD8C19CEA63000C1F5E0 /* Counters.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C6BBD8B19CEA63000C1F5E0 /* Counters.cpp */; };
</ins><span class="cx">                 7C74D42F188228F300E5ED57 /* StringView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C74D42D188228F300E5ED57 /* StringView.cpp */; };
</span><span class="cx">                 7C8DDAAB1735DEEE00EA5AC0 /* CloseThenTerminate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C8DDAA91735DE1D00EA5AC0 /* CloseThenTerminate.cpp */; };
</span><span class="cx">                 7C9ED98B17A19F4B00E4DC33 /* attributedStringStrikethrough.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 7C9ED98A17A19D0600E4DC33 /* attributedStringStrikethrough.html */; };
</span><span class="lines">@@ -463,6 +464,8 @@
</span><span class="cx">                 76E182D91547550100F1FADD /* WillSendSubmitEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WillSendSubmitEvent.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 76E182DC1547569100F1FADD /* WillSendSubmitEvent_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WillSendSubmitEvent_Bundle.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 76E182DE15475A8300F1FADD /* auto-submitting-form.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = &quot;auto-submitting-form.html&quot;; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                7C6BBD8A19CEA54300C1F5E0 /* Counters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Counters.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                7C6BBD8B19CEA63000C1F5E0 /* Counters.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Counters.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 7C74D42D188228F300E5ED57 /* StringView.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StringView.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 7C8DDAA91735DE1D00EA5AC0 /* CloseThenTerminate.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CloseThenTerminate.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 7C9ED98A17A19D0600E4DC33 /* attributedStringStrikethrough.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = attributedStringStrikethrough.html; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -670,6 +673,8 @@
</span><span class="cx">                                 2E9660DC16C07D7B00371B42 /* ios */,
</span><span class="cx">                                 BCA61C3A11700B9400460D1E /* mac */,
</span><span class="cx">                                 BC131A9E1171317C00B69727 /* config.h */,
</span><ins>+                                7C6BBD8A19CEA54300C1F5E0 /* Counters.h */,
+                                7C6BBD8B19CEA63000C1F5E0 /* Counters.cpp */,
</ins><span class="cx">                                 C0ADBE7A12FCA4D000D2C129 /* JavaScriptTest.cpp */,
</span><span class="cx">                                 C0ADBE7B12FCA4D000D2C129 /* JavaScriptTest.h */,
</span><span class="cx">                                 BC575BBF126F5752006F0F12 /* PlatformUtilities.cpp */,
</span><span class="lines">@@ -1384,6 +1389,7 @@
</span><span class="cx">                                 BC7B61AA129A038700D174A4 /* WKPreferences.cpp in Sources */,
</span><span class="cx">                                 BC90995E12567BC100083756 /* WKString.cpp in Sources */,
</span><span class="cx">                                 BC9099941256ACF100083756 /* WKStringJSString.cpp in Sources */,
</span><ins>+                                7C6BBD8C19CEA63000C1F5E0 /* Counters.cpp in Sources */,
</ins><span class="cx">                                 265AF55015D1E48A00B0CB4A /* WTFString.cpp in Sources */,
</span><span class="cx">                                 2E7765CD16C4D80A00BA2BB1 /* mainIOS.mm in Sources */,
</span><span class="cx">                                 2E7765CF16C4D81100BA2BB1 /* mainMac.mm in Sources */,
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestsWTFCopyMoveCounterh"></a>
<div class="delfile"><h4>Deleted: trunk/Tools/TestWebKitAPI/Tests/WTF/CopyMoveCounter.h (173800 => 173801)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Tests/WTF/CopyMoveCounter.h        2014-09-22 00:18:50 UTC (rev 173800)
+++ trunk/Tools/TestWebKitAPI/Tests/WTF/CopyMoveCounter.h        2014-09-22 00:24:44 UTC (rev 173801)
</span><span class="lines">@@ -1,54 +0,0 @@
</span><del>-/*
- * Copyright (C) 2014 Igalia S.L.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef CopyMoveCounter_h
-#define CopyMoveCounter_h
-
-struct CopyMoveCounter {
-    static unsigned constructionCount;
-    static unsigned copyCount;
-    static unsigned moveCount;
-
-    struct TestingScope {
-        TestingScope()
-        {
-            constructionCount = 0;
-            copyCount = 0;
-            moveCount = 0;
-        }
-    };
-
-    CopyMoveCounter() { constructionCount++; }
-    CopyMoveCounter(const CopyMoveCounter&amp;) { copyCount++; }
-    CopyMoveCounter&amp; operator=(const CopyMoveCounter&amp;) { copyCount++; return *this; }
-    CopyMoveCounter(CopyMoveCounter&amp;&amp;) { moveCount++; }
-    CopyMoveCounter&amp; operator=(CopyMoveCounter&amp;&amp;) { moveCount++; return *this; }
-};
-
-unsigned CopyMoveCounter::constructionCount = 0;
-unsigned CopyMoveCounter::copyCount = 0;
-unsigned CopyMoveCounter::moveCount = 0;
-
-#endif
</del></span></pre></div>
<a id="trunkToolsTestWebKitAPITestsWTFHashMapcpp"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/Tests/WTF/HashMap.cpp (173800 => 173801)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Tests/WTF/HashMap.cpp        2014-09-22 00:18:50 UTC (rev 173800)
+++ trunk/Tools/TestWebKitAPI/Tests/WTF/HashMap.cpp        2014-09-22 00:24:44 UTC (rev 173801)
</span><span class="lines">@@ -25,11 +25,13 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> 
</span><del>-#include &quot;CopyMoveCounter.h&quot;
</del><ins>+#include &quot;Counters.h&quot;
</ins><span class="cx"> #include &quot;MoveOnly.h&quot;
</span><span class="cx"> #include &lt;string&gt;
</span><span class="cx"> #include &lt;wtf/HashMap.h&gt;
</span><span class="cx"> #include &lt;wtf/text/StringHash.h&gt;
</span><ins>+#include &lt;wtf/OwnPtr.h&gt;
+#include &lt;wtf/PassOwnPtr.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> namespace TestWebKitAPI {
</span><span class="cx"> 
</span><span class="lines">@@ -171,4 +173,217 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+TEST(WTF_HashMap, OwnPtrKey)
+{
+    ConstructorDestructorCounter::TestingScope scope;
+
+    HashMap&lt;OwnPtr&lt;ConstructorDestructorCounter&gt;, int&gt; map;
+
+    OwnPtr&lt;ConstructorDestructorCounter&gt; ownPtr = adoptPtr(new ConstructorDestructorCounter);
+    map.add(WTF::move(ownPtr), 2);
+
+    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
+    EXPECT_EQ(0u, ConstructorDestructorCounter::destructionCount);
+
+    map.clear();
+    
+    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
+    EXPECT_EQ(1u, ConstructorDestructorCounter::destructionCount);
+}
+
+TEST(WTF_HashMap, OwnPtrKey_FindUsingRawPointer)
+{
+    HashMap&lt;OwnPtr&lt;int&gt;, int&gt; map;
+
+    OwnPtr&lt;int&gt; ownPtr = adoptPtr(new int(5));
+    int* ptr = ownPtr.get();
+    map.add(WTF::move(ownPtr), 2);
+
+    auto it = map.find(ptr);
+    ASSERT_TRUE(it != map.end());
+    EXPECT_EQ(ptr, it-&gt;key.get());
+    EXPECT_EQ(2, it-&gt;value);
+}
+
+TEST(WTF_HashMap, OwnPtrKey_ContainsUsingRawPointer)
+{
+    HashMap&lt;OwnPtr&lt;int&gt;, int&gt; map;
+
+    OwnPtr&lt;int&gt; ownPtr = adoptPtr(new int(5));
+    int* ptr = ownPtr.get();
+    map.add(WTF::move(ownPtr), 2);
+
+    EXPECT_EQ(true, map.contains(ptr));
+}
+
+TEST(WTF_HashMap, OwnPtrKey_GetUsingRawPointer)
+{
+    HashMap&lt;OwnPtr&lt;int&gt;, int&gt; map;
+
+    OwnPtr&lt;int&gt; ownPtr = adoptPtr(new int(5));
+    int* ptr = ownPtr.get();
+    map.add(WTF::move(ownPtr), 2);
+
+    int value = map.get(ptr);
+    EXPECT_EQ(2, value);
+}
+
+TEST(WTF_HashMap, OwnPtrKey_RemoveUsingRawPointer)
+{
+    ConstructorDestructorCounter::TestingScope scope;
+
+    HashMap&lt;OwnPtr&lt;ConstructorDestructorCounter&gt;, int&gt; map;
+
+    OwnPtr&lt;ConstructorDestructorCounter&gt; ownPtr = adoptPtr(new ConstructorDestructorCounter);
+    ConstructorDestructorCounter* ptr = ownPtr.get();
+    map.add(WTF::move(ownPtr), 2);
+
+    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
+    EXPECT_EQ(0u, ConstructorDestructorCounter::destructionCount);
+
+    bool result = map.remove(ptr);
+    EXPECT_EQ(true, result);
+
+    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
+    EXPECT_EQ(1u, ConstructorDestructorCounter::destructionCount);
+}
+
+TEST(WTF_HashMap, OwnPtrKey_TakeUsingRawPointer)
+{
+    ConstructorDestructorCounter::TestingScope scope;
+
+    HashMap&lt;OwnPtr&lt;ConstructorDestructorCounter&gt;, int&gt; map;
+
+    OwnPtr&lt;ConstructorDestructorCounter&gt; ownPtr = adoptPtr(new ConstructorDestructorCounter);
+    ConstructorDestructorCounter* ptr = ownPtr.get();
+    map.add(WTF::move(ownPtr), 2);
+
+    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
+    EXPECT_EQ(0u, ConstructorDestructorCounter::destructionCount);
+
+    int result = map.take(ptr);
+    EXPECT_EQ(2, result);
+
+    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
+    EXPECT_EQ(1u, ConstructorDestructorCounter::destructionCount);
+}
+
+TEST(WTF_HashMap, UniquePtrKey)
+{
+    ConstructorDestructorCounter::TestingScope scope;
+
+    HashMap&lt;std::unique_ptr&lt;ConstructorDestructorCounter&gt;, int&gt; map;
+
+    auto uniquePtr = std::make_unique&lt;ConstructorDestructorCounter&gt;();
+    map.add(WTF::move(uniquePtr), 2);
+
+    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
+    EXPECT_EQ(0u, ConstructorDestructorCounter::destructionCount);
+
+    map.clear();
+    
+    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
+    EXPECT_EQ(1u, ConstructorDestructorCounter::destructionCount);
+}
+
+TEST(WTF_HashMap, UniquePtrKey_CustomDeleter)
+{
+    ConstructorDestructorCounter::TestingScope constructorDestructorCounterScope;
+    DeleterCounter&lt;ConstructorDestructorCounter&gt;::TestingScope deleterCounterScope;
+
+    HashMap&lt;std::unique_ptr&lt;ConstructorDestructorCounter, DeleterCounter&lt;ConstructorDestructorCounter&gt;&gt;, int&gt; map;
+
+    std::unique_ptr&lt;ConstructorDestructorCounter, DeleterCounter&lt;ConstructorDestructorCounter&gt;&gt; uniquePtr(new ConstructorDestructorCounter(), DeleterCounter&lt;ConstructorDestructorCounter&gt;());
+    map.add(WTF::move(uniquePtr), 2);
+
+    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
+    EXPECT_EQ(0u, ConstructorDestructorCounter::destructionCount);
+
+    EXPECT_EQ(0u, DeleterCounter&lt;ConstructorDestructorCounter&gt;::deleterCount);
+
+    map.clear();
+    
+    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
+    EXPECT_EQ(1u, ConstructorDestructorCounter::destructionCount);
+
+    EXPECT_EQ(1u, DeleterCounter&lt;ConstructorDestructorCounter&gt;::deleterCount);
+}
+
+TEST(WTF_HashMap, UniquePtrKey_FindUsingRawPointer)
+{
+    HashMap&lt;std::unique_ptr&lt;int&gt;, int&gt; map;
+
+    auto uniquePtr = std::make_unique&lt;int&gt;(5);
+    int* ptr = uniquePtr.get();
+    map.add(WTF::move(uniquePtr), 2);
+
+    auto it = map.find(ptr);
+    ASSERT_TRUE(it != map.end());
+    EXPECT_EQ(ptr, it-&gt;key.get());
+    EXPECT_EQ(2, it-&gt;value);
+}
+
+TEST(WTF_HashMap, UniquePtrKey_ContainsUsingRawPointer)
+{
+    HashMap&lt;std::unique_ptr&lt;int&gt;, int&gt; map;
+
+    auto uniquePtr = std::make_unique&lt;int&gt;(5);
+    int* ptr = uniquePtr.get();
+    map.add(WTF::move(uniquePtr), 2);
+
+    EXPECT_EQ(true, map.contains(ptr));
+}
+
+TEST(WTF_HashMap, UniquePtrKey_GetUsingRawPointer)
+{
+    HashMap&lt;std::unique_ptr&lt;int&gt;, int&gt; map;
+
+    auto uniquePtr = std::make_unique&lt;int&gt;(5);
+    int* ptr = uniquePtr.get();
+    map.add(WTF::move(uniquePtr), 2);
+
+    int value = map.get(ptr);
+    EXPECT_EQ(2, value);
+}
+
+TEST(WTF_HashMap, UniquePtrKey_RemoveUsingRawPointer)
+{
+    ConstructorDestructorCounter::TestingScope scope;
+
+    HashMap&lt;std::unique_ptr&lt;ConstructorDestructorCounter&gt;, int&gt; map;
+
+    auto uniquePtr = std::make_unique&lt;ConstructorDestructorCounter&gt;();
+    ConstructorDestructorCounter* ptr = uniquePtr.get();
+    map.add(WTF::move(uniquePtr), 2);
+
+    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
+    EXPECT_EQ(0u, ConstructorDestructorCounter::destructionCount);
+
+    bool result = map.remove(ptr);
+    EXPECT_EQ(true, result);
+
+    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
+    EXPECT_EQ(1u, ConstructorDestructorCounter::destructionCount);
+}
+
+TEST(WTF_HashMap, UniquePtrKey_TakeUsingRawPointer)
+{
+    ConstructorDestructorCounter::TestingScope scope;
+
+    HashMap&lt;std::unique_ptr&lt;ConstructorDestructorCounter&gt;, int&gt; map;
+
+    auto uniquePtr = std::make_unique&lt;ConstructorDestructorCounter&gt;();
+    ConstructorDestructorCounter* ptr = uniquePtr.get();
+    map.add(WTF::move(uniquePtr), 2);
+
+    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
+    EXPECT_EQ(0u, ConstructorDestructorCounter::destructionCount);
+
+    int result = map.take(ptr);
+    EXPECT_EQ(2, result);
+
+    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
+    EXPECT_EQ(1u, ConstructorDestructorCounter::destructionCount);
+}
+
</ins><span class="cx"> } // namespace TestWebKitAPI
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestsWTFHashSetcpp"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/Tests/WTF/HashSet.cpp (173800 => 173801)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Tests/WTF/HashSet.cpp        2014-09-22 00:18:50 UTC (rev 173800)
+++ trunk/Tools/TestWebKitAPI/Tests/WTF/HashSet.cpp        2014-09-22 00:24:44 UTC (rev 173801)
</span><span class="lines">@@ -25,10 +25,12 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> 
</span><ins>+#include &quot;Counters.h&quot;
</ins><span class="cx"> #include &quot;MoveOnly.h&quot;
</span><span class="cx"> #include &lt;wtf/HashSet.h&gt;
</span><ins>+#include &lt;wtf/OwnPtr.h&gt;
+#include &lt;wtf/PassOwnPtr.h&gt;
</ins><span class="cx"> 
</span><del>-
</del><span class="cx"> namespace TestWebKitAPI {
</span><span class="cx"> 
</span><span class="cx"> template&lt;int initialCapacity&gt;
</span><span class="lines">@@ -117,4 +119,180 @@
</span><span class="cx">         EXPECT_TRUE(secondSet.contains(MoveOnly(i + 1)));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+TEST(WTF_HashSet, OwnPtrKey)
+{
+    ConstructorDestructorCounter::TestingScope scope;
+
+    HashSet&lt;OwnPtr&lt;ConstructorDestructorCounter&gt;&gt; set;
+
+    OwnPtr&lt;ConstructorDestructorCounter&gt; ownPtr = adoptPtr(new ConstructorDestructorCounter);
+    set.add(WTF::move(ownPtr));
+
+    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
+    EXPECT_EQ(0u, ConstructorDestructorCounter::destructionCount);
+
+    set.clear();
+    
+    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
+    EXPECT_EQ(1u, ConstructorDestructorCounter::destructionCount);
+}
+
+TEST(WTF_HashSet, OwnPtrKey_FindUsingRawPointer)
+{
+    HashSet&lt;OwnPtr&lt;int&gt;&gt; set;
+
+    OwnPtr&lt;int&gt; ownPtr = adoptPtr(new int(5));
+    int* ptr = ownPtr.get();
+    set.add(WTF::move(ownPtr));
+
+    auto it = set.find(ptr);
+    ASSERT_TRUE(it != set.end());
+    EXPECT_EQ(ptr, it-&gt;get());
+    EXPECT_EQ(5, *it-&gt;get());
+}
+
+TEST(WTF_HashSet, OwnPtrKey_ContainsUsingRawPointer)
+{
+    HashSet&lt;OwnPtr&lt;int&gt;&gt; set;
+
+    OwnPtr&lt;int&gt; ownPtr = adoptPtr(new int(5));
+    int* ptr = ownPtr.get();
+    set.add(WTF::move(ownPtr));
+
+    EXPECT_EQ(true, set.contains(ptr));
+}
+
+TEST(WTF_HashSet, OwnPtrKey_RemoveUsingRawPointer)
+{
+    ConstructorDestructorCounter::TestingScope scope;
+
+    HashSet&lt;OwnPtr&lt;ConstructorDestructorCounter&gt;&gt; set;
+
+    OwnPtr&lt;ConstructorDestructorCounter&gt; ownPtr = adoptPtr(new ConstructorDestructorCounter);
+    ConstructorDestructorCounter* ptr = ownPtr.get();
+    set.add(WTF::move(ownPtr));
+
+    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
+    EXPECT_EQ(0u, ConstructorDestructorCounter::destructionCount);
+
+    bool result = set.remove(ptr);
+    EXPECT_EQ(true, result);
+
+    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
+    EXPECT_EQ(1u, ConstructorDestructorCounter::destructionCount);
+}
+
+TEST(WTF_HashSet, OwnPtrKey_TakeUsingRawPointer)
+{
+    ConstructorDestructorCounter::TestingScope scope;
+
+    HashSet&lt;OwnPtr&lt;ConstructorDestructorCounter&gt;&gt; set;
+
+    OwnPtr&lt;ConstructorDestructorCounter&gt; ownPtr = adoptPtr(new ConstructorDestructorCounter);
+    ConstructorDestructorCounter* ptr = ownPtr.get();
+    set.add(WTF::move(ownPtr));
+
+    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
+    EXPECT_EQ(0u, ConstructorDestructorCounter::destructionCount);
+
+    auto result = set.take(ptr);
+    EXPECT_EQ(ptr, result.get());
+
+    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
+    EXPECT_EQ(0u, ConstructorDestructorCounter::destructionCount);
+
+    result = nullptr;
+
+    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
+    EXPECT_EQ(1u, ConstructorDestructorCounter::destructionCount);
+}
+
+TEST(WTF_HashSet, UniquePtrKey)
+{
+    ConstructorDestructorCounter::TestingScope scope;
+
+    HashSet&lt;std::unique_ptr&lt;ConstructorDestructorCounter&gt;&gt; set;
+
+    auto uniquePtr = std::make_unique&lt;ConstructorDestructorCounter&gt;();
+    set.add(WTF::move(uniquePtr));
+
+    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
+    EXPECT_EQ(0u, ConstructorDestructorCounter::destructionCount);
+
+    set.clear();
+
+    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
+    EXPECT_EQ(1u, ConstructorDestructorCounter::destructionCount);
+}
+
+TEST(WTF_HashSet, UniquePtrKey_FindUsingRawPointer)
+{
+    HashSet&lt;std::unique_ptr&lt;int&gt;&gt; set;
+
+    auto uniquePtr = std::make_unique&lt;int&gt;(5);
+    int* ptr = uniquePtr.get();
+    set.add(WTF::move(uniquePtr));
+
+    auto it = set.find(ptr);
+    ASSERT_TRUE(it != set.end());
+    EXPECT_EQ(ptr, it-&gt;get());
+    EXPECT_EQ(5, *it-&gt;get());
+}
+
+TEST(WTF_HashSet, UniquePtrKey_ContainsUsingRawPointer)
+{
+    HashSet&lt;std::unique_ptr&lt;int&gt;&gt; set;
+
+    auto uniquePtr = std::make_unique&lt;int&gt;(5);
+    int* ptr = uniquePtr.get();
+    set.add(WTF::move(uniquePtr));
+
+    EXPECT_EQ(true, set.contains(ptr));
+}
+
+TEST(WTF_HashSet, UniquePtrKey_RemoveUsingRawPointer)
+{
+    ConstructorDestructorCounter::TestingScope scope;
+
+    HashSet&lt;std::unique_ptr&lt;ConstructorDestructorCounter&gt;&gt; set;
+
+    auto uniquePtr = std::make_unique&lt;ConstructorDestructorCounter&gt;();
+    ConstructorDestructorCounter* ptr = uniquePtr.get();
+    set.add(WTF::move(uniquePtr));
+
+    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
+    EXPECT_EQ(0u, ConstructorDestructorCounter::destructionCount);
+
+    bool result = set.remove(ptr);
+    EXPECT_EQ(true, result);
+
+    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
+    EXPECT_EQ(1u, ConstructorDestructorCounter::destructionCount);
+}
+
+TEST(WTF_HashSet, UniquePtrKey_TakeUsingRawPointer)
+{
+    ConstructorDestructorCounter::TestingScope scope;
+
+    HashSet&lt;std::unique_ptr&lt;ConstructorDestructorCounter&gt;&gt; set;
+
+    auto uniquePtr = std::make_unique&lt;ConstructorDestructorCounter&gt;();
+    ConstructorDestructorCounter* ptr = uniquePtr.get();
+    set.add(WTF::move(uniquePtr));
+
+    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
+    EXPECT_EQ(0u, ConstructorDestructorCounter::destructionCount);
+
+    auto result = set.take(ptr);
+    EXPECT_EQ(ptr, result.get());
+
+    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
+    EXPECT_EQ(0u, ConstructorDestructorCounter::destructionCount);
+    
+    result = nullptr;
+
+    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
+    EXPECT_EQ(1u, ConstructorDestructorCounter::destructionCount);
+}
+
</ins><span class="cx"> } // namespace TestWebKitAPI
</span></span></pre>
</div>
</div>

</body>
</html>