text: static inline void
  yield_each_with_index(dtype x, size_t *c, VALUE *a, int nd, int md)
  {
      int j;
  
      a[0] = m_data_to_num(x);
      for (j=0; j<=nd; j++) {
          a[j+1] = SIZET2NUM(c[j]);
      }
      rb_yield(rb_ary_new4(md,a));
  }
  
  
  static void
  <%=c_iter%>(na_loop_t *const lp)
  {
      size_t i, s1;
      char *p1;
      size_t *idx1;
      dtype x;
      VALUE *a;
      size_t *c;
      int nd, md;
  
      c = (size_t*)(lp->opt_ptr);
      nd = lp->ndim;
      if (nd > 0) {nd--;}
      md = nd + 2;
      a = ALLOCA_N(VALUE,md);
  
      INIT_COUNTER(lp, i);
      INIT_PTR_IDX(lp, 0, p1, s1, idx1);
      c[nd] = 0;
      if (idx1) {
          for (; i--;) {
              GET_DATA_INDEX(p1,idx1,dtype,x);
              yield_each_with_index(x,c,a,nd,md);
              c[nd]++;
          }
      } else {
          for (; i--;) {
              GET_DATA_STRIDE(p1,s1,dtype,x);
              yield_each_with_index(x,c,a,nd,md);
              c[nd]++;
          }
      }
  }
  
  /*
    Invokes the given block once for each element of self,
    passing that element and indices along each axis as parameters.
    @overload <%=name%>
    @return [Numo::NArray] self
    For a block {|x,i,j,...| ... }
    @yield [x,i,j,...]  x is an element, i,j,... are multidimensional indices.
  */
  static VALUE
  <%=c_func(0)%>(VALUE self)
  {
      ndfunc_arg_in_t ain[1] = {{Qnil,0}};
      ndfunc_t ndf = {<%=c_iter%>, FULL_LOOP_NIP, 1,0, ain,0};
  
      na_ndloop_with_index(&ndf, 1, self);
      return self;
  }
  