January 29, 2014 Re: Typed variadic template syntax? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Etienne | On Wednesday, 29 January 2014 at 21:18:06 UTC, Etienne wrote:
>>
>> void exec(string command)(){
>> foreach(str ; choice.splitter(".")){
>> writeln(str);
>> }
>> }
>
> I'd like to take the opportunity to say how much I'd love to be able to do a static foreach rather than use recursion.
You can use TypeTuple for static foreach.
void foo(int x)()
{
import std.stdio;
writeln(x);
}
void main()
{
import std.typetuple;
foreach (x; TypeTuple!(1, 2, 3))
foo!x();
}
Notice that the loop variable x is used as a template parameter at compile time. The code expands to:
foo!1();
foo!2();
foo!3();
|
January 29, 2014 Re: Typed variadic template syntax? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Wednesday, 29 January 2014 at 07:02:00 UTC, Andrei Alexandrescu wrote:
> On 1/28/14 4:14 PM, bearophile wrote:
>> This is not an enhancement request, but it presents a potential
>> enhancement.
>>
>>
>> This is C++11 code:
>>
>> template<int... digits> struct value;
>>
>> template<> struct value<> {
>> static const int v = 0;
>> };
>>
>> template<int first, int... rest> struct value<first, rest...> {
>> static int const v = 10 * value<rest...>::v + first;
>> };
>>
>>
>>
>> You can translate it to D like this:
>>
>>
>> enum isInt(T) = is(T == int);
>>
>> template value(xs...) if (allSatisfy!(isInt, xs)) {
>> static if (xs.length == 0)
>> enum value = 0;
>> else
>> enum value = xs[0] + 10 * value!(xs[1 .. $]);
>> }
>
> int value(int xs[]...) {
> int result = 0;
> foreach (i; xs) {
> result += 10 * result + i;
> }
> return result;
> }
>
> unittest
> {
> static assert(value(1, 2) == 21);
> }
>
>
> Andrei
This allocates memory and as such an inferior solution. I'd prefer ugly code over this any day.
|
January 29, 2014 Re: Typed variadic template syntax? | ||||
---|---|---|---|---|
| ||||
Posted in reply to inout | On Wednesday, 29 January 2014 at 22:25:45 UTC, inout wrote:
>> int value(int xs[]...) {
>> int result = 0;
>> foreach (i; xs) {
>> result += 10 * result + i;
>> }
>> return result;
>> }
>>
>> unittest
>> {
>> static assert(value(1, 2) == 21);
>> }
>>
>>
>> Andrei
>
> This allocates memory
no
|
January 30, 2014 Re: Typed variadic template syntax? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Peter Alexander | On Wednesday, 29 January 2014 at 22:16:57 UTC, Peter Alexander wrote:
> On Wednesday, 29 January 2014 at 21:18:06 UTC, Etienne wrote:
>>>
>>> void exec(string command)(){
>>> foreach(str ; choice.splitter(".")){
>>> writeln(str);
>>> }
>>> }
>>
>> I'd like to take the opportunity to say how much I'd love to be able to do a static foreach rather than use recursion.
>
> You can use TypeTuple for static foreach.
>
> void foo(int x)()
> {
> import std.stdio;
> writeln(x);
> }
>
> void main()
> {
> import std.typetuple;
> foreach (x; TypeTuple!(1, 2, 3))
> foo!x();
> }
>
> Notice that the loop variable x is used as a template parameter at compile time. The code expands to:
>
> foo!1();
> foo!2();
> foo!3();
Two problems:
1) You can't use `foreach` outside functions. That means that you write:
struct Foo{
foreach(i;TypeTuple!(1,2,3)){
mixin("int num"~i.stringof~";");
}
}
2) `foreach` creates it's own scope. This won't work:
foreach(i; TypeTuple!(1,2,3)){
mixin("int num"~i.stringof~";");
}
num1=1;
num2=2;
num3=3;
writeln(num1,num2,num3);
|
January 30, 2014 Re: Typed variadic template syntax? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Idan Arye | On Thursday, 30 January 2014 at 11:19:33 UTC, Idan Arye wrote: > On Wednesday, 29 January 2014 at 22:16:57 UTC, Peter Alexander wrote: >> On Wednesday, 29 January 2014 at 21:18:06 UTC, Etienne wrote: >>>> >>>> void exec(string command)(){ >>>> foreach(str ; choice.splitter(".")){ >>>> writeln(str); >>>> } >>>> } >>> >>> I'd like to take the opportunity to say how much I'd love to be able to do a static foreach rather than use recursion. >> >> You can use TypeTuple for static foreach. >> >> void foo(int x)() >> { >> import std.stdio; >> writeln(x); >> } >> >> void main() >> { >> import std.typetuple; >> foreach (x; TypeTuple!(1, 2, 3)) >> foo!x(); >> } >> >> Notice that the loop variable x is used as a template parameter at compile time. The code expands to: >> >> foo!1(); >> foo!2(); >> foo!3(); > > Two problems: > > 1) You can't use `foreach` outside functions. That means that you write: > struct Foo{ > foreach(i;TypeTuple!(1,2,3)){ > mixin("int num"~i.stringof~";"); > } > } > > 2) `foreach` creates it's own scope. This won't work: > foreach(i; TypeTuple!(1,2,3)){ > mixin("int num"~i.stringof~";"); > } > num1=1; > num2=2; > num3=3; > writeln(num1,num2,num3); 1) You can use mixin(format("<Prolog>%(<Begin>%s<End>%)<Epilog>", CompileTimeRange)); See std.format for ranges and std.string.format. 2) no. This should work for compile time foreach and TypeTuples. There are many examples in source code of Phobos. |
January 30, 2014 Re: Typed variadic template syntax? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Peter Alexander | On Wednesday, 29 January 2014 at 22:16:57 UTC, Peter Alexander wrote:
> You can use TypeTuple for static foreach.
>
> ...
This is why I think using term "declaration foreach" is less confusing. It is pretty much the same but shifts attention away from essentional use case.
|
January 30, 2014 Re: Typed variadic template syntax? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ilya Yaroshenko | On 01/30/2014 03:08 PM, Ilya Yaroshenko wrote:
>>
>> 2) `foreach` creates it's own scope. This won't work:
>> foreach(i; TypeTuple!(1,2,3)){
>> mixin("int num"~i.stringof~";");
>> }
>> num1=1;
>> num2=2;
>> num3=3;
>> writeln(num1,num2,num3);
>
> ...
> 2) no. This should work for compile time foreach and TypeTuples. There
> are many examples in source code of Phobos.
The following code fails to compile:
import std.typetuple, std.stdio;
void main(){
foreach(i; TypeTuple!(1,2,3)){
mixin("int num"~i.stringof~";");
}
num1=1;
num2=2;
num3=3;
writeln(num1,num2,num3);
}
|
January 30, 2014 Re: Typed variadic template syntax? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On 2014-01-30 10:28 AM, Timon Gehr wrote:
> import std.typetuple, std.stdio;
> void main(){
> foreach(i; TypeTuple!(1,2,3)){
> mixin("int num"~i.stringof~";");
> }
> num1=1;
> num2=2;
> num3=3;
> writeln(num1,num2,num3);
> }
>
>
This written as a static foreach or declarative foreach, would be awesome if it exposed the scope. For now the only solution is to build a string and mixin the string like this
string fct(R)(){
string str;
foreach (range ; R)
str ~= "int num " ~ range.stringof ~ ";";
return str;
}
mixin(fct!(TypeTuple!(1,2,3));
writeln(num1,num2, num3);
Looks a little less convenient than
static foreach ( i; 0..3 )
mixin("int num" ~ i.stringof ~ ";");
writeln(num1,num2, num3);
|
January 30, 2014 Re: Typed variadic template syntax? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On Thursday, 30 January 2014 at 15:28:34 UTC, Timon Gehr wrote:
> On 01/30/2014 03:08 PM, Ilya Yaroshenko wrote:
>>>
>>> 2) `foreach` creates it's own scope. This won't work:
>>> foreach(i; TypeTuple!(1,2,3)){
>>> mixin("int num"~i.stringof~";");
>>> }
>>> num1=1;
>>> num2=2;
>>> num3=3;
>>> writeln(num1,num2,num3);
>>
>> ...
>> 2) no. This should work for compile time foreach and TypeTuples. There
>> are many examples in source code of Phobos.
>
> The following code fails to compile:
>
> import std.typetuple, std.stdio;
> void main(){
> foreach(i; TypeTuple!(1,2,3)){
> mixin("int num"~i.stringof~";");
> }
> num1=1;
> num2=2;
> num3=3;
> writeln(num1,num2,num3);
> }
I am wrong, foreach always has own scope
foreach(S; TypeTuple!(string, wstring, dstring))
{
import std.conv : to;
S a = " a bcd ef gh ";
assert(equal(splitter(a), [to!S("a"), to!S("bcd"), to!S("ef"), to!S("gh")]));
a = "";
assert(splitter(a).empty);
}
You can use mixin and format instead:
import std.typetuple, std.stdio;
void main(){
mixin(format("%(int num%s; %);", [1,2,3])); //<----
num1=1;
num2=2;
num3=3;
writeln(num1,num2,num3);
}
|
January 30, 2014 Re: Typed variadic template syntax? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Etienne | On Thursday, 30 January 2014 at 17:12:51 UTC, Etienne wrote:
> On 2014-01-30 10:28 AM, Timon Gehr wrote:
>> import std.typetuple, std.stdio;
>> void main(){
>> foreach(i; TypeTuple!(1,2,3)){
>> mixin("int num"~i.stringof~";");
>> }
>> num1=1;
>> num2=2;
>> num3=3;
>> writeln(num1,num2,num3);
>> }
>>
>>
>
> This written as a static foreach or declarative foreach, would be awesome if it exposed the scope. For now the only solution is to build a string and mixin the string like this
>
> string fct(R)(){
> string str;
> foreach (range ; R)
> str ~= "int num " ~ range.stringof ~ ";";
>
> return str;
> }
>
> mixin(fct!(TypeTuple!(1,2,3));
> writeln(num1,num2, num3);
>
> Looks a little less convenient than
>
> static foreach ( i; 0..3 )
> mixin("int num" ~ i.stringof ~ ";");
> writeln(num1,num2, num3);
It works now:
mixin(format("%(int num%s; %);", [1,2,3])); //<----
writeln(num1,num2,num3);
|
Copyright © 1999-2021 by the D Language Foundation