BOOT_PP_REPEAT simple nesting problem
Hi all, I'm trying to use BOOST_PP to generate some code.
I can generate the sequence int x_0 to int x_4 using the code below.
#include
On Sat, Sep 20, 2014 at 6:35 AM, Colin Fowler
I've tried nesting BOOST_PP_REPEAT but so far I've been unable to produce the desired behaviour unless I hardcode one of the iteration counts.
To "recurse" you need to use use the BOOST_PP_REPEAT_ <z> form. -- -Matt Calabrese
On 21-09-2014 05:46, Matt Calabrese wrote:
On Sat, Sep 20, 2014 at 6:35 AM, Colin Fowler
wrote: I've tried nesting BOOST_PP_REPEAT but so far I've been unable to produce the desired behaviour unless I hardcode one of the iteration counts.
To "recurse" you need to use use the BOOST_PP_REPEAT_ <z> form.
Hi Matt, thanks for the reply. I've tried working may different incantations of BOOST_PP_REPEAT_ ## z etc for the past few hours and I'm getting nowhere fast. Working with the preprocessor is so vastly different from interacting with the standard c++ environment that I'm having difficulty grasping the basic concepts and there doesn't seem to be much in the way of very simple examples anywhere. This is especially annoying as preprocessor code is difficult to read and the error messages make little sense. I generally loathe handholding, but in this case I'm not above asking for a dig out. Any chance you could point out the obvious to me? Regards, Colin
-- -Matt Calabrese _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
On 9/20/2014 9:35 AM, Colin Fowler wrote:
Hi all, I'm trying to use BOOST_PP to generate some code.
I can generate the sequence int x_0 to int x_4 using the code below.
#include
#define DECL1(z, n, text) text ## _ ## n = n; #define decl1(text, count) BOOST_PP_REPEAT(count, DECL1, text) decl1 (int x, 5) What I'd like to do is write a decl2 that can be used something like this:
decl2 (int x, 5, 2)
to generate int x_0_0 to int x_4_1
I've tried nesting BOOST_PP_REPEAT but so far I've been unable to produce the desired behaviour unless I hardcode one of the iteration counts.
I'd like to also eventually write a decl3(int x, 5, 3, 4) when I understand how a decl2 would work. Any help much appreciated!
The BOOST_PP_REPEAT macro takes a single count, so you would need to pass into the macro a single repetition count while preserving the individual counts in some way for BOOST_PP_REPEAT. The only way you could do this is by having the 'data' field of BOOST_PP_REPEAT be more complicated, ie. by having the 'data' field include both your 'text' and the individual count numbers. When you need a single input to include complicated data you should look at how to work with Boost PP arrays, lists, tuples, and/or seqs; all of which let you incorporate a number of pieces of data in a single input. So given: decl2 ( int x, 5, 2 ) and using a Boost PP tuple, you want to pass to initially pass to BOOST_PP_REPEAT something like (10, DECL2, (text,(5,2))) and then you can work out how to generate your output for each of the 10 repetitions of DECL2. You can recursively call BOOST_PP_REPEAT from within BOOST_PP_REPEAT processing, and while it is advantageous to use the BOOST_PP_REPEAT_z form it is not necessary. I hope this helps you to figure out how to do what you want.
On 21-09-2014 17:51, Edward Diener wrote: <SNIP>
The BOOST_PP_REPEAT macro takes a single count, so you would need to pass into the macro a single repetition count while preserving the individual counts in some way for BOOST_PP_REPEAT. The only way you could do this is by having the 'data' field of BOOST_PP_REPEAT be more complicated, ie. by having the 'data' field include both your 'text' and the individual count numbers. When you need a single input to include complicated data you should look at how to work with Boost PP arrays, lists, tuples, and/or seqs; all of which let you incorporate a number of pieces of data in a single input.
So given:
decl2 ( int x, 5, 2 )
and using a Boost PP tuple,
you want to pass to initially pass to BOOST_PP_REPEAT something like (10, DECL2, (text,(5,2))) and then you can work out how to generate your output for each of the 10 repetitions of DECL2.
You can recursively call BOOST_PP_REPEAT from within BOOST_PP_REPEAT processing, and while it is advantageous to use the BOOST_PP_REPEAT_z form it is not necessary.
I hope this helps you to figure out how to do what you want.
Hi Edward, that was very helpful, thank you! I had tried using tuples
yesterday but couldn't get the syntax right. I've come up with the
following that's very close to doing exactly what I want (I need to
fiddle around the ordering of the output a bit).
#include
On 9/21/2014 2:21 PM, Colin Fowler wrote:
On 21-09-2014 17:51, Edward Diener wrote: <SNIP>
The BOOST_PP_REPEAT macro takes a single count, so you would need to pass into the macro a single repetition count while preserving the individual counts in some way for BOOST_PP_REPEAT. The only way you could do this is by having the 'data' field of BOOST_PP_REPEAT be more complicated, ie. by having the 'data' field include both your 'text' and the individual count numbers. When you need a single input to include complicated data you should look at how to work with Boost PP arrays, lists, tuples, and/or seqs; all of which let you incorporate a number of pieces of data in a single input.
So given:
decl2 ( int x, 5, 2 )
and using a Boost PP tuple,
you want to pass to initially pass to BOOST_PP_REPEAT something like (10, DECL2, (text,(5,2))) and then you can work out how to generate your output for each of the 10 repetitions of DECL2.
You can recursively call BOOST_PP_REPEAT from within BOOST_PP_REPEAT processing, and while it is advantageous to use the BOOST_PP_REPEAT_z form it is not necessary.
I hope this helps you to figure out how to do what you want.
Hi Edward, that was very helpful, thank you! I had tried using tuples yesterday but couldn't get the syntax right. I've come up with the following that's very close to doing exactly what I want (I need to fiddle around the ordering of the output a bit).
#include
#define DECL2B(z,n,text) BOOST_PP_CAT(BOOST_PP_CAT(BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 1, text), n), _), BOOST_PP_TUPLE_ELEM(2, 0, text)); #define DECL2A(z,n,text) BOOST_PP_REPEAT(BOOST_PP_TUPLE_ELEM(2, 0, text), DECL2B, (n,BOOST_PP_TUPLE_ELEM(2,1,text))) #define decl2( text, x, y ) BOOST_PP_REPEAT(y, DECL2A, (x,text)) decl2(int x_, 3, 2) I have to use BOOST_PP_CAT as for some reason ## still gives surrounding spaces after a BOOST_PP_TUPLE_ELEM. Can this be made more readable or am I doing things the correct way?
Here's the current output btw: int x_0_0; int x_1_0; int x_2_0; int x_0_1; int x_1_1; int x_2_1;
You have got the idea. The reason that BOOST_PP_CAT is needed instead of direct use of '##' is that '##" immediately attempts to concatenate, before any expansion of its left and right elements, while BOOST_PP_CAT concatenates only after full argument expansion.
You should try replacing the ## with BOOST_PP_CAT. The Preprocessor doc indicates that using ## directly can cause the preprocessor to terminate expansion.
---
Steve H.
-----Original Message-----
From: Colin Fowler [mailto:fowler@colinfowler.ie]
Sent: Saturday, September 20, 2014 6:36 AM
To: Boost-users@lists.boost.org
Subject: [Boost-users] BOOT_PP_REPEAT simple nesting problem
Hi all, I'm trying to use BOOST_PP to generate some code.
I can generate the sequence int x_0 to int x_4 using the code below.
#include
participants (4)
-
Colin Fowler
-
Edward Diener
-
Hickman, Steve (AdvTech)
-
Matt Calabrese