// File: dsharlet[P]array/include/array/array.h
// Function: void nda::for_each_value_in_order<nda::shape<nda::dim<-9l, -9l, -9l>, nda::dim<-9l, -9l, -9l>, nda::dim<-9l, -9l, -9l>>, nda::shape<nda::dim<-9l, -9l, -9l>, nda::dim<-9l, -9l, -9l>, nda::dim<-9l, -9l, -9l>>, int const*, nda::shape<nda::dim<-9l, -9l, -9l>, nda::dim<-9l, -9l, -9l>, nda::dim<-9l, -9l, -9l>>, int*, void (&)(int const&, int&), void>(nda::shape<nda::dim<-9l, -9l, -9l>, nda::dim<-9l, -9l, -9l>, nda::dim<-9l, -9l, -9l>> const&, nda::shape<nda::dim<-9l, -9l, -9l>, nda::dim<-9l, -9l, -9l>, nda::dim<-9l, -9l, -9l>> const&, int const*, nda::shape<nda::dim<-9l, -9l, -9l>, nda::dim<-9l, -9l, -9l>, nda::dim<-9l, -9l, -9l>> const&, int*, void (&)(int const&, int&))
NDARRAY_UNIQUE NDARRAY_HOST_DEVICE void for_each_value_in_order(const Shape& shape,
    const ShapeA& shape_a, PtrA base_a, const ShapeB& shape_b, PtrB base_b, Fn&& fn) {
  if (!base_a || !base_b) {
    assert(shape.empty());
    return;
  }
  base_a += shape_a[shape.min()];
  base_b += shape_b[shape.min()];
  // TODO: This is losing compile-time constant extents and strides info
  // (https://github.com/dsharlet/array/issues/1).
  auto a = std::make_pair(base_a, shape_a.stride());
  auto b = std::make_pair(base_b, shape_b.stride());
  internal::for_each_value_in_order<Shape::rank() - 1>(shape.extent(), fn, a, b);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1a0, %rsp            # imm = 0x1A0
movq %rdi, -0x68(%rbp)
movq %rsi, -0x70(%rbp)
movq %rdx, -0x78(%rbp)
movq %rcx, -0x80(%rbp)
movq %r8, -0x88(%rbp)
movq %r9, -0x90(%rbp)
cmpq $0x0, -0x78(%rbp)
je 0xbf2a
cmpq $0x0, -0x88(%rbp)
jne 0xbf5f
movq -0x68(%rbp), %rdi
callq 0x14440
testb $0x1, %al
jne 0xbf39
jmp 0xbf3b
jmp 0xbf5a
leaq 0x1d04a3(%rip), %rdi    # 0x1dc3e5
leaq 0x1d0198(%rip), %rsi    # 0x1dc0e1
movl $0x6b8, %edx            # imm = 0x6B8
leaq 0x1d06a8(%rip), %rcx    # 0x1dc5fd
callq 0x3130
jmp 0xc143
movq -0x70(%rbp), %rax
movq %rax, -0x198(%rbp)
movq -0x68(%rbp), %rsi
leaq -0xa8(%rbp), %rdi
callq 0x16050
movq -0x198(%rbp), %rdi
leaq -0xa8(%rbp), %rsi
callq 0x16020
shlq $0x2, %rax
addq -0x78(%rbp), %rax
movq %rax, -0x78(%rbp)
movq -0x80(%rbp), %rax
movq %rax, -0x190(%rbp)
movq -0x68(%rbp), %rsi
leaq -0xc0(%rbp), %rdi
callq 0x16050
movq -0x190(%rbp), %rdi
leaq -0xc0(%rbp), %rsi
callq 0x16020
shlq $0x2, %rax
addq -0x88(%rbp), %rax
movq %rax, -0x88(%rbp)
movq -0x70(%rbp), %rsi
leaq -0xf8(%rbp), %rdi
callq 0x144b0
leaq -0xe0(%rbp), %rdi
leaq -0x78(%rbp), %rsi
leaq -0xf8(%rbp), %rdx
callq 0x16080
movq -0x80(%rbp), %rsi
leaq -0x130(%rbp), %rdi
callq 0x144b0
leaq -0x118(%rbp), %rdi
leaq -0x88(%rbp), %rsi
leaq -0x130(%rbp), %rdx
callq 0x14470
movq -0x68(%rbp), %rsi
leaq -0x148(%rbp), %rdi
callq 0x144e0
movq -0x90(%rbp), %rax
movq -0xe0(%rbp), %rcx
movq %rcx, -0x168(%rbp)
movq -0xd8(%rbp), %rcx
movq %rcx, -0x160(%rbp)
movq -0xd0(%rbp), %rcx
movq %rcx, -0x158(%rbp)
movq -0xc8(%rbp), %rcx
movq %rcx, -0x150(%rbp)
movq -0x118(%rbp), %rcx
movq %rcx, -0x188(%rbp)
movq -0x110(%rbp), %rcx
movq %rcx, -0x180(%rbp)
movq -0x108(%rbp), %rcx
movq %rcx, -0x178(%rbp)
movq -0x100(%rbp), %rcx
movq %rcx, -0x170(%rbp)
leaq -0x148(%rbp), %rcx
movq %rcx, -0x8(%rbp)
movq %rax, -0x10(%rbp)
leaq -0x168(%rbp), %rax
movq %rax, -0x18(%rbp)
leaq -0x188(%rbp), %rax
movq %rax, -0x20(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x168(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x160(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x158(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x150(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x188(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x180(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x178(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x170(%rbp), %rax
movq %rax, -0x48(%rbp)
leaq -0x40(%rbp), %rdx
leaq -0x60(%rbp), %rcx
callq 0xc150
addq $0x1a0, %rsp            # imm = 0x1A0
popq %rbp
retq
nopl (%rax)