自定义 C++ boost::lambda 表达式帮助

发布于 2024-09-01 02:22:58 字数 1428 浏览 4 评论 0原文

一点背景知识:我有一些奇怪的多个嵌套循环,我将其转换为平面工作队列(基本上将单个索引循环折叠为单个多索引循环)。现在每个循环都是手工编码的。 我正在尝试使用 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)

flat 的内部结构类似于:

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 表达式返回上限、下限?

非常感谢

各位,lambda 仅支持三个占位符。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

自我难过 2024-09-08 02:22:58

好吧,这是迄今为止的原型

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));

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));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文