Skip to content

Commit

Permalink
Provide lexicographical comparator for SyntaxTreePath.
Browse files Browse the repository at this point in the history
This will be used to construct column schemas in aligned formatting.

PiperOrigin-RevId: 309828987
  • Loading branch information
fangism authored and hzeller committed May 4, 2020
1 parent a152898 commit 90dcd58
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 0 deletions.
1 change: 1 addition & 0 deletions common/text/tree_path_visitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ namespace verible {
// needs to be tracked in a stack-like manner during visitation
// because SyntaxTreeNode and Leaf do not maintain upward pointers
// to their parent nodes.
// e.g. use the LexicographicalLess comparator in common/util/algorithm.h.
// TODO(fangism): consider replacing with hybrid "small" vector to
// minimize heap allocations, because these are expected to be small.
using SyntaxTreePath = std::vector<size_t>;
Expand Down
14 changes: 14 additions & 0 deletions common/util/algorithm.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,20 @@ void find_all(InputIter iter, InputIter end, OutputIter output,
}
}

// Adapts std::lexicographical_compare to work on two sequences (including
// containers, ranges, spans, views).
struct LexicographicalLess {
// Enable heterogenous lookup.
using is_transparent = void;

// Compare two sequences lexicographically, element-by-element.
template <class T1, class T2>
bool operator()(const T1& left, const T2& right) const {
return std::lexicographical_compare(left.begin(), left.end(), right.begin(),
right.end());
}
};

} // namespace verible

#endif // VERIBLE_COMMON_UTIL_ALGORITHM_H_
51 changes: 51 additions & 0 deletions common/util/algorithm_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "common/util/algorithm.h"

#include <iterator> // for std::back_inserter
#include <list>
#include <string>
#include <vector>

Expand Down Expand Up @@ -342,5 +343,55 @@ TEST(FindAllTest, StrSplitEveryN) {
EXPECT_THAT(bounds, ElementsAre(b + 4, b + 8, b + 12));
}

TEST(LexicographicalLessTest, Containers) {
LexicographicalLess comp;
using List = std::list<int>;
using Vector = std::vector<int>;
EXPECT_FALSE(comp(List{}, List{}));
EXPECT_FALSE(comp(Vector{}, Vector{}));
EXPECT_FALSE(comp(Vector{}, List{}));
EXPECT_FALSE(comp(List{}, Vector{}));
EXPECT_TRUE(comp(Vector{}, List{1}));
EXPECT_FALSE(comp(Vector{0}, List{}));
EXPECT_FALSE(comp(Vector{0}, List{0}));
EXPECT_FALSE(comp(Vector{4}, List{4}));
EXPECT_TRUE(comp(List{1}, Vector{2}));
EXPECT_TRUE(comp(List{1}, Vector{1, -1}));
EXPECT_TRUE(comp(List{1}, List{1, -1}));
EXPECT_FALSE(comp(List{1, 0}, List{1, -1}));
EXPECT_TRUE(comp(List{1, -2}, List{1, -1}));
}

// like substr()
template <class T>
iterator_range<typename T::const_iterator> make_subrange(const T& t, size_t b,
size_t e) {
return make_range(t.begin() + b, t.begin() + e);
}

TEST(LexicographicalLessTest, Ranges) {
LexicographicalLess comp;
const std::vector<int> v{1, 0, 2, 1, 3};
EXPECT_FALSE(comp(make_subrange(v, 0, 0), make_subrange(v, 0, 0)));
EXPECT_FALSE(comp(make_subrange(v, 1, 1), make_subrange(v, 1, 1)));
EXPECT_FALSE(comp(v, v));
EXPECT_FALSE(comp(v, make_subrange(v, 0, 1)));
EXPECT_TRUE(comp(make_subrange(v, 0, 1), v));
EXPECT_FALSE(comp(v, make_subrange(v, 0, 5))); // whole vector
EXPECT_FALSE(comp(make_subrange(v, 0, 5), v)); // whole vector
EXPECT_FALSE(comp(v, make_subrange(v, 1, 2)));
EXPECT_TRUE(comp(v, make_subrange(v, 2, 3)));
EXPECT_FALSE(comp(v, make_subrange(v, 3, 4)));
EXPECT_TRUE(comp(v, make_subrange(v, 3, 5)));
EXPECT_FALSE(comp(make_subrange(v, 0, 1), make_subrange(v, 0, 1)));
EXPECT_FALSE(comp(make_subrange(v, 0, 5), make_subrange(v, 0, 5))); // whole
EXPECT_TRUE(comp(make_subrange(v, 1, 5), make_subrange(v, 0, 5)));
EXPECT_FALSE(comp(make_subrange(v, 0, 5), make_subrange(v, 1, 5)));
EXPECT_TRUE(comp(make_subrange(v, 0, 5), make_subrange(v, 2, 5)));
EXPECT_FALSE(comp(make_subrange(v, 2, 5), make_subrange(v, 0, 5)));
EXPECT_FALSE(comp(make_subrange(v, 0, 1), make_subrange(v, 3, 4)));
EXPECT_FALSE(comp(make_subrange(v, 3, 4), make_subrange(v, 0, 1)));
}

} // namespace
} // namespace verible

0 comments on commit 90dcd58

Please sign in to comment.