Commit 117c33c3 authored by Tom Jackson's avatar Tom Jackson Committed by Sara Golemon

Making 'just()' reference arguments like 'from()' (fixed)

Summary: That is, for all inputs except r-values. Now with support for GCC.

Test Plan: Run tests

Reviewed By: ajaymenon@fb.com

Subscribers: moharrami, trunkagent, folly-diffs@, yfeldblum

FB internal diff: D1822339

Signature: t1:1822339:1423683482:027871549d69017a7a23a675025851a0b876ad77
parent 01d474df
...@@ -328,13 +328,32 @@ class Empty : public GenImpl<Value, Empty<Value>> { ...@@ -328,13 +328,32 @@ class Empty : public GenImpl<Value, Empty<Value>> {
void foreach(Body&&) const {} void foreach(Body&&) const {}
}; };
template<class Value> template <class Value>
class Just : public GenImpl<const Value&, Just<Value>> { class SingleReference : public GenImpl<Value&, SingleReference<Value>> {
static_assert(!std::is_reference<Value>::value,
"SingleReference requires non-ref types");
Value* ptr_;
public:
explicit SingleReference(Value& ref) : ptr_(&ref) {}
template <class Handler>
bool apply(Handler&& handler) const {
return handler(*ptr_);
}
template <class Body>
void foreach(Body&& body) const {
body(*ptr_);
}
};
template <class Value>
class SingleCopy : public GenImpl<const Value&, SingleCopy<Value>> {
static_assert(!std::is_reference<Value>::value, static_assert(!std::is_reference<Value>::value,
"Just requires non-ref types"); "SingleCopy requires non-ref types");
const Value value_; Value value_;
public: public:
explicit Just(Value value) : value_(std::forward<Value>(value)) {} explicit SingleCopy(Value value) : value_(std::forward<Value>(value)) {}
template <class Handler> template <class Handler>
bool apply(Handler&& handler) const { bool apply(Handler&& handler) const {
......
...@@ -297,7 +297,10 @@ template<class Value> ...@@ -297,7 +297,10 @@ template<class Value>
class Empty; class Empty;
template<class Value> template<class Value>
class Just; class SingleReference;
template<class Value>
class SingleCopy;
/* /*
* Operators * Operators
...@@ -482,14 +485,19 @@ Yield generator(Source&& source) { ...@@ -482,14 +485,19 @@ Yield generator(Source&& source) {
/* /*
* empty() - for producing empty sequences. * empty() - for producing empty sequences.
*/ */
template<class Value> template <class Value>
detail::Empty<Value> empty() { detail::Empty<Value> empty() {
return {}; return {};
} }
template<class Value> template <
detail::Just<Value> just(Value value) { class Value,
return detail::Just<Value>(std::move(value)); class Just = typename std::conditional<
std::is_reference<Value>::value,
detail::SingleReference<typename std::remove_reference<Value>::type>,
detail::SingleCopy<Value>>::type>
Just just(Value&& value) {
return Just(std::forward<Value>(value));
} }
/* /*
......
...@@ -136,7 +136,7 @@ class Sub : public Operator<Sub<Sink>> { ...@@ -136,7 +136,7 @@ class Sub : public Operator<Sub<Sink>> {
class Source, class Source,
class Result = class Result =
decltype(std::declval<Sink>().compose(std::declval<Source>())), decltype(std::declval<Sink>().compose(std::declval<Source>())),
class Just = Just<typename std::decay<Result>::type>> class Just = SingleCopy<typename std::decay<Result>::type>>
Just compose(const GenImpl<Value, Source>& source) const { Just compose(const GenImpl<Value, Source>& source) const {
return Just(source | sink_); return Just(source | sink_);
} }
......
...@@ -1073,6 +1073,31 @@ TEST(Gen, BatchMove) { ...@@ -1073,6 +1073,31 @@ TEST(Gen, BatchMove) {
EXPECT_EQ(expected, actual); EXPECT_EQ(expected, actual);
} }
TEST(Gen, Just) {
{
int x = 3;
auto j = just(x);
EXPECT_EQ(&x, j | indirect | first);
x = 4;
EXPECT_EQ(4, j | first);
}
{
int x = 3;
const int& cx = x;
auto j = just(cx);
EXPECT_EQ(&x, j | indirect | first);
x = 5;
EXPECT_EQ(5, j | first);
}
{
int x = 3;
auto j = just(std::move(x));
EXPECT_NE(&x, j | indirect | first);
x = 5;
EXPECT_EQ(3, j | first);
}
}
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
testing::InitGoogleTest(&argc, argv); testing::InitGoogleTest(&argc, argv);
gflags::ParseCommandLineFlags(&argc, &argv, true); gflags::ParseCommandLineFlags(&argc, &argv, true);
......
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