BOOST_PP_ERROR(0x0003, BOOST_PP_REPEAT_OVERFLOW) with multiply nested BOOST_PP_REPEATS
I'm having a problem with multiple nested repeats. I need to generate int x_0_0_0_0 to int x_a_b_c_d. Attempting to do so results in a BOOST_PP_ERROR. For readability, a few shorter defines #define TUPLE_ELEM BOOST_PP_TUPLE_ELEM #define REPEAT BOOST_PP_REPEAT and I also neglect the necessary BOOST_PP_CAT statements in DECL4D in this example #define DECL4D(z, n, text) TUPLE_ELEM(3, text) TUPLE_ELEM(0, text) TUPLE_ELEM(1, text) TUPLE_ELEM(2, text) n; #define DECL4C(z, n, text) REPEAT(TUPLE_ELEM(0, text), DECL4D, (TUPLE_ELEM(1, text), TUPLE_ELEM(2, text), n, TUPLE_ELEM(3, text))) #define DECL4B(z, n, text) REPEAT(TUPLE_ELEM(0, text), DECL4C, (TUPLE_ELEM(1, text), TUPLE_ELEM(2, text), n, TUPLE_ELEM(3, text))) #define DECL4A(z, n, text) REPEAT(TUPLE_ELEM(0, text), DECL4B, (TUPLE_ELEM(1, text), TUPLE_ELEM(2, text), n, TUPLE_ELEM(3, text))) #define decl4(a, b, c, d, text) REPEAT(a, DECL4A, (b, c, d, text)) decl4(1, 1, 1, 1, int x_) Am I hitting a nesting depth limit or something else? Is there a way around this? Ideally I want to write a decl5 macro and have successfully written a decl1, decl2 and decl3 so far Regards, Colin
To partially answer my own question..... in repeat.hpp.... # define BOOST_PP_REPEAT_4(c, m, d) BOOST_PP_ERROR(0x0003) ARGGH :/ Any ideas on how to work around this? I suppose I could try the old modulus/divide trick to turn a for(X){for(Y} loop into a for(x*y) loop, however I'd definitely need to break the 256 repeat limit many times so that's pretty much useless Colin On 26-09-2014 15:44, Colin Fowler wrote:
I'm having a problem with multiple nested repeats. I need to generate int x_0_0_0_0 to int x_a_b_c_d. Attempting to do so results in a BOOST_PP_ERROR. For readability, a few shorter defines
#define TUPLE_ELEM BOOST_PP_TUPLE_ELEM #define REPEAT BOOST_PP_REPEAT
and I also neglect the necessary BOOST_PP_CAT statements in DECL4D in this example
#define DECL4D(z, n, text) TUPLE_ELEM(3, text) TUPLE_ELEM(0, text) TUPLE_ELEM(1, text) TUPLE_ELEM(2, text) n; #define DECL4C(z, n, text) REPEAT(TUPLE_ELEM(0, text), DECL4D, (TUPLE_ELEM(1, text), TUPLE_ELEM(2, text), n, TUPLE_ELEM(3, text))) #define DECL4B(z, n, text) REPEAT(TUPLE_ELEM(0, text), DECL4C, (TUPLE_ELEM(1, text), TUPLE_ELEM(2, text), n, TUPLE_ELEM(3, text))) #define DECL4A(z, n, text) REPEAT(TUPLE_ELEM(0, text), DECL4B, (TUPLE_ELEM(1, text), TUPLE_ELEM(2, text), n, TUPLE_ELEM(3, text))) #define decl4(a, b, c, d, text) REPEAT(a, DECL4A, (b, c, d, text))
decl4(1, 1, 1, 1, int x_)
Am I hitting a nesting depth limit or something else? Is there a way around this? Ideally I want to write a decl5 macro and have successfully written a decl1, decl2 and decl3 so far
Regards, Colin
Am I hitting a nesting depth limit or something else? Is there a way around this? Ideally I want to write a decl5 macro and have successfully written a decl1, decl2 and decl3 so far
Ok, the best way seems to generate a sequence of your data: #define GEN_SEQS_EACH_INNER(z, n, data) (n) #define GEN_SEQS_EACH(s, data, n) BOOST_PP_REPEAT(n, GEN_SEQS_EACH_INNER, ~) #define GEN_SEQS(dims) BOOST_PP_SEQ_TRANSFORM(GEN_SEQS_EACH, ~, dims) This would take a sequence of each of the max values and generates a sequence of sequences. So this: GEN_SEQS((2)(3)) Expands to: ( (0)(1) ) ( (0)(1)(2) ) Then you can use `BOOST_PP_SEQ_FOR_EACH_PRODUCT` to do the cross product of each of the sequences concated together: #define DECL_EACH(r, product) BOOST_PP_SEQ_CAT((int x)product); #define DECL(dims) BOOST_PP_SEQ_FOR_EACH_PRODUCT(DECL_EACH, GEN_SEQS(dims)) However, you may want underscores place between the number so you can use an intersperse macro like this: #define INTERSPERSE_EACH(r, data, i, elem) BOOST_PP_IF(i, (data)(elem), (elem)) #define INTERSPERSE(seq, x) BOOST_PP_SEQ_FOR_EACH_I(INTERSPERSE_EACH, x, seq) #define DECL_EACH(r, product) BOOST_PP_SEQ_CAT(INTERSPERSE((int x)product, _)); #define DECL(dims) BOOST_PP_SEQ_FOR_EACH_PRODUCT(DECL_EACH, GEN_SEQS(dims)) And then you can call it like this: DECL((2)(2)(2)(2)(2)) Which will generate this: int x_0_0_0_0_0; int x_0_0_0_0_1; int x_0_0_0_1_0; int x_0_0_0_1_1; int x_0_0_1_0_0; int x_0_0_1_0_1; int x_0_0_1_1_0; int x_0_0_1_1_1; int x_0_1_0_0_0; int x_0_1_0_0_1; int x_0_1_0_1_0; int x_0_1_0_1_1; int x_0_1_1_0_0; int x_0_1_1_0_1; int x_0_1_1_1_0; int x_0_1_1_1_1; int x_1_0_0_0_0; int x_1_0_0_0_1; int x_1_0_0_1_0; int x_1_0_0_1_1; int x_1_0_1_0_0; int x_1_0_1_0_1; int x_1_0_1_1_0; int x_1_0_1_1_1; int x_1_1_0_0_0; int x_1_1_0_0_1; int x_1_1_0_1_0; int x_1_1_0_1_1; int x_1_1_1_0_0; int x_1_1_1_0_1; int x_1_1_1_1_0; int x_1_1_1_1_1; Paul Fultz II -- View this message in context: http://boost.2283326.n4.nabble.com/BOOST-PP-ERROR-0x0003-BOOST-PP-REPEAT-OVE... Sent from the Boost - Users mailing list archive at Nabble.com.
On 26-09-2014 20:38, pfultz2 wrote:
Am I hitting a nesting depth limit or something else? Is there a way around this? Ideally I want to write a decl5 macro and have successfully written a decl1, decl2 and decl3 so far
Ok, the best way seems to generate a sequence of your data:
<SNIP>
Paul Fultz II
Thanks Paul, that is beautiful. My actual use case involves generating functions (not just int x_....) and using the values in the function name and body like so: void foo_6_5_4_3_2() { //Some function involving x,y,z,w such as bar[4] = foo[3] + 2 * 6 + sqrt(5); } Am I right in saying that I Ssould be able to turn the current sequence into a tuple and access the members for use in the function body? Regards, Colin
participants (2)
-
Colin Fowler
-
pfultz2