/*
 * Copyright 2013 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SkTDynamicHash_DEFINED
#define SkTDynamicHash_DEFINED

// This is now a simple API wrapper around THashTable<T*>;
// please just use SkTHash{Map,Set,Table} directly for new code.
#include "src/core/SkTHash.h"

// Traits requires:
//   static const Key& GetKey(const T&) { ... }
//   static uint32_t Hash(const Key&) { ... }
// We'll look on T for these by default, or you can pass a custom Traits type.
template <typename T,
          typename Key,
          typename Traits = T>
class SkTDynamicHash {
public:
    SkTDynamicHash() {}

    // It is not safe to call set() or remove() while iterating with either foreach().
    // If you mutate the entries be very careful not to change the Key.

    template <typename Fn>  // f(T*)
    void foreach(Fn&& fn) {
        fTable.foreach([&](T** entry) { fn(*entry); });
    }
    template <typename Fn>  // f(T) or f(const T&)
    void foreach(Fn&& fn) const {
        fTable.foreach([&](T* entry) { fn(*entry); });
    }

    int count() const { return fTable.count(); }

    size_t approxBytesUsed() const { return fTable.approxBytesUsed(); }

    T* find(const Key& key) const { return fTable.findOrNull(key); }

    void add(T* entry) { fTable.set(entry); }
    void remove(const Key& key) { fTable.remove(key); }

    void rewind() { fTable.reset(); }
    void reset () { fTable.reset(); }

private:
    struct AdaptedTraits {
        static const Key& GetKey(T* entry) { return Traits::GetKey(*entry); }
        static uint32_t Hash(const Key& key) { return Traits::Hash(key); }
    };
    skia_private::THashTable<T*, Key, AdaptedTraits> fTable;
};

#endif
