contains()
authorTom Jackson <tjackson@fb.com>
Wed, 16 Jan 2013 04:02:16 +0000 (20:02 -0800)
committerJordan DeLong <jdelong@fb.com>
Mon, 4 Feb 2013 17:26:26 +0000 (09:26 -0800)
Summary: TSIA

Test Plan: Unit tests

Reviewed By: tulloch@fb.com

FB internal diff: D680177

folly/experimental/Gen-inl.h
folly/experimental/Gen.h
folly/experimental/test/GenTest.cpp

index bde69792c7b9f151c99ed1191661af7ef572c922..6937fbb64ec2ad9943c7a6a3f4fad8b7773d2825 100644 (file)
@@ -1131,6 +1131,32 @@ class Sum : public Operator<Sum> {
   }
 };
 
+/**
+ * Contains - For testing whether a value matching the given value is contained
+ * in a sequence.
+ *
+ * This type should be used through the 'contains' helper method, like:
+ *
+ *   bool contained = seq(1, 10) | map(square) | contains(49);
+ */
+template<class Needle>
+class Contains : public Operator<Contains<Needle>> {
+  Needle needle_;
+ public:
+  explicit Contains(Needle needle)
+    : needle_(std::move(needle))
+  {}
+
+  template<class Source,
+           class Value,
+           class StorageType = typename std::decay<Value>::type>
+  bool compose(const GenImpl<Value, Source>& source) const {
+    return !(source | [this](Value value) {
+        return !(needle_ == std::forward<Value>(value));
+      });
+  }
+};
+
 /**
  * Min - For a value which minimizes a key, where the key is determined by a
  * given selector, and compared by given comparer.
index 4583af491b88a2f9472bd6f78bf73093870ffa7c..8d23e1ab3542bb1edac5b2cfeacbeec55fc2e5a6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2012 Facebook, Inc.
+ * Copyright 2013 Facebook, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -245,6 +245,9 @@ class Append;
 template<class Value>
 class GeneratorBuilder {};
 
+template<class Needle>
+class Contains;
+
 }
 
 /**
@@ -430,6 +433,12 @@ Append appendTo(Collection& collection) {
   return Append(&collection);
 }
 
+template<class Needle,
+         class Contains = detail::Contains<typename std::decay<Needle>::type>>
+Contains contains(Needle&& needle) {
+  return Contains(std::forward<Needle>(needle));
+}
+
 }} // folly::gen
 
 #include "folly/experimental/Gen-inl.h"
index de2e4afbebe63a099daa330afb99e65c64877f32..a4d1a77eef422f5f4ebbba98f08774412516bfe0 100644 (file)
@@ -144,6 +144,25 @@ TEST(Gen, Filter) {
   EXPECT_EQ(expected, actual);
 }
 
+TEST(Gen, Contains) {
+  {
+    auto gen =
+        seq(1, 9)
+      | map(square);
+    EXPECT_TRUE(gen | contains(49));
+    EXPECT_FALSE(gen | contains(50));
+  }
+  {
+    auto gen =
+        seq(1) // infinite, to prove laziness
+      | map(square)
+      | eachTo<std::string>();
+
+    // std::string gen, const char* needle
+    EXPECT_TRUE(gen | contains("49"));
+  }
+}
+
 TEST(Gen, Take) {
   auto expected = vector<int>{1, 4, 9, 16};
   auto actual =