[llvm] r278991 - Fix reverse to work on const rbegin()/rend().
Duncan P. N. Exon Smith via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 17 15:55:49 PDT 2016
> On 2016-Aug-17, at 15:06, Pete Cooper via llvm-commits <llvm-commits at lists.llvm.org> wrote:
>
> Author: pete
> Date: Wed Aug 17 17:06:59 2016
> New Revision: 278991
>
> URL: http://llvm.org/viewvc/llvm-project?rev=278991&view=rev
> Log:
> Fix reverse to work on const rbegin()/rend().
>
> Duncan found that reverse worked on mutable rbegin(), but the has_rbegin
> trait didn't work with a const method. See http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20160815/382890.html
> for more details.
>
> Turns out this was already solved in clang with has_getDecl. Copied that and made it work for rbegin.
>
> This includes the tests Duncan attached to that thread, including the traits test.
>
> Modified:
> llvm/trunk/include/llvm/ADT/STLExtras.h
> llvm/trunk/unittests/ADT/RangeAdapterTest.cpp
>
> Modified: llvm/trunk/include/llvm/ADT/STLExtras.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/STLExtras.h?rev=278991&r1=278990&r2=278991&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/ADT/STLExtras.h (original)
> +++ llvm/trunk/include/llvm/ADT/STLExtras.h Wed Aug 17 17:06:59 2016
> @@ -209,10 +209,19 @@ inline mapped_iterator<ItTy, FuncTy> map
> }
>
> /// \brief Metafunction to determine if type T has a member called rbegin().
> -template <typename T> struct has_rbegin {
> - template <typename U> static char(&f(const U &, decltype(&U::rbegin)))[1];
> - static char(&f(...))[2];
> - const static bool value = sizeof(f(std::declval<T>(), nullptr)) == 1;
> +template <typename Ty>
> +class has_rbegin {
> + typedef char yes[1];
> + typedef char no[2];
> +
> + template <typename Inner>
> + static yes& test(Inner *I, decltype(I->rbegin()) * = nullptr);
> +
> + template <typename>
> + static no& test(...);
> +
> +public:
> + static const bool value = sizeof(test<Ty>(nullptr)) == sizeof(yes);
> };
>
> // Returns an iterator_range over the given container which iterates in reverse.
>
> Modified: llvm/trunk/unittests/ADT/RangeAdapterTest.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/RangeAdapterTest.cpp?rev=278991&r1=278990&r2=278991&view=diff
> ==============================================================================
> --- llvm/trunk/unittests/ADT/RangeAdapterTest.cpp (original)
> +++ llvm/trunk/unittests/ADT/RangeAdapterTest.cpp Wed Aug 17 17:06:59 2016
> @@ -27,8 +27,11 @@ public:
> ReverseOnlyVector(std::initializer_list<int> list) : Vec(list) {}
>
> typedef std::vector<int>::reverse_iterator reverse_iterator;
> + typedef std::vector<int>::const_reverse_iterator const_reverse_iterator;
> reverse_iterator rbegin() { return Vec.rbegin(); }
> reverse_iterator rend() { return Vec.rend(); }
> + const_reverse_iterator rbegin() const { return Vec.rbegin(); }
> + const_reverse_iterator rend() const { return Vec.rend(); }
> };
>
> // A wrapper around vector which exposes begin(), end(), rbegin() and rend().
> @@ -49,6 +52,29 @@ public:
> reverse_iterator rend() { return Vec.rend(); }
> };
>
> +/// This is the same as BidirectionalVector but with the addition of const
> +/// begin/rbegin methods to ensure that the type traits for has_rbegin works.
> +class BidirectionalVectorConsts {
Do you need to hook this up to the unit test somehow?
> + std::vector<int> Vec;
> +
> +public:
> + BidirectionalVectorConsts(std::initializer_list<int> list) : Vec(list) {}
> +
> + typedef std::vector<int>::iterator iterator;
> + typedef std::vector<int>::const_iterator const_iterator;
> + iterator begin();
> + iterator end();
> + const_iterator begin() const;
> + const_iterator end() const;
> +
> + typedef std::vector<int>::reverse_iterator reverse_iterator;
> + typedef std::vector<int>::const_reverse_iterator const_reverse_iterator;
> + reverse_iterator rbegin() { return Vec.rbegin(); }
> + reverse_iterator rend() { return Vec.rend(); }
> + const_reverse_iterator rbegin() const { return Vec.rbegin(); }
> + const_reverse_iterator rend() const { return Vec.rend(); }
> +};
> +
> template <typename R> void TestRev(const R &r) {
> int counter = 3;
> for (int i : r)
> @@ -80,4 +106,8 @@ TYPED_TEST(RangeAdapterRValueTest, Trivi
> TestRev(reverse(TypeParam({0, 1, 2, 3})));
> }
>
> +TYPED_TEST(RangeAdapterRValueTest, HasRbegin) {
> + EXPECT_TRUE(has_rbegin<TypeParam>::value);
> +}
> +
> } // anonymous namespace
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list