aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Kummerlaender2015-01-25 20:35:38 +0100
committerAdrian Kummerlaender2015-01-25 20:35:38 +0100
commit8b6de4c8c89d31c5d0e16548767ef21f242aadd1 (patch)
tree021f5dc4b7c72114614bdfe38065ad962ec5d4f9
parent4f2aa4218ec63107b4624e576ff391c2019690a1 (diff)
downloadTypeAsValue-8b6de4c8c89d31c5d0e16548767ef21f242aadd1.tar
TypeAsValue-8b6de4c8c89d31c5d0e16548767ef21f242aadd1.tar.gz
TypeAsValue-8b6de4c8c89d31c5d0e16548767ef21f242aadd1.tar.bz2
TypeAsValue-8b6de4c8c89d31c5d0e16548767ef21f242aadd1.tar.lz
TypeAsValue-8b6de4c8c89d31c5d0e16548767ef21f242aadd1.tar.xz
TypeAsValue-8b6de4c8c89d31c5d0e16548767ef21f242aadd1.tar.zst
TypeAsValue-8b6de4c8c89d31c5d0e16548767ef21f242aadd1.zip
Implemented partial function application prototype
* function `Apply` enables partial supply of the template parameters of a given _function_ ** unsupplied parameters may be marked by _placeholders_, i.e. approach is similar to `std::bind` ** returns a template type taking the remaining, unsupplied parameters of the partially applied _function_ * this is a prototype in the sense, that neither full application using `Apply` or partial application of higher order functions is currently supported ** e.g. a `single_type` alias type declaration is required as the variadic template `template<typename...>` doesn't directly map to `template<typename>` * appropriate test cases document current feature set * the goal is to enable a concise defintion of _lambda-like_ expressions for easy specialization of e.g. functors provided to higher order functions
-rw-r--r--src/function/apply.h64
-rw-r--r--test.cc23
2 files changed, 87 insertions, 0 deletions
diff --git a/src/function/apply.h b/src/function/apply.h
new file mode 100644
index 0000000..d353169
--- /dev/null
+++ b/src/function/apply.h
@@ -0,0 +1,64 @@
+#ifndef TYPEASVALUE_SRC_FUNCTION_APPLY_H_
+#define TYPEASVALUE_SRC_FUNCTION_APPLY_H_
+
+#include <type_traits>
+
+namespace tav {
+
+namespace detail {
+
+struct placeholder_tag { };
+
+template <typename Type>
+using is_placeholder = tav::Boolean<
+ std::is_base_of<placeholder_tag, Type>::value
+>;
+
+template <int Index>
+struct placeholder : placeholder_tag { };
+
+template <
+ typename Partials,
+ typename Argument
+>
+struct resolve_placeholder {
+ typedef Argument type;
+};
+
+template <
+ typename Partials,
+ int Index
+>
+struct resolve_placeholder<Partials, placeholder<Index>> {
+ typedef typename Nth<Size<Index>, Partials>::type type;
+};
+
+}
+
+typedef detail::placeholder<0> _0;
+typedef detail::placeholder<1> _1;
+typedef detail::placeholder<2> _2;
+typedef detail::placeholder<3> _3;
+
+template <
+ template<typename...> class Function,
+ typename... Arguments
+>
+struct Apply {
+ typedef typename tav::List<Arguments...>::type argument_list;
+
+ template <typename... Partials>
+ using type = Function<
+ typename detail::resolve_placeholder<
+ typename tav::List<Partials...>::type,
+ Arguments
+ >::type...
+ >;
+
+ template <typename Partials>
+ using single_type = type<Partials>;
+};
+
+}
+
+#endif // TYPEASVALUE_SRC_FUNCTION_APPLY_H_
diff --git a/test.cc b/test.cc
index 62c6f85..6f95ca9 100644
--- a/test.cc
+++ b/test.cc
@@ -14,6 +14,8 @@
#include "list/generator/make_list.h"
#include "list/generator/higher/list_tabulate.h"
+#include "function/apply.h"
+
int main(int, char **) { }
// equality
@@ -631,3 +633,24 @@ static_assert(
>::value,
"(count even? (list 1 3 5)) != 0"
);
+
+// function apply
+
+static_assert(
+ std::is_same<
+ tav::Int<42>,
+ tav::Apply<tav::Multiply, tav::Int<21>, tav::_0>::type<tav::Int<2>>::type
+ >::value,
+ "((lambda (x) (* 21 x)) 2) != 42"
+);
+
+static_assert(
+ std::is_same<
+ tav::List<tav::Int<10>, tav::Int<12>, tav::Int<14>>::type,
+ tav::Map<
+ tav::Apply<tav::Add, tav::_0, tav::Int<10>>::single_type,
+ tav::List<tav::Int<0>, tav::Int<2>, tav::Int<4>>::type
+ >::type
+ >::value,
+ "(map (lambda (x) (+ x 10)) (list 0 2 4)) != (list 10 12 14)"
+);