// File: /workspace/github_cpp_makefile_star2_O1/ryanbarringtoncox[P]AVLTree/AVLTree.cpp
// Function: AVLTree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>::remove(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>)
void AVLTree<T>::remove(T v) {
	Node<T>** curr =&root;
	Node<T>** mom;
		vector<Node<T>**> path;
	
	//is v in tree?
	while(*curr!=0 && (*curr)->getValue()!= v) {
		path.push_back(curr);
		if (v < (*curr)->getValue()) {
			curr = &((*curr)->getLeftChild());
		} else if (v > (*curr)->getValue()) {
			curr = &((*curr)->getRightChild());
		}    
	}
	
	//v not found
	if (*curr==0) {
		return;
	}
	
	//v is Found
	else {
		Node<T>* nodeToRemove = *curr;	
		//no left child
		if ((nodeToRemove)->getLeftChild()==0) {
			*curr=nodeToRemove->getRightChild();
		}
		//if there's a left child find in-order-predecessor
		else {
			Node<T>* iop = nodeToRemove->getLeftChild();
			while (iop->getRightChild()!=0) {
				iop = iop->getRightChild();	
			}
			iop->setRightChild(*(nodeToRemove->getRightChild()));
			*curr=nodeToRemove->getLeftChild();
		}	  
		
		//update balances through path to root
		T currValue = v;
		mom=&*(path.back());
		
		//increment parent as necessary
		if (currValue < ((*mom))->getValue()) (*mom)->incBalance();
		if (currValue > (*mom)->getValue()) (*mom)->decBalance();

		//keep going with grandparents
		while ((*mom)->getBalance()!=1 && (*mom)->getBalance()!=-1) {		
			
			//rotations
			if ((*mom)->getBalance()==2) {
				(*mom)->resetBalance();
				leftRotation(*mom, mom);
				(*mom)->decBalance();
				
			}			
			if ((*mom)->getBalance()==-2) {
				(*mom)->resetBalance();
				rightRotation(*mom, mom);
				(*mom)->incBalance();
				
			}
			
			//balance adjustments
			if ((*mom)->getBalance()==0) {				
				currValue = (*mom)->getValue();
				path.pop_back();
				if (*mom == root) break;
				mom=&*(path.back());
				if (*mom) {			
					if (currValue < (*mom)->getValue()) (*mom)->incBalance();
					if (currValue > (*mom)->getValue()) (*mom)->decBalance();	
				}
			}
			
		}
		delete nodeToRemove;
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x98, %rsp
movq %rsi, %r15
leaq 0x8(%rsp), %rax
movq %rdi, 0x70(%rsp)
movq %rdi, (%rax)
xorps %xmm0, %xmm0
leaq 0x50(%rsp), %rax
movaps %xmm0, (%rax)
movq $0x0, 0x10(%rax)
leaq 0x88(%rsp), %r14
leaq 0x10(%rsp), %r13
leaq 0x78(%rsp), %rbp
movq 0x8(%rsp), %rax
movq (%rax), %rbx
testq %rbx, %rbx
je 0x679d
movq (%rax), %rsi
movq %rbp, %rdi
callq 0x7d2e
movq 0x80(%rsp), %rdx
movb $0x1, %r12b
cmpq 0x8(%r15), %rdx
jne 0x67a0
testq %rdx, %rdx
je 0x679d
movq (%r15), %rsi
movq 0x78(%rsp), %rdi
callq 0x2160
testl %eax, %eax
setne %r12b
jmp 0x67a0
xorl %r12d, %r12d
testq %rbx, %rbx
je 0x67bf
movq 0x78(%rsp), %rdi
cmpq %r14, %rdi
je 0x67bf
movq 0x88(%rsp), %rsi
incq %rsi
callq 0x2150
testb %r12b, %r12b
je 0x6897
movq 0x58(%rsp), %rsi
cmpq 0x60(%rsp), %rsi
je 0x67e4
movq 0x8(%rsp), %rax
movq %rax, (%rsi)
addq $0x8, 0x58(%rsp)
jmp 0x67f3
leaq 0x50(%rsp), %rdi
leaq 0x8(%rsp), %rdx
callq 0x7abe
movq 0x8(%rsp), %rax
movq (%rax), %rsi
movq %r13, %rdi
callq 0x7d2e
movq %r15, %rdi
movq %r13, %rsi
callq 0x2040
movl %eax, %ebx
movq 0x10(%rsp), %rdi
leaq 0x20(%rsp), %rax
cmpq %rax, %rdi
je 0x682c
movq 0x20(%rsp), %rsi
incq %rsi
callq 0x2150
testl %ebx, %ebx
js 0x6880
movq 0x8(%rsp), %rax
movq (%rax), %rsi
movq %r13, %rdi
callq 0x7d2e
movq %r15, %rdi
movq %r13, %rsi
callq 0x2040
movl %eax, %ebx
movq 0x10(%rsp), %rdi
leaq 0x20(%rsp), %rax
cmpq %rax, %rdi
je 0x6869
movq 0x20(%rsp), %rsi
incq %rsi
callq 0x2150
testl %ebx, %ebx
jle 0x675a
movq 0x8(%rsp), %rax
movq (%rax), %rdi
callq 0x7d7a
jmp 0x688d
movq 0x8(%rsp), %rax
movq (%rax), %rdi
callq 0x7d6e
movq %rax, 0x8(%rsp)
jmp 0x675a
movq 0x8(%rsp), %rax
movq (%rax), %r14
testq %r14, %r14
je 0x6c92
movq %r14, %rdi
callq 0x7d6e
cmpq $0x0, (%rax)
je 0x68f6
movq %r14, %rdi
callq 0x7d6e
movq (%rax), %r12
movq %r12, %rdi
callq 0x7d7a
cmpq $0x0, (%rax)
je 0x68d9
movq %r12, %rdi
callq 0x7d7a
jmp 0x68be
movq %r14, %rdi
callq 0x7d7a
movq (%rax), %rsi
movq %r12, %rdi
callq 0x7d80
movq %r14, %rdi
callq 0x7d6e
jmp 0x68fe
movq %r14, %rdi
callq 0x7d7a
movq (%rax), %rax
movq 0x8(%rsp), %rcx
movq %rax, (%rcx)
leaq 0x10(%rsp), %rdi
leaq 0x20(%rsp), %rax
movq %rax, (%rdi)
movq (%r15), %rsi
movq 0x8(%r15), %rdx
addq %rsi, %rdx
callq 0x77b6
movq 0x58(%rsp), %rax
movq -0x8(%rax), %r15
movq (%r15), %rsi
leaq 0x30(%rsp), %rdi
callq 0x7d2e
movq 0x18(%rsp), %rbx
movq 0x38(%rsp), %r13
cmpq %rbx, %r13
movq %rbx, %rdx
cmovbq %r13, %rdx
testq %rdx, %rdx
je 0x6968
movq 0x30(%rsp), %rsi
movq 0x10(%rsp), %rdi
callq 0x2090
movl %eax, %r12d
jmp 0x696b
xorl %r12d, %r12d
testl %r12d, %r12d
jne 0x6991
subq %r13, %rbx
cmpq $-0x7fffffff, %rbx      # imm = 0x80000001
movq $-0x80000000, %r12      # imm = 0x80000000
cmovgeq %rbx, %r12
movl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
cmpq %rax, %r12
cmovgeq %rax, %r12
leaq 0x40(%rsp), %rbx
movq -0x10(%rbx), %rdi
cmpq %rbx, %rdi
je 0x69ac
movq 0x40(%rsp), %rsi
incq %rsi
callq 0x2150
testl %r12d, %r12d
jns 0x69b9
movq (%r15), %rdi
callq 0x7d54
movq (%r15), %rsi
leaq 0x30(%rsp), %rdi
callq 0x7d2e
movq 0x18(%rsp), %r13
movq 0x38(%rsp), %rbp
cmpq %r13, %rbp
movq %r13, %rdx
cmovbq %rbp, %rdx
testq %rdx, %rdx
je 0x69f3
movq 0x30(%rsp), %rsi
movq 0x10(%rsp), %rdi
callq 0x2090
movl %eax, %r12d
jmp 0x69f6
xorl %r12d, %r12d
testl %r12d, %r12d
jne 0x6a1c
subq %rbp, %r13
cmpq $-0x7fffffff, %r13      # imm = 0x80000001
movq $-0x80000000, %r12      # imm = 0x80000000
cmovgeq %r13, %r12
movl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
cmpq %rax, %r12
cmovgeq %rax, %r12
movq 0x30(%rsp), %rdi
cmpq %rbx, %rdi
je 0x6a33
movq 0x40(%rsp), %rsi
incq %rsi
callq 0x2150
testl %r12d, %r12d
movq 0x70(%rsp), %r12
jle 0x6a45
movq (%r15), %rdi
callq 0x7d58
leaq 0x30(%rsp), %r13
leaq 0x10(%rsp), %rbp
movq (%r15), %rdi
callq 0x7d50
cmpl $0x1, %eax
je 0x6c52
movq (%r15), %rdi
callq 0x7d50
cmpl $-0x1, %eax
je 0x6c52
movq (%r15), %rdi
callq 0x7d50
cmpl $0x2, %eax
jne 0x6a9c
movq (%r15), %rdi
callq 0x7d5c
movq (%r15), %rsi
movq %r12, %rdi
movq %r15, %rdx
callq 0x63a4
movq (%r15), %rdi
callq 0x7d58
movq (%r15), %rdi
callq 0x7d50
cmpl $-0x2, %eax
jne 0x6ac7
movq (%r15), %rdi
callq 0x7d5c
movq (%r15), %rsi
movq %r12, %rdi
movq %r15, %rdx
callq 0x64b6
movq (%r15), %rdi
callq 0x7d54
movq (%r15), %rdi
callq 0x7d50
testl %eax, %eax
jne 0x6a4f
movq (%r15), %rsi
movq %r13, %rdi
callq 0x7d2e
movq %rbp, %rdi
movq %r13, %rsi
callq 0x2180
movq 0x30(%rsp), %rdi
cmpq %rbx, %rdi
je 0x6b04
movq 0x40(%rsp), %rsi
incq %rsi
callq 0x2150
movq 0x58(%rsp), %rax
leaq -0x8(%rax), %rcx
movq %rcx, 0x58(%rsp)
movq (%r15), %rcx
cmpq (%r12), %rcx
je 0x6c52
movq -0x10(%rax), %r15
cmpq $0x0, (%r15)
je 0x6a4f
movq (%r15), %rsi
movq %r13, %rdi
callq 0x7d2e
movq 0x18(%rsp), %r13
movq 0x38(%rsp), %r12
cmpq %r13, %r12
movq %r13, %rdx
cmovbq %r12, %rdx
testq %rdx, %rdx
je 0x6b64
movq 0x30(%rsp), %rsi
movq 0x10(%rsp), %rdi
callq 0x2090
movl %eax, %ebp
jmp 0x6b66
xorl %ebp, %ebp
testl %ebp, %ebp
jne 0x6b8e
subq %r12, %r13
cmpq $-0x7fffffff, %r13      # imm = 0x80000001
movq $-0x80000000, %rax      # imm = 0x80000000
cmovlq %rax, %r13
movl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
cmpq %rax, %r13
cmovgeq %rax, %r13
movl %r13d, %ebp
movq 0x30(%rsp), %rdi
cmpq %rbx, %rdi
je 0x6ba5
movq 0x40(%rsp), %rsi
incq %rsi
callq 0x2150
testl %ebp, %ebp
leaq 0x30(%rsp), %r12
jns 0x6bb6
movq (%r15), %rdi
callq 0x7d54
movq (%r15), %rsi
movq %r12, %rdi
callq 0x7d2e
movq 0x18(%rsp), %r13
movq 0x38(%rsp), %r12
cmpq %r13, %r12
movq %r13, %rdx
cmovbq %r12, %rdx
testq %rdx, %rdx
je 0x6bed
movq 0x30(%rsp), %rsi
movq 0x10(%rsp), %rdi
callq 0x2090
movl %eax, %ebp
jmp 0x6bef
xorl %ebp, %ebp
testl %ebp, %ebp
jne 0x6c17
subq %r12, %r13
cmpq $-0x7fffffff, %r13      # imm = 0x80000001
movq $-0x80000000, %rax      # imm = 0x80000000
cmovlq %rax, %r13
movl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
cmpq %rax, %r13
cmovgeq %rax, %r13
movl %r13d, %ebp
movq 0x30(%rsp), %rdi
cmpq %rbx, %rdi
je 0x6c2e
movq 0x40(%rsp), %rsi
incq %rsi
callq 0x2150
testl %ebp, %ebp
movq 0x70(%rsp), %r12
leaq 0x30(%rsp), %r13
leaq 0x10(%rsp), %rbp
jle 0x6a4f
movq (%r15), %rdi
callq 0x7d58
jmp 0x6a4f
movq (%r14), %rdi
leaq 0x10(%r14), %rax
cmpq %rax, %rdi
je 0x6c69
movq (%rax), %rsi
incq %rsi
callq 0x2150
movl $0x40, %esi
movq %r14, %rdi
callq 0x2150
movq 0x10(%rsp), %rdi
leaq 0x20(%rsp), %rax
cmpq %rax, %rdi
je 0x6c92
movq 0x20(%rsp), %rsi
incq %rsi
callq 0x2150
movq 0x50(%rsp), %rdi
testq %rdi, %rdi
je 0x6ca9
movq 0x60(%rsp), %rsi
subq %rdi, %rsi
callq 0x2150
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x6ce6
jmp 0x6ce6
jmp 0x6ce6
jmp 0x6ce6
jmp 0x6ce6
jmp 0x6ce6
jmp 0x6ce6
jmp 0x6ce1
jmp 0x6ce1
jmp 0x6ce1
jmp 0x6ce1
jmp 0x6cd9
jmp 0x6ce1
jmp 0x6ce1
jmp 0x6ce1
movq %rax, %rdi
callq 0x77aa
movq %rax, %rbx
jmp 0x6d05
movq %rax, %rbx
movq 0x10(%rsp), %rdi
leaq 0x20(%rsp), %rax
cmpq %rax, %rdi
je 0x6d05
movq 0x20(%rsp), %rsi
incq %rsi
callq 0x2150
movq 0x50(%rsp), %rdi
testq %rdi, %rdi
je 0x6d1c
movq 0x60(%rsp), %rsi
subq %rdi, %rsi
callq 0x2150
movq %rbx, %rdi
callq 0x21e0