// File: Pyboon[P]sage/./Eigen/src/Core/ProductEvaluators.h
// Function: void Eigen::internal::permutation_matrix_product<Eigen::CwiseNullaryOp<Eigen::internal::scalar_identity_op<std::complex<double>>, Eigen::Matrix<std::complex<double>, -1, -1, 0, -1, -1>>, 1, false, Eigen::DenseShape>::run<Eigen::Matrix<std::complex<double>, -1, -1, 0, -1, -1>, Eigen::PermutationMatrix<-1, -1, int>>(Eigen::Matrix<std::complex<double>, -1, -1, 0, -1, -1>&, Eigen::PermutationMatrix<-1, -1, int> const&, Eigen::CwiseNullaryOp<Eigen::internal::scalar_identity_op<std::complex<double>>, Eigen::Matrix<std::complex<double>, -1, -1, 0, -1, -1>> const&)
static inline void run(Dest& dst, const PermutationType& perm, const ExpressionType& xpr)
    {
      MatrixType mat(xpr);
      const Index n = Side==OnTheLeft ? mat.rows() : mat.cols();
      // FIXME we need an is_same for expression that is not sensitive to constness. For instance
      // is_same_xpr<Block<const Matrix>, Block<Matrix> >::value should be true.
      //if(is_same<MatrixTypeCleaned,Dest>::value && extract_data(dst) == extract_data(mat))
      if(is_same_dense(dst, mat))
      {
        // apply the permutation inplace
        Matrix<bool,PermutationType::RowsAtCompileTime,1,0,PermutationType::MaxRowsAtCompileTime> mask(perm.size());
        mask.fill(false);
        Index r = 0;
        while(r < perm.size())
        {
          // search for the next seed
          while(r<perm.size() && mask[r]) r++;
          if(r>=perm.size())
            break;
          // we got one, let's follow it until we are back to the seed
          Index k0 = r++;
          Index kPrev = k0;
          mask.coeffRef(k0) = true;
          for(Index k=perm.indices().coeff(k0); k!=k0; k=perm.indices().coeff(k))
          {
                  Block<Dest, Side==OnTheLeft ? 1 : Dest::RowsAtCompileTime, Side==OnTheRight ? 1 : Dest::ColsAtCompileTime>(dst, k)
            .swap(Block<Dest, Side==OnTheLeft ? 1 : Dest::RowsAtCompileTime, Side==OnTheRight ? 1 : Dest::ColsAtCompileTime>
                       (dst,((Side==OnTheLeft) ^ Transposed) ? k0 : kPrev));

            mask.coeffRef(k) = true;
            kPrev = k;
          }
        }
      }
      else
      {
        for(Index i = 0; i < n; ++i)
        {
          Block<Dest, Side==OnTheLeft ? 1 : Dest::RowsAtCompileTime, Side==OnTheRight ? 1 : Dest::ColsAtCompileTime>
               (dst, ((Side==OnTheLeft) ^ Transposed) ? perm.indices().coeff(i) : i)

          =

          Block<const MatrixTypeCleaned,Side==OnTheLeft ? 1 : MatrixTypeCleaned::RowsAtCompileTime,Side==OnTheRight ? 1 : MatrixTypeCleaned::ColsAtCompileTime>
               (mat, ((Side==OnTheRight) ^ Transposed) ? perm.indices().coeff(i) : i);
        }
      }
    }

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1d0, %rsp            # imm = 0x1D0
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x18(%rbp), %rsi
leaq -0x30(%rbp), %rdi
callq 0x5bd90
leaq -0x30(%rbp), %rdi
callq 0x5bb10
movq %rax, -0x38(%rbp)
movq -0x8(%rbp), %rdi
leaq -0x30(%rbp), %rsi
xorl %eax, %eax
movl %eax, %edx
callq 0x5c440
testb $0x1, %al
jne 0x5c13b
jmp 0x5c38c
movq -0x10(%rbp), %rdi
callq 0x5ae40
movq %rax, -0x50(%rbp)
leaq -0x48(%rbp), %rdi
movq %rdi, -0x178(%rbp)
leaq -0x50(%rbp), %rsi
callq 0x5c460
movq -0x178(%rbp), %rdi
movb $0x0, -0x51(%rbp)
leaq -0x51(%rbp), %rsi
callq 0x5c4c0
jmp 0x5c172
movq $0x0, -0x70(%rbp)
movq -0x70(%rbp), %rax
movq %rax, -0x188(%rbp)
movq -0x10(%rbp), %rdi
callq 0x5ae40
movq %rax, -0x180(%rbp)
jmp 0x5c197
movq -0x188(%rbp), %rax
movq -0x180(%rbp), %rcx
cmpq %rcx, %rax
jge 0x5c37e
jmp 0x5c1b0
movq -0x70(%rbp), %rax
movq %rax, -0x198(%rbp)
movq -0x10(%rbp), %rdi
callq 0x5ae40
movq %rax, -0x190(%rbp)
jmp 0x5c1cd
movq -0x198(%rbp), %rcx
movq -0x190(%rbp), %rdx
xorl %eax, %eax
cmpq %rdx, %rcx
movb %al, -0x199(%rbp)
jge 0x5c20d
movq -0x70(%rbp), %rsi
leaq -0x48(%rbp), %rdi
callq 0x5c4f0
movq %rax, -0x1a8(%rbp)
jmp 0x5c1fe
movq -0x1a8(%rbp), %rax
movb (%rax), %al
movb %al, -0x199(%rbp)
movb -0x199(%rbp), %al
testb $0x1, %al
jne 0x5c219
jmp 0x5c241
movq -0x70(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x70(%rbp)
jmp 0x5c1b0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0x48(%rbp), %rdi
callq 0x5c680
jmp 0x5c429
movq -0x70(%rbp), %rax
movq %rax, -0x1b8(%rbp)
movq -0x10(%rbp), %rdi
callq 0x5ae40
movq %rax, -0x1b0(%rbp)
jmp 0x5c25e
movq -0x1b8(%rbp), %rax
movq -0x1b0(%rbp), %rcx
cmpq %rcx, %rax
jl 0x5c276
jmp 0x5c37e
movq -0x70(%rbp), %rax
movq %rax, %rcx
incq %rcx
movq %rcx, -0x70(%rbp)
movq %rax, -0x78(%rbp)
movq -0x78(%rbp), %rax
movq %rax, -0x80(%rbp)
movq -0x78(%rbp), %rsi
leaq -0x48(%rbp), %rdi
callq 0x5c580
movq %rax, -0x1c0(%rbp)
jmp 0x5c2a6
movq -0x1c0(%rbp), %rax
movb $0x1, (%rax)
movq -0x10(%rbp), %rdi
callq 0x5b0b0
movq %rax, %rdi
movq -0x78(%rbp), %rsi
callq 0x5b0f0
movslq (%rax), %rax
movq %rax, -0x88(%rbp)
movq -0x88(%rbp), %rax
cmpq -0x78(%rbp), %rax
je 0x5c379
movq -0x8(%rbp), %rsi
movq -0x88(%rbp), %rdx
leaq -0xc0(%rbp), %rdi
callq 0x24310
jmp 0x5c2f9
movq -0x8(%rbp), %rsi
movq -0x78(%rbp), %rdx
leaq -0xf8(%rbp), %rdi
callq 0x24310
jmp 0x5c30f
leaq -0xc0(%rbp), %rdi
leaq -0xf8(%rbp), %rsi
callq 0x5c5b0
jmp 0x5c324
movq -0x88(%rbp), %rsi
leaq -0x48(%rbp), %rdi
callq 0x5c580
movq %rax, -0x1c8(%rbp)
jmp 0x5c33d
movq -0x1c8(%rbp), %rax
movb $0x1, (%rax)
movq -0x88(%rbp), %rax
movq %rax, -0x80(%rbp)
movq -0x10(%rbp), %rdi
callq 0x5b0b0
movq %rax, %rdi
movq -0x88(%rbp), %rsi
callq 0x5b0f0
movslq (%rax), %rax
movq %rax, -0x88(%rbp)
jmp 0x5c2cf
jmp 0x5c17a
leaq -0x48(%rbp), %rdi
callq 0x5c680
jmp 0x5c420
movq $0x0, -0x100(%rbp)
movq -0x100(%rbp), %rax
cmpq -0x38(%rbp), %rax
jge 0x5c41e
movq -0x100(%rbp), %rdx
leaq -0x138(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0x5c6a0
movq -0x8(%rbp), %rax
movq %rax, -0x1d0(%rbp)
movq -0x10(%rbp), %rdi
callq 0x5b0b0
movq %rax, %rdi
movq -0x100(%rbp), %rsi
callq 0x5b0f0
movq -0x1d0(%rbp), %rsi
movslq (%rax), %rdx
leaq -0x170(%rbp), %rdi
callq 0x24310
leaq -0x170(%rbp), %rdi
leaq -0x138(%rbp), %rsi
callq 0x5c730
movq -0x100(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x100(%rbp)
jmp 0x5c397
jmp 0x5c420
addq $0x1d0, %rsp            # imm = 0x1D0
popq %rbp
retq
movq -0x60(%rbp), %rdi
callq 0x9dc0
nopw %cs:(%rax,%rax)
nopl (%rax)