diff options
-rw-r--r-- | src/conditional/cond.h | 29 | ||||
-rw-r--r-- | src/function/apply.h | 26 | ||||
-rw-r--r-- | src/function/detail/apply.h | 8 | ||||
-rw-r--r-- | src/type.h | 3 | ||||
-rw-r--r-- | test.cc | 37 |
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< @@ -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_ @@ -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" +); |