Prevent accidental moves in filter()
authorTom Jackson <tjackson@fb.com>
Tue, 18 Aug 2015 19:52:16 +0000 (12:52 -0700)
committerfacebook-github-bot-4 <folly-bot@fb.com>
Tue, 18 Aug 2015 20:20:24 +0000 (13:20 -0700)
Summary: Per Boris's report.

Reviewed By: @yfeldblum

Differential Revision: D2357299

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

index 0c4e92f4556959aff2f6a17d994eb595e86c9ae3..23b919735a52ec5c8547aff4c979a12376315bed 100644 (file)
@@ -559,7 +559,8 @@ class Filter : public Operator<Filter<Predicate>> {
     template <class Body>
     void foreach(Body&& body) const {
       source_.foreach([&](Value value) {
-        if (pred_(std::forward<Value>(value))) {
+        // NB: Argument not forwarded to avoid accidental move-construction
+        if (pred_(value)) {
           body(std::forward<Value>(value));
         }
       });
@@ -568,7 +569,8 @@ class Filter : public Operator<Filter<Predicate>> {
     template <class Handler>
     bool apply(Handler&& handler) const {
       return source_.apply([&](Value value) -> bool {
-        if (pred_(std::forward<Value>(value))) {
+        // NB: Argument not forwarded to avoid accidental move-construction
+        if (pred_(value)) {
           return handler(std::forward<Value>(value));
         }
         return true;
index 7741b053fb52695f72ccdae8d67e1269eac7122d..e97cf6c39db9f482f87e64965a03907162aabb38 100644 (file)
@@ -289,6 +289,15 @@ TEST(Gen, FilterDefault) {
   }
 }
 
+TEST(Gen, FilterSink) {
+  auto actual
+    = seq(1, 2)
+    | map([](int x) { return vector<int>{x}; })
+    | filter([](vector<int> v) { return !v.empty(); })
+    | as<vector>();
+  EXPECT_FALSE(from(actual) | rconcat | isEmpty);
+}
+
 TEST(Gen, Contains) {
   {
     auto gen =