// File: /workspace/github_cpp_makefile_star2_O3/iZhangHui[P]CppPrimer/CH14_OverloadedOperationsAndConversions/examples/fcnobj.cc
// Function: main
int main() {

	cout << plus<int>()(3,4) << endl; // prints 7

	plus<int> intAdd;      // object that can add two int values
	negate<int> intNegate; // object that can negate an int value

	// uses intAdd::operator(int, int) to add 10 and 20
	int sum = intAdd(10, 20);         // equivalent to sum = 30
	cout << sum << endl;

	sum = intNegate(intAdd(10, 20));  // equivalent to sum = -30
	cout << sum << endl;

	// uses intNegate::operator(int) to generate -10
	// as the second argument to intAdd::operator(int, int)
	sum = intAdd(10, intNegate(10));  // sum = 0

	cout << sum << endl;

	vector<int> vec = {0,1,2,3,4,5,16,17,18,19};

	// bind second argument to less_equal
	// 0,1,2,3,4,5
	cout << count_if(vec.begin(), vec.end(),
		             bind(less_equal<int>(), _1, 10));
	cout << endl;

	vector<string> svec;
	string in;
	while (cin >> in)
		svec.push_back(in);

	// function<bool(const string&, string::size_type)> fp1 = size_compare;
	function<decltype(size_compare)> fp1 = size_compare;

	// decltype(fp1)::result_type ret;
	// function<bool(const string&)> fp2 = bind(size_compare, _1, 6);
	function<bool(const string&)> fp2 = bind(fp1, _1, 6);

	cout << count_if(svec.begin(), svec.end(), fp2)
	     << endl;
	cout << count_if(svec.begin(), svec.end(),
	                 bind(size_compare, _1, 6))
	     << endl;


	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0xe0, %rsp
movq 0x3cae(%rip), %rbx      # 0x5fd0
movq %rbx, %rdi
movl $0x7, %esi
callq 0x2170
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x20f0
movsbl %al, %esi
movq %r14, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2090
movq %rbx, %rdi
movl $0x1e, %esi
callq 0x2170
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x20f0
movsbl %al, %esi
movq %r14, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2090
movq %rbx, %rdi
movl $0xffffffe2, %esi       # imm = 0xFFFFFFE2
callq 0x2170
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x20f0
movsbl %al, %esi
movq %r14, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2090
xorl %r14d, %r14d
movq %rbx, %rdi
xorl %esi, %esi
callq 0x2170
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x20f0
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2090
movups 0x1c1f(%rip), %xmm0     # 0x4024
leaq -0xe0(%rbp), %rsi
movaps %xmm0, 0x10(%rsi)
movups 0x1bfd(%rip), %xmm0     # 0x4014
movaps %xmm0, (%rsi)
movabsq $0x1300000012, %rax     # imm = 0x1300000012
movq %rax, 0x20(%rsi)
leaq -0x78(%rbp), %rbx
leaq -0x60(%rbp), %rcx
movl $0xa, %edx
movq %rbx, %rdi
callq 0x27ae
movq (%rbx), %rax
movq 0x8(%rbx), %rcx
cmpq %rcx, %rax
je 0x2460
xorl %r14d, %r14d
xorl %edx, %edx
cmpl $0xb, (%rax)
setl %dl
addq %rdx, %r14
addq $0x4, %rax
cmpq %rcx, %rax
jne 0x244c
movq 0x3b69(%rip), %rbx      # 0x5fd0
movq %rbx, %rdi
movq %r14, %rsi
callq 0x20e0
movq (%rbx), %rax
addq -0x18(%rax), %rbx
movq %rbx, %rdi
movl $0xa, %esi
callq 0x20f0
movsbl %al, %esi
movq 0x3b40(%rip), %rdi      # 0x5fd0
callq 0x2030
movq %rax, %rdi
callq 0x2090
xorps %xmm0, %xmm0
leaq -0x40(%rbp), %rbx
movaps %xmm0, (%rbx)
xorl %eax, %eax
movq %rax, 0x10(%rbx)
leaq -0x50(%rbp), %r12
movq %r12, -0x10(%r12)
movq %rax, -0x8(%r12)
movb $0x0, (%r12)
movq 0x3b19(%rip), %r14      # 0x5fe0
leaq -0x60(%rbp), %r15
movq %r14, %rdi
movq %r15, %rsi
callq 0x2120
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
testb $0x5, 0x20(%rax,%rcx)
jne 0x24f1
movq %rbx, %rdi
movq %r15, %rsi
callq 0x27f4
jmp 0x24cb
leaq -0x100(%rbp), %rsi
movq $0x0, 0x8(%rsi)
leaq -0x20b(%rip), %rax      # 0x22fc
movq %rax, (%rsi)
leaq 0x8bd(%rip), %rax       # 0x2dce
movq %rax, 0x18(%rsi)
leaq 0x8c6(%rip), %rax       # 0x2de2
movq %rax, 0x10(%rsi)
leaq -0xe0(%rbp), %rdi
callq 0x2e0a
leaq -0xe0(%rbp), %rsi
movl $0x6, 0x20(%rsi)
leaq -0xb8(%rbp), %rdi
callq 0x2840
movq -0xd0(%rbp), %rax
testq %rax, %rax
je 0x2563
leaq -0xe0(%rbp), %rdi
movq %rdi, %rsi
movl $0x3, %edx
callq *%rax
movq -0x40(%rbp), %rbx
movq -0x38(%rbp), %r14
leaq -0x98(%rbp), %rdi
leaq -0xb8(%rbp), %rsi
callq 0x298c
leaq -0x98(%rbp), %rdx
movq %rbx, %rdi
movq %r14, %rsi
callq 0x289d
movq 0x3a39(%rip), %rdi      # 0x5fd0
movq %rax, %rsi
callq 0x20e0
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x20f0
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2090
movq -0x88(%rbp), %rax
testq %rax, %rax
je 0x25e6
leaq -0x98(%rbp), %rdi
movq %rdi, %rsi
movl $0x3, %edx
callq *%rax
movq -0x40(%rbp), %rax
movq -0x38(%rbp), %rcx
xorl %esi, %esi
cmpq %rcx, %rax
je 0x2604
cmpq $0x6, 0x8(%rax)
sbbq $-0x1, %rsi
addq $0x20, %rax
jmp 0x25f0
movq 0x39c5(%rip), %rdi      # 0x5fd0
callq 0x20e0
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x20f0
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2090
movq -0xa8(%rbp), %rax
testq %rax, %rax
je 0x2657
leaq -0xb8(%rbp), %rdi
movq %rdi, %rsi
movl $0x3, %edx
callq *%rax
movq -0xf0(%rbp), %rax
testq %rax, %rax
je 0x2674
leaq -0x100(%rbp), %rdi
movq %rdi, %rsi
movl $0x3, %edx
callq *%rax
movq -0x60(%rbp), %rdi
cmpq %r12, %rdi
je 0x2689
movq -0x50(%rbp), %rsi
incq %rsi
callq 0x2110
leaq -0x40(%rbp), %rdi
callq 0x29f2
movq -0x78(%rbp), %rdi
testq %rdi, %rdi
je 0x26a7
movq -0x68(%rbp), %rsi
subq %rdi, %rsi
callq 0x2110
xorl %eax, %eax
addq $0xe0, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
jmp 0x2767
jmp 0x2767
jmp 0x2767
jmp 0x2767
jmp 0x2702
movq %rax, %rbx
movq -0xd0(%rbp), %rax
testq %rax, %rax
je 0x2744
leaq -0xe0(%rbp), %rdi
movq %rdi, %rsi
movl $0x3, %edx
callq *%rax
jmp 0x2744
jmp 0x2767
movq %rax, %rbx
jmp 0x2744
jmp 0x26fa
movq %rax, %rbx
jmp 0x2790
movq %rax, %rbx
jmp 0x2727
movq %rax, %rbx
movq -0x88(%rbp), %rax
testq %rax, %rax
je 0x2727
leaq -0x98(%rbp), %rdi
movq %rdi, %rsi
movl $0x3, %edx
callq *%rax
movq -0xa8(%rbp), %rax
testq %rax, %rax
je 0x2744
leaq -0xb8(%rbp), %rdi
movq %rdi, %rsi
movl $0x3, %edx
callq *%rax
movq -0xf0(%rbp), %rax
testq %rax, %rax
je 0x2772
leaq -0x100(%rbp), %rdi
movq %rdi, %rsi
movl $0x3, %edx
callq *%rax
jmp 0x2772
jmp 0x2767
jmp 0x2767
movq %rax, %rdi
callq 0x2a5f
movq %rax, %rbx
movq -0x60(%rbp), %rdi
cmpq %r12, %rdi
je 0x2787
movq -0x50(%rbp), %rsi
incq %rsi
callq 0x2110
leaq -0x40(%rbp), %rdi
callq 0x29f2
movq -0x78(%rbp), %rdi
testq %rdi, %rdi
je 0x27a5
movq -0x68(%rbp), %rsi
subq %rdi, %rsi
callq 0x2110
movq %rbx, %rdi
callq 0x2180
nop