Hi,

The sequence data structure is very nice. One of the advantages is that it makes it possible to reduce syntactic clutter considerably compared to lists.

Unfortunately, due to preprocessor limitations, one is limited to parenthesized expressions that do not contain top-level commas. For example, the following is not considered a sequence:

(a,b)(c,d)(e,f)

But the following is a sequence:

((a,b))((c,d))((e,f))

In order to reduce syntactic clutter, it would be nice to have a macro that converts an arbitrary "relation"/"table" or "n-sequence" into a sequence. In other words:

RELATION_TO_SEQ(2,(a,b)(c,d)(e,f)) ==> ((a,b))((c,d))((e,f))
RELATION_TO_SEQ(3,(a,b,c)(d,e,f)) ==> ((a,b,c))((d,e,f))

I think that such a macro would be more than just a small convenience. The above examples do not do justice to the reduction in syntactic clutter. The most promising use for this construct would be as a building block for macros that essentially take relations as arguments. For example, the state machine example I presented previously, would essentially take a relation (actually nested relations) as an argument.

The implementation of RELATION_TO_SEQ() should not be very difficult, but there is a quick incomplete implementation in this post, that can give some ideas. A more generic "token sequence" to sequence conversion macro could also be very useful. Consider the following token sequences:

1 0 2 3
B o o s t SPACE 1 3 1

Neither of the above are sequences, but it would be possible to turn them into sequences using suitable macros (pseudo-code):

TOKEN_SEQ_TO_SEQ(FIRST, REST, IS_LAST, 1 0 2 3)
==> (1)(0)(2)(3)

TOKEN_SEQ_TO_SEQ(FIRST, REST, IS_LAST, B o o s t SPACE 1 3 1)
==> (B)(o)(o)(s)(t)(SPACE)(1)(3)(1)

The macros FIRST, REST and IS_LAST would be used by the TOKEN_SEQ_TO_SEQ conversion macro to extract tokens from the token sequence. The RELATION_TO_SEQ macro could easily be implemented in terms of the TOKEN_SEQ_TO_SEQ macro.

The intention behind these conversion macros is to allow making more-convenient-to-use code generating macros using the preprocessor library. They essentially help to reduce the amount of unnecessary punctuation for the user of such code generating macros.

None of these macros would be strictly necessary, as similar things can be achieved using lists and sequences.

...

BTW, the naming of SEQ_HEAD and SEQ_TAIL is, IMO, unfortunate, as they do not match the precedent made by LIST_FIRST and LIST_REST. IIRC, I polled the group when I designed the initial list support for naming suggestions and FIRST/REST was the preferred choice. Even if HEAD and TAIL would, in some sense, be slightly better, I think that it is more important to try to be consistent. This is not a big issue, but it could, for instance, be useful for designing generic sequence manipulation macros. Actually, perhaps there is a good reason to use the name SEQ_TAIL as a sequence can not be empty.

- Vesa Karvonen

#include "boost/preprocessor/tuple/eat.hpp"
#include "boost/preprocessor/tuple/elem.hpp"
#include "boost/preprocessor/control/while.hpp"
#include "boost/preprocessor/control/if.hpp"
#include "boost/preprocessor/cat.hpp"

#define MAKE_SEQ(n,seq) BOOST_PP_IF(MORE(n,seq),MAKE_SEQ_N,MAKE_SEQ_1)(n,seq)
#define MAKE_SEQ_1(n,seq) (FIRST(n,seq))
#define MAKE_SEQ_N(n,seq) BOOST_PP_TUPLE_ELEM(3,0,BOOST_PP_WHILE(MAKE_SEQ_P,MAKE_SEQ_O,((FIRST(n,seq)),n,REST(n,seq) FIRST(n,seq))))
#define MAKE_SEQ_P(d,rns) MORE(BOOST_PP_TUPLE_ELEM(3,1,rns),BOOST_PP_TUPLE_ELEM(3,2,rns))
#define MAKE_SEQ_O(d,rns)\
(BOOST_PP_TUPLE_ELEM(3,0,rns)(FIRST(BOOST_PP_TUPLE_ELEM(3,1,rns),BOOST_PP_TUPLE_ELEM(3,2,rns)))\
,BOOST_PP_TUPLE_ELEM(3,1,rns)\
,REST(BOOST_PP_TUPLE_ELEM(3,1,rns),BOOST_PP_TUPLE_ELEM(3,2,rns))\
)

#define FIRST(n,seq) BOOST_PP_TUPLE_ELEM(n,0,(BOOST_PP_CAT(FIRST_H,n) seq))
#define FIRST_H2(x,y) (x,y), BOOST_PP_NIL
#define REST(n,seq) BOOST_PP_TUPLE_EAT(n) seq
#define MORE(n,seq) BOOST_PP_TUPLE_ELEM(2,0,(BOOST_PP_CAT(MORE_,BOOST_PP_CAT(MORE_H,n) seq)))
#define MORE_H2(x,y) ONE2
#define ONE2(x,y) TWO
#define MORE_ONE2 0, BOOST_PP_NIL
#define MORE_TWO 1, BOOST_PP_NIL

// test

#define SEQ2 (a,b)(c,d)(e,f)
MAKE_SEQ(2,SEQ2)


_________________________________________________________________
STOP MORE SPAM with the new MSN 8 and get 2 months FREE* http://join.msn.com/?page=features/junkmail

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Reply via email to