// 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>>>::check_subtree(std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>> const&, 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 const*, 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 const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const*)
static std::pair<size_type, size_type>
    check_subtree(const key_compare& cmp,
		  const node *parent, const node *n,
		  const key_type *lower_bound,
		  const key_type *upper_bound)
    {
	if (!n)
	    return std::make_pair(0, 0);

	// Check that the parent pointer points to the node we came
	// from.
	assert(n->parent == parent);

	// Check that the key is within the expected range
	assert(!upper_bound || cmp(n->value.first, *upper_bound));
	assert(!lower_bound || cmp(*lower_bound, n->value.first));

	// Red nodes always have black parents
	assert(is_black(n) || is_black(parent));

	// Recursively check subtrees
	std::pair<size_type, size_type> left =
	    check_subtree(cmp, n, n->left, lower_bound, &n->value.first);
	std::pair<size_type, size_type> right =
	    check_subtree(cmp, n, n->right, &n->value.first, upper_bound);

	// Verify that this subtree is black-balanced
	assert(left.second == right.second);

	// Compile totals for this subtree
	const size_type black_self = is_black(n) ? 1 : 0;

	return std::make_pair(left.first + right.first + 1,
			      left.second + black_self);
    }

// Assembly:
subq $0x88, %rsp
movq %rdi, 0x70(%rsp)
movq %rsi, 0x68(%rsp)
movq %rdx, 0x60(%rsp)
movq %rcx, 0x58(%rsp)
movq %r8, 0x50(%rsp)
cmpq $0x0, 0x60(%rsp)
jne 0x4180
movl $0x0, 0x44(%rsp)
movl $0x0, 0x40(%rsp)
leaq 0x44(%rsp), %rdi
leaq 0x40(%rsp), %rsi
callq 0x43a0
movq %rax, 0x48(%rsp)
leaq 0x78(%rsp), %rdi
leaq 0x48(%rsp), %rsi
callq 0x43d0
jmp 0x4386
movq 0x60(%rsp), %rax
movq 0x40(%rax), %rax
cmpq 0x68(%rsp), %rax
jne 0x4192
jmp 0x41b1
leaq 0x21b7(%rip), %rdi      # 0x6350
leaq 0x203f(%rip), %rsi      # 0x61df
movl $0x38a, %edx            # imm = 0x38A
leaq 0x21b8(%rip), %rcx      # 0x6364
callq 0x20e0
movb $0x1, %al
cmpq $0x0, 0x50(%rsp)
movb %al, 0x7(%rsp)
je 0x41d7
movq 0x70(%rsp), %rdi
movq 0x60(%rsp), %rsi
movq 0x50(%rsp), %rdx
callq 0x3270
movb %al, 0x7(%rsp)
movb 0x7(%rsp), %al
testb $0x1, %al
jne 0x41e1
jmp 0x41e3
jmp 0x4202
leaq 0x2340(%rip), %rdi      # 0x652a
leaq 0x1fee(%rip), %rsi      # 0x61df
movl $0x38d, %edx            # imm = 0x38D
leaq 0x2167(%rip), %rcx      # 0x6364
callq 0x20e0
movb $0x1, %al
cmpq $0x0, 0x58(%rsp)
movb %al, 0x6(%rsp)
je 0x4228
movq 0x70(%rsp), %rdi
movq 0x58(%rsp), %rsi
movq 0x60(%rsp), %rdx
callq 0x3270
movb %al, 0x6(%rsp)
movb 0x6(%rsp), %al
testb $0x1, %al
jne 0x4232
jmp 0x4234
jmp 0x4253
leaq 0x2321(%rip), %rdi      # 0x655c
leaq 0x1f9d(%rip), %rsi      # 0x61df
movl $0x38e, %edx            # imm = 0x38E
leaq 0x2116(%rip), %rcx      # 0x6364
callq 0x20e0
movq 0x60(%rsp), %rdi
callq 0x3e40
movb %al, %cl
movb $0x1, %al
testb $0x1, %cl
movb %al, 0x5(%rsp)
jne 0x4278
movq 0x68(%rsp), %rdi
callq 0x3e40
movb %al, 0x5(%rsp)
movb 0x5(%rsp), %al
testb $0x1, %al
jne 0x4282
jmp 0x4284
jmp 0x42a3
leaq 0x2303(%rip), %rdi      # 0x658e
leaq 0x1f4d(%rip), %rsi      # 0x61df
movl $0x391, %edx            # imm = 0x391
leaq 0x20c6(%rip), %rcx      # 0x6364
callq 0x20e0
movq 0x70(%rsp), %rdi
movq 0x60(%rsp), %rsi
movq 0x60(%rsp), %rax
movq 0x30(%rax), %rdx
movq 0x58(%rsp), %rcx
movq 0x60(%rsp), %r8
callq 0x4120
movq %rax, 0x30(%rsp)
movq %rdx, 0x38(%rsp)
movq 0x70(%rsp), %rdi
movq 0x60(%rsp), %rsi
movq 0x60(%rsp), %rax
movq 0x38(%rax), %rdx
movq 0x60(%rsp), %rcx
movq 0x50(%rsp), %r8
callq 0x4120
movq %rax, 0x20(%rsp)
movq %rdx, 0x28(%rsp)
movq 0x38(%rsp), %rax
cmpq 0x28(%rsp), %rax
jne 0x4309
jmp 0x4328
leaq 0x229e(%rip), %rdi      # 0x65ae
leaq 0x1ec8(%rip), %rsi      # 0x61df
movl $0x39a, %edx            # imm = 0x39A
leaq 0x2041(%rip), %rcx      # 0x6364
callq 0x20e0
movq 0x60(%rsp), %rdi
callq 0x3e40
movb %al, %dl
xorl %eax, %eax
movl $0x1, %ecx
testb $0x1, %dl
cmovnel %ecx, %eax
cltq
movq %rax, 0x18(%rsp)
movq 0x30(%rsp), %rax
addq 0x20(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x10(%rsp)
movq 0x38(%rsp), %rax
addq 0x18(%rsp), %rax
movq %rax, 0x8(%rsp)
leaq 0x10(%rsp), %rdi
leaq 0x8(%rsp), %rsi
callq 0x4400
movq %rax, 0x78(%rsp)
movq %rdx, 0x80(%rsp)
movq 0x78(%rsp), %rax
movq 0x80(%rsp), %rdx
addq $0x88, %rsp
retq
nopl (%rax,%rax)