// File: arturb-dev[P]CPP-Dynamic-Class-Loading/main.cpp
// Function: main
int main(void) {

    auto dlTriangle = new DLClass<Polygon>("./triangle.so");
    auto dlSquare = new DLClass<Polygon>("./square.so");
    
    int x = 5;
    std::shared_ptr<Polygon> triangle = dlTriangle->make_obj(3);
    std::shared_ptr<Polygon> square = dlSquare->make_obj(x);
    delete dlTriangle;
    delete dlSquare;
    
    if(!triangle) {
        std::cerr << "Failed to instantiate a triangle." << std::endl;
        return 1;
    }

    std::cout << "Triangle area: " << triangle->area() << std::endl;
    triangle = std::shared_ptr<Polygon>(NULL);
    
    if(!square) {
        std::cerr << "Failed to instantiate a triangle." << std::endl;
        return 1;
    }

    std::cout << "Square area: " << square->area() << std::endl;
    square = std::shared_ptr<Polygon>(NULL);

    
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x130, %rsp            # imm = 0x130
movl $0x0, -0x4(%rbp)
movl $0x30, %edi
callq 0x2110
movq %rax, -0xd0(%rbp)
movb $0x1, -0x45(%rbp)
leaq -0x31(%rbp), %rdi
movq %rdi, -0xc8(%rbp)
callq 0x21b0
movq -0xc8(%rbp), %rdx
leaq 0x2caf(%rip), %rsi      # 0x5004
leaq -0x30(%rbp), %rdi
callq 0x2140
jmp 0x2360
movq -0xd0(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0x2780
jmp 0x2372
movb $0x0, -0x45(%rbp)
leaq -0x30(%rbp), %rdi
callq 0x2090
leaq -0x31(%rbp), %rdi
callq 0x2130
movq -0xd0(%rbp), %rax
movq %rax, -0x10(%rbp)
movl $0x30, %edi
callq 0x2110
movq %rax, -0xe0(%rbp)
movb $0x1, -0x72(%rbp)
leaq -0x71(%rbp), %rdi
movq %rdi, -0xd8(%rbp)
callq 0x21b0
movq -0xd8(%rbp), %rdx
leaq 0x2c4c(%rip), %rsi      # 0x5012
leaq -0x70(%rbp), %rdi
callq 0x2140
jmp 0x23d1
movq -0xe0(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0x2780
jmp 0x23e3
movb $0x0, -0x72(%rbp)
leaq -0x70(%rbp), %rdi
callq 0x2090
leaq -0x71(%rbp), %rdi
callq 0x2130
movq -0xe0(%rbp), %rax
movq %rax, -0x50(%rbp)
movl $0x5, -0x78(%rbp)
movq -0x10(%rbp), %rsi
leaq -0x88(%rbp), %rdi
movl $0x3, %edx
callq 0x2810
movq -0x50(%rbp), %rsi
movl -0x78(%rbp), %edx
leaq -0x98(%rbp), %rdi
callq 0x2810
jmp 0x2435
movq -0x10(%rbp), %rax
movq %rax, -0xe8(%rbp)
cmpq $0x0, %rax
je 0x245e
movq -0xe8(%rbp), %rdi
callq 0x29b0
movq -0xe8(%rbp), %rdi
callq 0x20f0
movq -0x50(%rbp), %rax
movq %rax, -0xf0(%rbp)
cmpq $0x0, %rax
je 0x2487
movq -0xf0(%rbp), %rdi
callq 0x29b0
movq -0xf0(%rbp), %rdi
callq 0x20f0
leaq -0x88(%rbp), %rdi
callq 0x29e0
testb $0x1, %al
jne 0x259a
movq 0x5b4e(%rip), %rdi      # 0x7ff0
leaq 0x2b75(%rip), %rsi      # 0x501e
callq 0x2100
movq %rax, -0xf8(%rbp)
jmp 0x24b7
movq -0xf8(%rbp), %rdi
movq 0x5af3(%rip), %rsi      # 0x7fb8
callq 0x2120
jmp 0x24cc
movl $0x1, -0x4(%rbp)
movl $0x1, -0x9c(%rbp)
jmp 0x2739
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x2505
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x30(%rbp), %rdi
callq 0x2090
leaq -0x31(%rbp), %rdi
callq 0x2130
testb $0x1, -0x45(%rbp)
jne 0x2516
jmp 0x2522
movq -0xd0(%rbp), %rdi
callq 0x20f0
jmp 0x2769
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x254a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x70(%rbp), %rdi
callq 0x2090
leaq -0x71(%rbp), %rdi
callq 0x2130
testb $0x1, -0x72(%rbp)
jne 0x255b
jmp 0x2567
movq -0xe0(%rbp), %rdi
callq 0x20f0
jmp 0x2769
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x275d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x98(%rbp), %rdi
callq 0x2a70
jmp 0x275d
movq 0x5a2f(%rip), %rdi      # 0x7fd0
leaq 0x2a98(%rip), %rsi      # 0x5040
callq 0x2100
movq %rax, -0x100(%rbp)
jmp 0x25b6
leaq -0x88(%rbp), %rdi
callq 0x2a00
movq %rax, %rdi
movq (%rdi), %rax
movq 0x10(%rax), %rax
callq *%rax
movsd %xmm0, -0x108(%rbp)
jmp 0x25d8
movsd -0x108(%rbp), %xmm0
movq -0x100(%rbp), %rdi
callq 0x21c0
movq %rax, -0x110(%rbp)
jmp 0x25f5
movq -0x110(%rbp), %rdi
movq 0x59b5(%rip), %rsi      # 0x7fb8
callq 0x2120
jmp 0x260a
leaq -0xb0(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x2a20
leaq -0x88(%rbp), %rdi
leaq -0xb0(%rbp), %rsi
callq 0x2a40
leaq -0xb0(%rbp), %rdi
callq 0x2a70
leaq -0x98(%rbp), %rdi
callq 0x29e0
testb $0x1, %al
jne 0x2690
movq 0x59a0(%rip), %rdi      # 0x7ff0
leaq 0x29c7(%rip), %rsi      # 0x501e
callq 0x2100
movq %rax, -0x118(%rbp)
jmp 0x2665
movq -0x118(%rbp), %rdi
movq 0x5945(%rip), %rsi      # 0x7fb8
callq 0x2120
jmp 0x267a
movl $0x1, -0x4(%rbp)
movl $0x1, -0x9c(%rbp)
jmp 0x2739
movq 0x5939(%rip), %rdi      # 0x7fd0
leaq 0x29b2(%rip), %rsi      # 0x5050
callq 0x2100
movq %rax, -0x120(%rbp)
jmp 0x26ac
leaq -0x98(%rbp), %rdi
callq 0x2a00
movq %rax, %rdi
movq (%rdi), %rax
movq 0x10(%rax), %rax
callq *%rax
movsd %xmm0, -0x128(%rbp)
jmp 0x26ce
movsd -0x128(%rbp), %xmm0
movq -0x120(%rbp), %rdi
callq 0x21c0
movq %rax, -0x130(%rbp)
jmp 0x26eb
movq -0x130(%rbp), %rdi
movq 0x58bf(%rip), %rsi      # 0x7fb8
callq 0x2120
jmp 0x2700
leaq -0xc0(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x2a20
leaq -0x98(%rbp), %rdi
leaq -0xc0(%rbp), %rsi
callq 0x2a40
leaq -0xc0(%rbp), %rdi
callq 0x2a70
movl $0x0, -0x9c(%rbp)
leaq -0x98(%rbp), %rdi
callq 0x2a70
leaq -0x88(%rbp), %rdi
callq 0x2a70
movl -0x4(%rbp), %eax
addq $0x130, %rsp            # imm = 0x130
popq %rbp
retq
leaq -0x88(%rbp), %rdi
callq 0x2a70
movq -0x40(%rbp), %rdi
callq 0x21a0
nopw %cs:(%rax,%rax)
nopl (%rax)