Don't assume that iterators can be compared.
std::string_view in MSVC has iterators that aren't just pointers and
that don't allow comparisons between different objects - not even if
those objects are views into the same string!
Change-Id: I0b61ca4a42bcbb9eda85df47c5f233dbf488e107
Reviewed-on: https://code-review.googlesource.com/c/re2/+/59330
Reviewed-by: Julien Goodwin <julieng@google.com>
Reviewed-by: Paul Wankadia <junyer@google.com>
diff --git a/re2/bitstate.cc b/re2/bitstate.cc
index 320d1ee..877e548 100644
--- a/re2/bitstate.cc
+++ b/re2/bitstate.cc
@@ -293,9 +293,9 @@
context_ = context;
if (context_.data() == NULL)
context_ = text;
- if (prog_->anchor_start() && context_.begin() != text.begin())
+ if (prog_->anchor_start() && BeginPtr(context_) != BeginPtr(text))
return false;
- if (prog_->anchor_end() && context_.end() != text.end())
+ if (prog_->anchor_end() && EndPtr(context_) != EndPtr(text))
return false;
anchored_ = anchored || prog_->anchor_start();
longest_ = longest || prog_->anchor_end();
@@ -377,7 +377,7 @@
bool longest = kind != kFirstMatch;
if (!b.Search(text, context, anchored, longest, match, nmatch))
return false;
- if (kind == kFullMatch && match[0].end() != text.end())
+ if (kind == kFullMatch && EndPtr(match[0]) != EndPtr(text))
return false;
return true;
}
diff --git a/re2/dfa.cc b/re2/dfa.cc
index 583303e..d47c7d5 100644
--- a/re2/dfa.cc
+++ b/re2/dfa.cc
@@ -1488,15 +1488,15 @@
int lastbyte;
if (run_forward) {
- if (params->text.end() == params->context.end())
+ if (EndPtr(params->text) == EndPtr(params->context))
lastbyte = kByteEndText;
else
- lastbyte = params->text.end()[0] & 0xFF;
+ lastbyte = EndPtr(params->text)[0] & 0xFF;
} else {
- if (params->text.begin() == params->context.begin())
+ if (BeginPtr(params->text) == BeginPtr(params->context))
lastbyte = kByteEndText;
else
- lastbyte = params->text.begin()[-1] & 0xFF;
+ lastbyte = BeginPtr(params->text)[-1] & 0xFF;
}
State* ns = s->next_[ByteMap(lastbyte)].load(std::memory_order_acquire);
@@ -1627,7 +1627,7 @@
const StringPiece& context = params->context;
// Sanity check: make sure that text lies within context.
- if (text.begin() < context.begin() || text.end() > context.end()) {
+ if (BeginPtr(text) < BeginPtr(context) || EndPtr(text) > EndPtr(context)) {
LOG(DFATAL) << "context does not contain text";
params->start = DeadState;
return true;
@@ -1637,13 +1637,13 @@
int start;
uint32_t flags;
if (params->run_forward) {
- if (text.begin() == context.begin()) {
+ if (BeginPtr(text) == BeginPtr(context)) {
start = kStartBeginText;
flags = kEmptyBeginText|kEmptyBeginLine;
- } else if (text.begin()[-1] == '\n') {
+ } else if (BeginPtr(text)[-1] == '\n') {
start = kStartBeginLine;
flags = kEmptyBeginLine;
- } else if (Prog::IsWordChar(text.begin()[-1] & 0xFF)) {
+ } else if (Prog::IsWordChar(BeginPtr(text)[-1] & 0xFF)) {
start = kStartAfterWordChar;
flags = kFlagLastWord;
} else {
@@ -1651,13 +1651,13 @@
flags = 0;
}
} else {
- if (text.end() == context.end()) {
+ if (EndPtr(text) == EndPtr(context)) {
start = kStartBeginText;
flags = kEmptyBeginText|kEmptyBeginLine;
- } else if (text.end()[0] == '\n') {
+ } else if (EndPtr(text)[0] == '\n') {
start = kStartBeginLine;
flags = kEmptyBeginLine;
- } else if (Prog::IsWordChar(text.end()[0] & 0xFF)) {
+ } else if (Prog::IsWordChar(EndPtr(text)[0] & 0xFF)) {
start = kStartAfterWordChar;
flags = kFlagLastWord;
} else {
@@ -1837,9 +1837,9 @@
using std::swap;
swap(caret, dollar);
}
- if (caret && context.begin() != text.begin())
+ if (caret && BeginPtr(context) != BeginPtr(text))
return false;
- if (dollar && context.end() != text.end())
+ if (dollar && EndPtr(context) != EndPtr(text))
return false;
// Handle full match by running an anchored longest match
diff --git a/re2/nfa.cc b/re2/nfa.cc
index e858451..c7339f8 100644
--- a/re2/nfa.cc
+++ b/re2/nfa.cc
@@ -456,14 +456,14 @@
context = text;
// Sanity check: make sure that text lies within context.
- if (text.begin() < context.begin() || text.end() > context.end()) {
+ if (BeginPtr(text) < BeginPtr(context) || EndPtr(text) > EndPtr(context)) {
LOG(DFATAL) << "context does not contain text";
return false;
}
- if (prog_->anchor_start() && context.begin() != text.begin())
+ if (prog_->anchor_start() && BeginPtr(context) != BeginPtr(text))
return false;
- if (prog_->anchor_end() && context.end() != text.end())
+ if (prog_->anchor_end() && EndPtr(context) != EndPtr(text))
return false;
anchored |= prog_->anchor_start();
if (prog_->anchor_end()) {
@@ -646,7 +646,7 @@
}
if (!nfa.Search(text, context, anchor == kAnchored, kind != kFirstMatch, match, nmatch))
return false;
- if (kind == kFullMatch && match[0].end() != text.end())
+ if (kind == kFullMatch && EndPtr(match[0]) != EndPtr(text))
return false;
return true;
}
diff --git a/re2/onepass.cc b/re2/onepass.cc
index 66a62d9..2639746 100644
--- a/re2/onepass.cc
+++ b/re2/onepass.cc
@@ -237,9 +237,9 @@
StringPiece context = const_context;
if (context.data() == NULL)
context = text;
- if (anchor_start() && context.begin() != text.begin())
+ if (anchor_start() && BeginPtr(context) != BeginPtr(text))
return false;
- if (anchor_end() && context.end() != text.end())
+ if (anchor_end() && EndPtr(context) != EndPtr(text))
return false;
if (anchor_end())
kind = kFullMatch;
diff --git a/re2/prog.h b/re2/prog.h
index 8ca9880..e701e8c 100644
--- a/re2/prog.h
+++ b/re2/prog.h
@@ -450,6 +450,17 @@
Prog& operator=(const Prog&) = delete;
};
+// std::string_view in MSVC has iterators that aren't just pointers and
+// that don't allow comparisons between different objects - not even if
+// those objects are views into the same string! Thus, we provide these
+// conversion functions for convenience.
+static inline const char* BeginPtr(const StringPiece& s) {
+ return s.data();
+}
+static inline const char* EndPtr(const StringPiece& s) {
+ return s.data() + s.size();
+}
+
} // namespace re2
#endif // RE2_PROG_H_
diff --git a/re2/re2.cc b/re2/re2.cc
index 128c8bd..150c5ad 100644
--- a/re2/re2.cc
+++ b/re2/re2.cc
@@ -920,7 +920,7 @@
}
if (consumed != NULL)
- *consumed = static_cast<size_t>(vec[0].end() - text.begin());
+ *consumed = static_cast<size_t>(EndPtr(vec[0]) - BeginPtr(text));
if (n == 0 || args == NULL) {
// We are not interested in results
diff --git a/re2/testing/backtrack.cc b/re2/testing/backtrack.cc
index 216d259..920a453 100644
--- a/re2/testing/backtrack.cc
+++ b/re2/testing/backtrack.cc
@@ -103,9 +103,9 @@
context_ = context;
if (context_.data() == NULL)
context_ = text;
- if (prog_->anchor_start() && text.begin() > context_.begin())
+ if (prog_->anchor_start() && BeginPtr(text) > BeginPtr(context_))
return false;
- if (prog_->anchor_end() && text.end() < context_.end())
+ if (prog_->anchor_end() && EndPtr(text) < EndPtr(context_))
return false;
anchored_ = anchored | prog_->anchor_start();
longest_ = longest | prog_->anchor_end();
@@ -267,7 +267,7 @@
bool longest = kind != kFirstMatch;
if (!b.Search(text, context, anchored, longest, match, nmatch))
return false;
- if (kind == kFullMatch && match[0].end() != text.end())
+ if (kind == kFullMatch && EndPtr(match[0]) != EndPtr(text))
return false;
return true;
}
diff --git a/re2/testing/exhaustive_tester.cc b/re2/testing/exhaustive_tester.cc
index bdac381..b0409c3 100644
--- a/re2/testing/exhaustive_tester.cc
+++ b/re2/testing/exhaustive_tester.cc
@@ -67,8 +67,8 @@
printf("-");
else
printf("%td-%td",
- m[i].begin() - input.begin(),
- m[i].end() - input.begin());
+ BeginPtr(m[i]) - BeginPtr(input),
+ EndPtr(m[i]) - BeginPtr(input));
}
}
diff --git a/re2/testing/tester.cc b/re2/testing/tester.cc
index d2ec4fb..b0c22f2 100644
--- a/re2/testing/tester.cc
+++ b/re2/testing/tester.cc
@@ -117,8 +117,8 @@
if (s.data() == NULL)
return "(?,?)";
return StringPrintf("(%td,%td)",
- s.begin() - text.begin(),
- s.end() - text.begin());
+ BeginPtr(s) - BeginPtr(text),
+ EndPtr(s) - BeginPtr(text));
}
// Returns whether text contains non-ASCII (>= 0x80) bytes.
@@ -403,7 +403,7 @@
case kEngineRE2:
case kEngineRE2a:
case kEngineRE2b: {
- if (!re2_ || text.end() != context.end()) {
+ if (!re2_ || EndPtr(text) != EndPtr(context)) {
result->skipped = true;
break;
}
@@ -418,8 +418,8 @@
result->matched = re2_->Match(
context,
- static_cast<size_t>(text.begin() - context.begin()),
- static_cast<size_t>(text.end() - context.begin()),
+ static_cast<size_t>(BeginPtr(text) - BeginPtr(context)),
+ static_cast<size_t>(EndPtr(text) - BeginPtr(context)),
re_anchor,
result->submatch,
nsubmatch);
@@ -428,8 +428,8 @@
}
case kEnginePCRE: {
- if (!re_ || text.begin() != context.begin() ||
- text.end() != context.end()) {
+ if (!re_ || BeginPtr(text) != BeginPtr(context) ||
+ EndPtr(text) != EndPtr(context)) {
result->skipped = true;
break;
}
@@ -606,9 +606,9 @@
<< " text "
<< CEscape(text)
<< " ("
- << text.begin() - context.begin()
+ << BeginPtr(text) - BeginPtr(context)
<< ","
- << text.end() - context.begin()
+ << EndPtr(text) - BeginPtr(context)
<< ") of context "
<< CEscape(context)
<< " (" << FormatKind(kind_)