// File: /workspace/github_cpp_makefile_star2_O2/andyn[P]libdlmm/dltest.cc
// Function: main
int main(void) {
    Dl dl("./libuseless.so");

    // Reading variables from a dynamic library

    std::cout << "Reading and modifying a local copy of variable in library..."
              << std::endl;
    int my_answer =
        dl.symbol<int>("answer_to_life_the_universe_and_everything");
    my_answer = -1;
    (void)my_answer;
    if (dl.symbol<int>("answer_to_life_the_universe_and_everything") != 42) {
        std::cout << "TEST FAILED: variable was changed inside library."
                  << std::endl;
        return -1;
    }

    std::cout << "Reading and changing a referenced variable in library..."
              << std::endl;
    int &my_better_answer =
        dl.symbol<int>("answer_to_life_the_universe_and_everything");
    if (my_better_answer != 42) {
        std::cout << "TEST FAILED: Expected 42, got " << my_better_answer
                  << std::endl;
        return -1;
    }
    my_better_answer = 11; // This one goes to eleven!
    if (dl.symbol<int>("answer_to_life_the_universe_and_everything") != 11) {
        std::cout << "TEST FAILED: could not change variable inside library."
                  << std::endl;
        return -1;
    }

    // Calling functions from a dynamic library

    std::cout << "Calling function in library... " << std::endl;
    auto print_and_increment =
        dl.symbol<int(std::ostringstream &, std::string const &, int)>(
            "print_and_increment");

    std::string input_string = "Hello World!";
    std::ostringstream output_string;
    int incremented_via_reference =
        print_and_increment(output_string, input_string, 100);
    if (output_string.str() != input_string) {
        std::cout << "TEST FAILED: function did not stream correct value "
                  << "(expected " << input_string << ", got "
                  << output_string.str() << ")." << std::endl;
        return -1;
    }
    if (101 != incremented_via_reference) {
        std::cout << "TEST FAILED: function did not return correct value "
                  << "(expected " << 101 << ", got "
                  << incremented_via_reference << ")." << std::endl;
        return -1;
    }

    // Catching exceptions

    std::cout << "Loading nonexistent library..." << std::endl;
    try {
        Dl dl2("DOES_NOT_EXIST");
        std::cout << "TEST FAILED: nonexistent library did not throw."
                  << std::endl;
        return -1;
    } catch (std::runtime_error &) {
    }

    std::cout << "Loading nonexistent symbol..." << std::endl;
    try {
        std::cout << dl.symbol<int>("DOES_NOT_EXIST");
        std::cout << "TEST FAILED: nonexistent symbol did not throw."
                  << std::endl;
        return -1;
    } catch (std::runtime_error &) {
    }

    std::cout << "Loading nonexistent version of an existing symbol..."
              << std::endl;
    try {
        std::cout << dl.symbol<int>(
            "answer_to_life_the_universe_and_everything", "DOES_NOT_EXIST");
        std::cout << "TEST FAILED: nonexistent version of existing symbol did "
                     "not throw."
                  << std::endl;
        return -1;
    } catch (std::runtime_error &) {
    }

    std::cout << "Done testing." << std::endl;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
subq $0x1f8, %rsp            # imm = 0x1F8
leaq 0xc84(%rip), %rsi       # 0x3004
leaq 0x80(%rsp), %rdi
leaq 0x40(%rsp), %rdx
callq 0x2a20
leaq 0x10(%rsp), %rdi
leaq 0x80(%rsp), %rsi
pushq $0x1
popq %rdx
callq 0x2a5c
leaq 0x80(%rsp), %rdi
callq 0x2090
movq 0x2c15(%rip), %rdi      # 0x4fd0
leaq 0xc52(%rip), %rsi       # 0x3014
callq 0x2150
movq %rax, %rdi
callq 0x20a0
leaq 0xc7b(%rip), %rsi       # 0x3051
leaq 0x80(%rsp), %rdi
leaq 0x40(%rsp), %rdx
callq 0x2a20
leaq 0x10(%rsp), %rdi
leaq 0x80(%rsp), %rsi
callq 0x2b3e
leaq 0x80(%rsp), %rdi
callq 0x2090
leaq 0xc43(%rip), %rsi       # 0x3051
leaq 0x80(%rsp), %rdi
leaq 0x40(%rsp), %rdx
callq 0x2a20
leaq 0x10(%rsp), %rdi
leaq 0x80(%rsp), %rsi
callq 0x2b3e
movl (%rax), %ebp
leaq 0x80(%rsp), %rdi
callq 0x2090
pushq $-0x1
popq %rbx
cmpl $0x2a, %ebp
jne 0x2642
movq 0x2b7c(%rip), %rdi      # 0x4fd0
leaq 0xc53(%rip), %rsi       # 0x30ae
callq 0x2150
movq %rax, %rdi
callq 0x20a0
leaq 0xbe2(%rip), %rsi       # 0x3051
leaq 0x80(%rsp), %rdi
leaq 0x40(%rsp), %rdx
callq 0x2a20
leaq 0x10(%rsp), %rdi
leaq 0x80(%rsp), %rsi
callq 0x2b3e
movq %rax, %r14
leaq 0x80(%rsp), %rdi
callq 0x2090
cmpl $0x2a, (%r14)
jne 0x2662
movl $0xb, (%r14)
leaq 0xb96(%rip), %rsi       # 0x3051
leaq 0x80(%rsp), %rdi
leaq 0x40(%rsp), %rdx
callq 0x2a20
leaq 0x10(%rsp), %rdi
leaq 0x80(%rsp), %rsi
callq 0x2b3e
movl (%rax), %ebp
leaq 0x80(%rsp), %rdi
callq 0x2090
cmpl $0xb, %ebp
jne 0x2682
movq 0x2ad2(%rip), %rdi      # 0x4fd0
leaq 0xc38(%rip), %rsi       # 0x313d
callq 0x2150
movq %rax, %rdi
callq 0x20a0
leaq 0xc44(%rip), %rsi       # 0x315d
leaq 0x80(%rsp), %rdi
leaq 0x40(%rsp), %rdx
callq 0x2a20
leaq 0x10(%rsp), %rdi
leaq 0x80(%rsp), %rsi
callq 0x2c1c
movq %rax, %rbx
leaq 0x80(%rsp), %rdi
callq 0x2090
leaq 0xc1d(%rip), %rsi       # 0x3171
leaq 0x40(%rsp), %rdi
leaq 0x80(%rsp), %rdx
callq 0x2a20
leaq 0x80(%rsp), %rdi
callq 0x2170
leaq 0x80(%rsp), %rdi
leaq 0x40(%rsp), %rsi
pushq $0x64
popq %rdx
callq *%rbx
movl %eax, %ebx
leaq 0x88(%rsp), %r14
leaq 0x20(%rsp), %rdi
movq %r14, %rsi
callq 0x21b0
leaq 0x20(%rsp), %r15
leaq 0x40(%rsp), %rsi
movq %r15, %rdi
callq 0x2cf9
movl %eax, %ebp
movq %r15, %rdi
callq 0x2090
testb %bpl, %bpl
je 0x26a2
movq 0x2a08(%rip), %rdi      # 0x4fd0
leaq 0xbaf(%rip), %rsi       # 0x317e
callq 0x2150
leaq 0xbd7(%rip), %rsi       # 0x31b2
movq %rax, %rdi
callq 0x2150
leaq 0x40(%rsp), %rsi
movq %rax, %rdi
callq 0x2120
leaq 0xb08(%rip), %rsi       # 0x30ff
movq %rax, %rdi
callq 0x2150
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
movq %r14, %rsi
callq 0x21b0
leaq 0x20(%rsp), %rsi
movq %rbx, %rdi
callq 0x2120
leaq 0xb9a(%rip), %rsi       # 0x31bd
movq %rax, %rdi
callq 0x2150
movq %rax, %rdi
callq 0x20a0
leaq 0x20(%rsp), %rdi
callq 0x2090
jmp 0x2778
movq 0x2987(%rip), %rdi      # 0x4fd0
leaq 0xa2c(%rip), %rsi       # 0x307c
callq 0x2150
movq %rax, %rdi
callq 0x20a0
jmp 0x2792
movq 0x2967(%rip), %rdi      # 0x4fd0
leaq 0xa77(%rip), %rsi       # 0x30e7
callq 0x2150
movl (%r14), %esi
movq %rax, %rdi
callq 0x21f0
jmp 0x2695
movq 0x2947(%rip), %rdi      # 0x4fd0
leaq 0xa76(%rip), %rsi       # 0x3106
callq 0x2150
movq %rax, %rdi
callq 0x20a0
jmp 0x2792
cmpl $0x65, %ebx
jne 0x271b
movq 0x2922(%rip), %rdi      # 0x4fd0
leaq 0xb3f(%rip), %rsi       # 0x31f4
callq 0x2150
movq %rax, %rdi
callq 0x20a0
leaq 0xb4a(%rip), %rsi       # 0x3213
leaq 0x20(%rsp), %rdi
leaq 0xf(%rsp), %rdx
callq 0x2a20
leaq 0x60(%rsp), %rdi
leaq 0x20(%rsp), %rsi
pushq $0x1
popq %rdx
callq 0x2a5c
leaq 0x20(%rsp), %rdi
callq 0x2090
movq 0x28d5(%rip), %rdi      # 0x4fd0
leaq 0xb20(%rip), %rsi       # 0x3222
callq 0x2150
movq %rax, %rdi
callq 0x20a0
movq 0x60(%rsp), %rdi
callq 0x20f0
jmp 0x2778
movq 0x28ae(%rip), %rdi      # 0x4fd0
leaq 0xa97(%rip), %rsi       # 0x31c0
callq 0x2150
leaq 0xa7d(%rip), %rsi       # 0x31b2
movq %rax, %rdi
callq 0x2150
pushq $0x65
popq %rsi
movq %rax, %rdi
callq 0x21f0
leaq 0x9b0(%rip), %rsi       # 0x30ff
movq %rax, %rdi
callq 0x2150
movq %rax, %rdi
movl %ebx, %esi
callq 0x21f0
leaq 0xa55(%rip), %rsi       # 0x31bd
movq %rax, %rdi
callq 0x2150
movq %rax, %rdi
callq 0x20a0
pushq $-0x1
popq %rbx
leaq 0x80(%rsp), %rdi
callq 0x2040
leaq 0x40(%rsp), %rdi
callq 0x2090
movq 0x10(%rsp), %rdi
callq 0x20f0
movl %ebx, %eax
addq $0x1f8, %rsp            # imm = 0x1F8
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
movq %rdx, %rbx
movq %rax, %r14
leaq 0x20(%rsp), %rdi
callq 0x2090
jmp 0x27d6
movq %rdx, %rbx
movq %rax, %r14
jmp 0x27d6
movq %rdx, %rbx
movq %rax, %r14
movq 0x60(%rsp), %rdi
callq 0x20f0
cmpl $0x1, %ebx
jne 0x29c3
movq %r14, %rdi
callq 0x2060
callq 0x21d0
movq 0x27dd(%rip), %rdi      # 0x4fd0
leaq 0xa58(%rip), %rsi       # 0x3252
callq 0x2150
movq %rax, %rdi
callq 0x20a0
leaq 0xa05(%rip), %rsi       # 0x3213
leaq 0x20(%rsp), %rdi
leaq 0x60(%rsp), %rdx
callq 0x2a20
leaq 0x10(%rsp), %rdi
leaq 0x20(%rsp), %rsi
callq 0x2b3e
movl (%rax), %esi
movq 0x279b(%rip), %rdi      # 0x4fd0
callq 0x21f0
leaq 0x20(%rsp), %rdi
callq 0x2090
movq 0x2785(%rip), %rdi      # 0x4fd0
leaq 0xa1e(%rip), %rsi       # 0x3270
callq 0x2150
movq %rax, %rdi
callq 0x20a0
jmp 0x2778
jmp 0x286b
jmp 0x29c0
movq %rdx, %r15
movq %rax, %r14
jmp 0x2883
movq %rdx, %r15
movq %rax, %r14
leaq 0x20(%rsp), %rdi
callq 0x2090
cmpl %ebx, %r15d
jne 0x29c3
movq %r14, %rdi
callq 0x2060
callq 0x21d0
movq 0x2730(%rip), %rdi      # 0x4fd0
leaq 0x9f8(%rip), %rsi       # 0x329f
callq 0x2150
movq %rax, %rdi
callq 0x20a0
leaq 0x796(%rip), %rsi       # 0x3051
leaq 0x20(%rsp), %rdi
leaq 0xf(%rsp), %rdx
callq 0x2a20
leaq 0x942(%rip), %rsi       # 0x3213
leaq 0x60(%rsp), %rdi
leaq 0x1f(%rsp), %rdx
callq 0x2a20
leaq 0x10(%rsp), %rdi
leaq 0x20(%rsp), %rsi
leaq 0x60(%rsp), %rdx
callq 0x2d04
movl (%rax), %esi
movq 0x26d3(%rip), %rdi      # 0x4fd0
callq 0x21f0
leaq 0x60(%rsp), %rdi
callq 0x2090
leaq 0x20(%rsp), %rdi
callq 0x2090
movq 0x26b3(%rip), %rdi      # 0x4fd0
leaq 0x9b0(%rip), %rsi       # 0x32d4
callq 0x2150
movq %rax, %rdi
callq 0x20a0
jmp 0x2778
jmp 0x295c
movq %rdx, %r15
movq %rax, %r14
leaq 0x60(%rsp), %rdi
callq 0x2090
jmp 0x2950
movq %rdx, %r15
movq %rax, %r14
leaq 0x20(%rsp), %rdi
callq 0x2090
jmp 0x2962
movq %rdx, %r15
movq %rax, %r14
cmpl %ebx, %r15d
jne 0x29c3
movq %r14, %rdi
callq 0x2060
callq 0x21d0
movq 0x2655(%rip), %rdi      # 0x4fd0
leaq 0x995(%rip), %rsi       # 0x3317
callq 0x2150
xorl %ebx, %ebx
movq %rax, %rdi
callq 0x20a0
jmp 0x277b
jmp 0x29c0
jmp 0x29c0
jmp 0x29c0
jmp 0x29c0
movq %rax, %r14
jmp 0x29d0
jmp 0x2a0a
jmp 0x29db
jmp 0x2a0a
movq %rax, %r14
leaq 0x20(%rsp), %rdi
callq 0x2090
jmp 0x29c3
jmp 0x29db
jmp 0x2a0a
jmp 0x29db
jmp 0x2a0a
movq %rax, %r14
leaq 0x80(%rsp), %rdi
callq 0x2040
leaq 0x40(%rsp), %rdi
jmp 0x29e6
jmp 0x29db
jmp 0x2a0a
movq %rax, %r14
leaq 0x80(%rsp), %rdi
callq 0x2090
jmp 0x2a0d
jmp 0x2a0a
movq %rax, %r14
leaq 0x80(%rsp), %rdi
callq 0x2090
jmp 0x2a17
movq %rax, %r14
jmp 0x2a17
jmp 0x2a0a
jmp 0x2a0a
movq %rax, %r14
movq 0x10(%rsp), %rdi
callq 0x20f0
movq %r14, %rdi
callq 0x2200
nop