// File: /workspace/github_cpp_makefile_star2_O3/onlyuser[P]Sandbox/test_c/c++14/main.cpp
// Function: main
int main(int argc, char** argv)
{
    // NOTE: won't compile
    //std::cout << "\ntest0" << std::endl;
    //{
    //    f0(g()); // rvalue won't bind to "A&"
    //}

    std::cout << "\ntest1" << std::endl;
    {
        f(the_a); // lvalue reference prefers "A&"
        f(g());   // rvalue reference links to "const A&", but not "A&" (why write to a temporary? that's what rvalue ref is for!)
    }

    std::cout << "\ntest2" << std::endl;
    {
        f2(the_a); // lvalue reference prefers "A&"
        f2(g());   // rvalue reference prefers "A&&" over "const A&"
    }

    std::cout << "\ntest3" << std::endl;
    {
        f2_forward(the_a); // preserves rvalueness despite rvalue collapse rule (T& + T&& ==> T&)
        f2_forward(g());   // preserves rvalueness despite rvalue collapse rule (T& + T&& ==> T&)
    }

    std::cout << "\ntest4" << std::endl;
    {
        std::shared_ptr<::A> shared_a = std::make_shared<::A>("outer");

        std::cout << "ENTER SCOPE" << std::endl;
        {
            auto unique_a = std::make_unique<::A>("inner");
            shared_a = std::move(unique_a); // exchanges ownership with outer
        }
        std::cout << "LEAVE SCOPE" << std::endl;
    }

    std::cout << "\ntest5" << std::endl;
    {
        ::A a1("outer");

        std::cout << "ENTER SCOPE" << std::endl;
        {
            ::A a2("inner");
            std::swap(a1, a2); // swap works as you'd expect; exchanges ownership with outer
        }
        std::cout << "LEAVE SCOPE" << std::endl;
    }

    std::cout << "\ntest6" << std::endl;
    {
        A(A(A("hello world"))); // anonymous construction of object of type A; RVO is default behavior unless use gcc switch -fno-elide-constructors
    }

    std::cout << "\ntest7" << std::endl;
    {
        A(A(A(), 0), 0); // anonymous construction of object of type A; RVO not possible because "A(A(A()))" pattern is broken
    }

    std::cout << "\ntest8" << std::endl;
    {
        {
            A(A(A())); // center A is local variable declaration of function pointer type
            std::cout << typeid(A).name() << std::endl; // A (A (*)())
        }

        {
            typedef A(A(A())); // center A is function pointer type
            std::cout << typeid(A).name() << std::endl; // A (A (*)())
        }
    }

    std::cout << "\ntest9" << std::endl;
    {
        std::vector<::A> v;
        v.emplace_back("hello world"); // emplace is unrelated to rvalue reference
    }

    std::cout << "\ntest10" << std::endl;
    {
        std::shared_ptr<A> a = std::make_shared<A>("hello world"); // std::make_shared is unrelated to rvalue reference
    }

    return 0;
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
subq $0x40, %rsp
movq 0x3b63(%rip), %rbx      # 0x5fd8
leaq 0x1bd5(%rip), %rsi      # 0x4051
movl $0x6, %edx
movq %rbx, %rdi
callq 0x2110
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x20e0
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x20b0
callq 0x22fc
leaq 0x3c34(%rip), %rsi      # 0x60f0
leaq 0x10(%rsp), %rdi
callq 0x2cd4
callq 0x2340
leaq 0x10(%rsp), %rdi
callq 0x2bc0
leaq 0x1b7c(%rip), %rsi      # 0x4058
movl $0x6, %edx
movq %rbx, %rdi
callq 0x2110
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x20e0
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x20b0
callq 0x2384
leaq 0x3bd4(%rip), %rsi      # 0x60f0
leaq 0x10(%rsp), %rdi
callq 0x2cd4
callq 0x240c
leaq 0x10(%rsp), %rdi
callq 0x2bc0
leaq 0x1b23(%rip), %rsi      # 0x405f
movl $0x6, %edx
movq %rbx, %rdi
callq 0x2110
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x20e0
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x20b0
callq 0x2384
leaq 0x3b74(%rip), %rsi      # 0x60f0
leaq 0x10(%rsp), %rdi
callq 0x2cd4
callq 0x240c
leaq 0x10(%rsp), %r14
movq %r14, %rdi
callq 0x2bc0
leaq 0x1ac7(%rip), %rsi      # 0x4066
movl $0x6, %edx
movq %rbx, %rdi
callq 0x2110
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x20e0
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x20b0
movq $0x0, (%r14)
leaq 0x18(%rsp), %rdi
leaq 0x1a87(%rip), %rcx      # 0x406d
leaq 0x10(%rsp), %rsi
leaq 0x8(%rsp), %rdx
callq 0x2f4a
leaq 0x1a77(%rip), %rsi      # 0x4073
movl $0xb, %edx
movq %rbx, %rdi
callq 0x2110
movq (%rbx), %rax
addq -0x18(%rax), %rbx
movq %rbx, %rdi
movl $0xa, %esi
callq 0x20e0
movsbl %al, %esi
movq 0x39b1(%rip), %rdi      # 0x5fd8
callq 0x2040
movq %rax, %rdi
callq 0x20b0
movl $0x8, %edi
callq 0x20f0
movq %rax, %r14
leaq 0x1a37(%rip), %rsi      # 0x407f
movq %rax, %rdi
callq 0x2afc
leaq 0x8(%rsp), %rsi
movq %r14, (%rsi)
leaq 0x10(%rsp), %rdi
callq 0x301c
leaq 0x8(%rsp), %rdi
callq 0x2d4a
movq 0x3965(%rip), %rbx      # 0x5fd8
leaq 0x1a0b(%rip), %rsi      # 0x4085
movl $0xb, %edx
movq %rbx, %rdi
callq 0x2110
movq (%rbx), %rax
addq -0x18(%rax), %rbx
movq %rbx, %rdi
movl $0xa, %esi
callq 0x20e0
movsbl %al, %esi
movq 0x3933(%rip), %rbx      # 0x5fd8
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x20b0
movq 0x18(%rsp), %rdi
testq %rdi, %rdi
je 0x26c4
callq 0x2eda
leaq 0x19c6(%rip), %rsi      # 0x4091
movl $0x6, %edx
movq %rbx, %rdi
callq 0x2110
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x20e0
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x20b0
leaq 0x1967(%rip), %rsi      # 0x406d
leaq 0x8(%rsp), %rdi
callq 0x2afc
leaq 0x195c(%rip), %rsi      # 0x4073
movl $0xb, %edx
movq %rbx, %rdi
callq 0x2110
movq (%rbx), %rax
addq -0x18(%rax), %rbx
movq %rbx, %rdi
movl $0xa, %esi
callq 0x20e0
movsbl %al, %esi
movq 0x3896(%rip), %rdi      # 0x5fd8
callq 0x2040
movq %rax, %rdi
callq 0x20b0
leaq 0x1929(%rip), %rsi      # 0x407f
leaq 0x28(%rsp), %rdi
callq 0x2afc
leaq 0x10(%rsp), %rdi
leaq 0x8(%rsp), %rsi
callq 0x31a4
leaq 0x8(%rsp), %rdi
leaq 0x28(%rsp), %rsi
callq 0x320a
leaq 0x28(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0x320a
leaq 0x10(%rsp), %rdi
callq 0x2bc0
leaq 0x28(%rsp), %rdi
callq 0x2bc0
movq 0x3830(%rip), %rbx      # 0x5fd8
leaq 0x18d6(%rip), %rsi      # 0x4085
movl $0xb, %edx
movq %rbx, %rdi
callq 0x2110
movq (%rbx), %rax
addq -0x18(%rax), %rbx
movq %rbx, %rdi
movl $0xa, %esi
callq 0x20e0
movsbl %al, %esi
movq 0x37fe(%rip), %rbx      # 0x5fd8
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x20b0
leaq 0x8(%rsp), %rdi
callq 0x2bc0
leaq 0x189d(%rip), %rsi      # 0x4098
movl $0x6, %edx
movq %rbx, %rdi
callq 0x2110
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x20e0
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x20b0
leaq 0x1869(%rip), %rsi      # 0x409f
leaq 0x38(%rsp), %r14
movq %r14, %rdi
callq 0x2afc
movq %r14, %rdi
callq 0x2bc0
leaq 0x1859(%rip), %rsi      # 0x40ab
movl $0x6, %edx
movq %rbx, %rdi
callq 0x2110
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x20e0
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x20b0
leaq 0x8(%rsp), %r14
movq %r14, %rdi
callq 0x2d7e
leaq 0x10(%rsp), %rdi
movq %r14, %rsi
xorl %edx, %edx
callq 0x2de6
leaq 0x30(%rsp), %rdi
leaq 0x10(%rsp), %rsi
xorl %edx, %edx
callq 0x2de6
leaq 0x30(%rsp), %rdi
callq 0x2bc0
leaq 0x10(%rsp), %r14
movq %r14, %rdi
callq 0x2bc0
leaq 0x8(%rsp), %rdi
callq 0x2bc0
leaq 0x17d7(%rip), %rsi      # 0x40b2
movl $0x6, %edx
movq %rbx, %rdi
callq 0x2110
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x20e0
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x20b0
leaq 0x1833(%rip), %r15      # 0x4149
movl $0xa, %edx
movq %rbx, %rdi
movq %r15, %rsi
callq 0x2110
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x20e0
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x20b0
movl $0xa, %edx
movq %rbx, %rdi
movq %r15, %rsi
callq 0x2110
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x20e0
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x20b0
leaq 0x172e(%rip), %rsi      # 0x40b9
movl $0x6, %edx
movq %rbx, %rdi
callq 0x2110
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x20e0
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x20b0
xorps %xmm0, %xmm0
movaps %xmm0, (%r14)
movq $0x0, 0x10(%r14)
leaq 0x16ca(%rip), %rsi      # 0x409f
leaq 0x10(%rsp), %rdi
callq 0x2e4c
leaq 0x10(%rsp), %r14
movq %r14, %rdi
callq 0x2e88
leaq 0x16cd(%rip), %rsi      # 0x40c0
movl $0x7, %edx
movq %rbx, %rdi
callq 0x2110
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x20e0
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x20b0
movq $0x0, (%r14)
leaq 0x18(%rsp), %rdi
leaq 0x1665(%rip), %rcx      # 0x409f
leaq 0x10(%rsp), %rbx
leaq 0x8(%rsp), %rdx
movq %rbx, %rsi
callq 0x34ba
movq 0x8(%rbx), %rdi
testq %rdi, %rdi
je 0x2a5a
callq 0x2eda
xorl %eax, %eax
addq $0x40, %rsp
popq %rbx
popq %r14
popq %r15
retq
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
callq 0x2e88
jmp 0x2af3
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
jmp 0x2acb
jmp 0x2ad2
movq %rax, %rbx
jmp 0x2ac6
jmp 0x2ad2
movq %rax, %rbx
leaq 0x8(%rsp), %rdi
callq 0x2d4a
jmp 0x2ae4
movq %rax, %rbx
movl $0x8, %esi
movq %r14, %rdi
callq 0x2100
jmp 0x2ae4
jmp 0x2ae1
jmp 0x2aaf
jmp 0x2aaf
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
jmp 0x2ada
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
callq 0x2bc0
leaq 0x28(%rsp), %rdi
callq 0x2bc0
jmp 0x2ad5
movq %rax, %rbx
leaq 0x8(%rsp), %rdi
callq 0x2bc0
jmp 0x2af3
movq %rax, %rbx
movq 0x18(%rsp), %rdi
testq %rdi, %rdi
je 0x2af3
callq 0x2eda
movq %rbx, %rdi
callq 0x2180
nop