You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by ar...@apache.org on 2018/03/14 17:10:15 UTC

[5/8] mesos git commit: Added lambda::zip.

Added lambda::zip.

Introduces the abstractions `lambda::zip` and `lambda::zipto` which
provides a functionality similar to python's  `zip()` call.

This patch supersedes the stalled review
https://reviews.apache.org/r/63292/.

Review: https://reviews.apache.org/r/65310/


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/28a20bab
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/28a20bab
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/28a20bab

Branch: refs/heads/master
Commit: 28a20babdb2f6bb044ff4b142713507e787b38fe
Parents: ea9470c
Author: Alexander Rojas <al...@mesosphere.io>
Authored: Thu Jan 25 16:10:10 2018 +0100
Committer: Alexander Rojas <al...@mesosphere.io>
Committed: Wed Mar 14 18:09:20 2018 +0100

----------------------------------------------------------------------
 3rdparty/stout/include/stout/lambda.hpp | 73 ++++++++++++++++++++++++++++
 3rdparty/stout/tests/lambda_tests.cpp   | 30 +++++++++++-
 2 files changed, 102 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/28a20bab/3rdparty/stout/include/stout/lambda.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/stout/include/stout/lambda.hpp b/3rdparty/stout/include/stout/lambda.hpp
index c9212be..252de89 100644
--- a/3rdparty/stout/include/stout/lambda.hpp
+++ b/3rdparty/stout/include/stout/lambda.hpp
@@ -24,6 +24,7 @@
 
 #include <stout/cpp14.hpp>
 #include <stout/cpp17.hpp>
+#include <stout/hashmap.hpp>
 #include <stout/result_of.hpp>
 
 namespace lambda {
@@ -163,6 +164,78 @@ std::vector<V> map(F&& f, std::initializer_list<U> input)
 }
 
 
+// TODO(arojas): Make this generic enough such that an arbitrary
+// number of inputs can be used.
+// It would be nice to be able to choose between `std::pair` and
+// `std::tuple` or other heterogeneous compilers.
+template <
+  template <typename...> class OutputIterable,
+  template <typename...> class InputIterable1,
+  template <typename...> class InputIterable2,
+  typename U1,
+  typename U2,
+  typename... U1s,
+  typename... U2s>
+OutputIterable<std::pair<U1, U2>> zipto(
+    const InputIterable1<U1, U1s...>& input1,
+    const InputIterable2<U2, U2s...>& input2)
+{
+  OutputIterable<std::pair<U1, U2>> output;
+
+  auto iterator1 = input1.begin();
+  auto iterator2 = input2.begin();
+
+  auto inserter = std::inserter(output, output.begin());
+
+  // We zip only as many elements as we can.
+  while (iterator1 != input1.end() && iterator2 != input2.end()) {
+    inserter = std::make_pair(*iterator1, *iterator2);
+    iterator1++;
+    iterator2++;
+  }
+
+  return output;
+}
+
+
+// TODO(arojas): Make this generic enough such that the output
+// container type can be parametrized, i.e. `hashmap`, `std::unordered_map`,
+// `std::map`, `std::vector<std::pair<U1, U2>`.
+// NOTE: by default we zip into a `hashmap`. See the `zip()` overload
+// for zipping into another iterable as `std::pair`.
+template <
+  template <typename...> class InputIterable1,
+  template <typename...> class InputIterable2,
+  typename U1,
+  typename U2,
+  typename... U1s,
+  typename... U2s>
+hashmap<U1, U2> zip(
+    const InputIterable1<U1, U1s...>& input1,
+    const InputIterable2<U2, U2s...>& input2)
+{
+  // TODO(benh): Use the overload of `zip()`, something like:
+  //   std::vector<std::pair<U1, U2>> vector = zip<std::vector>(input1, input2);
+  //   return hashmap<U1, U2>(
+  //     std::make_move_iterator(vector.begin()),
+  //     std::make_move_iterator(vector.end()));
+
+  hashmap<U1, U2> output;
+
+  auto iterator1 = input1.begin();
+  auto iterator2 = input2.begin();
+
+  // We zip only as many elements as we can.
+  while (iterator1 != input1.end() && iterator2 != input2.end()) {
+    output.put(*iterator1, *iterator2);
+    iterator1++;
+    iterator2++;
+  }
+
+  return output;
+}
+
+
 #define RETURN(...) -> decltype(__VA_ARGS__) { return __VA_ARGS__; }
 
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/28a20bab/3rdparty/stout/tests/lambda_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/stout/tests/lambda_tests.cpp b/3rdparty/stout/tests/lambda_tests.cpp
index 11b0343..7583257 100644
--- a/3rdparty/stout/tests/lambda_tests.cpp
+++ b/3rdparty/stout/tests/lambda_tests.cpp
@@ -10,12 +10,17 @@
 // See the License for the specific language governing permissions and
 // limitations under the License
 
+#include <list>
+#include <string>
+#include <utility>
+#include <vector>
+
 #include <gtest/gtest.h>
 
+#include <stout/hashmap.hpp>
 #include <stout/lambda.hpp>
 #include <stout/numify.hpp>
 
-
 struct OnlyMoveable
 {
   OnlyMoveable() : i(-1) {}
@@ -105,6 +110,29 @@ TEST(LambdaTest, Map)
 }
 
 
+TEST(LambdaTest, Zip)
+{
+  std::vector<int> ints = {1, 2, 3, 4, 5, 6, 7, 8};
+  std::list<std::string> strings = {"hello", "world"};
+
+  hashmap<int, std::string> zip1 = lambda::zip(ints, strings);
+
+  ASSERT_EQ(2u, zip1.size());
+  EXPECT_EQ(std::string("hello"), zip1[1]);
+  EXPECT_EQ(std::string("world"), zip1[2]);
+
+  ints = {1, 2};
+  strings = {"hello", "world", "!"};
+
+  std::vector<std::pair<int, std::string>> zip2 =
+    lambda::zipto<std::vector>(ints, strings);
+
+  ASSERT_EQ(2u, zip2.size());
+  EXPECT_EQ(std::make_pair(1, std::string("hello")), zip2.at(0));
+  EXPECT_EQ(std::make_pair(2, std::string("world")), zip2.at(1));
+}
+
+
 namespace {
 
 template <typename F, typename ...Args>