[llvm] r297633 - [ADT] Improve the genericity of llvm::enumerate().

Adrian Prantl via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 13 11:50:06 PDT 2017


+Mike
Strange, it looks like the green dragon incremental bot didn;t build anything after 9:44AM today.

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

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170313/6f35e56a/attachment.html>


More information about the llvm-commits mailing list