// File: lemire[P]fastscancount/benchmark/counters.cpp
// Function: void test<demo_data(std::vector<std::vector<unsigned int, std::allocator<unsigned int>>, std::allocator<std::vector<unsigned int, std::allocator<unsigned int>>>> const&, std::vector<std::vector<unsigned int, std::allocator<unsigned int>>, std::allocator<std::vector<unsigned int, std::allocator<unsigned int>>>> const&, unsigned long)::$_0>(demo_data(std::vector<std::vector<unsigned int, std::allocator<unsigned int>>, std::allocator<std::vector<unsigned int, std::allocator<unsigned int>>>> const&, std::vector<std::vector<unsigned int, std::allocator<unsigned int>>, std::allocator<std::vector<unsigned int, std::allocator<unsigned int>>>> const&, unsigned long)::$_0, std::vector<std::vector<unsigned int, std::allocator<unsigned int>> const*, std::allocator<std::vector<unsigned int, std::allocator<unsigned int>> const*>> const&, std::vector<unsigned int, std::allocator<unsigned int>>&, unsigned int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&)
void test(F f, const std::vector<const std::vector<uint32_t>*>& data_ptrs,
          std::vector<uint32_t>& answer, unsigned threshold, const std::string &name) {
  scancount(data_ptrs, answer, threshold);
  size_t s1 = answer.size();
  auto a1 (answer);
  std::sort(a1.begin(), a1.end());
  answer.clear();
  f();
  size_t s2 = answer.size();
  auto a2 (answer);
  std::sort(a2.begin(), a2.end());
  if (a1 != a2) {
    std::cout << "s1: " << s1 << " s2: " << s2 << std::endl;
    for(size_t j = 0; j < std::min(s1, s2); j++) {
      std::cout << j << " " << a1[j] << " vs " << a2[j] ;

      if(a1[j] != a2[j]) std::cout << " oh oh ";
      std::cout << std::endl;
    }
    throw std::runtime_error("bug: " + name);
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x140, %rsp            # imm = 0x140
leaq 0x10(%rbp), %rax
movq %rax, -0xd0(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movq %rcx, -0x20(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %eax
movl %eax, %edx
callq 0x3d00
movq -0x10(%rbp), %rdi
callq 0x7a40
movq %rax, -0x28(%rbp)
movq -0x10(%rbp), %rsi
leaq -0x40(%rbp), %rdi
movq %rdi, -0xc8(%rbp)
callq 0x10870
movq -0xc8(%rbp), %rdi
callq 0x8980
movq -0xc8(%rbp), %rdi
movq %rax, -0x48(%rbp)
callq 0x89b0
movq %rax, -0x50(%rbp)
movq -0x48(%rbp), %rdi
movq -0x50(%rbp), %rsi
callq 0x8940
jmp 0x4e27
movq -0x10(%rbp), %rdi
callq 0x7c60
movq -0xd0(%rbp), %rdi
callq 0x76b0
jmp 0x4e3e
movq -0x10(%rbp), %rdi
callq 0x7a40
movq %rax, -0x68(%rbp)
movq -0x10(%rbp), %rsi
leaq -0x80(%rbp), %rdi
callq 0x10870
jmp 0x4e5a
leaq -0x80(%rbp), %rdi
movq %rdi, -0xd8(%rbp)
callq 0x8980
movq -0xd8(%rbp), %rdi
movq %rax, -0x88(%rbp)
callq 0x89b0
movq %rax, -0x90(%rbp)
movq -0x88(%rbp), %rdi
movq -0x90(%rbp), %rsi
callq 0x8940
jmp 0x4e99
leaq -0x40(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x10960
movb %al, -0xd9(%rbp)
jmp 0x4eae
movb -0xd9(%rbp), %al
testb $0x1, %al
jne 0x4ebd
jmp 0x5154
movq 0x19104(%rip), %rdi     # 0x1dfc8
leaq 0xf3af(%rip), %rsi      # 0x1427a
callq 0x3280
movq %rax, -0xe8(%rbp)
jmp 0x4ed9
movq -0xe8(%rbp), %rdi
movq -0x28(%rbp), %rsi
callq 0x3090
movq %rax, -0xf0(%rbp)
jmp 0x4ef2
movq -0xf0(%rbp), %rdi
leaq 0xf37f(%rip), %rsi      # 0x1427f
callq 0x3280
movq %rax, -0xf8(%rbp)
jmp 0x4f0e
movq -0xf8(%rbp), %rdi
movq -0x68(%rbp), %rsi
callq 0x3090
movq %rax, -0x100(%rbp)
jmp 0x4f27
movq -0x100(%rbp), %rdi
movq 0x19073(%rip), %rsi     # 0x1dfa8
callq 0x32c0
jmp 0x4f3c
movq $0x0, -0x98(%rbp)
movq -0x98(%rbp), %rax
movq %rax, -0x108(%rbp)
leaq -0x28(%rbp), %rdi
leaq -0x68(%rbp), %rsi
callq 0xcd60
movq %rax, %rcx
movq -0x108(%rbp), %rax
cmpq (%rcx), %rax
jae 0x50ac
movq -0x98(%rbp), %rsi
movq 0x19045(%rip), %rdi     # 0x1dfc8
callq 0x3090
movq %rax, -0x110(%rbp)
jmp 0x4f91
movq -0x110(%rbp), %rdi
leaq 0xf2de(%rip), %rsi      # 0x1427d
callq 0x3280
movq %rax, -0x118(%rbp)
jmp 0x4fad
movq -0x98(%rbp), %rsi
leaq -0x40(%rbp), %rdi
callq 0x10990
movq -0x118(%rbp), %rdi
movl (%rax), %esi
callq 0x3340
movq %rax, -0x120(%rbp)
jmp 0x4fd4
movq -0x120(%rbp), %rdi
leaq 0xf2a3(%rip), %rsi      # 0x14285
callq 0x3280
movq %rax, -0x128(%rbp)
jmp 0x4ff0
movq -0x98(%rbp), %rsi
leaq -0x80(%rbp), %rdi
callq 0x10990
movq -0x128(%rbp), %rdi
movl (%rax), %esi
callq 0x3340
jmp 0x5010
movq -0x98(%rbp), %rsi
leaq -0x40(%rbp), %rdi
callq 0x10990
movl (%rax), %eax
movl %eax, -0x12c(%rbp)
movq -0x98(%rbp), %rsi
leaq -0x80(%rbp), %rdi
callq 0x10990
movq %rax, %rcx
movl -0x12c(%rbp), %eax
cmpl (%rcx), %eax
je 0x507e
movq 0x18f7c(%rip), %rdi     # 0x1dfc8
leaq 0xf237(%rip), %rsi      # 0x1428a
callq 0x3280
jmp 0x505a
jmp 0x507e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x5178
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x516f
movq 0x18f43(%rip), %rdi     # 0x1dfc8
movq 0x18f1c(%rip), %rsi     # 0x1dfa8
callq 0x32c0
jmp 0x5093
jmp 0x5095
movq -0x98(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x98(%rbp)
jmp 0x4f47
movb $0x1, -0xb9(%rbp)
movl $0x10, %edi
callq 0x3160
movq %rax, -0x138(%rbp)
movq -0x20(%rbp), %rdx
leaq 0xf1c3(%rip), %rsi      # 0x14292
leaq -0xb8(%rbp), %rdi
callq 0x8b40
jmp 0x50dd
movq -0x138(%rbp), %rdi
leaq -0xb8(%rbp), %rsi
callq 0x3410
jmp 0x50f2
movq -0x138(%rbp), %rdi
movb $0x0, -0xb9(%rbp)
movq 0x18ee9(%rip), %rsi     # 0x1dff0
movq 0x18eaa(%rip), %rdx     # 0x1dfb8
callq 0x3450
jmp 0x518a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x513b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0xb8(%rbp), %rdi
callq 0x31b0
testb $0x1, -0xb9(%rbp)
jne 0x5146
jmp 0x5152
movq -0x138(%rbp), %rdi
callq 0x3200
jmp 0x516f
leaq -0x80(%rbp), %rdi
callq 0x8800
leaq -0x40(%rbp), %rdi
callq 0x8800
addq $0x140, %rsp            # imm = 0x140
popq %rbp
retq
leaq -0x80(%rbp), %rdi
callq 0x8800
leaq -0x40(%rbp), %rdi
callq 0x8800
movq -0x58(%rbp), %rdi
callq 0x3470
nopw (%rax,%rax)