Metalang99 1.13.5
Full-blown preprocessor metaprogramming
Loading...
Searching...
No Matches
list.h
Go to the documentation of this file.
1
6#ifndef ML99_LIST_H
7#define ML99_LIST_H
8
9#include <metalang99/priv/bool.h>
10#include <metalang99/priv/util.h>
11
12#include <metalang99/bool.h>
13#include <metalang99/choice.h>
14#include <metalang99/nat.h>
15#include <metalang99/seq.h>
16#include <metalang99/util.h>
18
30#define ML99_cons(x, xs) ML99_call(ML99_cons, x, xs)
31
35#define ML99_nil(...) ML99_callUneval(ML99_nil, )
36
52#define ML99_isCons(list) ML99_call(ML99_isCons, list)
53
69#define ML99_isNil(list) ML99_call(ML99_isNil, list)
70
83#define ML99_listHead(list) ML99_call(ML99_listHead, list)
84
100#define ML99_listTail(list) ML99_call(ML99_listTail, list)
101
114#define ML99_listLast(list) ML99_call(ML99_listLast, list)
115
131#define ML99_listInit(list) ML99_call(ML99_listInit, list)
132
147#define ML99_list(...) ML99_call(ML99_list, __VA_ARGS__)
148
171#define ML99_listFromTuples(f, ...) ML99_call(ML99_listFromTuples, f, __VA_ARGS__)
172
191#define ML99_listFromSeq(seq) ML99_call(ML99_listFromSeq, seq)
192
208#define ML99_listLen(list) ML99_call(ML99_listLen, list)
209
227#define ML99_LIST_EVAL(...) ML99_EVAL(ML99_call(ML99_listUnwrap, __VA_ARGS__))
228
244#define ML99_LIST_EVAL_COMMA_SEP(...) ML99_EVAL(ML99_call(ML99_listUnwrapCommaSep, __VA_ARGS__))
245
258#define ML99_listAppend(list, other) ML99_call(ML99_listAppend, list, other)
259
272#define ML99_listAppendItem(item, list) ML99_call(ML99_listAppendItem, item, list)
273
290#define ML99_listUnwrap(list) ML99_call(ML99_listUnwrap, list)
291
308#define ML99_listUnwrapCommaSep(list) ML99_call(ML99_listUnwrapCommaSep, list)
309
322#define ML99_listReverse(list) ML99_call(ML99_listReverse, list)
323
336#define ML99_listGet(i, list) ML99_call(ML99_listGet, i, list)
337
355#define ML99_listFoldr(f, init, list) ML99_call(ML99_listFoldr, f, init, list)
356
374#define ML99_listFoldl(f, init, list) ML99_call(ML99_listFoldl, f, init, list)
375
390#define ML99_listFoldl1(f, list) ML99_call(ML99_listFoldl1, f, list)
391
404#define ML99_listIntersperse(item, list) ML99_call(ML99_listIntersperse, item, list)
405
418#define ML99_listPrependToAll(item, list) ML99_call(ML99_listPrependToAll, item, list)
419
433#define ML99_listMap(f, list) ML99_call(ML99_listMap, f, list)
434
450#define ML99_listMapI(f, list) ML99_call(ML99_listMapI, f, list)
451
457#define ML99_listMapInPlace(f, list) ML99_call(ML99_listMapInPlace, f, list)
458
464#define ML99_listMapInPlaceI(f, list) ML99_call(ML99_listMapInPlaceI, f, list)
465
479#define ML99_listFor(list, f) ML99_call(ML99_listFor, list, f)
480
493#define ML99_listMapInitLast(f_init, f_last, list) \
494 ML99_call(ML99_listMapInitLast, f_init, f_last, list)
495
507#define ML99_listForInitLast(list, f_init, f_last) \
508 ML99_call(ML99_listForInitLast, list, f_init, f_last)
509
523#define ML99_listFilter(f, list) ML99_call(ML99_listFilter, f, list)
524
543#define ML99_listFilterMap(f, list) ML99_call(ML99_listFilterMap, f, list)
544
561#define ML99_listEq(cmp, list, other) ML99_call(ML99_listEq, cmp, list, other)
562
579#define ML99_listContains(cmp, item, list) ML99_call(ML99_listContains, cmp, item, list)
580
594#define ML99_listTake(n, list) ML99_call(ML99_listTake, n, list)
595
609#define ML99_listTakeWhile(f, list) ML99_call(ML99_listTakeWhile, f, list)
610
624#define ML99_listDrop(n, list) ML99_call(ML99_listDrop, n, list)
625
639#define ML99_listDropWhile(f, list) ML99_call(ML99_listDropWhile, f, list)
640
653#define ML99_listZip(list, other) ML99_call(ML99_listZip, list, other)
654
669#define ML99_listUnzip(list) ML99_call(ML99_listUnzip, list)
670
686#define ML99_listReplicate(n, item) ML99_call(ML99_listReplicate, n, item)
687
702#define ML99_listPartition(f, list) ML99_call(ML99_listPartition, f, list)
703
725#define ML99_listAppl(f, list) ML99_call(ML99_listAppl, f, list)
726
727#define ML99_CONS(x, xs) ML99_CHOICE(cons, x, xs)
728#define ML99_NIL(...) ML99_CHOICE(nil, ~)
729#define ML99_IS_CONS(list) ML99_NOT(ML99_IS_NIL(list))
730#define ML99_IS_NIL(list) ML99_PRIV_IS_NIL(list)
731
732#ifndef DOXYGEN_IGNORE
733
734#define ML99_cons_IMPL(x, xs) v(ML99_CONS(x, xs))
735#define ML99_nil_IMPL(...) v(ML99_NIL())
736
737#define ML99_isCons_IMPL(list) v(ML99_IS_CONS(list))
738#define ML99_isNil_IMPL(list) v(ML99_IS_NIL(list))
739
740#define ML99_listHead_IMPL(list) ML99_match_IMPL(list, ML99_PRIV_listHead_)
741#define ML99_PRIV_listHead_nil_IMPL(_) ML99_PRIV_EMPTY_LIST_ERROR(listHead)
742#define ML99_PRIV_listHead_cons_IMPL(x, _xs) v(x)
743
744#define ML99_listTail_IMPL(list) ML99_match_IMPL(list, ML99_PRIV_listTail_)
745#define ML99_PRIV_listTail_nil_IMPL(_) ML99_PRIV_EMPTY_LIST_ERROR(listTail)
746#define ML99_PRIV_listTail_cons_IMPL(_x, xs) v(xs)
747
748#define ML99_listLast_IMPL(list) ML99_match_IMPL(list, ML99_PRIV_listLast_)
749#define ML99_PRIV_listLast_nil_IMPL(_) ML99_PRIV_EMPTY_LIST_ERROR(listLast)
750#define ML99_PRIV_listLast_cons_IMPL(x, xs) \
751 ML99_PRIV_IF(ML99_IS_NIL(xs), v(x), ML99_listLast_IMPL(xs))
752
753#define ML99_listInit_IMPL(list) ML99_match_IMPL(list, ML99_PRIV_listInit_)
754#define ML99_PRIV_listInit_nil_IMPL(_) ML99_PRIV_EMPTY_LIST_ERROR(listInit)
755#define ML99_PRIV_listInit_cons_IMPL(x, xs) \
756 ML99_PRIV_IF(ML99_IS_NIL(xs), v(ML99_NIL()), ML99_cons(v(x), ML99_listInit_IMPL(xs)))
757
758// ML99_list_IMPL {
759
760#define ML99_list_IMPL(...) \
761 ML99_PRIV_listProgress_IMPL(ML99_VARIADICS_COUNT(__VA_ARGS__), __VA_ARGS__, ~)
762
763// Last 4 recursion steps unrolled.
764#define ML99_PRIV_listProgress_IMPL(count, ...) \
765 ML99_PRIV_IF( \
766 ML99_NAT_EQ(count, 4), \
767 ML99_PRIV_listDone_4, \
768 ML99_PRIV_IF( \
769 ML99_NAT_EQ(count, 3), \
770 ML99_PRIV_listDone_3, \
771 ML99_PRIV_IF( \
772 ML99_NAT_EQ(count, 2), \
773 ML99_PRIV_listDone_2, \
774 ML99_PRIV_IF( \
775 ML99_NAT_EQ(count, 1), \
776 ML99_PRIV_listDone_1, \
777 ML99_PRIV_IF( \
778 ML99_NAT_EQ(count, 0), \
779 ML99_PRIV_listDone_0, \
780 ML99_PRIV_listProgressAux))))) \
781 (count, __VA_ARGS__)
782
783#define ML99_PRIV_listProgressAux(count, x, ...) \
784 ML99_cons(v(x), ML99_callUneval(ML99_PRIV_listProgress, ML99_DEC(count), __VA_ARGS__))
785
786#define ML99_PRIV_listDone_0(_count, _) v(ML99_NIL())
787#define ML99_PRIV_listDone_1(_count, a, _) v(ML99_CONS(a, ML99_NIL()))
788#define ML99_PRIV_listDone_2(_count, a, b, _) v(ML99_CONS(a, ML99_CONS(b, ML99_NIL())))
789#define ML99_PRIV_listDone_3(_count, a, b, c, _) \
790 v(ML99_CONS(a, ML99_CONS(b, ML99_CONS(c, ML99_NIL()))))
791#define ML99_PRIV_listDone_4(_count, a, b, c, d, _) \
792 v(ML99_CONS(a, ML99_CONS(b, ML99_CONS(c, ML99_CONS(d, ML99_NIL())))))
793// } (ML99_list_IMPL)
794
795// ML99_listFromTuples_IMPL {
796
797#define ML99_listFromTuples_IMPL(f, ...) ML99_PRIV_listFromTuplesAux_IMPL(f, __VA_ARGS__, ~)
798
799#define ML99_PRIV_listFromTuplesAux_IMPL(f, x, ...) \
800 ML99_PRIV_CAT(ML99_PRIV_listFromTuples_, ML99_IS_UNTUPLE(x))(f, x, __VA_ARGS__)
801
802#define ML99_PRIV_listFromTuples_1(_f, x, ...) ML99_PRIV_NOT_TUPLE_ERROR(x)
803#define ML99_PRIV_listFromTuples_0(f, x, ...) \
804 ML99_cons( \
805 ML99_appl_IMPL(f, ML99_UNTUPLE(x)), \
806 ML99_PRIV_IF( \
807 ML99_VARIADICS_IS_SINGLE(__VA_ARGS__), \
808 v(ML99_NIL()), \
809 ML99_callUneval(ML99_PRIV_listFromTuplesAux, f, __VA_ARGS__)))
810// } (ML99_listFromTuples_IMPL)
811
812#define ML99_listFromSeq_IMPL(seq) \
813 ML99_PRIV_CAT(ML99_PRIV_listFromSeq_, ML99_SEQ_IS_EMPTY(seq))(seq)
814#define ML99_PRIV_listFromSeq_1 ML99_nil_IMPL
815#define ML99_PRIV_listFromSeq_0(seq) \
816 ML99_cons(v(ML99_SEQ_GET(0)(seq)), ML99_callUneval(ML99_listFromSeq, ML99_SEQ_TAIL(seq)))
817
818#define ML99_listLen_IMPL(list) ML99_match_IMPL(list, ML99_PRIV_listLen_)
819#define ML99_PRIV_listLen_nil_IMPL(_) v(0)
820#define ML99_PRIV_listLen_cons_IMPL(_x, xs) ML99_inc(ML99_listLen_IMPL(xs))
821
822#define ML99_listAppend_IMPL(list, other) \
823 ML99_matchWithArgs_IMPL(list, ML99_PRIV_listAppend_, other)
824#define ML99_PRIV_listAppend_nil_IMPL(_, other) v(other)
825#define ML99_PRIV_listAppend_cons_IMPL(x, xs, other) \
826 ML99_cons(v(x), ML99_listAppend_IMPL(xs, other))
827
828#define ML99_listAppendItem_IMPL(item, list) ML99_listAppend_IMPL(list, ML99_CONS(item, ML99_NIL()))
829
830#define ML99_listUnwrap_IMPL(list) ML99_match_IMPL(list, ML99_PRIV_listUnwrap_)
831#define ML99_PRIV_listUnwrap_nil_IMPL ML99_empty_IMPL
832#define ML99_PRIV_listUnwrap_cons_IMPL(x, xs) ML99_TERMS(v(x), ML99_listUnwrap_IMPL(xs))
833
834#define ML99_listReverse_IMPL(list) ML99_match_IMPL(list, ML99_PRIV_listReverse_)
835#define ML99_PRIV_listReverse_nil_IMPL ML99_nil_IMPL
836#define ML99_PRIV_listReverse_cons_IMPL(x, xs) ML99_listAppendItem(v(x), ML99_listReverse_IMPL(xs))
837
838#define ML99_listGet_IMPL(i, list) ML99_matchWithArgs_IMPL(list, ML99_PRIV_listGet_, i)
839#define ML99_PRIV_listGet_nil_IMPL(_, i) ML99_PRIV_EMPTY_LIST_ERROR(ML99_listGet)
840#define ML99_PRIV_listGet_cons_IMPL(x, xs, i) \
841 ML99_PRIV_IF(ML99_NAT_EQ(i, 0), v(x), ML99_listGet_IMPL(ML99_DEC(i), xs))
842
843#define ML99_listFoldr_IMPL(f, init, list) \
844 ML99_matchWithArgs_IMPL(list, ML99_PRIV_listFoldr_, f, init)
845#define ML99_PRIV_listFoldr_nil_IMPL(_, _f, acc) v(acc)
846#define ML99_PRIV_listFoldr_cons_IMPL(x, xs, f, acc) \
847 ML99_call(ML99_appl2, v(f, x), ML99_listFoldr_IMPL(f, acc, xs))
848
849#define ML99_listFoldl_IMPL(f, init, list) \
850 ML99_matchWithArgs_IMPL(list, ML99_PRIV_listFoldl_, f, init)
851#define ML99_PRIV_listFoldl_nil_IMPL(_, _f, acc) v(acc)
852#define ML99_PRIV_listFoldl_cons_IMPL(x, xs, f, acc) \
853 ML99_listFoldl(v(f), ML99_appl2_IMPL(f, acc, x), v(xs))
854
855#define ML99_listFoldl1_IMPL(f, list) ML99_matchWithArgs_IMPL(list, ML99_PRIV_listFoldl1_, f)
856#define ML99_PRIV_listFoldl1_nil_IMPL(_, _f) ML99_PRIV_EMPTY_LIST_ERROR(ML99_listFoldl1)
857#define ML99_PRIV_listFoldl1_cons_IMPL(x, xs, f) ML99_listFoldl_IMPL(f, x, xs)
858
859#define ML99_listIntersperse_IMPL(item, list) \
860 ML99_matchWithArgs_IMPL(list, ML99_PRIV_listIntersperse_, item)
861#define ML99_PRIV_listIntersperse_nil_IMPL ML99_nil_IMPL
862#define ML99_PRIV_listIntersperse_cons_IMPL(x, xs, item) \
863 ML99_cons(v(x), ML99_listPrependToAll_IMPL(item, xs))
864
865#define ML99_listPrependToAll_IMPL(item, list) \
866 ML99_matchWithArgs_IMPL(list, ML99_PRIV_listPrependToAll_, item)
867#define ML99_PRIV_listPrependToAll_nil_IMPL ML99_nil_IMPL
868#define ML99_PRIV_listPrependToAll_cons_IMPL(x, xs, item) \
869 ML99_cons(v(item), ML99_cons(v(x), ML99_listPrependToAll_IMPL(item, xs)))
870
871#define ML99_listMap_IMPL(f, list) ML99_matchWithArgs_IMPL(list, ML99_PRIV_listMap_, f)
872#define ML99_PRIV_listMap_nil_IMPL ML99_nil_IMPL
873#define ML99_PRIV_listMap_cons_IMPL(x, xs, f) \
874 ML99_cons(ML99_appl_IMPL(f, x), ML99_listMap_IMPL(f, xs))
875
876#define ML99_listMapI_IMPL(f, list) ML99_PRIV_listMapIAux_IMPL(f, list, 0)
877#define ML99_PRIV_listMapIAux_IMPL(f, list, i) \
878 ML99_matchWithArgs_IMPL(list, ML99_PRIV_listMapI_, f, i)
879#define ML99_PRIV_listMapI_nil_IMPL ML99_nil_IMPL
880#define ML99_PRIV_listMapI_cons_IMPL(x, xs, f, i) \
881 ML99_cons(ML99_appl2_IMPL(f, x, i), ML99_PRIV_listMapIAux_IMPL(f, xs, ML99_INC(i)))
882
883#define ML99_listMapInPlace_IMPL(f, list) \
884 ML99_matchWithArgs_IMPL(list, ML99_PRIV_listMapInPlace_, f)
885#define ML99_PRIV_listMapInPlace_nil_IMPL ML99_empty_IMPL
886#define ML99_PRIV_listMapInPlace_cons_IMPL(x, xs, f) \
887 ML99_TERMS(ML99_appl_IMPL(f, x), ML99_listMapInPlace_IMPL(f, xs))
888
889#define ML99_listMapInPlaceI_IMPL(f, list) ML99_PRIV_listMapInPlaceIAux_IMPL(f, list, 0)
890#define ML99_PRIV_listMapInPlaceIAux_IMPL(f, list, i) \
891 ML99_matchWithArgs_IMPL(list, ML99_PRIV_listMapInPlaceI_, f, i)
892#define ML99_PRIV_listMapInPlaceI_nil_IMPL ML99_empty_IMPL
893#define ML99_PRIV_listMapInPlaceI_cons_IMPL(x, xs, f, i) \
894 ML99_TERMS(ML99_appl2_IMPL(f, x, i), ML99_PRIV_listMapInPlaceIAux_IMPL(f, xs, ML99_INC(i)))
895
896#define ML99_listFor_IMPL(list, f) ML99_listMap_IMPL(f, list)
897
898#define ML99_listMapInitLast_IMPL(f_init, f_last, list) \
899 ML99_listAppendItem( \
900 ML99_appl(v(f_last), ML99_listLast_IMPL(list)), \
901 ML99_listMap(v(f_init), ML99_listInit_IMPL(list)))
902
903#define ML99_listForInitLast_IMPL(list, f_init, f_last) \
904 ML99_listMapInitLast_IMPL(f_init, f_last, list)
905
906// ML99_listFilter_IMPL {
907
908#define ML99_listFilter_IMPL(f, list) ML99_matchWithArgs_IMPL(list, ML99_PRIV_listFilter_, f)
909
910#define ML99_PRIV_listFilter_nil_IMPL ML99_nil_IMPL
911#define ML99_PRIV_listFilter_cons_IMPL(x, xs, f) \
912 ML99_call( \
913 ML99_boolMatchWithArgs, \
914 ML99_appl_IMPL(f, x), \
915 v(ML99_PRIV_listFilter_cons_, x), \
916 ML99_listFilter_IMPL(f, xs))
917
918#define ML99_PRIV_listFilter_cons_1_IMPL(x, rest) v(ML99_CONS(x, rest))
919#define ML99_PRIV_listFilter_cons_0_IMPL(_x, rest) v(rest)
920// } (ML99_listFilter_IMPL)
921
922// ML99_listFilterMap_IMPL {
923
924#define ML99_listFilterMap_IMPL(f, list) ML99_matchWithArgs_IMPL(list, ML99_PRIV_listFilterMap_, f)
925
926#define ML99_PRIV_listFilterMap_nil_IMPL ML99_nil_IMPL
927#define ML99_PRIV_listFilterMap_cons_IMPL(x, xs, f) \
928 ML99_call(ML99_matchWithArgs, ML99_appl_IMPL(f, x), v(ML99_PRIV_listFilterMap_cons_, f, xs))
929
930#define ML99_PRIV_listFilterMap_cons_just_IMPL(y, f, xs) \
931 ML99_cons(v(y), ML99_listFilterMap_IMPL(f, xs))
932#define ML99_PRIV_listFilterMap_cons_nothing_IMPL(_, f, xs) ML99_listFilterMap_IMPL(f, xs)
933// } (ML99_listFilterMap_IMPL)
934
935// ML99_listEq_IMPL {
936
937#define ML99_listEq_IMPL(cmp, list, other) \
938 ML99_matchWithArgs_IMPL(list, ML99_PRIV_listEq_, other, cmp)
939
940#define ML99_PRIV_listEq_nil_IMPL(_, other, _cmp) v(ML99_IS_NIL(other))
941#define ML99_PRIV_listEq_cons_IMPL(x, xs, other, cmp) \
942 ML99_matchWithArgs_IMPL(other, ML99_PRIV_listEq_cons_, x, xs, cmp)
943
944#define ML99_PRIV_listEq_cons_nil_IMPL ML99_false_IMPL
945#define ML99_PRIV_listEq_cons_cons_IMPL(other_x, other_xs, x, xs, cmp) \
946 ML99_call( \
947 ML99_call(ML99_if, ML99_appl2_IMPL(cmp, x, other_x), v(ML99_listEq, ML99_false)), \
948 v(cmp, xs, other_xs))
949// } (ML99_listEq_IMPL)
950
951#define ML99_listContains_IMPL(cmp, item, list) \
952 ML99_matchWithArgs_IMPL(list, ML99_PRIV_listContains_, item, cmp)
953#define ML99_PRIV_listContains_nil_IMPL ML99_false_IMPL
954#define ML99_PRIV_listContains_cons_IMPL(x, xs, item, cmp) \
955 ML99_call( \
956 ML99_call(ML99_if, ML99_appl2_IMPL(cmp, x, item), v(ML99_true, ML99_listContains)), \
957 v(cmp, item, xs))
958
959#define ML99_listTake_IMPL(n, list) ML99_matchWithArgs_IMPL(list, ML99_PRIV_listTake_, n)
960#define ML99_PRIV_listTake_nil_IMPL ML99_nil_IMPL
961#define ML99_PRIV_listTake_cons_IMPL(x, xs, i) \
962 ML99_PRIV_IF( \
963 ML99_NAT_EQ(i, 0), \
964 v(ML99_NIL()), \
965 ML99_cons(v(x), ML99_listTake_IMPL(ML99_DEC(i), xs)))
966
967// ML99_listTakeWhile_IMPL {
968
969#define ML99_listTakeWhile_IMPL(f, list) ML99_matchWithArgs_IMPL(list, ML99_PRIV_listTakeWhile_, f)
970
971#define ML99_PRIV_listTakeWhile_nil_IMPL ML99_nil_IMPL
972#define ML99_PRIV_listTakeWhile_cons_IMPL(x, xs, f) \
973 ML99_call( \
974 ML99_boolMatchWithArgs, \
975 ML99_appl_IMPL(f, x), \
976 v(ML99_PRIV_listTakeWhile_cons_, x, xs, f))
977
978#define ML99_PRIV_listTakeWhile_cons_1_IMPL(x, xs, f) \
979 ML99_cons(v(x), ML99_listTakeWhile_IMPL(f, xs))
980#define ML99_PRIV_listTakeWhile_cons_0_IMPL ML99_nil_IMPL
981// } (ML99_listTakeWhile_IMPL)
982
983#define ML99_listDrop_IMPL(n, list) ML99_matchWithArgs_IMPL(list, ML99_PRIV_listDrop_, n)
984#define ML99_PRIV_listDrop_nil_IMPL ML99_nil_IMPL
985#define ML99_PRIV_listDrop_cons_IMPL(x, xs, i) \
986 ML99_PRIV_IF(ML99_NAT_EQ(i, 0), v(ML99_CONS(x, xs)), ML99_listDrop_IMPL(ML99_DEC(i), xs))
987
988// ML99_listDropWhile_IMPL {
989
990#define ML99_listDropWhile_IMPL(f, list) ML99_matchWithArgs_IMPL(list, ML99_PRIV_listDropWhile_, f)
991
992#define ML99_PRIV_listDropWhile_nil_IMPL ML99_nil_IMPL
993#define ML99_PRIV_listDropWhile_cons_IMPL(x, xs, f) \
994 ML99_call( \
995 ML99_boolMatchWithArgs, \
996 ML99_appl_IMPL(f, x), \
997 v(ML99_PRIV_listDropWhile_cons_, x, xs, f))
998
999#define ML99_PRIV_listDropWhile_cons_0_IMPL(x, xs, _f) v(ML99_CONS(x, xs))
1000#define ML99_PRIV_listDropWhile_cons_1_IMPL(_x, xs, f) ML99_listDropWhile_IMPL(f, xs)
1001// } (ML99_listDropWhile_IMPL)
1002
1003// ML99_listZip_IMPL {
1004
1005#define ML99_listZip_IMPL(list, other) ML99_matchWithArgs_IMPL(list, ML99_PRIV_listZip_, other)
1006
1007#define ML99_PRIV_listZip_nil_IMPL ML99_nil_IMPL
1008#define ML99_PRIV_listZip_cons_IMPL(x, xs, other) \
1009 ML99_matchWithArgs_IMPL(other, ML99_PRIV_listZip_cons_, x, xs)
1010
1011#define ML99_PRIV_listZip_cons_nil_IMPL ML99_nil_IMPL
1012#define ML99_PRIV_listZip_cons_cons_IMPL(other_x, other_xs, x, xs) \
1013 ML99_cons(v(ML99_TUPLE(x, other_x)), ML99_listZip_IMPL(xs, other_xs))
1014// } (ML99_listZip_IMPL)
1015
1016// ML99_listUnzip_IMPL {
1017
1018#define ML99_listUnzip_IMPL(list) ML99_match_IMPL(list, ML99_PRIV_listUnzip_)
1019
1020#define ML99_PRIV_listUnzip_nil_IMPL(_) v(ML99_TUPLE(ML99_NIL(), ML99_NIL()))
1021#define ML99_PRIV_listUnzip_cons_IMPL(x, xs) \
1022 ML99_call(ML99_PRIV_listUnzipProgress, v(x), ML99_listUnzip_IMPL(xs))
1023
1024#define ML99_PRIV_listUnzipProgress_IMPL(x, rest) \
1025 v(ML99_TUPLE(ML99_PRIV_LIST_UNZIP_EXTEND(x, rest, 0), ML99_PRIV_LIST_UNZIP_EXTEND(x, rest, 1)))
1026
1027#define ML99_PRIV_LIST_UNZIP_EXTEND(x, rest, i) \
1028 ML99_CONS(ML99_TUPLE_GET(i)(x), ML99_TUPLE_GET(i)(rest))
1029// } (ML99_listUnzip_IMPL)
1030
1031#define ML99_listReplicate_IMPL(n, item) \
1032 ML99_natMatchWithArgs_IMPL(n, ML99_PRIV_listReplicate_, item)
1033#define ML99_PRIV_listReplicate_Z_IMPL ML99_nil_IMPL
1034#define ML99_PRIV_listReplicate_S_IMPL(n, item) ML99_cons(v(item), ML99_listReplicate_IMPL(n, item))
1035
1036// ML99_listPartition_IMPL {
1037
1038#define ML99_listPartition_IMPL(f, list) \
1039 ML99_listFoldr( \
1040 ML99_appl_IMPL(ML99_PRIV_listPartitionAux, f), \
1041 v(ML99_TUPLE(ML99_NIL(), ML99_NIL())), \
1042 v(list))
1043
1044#define ML99_PRIV_listPartitionAux_IMPL(f, x, acc) \
1045 ML99_call( \
1046 ML99_boolMatchWithArgs, \
1047 ML99_appl_IMPL(f, x), \
1048 v(ML99_PRIV_listPartition_, x, ML99_UNTUPLE(acc)))
1049
1050#define ML99_PRIV_listPartition_1_IMPL(x, fst, snd) v(ML99_TUPLE(ML99_CONS(x, fst), snd))
1051#define ML99_PRIV_listPartition_0_IMPL(x, fst, snd) v(ML99_TUPLE(fst, ML99_CONS(x, snd)))
1052// } (ML99_listPartition_IMPL)
1053
1054#define ML99_listAppl_IMPL(f, list) ML99_listFoldl_IMPL(ML99_appl, f, list)
1055
1056// ML99_listUnwrapCommaSep_IMPL {
1057
1058#define ML99_listUnwrapCommaSep_IMPL(list) \
1059 ML99_PRIV_IF( \
1060 ML99_IS_NIL(list), \
1061 v(ML99_EMPTY()), \
1062 ML99_variadicsTail(ML99_PRIV_listUnwrapCommaSepAux_IMPL(list)))
1063
1064#define ML99_PRIV_listUnwrapCommaSepAux_IMPL(xs) ML99_match_IMPL(xs, ML99_PRIV_listUnwrapCommaSep_)
1065
1066#define ML99_PRIV_listUnwrapCommaSep_nil_IMPL ML99_empty_IMPL
1067#define ML99_PRIV_listUnwrapCommaSep_cons_IMPL(x, xs) \
1068 ML99_TERMS(v(, x), ML99_PRIV_listUnwrapCommaSepAux_IMPL(xs))
1069// } (ML99_listUnwrapCommaSep_IMPL)
1070
1071// clang-format off
1072#define ML99_PRIV_EMPTY_LIST_ERROR(f) ML99_fatal(ML99_##f, expected a non-empty list)
1073// clang-format on
1074
1075#define ML99_PRIV_IS_NIL(list) ML99_DETECT_IDENT(ML99_PRIV_IS_NIL_, ML99_CHOICE_TAG(list))
1076#define ML99_PRIV_IS_NIL_nil ()
1077
1078// Arity specifiers {
1079
1080#define ML99_cons_ARITY 2
1081#define ML99_nil_ARITY 1
1082#define ML99_isCons_ARITY 1
1083#define ML99_isNil_ARITY 1
1084#define ML99_listHead_ARITY 1
1085#define ML99_listTail_ARITY 1
1086#define ML99_listLast_ARITY 1
1087#define ML99_listInit_ARITY 1
1088#define ML99_list_ARITY 1
1089#define ML99_listFromTuples_ARITY 2
1090#define ML99_listFromSeq_ARITY 1
1091#define ML99_listLen_ARITY 1
1092#define ML99_listAppend_ARITY 2
1093#define ML99_listAppendItem_ARITY 2
1094#define ML99_listUnwrap_ARITY 1
1095#define ML99_listUnwrapCommaSep_ARITY 1
1096#define ML99_listReverse_ARITY 1
1097#define ML99_listGet_ARITY 2
1098#define ML99_listFoldr_ARITY 3
1099#define ML99_listFoldl_ARITY 3
1100#define ML99_listFoldl1_ARITY 2
1101#define ML99_listIntersperse_ARITY 2
1102#define ML99_listPrependToAll_ARITY 2
1103#define ML99_listMap_ARITY 2
1104#define ML99_listMapI_ARITY 2
1105#define ML99_listMapInPlace_ARITY 2
1106#define ML99_listMapInPlaceI_ARITY 2
1107#define ML99_listFor_ARITY 2
1108#define ML99_listMapInitLast_ARITY 3
1109#define ML99_listForInitLast_ARITY 3
1110#define ML99_listFilter_ARITY 2
1111#define ML99_listFilterMap_ARITY 2
1112#define ML99_listEq_ARITY 3
1113#define ML99_listContains_ARITY 3
1114#define ML99_listTake_ARITY 2
1115#define ML99_listTakeWhile_ARITY 2
1116#define ML99_listDrop_ARITY 2
1117#define ML99_listDropWhile_ARITY 2
1118#define ML99_listZip_ARITY 2
1119#define ML99_listUnzip_ARITY 1
1120#define ML99_listReplicate_ARITY 2
1121#define ML99_listPartition_ARITY 2
1122#define ML99_listAppl_ARITY 2
1123
1124#define ML99_PRIV_listPartitionAux_ARITY 3
1125// } (Arity specifiers)
1126
1127#endif // DOXYGEN_IGNORE
1128
1129#endif // ML99_LIST_H
Boolean algebra.
Choice types: (tag, ...).
Natural numbers: [0; 255].
Sequences: (x)(y)(z).
Utilitary stuff.
Variadic arguments: x, y, z.