// File: calgagi[P]cp_gen/main.cpp
// Function: output_templates(std::basic_fstream<char, std::char_traits<char>>&, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>> const&)
void output_templates(fstream& new_file, const vector<string>& templates) {
    // this assumes that gen is in the root directory of cp_gen (where lib is)
    string gen_path = pathToGen();
    gen_path += "lib/";

    set<string> already_outputted;

    for (const string& ds : templates) {
        vector<string> to_output;

        queue<string> q;
        q.push(ds);

        // perform BFS on dependency graph
        while (!q.empty()) {
            string cur_lib = q.front();
            q.pop();
            if (already_outputted.find(cur_lib) != already_outputted.end()) {
                continue;
            }
            already_outputted.insert(cur_lib);
            to_output.push_back(cur_lib);
            for (const string& dep : dep_graph[cur_lib]) {
                q.push(dep);
            }
        }
        
        // output files in reverse visited order
        for (int i = to_output.size() - 1; ~i; i--) {
            output_file(new_file, gen_path + to_output[i] + ".hpp");
            new_file << endl;
        }
    }

    return;
}

// Assembly:
subq $0x1e8, %rsp            # imm = 0x1E8
movq %rdi, 0x1e0(%rsp)
movq %rsi, 0x1d8(%rsp)
leaq 0x1b8(%rsp), %rdi
movq %rdi, 0x38(%rsp)
callq 0x3c80
movq 0x38(%rsp), %rdi
leaq 0x7060(%rip), %rsi      # 0xb0a5
callq 0x3250
jmp 0x404c
leaq 0x178(%rsp), %rdi
callq 0x52f0
movq 0x1d8(%rsp), %rax
movq %rax, 0x170(%rsp)
movq 0x170(%rsp), %rdi
callq 0x5300
movq %rax, 0x168(%rsp)
movq 0x170(%rsp), %rdi
callq 0x5330
movq %rax, 0x160(%rsp)
leaq 0x168(%rsp), %rdi
leaq 0x160(%rsp), %rsi
callq 0x5360
testb $0x1, %al
jne 0x40b1
jmp 0x44bf
leaq 0x168(%rsp), %rdi
callq 0x53a0
movq %rax, 0x158(%rsp)
leaq 0x140(%rsp), %rdi
callq 0x53b0
leaq 0xf0(%rsp), %rdi
callq 0x53c0
jmp 0x40e2
movq 0x158(%rsp), %rsi
leaq 0xf0(%rsp), %rdi
callq 0x53f0
jmp 0x40f9
jmp 0x40fb
leaq 0xf0(%rsp), %rdi
callq 0x5420
movb %al, 0x37(%rsp)
jmp 0x410e
movb 0x37(%rsp), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x411d
jmp 0x4359
leaq 0xf0(%rsp), %rdi
callq 0x5440
movq %rax, 0x28(%rsp)
jmp 0x4131
movq 0x28(%rsp), %rsi
leaq 0xd0(%rsp), %rdi
callq 0x3110
jmp 0x4145
leaq 0xf0(%rsp), %rdi
callq 0x5450
jmp 0x4154
leaq 0x178(%rsp), %rdi
leaq 0xd0(%rsp), %rsi
callq 0x5480
movq %rax, 0x20(%rsp)
jmp 0x4170
movq 0x20(%rsp), %rax
movq %rax, 0xc8(%rsp)
leaq 0x178(%rsp), %rdi
callq 0x54c0
movq %rax, 0xc0(%rsp)
leaq 0xc8(%rsp), %rdi
leaq 0xc0(%rsp), %rsi
callq 0x5460
testb $0x1, %al
jne 0x41b0
jmp 0x4231
movl $0x4, 0xbc(%rsp)
jmp 0x4335
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1b0(%rsp)
movl %eax, 0x1ac(%rsp)
jmp 0x44ec
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1b0(%rsp)
movl %eax, 0x1ac(%rsp)
jmp 0x44a3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1b0(%rsp)
movl %eax, 0x1ac(%rsp)
jmp 0x4496
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1b0(%rsp)
movl %eax, 0x1ac(%rsp)
leaq 0xd0(%rsp), %rdi
callq 0x34a8
jmp 0x4496
leaq 0x178(%rsp), %rdi
leaq 0xd0(%rsp), %rsi
callq 0x54f0
movb %dl, 0x17(%rsp)
movq %rax, 0x18(%rsp)
jmp 0x4251
movb 0x17(%rsp), %al
movq 0x18(%rsp), %rcx
movq %rcx, 0xa8(%rsp)
movb %al, 0xb0(%rsp)
leaq 0x140(%rsp), %rdi
leaq 0xd0(%rsp), %rsi
callq 0x5550
jmp 0x4280
leaq 0xc011(%rip), %rdi      # 0x10298
leaq 0xd0(%rsp), %rsi
callq 0x55c0
movq %rax, 0x8(%rsp)
jmp 0x429b
movq 0x8(%rsp), %rax
movq %rax, 0xa0(%rsp)
movq 0xa0(%rsp), %rdi
callq 0x56b0
movq %rax, 0x98(%rsp)
movq 0xa0(%rsp), %rdi
callq 0x56e0
movq %rax, 0x90(%rsp)
leaq 0x98(%rsp), %rdi
leaq 0x90(%rsp), %rsi
callq 0x5710
testb $0x1, %al
jne 0x42ed
jmp 0x432a
leaq 0x98(%rsp), %rdi
callq 0x5750
movq %rax, 0x88(%rsp)
movq 0x88(%rsp), %rsi
leaq 0xf0(%rsp), %rdi
callq 0x53f0
jmp 0x4319
jmp 0x431b
leaq 0x98(%rsp), %rdi
callq 0x5760
jmp 0x42d2
movl $0x0, 0xbc(%rsp)
leaq 0xd0(%rsp), %rdi
callq 0x34a8
movl 0xbc(%rsp), %eax
testl %eax, %eax
je 0x4354
jmp 0x434f
jmp 0x40fb
jmp 0x40fb
leaq 0x140(%rsp), %rdi
callq 0x5780
subq $0x1, %rax
movl %eax, 0x84(%rsp)
movl 0x84(%rsp), %eax
xorl $-0x1, %eax
cmpl $0x0, %eax
je 0x446a
movq 0x1e0(%rsp), %rax
movq %rax, (%rsp)
movslq 0x84(%rsp), %rsi
leaq 0x140(%rsp), %rdi
callq 0x5830
movq %rax, %rdx
leaq 0x40(%rsp), %rdi
leaq 0x1b8(%rsp), %rsi
callq 0x57a0
jmp 0x43bc
leaq 0x6ce7(%rip), %rdx      # 0xb0aa
leaq 0x60(%rsp), %rdi
leaq 0x40(%rsp), %rsi
callq 0x5140
jmp 0x43d4
movq (%rsp), %rdi
leaq 0x60(%rsp), %rsi
callq 0x3de0
jmp 0x43e4
leaq 0x60(%rsp), %rdi
callq 0x34a8
leaq 0x40(%rsp), %rdi
callq 0x34a8
movq 0x1e0(%rsp), %rdi
addq $0x10, %rdi
movq 0xbbad(%rip), %rsi      # 0xffb8
callq 0x32b0
jmp 0x4412
jmp 0x4414
movl 0x84(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0x84(%rsp)
jmp 0x4371
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1b0(%rsp)
movl %eax, 0x1ac(%rsp)
jmp 0x445e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1b0(%rsp)
movl %eax, 0x1ac(%rsp)
leaq 0x60(%rsp), %rdi
callq 0x34a8
leaq 0x40(%rsp), %rdi
callq 0x34a8
jmp 0x4496
leaq 0xf0(%rsp), %rdi
callq 0x5850
leaq 0x140(%rsp), %rdi
callq 0x50a0
leaq 0x168(%rsp), %rdi
callq 0x5860
jmp 0x4093
leaq 0xf0(%rsp), %rdi
callq 0x5850
leaq 0x140(%rsp), %rdi
callq 0x50a0
leaq 0x178(%rsp), %rdi
callq 0x5880
jmp 0x44ec
movl $0x1, 0xbc(%rsp)
leaq 0x178(%rsp), %rdi
callq 0x5880
leaq 0x1b8(%rsp), %rdi
callq 0x34a8
addq $0x1e8, %rsp            # imm = 0x1E8
retq
leaq 0x1b8(%rsp), %rdi
callq 0x34a8
movq 0x1b0(%rsp), %rdi
callq 0x3420
nopw %cs:(%rax,%rax)