<!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>[196791] 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/196791">196791</a></dd>
<dt>Author</dt> <dd>bfulgham@apple.com</dd>
<dt>Date</dt> <dd>2016-02-18 17:14:07 -0800 (Thu, 18 Feb 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Extend HashCountedSet with a method to efficiently set the count of an entry
https://bugs.webkit.org/show_bug.cgi?id=154352

Reviewed by Geoffrey Garen.

Source/WebCore:

Tested by new TestWebKitAPI tests.

* loader/ResourceLoadStatistics.cpp:
(WebCore::decodeHashCountedSet): Update to use new HashCountedSet::add method.

Source/WTF:

Tested by new TestWebKitAPI tests.

Update the HashCountedSet class with a new 'add' method to support efficient initialization of
the count of a given key. Also provide move and pointer template specializations to expand the
types of data that can be used as 'keys' in the HashCountedSet to match the underlying HashMap
implementation.

* wtf/HashCountedSet.h:
(WTF::Traits&gt;::add): Added new overload supporting a supplied count.

Tools:

* TestWebKitAPI/CMakeLists.txt: Add new HashCountedSet test files.
* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: Ditto.
* TestWebKitAPI/Tests/WTF/HashCountedSet.cpp: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWTFChangeLog">trunk/Source/WTF/ChangeLog</a></li>
<li><a href="#trunkSourceWTFwtfHashCountedSeth">trunk/Source/WTF/wtf/HashCountedSet.h</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreloaderResourceLoadStatisticscpp">trunk/Source/WebCore/loader/ResourceLoadStatistics.cpp</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="#trunkToolsTestWebKitAPITestWebKitAPIxcodeprojprojectpbxproj">trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkToolsTestWebKitAPITestsWTFHashCountedSetcpp">trunk/Tools/TestWebKitAPI/Tests/WTF/HashCountedSet.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (196790 => 196791)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/ChangeLog        2016-02-19 01:13:15 UTC (rev 196790)
+++ trunk/Source/WTF/ChangeLog        2016-02-19 01:14:07 UTC (rev 196791)
</span><span class="lines">@@ -1,3 +1,20 @@
</span><ins>+2016-02-18  Brent Fulgham  &lt;bfulgham@apple.com&gt;
+
+        Extend HashCountedSet with a method to efficiently set the count of an entry
+        https://bugs.webkit.org/show_bug.cgi?id=154352
+
+        Reviewed by Geoffrey Garen.
+
+        Tested by new TestWebKitAPI tests.
+
+        Update the HashCountedSet class with a new 'add' method to support efficient initialization of
+        the count of a given key. Also provide move and pointer template specializations to expand the
+        types of data that can be used as 'keys' in the HashCountedSet to match the underlying HashMap
+        implementation.
+
+        * wtf/HashCountedSet.h:
+        (WTF::Traits&gt;::add): Added new overload supporting a supplied count.
+
</ins><span class="cx"> 2016-02-17  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Remove LLVM dependencies from WebKit
</span></span></pre></div>
<a id="trunkSourceWTFwtfHashCountedSeth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/HashCountedSet.h (196790 => 196791)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/HashCountedSet.h        2016-02-19 01:13:15 UTC (rev 196790)
+++ trunk/Source/WTF/wtf/HashCountedSet.h        2016-02-19 01:14:07 UTC (rev 196791)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2005, 2006, 2008, 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2005, 2006, 2008, 2013, 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * This library is free software; you can redistribute it and/or
</span><span class="cx">  * modify it under the terms of the GNU Library General Public
</span><span class="lines">@@ -21,6 +21,7 @@
</span><span class="cx"> #ifndef WTF_HashCountedSet_h
</span><span class="cx"> #define WTF_HashCountedSet_h
</span><span class="cx"> 
</span><ins>+#include &lt;initializer_list&gt;
</ins><span class="cx"> #include &lt;wtf/Assertions.h&gt;
</span><span class="cx"> #include &lt;wtf/HashMap.h&gt;
</span><span class="cx"> #include &lt;wtf/Vector.h&gt;
</span><span class="lines">@@ -37,6 +38,22 @@
</span><span class="cx">         typedef typename ImplType::iterator iterator;
</span><span class="cx">         typedef typename ImplType::const_iterator const_iterator;
</span><span class="cx">         typedef typename ImplType::AddResult AddResult;
</span><ins>+
+        HashCountedSet()
+        {
+        }
+
+        HashCountedSet(std::initializer_list&lt;typename ImplType::KeyValuePairType&gt; initializerList)
+        {
+            for (const auto&amp; keyValuePair : initializerList)
+                add(keyValuePair.key, keyValuePair.value);
+        }
+
+        HashCountedSet(std::initializer_list&lt;typename ImplType::KeyType&gt; initializerList)
+        {
+            for (const auto&amp; value : initializerList)
+                add(value);
+        }
</ins><span class="cx">         
</span><span class="cx">         void swap(HashCountedSet&amp;);
</span><span class="cx">         
</span><span class="lines">@@ -59,7 +76,12 @@
</span><span class="cx">         // The return value includes both an iterator to the value's location,
</span><span class="cx">         // and an isNewEntry bool that indicates whether it is a new or existing entry.
</span><span class="cx">         AddResult add(const ValueType&amp;);
</span><del>-        
</del><ins>+        AddResult add(ValueType&amp;&amp;);
+
+        // Increments the count of a value by the passed amount.
+        AddResult add(const ValueType&amp;, unsigned);
+        AddResult add(ValueType&amp;&amp;, unsigned);
+
</ins><span class="cx">         // Decrements the count of the value, and removes it if count goes down to zero.
</span><span class="cx">         // Returns true if the value is removed.
</span><span class="cx">         bool remove(const ValueType&amp;);
</span><span class="lines">@@ -73,10 +95,18 @@
</span><span class="cx">         // Clears the whole set.
</span><span class="cx">         void clear();
</span><span class="cx"> 
</span><ins>+        // Overloads for smart pointer keys 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);
+        template&lt;typename V = ValueType&gt; typename std::enable_if&lt;IsSmartPtr&lt;V&gt;::value, const_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, unsigned&gt;::type count(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);
+
</ins><span class="cx">     private:
</span><span class="cx">         ImplType m_impl;
</span><span class="cx">     };
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     template&lt;typename Value, typename HashFunctions, typename Traits&gt;
</span><span class="cx">     inline void HashCountedSet&lt;Value, HashFunctions, Traits&gt;::swap(HashCountedSet&amp; other)
</span><span class="cx">     {
</span><span class="lines">@@ -156,8 +186,32 @@
</span><span class="cx">         ++result.iterator-&gt;value;
</span><span class="cx">         return result;
</span><span class="cx">     }
</span><ins>+
+    template&lt;typename Value, typename HashFunctions, typename Traits&gt;
+    inline typename HashCountedSet&lt;Value, HashFunctions, Traits&gt;::AddResult HashCountedSet&lt;Value, HashFunctions, Traits&gt;::add(ValueType&amp;&amp; value)
+    {
+        AddResult result = m_impl.add(std::forward&lt;Value&gt;(value), 0);
+        ++result.iterator-&gt;value;
+        return result;
+    }
+
+    template&lt;typename Value, typename HashFunctions, typename Traits&gt;
+    inline typename HashCountedSet&lt;Value, HashFunctions, Traits&gt;::AddResult HashCountedSet&lt;Value, HashFunctions, Traits&gt;::add(const ValueType&amp; value, unsigned count)
+    {
+        AddResult result = m_impl.add(value, 0);
+        result.iterator-&gt;value += count;
+        return result;
+    }
</ins><span class="cx">     
</span><span class="cx">     template&lt;typename Value, typename HashFunctions, typename Traits&gt;
</span><ins>+    inline typename HashCountedSet&lt;Value, HashFunctions, Traits&gt;::AddResult HashCountedSet&lt;Value, HashFunctions, Traits&gt;::add(ValueType&amp;&amp; value, unsigned count)
+    {
+        AddResult result = m_impl.add(std::forward&lt;Value&gt;(value), 0);
+        result.iterator-&gt;value += count;
+        return result;
+    }
+    
+    template&lt;typename Value, typename HashFunctions, typename Traits&gt;
</ins><span class="cx">     inline bool HashCountedSet&lt;Value, HashFunctions, Traits&gt;::remove(const ValueType&amp; value)
</span><span class="cx">     {
</span><span class="cx">         return remove(find(value));
</span><span class="lines">@@ -229,8 +283,42 @@
</span><span class="cx">             vector[i] = (*it).key;
</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 HashCountedSet&lt;Value, HashFunctions, Traits&gt;::find(typename GetPtrHelper&lt;V&gt;::PtrType value) -&gt; typename std::enable_if&lt;IsSmartPtr&lt;V&gt;::value, iterator&gt;::type
+    {
+        return m_impl.template find(value);
+    }
+    
+    template&lt;typename Value, typename HashFunctions, typename Traits&gt;
+    template&lt;typename V&gt;
+    inline auto HashCountedSet&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, const_iterator&gt;::type
+    {
+        return m_impl.template find(value);
+    }
+    
+    template&lt;typename Value, typename HashFunctions, typename Traits&gt;
+    template&lt;typename V&gt;
+    inline auto HashCountedSet&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(value);
+    }
+    
+    template&lt;typename Value, typename HashFunctions, typename Traits&gt;
+    template&lt;typename V&gt;
+    inline auto HashCountedSet&lt;Value, HashFunctions, Traits&gt;::count(typename GetPtrHelper&lt;V&gt;::PtrType value) const -&gt; typename std::enable_if&lt;IsSmartPtr&lt;V&gt;::value, unsigned&gt;::type
+    {
+        return m_impl.template get(value);
+    }
+    
+    template&lt;typename Value, typename HashFunctions, typename Traits&gt;
+    template&lt;typename V&gt;
+    inline auto HashCountedSet&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));
+    }
</ins><span class="cx"> 
</span><del>-} // namespace khtml
</del><ins>+} // namespace WTF
</ins><span class="cx"> 
</span><span class="cx"> using WTF::HashCountedSet;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (196790 => 196791)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-02-19 01:13:15 UTC (rev 196790)
+++ trunk/Source/WebCore/ChangeLog        2016-02-19 01:14:07 UTC (rev 196791)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2016-02-18  Brent Fulgham  &lt;bfulgham@apple.com&gt;
+
+        Extend HashCountedSet with a method to efficiently set the count of an entry
+        https://bugs.webkit.org/show_bug.cgi?id=154352
+
+        Reviewed by Geoffrey Garen.
+
+        Tested by new TestWebKitAPI tests.
+
+        * loader/ResourceLoadStatistics.cpp:
+        (WebCore::decodeHashCountedSet): Update to use new HashCountedSet::add method.
+
</ins><span class="cx"> 2016-02-18  Simon Fraser  &lt;simon.fraser@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Wheel event callback removing the window causes crash in WebCore.
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderResourceLoadStatisticscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/ResourceLoadStatistics.cpp (196790 => 196791)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/ResourceLoadStatistics.cpp        2016-02-19 01:13:15 UTC (rev 196790)
+++ trunk/Source/WebCore/loader/ResourceLoadStatistics.cpp        2016-02-19 01:14:07 UTC (rev 196791)
</span><span class="lines">@@ -124,10 +124,8 @@
</span><span class="cx">         unsigned count;
</span><span class="cx">         if (!decoderInner.decodeUInt32(&quot;count&quot;, count))
</span><span class="cx">             return false;
</span><del>-        
-        // FIXME: Create a HashCountedSet method to do this efficiently
-        for (unsigned i = 0; i &lt; count; ++i)
-            hashCountedSet.add(origin);
</del><ins>+
+        hashCountedSet.add(origin, count);
</ins><span class="cx">         return true;
</span><span class="cx">     });
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (196790 => 196791)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2016-02-19 01:13:15 UTC (rev 196790)
+++ trunk/Tools/ChangeLog        2016-02-19 01:14:07 UTC (rev 196791)
</span><span class="lines">@@ -1,3 +1,14 @@
</span><ins>+2016-02-18  Brent Fulgham  &lt;bfulgham@apple.com&gt;
+
+        Extend HashCountedSet with a method to efficiently set the count of an entry
+        https://bugs.webkit.org/show_bug.cgi?id=154352
+
+        Reviewed by Geoffrey Garen.
+
+        * TestWebKitAPI/CMakeLists.txt: Add new HashCountedSet test files.
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: Ditto.
+        * TestWebKitAPI/Tests/WTF/HashCountedSet.cpp: Added.
+
</ins><span class="cx"> 2016-02-18  Anders Carlsson  &lt;andersca@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Get rid of the --target-web-process and --use-web-process-xpc-service options.
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPICMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/CMakeLists.txt (196790 => 196791)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/CMakeLists.txt        2016-02-19 01:13:15 UTC (rev 196790)
+++ trunk/Tools/TestWebKitAPI/CMakeLists.txt        2016-02-19 01:14:07 UTC (rev 196791)
</span><span class="lines">@@ -47,6 +47,7 @@
</span><span class="cx">     ${TESTWEBKITAPI_DIR}/Tests/WTF/DateMath.cpp
</span><span class="cx">     ${TESTWEBKITAPI_DIR}/Tests/WTF/Deque.cpp
</span><span class="cx">     ${TESTWEBKITAPI_DIR}/Tests/WTF/Functional.cpp
</span><ins>+    ${TESTWEBKITAPI_DIR}/Tests/WTF/HashCountedSet.cpp
</ins><span class="cx">     ${TESTWEBKITAPI_DIR}/Tests/WTF/HashMap.cpp
</span><span class="cx">     ${TESTWEBKITAPI_DIR}/Tests/WTF/HashSet.cpp
</span><span class="cx">     ${TESTWEBKITAPI_DIR}/Tests/WTF/IntegerToStringConversion.cpp
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestWebKitAPIxcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (196790 => 196791)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj        2016-02-19 01:13:15 UTC (rev 196790)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj        2016-02-19 01:14:07 UTC (rev 196791)
</span><span class="lines">@@ -79,6 +79,7 @@
</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><span class="cx">                 7A1458FC1AD5C07000E06772 /* mouse-button-listener.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 7A1458FB1AD5C03500E06772 /* mouse-button-listener.html */; };
</span><ins>+                7A38D7E61C752D5F004F157D /* HashCountedSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7A38D7E51C752D5F004F157D /* HashCountedSet.cpp */; };
</ins><span class="cx">                 7A5623111AD5AF3E0096B920 /* MenuTypesForMouseEvents.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7A5623101AD5AF3E0096B920 /* MenuTypesForMouseEvents.cpp */; };
</span><span class="cx">                 7A99D9941AD4A29D00373141 /* MenuTypesForMouseEvents.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7A99D9931AD4A29D00373141 /* MenuTypesForMouseEvents.mm */; };
</span><span class="cx">                 7AA021BB1AB09EA70052953F /* DateMath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7AA021BA1AB09EA70052953F /* DateMath.cpp */; };
</span><span class="lines">@@ -610,6 +611,7 @@
</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><span class="cx">                 7A1458FB1AD5C03500E06772 /* mouse-button-listener.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = &quot;mouse-button-listener.html&quot;; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                7A38D7E51C752D5F004F157D /* HashCountedSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HashCountedSet.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 7A5623101AD5AF3E0096B920 /* MenuTypesForMouseEvents.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MenuTypesForMouseEvents.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 7A99D9931AD4A29D00373141 /* MenuTypesForMouseEvents.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MenuTypesForMouseEvents.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 7AA021BA1AB09EA70052953F /* DateMath.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DateMath.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -1228,6 +1230,7 @@
</span><span class="cx">                                 7AA021BA1AB09EA70052953F /* DateMath.cpp */,
</span><span class="cx">                                 E4A757D3178AEA5B00B5D7A4 /* Deque.cpp */,
</span><span class="cx">                                 1AA9E55714980A9900001A8A /* Functional.cpp */,
</span><ins>+                                7A38D7E51C752D5F004F157D /* HashCountedSet.cpp */,
</ins><span class="cx">                                 0BCD833414857CE400EA2003 /* HashMap.cpp */,
</span><span class="cx">                                 26B2DFF815BDE599004F691D /* HashSet.cpp */,
</span><span class="cx">                                 266FAFD215E5775200F61D5B /* IntegerToStringConversion.cpp */,
</span><span class="lines">@@ -1863,6 +1866,7 @@
</span><span class="cx">                                 9B0786A31C58830F00D159E3 /* InjectedBundleMakeAllShadowRootsOpen.cpp in Sources */,
</span><span class="cx">                                 1A4F81CC1BDFFD37004E672E /* RemoteObjectRegistry.mm in Sources */,
</span><span class="cx">                                 51CB4AD81B3A079C00C1B1C6 /* ModalAlertsSPI.cpp in Sources */,
</span><ins>+                                7A38D7E61C752D5F004F157D /* HashCountedSet.cpp in Sources */,
</ins><span class="cx">                                 9B7916501BD89D0D00D50B8F /* FirstResponderScrollingPosition.mm in Sources */,
</span><span class="cx">                                 1CF0D3791BBF2F3D00B4EF54 /* WKRetainPtr.cpp in Sources */,
</span><span class="cx">                                 26F6E1F01ADC749B00DE696B /* DFAMinimizer.cpp in Sources */,
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestsWTFHashCountedSetcpp"></a>
<div class="addfile"><h4>Added: trunk/Tools/TestWebKitAPI/Tests/WTF/HashCountedSet.cpp (0 => 196791)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Tests/WTF/HashCountedSet.cpp                                (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WTF/HashCountedSet.cpp        2016-02-19 01:14:07 UTC (rev 196791)
</span><span class="lines">@@ -0,0 +1,468 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2011 Google 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;
+#include &quot;MoveOnly.h&quot;
+#include &quot;RefLogger.h&quot;
+#include &lt;string&gt;
+#include &lt;wtf/HashCountedSet.h&gt;
+#include &lt;wtf/text/StringHash.h&gt;
+
+namespace TestWebKitAPI {
+    
+typedef WTF::HashCountedSet&lt;int&gt; IntHashCountedSet;
+
+TEST(WTF_HashCountedSet, HashTableIteratorComparison)
+{
+    IntHashCountedSet hashCountedSet;
+    hashCountedSet.add(1);
+    ASSERT_TRUE(hashCountedSet.begin() != hashCountedSet.end());
+    ASSERT_FALSE(hashCountedSet.begin() == hashCountedSet.end());
+    
+    IntHashCountedSet::const_iterator begin = hashCountedSet.begin();
+    ASSERT_TRUE(begin == hashCountedSet.begin());
+    ASSERT_TRUE(hashCountedSet.begin() == begin);
+    ASSERT_TRUE(begin != hashCountedSet.end());
+    ASSERT_TRUE(hashCountedSet.end() != begin);
+    ASSERT_FALSE(begin != hashCountedSet.begin());
+    ASSERT_FALSE(hashCountedSet.begin() != begin);
+    ASSERT_FALSE(begin == hashCountedSet.end());
+    ASSERT_FALSE(hashCountedSet.end() == begin);
+}
+
+struct TestDoubleHashTraits : HashTraits&lt;double&gt; {
+    static const int minimumTableSize = 8;
+};
+
+typedef HashCountedSet&lt;double, DefaultHash&lt;double&gt;::Hash, TestDoubleHashTraits&gt; DoubleHashCountedSet;
+
+static int bucketForKey(double key)
+{
+    return DefaultHash&lt;double&gt;::Hash::hash(key) &amp; (TestDoubleHashTraits::minimumTableSize - 1);
+}
+
+TEST(WTF_HashCountedSet, DoubleHashCollisions)
+{
+    // The &quot;clobber&quot; key here is one that ends up stealing the bucket that the -0 key
+    // originally wants to be in. This makes the 0 and -0 keys collide and the test then
+    // fails unless the FloatHash::equals() implementation can distinguish them.
+    const double clobberKey = 6;
+    const double zeroKey = 0;
+    const double negativeZeroKey = -zeroKey;
+    
+    DoubleHashCountedSet hashCountedSet;
+    
+    hashCountedSet.add(clobberKey);
+
+    ASSERT_EQ(hashCountedSet.count(clobberKey), 1u);
+    ASSERT_EQ(hashCountedSet.count(zeroKey), 0u);
+    ASSERT_EQ(hashCountedSet.count(negativeZeroKey), 0u);
+
+    hashCountedSet.add(zeroKey);
+    hashCountedSet.add(negativeZeroKey);
+    
+    ASSERT_EQ(bucketForKey(clobberKey), bucketForKey(negativeZeroKey));
+    ASSERT_EQ(hashCountedSet.count(clobberKey), 1u);
+    ASSERT_EQ(hashCountedSet.count(zeroKey), 1u);
+    ASSERT_EQ(hashCountedSet.count(negativeZeroKey), 1u);
+
+    hashCountedSet.add(clobberKey);
+    hashCountedSet.add(zeroKey);
+    hashCountedSet.add(negativeZeroKey);
+    
+    ASSERT_EQ(hashCountedSet.count(clobberKey), 2u);
+    ASSERT_EQ(hashCountedSet.count(zeroKey), 2u);
+    ASSERT_EQ(hashCountedSet.count(negativeZeroKey), 2u);
+
+    hashCountedSet.add(clobberKey, 12);
+    hashCountedSet.add(zeroKey, 15);
+    hashCountedSet.add(negativeZeroKey, 17);
+    
+    ASSERT_EQ(hashCountedSet.count(clobberKey), 14u);
+    ASSERT_EQ(hashCountedSet.count(zeroKey), 17u);
+    ASSERT_EQ(hashCountedSet.count(negativeZeroKey), 19u);
+}
+
+TEST(WTF_HashCountedSet, DoubleHashCollisionsInitialCount)
+{
+    // The &quot;clobber&quot; key here is one that ends up stealing the bucket that the -0 key
+    // originally wants to be in. This makes the 0 and -0 keys collide and the test then
+    // fails unless the FloatHash::equals() implementation can distinguish them.
+    const double clobberKey = 6;
+    const double zeroKey = 0;
+    const double negativeZeroKey = -zeroKey;
+    
+    DoubleHashCountedSet hashCountedSet;
+    
+    hashCountedSet.add(clobberKey, 5);
+    
+    ASSERT_EQ(hashCountedSet.count(clobberKey), 5u);
+    ASSERT_EQ(hashCountedSet.count(zeroKey), 0u);
+    ASSERT_EQ(hashCountedSet.count(negativeZeroKey), 0u);
+    
+    hashCountedSet.add(zeroKey, 22);
+    hashCountedSet.add(negativeZeroKey, 0);
+    
+    ASSERT_EQ(bucketForKey(clobberKey), bucketForKey(negativeZeroKey));
+    ASSERT_EQ(hashCountedSet.count(clobberKey), 5u);
+    ASSERT_EQ(hashCountedSet.count(zeroKey), 22u);
+    ASSERT_EQ(hashCountedSet.count(negativeZeroKey), 0u);
+    
+    hashCountedSet.add(clobberKey);
+    hashCountedSet.add(zeroKey);
+    hashCountedSet.add(negativeZeroKey);
+    
+    ASSERT_EQ(hashCountedSet.count(clobberKey), 6u);
+    ASSERT_EQ(hashCountedSet.count(zeroKey), 23u);
+    ASSERT_EQ(hashCountedSet.count(negativeZeroKey), 1u);
+}
+
+
+TEST(WTF_HashCountedSet, MoveOnlyKeys)
+{
+    HashCountedSet&lt;MoveOnly&gt; moveOnlyKeys;
+    
+    for (size_t i = 0; i &lt; 100; ++i) {
+        MoveOnly moveOnly(i + 1);
+        moveOnlyKeys.add(WTFMove(moveOnly));
+    }
+    
+    for (size_t i = 0; i &lt; 100; ++i) {
+        auto it = moveOnlyKeys.find(MoveOnly(i + 1));
+        ASSERT_FALSE(it == moveOnlyKeys.end());
+        ASSERT_EQ(it-&gt;value, 1u);
+    }
+    
+    for (size_t i = 0; i &lt; 100; ++i)
+        ASSERT_FALSE(moveOnlyKeys.add(MoveOnly(i + 1)).isNewEntry);
+    
+    for (size_t i = 0; i &lt; 100; ++i)
+        ASSERT_FALSE(moveOnlyKeys.remove(MoveOnly(i + 1)));
+
+    for (size_t i = 0; i &lt; 100; ++i)
+        ASSERT_TRUE(moveOnlyKeys.remove(MoveOnly(i + 1)));
+
+    ASSERT_TRUE(moveOnlyKeys.isEmpty());
+}
+
+TEST(WTF_HashCountedSet, MoveOnlyKeysInitialCount)
+{
+    HashCountedSet&lt;MoveOnly&gt; moveOnlyKeys;
+    
+    for (size_t i = 0; i &lt; 100; ++i) {
+        MoveOnly moveOnly(i + 1);
+        moveOnlyKeys.add(WTFMove(moveOnly), i + 1);
+    }
+    
+    for (size_t i = 0; i &lt; 100; ++i) {
+        auto it = moveOnlyKeys.find(MoveOnly(i + 1));
+        ASSERT_FALSE(it == moveOnlyKeys.end());
+        ASSERT_EQ(it-&gt;value, i + 1);
+    }
+    
+    for (size_t i = 0; i &lt; 100; ++i)
+        ASSERT_FALSE(moveOnlyKeys.add(MoveOnly(i + 1)).isNewEntry);
+    
+    for (size_t i = 0; i &lt; 100; ++i)
+        ASSERT_EQ(moveOnlyKeys.count(MoveOnly(i + 1)), i + 2);
+    
+    for (size_t i = 0; i &lt; 100; ++i)
+        ASSERT_FALSE(moveOnlyKeys.remove(MoveOnly(i + 1)));
+
+    for (size_t i = 0; i &lt; 100; ++i)
+        ASSERT_EQ(moveOnlyKeys.count(MoveOnly(i + 1)), i + 1);
+}
+
+TEST(WTF_HashCountedSet, InitializerList)
+{
+    HashCountedSet&lt;String&gt; hashCountedSet = {
+        &quot;one&quot;,
+        &quot;two&quot;,
+        &quot;three&quot;,
+        &quot;four&quot;,
+        &quot;four&quot;,
+        &quot;four&quot;,
+        &quot;four&quot;,
+    };
+    
+    EXPECT_EQ(4u, hashCountedSet.size());
+    
+    EXPECT_EQ(hashCountedSet.count(&quot;one&quot;), 1u);
+    EXPECT_EQ(hashCountedSet.count(&quot;two&quot;), 1u);
+    EXPECT_EQ(hashCountedSet.count(&quot;three&quot;), 1u);
+    EXPECT_EQ(hashCountedSet.count(&quot;four&quot;), 4u);
+}
+
+TEST(WTF_HashCountedSet, InitializerListInitialCount)
+{
+    HashCountedSet&lt;String&gt; hashCountedSet = {
+        { String(&quot;one&quot;), 1u },
+        { String(&quot;two&quot;), 2u },
+        { String(&quot;three&quot;), 3u },
+        { String(&quot;four&quot;), 4u },
+    };
+    
+    EXPECT_EQ(4u, hashCountedSet.size());
+    
+    EXPECT_EQ(hashCountedSet.count(&quot;one&quot;), 1u);
+    EXPECT_EQ(hashCountedSet.count(&quot;two&quot;), 2u);
+    EXPECT_EQ(hashCountedSet.count(&quot;three&quot;), 3u);
+    EXPECT_EQ(hashCountedSet.count(&quot;four&quot;), 4u);
+}
+
+TEST(WTF_HashCountedSet, UniquePtrKey)
+{
+    ConstructorDestructorCounter::TestingScope scope;
+    
+    HashCountedSet&lt;std::unique_ptr&lt;ConstructorDestructorCounter&gt;&gt; hashCountedSet;
+    
+    auto uniquePtr = std::make_unique&lt;ConstructorDestructorCounter&gt;();
+    hashCountedSet.add(WTFMove(uniquePtr));
+    
+    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
+    EXPECT_EQ(0u, ConstructorDestructorCounter::destructionCount);
+    
+    hashCountedSet.clear();
+    
+    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
+    EXPECT_EQ(1u, ConstructorDestructorCounter::destructionCount);
+}
+
+TEST(WTF_HashCountedSet, UniquePtrKeyInitialCount)
+{
+    ConstructorDestructorCounter::TestingScope scope;
+    
+    HashCountedSet&lt;std::unique_ptr&lt;ConstructorDestructorCounter&gt;&gt; hashCountedSet;
+    
+    auto uniquePtr = std::make_unique&lt;ConstructorDestructorCounter&gt;();
+    hashCountedSet.add(WTFMove(uniquePtr), 12);
+    
+    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
+    EXPECT_EQ(0u, ConstructorDestructorCounter::destructionCount);
+    
+    hashCountedSet.clear();
+    
+    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
+    EXPECT_EQ(1u, ConstructorDestructorCounter::destructionCount);
+}
+
+TEST(WTF_HashCountedSet, UniquePtrKey_CustomDeleter)
+{
+    ConstructorDestructorCounter::TestingScope constructorDestructorCounterScope;
+    DeleterCounter&lt;ConstructorDestructorCounter&gt;::TestingScope deleterCounterScope;
+    
+    HashCountedSet&lt;std::unique_ptr&lt;ConstructorDestructorCounter, DeleterCounter&lt;ConstructorDestructorCounter&gt;&gt;&gt; hashCountedSet;
+    
+    std::unique_ptr&lt;ConstructorDestructorCounter, DeleterCounter&lt;ConstructorDestructorCounter&gt;&gt; uniquePtr(new ConstructorDestructorCounter(), DeleterCounter&lt;ConstructorDestructorCounter&gt;());
+    hashCountedSet.add(WTFMove(uniquePtr));
+    
+    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
+    EXPECT_EQ(0u, ConstructorDestructorCounter::destructionCount);
+    
+    EXPECT_EQ(0u, DeleterCounter&lt;ConstructorDestructorCounter&gt;::deleterCount);
+    
+    hashCountedSet.clear();
+    
+    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
+    EXPECT_EQ(1u, ConstructorDestructorCounter::destructionCount);
+    
+    EXPECT_EQ(1u, DeleterCounter&lt;ConstructorDestructorCounter&gt;::deleterCount);
+}
+
+TEST(WTF_HashCountedSet, UniquePtrKey_FindUsingRawPointer)
+{
+    HashCountedSet&lt;std::unique_ptr&lt;int&gt;&gt; hashCountedSet;
+    
+    auto uniquePtr = std::make_unique&lt;int&gt;(5);
+    int* ptr = uniquePtr.get();
+    hashCountedSet.add(WTFMove(uniquePtr));
+    
+    auto it = hashCountedSet.find(ptr);
+    ASSERT_TRUE(it != hashCountedSet.end());
+    EXPECT_EQ(ptr, it-&gt;key.get());
+    EXPECT_EQ(1u, it-&gt;value);
+}
+
+TEST(WTF_HashCountedSet, UniquePtrKey_ContainsUsingRawPointer)
+{
+    HashCountedSet&lt;std::unique_ptr&lt;int&gt;&gt; hashCountedSet;
+    
+    auto uniquePtr = std::make_unique&lt;int&gt;(5);
+    int* ptr = uniquePtr.get();
+    hashCountedSet.add(WTFMove(uniquePtr));
+    
+    EXPECT_EQ(true, hashCountedSet.contains(ptr));
+}
+
+TEST(WTF_HashCountedSet, UniquePtrKey_GetUsingRawPointer)
+{
+    HashCountedSet&lt;std::unique_ptr&lt;int&gt;&gt; hashCountedSet;
+    
+    auto uniquePtr = std::make_unique&lt;int&gt;(5);
+    int* ptr = uniquePtr.get();
+    hashCountedSet.add(WTFMove(uniquePtr));
+    
+    int value = hashCountedSet.count(ptr);
+    EXPECT_EQ(1, value);
+}
+
+TEST(WTF_HashCountedSet, UniquePtrKey_RemoveUsingRawPointer)
+{
+    ConstructorDestructorCounter::TestingScope scope;
+    
+    HashCountedSet&lt;std::unique_ptr&lt;ConstructorDestructorCounter&gt;&gt; hashCountedSet;
+    
+    auto uniquePtr = std::make_unique&lt;ConstructorDestructorCounter&gt;();
+    ConstructorDestructorCounter* ptr = uniquePtr.get();
+    hashCountedSet.add(WTFMove(uniquePtr));
+    
+    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
+    EXPECT_EQ(0u, ConstructorDestructorCounter::destructionCount);
+    
+    bool result = hashCountedSet.remove(ptr);
+    EXPECT_EQ(true, result);
+    
+    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
+    EXPECT_EQ(1u, ConstructorDestructorCounter::destructionCount);
+}
+
+TEST(WTF_HashCountedSet, RefPtrKey_Add)
+{
+    HashCountedSet&lt;RefPtr&lt;RefLogger&gt;&gt; hashCountedSet;
+    
+    DerivedRefLogger a(&quot;a&quot;);
+    RefPtr&lt;RefLogger&gt; ptr(&amp;a);
+    hashCountedSet.add(ptr);
+    
+    ASSERT_STREQ(&quot;ref(a) ref(a) &quot;, takeLogStr().c_str());
+    EXPECT_EQ(1U, hashCountedSet.count(ptr));
+    EXPECT_EQ(1U, hashCountedSet.count(ptr.get()));
+}
+
+TEST(WTF_HashCountedSet, RefPtrKey_AddUsingRelease)
+{
+    HashCountedSet&lt;RefPtr&lt;RefLogger&gt;&gt; hashCountedSet;
+    
+    DerivedRefLogger a(&quot;a&quot;);
+    RefPtr&lt;RefLogger&gt; ptr(&amp;a);
+    hashCountedSet.add(ptr.release());
+    
+    EXPECT_STREQ(&quot;ref(a) &quot;, takeLogStr().c_str());
+}
+
+TEST(WTF_HashCountedSet, RefPtrKey_AddUsingMove)
+{
+    HashCountedSet&lt;RefPtr&lt;RefLogger&gt;&gt; hashCountedSet;
+    
+    DerivedRefLogger a(&quot;a&quot;);
+    RefPtr&lt;RefLogger&gt; ptr(&amp;a);
+    hashCountedSet.add(WTFMove(ptr));
+    
+    EXPECT_STREQ(&quot;ref(a) &quot;, takeLogStr().c_str());
+}
+
+TEST(WTF_HashCountedSet, RefPtrKey_AddUsingRaw)
+{
+    HashCountedSet&lt;RefPtr&lt;RefLogger&gt;&gt; hashCountedSet;
+    
+    DerivedRefLogger a(&quot;a&quot;);
+    RefPtr&lt;RefLogger&gt; ptr(&amp;a);
+    hashCountedSet.add(ptr.get());
+    
+    EXPECT_STREQ(&quot;ref(a) ref(a) &quot;, takeLogStr().c_str());
+    EXPECT_EQ(1U, hashCountedSet.count(ptr));
+    EXPECT_EQ(1U, hashCountedSet.count(ptr.get()));
+}
+
+TEST(WTF_HashCountedSet, RefPtrKey_AddKeyAlreadyPresent)
+{
+    HashCountedSet&lt;RefPtr&lt;RefLogger&gt;&gt; hashCountedSet;
+    
+    DerivedRefLogger a(&quot;a&quot;);
+    
+    {
+        RefPtr&lt;RefLogger&gt; ptr(&amp;a);
+        hashCountedSet.add(ptr);
+    }
+    
+    EXPECT_STREQ(&quot;ref(a) ref(a) deref(a) &quot;, takeLogStr().c_str());
+    
+    {
+        RefPtr&lt;RefLogger&gt; ptr2(&amp;a);
+        auto addResult = hashCountedSet.add(ptr2);
+        EXPECT_FALSE(addResult.isNewEntry);
+    }
+    
+    EXPECT_STREQ(&quot;ref(a) deref(a) &quot;, takeLogStr().c_str());
+}
+
+TEST(WTF_HashCountedSet, RefPtrKey_AddUsingReleaseKeyAlreadyPresent)
+{
+    HashCountedSet&lt;RefPtr&lt;RefLogger&gt;&gt; hashCountedSet;
+    
+    DerivedRefLogger a(&quot;a&quot;);
+    
+    {
+        RefPtr&lt;RefLogger&gt; ptr(&amp;a);
+        hashCountedSet.add(ptr);
+    }
+    
+    EXPECT_STREQ(&quot;ref(a) ref(a) deref(a) &quot;, takeLogStr().c_str());
+    
+    {
+        RefPtr&lt;RefLogger&gt; ptr2(&amp;a);
+        auto addResult = hashCountedSet.add(ptr2.release());
+        EXPECT_FALSE(addResult.isNewEntry);
+    }
+    
+    EXPECT_STREQ(&quot;ref(a) deref(a) &quot;, takeLogStr().c_str());
+}
+
+TEST(WTF_HashCountedSet, RefPtrKey_AddUsingMoveKeyAlreadyPresent)
+{
+    HashCountedSet&lt;RefPtr&lt;RefLogger&gt;&gt; hashCountedSet;
+    
+    DerivedRefLogger a(&quot;a&quot;);
+    
+    {
+        RefPtr&lt;RefLogger&gt; ptr(&amp;a);
+        hashCountedSet.add(ptr);
+    }
+    
+    EXPECT_STREQ(&quot;ref(a) ref(a) deref(a) &quot;, takeLogStr().c_str());
+    
+    {
+        RefPtr&lt;RefLogger&gt; ptr2(&amp;a);
+        auto addResult = hashCountedSet.add(WTFMove(ptr2));
+        EXPECT_FALSE(addResult.isNewEntry);
+    }
+    
+    EXPECT_STREQ(&quot;ref(a) deref(a) &quot;, takeLogStr().c_str());
+}
+    
+} // namespace TestWebKitAPI
</ins></span></pre>
</div>
</div>

</body>
</html>