// File: 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
movq %rsp, %rbp
movq 0x2e0d(%rip), %rdi      # 0x3fd8
leaq 0xe32(%rip), %rsi       # 0x2004
callq 0x1040
callq 0x1410
movq 0x2df5(%rip), %rdi      # 0x3fd8
leaq 0xe28(%rip), %rsi       # 0x2012
callq 0x1040
callq 0x1440
movq 0x2ddd(%rip), %rdi      # 0x3fd8
leaq 0xe25(%rip), %rsi       # 0x2027
callq 0x1040
movq %rax, %rdi
movl $0xa, %esi
callq 0x1070
movq %rax, %rdi
movq 0x2daa(%rip), %rsi      # 0x3fc8
callq 0x1050
movq 0x2dae(%rip), %rdi      # 0x3fd8
leaq 0xdfe(%rip), %rsi       # 0x202f
callq 0x1040
movq %rax, %rdi
movl $0x5, %esi
callq 0x1070
movq %rax, %rdi
movq 0x2d7b(%rip), %rsi      # 0x3fc8
callq 0x1050
movq 0x2d7f(%rip), %rdi      # 0x3fd8
leaq 0xdd9(%rip), %rsi       # 0x2039
callq 0x1040
movq %rax, %rdi
movl $0x30, %esi
callq 0x1070
movq %rax, %rdi
movq 0x2d4c(%rip), %rsi      # 0x3fc8
callq 0x1050
movq 0x2d50(%rip), %rdi      # 0x3fd8
leaq 0xdb1(%rip), %rsi       # 0x2040
callq 0x1040
movq %rax, %rdi
movl $0x2, %esi
callq 0x1070
movq %rax, %rdi
movq 0x2d1d(%rip), %rsi      # 0x3fc8
callq 0x1050
movq 0x2d21(%rip), %rdi      # 0x3fd8
leaq 0xd8d(%rip), %rsi       # 0x204b
callq 0x1040
movq %rax, %rdi
movl $0x2da, %esi            # imm = 0x2DA
callq 0x1070
movq %rax, %rdi
movq 0x2cee(%rip), %rsi      # 0x3fc8
callq 0x1050
movq 0x2cf2(%rip), %rdi      # 0x3fd8
leaq 0xd80(%rip), %rsi       # 0x206d
callq 0x1040
movq %rax, %rdi
movl $0x2, %esi
callq 0x1070
movq %rax, %rdi
movq 0x2cbf(%rip), %rsi      # 0x3fc8
callq 0x1050
movq 0x2cc3(%rip), %rdi      # 0x3fd8
leaq 0xd6c(%rip), %rsi       # 0x2088
callq 0x1040
movq %rax, %rdi
movl $0x30, %esi
callq 0x1070
movq %rax, %rdi
movq 0x2c90(%rip), %rsi      # 0x3fc8
callq 0x1050
movq 0x2c94(%rip), %rdi      # 0x3fd8
leaq 0xd59(%rip), %rsi       # 0x20a4
callq 0x1040
callq 0x1470
movq 0x2c7c(%rip), %rdi      # 0x3fd8
leaq 0xd61(%rip), %rsi       # 0x20c4
callq 0x1040
callq 0x14a0
movq 0x2c64(%rip), %rdi      # 0x3fd8
leaq 0xd6c(%rip), %rsi       # 0x20e7
callq 0x1040
callq 0x14d0
movq 0x2c4c(%rip), %rdi      # 0x3fd8
leaq 0xd66(%rip), %rsi       # 0x20f9
callq 0x1040
callq 0x1500
movq 0x2c34(%rip), %rdi      # 0x3fd8
leaq 0xd5f(%rip), %rsi       # 0x210a
callq 0x1040
callq 0x1500
movq 0x2c1c(%rip), %rdi      # 0x3fd8
leaq 0xd5f(%rip), %rsi       # 0x2122
callq 0x1040
callq 0x1530
movq 0x2c04(%rip), %rdi      # 0x3fd8
leaq 0xd5e(%rip), %rsi       # 0x2139
callq 0x1040
callq 0x1560
movq 0x2bec(%rip), %rdi      # 0x3fd8
leaq 0xd61(%rip), %rsi       # 0x2154
callq 0x1040
callq 0x1590
xorl %eax, %eax
popq %rbp
retq
nopw %cs:(%rax,%rax)
nopl (%rax,%rax)