Thread overview
Accessing all data in TypeTupple (AliasSeq) and stringify them
Feb 25, 2016
Voitech
Feb 25, 2016
Nicholas Wilson
Feb 25, 2016
Voitech
Feb 25, 2016
Nicholas Wilson
Feb 25, 2016
Ali Çehreli
February 25, 2016
Hi, I have some code processing functions definition in compile time, I want to override
them in some other class but not explicitly so created this code:

template MixinFunction(alias attributes,alias returnType,alias name,alias parameters,alias bodyy){

	enum string MixinFunction = format(q{
			%s %s %s(%s){

				%s

			}

		},attributes,returnType,name,parameters,bodyy);
}
unittest{
	alias func=MixinFunction!("static","void","testFunc","int a,int b",q{

			import std.stdio;
			writeln("im void body");

		});
	pragma(msg,func);
	mixin(func);
}

Now i acquired all data like return type, parameters but need to turn them into string for example function parameters must have form of:

for function func:
void func(int a,string b){}

alias parameters=Parameters!func;

returns me AliasSeq!(int,string)
I want to to turn them into string: like "int param0, string param1", but in template

    template AliasSeqToString(TList...){

        enum AliasSeqToString= ... //each ?


    }
How to operate on TypeTuple/AliasSeq elemens withouth foreach ?




February 25, 2016
On Thursday, 25 February 2016 at 13:16:43 UTC, Voitech wrote:
> Hi, I have some code processing functions definition in compile time, I want to override
> them in some other class but not explicitly so created this code:
>
> template MixinFunction(alias attributes,alias returnType,alias name,alias parameters,alias bodyy){
>
> 	enum string MixinFunction = format(q{
> 			%s %s %s(%s){
>
> 				%s
>
> 			}
>
> 		},attributes,returnType,name,parameters,bodyy);
> }
> unittest{
> 	alias func=MixinFunction!("static","void","testFunc","int a,int b",q{
>
> 			import std.stdio;
> 			writeln("im void body");
>
> 		});
> 	pragma(msg,func);
> 	mixin(func);
> }
>
> Now i acquired all data like return type, parameters but need to turn them into string for example function parameters must have form of:
>
> for function func:
> void func(int a,string b){}
>
> alias parameters=Parameters!func;
>
> returns me AliasSeq!(int,string)
> I want to to turn them into string: like "int param0, string param1", but in template
>
>     template AliasSeqToString(TList...){
>
>         enum AliasSeqToString= ... //each ?
>
>
>     }
> How to operate on TypeTuple/AliasSeq elemens withouth foreach ?

You can (see std.meta/(std.traits?) , with recursive templates), but there is nothing stopping from using for/foreach in a template

this should do what you want
string[] functionSig;
string[] params;
foreach(s; Parameters!T)) // returns AliasSeq of types
 {
       params ~=s.stringof;
 }
  string[] pits;
 foreach(p; ParameterIdentifierTuple!(T)); // returns AliasSeq of strings
{
           pits ~=p;
}
and the either join(er) or do as you see fit.
or use plain old for
for(auto i=0;i< pits.length; i++)
{
     functionSig ~= params[i];
     functionSig ~= pits[i];
}
writeln(functionSig);
// should print ["int" , "param0" , "string" , "param1"]

Nic
February 25, 2016
On Thursday, 25 February 2016 at 14:29:30 UTC, Nicholas Wilson wrote:
> On Thursday, 25 February 2016 at 13:16:43 UTC, Voitech wrote:
>> Hi, I have some code processing functions definition in compile time, I want to override
>> them in some other class but not explicitly so created this code:
>>
>> template MixinFunction(alias attributes,alias returnType,alias name,alias parameters,alias bodyy){
>>
>> 	enum string MixinFunction = format(q{
>> 			%s %s %s(%s){
>>
>> 				%s
>>
>> 			}
>>
>> 		},attributes,returnType,name,parameters,bodyy);
>> }
>> unittest{
>> 	alias func=MixinFunction!("static","void","testFunc","int a,int b",q{
>>
>> 			import std.stdio;
>> 			writeln("im void body");
>>
>> 		});
>> 	pragma(msg,func);
>> 	mixin(func);
>> }
>>
>> Now i acquired all data like return type, parameters but need to turn them into string for example function parameters must have form of:
>>
>> for function func:
>> void func(int a,string b){}
>>
>> alias parameters=Parameters!func;
>>
>> returns me AliasSeq!(int,string)
>> I want to to turn them into string: like "int param0, string param1", but in template
>>
>>     template AliasSeqToString(TList...){
>>
>>         enum AliasSeqToString= ... //each ?
>>
>>
>>     }
>> How to operate on TypeTuple/AliasSeq elemens withouth foreach ?
>
> You can (see std.meta/(std.traits?) , with recursive templates), but there is nothing stopping from using for/foreach in a template
>
> this should do what you want
> string[] functionSig;
> string[] params;
> foreach(s; Parameters!T)) // returns AliasSeq of types
>  {
>        params ~=s.stringof;
>  }
>   string[] pits;
>  foreach(p; ParameterIdentifierTuple!(T)); // returns AliasSeq of strings
> {
>            pits ~=p;
> }
> and the either join(er) or do as you see fit.
> or use plain old for
> for(auto i=0;i< pits.length; i++)
> {
>      functionSig ~= params[i];
>      functionSig ~= pits[i];
> }
> writeln(functionSig);
> // should print ["int" , "param0" , "string" , "param1"]
>
> Nic

Thank You for answering, well i wanted to make all of this in template block, not using template functions (testing if it is possible), but i'm getting error when i try to create something like

template TupleToString(TList...){

    string a;
    foreach(T;TList){ // Error: declaration expected, not 'foreach'
        a~=T.stringof;
    }
    enum string TupleToString=a;
}

Of course i can use template function, but wanted to know if can omit this.
Cheers Voitech

February 25, 2016
On Thursday, 25 February 2016 at 20:53:12 UTC, Voitech wrote:
> On Thursday, 25 February 2016 at 14:29:30 UTC, Nicholas Wilson wrote:
>> On Thursday, 25 February 2016 at 13:16:43 UTC, Voitech wrote:
>>> [...]
>>
>> You can (see std.meta/(std.traits?) , with recursive templates), but there is nothing stopping from using for/foreach in a template
>>
>> this should do what you want
>> string[] functionSig;
>> string[] params;
>> foreach(s; Parameters!T)) // returns AliasSeq of types
>>  {
>>        params ~=s.stringof;
>>  }
>>   string[] pits;
>>  foreach(p; ParameterIdentifierTuple!(T)); // returns AliasSeq of strings
>> {
>>            pits ~=p;
>> }
>> and the either join(er) or do as you see fit.
>> or use plain old for
>> for(auto i=0;i< pits.length; i++)
>> {
>>      functionSig ~= params[i];
>>      functionSig ~= pits[i];
>> }
>> writeln(functionSig);
>> // should print ["int" , "param0" , "string" , "param1"]
>>
>> Nic
>
> Thank You for answering, well i wanted to make all of this in template block, not using template functions (testing if it is possible), but i'm getting error when i try to create something like
>
> template TupleToString(TList...){
>
>     string a;
>     foreach(T;TList){ // Error: declaration expected, not 'foreach'
>         a~=T.stringof;
>     }
>     enum string TupleToString=a;
> }
>
> Of course i can use template function, but wanted to know if can omit this.
> Cheers Voitech

See the recursive templates in std.meta;

this would be something like

 template TupleToString(TList...)
{
       static if(Tlist.length == 0)
              enum string TupleToString = "";
       else
             enum string TupleToString=TList[0].stringof ~ TupleToString(TList[1 . $];
 }

Nic
February 25, 2016
On 02/25/2016 12:53 PM, Voitech wrote:

> template TupleToString(TList...){
>
>      string a;
>      foreach(T;TList){ // Error: declaration expected, not 'foreach'
>          a~=T.stringof;
>      }
>      enum string TupleToString=a;
> }
>
> Of course i can use template function, but wanted to know if can omit this.
> Cheers Voitech
>

You have to wrap the logic in a function and call that function:

template TupleToString(TList...){

    string make_a() {
        string a;
        foreach(T;TList){
            a~=T.stringof;
        }
        return a;
    }

    enum string TupleToString=make_a();
}

Ali