/*
 * 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_
