Modified: trunk/Source/WTF/wtf/HashMap.h (155620 => 155621)
--- trunk/Source/WTF/wtf/HashMap.h 2013-09-12 16:07:23 UTC (rev 155620)
+++ trunk/Source/WTF/wtf/HashMap.h 2013-09-12 16:13:47 UTC (rev 155621)
@@ -99,7 +99,7 @@
// replaces value but not key if key is already present
// return value is a pair of the iterator to the key location,
// and a boolean that's true if a new value was actually added
- AddResult set(const KeyType&, MappedPassInType);
+ template<typename V> AddResult set(const KeyType&, V&&);
// does nothing if key is already present
// return value is a pair of the iterator to the key location,
@@ -134,7 +134,8 @@
static bool isValidKey(const KeyType&);
private:
- AddResult inlineAdd(const KeyType&, MappedPassInReferenceType);
+ template<typename T>
+ AddResult inlineAdd(const KeyType&, T&&);
HashTableType m_impl;
};
@@ -226,10 +227,10 @@
struct HashMapTranslator {
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, const U& key, const V& mapped)
+ template<typename T, typename U, typename V> static void translate(T& location, const U& key, V&& mapped)
{
location.key = key;
- ValueTraits::ValueTraits::store(mapped, location.value);
+ location.value = std::forward<V>(mapped);
}
};
@@ -333,19 +334,21 @@
return m_impl.template contains<HashMapTranslatorAdapter<ValueTraits, HashTranslator>>(value);
}
- template<typename T, typename U, typename V, typename W, typename X>
- auto HashMap<T, U, V, W, X>::inlineAdd(const KeyType& key, MappedPassInReferenceType mapped) -> AddResult
+ template<typename KeyArg, typename MappedArg, typename HashArg, typename KeyTraitsArg, typename MappedTraitsArg>
+ template<typename T>
+ auto HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg>::inlineAdd(const KeyType& key, T&& mapped) -> AddResult
{
- return m_impl.template add<HashMapTranslator<ValueTraits, HashFunctions>>(key, mapped);
+ return m_impl.template add<HashMapTranslator<ValueTraits, HashFunctions>>(key, std::forward<T>(mapped));
}
- template<typename T, typename U, typename V, typename W, typename X>
- auto HashMap<T, U, V, W, X>::set(const KeyType& key, MappedPassInType mapped) -> AddResult
+ template<typename KeyArg, typename MappedArg, typename HashArg, typename KeyTraitsArg, typename MappedTraitsArg>
+ template<typename T>
+ auto HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg>::set(const KeyType& key, T&& mapped) -> AddResult
{
- AddResult result = inlineAdd(key, mapped);
+ AddResult result = inlineAdd(key, std::forward<T>(mapped));
if (!result.isNewEntry) {
// The inlineAdd call above found an existing hash table entry; we need to set the mapped value.
- MappedTraits::store(mapped, result.iterator->value);
+ result.iterator->value = std::forward<T>(mapped);
}
return result;
}
Modified: trunk/Source/WTF/wtf/HashTraits.h (155620 => 155621)
--- trunk/Source/WTF/wtf/HashTraits.h 2013-09-12 16:07:23 UTC (rev 155620)
+++ trunk/Source/WTF/wtf/HashTraits.h 2013-09-12 16:13:47 UTC (rev 155621)
@@ -201,16 +201,17 @@
{
}
- KeyValuePair(const KeyTypeArg& key, const ValueTypeArg& value)
- : key(key)
- , value(value)
+ template<typename K, typename V>
+ KeyValuePair(K&& key, V&& value)
+ : key(std::forward<K>(key))
+ , value(std::forward<V>(value))
{
}
template <typename OtherKeyType, typename OtherValueType>
- KeyValuePair(const KeyValuePair<OtherKeyType, OtherValueType>& other)
- : key(other.key)
- , value(other.value)
+ KeyValuePair(KeyValuePair<OtherKeyType, OtherValueType>&& other)
+ : key(std::forward<OtherKeyType>(other.key))
+ , value(std::forward<OtherValueType>(other.value))
{
}
Modified: trunk/Tools/TestWebKitAPI/Tests/WTF/HashMap.cpp (155620 => 155621)
--- trunk/Tools/TestWebKitAPI/Tests/WTF/HashMap.cpp 2013-09-12 16:07:23 UTC (rev 155620)
+++ trunk/Tools/TestWebKitAPI/Tests/WTF/HashMap.cpp 2013-09-12 16:13:47 UTC (rev 155621)
@@ -25,13 +25,14 @@
#include "config.h"
+#include "MoveOnly.h"
#include <wtf/HashMap.h>
namespace TestWebKitAPI {
typedef WTF::HashMap<int, int> IntHashMap;
-TEST(WTF, HashTableIteratorComparison)
+TEST(WTF_HashMap, HashTableIteratorComparison)
{
IntHashMap map;
map.add(1, 2);
@@ -60,7 +61,7 @@
return DefaultHash<double>::Hash::hash(key) & (TestDoubleHashTraits::minimumTableSize - 1);
}
-TEST(WTF, DoubleHashCollisions)
+TEST(WTF_HashMap, DoubleHashCollisions)
{
// The "clobber" 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
@@ -81,4 +82,24 @@
ASSERT_EQ(map.get(negativeZeroKey), 3);
}
+TEST(WTF_HashMap, MoveOnly)
+{
+ HashMap<unsigned, MoveOnly> moveOnlyValues;
+
+ for (size_t i = 0; i < 100; ++i) {
+ MoveOnly moveOnly(i + 1);
+ moveOnlyValues.set(i + 1, std::move(moveOnly));
+ }
+
+ for (size_t i = 0; i < 100; ++i) {
+ auto it = moveOnlyValues.find(i + 1);
+ ASSERT_FALSE(it == moveOnlyValues.end());
+ }
+
+ for (size_t i = 0; i < 100; ++i)
+ ASSERT_TRUE(moveOnlyValues.remove(i + 1));
+
+ ASSERT_TRUE(moveOnlyValues.isEmpty());
+}
+
} // namespace TestWebKitAPI