Explorar o código

Adding collect to fluent stream
Adding test suite, mirroring the other stream.t.h, but using the fluent interface.

Samuel Jaffe %!s(int64=8) %!d(string=hai) anos
pai
achega
dc8ba3ef47
Modificáronse 3 ficheiros con 95 adicións e 5 borrados
  1. 4 1
      stream.xcodeproj/project.pbxproj
  2. 83 0
      stream_fluent.t.h
  3. 8 4
      streams/fluent.hpp

+ 4 - 1
stream.xcodeproj/project.pbxproj

@@ -34,6 +34,7 @@
 		CD9337281E3CD78B00699FF5 /* stream.t.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = stream.t.h; sourceTree = "<group>"; };
 		CD93372D1E3CD79E00699FF5 /* stream_tc */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = stream_tc; sourceTree = BUILT_PRODUCTS_DIR; };
 		CDF9374C1E3D81D4003E5D5C /* fluent.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = fluent.hpp; sourceTree = "<group>"; };
+		CDF9374E1E3D9AD7003E5D5C /* stream_fluent.t.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = stream_fluent.t.h; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
@@ -83,6 +84,7 @@
 			children = (
 				CD9337271E3CD78B00699FF5 /* stream_tc.cpp */,
 				CD9337281E3CD78B00699FF5 /* stream.t.h */,
+				CDF9374E1E3D9AD7003E5D5C /* stream_fluent.t.h */,
 			);
 			name = test;
 			sourceTree = "<group>";
@@ -155,13 +157,14 @@
 			);
 			inputPaths = (
 				"$(SRCROOT)/stream.t.h",
+				"$(SRCROOT)/stream_fluent.t.h",
 			);
 			outputPaths = (
 				"$(SRCROOT)/stream_tc.cpp",
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
-			shellScript = "cxxtestgen --error-printer -o stream_tc.cpp stream.t.h";
+			shellScript = "cxxtestgen --error-printer -o stream_tc.cpp stream.t.h stream_fluent.t.h";
 		};
 /* End PBXShellScriptBuildPhase section */
 

+ 83 - 0
stream_fluent.t.h

@@ -0,0 +1,83 @@
+//
+//  stream_fluent.t.h
+//  stream
+//
+//  Created by Sam Jaffe on 1/28/17.
+//
+
+#pragma once
+
+#include <cxxtest/TestSuite.h>
+
+#include <vector>
+
+#include "streams.hpp"
+#include "streams/fluent.hpp"
+
+
+class stream_fluent_TestSuite : public CxxTest::TestSuite {
+public:
+  using int_t = int const &;
+  using vec_t = std::vector<int>;
+public:
+  void test_collect_arg_preserves() {
+    vec_t v{1, 2, 3, 4, 5};
+    auto s = stream::make_stream(v);
+    std::set<int> o{};
+    s > o;
+    for ( int i : v ) {
+      TS_ASSERT_EQUALS(o.count( i ), 1);
+    }
+  }
+  
+  void test_map_identity() {
+    vec_t v{1, 2, 3, 4, 5};
+    auto identity = [](int_t i) { return i; };
+    auto s = stream::make_stream(v) | stream::map<int, int>( identity );
+    vec_t o{s.begin(), s.end()};
+    TS_ASSERT_EQUALS(v, o);
+  }
+  
+  void test_map_change() {
+    vec_t v{1, 2, 3, 4, 5};
+    vec_t expected{3, 5, 7, 9, 11};
+    auto fmap = [](int_t i) { return 2*i+1; };
+    auto s = stream::make_stream(v) | stream::map<int, int>( fmap );
+    vec_t o{s.begin(), s.end()};
+    TS_ASSERT_EQUALS(expected, o);
+  }
+  
+  void test_filter_noop() {
+    vec_t v{1, 2, 3, 4, 5};
+    auto pass = [](int_t i) { return true; };
+    auto s = stream::make_stream(v) | stream::filter<int>( pass );
+    vec_t o{s.begin(), s.end()};
+    TS_ASSERT_EQUALS(v, o);
+  }
+  
+  void test_filter_value() {
+    vec_t v{1, 2, 3, 4, 5};
+    vec_t expected{2, 4};
+    auto even = [](int_t i) { return i%2 == 0; };
+    auto s = stream::make_stream(v) | stream::filter<int>( even );
+    vec_t o{s.begin(), s.end()};
+    TS_ASSERT_EQUALS(expected, o);
+  }
+  
+  void test_accumulate() {
+    vec_t v{1, 2, 3, 4, 5};
+    auto even = [](int_t i) { return i%2 == 0; };
+    auto sum =[](int_t lhs, int_t rhs) { return lhs + rhs; };
+    auto s = stream::make_stream(v) | stream::filter<int>( even );
+    TS_ASSERT_EQUALS( 6 , s > stream::fold_left<int>(sum) );
+  }
+  
+  void test_flatmap_joins_lists() {
+    vec_t vv{1, 2, 3, 4, 5};
+    auto next3 = [](int_t i) { return vec_t{i, i+1, i+2}; };
+    vec_t expected{1, 2, 3, 2, 3, 4, 3, 4, 5, 4, 5, 6, 5, 6, 7};
+    auto s = stream::make_stream(vv) | stream::flatmap<int, vec_t>( next3 );
+    vec_t o{s.begin(), s.end()};
+    TS_ASSERT_EQUALS(expected, o);
+  }
+};

+ 8 - 4
streams/fluent.hpp

@@ -33,12 +33,10 @@ namespace stream {
     std::function<bool(const T&)> pred;
   };
 
-  template <typename L, typename R>
+  template <typename L, typename R = L>
   struct fold_left {
     template <typename F>
-    explicit fold_left(F&& f) : init(), fold(f) {}
-    template <typename F>
-    fold_left(L const & i, F&& f) : init(i), fold(f) {}
+    explicit fold_left(F&& f, L const & i = L()) : init(i), fold(f) {}
     L init;
     std::function<L(const L&, const R&)> fold;
   };
@@ -64,4 +62,10 @@ namespace stream { namespace detail {
   L operator >(stream_base<R> const &s, ::stream::fold_left<L, R> && f) {
     return std::accumulate(s.begin(), s.end(), f.init, f.fold);
   }
+  
+  template <typename T, typename C>
+  C & operator >(stream_base<T> const & s, C & c) {
+    s.collect(c);
+    return c;
+  }
 } }