// File: /workspace/github_cpp_makefile_star2_O3/A-deLuna[P]encora-cpp-test/main.cpp
// Function: testBitwiseAdd()
void testBitwiseAdd() {
  struct TestCase {
    int a;
    int b;
    int result;
    bool overflow;
  };
  // I know designated initializers are not part of the standard yet...
  // but I feel they make the code a lot better and they're supported by
  // clang and gcc.
  TestCase cases[] = {
      {.a = 0, .b = 0, .result = 0, .overflow = false},
      {.a = 1, .b = 1, .result = 2, .overflow = false},
      {.a = -1, .b = -1, .result = -2, .overflow = false},
      {.a = -1, .b = 1, .result = 0, .overflow = false},
      {.a = -10, .b = 5, .result = -5, .overflow = false},
      {.a = 10, .b = -5, .result = 5, .overflow = false},

      {.a = std::numeric_limits<int>::max(), .b = 1, .overflow = true},
      {.a = std::numeric_limits<int>::min(), .b = -1, .overflow = true},
  };

  int failedCases = 0;
  for (const TestCase& c : cases) {
    bool threw = false;
    int result = 0;
    try {
      result = add(c.a, c.b);
    } catch (const std::overflow_error& e) {
      threw = true;
    }
    if (c.overflow && !threw) {
      std::cout << "error on test case add(" << c.a << ", " << c.b << ");\n";
      std::cout << "expected exception and did not throw.\n";
      failedCases++;
      continue;
    }
    if (!c.overflow && threw) {
      std::cout << "error on test case add(" << c.a << ", " << c.b << ");\n";
      std::cout << "received exception but did not expect any.\n";
      failedCases++;
      continue;
    }

    if (result != c.result) {
      std::cout << "result of add(" << c.a << ", " << c.b << ") was " << result
                << "\n";
      std::cout << "but expected " << c.result << "\n";
      failedCases++;
      continue;
    }
  }
  if (failedCases == 0) {
    std::cout << "bitwise add: All cases succeeded\n";
  } else {
    std::cout << "bitwise add: failed a total of " << failedCases << " cases\n";
  }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq $0x0, (%rsp)
leaq 0x155e(%rip), %r14      # 0x30d0
xorl %ebx, %ebx
movl (%rbx,%r14), %ebp
movl 0x4(%rbx,%r14), %r13d
movl %ebp, %edi
movl %r13d, %esi
callq 0x133c
movl %eax, %r12d
cmpb $0x1, 0xc(%rbx,%r14)
jne 0x1c38
movl $0x17, %edx
movq 0x3436(%rip), %r14      # 0x4fd8
movq %r14, %rdi
leaq 0x15e8(%rip), %rsi      # 0x3194
callq 0x10f0
movq %r14, %rdi
movl %ebp, %esi
callq 0x1150
movq %rax, %r15
movl $0x2, %edx
movq %rax, %rdi
leaq 0x15df(%rip), %rsi      # 0x31ac
callq 0x10f0
movq %r15, %rdi
movl %r13d, %esi
callq 0x1150
movl $0x3, %edx
movq %rax, %rdi
leaq 0x15c3(%rip), %rsi      # 0x31af
callq 0x10f0
movl $0x26, %edx
movq %r14, %rdi
leaq 0x14d0(%rip), %r14      # 0x30d0
leaq 0x15ac(%rip), %rsi      # 0x31b3
jmp 0x1cf7
movq %rax, %rdi
cmpl $0x1, %edx
jne 0x1df3
callq 0x1060
callq 0x1130
xorl %r12d, %r12d
leaq 0x14a4(%rip), %r14      # 0x30d0
cmpb $0x0, 0xc(%rbx,%r14)
je 0x1d19
movl 0x8(%rbx,%r14), %r15d
cmpl %r15d, %r12d
je 0x1d06
movl $0xe, %edx
movq 0x3386(%rip), %r14      # 0x4fd8
movq %r14, %rdi
leaq 0x15aa(%rip), %rsi      # 0x3206
callq 0x10f0
movq %r14, %rdi
movl %ebp, %esi
callq 0x1150
movq %rax, %rbp
movl $0x2, %edx
movq %rax, %rdi
leaq 0x152f(%rip), %rsi      # 0x31ac
callq 0x10f0
movq %rbp, %rdi
movl %r13d, %esi
callq 0x1150
movq %rax, %r13
movl $0x6, %edx
movq %rax, %rdi
leaq 0x1576(%rip), %rsi      # 0x3215
callq 0x10f0
movq %r13, %rdi
movl %r12d, %esi
callq 0x1150
movl $0x1, %edx
movq %rax, %rdi
leaq 0x151a(%rip), %r12      # 0x31d8
movq %r12, %rsi
callq 0x10f0
movl $0xd, %edx
movq %r14, %rdi
leaq 0x1547(%rip), %rsi      # 0x321c
callq 0x10f0
movq %r14, %rdi
leaq 0x13ec(%rip), %r14      # 0x30d0
movl %r15d, %esi
callq 0x1150
movl $0x1, %edx
movq %rax, %rdi
movq %r12, %rsi
callq 0x10f0
movq (%rsp), %rax
incl %eax
movq %rax, (%rsp)
addq $0x10, %rbx
cmpq $0x80, %rbx
jne 0x1b74
jmp 0x1d8f
movl $0x17, %edx
movq 0x32b3(%rip), %r14      # 0x4fd8
movq %r14, %rdi
leaq 0x1465(%rip), %rsi      # 0x3194
callq 0x10f0
movq %r14, %rdi
movl %ebp, %esi
callq 0x1150
movq %rax, %r15
movl $0x2, %edx
movq %rax, %rdi
leaq 0x145c(%rip), %rsi      # 0x31ac
callq 0x10f0
movq %r15, %rdi
movl %r13d, %esi
callq 0x1150
movl $0x3, %edx
movq %rax, %rdi
leaq 0x1440(%rip), %rsi      # 0x31af
callq 0x10f0
movl $0x2b, %edx
movq %r14, %rdi
leaq 0x134d(%rip), %r14      # 0x30d0
leaq 0x1450(%rip), %rsi      # 0x31da
jmp 0x1cf7
movq (%rsp), %rbx
testl %ebx, %ebx
je 0x1dcd
movq 0x323a(%rip), %r14      # 0x4fd8
leaq 0x14a7(%rip), %rsi      # 0x324c
movl $0x1f, %edx
movq %r14, %rdi
callq 0x10f0
movq %r14, %rdi
movl %ebx, %esi
callq 0x1150
leaq 0x14a9(%rip), %rsi      # 0x326c
movl $0x7, %edx
movq %rax, %rdi
jmp 0x1de0
movq 0x3204(%rip), %rdi      # 0x4fd8
leaq 0x144f(%rip), %rsi      # 0x322a
movl $0x21, %edx
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x10f0
callq 0x1160