Bug 1679987 - Make nsTokenizerFlags a scoped enum and make them a template argument to nsTCharSeparatedTokenizer. r=xpcom-reviewers,necko-reviewers,nika

There are no uses of nsTCharSeparatedTokenizer that require run-time
configuration of the flags, so having them a compile-time template
argument allows for generation of more efficient code.

This might not matter that much now, but a subsequent patch will add another
flag to allow merging the implementation of nsTSubstring::Split with
nsTCharSeparatedTokenizer, through which the compile-time evaluation will
become more relevant.

Differential Revision: https://phabricator.services.mozilla.com/D99368
This commit is contained in:
Simon Giesecke 2020-12-16 19:10:21 +00:00
Родитель ae63265100
Коммит 4a023dd2aa
12 изменённых файлов: 64 добавлений и 47 удалений

Просмотреть файл

@ -435,9 +435,9 @@ bool SMILParserUtils::ParseKeySplines(
nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace>
controlPointTokenizer(aSpec, ';');
while (controlPointTokenizer.hasMoreTokens()) {
nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace>
tokenizer(controlPointTokenizer.nextToken(), ',',
nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace,
nsTokenizerFlags::SeparatorOptional>
tokenizer(controlPointTokenizer.nextToken(), ',');
double values[4];
for (auto& value : values) {

Просмотреть файл

@ -69,8 +69,9 @@ static SVGAttrTearoffTable<SVGAnimatedIntegerPair,
static nsresult ParseIntegerOptionalInteger(const nsAString& aValue,
int32_t aValues[2]) {
nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace> tokenizer(
aValue, ',', nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace,
nsTokenizerFlags::SeparatorOptional>
tokenizer(aValue, ',');
uint32_t i;
for (i = 0; i < 2 && tokenizer.hasMoreTokens(); ++i) {
if (!SVGContentUtils::ParseInteger(tokenizer.nextToken(), aValues[i])) {

Просмотреть файл

@ -63,8 +63,9 @@ static SVGAttrTearoffTable<SVGAnimatedNumberPair,
static nsresult ParseNumberOptionalNumber(const nsAString& aValue,
float aValues[2]) {
nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace> tokenizer(
aValue, ',', nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace,
nsTokenizerFlags::SeparatorOptional>
tokenizer(aValue, ',');
uint32_t i;
for (i = 0; i < 2 && tokenizer.hasMoreTokens(); ++i) {
if (!SVGContentUtils::ParseNumber(tokenizer.nextToken(), aValues[i])) {

Просмотреть файл

@ -245,8 +245,9 @@ void SVGAnimatedTransformList::SMILAnimatedTransformList::ParseValue(
int32_t SVGAnimatedTransformList::SMILAnimatedTransformList::ParseParameterList(
const nsAString& aSpec, float* aVars, int32_t aNVars) {
nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace> tokenizer(
aSpec, ',', nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace,
nsTokenizerFlags::SeparatorOptional>
tokenizer(aSpec, ',');
int numArgsFound = 0;

Просмотреть файл

@ -40,8 +40,9 @@ nsresult SVGViewBox::FromString(const nsAString& aStr, SVGViewBox* aViewBox) {
return NS_OK;
}
nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace> tokenizer(
aStr, ',', nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace,
nsTokenizerFlags::SeparatorOptional>
tokenizer(aStr, ',');
float vals[NUM_VIEWBOX_COMPONENTS];
uint32_t i;
for (i = 0; i < NUM_VIEWBOX_COMPONENTS && tokenizer.hasMoreTokens(); ++i) {

Просмотреть файл

@ -40,8 +40,9 @@ void SVGLengthList::GetValueAsString(nsAString& aValue) const {
nsresult SVGLengthList::SetValueFromString(const nsAString& aValue) {
SVGLengthList temp;
nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace> tokenizer(
aValue, ',', nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace,
nsTokenizerFlags::SeparatorOptional>
tokenizer(aValue, ',');
while (tokenizer.hasMoreTokens()) {
SVGLength length;

Просмотреть файл

@ -81,8 +81,9 @@ SVGMotionSMILPathUtils::PathGenerator::GetResultingPath() {
bool SVGMotionSMILPathUtils::PathGenerator::ParseCoordinatePair(
const nsAString& aCoordPairStr, float& aXVal, float& aYVal) {
nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace> tokenizer(
aCoordPairStr, ',', nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace,
nsTokenizerFlags::SeparatorOptional>
tokenizer(aCoordPairStr, ',');
SVGLength x, y;

Просмотреть файл

@ -42,8 +42,9 @@ void SVGNumberList::GetValueAsString(nsAString& aValue) const {
nsresult SVGNumberList::SetValueFromString(const nsAString& aValue) {
SVGNumberList temp;
nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace> tokenizer(
aValue, ',', nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace,
nsTokenizerFlags::SeparatorOptional>
tokenizer(aValue, ',');
while (tokenizer.hasMoreTokens()) {
float num;

Просмотреть файл

@ -48,8 +48,9 @@ nsresult SVGPointList::SetValueFromString(const nsAString& aValue) {
SVGPointList temp;
nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace> tokenizer(
aValue, ',', nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
nsCharSeparatedTokenizerTemplate<nsContentUtils::IsHTMLWhitespace,
nsTokenizerFlags::SeparatorOptional>
tokenizer(aValue, ',');
while (tokenizer.hasMoreTokens()) {
const nsAString& token = tokenizer.nextToken();

Просмотреть файл

@ -360,8 +360,9 @@ nsresult TRRService::ReadPrefs(const char* name) {
return;
}
nsCCharSeparatedTokenizer tokenizer(
excludedDomains, ',', nsCCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
nsCCharSeparatedTokenizerTemplate<NS_IsAsciiWhitespace,
nsTokenizerFlags::SeparatorOptional>
tokenizer(excludedDomains, ',');
while (tokenizer.hasMoreTokens()) {
nsAutoCString token(tokenizer.nextToken());
LOG(("TRRService::ReadPrefs %s host:[%s]\n", aPrefName, token.get()));

Просмотреть файл

@ -741,8 +741,9 @@ nsresult nsDNSService::ReadPrefs(const char* name) {
MutexAutoLock lock(mLock);
mLocalDomains.Clear();
if (!localDomains.IsEmpty()) {
nsCCharSeparatedTokenizer tokenizer(
localDomains, ',', nsCCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
nsCCharSeparatedTokenizerTemplate<NS_IsAsciiWhitespace,
nsTokenizerFlags::SeparatorOptional>
tokenizer(localDomains, ',');
while (tokenizer.hasMoreTokens()) {
mLocalDomains.PutEntry(tokenizer.nextToken());
}

Просмотреть файл

@ -9,10 +9,17 @@
#include "mozilla/Maybe.h"
#include "mozilla/RangedPtr.h"
#include "mozilla/TypedEnumBits.h"
#include "nsDependentSubstring.h"
#include "nsCRTGlue.h"
// Flags -- only one for now. If we need more, they should be defined to
// be 1 << 1, 1 << 2, etc. (They're masks, and aFlags is a bitfield.)
enum class nsTokenizerFlags { Default = 0, SeparatorOptional = 1 << 0 };
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(nsTokenizerFlags)
/**
* This parses a SeparatorChar-separated string into tokens.
* Whitespace surrounding tokens is not treated as part of tokens, however
@ -31,28 +38,24 @@
* The function used for whitespace detection is a template argument.
* By default, it is NS_IsAsciiWhitespace.
*/
template <typename TDependentSubstringType, bool IsWhitespace(char16_t)>
template <typename TDependentSubstringType, bool IsWhitespace(char16_t),
nsTokenizerFlags Flags = nsTokenizerFlags::Default>
class nsTCharSeparatedTokenizer {
using CharType = typename TDependentSubstringType::char_type;
using SubstringType = typename TDependentSubstringType::substring_type;
public:
// Flags -- only one for now. If we need more, they should be defined to
// be 1 << 1, 1 << 2, etc. (They're masks, and aFlags is a bitfield.)
enum { SEPARATOR_OPTIONAL = 1 };
using DependentSubstringType = TDependentSubstringType;
nsTCharSeparatedTokenizer(const SubstringType& aSource,
CharType aSeparatorChar, uint32_t aFlags = 0)
CharType aSeparatorChar)
: mIter(aSource.Data(), aSource.Length()),
mEnd(aSource.Data() + aSource.Length(), aSource.Data(),
aSource.Length()),
mSeparatorChar(aSeparatorChar),
mWhitespaceBeforeFirstToken(false),
mWhitespaceAfterCurrentToken(false),
mSeparatorAfterCurrentToken(false),
mSeparatorOptional(aFlags & SEPARATOR_OPTIONAL) {
mSeparatorAfterCurrentToken(false) {
// Skip initial whitespace
while (mIter < mEnd && IsWhitespace(*mIter)) {
mWhitespaceBeforeFirstToken = true;
@ -119,7 +122,7 @@ class nsTCharSeparatedTokenizer {
mWhitespaceAfterCurrentToken = true;
++mIter;
}
if (mSeparatorOptional) {
if constexpr (Flags & nsTokenizerFlags::SeparatorOptional) {
// We've hit (and skipped) whitespace, and that's sufficient to end
// our token, regardless of whether we've reached a SeparatorChar.
break;
@ -127,11 +130,11 @@ class nsTCharSeparatedTokenizer {
}
mSeparatorAfterCurrentToken = (mIter != mEnd && *mIter == mSeparatorChar);
MOZ_ASSERT(
mSeparatorOptional || (mSeparatorAfterCurrentToken == (mIter < mEnd)),
"If we require a separator and haven't hit the end of "
"our string, then we shouldn't have left the loop "
"unless we hit a separator");
MOZ_ASSERT((Flags & nsTokenizerFlags::SeparatorOptional) ||
(mSeparatorAfterCurrentToken == (mIter < mEnd)),
"If we require a separator and haven't hit the end of "
"our string, then we shouldn't have left the loop "
"unless we hit a separator");
// Skip separator (and any whitespace after it), if we're at one.
if (mSeparatorAfterCurrentToken) {
@ -155,25 +158,28 @@ class nsTCharSeparatedTokenizer {
bool mWhitespaceBeforeFirstToken;
bool mWhitespaceAfterCurrentToken;
bool mSeparatorAfterCurrentToken;
bool mSeparatorOptional;
};
constexpr bool NS_TokenizerIgnoreNothing(char16_t) { return false; }
template <bool IsWhitespace(char16_t), typename CharType>
template <bool IsWhitespace(char16_t), typename CharType,
nsTokenizerFlags Flags = nsTokenizerFlags::Default>
using nsTCharSeparatedTokenizerTemplate =
nsTCharSeparatedTokenizer<nsTDependentSubstring<CharType>, IsWhitespace>;
nsTCharSeparatedTokenizer<nsTDependentSubstring<CharType>, IsWhitespace,
Flags>;
template <bool IsWhitespace(char16_t)>
template <bool IsWhitespace(char16_t),
nsTokenizerFlags Flags = nsTokenizerFlags::Default>
using nsCharSeparatedTokenizerTemplate =
nsTCharSeparatedTokenizerTemplate<IsWhitespace, char16_t>;
nsTCharSeparatedTokenizerTemplate<IsWhitespace, char16_t, Flags>;
using nsCharSeparatedTokenizer =
nsCharSeparatedTokenizerTemplate<NS_IsAsciiWhitespace>;
template <bool IsWhitespace(char16_t)>
template <bool IsWhitespace(char16_t),
nsTokenizerFlags Flags = nsTokenizerFlags::Default>
using nsCCharSeparatedTokenizerTemplate =
nsTCharSeparatedTokenizerTemplate<IsWhitespace, char>;
nsTCharSeparatedTokenizerTemplate<IsWhitespace, char, Flags>;
using nsCCharSeparatedTokenizer =
nsCCharSeparatedTokenizerTemplate<NS_IsAsciiWhitespace>;
@ -234,9 +240,10 @@ class nsTokenizedRange {
const Tokenizer mTokenizer;
};
template <typename TDependentSubstringType, bool IsWhitespace(char16_t)>
auto nsTCharSeparatedTokenizer<TDependentSubstringType, IsWhitespace>::ToRange()
const {
template <typename TDependentSubstringType, bool IsWhitespace(char16_t),
nsTokenizerFlags Flags>
auto nsTCharSeparatedTokenizer<TDependentSubstringType, IsWhitespace,
Flags>::ToRange() const {
return nsTokenizedRange{nsTCharSeparatedTokenizer{*this}};
}