// File: redpony[P]cpyp/./cpyp/mf_crp.h
// Function: std::pair<unsigned int, int> cpyp::mf_crp<2u, unsigned int, std::hash<unsigned int>>::increment<long double*, double*, cpyp::MT19937>(unsigned int const&, long double*, double*, cpyp::MT19937&)
std::pair<unsigned,int> increment(const Dish& dish, InputIterator p0i, InputIterator2 lambdas, Engine& eng) {
    typedef decltype(*p0i + 0.0) F;

    const F marginal_p0 = std::inner_product(p0i, p0i + NumFloors, lambdas, F(0.0));
    if (marginal_p0 > F(1.000001)) {
      std::cerr << "bad marginal: " << marginal_p0 << std::endl;
      abort();
    }

    crp_table_manager<NumFloors>& loc = dish_locs_[dish];
    bool share_table = false;
    if (loc.num_customers()) {
      const F p_empty = F(strength_ + num_tables_ * discount_) * marginal_p0;
      const F p_share = F(loc.num_customers() - loc.num_tables() * discount_);
      share_table = sample_bernoulli(p_empty, p_share, eng);
    }

    unsigned floor = 0;
    if (share_table) {
      unsigned n = loc.share_table(discount_, eng);
      update_llh_add_customer_to_table_seating(n);
    } else {
      if (NumFloors > 1) { // sample floor
        F r = F(sample_uniform01<double>(eng)) * marginal_p0;
        for (unsigned i = 0; i < NumFloors; ++i) {
          r -= (*p0i) * (*lambdas);
          ++p0i;
          ++lambdas;
          if (r <= F(0.0)) { floor = i; break; }
        }
      }
      loc.create_table(floor);
      update_llh_add_customer_to_table_seating(0);
      ++num_tables_;
    }
    ++num_customers_;
    return std::make_pair(floor, share_table ? 0 : 1);
  }

// Assembly:
subq $0xe8, %rsp
movq %rdi, 0xd8(%rsp)
movq %rsi, 0xd0(%rsp)
movq %rdx, 0xc8(%rsp)
movq %rcx, 0xc0(%rsp)
movq %r8, 0xb8(%rsp)
movq 0xd8(%rsp), %rax
movq %rax, 0x28(%rsp)
movq 0xc8(%rsp), %rdi
movq %rdi, %rsi
addq $0x20, %rsi
movq 0xc0(%rsp), %rdx
movq %rsp, %rax
fldz
fstpt (%rax)
callq 0x123f0
fstpt 0xa0(%rsp)
fldt 0xa0(%rsp)
fldl 0xe2bd(%rip)            # 0x15040
fxch %st(1)
fucompi %st(1), %st
fstp %st(0)
jbe 0x6dc8
jmp 0x6d8d
movq 0x1725c(%rip), %rdi     # 0x1dff0
leaq 0xed56(%rip), %rsi      # 0x15af1
callq 0x2180
movq %rax, %rdi
fldt 0xa0(%rsp)
movq %rsp, %rax
fstpt (%rax)
callq 0x21b0
movq %rax, %rdi
movq 0x1720a(%rip), %rsi     # 0x1dfc8
callq 0x21a0
callq 0x20d0
movq 0x28(%rsp), %rdi
addq $0x8, %rdi
movq 0xd0(%rsp), %rsi
callq 0x12450
movq %rax, 0x98(%rsp)
movb $0x0, 0x97(%rsp)
movq 0x98(%rsp), %rdi
callq 0x12480
cmpl $0x0, %eax
je 0x6ec1
movq 0x28(%rsp), %rax
movsd 0x48(%rax), %xmm1
movl (%rax), %ecx
cvtsi2sd %rcx, %xmm0
movsd 0x40(%rax), %xmm2
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x40(%rsp)
fldl 0x40(%rsp)
fldt 0xa0(%rsp)
fmulp %st, %st(1)
fstpt 0x80(%rsp)
movq 0x98(%rsp), %rdi
callq 0x12480
movl %eax, %eax
cvtsi2sd %rax, %xmm0
movsd %xmm0, 0x20(%rsp)
movq 0x98(%rsp), %rdi
callq 0x122f0
movsd 0x20(%rsp), %xmm0
movl %eax, %ecx
movq 0x28(%rsp), %rax
movl %ecx, %ecx
cvtsi2sd %rcx, %xmm1
movsd 0x40(%rax), %xmm2
mulsd %xmm2, %xmm1
subsd %xmm1, %xmm0
movsd %xmm0, 0x38(%rsp)
fldl 0x38(%rsp)
fstpt 0x70(%rsp)
fldt 0x80(%rsp)
fldt 0x70(%rsp)
movq 0xb8(%rsp), %rdi
movq %rsp, %rax
fstpt 0x10(%rax)
fstpt (%rax)
callq 0x12490
cmpl $0x0, %eax
setne %al
andb $0x1, %al
movb %al, 0x97(%rsp)
movl $0x0, 0x6c(%rsp)
testb $0x1, 0x97(%rsp)
je 0x6f09
movq 0x28(%rsp), %rax
movq 0x98(%rsp), %rdi
movsd 0x40(%rax), %xmm0
movq 0xb8(%rsp), %rsi
callq 0x124e0
movq 0x28(%rsp), %rdi
movl %eax, 0x68(%rsp)
movl 0x68(%rsp), %esi
callq 0x125f0
jmp 0x6fd6
movq 0xb8(%rsp), %rdi
callq 0x6510
movsd %xmm0, 0x30(%rsp)
fldl 0x30(%rsp)
fldt 0xa0(%rsp)
fmulp %st, %st(1)
fstpt 0x50(%rsp)
movl $0x0, 0x4c(%rsp)
cmpl $0x2, 0x4c(%rsp)
jae 0x6fad
movq 0xc8(%rsp), %rax
fldt (%rax)
movq 0xc0(%rsp), %rax
fldl (%rax)
fldt 0x50(%rsp)
fxch %st(2)
fmulp %st, %st(1)
fsubrp %st, %st(1)
fstpt 0x50(%rsp)
movq 0xc8(%rsp), %rax
addq $0x10, %rax
movq %rax, 0xc8(%rsp)
movq 0xc0(%rsp), %rax
addq $0x8, %rax
movq %rax, 0xc0(%rsp)
fldt 0x50(%rsp)
fldz
fucompi %st(1), %st
fstp %st(0)
jb 0x6f9e
jmp 0x6f94
movl 0x4c(%rsp), %eax
movl %eax, 0x6c(%rsp)
jmp 0x6fad
jmp 0x6fa0
movl 0x4c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x4c(%rsp)
jmp 0x6f35
movq 0x98(%rsp), %rdi
movl 0x6c(%rsp), %esi
callq 0x126e0
movq 0x28(%rsp), %rdi
xorl %esi, %esi
callq 0x125f0
movq 0x28(%rsp), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
movq 0x28(%rsp), %rax
movl 0x4(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x4(%rax)
movb 0x97(%rsp), %dl
movl $0x1, %eax
xorl %ecx, %ecx
testb $0x1, %dl
cmovnel %ecx, %eax
movl %eax, 0x48(%rsp)
leaq 0x6c(%rsp), %rdi
leaq 0x48(%rsp), %rsi
callq 0x12760
movq %rax, 0xe0(%rsp)
movq 0xe0(%rsp), %rax
addq $0xe8, %rsp
retq
nopw %cs:(%rax,%rax)
nopl (%rax)