chromium/third_party/blink/public/common/tokens/multi_token.h

// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Helper class for a strongly-typed multiple variant token. Allows creating
// a token that can represent one of a collection of distinct token types.
// It would be great to replace this with a much simpler C++17 std::variant
// when that is available.

#ifndef THIRD_PARTY_BLINK_PUBLIC_COMMON_TOKENS_MULTI_TOKEN_H_
#define THIRD_PARTY_BLINK_PUBLIC_COMMON_TOKENS_MULTI_TOKEN_H_

#include <stdint.h>

#include <compare>
#include <limits>
#include <type_traits>

#include "base/types/variant_util.h"
#include "base/unguessable_token.h"
#include "third_party/abseil-cpp/absl/types/variant.h"
#include "third_party/blink/public/common/tokens/multi_token_internal.h"

namespace blink {

// `MultiToken<Tokens...>` is a variant of 2 or more token types. Each token
// type must be an instantiation of `base::TokenType`, and each token type must
// be unique within `Tokens...`. Unlike `base::UnguessableToken`, a `MultiToken`
// is always valid: there is no null state. Default constructing a `MultiToken`
// will create a `MultiToken` containing an instance of the first token type in
// `Tokens`.
//
// Usage:
//
// using CowToken = base::TokenType<class CowTokenTag>;
// using GoatToken = base::TokenType<class GoatTokenTag>;
// using UngulateToken = blink::MultiToken<CowToken, GoatToken>;
//
// void TeleportCow(const CowToken&);
// void TeleportGoat(const GoatToken&);
//
// void TeleportUngulate(const UngulateToken& token) {
//   token.Visit(base::Overloaded(
//         [](const CowToken& cow_token) { TeleportCow(cow_token); },
//         [](const GoatToken& goat_token) { TeleportGoat(goat_token); }));
// }
template <typename... Tokens>
  requires(sizeof...(Tokens) > 1 &&
           sizeof...(Tokens) <= std::numeric_limits<uint32_t>::max() &&
           (internal::IsBaseToken<Tokens> && ...) &&
           internal::AreAllUnique<Tokens...>)
class MultiToken {};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_PUBLIC_COMMON_TOKENS_MULTI_TOKEN_H_