// File: /workspace/github_cpp_makefile_star2_O2/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 $0x68, %rsp
movq %rsi, %r15
movq %rdi, %rbx
leaq 0x8(%rsp), %r14
movq %rdi, (%r14)
leaq 0x50(%rsp), %r12
andq $0x0, 0x10(%r12)
xorps %xmm0, %xmm0
movaps %xmm0, (%r12)
leaq 0x30(%rsp), %r13
movq %rdi, %rax
movq (%rax), %rsi
testq %rsi, %rsi
je 0x55fc
movq %r13, %rdi
callq 0x668e
movq %r13, %rdi
movq %r15, %rsi
callq 0x5274
movl %eax, %ebp
movq %r13, %rdi
callq 0x20a0
testb %bpl, %bpl
je 0x53a0
movq %r12, %rdi
movq %r14, %rsi
callq 0x5656
movq 0x8(%rsp), %rax
movq (%rax), %rsi
movq %r13, %rdi
callq 0x668e
movq %r15, %rdi
movq %r13, %rsi
callq 0x527e
movl %eax, %ebp
movq %r13, %rdi
callq 0x20a0
testb %bpl, %bpl
je 0x535b
movq 0x8(%rsp), %rax
movq (%rax), %rdi
callq 0x66b4
jmp 0x5396
movq 0x8(%rsp), %rax
movq (%rax), %rsi
movq %r13, %rdi
callq 0x668e
movq %r15, %rdi
movq %r13, %rsi
callq 0x5291
movl %eax, %ebp
movq %r13, %rdi
callq 0x20a0
movq 0x8(%rsp), %rax
testb %bpl, %bpl
je 0x52e5
movq (%rax), %rdi
callq 0x66c0
movq %rax, 0x8(%rsp)
jmp 0x52e5
movq 0x8(%rsp), %rax
movq (%rax), %r14
testq %r14, %r14
je 0x55fc
movq %r14, %rdi
callq 0x66b4
cmpq $0x0, (%rax)
je 0x53ff
movq %r14, %rdi
callq 0x66b4
movq (%rax), %r12
movq %r12, %rdi
callq 0x66c0
cmpq $0x0, (%rax)
je 0x53e2
movq %r12, %rdi
callq 0x66c0
jmp 0x53c7
movq %r14, %rdi
callq 0x66c0
movq (%rax), %rsi
movq %r12, %rdi
callq 0x66c6
movq %r14, %rdi
callq 0x66b4
jmp 0x5407
movq %r14, %rdi
callq 0x66c0
movq (%rax), %rax
movq 0x8(%rsp), %rcx
movq %rax, (%rcx)
leaq 0x30(%rsp), %rdi
movq %r15, %rsi
callq 0x2190
movq 0x58(%rsp), %rax
movq -0x8(%rax), %r15
movq (%r15), %rsi
leaq 0x10(%rsp), %rdi
callq 0x668e
leaq 0x30(%rsp), %rdi
leaq 0x10(%rsp), %r12
movq %r12, %rsi
callq 0x527e
movl %eax, %ebp
movq %r12, %rdi
callq 0x20a0
testb %bpl, %bpl
je 0x545e
movq (%r15), %rdi
callq 0x66a0
movq (%r15), %rsi
leaq 0x10(%rsp), %rdi
callq 0x668e
leaq 0x30(%rsp), %rdi
leaq 0x10(%rsp), %r12
movq %r12, %rsi
callq 0x5291
movl %eax, %ebp
movq %r12, %rdi
callq 0x20a0
testb %bpl, %bpl
je 0x5494
movq (%r15), %rdi
callq 0x66a4
movq (%r15), %rdi
callq 0x669c
cmpl $0x1, %eax
je 0x55df
movq (%r15), %rdi
callq 0x669c
cmpl $-0x1, %eax
je 0x55df
movq (%r15), %rdi
callq 0x669c
cmpl $0x2, %eax
jne 0x54e1
movq (%r15), %rdi
callq 0x66a8
movq (%r15), %rsi
movq %rbx, %rdi
movq %r15, %rdx
callq 0x5028
movq (%r15), %rdi
callq 0x66a4
movq (%r15), %rdi
callq 0x669c
cmpl $-0x2, %eax
jne 0x550c
movq (%r15), %rdi
callq 0x66a8
movq (%r15), %rsi
movq %rbx, %rdi
movq %r15, %rdx
callq 0x50ea
movq (%r15), %rdi
callq 0x66a0
movq (%r15), %rdi
callq 0x669c
testl %eax, %eax
jne 0x5494
movq (%r15), %rsi
leaq 0x10(%rsp), %rdi
callq 0x668e
leaq 0x30(%rsp), %rdi
leaq 0x10(%rsp), %r12
movq %r12, %rsi
callq 0x2170
movq %r12, %rdi
callq 0x20a0
movq 0x58(%rsp), %rax
leaq -0x8(%rax), %rcx
movq %rcx, 0x58(%rsp)
movq (%r15), %rcx
cmpq (%rbx), %rcx
je 0x55df
movq -0x10(%rax), %r15
movq (%r15), %rsi
testq %rsi, %rsi
je 0x5494
leaq 0x10(%rsp), %rdi
callq 0x668e
leaq 0x30(%rsp), %rdi
leaq 0x10(%rsp), %r12
movq %r12, %rsi
callq 0x527e
movl %eax, %ebp
movq %r12, %rdi
callq 0x20a0
testb %bpl, %bpl
je 0x55a0
movq (%r15), %rdi
callq 0x66a0
movq (%r15), %rsi
leaq 0x10(%rsp), %rdi
callq 0x668e
leaq 0x30(%rsp), %rdi
leaq 0x10(%rsp), %r12
movq %r12, %rsi
callq 0x5291
movl %eax, %ebp
movq %r12, %rdi
callq 0x20a0
testb %bpl, %bpl
je 0x5494
movq (%r15), %rdi
callq 0x66a4
jmp 0x5494
movq %r14, %rdi
callq 0x20a0
pushq $0x40
popq %rsi
movq %r14, %rdi
callq 0x2160
leaq 0x30(%rsp), %rdi
callq 0x20a0
leaq 0x50(%rsp), %rdi
callq 0x6330
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x5636
jmp 0x5636
jmp 0x5636
jmp 0x5636
jmp 0x5636
jmp 0x5636
jmp 0x5636
jmp 0x5631
jmp 0x5631
jmp 0x5631
jmp 0x5631
jmp 0x5631
jmp 0x5631
jmp 0x5631
movq %rax, %rbx
jmp 0x5643
movq %rax, %rbx
leaq 0x30(%rsp), %rdi
callq 0x20a0
leaq 0x50(%rsp), %rdi
callq 0x6330
movq %rbx, %rdi
callq 0x2210
nop