// File: /workspace/github_cpp_makefile_star2_O2/Baobaobear[P]sort/./sortlib.hpp
// Function: void baobao::internal::shell_sort<baobao::internal::indirect_sort_iter_warp<baobao::TestClass*>*, baobao::internal::indirect_sort_comp_warp<baobao::TestClass*, std::less<baobao::TestClass>>>(baobao::internal::indirect_sort_iter_warp<baobao::TestClass*>*, baobao::internal::indirect_sort_iter_warp<baobao::TestClass*>*, baobao::internal::indirect_sort_comp_warp<baobao::TestClass*, std::less<baobao::TestClass>>)
void shell_sort(RandomAccessIterator beg, RandomAccessIterator end, Comp compare)
{
    if (end - beg > shellsort_insertion_sort_threshold)
    {
        typedef typename std::iterator_traits<RandomAccessIterator>::difference_type diff_type;
        typedef typename std::iterator_traits<RandomAccessIterator>::value_type value_type;
        diff_type len = end - beg;
        diff_type incre_list[61] = { 0, 9, 34, 182, 836, 4025, 19001, 90358, 428481, 2034035, 9651787, 45806244, 217378076, 1031612713 };
        const double incre_factor = 2.9; // simple and fast enought

        if (!util::is_scalar<value_type>::value)
        {
            incre_list[1] = 10;
        }
        diff_type incre_index = 0;
        for (diff_type i = 1; i < 60; ++i)
        {
            diff_type mul = incre_list[i];
            if (mul * incre_factor >= len)
            {
                incre_index = i;
                break;
            }
            if (!util::is_scalar<value_type>::value || incre_list[i + 1] == 0)
            {
                incre_list[i + 1] = (diff_type)(mul * incre_factor);
            }
        }

        for (; incre_index > 0; --incre_index)
        {
            bool swaped = false;
            diff_type incre = incre_list[incre_index];
            for (diff_type i = incre; i < len; i++)
            {
                if (compare(*(beg + i), *(beg + i - incre)))
                {
                    value_type val = *(beg + i);
                    *(beg + i) = *(beg + i - incre);
                    diff_type pos = i - incre;
                    for (; pos >= incre && compare(val, *(beg + pos - incre)); pos -= incre)
                    {
                        *(beg + pos) = *(beg + pos - incre);
                    }
                    *(beg + pos) = val;
                    swaped = true;
                }
            }
            if (!swaped)
            {
                RandomAccessIterator last = insert_sort_limit(beg, end, compare, 1);
                if (last == end)
                {
                    return;
                }
                if (last - beg >= incre << 1)
                {
                    beg += ((last - beg) / incre - 1) * incre;
                    len = end - beg;
                }
            }
        }

        insert_sort(beg, beg + incre_list[1], compare);
        unguarded_insert_sort(beg + incre_list[1], end, compare);
    }
    else
    {
        insert_sort(beg, end, compare);
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x238, %rsp            # imm = 0x238
movq %rdx, 0x28(%rsp)
movq %rsi, %rbx
movq %rsi, %r13
subq %rdi, %r13
sarq $0x4, %r13
cmpq $0x21, %r13
jl 0x87da
leaq 0x6b6f(%rip), %rsi      # 0xf2f0
movq %rdi, %r14
leaq 0x50(%rsp), %r12
movl $0x1e8, %edx            # imm = 0x1E8
movq %r12, %rdi
callq 0x2150
cvtsi2sd %r13, %xmm0
movq $0xa, 0x8(%r12)
movq %r14, %r12
pushq $0x2
popq %rax
xorl %edx, %edx
movsd 0x6854(%rip), %xmm1     # 0xf008
cmpq $0x3d, %rax
je 0x87f2
cvtsi2sdq 0x48(%rsp,%rax,8), %xmm2
mulsd %xmm1, %xmm2
ucomisd %xmm0, %xmm2
jae 0x87ec
cvttsd2si %xmm2, %rcx
movq %rcx, 0x50(%rsp,%rax,8)
incq %rax
jmp 0x87b4
leaq 0x4(%rsp), %rdx
movq %rbx, %rsi
callq 0x8d5a
jmp 0x8990
decq %rax
movq %rax, %rdx
movq %rbx, 0x8(%rsp)
testq %rdx, %rdx
jle 0x895e
movq %rdx, 0x20(%rsp)
movq 0x50(%rsp,%rdx,8), %r15
movq %r15, %rax
negq %rax
cmpq %r15, %r13
movq %r15, %rcx
movq %r13, 0x10(%rsp)
cmovgq %r13, %rcx
movq %rcx, 0x40(%rsp)
movq %r15, %rbx
shlq $0x4, %rbx
negq %rbx
xorl %ebp, %ebp
shlq $0x4, %rax
movq %rax, 0x30(%rsp)
movq %r12, %r14
movq $0x0, 0x18(%rsp)
movq %r15, %r13
movq %r12, 0x38(%rsp)
cmpq 0x40(%rsp), %r13
je 0x88ef
movq %r13, 0x48(%rsp)
shlq $0x4, %r13
addq %r12, %r13
movq 0x30(%rsp), %rax
leaq (%rax,%r13), %r12
movq 0x28(%rsp), %rdi
movq %r13, %rsi
movq %r12, %rdx
callq 0x8b7a
testb %al, %al
je 0x88d6
movq (%r13), %rax
movq 0x8(%r13), %rcx
movupd (%r12), %xmm0
movupd %xmm0, (%r13)
movq %rbp, %rdx
movq %r14, %rsi
subq %r15, %rdx
jl 0x88c8
leaq (%rsi,%rbx), %rdi
movq 0x8(%rsi,%rbx), %r8
movl (%rcx), %r9d
movl (%r8), %r8d
cmpl %r8d, %r9d
jl 0x88bb
jg 0x88c8
cmpq (%rdi), %rax
jae 0x88c8
movupd (%rdi), %xmm0
movupd %xmm0, (%rsi)
movq %rdi, %rsi
jmp 0x889b
movq %rax, (%rsi)
movq %rcx, 0x8(%rsi)
movb $0x1, %al
movq %rax, 0x18(%rsp)
movq 0x48(%rsp), %r13
incq %r13
addq $0x10, %r14
incq %rbp
movq 0x38(%rsp), %r12
jmp 0x884d
testb $0x1, 0x18(%rsp)
je 0x8902
movq 0x8(%rsp), %rbx
movq 0x10(%rsp), %r13
jmp 0x8951
movq %r12, %rdi
movq 0x8(%rsp), %rbx
movq %rbx, %rsi
leaq 0x7(%rsp), %rdx
pushq $0x1
popq %rcx
callq 0x8b9b
cmpq %rbx, %rax
movq 0x10(%rsp), %r13
je 0x8990
subq %r12, %rax
sarq $0x4, %rax
leaq (%r15,%r15), %rcx
cmpq %rcx, %rax
jl 0x8951
cqto
idivq %r15
decq %rax
imulq %r15, %rax
shlq $0x4, %rax
addq %rax, %r12
movq %rbx, %r13
subq %r12, %r13
sarq $0x4, %r13
movq 0x20(%rsp), %rdx
decq %rdx
jmp 0x87f7
movq 0x58(%rsp), %rsi
shlq $0x4, %rsi
addq %r12, %rsi
leaq 0x6(%rsp), %rdx
movq %r12, %rdi
callq 0x8d5a
movq 0x58(%rsp), %rdi
shlq $0x4, %rdi
addq %r12, %rdi
leaq 0x5(%rsp), %rdx
movq %rbx, %rsi
callq 0x8e01
addq $0x238, %rsp            # imm = 0x238
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq