// File: /workspace/github_cpp_makefile_star2_O3/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 $0x78, %rsp
movq %rsi, %r15
movq %rdi, 0x8(%rsp)
xorps %xmm0, %xmm0
movaps %xmm0, 0x50(%rsp)
movq $0x0, 0x60(%rsp)
movq (%rdi), %rsi
testq %rsi, %rsi
je 0x6839
movq %rdi, 0x68(%rsp)
leaq 0x20(%rsp), %rbx
leaq 0x10(%rsp), %r14
leaq 0x8(%rsp), %r13
movq %r14, %rdi
callq 0x7cda
movq 0x18(%rsp), %rdx
cmpq 0x8(%r15), %rdx
jne 0x6743
movq 0x10(%rsp), %rbp
testq %rdx, %rdx
je 0x674d
movq (%r15), %rsi
movq %rbp, %rdi
callq 0x2160
testl %eax, %eax
setne %r12b
jmp 0x6750
movb $0x1, %r12b
movq 0x10(%rsp), %rbp
jmp 0x6750
xorl %r12d, %r12d
cmpq %rbx, %rbp
je 0x6765
movq 0x20(%rsp), %rsi
incq %rsi
movq %rbp, %rdi
callq 0x2150
testb %r12b, %r12b
je 0x6840
movq 0x58(%rsp), %rsi
cmpq 0x60(%rsp), %rsi
je 0x678a
movq 0x8(%rsp), %rax
movq %rax, (%rsi)
addq $0x8, 0x58(%rsp)
jmp 0x679c
leaq 0x50(%rsp), %rdi
movq %r13, %rdx
callq 0x7a6c
movq 0x8(%rsp), %rax
movq (%rax), %rsi
movq %r14, %rdi
callq 0x7cda
movq %r15, %rdi
movq %r14, %rsi
callq 0x2040
movl %eax, %ebp
movq 0x10(%rsp), %rdi
cmpq %rbx, %rdi
je 0x67cb
movq 0x20(%rsp), %rsi
incq %rsi
callq 0x2150
testl %ebp, %ebp
js 0x6816
movq 0x8(%rsp), %rax
movq (%rax), %rsi
movq %r14, %rdi
callq 0x7cda
movq %r15, %rdi
movq %r14, %rsi
callq 0x2040
movl %eax, %ebp
movq 0x10(%rsp), %rdi
cmpq %rbx, %rdi
je 0x6803
movq 0x20(%rsp), %rsi
incq %rsi
callq 0x2150
movq 0x8(%rsp), %rax
testl %ebp, %ebp
jle 0x6828
movq (%rax), %rdi
callq 0x7d26
jmp 0x6823
movq 0x8(%rsp), %rax
movq (%rax), %rdi
callq 0x7d1a
movq %rax, 0x8(%rsp)
movq (%rax), %rsi
testq %rsi, %rsi
jne 0x6713
jmp 0x6c42
xorl %edi, %edi
jmp 0x6c47
movq 0x8(%rsp), %rax
movq (%rax), %r14
testq %r14, %r14
je 0x6c42
movq %r14, %rdi
callq 0x7d1a
cmpq $0x0, (%rax)
je 0x689f
movq %r14, %rdi
callq 0x7d1a
movq (%rax), %r12
movq %r12, %rdi
callq 0x7d26
cmpq $0x0, (%rax)
je 0x6882
movq %r12, %rdi
callq 0x7d26
jmp 0x6867
movq %r14, %rdi
callq 0x7d26
movq (%rax), %rsi
movq %r12, %rdi
callq 0x7d2c
movq %r14, %rdi
callq 0x7d1a
jmp 0x68a7
movq %r14, %rdi
callq 0x7d26
movq (%rax), %rax
movq 0x8(%rsp), %rcx
movq %rax, (%rcx)
leaq 0x10(%rsp), %rdi
movq %rbx, (%rdi)
movq (%r15), %rsi
movq 0x8(%r15), %rdx
addq %rsi, %rdx
callq 0x775e
movq %r14, 0x70(%rsp)
movq 0x58(%rsp), %rax
movq -0x8(%rax), %r15
movq (%r15), %rsi
leaq 0x30(%rsp), %rdi
callq 0x7cda
movq 0x18(%rsp), %rbp
movq 0x30(%rsp), %r12
movq 0x38(%rsp), %r14
cmpq %rbp, %r14
movq %rbp, %rdx
cmovbq %r14, %rdx
testq %rdx, %rdx
je 0x6916
movq 0x10(%rsp), %rdi
movq %r12, %rsi
callq 0x2090
movl %eax, %r13d
testl %eax, %eax
jne 0x6937
subq %r14, %rbp
cmpq $-0x7fffffff, %rbp      # imm = 0x80000001
movq $-0x80000000, %r13      # imm = 0x80000000
cmovgeq %rbp, %r13
movl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
cmpq %rax, %r13
cmovgeq %rax, %r13
leaq 0x40(%rsp), %rax
cmpq %rax, %r12
je 0x6951
movq 0x40(%rsp), %rsi
incq %rsi
movq %r12, %rdi
callq 0x2150
testl %r13d, %r13d
jns 0x695e
movq (%r15), %rdi
callq 0x7d00
movq (%r15), %rsi
leaq 0x30(%rsp), %rdi
callq 0x7cda
movq 0x18(%rsp), %rbp
movq 0x30(%rsp), %r12
movq 0x38(%rsp), %r14
cmpq %rbp, %r14
movq %rbp, %rdx
cmovbq %r14, %rdx
testq %rdx, %rdx
je 0x699d
movq 0x10(%rsp), %rdi
movq %r12, %rsi
callq 0x2090
movl %eax, %r13d
testl %eax, %eax
jne 0x69be
subq %r14, %rbp
cmpq $-0x7fffffff, %rbp      # imm = 0x80000001
movq $-0x80000000, %r13      # imm = 0x80000000
cmovgeq %rbp, %r13
movl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
cmpq %rax, %r13
cmovgeq %rax, %r13
leaq 0x40(%rsp), %rax
cmpq %rax, %r12
je 0x69d8
movq 0x40(%rsp), %rsi
incq %rsi
movq %r12, %rdi
callq 0x2150
testl %r13d, %r13d
jle 0x69e5
movq (%r15), %rdi
callq 0x7d04
leaq 0x30(%rsp), %r12
leaq 0x10(%rsp), %r13
movq 0x68(%rsp), %r14
movq (%r15), %rdi
callq 0x7cfc
cmpl $0x1, %eax
je 0x6c02
movq (%r15), %rdi
callq 0x7cfc
cmpl $-0x1, %eax
je 0x6c02
movq (%r15), %rdi
callq 0x7cfc
cmpl $0x2, %eax
jne 0x6a41
movq (%r15), %rdi
callq 0x7d08
movq (%r15), %rsi
movq %r14, %rdi
movq %r15, %rdx
callq 0x6366
movq (%r15), %rdi
callq 0x7d04
movq (%r15), %rdi
callq 0x7cfc
cmpl $-0x2, %eax
jne 0x6a6c
movq (%r15), %rdi
callq 0x7d08
movq (%r15), %rsi
movq %r14, %rdi
movq %r15, %rdx
callq 0x6478
movq (%r15), %rdi
callq 0x7d00
movq (%r15), %rdi
callq 0x7cfc
testl %eax, %eax
jne 0x69f4
movq (%r15), %rsi
movq %r12, %rdi
callq 0x7cda
movq %r13, %rdi
movq %r12, %rsi
callq 0x2180
movq 0x30(%rsp), %rdi
leaq 0x40(%rsp), %rax
cmpq %rax, %rdi
je 0x6aae
movq 0x40(%rsp), %rsi
incq %rsi
callq 0x2150
movq 0x58(%rsp), %rax
leaq -0x8(%rax), %rcx
movq %rcx, 0x58(%rsp)
movq (%r15), %rcx
cmpq (%r14), %rcx
je 0x6c02
movq -0x10(%rax), %r15
movq (%r15), %rsi
testq %rsi, %rsi
je 0x69f4
movq %r12, %rdi
callq 0x7cda
movq 0x18(%rsp), %r12
movq 0x30(%rsp), %rbp
movq 0x38(%rsp), %r14
cmpq %r12, %r14
movq %r12, %rdx
cmovbq %r14, %rdx
testq %rdx, %rdx
je 0x6b12
movq 0x10(%rsp), %rdi
movq %rbp, %rsi
callq 0x2090
movl %eax, %r13d
testl %eax, %eax
jne 0x6b36
subq %r14, %r12
cmpq $-0x7fffffff, %r12      # imm = 0x80000001
movq $-0x80000000, %rax      # imm = 0x80000000
cmovlq %rax, %r12
movl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
cmpq %rax, %r12
cmovgeq %rax, %r12
movl %r12d, %r13d
leaq 0x40(%rsp), %rax
cmpq %rax, %rbp
je 0x6b50
movq 0x40(%rsp), %rsi
incq %rsi
movq %rbp, %rdi
callq 0x2150
testl %r13d, %r13d
leaq 0x30(%rsp), %r14
jns 0x6b62
movq (%r15), %rdi
callq 0x7d00
movq (%r15), %rsi
movq %r14, %rdi
callq 0x7cda
movq 0x18(%rsp), %r12
movq 0x30(%rsp), %rbp
movq 0x38(%rsp), %r14
cmpq %r12, %r14
movq %r12, %rdx
cmovbq %r14, %rdx
testq %rdx, %rdx
je 0x6b9f
movq 0x10(%rsp), %rdi
movq %rbp, %rsi
callq 0x2090
movl %eax, %r13d
testl %eax, %eax
jne 0x6bc3
subq %r14, %r12
cmpq $-0x7fffffff, %r12      # imm = 0x80000001
movq $-0x80000000, %rax      # imm = 0x80000000
cmovlq %rax, %r12
movl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
cmpq %rax, %r12
cmovgeq %rax, %r12
movl %r12d, %r13d
leaq 0x40(%rsp), %rax
cmpq %rax, %rbp
je 0x6bdd
movq 0x40(%rsp), %rsi
incq %rsi
movq %rbp, %rdi
callq 0x2150
testl %r13d, %r13d
movq 0x68(%rsp), %r14
leaq 0x30(%rsp), %r12
leaq 0x10(%rsp), %r13
jle 0x69f4
movq (%r15), %rdi
callq 0x7d04
jmp 0x69f4
movq 0x70(%rsp), %r14
movq (%r14), %rdi
leaq 0x10(%r14), %rax
cmpq %rax, %rdi
je 0x6c1e
movq (%rax), %rsi
incq %rsi
callq 0x2150
movl $0x40, %esi
movq %r14, %rdi
callq 0x2150
movq 0x10(%rsp), %rdi
cmpq %rbx, %rdi
je 0x6c42
movq 0x20(%rsp), %rsi
incq %rsi
callq 0x2150
movq 0x50(%rsp), %rdi
testq %rdi, %rdi
je 0x6c59
movq 0x60(%rsp), %rsi
subq %rdi, %rsi
callq 0x2150
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x6c93
jmp 0x6c93
jmp 0x6c93
jmp 0x6c93
jmp 0x6c93
jmp 0x6c93
jmp 0x6c93
jmp 0x6c8e
jmp 0x6c8e
jmp 0x6c8e
jmp 0x6c8e
jmp 0x6c84
jmp 0x6c8e
jmp 0x6c8e
movq %rax, %rdi
callq 0x7752
jmp 0x6c8e
movq %rax, %r14
jmp 0x6cad
movq %rax, %r14
movq 0x10(%rsp), %rdi
cmpq %rbx, %rdi
je 0x6cad
movq 0x20(%rsp), %rsi
incq %rsi
callq 0x2150
movq 0x50(%rsp), %rdi
testq %rdi, %rdi
je 0x6cc4
movq 0x60(%rsp), %rsi
subq %rdi, %rsi
callq 0x2150
movq %r14, %rdi
callq 0x21e0