/** \file */

#ifndef _CITY_HASHER_HH
#define _CITY_HASHER_HH

#include <city.h>
#include <string>

/*! CityHasher is a std::hash-style wrapper around CityHash. We
 *  encourage using CityHasher instead of the default std::hash if
 *  possible. */
template <class Key> class CityHasher {
public:
  //! The function call operator for our hash function
  size_t operator()(const Key &k) const {
    if (sizeof(size_t) < 8) {
      return CityHash32((const char *)&k, sizeof(k));
    }
    /* Although the following line should be optimized away on 32-bit
     * builds, the cast is still necessary to stop MSVC emitting a
     * truncation warning. */
    return static_cast<size_t>(CityHash64((const char *)&k, sizeof(k)));
  }
};

/*! This is a template specialization of CityHasher for
 *  std::string. */
template <> class CityHasher<std::string> {
public:
  //! The function call operator for our hash function
  size_t operator()(const std::string &k) const {
    if (sizeof(size_t) < 8) {
      return CityHash32(k.c_str(), k.size());
    }
    /* Although the following line should be optimized away on 32-bit
     * builds, the cast is still necessary to stop MSVC emitting a
     * truncation warning. */
    return static_cast<size_t>(CityHash64(k.c_str(), k.size()));
  }
};

#endif // _CITY_HASHER_HH
