// 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_