Title: [173801] trunk
Revision
173801
Author
[email protected]
Date
2014-09-21 17:24:44 -0700 (Sun, 21 Sep 2014)

Log Message

Make possible HashSet<std::unique_ptr<>>
https://bugs.webkit.org/show_bug.cgi?id=136166

Reviewed by Darin Adler.

Source/WTF:

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

* wtf/HashFunctions.h:
(WTF::PtrHash<std::unique_ptr<P>>):
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 "smart pointers" that
take the raw pointer type as the parameter. These use SFINAE to make themselves only available
when the IsSmartPtr<KeyType>::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<OwnPtr<P>>::hash):
(WTF::PtrHash<OwnPtr<P>>::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.

Modified Paths

Added Paths

Removed Paths

Diff

Modified: trunk/Source/WTF/ChangeLog (173800 => 173801)


--- 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)
@@ -1,3 +1,48 @@
+2014-09-20  Sam Weinig  <[email protected]>
+
+        Make possible HashSet<std::unique_ptr<>>
+        https://bugs.webkit.org/show_bug.cgi?id=136166
+
+        Reviewed by Darin Adler.
+
+        * wtf/GetPtr.h:
+        (WTF::getPtr):
+        (WTF::GetPtrHelper<std::unique_ptr<T>>::getPtr):
+        Make specializing GetPtrHelper a bit cleaner (you don't have to put 
+        IsSmartPtr<T>::value everywhere any more) and add specializations for
+        std::unique_ptr.
+
+        * wtf/HashFunctions.h:
+        (WTF::PtrHash<std::unique_ptr<P>>):
+        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 "smart pointers" that
+        take the raw pointer type as the parameter. These use SFINAE to make themselves only available
+        when the IsSmartPtr<KeyType>::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<OwnPtr<P>>::hash):
+        (WTF::PtrHash<OwnPtr<P>>::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.
+
 2014-09-19  Chris Dumez  <[email protected]>
 
         Allow DOM methods to return references instead of pointers

Modified: trunk/Source/WTF/wtf/GetPtr.h (173800 => 173801)


--- 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)
@@ -21,6 +21,8 @@
 #ifndef WTF_GetPtr_h
 #define WTF_GetPtr_h
 
+#include <memory>
+
 namespace WTF {
 
 template <typename T> inline T* getPtr(T* p) { return p; }
@@ -30,32 +32,48 @@
 };
 
 template <typename T, bool isSmartPtr>
-struct GetPtrHelper;
+struct GetPtrHelperBase;
 
 template <typename T>
-struct GetPtrHelper<T, false /* isSmartPtr */> {
+struct GetPtrHelperBase<T, false /* isSmartPtr */> {
     typedef T* PtrType;
     static T* getPtr(T& p) { return &p; }
 };
 
 template <typename T>
-struct GetPtrHelper<T, true /* isSmartPtr */> {
+struct GetPtrHelperBase<T, true /* isSmartPtr */> {
     typedef typename T::PtrType PtrType;
     static PtrType getPtr(const T& p) { return p.get(); }
 };
 
 template <typename T>
-inline typename GetPtrHelper<T, IsSmartPtr<T>::value>::PtrType getPtr(T& p)
+struct GetPtrHelper : GetPtrHelperBase<T, IsSmartPtr<T>::value> {
+};
+
+template <typename T>
+inline typename GetPtrHelper<T>::PtrType getPtr(T& p)
 {
-    return GetPtrHelper<T, IsSmartPtr<T>::value>::getPtr(p);
+    return GetPtrHelper<T>::getPtr(p);
 }
 
 template <typename T>
-inline typename GetPtrHelper<T, IsSmartPtr<T>::value>::PtrType getPtr(const T& p)
+inline typename GetPtrHelper<T>::PtrType getPtr(const T& p)
 {
-    return GetPtrHelper<T, IsSmartPtr<T>::value>::getPtr(p);
+    return GetPtrHelper<T>::getPtr(p);
 }
 
+// Explicit specialization for C++ standard library types.
+
+template <typename T, typename Deleter> struct IsSmartPtr<std::unique_ptr<T, Deleter>> {
+    static const bool value = true;
+};
+
+template <typename T, typename Deleter>
+struct GetPtrHelper<std::unique_ptr<T, Deleter>> {
+    typedef T* PtrType;
+    static T* getPtr(const std::unique_ptr<T, Deleter>& p) { return const_cast<T*>(p.get()); }
+};
+
 } // namespace WTF
 
 #endif // WTF_GetPtr_h

Modified: trunk/Source/WTF/wtf/HashFunctions.h (173800 => 173801)


--- 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)
@@ -127,6 +127,7 @@
         static bool equal(T a, T b) { return a == b; }
         static const bool safeToCompareToEmptyOrDeleted = true;
     };
+
     template<typename P> struct PtrHash<RefPtr<P>> : PtrHash<P*> {
         using PtrHash<P*>::hash;
         static unsigned hash(const RefPtr<P>& key) { return hash(key.get()); }
@@ -136,6 +137,15 @@
         static bool equal(const RefPtr<P>& a, P* b) { return a == b; }
     };
 
+    template<typename P, typename Deleter> struct PtrHash<std::unique_ptr<P, Deleter>> : PtrHash<P*> {
+        using PtrHash<P*>::hash;
+        static unsigned hash(const std::unique_ptr<P, Deleter>& key) { return hash(key.get()); }
+        using PtrHash<P*>::equal;
+        static bool equal(const std::unique_ptr<P, Deleter>& a, const std::unique_ptr<P, Deleter>& b) { return a.get() == b.get(); }
+        static bool equal(P* a, const std::unique_ptr<P, Deleter>& b) { return a == b.get(); }
+        static bool equal(const std::unique_ptr<P, Deleter>& a, P* b) { return a.get() == b; }
+    };
+
     // default hash function for each type
 
     template<typename T> struct DefaultHash;
@@ -181,6 +191,7 @@
 
     template<typename P> struct DefaultHash<P*> { typedef PtrHash<P*> Hash; };
     template<typename P> struct DefaultHash<RefPtr<P>> { typedef PtrHash<RefPtr<P>> Hash; };
+    template<typename P, typename Deleter> struct DefaultHash<std::unique_ptr<P, Deleter>> { typedef PtrHash<std::unique_ptr<P, Deleter>> Hash; };
 
     // make IntPairHash the default hash function for pairs of (at most) 32-bit integers.
 

Modified: trunk/Source/WTF/wtf/HashMap.h (173800 => 173801)


--- 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)
@@ -22,6 +22,7 @@
 #define WTF_HashMap_h
 
 #include <initializer_list>
+#include <wtf/GetPtr.h>
 #include <wtf/HashTable.h>
 #include <wtf/IteratorRange.h>
 
@@ -143,6 +144,14 @@
     //   static translate(ValueType&, const T&, unsigned hashCode);
     template<typename HashTranslator, typename K, typename V> AddResult add(K&&, V&&);
 
+    // Overloads for smart pointer keys that take the raw pointer type as the parameter.
+    template<typename K = KeyType> typename std::enable_if<IsSmartPtr<K>::value, iterator>::type find(typename GetPtrHelper<K>::PtrType);
+    template<typename K = KeyType> typename std::enable_if<IsSmartPtr<K>::value, const_iterator>::type find(typename GetPtrHelper<K>::PtrType) const;
+    template<typename K = KeyType> typename std::enable_if<IsSmartPtr<K>::value, bool>::type contains(typename GetPtrHelper<K>::PtrType) const;
+    template<typename K = KeyType> typename std::enable_if<IsSmartPtr<K>::value, MappedPeekType>::type get(typename GetPtrHelper<K>::PtrType) const;
+    template<typename K = KeyType> typename std::enable_if<IsSmartPtr<K>::value, bool>::type remove(typename GetPtrHelper<K>::PtrType);
+    template<typename K = KeyType> typename std::enable_if<IsSmartPtr<K>::value, MappedType>::type take(typename GetPtrHelper<K>::PtrType);
+
     void checkConsistency() const;
 
     static bool isValidKey(const KeyType&);
@@ -386,6 +395,56 @@
 }
 
 template<typename T, typename U, typename V, typename W, typename X>
+template<typename K>
+inline auto HashMap<T, U, V, W, X>::find(typename GetPtrHelper<K>::PtrType key) -> typename std::enable_if<IsSmartPtr<K>::value, iterator>::type
+{
+    return m_impl.template find<HashMapTranslator<KeyValuePairTraits, HashFunctions>>(key);
+}
+
+template<typename T, typename U, typename V, typename W, typename X>
+template<typename K>
+inline auto HashMap<T, U, V, W, X>::find(typename GetPtrHelper<K>::PtrType key) const -> typename std::enable_if<IsSmartPtr<K>::value, const_iterator>::type
+{
+    return m_impl.template find<HashMapTranslator<KeyValuePairTraits, HashFunctions>>(key);
+}
+
+template<typename T, typename U, typename V, typename W, typename X>
+template<typename K>
+inline auto HashMap<T, U, V, W, X>::contains(typename GetPtrHelper<K>::PtrType key) const -> typename std::enable_if<IsSmartPtr<K>::value, bool>::type
+{
+    return m_impl.template contains<HashMapTranslator<KeyValuePairTraits, HashFunctions>>(key);
+}
+
+template<typename T, typename U, typename V, typename W, typename X>
+template<typename K>
+inline auto HashMap<T, U, V, W, X>::get(typename GetPtrHelper<K>::PtrType key) const -> typename std::enable_if<IsSmartPtr<K>::value, MappedPeekType>::type
+{
+    KeyValuePairType* entry = const_cast<HashTableType&>(m_impl).template lookup<HashMapTranslator<KeyValuePairTraits, HashFunctions>>(key);
+    if (!entry)
+        return MappedTraits::peek(MappedTraits::emptyValue());
+    return MappedTraits::peek(entry->value);
+}
+
+template<typename T, typename U, typename V, typename W, typename X>
+template<typename K>
+inline auto HashMap<T, U, V, W, X>::remove(typename GetPtrHelper<K>::PtrType key) -> typename std::enable_if<IsSmartPtr<K>::value, bool>::type
+{
+    return remove(find(key));
+}
+
+template<typename T, typename U, typename V, typename W, typename X>
+template<typename K>
+inline auto HashMap<T, U, V, W, X>::take(typename GetPtrHelper<K>::PtrType key) -> typename std::enable_if<IsSmartPtr<K>::value, MappedType>::type
+{
+    iterator it = find(key);
+    if (it == end())
+        return MappedTraits::emptyValue();
+    MappedType value = WTF::move(it->value);
+    remove(it);
+    return value;
+}
+
+template<typename T, typename U, typename V, typename W, typename X>
 inline void HashMap<T, U, V, W, X>::checkConsistency() const
 {
     m_impl.checkTableConsistency();

Modified: trunk/Source/WTF/wtf/HashSet.h (173800 => 173801)


--- 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)
@@ -23,6 +23,7 @@
 
 #include <initializer_list>
 #include <wtf/FastMalloc.h>
+#include <wtf/GetPtr.h>
 #include <wtf/HashTable.h>
 
 namespace WTF {
@@ -106,6 +107,12 @@
         ValueType take(iterator);
         ValueType takeAny();
 
+        // Overloads for smart pointer values that take the raw pointer type as the parameter.
+        template<typename V = ValueType> typename std::enable_if<IsSmartPtr<V>::value, iterator>::type find(typename GetPtrHelper<V>::PtrType) const;
+        template<typename V = ValueType> typename std::enable_if<IsSmartPtr<V>::value, bool>::type contains(typename GetPtrHelper<V>::PtrType) const;
+        template<typename V = ValueType> typename std::enable_if<IsSmartPtr<V>::value, bool>::type remove(typename GetPtrHelper<V>::PtrType);
+        template<typename V = ValueType> typename std::enable_if<IsSmartPtr<V>::value, ValueType>::type take(typename GetPtrHelper<V>::PtrType);
+
         static bool isValidValue(const ValueType&);
         
         bool operator==(const HashSet&) const;
@@ -118,6 +125,13 @@
         template<typename T> static const T& extract(const T& t) { return t; }
     };
 
+    template<typename HashFunctions>
+    struct HashSetTranslator {
+        template<typename T> static unsigned hash(const T& key) { return HashFunctions::hash(key); }
+        template<typename T, typename U> static bool equal(const T& a, const U& b) { return HashFunctions::equal(a, b); }
+        template<typename T, typename U, typename V> static void translate(T& location, U&&, V&& value) { location = std::forward<V>(value); }
+    };
+
     template<typename Translator>
     struct HashSetTranslatorAdapter {
         template<typename T> static unsigned hash(const T& key) { return Translator::hash(key); }
@@ -264,6 +278,34 @@
         return take(begin());
     }
 
+    template<typename Value, typename HashFunctions, typename Traits>
+    template<typename V>
+    inline auto HashSet<Value, HashFunctions, Traits>::find(typename GetPtrHelper<V>::PtrType value) const -> typename std::enable_if<IsSmartPtr<V>::value, iterator>::type
+    {
+        return m_impl.template find<HashSetTranslator<HashFunctions>>(value);
+    }
+
+    template<typename Value, typename HashFunctions, typename Traits>
+    template<typename V>
+    inline auto HashSet<Value, HashFunctions, Traits>::contains(typename GetPtrHelper<V>::PtrType value) const -> typename std::enable_if<IsSmartPtr<V>::value, bool>::type
+    {
+        return m_impl.template contains<HashSetTranslator<HashFunctions>>(value);
+    }
+
+    template<typename Value, typename HashFunctions, typename Traits>
+    template<typename V>
+    inline auto HashSet<Value, HashFunctions, Traits>::remove(typename GetPtrHelper<V>::PtrType value) -> typename std::enable_if<IsSmartPtr<V>::value, bool>::type
+    {
+        return remove(find(value));
+    }
+
+    template<typename Value, typename HashFunctions, typename Traits>
+    template<typename V>
+    inline auto HashSet<Value, HashFunctions, Traits>::take(typename GetPtrHelper<V>::PtrType value) -> typename std::enable_if<IsSmartPtr<V>::value, ValueType>::type
+    {
+        return take(find(value));
+    }
+
     template<typename T, typename U, typename V>
     inline bool HashSet<T, U, V>::isValidValue(const ValueType& value)
     {

Modified: trunk/Source/WTF/wtf/HashTraits.h (173800 => 173801)


--- 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)
@@ -104,6 +104,9 @@
     typedef std::nullptr_t EmptyValueType;
     static EmptyValueType emptyValue() { return nullptr; }
 
+    static void constructDeletedValue(std::unique_ptr<T, Deleter>& slot) { new (NotNull, &slot) std::unique_ptr<T, Deleter> { reinterpret_cast<T*>(-1) }; }
+    static bool isDeletedValue(const std::unique_ptr<T, Deleter>& value) { return value.get() == reinterpret_cast<T*>(-1); }
+
     typedef T* PeekType;
     static T* peek(const std::unique_ptr<T, Deleter>& value) { return value.get(); }
     static T* peek(std::nullptr_t) { return nullptr; }

Modified: trunk/Source/WTF/wtf/OwnPtr.h (173800 => 173801)


--- 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)
@@ -21,14 +21,15 @@
 #ifndef WTF_OwnPtr_h
 #define WTF_OwnPtr_h
 
+#include <algorithm>
+#include <cstddef>
+#include <memory>
 #include <wtf/Assertions.h>
 #include <wtf/Atomics.h>
 #include <wtf/GetPtr.h>
+#include <wtf/HashTraits.h>
 #include <wtf/Noncopyable.h>
 #include <wtf/OwnPtrCommon.h>
-#include <algorithm>
-#include <cstddef>
-#include <memory>
 
 namespace WTF {
 
@@ -73,6 +74,10 @@
         OwnPtr& operator=(OwnPtr&&);
         template<typename U> OwnPtr& operator=(OwnPtr<U>&&);
 
+        // 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(); }
+
         void swap(OwnPtr& o) { std::swap(m_ptr, o.m_ptr); }
         
         // Construct an object to store into this OwnPtr, but only so long as this OwnPtr
@@ -89,6 +94,8 @@
     private:
         explicit OwnPtr(PtrType ptr) : m_ptr(ptr) { }
 
+        static PtrType hashTableDeletedValue() { return reinterpret_cast<PtrType>(-1); }
+
         // We should never have two OwnPtrs for the same underlying object (otherwise we'll get
         // double-destruction), so these equality operators should never be needed.
         template<typename U> bool operator==(const OwnPtr<U>&) { COMPILE_ASSERT(!sizeof(U*), OwnPtrs_should_never_be_equal); return false; }
@@ -220,6 +227,17 @@
 #endif
     }
 
+    template<typename P> struct PtrHash<OwnPtr<P>> : PtrHash<P*> {
+        using PtrHash<P*>::hash;
+        static unsigned hash(const OwnPtr<P>& key) { return hash(key.get()); }
+        using PtrHash<P*>::equal;
+        static bool equal(const OwnPtr<P>& a, const OwnPtr<P>& b) { return a.get() == b.get(); }
+        static bool equal(P* a, const OwnPtr<P>& b) { return a == b.get(); }
+        static bool equal(const OwnPtr<P>& a, P* b) { return a.get() == b; }
+    };
+
+    template<typename P> struct DefaultHash<OwnPtr<P>> { typedef PtrHash<OwnPtr<P>> Hash; };
+
 } // namespace WTF
 
 using WTF::OwnPtr;

Modified: trunk/Source/WTF/wtf/Ref.h (173800 => 173801)


--- 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)
@@ -75,7 +75,7 @@
 }
 
 template <typename T>
-struct GetPtrHelper<Ref<T>, false /* isSmartPtr */> {
+struct GetPtrHelper<Ref<T>> {
     typedef T* PtrType;
     static T* getPtr(const Ref<T>& p) { return const_cast<T*>(&p.get()); }
 };

Modified: trunk/Tools/ChangeLog (173800 => 173801)


--- trunk/Tools/ChangeLog	2014-09-22 00:18:50 UTC (rev 173800)
+++ trunk/Tools/ChangeLog	2014-09-22 00:24:44 UTC (rev 173801)
@@ -1,3 +1,26 @@
+2014-09-20  Sam Weinig  <[email protected]>
+
+        Make possible HashSet<std::unique_ptr<>>
+        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.
+
 2014-09-21  Youenn Fablet  <[email protected]>
 
         run-webkit-tests should count tests submitted as absolute paths once

Modified: trunk/Tools/TestWebKitAPI/CMakeLists.txt (173800 => 173801)


--- 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)
@@ -65,6 +65,7 @@
 )
 
 set(TestWTF_SOURCES
+    ${TESTWEBKITAPI_DIR}/Counters.cpp
     ${TESTWEBKITAPI_DIR}/TestsController.cpp
     ${TESTWEBKITAPI_DIR}/Tests/WTF/AtomicString.cpp
     ${TESTWEBKITAPI_DIR}/Tests/WTF/CString.cpp

Added: trunk/Tools/TestWebKitAPI/Counters.cpp (0 => 173801)


--- trunk/Tools/TestWebKitAPI/Counters.cpp	                        (rev 0)
+++ trunk/Tools/TestWebKitAPI/Counters.cpp	2014-09-22 00:24:44 UTC (rev 173801)
@@ -0,0 +1,34 @@
+/*
+ * 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 "config.h"
+#include "Counters.h"
+
+unsigned CopyMoveCounter::constructionCount = 0;
+unsigned CopyMoveCounter::copyCount = 0;
+unsigned CopyMoveCounter::moveCount = 0;
+
+unsigned ConstructorDestructorCounter::constructionCount = 0;
+unsigned ConstructorDestructorCounter::destructionCount = 0;

Copied: trunk/Tools/TestWebKitAPI/Counters.h (from rev 173795, trunk/Tools/TestWebKitAPI/Tests/WTF/CopyMoveCounter.h) (0 => 173801)


--- trunk/Tools/TestWebKitAPI/Counters.h	                        (rev 0)
+++ trunk/Tools/TestWebKitAPI/Counters.h	2014-09-22 00:24:44 UTC (rev 173801)
@@ -0,0 +1,88 @@
+/*
+ * 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&) { copyCount++; }
+    CopyMoveCounter& operator=(const CopyMoveCounter&) { copyCount++; return *this; }
+    CopyMoveCounter(CopyMoveCounter&&) { moveCount++; }
+    CopyMoveCounter& operator=(CopyMoveCounter&&) { moveCount++; return *this; }
+};
+
+
+struct ConstructorDestructorCounter {
+    static unsigned constructionCount;
+    static unsigned destructionCount;
+
+    struct TestingScope {
+        TestingScope()
+        {
+            constructionCount = 0;
+            destructionCount = 0;
+        }
+    };
+
+    ConstructorDestructorCounter() { constructionCount++; }
+    ~ConstructorDestructorCounter() { destructionCount++; }
+};
+
+template<typename T>
+struct DeleterCounter {
+    static unsigned deleterCount;
+
+    struct TestingScope {
+        TestingScope()
+        {
+            deleterCount = 0;
+        }
+    };
+
+    void operator()(T* p) const
+    {
+        deleterCount++;
+        delete p;
+    }
+};
+
+template<class T> unsigned DeleterCounter<T>::deleterCount = 0;
+
+#endif // Counters_h

Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPI.vcxproj (173800 => 173801)


--- 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)
@@ -280,11 +280,13 @@
   </ItemDefinitionGroup>
   <ItemGroup>
     <ClInclude Include="..\config.h" />
+    <ClInclude Include="..\Counters.h" />
     <ClInclude Include="..\Test.h" />
     <ClInclude Include="..\TestsController.h" />
     <ClInclude Include="..\win\HostWindow.h" />
   </ItemGroup>
   <ItemGroup>
+    <ClCompile Include="..\Counters.cpp" />
     <ClCompile Include="..\TestsController.cpp" />
     <ClCompile Include="..\Tests\WebCore\LayoutUnit.cpp" />
     <ClCompile Include="..\Tests\WebCore\win\BitmapImage.cpp">

Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.vcxproj/TestWebKitAPI.vcxproj.filters (173800 => 173801)


--- 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)
@@ -22,6 +22,7 @@
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\config.h" />
+    <ClInclude Include="..\Counters.h" />
     <ClInclude Include="..\Test.h" />
     <ClInclude Include="..\TestsController.h" />
     <ClInclude Include="..\win\HostWindow.h">
@@ -29,6 +30,7 @@
     </ClInclude>
   </ItemGroup>
   <ItemGroup>
+    <ClCompile Include="..\Counters.cpp" />
     <ClCompile Include="..\TestsController.cpp" />
     <ClCompile Include="..\win\HostWindow.cpp">
       <Filter>win</Filter>

Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (173800 => 173801)


--- 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)
@@ -119,6 +119,7 @@
 		76E182DA1547550100F1FADD /* WillSendSubmitEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 76E182D91547550100F1FADD /* WillSendSubmitEvent.cpp */; };
 		76E182DD1547569100F1FADD /* WillSendSubmitEvent_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 76E182DC1547569100F1FADD /* WillSendSubmitEvent_Bundle.cpp */; };
 		76E182DF154767E600F1FADD /* auto-submitting-form.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 76E182DE15475A8300F1FADD /* auto-submitting-form.html */; };
+		7C6BBD8C19CEA63000C1F5E0 /* Counters.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C6BBD8B19CEA63000C1F5E0 /* Counters.cpp */; };
 		7C74D42F188228F300E5ED57 /* StringView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C74D42D188228F300E5ED57 /* StringView.cpp */; };
 		7C8DDAAB1735DEEE00EA5AC0 /* CloseThenTerminate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C8DDAA91735DE1D00EA5AC0 /* CloseThenTerminate.cpp */; };
 		7C9ED98B17A19F4B00E4DC33 /* attributedStringStrikethrough.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 7C9ED98A17A19D0600E4DC33 /* attributedStringStrikethrough.html */; };
@@ -463,6 +464,8 @@
 		76E182D91547550100F1FADD /* WillSendSubmitEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WillSendSubmitEvent.cpp; sourceTree = "<group>"; };
 		76E182DC1547569100F1FADD /* WillSendSubmitEvent_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WillSendSubmitEvent_Bundle.cpp; sourceTree = "<group>"; };
 		76E182DE15475A8300F1FADD /* auto-submitting-form.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "auto-submitting-form.html"; sourceTree = "<group>"; };
+		7C6BBD8A19CEA54300C1F5E0 /* Counters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Counters.h; sourceTree = "<group>"; };
+		7C6BBD8B19CEA63000C1F5E0 /* Counters.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Counters.cpp; sourceTree = "<group>"; };
 		7C74D42D188228F300E5ED57 /* StringView.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StringView.cpp; sourceTree = "<group>"; };
 		7C8DDAA91735DE1D00EA5AC0 /* CloseThenTerminate.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CloseThenTerminate.cpp; sourceTree = "<group>"; };
 		7C9ED98A17A19D0600E4DC33 /* attributedStringStrikethrough.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = attributedStringStrikethrough.html; sourceTree = "<group>"; };
@@ -670,6 +673,8 @@
 				2E9660DC16C07D7B00371B42 /* ios */,
 				BCA61C3A11700B9400460D1E /* mac */,
 				BC131A9E1171317C00B69727 /* config.h */,
+				7C6BBD8A19CEA54300C1F5E0 /* Counters.h */,
+				7C6BBD8B19CEA63000C1F5E0 /* Counters.cpp */,
 				C0ADBE7A12FCA4D000D2C129 /* _javascript_Test.cpp */,
 				C0ADBE7B12FCA4D000D2C129 /* _javascript_Test.h */,
 				BC575BBF126F5752006F0F12 /* PlatformUtilities.cpp */,
@@ -1384,6 +1389,7 @@
 				BC7B61AA129A038700D174A4 /* WKPreferences.cpp in Sources */,
 				BC90995E12567BC100083756 /* WKString.cpp in Sources */,
 				BC9099941256ACF100083756 /* WKStringJSString.cpp in Sources */,
+				7C6BBD8C19CEA63000C1F5E0 /* Counters.cpp in Sources */,
 				265AF55015D1E48A00B0CB4A /* WTFString.cpp in Sources */,
 				2E7765CD16C4D80A00BA2BB1 /* mainIOS.mm in Sources */,
 				2E7765CF16C4D81100BA2BB1 /* mainMac.mm in Sources */,

Deleted: trunk/Tools/TestWebKitAPI/Tests/WTF/CopyMoveCounter.h (173800 => 173801)


--- 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)
@@ -1,54 +0,0 @@
-/*
- * 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&) { copyCount++; }
-    CopyMoveCounter& operator=(const CopyMoveCounter&) { copyCount++; return *this; }
-    CopyMoveCounter(CopyMoveCounter&&) { moveCount++; }
-    CopyMoveCounter& operator=(CopyMoveCounter&&) { moveCount++; return *this; }
-};
-
-unsigned CopyMoveCounter::constructionCount = 0;
-unsigned CopyMoveCounter::copyCount = 0;
-unsigned CopyMoveCounter::moveCount = 0;
-
-#endif

Modified: trunk/Tools/TestWebKitAPI/Tests/WTF/HashMap.cpp (173800 => 173801)


--- 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)
@@ -25,11 +25,13 @@
 
 #include "config.h"
 
-#include "CopyMoveCounter.h"
+#include "Counters.h"
 #include "MoveOnly.h"
 #include <string>
 #include <wtf/HashMap.h>
 #include <wtf/text/StringHash.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
 
 namespace TestWebKitAPI {
 
@@ -171,4 +173,217 @@
     }
 }
 
+TEST(WTF_HashMap, OwnPtrKey)
+{
+    ConstructorDestructorCounter::TestingScope scope;
+
+    HashMap<OwnPtr<ConstructorDestructorCounter>, int> map;
+
+    OwnPtr<ConstructorDestructorCounter> 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<OwnPtr<int>, int> map;
+
+    OwnPtr<int> 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->key.get());
+    EXPECT_EQ(2, it->value);
+}
+
+TEST(WTF_HashMap, OwnPtrKey_ContainsUsingRawPointer)
+{
+    HashMap<OwnPtr<int>, int> map;
+
+    OwnPtr<int> 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<OwnPtr<int>, int> map;
+
+    OwnPtr<int> 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<OwnPtr<ConstructorDestructorCounter>, int> map;
+
+    OwnPtr<ConstructorDestructorCounter> 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<OwnPtr<ConstructorDestructorCounter>, int> map;
+
+    OwnPtr<ConstructorDestructorCounter> 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<std::unique_ptr<ConstructorDestructorCounter>, int> map;
+
+    auto uniquePtr = std::make_unique<ConstructorDestructorCounter>();
+    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<ConstructorDestructorCounter>::TestingScope deleterCounterScope;
+
+    HashMap<std::unique_ptr<ConstructorDestructorCounter, DeleterCounter<ConstructorDestructorCounter>>, int> map;
+
+    std::unique_ptr<ConstructorDestructorCounter, DeleterCounter<ConstructorDestructorCounter>> uniquePtr(new ConstructorDestructorCounter(), DeleterCounter<ConstructorDestructorCounter>());
+    map.add(WTF::move(uniquePtr), 2);
+
+    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
+    EXPECT_EQ(0u, ConstructorDestructorCounter::destructionCount);
+
+    EXPECT_EQ(0u, DeleterCounter<ConstructorDestructorCounter>::deleterCount);
+
+    map.clear();
+    
+    EXPECT_EQ(1u, ConstructorDestructorCounter::constructionCount);
+    EXPECT_EQ(1u, ConstructorDestructorCounter::destructionCount);
+
+    EXPECT_EQ(1u, DeleterCounter<ConstructorDestructorCounter>::deleterCount);
+}
+
+TEST(WTF_HashMap, UniquePtrKey_FindUsingRawPointer)
+{
+    HashMap<std::unique_ptr<int>, int> map;
+
+    auto uniquePtr = std::make_unique<int>(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->key.get());
+    EXPECT_EQ(2, it->value);
+}
+
+TEST(WTF_HashMap, UniquePtrKey_ContainsUsingRawPointer)
+{
+    HashMap<std::unique_ptr<int>, int> map;
+
+    auto uniquePtr = std::make_unique<int>(5);
+    int* ptr = uniquePtr.get();
+    map.add(WTF::move(uniquePtr), 2);
+
+    EXPECT_EQ(true, map.contains(ptr));
+}
+
+TEST(WTF_HashMap, UniquePtrKey_GetUsingRawPointer)
+{
+    HashMap<std::unique_ptr<int>, int> map;
+
+    auto uniquePtr = std::make_unique<int>(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<std::unique_ptr<ConstructorDestructorCounter>, int> map;
+
+    auto uniquePtr = std::make_unique<ConstructorDestructorCounter>();
+    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<std::unique_ptr<ConstructorDestructorCounter>, int> map;
+
+    auto uniquePtr = std::make_unique<ConstructorDestructorCounter>();
+    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);
+}
+
 } // namespace TestWebKitAPI

Modified: trunk/Tools/TestWebKitAPI/Tests/WTF/HashSet.cpp (173800 => 173801)


--- 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)
@@ -25,10 +25,12 @@
 
 #include "config.h"
 
+#include "Counters.h"
 #include "MoveOnly.h"
 #include <wtf/HashSet.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
 
-
 namespace TestWebKitAPI {
 
 template<int initialCapacity>
@@ -117,4 +119,180 @@
         EXPECT_TRUE(secondSet.contains(MoveOnly(i + 1)));
 }
 
+TEST(WTF_HashSet, OwnPtrKey)
+{
+    ConstructorDestructorCounter::TestingScope scope;
+
+    HashSet<OwnPtr<ConstructorDestructorCounter>> set;
+
+    OwnPtr<ConstructorDestructorCounter> 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<OwnPtr<int>> set;
+
+    OwnPtr<int> 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->get());
+    EXPECT_EQ(5, *it->get());
+}
+
+TEST(WTF_HashSet, OwnPtrKey_ContainsUsingRawPointer)
+{
+    HashSet<OwnPtr<int>> set;
+
+    OwnPtr<int> 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<OwnPtr<ConstructorDestructorCounter>> set;
+
+    OwnPtr<ConstructorDestructorCounter> 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<OwnPtr<ConstructorDestructorCounter>> set;
+
+    OwnPtr<ConstructorDestructorCounter> 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<std::unique_ptr<ConstructorDestructorCounter>> set;
+
+    auto uniquePtr = std::make_unique<ConstructorDestructorCounter>();
+    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<std::unique_ptr<int>> set;
+
+    auto uniquePtr = std::make_unique<int>(5);
+    int* ptr = uniquePtr.get();
+    set.add(WTF::move(uniquePtr));
+
+    auto it = set.find(ptr);
+    ASSERT_TRUE(it != set.end());
+    EXPECT_EQ(ptr, it->get());
+    EXPECT_EQ(5, *it->get());
+}
+
+TEST(WTF_HashSet, UniquePtrKey_ContainsUsingRawPointer)
+{
+    HashSet<std::unique_ptr<int>> set;
+
+    auto uniquePtr = std::make_unique<int>(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<std::unique_ptr<ConstructorDestructorCounter>> set;
+
+    auto uniquePtr = std::make_unique<ConstructorDestructorCounter>();
+    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<std::unique_ptr<ConstructorDestructorCounter>> set;
+
+    auto uniquePtr = std::make_unique<ConstructorDestructorCounter>();
+    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);
+}
+
 } // namespace TestWebKitAPI
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to