// File: /workspace/github_cpp_makefile_star2_O1/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, 0x20(%rsp)
movq (%rsi), %rax
movq 0x8(%rsi), %rcx
cmpq %rcx, %rax
je 0x41ae
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)
movl $0x18, %edx
movsd (%rax), %xmm0
movsd %xmm0, 0x28(%rsp,%rdx)
movsd 0x8(%rax), %xmm1
movsd %xmm1, 0x30(%rsp,%rdx)
movsd %xmm0, 0x18(%rsp,%rdx)
movsd %xmm1, 0x20(%rsp,%rdx)
addq $0x20, %rdx
cmpq $0x98, %rdx
jne 0x3abb
jmp 0x3d0a
movl $0x3, %edi
xorl %edx, %edx
xorl %esi, %esi
movl %edi, %r8d
movl %esi, %edi
testl $0xfffffffd, %esi       # imm = 0xFFFFFFFD
jne 0x3b1a
movsd (%rax), %xmm0
movl %r8d, %r9d
shlq $0x5, %r9
ucomisd 0x40(%rsp,%r9), %xmm0
jne 0x3b1a
jnp 0x3b4a
movl %edi, %r9d
orl $0x2, %r9d
cmpl $0x3, %r9d
jne 0x3bce
movsd 0x8(%rax), %xmm0
movl %r8d, %r9d
shlq $0x5, %r9
ucomisd 0x48(%rsp,%r9), %xmm0
jne 0x3bce
jp 0x3bce
testq %rdx, %rdx
jne 0x3b64
movl %r8d, %r9d
shlq $0x5, %r9
movsd 0x48(%rsp,%r9), %xmm0
ucomisd 0x8(%rax), %xmm0
ja 0x3bbb
cmpq $0x20, %rdx
jne 0x3b7e
movsd (%rax), %xmm0
movl %r8d, %r9d
shlq $0x5, %r9
ucomisd 0x40(%rsp,%r9), %xmm0
ja 0x3bbb
cmpq $0x40, %rdx
jne 0x3b99
movsd 0x8(%rax), %xmm0
movl %r8d, %r9d
shlq $0x5, %r9
ucomisd 0x48(%rsp,%r9), %xmm0
ja 0x3bbb
cmpq $0x60, %rdx
jne 0x3c67
movl %r8d, %r9d
shlq $0x5, %r9
movsd 0x40(%rsp,%r9), %xmm0
ucomisd (%rax), %xmm0
jbe 0x3c67
movl %r8d, %r8d
shlq $0x5, %r8
addq %rsp, %r8
addq $0x40, %r8
jmp 0x3cde
testq %rdx, %rdx
jne 0x3be7
movsd (%rax), %xmm0
movl %r8d, %r9d
shlq $0x5, %r9
ucomisd 0x40(%rsp,%r9), %xmm0
ja 0x3c3f
cmpq $0x20, %rdx
jne 0x3c02
movsd 0x8(%rax), %xmm0
movl %r8d, %r9d
shlq $0x5, %r9
ucomisd 0x48(%rsp,%r9), %xmm0
ja 0x3c3f
cmpq $0x40, %rdx
jne 0x3c1c
movl %r8d, %r9d
shlq $0x5, %r9
movsd 0x40(%rsp,%r9), %xmm0
ucomisd (%rax), %xmm0
ja 0x3c3f
cmpq $0x60, %rdx
jne 0x3cf2
movl %r8d, %r9d
shlq $0x5, %r9
movsd 0x48(%rsp,%r9), %xmm0
ucomisd 0x8(%rax), %xmm0
jbe 0x3cf2
movl %r8d, %r8d
shlq $0x5, %r8
movsd (%rax), %xmm0
movsd %xmm0, 0x40(%rsp,%r8)
movsd 0x8(%rax), %xmm0
movsd %xmm0, 0x48(%rsp,%r8)
leaq (%rsp,%rdx), %r8
addq $0x30, %r8
jmp 0x3cde
testq %rdx, %rdx
jne 0x3c81
movsd 0x8(%rax), %xmm0
movl %r8d, %r9d
shlq $0x5, %r9
ucomisd 0x38(%rsp,%r9), %xmm0
ja 0x3cd0
cmpq $0x20, %rdx
jne 0x3c9b
movl %r8d, %r9d
shlq $0x5, %r9
movsd 0x30(%rsp,%r9), %xmm0
ucomisd (%rax), %xmm0
ja 0x3cd0
cmpq $0x40, %rdx
jne 0x3cb6
movl %r8d, %r9d
shlq $0x5, %r9
movsd 0x38(%rsp,%r9), %xmm0
ucomisd 0x8(%rax), %xmm0
ja 0x3cd0
cmpq $0x60, %rdx
jne 0x3cf2
movsd (%rax), %xmm0
movl %r8d, %r8d
shlq $0x5, %r8
ucomisd 0x30(%rsp,%r8), %xmm0
jbe 0x3cf2
movq %rsi, %r8
shlq $0x5, %r8
addq %rsp, %r8
addq $0x30, %r8
movsd (%rax), %xmm0
movsd %xmm0, (%r8)
movsd 0x8(%rax), %xmm0
movsd %xmm0, 0x8(%r8)
incq %rsi
addq $0x20, %rdx
cmpq $0x80, %rdx
jne 0x3af7
addq $0x10, %rax
cmpq %rcx, %rax
jne 0x3aee
xorl %ebx, %ebx
movq 0x20(%rsp), %r14
leaq (%rsp,%rbx), %rdx
addq $0x30, %rdx
movq 0x8(%r14), %rsi
cmpq 0x10(%r14), %rsi
je 0x3d3b
movupd (%rdx), %xmm0
movupd %xmm0, (%rsi)
addq $0x10, 0x8(%r14)
jmp 0x3d43
movq %r14, %rdi
callq 0x44ac
movsd 0x30(%rsp,%rbx), %xmm0
ucomisd 0x40(%rsp,%rbx), %xmm0
jne 0x3d63
jp 0x3d63
movsd 0x38(%rsp,%rbx), %xmm0
ucomisd 0x48(%rsp,%rbx), %xmm0
jne 0x3d63
jnp 0x3d8c
leaq (%rsp,%rbx), %rdx
addq $0x40, %rdx
movq 0x8(%r14), %rsi
cmpq 0x10(%r14), %rsi
je 0x3d84
movupd (%rdx), %xmm0
movupd %xmm0, (%rsi)
addq $0x10, 0x8(%r14)
jmp 0x3d8c
movq %r14, %rdi
callq 0x44ac
addq $0x18, %r14
addq $0x20, %rbx
cmpq $0x80, %rbx
jne 0x3d1a
movq (%r15), %rbx
movq 0x8(%r15), %rax
movq %rax, 0xc0(%rsp)
cmpq %rax, %rbx
je 0x41ae
xorpd %xmm7, %xmm7
movsd (%rbx), %xmm0
ucomisd 0x40(%rsp), %xmm0
jbe 0x3df5
movsd 0x8(%rbx), %xmm1
ucomisd 0x38(%rsp), %xmm1
jbe 0x3df5
movq %rbx, (%rsp)
movb $0x1, %r8b
xorl %r9d, %r9d
xorl %ebx, %ebx
movq $0x0, 0x10(%rsp)
movb $0x1, %bpl
xorl %eax, %eax
jmp 0x3ea2
movsd 0x50(%rsp), %xmm1
ucomisd %xmm0, %xmm1
jbe 0x3e2d
movsd 0x8(%rbx), %xmm1
ucomisd 0x68(%rsp), %xmm1
jbe 0x3e2d
movq %rbx, (%rsp)
movl $0x1, %eax
movb $0x1, %r9b
xorl %r8d, %r8d
xorl %ebx, %ebx
movq $0x0, 0x10(%rsp)
movb $0x1, %bpl
jmp 0x3ea2
movsd 0x80(%rsp), %xmm1
ucomisd %xmm0, %xmm1
jbe 0x3e65
movsd 0x78(%rsp), %xmm1
ucomisd 0x8(%rbx), %xmm1
jbe 0x3e65
movq %rbx, (%rsp)
movl $0x2, %eax
movb $0x1, %bl
xorl %r8d, %r8d
xorl %r9d, %r9d
movq $0x0, 0x10(%rsp)
jmp 0x3ea0
ucomisd 0x90(%rsp), %xmm0
jbe 0x419c
movsd 0xa8(%rsp), %xmm1
ucomisd 0x8(%rbx), %xmm1
jbe 0x419c
movq %rbx, (%rsp)
movl $0x3, %eax
movb $0x1, %cl
movq %rcx, 0x10(%rsp)
xorl %r8d, %r8d
xorl %r9d, %r9d
xorl %ebx, %ebx
xorl %ebp, %ebp
leaq (%rax,%rax,2), %rax
movq 0x20(%rsp), %rcx
leaq (%rcx,%rax,8), %rax
movq (%rax), %rsi
movq %rax, 0x18(%rsp)
movq 0x8(%rax), %rdi
subq %rsi, %rdi
shrq $0x4, %rdi
movq (%rcx), %r13
movq 0x18(%rcx), %r15
movq 0x30(%rcx), %rax
movq %rax, 0x28(%rsp)
movq 0x48(%rcx), %r10
movl $0x0, 0xc(%rsp)
movq %rdi, 0xb8(%rsp)
xorl %edx, %edx
leal -0x1(%rdi), %r12d
cmpl %r12d, %edx
jge 0x3ff8
movl %edi, %eax
subl %edx, %eax
sarl %eax
addl %edx, %eax
movslq %eax, %r14
testb %r8b, %r8b
je 0x3f30
movq %r14, %rcx
shlq $0x4, %rcx
movsd (%r13,%rcx), %xmm1
ucomisd %xmm0, %xmm1
jb 0x3f30
addq %r13, %rcx
movsd 0x8(%rcx), %xmm1
movq (%rsp), %rcx
ucomisd 0x8(%rcx), %xmm1
jae 0x3fb3
testb %r9b, %r9b
je 0x3f57
movq %r14, %rcx
shlq $0x4, %rcx
ucomisd (%r15,%rcx), %xmm0
jb 0x3f57
addq %r15, %rcx
movsd 0x8(%rcx), %xmm1
movq (%rsp), %rcx
ucomisd 0x8(%rcx), %xmm1
jae 0x3fb3
testb %bl, %bl
je 0x3f85
movq %r14, %rcx
shlq $0x4, %rcx
movq 0x28(%rsp), %r11
ucomisd (%r11,%rcx), %xmm0
jb 0x3f85
addq 0x28(%rsp), %rcx
movq (%rsp), %r11
movsd 0x8(%r11), %xmm1
ucomisd 0x8(%rcx), %xmm1
jae 0x3fb3
cmpb $0x0, 0x10(%rsp)
je 0x3fb9
movq %r14, %rcx
shlq $0x4, %rcx
movsd (%r10,%rcx), %xmm1
ucomisd %xmm0, %xmm1
jb 0x3fb9
addq %r10, %rcx
movq (%rsp), %r11
movsd 0x8(%r11), %xmm1
ucomisd 0x8(%rcx), %xmm1
jb 0x3fb9
movb $0x1, %cl
movl %ecx, 0xc(%rsp)
testb %bpl, %bpl
je 0x3fcc
movq %r14, %rcx
shlq $0x4, %rcx
ucomisd (%rsi,%rcx), %xmm0
ja 0x3fea
shlq $0x4, %r14
movsd (%rsi,%r14), %xmm1
ucomisd %xmm0, %xmm1
ja 0x3fea
ucomisd %xmm1, %xmm0
movl %eax, %edx
ja 0x3eec
jmp 0x3ff1
movl %eax, %edi
jmp 0x3ee8
leal -0x1(%rax), %edx
incl %eax
movl %eax, %edi
testb $0x1, 0xc(%rsp)
movq (%rsp), %rbx
jne 0x419c
movslq %edx, %rax
shlq $0x4, %rax
movsd (%rsi,%rax), %xmm2
movsd 0x8(%rsi,%rax), %xmm3
movslq %edi, %rcx
movq %rcx, %rax
shlq $0x4, %rax
movsd (%rsi,%rax), %xmm4
movsd 0x8(%rsi,%rax), %xmm5
movsd 0x8(%rbx), %xmm1
subsd %xmm2, %xmm4
movapd %xmm1, %xmm6
subsd %xmm3, %xmm6
mulsd %xmm4, %xmm6
subsd %xmm3, %xmm5
movapd %xmm0, %xmm3
subsd %xmm2, %xmm3
mulsd %xmm5, %xmm3
subsd %xmm3, %xmm6
ucomisd %xmm6, %xmm7
jbe 0x419c
movl %edx, %r9d
movl %edx, %r8d
sarl $0x1f, %r8d
andl %edx, %r8d
shlq $0x4, %r9
addq %rsi, %r9
testl %edx, %edx
jle 0x40c5
movsd -0x10(%r9), %xmm2
movsd -0x8(%r9), %xmm3
movsd (%r9), %xmm4
movsd 0x8(%r9), %xmm5
addq $-0x10, %r9
movapd %xmm0, %xmm6
subsd %xmm2, %xmm6
subsd %xmm3, %xmm5
mulsd %xmm6, %xmm5
movapd %xmm1, %xmm6
subsd %xmm3, %xmm6
subsd %xmm2, %xmm4
mulsd %xmm6, %xmm4
subsd %xmm4, %xmm5
decl %edx
ucomisd %xmm5, %xmm7
jbe 0x4075
incl %edx
movl %edx, %r8d
movq 0xb8(%rsp), %r9
decl %r9d
cmpl %r9d, %ecx
cmovgl %ecx, %r9d
movslq %r9d, %rdx
subq %rdx, %rcx
leaq (%rsi,%rax), %rdx
addq $0x18, %rdx
xorl %eax, %eax
cmpq %rax, %rcx
je 0x412f
movsd -0x8(%rdx), %xmm2
movsd (%rdx), %xmm3
movsd -0x18(%rdx), %xmm4
movsd -0x10(%rdx), %xmm5
subsd %xmm0, %xmm2
subsd %xmm1, %xmm5
mulsd %xmm2, %xmm5
subsd %xmm1, %xmm3
subsd %xmm0, %xmm4
mulsd %xmm3, %xmm4
subsd %xmm4, %xmm5
decq %rax
addq $0x10, %rdx
ucomisd %xmm5, %xmm7
jbe 0x40e7
notl %eax
addl %edi, %eax
movl %eax, %r9d
leal 0x1(%r8), %eax
cmpl %r9d, %eax
jne 0x4151
movslq %r9d, %rax
shlq $0x4, %rax
addq %rax, %rsi
movq 0x18(%rsp), %rdi
movq %rbx, %rdx
callq 0x43c2
jmp 0x4198
cltq
shlq $0x4, %rax
movsd %xmm0, (%rsi,%rax)
movsd %xmm1, 0x8(%rsi,%rax)
leal 0x2(%r8), %eax
cmpl %r9d, %eax
je 0x419c
movq %r9, %rcx
movslq %r8d, %rax
shlq $0x4, %rax
addq %rsi, %rax
addq $0x20, %rax
movslq %ecx, %rcx
shlq $0x4, %rcx
leaq (%rsi,%rcx), %rdx
addq $-0x10, %rdx
movq 0x18(%rsp), %rdi
movq %rax, %rsi
callq 0x458c
xorpd %xmm7, %xmm7
addq $0x10, %rbx
cmpq 0xc0(%rsp), %rbx
jne 0x3dbd
addq $0xc8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq