// File: cjc12[P]ezSTL/src/../include/rbtree.h
// Function: ezSTL::rbtree<int, ezSTL::less<int>, ezSTL::allocator<ezSTL::__rbtree_node<int>>>::delete_fixup(ezSTL::__rbtree_node<int>*, ezSTL::__rbtree_node<int>*)
void rbtree<T, Compare, Alloc>::delete_fixup(link_type father, link_type son) {
		while (son != root() && (!son || son->color == __rbtree_black)) {
			link_type brother = nullptr;
			if (son == father->left) {
				brother = father->right;
				// case 1: color of brother is red
				if (brother->color == __rbtree_red) {
					brother->color = __rbtree_black;
					father->color = __rbtree_red;
					left_rotate(father);
					brother = father->right;
				}
				// case 2: color of brother's sons are both black
				if ((!brother->left || brother->left->color == __rbtree_black) &&
					(!brother->right || brother->right->color == __rbtree_black)) {
					brother->color = __rbtree_red;
					son = father;
					father = father->parent;
				}
				else {
					// case 3: color of brother's right son is black
					if (!brother->right || brother->right->color == __rbtree_black) {
						brother->color = __rbtree_red;
						if (brother->left)
							brother->left->color = __rbtree_black;
						right_rotate(brother);
						brother = father->right;
					}
					// case 4: color of brother's left son is black
					brother->color = father->color;
					father->color = __rbtree_black;
					if (brother->right)
						brother->right->color = __rbtree_black;
					left_rotate(father);
					break;
				}
			}
			// similar as above, only change left to right, change right to left
			else {
				brother = father->left;
				if (brother->color == __rbtree_red) {
					brother->color = __rbtree_black;
					father->color = __rbtree_red;
					right_rotate(father);
					brother = father->left;
				}
				if ((!brother->right || brother->right->color == __rbtree_black) &&
					(!brother->left || brother->left->color == __rbtree_black)) {
					brother->color = __rbtree_red;
					son = father;
					father = father->parent;
				}
				else {
					if (!brother->left || brother->left->color == __rbtree_black) {
						brother->color = __rbtree_red;
						if (brother->right)
							brother->right->color = __rbtree_black;
						left_rotate(brother);
						brother = father->left;
					}
					brother->color = father->color;
					father->color = __rbtree_black;
					if (brother->left)
						brother->left->color = __rbtree_black;
					right_rotate(father);
					break;
				}
			}
		}
		if (son)
			son->color = __rbtree_black;
	}

// Assembly:
subq $0x48, %rsp
movq %rdi, 0x40(%rsp)
movq %rsi, 0x38(%rsp)
movq %rdx, 0x30(%rsp)
movq 0x40(%rsp), %rax
movq %rax, 0x20(%rsp)
movq 0x20(%rsp), %rdi
movq 0x30(%rsp), %rax
movq %rax, 0x10(%rsp)
callq 0x12390
movq 0x10(%rsp), %rcx
movq %rax, %rdx
xorl %eax, %eax
cmpq %rdx, %rcx
movb %al, 0x1f(%rsp)
je 0x12b20
movb $0x1, %al
cmpq $0x0, 0x30(%rsp)
movb %al, 0xf(%rsp)
je 0x12b18
movq 0x30(%rsp), %rax
movb (%rax), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
sete %al
movb %al, 0xf(%rsp)
movb 0xf(%rsp), %al
movb %al, 0x1f(%rsp)
movb 0x1f(%rsp), %al
testb $0x1, %al
jne 0x12b2d
jmp 0x12dff
movq $0x0, 0x28(%rsp)
movq 0x30(%rsp), %rax
movq 0x38(%rsp), %rcx
cmpq 0x10(%rcx), %rax
jne 0x12ca5
movq 0x38(%rsp), %rax
movq 0x18(%rax), %rax
movq %rax, 0x28(%rsp)
movq 0x28(%rsp), %rax
movb (%rax), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x12b96
movq 0x20(%rsp), %rdi
movq 0x28(%rsp), %rax
movb $0x1, (%rax)
movq 0x38(%rsp), %rax
movb $0x0, (%rax)
movq 0x38(%rsp), %rsi
callq 0x12800
movq 0x38(%rsp), %rax
movq 0x18(%rax), %rax
movq %rax, 0x28(%rsp)
movq 0x28(%rsp), %rax
cmpq $0x0, 0x10(%rax)
je 0x12bb7
movq 0x28(%rsp), %rax
movq 0x10(%rax), %rax
movb (%rax), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0x12bfd
movq 0x28(%rsp), %rax
cmpq $0x0, 0x18(%rax)
je 0x12bd8
movq 0x28(%rsp), %rax
movq 0x18(%rax), %rax
movb (%rax), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0x12bfd
movq 0x28(%rsp), %rax
movb $0x0, (%rax)
movq 0x38(%rsp), %rax
movq %rax, 0x30(%rsp)
movq 0x38(%rsp), %rax
movq 0x8(%rax), %rax
movq %rax, 0x38(%rsp)
jmp 0x12ca0
movq 0x28(%rsp), %rax
cmpq $0x0, 0x18(%rax)
je 0x12c1e
movq 0x28(%rsp), %rax
movq 0x18(%rax), %rax
movb (%rax), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0x12c5b
movq 0x28(%rsp), %rax
movb $0x0, (%rax)
movq 0x28(%rsp), %rax
cmpq $0x0, 0x10(%rax)
je 0x12c3e
movq 0x28(%rsp), %rax
movq 0x10(%rax), %rax
movb $0x1, (%rax)
movq 0x20(%rsp), %rdi
movq 0x28(%rsp), %rsi
callq 0x12910
movq 0x38(%rsp), %rax
movq 0x18(%rax), %rax
movq %rax, 0x28(%rsp)
movq 0x38(%rsp), %rax
movb (%rax), %cl
movq 0x28(%rsp), %rax
andb $0x1, %cl
movb %cl, (%rax)
movq 0x38(%rsp), %rax
movb $0x1, (%rax)
movq 0x28(%rsp), %rax
cmpq $0x0, 0x18(%rax)
je 0x12c8c
movq 0x28(%rsp), %rax
movq 0x18(%rax), %rax
movb $0x1, (%rax)
movq 0x20(%rsp), %rdi
movq 0x38(%rsp), %rsi
callq 0x12800
jmp 0x12dff
jmp 0x12dfa
movq 0x38(%rsp), %rax
movq 0x10(%rax), %rax
movq %rax, 0x28(%rsp)
movq 0x28(%rsp), %rax
movb (%rax), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x12cf1
movq 0x20(%rsp), %rdi
movq 0x28(%rsp), %rax
movb $0x1, (%rax)
movq 0x38(%rsp), %rax
movb $0x0, (%rax)
movq 0x38(%rsp), %rsi
callq 0x12910
movq 0x38(%rsp), %rax
movq 0x10(%rax), %rax
movq %rax, 0x28(%rsp)
movq 0x28(%rsp), %rax
cmpq $0x0, 0x18(%rax)
je 0x12d12
movq 0x28(%rsp), %rax
movq 0x18(%rax), %rax
movb (%rax), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0x12d58
movq 0x28(%rsp), %rax
cmpq $0x0, 0x10(%rax)
je 0x12d33
movq 0x28(%rsp), %rax
movq 0x10(%rax), %rax
movb (%rax), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0x12d58
movq 0x28(%rsp), %rax
movb $0x0, (%rax)
movq 0x38(%rsp), %rax
movq %rax, 0x30(%rsp)
movq 0x38(%rsp), %rax
movq 0x8(%rax), %rax
movq %rax, 0x38(%rsp)
jmp 0x12df8
movq 0x28(%rsp), %rax
cmpq $0x0, 0x10(%rax)
je 0x12d79
movq 0x28(%rsp), %rax
movq 0x10(%rax), %rax
movb (%rax), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0x12db6
movq 0x28(%rsp), %rax
movb $0x0, (%rax)
movq 0x28(%rsp), %rax
cmpq $0x0, 0x18(%rax)
je 0x12d99
movq 0x28(%rsp), %rax
movq 0x18(%rax), %rax
movb $0x1, (%rax)
movq 0x20(%rsp), %rdi
movq 0x28(%rsp), %rsi
callq 0x12800
movq 0x38(%rsp), %rax
movq 0x10(%rax), %rax
movq %rax, 0x28(%rsp)
movq 0x38(%rsp), %rax
movb (%rax), %cl
movq 0x28(%rsp), %rax
andb $0x1, %cl
movb %cl, (%rax)
movq 0x38(%rsp), %rax
movb $0x1, (%rax)
movq 0x28(%rsp), %rax
cmpq $0x0, 0x10(%rax)
je 0x12de7
movq 0x28(%rsp), %rax
movq 0x10(%rax), %rax
movb $0x1, (%rax)
movq 0x20(%rsp), %rdi
movq 0x38(%rsp), %rsi
callq 0x12910
jmp 0x12dff
jmp 0x12dfa
jmp 0x12acd
cmpq $0x0, 0x30(%rsp)
je 0x12e0f
movq 0x30(%rsp), %rax
movb $0x1, (%rax)
addq $0x48, %rsp
retq
nopw %cs:(%rax,%rax)
nop