aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/conditional/cond.h29
-rw-r--r--src/function/apply.h26
-rw-r--r--src/function/detail/apply.h8
-rw-r--r--src/type.h3
-rw-r--r--test.cc37
5 files changed, 95 insertions, 8 deletions
diff --git a/src/conditional/cond.h b/src/conditional/cond.h
new file mode 100644
index 0000000..0c2b1a8
--- /dev/null
+++ b/src/conditional/cond.h
@@ -0,0 +1,29 @@
+#ifndef TYPEASVALUE_SRC_CONDITIONAL_COND_H_
+#define TYPEASVALUE_SRC_CONDITIONAL_COND_H_
+
+#include <type_traits>
+
+#include "list/list.h"
+#include "list/operation/higher/find.h"
+
+namespace tav {
+
+template <typename... Branches>
+class Cond {
+ private:
+ template <typename Pair>
+ using predicate = IsTrue<typename Car<Pair>::type::type>;
+
+ public:
+ typedef typename Cdr<
+ typename Find<
+ predicate,
+ typename List<Branches...>::type
+ >::type
+ >::type type;
+
+};
+
+}
+
+#endif // TYPEASVALUE_SRC_CONDITIONAL_COND_H_
diff --git a/src/function/apply.h b/src/function/apply.h
index 21364a8..5a2105c 100644
--- a/src/function/apply.h
+++ b/src/function/apply.h
@@ -1,7 +1,8 @@
#ifndef TYPEASVALUE_SRC_FUNCTION_APPLY_H_
#define TYPEASVALUE_SRC_FUNCTION_APPLY_H_
-#include "conditional/if.h"
+#include "operation/math.h"
+#include "conditional/cond.h"
#include "detail/apply.h"
@@ -16,14 +17,23 @@ template <
template<typename...> class Function,
typename... Arguments
>
-struct Apply : If<
- (detail::count_placeholders<Arguments...>::type::value > 2),
- detail::apply_variadic<Function, Arguments...>,
- typename If<
- detail::count_placeholders<Arguments...>::type::value == 2,
- detail::apply_pair<Function, Arguments...>,
+struct Apply : Cond<
+ Pair<
+ GreaterThan<typename detail::count_placeholders<Arguments...>::type, Size<2>>,
+ detail::apply_variadic<Function, Arguments...>
+ >,
+ Pair<
+ IsEqualValue<typename detail::count_placeholders<Arguments...>::type, Size<2>>,
+ detail::apply_pair<Function, Arguments...>
+ >,
+ Pair<
+ IsEqualValue<typename detail::count_placeholders<Arguments...>::type, Size<1>>,
detail::apply_single<Function, Arguments...>
- >::type
+ >,
+ Pair<
+ Boolean<true>,
+ detail::apply_none<Function, Arguments...>
+ >
>::type { };
}
diff --git a/src/function/detail/apply.h b/src/function/detail/apply.h
index bf60be1..d9f058a 100644
--- a/src/function/detail/apply.h
+++ b/src/function/detail/apply.h
@@ -46,6 +46,14 @@ template <
template<typename...> class Function,
typename... Arguments
>
+struct apply_none {
+ using type = Function<Arguments...>;
+};
+
+template <
+ template<typename...> class Function,
+ typename... Arguments
+>
struct apply_variadic {
template <typename... Partials>
using type = Function<
diff --git a/src/type.h b/src/type.h
index c175c36..15ba2f8 100644
--- a/src/type.h
+++ b/src/type.h
@@ -32,6 +32,9 @@ template <
>
using IsEqualValue = Boolean<X::value == Y::value>;
+template <typename X>
+using IsTrue = IsEqualValue<X, Boolean<true>>;
+
}
#endif // TYPEASVALUE_SRC_TYPE_H_
diff --git a/test.cc b/test.cc
index e89fcb1..db19889 100644
--- a/test.cc
+++ b/test.cc
@@ -233,6 +233,31 @@ static_assert(
"(if #f 1 2) != 2"
);
+static_assert(
+ std::is_same<
+ tav::Int<2>,
+ tav::Cond<
+ tav::Pair<tav::IsEqualValue<tav::Int<1>, tav::Int<2>>, tav::Int<1>>,
+ tav::Pair<tav::IsEqualValue<tav::Int<2>, tav::Int<2>>, tav::Int<2>>,
+ tav::Pair<tav::IsEqualValue<tav::Int<3>, tav::Int<2>>, tav::Int<3>>
+ >::type
+ >::value,
+ "(cond ((= 1 2) 1) ((= 2 2) 2) ((= 3 2) 3)) != 2"
+);
+
+static_assert(
+ std::is_same<
+ tav::Int<-1>,
+ tav::Cond<
+ tav::Pair<tav::IsEqualValue<tav::Int<1>, tav::Int<2>>, tav::Int< 1>>,
+ tav::Pair<tav::IsEqualValue<tav::Int<2>, tav::Int<3>>, tav::Int< 2>>,
+ tav::Pair<tav::IsEqualValue<tav::Int<3>, tav::Int<4>>, tav::Int< 3>>,
+ tav::Pair<tav::Boolean<true>, tav::Int<-1>>
+ >::type
+ >::value,
+ "(cond ((= 1 2) 1) ((= 2 3) 2) ((= 3 4) 3) (else -1)) != -1"
+);
+
// cons
static_assert(
@@ -1020,3 +1045,15 @@ static_assert(
>::value,
"(map (lambda (x) (+ x 10)) (list 0 2 4)) != (list 10 12 14)"
);
+
+static_assert(
+ std::is_same<
+ tav::Int<42>,
+ tav::Apply<
+ tav::Multiply,
+ tav::Int<21>,
+ tav::Int<2>
+ >::type::type
+ >::value,
+ "(* 21 2) != 42"
+);