[llvm] r287722 - Add some searching functions for ArrayRef<T>.
David Blaikie via llvm-commits
llvm-commits at lists.llvm.org
Mon Nov 28 10:16:20 PST 2016
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/cca37dec/attachment.html>
More information about the llvm-commits
mailing list