Commit 300142f1 authored by Daniil Burdakov's avatar Daniil Burdakov Committed by Dave Watson

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
parent 9529709d
......@@ -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_);
}
......
......@@ -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)
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment