<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">This seems to have broken some bots:<div class=""><br class=""></div><div class=""><a href="http://green.lab.llvm.org/green/job/clang-stage1-cmake-RA-incremental_build/36596/consoleFull#67046690349ba4694-19c4-4d7e-bec5-911270d8a58c" class="">http://green.lab.llvm.org/green/job/clang-stage1-cmake-RA-incremental_build/36596/consoleFull#67046690349ba4694-19c4-4d7e-bec5-911270d8a58c</a></div><div class=""><br class=""></div><div class="">could you please take a look?</div><div class="">-- adrian</div><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Mar 13, 2017, at 9:24 AM, Zachary Turner via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org" class="">llvm-commits@lists.llvm.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">Author: zturner<br class="">Date: Mon Mar 13 11:24:10 2017<br class="">New Revision: 297633<br class=""><br class="">URL: <a href="http://llvm.org/viewvc/llvm-project?rev=297633&view=rev" class="">http://llvm.org/viewvc/llvm-project?rev=297633&view=rev</a><br class="">Log:<br class="">[ADT] Improve the genericity of llvm::enumerate().<br class=""><br class="">There were some issues in the implementation of enumerate()<br class="">preventing it from being used in various contexts. These were<br class="">all related to the fact that it did not supporter llvm's<br class="">iterator_facade_base class. So this patch adds support for that<br class="">and additionally exposes a new helper method to_vector() that<br class="">will evaluate an entire range and store the results in a<br class="">vector.<br class=""><br class="">Differential Revision: <a href="https://reviews.llvm.org/D30853" class="">https://reviews.llvm.org/D30853</a><br class=""><br class="">Modified:<br class=""> llvm/trunk/include/llvm/ADT/STLExtras.h<br class=""> llvm/trunk/unittests/ADT/STLExtrasTest.cpp<br class=""> llvm/trunk/utils/TableGen/GlobalISelEmitter.cpp<br class=""><br class="">Modified: llvm/trunk/include/llvm/ADT/STLExtras.h<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/STLExtras.h?rev=297633&r1=297632&r2=297633&view=diff" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/STLExtras.h?rev=297633&r1=297632&r2=297633&view=diff</a><br class="">==============================================================================<br class="">--- llvm/trunk/include/llvm/ADT/STLExtras.h (original)<br class="">+++ llvm/trunk/include/llvm/ADT/STLExtras.h Mon Mar 13 11:24:10 2017<br class="">@@ -28,6 +28,7 @@<br class=""> #include <utility> // for std::pair<br class=""><br class=""> #include "llvm/ADT/Optional.h"<br class="">+#include "llvm/ADT/SmallVector.h"<br class=""> #include "llvm/ADT/iterator.h"<br class=""> #include "llvm/ADT/iterator_range.h"<br class=""> #include "llvm/Support/Compiler.h"<br class="">@@ -44,6 +45,10 @@ namespace detail {<br class=""> template <typename RangeT><br class=""> using IterOfRange = decltype(std::begin(std::declval<RangeT &>()));<br class=""><br class="">+template <typename RangeT><br class="">+using ValueOfRange = typename std::remove_reference<decltype(<br class="">+ *std::begin(std::declval<RangeT &>()))>::type;<br class="">+<br class=""> } // End detail namespace<br class=""><br class=""> //===----------------------------------------------------------------------===//<br class="">@@ -883,6 +888,14 @@ auto partition(R &&Range, UnaryPredicate<br class=""> return std::partition(std::begin(Range), std::end(Range), P);<br class=""> }<br class=""><br class="">+/// \brief Given a range of type R, iterate the entire range and return a<br class="">+/// SmallVector with elements of the vector. This is useful, for example,<br class="">+/// when you want to iterate a range and then sort the results.<br class="">+template <unsigned Size, typename R><br class="">+SmallVector<detail::ValueOfRange<R>, Size> to_vector(R &&Range) {<br class="">+ return {std::begin(Range), std::end(Range)};<br class="">+}<br class="">+<br class=""> /// Provide a container algorithm similar to C++ Library Fundamentals v2's<br class=""> /// `erase_if` which is equivalent to:<br class=""> ///<br class="">@@ -977,47 +990,82 @@ template <typename T> struct deref {<br class=""> };<br class=""><br class=""> namespace detail {<br class="">-template <typename R> class enumerator_impl {<br class="">+template <typename R> class enumerator_iter;<br class="">+<br class="">+template <typename R> struct result_pair {<br class="">+ friend class enumerator_iter<R>;<br class="">+<br class="">+ result_pair() : Index(-1) {}<br class="">+ result_pair(std::size_t Index, IterOfRange<R> Iter)<br class="">+ : Index(Index), Iter(Iter) {}<br class="">+<br class="">+ result_pair<R> &operator=(const result_pair<R> &Other) {<br class="">+ Index = Other.Index;<br class="">+ Iter = Other.Iter;<br class="">+ return *this;<br class="">+ }<br class="">+<br class="">+ std::size_t index() const { return Index; }<br class="">+ const ValueOfRange<R> &value() const { return *Iter; }<br class="">+ ValueOfRange<R> &value() { return *Iter; }<br class="">+<br class="">+private:<br class="">+ std::size_t Index;<br class="">+ IterOfRange<R> Iter;<br class="">+};<br class="">+<br class="">+template <typename R><br class="">+class enumerator_iter<br class="">+ : public iterator_facade_base<<br class="">+ enumerator_iter<R>, std::forward_iterator_tag, result_pair<R>,<br class="">+ typename std::iterator_traits<IterOfRange<R>>::difference_type,<br class="">+ typename std::iterator_traits<IterOfRange<R>>::pointer,<br class="">+ typename std::iterator_traits<IterOfRange<R>>::reference> {<br class="">+ using result_type = result_pair<R>;<br class="">+<br class=""> public:<br class="">- template <typename X> struct result_pair {<br class="">- result_pair(std::size_t Index, X Value) : Index(Index), Value(Value) {}<br class="">+ enumerator_iter(std::size_t Index, IterOfRange<R> Iter)<br class="">+ : Result(Index, Iter) {}<br class=""><br class="">- const std::size_t Index;<br class="">- X Value;<br class="">- };<br class="">+ result_type &operator*() { return Result; }<br class="">+ const result_type &operator*() const { return Result; }<br class=""><br class="">- class iterator {<br class="">- typedef<br class="">- typename std::iterator_traits<IterOfRange<R>>::reference iter_reference;<br class="">- typedef result_pair<iter_reference> result_type;<br class="">-<br class="">- public:<br class="">- iterator(IterOfRange<R> &&Iter, std::size_t Index)<br class="">- : Iter(Iter), Index(Index) {}<br class="">-<br class="">- result_type operator*() const { return result_type(Index, *Iter); }<br class="">-<br class="">- iterator &operator++() {<br class="">- ++Iter;<br class="">- ++Index;<br class="">- return *this;<br class="">- }<br class="">-<br class="">- bool operator!=(const iterator &RHS) const { return Iter != RHS.Iter; }<br class="">-<br class="">- private:<br class="">- IterOfRange<R> Iter;<br class="">- std::size_t Index;<br class="">- };<br class="">+ enumerator_iter<R> &operator++() {<br class="">+ assert(Result.Index != -1);<br class="">+ ++Result.Iter;<br class="">+ ++Result.Index;<br class="">+ return *this;<br class="">+ }<br class="">+<br class="">+ bool operator==(const enumerator_iter<R> &RHS) const {<br class="">+ // Don't compare indices here, only iterators. It's possible for an end<br class="">+ // iterator to have different indices depending on whether it was created<br class="">+ // by calling std::end() versus incrementing a valid iterator.<br class="">+ return Result.Iter == RHS.Result.Iter;<br class="">+ }<br class="">+<br class="">+ enumerator_iter<R> &operator=(const enumerator_iter<R> &Other) {<br class="">+ Result = Other.Result;<br class="">+ return *this;<br class="">+ }<br class=""><br class="">+private:<br class="">+ result_type Result;<br class="">+};<br class="">+<br class="">+template <typename R> class enumerator {<br class=""> public:<br class="">- explicit enumerator_impl(R &&Range) : Range(std::forward<R>(Range)) {}<br class="">+ explicit enumerator(R &&Range) : TheRange(std::forward<R>(Range)) {}<br class=""><br class="">- iterator begin() { return iterator(std::begin(Range), 0); }<br class="">- iterator end() { return iterator(std::end(Range), std::size_t(-1)); }<br class="">+ enumerator_iter<R> begin() {<br class="">+ return enumerator_iter<R>(0, std::begin(TheRange));<br class="">+ }<br class="">+ enumerator_iter<R> end() {<br class="">+ return enumerator_iter<R>(-1, std::end(TheRange));<br class="">+ }<br class=""><br class=""> private:<br class="">- R Range;<br class="">+ R TheRange;<br class=""> };<br class=""> }<br class=""><br class="">@@ -1036,8 +1084,8 @@ private:<br class=""> /// Item 2 - C<br class=""> /// Item 3 - D<br class=""> ///<br class="">-template <typename R> detail::enumerator_impl<R> enumerate(R &&Range) {<br class="">- return detail::enumerator_impl<R>(std::forward<R>(Range));<br class="">+template <typename R> detail::enumerator<R> enumerate(R &&TheRange) {<br class="">+ return detail::enumerator<R>(std::forward<R>(TheRange));<br class=""> }<br class=""><br class=""> namespace detail {<br class=""><br class="">Modified: llvm/trunk/unittests/ADT/STLExtrasTest.cpp<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/STLExtrasTest.cpp?rev=297633&r1=297632&r2=297633&view=diff" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/STLExtrasTest.cpp?rev=297633&r1=297632&r2=297633&view=diff</a><br class="">==============================================================================<br class="">--- llvm/trunk/unittests/ADT/STLExtrasTest.cpp (original)<br class="">+++ llvm/trunk/unittests/ADT/STLExtrasTest.cpp Mon Mar 13 11:24:10 2017<br class="">@@ -48,7 +48,7 @@ TEST(STLExtrasTest, EnumerateLValue) {<br class=""> std::vector<CharPairType> CharResults;<br class=""><br class=""> for (auto X : llvm::enumerate(foo)) {<br class="">- CharResults.emplace_back(X.Index, X.Value);<br class="">+ CharResults.emplace_back(X.index(), X.value());<br class=""> }<br class=""> ASSERT_EQ(3u, CharResults.size());<br class=""> EXPECT_EQ(CharPairType(0u, 'a'), CharResults[0]);<br class="">@@ -60,7 +60,7 @@ TEST(STLExtrasTest, EnumerateLValue) {<br class=""> std::vector<IntPairType> IntResults;<br class=""> const std::vector<int> bar = {1, 2, 3};<br class=""> for (auto X : llvm::enumerate(bar)) {<br class="">- IntResults.emplace_back(X.Index, X.Value);<br class="">+ IntResults.emplace_back(X.index(), X.value());<br class=""> }<br class=""> ASSERT_EQ(3u, IntResults.size());<br class=""> EXPECT_EQ(IntPairType(0u, 1), IntResults[0]);<br class="">@@ -71,7 +71,7 @@ TEST(STLExtrasTest, EnumerateLValue) {<br class=""> IntResults.clear();<br class=""> const std::vector<int> baz{};<br class=""> for (auto X : llvm::enumerate(baz)) {<br class="">- IntResults.emplace_back(X.Index, X.Value);<br class="">+ IntResults.emplace_back(X.index(), X.value());<br class=""> }<br class=""> EXPECT_TRUE(IntResults.empty());<br class=""> }<br class="">@@ -82,7 +82,7 @@ TEST(STLExtrasTest, EnumerateModifyLValu<br class=""> std::vector<char> foo = {'a', 'b', 'c'};<br class=""><br class=""> for (auto X : llvm::enumerate(foo)) {<br class="">- ++X.Value;<br class="">+ ++X.value();<br class=""> }<br class=""> EXPECT_EQ('b', foo[0]);<br class=""> EXPECT_EQ('c', foo[1]);<br class="">@@ -97,7 +97,7 @@ TEST(STLExtrasTest, EnumerateRValueRef)<br class=""> auto Enumerator = llvm::enumerate(std::vector<int>{1, 2, 3});<br class=""><br class=""> for (auto X : llvm::enumerate(std::vector<int>{1, 2, 3})) {<br class="">- Results.emplace_back(X.Index, X.Value);<br class="">+ Results.emplace_back(X.index(), X.value());<br class=""> }<br class=""><br class=""> ASSERT_EQ(3u, Results.size());<br class="">@@ -114,8 +114,8 @@ TEST(STLExtrasTest, EnumerateModifyRValu<br class=""> std::vector<PairType> Results;<br class=""><br class=""> for (auto X : llvm::enumerate(std::vector<char>{'1', '2', '3'})) {<br class="">- ++X.Value;<br class="">- Results.emplace_back(X.Index, X.Value);<br class="">+ ++X.value();<br class="">+ Results.emplace_back(X.index(), X.value());<br class=""> }<br class=""><br class=""> ASSERT_EQ(3u, Results.size());<br class="">@@ -255,6 +255,16 @@ TEST(STLExtrasTest, CountAdaptor) {<br class=""> EXPECT_EQ(1, count(v, 4));<br class=""> }<br class=""><br class="">+TEST(STLExtrasTest, ToVector) {<br class="">+ std::vector<char> v = {'a', 'b', 'c'};<br class="">+ auto Enumerated = to_vector<4>(enumerate(v));<br class="">+ ASSERT_EQ(3, Enumerated.size());<br class="">+ for (size_t I = 0; I < v.size(); ++I) {<br class="">+ EXPECT_EQ(I, Enumerated[I].index());<br class="">+ EXPECT_EQ(v[I], Enumerated[I].value());<br class="">+ }<br class="">+}<br class="">+<br class=""> TEST(STLExtrasTest, ConcatRange) {<br class=""> std::vector<int> Expected = {1, 2, 3, 4, 5, 6, 7, 8};<br class=""> std::vector<int> Test;<br class=""><br class="">Modified: llvm/trunk/utils/TableGen/GlobalISelEmitter.cpp<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/GlobalISelEmitter.cpp?rev=297633&r1=297632&r2=297633&view=diff" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/GlobalISelEmitter.cpp?rev=297633&r1=297632&r2=297633&view=diff</a><br class="">==============================================================================<br class="">--- llvm/trunk/utils/TableGen/GlobalISelEmitter.cpp (original)<br class="">+++ llvm/trunk/utils/TableGen/GlobalISelEmitter.cpp Mon Mar 13 11:24:10 2017<br class="">@@ -582,9 +582,9 @@ private:<br class=""> /// True if the instruction can be built solely by mutating the opcode.<br class=""> bool canMutate() const {<br class=""> for (const auto &Renderer : enumerate(OperandRenderers)) {<br class="">- if (const auto *Copy = dyn_cast<CopyRenderer>(&*Renderer.Value)) {<br class="">+ if (const auto *Copy = dyn_cast<CopyRenderer>(&*Renderer.value())) {<br class=""> if (Matched.getOperand(Copy->getSymbolicName()).getOperandIndex() !=<br class="">- Renderer.Index)<br class="">+ Renderer.index())<br class=""> return false;<br class=""> } else<br class=""> return false;<br class=""><br class=""><br class="">_______________________________________________<br class="">llvm-commits mailing list<br class=""><a href="mailto:llvm-commits@lists.llvm.org" class="">llvm-commits@lists.llvm.org</a><br class="">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits<br class=""></div></div></blockquote></div><br class=""></div></body></html>