// File: /workspace/github_cpp_makefile_star2_O1/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
xorl %ebx, %ebx
leaq 0x1630(%rip), %r12      # 0x3090
xorl %r14d, %r14d
movl (%r14,%r12), %r15d
movl 0x4(%r14,%r12), %ebp
movl %r15d, %edi
movl %ebp, %esi
callq 0x133c
movl %eax, %r13d
movb $0x1, %al
movb 0xc(%r14,%r12), %cl
movl %eax, %edx
andb %cl, %dl
cmpb $0x1, %dl
jne 0x1af8
movl $0x17, %edx
movq 0x3543(%rip), %r13      # 0x4fd8
movq %r13, %rdi
leaq 0x16b5(%rip), %rsi      # 0x3154
callq 0x10f0
movq %r13, %rdi
movl %r15d, %esi
callq 0x1150
movq %rax, %r15
movl $0x2, %edx
movq %rax, %rdi
leaq 0x16ab(%rip), %rsi      # 0x316c
callq 0x10f0
movq %r15, %rdi
movl %ebp, %esi
callq 0x1150
movl $0x3, %edx
movq %rax, %rdi
leaq 0x1690(%rip), %rsi      # 0x316f
callq 0x10f0
movl $0x26, %edx
movq %r13, %rdi
leaq 0x1680(%rip), %rsi      # 0x3173
jmp 0x1c3a
orb %cl, %al
je 0x1bd0
movl 0x8(%r14,%r12), %r12d
cmpl %r12d, %r13d
je 0x1bc7
movl $0xe, %edx
movq 0x34be(%rip), %rdi      # 0x4fd8
leaq 0x16a5(%rip), %rsi      # 0x31c6
callq 0x10f0
movq 0x34ab(%rip), %rdi      # 0x4fd8
movl %r15d, %esi
callq 0x1150
movq %rax, %r15
movl $0x2, %edx
movq %rax, %rdi
leaq 0x1625(%rip), %rsi      # 0x316c
callq 0x10f0
movq %r15, %rdi
movl %ebp, %esi
callq 0x1150
movq %rax, %r15
movl $0x6, %edx
movq %rax, %rdi
leaq 0x166d(%rip), %rsi      # 0x31d5
callq 0x10f0
movq %r15, %rdi
movl %r13d, %esi
callq 0x1150
movl $0x1, %edx
movq %rax, %rdi
leaq 0x1611(%rip), %r15      # 0x3198
movq %r15, %rsi
callq 0x10f0
movl $0xd, %edx
movq 0x343d(%rip), %r13      # 0x4fd8
movq %r13, %rdi
leaq 0x1637(%rip), %rsi      # 0x31dc
callq 0x10f0
movq %r13, %rdi
movl %r12d, %esi
callq 0x1150
movl $0x1, %edx
movq %rax, %rdi
movq %r15, %rsi
callq 0x10f0
incl %ebx
leaq 0x14c2(%rip), %r12      # 0x3090
jmp 0x1c41
movl $0x17, %edx
movq 0x33fc(%rip), %r13      # 0x4fd8
movq %r13, %rdi
leaq 0x156e(%rip), %rsi      # 0x3154
callq 0x10f0
movq %r13, %rdi
movl %r15d, %esi
callq 0x1150
movq %rax, %r15
movl $0x2, %edx
movq %rax, %rdi
leaq 0x1564(%rip), %rsi      # 0x316c
callq 0x10f0
movq %r15, %rdi
movl %ebp, %esi
callq 0x1150
movl $0x3, %edx
movq %rax, %rdi
leaq 0x1549(%rip), %rsi      # 0x316f
callq 0x10f0
movl $0x2b, %edx
movq %r13, %rdi
leaq 0x1560(%rip), %rsi      # 0x319a
callq 0x10f0
incl %ebx
addq $0x10, %r14
cmpq $0x80, %r14
jne 0x1a63
jmp 0x1c70
movq %rax, %rdi
cmpl $0x1, %edx
jne 0x1cd0
callq 0x1060
callq 0x1130
xorl %eax, %eax
xorl %r13d, %r13d
jmp 0x1a7b
testl %ebx, %ebx
je 0x1caa
movq 0x335d(%rip), %r14      # 0x4fd8
leaq 0x158a(%rip), %rsi      # 0x320c
movl $0x1f, %edx
movq %r14, %rdi
callq 0x10f0
movq %r14, %rdi
movl %ebx, %esi
callq 0x1150
leaq 0x158c(%rip), %rsi      # 0x322c
movl $0x7, %edx
movq %rax, %rdi
jmp 0x1cbd
movq 0x3327(%rip), %rdi      # 0x4fd8
leaq 0x1532(%rip), %rsi      # 0x31ea
movl $0x21, %edx
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x10f0
callq 0x1160