Custom C ++ boost :: lambda expression help

A bit of background: I have some weird multiple nested loops that I converted to a flat work queue (basically folding single indices into a single multi-index loop). right now, every loop is manually coded. I'm trying to generalize the approach to dealing with any constraints using lambda expressions:

For instance:

// 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 interior of the apartment is 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 on how to write lambda (derived from boost) that can be bound to an array index to return upper and lower bounds according to the lambda expression?

Many thanks

bummers, lambda only supports three placeholders.

+2


a source to share


1 answer


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 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 (possibly broken, multiple features required)

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

      

0


a source







All Articles