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>> {
void foreach(Body&&) const {}
};
template<class Value>
class Just : public GenImpl<const Value&, Just<Value>> {
template <class 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,
"Just requires non-ref types");
const Value value_;
"SingleCopy requires non-ref types");
Value value_;
public:
explicit Just(Value value) : value_(std::forward<Value>(value)) {}
explicit SingleCopy(Value value) : value_(std::forward<Value>(value)) {}
template <class Handler>
bool apply(Handler&& handler) const {
......
......@@ -297,7 +297,10 @@ template<class Value>
class Empty;
template<class Value>
class Just;
class SingleReference;
template<class Value>
class SingleCopy;
/*
* Operators
......@@ -482,14 +485,19 @@ Yield generator(Source&& source) {
/*
* empty() - for producing empty sequences.
*/
template<class Value>
template <class Value>
detail::Empty<Value> empty() {
return {};
}
template<class Value>
detail::Just<Value> just(Value value) {
return detail::Just<Value>(std::move(value));
template <
class 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>> {
class Source,
class Result =
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 {
return Just(source | sink_);
}
......
......@@ -1073,6 +1073,31 @@ TEST(Gen, BatchMove) {
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[]) {
testing::InitGoogleTest(&argc, argv);
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