• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef BASE_TYPES_TOKEN_TYPE_H_
6 #define BASE_TYPES_TOKEN_TYPE_H_
7 
8 #include <compare>
9 #include <type_traits>
10 
11 #include "base/check.h"
12 #include "base/types/strong_alias.h"
13 #include "base/unguessable_token.h"
14 
15 namespace base {
16 
17 // A specialization of StrongAlias for UnguessableToken. Unlike
18 // UnguessableToken, a TokenType<...> does not default to null and does not
19 // expose the concept of null tokens. If you need to indicate a null token,
20 // please use absl::optional<TokenType<...>>.
21 template <typename TypeMarker>
22 class TokenType : public StrongAlias<TypeMarker, UnguessableToken> {
23  private:
24   using Super = StrongAlias<TypeMarker, UnguessableToken>;
25 
26  public:
TokenType()27   TokenType() : Super(UnguessableToken::Create()) {}
TokenType(const UnguessableToken & token)28   explicit TokenType(const UnguessableToken& token) : Super(token) {
29     // Disallow attempts to force a null UnguessableToken into a strongly-typed
30     // token. Allowing in-place nullability of UnguessableToken was a design
31     // mistake; do not propagate that mistake here as well.
32     CHECK(!token.is_empty());
33   }
34 
35   // This object allows default assignment operators for compatibility with
36   // STL containers.
37   TokenType(const TokenType& token) = default;
38   TokenType(TokenType&& token) noexcept = default;
39   TokenType& operator=(const TokenType& token) = default;
40   TokenType& operator=(TokenType&& token) noexcept = default;
41 
42   // StrongAlias doesn't define <=> because not all underlying types will
43   // implement it. TokenType can define it using UnguessableToken's
44   // implementation, though.
45   friend constexpr auto operator<=>(const TokenType& lhs,
46                                     const TokenType& rhs) {
47     return lhs.value() <=> rhs.value();
48   }
49   friend constexpr bool operator==(const TokenType& lhs, const TokenType& rhs) {
50     return lhs.value() == rhs.value();
51   }
52 
53   // Hash functor for use in unordered containers.
54   struct Hasher {
55     using argument_type = TokenType;
56     using result_type = size_t;
operatorHasher57     result_type operator()(const argument_type& token) const {
58       return UnguessableTokenHash()(token.value());
59     }
60   };
61 
62   // Mimic the UnguessableToken API for ease and familiarity of use.
ToString()63   std::string ToString() const { return this->value().ToString(); }
64 };
65 
66 }  // namespace base
67 
68 #endif  // BASE_TYPES_TOKEN_TYPE_H_
69