// File: f18m[P]boost-intrusive-pool/tests/tutorial.cpp
// Function: showcase_boost_intrusive_pool()
void showcase_boost_intrusive_pool()
{
    print_header();

    {
        std::cout << "  Now allocating a new memorypool::boost_intrusive_pool<>. A large malloc will happen."
                  << std::endl;

        memorypool::boost_intrusive_pool<DummyClass> pool(4, 1);
        // you will see a memory malloc traced when running this line

        std::cout << "  Boost Intrusive Pool for DummyClass has size: " << sizeof(pool) << std::endl;

        {
            std::cout << "  Now allocating dummy class of size: " << sizeof(DummyClass)
                      << " from the memory pool. This time no mallocs will happen!" << std::endl;
            boost::intrusive_ptr<DummyClass> hdummy = pool.allocate();

            // of course copying pointers around does not trigger any memory allocation:
            boost::intrusive_ptr<DummyClass> hdummy2 = hdummy;
            std::cout << "  Value from allocated dummy class constructed via default ctor: " << hdummy2->dummy()
                      << std::endl;

            observe_pool(pool);

            std::cout << "  Going to release the references to the boost::intrusive_ptr<> created so far. This time no "
                         "free() will happen!"
                      << std::endl;

        } // this time no memory free() will happen!

        observe_pool(pool);

        std::cout << "  Going to release the whole memory pool. You will see a bunch of dtor and memory free happen!"
                  << std::endl;
    } // you will see a memory free traced when running this line

    print_header();

    // now showcase a memory pool of objects having the following class hierarchy:
    //   boost_intrusive_pool_item
    //   \--- DummyClass
    //        \--- DummyDerivedClass

    {
        std::cout << "  Now allocating a new memorypool::boost_intrusive_pool<>. A large malloc will happen."
                  << std::endl;
        memorypool::boost_intrusive_pool<DummyDerivedClass> pool(4, 1);

        {
            std::cout << "  Now allocating derived dummy class of size: " << sizeof(DummyDerivedClass)
                      << " from the memory pool. This time no mallocs will happen but the ctor will get called again!"
                      << std::endl;

            size_t initializer_value = 3;

            auto custom_init_fn
                = [&initializer_value](DummyDerivedClass& object) { object.yet_another_init_fun(initializer_value); };

            // just for fun this time we allocate the object using non-default constructor:
            boost::intrusive_ptr<DummyDerivedClass> hdummy = pool.allocate_through_function(custom_init_fn);

            std::cout << "  Value from allocated dummy class constructed via NON default ctor: " << hdummy->dummy()
                      << std::endl;

            observe_pool(pool);

            std::cout << "  Going to release the references to the boost::intrusive_ptr<> created so far. This time no "
                         "free() will happen, just a dtor call!"
                      << std::endl;

        } // this time no memory free() will happen!

        observe_pool(pool);

        std::cout << "  Going to release the whole memory pool. You will see a bunch of dtor and memory free happen!"
                  << std::endl;
    } // you will see a memory free traced when running this line

    std::cout << "Note that the overhead of memory pool support is sizeof(memorypool::boost_intrusive_pool_item)="
              << sizeof(memorypool::boost_intrusive_pool_item) << "bytes" << std::endl;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x180, %rsp            # imm = 0x180
callq 0x2490
movq 0xc691(%rip), %rdi      # 0xefd8
leaq 0x6945(%rip), %rsi      # 0x9293
callq 0x20f0
movq %rax, %rdi
movq 0xc663(%rip), %rsi      # 0xefc0
callq 0x2100
xorl %eax, %eax
movl %eax, -0xc4(%rbp)
movl %eax, %esi
movq %rsi, -0xd0(%rbp)
leaq -0x30(%rbp), %rdi
movq %rdi, -0xc0(%rbp)
callq 0x3670
movq -0xd0(%rbp), %rcx
movl -0xc4(%rbp), %r8d
movq -0xc0(%rbp), %r9
leaq -0x10(%rbp), %rdi
movl $0x4, %esi
movl $0x1, %edx
callq 0x36b0
jmp 0x29ad
leaq -0x30(%rbp), %rdi
callq 0x37a0
movq 0xc61b(%rip), %rdi      # 0xefd8
leaq 0x6926(%rip), %rsi      # 0x92ea
callq 0x20f0
movq %rax, -0xd8(%rbp)
jmp 0x29d2
movq -0xd8(%rbp), %rdi
movl $0x10, %esi
callq 0x2040
movq %rax, -0xe0(%rbp)
jmp 0x29ec
movq -0xe0(%rbp), %rdi
movq 0xc5c6(%rip), %rsi      # 0xefc0
callq 0x2100
jmp 0x2a01
movq 0xc5d0(%rip), %rdi      # 0xefd8
leaq 0x66f6(%rip), %rsi      # 0x9105
callq 0x20f0
movq %rax, -0xe8(%rbp)
jmp 0x2a1d
movq -0xe8(%rbp), %rdi
movl $0x420, %esi            # imm = 0x420
callq 0x2040
movq %rax, -0xf0(%rbp)
jmp 0x2a37
movq -0xf0(%rbp), %rdi
leaq 0x68d6(%rip), %rsi      # 0x931b
callq 0x20f0
movq %rax, -0xf8(%rbp)
jmp 0x2a53
movq -0xf8(%rbp), %rdi
movq 0xc55f(%rip), %rsi      # 0xefc0
callq 0x2100
jmp 0x2a68
leaq -0x48(%rbp), %rdi
leaq -0x10(%rbp), %rsi
callq 0x37c0
jmp 0x2a77
leaq -0x50(%rbp), %rdi
leaq -0x48(%rbp), %rsi
callq 0x3550
jmp 0x2a86
movq 0xc54b(%rip), %rdi      # 0xefd8
leaq 0x68c0(%rip), %rsi      # 0x9354
callq 0x20f0
movq %rax, -0x100(%rbp)
jmp 0x2aa2
leaq -0x50(%rbp), %rdi
callq 0x3590
movq %rax, %rdi
movq (%rdi), %rax
movq 0x18(%rax), %rax
callq *%rax
movb %al, -0x101(%rbp)
jmp 0x2abf
movq -0x100(%rbp), %rdi
movb -0x101(%rbp), %al
movsbl %al, %esi
callq 0x2120
movq %rax, -0x110(%rbp)
jmp 0x2add
movq -0x110(%rbp), %rdi
movq 0xc4d5(%rip), %rsi      # 0xefc0
callq 0x2100
jmp 0x2af2
leaq -0x10(%rbp), %rdi
callq 0x38c0
jmp 0x2afd
movq 0xc4d4(%rip), %rdi      # 0xefd8
leaq 0x688b(%rip), %rsi      # 0x9396
callq 0x20f0
movq %rax, -0x118(%rbp)
jmp 0x2b19
movq -0x118(%rbp), %rdi
movq 0xc499(%rip), %rsi      # 0xefc0
callq 0x2100
jmp 0x2b2e
leaq -0x50(%rbp), %rdi
callq 0x3630
leaq -0x48(%rbp), %rdi
callq 0x3630
leaq -0x10(%rbp), %rdi
callq 0x38c0
jmp 0x2b4b
movq 0xc486(%rip), %rdi      # 0xefd8
leaq 0x68ae(%rip), %rsi      # 0x9407
callq 0x20f0
movq %rax, -0x120(%rbp)
jmp 0x2b67
movq -0x120(%rbp), %rdi
movq 0xc44b(%rip), %rsi      # 0xefc0
callq 0x2100
jmp 0x2b7c
leaq -0x10(%rbp), %rdi
callq 0x3960
callq 0x2490
movq 0xc447(%rip), %rdi      # 0xefd8
leaq 0x66fb(%rip), %rsi      # 0x9293
callq 0x20f0
movq %rax, %rdi
movq 0xc419(%rip), %rsi      # 0xefc0
callq 0x2100
xorl %eax, %eax
movl %eax, -0x12c(%rbp)
movl %eax, %esi
movq %rsi, -0x138(%rbp)
leaq -0x80(%rbp), %rdi
movq %rdi, -0x128(%rbp)
callq 0x39d0
movq -0x138(%rbp), %rcx
movl -0x12c(%rbp), %r8d
movq -0x128(%rbp), %r9
leaq -0x60(%rbp), %rdi
movl $0x4, %esi
movl $0x1, %edx
callq 0x3a10
jmp 0x2bf7
leaq -0x80(%rbp), %rdi
callq 0x3b00
movq 0xc3d1(%rip), %rdi      # 0xefd8
leaq 0x6858(%rip), %rsi      # 0x9466
callq 0x20f0
movq %rax, -0x140(%rbp)
jmp 0x2c1c
movq -0x140(%rbp), %rdi
movl $0x4420, %esi           # imm = 0x4420
callq 0x2040
movq %rax, -0x148(%rbp)
jmp 0x2c36
movq -0x148(%rbp), %rdi
leaq 0x6851(%rip), %rsi      # 0x9495
callq 0x20f0
movq %rax, -0x150(%rbp)
jmp 0x2c52
movq -0x150(%rbp), %rdi
movq 0xc360(%rip), %rsi      # 0xefc0
callq 0x2100
jmp 0x2c67
movq $0x3, -0x88(%rbp)
leaq -0x88(%rbp), %rax
movq %rax, -0x90(%rbp)
leaq -0xb8(%rbp), %rdi
movq %rdi, -0x158(%rbp)
leaq -0x90(%rbp), %rsi
callq 0x2ed0
movq -0x158(%rbp), %rdx
leaq -0x98(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0x3b20
jmp 0x2cb3
leaq -0xb8(%rbp), %rdi
callq 0x3b00
movq 0xc312(%rip), %rdi      # 0xefd8
leaq 0x6824(%rip), %rsi      # 0x94f1
callq 0x20f0
movq %rax, -0x160(%rbp)
jmp 0x2cdb
leaq -0x98(%rbp), %rdi
callq 0x3c80
movq %rax, %rdi
movq (%rdi), %rax
movq 0x18(%rax), %rax
callq *%rax
movb %al, -0x161(%rbp)
jmp 0x2cfb
movq -0x160(%rbp), %rdi
movb -0x161(%rbp), %al
movsbl %al, %esi
callq 0x2120
movq %rax, -0x170(%rbp)
jmp 0x2d19
movq -0x170(%rbp), %rdi
movq 0xc299(%rip), %rsi      # 0xefc0
callq 0x2100
jmp 0x2d2e
leaq -0x60(%rbp), %rdi
callq 0x3cd0
jmp 0x2d39
movq 0xc298(%rip), %rdi      # 0xefd8
leaq 0x67f0(%rip), %rsi      # 0x9537
callq 0x20f0
movq %rax, -0x178(%rbp)
jmp 0x2d55
movq -0x178(%rbp), %rdi
movq 0xc25d(%rip), %rsi      # 0xefc0
callq 0x2100
jmp 0x2d6a
leaq -0x98(%rbp), %rdi
callq 0x3d70
leaq -0x60(%rbp), %rdi
callq 0x3cd0
jmp 0x2d81
movq 0xc250(%rip), %rdi      # 0xefd8
leaq 0x6678(%rip), %rsi      # 0x9407
callq 0x20f0
movq %rax, -0x180(%rbp)
jmp 0x2d9d
movq -0x180(%rbp), %rdi
movq 0xc215(%rip), %rsi      # 0xefc0
callq 0x2100
jmp 0x2db2
leaq -0x60(%rbp), %rdi
callq 0x3db0
movq 0xc216(%rip), %rdi      # 0xefd8
leaq 0x67f1(%rip), %rsi      # 0x95ba
callq 0x20f0
movq %rax, %rdi
movl $0x20, %esi
callq 0x2040
movq %rax, %rdi
leaq 0x6835(%rip), %rsi      # 0x961a
callq 0x20f0
movq %rax, %rdi
movq 0xc1cc(%rip), %rsi      # 0xefc0
callq 0x2100
addq $0x180, %rsp            # imm = 0x180
popq %rbp
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
leaq -0x30(%rbp), %rdi
callq 0x37a0
jmp 0x2ec1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
jmp 0x2e56
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
jmp 0x2e4d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
leaq -0x50(%rbp), %rdi
callq 0x3630
leaq -0x48(%rbp), %rdi
callq 0x3630
leaq -0x10(%rbp), %rdi
callq 0x3960
jmp 0x2ec1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
leaq -0x80(%rbp), %rdi
callq 0x3b00
jmp 0x2ec1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
jmp 0x2eb8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
leaq -0xb8(%rbp), %rdi
callq 0x3b00
jmp 0x2eb8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
leaq -0x98(%rbp), %rdi
callq 0x3d70
leaq -0x60(%rbp), %rdi
callq 0x3db0
movq -0x38(%rbp), %rdi
callq 0x2190
nopw (%rax,%rax)