// File: /workspace/github_cpp_makefile_star2_O2/salda[P]convex_hull_of_intersections/Ouellet_hull.cpp
// Function: Ouellet_hull::compute_convex_hull(std::vector<std::pair<double, double>, std::allocator<std::pair<double, double>>>)
void Ouellet_hull::compute_convex_hull(vector<pair<double, double>> points) {
	if (points.empty())
		return;

	array<pair<pair<double, double>, pair<double, double>>, 4> initialization_extremes_for_quadrants;
	for (auto& initialization_pair : initialization_extremes_for_quadrants)
		initialization_pair.first = initialization_pair.second = points.front();
	
	for (auto& point : points) {
	    int previous_quadrant = 3;
		for (int quadrant = 0; quadrant != 4; ++quadrant) {
			if (((quadrant == 0 || quadrant == 2) && point.first == initialization_extremes_for_quadrants[previous_quadrant].second.first)
			 || ((quadrant == 1 || quadrant == 3) && point.second == initialization_extremes_for_quadrants[previous_quadrant].second.second)) {
				if ((quadrant == 0 && point.second < initialization_extremes_for_quadrants[previous_quadrant].second.second)
				 || (quadrant == 1 && point.first > initialization_extremes_for_quadrants[previous_quadrant].second.first)
				 || (quadrant == 2 && point.second > initialization_extremes_for_quadrants[previous_quadrant].second.second)
				 || (quadrant == 3 && point.first < initialization_extremes_for_quadrants[previous_quadrant].second.first))
					initialization_extremes_for_quadrants[previous_quadrant].second = point;
				else if ((quadrant == 0 && point.second > initialization_extremes_for_quadrants[previous_quadrant].first.second)
					  || (quadrant == 1 && point.first < initialization_extremes_for_quadrants[previous_quadrant].first.first)
					  || (quadrant == 2 && point.second < initialization_extremes_for_quadrants[previous_quadrant].first.second)
					  || (quadrant == 3 && point.first > initialization_extremes_for_quadrants[previous_quadrant].first.first))
					initialization_extremes_for_quadrants[quadrant].first = point;
			}
			else if ((quadrant == 0 && point.first > initialization_extremes_for_quadrants[previous_quadrant].second.first)
				  || (quadrant == 1 && point.second > initialization_extremes_for_quadrants[previous_quadrant].second.second)
				  || (quadrant == 2 && point.first < initialization_extremes_for_quadrants[previous_quadrant].second.first)
				  || (quadrant == 3 && point.second < initialization_extremes_for_quadrants[previous_quadrant].second.second)) {
				initialization_extremes_for_quadrants[previous_quadrant].second = point;
				initialization_extremes_for_quadrants[quadrant].first = point;
			}
        	previous_quadrant = quadrant;
		}
	}

	for (int quadrant = 0; quadrant != 4; ++quadrant) { // init quadrants
		quadrants[quadrant].push_back(initialization_extremes_for_quadrants[quadrant].first);
		if (initialization_extremes_for_quadrants[quadrant].first != initialization_extremes_for_quadrants[quadrant].second)
			quadrants[quadrant].push_back(initialization_extremes_for_quadrants[quadrant].second);
	}
	
	int index, indexLow, indexHi, quadrant;
	for (auto& point : points) { // filter non convex hull points
		if (point.first > initialization_extremes_for_quadrants[0].second.first && point.second > initialization_extremes_for_quadrants[0].first.second)
			quadrant = 0;
		else if (point.first < initialization_extremes_for_quadrants[1].first.first && point.second > initialization_extremes_for_quadrants[1].second.second)
			quadrant = 1;
		else if (point.first < initialization_extremes_for_quadrants[2].second.first && point.second < initialization_extremes_for_quadrants[2].first.second)
			quadrant = 2;
		else if (point.first > initialization_extremes_for_quadrants[3].first.first && point.second < initialization_extremes_for_quadrants[3].second.second)
			quadrant = 3;
		else
			continue;

		indexLow = 0;
		indexHi = quadrants[quadrant].size();

		bool breaker = false;
		while (indexLow < indexHi - 1) {
			index = ((indexHi - indexLow) >> 1) + indexLow;

			if ((quadrant == 0 && point.first <= quadrants[0][index].first && point.second <= quadrants[0][index].second)
			 || (quadrant == 1 && point.first >= quadrants[1][index].first && point.second <= quadrants[1][index].second)
			 || (quadrant == 2 && point.first >= quadrants[2][index].first && point.second >= quadrants[2][index].second)
			 || (quadrant == 3 && point.first <= quadrants[3][index].first && point.second >= quadrants[3][index].second))
				breaker = true; // no computation needed

			if ((quadrant < 2 && point.first > quadrants[quadrant][index].first) || point.first < quadrants[quadrant][index].first) { // TODO check "< 2" condition
				indexHi = index;
				continue;
			}

			if ((quadrant < 2 && point.first < quadrants[quadrant][index].first) || point.first > quadrants[quadrant][index].first) { // TODO check "< 2" condition
				indexLow = index;
				continue;
			}

			indexLow = index - 1;
			indexHi = index + 1;
			break;
		}
		if (breaker || !is_right_turn(quadrants[quadrant][indexLow], quadrants[quadrant][indexHi], point))
			continue;

		// here indexLow should contain the index where the point should be inserted if calculation does not invalidate it

		// find lower bound (remove point invalidated by the new one that comes before)
		while (indexLow > 0) {
			if (is_right_turn(quadrants[quadrant][indexLow - 1], point, quadrants[quadrant][indexLow]))
				break; // found the lower index limit of points to keep, new point should be added right after indexLow
			--indexLow;
		}

		// find upper bound (remove point invalidated by the new one that comes after)
		int maxIndexHi = quadrants[quadrant].size() - 1;
		while (indexHi < maxIndexHi) {
			if (is_right_turn(point, quadrants[quadrant][indexHi + 1], quadrants[quadrant][indexHi]))
				break; // found the higher index limit of points to keep, new point should be added right before indexHi
			++indexHi;
		}

		if (indexLow + 1 == indexHi)
			quadrants[quadrant].insert(quadrants[quadrant].begin() + indexHi, point);
		else {
			quadrants[quadrant][indexLow + 1] = point;
			if (indexLow + 2 != indexHi)
				quadrants[quadrant].erase(quadrants[quadrant].begin() + indexLow + 2, quadrants[quadrant].begin() + indexHi -1);
		}
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xc8, %rsp
movq %rdi, 0x28(%rsp)
movq (%rsi), %rax
movq 0x8(%rsi), %rcx
cmpq %rcx, %rax
je 0x40aa
movq %rsi, %r15
xorpd %xmm0, %xmm0
movapd %xmm0, 0xa0(%rsp)
movapd %xmm0, 0x90(%rsp)
movapd %xmm0, 0x80(%rsp)
movapd %xmm0, 0x70(%rsp)
movapd %xmm0, 0x60(%rsp)
movapd %xmm0, 0x50(%rsp)
movapd %xmm0, 0x40(%rsp)
movapd %xmm0, 0x30(%rsp)
pushq $0x10
popq %rdx
cmpq $0x90, %rdx
je 0x3a1c
movupd (%rax), %xmm0
movupd %xmm0, 0x30(%rsp,%rdx)
movupd %xmm0, 0x20(%rsp,%rdx)
addq $0x20, %rdx
jmp 0x39fd
pushq $0x3
popq %rdx
cmpq %rcx, %rax
je 0x3c46
xorl %esi, %esi
xorl %edi, %edi
movl %edx, %r8d
cmpq $0x80, %rsi
je 0x3c3d
movl %r8d, %r9d
movl %edi, %r8d
movl %r9d, %r9d
testl $0xfffffffd, %edi       # imm = 0xFFFFFFFD
jne 0x3a7f
movsd (%rax), %xmm0
movq %r9, %r10
shlq $0x5, %r10
ucomisd 0x40(%rsp,%r10), %xmm0
jne 0x3a7f
jp 0x3a7f
testq %rsi, %rsi
jne 0x3aa3
movsd 0x48(%rsp,%r10), %xmm1
ucomisd 0x8(%rax), %xmm1
ja 0x3b6e
jmp 0x3bf8
movl %r8d, %r10d
orl $0x2, %r10d
cmpl $0x3, %r10d
jne 0x3b00
movsd 0x8(%rax), %xmm0
movq %r9, %r10
shlq $0x5, %r10
ucomisd 0x48(%rsp,%r10), %xmm0
jne 0x3b05
jp 0x3b05
cmpq $0x20, %rsi
jne 0x3adb
movsd (%rax), %xmm0
movq %r9, %r10
shlq $0x5, %r10
ucomisd 0x40(%rsp,%r10), %xmm0
ja 0x3b6e
shlq $0x5, %r9
movsd 0x30(%rsp,%r9), %xmm0
ucomisd (%rax), %xmm0
ja 0x3c15
jmp 0x3c31
cmpq $0x40, %rsi
jne 0x3b48
movsd 0x8(%rax), %xmm0
movq %r9, %r10
shlq $0x5, %r10
ucomisd 0x48(%rsp,%r10), %xmm0
jbe 0x3bdf
movsd (%rax), %xmm0
jmp 0x3b6e
testq %rsi, %rsi
je 0x3b7e
cmpq $0x20, %rsi
jne 0x3b29
movsd 0x8(%rax), %xmm0
movq %r9, %r10
shlq $0x5, %r10
ucomisd 0x48(%rsp,%r10), %xmm0
ja 0x3bb6
jmp 0x3c31
cmpq $0x40, %rsi
jne 0x3b97
movq %r9, %r10
shlq $0x5, %r10
movsd 0x40(%rsp,%r10), %xmm0
ucomisd (%rax), %xmm0
ja 0x3bb6
jmp 0x3c31
cmpq $0x60, %rsi
jne 0x3bf3
movsd (%rax), %xmm0
movq %r9, %r10
shlq $0x5, %r10
movsd 0x40(%rsp,%r10), %xmm1
ucomisd %xmm0, %xmm1
jbe 0x3c0c
shlq $0x5, %r9
addq %rsp, %r9
addq $0x40, %r9
jmp 0x3c21
movsd (%rax), %xmm0
movq %r9, %r10
shlq $0x5, %r10
ucomisd 0x40(%rsp,%r10), %xmm0
ja 0x3bb6
jmp 0x3c31
cmpq $0x60, %rsi
jne 0x3c31
movq %r9, %r10
shlq $0x5, %r10
movsd 0x48(%rsp,%r10), %xmm0
ucomisd 0x8(%rax), %xmm0
jbe 0x3c31
shlq $0x5, %r9
movupd (%rax), %xmm0
movupd %xmm0, 0x40(%rsp,%r9)
movq %rdi, %r9
shlq $0x5, %r9
addq %rsp, %r9
addq $0x30, %r9
movlpd %xmm0, 0x30(%rsp,%rsi)
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
jmp 0x3c2b
shlq $0x5, %r9
movsd 0x38(%rsp,%r9), %xmm0
ucomisd 0x8(%rax), %xmm0
ja 0x3c15
jmp 0x3c31
testq %rsi, %rsi
jne 0x3c31
movsd 0x8(%rax), %xmm0
shlq $0x5, %r9
ucomisd 0x38(%rsp,%r9), %xmm0
ja 0x3c15
jmp 0x3c31
ucomisd 0x30(%rsp,%r10), %xmm0
jbe 0x3c31
leaq (%rsp,%rsi), %r9
addq $0x30, %r9
movsd (%rax), %xmm0
movsd %xmm0, (%r9)
movsd 0x8(%rax), %xmm0
movsd %xmm0, 0x8(%r9)
incq %rdi
addq $0x20, %rsi
jmp 0x3a2f
addq $0x10, %rax
jmp 0x3a1f
leaq 0x40(%rsp), %r14
xorl %ebx, %ebx
cmpq $0x60, %rbx
je 0x3c9c
movq 0x28(%rsp), %rax
leaq (%rax,%rbx), %r12
leaq -0x10(%r14), %rsi
movq %r12, %rdi
callq 0x4266
movsd -0x10(%r14), %xmm0
ucomisd (%r14), %xmm0
jne 0x3c87
jp 0x3c87
movsd -0x8(%r14), %xmm0
ucomisd 0x8(%r14), %xmm0
jne 0x3c87
jnp 0x3c92
movq %r12, %rdi
movq %r14, %rsi
callq 0x4266
addq $0x18, %rbx
addq $0x20, %r14
jmp 0x3c4d
movq (%r15), %rbx
movq 0x8(%r15), %rax
movq %rax, 0xc0(%rsp)
xorpd %xmm9, %xmm9
cmpq 0xc0(%rsp), %rbx
je 0x40aa
movsd (%rbx), %xmm0
ucomisd 0x40(%rsp), %xmm0
jbe 0x3cf8
movsd 0x8(%rbx), %xmm1
ucomisd 0x38(%rsp), %xmm1
jbe 0x3cf8
movq %rbx, 0x10(%rsp)
movb $0x1, %r8b
xorl %r9d, %r9d
xorl %r10d, %r10d
movq $0x0, 0x18(%rsp)
movb $0x1, %bpl
xorl %eax, %eax
jmp 0x3dad
movsd 0x50(%rsp), %xmm1
ucomisd %xmm0, %xmm1
jbe 0x3d2f
movsd 0x8(%rbx), %xmm1
ucomisd 0x68(%rsp), %xmm1
jbe 0x3d2f
movq %rbx, 0x10(%rsp)
movb $0x1, %r9b
xorl %r8d, %r8d
xorl %r10d, %r10d
movq $0x0, 0x18(%rsp)
movb $0x1, %bpl
pushq $0x1
jmp 0x3dac
movsd 0x80(%rsp), %xmm1
ucomisd %xmm0, %xmm1
jbe 0x3d6c
movsd 0x8(%rbx), %xmm1
movsd 0x78(%rsp), %xmm2
ucomisd %xmm1, %xmm2
jbe 0x3d6c
movq %rbx, 0x10(%rsp)
movb $0x1, %r10b
xorl %r8d, %r8d
xorl %r9d, %r9d
movq $0x0, 0x18(%rsp)
xorl %ebp, %ebp
pushq $0x2
jmp 0x3dac
ucomisd 0x90(%rsp), %xmm0
jbe 0x40a1
movsd 0x8(%rbx), %xmm1
movsd 0xa8(%rsp), %xmm2
ucomisd %xmm1, %xmm2
jbe 0x40a1
movq %rbx, 0x10(%rsp)
movb $0x1, %al
movq %rax, 0x18(%rsp)
xorl %r8d, %r8d
xorl %r9d, %r9d
xorl %r10d, %r10d
xorl %ebp, %ebp
pushq $0x3
popq %rax
imulq $0x18, %rax, %rax
movq 0x28(%rsp), %rcx
leaq (%rcx,%rax), %rdx
movq %rdx, 0x20(%rsp)
movq (%rcx,%rax), %rdx
movq 0x8(%rcx,%rax), %rax
movq %rdx, (%rsp)
subq %rdx, %rax
shrq $0x4, %rax
movq (%rcx), %r13
movq 0x18(%rcx), %r12
movq 0x30(%rcx), %rsi
movq 0x48(%rcx), %r15
movl $0x0, 0xc(%rsp)
movq %rax, 0xb8(%rsp)
movl %eax, %ecx
xorl %edx, %edx
leal -0x1(%rcx), %edi
cmpl %edi, %edx
jge 0x3ed1
movl %ecx, %eax
subl %edx, %eax
sarl %eax
addl %edx, %eax
movslq %eax, %r14
testb %r8b, %r8b
je 0x3e33
movq %r14, %rbx
shlq $0x4, %rbx
movsd (%r13,%rbx), %xmm2
ucomisd %xmm0, %xmm2
jb 0x3e33
addq %r13, %rbx
movsd 0x8(%rbx), %xmm2
ucomisd %xmm1, %xmm2
jae 0x3e96
testb %r9b, %r9b
je 0x3e55
movq %r14, %rbx
shlq $0x4, %rbx
ucomisd (%r12,%rbx), %xmm0
jb 0x3e55
addq %r12, %rbx
movsd 0x8(%rbx), %xmm2
ucomisd %xmm1, %xmm2
jae 0x3e96
testb %r10b, %r10b
je 0x3e72
movq %r14, %rbx
shlq $0x4, %rbx
ucomisd (%rsi,%rbx), %xmm0
jb 0x3e72
addq %rsi, %rbx
ucomisd 0x8(%rbx), %xmm1
jae 0x3e96
cmpb $0x0, 0x18(%rsp)
je 0x3e9c
movq %r14, %rbx
shlq $0x4, %rbx
movsd (%r15,%rbx), %xmm2
ucomisd %xmm0, %xmm2
jb 0x3e9c
addq %r15, %rbx
ucomisd 0x8(%rbx), %xmm1
jb 0x3e9c
movb $0x1, %bl
movl %ebx, 0xc(%rsp)
shlq $0x4, %r14
movq (%rsp), %r11
movsd (%r11,%r14), %xmm2
ucomisd %xmm2, %xmm0
seta %bl
testb %bl, %bpl
jne 0x3eca
ucomisd %xmm0, %xmm2
ja 0x3eca
ucomisd %xmm2, %xmm0
movl %eax, %edx
ja 0x3df9
jmp 0x3ee3
movl %eax, %ecx
jmp 0x3df6
testb $0x1, 0xc(%rsp)
movq 0x10(%rsp), %rbx
jne 0x40a1
jmp 0x3efa
testb $0x1, 0xc(%rsp)
movq 0x10(%rsp), %rbx
jne 0x40a1
leal -0x1(%rax), %edx
incl %eax
movl %eax, %ecx
movslq %edx, %rax
shlq $0x4, %rax
movq (%rsp), %rsi
movsd (%rsi,%rax), %xmm4
movsd 0x8(%rsi,%rax), %xmm5
movslq %ecx, %r8
movq %r8, %rax
shlq $0x4, %rax
movsd (%rsi,%rax), %xmm3
movsd 0x8(%rsi,%rax), %xmm2
movapd %xmm3, %xmm6
subsd %xmm4, %xmm6
movapd %xmm1, %xmm7
subsd %xmm5, %xmm7
mulsd %xmm6, %xmm7
movapd %xmm2, %xmm6
subsd %xmm5, %xmm6
movapd %xmm0, %xmm5
subsd %xmm4, %xmm5
mulsd %xmm6, %xmm5
subsd %xmm5, %xmm7
ucomisd %xmm7, %xmm9
jbe 0x40a1
movl %edx, %edi
movl %edx, %r9d
sarl $0x1f, %r9d
andl %edx, %r9d
shlq $0x4, %rdi
addq (%rsp), %rdi
testl %edx, %edx
jle 0x3fc3
movsd -0x10(%rdi), %xmm4
movsd -0x8(%rdi), %xmm5
movsd (%rdi), %xmm6
movsd 0x8(%rdi), %xmm7
addq $-0x10, %rdi
movapd %xmm0, %xmm8
subsd %xmm4, %xmm8
subsd %xmm5, %xmm7
mulsd %xmm8, %xmm7
movapd %xmm1, %xmm8
subsd %xmm5, %xmm8
subsd %xmm4, %xmm6
mulsd %xmm8, %xmm6
subsd %xmm6, %xmm7
decl %edx
ucomisd %xmm7, %xmm9
jbe 0x3f70
incl %edx
movl %edx, %r9d
movq 0xb8(%rsp), %rdx
decl %edx
movslq %edx, %rdx
cmpl %edx, %ecx
movl %edx, %edi
cmovgl %ecx, %edi
decl %ecx
movq (%rsp), %rsi
addq %rsi, %rax
addq $0x18, %rax
cmpq %rdx, %r8
jge 0x4030
incq %r8
movsd -0x8(%rax), %xmm4
movsd (%rax), %xmm5
movapd %xmm4, %xmm6
subsd %xmm0, %xmm6
subsd %xmm1, %xmm2
mulsd %xmm6, %xmm2
movapd %xmm5, %xmm6
subsd %xmm1, %xmm6
subsd %xmm0, %xmm3
mulsd %xmm6, %xmm3
subsd %xmm3, %xmm2
incl %ecx
addq $0x10, %rax
ucomisd %xmm2, %xmm9
movapd %xmm5, %xmm2
movapd %xmm4, %xmm3
jbe 0x3fe4
jmp 0x4032
movl %edi, %ecx
leal 0x1(%r9), %eax
movslq %ecx, %rdx
cmpl %ecx, %eax
jne 0x4057
shlq $0x4, %rdx
movq (%rsp), %rsi
addq %rdx, %rsi
movq 0x20(%rsp), %rdi
movq %rbx, %rdx
callq 0x4284
jmp 0x409c
cltq
shlq $0x4, %rax
movq (%rsp), %rsi
movsd %xmm0, (%rsi,%rax)
movsd %xmm1, 0x8(%rsi,%rax)
leal 0x2(%r9), %eax
cmpl %ecx, %eax
je 0x40a1
movslq %r9d, %rax
shlq $0x4, %rax
movq (%rsp), %rcx
leaq (%rcx,%rax), %rsi
addq $0x20, %rsi
shlq $0x4, %rdx
addq %rcx, %rdx
addq $-0x10, %rdx
movq 0x20(%rsp), %rdi
callq 0x2e36
xorpd %xmm9, %xmm9
addq $0x10, %rbx
jmp 0x3cb0
addq $0xc8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq