一点背景:我有一些奇怪的多个嵌套循环,我将其转换为平面工作队列(基本上将单个索引循环折叠为单个多索引循环)。现在每个循环都是手工编码的。 我正在尝试使用lambda表达式来处理任何边界的通用方法:
例如:
// 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)
公寓的内部结构如下:
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();
}
}
//...,
}
我的问题是,你能给我一些想法如何编写lambda(派生自boost),它可以绑定到索引数组引用,根据lambda表达式返回上限,下限?
非常感谢
bummers,lambda只支持三个占位符。
答案 0 :(得分:0)
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 }
示例(可能已损坏,需要更多功能)
using namespace generator;
For(range(_2, _3), range(std::max(_3, _4), N), range(N), range(N));