// File: /workspace/github_cpp_makefile_star2_O2/DaCasBe[P]Gestion-de-asignaturas-mediante-arboles-binarios-ordenados/nodoEnlazadoArbolBinarioEstudiante.cpp
// Function: ed::NodoEnlazadoArbolBinarioEstudiante::remove(ed::Estudiante const&)
void ed::NodoEnlazadoArbolBinarioEstudiante::remove(ed::Estudiante const &item){
	ed::Estudiante e(item); //Creamos un estudiante auxiliar
	
	//Precondición
	#ifndef NDEBUG
		assert(exists(e));
	#endif
	
	if(item==getItem()){ //El nodo actual contiene el ítem a eliminar
		ed::NodoEnlazadoArbolBinarioEstudiante * auxiliar; //Creamos un nodo auxiliar
		
		if(!hasLeftTree() and !hasRightTree()){ //El nodo actual no tiene hijos
			if(hasParent()){ //El nodo actual tiene padre
				if(getParent()->getLeftTree()==this){ //El nodo actual es el hijo izquierdo de su padre
					getParent()->setLeftTree(NULL);
				}

				else{ //El nodo actual es el hijo derecho de su padre
					getParent()->setRightTree(NULL);
				}
				
				//Borramos el ítem del nodo actual
				delete _item;
				_item=NULL;
			}
			
			else{ //El nodo atual no tiene padre
				//Borramos el ítem del nodo actual
				_item=NULL;
			}
		}

		else if(hasLeftTree() and !hasRightTree()){ //El nodo actual sólo tiene hijo izquierdo
			if(hasParent()){ //El nodo actual tiene padre
				if(getParent()->getLeftTree()==this){ //El nodo actual es el hijo izquierdo de su padre
					getParent()->setLeftTree(getLeftTree());
				}

				else{ //El nodo actual es el hijo derecho de su padre
					getParent()->setRightTree(getLeftTree());
				}
				
				getLeftTree()->setParent(getParent()); //Enlazamos el hijo del nodo actual con el padre de este
				
				_item=NULL; //Borramos el ítem el nodo actual
				
				//Desenlazamos y borramos el nodo actual
				auxiliar=this;
				auxiliar->setParent(NULL);
				auxiliar->setLeftTree(NULL);
				
				delete auxiliar;
			}

			else{ //El nodo actual no tiene padre
				*this=*getLeftTree(); //Hacemos que el nodo actual sea el hijo
				
				//Desenlazamos el nodo actual
				getParent()->setLeftTree(NULL);
				setParent(NULL);
			}
		}

		else if(!hasLeftTree() and hasRightTree()){ //El nodo actual sólo tiene hijo derecho
			if(hasParent()){ //El nodo actual tiene padre

				if(getParent()->getLeftTree()==this){ //El nodo actual es el hijo izquierdo de su padre
					getParent()->setLeftTree(getRightTree());
				}

				else{ //El nodo actual es el hijo derecho de su padre
					getParent()->setRightTree(getRightTree());
				}

				getRightTree()->setParent(getParent()); //Enlazamos el hijo del nodo actual con el padre de este
				
				_item=NULL; //Borramos el ítem el nodo actual
				
				//Desenlazamos y borramos el nodo actual
				auxiliar=this;
				auxiliar->setParent(NULL);
				auxiliar->setRightTree(NULL);
			
				delete auxiliar;
				
			}

			else{ //El nodo actual no tiene padre
				*this=*getRightTree(); //Hacemos que el nodo actual sea el hijo
				
				//Desenlazamos el nodo actual
				getParent()->setRightTree(NULL);
				setParent(NULL);
			}
		}

		else{ //El nodo actual tiene hijo izquierdo y hijo derecho
			setItem(getRightTree()->getMinor()); //Asignamos al nodo actual el ítem del descendiente menor de su hijo derecho
			getRightTree()->remove(getRightTree()->getMinor()); //Borramos el ítem del descendiente menor del hijo derecho del nodo actual
		}
	}

	else if(item<getItem()){ //El ítem es menor que el ítem del nodo actual
		getLeftTree()->remove(item); //Borramos el ítem en el subárbol hijo izquierdo
	}

	else{ //El ítem es mayor que el ítem del nodo actual
		getRightTree()->remove(item); //Borramos el ítem en el subárbol hijo derecho
	}

	//Postcondición
	#ifndef NDEBUG
		assert(!exists(e));
	#endif
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
subq $0x50, %rsp
movq %rsi, %r14
movq %rdi, %rbx
movq %rsp, %r15
movq %r15, %rdi
callq 0x30d0
movq %rbx, %rdi
movq %r15, %rsi
callq 0x2a80
testb %al, %al
je 0x2fa3
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x10(%rax)
movq %r14, %rdi
movq %rax, %rsi
callq 0x27e4
testb %al, %al
je 0x2e74
movq 0x10(%rbx), %rax
movq 0x18(%rbx), %rdi
testq %rax, %rax
je 0x2e9f
testq %rdi, %rdi
je 0x2ec7
callq 0x2bd2
movq (%rbx), %rcx
movq %rbx, %rdi
movq %rax, %rsi
callq *0x18(%rcx)
movq 0x18(%rbx), %r14
movq %r14, %rdi
callq 0x2bd2
movq %r14, %rdi
movq %rax, %rsi
callq 0x2dec
jmp 0x2f82
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x10(%rax)
movq %r14, %rdi
movq %rax, %rsi
callq 0x284c
xorb $0x1, %al
movzbl %al, %eax
movq 0x10(%rbx,%rax,8), %rdi
movq %r14, %rsi
callq 0x2dec
jmp 0x2f82
movq 0x20(%rbx), %rax
testq %rdi, %rdi
je 0x2ee0
testq %rax, %rax
je 0x2f0d
leaq 0x18(%rbx), %rcx
cmpq %rbx, 0x10(%rax)
je 0x2f47
movq %rdi, 0x18(%rax)
movq (%rcx), %rdi
jmp 0x2f4b
leaq 0x20(%rbx), %r14
movq 0x20(%rbx), %rcx
testq %rcx, %rcx
je 0x2f2c
cmpq %rbx, 0x10(%rcx)
je 0x2f55
movq %rax, 0x18(%rcx)
jmp 0x2f5d
testq %rax, %rax
je 0x2f7a
xorl %ecx, %ecx
cmpq %rbx, 0x10(%rax)
setne %cl
andq $0x0, 0x10(%rax,%rcx,8)
leaq 0x8(%rbx), %r14
movq 0x8(%rbx), %rdi
testq %rdi, %rdi
je 0x2f7e
movq (%rdi), %rax
callq *0x8(%rax)
jmp 0x2f7e
leaq 0x20(%rbx), %r14
movups 0x8(%rdi), %xmm0
movups 0x18(%rdi), %xmm1
movups %xmm1, 0x18(%rbx)
movups %xmm0, 0x8(%rbx)
movq 0x20(%rbx), %rax
andq $0x0, 0x18(%rax)
jmp 0x2f7e
movups 0x8(%rax), %xmm0
movups 0x18(%rax), %xmm1
movups %xmm1, 0x18(%rbx)
movups %xmm0, 0x8(%rbx)
movq 0x20(%rbx), %rax
andq $0x0, 0x10(%rax)
jmp 0x2f7e
movq %rdi, 0x10(%rax)
movq %rax, 0x20(%rdi)
leaq 0x8(%rbx), %r14
jmp 0x2f65
movq %rax, 0x10(%rcx)
movq 0x10(%rbx), %rax
movq %rcx, 0x20(%rax)
leaq 0x8(%rbx), %rcx
andq $0x0, (%r14)
xorps %xmm0, %xmm0
movups %xmm0, (%rcx)
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x8(%rax)
jmp 0x2f82
leaq 0x8(%rbx), %r14
andq $0x0, (%r14)
movq %rsp, %rsi
movq %rbx, %rdi
callq 0x2a80
testb %al, %al
jne 0x2fc2
movq %rsp, %rdi
callq 0x3198
addq $0x50, %rsp
popq %rbx
popq %r14
popq %r15
retq
leaq 0x43f6(%rip), %rdi      # 0x73a0
leaq 0x419f(%rip), %rsi      # 0x7150
leaq 0x439b(%rip), %rcx      # 0x7353
movl $0xf4, %edx
callq 0x2110
leaq 0x43d6(%rip), %rdi      # 0x739f
leaq 0x4180(%rip), %rsi      # 0x7150
leaq 0x437c(%rip), %rcx      # 0x7353
movl $0x15f, %edx            # imm = 0x15F
callq 0x2110
jmp 0x2fe3
movq %rax, %rbx
movq %rsp, %rdi
callq 0x3198
movq %rbx, %rdi
callq 0x2230
movq %rax, %rdi
callq 0x3298