mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
278 lines
9.8 KiB
C++
278 lines
9.8 KiB
C++
/*
|
|
* Copyright (C) 2005, 2006, 2007, 2008, 2011 Apple Inc. All rights reserved.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Library General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Library General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Library General Public License
|
|
* along with this library; see the file COPYING.LIB. If not, write to
|
|
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
* Boston, MA 02110-1301, USA.
|
|
*
|
|
*/
|
|
|
|
#ifndef SKY_ENGINE_WTF_HASHSET_H_
|
|
#define SKY_ENGINE_WTF_HASHSET_H_
|
|
|
|
#include "sky/engine/wtf/DefaultAllocator.h"
|
|
#include "sky/engine/wtf/HashTable.h"
|
|
|
|
namespace WTF {
|
|
|
|
struct IdentityExtractor;
|
|
|
|
// Note: empty or deleted values are not allowed, using them may lead to undefined behavior.
|
|
// For pointer valuess this means that null pointers are not allowed unless you supply custom traits.
|
|
template<
|
|
typename ValueArg,
|
|
typename HashArg = typename DefaultHash<ValueArg>::Hash,
|
|
typename TraitsArg = HashTraits<ValueArg>,
|
|
typename Allocator = DefaultAllocator> class HashSet {
|
|
WTF_USE_ALLOCATOR(HashSet, Allocator);
|
|
private:
|
|
typedef HashArg HashFunctions;
|
|
typedef TraitsArg ValueTraits;
|
|
typedef typename ValueTraits::PeekInType ValuePeekInType;
|
|
typedef typename ValueTraits::PassInType ValuePassInType;
|
|
typedef typename ValueTraits::PassOutType ValuePassOutType;
|
|
|
|
public:
|
|
typedef typename ValueTraits::TraitType ValueType;
|
|
|
|
private:
|
|
typedef HashTable<ValueType, ValueType, IdentityExtractor,
|
|
HashFunctions, ValueTraits, ValueTraits, Allocator> HashTableType;
|
|
|
|
public:
|
|
typedef HashTableConstIteratorAdapter<HashTableType, ValueTraits> iterator;
|
|
typedef HashTableConstIteratorAdapter<HashTableType, ValueTraits> const_iterator;
|
|
typedef typename HashTableType::AddResult AddResult;
|
|
|
|
void swap(HashSet& ref)
|
|
{
|
|
m_impl.swap(ref.m_impl);
|
|
}
|
|
|
|
void swap(typename Allocator::template OtherType<HashSet>::Type other)
|
|
{
|
|
HashSet& ref = Allocator::getOther(other);
|
|
m_impl.swap(ref.m_impl);
|
|
}
|
|
|
|
unsigned size() const;
|
|
unsigned capacity() const;
|
|
bool isEmpty() const;
|
|
|
|
iterator begin() const;
|
|
iterator end() const;
|
|
|
|
iterator find(ValuePeekInType) const;
|
|
bool contains(ValuePeekInType) const;
|
|
|
|
// An alternate version of find() that finds the object by hashing and comparing
|
|
// with some other type, to avoid the cost of type conversion. HashTranslator
|
|
// must have the following function members:
|
|
// static unsigned hash(const T&);
|
|
// static bool equal(const ValueType&, const T&);
|
|
template<typename HashTranslator, typename T> iterator find(const T&) const;
|
|
template<typename HashTranslator, typename T> bool contains(const T&) const;
|
|
|
|
// The return value is a pair of an iterator to the new value's location,
|
|
// and a bool that is true if an new entry was added.
|
|
AddResult add(ValuePassInType);
|
|
|
|
// An alternate version of add() that finds the object by hashing and comparing
|
|
// with some other type, to avoid the cost of type conversion if the object is already
|
|
// in the table. HashTranslator must have the following function members:
|
|
// static unsigned hash(const T&);
|
|
// static bool equal(const ValueType&, const T&);
|
|
// static translate(ValueType&, const T&, unsigned hashCode);
|
|
template<typename HashTranslator, typename T> AddResult add(const T&);
|
|
|
|
void remove(ValuePeekInType);
|
|
void remove(iterator);
|
|
void clear();
|
|
template<typename Collection>
|
|
void removeAll(const Collection& toBeRemoved) { WTF::removeAll(*this, toBeRemoved); }
|
|
|
|
static bool isValidValue(ValuePeekInType);
|
|
|
|
ValuePassOutType take(iterator);
|
|
ValuePassOutType take(ValuePeekInType);
|
|
ValuePassOutType takeAny();
|
|
|
|
private:
|
|
HashTableType m_impl;
|
|
};
|
|
|
|
struct IdentityExtractor {
|
|
template<typename T>
|
|
static const T& extract(const T& t) { return t; }
|
|
};
|
|
|
|
template<typename Translator>
|
|
struct HashSetTranslatorAdapter {
|
|
template<typename T> static unsigned hash(const T& key) { return Translator::hash(key); }
|
|
template<typename T, typename U> static bool equal(const T& a, const U& b) { return Translator::equal(a, b); }
|
|
template<typename T, typename U> static void translate(T& location, const U& key, const U&, unsigned hashCode)
|
|
{
|
|
Translator::translate(location, key, hashCode);
|
|
}
|
|
};
|
|
|
|
template<typename T, typename U, typename V, typename W>
|
|
inline unsigned HashSet<T, U, V, W>::size() const
|
|
{
|
|
return m_impl.size();
|
|
}
|
|
|
|
template<typename T, typename U, typename V, typename W>
|
|
inline unsigned HashSet<T, U, V, W>::capacity() const
|
|
{
|
|
return m_impl.capacity();
|
|
}
|
|
|
|
template<typename T, typename U, typename V, typename W>
|
|
inline bool HashSet<T, U, V, W>::isEmpty() const
|
|
{
|
|
return m_impl.isEmpty();
|
|
}
|
|
|
|
template<typename T, typename U, typename V, typename W>
|
|
inline typename HashSet<T, U, V, W>::iterator HashSet<T, U, V, W>::begin() const
|
|
{
|
|
return m_impl.begin();
|
|
}
|
|
|
|
template<typename T, typename U, typename V, typename W>
|
|
inline typename HashSet<T, U, V, W>::iterator HashSet<T, U, V, W>::end() const
|
|
{
|
|
return m_impl.end();
|
|
}
|
|
|
|
template<typename T, typename U, typename V, typename W>
|
|
inline typename HashSet<T, U, V, W>::iterator HashSet<T, U, V, W>::find(ValuePeekInType value) const
|
|
{
|
|
return m_impl.find(value);
|
|
}
|
|
|
|
template<typename Value, typename HashFunctions, typename Traits, typename Allocator>
|
|
inline bool HashSet<Value, HashFunctions, Traits, Allocator>::contains(ValuePeekInType value) const
|
|
{
|
|
return m_impl.contains(value);
|
|
}
|
|
|
|
template<typename Value, typename HashFunctions, typename Traits, typename Allocator>
|
|
template<typename HashTranslator, typename T>
|
|
typename HashSet<Value, HashFunctions, Traits, Allocator>::iterator
|
|
inline HashSet<Value, HashFunctions, Traits, Allocator>::find(const T& value) const
|
|
{
|
|
return m_impl.template find<HashSetTranslatorAdapter<HashTranslator> >(value);
|
|
}
|
|
|
|
template<typename Value, typename HashFunctions, typename Traits, typename Allocator>
|
|
template<typename HashTranslator, typename T>
|
|
inline bool HashSet<Value, HashFunctions, Traits, Allocator>::contains(const T& value) const
|
|
{
|
|
return m_impl.template contains<HashSetTranslatorAdapter<HashTranslator> >(value);
|
|
}
|
|
|
|
template<typename T, typename U, typename V, typename W>
|
|
inline typename HashSet<T, U, V, W>::AddResult HashSet<T, U, V, W>::add(ValuePassInType value)
|
|
{
|
|
return m_impl.add(value);
|
|
}
|
|
|
|
template<typename Value, typename HashFunctions, typename Traits, typename Allocator>
|
|
template<typename HashTranslator, typename T>
|
|
inline typename HashSet<Value, HashFunctions, Traits, Allocator>::AddResult
|
|
HashSet<Value, HashFunctions, Traits, Allocator>::add(const T& value)
|
|
{
|
|
return m_impl.template addPassingHashCode<HashSetTranslatorAdapter<HashTranslator> >(value, value);
|
|
}
|
|
|
|
template<typename T, typename U, typename V, typename W>
|
|
inline void HashSet<T, U, V, W>::remove(iterator it)
|
|
{
|
|
m_impl.remove(it.m_impl);
|
|
}
|
|
|
|
template<typename T, typename U, typename V, typename W>
|
|
inline void HashSet<T, U, V, W>::remove(ValuePeekInType value)
|
|
{
|
|
remove(find(value));
|
|
}
|
|
|
|
template<typename T, typename U, typename V, typename W>
|
|
inline void HashSet<T, U, V, W>::clear()
|
|
{
|
|
m_impl.clear();
|
|
}
|
|
|
|
template<typename T, typename U, typename V, typename W>
|
|
inline bool HashSet<T, U, V, W>::isValidValue(ValuePeekInType value)
|
|
{
|
|
if (ValueTraits::isDeletedValue(value))
|
|
return false;
|
|
|
|
if (HashFunctions::safeToCompareToEmptyOrDeleted) {
|
|
if (value == ValueTraits::emptyValue())
|
|
return false;
|
|
} else {
|
|
if (isHashTraitsEmptyValue<ValueTraits>(value))
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
template<typename T, typename U, typename V, typename W>
|
|
inline typename HashSet<T, U, V, W>::ValuePassOutType HashSet<T, U, V, W>::take(iterator it)
|
|
{
|
|
if (it == end())
|
|
return ValueTraits::emptyValue();
|
|
|
|
ValuePassOutType result = ValueTraits::passOut(const_cast<ValueType&>(*it));
|
|
remove(it);
|
|
|
|
return result;
|
|
}
|
|
|
|
template<typename T, typename U, typename V, typename W>
|
|
inline typename HashSet<T, U, V, W>::ValuePassOutType HashSet<T, U, V, W>::take(ValuePeekInType value)
|
|
{
|
|
return take(find(value));
|
|
}
|
|
|
|
template<typename T, typename U, typename V, typename W>
|
|
inline typename HashSet<T, U, V, W>::ValuePassOutType HashSet<T, U, V, W>::takeAny()
|
|
{
|
|
return take(begin());
|
|
}
|
|
|
|
template<typename C, typename W>
|
|
inline void copyToVector(const C& collection, W& vector)
|
|
{
|
|
typedef typename C::const_iterator iterator;
|
|
|
|
vector.resize(collection.size());
|
|
|
|
iterator it = collection.begin();
|
|
iterator end = collection.end();
|
|
for (unsigned i = 0; it != end; ++it, ++i)
|
|
vector[i] = *it;
|
|
}
|
|
|
|
} // namespace WTF
|
|
|
|
using WTF::HashSet;
|
|
|
|
#endif // SKY_ENGINE_WTF_HASHSET_H_
|