// File: Baobaobear[P]sort/./sortlib.hpp
// Function: void baobao::internal::merge_sort_with_buffer<false, baobao::TestClass*, std::less<baobao::TestClass>>(baobao::TestClass*, baobao::TestClass*, std::less<baobao::TestClass>, bool)
void merge_sort_with_buffer(RandomAccessIterator beg, RandomAccessIterator end, Comp compare, bool buffered)
{
    if (end - beg > 1)
    {
        typedef typename std::iterator_traits<RandomAccessIterator>::value_type value_type;
        if (buffered)
        {
            if ((end - beg) / 2 * sizeof(value_type) <= merge_sort_stack_buffer_size)
            {
                value_type buf[merge_sort_stack_buffer_size / sizeof(value_type)];
                merge_sort_recursive<safecopy>(buf, beg, end, compare);
            }
            else if (merge_sort_alloc_buffer)
            {
                size_t bufsize = (size_t)sqrt(end - beg + 0.1);
                value_type * buf = new value_type[bufsize];
                merge_sort_recursive_with_buffer<safecopy>(buf, bufsize, beg, end, compare);
                delete[] buf;
            }
            else
            {
                // not really in-place, uses a fixed size of buffer in stack
                value_type buf[merge_sort_stack_buffer_size / sizeof(value_type)];
                merge_sort_recursive_with_buffer<safecopy>(buf, sizeof(buf) / sizeof(value_type), beg, end, compare);
            }
        }
        else
        {
            merge_sort_recursive_with_buffer<false>((value_type*)NULL, 0, beg, end, compare);
        }
    }
}

// Assembly:
subq $0x4098, %rsp           # imm = 0x4098
movb %dl, %al
movq %rdi, 0x4088(%rsp)
movq %rsi, 0x4080(%rsp)
andb $0x1, %al
movb %al, 0x407f(%rsp)
movq 0x4080(%rsp), %rax
movq 0x4088(%rsp), %rcx
subq %rcx, %rax
sarq $0x5, %rax
cmpq $0x1, %rax
jle 0xe567
testb $0x1, 0x407f(%rsp)
je 0xe549
movq 0x4080(%rsp), %rax
movq 0x4088(%rsp), %rcx
subq %rcx, %rax
sarq $0x5, %rax
movl $0x2, %ecx
cqto
idivq %rcx
shlq $0x5, %rax
cmpq $0x4000, %rax           # imm = 0x4000
ja 0xe40d
leaq 0x70(%rsp), %rax
movq %rax, %rcx
addq $0x4000, %rcx           # imm = 0x4000
movq %rcx, 0x38(%rsp)
movq %rax, 0x40(%rsp)
movq 0x40(%rsp), %rdi
movq %rdi, 0x30(%rsp)
callq 0x61b0
movq 0x30(%rsp), %rax
movq 0x38(%rsp), %rcx
addq $0x20, %rax
cmpq %rcx, %rax
movq %rax, 0x40(%rsp)
jne 0xe3c7
leaq 0x70(%rsp), %rdi
movq 0x4088(%rsp), %rsi
movq 0x4080(%rsp), %rdx
callq 0xd6a0
jmp 0xe547
movq 0x4080(%rsp), %rax
movq 0x4088(%rsp), %rcx
subq %rcx, %rax
sarq $0x5, %rax
cvtsi2sd %rax, %xmm0
movsd 0x18bdf(%rip), %xmm1    # 0x27010
addsd %xmm1, %xmm0
callq 0x2160
movaps %xmm0, %xmm1
cvttsd2si %xmm1, %rax
movq %rax, %rdx
sarq $0x3f, %rdx
movsd 0x18bc7(%rip), %xmm1    # 0x27018
subsd %xmm1, %xmm0
cvttsd2si %xmm0, %rcx
andq %rdx, %rcx
orq %rcx, %rax
movq %rax, 0x60(%rsp)
movq 0x60(%rsp), %rax
movq %rax, 0x20(%rsp)
movl $0x20, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0x2030
movq %rax, %rcx
movq 0x20(%rsp), %rax
movq %rcx, 0x28(%rsp)
cmpq $0x0, %rax
je 0xe4ea
movq 0x28(%rsp), %rax
movq 0x20(%rsp), %rdx
shlq $0x5, %rdx
movq %rax, %rcx
addq %rdx, %rcx
movq %rcx, 0x10(%rsp)
movq %rax, 0x18(%rsp)
movq 0x18(%rsp), %rdi
movq %rdi, 0x8(%rsp)
callq 0x61b0
jmp 0xe4d2
movq 0x10(%rsp), %rcx
movq 0x8(%rsp), %rax
addq $0x20, %rax
cmpq %rcx, %rax
movq %rax, 0x18(%rsp)
jne 0xe4c1
movq 0x28(%rsp), %rax
movq %rax, 0x58(%rsp)
movq 0x58(%rsp), %rdi
movq 0x60(%rsp), %rsi
movq 0x4088(%rsp), %rdx
movq 0x4080(%rsp), %rcx
callq 0xe580
movq 0x58(%rsp), %rax
movq %rax, (%rsp)
cmpq $0x0, %rax
je 0xe52b
movq (%rsp), %rdi
callq 0x2200
jmp 0xe547
movq 0x28(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x50(%rsp)
movl %eax, 0x4c(%rsp)
callq 0x2200
jmp 0xe56f
jmp 0xe565
movq 0x4088(%rsp), %rdx
movq 0x4080(%rsp), %rcx
xorl %eax, %eax
movl %eax, %esi
movq %rsi, %rdi
callq 0xe580
jmp 0xe567
addq $0x4098, %rsp           # imm = 0x4098
retq
movq 0x50(%rsp), %rdi
callq 0x2280
nopl (%rax)