Reverse range adapter

David Blaikie dblaikie at gmail.com
Wed Jul 29 14:22:10 PDT 2015


On Wed, Jul 29, 2015 at 2:02 PM, Pete Cooper <peter_cooper at apple.com> wrote:

>
> On Jul 29, 2015, at 1:50 PM, David Blaikie <dblaikie at gmail.com> wrote:
>
> Yep, something like that looks about right. I'm not sure if it can be
> generalized further so we can reuse some of the machinery for begin, end,
> rbegin, rend, getDecl, etc. You can probably just SFINAE on begin/rbegin
> and assume end/rend exist - but if we can get the SFINAE tidy enough it
> wouldn't hurt to test for both, I suppose.
>
> btw, my change to the test that demonstrates the problem with using
> universal ref/lvalue ref distinction to differentiate is this: add "const
> ReverseOnlyVector/const BidirectionalVector" to the Types vector & you'll
> see failures in the existing implementation. Alternatively/in addition,
> could refactor out the body of the TrivialOperation test into a template,
> then instantiate that template with TypeParam and const TypeParam, so you
> don't have to list all of them as const/non-const in the list of types.
>
> Also, I added this rvalue version:
>
> template <typename T> struct RangeAdapterRValueTest : testing::Test {};
>
> typedef ::testing::Types<std::vector<int>, std::list<int>,
> ReverseOnlyVector,
>                          BidirectionalVector> RangeAdapterRValueTestTypes;
> TYPED_TEST_CASE(RangeAdapterRValueTest, RangeAdapterRValueTestTypes);
>
>
> template<typename R>
> void TestRev(const R& r) {
>   int counter = 3;
>   for (int i : r)
>     EXPECT_EQ(i, counter--);
> }
>
> TYPED_TEST(RangeAdapterRValueTest, TrivialOperation) {
>   TestRev(reverse(TypeParam({0, 1, 2, 3})));
> }
>
> Very nice.  Thanks for doing that.
>
> Here’s a patch with the fixes.  I had to extend has_rbegin to handle
> whether its a class or not (int[] failed without that).  Otherwise its
> basically just like has_getDecl.  I think has_getDecl is in an internal
> namespace.  I can do the same here if you like, i’m fine either way.
>

So the rvalue tests I added don't cover the non-rvalue case your existing
test cases covered (nor the array cases) - looks like you dropped the
originals?

I wonder if the SFINAE can be done without trying to derive from the type
(some types might not be derivable)

Maybe the hasDecl was written pre-C++11?

This /seems/ to work in the basic case:

struct foo {
  void func();
};

struct bar {
};

template<typename T>
struct has_func {
  template<typename U>
  static char (&f(const U&, decltype(&U::func)))[1];
  static char (&f(...))[2];
  const static bool value = sizeof(f(std::declval<T>(), nullptr)) == 1;
};

static_assert(has_func<foo>::value, "");
static_assert(!has_func<bar>::value, "");

(plus the extra non-class detection you had too)


>
> Cheers,
> Pete
>
>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150729/bb0874ec/attachment.html>


More information about the llvm-commits mailing list