[llvm] r297633 - [ADT] Improve the genericity of llvm::enumerate().
Mike Edwards via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 13 12:16:17 PDT 2017
Looks like the mirror in the lab is not updating again. I’ll ping Galina and see if she can give it a kick. Thanks for the heads up.
-Mike
Mike Edwards
Apple, Inc.
☏ 408-862-7095
medwards at apple.com
> On Mar 13, 2017, at 11:50 AM, Adrian Prantl <aprantl at apple.com> wrote:
>
> +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 <mailto: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/26a84adf/attachment.html>
More information about the llvm-commits
mailing list