[llvm] r287722 - Add some searching functions for ArrayRef<T>.
David Blaikie via llvm-commits
llvm-commits at lists.llvm.org
Mon Nov 28 10:23:23 PST 2016
On Mon, Nov 28, 2016 at 10:19 AM Zachary Turner <zturner at google.com> wrote:
> Having a single type for cost and mutable would be great, if we could make
> it work. Seems like a huge change across the codebase, but probably worth
> it if myself or someone gets some cycles to do it.
>
Yep - big, but fairly mechanical change. If you/anyone else wants to do
this, I'd suggest floating it on llvm-dev first, just so everyone's aware
of the ArrayRef<T> -> ArrayRef<const T> change that would fall out of this.
> And good point about having drop_front call slice. I can make it parallel
> the interface of ArrayRef for now, until we figure out what to do about
> constness.
>
Yep yep
>
> On Mon, Nov 28, 2016 at 10:16 AM David Blaikie <dblaikie at gmail.com> wrote:
>
> On Tue, Nov 22, 2016 at 3:32 PM Zachary Turner via llvm-commits <
> llvm-commits at lists.llvm.org> wrote:
>
> Author: zturner
> Date: Tue Nov 22 17:22:19 2016
> New Revision: 287722
>
> URL: http://llvm.org/viewvc/llvm-project?rev=287722&view=rev
> Log:
> Add some searching functions for ArrayRef<T>.
>
> Differential Revision: https://reviews.llvm.org/D26999
>
> Modified:
> llvm/trunk/include/llvm/ADT/ArrayRef.h
> llvm/trunk/include/llvm/ADT/STLExtras.h
> llvm/trunk/unittests/ADT/ArrayRefTest.cpp
>
> Modified: llvm/trunk/include/llvm/ADT/ArrayRef.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/ArrayRef.h?rev=287722&r1=287721&r2=287722&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/ADT/ArrayRef.h (original)
> +++ llvm/trunk/include/llvm/ADT/ArrayRef.h Tue Nov 22 17:22:19 2016
> @@ -12,6 +12,7 @@
>
> #include "llvm/ADT/Hashing.h"
> #include "llvm/ADT/None.h"
> +#include "llvm/ADT/STLExtras.h"
> #include "llvm/ADT/SmallVector.h"
> #include <array>
> #include <vector>
> @@ -165,12 +166,6 @@ namespace llvm {
> return std::equal(begin(), end(), RHS.begin());
> }
>
> - /// slice(n) - Chop off the first N elements of the array.
> - ArrayRef<T> slice(size_t N) const {
> - assert(N <= size() && "Invalid specifier");
> - return ArrayRef<T>(data()+N, size()-N);
>
>
> This might be easier written as ArrayRef(begin() + N, end()) - similar
> suggestion in MutableArrayRef. (worth adding a CRTP base to implement some
> of these common functions in both? - alternatively I'll float the
> suggestion I made when Chris originally committed MutableArrayRef: Maybe we
> just fix ArrayRef<T> -> ArrayRef<const T> and ArrayRef<T> is
> MutableArrayRef<T> and there's no need for two types, etc)
>
> (note you don't need to specify <T> when referencing ArrayRef<T> from
> within the class itself - applies across this change)
>
>
> - }
> -
> /// slice(n, m) - Chop off the first N elements of the array, and
> keep M
> /// elements in the array.
> ArrayRef<T> slice(size_t N, size_t M) const {
> @@ -178,6 +173,9 @@ namespace llvm {
> return ArrayRef<T>(data()+N, M);
> }
>
> + /// slice(n) - Chop off the first N elements of the array.
>
>
> This is an alias for drop_front below, right? Should one call the other?
>
>
> + ArrayRef<T> slice(size_t N) const { return slice(N, size() - N); }
> +
> /// \brief Drop the first \p N elements of the array.
> ArrayRef<T> drop_front(size_t N = 1) const {
> assert(size() >= N && "Dropping more elements than exist");
> @@ -190,6 +188,18 @@ namespace llvm {
> return slice(0, size() - N);
> }
>
> + /// \brief Return a copy of *this with the first N elements
> satisfying the
> + /// given predicate removed.
> + template <class PredicateT> ArrayRef<T> drop_while(PredicateT Pred)
> const {
> + return ArrayRef<T>(find_if_not(*this, Pred), end());
> + }
> +
> + /// \brief Return a copy of *this with the first N elements not
> satisfying
> + /// the given predicate removed.
> + template <class PredicateT> ArrayRef<T> drop_until(PredicateT Pred)
> const {
> + return ArrayRef<T>(find_if(*this, Pred), end());
> + }
> +
> /// \brief Return a copy of *this with only the first \p N elements.
> ArrayRef<T> take_front(size_t N = 1) const {
> if (N >= size())
> @@ -204,6 +214,18 @@ namespace llvm {
> return drop_front(size() - N);
> }
>
> + /// \brief Return the first N elements of this Array that satisfy the
> given
> + /// predicate.
> + template <class PredicateT> ArrayRef<T> take_while(PredicateT Pred)
> const {
> + return ArrayRef<T>(begin(), find_if_not(*this, Pred));
> + }
> +
> + /// \brief Return the first N elements of this Array that don't
> satisfy the
> + /// given predicate.
> + template <class PredicateT> ArrayRef<T> take_until(PredicateT Pred)
> const {
> + return ArrayRef<T>(begin(), find_if(*this, Pred));
> + }
> +
> /// @}
> /// @name Operator Overloads
> /// @{
> @@ -317,17 +339,16 @@ namespace llvm {
> return data()[this->size()-1];
> }
>
> - /// slice(n) - Chop off the first N elements of the array.
> - MutableArrayRef<T> slice(size_t N) const {
> - assert(N <= this->size() && "Invalid specifier");
> - return MutableArrayRef<T>(data()+N, this->size()-N);
> - }
> -
> /// slice(n, m) - Chop off the first N elements of the array, and
> keep M
> /// elements in the array.
> MutableArrayRef<T> slice(size_t N, size_t M) const {
> - assert(N+M <= this->size() && "Invalid specifier");
> - return MutableArrayRef<T>(data()+N, M);
> + assert(N + M <= this->size() && "Invalid specifier");
> + return MutableArrayRef<T>(this->data() + N, M);
> + }
> +
> + /// slice(n) - Chop off the first N elements of the array.
> + MutableArrayRef<T> slice(size_t N) const {
> + return slice(N, this->size() - N);
> }
>
> /// \brief Drop the first \p N elements of the array.
> @@ -341,6 +362,20 @@ namespace llvm {
> return slice(0, this->size() - N);
> }
>
> + /// \brief Return a copy of *this with the first N elements
> satisfying the
> + /// given predicate removed.
> + template <class PredicateT>
> + MutableArrayRef<T> drop_while(PredicateT Pred) const {
> + return MutableArrayRef<T>(find_if_not(*this, Pred), end());
> + }
> +
> + /// \brief Return a copy of *this with the first N elements not
> satisfying
> + /// the given predicate removed.
> + template <class PredicateT>
> + MutableArrayRef<T> drop_until(PredicateT Pred) const {
> + return MutableArrayRef<T>(find_if(*this, Pred), end());
> + }
> +
> /// \brief Return a copy of *this with only the first \p N elements.
> MutableArrayRef<T> take_front(size_t N = 1) const {
> if (N >= this->size())
> @@ -355,6 +390,20 @@ namespace llvm {
> return drop_front(this->size() - N);
> }
>
> + /// \brief Return the first N elements of this Array that satisfy the
> given
> + /// predicate.
> + template <class PredicateT>
> + MutableArrayRef<T> take_while(PredicateT Pred) const {
> + return MutableArrayRef<T>(begin(), find_if_not(*this, Pred));
> + }
> +
> + /// \brief Return the first N elements of this Array that don't
> satisfy the
> + /// given predicate.
> + template <class PredicateT>
> + MutableArrayRef<T> take_until(PredicateT Pred) const {
> + return MutableArrayRef<T>(begin(), find_if(*this, Pred));
> + }
> +
> /// @}
> /// @name Operator Overloads
> /// @{
>
> Modified: llvm/trunk/include/llvm/ADT/STLExtras.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/STLExtras.h?rev=287722&r1=287721&r2=287722&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/ADT/STLExtras.h (original)
> +++ llvm/trunk/include/llvm/ADT/STLExtras.h Tue Nov 22 17:22:19 2016
> @@ -622,6 +622,11 @@ auto find_if(R &&Range, const T &Pred) -
> return std::find_if(Range.begin(), Range.end(), Pred);
> }
>
> +template <typename R, class PredicateT>
> +auto find_if_not(R &&Range, PredicateT Pred) -> decltype(Range.begin()) {
> + return std::find_if_not(Range.begin(), Range.end(), Pred);
> +}
> +
> /// Provide wrappers to std::remove_if which take ranges instead of
> having to
> /// pass begin/end explicitly.
> template<typename R, class UnaryPredicate>
>
> Modified: llvm/trunk/unittests/ADT/ArrayRefTest.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/ArrayRefTest.cpp?rev=287722&r1=287721&r2=287722&view=diff
>
> ==============================================================================
> --- llvm/trunk/unittests/ADT/ArrayRefTest.cpp (original)
> +++ llvm/trunk/unittests/ADT/ArrayRefTest.cpp Tue Nov 22 17:22:19 2016
> @@ -102,6 +102,28 @@ TEST(ArrayRefTest, DropFront) {
> EXPECT_EQ(1U, AR3.drop_front(AR3.size() - 1).size());
> }
>
> +TEST(ArrayRefTest, DropWhile) {
> + static const int TheNumbers[] = {1, 3, 5, 8, 10, 11};
> + ArrayRef<int> AR1(TheNumbers);
> + ArrayRef<int> Expected = AR1.drop_front(3);
> + EXPECT_EQ(Expected, AR1.drop_while([](const int &N) { return N % 2 ==
> 1; }));
> +
> + EXPECT_EQ(AR1, AR1.drop_while([](const int &N) { return N < 0; }));
> + EXPECT_EQ(ArrayRef<int>(),
> + AR1.drop_while([](const int &N) { return N > 0; }));
> +}
> +
> +TEST(ArrayRefTest, DropUntil) {
> + static const int TheNumbers[] = {1, 3, 5, 8, 10, 11};
> + ArrayRef<int> AR1(TheNumbers);
> + ArrayRef<int> Expected = AR1.drop_front(3);
> + EXPECT_EQ(Expected, AR1.drop_until([](const int &N) { return N % 2 ==
> 0; }));
> +
> + EXPECT_EQ(ArrayRef<int>(),
> + AR1.drop_until([](const int &N) { return N < 0; }));
> + EXPECT_EQ(AR1, AR1.drop_until([](const int &N) { return N > 0; }));
> +}
> +
> TEST(ArrayRefTest, TakeBack) {
> static const int TheNumbers[] = {4, 8, 15, 16, 23, 42};
> ArrayRef<int> AR1(TheNumbers);
> @@ -116,6 +138,28 @@ TEST(ArrayRefTest, TakeFront) {
> EXPECT_TRUE(AR1.take_front(2).equals(AR2));
> }
>
> +TEST(ArrayRefTest, TakeWhile) {
> + static const int TheNumbers[] = {1, 3, 5, 8, 10, 11};
> + ArrayRef<int> AR1(TheNumbers);
> + ArrayRef<int> Expected = AR1.take_front(3);
> + EXPECT_EQ(Expected, AR1.take_while([](const int &N) { return N % 2 ==
> 1; }));
> +
> + EXPECT_EQ(ArrayRef<int>(),
> + AR1.take_while([](const int &N) { return N < 0; }));
> + EXPECT_EQ(AR1, AR1.take_while([](const int &N) { return N > 0; }));
> +}
> +
> +TEST(ArrayRefTest, TakeUntil) {
> + static const int TheNumbers[] = {1, 3, 5, 8, 10, 11};
> + ArrayRef<int> AR1(TheNumbers);
> + ArrayRef<int> Expected = AR1.take_front(3);
> + EXPECT_EQ(Expected, AR1.take_until([](const int &N) { return N % 2 ==
> 0; }));
> +
> + EXPECT_EQ(AR1, AR1.take_until([](const int &N) { return N < 0; }));
> + EXPECT_EQ(ArrayRef<int>(),
> + AR1.take_until([](const int &N) { return N > 0; }));
> +}
> +
> TEST(ArrayRefTest, Equals) {
> static const int A1[] = {1, 2, 3, 4, 5, 6, 7, 8};
> ArrayRef<int> AR1(A1);
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> 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/20161128/498fe867/attachment.html>
More information about the llvm-commits
mailing list