www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - AliasSeq of AliasSeq, or meta-functions that take multiple lists

reply Jean-Louis Leroy <jl leroy.nyc> writes:
I need to process two sequences in parallel (select some elements 
of sequence A depending of the corresponding element of sequence 
B). How can I pass two sequences to a meta-function? I tried 
nesting AliasSeqs but I get Perl4 style flattening:

   AliasSeq!(AliasSeq!(int, float),
             AliasSeq!(char, double))
   -> (int,float,char,double)

I worked around the problem by passing a single AliasSeq to my 
meta-function and using indexation to access the two sub-lists 
but now I need to process three sequences in parallel and I am 
looking for a cleaner solution.
Jun 19 2017
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 06/19/2017 12:54 PM, Jean-Louis Leroy wrote:
 I need to process two sequences in parallel (select some elements of
 sequence A depending of the corresponding element of sequence B). How
 can I pass two sequences to a meta-function? I tried nesting AliasSeqs
 but I get Perl4 style flattening:

   AliasSeq!(AliasSeq!(int, float),
             AliasSeq!(char, double))
   -> (int,float,char,double)

 I worked around the problem by passing a single AliasSeq to my
 meta-function and using indexation to access the two sub-lists but now I
 need to process three sequences in parallel and I am looking for a
 cleaner solution.
Hi Jean-Louis! :) One option is to nest templates: template foo(Args1...) { void bar(Args2...)() { } } void main() { foo!(int, float).bar!(char, double)(); } Ali
Jun 19 2017
next sibling parent "H. S. Teoh via Digitalmars-d-learn" <digitalmars-d-learn puremagic.com> writes:
On Mon, Jun 19, 2017 at 01:59:33PM -0700, Ali Çehreli via Digitalmars-d-learn
wrote:
 On 06/19/2017 12:54 PM, Jean-Louis Leroy wrote:
 I need to process two sequences in parallel (select some elements of
 sequence A depending of the corresponding element of sequence B).
 How can I pass two sequences to a meta-function? I tried nesting
 AliasSeqs but I get Perl4 style flattening:
 
   AliasSeq!(AliasSeq!(int, float),
             AliasSeq!(char, double))
   -> (int,float,char,double)
 
 I worked around the problem by passing a single AliasSeq to my
 meta-function and using indexation to access the two sub-lists but
 now I need to process three sequences in parallel and I am looking
 for a cleaner solution.
 
 
Hi Jean-Louis! :) One option is to nest templates: template foo(Args1...) { void bar(Args2...)() { } } void main() { foo!(int, float).bar!(char, double)(); }
[...] Another option is to encapsulate a sequence inside a non-eponymous template so that it doesn't auto-expand: template MySeq(T...) { alias elements = T; } template MyTemplate(T, U) if (is(T : MySeq!(V...), V) && is(U : MySeq!(V...), V)) { // do stuff with T.elements and U.elements } MyTemplate!(MySeq!(int, float), MySeq!(char, double)); The sig constraint in MyTemplate is not strictly necessary; it's just additional insurance against passing the wrong thing to MyTemplate and causing inscrutable template errors. T -- Without outlines, life would be pointless.
Jun 19 2017
prev sibling parent Jean-Louis Leroy <jl leroy.nyc> writes:
On Monday, 19 June 2017 at 20:59:33 UTC, Ali Çehreli wrote:
 On 06/19/2017 12:54 PM, Jean-Louis Leroy wrote:
 I need to process two sequences in parallel (select some 
 elements of
 sequence A depending of the corresponding element of sequence 
 B). How
 can I pass two sequences to a meta-function? I tried nesting 
 AliasSeqs
 but I get Perl4 style flattening:

   AliasSeq!(AliasSeq!(int, float),
             AliasSeq!(char, double))
   -> (int,float,char,double)

 I worked around the problem by passing a single AliasSeq to my
 meta-function and using indexation to access the two sub-lists 
 but now I
 need to process three sequences in parallel and I am looking 
 for a
 cleaner solution.
Hi Jean-Louis! :) One option is to nest templates: template foo(Args1...) { void bar(Args2...)() { } } void main() { foo!(int, float).bar!(char, double)(); } Ali
Hi Ali :) Thanks! It works perfectly for my purpose, which is to manipulate lists of types or values based on a list of types, e.g.: alias ParTypes = AliasSeq!(virtual!A, int, virtual!B); Signature!(ParTypes).UnqualArgs -> AliasSeq!(A, int, B) Signature!(ParTypes).VirtualArgs -> AliasSeq!(A, B) Signature!(ParTypes).Filter!(AliasSeq!(A, int, B)) -> AliasSeq!(A, B) J-L
Jun 20 2017