/*
 * Copyright (C) 2005, 2006, 2007, 2008, 2011, 2013, 2017 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.
 *
 */

#pragma once

#include <initializer_list>
#include <wtf/Forward.h>
#include <wtf/GetPtr.h>
#include <wtf/HashTable.h>

namespace WTF {

struct IdentityExtractor;

template<typename ValueArg, typename HashArg, typename TraitsArg>
class HashSet final {
    WTF_MAKE_FAST_ALLOCATED;
private:
    typedef HashArg HashFunctions;
    typedef TraitsArg ValueTraits;
    typedef typename ValueTraits::TakeType TakeType;

public:
    typedef typename ValueTraits::TraitType ValueType;

private:
    typedef HashTable<ValueType, ValueType, IdentityExtractor,
        HashFunctions, ValueTraits, ValueTraits> HashTableType;

public:
    /*
     * Since figuring out the entries of an iterator is confusing, here is a cheat sheet:
     * const KeyType& key = iterator->key;
     */
    typedef HashTableConstIteratorAdapter<HashTableType, ValueType> iterator;
    typedef HashTableConstIteratorAdapter<HashTableType, ValueType> const_iterator;

    /*
     * Since figuring out the entries of an AddResult is confusing, here is a cheat sheet:
     * iterator iter = addResult.iterator;
     * bool isNewEntry = addResult.isNewEntry;
     */
    typedef typename HashTableType::AddResult AddResult;

    HashSet()
    {
    }

    HashSet(std::initializer_list<ValueArg> initializerList)
    {
        for (const auto& value : initializerList)
            add(value);
    }

    void swap(HashSet&);

    unsigned size() const;
    unsigned capacity() const;
    bool isEmpty() const;

    iterator begin() const;
    iterator end() const;

    iterator random() const { return m_impl.random(); }

    iterator find(const ValueType&) const;
    bool contains(const ValueType&) 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 includes both an iterator to the added value's location,
    // and an isNewEntry bool that indicates if it is a new or existing entry in the set.
    AddResult add(const ValueType&);
    AddResult add(ValueType&&);
    void add(std::initializer_list<std::reference_wrapper<const ValueType>>);

    void addVoid(const ValueType&);
    void addVoid(ValueType&&);

    // 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&);
    
    // Attempts to add a list of things to the set. Returns true if any of
    // them are new to the set. Returns false if the set is unchanged.
    template<typename IteratorType>
    bool add(IteratorType begin, IteratorType end);

    bool remove(const ValueType&);
    bool remove(iterator);
    template<typename Functor>
    bool removeIf(const Functor&);
    void clear();

    TakeType take(const ValueType&);
    TakeType take(iterator);
    TakeType 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, TakeType>::type take(typename GetPtrHelper<V>::PtrType);

    static bool isValidValue(const ValueType&);

    template<typename OtherCollection>
    bool operator==(const OtherCollection&) const;
    
    template<typename OtherCollection>
    bool operator!=(const OtherCollection&) const;

    void checkConsistency() const;

private:
    HashTableType m_impl;
};

struct IdentityExtractor {
    template<typename T> static const T& extract(const T& t) { return t; }
};

template<typename ValueTraits, 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)
    { 
        ValueTraits::assignToEmpty(location, std::forward<V>(value));
    }
};

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>
inline void HashSet<T, U, V>::swap(HashSet& other)
{
    m_impl.swap(other.m_impl); 
}

template<typename T, typename U, typename V>
inline unsigned HashSet<T, U, V>::size() const
{
    return m_impl.size(); 
}

template<typename T, typename U, typename V>
inline unsigned HashSet<T, U, V>::capacity() const
{
    return m_impl.capacity(); 
}

template<typename T, typename U, typename V>
inline bool HashSet<T, U, V>::isEmpty() const
{
    return m_impl.isEmpty(); 
}

template<typename T, typename U, typename V>
inline auto HashSet<T, U, V>::begin() const -> iterator
{
    return m_impl.begin(); 
}

template<typename T, typename U, typename V>
inline auto HashSet<T, U, V>::end() const -> iterator
{
    return m_impl.end(); 
}

template<typename T, typename U, typename V>
inline auto HashSet<T, U, V>::find(const ValueType& value) const -> iterator
{
    return m_impl.find(value); 
}

template<typename T, typename U, typename V>
inline bool HashSet<T, U, V>::contains(const ValueType& value) const
{
    return m_impl.contains(value); 
}

template<typename Value, typename HashFunctions, typename Traits>
template<typename HashTranslator, typename T>
inline auto HashSet<Value, HashFunctions, Traits>::find(const T& value) const -> iterator
{
    return m_impl.template find<HashSetTranslatorAdapter<HashTranslator>>(value);
}

template<typename Value, typename HashFunctions, typename Traits>
template<typename HashTranslator, typename T>
inline bool HashSet<Value, HashFunctions, Traits>::contains(const T& value) const
{
    return m_impl.template contains<HashSetTranslatorAdapter<HashTranslator>>(value);
}

template<typename T, typename U, typename V>
inline auto HashSet<T, U, V>::add(const ValueType& value) -> AddResult
{
    return m_impl.add(value);
}

template<typename T, typename U, typename V>
inline auto HashSet<T, U, V>::add(ValueType&& value) -> AddResult
{
    return m_impl.add(WTFMove(value));
}

template<typename T, typename U, typename V>
inline void HashSet<T, U, V>::addVoid(const ValueType& value)
{
    m_impl.add(value);
}

template<typename T, typename U, typename V>
inline void HashSet<T, U, V>::addVoid(ValueType&& value)
{
    m_impl.add(WTFMove(value));
}

template<typename Value, typename HashFunctions, typename Traits>
template<typename HashTranslator, typename T>
inline auto HashSet<Value, HashFunctions, Traits>::add(const T& value) -> AddResult
{
    return m_impl.template addPassingHashCode<HashSetTranslatorAdapter<HashTranslator>>(value, value);
}

template<typename T, typename U, typename V>
template<typename IteratorType>
inline bool HashSet<T, U, V>::add(IteratorType begin, IteratorType end)
{
    bool changed = false;
    for (IteratorType iter = begin; iter != end; ++iter)
        changed |= add(*iter).isNewEntry;
    return changed;
}

template<typename T, typename U, typename V>
inline bool HashSet<T, U, V>::remove(iterator it)
{
    if (it.m_impl == m_impl.end())
        return false;
    m_impl.internalCheckTableConsistency();
    m_impl.removeWithoutEntryConsistencyCheck(it.m_impl);
    return true;
}

template<typename T, typename U, typename V>
inline bool HashSet<T, U, V>::remove(const ValueType& value)
{
    return remove(find(value));
}

template<typename T, typename U, typename V>
template<typename Functor>
inline bool HashSet<T, U, V>::removeIf(const Functor& functor)
{
    return m_impl.removeIf(functor);
}

template<typename T, typename U, typename V>
inline void HashSet<T, U, V>::clear()
{
    m_impl.clear(); 
}

template<typename T, typename U, typename V>
inline auto HashSet<T, U, V>::take(iterator it) -> TakeType
{
    if (it == end())
        return ValueTraits::take(ValueTraits::emptyValue());

    auto result = ValueTraits::take(WTFMove(const_cast<ValueType&>(*it)));
    remove(it);
    return result;
}

template<typename T, typename U, typename V>
inline auto HashSet<T, U, V>::take(const ValueType& value) -> TakeType
{
    return take(find(value));
}

template<typename T, typename U, typename V>
inline auto HashSet<T, U, V>::takeAny() -> TakeType
{
    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<Traits, 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<Traits, 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, TakeType>::type
{
    return take(find(value));
}

template<typename T, typename U, typename V>
inline bool HashSet<T, U, V>::isValidValue(const ValueType& 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>
template<typename OtherCollection>
inline bool HashSet<T, U, V>::operator==(const OtherCollection& otherCollection) const
{
    if (size() != otherCollection.size())
        return false;
    for (const auto& other : otherCollection) {
        if (!contains(other))
            return false;
    }
    return true;
}

template<typename T, typename U, typename V>
template<typename OtherCollection>
inline bool HashSet<T, U, V>::operator!=(const OtherCollection& otherCollection) const
{
    return !(*this == otherCollection);
}

template<typename T, typename U, typename V>
void HashSet<T, U, V>::add(std::initializer_list<std::reference_wrapper<const ValueType>> list)
{
    for (auto& value : list)
        add(value);
}

template<typename T, typename U, typename V>
inline void HashSet<T, U, V>::checkConsistency() const
{
    m_impl.checkTableConsistency();
}

} // namespace WTF

using WTF::HashSet;
