made folly::gen::member accept pointers to objects as well as references
authorDaniil Burdakov <burdakovd@fb.com>
Thu, 8 May 2014 11:57:20 +0000 (11:57 +0000)
committerDave Watson <davejwatson@fb.com>
Tue, 20 May 2014 19:53:58 +0000 (12:53 -0700)
Summary: subj

Test Plan: tests

Reviewed By: tjackson@fb.com

FB internal diff: D1318719

folly/gen/Base.h
folly/gen/test/BaseTest.cpp

index 287d4a6c441d3a9050b16cabaf8a84d5b455327a..46141ee27b6e958e6bbc1b6accb93265e217d1eb 100644 (file)
@@ -136,6 +136,10 @@ class MemberFunction {
   Result operator()(Class& x) const {
     return (x.*member_)();
   }
+
+  Result operator()(Class* x) const {
+    return (x->*member_)();
+  }
 };
 
 template<class Class,
@@ -153,6 +157,10 @@ class ConstMemberFunction{
   Result operator()(const Class& x) const {
     return (x.*member_)();
   }
+
+  Result operator()(const Class* x) const {
+    return (x->*member_)();
+  }
 };
 
 template<class Class,
@@ -171,10 +179,18 @@ class Field {
     return x.*field_;
   }
 
+  const FieldType& operator()(const Class* x) const {
+    return x->*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_);
   }
index 99644c28be3f0e67b357edbdcca687e8f4bf0246..b7c71377a71a5ac49c8edc9939d7c4bd3082de90 100644 (file)
@@ -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<X&>() | field(&X::a) | assert_type<const int&>();
+  empty<X*>() | field(&X::a) | assert_type<const int&>();
   empty<X&>() | field(&X::b) | assert_type<int&>();
+  empty<X*>() | field(&X::b) | assert_type<int&>();
   empty<X&>() | field(&X::c) | assert_type<int&>();
+  empty<X*>() | field(&X::c) | assert_type<int&>();
+
   empty<X&&>() | field(&X::a) | assert_type<const int&&>();
   empty<X&&>() | field(&X::b) | assert_type<int&&>();
   empty<X&&>() | field(&X::c) | assert_type<int&&>();
   // references don't imply ownership so they're not moved
+
   empty<const X&>() | field(&X::a) | assert_type<const int&>();
+  empty<const X*>() | field(&X::a) | assert_type<const int&>();
   empty<const X&>() | field(&X::b) | assert_type<const int&>();
+  empty<const X*>() | field(&X::b) | assert_type<const int&>();
   // 'mutable' has no effect on field pointers, by C++ spec
   empty<const X&>() | field(&X::c) | assert_type<const int&>();
+  empty<const X*>() | field(&X::c) | assert_type<const int&>();
 
   // can't form pointer-to-reference field: empty<X&>() | field(&X::d)
 }