From 117c33c3875216ef925c214bca91e362180a7ccc Mon Sep 17 00:00:00 2001 From: Tom Jackson Date: Wed, 11 Feb 2015 15:42:11 -0800 Subject: [PATCH] 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 --- folly/gen/Base-inl.h | 29 ++++++++++++++++++++++++----- folly/gen/Base.h | 18 +++++++++++++----- folly/gen/Parallel-inl.h | 2 +- folly/gen/test/BaseTest.cpp | 25 +++++++++++++++++++++++++ 4 files changed, 63 insertions(+), 11 deletions(-) diff --git a/folly/gen/Base-inl.h b/folly/gen/Base-inl.h index 083cf979..d4b68ebf 100644 --- a/folly/gen/Base-inl.h +++ b/folly/gen/Base-inl.h @@ -328,13 +328,32 @@ class Empty : public GenImpl> { void foreach(Body&&) const {} }; -template -class Just : public GenImpl> { +template +class SingleReference : public GenImpl> { + static_assert(!std::is_reference::value, + "SingleReference requires non-ref types"); + Value* ptr_; + public: + explicit SingleReference(Value& ref) : ptr_(&ref) {} + + template + bool apply(Handler&& handler) const { + return handler(*ptr_); + } + + template + void foreach(Body&& body) const { + body(*ptr_); + } +}; + +template +class SingleCopy : public GenImpl> { static_assert(!std::is_reference::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)) {} + explicit SingleCopy(Value value) : value_(std::forward(value)) {} template bool apply(Handler&& handler) const { diff --git a/folly/gen/Base.h b/folly/gen/Base.h index 12d917ed..6b96097b 100644 --- a/folly/gen/Base.h +++ b/folly/gen/Base.h @@ -297,7 +297,10 @@ template class Empty; template -class Just; +class SingleReference; + +template +class SingleCopy; /* * Operators @@ -482,14 +485,19 @@ Yield generator(Source&& source) { /* * empty() - for producing empty sequences. */ -template +template detail::Empty empty() { return {}; } -template -detail::Just just(Value value) { - return detail::Just(std::move(value)); +template < + class Value, + class Just = typename std::conditional< + std::is_reference::value, + detail::SingleReference::type>, + detail::SingleCopy>::type> +Just just(Value&& value) { + return Just(std::forward(value)); } /* diff --git a/folly/gen/Parallel-inl.h b/folly/gen/Parallel-inl.h index 666acb16..06f1af01 100644 --- a/folly/gen/Parallel-inl.h +++ b/folly/gen/Parallel-inl.h @@ -136,7 +136,7 @@ class Sub : public Operator> { class Source, class Result = decltype(std::declval().compose(std::declval())), - class Just = Just::type>> + class Just = SingleCopy::type>> Just compose(const GenImpl& source) const { return Just(source | sink_); } diff --git a/folly/gen/test/BaseTest.cpp b/folly/gen/test/BaseTest.cpp index 2b99f157..33b39bf5 100644 --- a/folly/gen/test/BaseTest.cpp +++ b/folly/gen/test/BaseTest.cpp @@ -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); -- 2.34.1