0

I want to implement the for each idiom for traversing all pixels/voxels of a 2d/3d matrix. Depending on the dimension, we have 2 loops or 3 loops. The code seems like that:

//template class for point
template<int Dim>
struct Point{
    int _data[Dim];
    int & operator ()( int index){return _data[index];}
}

//template class for multi dimensional array
template<int Dim>
struct MatN{
    enum{DIM=Dim};
    Point<Dim> _domain; 
    std::vector<double> _data;
    double & operator ()( Point<Dim> p){//in the real implementation template specialization
       if(Dim==2)return _data[p(0)+p(1)*_domain(0)];
       else if(Dim==3)return _data[p(0)+p(1)*_domain(0)+p(2)*_domain(0)*_domain(1)];
    }
    int sizeI(){return _domain(0);}
    int sizeJ(){return _domain(1);}
    int sizeK(){return _domain(2);}
};

#define ForEach(point,mat) ForEach##mat.DIM (point,mat) //compile error

#define ForEach2(point,mat) 
Point<2> point;\
for(point(0)=0;point(0)<mat.sizeI();point(0)++)\
for(point(1)=0;point(1)<mat.sizeJ();point(1)++)

#define ForEach3(point,mat) \
Point<3> point;\
for(point(0)=0;point(0)<mat.sizeI();point(0)++)\
for(point(1)=0;point(1)<mat.sizeJ();point(1)++)\
for(point(2)=0;point(2)<mat.sizeK();point(2)++)

int main(){    
    MatN<2> m2d;
    ForEach(p2,m2d){           
        //do something (in this process, I need the pixel position for a local process so I cannot use iterator)
       //for instance
       if(p2(0)*p2(1)>100)
          m2d(p2)=1;
       else
          m2d(p2)=0;   
    }
    MatN<3> m3d;
    ForEach(p3,m3d){
        //do something
    }
}

The problem is how to evaluate the template argument in macro.

Note : I do not want to use boost for dependency reasons.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Vincent
  • 63
  • 6
  • 3
    Stop using macro in this way. They don't simplify things, instead they make things even more complex. – Nawaz Nov 22 '13 at 13:02
  • Oke, I know that I can use Iterator. But in this case, I want to keep the pixel position as a point in the loop. – Vincent Nov 22 '13 at 13:08
  • Why can't you just have two functions, overloaded for the two template types - any reasonable compiler will inline them anyway, if the use of macros is a performance thing. – Will Dean Nov 22 '13 at 13:10
  • Because the foreach idiom is very usefull http://qt.developpez.com/doc/4.7/containers/#the-foreach-keyword http://www.boost.org/doc/libs/1_35_0/doc/html/foreach.html – Vincent Nov 22 '13 at 14:20
  • 2
    @Vincent C++ supports foreach using `for (auto&& x : xs)` syntax. No need for silly macros. –  Nov 27 '13 at 10:23
  • Macros only know about text. They manipulate text. Replace a string with another string. That's it. – n. m. could be an AI Nov 27 '13 at 10:41

0 Answers0