## 1. Project Overview & Quickstart (abseil/random)

# random

Open-source repository abseil/random

### Repository Details
- **Repository:** [abseil/random](https://github.com/abseil/random)
- **Primary Language:** Code

*Note: High-volume repository documentation is actively indexed and synchronized by YakaAI.*

## 2. Official Technical Reference & Guides (abseil/abseil.github.io)

## File: docs/cpp/guides/abslstringify.md

---
title: "AbslStringify"
layout: docs
sidenav: side-nav-cpp.html
type: markdown
---

# AbslStringify

Author: phoebeliang@

The `AbslStringify()` extension point is a lightweight mechanism that allows
users to format user-defined types as strings. User-defined types that provide
an `AbslStringify()` definition are able to be formatted with libraries such as:

*   [StrFormat](format)
*   [Abseil Strings](strings) (including `absl::StrCat` and
    `absl::Substitute`)
*   [Abseil Logging](logging)
*   [GoogleTest](https://github.com/google/googletest/blob/master/docs/index.md)

Important: As with most type extensions, you should own the type you wish to
extend.

## Basic Usage

Let's say that we have a simple `Point` struct:

```cpp
struct Point {
  int x;
  int y;
};
```

If we want a `Point` to be formattable, we add a `friend` function template
named `AbslStringify()`:

```cpp
struct Point {
  template <typename Sink>
  friend void AbslStringify(Sink& sink, const Point& p) {
    absl::Format(&sink, "(%d, %d)", p.x, p.y);
  }

  int x;
  int y;
};
```

For enums, an `AbslStringify()` definition should be provided after the
definition of the `enum`:

```cpp
namespace foo {

enum class EnumWithStringify { kMany = 0, kChoices = 1 };

template <typename Sink>
void AbslStringify(Sink& sink, EnumWithStringify e) {
  switch (e) {
    case EnumWithStringify::kMany:
      sink.Append("kMany");
      break;
    case EnumWithStringify::kChoices:
      sink.Append("kChoices");
      break;
  }
}

}  // namespace foo
```

If you can't declare the function in the class it's important that
`AbslStringify()` is defined in the **same** namespace that defines Point. C++'s
look-up rules rely on that.

Now these types will print correctly as defined with all the supported
libraries.

Examples using `Point`:

```cpp
// Strings and StrFormat
absl::StrFormat("The point is %v", p);
absl::StrCat("The point is ", p);
absl::StrAppend(&str, p);
absl::Substitute("The point is $0", p);

// Logging
LOG(INFO) << "The point is " << p;

// GoogleTest
EXPECT_EQ(p, expected); // error message prints type according to AbslStringify
testing::PrintToString(p);
```

Important: When using `absl::StrFormat` for user-defined types, use the `%v`
type specifier to format using `AbslStringify()`; using `%s` is not supported.
See https://abseil.io/docs/cpp/guides/format for more details.

Additionally, an implementation of `AbslStringify()` using `absl::Format` can
use `%v` within the format string argument to perform type deduction. Our
`Point` above could be formatted as `"(%v, %v)"` for example, which would give
the same output as `"(%d, %d)"` in this case where we are formatting the `int`
values `x` and `y`.

Note: `CHECK_EQ(p, expected)` does not currently support `AbslStringify`-enabled
types. `CHECK(p == expected) << p << "==" << expected` can be used for similar
error-checking and logging capabilities.

For more information about `AbslStringify`'s integration with any of these
libraries, please refer to the documentation of the relevant library.

### `AbslStringify`'s Sink

`AbslStringify`'s underlying `Sink` supports `Append` operations, as well as
`absl::Format`:

```cpp
// Append 3 copies of 'a'
sink.Append(3, 'a')

// Append "hello"
sink.Append("hello")

// Append "hello world"
absl::Format(&sink, "hello %s", "world")
```

Warning: User-defined sinks are not supported.

## Types with Built-In Support

### Protocol Buffers

Protocol buffer messages define `AbslStringify()` by default, so they can be
formatted by all libraries that use this extension point. This is an overall
smoother user experience over `DebugString()` as it produces less noisy code. It
is recommended that users format protocol buffers directly rather than
calling `DebugString()`.

```proto
message MyProto {
  optional string my_string = 1
}
```

```cpp
MyProto my_proto;
my_proto.set_my_string("hello world");

absl::StrCat("My proto is: ", my_proto);
absl::StrFormat("My proto is: %v", my_proto);
LOG(INFO) << "My proto is: " << my_proto;
EXPECT_THAT(my_proto, EqualsProto(expected_proto))
```

---

## File: docs/cpp/guides/base.md

---
title: "Abseil Fundamentals"
layout: docs
sidenav: side-nav-cpp.html
type: markdown
---

# Abseil Fundamentals

This guide covers concepts common to all work in Abseil. The topics covered
within this guide are sort of a kitchen sink of the following:

* Important policy decisions and design patterns useful for Abseil code
* Useful fundamental code that all Abseil-derived code should know about
* Inner machinery required for fundamental Abseil code, but likely not important
  from a development standpoint

## Abseil Style Guidelines

Abseil code adheres to the official
[Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html).
Additional constraints/concerns within Abseil code, where they diverge from the
above, appear below.

### Abseil Exception Policy

Google (rather famously) does not use exceptions within its production code. We
of course do not require that you adhere to such a policy. However, you should
be aware of some repercussions on your code base.

We do not believe there is good engineering reason for move constructors to
throw. At most, we will allow move constructors to throw because of allocation.
Within Abseil code, move constructors will not throw except because of
allocation if compiled without `-DABSL_ALLOCATOR_NOTHROW`. Holding move
constructors to this standard allows much better optimization, especially in
conjunction with standard library behavior (`std::vector` resizes much more
efficiently with non-throwing move constructors).

In general we will try to support exceptions in reasonable APIs and designs.
We are, however, opinionated about where exception-flexibility is trumped by
performance. We will try to be clear about where exceptions are a bad design
choice and mark things `noexcept` when possible. Do not confuse conceptual
support for exceptions with endorsement of exceptions in all places - if your
hash functor throws, you're on your own.

Be aware of the meaning of `noexcept`: this is not a promise that exceptions
do not happen, it is a promise that if an exception escapes that API, the
process will end with `std::terminate()`.

### Leak-Checking

Abseil code is designed to work with targets built with the LeakSanitizer
(LSan), a memory leak detector that is integrated within the AddressSanitizer
(ASan) as an additional component, or which can be used standalone. Leak
checking is enabled by default in all ASan builds.

For more information on the LeakSanitizer, see the
[Address Sanitizer docs](https://github.com/google/sanitizers/wiki/AddressSanitizerLeakSanitizer)

To enable LSan on your builds including Abseil code (using Bazel):

```
# Enable just LSan.
# Note that LSan requires Clang instead of gcc.
# You probably want to define a crosstool or bazel configuration to
# do this properly - provided for demonstration purposes only.
$ CC=clang BAZEL_COMPILER=llvm bazel build --copt=-DLEAK_SANITIZER \
    --linkopt=-fsanitize=leak *target*

# Enable ASan, which also includes LSan.
$ CC=clang BAZEL_COMPILER=llvm bazel build --copt=-DADDRESS_SANITIZER \
    --copt=-fsanitize=address --linkopt=-fsanitize=address *target*
```

The `debugging/leak_check.h` header file contains several utility functions to
customize leak checking behavior within your code. Consult that header file for
more information.

## The Abseil Base Library

Fundamental Abseil code resides in the `absl/base` directory. Technically, these
files are not a cohesive "library" in the normal sense. What distinguishes them
as base files is that they have no outside dependencies; `absl/base` header
files only depend on other `absl/base` header files. The base library contains
fundamental code that all other Abseil code depends on. As a result, the
contents of base are kept to the minimum of what is absolutely necessary.

This base library consists of configuration files, some required Abseil
utilities for core code, and initialization primitives.

The Base library's configuration header files consist of the following:

* `policy_checks.h`
  Enforces Abseil policies that can be enforced at build time,
  such as minimum compiler and library versions. For more information, consult
  the Abseil [Platforms Guide](/docs/cpp/platforms).
* `macros.h`
  Provides macros used within Abseil code for language features.
* `options.h` 
  Provides mechanisms to enforce static configuration of certain implementation
  details.
* `optimization.h`
  Provides several platform-dependent macros for implementing
  optimization techniques.
* `config.h`
  Provides macros for determining platform and compiler support.
  For more information, consult the
  [Feature Check Macros](/docs/cpp/platforms/feature_checks)
  guide.

Additionally, the Base library includes one utility header file:

* `casts.h`
  Provides a few useful extensions for performing safer type casts.

Consult that header file for more information.

The Base library's concurrency-related files, which are included in "base"
because they are fundamental to initialization and thread management, consist
of the following:

* `call_once.h`
  Provides a primitive for ensuring a function is called exactly
  once, which is used during object initialization.
* `thread_annotations.h`
  Provides a set of annotations to use within your code
  identifying intended behavior in concurrent environments.

These APIs are documented separately within the
[Synchronization Guide](synchronization) rather than within this guide,
because they are strongly related to the other abstractions within that guide.

---

## File: docs/cpp/guides/container.md

---
title: "Abseil Containers"
layout: docs
sidenav: side-nav-cpp.html
type: markdown
---

# Abseil Containers

Abseil provides a number of containers as alternatives to STL containers. These
containers generally adhere to the properties of STL containers, though there
are often some associated API differences and/or implementation details which
differ from the standard library.

The Abseil containers are designed to be more efficient in the general case; in
some cases, however, the STL containers may be more efficient. Unlike some other
abstractions that Abseil provides, these containers should not be considered
drop-in replacements for their STL counterparts, as there are API and/or
contract differences between the two sets of containers. For example, the Abseil
containers often do not guarantee pointer stability[^pointer-stability] after
insertions or deletions.

The Abseil `container` library defines the following sets of containers:

* Swiss table unordered containers
* B-tree ordered containers

See below for more information about each of these container types.

## Hash Tables

The Abseil `container` library contains a number of useful hash tables generally
adhering to the STL container API contract:

*   `absl::flat_hash_map`
*   `absl::flat_hash_set`
*   `absl::node_hash_map`
*   `absl::node_hash_set`

Collectively, these hash tables are known as "Swiss tables" and are designed to
be replacements for
[`std::unordered_map`](https://en.cppreference.com/w/cpp/container/unordered_map)
and [`std::unordered_set`](https://en.cppreference.com/w/cpp/container/unordered_set)
They provide several advantages over the `std::unordered_*` containers:

*   Provides C++14 support for C++17 mechanisms such as `try_emplace()` and
    C++20 mechanisms such as `contains()`.
*   Supports heterogeneous lookup.
*   Allows optimizations for `emplace({key, value})` to avoid allocating a pair
    in most common cases.
*   Supports a heterogeneous `std::initializer_list` to avoid extra copies for
    construction and insertion.
*   Guarantees an `O(1)` erase method by returning void instead of an iterator.

### Construction

The set of Swiss table containers support the same overload set as
`std::unordered_map` for construction and assignment:


```c++
// Examples using node_hash_set and node_hash_map are equivalent

// Default constructor
// No allocation for the table's elements is made.
absl::flat_hash_set<std::string> set1;

absl::flat_hash_map map1;

// Initializer List constructor
absl::flat_hash_set<std::string> set2 = {{"huey"}, {"dewey"}, {"louie"},};

absl::flat_hash_map map2 =
    {{1, "huey"}, {2, "dewey"}, {3, "louie"},};

// Copy constructor
absl::flat_hash_set<std::string> set3(set2);

absl::flat_hash_map map3(map2);

// Copy assignment operator
// Hash functor and Comparator are copied as well
absl::flat_hash_set<std::string> set4;
set4 = set3;

absl::flat_hash_map map4;
map4 = map3;

// Move constructor
// Move is guaranteed efficient
absl::flat_hash_set<std::string> set5(std::move(set4));

absl::flat_hash_map map5(std::move(map4));

// Move assignment operator
// May be efficient if allocators are compatible
absl::flat_hash_set<std::string> set6;
set6 = std::move(set5);

absl::flat_hash_map map6;
map6 = std::move(map5);

// Range constructor
std::vector<std::string> v = {"a", "b"};
absl::flat_hash_set<std::string> set7(v.begin(), v.end());

std::vector<std::pair> v = {{1, "a"}, {2, "b"}};
absl::flat_hash_map map7(v.begin(), v.end());
```


### `absl::flat_hash_map` and `absl::flat_hash_set`

`absl::flat_hash_map` and `absl::flat_hash_set` are the recommended unordered
containers for general use. These are flat data structures, which store their
`value_type` directly in the slot array.

#### Guarantees

*   Keys and values are stored inline.
*   Iterators, references, and pointers to elements are invalidated on rehash.
*   Move operations do not invalidate iterators or pointers.

#### Memory Usage



The container uses O(`(sizeof(std::pair<const K, V>) + 1) * bucket_count()`)
bytes. The *max load factor* is 87.5%, after which the table doubles in size
(making load factor go down by 2x). Thus `size()` is usually between
`0.4375*bucket_count()` and `0.875*bucket_count()`. For tables that have never
rehashed the load factor can be even lower, but these numbers are sufficient for
our estimates.

#### Recommendation

Use `absl::flat_hash_map` most of the time. If pointer stability of values (but
not keys) is needed, use `absl::flat_hash_map<Key, std::unique_ptr<Value>>`.

### `absl::node_hash_map` and `absl::node_hash_set`

These are near drop-in replacement for `std::unordered_map` and
`std::unordered_set`. They are useful:

*   When pointer stability is required for both key and value.
*   For automatic migrations from `std::unordered_map`, `std::unordered_set`,
    `hash_map` or `hash_set` where it's difficult to figure out whether the code
    relies on pointer stability.

These are node-based data structures in the STL standard sense: each
`value_type` is allocated in a separate node and the main table contains
pointers to those nodes.

#### Guarantees

*   Nodes have stable addresses.
*   Iterators are invalidated on rehash.
*   Move operations do not invalidate iterators.

#### Memory Usage



The slot array requires `(sizeof(void*) + 1) * bucket_count()` bytes and the
nodes themselves require `sizeof(value_type) * size()` bytes. Together, this is
O(`9*bucket_count() + sizeof(std::pair<const K, V>)*size()`) on most platforms.

#### Recommendation

Prefer `absl::flat_hash_map` or `absl::flat_hash_set` in most new code (see
above).

Use `absl::node_hash_map` or `absl::node_hash_set` when pointer stability of
both keys and values is required (rare), or for code migrations from other
containers with this property. *Note:* Do not use popularity as a guide. You
will see the "node" containers used a lot, but only because it was safe to
migrate code to them from other containers.

### Construction and Usage


```cpp
absl::flat_hash_map numbers =
    {{1, "one"}, {2, "two"}, {3, "three"}};
numbers.try_emplace(4, "four");

absl::flat_hash_map<string, std::unique_ptr<string>> strings;
strings.try_emplace("foo", absl::make_unique<string>("bar"));
```


### Heterogeneous Lookup

Inserting into or looking up an element within an associative container requires
a key. In general, containers require the keys to be of a specific type, which
can lead to inefficiencies at call sites that need to convert between
near-equivalent types (such as `std::string` and `absl::string_view`).


std::map&lt;std::string, int&gt; m = ...;
absl::string_view some_key = ...;
// Construct a temporary `std::string` to do the query.
// The allocation + copy + deallocation might dominate the find() call.
auto it = m.find(std::string(some_key));


To avoid this unnecessary work, the Swiss tables provide heterogeneous lookup
for conversions to string types (allowing `absl::string_view` in the lookup, for
example), and for conversions to smart pointer types (`std::unique_ptr`,
`std::shared_ptr`), through the `absl::Hash` hashing framework. (The supporting
comparators are built into `absl::Hash`.)

```cpp
absl::flat_hash_map<std::string, int> m = ...;
absl::string_view some_key = ...;
// We can use string_view directly as the key search.
auto it = m.find(some_key);
```

### Iteration Order Instability

While `std::unordered_map` makes no guarantees about iteration order, many
implementations happen to have a deterministic order based on the keys and their
insert order. This is not true of `absl::flat_hash_map` and
`absl::node_hash_map`. Thus, converting from `std::unordered_map` to
`absl::flat_hash_map` can expose latent bugs where the code incorrectly depends
on iteration order.

A special case which can create a subtle bug is summing `float` values in an
unordered container. While mathematical sums do not depend on order, floating
point sums do, and it can be the case that a sum is deterministic with
`std::unordered_set` but non-deterministic with `absl::flat_hash_set`.

## B-tree Ordered Containers

The Abseil `container` library contains ordered containers generally
adhering to the STL container API contract, but implemented using (generally
more efficient) B-trees rather than binary trees (as used in `std::map` et al):

*   `absl::btree_map`
*   `absl::btree_set`
*   `absl::btree_multimap`
*   `absl::btree_multiset`

These ordered containers are designed to be more efficient replacements for
[`std::map`](https://en.cppreference.com/w/cpp/container/map)
and [`std::set`](https://en.cppreference.com/w/cpp/container/set) in most cases.
Specifically, they provide several advantages over the ordered `std::`
containers:

*   Provide lower memory overhead in most cases than their STL equivalents.
*   Are generally more cache friendly (and hence faster) than their STL
    equivalents.
*   Provide C++14 support for C++17 mechanisms such as `try_emplace()` and C++20
    mechanisms such as `contains()`..
*   Support heterogeneous lookup.

### Construction

The set of B-tree containers support the same overload set as
`std::map` for construction and assignment:


```c++
// Examples using btree_multimap and btree_multiset are equivalent

// Default constructor
// No allocation for the B-tree's elements is made.
absl::btree_set<std::string> set1;

absl::btree_map map1;

// Initializer List constructor
absl::btree_set<std::string> set2 = {{"huey"}, {"dewey"}, {"louie"},};

absl::btree_map map2 =
    {{1, "huey"}, {2, "dewey"}, {3, "louie"},};

// Copy constructor
absl::btree_set<std::string> set3(set2);

absl::btree_map map3(map2);

// Copy assignment operator
// Hash functor and Comparator are copied as well
absl::btree_set<std::string> set4;
set4 = set3;

absl::btree_map map4;
map4 = map3;

// Move constructor
// Move is guaranteed efficient
absl::btree_set<std::string> set5(std::move(set4));

absl::btree_map map5(std::move(map4));

// Move assignment operator
// May be efficient if allocators are compatible
absl::btree_set<std::string> set6;
set6 = std::move(set5);

absl::btree_map map6;
map6 = std::move(map5);

// Range constructor
std::vector<std::string> v = {"a", "b"};
absl::btree_set<std::string> set7(v.begin(), v.end());

std::vector<std::pair> v = {{1, "a"}, {2, "b"}};
absl::btree_map map7(v.begin(), v.end());
```


## Notes

[^pointer-stability]: "Pointer stability" means that a pointer to an element
    remains valid (is not invalidated) so long as the element
    is present, allowing code to cache pointers to elements
    even when the underlying container is mutated. Saying that
    a container has pointer stability is the same as saying
    that it doesn't move elements in memory; their addresses
    do not change. Pointer stability/invalidation is the same
    as reference stability/invalidation.

---

## File: docs/cpp/guides/flags.md

---
title: "The Abseil Flags Library"
layout: docs
sidenav: side-nav-cpp.html
type: markdown
---

# The Abseil Flags Library

The Abseil flags library allows programmatic access to flag values passed on the
command-line to binaries. The Abseil Flags library provides the following
features:

* Access to Abseil flags in a thread-safe manner
* Access to flag values that are valid at any point during a program's lifetime
* Prevention of conflicting flag names by ensuring uniqueness within the same
  binary
* Associated help text provided by a number of built-in usage flags
* Has type support for boolean, integral and string types, and is extensible to
  support other Abseil types and custom types
* Default values and programmatic access to flag values for both reading and
  writing
* Allows distributed declaration and definition of flags, though this usage
  has drawbacks and should generally be avoided.

Values for these flags are parsed from the command line by
`absl::ParseCommandLine()`. The resulting value for each flag is stored in a
global variable of an unspecified type `absl::Flag<T>`.

## Introduction

**Command-line flags** are flags that users typically specify on the command
line when they run an executable as runtime parameters. (These flags are often
referred to as *options* in the GNU world, such as within the `getopt()`
command-line argument parser.)

In the command:

```sh
$ fgrep -l -f /var/tmp/foo johannes brahms
```

*   `-l` and `-f` are *command-line flags*.
*   The `-f` flag contains one argument, `/var/tmp/foo` which is its
    *command-line flag argument*.
*   The `johannes` and `brahms` arguments, which are not associated with any
    command-line flag, are *command-line positional arguments*.

NOTE: unlike `getopt()`, the Abseil flags library does not support flags with
both short and long options (e.g. `-v` and `--verbose` as short and long
versions of the same command-line option).

Typically, an application lists what flags the user is allowed to pass in, and
what arguments they take. In this example, `-l` takes no argument, and `-f`
takes a string (in particular, a filename) as an argument. Users use a library
to help parse the command-line and store the flags in some data structure.

## Do I Need Command Line Flags?

In general, don't reach for flags. More often than not, flags are poor choices
for binary configuration. As global variables, it is difficult to avoid
conflicts with other flags, and difficult to deprecate and remove flags once
they are no longer useful. Some flag values end up being wasteful within your
binary: a flag with a single value that never varies is effectively a constant,
but one whose associated code paths can never be optimized, as they are runtime
initialized.

Often, flags interact with other flags to provide configuration to a binary. If
that configuration is reasonably complex, a configuration file is usually a
better option. That said, sometimes flags are appropriate.

A flag is reasonable if you know you will need to change the flag’s value, and
if the associated logic of the flag is self-contained. For example, a flag is
useful for:

* Toggling features: flags such as `--enforce_quota` can be changed
  when quota is causing a problem. When a new feature is being rolled
  out, you may want a simple way to switch it off in an emergency. However, make
  sure to remove these flags once their intended purpose has run its course.
* Platform dependence: specifying values that change in different environments,
  especially for input/output parameters: file paths, URLs, etc.
* Tuning parameters: batch sizes, timeouts, thresholds, etc.
* Debugging: a debugging flag may be desired to log information at runtime
  without changing user-visible behavior. For example, a logging flag may
  collect information if a server appears to be slow to respond.

All that said, many flags are strictly unnecessary. During one of our audits in
2012, we discovered that the majority of our flags never varied in value. Before
you reach for flags, consider whether you really need them, and for how long.

## Flags Best Practices

OK, we've warned you about flag usage. But if we accept that you do need flags
in your binary, what are some best practices around flag usage?

*   Prefer to define flags only in the file containing the binary's `main()`
    function. Although Abseil flags may be defined anywhere in any source file,
    avoid any usage outside of `main()` as it will otherwise be difficult to
    resolve conflicts.
*   Prefer to reference flags only from within the file containing the binary's
    `main()` function, for the same reason.
*   Do not use flags to implement any binary logic.
*   Do not declare any flags that you do not own yourself.
*   Do not access a binary's flags within any tight loops. Flags are expensive
    to read.
*   Prefer using flag types already defined in Abseil rather than implementing
    your own custom flag types.

With these caveats, the rest of this documentation discusses using the Abseil
Flags library API.

## Defining Flags

Use the `ABSL_FLAG(type, name, default, help-text)` macro to define a flag of
the appropriate type:

```cpp
#include "absl/flags/flag.h"
#include "absl/time/time.h"

ABSL_FLAG(bool, big_menu, true,
          "Include 'advanced' options in the menu listing");
ABSL_FLAG(std::string, output_dir, "foo/bar/baz/", "output file dir");
ABSL_FLAG(std::vector<std::string>, languages,
          std::vector<std::string>({"english", "french", "german"}),
          "comma-separated list of languages to offer in the 'lang' menu");
ABSL_FLAG(absl::Duration, timeout, absl::Seconds(30), "Default RPC deadline");
ABSL_FLAG(std::optional<std::string>, image_file, std::nullopt,
          "Sets the image input from a file.");
```

Flags defined with `ABSL_FLAG` will create global variables named
`FLAGS_*name*` of the specified type and default value. Help
text will be displayed using the `--help` usage argument, if invoked. See
[Special Flags](#special_flags) for `--help` documentation.

### Standard Flags

Out of the box, the Abseil flags library supports the following types:

*   `bool`
*   `int16_t`
*   `uint16_t`
*   `int32_t`
*   `uint32_t`
*   `int64_t`
*   `uint64_t`
*   `float`
*   `double`
*   `std::string`
*   `std::vector<std::string>`
*   `std::optional<T>` (see "Optional Flags" below)
*   `absl::LogSeverity` (provided natively for layering reasons)

NOTE: support for integral types is implemented using overloads for
variable-width fundamental types (`short`, `int`, `long`, etc.). However, you
should prefer the fixed-width integral types listed above (`int32_t`,
`uint64_t`, etc.).

### Abseil Flags

In addition, several Abseil libraries provide their own custom support for
Abseil flags. Documentation for these formats is provided in the type's
`AbslParseFlag()` definition.

The Abseil [time library][time-library] provides the flag support for
absolute time values:

* `absl::Duration`
* `absl::Time`

The [civil-time library][civiltime-library] additionally provides flag support
for the following civil-time values:

* `absl::CivilSecond`
* `absl::CivilMinute`
* `absl::CivilHour`
* `absl::CivilDay`
* `absl::CivilMonth`
* `absl::CivilYear`

Additional support for Abseil types will be noted here as it is added.

See [Defining Custom Flag Types](#custom) for how to provide support for a new
type.

You can define a flag in any `.cc` file in your executable, but only define a
flag once! All flags should be defined outside any C++ namespace so if multiple
definitions of flags with the same name are linked into a single program the
linker will report an error. If you want to access a flag in more than one
source file, define it in a `.cc` file, and [declare](#declaring_flags) it in
the corresponding header file.

### Optional Flags

The Abseil flags library supports flags of type `std::optional<T>` where `T` is
a type of one of the supported flags. We refer to this flag type as an
"optional flag." An optional flag is either "valueless", holding no value of
type `T` (indicating that the flag has not been set) or a value of type `T`. The
valueless state in C++ code is represented by a value of `std::nullopt` for the
optional flag.

Using `std::nullopt` as an optional flag's default value allows you to check
whether such a flag was ever specified on the command line:

```cpp
if (absl::GetFlag(FLAGS_foo).has_value()) {
  // flag was set on command line
} else {
  // flag was not passed on command line
}
```

Using `std::optional<T>` in this manner avoids common workarounds for indicating
such an unset flag (such as using sentinel values to indicate this state).

An optional flag also allows a developer to pass a flag in an "unset" valueless
state on the command line, allowing the flag to later be set in binary logic. An
optional flag's valueless state is indicated by the special notation of passing
the value as an empty string through the syntax `--flag=` or `--flag ""`.

```sh
$ binary_with_optional --flag_in_unset_state=
$ binary_with_optional --flag_in_unset_state ""
```

NOTE: as a result of the above syntax requirements, an optional flag cannot be
set to a `T` of any value which unparses to the empty string.

## Accessing Flags

A flag defined via `ABSL_FLAG` is available as a variable of an unspecified
type and named using the name passed to `ABSL_FLAG`. `absl::GetFlag()` and
`absl::SetFlag()` can be used to access such flags. E.g., for flags of type
`absl::Duration`:

```cpp
// Creates variable "absl::Flag<absl::Duration> FLAGS_timeout;"
// Example command line usage: --timeout=1m30s
ABSL_FLAG(absl::Duration, timeout, absl::Seconds(30), "Default RPC timeout");

// Read the flag
absl::Duration d = absl::GetFlag(FLAGS_timeout);

// Modify the flag
absl::SetFlag(&FLAGS_timeout, d + absl::Seconds(10));
```

Accesses to `ABSL_FLAG` flags are thread-safe.

## Using a Flag in a Different File {#declaring_flags}

Accessing a flag in the manner of the previous section only works if the flag
was defined earlier in the same `.cc` file. If it wasn't, you'll get an
'unknown variable' error.

If you need to allow other modules to access the flag, you must export it in
some header file that is included by those modules. For an `ABSL_FLAG` flag
named `FLAGS_name` of type `T`, use the `ABSL_DECLARE_FLAG(T, name);` macro
defined in absl/flags/declare.h to do so:

```cpp
#include "absl/flags/declare.h"

ABSL_DECLARE_FLAG(absl::Duration, timeout);
```

The declaration should always be placed in the header file associated with the
`.cc` file that defines and owns the flag, as with any other exported entities.
If you need to do this for testing only, you can place it with an
`// Exposed for testing only` comment.

Warning: The necessity to access flags from different files, especially in
libraries, is generally a sign of a bad design. Given the "global variable"
nature of flags they should be avoided in libraries and be injected instead
(e.g. in constructors). (see
[abseil.io/tips/45](https://abseil.io/tips/45))

## Validating Flag Values

Some flag values may be invalid. E.g., the underlying type may have a larger
range than desired for the flag.

For `ABSL_FLAG` flags, extra checks on a flag value can be done by providing a
custom type and adding appropriate validation to the corresponding
`AbslParseFlag()` function, which defines how a particular flag should be
parsed.

Example:

```c++
#include <string>

#include "absl/flags/flag.h"
#include "absl/flags/marshalling.h"
#include "absl/strings/string_view.h"

struct PortNumber {
  explicit PortNumber(int p = 0) : port(p) {}

  int port;  // Valid range is [0..32767]
};

// Returns a textual flag value corresponding to the PortNumber `p`.
std::string AbslUnparseFlag(PortNumber p) {
  // Delegate to the usual unparsing for int.
  return absl::UnparseFlag(p.port);
}

// Parses a PortNumber from the command line flag value `text`.
// Returns true and sets `*p` on success; returns false and sets `*error`
// on failure.
bool AbslParseFlag(absl::string_view text, PortNumber* p, std::string* error) {
  // Convert from text to int using the int-flag parser.
  if (!absl::ParseFlag(text, &p->port, error)) {
    return false;
  }
  if (p->port < 0 || p->port > 32767) {
    *error = "not in range [0,32767]";
    return false;
  }
  return true;
}

ABSL_FLAG(PortNumber, port, PortNumber(0), "What port to listen on");
```

If `AbslParseFlag()` returns false for a value specified on the command-line,
the process will exit with an error message. Note that `AbslParseFlag()` does
not initiate any parsing itself, but simply defines the parsing behavior.

## Parsing Flags During Startup

Command-line flags should be parsed at startup, preferably before any other
business logic associated with your binary. To do so:

```cpp
absl::ParseCommandLine(argc, argv);
```

`absl::ParseCommandLine()` parses the set of command-line arguments passed in
the `argc` (argument count) and `argv[]` (argument vector) parameters from
`main()`, assigning values to any defined Abseil flags. (Any arguments passed
after the flag-terminating delimiter (`--`) are treated as positional arguments
and ignored.)

Any command-line flags (and arguments to those flags) are parsed into Abseil
Flag values, if those flags are defined. Any undefined flags will either
return an error, or be ignored if that flag is designated using `--undefok` to
indicate "undefined is OK."

Any command-line positional arguments not part of any command-line flag (or
arguments to a flag) are returned in a vector, with the program invocation
name at position 0 of that vector. (Note that this includes positional
arguments after the flag-terminating delimiter `--`.)

After all flags and flag arguments are parsed, this function looks for any
built-in usage flags (e.g. `--help`), and if any were specified, it reports
help messages and then exits the program. If command-line flags fail to pass
parsing and validation, the process will be terminated.

## Setting Flags on the Command Line

The reason you make something a flag instead of a compile-time constant, is to
allow users to specify a non-default value on the command-line. Here's how they
might do it for an application that links in `foo.cc`:

```sh
app_containing_foo --nobig_menu --languages="chinese,japanese,korean" ...
```

This sets `FLAGS_big_menu = false;` and `FLAGS_languages =
"chinese,japanese,korean"`, when `ParseCommandLine()` is run.

Note the atypical syntax for setting a boolean flag to false: putting "no" in
front of its name. There's a fair bit of flexibility to how flags may be
specified. Here's an example of all the ways to specify the "languages" flag:

-   `app_containing_foo --languages="chinese,japanese,korean"`
-   `app_containing_foo -languages="chinese,japanese,korean"`
-   `app_containing_foo --languages "chinese,japanese,korean"`
-   `app_containing_foo -languages "chinese,japanese,korean"`

For boolean flags, the possibilities are slightly different:

-   `app_containing_foo --big_menu`
-   `app_containing_foo --nobig_menu`
-   `app_containing_foo --big_menu=true`
-   `app_containing_foo --big_menu=false`

(as well as the single-dash variant on all of these).

Despite this flexibility, we recommend using only a single form:
`--variable=value` for non-boolean flags, and `--variable/--novariable` for
boolean flags. This consistency will make your code more readable.

Note that all command line flags are first parsed by the shell, which adheres to
the rules of [shell expansion][shell-expansions]. Specifically, quotes are
removed before passing any tokens off to the Flags Library. Care should be taken
to never use "smart" quotes in such command lines, as they will not parse
correctly.

For integer flag types (int32_t, int64_t, uint64_t, etc.), the following
formats are accepted:

- Decimal: `--my_int=24`
- Hexadecimal: `--my_int=0x18`

NOTE: Do not use two's complement hexadecimal representation to specify
negative values. Use a negative sign with a numeric value that is in range. Ex: `--my_int=-0x18`

Setting a flag of type `std::optional<T>` on the command line to show the
"unset" state requires a way to refer to this uninitialized value. For Abseil
flags, this value is specified using the empty string.

```sh
binary_with_optional --flag_in_unset_state=
binary_with_optional --flag_in_unset_state ""
```

NOTE: this usage prevents an optional flag from having a *value* of the empty
string in practice.

It is a fatal error to specify a flag on the command-line that has not been
defined somewhere in the executable. If you need that functionality for some
reason -- say you want to use the same set of flags for several executables, but
not all of them define every flag in your list -- you can specify
[--undefok](#special_flags) to suppress the error.

If a flag is specified more than once, only the last specification is used; the
others are ignored.

Note that Abseil flags do not have single-letter synonyms, like they do in the
`getopt()` library, nor do we allow "combining" flags behind a single dash, as
in `ls -laf`.

## Changing the Default Flag Value

Sometimes a flag is defined in a library, and you want to change its default
value in one application but not others. To do so, you can use `absl::SetFlag()`
to override this default value before calling `ParseCommandLine()`; if the
user does not pass a value on the command line, this new default will be used:

```cpp
int main(int argc, char** argv) {
  // Overrides the default for FLAGS_logtostderr
  absl::SetFlag(&FLAGS_logtostderr, true);
  // If the command-line contains a value for logtostderr, use that. Otherwise,
  // use the default (as set above).
  absl::ParseCommandLine(argc, argv);
}
```

Note that setting the flag *after* parsing the command-line is neither generally
useful nor recommended, as it will ignore the user's intentions with a
command-line flag and essentially set the flag as a constant value.

## Removing / Retiring Flags

When a flag is no longer useful (and no longer referenced in code), in some
cases it may be possible to simply remove the definition. However, if the flag
is referenced in configuration files, job launching scripts, and the like,
simply removing the definition will cause problems for deployment. For flags
referenced in complex deployments where a single configuration may be used with
multiple builds, it can be impossible to satisfy all constraints. To handle
these cases where timing and coordination are difficult, you can denote some
flags as "retired" flags via `ABSL_RETIRED_FLAG()`.

```cpp
ABSL_RETIRED_FLAG(bool, old_bool_flag, true, "old description");
```

Retired flags have a number of important behaviors. Specifically, they:

-   do not define a C++ `FLAGS_` variable.
-   have a type and a value, but that value is intentionally inaccessible.
-   do not appear in `--help` messages.
-   are fully supported by _all_ flag parsing routines.
-   consume args normally, and complain about type mismatches in those
    arguments.
-   emit a complaint but do not die if they are accessed by name through the
    flags API for parsing or otherwise.

In this way, you can safely remove flags that are used in (multiple) complex
deployments: retire the flag, wait for releases of affected binaries, then
remove reference to the flag from configuration files and startup scripts. Once
all jobs are starting up without logging warnings about reference to the retired
flag, the retired flag can be removed completely.

For more details, see the [Tip of the Week on retired flags][retired-flags].

## Special Usage Flags {#special_flags}

There are a few flags defined by the Abseil flags library itself. These usage
flags are reserved words and should not be declared by anyone other than the
Abseil team, just like any other flags which you don't own. Usage flags, if
invoked, cause the application to print some information about itself and exit.

```text
--help            show help on important flags for this binary
--helpfull        shows the full list of flags from all files, sorted by file
                  and then by name; shows the flagname, its default value, and
                  its help string
--helpshort       shows only flags for the file with the same name as the
                  executable (usually the one containing main())
--helpon=FILE     shows only flags defined in FILE.*
--helpmatch=S     shows only flags defined in *S*.*
--helppackage     shows flags defined in files in same directory as main()
--version         prints version info for the executable
```

NOTE: The help message for a flag will include its default value, so in most
cases there is no need to mention the default value in the definition of a
flag's `help-text`.

Additionally, some built-in flags have additional behavioral effects. These are
noted below.

### `--undefok`

The Abseil flags library also supports an `undefok` flag:

`--undefok=flagname,flagname,...`

For any listed `flagname`, this instructs the Abseil flags library to suppress
normal error signaling that occurs when `--flagname` is seen on the command-line
(or `--noflagname` since a listed flag might have been an old boolean flag), but
no flag with name `flagname` has been defined.

## Defining Custom Flag Types {#custom}

For a type `T` to be used as an Abseil flag type, it must support conversion to
and from strings supplied on the command-line. Custom types may have a unique
format for this command-line string, and hence may require custom support for
Abseil flags.

To add support for your user-defined type, add overloads of `AbslParseFlag()`
and `AbslUnparseFlag()` as free (non-member) functions to your type. If `T`
is a class type, these functions can be friend function definitions. These
overloads must be added to the same namespace where the type is defined, so
that they can be discovered by Argument-Dependent Lookup (ADL).

Example:

```cpp
namespace foo {
enum class OutputMode { kPlainText, kHtml };

// AbslParseFlag converts from a string to OutputMode.
// Must be in same namespace as OutputMode.

// Parses an OutputMode from the command line flag value `text`. Returns
// `true` and sets `*mode` on success; returns `false` and sets `*error`
// on failure.
bool AbslParseFlag(absl::string_view text,
                   OutputMode* mode,
                   std::string* error) {
  if (text == "plaintext") {
    *mode = OutputMode::kPlainText;
    return true;
  }
  if (text == "html") {
    *mode = OutputMode::kHtml;
    return true;
  }
  *error = "unknown value for enumeration";
  return false;
}

// AbslUnparseFlag converts from an OutputMode to a string.
// Must be in same namespace as OutputMode.

// Returns a textual flag value corresponding to the OutputMode `mode`.
std::string AbslUnparseFlag(OutputMode mode) {
  switch (mode) {
    case OutputMode::kPlainText: return "plaintext";
    case OutputMode::kHtml: return "html";
    default: return absl::StrCat(mode);
  }
}
}  // namespace foo
```

Notice that neither `AbslParseFlag()` nor `AbslUnparseFlag()` are class
members, but free functions. `AbslParseFlag/AbslUnparseFlag()` overloads
for a type should only be declared in the same file and namespace as said
type. The proper `AbslParseFlag/AbslUnparseFlag()` implementations for a
given type will be discovered via Argument-Dependent Lookup (ADL).

`AbslParseFlag()` may need, in turn, to parse simpler constituent types
using `absl::ParseFlag()`. For example, a custom struct `MyFlagType`
consisting of a `std::pair` would add an `AbslParseFlag()`
overload for its `MyFlagType` like so:

Example:

```cpp
namespace my_flag_namespace {

struct MyFlagType {
  std::pair my_flag_data;
};

bool AbslParseFlag(absl::string_view text, MyFlagType* flag,
                   std::string* err);

std::string AbslUnparseFlag(const MyFlagType&);

// Within the implementation, `AbslParseFlag()` will, in turn invoke
// `absl::ParseFlag()` on its constituent `int` and `std::string` types
// (which have built-in Abseil flag support.

bool AbslParseFlag(absl::string_view text, MyFlagType* flag,
                   std::string* err) {
  std::pair<absl::string_view, absl::string_view> tokens =
      absl::StrSplit(text, ',');
  if (!absl::ParseFlag(tokens.first, &flag->my_flag_data.first, err))
    return false;
  if (!absl::ParseFlag(tokens.second, &flag->my_flag_data.second, err))
    return false;
  return true;
}

// Similarly, for unparsing, we can simply invoke `absl::UnparseFlag()` on
// the constituent types.
std::string AbslUnparseFlag(const MyFlagType& flag) {
  return absl::StrCat(absl::UnparseFlag(flag.my_flag_data.first),
                      ",",
                      absl::UnparseFlag(flag.my_flag_data.second));
}
}  // my_flag_namespace
```

### Best Practices for Defining Custom Flag Types

*   Declare `AbslParseFlag()` and `AbslUnparseFlag()` in exactly one place for
    `T`, generally in the same file that declares `T`. If `T` is a class type,
    they can be defined with [friend _function-definitions_][friend-functions].
*   If you must declare `AbslParseFlag()` and `AbslUnparseFlag()` away from
    `T`'s declaration, you must still be the owner of `T` and must guarantee
    that the functions are defined exactly once in the codebase.
*   Document the format string of the flag where you declare `AbslParseFlag()`
    and `AbslUnparseFlag()`. As the owner of `T`, you are responsible for
    documenting this format.
*   `absl::StrSplit("")` returns `{""}` (a list with one element), so watch out
    for that if you are defining a compound flag type. Flags defined with
    `ABSL_FLAG(std::vector<std::string>, ...)` treat an empty string as an empty
    container.
*   Escape separators if they can occur in values for compound flag types.
*   Invoke `absl::ParseFlag()` and `absl::UnparseFlag()` within your free
    function overloads to get the string conversion behavior implemented for
    constituent built-in types.
*   Only boolean flags are allowed to not pass a value: e.g. `--enable_foo` or
    `--noenable_foo`. As a result, all custom flag types require an explicit
    value to be passed to `AbslParseFlag()` and `AbslUnparseFlag()`, even if
    that value is the empty string (e.g. `--my_custom_flag=""`).

[retired-flags]: https://abseil.io/tips/90
[friend-functions]: http://en.cppreference.com/w/cpp/language/friend
[time-library]: time.md#time-durations
[civiltime-library]: time.md#civil-times
[shell-expansions]: https://www.gnu.org/software/bash/manual/html_node/Shell-Expansions.html

---

## File: docs/cpp/guides/format.md

---
title: "absl::StrFormat()"
layout: docs
sidenav: side-nav-cpp.html
type: markdown
---

# absl::StrFormat()

The `str_format` library is a typesafe replacement for the family of `printf()`
string formatting routines within the `<cstdio>` standard library header. The
`str_format` library provides most of the functionality of `printf()` type
string formatting and a number of additional benefits:

*   Type safety, including native support for `std::string` and
    `absl::string_view`
*   Reliable behavior independent of standard libraries
*   Support for the POSIX positional extensions
*   Supports Abseil types such as `absl::Cord` natively and can be extended to
    support other types.
*   Much faster (generally 2 to 3 times faster) than native `printf` functions
*   Streamable to a variety of existing sinks
*   Extensible to custom sinks

Additionally, the library includes replacements for `printf()`, `fprintf()`, and
`snprintf()`.

## Basic Usage

The main `StrFormat()` function is a variadic template that returns a string
given a `printf()`-style *format string* and zero or more additional arguments.
Use it as you would `sprintf()`.

The format string generally consists of ordinary character data along with one
or more format conversion specifiers (denoted by the `%` character). Ordinary
character data is returned unchanged into the result string, while each
conversion specification performs a type substitution from `StrFormat()`'s other
arguments.

`StrFormat()` returns an empty string on error, and is marked as
`ABSL_MUST_USE_RESULT`.

Example:

```cpp
#include "absl/strings/str_format.h"

std::string s = absl::StrFormat("Welcome to %s, Number %d!", "The Village", 6);
EXPECT_EQ("Welcome to The Village, Number 6!", s);
```

The `StrFormat()` format string should usually be declared `constexpr`\*; as a
result, if you need to provide it as a variable, use an `absl::string_view`
instead of a `std::string`:

```cpp
// Won't compile, not constexpr (and the `std::string` can't be declared
// constexpr).
std::string format_string = "Welcome to %s, Number %d!";
std::string s = absl::StrFormat(format_string, "The Village", 6);

// This will compile.
constexpr absl::string_view kFormatString = "Welcome to %s, Number %d!";
std::string s = absl::StrFormat(kFormatString, "The Village", 6);
```

Requiring the format string to be `constexpr` allows compile-time checking of
the format strings.

NOTE: \* a format string must either be declared `constexpr` or dynamically
formatted using an `absl::ParsedFormat` type. See
[Advanced Formatting](#advanced) below.

### Conversion Specifiers

The `str_format` library mostly follows the POSIX syntax as used within the
[POSIX `printf()` family specification][1], which specifies the makeup of a
format conversion specifier. (Exceptions are noted below.)

A format conversion specifier is a string of the following form:

*   The `%` character
*   An optional positional specifier of the form `n$`, where `n` is a
    non-negative, positive value. (E.g. `3$`, `10$`, etc.). Note that positional
    modifiers are fully supported in `StrFormat`; they are a POSIX extension and
    not part of standard `printf` notation.
*   An optional set of justification and padding flags:
    *   `-` to left-justify the result. (Right-justification is the default.)
    *   `+` to force prepending a plus sign to positive results. (Minus signs
        are always prepended.)
    *   ` ` (space) to prepend spaces to the result of a signed conversion. (`+`
        takes precedence over spaces).
    *   `#` to use an alternative form of conversion for certain specifiers.
        (E.g. Using `#` on a hex conversion will prepend `0x` or `0X` to hex
        string results.)
    *   `0` (zero) to pad leading zeros for integer and floating-point
        conversions. (Zero-padding is ignored for integers if precision is
        explicitly specified.) This flag is ignored if `-` is used.
*   An optional integer value of the form `n` to specify the minimum width of
    the result, or `**variable*` to use a variable of type `int`
    to specify this value.
*   An optional precision value specified as `.n`, where `n` is a integral
    value, or `.**variable*` to use a variable of type `int` to
    specify this value.
*   A length modifier to modify the length of the data type. In `StrFormat()`,
    these values are largely ignored (and not needed, since `StrFormat()` is
    type-safe) but are allowed for backwards compatibility:
    *   `hh`, `h`, `l`, `ll`, `L`, `j`, `z`, `t`, `q`
    There is one case where the length modifier has a visible effect: if the
    requested type is `c`, an `l` modifier causes the supplied argument to be
    treated as a `wchar_t` instead of a `char`. (This happens automatically if
    the supplied argument is already of type `wchar_t`.)
*   A type-specifier:
    *   `c` for character values. These will be treated like `char` unless the
        supplied type is `wchar_t` or an `l` modifier is present, in which case
        they will be treated like `wchar_t` and converted to multibyte strings
        encoded as UTF-8.
    *   `s` for string values. Wide strings (`std::wstring`,
        `std::wstring_view`) will be converted to multibyte strings encoded as
        UTF-8.
    *   `d` or `i` for integer values, including enumerated type values
    *   `o` for unsigned integer conversions, including enumerated type values,
        into octal values
    *   `x` or `X` for unsigned integer conversions, including enumerated type
        values, into hex values
    *   `u` for unsigned integer values
    *   `f` or `F` for floating point values into decimal notation
    *   `e` or `E` for floating point values into exponential notation
    *   `a` or `A` for floating point values into hex exponential notation
    *   `g` or `G` for floating point values into decimal or exponential
        notation based on their precision
    *   `p` for pointer address values
    *   `n` for the special case of writing out the number of characters written
        to this point.
    *   `v` for values using the default format for a deduced type. These
        deduced types include many primitive types denoted here as well as
        user-defined types containing the proper extensions. (See
        [User Defined Formats](#user-defined-formats) below.)

NOTE: the `n` specifier within the `printf` family of functions is unsafe.
`StrFormat()` allows use of `%n` only when capturing such values within a safe
`FormatCountCapture` class. See example below.

NOTE: the `v` specifier (for "value") is a type specifier not present in the
`POSIX` specification. `%v` will format values according to their deduced type.
`v` uses `d` for signed integer values, `u` for unsigned integer values, `g` for
floating point values, and formats boolean values as `"true"`/`"false"` (instead
of `1` or `0` for booleans formatted using `d`). `const char*` is not supported;
please use `std::string` and `string_view`. `char` is also not supported due to
ambiguity of the type. This specifier does not support modifiers.

Examples:

```
/* Detailed source-code truncated for AI context efficiency. */
```

### Type Support

`StrFormat()` intrinsically supports all of these fundamental C++ types:

*   Characters:
    *   `char`
    *   `signed char`
    *   `unsigned char`
    *   `wchar_t`
*   Strings:
    *   `std::string`
    *   `std::wstring`
    *   `std::string_view` (if available)
    *   `std::wstring_view` (if available)
*   Integers:
    *   `int`
    *   `short`
    *   `unsigned short`
    *   `unsigned`
    *   `long`
    *   `unsigned long`
    *   `long long`
    *   `unsigned long long`
*   Floating-point:
    *   `float`
    *   `double`
    *   `long double`

Unlike the `printf` family of functions, `StrFormat()` doesn't rely on callers
encoding the exact types of arguments into the format string. (With `printf()`
this must be carefully done with length modifiers and conversion specifiers -
such as `%llu` encoding the type `unsigned long long`.) In the `str_format`
library, a format conversion specifies a broader C++ conceptual category
instead of an exact type. For example, `%s` binds to any string-like argument,
so `std::string`, `std::wstring`, `absl::string_view`, `const char*`, and
`const wchar_t*` are all accepted. Likewise, `%d` accepts any integer-like
argument, etc.

## Advanced Formats {#advanced}

Format strings that are very frequently used or performance-critical can be
specified using an `absl::ParsedFormat`. An `absl::ParsedFormat` represents a
pre-parsed `absl::FormatSpec` with template arguments specifying a collection of
conversion specifiers.

In C++14, these conversion specifiers are restricted to single char values (e.g.
`d`); in C++17 or later, you may also specify one or more
`absl::FormatConversionCharSet` enums (e.g. `absl::FormatConversionCharSet::d`
or `absl::FormatConversionCharSet::d | absl::FormatConversionCharSet::x` using
the bitwise-or combination.

Some enums specify whole conversion groups:

*   `absl::FormatConversionCharSet::kIntegral` = `d | i | u | o | x | X`
*   `absl::FormatConversionCharSet::kFloating` = `a | e | f | g | A | E | F | G`
*   `absl::FormatConversionCharSet::kNumeric` = `kIntegral | kFloating`
*   `absl::FormatConversionCharSet::kString` = `s`
*   `absl::FormatConversionCharSet::kPointer` = `p`

These type specifiers will be checked at compile-time. This approach is much
faster than reparsing `const char*` formats on each use.


```cpp
// Verified at compile time.
static const auto* const format_string =
    new absl::ParsedFormat<'s','d'>("Welcome to %s, Number %d!");
absl::StrFormat(*format_string, "TheVillage", 6);

// Verified at runtime.
auto format_runtime = absl::ParsedFormat<'d'>::New(format_string);
if (format_runtime) {
  value = absl::StrFormat(*format_runtime, i);
} else {
  ... error case ...
}

// C++17 allows extended formats to support multiple conversion characters per
// argument, specified via a combination of `FormatConversionCharSet` enums.
using MyFormat = absl::ParsedFormat<absl::FormatConversionCharSet::d |
                                    absl::FormatConversionCharSet::x>;
MyFormat GetFormat(bool use_hex) {
  if (use_hex) return MyFormat("foo %x bar");
  return MyFormat("foo %d bar");
}

```

Pre-compiled formats can also be used as a way to pass formats through API
boundaries in a type-safe manner. The format object encodes the type information
in its template arguments to allow compile-time checking in the formatting
functions.

Example:

```cpp
// Note: this example only compiles in C++17 and above.
class MyValue {
 public:
  // MyValueFormat can be constructed from a %d or a %x format and can be
  // used with any argument type that can be formatted with %d or %x.
  using MyValueFormat = absl::ParsedFormat<absl::FormatConversionCharSet::d |
                                           absl::FormatConversionCharSet::x>;
  const MyValueFormat& GetFormat(int radix) const {
    return radix == RADIX_HEX ? format_x_ : format_d_;
  }
 private:
   const MyValueFormat format_d_{"%6d"};
   const MyValueFormat format_x_{"%8x"};
};

std::string PrintIt(const MyValue& foo) {
  return absl::StringF(foo.GetFormat(mode), my_int_value_);
}
```

## PrintF Replacements

In addition to the `std::sprintf()`-like `StrFormat()` function, `str_format.h`
also provides a number of drop-in replacements for `std::printf()`,
`std::fprintf()` and `std::snprintf()`:

*   `absl::PrintF()`
*   `absl::FPrintF()`
*   `absl::SNPrintF()`

These functions are all analogs to the C builtin functions. In particular, they
take the same arguments, return an `int` with the same semantics and can set
`errno`. Use these functions as you would use any printf variant.

Example:

```cpp
absl::PrintF("Trying to request TITLE: %s USER: %s\n", title, user);
```

## Appending to a String

The `absl::StrAppendFormat()` function allows you to perform `printf`-like
formatting to an existing `&dest` string, appending the formatted string to it.
`StrAppendFormat()` returns `*dest` as a convenience for chaining purposes.

Example:

```cpp
std::string& absl::StrAppendFormat(&dest, format, ...)
```

## Writing to a Stream

`absl::StreamFormat()` returns an object that can be efficiently streamed to a
`std::ostream`, such as I/O or files.

NOTE: the returned object must be used immediately. That is, do not retain it in
an 'auto' variable.

Example:

```cpp
//  Stream to standard output
std::cout << absl::StreamFormat("name: %-20.4s: quota: %7.3f", name, quota);

// Stream to a file
if (FILE* file_handle = fopen("myfile.txt", "w"); file_handle != nullptr) {
  int result =
      absl::FPrintF(file_handle, "%s", "C:\\Windows\\System32\\");
  return result;
}
```

## User-Defined Formats {#user-defined-formats}

The `str_format` library provides customization utilities for formatting
user-defined types using `StrFormat()`. As with most type extensions, you should
own the type you wish to extend.

> Tip: For types you don't own you can use `absl::FormatStreamed()` to format
> types that have an `operator<<` but no intrinsic type support within
> `StrFormat()`.
>
> ```cpp
> absl::PrintF("My Foo: %s\n", absl::FormatStreamed(foo));
> ```

There are two methods of formatting user-defined types:

*   `AbslStringify()` provides a simpler user API using the `v` type specifier,
    and as well as working with `StrFormat()`, also works with `absl::StrCat()`,
    `absl::Substitute()`, logging and GoogleTest.[^1]
*   `AbslFormatConvert()` is more customizable, allowing users more control over
    type specifiers and additional modifiers for formatting their types.

We'll cover both of these approaches below.

### `AbslStringify()`

To make a type support the `AbslStringify()` extension point, define a suitable
`AbslStringify()` function template for that type as described below. For a
class type, `AbslStringify()` should be defined as a `friend` function template.
For an enumerated type `E`, define `AbslStringify()` at namespace scope in the
same namespace as `E` so that it can be found by argument-dependent looking
(ADL).

An `AbslStringify()` overload should have the following signature:

```cpp
template <typename Sink>
void AbslStringify(Sink& sink, const UserDefinedType& value);
```

Note: `AbslStringify()` utilizes a generic "sink" buffer to construct its
string. For information about supported operations on `AbslStringify()`'s sink,
see https://abseil.io/docs/cpp/guides/abslstringify.

`AbslStringify()` only supports use with the type specifier `%v`, which uses
type deduction for formatting purposes.

An example usage within a user-defined type is shown below:

```cpp
struct Point {

  ...
  // StrFormat support is added to the Point class through an AbslStringify()
  // friend declaration.
  template <typename Sink>
  friend void AbslStringify(Sink& sink, const Point& p) {
    absl::Format(&sink, "(%d, %d)", p.x, p.y);
  }

  int x;
  int y;
}
```

Formatting a `Point` can then simply use the `%v` type specifier:

```cpp
// StrFormat has built-in support for types extended with AbslStringify
absl::StrFormat("The point is %v", p);
// AbslStringify also automatically includes support for absl::StrCat and
// absl::Substitute()
absl::StrCat("The point is ", p);
absl::Substitute("The point is $0", p);
```

Additionally, `AbslStringify()` itself can use `%v` within its own format
strings to perform this type deduction. Our `Point` above could be formatted as
`"(%v, %v)"` for example, and deduce the `int` values as `%d`.

### `AbslFormatConvert()`

To extend formatting to your custom type using `AbslFormatConvert()`, provide an
`AbslFormatConvert()` overload as a free (non-member) function within the same
file and namespace of that type, usually as a `friend` definition. The
`str_format` library will check for such an overload when formatting
user-defined types using `StrFormat()`.

An `AbslFormatConvert()` overload should have the following signature:

```cpp
absl::FormatConvertResult<...> AbslFormatConvert(
    const X& value,
    const absl::FormatConversionSpec& conversion_spec,
    absl::FormatSink *output_sink);
```

* The `absl::FormatConvertResult` return value holds the set of
  `absl::FormatConversionCharSet` values valid for this custom type. A return
  value of `true` indicates the conversion was successful; if `false` is
  returned, `StrFormat()` will produce an empty string and this result will be
  propagated to `FormatUntyped()`.
* `absl::FormatConversionSpec` holds the fields pulled from the user string as
  they are processed. See "Conversion Specifiers" above for full documentation
  on this format.
* `absl::FormatSink` holds the formatted string as it is built.

The `absl::FormatConversionSpec` class also has a number of member functions to
inspect the returned conversion character specification:

* `conversion_char()` returns the basic conversion character for this format
  operation.
* `width()` and `precision()` indicate that the conversion operation should
  adjust the resulting width or precision of the result.
* `is_basic()` indicates that no additional conversion flags are included in the
  conversion, including any for modifying the width or precision. This method is
  useful for optimizing conversions via a fast path.
* `has_left_flag()` indicates whether the result should be left justified,
  through use of a '-' character in the format string. E.g. "%-s"
* `has_show_pos_flag()` indicates whether a sign column is prepended to the
  result for this conversion character in the format string, even if the result
  is positive, through use of a '+' character in the format string. E.g. "%+d"
* `has_sign_col_flag()` indicates whether a mandatory sign column is added to
  the result for this conversion character, through use of a space character
  (' ') in the format string. E.g. "% i"
* `has_alt_flag()` indicates whether an "alternate" format is applied to the
  result for this conversion character. E.g. "%#h"
* `has_zero_flag()` indicates whether zeroes should be prepended to the result
  for this conversion character instead of spaces, through use of the '0'
  character in the format string. E.g. "%0f"

These member functions can be used to select how to process conversion
operations encountered in the source format strings.

An example usage within a user-defined type is shown below:

```cpp
struct Point {

  ...
  // StrFormat support is added to the Point class through an
  // AbslFormatConvert() friend declaration.
  //
  // FormatConvertResult indicates that this formatting extension will accept
  // kIntegral ( d | i | u | o | x | X) or kString (s) specifiers. Successful
  // conversions will return `true`.
  friend absl::FormatConvertResult<absl::FormatConversionCharSet::kString |
                                   absl::FormatConversionCharSet::kIntegral>
  AbslFormatConvert(const Point& p,
                    const absl::FormatConversionSpec& spec,
                    absl::FormatSink* s) {
    if (spec.conversion_char() == absl::FormatConversionChar::s) {
      // If the conversion char is %s, produce output of the form "x=1 y=2"
      absl::Format(s, "x=%vy=%v", p.x, p.y);
    } else {
      // If the conversion char is integral (%i, %d ...) , produce output of the
      // form "1,2". Note that no padding will occur here.
      absl::Format(s, "%v,%v", p.x, p.y);
    }
    return {true};
  }

  int x;
  int y;
};
```

## Custom Sinks

```cpp
bool absl::Format(&dest, format, ...)
```

Similar to `absl::StrAppendFormat`, but the output is an arbitrary destination
object that supports the `RawSink` interface. To implement this interface,
provide an overload of `AbslFormatFlush()` for your sink object:

```cpp
void AbslFormatFlush(MySink* dest, absl::string_view part);
```

where `dest` is the pointer passed to `absl::Format()`. This is usually
accomplished by providing a free function that can be found by ADL.

The library already provides builtin support for using sinks of type
`std::string`, `std::ostream`, and `absl::Cord` with `absl::Format()`.

Note: Remember that only the type owner should write extensions like this. An
overload for the type `MySink` should **only** be declared in the header that
declares `MySink`, and in the same namespace as `MySink`. If a particular type
does not support this extension ask the owner to write one, or make your own
wrapper type that supports it.

[1]: http://pubs.opengroup.org/onlinepubs/9699919799/functions/fprintf.html

[^1]: See https://abseil.io/docs/cpp/guides/abslstringify for more documentation on other libraries that
    support `AbslStringify()`

---

## File: docs/cpp/guides/hash.md

---
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`](https://en.cppreference.com/w/cpp/utility/hash) and various
other hash functors. 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.

## Including the `absl::Hash` Library

You only need to include the `absl::Hash` library if you need to invoke
`absl::Hash()` directly. You don't need to include this library to make your
types hashable.

```cpp
#include "absl/hash/hash.h"
```

## **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 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++
#include "absl/hash/hash_testing.h"

...

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 Abseil. All
types hashable by the `absl::Hash` framework will automatically be hashable in
Abseil containers.

However, you should usually not pass `absl::Hash<T>` directly when passing a
hasher to be used by a container. Instead specify
`absl::DefaultHashContainerHash<T>`, which adds support for heterogeneous lookup
and matches what the Abseil containers do by default.

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

```c++
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, or across different dynamically loaded
libraries in your program.

### 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::Cord`
    *   `absl::string_view`
    *   `std::string` (as well as any instance of `std::basic_string` that uses
        `char` and `std::char_traits<char>`)
    *   `std::string_view`
    *   `std::wstring`
    *   `std::u16string`
    *   `std::u32string`
*   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`
*   absl hash tables themselves (provided the elements are hashable):
    *    `absl::flat_hash_map`
    *    `absl::flat_hash_set`
    *    `absl::node_hash_map`
    *    `absl::node_hash_set`

NOTE: the list above is not meant to be exhaustive. Additional type support
may be added, in which case the above list will be updated.

Unlike `std::hash` and similar hashers, `absl::Hash` should **not** be
specialized. Instead, user-defined types can be made hashable by providing
an `AbslHashValue()` overload, as discussed [below](#making-hashable-types).

### `absl::Hash` Invocation Evaluation
When invoked, `absl::Hash<T>` searches for supplied hash functions in the
following order:

*   Natively supported types out of the box (see above)
*   Types for which an `AbslHashValue()` overload is provided (such as
    user-defined types). See
    [Making Your User-Defined Types Hashable](#making-hashable-types) below.
*   Types which define a `HASH_NAMESPACE::hash<T>` specialization (aka
    `__gnu_cxx::hash<T>` for gcc/Clang or `stdext::hash<T>` for MSVC)
*   Types which define a `std::hash<T>` specialization

The fallback to legacy hash functions exists mainly for backward compatibility.
If you have a choice, prefer defining an `AbslHashValue()` overload instead of
specializing any legacy hash functors. Legacy APIs can reduce the quality or
performance of the hash algorithm so their use is only recommended if
`AbslHashValue()` cannot be provided for a type.

## Making Your User-Defined Types Hashable {#making-hashable-types}

If you want your type to be hashable by `absl::Hash`, you need to define an
overload of `AbslHashValue()` for your type. The overload should combine
state with the existing hash state (denoted as `H` in the template below), and
your class must provide an equality operator.

### Example

```c++
class MyClass {
  // ...

  friend bool operator==(const MyClass& lhs, const MyClass& rhs);
  template <typename H>
  friend H AbslHashValue(H h, const MyClass& m);

 private:
  std::vector v;
  std::string str;
  bool b;
};

bool operator==(const MyClass& lhs, const MyClass& rhs) {
  return lhs.v == rhs.v && lhs.str == rhs.str && lhs.b == rhs.b;
}

template <typename H>
H AbslHashValue(H h, const MyClass& m) {
  return H::combine(std::move(h), m.v, m.str, m.b);
}
```

Notice that `AbslHashValue()` is not a class member, but an ordinary function.
An `AbslHashValue()` overload for a type `Foo` should **only** be declared in
the header that defines `Foo`, and in the same namespace as `Foo`.

Also note that `MyClass` does not require adding an additional `#include` or any
`BUILD` dependency to provide its overload of `AbslHashValue()`.

### The `AbslHashValue()` Overload

An `AbslHashValue()` overload is a function template that takes two arguments:

1.  An object representing the current state of the hash algorithm, i.e. all of
    the input it has received so far, in some unspecified partially-hashed form
2.  The value to be hashed

It must return the resulting state object after combining its state to the
existing state, using the `Hash::combine()` or `Hash::combine_contiguous()`
functions. (See [Combining Hash States](#combining-states) below.)

NOTE: The hash state object type and value is unspecified except for the two
`combine*` functions. Users should not rely upon any other parts
of the state object.

If there is an `AbslHashValue()` overload that takes `Foo` as its second
argument, we say that `Foo` is "hashable".

`AbslHashValue()`'s job is to produce a new hash state by combining the input
hash state with a representation of the value, called the value's *hash
expansion*. The hash expansion is a sequence of simpler hashable values that
satisfies the following runtime requirements:

*   If two `Foo` objects are equal, then their hash expansions must be equal
*   Similarly, if two `Foo` objects are unequal, their hash expansions should be
    unequal[^unequal]
*   If two `Foo` objects are unequal, neither hash expansion should be a suffix
    of the other

[^unequal]: It can be OK for unequal values to have equal hash expansions, so
    long as that happens with very low probability. However, this is
    rarely necessary, and it degrades the quality of the final hash, so
    you should avoid it if possible.

These requirements are built on the concept of equality, so how you define
`AbslHashValue()` depends very much on how you define `operator==()`. In the
example above, two `MyClass` values are equal if and only if each of their
members are equal, so we can satisfy all the requirements for making `MyClass`
hashable by making the hash expansion consist simply of a list of those members.

More generally, if your `==` operator doesn't contain any loops or branches, but
just compares a fixed set of values, then your hash expansion should resolve to
that fixed set of values. Note that for this rule of thumb, only the code
directly in your `==` operator is of concern, not in the other `==` operators
that it calls; for example, `MyClass`'s hash expansion is just the values (`v`,
`str`, `b`), because its `==` operator doesn't contain any loops, even though it
calls `vector`'s `==` operator, which does.

### Combining Hash States {#combining-states}

Once you've figured out what your hash expansion is, you just need to combine it
with the hash state. The hash state object provides three static functions for
doing this:

*   `HashState::combine(H, const Args&...)`: Combines an arbitrary number of
    values into a hash state, returning the updated state. Each of the `Args`
    types must be hashable.

> NOTE:
>
> ```c++
>   state = H::combine(std::move(state), value1, value2, value3);
> ```
>
> is guaranteed to produce the same hash expansion as
>
> ```c++
>   state = H::combine(std::move(state), value1);
>   state = H::combine(std::move(state), value2);
>   state = H::combine(std::move(state), value3);
> ```

*   `HashState::combine_contiguous(H, const T*, size_t)`: Combines a contiguous
    array of `size` elements into a hash state, returning the updated state.

> NOTE:
>
> ```c++
>   state = H::combine_contiguous(std::move(state), data, size);
> ```
>
> is NOT guaranteed to produce the same hash expansion as a for loop but it may
> be faster. If you need this guarantee, write out the for loop instead.

*   `HashState::combine_unordered(H, begin, end)`: Combines a set of elements
    denoted by an iterator pair into a hash state, returning the updated state.

    Unlike the other two methods, the hashing is order-independent. This can be
    used to hash unordered collections.  It should *not* be used if the order of
    the elements is significant.

Note that the state objects should always be passed by value. Furthermore, they
are move-only types (like `std::unique_ptr`), so you'll often have to use
`std::move` when passing them.

## Testing Your Custom `AbslHashValue` Implementation {#testing-hashable-types}

The Abseil hash library provides  `absl::VerifyTypeImplementsAbslHashCorrectly`
to verify that a type implements its overload correctly. This function has a few
requirements:

*   The type must implement the `==` operator correctly.
*   The caller must provide instances of the type that include any interesting
    representations for their type. (For example, a type with a small size
    optimization should include equivalent instances that use the small size
    optimization and that do not.)

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

This call will verify that for any two elements `x` and `y` passed:

*   if `(x == y)`, then their hash expansions must be equal
*   if `!(x == y)` then their hash expansions must differ, and neither can be a
    suffix of the other.

In case of errors, `absl::VerifyTypeImplementsAbslHashCorrectly()` will print
diagnostics indicating which two elements violated these requirements.

`absl::VerifyTypeImplementsAbslHashCorrectly()` also supports testing
heterogeneous lookup and custom equality operators. In this case, we would use a
tuple to pass mixed types.

```c++
// I have two types that share a `==` domain, and the hash function is
// supposed to be consistent between them.

TEST(Cord, HashMatchesString) {
  EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(std::make_tuple(
    std::string(""), std::string("ABC"), std::string(1000,'a'),
    absl::Cord(""), absl::Cord("ABC"), absl::Cord(std::string(1000,'a'))
  )));
}

// Sometimes the types can't be directly compared, but you still want to ensure
// that equivalent values have the same hash value.
// This is rare, as it would require a custom Eq operator to match the default
// Hash.

TEST(MyClass, SupportsAbslHash) {
  EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(std::make_tuple(
      // MyClass elements
      MyClass(),
      MyClass(1, 2),
      MyClass(2, 3),
      MyClass(0, 0),

      // MyOtherClass elements
      MyOtherClass(),
      MyOtherClass("A"),
      MyOtherClass("AB"),
      MyOtherClass("ABC"),
  ), CustomEqThatSupportsMyClassAndMyOtherClass()));
}

```

### Extending Types You Don't Own

As mentioned above, the only correct place to extend an API for a type is in the
same file that declares the type. This includes the `AbslHashValue()` extension
point.

If you want to hash objects of types you do not own, the solution depends on the
type in question, but the most common ones:

*   Use an explicit hash/equality function when declaring a hash table. Some
    types already provide these functions. For others you might need to write
    one yourself.
*   Add the extension point in the right place, or ask the owners of that code
    to do it for you.

For some known types that you may wish to hash, see the sections below for
advice.

#### Types in `std`

Most relevant types in the `std` namespace are directly supported by
`absl::Hash`. This includes all sequence and ordered associative containers.

### Making Your Types Hashable When You Cannot Use Templates

The `AbslHashValue` extension point is a function template that accepts
arbitrary hash state objects. This decouples the specific hash state from the
hash expansion code path. However, not all types can implement this function as
a template.

Two common cases where this technique fails are PImpl classes and interfaces
with virtual functions. For these cases the framework provides the class
`absl::HashState`, which is a type-erased version of the hash state object.

Usage example:

```c++
#include "absl/hash/hash.h"  // For definition of `absl::HashState`

// A class that uses the PImpl technique:

// in .h file
class MyClass {
 public:
  template <typename H>
  friend H AbslHashValue(H state, const MyClass& value) {
    value.HashValue(absl::HashState::Create(&state));
    return std::move(state);
  }

 private:
  void HashValue(absl::HashState state) const;

  class MyClassImpl;
  std::unique_ptr<MyClassImpl> impl_;
};

// in .cc file
...
void MyClass::HashValue(absl::HashState state) const {
  absl::HashState::combine(std::move(state), impl_->a, impl_->b, impl_->c);
}
```

---

## File: docs/cpp/guides/index.md

---
title: "C++ Programming Guides"
layout: docs
sidenav: side-nav-cpp.html
type: markdown
---

# C++ Programming Guides

The developer guides below complement comments within the Abseil header files.
Over time, we hope to have comprehensive documentation, including examples, for
all code within Abseil within this guide.

* [Abseil Fundamentals](base)
* [Container Library](container)
* [Flags Library](flags)
* [Hash Library](hash)
* [Logging Library](logging)
* [Meta Library Guide](meta)
* [Numeric Library Guide](numeric)
* [Options Guide](options)
* [Random Library](random)
* [Status Guide](status)
* [Synchronization Guide](synchronization)
* [StrFormat Guide](format)
* [Strings Guide](strings)
* [Time Library](time)
* [Types Library](types)

---

## File: docs/cpp/guides/logging.md

---
title: "The Abseil Logging Library"
layout: docs
sidenav: side-nav-cpp.html
type: markdown
---

# The Abseil Logging Library

The Abseil Logging library provides facilities for writing short text messages
about the status of a program to `stderr`, disk files, or other sinks (via an
extension API).

## API Overview {#API}

The `LOG()` and `CHECK()` macro families are the core of the API. Each forms the
beginning of a statement that additional data may optionally be streamed into
just like `std::cout`.

All data streamed into a single macro will be concatenated and written to the
logfiles as a single message with a [prefix](#prefix) formed from metadata
(time, file/line, etc.). In particular, and unlike `std::cout`, the library
supplies a newline at the end of each message, so you shouldn't generally end
logging statements with `\n` or `std::endl`. Any newlines that *are* streamed in
will show up in the logfiles.

For more detailed information, see the header files.

### Header Files for `LOG()` and `CHECK()`

Import the logging and check macros with the following #includes. The path to
`absl` may differ depending on its installation location within your system.

```c++
#include "absl/log/log.h"
#include "absl/log/check.h"
```

### `LOG()` Macro {#LOG}

`LOG()` takes a severity level as an argument, which defines the granularity and
type of logging information to log. The four basic severity levels are `INFO`,
`WARNING`, `ERROR`, and `FATAL`. `FATAL` is not named idly; it causes the
logging library to terminate the process after recording the streamed message.
See below for more about [severity levels](#severity), including best practices
for picking one.

```c++
LOG(INFO) << "Hello world!";
```

This will produce a message in the logs like:

```
I0926 09:00:00.000000   12345 foo.cc:10] Hello world!
```

The format of the metadata is documented [below](#prefix).

### `CHECK()` Macro {#CHECK}

`CHECK()` is an assertion. Its severity is always `FATAL`, so its only argument
is a condition that *should* be true. If it isn't, `CHECK()` writes to the log
and terminates the process. It's active in **all build modes** (unlike the C
`assert()` macro) and logs failures to the application logs in the same way as
`LOG()` but with additional information about what failed and where.

Like `FATAL`, a `CHECK()` assertion should be used sparingly (especially in
server code) and only in cases where it is preferable to actually terminate the
process rather than attempt recovery: e.g. no recovery is possible, or memory
corruption could damage user data. Note that you should also be aware of where
your code may be running; a `CHECK()` in a commandline utility or batch
processing job needs less caution than a `CHECK()` in a user-facing service. If
you are unsure where your code will run (if you are writing a utility library,
for example), be conservative and assume it will be used in production-facing
services and should avoid `CHECK()` where possible.

```c++
CHECK(!filenames_sorted.empty()) << "no files matched";
ProcessFile(filenames_sorted.front());
```

This will produce a message in the logs like:

```
F0926 09:00:01.000000   12345 foo.cc:100] Check failed: !filenames_sorted.empty() no files matched
E0926 09:00:01.150000   12345 process_state.cc:1133] *** SIGABRT received by PID 12345 (TID 12345) on cpu 0 from PID 12345; stack trace: ***
E0926 09:00:01.250000   12345 process_state.cc:1136] PC: @     0xdeadbeef  (unknown)  raise
    @     0xdeadbeef       1920  FailureSignalHandler()
    @     0xdeadc0w5    2377680  (unknown)
(more stack frames follow)
```

Note that this log entry uses the prefix `F` for a severity level of `FATAL`.
The text of the condition itself is logged before the streamed operands.
Additionally, a stack trace is logged at severity `ERROR` (on lines prefixed
with `E`) after the `FATAL` message but before the process terminates.

Special two-argument forms spelled `CHECK_EQ()`, `CHECK_GT()`, `CHECK_STREQ()`
(for `char*` strings), etc. can be used to make assertions about comparisons
between streamable, comparable types. In addition to the text of the arguments,
these forms log the actual values of the arguments.

```c++
int x = 3, y = 5;
CHECK_EQ(2 * x, y) << "oops!";
```

This will produce a message in the logs like:

```
F0926 09:00:02.000000   12345 foo.cc:20] Check failed: 2 * x == y (6 vs. 5) oops!
```

### Alternate Macro Names for Interoperability

Abseil provides alternative macro names prefixed with `ABSL_` (e.g. `ABSL_LOG`)
for the benefit of projects that need them.  These macros are provided in
separate `absl_log.h` and `absl_check.h` header files.  Both names are identical
and are equally supported.

We expect most libraries to avoid logging in headers, and most projects to use
only one logging framework.  In these cases, the shorter names tend to be more
convenient and readable, which is especially valuable for macros used as heavily
as these tend to be.

### Severity Levels {#severity}

The `absl::LogSeverity` type represents severity levels. `LOG()`'s parameter is
actually not of this type, or of *any* type. Some [macro tricks](#hygiene) are
used to make `LOG(ERROR)` work without using a macro or global symbol named
`ERROR`. This is necessary because `ERROR` is defined by some popular
third-party packages (e.g. Microsoft Windows) and cannot be redefined.

There are four proper severity levels:

*   [`INFO`](#severity-info){#severity-info} corresponds to
    `absl::LogSeverity::kInfo`. It describes *expected* events that are
    important for understanding the state *of the program* but which are not
    indicative of a problem. Libraries, especially low-level common libraries,
    should use this level sparingly lest they spam the logs of every program
    that uses them.
    The [`VLOG()`](#VLOG) macro uses `INFO` severity with an additional
    verbosity parameter and can be switched on and off on a per-source-file
    basis. It is a good alternative for libraries.
*   [`WARNING`](#severity-warning){#severity-warning} corresponds to
    `absl::LogSeverity::kWarning`. It describes unexpected events which *may*
    indicate a problem.
*   [`ERROR`](#severity-error){#severity-error} corresponds to
    `absl::LogSeverity::kError`. It describes unexpected problematic events that
    the program is able to recover from. `ERROR` messages should be actionable,
    meaning that they should describe actual problems with the software or its
    configuration (and not e.g. with user input) and the combination of the
    message, the file name and line number, and surrounding messages should be
    sufficient to at least understand the event being reported.
*   [`FATAL`](#severity-fatal){#severity-fatal} corresponds to
    `absl::LogSeverity::kFatal` and is the implicit severity level for `CHECK`
    failures. It describes unrecoverable problems. Logging at this level
    terminates the process. The `FATAL` logging level should be used sparingly
    and carefully in services, especially user-facing services, and in library
    code that may be included in such services. Each fatal log is a potential
    outage if a significant fraction of the serving jobs hit it at once.
    Fatal logging is more often appropriate for developer tools, some batch
    jobs, and failures at job startup. That said, process termination and
    outages are always preferable to undefined behavior (which could include
    user data corruption and/or a security or privacy incident), so `FATAL` is
    sometimes appropriate even in server and library code as a last resort in
    response to unexpected behavior that cannot be handled any other way.

There are also two pseudo-levels:

*   [`DFATAL`](#severity-dfatal){#severity-dfatal} ("debug fatal") corresponds
    to `absl::kLogDebugFatal`. Its value is `ERROR` in optimized builds (e.g. in
    production) and `FATAL` in other builds (e.g. tests). It can be useful for
    ensuring that an unexpected event causes tests to fail (by terminating the
    process) but does not harm production. Since production jobs will continue
    past a `DFATAL` failure, make sure to recover
    gracefully.
*   [`QFATAL`](#severity-qfatal){#severity-qfatal} ("quiet fatal") does not have
    a corresponding `absl::LogSeverity` value. It behaves like `FATAL` except
    that no stack trace is logged and `atexit()` handlers are not run. It is
    usually the best choice for errors occurring at startup (e.g. flag
    validation) where the control flow is uninteresting and unnecessary to
    diagnosis.
*   [`DO_NOT_SUBMIT`](#severity-do-not-submit){#severity-do-not-submit} is an
    alias for `ERROR`, and is the right level to use when you are using `LOG`
    for what's often called
    [`printf()` debugging](https://en.wikipedia.org/wiki/Debugging#printf_debugging).
    The name is easy to spot in review and is caught by common (but not
    on-by-default) presubmit
    checks.
    The contract is that **it must not be checked in**, so the Abseil team
    reserves the right to delete it, change what it does, and/or scrub any
    instances that do end up checked in, with or without notice.

If you want to specify a severity level using a C++ expression, e.g. so that the
level used varies at runtime, you can do that too:

```c++
LOG(LEVEL(MoonPhase() == kFullMoon ? absl::LogSeverity::kFatal
                                   : absl::LogSeverity::kError))
      << "Spooky error!";
```

### `VLOG()` Macro {#VLOG}

`VLOG()` ("verbose log") is used for runtime-configurable debug logging. The
macro takes a non-negative integer verbosity level as an argument - `INFO`
severity is implied. Verbosity level values are arbitrary, however lower values
correspond to more readily-visible messages. Non-zero verbosity levels are
disabled by default, and disabled `VLOG()`s have a very small performance cost,
so liberal use of `VLOG()` is acceptable in most cases without risk of serious
performance degradation or unacceptable log spam.

```c++
Foo::Foo(int num_bars) {
  VLOG(4) << "Constructing a new Foo with " << num_bars << " Bars";
  for (int i = 0; i < num_bars; i++) bars_.push_back(MakeBar(this));
}
```

Setting the `--v` flag will turn on all `VLOG()` messages at or below the
specified level. This is likely to make your logs hard to read and/or fill up
your disk. The `--vmodule` flag allows different levels to be set for different
source files; it takes a comma-delimited list of `key=value` pairs where each
key is a glob matched against filenames and each value is the verbosity level
that should be effective in matching files. The verbose logging level can also
be changed at runtime with `absl::SetVLogLevel` and `absl::SetGlobalVLogLevel`:

```c++
class FooTest : public testing::Test {
 protected:
  FooTest() {
    // Crank up the `VLOG()` level for `Foo` since it does not log much otherwise:
    absl::SetVLogLevel("foo_impl", 4);
  }
};
```

### Other Macro Variants {#macros}

The logging API contains a number of additional macros for special cases.

*   `QCHECK()` works like `CHECK()` but with the same variations as `QFATAL` vs.
    `FATAL`: it does not log a stack trace or run `atexit()` handlers on
    failure.

    ```c++
    int main (int argc, char**argv) {
      absl::ParseCommandLine(argc, argv);
      QCHECK(!absl::GetFlag(FLAGS_path).empty()) << "--path is required";
      ...
    ```

*   `PLOG()` and `PCHECK()` automatically append a string describing `errno` to
    the logged message. They are useful with system library calls that set
    `errno` on failure to indicate the nature of the failure. Their names are
    intended to be consistent with the `perror` library function.

    ```c++
    const int fd = open(path.c_str(), O_RDONLY);
    PCHECK(fd != -1) << "Failed to open " << path;

    const ssize_t bytes_read = read(fd, buf, sizeof(buf));
    PCHECK(bytes_read != -1) << "Failed to read from " << path;

    const int close_ret = close(fd);
    if (close_ret == -1) PLOG(WARNING) << "Failed to close " << path;
    ```

*   `DLOG()` ("debug log") and `DCHECK()` disappear from the binary completely
    in optimized builds. Note that `DLOG(FATAL)` and `DCHECK()` have very
    different semantics from `LOG(DFATAL)`.
    Debug logging is helpful for information that's useful when debugging tests
    but expensive to collect (e.g. acquiring a contended lock) in production:

    ```c++
    DLOG(INFO) << server.State();
    ```

    Be careful with `DCHECK()`; if it's worth checking in tests it's probably
    worth checking in production too:

    ```c++
    DCHECK(ptr != nullptr);
    ptr->Method();
    ```

    `DCHECK` can sometimes be useful for checking invariants in very hot
    codepaths, where checks in tests must be assumed to validate behavior in
    production.
    Just like `assert()`, be sure not to rely on evaluation of side-effects
    inside `DCHECK` and `DLOG` statements:

    ```c++ {.bad}
    DCHECK(server.Start());
    // In an optimized build, no attempt will have been made to start the
    // server!
    ```

*   `LOG_IF()` adds a condition parameter and is equivalent to an `if`
    statement. As with `if` and the ternary operator, the condition will be
    contextually converted to `bool`. `PLOG_IF()` and `DLOG_IF()` variants also
    exist.

    ```c++
    LOG_IF(INFO, absl::GetFlag(FLAGS_dry_run))
        << "--dry_run set; no changes will be made";
    ```

*   `LOG_EVERY_N()`, `LOG_FIRST_N()`, `LOG_EVERY_N_SEC()`, and
    `LOG_EVERY_POW_2()` add more complicated conditions that can't be easily
    replicated with a simple `if` statement. Each of these maintains a
    per-statement state object in static storage that's used to determine
    whether it's time to log again. They are thread-safe.
    The token `COUNTER` may be streamed into these; it will be replaced by a
    monotonically increasing count of the number of times execution has passed
    through this statement, including both the times when logging happened and
    the times when it did not. Macro variants with an added condition (e.g.
    `LOG_IF_EVERY_N()`) also exist, as do many combinations with `VLOG()`,
    `PLOG()`, and `DLOG()`.

    ```c++
    LOG_EVERY_N(WARNING, 1000) << "Got a packet with a bad CRC (" << COUNTER
                               << " total)";
    ```

### Mutator Methods {#mutators}

The `LOG()` and `CHECK()` macros support some chainable methods that alter their
behavior.

*   `.AtLocation(absl::string_view file, int line)`
    Overrides the location inferred from the callsite. The string pointed to by
    `file` must be valid until the end of the statement.
*   `.NoPrefix()`
    Omits the [prefix](#prefix) from this line. The prefix includes metadata
    about the logged data such as source code location and timestamp.
*   `.WithVerbosity(int verbose_level)`
    Sets the verbosity field of the logged message as if it was logged by
    `VLOG(verbose_level)`. Unlike `VLOG()`, this method does not affect whether
    statement is evaluated when the specified `verbose_level` has been disabled.
    The only effect is on `LogSink` implementations which make use of the
    `absl::LogSink::verbosity()` value. The value
    `absl::LogEntry::kNoVerbosityLevel` can be specified to mark the message not
    verbose.
*   `.WithTimestamp(absl::Time timestamp)`
    Uses the specified timestamp instead of one collected at the time of
    execution.
*   `.WithThreadID(absl::LogEntry::tid_t tid)`
    Uses the specified thread ID instead of one collected at the time of
    execution.
*   `.WithMetadataFrom(const absl::LogEntry &entry)`
    Copies all metadata (but no data) from the specified `absl::LogEntry`.
    This can be used to change the severity of a message, but it has some
    limitations:
    *   `ABSL_MIN_LOG_LEVEL` is evaluated against the severity passed into `LOG`
        (or the implicit `FATAL` level of `CHECK`).
    *   `LOG(FATAL)` and `CHECK` terminate the process unconditionally, even if
        the severity is changed later.
*   `.WithPerror()`
    Appends to the logged message a colon, a space, a textual description of the
    current value of `errno` (as by `strerror(3)`), and the numerical value of
    `errno`. The result is comparable to `PLOG()` and `PCHECK()`.
*   `.ToSinkAlso(absl::LogSink* sink)`
    Sends this message to `*sink` in addition to whatever other sinks it would
    otherwise have been sent to. `sink` must not be null.
*   `.ToSinkOnly(absl::LogSink* sink)`
    Sends this message to `*sink` and no others. `sink` must not be null.

## Logged Message Output {#output}

### Log Line Format {#prefix}

Each message is logged with metadata of the following form:

```
I0926 09:00:00.000000   12345 foo.cc:10] Hello world!
```

The prefix starts with an `I`, representing the `INFO` severity level, combined
with a date, `0926`. The time follows, with microseconds, in the machine's local
timezone. `12345` is a thread ID number. `foo.cc:10` is the source code
location where the `LOG()` statement appears, and the bracket and space are a
fixed delimiter before the message itself.

The prefix can be suppressed globally with the `--nolog_prefix` flag or for a
single message the `.NoPrefix()` [mutator method](#mutators).

### `absl::LogSink` {#LogSink}

`absl::LogSink` is an extension point for processing logged messages, such as by
writing them to a disk file.  A single message can be directed to it with the
`.ToSinkOnly()` or `.ToSinkAlso()` [mutator methods](#mutators), or a sink can
be registered to observe all logged messages (except those logged with
`.ToSinkOnly()`) with `absl::AddLogSink()` and unregistered with
`absl::RemoveLogSink`.  For example:

```c++
class LinePrinterLogSink : public absl::LogSink {
 public:
  LinePrinterLogSink() : fp_(fopen("/dev/lp0", "a")) {
    PCHECK(fp_ != nullptr) << "Failed to open /dev/lp0";
  }
  ~LinePrinterLogSink() {
    fputc('\f', fp_);
    PCHECK(fclose(fp_) == 0) << "Failed to close /dev/lp0";
  }
  void Send(const absl::LogEntry& entry) override {
    for (absl::string_view line :
         absl::StrSplit(entry.text_message_with_prefix(), absl::ByChar('\n'))) {
      // Overprint severe entries for emphasis:
      for (int i = static_cast(absl::LogSeverity::kInfo);
           i <= static_cast(entry.log_severity()); i++) {
        absl::FPrintF(fp_, "%s\r", line);
      }
      fputc('\n', fp_);
    }
  }

 private:
  FILE* const fp_;
};
```

A `LogSink` receives two copies of each `FATAL` message: one without a
stacktrace, and then one with. This quirk allows some diagnostic data to be
observed even if stacktrace collection fails or takes too long. The process will
terminate once the `LogSink` returns, i.e., there's no need for the sink to call
`abort()`.

Any logging that takes place in a registered `LogSink` or in a function called
by a registered `LogSink` is sent only to `stderr` and not to any registered
`LogSink`s so as to avoid infinite recursion.

### `stderr` Output {#stderr}

A `LogSink` that writes to `stderr` is included and registered by default.
globals.h declares some knobs that control which severity levels this sink
writes to stderr and which it discards.

## Configuration and Flags

There are a small number of runtime configuration knobs with accessors in
globals.h.  An optional `:flags` target is provided which defines Abseil flags
that control these knobs from the command-line.  If this target is not linked
in, logging does not depend on Abseil flags (nor vice-versa).

If `ABSL_MIN_LOG_LEVEL` is defined as a preprocessor macro at build-time,
logging at any severity less than its value (converted to `absl::LogSeverity`)
is removed and fatal statements (e.g. `CHECK`, `LOG(FATAL)`) terminate silently.
Expressions in logged messages are not evaluated, and string literals streamed
to such statements are typically stripped as dead code.  If this stripping is to
be relied upon, the unit tests in stripping_test.cc should be run regularly with
the toolchain and flags as the build you want stripped.  This behavior is beyond
the scope of what's guaranteed by the C++ standard, so it cannot be guaranteed
by Abseil.

If `ABSL_MAX_VLOG_VERBOSITY` is defined (as an integer) at build-time, `VLOG`s
with *greater* verbosity are similarly removed.

## FAQ {#FAQ}

### How do I make my type streamable into `LOG()`? {#streaming}

For a class type, define an `AbslStringify()` overload as a `friend` function
template for your type. The logging library will check for such an overload when
formatting user-defined types.

```cpp
namespace foo {

class Point {
  ...
  template <typename Sink>
  friend void AbslStringify(Sink& sink, const Point& point) {
    absl::Format(&sink, "(%d, %d)", point.x, point.y);
  }

  int x;
  int y;
};

// If you can't declare the function in the class it's important that the
// AbslStringify overload is defined in the SAME namespace that defines Point.
// C++'s lookup rules rely on that.
enum class EnumWithStringify { kMany = 0, kChoices = 1 };

template <typename Sink>
void AbslStringify(Sink& sink, EnumWithStringify e) {
  absl::Format(&sink, "%s", e == EnumWithStringify::kMany ? "Many" : "Choices");
}

}  // namespace foo
```

`AbslStringify()` can also use `absl::StrFormat`'s catch-all `%v` type specifier
within its own format strings to perform type deduction. `Point` above could be
formatted as `"(%v, %v)"` for example, and deduce the `int` values as `%d`.

For more details regarding `AbslStringify()` and its integration with other
libraries, see https://abseil.io/docs/cpp/guides/abslstringify.

Note: Types that implement `operator<<(std::ostream &, T)` can also be streamed
into `LOG()` but it is recommended that users implement `AbslStringify()` as it
has greater compatibility with other string formatting libraries.

### Why does logging use macros and not functions?

There are several reasons the logging system uses macros:

*   `CHECK()` uses stringification to include the source code text of the failed
    condition in the failure message. There's no way to do this in a function.

*   `CHECK(bar()) << foo();` does not evaluate `foo()` when `bar()` returns
    `true`. Likewise `LOG(INFO) << foo();` does not evaluate `foo()` if
    `ABSL_MIN_LOG_LEVEL` is `kWarning`. Functions can't do this.

### Okay, but how does `LOG(ERROR)` not use the name `ERROR`? It's right there! {#hygiene}

`LOG(severity)` is a preprocessor macro whose definition looks like
`LONG_INTERNAL_MACRO_NAME_##severity`. The `##` preprocessor operator
concatenates tokens, so writing `LOG(ERROR)` is just like writing
`LONG_INTERNAL_MACRO_NAME_ERROR`. The preprocessor works from left to right, so
it expands `LOG()` before it inspects `ERROR`, and after expanding `LOG()` there
is no longer an `ERROR` token to expand.

`LONG_INTERNAL_MACRO_NAME_ERROR` in turn expands to something like
`::internal_namespace::LogMessage(__FILE__,
__LINE__, ::absl::LogSeverity::kError)`, which does not use the name `ERROR`
either.

`LONG_INTERNAL_MACRO_NAME_LEVEL(x)` is a function-like macro of one argument;
this is how `LOG(LEVEL(x))` works.

This is also why misspelling a severity level, e.g. `LOG(WARN)` (this should be
`WARNING`), produces a diagnostic about `LONG_INTERNAL_MACRO_NAME_WARN` not
being defined rather than about `WARN` not being defined.

---

## File: docs/cpp/guides/meta.md

---
title: "The Meta Library"
layout: docs
sidenav: side-nav-cpp.html
type: markdown
---

# The Meta Library

This `meta` library contains C++14-compatible versions of standard
[`<type_traits>`][type_traits] API functions for determining the characteristics
of types. Such traits can support type inference, classification, and
transformation, as well as make it easier to write templates based on generic
type behavior.

> WARNING: use of many of the constructs in this header will count as "complex
> template metaprogramming", so before proceeding, please carefully consider the
> Style Guide's [advice on template metaprogramming][style-guide-templates].
>
> Using template metaprogramming to detect or depend on API features is brittle
> and not guaranteed. Neither the standard library nor Abseil provides any
> guarantee that APIs are stable in the face of template metaprogramming. Use
> with caution.

## Type Trait Usage

Type traits in C++ provide compile-time inspection of the properties of types.
This header file contains two sets of abstractions:

*   C++14 compatible versions of `<type_traits>` methods that either aren't
    available in C++14, or which have incomplete compiler support.
*   C++14 compatible definitions of C++17 `<type_traits>` aliases

## Type Traits Class Templates

*   `absl::void_t` provides a version of the C++17 `std::void_t` utility
    metafunction.
*   `absl::conjunction`, `absl::disjunction` and `absl::negation` provide
    versions of the C++17 abstractions for performing compile-time logical
    operations.
*   `absl::is_trivially_destructible`,
    `absl::is_trivially_default_constructible`, `absl::is_trivially_assignable`,
    and `absl::is_trivially_copy_assignable` provide versions of these type
    traits metafunctions that include fixes for platforms that did not
    fully-implement them.

[type_traits]: https://en.cppreference.com/w/cpp/header/type_traits
[style-guide-templates]: https://google.github.io/styleguide/cppguide.html#Template_metaprogramming