<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>