tags:

views:

161

answers:

1

hello.

A little bit of background: I have some strange multiple nested loops which I converted to flat work queue (basically collapse single index loops to single multi-index loop). right now each loop is hand coded. I am trying to generalized approach to work with any bounds using lambda expressions:

For example:

// RANGE(i,I,N) is basically a macro to generate  `int i = I; i < N; ++i `
// for (RANGE(lb, N)) {
//      for (RANGE(jb, N)) {
//          for (RANGE(kb, max(lb, jb), N)) {
//              for (RANGE(ib, jb, kb+1)) {

// is equivalent to something like (overload , to produce range)
flat<1, 3, 2, 4>((_2, _3+1), (max(_4,_3), N), N, N)

the internals of flat are something like:

template<size_t  I1, size_t I2, ...,
         class L1_, class L2, ..._>
 boost::array<int,4> flat(L1_ L1, L2_ L2, ...){
     //boost::array<int,4> current; class or static variable

     // basically, the code below this is going to be done using recursion templates
     // but to do that I need to apply lambda expression to current array
     // to get runtime bounds

     bool advance;
     L2_ l2 = L2.bind(current); // bind current value to lambda
     {
          L1_ l1 = L1.bind(current); //bind current value to innermost lambda
          l1.next();
          advance = !(l1 < l1.upper()); // some internal logic
          if (advance) {
              l2.next();
              current[0] = l1.lower();
          }
     }
     //...,
}

my question is, can you give me some ideas how to write lambda (derived from boost) which can be bound to index array reference to return upper, lower bounds according to lambda expression?

thank you much

bummers, lambda only supports three placeholders.

A: 

well, this is the prototype so far

119 #include <boost/lambda/lambda.hpp>
120
121 namespace generator {
122
123     // there is no _1 because it's innermost
124     // and lambda only has three placeholders
125     boost::lambda::placeholder1_type _2;
126     boost::lambda::placeholder2_type _3;
127     boost::lambda::placeholder3_type _4;
128
129     template<class L, class U>
130     struct range_ {
131         typedef boost::array<int,4> index_type;
132         range_(L lower, U upper) : lower_(lower), upper_(upper) {}
133         size_t lower(const index_type &index) {
134             return lower_(index[1], index[2], index[3]);
135         }
136         size_t upper(const index_type &index) {
137             return upper_(index[1], index[2], index[3]);
138         }
139         L lower_; U upper_;
140     };
141
142     template<class L, class U>
143     range_<L,U> range(L lower, U upper) {
144         return range_<L,U>(lower, upper);
145     }
146
147     template<class R1, class R2, class R3, class R4>
148     struct for_{
149         typedef boost::array<int,4> index_type;
150         index_type index;
151         R1 r1_; R2 r2_; R3 r3_; R4 r4_;
152         for_(R1 r1, R2 r2, R3 r3, R4 r4)
153             : r1_(r1), r2_(r2), r3_(r3), r4_(r4) {}
154         index_type next() {
155             index_type next = index;
156
157             bool advance = false;
158             index[0] += 1;
159
160             advance = !(index[0] < r1_.upper(index));
161             if (advance) {
162                 index[1] += 1;
163                 index[0] = r1_.lower(index);
164             }
165
166             advance = advance && !(index[1] < r2_.upper(index));
167             if (advance) {
168                 index[2] += 1;
169                 index[1] = r2_.lower(index);
170                 index[0] = r1_.lower(index);
171             }
172
173             advance = advance && !(index[2] < r3_.upper(index));
174             if (advance) {
175                 index[3] += 1;
176                 index[2] = r3_.lower(index);
177                 index[1] = r2_.lower(index);
178                 index[0] = r1_.lower(index);
179             }
180
181             //std::cout << next << std::endl;
182             return next;
183
184         }
185     };
186
187     template<class R1, class R2, class R3, class R4>
188     for_<R1, R2, R3, R4> For(R1 r1, R2 r2, R3 r3, R4 r4) {
189         return for_<R1, R2, R3, R4>(r1, r2, r3, r4);
190     }
191
192 }

example (probably broken, needs few more functions)

using namespace generator;
For(range(_2, _3), range(std::max(_3, _4), N), range(N), range(N));
aaa