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 to share