// File: reddragon[P]packed-memory-array/impl1.cpp
// Function: PackedMemoryArray<int>::PackedMemoryArray(int)
PackedMemoryArray<E>::PackedMemoryArray(E e) : t_0(VAL_T_0), t_l(VAL_T_L), c(VAL_C) {
    // Assert that c is a power of 2 and > 1
#ifndef OPTIMIZE
    assert(c > 1 && !(c & (c-1)));
#endif
    s = 0;
    // Get the new store
    store.resize(c*1);
    // Resize the bitmask as well
    exists.resize((size_t)ceil(c));
    insert_element_at(e, 0);
    
    // One liner log2 since c is a power of 2 :-P
    int log2n = __builtin_popcount(store.size()-1);
    if(log2n & (log2n-1)) {
        // log2n is not a power of 2, round it up to the nearest power of 2.
        segment_size = (int)floor(log2(1<<(log2n+1)));
    }
    else {
        // log2n is a power of 2, so, all is fine.
        segment_size = log2n;
    }
    l = log2n - log2(segment_size);

    // Now assert that the upper thresholds are sane, and you do not go out of balance the very first time.
#ifndef OPTIMIZE
    assert(!is_too_full());
#endif
    // And we have set this thing in motion. Pray!
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x28(%rbp)
movq %rdi, %rax
movq %rax, -0x38(%rbp)
callq 0x16f0
movq -0x28(%rbp), %rdi
addq $0x18, %rdi
movq %rdi, -0x30(%rbp)
callq 0x1710
movq -0x28(%rbp), %rdi
movabsq $0x3ff0000000000000, %rax # imm = 0x3FF0000000000000
movq %rax, 0x40(%rdi)
movabsq $0x3fe0000000000000, %rax # imm = 0x3FE0000000000000
movq %rax, 0x48(%rdi)
movl $0x2, 0x50(%rdi)
movl $0x0, 0x58(%rdi)
movslq 0x50(%rdi), %rsi
callq 0x1730
jmp 0x147d
movq -0x38(%rbp), %rax
movq %rax, %rcx
addq $0x18, %rcx
movq %rcx, -0x40(%rbp)
cvtsi2sdl 0x50(%rax), %xmm0
callq 0x1030
movq -0x40(%rbp), %rdi
movsd 0x5b6e(%rip), %xmm2     # 0x7010
movaps %xmm0, %xmm1
subsd %xmm2, %xmm1
cvttsd2si %xmm1, %rax
cvttsd2si %xmm0, %rsi
movq %rsi, %rcx
sarq $0x3f, %rcx
andq %rcx, %rax
orq %rax, %rsi
xorl %edx, %edx
callq 0x17c0
jmp 0x14c9
movq -0x38(%rbp), %rdi
movl -0xc(%rbp), %esi
xorl %edx, %edx
callq 0x18e0
jmp 0x14d9
movq -0x38(%rbp), %rdi
callq 0x1950
subq $0x1, %rax
movl %eax, %ecx
movl %ecx, %eax
shrl %eax
andl $0x55555555, %eax       # imm = 0x55555555
subl %eax, %ecx
movl %ecx, %eax
andl $0x33333333, %eax       # imm = 0x33333333
shrl $0x2, %ecx
andl $0x33333333, %ecx       # imm = 0x33333333
addl %ecx, %eax
movl %eax, %ecx
shrl $0x4, %ecx
addl %ecx, %eax
andl $0xf0f0f0f, %eax        # imm = 0xF0F0F0F
imull $0x1010101, %eax, %eax  # imm = 0x1010101
shrl $0x18, %eax
movl %eax, -0x20(%rbp)
movl -0x20(%rbp), %eax
movl -0x20(%rbp), %ecx
subl $0x1, %ecx
andl %ecx, %eax
cmpl $0x0, %eax
je 0x1575
movl -0x20(%rbp), %ecx
addl $0x1, %ecx
movl $0x1, %eax
shll %cl, %eax
cvtsi2sd %eax, %xmm0
callq 0x1180
callq 0x1160
movq -0x38(%rbp), %rax
cvttsd2si %xmm0, %ecx
movl %ecx, 0x5c(%rax)
jmp 0x157f
movq -0x30(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
callq 0x1970
movq -0x28(%rbp), %rdi
callq 0x1990
jmp 0x15b4
movq -0x38(%rbp), %rax
movl -0x20(%rbp), %ecx
movl %ecx, 0x5c(%rax)
movq -0x38(%rbp), %rax
cvtsi2sdl -0x20(%rbp), %xmm0
movsd %xmm0, -0x48(%rbp)
cvtsi2sdl 0x5c(%rax), %xmm0
callq 0x1180
movq -0x38(%rbp), %rax
movaps %xmm0, %xmm1
movsd -0x48(%rbp), %xmm0
subsd %xmm1, %xmm0
cvttsd2si %xmm0, %ecx
movl %ecx, 0x54(%rax)
addq $0x50, %rsp
popq %rbp
retq
movq -0x18(%rbp), %rdi
callq 0x1170
nopl (%rax)