// File: /workspace/github_cpp_makefile_star2_O2/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 %rbx
subq $0xf8, %rsp
movq 0x3cf0(%rip), %rbx      # 0x5fd0
pushq $0x7
popq %rsi
movq %rbx, %rdi
callq 0x2160
movq %rax, %rdi
callq 0x2080
pushq $0x1e
popq %rsi
movq %rbx, %rdi
callq 0x2160
movq %rax, %rdi
callq 0x2080
pushq $-0x1e
popq %rsi
movq %rbx, %rdi
callq 0x2160
movq %rax, %rdi
callq 0x2080
movq %rbx, %rdi
xorl %esi, %esi
callq 0x2160
movq %rax, %rdi
callq 0x2080
movups 0xcf2(%rip), %xmm0      # 0x3024
leaq -0x80(%rbp), %rsi
movaps %xmm0, 0x10(%rsi)
movups 0xcd3(%rip), %xmm0      # 0x3014
movaps %xmm0, (%rsi)
movabsq $0x1300000012, %rax     # imm = 0x1300000012
movq %rax, 0x20(%rsi)
leaq -0xd8(%rbp), %rbx
pushq $0xa
popq %rdx
leaq -0x50(%rbp), %rcx
movq %rbx, %rdi
callq 0x257c
movq (%rbx), %rdi
movq 0x8(%rbx), %rsi
leaq -0xe0(%rbp), %rdx
movl $0xa, 0x4(%rdx)
callq 0x25b2
movq 0x3c47(%rip), %rdi      # 0x5fd0
movq %rax, %rsi
callq 0x20c0
movq 0x3c38(%rip), %rdi      # 0x5fd0
callq 0x2080
xorps %xmm0, %xmm0
leaq -0x30(%rbp), %rbx
andq $0x0, 0x10(%rbx)
leaq -0x40(%rbp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movaps %xmm0, (%rbx)
movb $0x0, (%rax)
movq 0x3c1d(%rip), %r14      # 0x5fe0
leaq -0x50(%rbp), %r15
movq %r14, %rdi
movq %r15, %rsi
callq 0x20f0
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
testb $0x5, 0x20(%rax,%rcx)
jne 0x23ed
movq %rbx, %rdi
movq %r15, %rsi
callq 0x25d0
jmp 0x23c7
leaq -0x100(%rbp), %rsi
andq $0x0, 0x8(%rsi)
leaq -0x144(%rip), %r15      # 0x22bc
movq %r15, (%rsi)
leaq 0x716(%rip), %rax       # 0x2b20
movq %rax, 0x18(%rsi)
leaq 0x71f(%rip), %rax       # 0x2b34
movq %rax, 0x10(%rsi)
leaq -0x80(%rbp), %rdi
callq 0x2b5c
leaq -0x80(%rbp), %rsi
movl $0x6, 0x20(%rsi)
leaq -0xc0(%rbp), %rdi
callq 0x260c
leaq -0x80(%rbp), %rdi
callq 0x2746
movq -0x30(%rbp), %rbx
movq -0x28(%rbp), %r14
leaq -0xa0(%rbp), %rdi
leaq -0xc0(%rbp), %rsi
callq 0x26d6
leaq -0xa0(%rbp), %rdx
movq %rbx, %rdi
movq %r14, %rsi
callq 0x2653
movq 0x3b5a(%rip), %rdi      # 0x5fd0
movq %rax, %rsi
callq 0x20c0
movq %rax, %rdi
callq 0x2080
leaq -0xa0(%rbp), %rdi
callq 0x2746
movq -0x30(%rbp), %rdi
movq -0x28(%rbp), %rsi
leaq -0x110(%rbp), %rdx
movq %r15, (%rdx)
movl $0x6, 0x8(%rdx)
callq 0x2723
movq 0x3b19(%rip), %rdi      # 0x5fd0
movq %rax, %rsi
callq 0x20c0
movq %rax, %rdi
callq 0x2080
leaq -0xc0(%rbp), %rdi
callq 0x2746
leaq -0x100(%rbp), %rdi
callq 0x2746
leaq -0x50(%rbp), %rdi
callq 0x2070
leaq -0x30(%rbp), %rdi
callq 0x2766
leaq -0xd8(%rbp), %rdi
callq 0x27fc
xorl %eax, %eax
addq $0xf8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
jmp 0x2524
movq %rax, %rbx
leaq -0x80(%rbp), %rdi
jmp 0x253f
movq %rax, %rbx
jmp 0x2544
jmp 0x251f
movq %rax, %rbx
jmp 0x2567
movq %rax, %rbx
jmp 0x2538
movq %rax, %rbx
leaq -0xa0(%rbp), %rdi
callq 0x2746
leaq -0xc0(%rbp), %rdi
callq 0x2746
leaq -0x100(%rbp), %rdi
callq 0x2746
jmp 0x2555
movq %rax, %rbx
leaq -0x50(%rbp), %rdi
callq 0x2070
leaq -0x30(%rbp), %rdi
callq 0x2766
leaq -0xd8(%rbp), %rdi
callq 0x27fc
movq %rbx, %rdi
callq 0x2170
nop