220 8724 <17ff52ed-e7fd-49d0-931a-524945cf5212@isocpp.org> article
Path: news.gmane.org!not-for-mail
From: Andrew Tomazos <andrewtomazos@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: "Raw" preprocessor macro arguments
Date: Sun, 19 Jan 2014 18:49:25 -0800 (PST)
Lines: 419
Approved: news@gmane.org
Message-ID: <17ff52ed-e7fd-49d0-931a-524945cf5212@isocpp.org>
References: <c0398870-b265-4d02-a814-ad84a472520c@isocpp.org>
 <47db64d6-64fb-4243-bded-e36fc8be30b2@isocpp.org>
 <0948fc8a-2191-4ab0-97df-cf354a470828@isocpp.org>
 <f5e84374-d3a7-4046-a674-33259e520ee5@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: plane.gmane.org
Mime-Version: 1.0
Content-Type: multipart/alternative; 
	boundary="----=_Part_1863_8535418.1390186165826"
X-Trace: ger.gmane.org 1390186162 493 80.91.229.3 (20 Jan 2014 02:49:22 GMT)
X-Complaints-To: usenet@ger.gmane.org
NNTP-Posting-Date: Mon, 20 Jan 2014 02:49:22 +0000 (UTC)
Cc: jgottman6@gmail.com
To: std-proposals@isocpp.org
Original-X-From: std-proposals+bncBD5KHQXXWYPRBNU56KLAKGQE5CN5N4I@isocpp.org Mon Jan 20 03:49:28 2014
Return-path: <std-proposals+bncBD5KHQXXWYPRBNU56KLAKGQE5CN5N4I@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-qa0-f72.google.com ([209.85.216.72])
	by plane.gmane.org with esmtp (Exim 4.69)
	(envelope-from <std-proposals+bncBD5KHQXXWYPRBNU56KLAKGQE5CN5N4I@isocpp.org>)
	id 1W54vX-0005pZ-VW
	for gclcip-std-proposals@m.gmane.org; Mon, 20 Jan 2014 03:49:28 +0100
Original-Received: by mail-qa0-f72.google.com with SMTP id f11sf10453609qae.3
        for <gclcip-std-proposals@m.gmane.org>; Sun, 19 Jan 2014 18:49:27 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20120113;
        h=date:from:to:cc:message-id:in-reply-to:references:subject
         :mime-version:x-original-sender:reply-to:precedence:mailing-list
         :list-id:list-post:list-help:list-archive:list-subscribe
         :list-unsubscribe:content-type;
        bh=ZaGi343gfuNxUZUwnNKTF5yPCqAuhoGxbJPoEDfyOm4=;
        b=M/Vb7PXhm8UQ69C83lE+br2FqjEttT0KadFvwTIWekt3aO2pWzbm23RsfCS6yI2H67
         ZsMC/V90E8x9Y34gEPBVs3n8TXs0pk0rSBhfVpgfESrwpYMrEyi3sxnV082zLvbscNSn
         xYp6Nbvh3p4P4B+GMkdmO2DHJN1XX05yh1LpHKxsfnppdzi+9xYY6byTJJvlMY5rdhBR
         AG48JcBPWc2CGLEdLwAbwvj0f//9V6jINujfv+OsETxIk9/JXLCjQIv/by5bsLmG21nS
         BRwmzfG7JXKNMky7qkgdQELRjkHe1P+MeoV7K2+1BDGkec9pahtPihrN9ZL6cI0aIw/a
         khtg==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20130820;
        h=x-gm-message-state:date:from:to:cc:message-id:in-reply-to
         :references:subject:mime-version:x-original-sender:reply-to
         :precedence:mailing-list:list-id:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe:content-type;
        bh=ZaGi343gfuNxUZUwnNKTF5yPCqAuhoGxbJPoEDfyOm4=;
        b=YncHkAwmzdy6/3LGMbwkMWjpFYfMLa5PToAwqpC76fmq4u2Dhr48YzyMMpMoehwyV9
         AZIeJoHSUyBFh5837gGa24JwYpsZeIXu37A2KyKFOnLktVgSEfwxKfwQT9G6IJmpKe0+
         JoQIzB18LqOzibGOeiw7rHgx9jxlf3iuC6CUZMPq6dIGEyKMmOBW7RKno1rCLVBa5T/t
         z1uMPauZ6b8kquehP5H8CkBl5nW3413AdcrFcSfaqgeUdVZd2cC15by/EFjltIm54ANK
         JzvVGGyrzuAZFEvQQn4YLk0tvPA0qkT3BzBKDZAm2vkc8nhdTG69QvCzjgAWQYRnwOl+
         zUEA==
X-Gm-Message-State: ALoCoQncPLtbrHdZJ/nLs7/IO8fS3VQqBr65x2G36e4R+mfWN8+JzVjXa9dxa4P704B2Q2b5u+Pj
X-Received: by 10.58.46.204 with SMTP id x12mr5838303vem.19.1390186166931;
        Sun, 19 Jan 2014 18:49:26 -0800 (PST)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.49.94.51 with SMTP id cz19ls476947qeb.57.gmail; Sun, 19 Jan
 2014 18:49:26 -0800 (PST)
X-Received: by 10.140.26.243 with SMTP id 106mr143qgv.31.1390186166227;
        Sun, 19 Jan 2014 18:49:26 -0800 (PST)
In-Reply-To: <f5e84374-d3a7-4046-a674-33259e520ee5@isocpp.org>
X-Original-Sender: andrewtomazos@gmail.com
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <std-proposals.isocpp.org>
X-Google-Group-Id: 399137483710
List-Post: <http://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <http://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <http://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:std-proposals+subscribe@isocpp.org>
List-Unsubscribe: <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:8724
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/8724>

------=_Part_1863_8535418.1390186165826
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

No it won't, __VA_ARGS__ leaves the commas in.
  -Andrew.

On Monday, January 20, 2014 2:06:18 AM UTC+1, jgot...@gmail.com wrote:
>
> I think this is still slightly wrong.  Won't it eat the comma, so that=20
> RAW(std::pair<int, int>)
> becomes
> std::pair<int int> //no comma!
>
> Joe Gottman
>
> On Sunday, January 19, 2014 5:15:46 PM UTC-5, Andrew Tomazos wrote:
>>
>> Actually sorry, I am slightly wrong about that solution.  The argument t=
o=20
>> RAW will be parsed in turn as two arguments and not one.  It should be:
>>
>>     #define RAW(...) __VA_ARGS__
>>
>> This will work I think.
>>
>> On Sunday, January 19, 2014 10:11:35 PM UTC+1, Andrew Tomazos wrote:
>>>
>>> #define RAW(x) x
>>>
>>> GENERATE_FUNC(RAW(std::pair<int, int>), getPair1), return std::make_pai=
r
>>> (1, 1));
>>>
>>> The arguments to a macro are identified before macro expansion takes=20
>>> place on the arguments.  So the above will nest out the comma like you =
want.
>>>
>>> The preprocessor respects parenthesis for nesting arguments.
>>>
>>> From 16.2:
>>>
>>> The sequence of preprocessing tokens bounded by the outside-most=20
>>> matching parentheses forms the list of
>>> arguments for the function-like macro. The individual arguments within=
=20
>>> the list are separated by comma
>>> preprocessing tokens, *but comma preprocessing tokens between matching=
=20
>>> inner parentheses do not separate*
>>> *arguments*.
>>>
>>> *After the arguments for the invocation of a function-like macro have=
=20
>>> been identi=EF=AC=81ed, argument substitution*
>>> *takes place.* A parameter in the replacement list, unless preceded by=
=20
>>> a # or ## preprocessing token or
>>> followed by a ## preprocessing token (see below), is replaced by the=20
>>> corresponding argument after all macros
>>> contained therein have been expanded. Before being substituted, each=20
>>> argument=E2=80=99s preprocessing tokens are
>>> completely macro replaced as if they formed the rest of the=20
>>> preprocessing =EF=AC=81le; no other preprocessing tokens
>>> are available.
>>>
>>> On Sunday, January 19, 2014 6:28:43 PM UTC+1, Vittorio Romeo wrote:
>>>>
>>>> *Preprocessor macros*, even if potentially *unsafe*, still have place=
=20
>>>> in a lot of C/C++ programs. Using macros is the sometimes only way to =
avoid=20
>>>> verbose code repetition, to simulate static reflection or to generate =
code=20
>>>> that would be impossible to generate only using templates.
>>>> An issue with macros is that passing arguments is sometimes really=20
>>>> counter-intuitive and dangerous.=20
>>>>
>>>> Example:
>>>> #define GENERATE_FUNC(mType, mName, mBody) mType mName(){ mBody }
>>>>
>>>>
>>>> // Ok, generates valid code
>>>> GENERATE_FUNC(void, printHi, printf("hi");)
>>>>
>>>>
>>>> // Ok, generates valid code
>>>> GENERATE_FUNC(void, printNumber, printf("%d", 5);)
>>>>
>>>>
>>>> // The comma in "<int, int>" is read as an additional argument - macro=
=20
>>>> expansion fails
>>>> GENERATE_FUNC(std::pair<int, int>, getPair1, return std::make_pair(1, =
1
>>>> );)
>>>>
>>>>
>>>> // The comma in "<int, int>" is read correctly, but the generated code=
=20
>>>> is invalid, as=20
>>>> // the round parenthesis persist in the return type (look below for th=
e=20
>>>> expansion)
>>>> GENERATE_FUNC((std::pair<int, int>), getPair2, return std::make_pair(1=
,=20
>>>> 1);)
>>>> /*
>>>>     (std::pair<int, int>) getPair2() { return std::make_pair(1, 1); }
>>>> */
>>>>
>>>> There are possible solutions to this issue:
>>>> 1. Create a typedef for `std::pair<int, int>` - this solution is=20
>>>> specific to this case, and may not always be applicable. Additionally,=
 it=20
>>>> requires the coder to define a new typedef,
>>>> 2. Create multiple macros (for example, GENERATE_FUNC_START and=20
>>>> GENERATE_FUNC_END), and let the user write the code in-between - this=
=20
>>>> solution is ugly and error prone. Also, it scales poorly, as k "body"=
=20
>>>> arguments would require k+1 macro definitions.
>>>>
>>>> These solutions, however, can be defined *hacks. *The issue is that=20
>>>> there is no way to pass a "raw" argument to the preprocessor.=20
>>>>
>>>> Here's what I propose:
>>>> *Similarly to C++11 raw strings, have a new syntax that allows the use=
r=20
>>>> to pass "raw arguments" to preprocessor macros.*
>>>>
>>>> Example:
>>>> GENERATE_FUNC(__R(std::pair<int, int>), __R(getPairRaw), __R(return st=
d
>>>> ::make_pair(1, 1))
>>>>
>>>> Specification:
>>>> < __R > <prefix> <(> <...> <)> <suffix>=20
>>>>
>>>> Prefix/suffix example:
>>>> GENERATE_FUNC(__R***(ReturnType(int*))***, __R(getIntPtr), __R(return =
&
>>>> someInt;))
>>>>
>>>> Unit test before example:
>>>> UNIT_TEST_START()
>>>>      EXPECT(some predicate);
>>>>      ...=20
>>>> UNIT_TEST_END()
>>>>
>>>> Unit test after example:
>>>> UNIT_TEST(__R(
>>>>      EXPECT(some predicate);
>>>>      ...=20
>>>> ))
>>>>
>>>> This "raw syntax" would also fix the "comma problem", that forced user=
s=20
>>>> to define a "COMMA" macro for years:
>>>> __R(,)
>>>>
>>>> *What do you think?*
>>>>
>>>

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_1863_8535418.1390186165826
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">No it won't, __VA_ARGS__ leaves the commas in.<br>&nbsp; -=
Andrew.<br><br>On Monday, January 20, 2014 2:06:18 AM UTC+1, jgot...@gmail.=
com wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:=
 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">I t=
hink this is still slightly wrong.&nbsp; Won't it eat the comma, so that <d=
iv style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187)=
;border-style:solid;border-width:1px;word-wrap:break-word"><code><div><span=
 style=3D"color:#000">RAW</span><span style=3D"color:#660">(</span><span st=
yle=3D"color:#000">std</span><span style=3D"color:#660">::</span><span styl=
e=3D"color:#000">pair</span><span style=3D"color:#660">&lt;</span><span sty=
le=3D"color:#008">int</span><span style=3D"color:#660">,</span><span style=
=3D"color:#000"> </span><span style=3D"color:#008">int</span><span style=3D=
"color:#660">&gt;)</span><span style=3D"color:#000"><br></span></div></code=
></div>becomes<br><div style=3D"background-color:rgb(250,250,250);border-co=
lor:rgb(187,187,187);border-style:solid;border-width:1px;word-wrap:break-wo=
rd"><code><div><span style=3D"color:#000">std</span><span style=3D"color:#6=
60">::</span><span style=3D"color:#000">pair</span><span style=3D"color:#66=
0">&lt;</span><span style=3D"color:#008">int</span><span style=3D"color:#00=
0"> </span><span style=3D"color:#008">int</span><span style=3D"color:#660">=
&gt;</span><span style=3D"color:#000"> </span><span style=3D"color:#800">//=
no comma!</span><span style=3D"color:#000"><br></span></div></code></div><b=
r>Joe Gottman<br><br>On Sunday, January 19, 2014 5:15:46 PM UTC-5, Andrew T=
omazos wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-lef=
t:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">Actua=
lly sorry, I am slightly wrong about that solution. &nbsp;The argument to R=
AW will be parsed in turn as two arguments and not one. &nbsp;It should be:=
<div><br></div><div>&nbsp; &nbsp; #define RAW(...) __VA_ARGS__<br><br>This =
will work I think.</div><div><br></div><div>On Sunday, January 19, 2014 10:=
11:35 PM UTC+1, Andrew Tomazos wrote:<blockquote class=3D"gmail_quote" styl=
e=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex=
"><div dir=3D"ltr">#define RAW(x) x<div><br></div><div><span style=3D"font-=
family:monospace;background-color:rgb(250,250,250);color:rgb(0,0,0)">GENERA=
TE_FUNC</span><span style=3D"font-family:monospace;background-color:rgb(250=
,250,250);color:rgb(102,102,0)">(RAW(</span><span style=3D"font-family:mono=
space;background-color:rgb(250,250,250);color:rgb(0,0,0)">std</span><span s=
tyle=3D"font-family:monospace;background-color:rgb(250,250,250);color:rgb(1=
02,102,0)">::</span><span style=3D"font-family:monospace;background-color:r=
gb(250,250,250);color:rgb(0,0,0)">pair</span><span style=3D"font-family:mon=
ospace;background-color:rgb(250,250,250);color:rgb(102,102,0)">&lt;</span><=
span style=3D"font-family:monospace;background-color:rgb(250,250,250);color=
:rgb(0,0,136)">in<wbr>t</span><span style=3D"font-family:monospace;backgrou=
nd-color:rgb(250,250,250);color:rgb(102,102,0)">,</span><span style=3D"font=
-family:monospace;background-color:rgb(250,250,250);color:rgb(0,0,0)">&nbsp=
;</span><span style=3D"font-family:monospace;background-color:rgb(250,250,2=
50);color:rgb(0,0,136)">int</span><span style=3D"font-family:monospace;back=
ground-color:rgb(250,250,250);color:rgb(102,102,0)">&gt;),</span><span styl=
e=3D"font-family:monospace;background-color:rgb(250,250,250);color:rgb(0,0,=
0)">&nbsp;getPair1)</span><span style=3D"font-family:monospace;background-c=
olor:rgb(250,250,250);color:rgb(102,102,0)">,</span><span style=3D"font-fam=
ily:monospace;background-color:rgb(250,250,250);color:rgb(0,0,0)">&nbsp;</s=
pan><span style=3D"font-family:monospace;background-color:rgb(250,250,250);=
color:rgb(0,0,136)">return</span><span style=3D"font-family:monospace;backg=
round-color:rgb(250,250,250);color:rgb(0,0,0)">&nbsp;<wbr>std</span><span s=
tyle=3D"font-family:monospace;background-color:rgb(250,250,250);color:rgb(1=
02,102,0)">::</span><span style=3D"font-family:monospace;background-color:r=
gb(250,250,250);color:rgb(0,0,0)">make_pair</span><span style=3D"font-famil=
y:monospace;background-color:rgb(250,250,250);color:rgb(102,102,0)">(</span=
><span style=3D"font-family:monospace;background-color:rgb(250,250,250);col=
or:rgb(0,102,102)">1</span><span style=3D"font-family:monospace;background-=
color:rgb(250,250,250);color:rgb(102,102,0)">,</span><span style=3D"font-fa=
mily:monospace;background-color:rgb(250,250,250);color:rgb(0,0,0)">&nbsp;</=
span><span style=3D"font-family:monospace;background-color:rgb(250,250,250)=
;color:rgb(0,102,102)">1</span><span style=3D"font-family:monospace;backgro=
und-color:rgb(250,250,250)"><font color=3D"#666600">));</font></span><br></=
div><div><br></div><div>The arguments to a macro are identified before macr=
o expansion takes place on the arguments. &nbsp;So the above will nest out =
the comma like you want.</div><div><br></div><div>The preprocessor respects=
 parenthesis for nesting arguments.</div><div><br></div><div>From 16.2:</di=
v><div><br><div>The sequence of preprocessing tokens bounded by the outside=
-most matching parentheses forms the list of</div><div>arguments for the fu=
nction-like macro. The individual arguments within the list are separated b=
y comma</div><div>preprocessing tokens, <b>but comma preprocessing tokens b=
etween matching inner parentheses do not separate</b></div><div><b>argument=
s</b>.</div><div><br></div><div><div><b>After the arguments for the invocat=
ion of a function-like macro have been identi=EF=AC=81ed, argument substitu=
tion</b></div><div><b>takes place.</b> A parameter in the replacement list,=
 unless preceded by a # or ## preprocessing token or</div><div>followed by =
a ## preprocessing token (see below), is replaced by the corresponding argu=
ment after all macros</div><div>contained therein have been expanded. Befor=
e being substituted, each argument=E2=80=99s preprocessing tokens are</div>=
<div>completely macro replaced as if they formed the rest of the preprocess=
ing =EF=AC=81le; no other preprocessing tokens</div><div>are available.</di=
v></div><div><br></div>On Sunday, January 19, 2014 6:28:43 PM UTC+1, Vittor=
io Romeo wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-l=
eft:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><b>=
Preprocessor macros</b>,&nbsp;even if potentially&nbsp;<i>unsafe</i>, still=
 have place in a lot of C/C++ programs. Using macros is the sometimes only =
way to avoid verbose code repetition, to simulate static reflection or to g=
enerate code that would be impossible to generate only using templates.<div=
>An issue with macros is that passing arguments is sometimes really counter=
-intuitive and dangerous.&nbsp;<br><br>Example:</div><div><div style=3D"bac=
kground-color:rgb(250,250,250);border:1px solid rgb(187,187,187);word-wrap:=
break-word"><code><div><span style=3D"color:#800">#define</span><span style=
=3D"color:#000"> GENERATE_FUNC</span><span style=3D"color:#660">(</span><sp=
an style=3D"color:#000">mType</span><span style=3D"color:#660">,</span><spa=
n style=3D"color:#000"> mName</span><span style=3D"color:#660">,</span><spa=
n style=3D"color:#000"> mBody</span><span style=3D"color:#660">)</span><spa=
n style=3D"color:#000"> mType mName</span><span style=3D"color:#660">(){</s=
pan><span style=3D"color:#000"> mBody </span><span style=3D"color:#660">}</=
span><span style=3D"color:#000"><br><br><br></span><span style=3D"color:#80=
0">// Ok, generates valid code</span><span style=3D"color:#000"><br>GENERAT=
E_FUNC</span><span style=3D"color:#660">(</span><span style=3D"color:#008">=
void</span><span style=3D"color:#660">,</span><span style=3D"color:#000"> p=
rintHi</span><span style=3D"color:#660">,</span><span style=3D"color:#000">=
 printf</span><span style=3D"color:#660">(</span><span style=3D"color:#080"=
>"hi"</span><span style=3D"color:#660">);)</span><span style=3D"color:#000"=
><br><br><br></span><span style=3D"color:#800">// Ok, generates valid code<=
/span><span style=3D"color:#000"><br>GENERATE_FUNC</span><span style=3D"col=
or:#660">(</span><span style=3D"color:#008">void</span><span style=3D"color=
:#660">,</span><span style=3D"color:#000"> printNumber</span><span style=3D=
"color:#660">,</span><span style=3D"color:#000"> printf</span><span style=
=3D"color:#660">(</span><span style=3D"color:#080">"%d"</span><span style=
=3D"color:#660">,</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#066">5</span><span style=3D"color:#660">);)</span><span style=3D"colo=
r:#000"><br><br><br></span><span style=3D"color:#800">// The comma in "&lt;=
int, int&gt;" is read as an additional argument - macro expansion fails</sp=
an><span style=3D"color:#000"><br>GENERATE_FUNC</span><span style=3D"color:=
#660">(</span><span style=3D"color:#000">std</span><span style=3D"color:#66=
0">::</span><span style=3D"color:#000">pair</span><span style=3D"color:#660=
">&lt;</span><span style=3D"color:#008">int</span><span style=3D"color:#660=
">,</span><span style=3D"color:#000"> </span><span style=3D"color:#008">int=
</span><span style=3D"color:#660">&gt;,</span><span style=3D"color:#000"> g=
etPair1</span><span style=3D"color:#660">,</span><span style=3D"color:#000"=
> </span><span style=3D"color:#008">return</span><span style=3D"color:#000"=
> std</span><span style=3D"color:#660">::</span><span style=3D"color:#000">=
make_pair</span><span style=3D"color:#660">(</span><span style=3D"color:#06=
6">1</span><span style=3D"color:#660">,</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#066">1</span><span style=3D"color:#660">);)</sp=
an><span style=3D"color:#000"><br><br><br></span><span style=3D"color:#800"=
>// The comma in "&lt;int, int&gt;" is read correctly, but the generated co=
de is invalid, as </span><span style=3D"color:#000"><br></span><span style=
=3D"color:#800">// the round parenthesis persist in the return type (look b=
elow for the expansion)</span><span style=3D"color:#000"><br>GENERATE_FUNC<=
/span><span style=3D"color:#660">((</span><span style=3D"color:#000">std</s=
pan><span style=3D"color:#660">::</span><span style=3D"color:#000">pair</sp=
an><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">int</sp=
an><span style=3D"color:#660">,</span><span style=3D"color:#000"> </span><s=
pan style=3D"color:#008">int</span><span style=3D"color:#660">&gt;),</span>=
<span style=3D"color:#000"> getPair2</span><span style=3D"color:#660">,</sp=
an><span style=3D"color:#000"> </span><span style=3D"color:#008">return</sp=
an><span style=3D"color:#000"> std</span><span style=3D"color:#660">::</spa=
n><span style=3D"color:#000">make_pair</span><span style=3D"color:#660">(</=
span><span style=3D"color:#066">1</span><span style=3D"color:#660">,</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#066">1</span><span=
 style=3D"color:#660">);)</span><span style=3D"color:#000"><br></span><span=
 style=3D"color:#800">/*<br>&nbsp; &nbsp; (std::pair&lt;int, int&gt;) getPa=
ir2() { return std::make_pair(1, 1); }<br>*/</span></div></code></div><div>=
<br></div></div><div>There are possible solutions to this issue:</div>1. Cr=
eate a typedef for `std::pair&lt;int, int&gt;` - this solution is specific =
to this case, and may not always be applicable. Additionally, it requires t=
he coder to define a new typedef,<div>2. Create multiple macros (for exampl=
e, GENERATE_FUNC_START and GENERATE_FUNC_END), and let the user write the c=
ode in-between - this solution is ugly and error prone. Also, it scales poo=
rly, as k "body" arguments would require k+1 macro definitions.</div><div><=
br></div><div>These solutions, however, can be defined <i>hacks. </i>The is=
sue is that there is no way to pass a "raw" argument to the preprocessor.&n=
bsp;</div><div><br></div><div>Here's what I propose:</div><div><b>Similarly=
 to C++11 raw strings, have a new syntax that allows the user to pass "raw =
arguments" to preprocessor macros.</b></div><div><br></div><div>Example:</d=
iv><div><div style=3D"background-color:rgb(250,250,250);border:1px solid rg=
b(187,187,187);word-wrap:break-word"><code><div><font color=3D"#000000"><sp=
an style=3D"color:#000">GENERATE_FUNC</span><span style=3D"color:#660">(</s=
pan><span style=3D"color:#000">__R</span><span style=3D"color:#660">(</span=
><span style=3D"color:#000">std</span><span style=3D"color:#660">::</span><=
span style=3D"color:#000">pair</span><span style=3D"color:#660">&lt;</span>=
<span style=3D"color:#008">in<wbr>t</span><span style=3D"color:#660">,</spa=
n><span style=3D"color:#000"> </span><span style=3D"color:#008">int</span><=
span style=3D"color:#660">&gt;),</span><span style=3D"color:#000"> __R</spa=
n><span style=3D"color:#660">(</span><span style=3D"color:#000">getPairRaw<=
/span><span style=3D"color:#660">),</span><span style=3D"color:#000"> __R</=
span><span style=3D"color:#660">(</span><span style=3D"color:#008">return</=
span><span style=3D"color:#000"> std</span><span style=3D"color:#660">::</s=
pan><span style=3D"color:#000">make_pair</span><span style=3D"color:#660">(=
</span><span style=3D"color:#066">1</span><span style=3D"color:#660">,</spa=
n><span style=3D"color:#000"> </span><span style=3D"color:#066">1</span><sp=
an style=3D"color:#660">))</span><span style=3D"color:#000"><br></span></fo=
nt></div></code></div><br>Specification:</div><div><div style=3D"background=
-color:rgb(250,250,250);border:1px solid rgb(187,187,187);word-wrap:break-w=
ord"><code><div><font color=3D"#660066"><span style=3D"color:#000">&lt; __R=
 &gt; </span><span style=3D"color:#008">&lt;prefix&gt;</span><span style=3D=
"color:#000"> &lt;(&gt; &lt;...&gt; &lt;)&gt; </span><span style=3D"color:#=
008">&lt;suffix&gt;</span><span style=3D"color:#000"> </span></font></div><=
/code></div><br>Prefix/suffix example:</div><div><div style=3D"background-c=
olor:rgb(250,250,250);border:1px solid rgb(187,187,187);word-wrap:break-wor=
d"><code><div><span style=3D"color:#000">GENERATE_FUNC</span><span style=3D=
"color:#660">(</span><span style=3D"color:#000">__R</span><span style=3D"co=
lor:#660">***(</span><span style=3D"color:#606">ReturnTyp<wbr>e</span><span=
 style=3D"color:#660">(</span><span style=3D"color:#008">int</span><span st=
yle=3D"color:#660">*))***,</span><span style=3D"color:#000"> __R</span><spa=
n style=3D"color:#660">(</span><span style=3D"color:#000">getIntPtr</span><=
span style=3D"color:#660">),</span><span style=3D"color:#000"> __R</span><s=
pan style=3D"color:#660">(</span><span style=3D"color:#008">return</span><s=
pan style=3D"color:#000"> </span><span style=3D"color:#660">&amp;</span><fo=
nt color=3D"#006666"><span style=3D"color:#000">someInt</span><span style=
=3D"color:#660">;))</span><span style=3D"color:#000"><br></span></font></di=
v></code></div><br></div><div>Unit test before example:</div><div><div styl=
e=3D"background-color:rgb(250,250,250);border:1px solid rgb(187,187,187);wo=
rd-wrap:break-word"><code><div><font color=3D"#660066"><span style=3D"color=
:#000">UNIT_TEST_START</span><span style=3D"color:#660">()</span><span styl=
e=3D"color:#000"><br></span></font><span style=3D"color:#000">&nbsp; &nbsp;=
 &nbsp;EXPECT</span><span style=3D"color:#660">(</span><span style=3D"color=
:#000">some predicate</span><span style=3D"color:#660">);</span><span style=
=3D"color:#000"><br>&nbsp; &nbsp; &nbsp;</span><span style=3D"color:#660">.=
...</span><span style=3D"color:#000"> <br></span><font color=3D"#660066"><sp=
an style=3D"color:#000">UNIT_TEST_END</span><span style=3D"color:#660">()</=
span></font></div></code></div><br></div><div>Unit test after example:</div=
><div><div style=3D"background-color:rgb(250,250,250);border:1px solid rgb(=
187,187,187);word-wrap:break-word"><code><div><font color=3D"#660066"><span=
 style=3D"color:#000">UNIT_TEST</span><span style=3D"color:#660">(</span><s=
pan style=3D"color:#000">__R</span><span style=3D"color:#660">(</span><span=
 style=3D"color:#000"><br>&nbsp; &nbsp; &nbsp;EXPECT</span><span style=3D"c=
olor:#660">(</span><span style=3D"color:#000">some predicate</span><span st=
yle=3D"color:#660">);</span><span style=3D"color:#000"><br>&nbsp; &nbsp; &n=
bsp;</span><span style=3D"color:#660">...</span><span style=3D"color:#000">=
 <br></span><span style=3D"color:#660">))</span></font></div></code></div><=
br>This "raw syntax" would also fix the "comma problem", that forced users =
to define a "COMMA" macro for years:</div><div><div style=3D"background-col=
or:rgb(250,250,250);border:1px solid rgb(187,187,187);word-wrap:break-word"=
><code><div><font color=3D"#660066"><span style=3D"color:#000">__R</span><s=
pan style=3D"color:#660">(,)</span></font></div></code></div><br><b>What do=
 you think?</b></div></div></blockquote></div></div></blockquote></div></di=
v></blockquote></div></blockquote></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_1863_8535418.1390186165826--

.
