Created
December 17, 2013 16:47
-
-
Save splinterofchaos/8008127 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/include/ftl/function.h b/include/ftl/function.h | |
index 1911efa..c9ccc54 100644 | |
--- a/include/ftl/function.h | |
+++ b/include/ftl/function.h | |
@@ -350,13 +350,30 @@ namespace ftl { | |
template<typename R, typename P1, typename P2, typename...Ps> | |
struct curried<R,P1,P2,Ps...> { | |
- | |
- function<R(P2,Ps...)> operator() (P1 p1) const { | |
+ private: | |
+ /// Apply one argument. | |
+ using applied_type = function<R(P2,Ps...)>; | |
+ applied_type apply_one(P1 p1) const { | |
auto self = *reinterpret_cast<const function<R(P1,P2,Ps...)>*>(this); | |
return [self,p1] (P2 p2, Ps...ps) { | |
return self.operator()(p1, std::forward<P2>(p2), std::forward<Ps>(ps)...); | |
- }; | |
+ }; | |
+ } | |
+ public: | |
+ function<R(P2,Ps...)> operator() (P1 p1) const { | |
+ return apply_one(std::move(p1)); | |
} | |
+ | |
+ // Apply each argument, return a new function. | |
+ // If the number of arguments equals the function's arity, | |
+ // ftl::function::operator() will be called instead. | |
+ template<typename...Ps2> | |
+ auto operator()(P1 p1, P2 p2, Ps2...ps2) const | |
+ -> typename std::result_of<applied_type(P2,Ps2...)>::type | |
+ { | |
+ applied_type g = apply_one(std::move(p1)); | |
+ return g(std::move(p2),std::move(ps2)...); | |
+ } | |
}; | |
} | |
diff --git a/tests/functional_tests.cpp b/tests/functional_tests.cpp | |
index 1834e4b..e40b79b 100644 | |
--- a/tests/functional_tests.cpp | |
+++ b/tests/functional_tests.cpp | |
@@ -38,7 +38,10 @@ test_set functional_tests{ | |
ftl::function<int(int,int,int)> g = | |
[](int x, int y, int z){ return x + y + z; }; | |
- return f(1)(2) == 3 && g(1)(2,3) == 6; | |
+ return f(1)(2) == 3 | |
+ && g(1)(2,3) == g(1,2)(3) | |
+ && g(1)(2)(3) == g(1,2,3) | |
+ && g(1,2,3) == 6; | |
}) | |
), | |
std::make_tuple( | |
lines 1-54/54 (END) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment