// File: /workspace/github_cpp_makefile_star2_O2/klmr[P]multifunction/example.cpp
// Function: main
int main() {
    static_assert(
        std::is_same<
            util::multifunction<void(int)>::argument_type,
            int
        >::value,
        "util::multifunction member types are wrong");

    util::multifunction<void(int)> event;

    cout << "Adding f, g, h\n";
    auto f_tok = event += f;
    auto g_tok = event += g();
    auto h_tok = event += h;

    event(1);

    cout << "\nRemoving g\n";
    event -= g_tok;
    event(2);

    cout << "\nRemoving h\n";
    event -= h_tok;
    event(3);

    cout << "\nRemoving g (again!)\n";
    event -= g_tok;
    event(4);

    cout << "\nRemoving f\n";
    event -= f_tok;
    event(5);

    cout << "\nOnce more, with lambdas\n";
    event += [](int n) { cout << "[](" << n << ")\n"; };
    event += [=](int n) { cout << "[=](" << n << ")\n"; };
    event += [&](int n) { cout << "[&](" << n << ")\n"; };
    int n = 6;
    event(n);
}

// Assembly:
pushq %rbp
pushq %r14
pushq %rbx
subq $0x50, %rsp
xorps %xmm0, %xmm0
movaps %xmm0, 0x40(%rsp)
movaps %xmm0, 0x30(%rsp)
movaps %xmm0, 0x20(%rsp)
movq 0x2d05(%rip), %rdi      # 0x3fd8
leaq 0xd30(%rip), %rsi       # 0x200a
callq 0x10a0
leaq -0x9a(%rip), %rsi       # 0x124c
leaq 0x20(%rsp), %rdi
callq 0x1722
movl %eax, %ebx
leaq 0x20(%rsp), %rdi
callq 0x1b52
movl %eax, %ebp
leaq -0x89(%rip), %rsi       # 0x127c
leaq 0x20(%rsp), %rdi
callq 0x1c28
movl %eax, %r14d
movq %rsp, %rsi
movl $0x1, (%rsi)
leaq 0x20(%rsp), %rdi
callq 0x1ce4
movq 0x2cac(%rip), %rdi      # 0x3fd8
leaq 0xce7(%rip), %rsi       # 0x201a
callq 0x10a0
leaq 0x20(%rsp), %rdi
movl %ebp, %esi
callq 0x1daa
movq %rsp, %rsi
movl $0x2, (%rsi)
leaq 0x20(%rsp), %rdi
callq 0x1ce4
movq 0x2c7a(%rip), %rdi      # 0x3fd8
leaq 0xcc2(%rip), %rsi       # 0x2027
callq 0x10a0
leaq 0x20(%rsp), %rdi
movl %r14d, %esi
callq 0x1daa
movq %rsp, %rsi
movl $0x3, (%rsi)
leaq 0x20(%rsp), %rdi
callq 0x1ce4
movq 0x2c47(%rip), %rdi      # 0x3fd8
leaq 0xc9c(%rip), %rsi       # 0x2034
callq 0x10a0
leaq 0x20(%rsp), %rdi
movl %ebp, %esi
callq 0x1daa
movq %rsp, %rsi
movl $0x4, (%rsi)
leaq 0x20(%rsp), %rdi
callq 0x1ce4
movq 0x2c15(%rip), %rdi      # 0x3fd8
leaq 0xc80(%rip), %rsi       # 0x204a
callq 0x10a0
leaq 0x20(%rsp), %rdi
movl %ebx, %esi
callq 0x1daa
movq %rsp, %rsi
movl $0x5, (%rsi)
leaq 0x20(%rsp), %rdi
callq 0x1ce4
movq 0x2be3(%rip), %rdi      # 0x3fd8
leaq 0xc5b(%rip), %rsi       # 0x2057
callq 0x10a0
xorps %xmm0, %xmm0
movq %rsp, %rsi
movaps %xmm0, (%rsi)
leaq 0x14d(%rip), %rax       # 0x155e
movq %rax, 0x18(%rsi)
leaq 0x172(%rip), %rax       # 0x158e
movq %rax, 0x10(%rsi)
leaq 0x20(%rsp), %rdi
callq 0x17b6
movq %rsp, %r14
movq %r14, %rdi
callq 0x16f0
leaq 0x38(%rsp), %rbx
movq -0x10(%rbx), %rax
subq -0x18(%rbx), %rax
sarq $0x5, %rax
decq %rax
movq %rax, (%r14)
movq %rsp, %rsi
movq %rbx, %rdi
callq 0x19d8
xorps %xmm0, %xmm0
movq %rsp, %rsi
movaps %xmm0, (%rsi)
leaq 0x13f(%rip), %rax       # 0x15a6
movq %rax, 0x18(%rsi)
leaq 0x164(%rip), %rax       # 0x15d6
movq %rax, 0x10(%rsi)
leaq 0x20(%rsp), %rdi
callq 0x17b6
movq %rsp, %r14
movq %r14, %rdi
callq 0x16f0
movq 0x28(%rsp), %rax
subq 0x20(%rsp), %rax
sarq $0x5, %rax
decq %rax
movq %rax, (%r14)
movq %rsp, %rsi
movq %rbx, %rdi
callq 0x19d8
xorps %xmm0, %xmm0
movq %rsp, %rsi
movaps %xmm0, (%rsi)
leaq 0x134(%rip), %rax       # 0x15ee
movq %rax, 0x18(%rsi)
leaq 0x159(%rip), %rax       # 0x161e
movq %rax, 0x10(%rsi)
leaq 0x20(%rsp), %rdi
callq 0x17b6
movq %rsp, %r14
movq %r14, %rdi
callq 0x16f0
movq 0x28(%rsp), %rax
subq 0x20(%rsp), %rax
sarq $0x5, %rax
decq %rax
movq %rax, (%r14)
movq %rsp, %rsi
movq %rbx, %rdi
callq 0x19d8
movq %rsp, %rsi
movl $0x6, (%rsi)
leaq 0x20(%rsp), %rdi
callq 0x1ef8
leaq 0x20(%rsp), %rdi
callq 0x1636
xorl %eax, %eax
addq $0x50, %rsp
popq %rbx
popq %r14
popq %rbp
retq
jmp 0x1548
jmp 0x152b
jmp 0x152b
movq %rax, %rbx
movq %rsp, %rdi
callq 0x16f0
jmp 0x154b
jmp 0x1548
jmp 0x1548
jmp 0x1548
jmp 0x1548
jmp 0x1548
jmp 0x1548
jmp 0x1548
jmp 0x1548
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
callq 0x1636
movq %rbx, %rdi
callq 0x1110
nop