// File: dlbeer[P]summary_map/./summary_map.hpp
// Function: summary_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, int, summary, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, aggregator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, int>, summary>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, int>>>::rebalance_after_insert(summary_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, int, summary, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, aggregator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, int>, summary>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, int>>>::node*)
static void rebalance_after_insert(node *n)
    {
	make_red(n);

	// Because the current node is now red, it's possible that we
	// have violated the property that red nodes have only black
	// children (because n might have a red parent). Go up from the
	// newly inserted node and attempt to fix the property by
	// recolouring.
	//
	// No structural changes occur in this phase, so no summaries
	// are invalidated.
	for (;;) {
	    // If we've hit the root, we're done -- just make sure it's
	    // black.
	    if (is_root(n)) {
		make_black(n);
		return;
	    }

	    // If the parent is black, everything's fine.
	    if (is_black(n->parent))
		return;

	    // We definitely have grandparent, because our parent is
	    // red (and therefore is not the root). If our uncle is also
	    // red, we can recolour and propagate upwards. Otherwise (if
	    // the uncle is black), we need to continue to the next
	    // phase of fix-ups.
	    node *uncle = sibling(n->parent);
	    if (is_black(uncle))
		break;

	    // Recolour as described above and continue upwards.
	    make_black(n->parent);
	    make_black(uncle);
	    n = grandparent(n);
	    make_red(n);
	}

	// If we got to this stage, we have a grandparent, our parent is
	// red, and our uncle is black.
	//
	// First, if the node and its parent descend in different
	// directions (zig-zag ancestry), then rotate the parent in such
	// a way as to straighten the path.
	//
	// We take, as our new node, the parent which has now been
	// pushed down (it is red). Note that since both the initial
	// node and the parent were both red, we haven't affected the
	// black-count.
	//
	// Also note that the summaries which would be invalidated by
	// this rotation have already been invalidated by the insertion
	// operation.
	if (is_left_child(n) && is_right_child(n->parent)) {
	    rotate_right(n->parent);
	    n = n->right;
	} else if (is_right_child(n) && is_left_child(n->parent)) {
	    rotate_left(n->parent);
	    n = n->left;
	}

	// The node has straight ancestry to its parent. If we now
	// recolour and rotate the grandparent, we will have balanced
	// the tree.
	make_black(n->parent);
	make_red(grandparent(n));

	if (is_left_child(n))
	    rotate_right(grandparent(n));
	else
	    rotate_left(grandparent(n));
    }

// Assembly:
subq $0x18, %rsp
movq %rdi, 0x10(%rsp)
movq 0x10(%rsp), %rdi
callq 0x40f0
movq 0x10(%rsp), %rdi
callq 0x4110
testb $0x1, %al
jne 0x3d33
jmp 0x3d42
movq 0x10(%rsp), %rdi
callq 0x4130
jmp 0x3e90
movq 0x10(%rsp), %rax
movq 0x40(%rax), %rdi
callq 0x4150
testb $0x1, %al
jne 0x3d56
jmp 0x3d5b
jmp 0x3e90
movq 0x10(%rsp), %rax
movq 0x40(%rax), %rdi
callq 0x4190
movq %rax, 0x8(%rsp)
movq 0x8(%rsp), %rdi
callq 0x4150
testb $0x1, %al
jne 0x3d7e
jmp 0x3d80
jmp 0x3db6
movq 0x10(%rsp), %rax
movq 0x40(%rax), %rdi
callq 0x4130
movq 0x8(%rsp), %rdi
callq 0x4130
movq 0x10(%rsp), %rdi
callq 0x41e0
movq %rax, 0x10(%rsp)
movq 0x10(%rsp), %rdi
callq 0x40f0
jmp 0x3d23
movq 0x10(%rsp), %rdi
callq 0x4200
testb $0x1, %al
jne 0x3dc6
jmp 0x3df8
movq 0x10(%rsp), %rax
movq 0x40(%rax), %rdi
callq 0x4220
testb $0x1, %al
jne 0x3dda
jmp 0x3df8
movq 0x10(%rsp), %rax
movq 0x40(%rax), %rdi
callq 0x4240
movq 0x10(%rsp), %rax
movq 0x38(%rax), %rax
movq %rax, 0x10(%rsp)
jmp 0x3e3a
movq 0x10(%rsp), %rdi
callq 0x4220
testb $0x1, %al
jne 0x3e08
jmp 0x3e38
movq 0x10(%rsp), %rax
movq 0x40(%rax), %rdi
callq 0x4200
testb $0x1, %al
jne 0x3e1c
jmp 0x3e38
movq 0x10(%rsp), %rax
movq 0x40(%rax), %rdi
callq 0x42e0
movq 0x10(%rsp), %rax
movq 0x30(%rax), %rax
movq %rax, 0x10(%rsp)
jmp 0x3e3a
movq 0x10(%rsp), %rax
movq 0x40(%rax), %rdi
callq 0x4130
movq 0x10(%rsp), %rdi
callq 0x41e0
movq %rax, %rdi
callq 0x40f0
movq 0x10(%rsp), %rdi
callq 0x4200
testb $0x1, %al
jne 0x3e6a
jmp 0x3e7e
movq 0x10(%rsp), %rdi
callq 0x41e0
movq %rax, %rdi
callq 0x4240
jmp 0x3e90
movq 0x10(%rsp), %rdi
callq 0x41e0
movq %rax, %rdi
callq 0x42e0
addq $0x18, %rsp
retq
nopw %cs:(%rax,%rax)
nop