ASPN ActiveState Programmer Network
ActiveState
/ Home / Perl / PHP / Python / Tcl / XSLT /
/ Safari / My ASPN /
Cookbooks | Documentation | Mailing Lists | Modules | News Feeds | Products | User Groups


Recent Messages
List Archives
About the List
List Leaders
Subscription Options

View Subscriptions
Help

View by Topic
ActiveState
.NET Framework
Open Source
Perl
PHP
Python
Tcl
Web Services
XML & XSLT

View by Category
Database
General
SOAP
System Administration
Tools
User Interfaces
Web Programming
XML Programming


MyASPN >> Mail Archive >> boost
boost
Re: [boost] Re: ATTN: All Developers Interested in Boost.Preprocessor
by Rene Rivera other posts by this author
May 1 2003 3:25AM messages near this date
Re: [boost] Re: ATTN: All Developers Interested in Boost.Preprocessor | Re: [boost] Re: ATTN: All Developers Interested in Boost.Preprocessor
[2003-04-30] Paul Mensonides wrote:

> Rene Rivera wrote:
> > [2003-04-30] Paul Mensonides wrote:
> >
> >> It is not something that can't be worked around, but it is a
> >> nuisance. Basically, you have to expand a macro to produce a
> >> comma--but do it only at the last possible step so it doesn't go
> >> through any other macros.  The problem is not that so much.  Rather,
> >> it implies that you have to pass everything else as such an
> >> "invocable" entity--which is annoying at best.
> >
> > If that's the case would not a more general utility to insert/escape
> > literals be desirable.

I think I lost you on some of your explanation so bear with me...

> The only problem tokens are , ( ) # and ## (as well as %: and %:%:). 
Everything
> else is fine.  The problems with those tokens arise only from the fact they
have
> special meaning to the syntactic/semantic model of the preprocessor.  As I
said,
> we can work around this problem, but the workaround is not local--i.e. it
makes
> it necessary to apply the workaround globally an any situation where you
might
> want to pass one of those tokens.

I don't see what difference the problem tokens are. If the preprocessor
knows to not parse a specific token sequence you tell it how can it be a
problem?

> Say, for example, that you have a repetition construct that takes a
"delineator"
> argument.  I.e. a token (or tokens) to delineate the repetitions:
> 
> R(0) , R(1) , R(2)
>      ^      ^

OK.

> Because this delineator might be a comma, you have to "abstract" it into an
> invocable macro:
> 
> #define COMMA() ,

Or define it as:

    #define COMMA #escape ","

> And then pass it through other macros without invoking it:
> 
> MACRO( COMMA )

No need if defined as above.

> Ultimately, however, the macro must be expanded or you'll get this:
> 
> R(0) COMMA R(1) COMMA R(2)

Or in the #escape construct:

R(0) #escape "," R(1) #escape "," R(2)

> So, you make the requirement that the delineator must be invocable:
> 
> R(0) COMMA() R(1) COMMA() R(2)

And #escape is ultimately invocable only after the macro expansion recursion
finishes.

> Which expands to:
> 
> R(0) , R(1) , R(2)

Same.

> Everything is not too bad so far, but generalization makes it annoying. 
What if
> you want to use + as a separator?  You can't do this:
> 
> MACRO( + )

You could do:

    MACRO( #escape "+" )

> Because you'd get this:
> 
> R(0) +() R(1) +() R(2)

And would get the desired:

    R(0) + R(1) + R(2)

> So, you have to either 1) make a PLUS() macro or 2) use some type of
invocable
> identity macro:
> 
> #define COMMA() ,
> 
> #define EMPTY()
> #define IDENTITY(x) x EMPTY
> 
> MACRO( COMMA       ) // R(0) , R(1) , R(2)
> MACRO( EMPTY       ) // R(0)   R(1)   R(2)
> MACRO( IDENTITY(+) ) // R(0) + R(1) + R(2)
> MACRO( IDENTITY(;) ) // R(0) ; R(1) ; R(2)

    MACRO( #escape "," ) // R(0) , R(1) , R(2)
    MACRO( #escape " " ) // R(0)   R(1)   R(2)
    MACRO( #escape "+" ) // R(0) + R(1) + R(2)
    MACRO( #escape ";" ) // R(0) ; R(1) ; R(2)

> Etc.
> 
> In other words, the "fix" takes over everything that isn't the problem to
begin
> with.  I.e. it is intrusive.  There are other options, of course, but all
of
> them have some type of intrusive drawback--for instance what if you wanted
"(("
> as a delineator...
> 
> Late-bound expansion for __comma__, __lparen__, and __rparen__ would
*partially*
> solve the problem.  However, it would not fix the problem completely.  For
> instance, if the above result was used as arguments to an other macro:
> 
> #define OTHER(x) OTHER_I x
Did you mean #define OTHER(x) OTHER_I(x) ???
> #define OTHER_I(a, b, c) a b c
> 
> OTHER( MACRO(__comma__) ) // error
> 
> The same caveat applies to parentheses.  They permanently become
"non-operators"
> to the preprocessor which can be a major limitation.

Ahh (after a few minutes of contemplation ;-)... I see that problem.
Basically there is no general point of macro replacement that will solve it
in all cases. Currently it's "replace asap", and with the __comma__ &
#escape it's "replace last".

OK, so here's another idea. Let the macro writer/user specify where the
replacement point is. With lets say an #eval command. The problem example
above could then be implemented as:

#define OTHER(x) OTHER_I( #eval x )

Or for the user...

OTHER( #eval MACRO(#escape ",") )


-- grafik - Don't Assume Anything
-- rrivera@[...].org - grafik@[...].com
-- 102708583@icq
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Thread:
Vesa Karvonen
Paul Mensonides
David Abrahams
Rene Rivera
Paul Mensonides
Rene Rivera
Paul Mensonides
Rene Rivera
Paul Mensonides
Rene Rivera
Paul Mensonides
David Abrahams
Beman Dawes
Hartmut Kaiser
David Abrahams
Beman Dawes
David Abrahams

Privacy Policy | Email Opt-out | Feedback | Syndication
© ActiveState Software Inc. All rights reserved