diff options
author | Adrian Kummerlaender | 2015-02-17 18:55:08 +0100 |
---|---|---|
committer | Adrian Kummerlaender | 2015-02-17 18:55:08 +0100 |
commit | 8e4e3466694e5bef43f1308296a76086a7db453d (patch) | |
tree | 84049e2604341a0326e99d31cbed898fe5448d2d | |
parent | f81cd736e00c28cf24412a4099bae08ff2e6c493 (diff) | |
download | TypeAsValue-8e4e3466694e5bef43f1308296a76086a7db453d.tar TypeAsValue-8e4e3466694e5bef43f1308296a76086a7db453d.tar.gz TypeAsValue-8e4e3466694e5bef43f1308296a76086a7db453d.tar.bz2 TypeAsValue-8e4e3466694e5bef43f1308296a76086a7db453d.tar.lz TypeAsValue-8e4e3466694e5bef43f1308296a76086a7db453d.tar.xz TypeAsValue-8e4e3466694e5bef43f1308296a76086a7db453d.tar.zst TypeAsValue-8e4e3466694e5bef43f1308296a76086a7db453d.zip |
Expressed `Take` and `Drop` in terms of new `Section` operation
* unifies the common functionality between `Take` and `Drop`
* renamed `basic.h` to `length.h` as it only contains the `Length` implementation
-rw-r--r-- | src/list/generator/higher/list_tabulate.h | 2 | ||||
-rw-r--r-- | src/list/list.h | 2 | ||||
-rw-r--r-- | src/list/operation/drop.h | 41 | ||||
-rw-r--r-- | src/list/operation/higher/fold.h | 10 | ||||
-rw-r--r-- | src/list/operation/length.h (renamed from src/list/operation/basic.h) | 6 | ||||
-rw-r--r-- | src/list/operation/section.h | 76 | ||||
-rw-r--r-- | src/list/operation/take.h | 43 | ||||
-rw-r--r-- | test.cc | 132 |
8 files changed, 167 insertions, 145 deletions
diff --git a/src/list/generator/higher/list_tabulate.h b/src/list/generator/higher/list_tabulate.h index 856ed11..4ffbc02 100644 --- a/src/list/generator/higher/list_tabulate.h +++ b/src/list/generator/higher/list_tabulate.h @@ -12,7 +12,7 @@ template < > using ListTabulate = Map< Initializer, - Eval<Iota<Count, Size<0>, Size<1>>> + Iota<Count, Size<0>, Size<1>> >; } diff --git a/src/list/list.h b/src/list/list.h index edb52ec..cf4f415 100644 --- a/src/list/list.h +++ b/src/list/list.h @@ -26,7 +26,7 @@ using Tail = Cdr<Cons>; } -#include "operation/basic.h" +#include "operation/length.h" #include "operation/nth.h" #include "operation/take.h" #include "operation/drop.h" diff --git a/src/list/operation/drop.h b/src/list/operation/drop.h index c7745d7..aef88d3 100644 --- a/src/list/operation/drop.h +++ b/src/list/operation/drop.h @@ -1,45 +1,20 @@ #ifndef TYPEASVALUE_SRC_LIST_OPERATION_DROP_H_ #define TYPEASVALUE_SRC_LIST_OPERATION_DROP_H_ -#include "operation/math.h" +#include "length.h" +#include "section.h" namespace tav { -namespace detail { - -template < - typename Count, - typename Current -> -struct Drop { - typedef Eval<Drop< - Substract<Count, Size<1>>, - Tail<Current> - >> type; -}; - -template <typename Current> -struct Drop<Size<0>, Current> { - typedef Current type; -}; - -template <typename Count> -struct Drop<Count, void> { - typedef void type; -}; - -template <> -struct Drop<Size<0>, void> { - typedef void type; -}; - -} - template < typename Count, - typename Current + typename List > -using Drop = Eval<detail::Drop<Count, Current>>; +using Drop = Section< + Count, + Substract<Length<List>, Size<1>>, + List +>; } diff --git a/src/list/operation/higher/fold.h b/src/list/operation/higher/fold.h index 3f39b40..38c3554 100644 --- a/src/list/operation/higher/fold.h +++ b/src/list/operation/higher/fold.h @@ -8,12 +8,12 @@ namespace detail { template < template<typename, typename> class Function, typename Initial, - typename Current + typename Pair > struct fold_pair { typedef Function< - Head<Current>, - Eval<fold_pair<Function, Initial, Tail<Current>>> + Car<Pair>, + Eval<fold_pair<Function, Initial, Cdr<Pair>>> > type; }; @@ -30,9 +30,9 @@ struct fold_pair<Function, Initial, void> { template < template<typename, typename> class Function, typename Initial, - typename Current + typename List > -using Fold = Eval<detail::fold_pair<Function, Initial, Current>>; +using Fold = Eval<detail::fold_pair<Function, Initial, List>>; } diff --git a/src/list/operation/basic.h b/src/list/operation/length.h index d0f6212..1f609d4 100644 --- a/src/list/operation/basic.h +++ b/src/list/operation/length.h @@ -1,5 +1,5 @@ -#ifndef TYPEASVALUE_SRC_LIST_OPERATION_BASIC_H_ -#define TYPEASVALUE_SRC_LIST_OPERATION_BASIC_H_ +#ifndef TYPEASVALUE_SRC_LIST_OPERATION_LENGTH_H_ +#define TYPEASVALUE_SRC_LIST_OPERATION_LENGTH_H_ #include "higher/fold.h" #include "operation/math.h" @@ -18,4 +18,4 @@ using Length = Fold<detail::length_accumulate, Size<0>, List>; } -#endif // TYPEASVALUE_SRC_LIST_OPERATION_BASIC_H_ +#endif // TYPEASVALUE_SRC_LIST_OPERATION_LENGTH_H_ diff --git a/src/list/operation/section.h b/src/list/operation/section.h new file mode 100644 index 0000000..214c9fd --- /dev/null +++ b/src/list/operation/section.h @@ -0,0 +1,76 @@ +#ifndef TYPEASVALUE_SRC_LIST_OPERATION_SECTION_H_ +#define TYPEASVALUE_SRC_LIST_OPERATION_SECTION_H_ + +#include "operation/math.h" + +namespace tav { + +namespace detail { + +template < + typename Index, + typename Count, + typename List +> +struct take_count_at { + typedef Eval<take_count_at< + Substract<Index, Size<1>>, + Count, + Tail<List> + >> type; +}; + +template < + typename Count, + typename List +> +struct take_count_at<Size<0>, Count, List> { + typedef Cons< + Head<List>, + Eval<take_count_at< + Size<0>, + Substract<Count, Size<1>>, + Tail<List> + >> + > type; +}; + +template < + typename Index, + typename Count +> +struct take_count_at<Index, Count, void> { + typedef void type; +}; + +template <typename Count> +struct take_count_at<Size<0>, Count, void> { + typedef void type; +}; + +template <typename List> +struct take_count_at<Size<0>, Size<0>, List> { + typedef void type; +}; + +template <> +struct take_count_at<Size<0>, Size<0>, void> { + typedef void type; +}; + +} + +template < + typename Start, + typename End, + typename List +> +using Section = Eval<detail::take_count_at< + Start, + Substract<Add<End, Size<1>>, Start>, + List +>>; + +} + +#endif // TYPEASVALUE_SRC_LIST_OPERATION_SECTION_H_ diff --git a/src/list/operation/take.h b/src/list/operation/take.h index effba33..f9aa4b0 100644 --- a/src/list/operation/take.h +++ b/src/list/operation/take.h @@ -1,48 +1,19 @@ #ifndef TYPEASVALUE_SRC_LIST_OPERATION_TAKE_H_ #define TYPEASVALUE_SRC_LIST_OPERATION_TAKE_H_ -#include "operation/math.h" +#include "section.h" namespace tav { -namespace detail { - -template < - typename Count, - typename Current -> -struct Take { - typedef Cons< - Head<Current>, - Eval<Take< - Substract<Count, Size<1>>, - Tail<Current> - >> - > type; -}; - -template <typename Current> -struct Take<Size<0>, Current> { - typedef void type; -}; - -template <typename Count> -struct Take<Count, void> { - typedef void type; -}; - -template <> -struct Take<Size<0>, void> { - typedef void type; -}; - -} - template < typename Count, - typename Current + typename List > -using Take = Eval<detail::Take<Count, Current>>; +using Take = Section< + Size<0>, + Substract<Count, Size<1>>, + List +>; } @@ -359,155 +359,155 @@ static_assert( "(list 1 2) != (cons 1 (cons 2 void))" ); -// list length +// list take static_assert( std::is_same< - tav::Size<1>, - tav::Length< - tav::List<tav::Int<1>> + tav::List<tav::Int<1>>, + tav::Take< + tav::Size<1>, + tav::List<tav::Int<1>, tav::Int<2>> > >::value, - "(length (list 1)) != 1" + "(take 1 (list 1 2)) != (list 1)" ); static_assert( std::is_same< - tav::Size<2>, - tav::Length< + tav::List<tav::Int<1>, tav::Int<2>>, + tav::Take< + tav::Size<2>, tav::List<tav::Int<1>, tav::Int<2>> > >::value, - "(length (list 1 2)) != 2" + "(take 2 (list 1 2)) != (list 1 2)" ); -// list nth - static_assert( std::is_same< - tav::Int<1>, - tav::Nth< - tav::Size<0>, - tav::List<tav::Int<1>> + tav::List<tav::Int<1>, tav::Int<2>>, + tav::Take< + tav::Size<3>, + tav::List<tav::Int<1>, tav::Int<2>> > >::value, - "(nth 0 (list 1)) != 1" + "(take 3 (list 1 2)) != (list 1 2)" ); +// list drop + static_assert( std::is_same< - tav::Int<1>, - tav::Nth< - tav::Size<0>, + tav::List<tav::Int<2>>, + tav::Drop< + tav::Size<1>, tav::List<tav::Int<1>, tav::Int<2>> > >::value, - "(nth 0 (list 1 2)) != 1" + "(drop 1 (list 1 2)) != (list 2)" ); static_assert( std::is_same< - tav::Int<2>, - tav::Nth< - tav::Size<1>, + void, + tav::Drop< + tav::Size<2>, tav::List<tav::Int<1>, tav::Int<2>> > >::value, - "(nth 1 (list 1 2)) != 2" + "(drop 2 (list 1 2)) != void" ); static_assert( std::is_same< - tav::Int<1>, - tav::First<tav::List<tav::Int<1>, tav::Int<2>, tav::Int<3>>> + void, + tav::Drop< + tav::Size<3>, + tav::List<tav::Int<1>, tav::Int<2>> + > >::value, - "(first (list 1 2 3)) != 1" + "(drop 3 (list 1 2)) != void" ); +// list length + static_assert( std::is_same< - tav::Int<2>, - tav::Second<tav::List<tav::Int<1>, tav::Int<2>, tav::Int<3>>> + tav::Size<1>, + tav::Length< + tav::List<tav::Int<1>> + > >::value, - "(second (list 1 2 3)) != 2" + "(length (list 1)) != 1" ); static_assert( std::is_same< - tav::Int<3>, - tav::Third<tav::List<tav::Int<1>, tav::Int<2>, tav::Int<3>>> + tav::Size<2>, + tav::Length< + tav::List<tav::Int<1>, tav::Int<2>> + > >::value, - "(third (list 1 2 3)) != 3" + "(length (list 1 2)) != 2" ); -// list take +// list nth static_assert( std::is_same< - tav::List<tav::Int<1>>, - tav::Take< - tav::Size<1>, - tav::List<tav::Int<1>, tav::Int<2>> + tav::Int<1>, + tav::Nth< + tav::Size<0>, + tav::List<tav::Int<1>> > >::value, - "(take 1 (list 1 2)) != (list 1)" + "(nth 0 (list 1)) != 1" ); static_assert( std::is_same< - tav::List<tav::Int<1>, tav::Int<2>>, - tav::Take< - tav::Size<2>, + tav::Int<1>, + tav::Nth< + tav::Size<0>, tav::List<tav::Int<1>, tav::Int<2>> > >::value, - "(take 2 (list 1 2)) != (list 1 2)" + "(nth 0 (list 1 2)) != 1" ); static_assert( std::is_same< - tav::List<tav::Int<1>, tav::Int<2>>, - tav::Take< - tav::Size<3>, + tav::Int<2>, + tav::Nth< + tav::Size<1>, tav::List<tav::Int<1>, tav::Int<2>> > >::value, - "(take 3 (list 1 2)) != (list 1 2)" + "(nth 1 (list 1 2)) != 2" ); -// list drop - static_assert( std::is_same< - tav::List<tav::Int<2>>, - tav::Drop< - tav::Size<1>, - tav::List<tav::Int<1>, tav::Int<2>> - > + tav::Int<1>, + tav::First<tav::List<tav::Int<1>, tav::Int<2>, tav::Int<3>>> >::value, - "(drop 1 (list 1 2)) != (list 2)" + "(first (list 1 2 3)) != 1" ); static_assert( std::is_same< - void, - tav::Drop< - tav::Size<2>, - tav::List<tav::Int<1>, tav::Int<2>> - > + tav::Int<2>, + tav::Second<tav::List<tav::Int<1>, tav::Int<2>, tav::Int<3>>> >::value, - "(drop 2 (list 1 2)) != void" + "(second (list 1 2 3)) != 2" ); static_assert( std::is_same< - void, - tav::Drop< - tav::Size<3>, - tav::List<tav::Int<1>, tav::Int<2>> - > + tav::Int<3>, + tav::Third<tav::List<tav::Int<1>, tav::Int<2>, tav::Int<3>>> >::value, - "(drop 3 (list 1 2)) != void" + "(third (list 1 2 3)) != 3" ); // list append |