Skip to content

Commit

Permalink
Add != to YAMLParser's basic_collection_iterator.
Browse files Browse the repository at this point in the history
...and mark it as merely an input_iterator rather than a forward_iterator,
since it is destructive. And then rewrite == to take advantage of that.

Patch by Alex Denisov!

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@256913 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
jrose-apple committed Jan 6, 2016
1 parent 4cb9f9d commit 71a6baa
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 5 deletions.
23 changes: 18 additions & 5 deletions include/llvm/Support/YAMLParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ class KeyValueNode final : public Node {
/// increment() which must set CurrentEntry to 0 to create an end iterator.
template <class BaseT, class ValueT>
class basic_collection_iterator
: public std::iterator<std::forward_iterator_tag, ValueT> {
: public std::iterator<std::input_iterator_tag, ValueT> {
public:
basic_collection_iterator() : Base(nullptr) {}
basic_collection_iterator(BaseT *B) : Base(B) {}
Expand All @@ -326,11 +326,24 @@ class basic_collection_iterator
return Base->CurrentEntry;
}

/// Note on EqualityComparable:
///
/// The iterator is not re-entrant,
/// it is meant to be used for parsing YAML on-demand
/// Once iteration started - it can point only to one entry at a time
/// hence Base.CurrentEntry and Other.Base.CurrentEntry are equal
/// iff Base and Other.Base are equal.
bool operator==(const basic_collection_iterator &Other) const {
if (Base && (Base == Other.Base)) {
assert((Base->CurrentEntry == Other.Base->CurrentEntry)
&& "Equal Bases expected to point to equal Entries");
}

return Base == Other.Base;
}

bool operator!=(const basic_collection_iterator &Other) const {
if (Base != Other.Base)
return true;
return (Base && Other.Base) &&
Base->CurrentEntry != Other.Base->CurrentEntry;
return !(Base == Other.Base);
}

basic_collection_iterator &operator++() {
Expand Down
72 changes: 72 additions & 0 deletions unittests/Support/YAMLParserTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -260,4 +260,76 @@ TEST(YAMLParser, DiagnosticFilenameFromBufferID) {
EXPECT_EQ("buffername.yaml", GeneratedDiag.getFilename());
}

TEST(YAMLParser, SameNodeIteratorOperatorNotEquals) {
SourceMgr SM;
yaml::Stream Stream("[\"1\", \"2\"]", SM);

yaml::SequenceNode *Node = dyn_cast<yaml::SequenceNode>(
Stream.begin()->getRoot());

auto Begin = Node->begin();
auto End = Node->end();

EXPECT_TRUE(Begin != End);
EXPECT_FALSE(Begin != Begin);
EXPECT_FALSE(End != End);
}

TEST(YAMLParser, SameNodeIteratorOperatorEquals) {
SourceMgr SM;
yaml::Stream Stream("[\"1\", \"2\"]", SM);

yaml::SequenceNode *Node = dyn_cast<yaml::SequenceNode>(
Stream.begin()->getRoot());

auto Begin = Node->begin();
auto End = Node->end();

EXPECT_FALSE(Begin == End);
EXPECT_TRUE(Begin == Begin);
EXPECT_TRUE(End == End);
}

TEST(YAMLParser, DifferentNodesIteratorOperatorNotEquals) {
SourceMgr SM;
yaml::Stream Stream("[\"1\", \"2\"]", SM);
yaml::Stream AnotherStream("[\"1\", \"2\"]", SM);

yaml::SequenceNode *Node = dyn_cast<yaml::SequenceNode>(
Stream.begin()->getRoot());
yaml::SequenceNode *AnotherNode = dyn_cast<yaml::SequenceNode>(
AnotherStream.begin()->getRoot());

auto Begin = Node->begin();
auto End = Node->end();

auto AnotherBegin = AnotherNode->begin();
auto AnotherEnd = AnotherNode->end();

EXPECT_TRUE(Begin != AnotherBegin);
EXPECT_TRUE(Begin != AnotherEnd);
EXPECT_FALSE(End != AnotherEnd);
}

TEST(YAMLParser, DifferentNodesIteratorOperatorEquals) {
SourceMgr SM;
yaml::Stream Stream("[\"1\", \"2\"]", SM);
yaml::Stream AnotherStream("[\"1\", \"2\"]", SM);

yaml::SequenceNode *Node = dyn_cast<yaml::SequenceNode>(
Stream.begin()->getRoot());
yaml::SequenceNode *AnotherNode = dyn_cast<yaml::SequenceNode>(
AnotherStream.begin()->getRoot());

auto Begin = Node->begin();
auto End = Node->end();

auto AnotherBegin = AnotherNode->begin();
auto AnotherEnd = AnotherNode->end();

EXPECT_FALSE(Begin == AnotherBegin);
EXPECT_FALSE(Begin == AnotherEnd);
EXPECT_TRUE(End == AnotherEnd);
}

} // end namespace llvm

0 comments on commit 71a6baa

Please sign in to comment.