summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Support/StringRef.cpp
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2015-09-10 07:51:37 +0000
committerChandler Carruth <chandlerc@gmail.com>2015-09-10 07:51:37 +0000
commit4425c91deac5001cc7f2dd5c0b8a14f8bf87ce27 (patch)
treeccb9689b72fdf5847a7ea3e54ff9f664f9baa56e /llvm/lib/Support/StringRef.cpp
parentcca07d7c48299639b91d8efa43daadf326d44883 (diff)
downloadbcm5719-llvm-4425c91deac5001cc7f2dd5c0b8a14f8bf87ce27.tar.gz
bcm5719-llvm-4425c91deac5001cc7f2dd5c0b8a14f8bf87ce27.zip
[ADT] Fix a confusing interface spec and some annoying peculiarities
with the StringRef::split method when used with a MaxSplit argument other than '-1' (which nobody really does today, but which should actually work). The spec claimed both to split up to MaxSplit times, but also to append <= MaxSplit strings to the vector. One of these doesn't make sense. Given the name "MaxSplit", let's go with it being a max over how many *splits* occur, which means the max on how many strings get appended is MaxSplit+1. I'm not actually sure the implementation correctly provided this logic either, as it used a really opaque loop structure. The implementation was also playing weird games with nullptr in the data field to try to rely on a totally opaque hidden property of the split method that returns a pair. Nasty IMO. Replace all of this with what is (IMO) simpler code that doesn't use the pair returning split method, and instead just finds each separator and appends directly. I think this is a lot easier to read, and it most definitely matches the spec. Added some tests that exercise the corner cases around StringRef() and StringRef("") that all now pass. I'll start using this in code in the next commit. llvm-svn: 247249
Diffstat (limited to 'llvm/lib/Support/StringRef.cpp')
-rw-r--r--llvm/lib/Support/StringRef.cpp74
1 files changed, 43 insertions, 31 deletions
diff --git a/llvm/lib/Support/StringRef.cpp b/llvm/lib/Support/StringRef.cpp
index f2e587cb527..88f920479dd 100644
--- a/llvm/lib/Support/StringRef.cpp
+++ b/llvm/lib/Support/StringRef.cpp
@@ -274,44 +274,56 @@ StringRef::size_type StringRef::find_last_not_of(StringRef Chars,
}
void StringRef::split(SmallVectorImpl<StringRef> &A,
- StringRef Separators, int MaxSplit,
+ StringRef Separator, int MaxSplit,
bool KeepEmpty) const {
- StringRef rest = *this;
-
- // rest.data() is used to distinguish cases like "a," that splits into
- // "a" + "" and "a" that splits into "a" + 0.
- for (int splits = 0;
- rest.data() != nullptr && (MaxSplit < 0 || splits < MaxSplit);
- ++splits) {
- std::pair<StringRef, StringRef> p = rest.split(Separators);
-
- if (KeepEmpty || p.first.size() != 0)
- A.push_back(p.first);
- rest = p.second;
+ StringRef S = *this;
+
+ // Count down from MaxSplit. When MaxSplit is -1, this will just split
+ // "forever". This doesn't support splitting more than 2^31 times
+ // intentionally; if we ever want that we can make MaxSplit a 64-bit integer
+ // but that seems unlikely to be useful.
+ while (MaxSplit-- != 0) {
+ size_t Idx = S.find(Separator);
+ if (Idx == npos)
+ break;
+
+ // Push this split.
+ if (KeepEmpty || Idx > 0)
+ A.push_back(S.slice(0, Idx));
+
+ // Jump forward.
+ S = S.slice(Idx + Separator.size(), npos);
}
- // If we have a tail left, add it.
- if (rest.data() != nullptr && (rest.size() != 0 || KeepEmpty))
- A.push_back(rest);
+
+ // Push the tail.
+ if (KeepEmpty || !S.empty())
+ A.push_back(S);
}
void StringRef::split(SmallVectorImpl<StringRef> &A, char Separator,
int MaxSplit, bool KeepEmpty) const {
- StringRef rest = *this;
-
- // rest.data() is used to distinguish cases like "a," that splits into
- // "a" + "" and "a" that splits into "a" + 0.
- for (int splits = 0;
- rest.data() != nullptr && (MaxSplit < 0 || splits < MaxSplit);
- ++splits) {
- std::pair<StringRef, StringRef> p = rest.split(Separator);
-
- if (KeepEmpty || p.first.size() != 0)
- A.push_back(p.first);
- rest = p.second;
+ StringRef S = *this;
+
+ // Count down from MaxSplit. When MaxSplit is -1, this will just split
+ // "forever". This doesn't support splitting more than 2^31 times
+ // intentionally; if we ever want that we can make MaxSplit a 64-bit integer
+ // but that seems unlikely to be useful.
+ while (MaxSplit-- != 0) {
+ size_t Idx = S.find(Separator);
+ if (Idx == npos)
+ break;
+
+ // Push this split.
+ if (KeepEmpty || Idx > 0)
+ A.push_back(S.slice(0, Idx));
+
+ // Jump forward.
+ S = S.slice(Idx + 1, npos);
}
- // If we have a tail left, add it.
- if (rest.data() != nullptr && (rest.size() != 0 || KeepEmpty))
- A.push_back(rest);
+
+ // Push the tail.
+ if (KeepEmpty || !S.empty())
+ A.push_back(S);
}
//===----------------------------------------------------------------------===//
OpenPOWER on IntegriCloud