From 300142f124f3f7f2f060d2749959e4a128d0ae80 Mon Sep 17 00:00:00 2001 From: Daniil Burdakov Date: Thu, 8 May 2014 11:57:20 +0000 Subject: [PATCH] made folly::gen::member accept pointers to objects as well as references Summary: subj Test Plan: tests Reviewed By: tjackson@fb.com FB internal diff: D1318719 --- folly/gen/Base.h | 16 ++++++++++++++++ folly/gen/test/BaseTest.cpp | 23 ++++++++++++++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/folly/gen/Base.h b/folly/gen/Base.h index 287d4a6c..46141ee2 100644 --- a/folly/gen/Base.h +++ b/folly/gen/Base.h @@ -136,6 +136,10 @@ class MemberFunction { Result operator()(Class& x) const { return (x.*member_)(); } + + Result operator()(Class* x) const { + return (x->*member_)(); + } }; template*member_)(); + } }; template*field_; + } + FieldType& operator()(Class& x) const { return x.*field_; } + FieldType& operator()(Class* x) const { + return x->*field_; + } + FieldType&& operator()(Class&& x) const { return std::move(x.*field_); } diff --git a/folly/gen/test/BaseTest.cpp b/folly/gen/test/BaseTest.cpp index 99644c28..b7c71377 100644 --- a/folly/gen/test/BaseTest.cpp +++ b/folly/gen/test/BaseTest.cpp @@ -122,11 +122,21 @@ TEST(Gen, Member) { from(counters) | member(&Counter::count) | sum); + EXPECT_EQ(10 * (1 + 10) / 2, + from(counters) + | mapped([](const Counter& c) { return &c; }) + | member(&Counter::count) + | sum); EXPECT_EQ(10 * (2 + 11) / 2, from(counters) | member(&Counter::incr) | sum); - EXPECT_EQ(10 * (2 + 11) / 2, + EXPECT_EQ(10 * (3 + 12) / 2, + from(counters) + | mapped([](Counter& c) { return &c; }) + | member(&Counter::incr) + | sum); + EXPECT_EQ(10 * (3 + 12) / 2, from(counters) | member(&Counter::count) | sum); @@ -162,18 +172,29 @@ TEST(Gen, Field) { EXPECT_EQ(4, from(xs) | field(&X::c) | first); + EXPECT_EQ(2, seq(&xs[0], &xs[0]) + | field(&X::a) + | first); // type-verification empty() | field(&X::a) | assert_type(); + empty() | field(&X::a) | assert_type(); empty() | field(&X::b) | assert_type(); + empty() | field(&X::b) | assert_type(); empty() | field(&X::c) | assert_type(); + empty() | field(&X::c) | assert_type(); + empty() | field(&X::a) | assert_type(); empty() | field(&X::b) | assert_type(); empty() | field(&X::c) | assert_type(); // references don't imply ownership so they're not moved + empty() | field(&X::a) | assert_type(); + empty() | field(&X::a) | assert_type(); empty() | field(&X::b) | assert_type(); + empty() | field(&X::b) | assert_type(); // 'mutable' has no effect on field pointers, by C++ spec empty() | field(&X::c) | assert_type(); + empty() | field(&X::c) | assert_type(); // can't form pointer-to-reference field: empty() | field(&X::d) } -- 2.34.1