<commit_before>---
title: "`absl::Hash`"
layout: docs
sidenav: side-nav-cpp.html
type: markdown
---

# `absl::Hash`

The `absl::Hash` library consists of the following components:

*   `absl::Hash<T>`, a concrete hash functor object, which you can use out of
    the box
*   A generic hashing framework for specializing hashing behavior and making
    user-defined types hashable

This library is designed to be used as a replacement for
[`std::hash`](http://en.cppreference.com/w/cpp/utility/hash) and the various
other hash functors used in google3. It provides several advantages over them:

*   It can hash objects of almost any standard type, including `std::pair`,
    `std::tuple`, and most standard containers
*   It can be extended to support user-defined types. Our goal is that if it
    makes sense to hash an object of type `Foo`, then `absl::Hash<Foo>` will
    just work. These extensions are easy to write and efficient to execute.
*   The underlying hash algorithm can be changed without modifying user code,
    which allows us to improve it over time. For example, to improve performance
    and to defend against some hash-flooding attacks.

The `absl::Hash` framework is the default hash implementation for "Swiss tables"
`absl::{flat,node}_hash_{set,map}` and does not need to be explicitly specified
when working with that library.


## **TL;DR** How Do I Make My Type Hashable?

To make your type hashable, add a friend function like:

```c++
class Circle {
 public:
  ...

  template <typename H>
  friend H AbslHashValue(H h, const Circle& c) {
    return H::combine(std::move(h), c.center_, c.radius_);
  }

  ...

 private:
  std::pair<int, int> center_;
  int radius_;
};
```

where `H` refers to the existing `HashState`. If you need anything more complex
than this, please see
[Making Your User-Defined Types Hashable](#making-hashable-types) below.

To test your hash function, add a test like:

```c++
TEST(Circle, Hash) {
  EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly({
      Circle(),
      Circle(1, 2),
      Circle(2, 3),
      Circle(0, 0),
  }));
}
```

where the values passed should provide coverage for all interesting states of
the object.

For more complex cases, please see
[Testing Your Custom `AbslHashValue` Implementation](#testing-hashable-types)
below.

## Using `absl::Hash`

The `absl::Hash` framework is the default hash implementation for the "Swiss
table" hash tables. All types hashable by the `absl::Hash` framework will
automatically be hashable within Swiss tables.


For other hash table implementations, `absl::Hash` can be used just like any
other hash functor:

```c++
#include "third_party/absl/hash/hash.h"

std::unordered_map<MyKey, MyValue, absl::Hash<MyKey>> my_map;
```

Of course, this works only if `MyKey` is hashable by `absl::Hash`, i.e.
`absl::Hash` supports the `MyKey` type.

NOTE: the hash codes computed by `absl::Hash` are not guaranteed to be stable
across different runs of your program. In fact, in the usual case it randomly
seeds itself at program startup.

### Intrinsic Type Support

`absl::Hash` intrinsically supports the following types:

*   All integral types (including bool)
*   All enum types
*   All floating-point types (although hashing them is discouraged; we guarantee
    that `0.0` and `-0.0` produce the same hash)
*   All pointer types, including `nullptr_t`. Note that the pointer itself is
    hashed, not the value it points to.
*   `std::pair<T1, T2>`, if `T1` and `T2` are hashable
*   `std::tuple<Ts...>`, if all the `Ts...` are hashable
*   `std::unique_ptr` and `std::shared_ptr` (as with plain pointers, the pointer
    itself is hashed, not the value it points to)
*   All string-like types including:
    *   `absl::string_view`
    *   `std::string`
    *   `std::string_view` (as well as any instance of `std::basic_string` that
        uses `char` and `std::char_traits`)
*   All the standard sequence containers (provided the elements are hashable)
*   All the standard ordered associative containers (provided the elements are
    hashable)
*   absl types such as the following:
    *   `absl::InlinedVector`
    *   `absl::FixedArray`
    *   `absl::unit128`
    *   `absl::Time`, `absl::Duration`, and `absl::TimeZone`

NOTE: the list above is not meant to be exhaustive. Additional type support<commit_msg>Fix absl::unit128 -> absl::uint128 typo<commit_after>---
title: "`absl::Hash`"
layout: docs
sidenav: side-nav-cpp.html
type: markdown
---

# `absl::Hash`

The `absl::Hash` library consists of the following components:

*   `absl::Hash<T>`, a concrete hash functor object, which you can use out of
    the box
*   A generic hashing framework for specializing hashing behavior and making
    user-defined types hashable

This library is designed to be used as a replacement for
[`std::hash`](http://en.cppreference.com/w/cpp/utility/hash) and the various
other hash functors used in google3. It provides several advantages over them:

*   It can hash objects of almost any standard type, including `std::pair`,
    `std::tuple`, and most standard containers
*   It can be extended to support user-defined types. Our goal is that if it
    makes sense to hash an object of type `Foo`, then `absl::Hash<Foo>` will
    just work. These extensions are easy to write and efficient to execute.
*   The underlying hash algorithm can be changed without modifying user code,
    which allows us to improve it over time. For example, to improve performance
    and to defend against some hash-flooding attacks.

The `absl::Hash` framework is the default hash implementation for "Swiss tables"
`absl::{flat,node}_hash_{set,map}` and does not need to be explicitly specified
when working with that library.


## **TL;DR** How Do I Make My Type Hashable?

To make your type hashable, add a friend function like:

```c++
class Circle {
 public:
  ...

  template <typename H>
  friend H AbslHashValue(H h, const Circle& c) {
    return H::combine(std::move(h), c.center_, c.radius_);
  }

  ...

 private:
  std::pair<int, int> center_;
  int radius_;
};
```

where `H` refers to the existing `HashState`. If you need anything more complex
than this, please see
[Making Your User-Defined Types Hashable](#making-hashable-types) below.

To test your hash function, add a test like:

```c++
TEST(Circle, Hash) {
  EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly({
      Circle(),
      Circle(1, 2),
      Circle(2, 3),
      Circle(0, 0),
  }));
}
```

where the values passed should provide coverage for all interesting states of
the object.

For more complex cases, please see
[Testing Your Custom `AbslHashValue` Implementation](#testing-hashable-types)
below.

## Using `absl::Hash`

The `absl::Hash` framework is the default hash implementation for the "Swiss
table" hash tables. All types hashable by the `absl::Hash` framework will
automatically be hashable within Swiss tables.


For other hash table implementations, `absl::Hash` can be used just like any
other hash functor:

```c++
#include "third_party/absl/hash/hash.h"

std::unordered_map<MyKey, MyValue, absl::Hash<MyKey>> my_map;
```

Of course, this works only if `MyKey` is hashable by `absl::Hash`, i.e.
`absl::Hash` supports the `MyKey` type.

NOTE: the hash codes computed by `absl::Hash` are not guaranteed to be stable
across different runs of your program. In fact, in the usual case it randomly
seeds itself at program startup.

### Intrinsic Type Support

`absl::Hash` intrinsically supports the following types:

*   All integral types (including bool)
*   All enum types
*   All floating-point types (although hashing them is discouraged; we guarantee
    that `0.0` and `-0.0` produce the same hash)
*   All pointer types, including `nullptr_t`. Note that the pointer itself is
    hashed, not the value it points to.
*   `std::pair<T1, T2>`, if `T1` and `T2` are hashable
*   `std::tuple<Ts...>`, if all the `Ts...` are hashable
*   `std::unique_ptr` and `std::shared_ptr` (as with plain pointers, the pointer
    itself is hashed, not the value it points to)
*   All string-like types including:
    *   `absl::string_view`
    *   `std::string`
    *   `std::string_view` (as well as any instance of `std::basic_string` that
        uses `char` and `std::char_traits`)
*   All the standard sequence containers (provided the elements are hashable)
*   All the standard ordered associative containers (provided the elements are
    hashable)
*   absl types such as the following:
    *   `absl::InlinedVector`
    *   `absl::FixedArray`
    *   `absl::uint128`
    *   `absl::Time`, `absl::Duration`, and `absl::TimeZone`

NOTE: the list above is not meant to be exhaustive. Additional type support
{'fraction_non_alphanumeric': 0.10445362718089991, 'fraction_numerical': 0.0048209366391184574, 'mean_word_length': 4.059814169570267, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 20, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7212749', 'n_tokens_mistral': 2672, 'n_tokens_neox': 2599, 'n_words': 1094}