title: specialise for loop with visitor pattern?
body: <p>Let's say that I have a struct named like this one:</p>
  
  <pre><code>struct OneBodyMatrixElements {
    static const bool is_selfadjoint = 1;
    static const bool property2 = 0; 
    // ........
  
    static value_type val( const std::size_t i, const std::size_t j ) {
      value_type ret = 0.;
      if( i == j )  ret = 1.;
      if( i == j + 1 || i == j - 1 ) ret = -1.;
      if( i == 0 &amp;&amp; j == 6 ) ret = -1.;
      if( i == 6 &amp;&amp; j == 0 ) ret = -1.;
      return static_cast&lt;value_type&gt;(ret);
    }
  };
  </code></pre>
  
  <p>The static variable define different properties of this class and the static function val return the value depending on (i,j). This actually represents a matrix of size 7 whose scalar type is value_type (either float, double, std::complex). </p>
  
  <p>In another part of my code, I need to loop over (i,j) for i,j=0,...,N (here for example N=7):</p>
  
  <pre><code>for( std::size_t i = 0; i &lt; N; i++ ) {
    for( std::size_t j = 0; j &lt; N; j++ ) {
      if( "OneBodyMatrixElements::val( i, j ) is non zero" ) {
        //...
        OneBodyMatrixElements::val( i, j ) * func( i, j );
        //...
      }
  }
  </code></pre>
  
  <p>I have an if close to check if the OneBodyMatrixElements is zero because the multiplication just below is expensive and does not need to be computed if the prefactor is zero.</p>
  
  <p>My question is the following: Since I know the properties of OneBodyMatrixElements, i.e. selfadjoint or diagonal, I also know the location of zero elements, how can I optimise the two for loops to iterate only over non zero elements and also take into account the selfadjoint property?</p>
  
  <p>The obvious answer to this question would be to use Eigen SparseMatrix but I is not what I want because</p>
  
  <ul>
  <li>I do not want to actually store the matrix</li>
  <li>I actually have another struct with four indices (i,j,k,l) and loop over these four indices. I therefore need something generic that also work for four indices. In Eigen, there is no support for SparseTensors. </li>
  </ul>
  
  <p>I did have a look to the visitor pattern but I'm not sure that this is what is need. Any comments on the code is also welcome and a solution which actually store the values in the memory in a sparse form is acceptable. A solution involving only iterations over non-zero elements is also acceptable. Thank you.</p>
  
  <p><strong>EDIT: Answer:</strong></p>
  
  <p>Thank you very much for your answers. I did implement a custom iterator as explained below. For the sake of completeness, here is my version:</p>
  
  <pre><code>class tridiag_iterator {
    std::size_t i, j;
  public:
    struct value_type {
      std::size_t i, j;
    };
  
    tridiag_iterator( std::size_t i_, std::size_t j_ ) : i( i_ ), j( j_ ) { }
  
    value_type operator*() const {
      return { i, j };
    }
  
    bool operator!=( const tridiag_iterator &amp;other ) {
      if( i &gt;= other.i &amp;&amp; j &gt; other.j ) return 0;
      else return 1;
    }
  
    tridiag_iterator &amp;operator++() {
      if( j == i ) j = i + 1;
      else if( j == i - 1 ) j = i;
      else if( j == i + 1 ) {
        i = i + 1;
        j = i - 1;
      }
    }
  };
  </code></pre>
  
  <p>and I added two members to OneBodyMatrixElements:</p>
  
  <pre><code>  static tridiag_iterator begin() {
      return tridiag_iterator( 0, 0 );
    }
  
    static tridiag_iterator end() {
      return tridiag_iterator( N - 1, N - 1 );
    }
  </code></pre>
  
  <p>with N defined elsewhere. Usage:</p>
  
  <pre><code>  for( auto it = OneBodyMatrixElements::begin(), end = OneBodyMatrixElements::end(); it != end; ++it ) {
      OneBodyMatrixElements::val( (*it).i, (*it).j ) * func( (*it).i, (*it).j );
    }
  </code></pre>
  
  <p>Any comments are still welcome.</p>