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