// File: /workspace/github_cpp_makefile_star2_O2/tismith[P]tmp-play/list.cpp
// Function: main
int main() {

    /* The best example */
    std::cout << "The list is: ";
    ListPrinter<myList>::print(); // this one generates tons of classes

    std::cout << "The sorted list is: ";
    ListPrinter<SORT<ORD, myList>::TYPE>::print();

    /* basic list operations */
    std::cout << "head = " << myList::HEAD << std::endl;
    std::cout << "length = " << myList::LENGTH << std::endl;
    std::cout << "sum = " << SUM< myList >::RESULT << std::endl;
    std::cout << "minimum = " << myList::MINIMUM << std::endl;

    /* map-reduce or fold */
    std::cout << "sum of squares with map_reduce = " << MAP_REDUCE< myList, SQUARE, ADDITION, 0 >::RESULT << std::endl;
    std::cout << "minimum with map_reduce = " << MAP_REDUCE< myList, ID, MIN, INT_MAX >::RESULT << std::endl;
    std::cout << "sum done with map_reduce = " << MAP_REDUCE< myList, ID, ADDITION, 0 >::RESULT << std::endl;
    std::cout << "mapping square over the list = ";
    ListPrinter<MAP<myList, SQUARE>::TYPE>::print();
    std::cout << "mapping increment over the list = ";
    ListPrinter<MAP<myList, INCREMENT >::TYPE>::print();

    /* other list operations */
    std::cout << "prepending '3' = ";
    ListPrinter<PREPEND<3,myList>::TYPE>::print();
    std::cout << "tail function = ";
    ListPrinter<TAIL<myList>::TYPE>::print();
    std::cout << "tail member function = ";
    ListPrinter<myList::TAIL>::print();

    /* internal routines used for the merge sort */
    std::cout << "merge (1,6,8) (6,9) = ";
    ListPrinter<MERGE<ORD, LIST3<1,6,8>::TYPE, LIST2<6,9>::TYPE>::TYPE>::print();
    std::cout << "fst . split (1,6,8,6,9) = ";
    ListPrinter<SPLIT<LIST5<1,6,8,6,9>::TYPE>::TYPE::FST>::print();
    std::cout << "snd . split (1,6,8,6,9) = ";
    ListPrinter<SPLIT<LIST5<1,6,8,6,9>::TYPE>::TYPE::SND>::print();
}

// Assembly:
pushq %rbp
pushq %r14
pushq %rbx
movq 0x2e21(%rip), %rbx      # 0x3fd8
leaq 0xe46(%rip), %rsi       # 0x2004
movq %rbx, %rdi
callq 0x1050
callq 0x137c
leaq 0xe40(%rip), %rsi       # 0x2012
movq %rbx, %rdi
callq 0x1050
callq 0x13a2
leaq 0xe41(%rip), %rsi       # 0x2027
movq %rbx, %rdi
callq 0x1050
pushq $0xa
popq %rsi
movq %rax, %rdi
callq 0x1070
movq %rax, %rdi
callq 0x1030
leaq 0xe27(%rip), %rsi       # 0x202f
movq %rbx, %rdi
callq 0x1050
pushq $0x5
popq %rsi
movq %rax, %rdi
callq 0x1070
movq %rax, %rdi
callq 0x1030
leaq 0xe0f(%rip), %rsi       # 0x2039
movq %rbx, %rdi
callq 0x1050
pushq $0x30
popq %rbp
movq %rax, %rdi
movl %ebp, %esi
callq 0x1070
movq %rax, %rdi
callq 0x1030
leaq 0xdf2(%rip), %rsi       # 0x2040
movq %rbx, %rdi
callq 0x1050
pushq $0x2
popq %r14
movq %rax, %rdi
movl %r14d, %esi
callq 0x1070
movq %rax, %rdi
callq 0x1030
leaq 0xdd7(%rip), %rsi       # 0x204b
movq %rbx, %rdi
callq 0x1050
movq %rax, %rdi
movl $0x2da, %esi            # imm = 0x2DA
callq 0x1070
movq %rax, %rdi
callq 0x1030
leaq 0xdd5(%rip), %rsi       # 0x206d
movq %rbx, %rdi
callq 0x1050
movq %rax, %rdi
movl %r14d, %esi
callq 0x1070
movq %rax, %rdi
callq 0x1030
leaq 0xdce(%rip), %rsi       # 0x2088
movq %rbx, %rdi
callq 0x1050
movq %rax, %rdi
movl %ebp, %esi
callq 0x1070
movq %rax, %rdi
callq 0x1030
leaq 0xdc9(%rip), %rsi       # 0x20a4
movq %rbx, %rdi
callq 0x1050
callq 0x13c8
leaq 0xdd5(%rip), %rsi       # 0x20c4
movq %rbx, %rdi
callq 0x1050
callq 0x13ee
leaq 0xde4(%rip), %rsi       # 0x20e7
movq %rbx, %rdi
callq 0x1050
callq 0x1414
leaq 0xde2(%rip), %rsi       # 0x20f9
movq %rbx, %rdi
callq 0x1050
callq 0x143a
leaq 0xddf(%rip), %rsi       # 0x210a
movq %rbx, %rdi
callq 0x1050
callq 0x143a
leaq 0xde3(%rip), %rsi       # 0x2122
movq %rbx, %rdi
callq 0x1050
callq 0x1460
leaq 0xde6(%rip), %rsi       # 0x2139
movq %rbx, %rdi
callq 0x1050
callq 0x1486
leaq 0xded(%rip), %rsi       # 0x2154
movq %rbx, %rdi
callq 0x1050
callq 0x14ac
xorl %eax, %eax
popq %rbx
popq %r14
popq %rbp
retq
nop