// File: cfiutak1[P]HPyC-KD-Tree/./utils/filewriter/../../src/kdtree/../quickselect/AdaptiveCacheAwareBlockquickselect.hpp
// Function: hpyc::AdaptiveCacheAwareBlockquickselect<float, 64ul, 64ul>::dynamicBlockPartition(unsigned long, unsigned long, unsigned long, unsigned long*, unsigned long*)
inline std::size_t dynamicBlockPartition(std::size_t pivot, std::size_t unpartitioned_range_begin, std::size_t last_unpartitioned_item, std::size_t* left_buffer, std::size_t* right_buffer) {
        /*
         * Partitioning phase
         */
        // + 1 because last_unpartitioned_item is inclusive
        std::size_t remaining_unpartitioned_size = last_unpartitioned_item - unpartitioned_range_begin + 1;

        std::size_t left_buffer_size = 0;
        std::size_t right_buffer_size = 0;

        // Iterate over the array chunk, populating the left and right swap buffers.
        for (size_t i = 0; i < remaining_unpartitioned_size / 2; ++i) {
            left_buffer[left_buffer_size] = i;
            left_buffer_size += (this->cellAt(pivot) < this->cellAt(unpartitioned_range_begin + i));

            right_buffer[right_buffer_size] = i;
            right_buffer_size += (this->cellAt(last_unpartitioned_item - i) < this->cellAt(pivot));
        }

        // The number of items to swap is the size of the smaller bucket.
        std::size_t num_mutual_swaps = std::min(left_buffer_size, right_buffer_size);

        // Perform a mutual exchange of misplaced values.
        for (size_t i = 0; i < num_mutual_swaps; ++i) {
            this->swap(
                unpartitioned_range_begin + left_buffer[i],
                last_unpartitioned_item - right_buffer[i]
            );
        }

        /*
         * Cleanup phase
         */
        std::size_t initial_unpartitioned_range_begin = unpartitioned_range_begin;

        // Update unpartitioned_range_begin to be at the beginning of the !comp() partition. If the array chunk is odd, the middle
        // item has not been inspected. If this item compares with the pivot, the comp() partition's size is incremented by 1.
        unpartitioned_range_begin += (remaining_unpartitioned_size / 2);
        unpartitioned_range_begin += ((remaining_unpartitioned_size % 2) && (this->cellAt(unpartitioned_range_begin) < this->cellAt(pivot)));

        // If there are remaining elements in the left buffer, move them to the right end of the comp() partition.
        // The elements closer to the chunk center are moved first, then the elements at the edges of the array.
        for (size_t i = 0; i < left_buffer_size - num_mutual_swaps; ++i) {
            this->swap(
                initial_unpartitioned_range_begin + left_buffer[left_buffer_size - 1 - i],
                unpartitioned_range_begin - 1 - i
           );
        }

        // Ditto for the left buffer and the !comp() partition.
        for (size_t i = 0; i < right_buffer_size - num_mutual_swaps; ++i) {
            this->swap(
                last_unpartitioned_item - right_buffer[right_buffer_size - 1 - i],
                unpartitioned_range_begin + i
            );
        }

        left_buffer_size -= num_mutual_swaps;
        right_buffer_size -= num_mutual_swaps;

        // Move unpartitioned_range_begin to the left/right, depending on which (if any) of the buffers had remaining items.
        unpartitioned_range_begin -= left_buffer_size;
        unpartitioned_range_begin += right_buffer_size;

        // Swap the pivot with the last item in the comp() partition.
        this->swap(unpartitioned_range_begin - 1, pivot);

        return unpartitioned_range_begin - 1;
    }

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movq %r9, -0x30(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x80(%rbp)
movq -0x20(%rbp), %rax
subq -0x18(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
movq $0x0, -0x40(%rbp)
movq $0x0, -0x48(%rbp)
movq $0x0, -0x50(%rbp)
movq -0x50(%rbp), %rax
movq -0x38(%rbp), %rcx
shrq %rcx
cmpq %rcx, %rax
jae 0x51ba
movq -0x80(%rbp), %rdi
movq -0x50(%rbp), %rdx
movq -0x28(%rbp), %rax
movq -0x40(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movq -0x10(%rbp), %rsi
callq 0x4200
movq -0x80(%rbp), %rdi
movss (%rax), %xmm0
movss %xmm0, -0x88(%rbp)
movq -0x18(%rbp), %rsi
addq -0x50(%rbp), %rsi
callq 0x4200
movss -0x88(%rbp), %xmm1
movq -0x80(%rbp), %rdi
movss (%rax), %xmm0
ucomiss %xmm1, %xmm0
seta %al
andb $0x1, %al
movzbl %al, %eax
addq -0x40(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x50(%rbp), %rdx
movq -0x30(%rbp), %rax
movq -0x48(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movq -0x20(%rbp), %rsi
subq -0x50(%rbp), %rsi
callq 0x4200
movq -0x80(%rbp), %rdi
movss (%rax), %xmm0
movss %xmm0, -0x84(%rbp)
movq -0x10(%rbp), %rsi
callq 0x4200
movss -0x84(%rbp), %xmm1
movss (%rax), %xmm0
ucomiss %xmm1, %xmm0
seta %al
andb $0x1, %al
movzbl %al, %eax
addq -0x48(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x50(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x50(%rbp)
jmp 0x50e3
leaq -0x40(%rbp), %rdi
leaq -0x48(%rbp), %rsi
callq 0x53a0
movq (%rax), %rax
movq %rax, -0x58(%rbp)
movq $0x0, -0x60(%rbp)
movq -0x60(%rbp), %rax
cmpq -0x58(%rbp), %rax
jae 0x5217
movq -0x80(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x28(%rbp), %rax
movq -0x60(%rbp), %rcx
addq (%rax,%rcx,8), %rsi
movq -0x20(%rbp), %rdx
movq -0x30(%rbp), %rax
movq -0x60(%rbp), %rcx
subq (%rax,%rcx,8), %rdx
callq 0x4230
movq -0x60(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x60(%rbp)
jmp 0x51d6
movq -0x18(%rbp), %rax
movq %rax, -0x68(%rbp)
movq -0x38(%rbp), %rax
shrq %rax
addq -0x18(%rbp), %rax
movq %rax, -0x18(%rbp)
movq -0x38(%rbp), %rcx
andq $0x1, %rcx
xorl %eax, %eax
cmpq $0x0, %rcx
movb %al, -0x89(%rbp)
je 0x5282
movq -0x80(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x4200
movq -0x80(%rbp), %rdi
movss (%rax), %xmm0
movss %xmm0, -0x90(%rbp)
movq -0x10(%rbp), %rsi
callq 0x4200
movss -0x90(%rbp), %xmm1
movss (%rax), %xmm0
ucomiss %xmm1, %xmm0
seta %al
movb %al, -0x89(%rbp)
movb -0x89(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
addq -0x18(%rbp), %rax
movq %rax, -0x18(%rbp)
movq $0x0, -0x70(%rbp)
movq -0x70(%rbp), %rax
movq -0x40(%rbp), %rcx
subq -0x58(%rbp), %rcx
cmpq %rcx, %rax
jae 0x52e9
movq -0x80(%rbp), %rdi
movq -0x68(%rbp), %rsi
movq -0x28(%rbp), %rax
movq -0x40(%rbp), %rcx
subq $0x1, %rcx
subq -0x70(%rbp), %rcx
addq (%rax,%rcx,8), %rsi
movq -0x18(%rbp), %rdx
subq $0x1, %rdx
subq -0x70(%rbp), %rdx
callq 0x4230
movq -0x70(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x70(%rbp)
jmp 0x529d
movq $0x0, -0x78(%rbp)
movq -0x78(%rbp), %rax
movq -0x48(%rbp), %rcx
subq -0x58(%rbp), %rcx
cmpq %rcx, %rax
jae 0x5339
movq -0x80(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq -0x30(%rbp), %rax
movq -0x48(%rbp), %rcx
subq $0x1, %rcx
subq -0x78(%rbp), %rcx
subq (%rax,%rcx,8), %rsi
movq -0x18(%rbp), %rdx
addq -0x78(%rbp), %rdx
callq 0x4230
movq -0x78(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x78(%rbp)
jmp 0x52f1
movq -0x80(%rbp), %rdi
movq -0x58(%rbp), %rcx
movq -0x40(%rbp), %rax
subq %rcx, %rax
movq %rax, -0x40(%rbp)
movq -0x58(%rbp), %rcx
movq -0x48(%rbp), %rax
subq %rcx, %rax
movq %rax, -0x48(%rbp)
movq -0x40(%rbp), %rcx
movq -0x18(%rbp), %rax
subq %rcx, %rax
movq %rax, -0x18(%rbp)
movq -0x48(%rbp), %rax
addq -0x18(%rbp), %rax
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rsi
subq $0x1, %rsi
movq -0x10(%rbp), %rdx
callq 0x4230
movq -0x18(%rbp), %rax
subq $0x1, %rax
addq $0x90, %rsp
popq %rbp
retq
nopl (%rax,%rax)