Commit e49eafee authored by Chris Hamilton's avatar Chris Hamilton Committed by Commit Bot

Create util::TokenType<...>.

This is similar to util::IdType<...>, except it adapts StrongAlias
wrappers of base::UnguessableTokens, for code that wants to use a
token as an identifier.

This will be used in upcoming work to migrate much of current
base::UnguessableToken usage to be strongly-typed.

BUG=1096617

Change-Id: Icba4d6ace622dc7cc55cf731fc85d15aa12443b5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2302727Reviewed-by: default avatarŁukasz Anforowicz <lukasza@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Commit-Queue: Chris Hamilton <chrisha@chromium.org>
Cr-Commit-Position: refs/heads/master@{#789654}
parent e828fec0
......@@ -13,7 +13,10 @@ source_set("type_safety") {
"id_type.h",
"pass_key.h",
"strong_alias.h",
"token_type.h",
]
deps = [ "//base" ]
}
source_set("tests") {
......@@ -22,6 +25,7 @@ source_set("tests") {
"id_type_unittest.cc",
"pass_key_unittest.cc",
"strong_alias_unittest.cc",
"token_type_unittest.cc",
]
deps = [
......
include_rules = [
"-base",
"+base/unguessable_token.h",
"+base/util/type_safety",
"-third_party",
]
......@@ -63,6 +63,8 @@ namespace util {
// using StrongAlias<Tag, bool> instead of a bare bool.
// - util::IdType<...> which provides helpers for specializing
// StrongAlias to be used as an id.
// - util::TokenType<...> which provides helpers for specializing StrongAlias
// to be used as a wrapper of base::UnguessableToken.
template <typename TagType, typename UnderlyingType>
class StrongAlias {
public:
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef BASE_UTIL_TYPE_SAFETY_TOKEN_TYPE_H_
#define BASE_UTIL_TYPE_SAFETY_TOKEN_TYPE_H_
#include "base/unguessable_token.h"
#include "base/util/type_safety/strong_alias.h"
namespace util {
// A specialization of StrongAlias for base::UnguessableToken.
template <typename TypeMarker>
class TokenType : public StrongAlias<TypeMarker, base::UnguessableToken> {
public:
// Inherit constructors.
using StrongAlias<TypeMarker, base::UnguessableToken>::StrongAlias;
// This object allows default assignment operators for compatibility with
// STL containers.
// Hash functor for use in unordered containers.
struct Hasher {
using argument_type = TokenType;
using result_type = size_t;
result_type operator()(const argument_type& token) const {
return base::UnguessableTokenHash()(token.value());
}
};
// Mimic the base::UnguessableToken API for ease and familiarity of use.
static TokenType Create() {
return TokenType(base::UnguessableToken::Create());
}
static const TokenType& Null() {
static const TokenType kNull;
return kNull;
}
bool is_empty() const { return this->value().is_empty(); }
std::string ToString() const { return this->value().ToString(); }
explicit constexpr operator bool() const { return !is_empty(); }
};
} // namespace util
#endif // BASE_UTIL_TYPE_SAFETY_TOKEN_TYPE_H_
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/util/type_safety/token_type.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace util {
using FooToken = TokenType<class Foo>;
TEST(TokenType, TokenApi) {
// Test static builders.
EXPECT_TRUE(FooToken::Null().is_empty());
EXPECT_FALSE(FooToken::Create().is_empty());
// Test default initialization.
FooToken token1;
EXPECT_TRUE(token1.is_empty());
// Test copy construction.
FooToken token2(FooToken::Create());
EXPECT_FALSE(token2.is_empty());
// Test assignment.
FooToken token3;
EXPECT_TRUE(token3.is_empty());
token3 = token2;
EXPECT_FALSE(token3.is_empty());
// Test bool conversion.
EXPECT_FALSE(token1);
EXPECT_TRUE(token2);
EXPECT_TRUE(token3);
// Test comparison operators.
EXPECT_TRUE(token1 == FooToken::Null());
EXPECT_FALSE(token1 == token2);
EXPECT_TRUE(token2 == token3);
EXPECT_FALSE(token1 != FooToken::Null());
EXPECT_TRUE(token1 != token2);
EXPECT_FALSE(token2 != token3);
EXPECT_TRUE(token1 < token2);
EXPECT_FALSE(token2 < token3);
// Test hasher.
EXPECT_EQ(FooToken::Hasher()(token2),
base::UnguessableTokenHash()(token2.value()));
// Test string representation.
EXPECT_EQ(token2.ToString(), token2.value().ToString());
}
} // namespace util
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment