From 27aaee43499c268903332c7e9e1e6ec2d193dc3a Mon Sep 17 00:00:00 2001 From: Adrian Kummerlaender Date: Fri, 6 Feb 2015 19:26:26 +0100 Subject: Revamped to use `Cons` as a function and `Pair` as its result * this is analogous to _Scheme_ where a pair (dot-expression) is returned from a call to `cons` * `Head` and `Tail` are kept as direct references to the `CAR` and `CDR` values of a pair to match e.g. the math operators --- example/prime/prime.cc | 4 ++-- src/list/cons.h | 27 +++++++++++++++++++++------ src/list/generator/iota.h | 6 +++--- src/list/generator/make_list.h | 6 +++--- src/list/list.h | 10 +++++----- src/list/operation/append.h | 4 ++-- src/list/operation/basic.h | 4 ++-- src/list/operation/higher/filter.h | 2 +- src/list/operation/higher/map.h | 10 ++++------ src/list/operation/higher/partition.h | 10 ++++------ src/list/operation/higher/take_while.h | 4 ++-- src/list/operation/nth.h | 10 +++++----- src/list/operation/reverse.h | 2 +- src/list/operation/take.h | 4 ++-- src/pair.h | 26 ++++++++++++++++++++++++++ src/runtime/list/for_each.h | 2 +- test.cc | 28 ++++++++++++++-------------- 17 files changed, 98 insertions(+), 61 deletions(-) create mode 100644 src/pair.h diff --git a/example/prime/prime.cc b/example/prime/prime.cc index 93b7db5..17d437c 100644 --- a/example/prime/prime.cc +++ b/example/prime/prime.cc @@ -31,7 +31,7 @@ using removeMultiplesOf = tav::Remove< template struct Sieve { - typedef tav::Cons< + typedef typename tav::Cons< tav::Head, typename Sieve< typename removeMultiplesOf< @@ -39,7 +39,7 @@ struct Sieve { tav::Head >::type >::type - > type; + >::type type; }; template <> diff --git a/src/list/cons.h b/src/list/cons.h index b858c4c..7f54eb5 100644 --- a/src/list/cons.h +++ b/src/list/cons.h @@ -1,6 +1,8 @@ #ifndef TYPEASVALUE_SRC_LIST_CONS_H_ #define TYPEASVALUE_SRC_LIST_CONS_H_ +#include "pair.h" + namespace tav { template < @@ -8,15 +10,28 @@ template < typename CDR > struct Cons { - typedef CAR car; - typedef CDR cdr; + typedef Pair type; }; -template -using Car = typename Cons::car; +template +struct Car { + static_assert( + IsPair::type::value, + "Pair type required" + ); + + typedef typename Pair::car type; +}; -template -using Cdr = typename Cons::cdr; +template +struct Cdr { + static_assert( + IsPair::type::value, + "Pair type required" + ); + + typedef typename Pair::cdr type; +}; } diff --git a/src/list/generator/iota.h b/src/list/generator/iota.h index 54f0f40..2d5b506 100644 --- a/src/list/generator/iota.h +++ b/src/list/generator/iota.h @@ -11,14 +11,14 @@ template < typename Step > struct Iota { - typedef Cons< + typedef typename Cons< Initial, typename Iota< Substract>, Add, Step >::type - > type; + >::type type; }; template < @@ -26,7 +26,7 @@ template < typename Step > struct Iota, Initial, Step> { - typedef Cons type; + typedef typename Cons::type type; }; } diff --git a/src/list/generator/make_list.h b/src/list/generator/make_list.h index 3bf65a2..33419cb 100644 --- a/src/list/generator/make_list.h +++ b/src/list/generator/make_list.h @@ -11,18 +11,18 @@ template < typename Element > struct MakeList { - typedef Cons< + typedef typename Cons< Element, typename MakeList< Substract>, Element >::type - > type; + >::type type; }; template struct MakeList, Element> { - typedef Cons type; + typedef typename Cons::type type; }; } diff --git a/src/list/list.h b/src/list/list.h index 66394fc..2e335e2 100644 --- a/src/list/list.h +++ b/src/list/list.h @@ -10,15 +10,15 @@ template < typename... Tail > struct List { - typedef Cons< + typedef typename Cons< Head, typename List::type - > type; + >::type type; }; template struct List { - typedef Cons type; + typedef typename Cons::type type; }; template < @@ -30,10 +30,10 @@ using ListOfType = List< >; template -using Head = Car; +using Head = typename Car::type; template -using Tail = Cdr; +using Tail = typename Cdr::type; } diff --git a/src/list/operation/append.h b/src/list/operation/append.h index 9e1be79..6cf15f0 100644 --- a/src/list/operation/append.h +++ b/src/list/operation/append.h @@ -8,13 +8,13 @@ template < typename Secondary > struct Append { - typedef Cons< + typedef typename Cons< Head, typename Append< Tail, Secondary >::type - > type; + >::type type; }; template diff --git a/src/list/operation/basic.h b/src/list/operation/basic.h index 1f4b043..cbbe22c 100644 --- a/src/list/operation/basic.h +++ b/src/list/operation/basic.h @@ -7,11 +7,11 @@ namespace tav { -template +template using Length = Fold< Apply, _1>::pair_type, Size<0>, - Cons + Pair >; } diff --git a/src/list/operation/higher/filter.h b/src/list/operation/higher/filter.h index 3fc08ee..acc1422 100644 --- a/src/list/operation/higher/filter.h +++ b/src/list/operation/higher/filter.h @@ -18,7 +18,7 @@ class Filter { > using predicate_wrapper = If< Predicate::type::value, - Cons, + typename Cons::type, Previous >; diff --git a/src/list/operation/higher/map.h b/src/list/operation/higher/map.h index a451b2a..9cb6524 100644 --- a/src/list/operation/higher/map.h +++ b/src/list/operation/higher/map.h @@ -15,12 +15,10 @@ class Map { typename Current, typename Previous > - struct function_wrapper { - typedef Cons< - typename Function::type, - Previous - > type; - }; + using function_wrapper = Cons< + typename Function::type, + Previous + >; public: typedef typename Fold::type type; diff --git a/src/list/operation/higher/partition.h b/src/list/operation/higher/partition.h index e42b971..a0ea379 100644 --- a/src/list/operation/higher/partition.h +++ b/src/list/operation/higher/partition.h @@ -9,12 +9,10 @@ template < template class Predicate, typename List > -struct Partition { - typedef Cons< - typename Filter::type, - typename Remove::type - > type; -}; +using Partition = Cons< + typename Filter::type, + typename Remove::type +>; } diff --git a/src/list/operation/higher/take_while.h b/src/list/operation/higher/take_while.h index 27f58ed..d04dc2d 100644 --- a/src/list/operation/higher/take_while.h +++ b/src/list/operation/higher/take_while.h @@ -12,10 +12,10 @@ template < struct TakeWhile { typedef typename If< Predicate>::type::value, - Cons< + typename Cons< Head, typename TakeWhile>::type - >, + >::type, void >::type type; }; diff --git a/src/list/operation/nth.h b/src/list/operation/nth.h index 8eb88ba..6020dcb 100644 --- a/src/list/operation/nth.h +++ b/src/list/operation/nth.h @@ -7,18 +7,18 @@ namespace tav { template < typename Index, - typename Cons + typename Pair > struct Nth { typedef typename Nth< Substract>, - Tail + Tail >::type type; }; -template -struct Nth, Cons> { - typedef Head type; +template +struct Nth, Pair> { + typedef Head type; }; template diff --git a/src/list/operation/reverse.h b/src/list/operation/reverse.h index 632fa5b..83691f8 100644 --- a/src/list/operation/reverse.h +++ b/src/list/operation/reverse.h @@ -16,7 +16,7 @@ class Reverse { struct reversed_append { typedef typename Append< Previous, - Cons + typename Cons::type >::type type; }; diff --git a/src/list/operation/take.h b/src/list/operation/take.h index db25640..c396c28 100644 --- a/src/list/operation/take.h +++ b/src/list/operation/take.h @@ -10,13 +10,13 @@ template < typename Current > struct Take { - typedef Cons< + typedef typename Cons< Head, typename Take< Substract>, Tail >::type - > type; + >::type type; }; template diff --git a/src/pair.h b/src/pair.h new file mode 100644 index 0000000..20bef4e --- /dev/null +++ b/src/pair.h @@ -0,0 +1,26 @@ +#ifndef TYPEASVALUE_SRC_PAIR_H_ +#define TYPEASVALUE_SRC_PAIR_H_ + +#include + +namespace tav { + +namespace detail { struct pair_tag { }; } + +template < + typename CAR, + typename CDR +> +struct Pair : detail::pair_tag { + typedef CAR car; + typedef CDR cdr; + + typedef Pair type; +}; + +template +using IsPair = std::is_base_of; + +} + +#endif // TYPEASVALUE_SRC_PAIR_H_ diff --git a/src/runtime/list/for_each.h b/src/runtime/list/for_each.h index 8986135..1ca2034 100644 --- a/src/runtime/list/for_each.h +++ b/src/runtime/list/for_each.h @@ -21,7 +21,7 @@ template < typename std::enable_if::value, std::size_t>::type = 0 > void for_each(const Function& function) { - function(Head::value); + function(Head::type::value); for_each, Function>(function); } diff --git a/test.cc b/test.cc index da3193f..9037e25 100644 --- a/test.cc +++ b/test.cc @@ -189,8 +189,8 @@ static_assert( std::is_same< tav::Int<1>, tav::Car< - tav::Cons, void> - > + tav::Cons, void>::type + >::type >::value, "(car (cons 1 void)) != 1" ); @@ -199,8 +199,8 @@ static_assert( std::is_same< tav::Int<1>, tav::Car< - tav::Cons, tav::Int<2>> - > + tav::Cons, tav::Int<2>>::type + >::type >::value, "(car (cons 1 2)) != 1" ); @@ -209,8 +209,8 @@ static_assert( std::is_same< tav::Int<2>, tav::Cdr< - tav::Cons, tav::Int<2>> - > + tav::Cons, tav::Int<2>>::type + >::type >::value, "(cdr (cons 1 2)) != 2" ); @@ -220,9 +220,9 @@ static_assert( tav::Int<2>, tav::Car< tav::Cdr< - tav::Cons, tav::Cons, tav::Int<3>>> - > - > + tav::Cons, tav::Cons, tav::Int<3>>::type>::type + >::type + >::type >::value, "(car (cdr (cons 1 (cons 2 3)))) != 2" ); @@ -231,7 +231,7 @@ static_assert( static_assert( std::is_same< - tav::Cons, void>, + tav::Pair, void>, tav::List>::type >::value, "(list 1) != (cons 1 void)" @@ -239,7 +239,7 @@ static_assert( static_assert( std::is_same< - tav::Cons, tav::Cons, void>>, + tav::Pair, tav::Pair, void>>, tav::List, tav::Int<2>>::type >::value, "(list 1 2) != (cons 1 (cons 2 void))" @@ -249,7 +249,7 @@ static_assert( static_assert( std::is_same< - tav::Cons, void>, + tav::Pair, void>, tav::ListOfType::type >::value, "(list 1) != (cons 1 void)" @@ -257,7 +257,7 @@ static_assert( static_assert( std::is_same< - tav::Cons, tav::Cons, void>>, + tav::Pair, tav::Pair, void>>, tav::ListOfType::type >::value, "(list 1 2) != (cons 1 (cons 2 void))" @@ -463,7 +463,7 @@ static_assert( static_assert( std::is_same< - tav::Cons< + tav::Pair< tav::List, tav::Int<3>>::type, tav::List>::type >, -- cgit v1.2.3