// File: DimitriDaSilva[P]42_ft_containers/containers/utils/red_black_tree.hpp
// Function: ft::red_black_tree<int, int, ft::less<int>, std::allocator<ft::red_black_tree_node<int>>>::fix_double_black(ft::red_black_tree_node<int>*)
void
		fix_double_black(node_pointer node)
		{
			node_pointer parent;
			node_pointer sibling;

			// Base case of recursion: if DB is root, nothing to do
			if (node == _root)
				return;

			parent = node->parent;

			// Get double black's sibling. If it's a double black, it
			// necessarily has one
			if (parent->left == node)
				sibling = parent->right;
			else
				sibling = parent->left;

			// Case: DB's sibling is black and its children are black
			if (sibling->color == black
					&& sibling->left->color == black
					&& sibling->right->color == black)
			{
				// DB gives blackness to parent and sibling
				// gets mad (ie becomes red)
				if (parent->color == red)
				{
					parent->color = black;
					sibling->color = red;
				}
				else if (parent->color == black)
				{
					sibling->color = red;
					// If parent is already black it carries double-blackness
					fix_double_black(parent);
				}
			}
			// Case: DB's sibling is red
			else if (sibling->color == red)
			{
				parent->color = red;
				sibling->color = black;

				// Rotate towards the direction of the node we want to delete
				if (parent->left == node)
					rotate_left(sibling);
				else
					rotate_right(sibling);

				// Double black case still exists but the sibling of the node
				// we want to delete has changed
				fix_double_black(node);
			}
			// Case: DB's sibling is black and nearest sibling's child is red
			// and furthest from DB is black
			else if (sibling->color == black
					&& ((sibling == parent->right
						&& sibling->left->color == red
						&& sibling->right->color == black)
						|| (sibling == parent->left
							&& sibling->left->color == black
							&& sibling->right->color == red)))
			{
				if (sibling == parent->right)
				{
					swap_color(sibling, sibling->left);
					rotate_right(sibling->left);
				}
				else
				{
					swap_color(sibling, sibling->right);
					rotate_left(sibling->right);
				}

				// Double black case still exists but the sibling of the node
				// we want to delete has changed
				fix_double_black(node);
			}
			// Case: DB's sibling is black and furthest sibling's child is red
			else if (sibling->color == black
					&& ((sibling == parent->right
						&& sibling->right->color == red)
						|| (sibling == parent->left
							&& sibling->left->color == red)))
			{
				swap_color(parent, sibling);

				// Rotate parent towards DB
				if (sibling == parent->right)
				{
					rotate_left(sibling);
					sibling->right->color = black;
				}
				else
				{
					rotate_right(sibling);
					sibling->left->color = black;
				}
			}
		}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rcx
movq %rcx, -0x28(%rbp)
movq -0x10(%rbp), %rax
cmpq 0x8(%rcx), %rax
jne 0x15ff7
jmp 0x16273
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rax
movq 0x10(%rax), %rax
cmpq -0x10(%rbp), %rax
jne 0x1601f
movq -0x18(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x20(%rbp)
jmp 0x1602b
movq -0x18(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
cmpl $0x1, 0x20(%rax)
jne 0x1609c
movq -0x20(%rbp), %rax
movq 0x10(%rax), %rax
cmpl $0x1, 0x20(%rax)
jne 0x1609c
movq -0x20(%rbp), %rax
movq 0x18(%rax), %rax
cmpl $0x1, 0x20(%rax)
jne 0x1609c
movq -0x18(%rbp), %rax
cmpl $0x0, 0x20(%rax)
jne 0x16073
movq -0x18(%rbp), %rax
movl $0x1, 0x20(%rax)
movq -0x20(%rbp), %rax
movl $0x0, 0x20(%rax)
jmp 0x16097
movq -0x18(%rbp), %rax
cmpl $0x1, 0x20(%rax)
jne 0x16095
movq -0x28(%rbp), %rdi
movq -0x20(%rbp), %rax
movl $0x0, 0x20(%rax)
movq -0x18(%rbp), %rsi
callq 0x15fd0
jmp 0x16097
jmp 0x16273
movq -0x20(%rbp), %rax
cmpl $0x0, 0x20(%rax)
jne 0x160f8
movq -0x18(%rbp), %rax
movl $0x0, 0x20(%rax)
movq -0x20(%rbp), %rax
movl $0x1, 0x20(%rax)
movq -0x18(%rbp), %rax
movq 0x10(%rax), %rax
cmpq -0x10(%rbp), %rax
jne 0x160d9
movq -0x28(%rbp), %rdi
leaq -0x20(%rbp), %rsi
callq 0xe5c0
jmp 0x160e6
movq -0x28(%rbp), %rdi
leaq -0x20(%rbp), %rsi
callq 0xe710
movq -0x28(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x15fd0
jmp 0x16271
movq -0x20(%rbp), %rax
cmpl $0x1, 0x20(%rax)
jne 0x161cc
movq -0x20(%rbp), %rax
movq -0x18(%rbp), %rcx
cmpq 0x18(%rcx), %rax
jne 0x16130
movq -0x20(%rbp), %rax
movq 0x10(%rax), %rax
cmpl $0x0, 0x20(%rax)
jne 0x16130
movq -0x20(%rbp), %rax
movq 0x18(%rax), %rax
cmpl $0x1, 0x20(%rax)
je 0x1615e
movq -0x20(%rbp), %rax
movq -0x18(%rbp), %rcx
cmpq 0x10(%rcx), %rax
jne 0x161cc
movq -0x20(%rbp), %rax
movq 0x10(%rax), %rax
cmpl $0x1, 0x20(%rax)
jne 0x161cc
movq -0x20(%rbp), %rax
movq 0x18(%rax), %rax
cmpl $0x0, 0x20(%rax)
jne 0x161cc
movq -0x20(%rbp), %rax
movq -0x18(%rbp), %rcx
cmpq 0x18(%rcx), %rax
jne 0x16194
movq -0x28(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq -0x20(%rbp), %rax
movq 0x10(%rax), %rdx
callq 0x16520
movq -0x28(%rbp), %rdi
movq -0x20(%rbp), %rsi
addq $0x10, %rsi
callq 0xe710
jmp 0x161ba
movq -0x28(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq -0x20(%rbp), %rax
movq 0x18(%rax), %rdx
callq 0x16520
movq -0x28(%rbp), %rdi
movq -0x20(%rbp), %rsi
addq $0x18, %rsi
callq 0xe5c0
movq -0x28(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x15fd0
jmp 0x1626f
movq -0x20(%rbp), %rax
cmpl $0x1, 0x20(%rax)
jne 0x1626d
movq -0x20(%rbp), %rax
movq -0x18(%rbp), %rcx
cmpq 0x18(%rcx), %rax
jne 0x161f6
movq -0x20(%rbp), %rax
movq 0x18(%rax), %rax
cmpl $0x0, 0x20(%rax)
je 0x16212
movq -0x20(%rbp), %rax
movq -0x18(%rbp), %rcx
cmpq 0x10(%rcx), %rax
jne 0x1626d
movq -0x20(%rbp), %rax
movq 0x10(%rax), %rax
cmpl $0x0, 0x20(%rax)
jne 0x1626d
movq -0x28(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
callq 0x16520
movq -0x20(%rbp), %rax
movq -0x18(%rbp), %rcx
cmpq 0x18(%rcx), %rax
jne 0x1624f
movq -0x28(%rbp), %rdi
leaq -0x20(%rbp), %rsi
callq 0xe5c0
movq -0x20(%rbp), %rax
movq 0x18(%rax), %rax
movl $0x1, 0x20(%rax)
jmp 0x1626b
movq -0x28(%rbp), %rdi
leaq -0x20(%rbp), %rsi
callq 0xe710
movq -0x20(%rbp), %rax
movq 0x10(%rax), %rax
movl $0x1, 0x20(%rax)
jmp 0x1626d
jmp 0x1626f
jmp 0x16271
jmp 0x16273
addq $0x30, %rsp
popq %rbp
retq
nopl (%rax)