www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Handy templates

reply "Simen kjaeraas" <simen.kjaras gmail.com> writes:
Here's a collection of templates I have created and use often. Some of  
these may be fit for inclusion in Phobos, others maybe not as much.
Please critique, and post your own indispensable snippets.

/**
Checks if one tuple contains another.

Example:
----
static assert(Contained!(int).In!(float, int));
static assert(!Contained!(int).In!(float, "foo"));
static assert(Contained!(int,"foo").In!(float, int, "foo", "bar"));
----
  */
template Contained(T...) {
     template In(U...) {
         static if (T.length == 0) {
             enum In = true;
         } else static if (U.length >= T.length) {
             enum In = SameTuple!(T).As!( U[0..T.length]) ||
                 Contained!(T).In!(U[1..$]);
         } else {
             enum In = false;
         }
     }
}

unittest {
     static assert(Contained!(int).In!(float, int));
     static assert(!Contained!(int).In!(float, "foo"));
     static assert(Contained!(int,"foo").In!(float, int, "foo", "bar"));
     static assert(!Contained!(int,"foo").In!(float, int, "bar", "foo"));
     static assert(Contained!().In!(float, int, "bar", "foo"));
}


/**
Evaluates to $(D F!(T[0..tupleLength]) &&  
F!(T[tupleLength..2*tupleLength]) && ... && F[T[$-tupleLength..$]]).

Example:
----
     static assert(allTuplesSatisfy!(Contained!(int).In, 2, int, float,  
"foo", int));
     static assert(!allTuplesSatisfy!(Contained!(int).In, 2, int, float,  
"foo",string));
----
  */
template allTuplesSatisfy( alias F, uint tupleLength, T... ) {
     static assert( !( T.length % tupleLength ) );

     static if ( T.length == tupleLength ) {
         enum allTuplesSatisfy = F!( T );
     } else {
         enum allTuplesSatisfy = F!( T[0..tupleLength] ) &&  
allTuplesSatisfy!( F, tupleLength, T[tupleLength..$] );
     }
}

unittest {
     static assert(allTuplesSatisfy!(Contained!(int).In, 2, int, float,  
"foo", int));
     static assert(!allTuplesSatisfy!(Contained!(int).In, 2, int, float,  
"foo",string));
}

/**
Repeats a type or tuple $(D num) times.

Example:
----
     static assert(allTuplesSatisfy!(Contained!(int).In, 2, int, float,  
"foo", int));
     static assert(!allTuplesSatisfy!(Contained!(int).In, 2, int, float,  
"foo",string));
----
  */
template Repeat( uint num, T... ) {
     static if ( num > 1 ) {
         alias TypeTuple!( T, Repeat!( num -1, T ) ) Repeat;
     } else {
         alias T Repeat;
     }
}

unittest {
     static assert(SameTuple!(Repeat!(4, int)).As!(int, int, int, int));
     static assert(SameTuple!(Repeat!(4, "foo")).As!("foo", "foo", "foo",  
"foo"));
     static assert(SameTuple!(Repeat!(2, int, "foo")).As!(int, "foo", int,  
"foo"));
     static assert(!SameTuple!(Repeat!(2, int)).As!());
}


-- 
Simen
May 26 2010
next sibling parent reply Philippe Sigaud <philippe.sigaud gmail.com> writes:
On Thu, May 27, 2010 at 01:00, Simen kjaeraas <simen.kjaras gmail.com>wrote:
Here's a collection of templates I have created and use often.
Some of these may be fit for inclusion in Phobos, others maybe not as much.
Please critique, and post your own indispensable snippets.
Hey, cool idea ! Do you have a site to put them online? The one you call Repeat, I call TypeNuple and use it almost on a daily basis. I have a bunch of those there: http://svn.dsource.org/projects/dranges/trunk/dranges/docs/templates.html I'm particularly fond of Compose, TemplateParametersTypeTuple, and TemplateFunArity. Any comme I also have templates acting specifically on typetuples there: http://svn.dsource.org/projects/dranges/trunk/dranges/docs/typetuple2.html Strangely enough, I _have_ uses for things like StaticScan...

May 27 2010
parent reply Don <nospam nospam.com> writes:
Philippe Sigaud wrote:
  >On Thu, May 27, 2010 at 01:00, Simen kjaeraas <simen.kjaras gmail.com 
 <mailto:simen.kjaras gmail.com>> wrote:
  >Here's a collection of templates I have created and use often.
  >Some of these may be fit for inclusion in Phobos, others maybe not as 
 much.
  >Please critique, and post your own indispensable snippets.
 
 
 Hey, cool idea ! Do you have a site to put them online?
If not, please put them in dsource/scrapple.
 The one you call Repeat, I call TypeNuple and use it almost on a daily 
 basis.
 
 I have a bunch of those there:
 
 http://svn.dsource.org/projects/dranges/trunk/dranges/docs/templates.html
 
 I'm particularly fond of Compose, TemplateParametersTypeTuple, and 
 TemplateFunArity. Any comme
 
 I also have templates acting specifically on typetuples there:
 
 http://svn.dsource.org/projects/dranges/trunk/dranges/docs/typetuple2.html
 
 Strangely enough, I _have_ uses for things like StaticScan...
 
 
 
May 28 2010
parent BCS <none anon.com> writes:
Hello Don,

 Philippe Sigaud wrote:
 
 On Thu, May 27, 2010 at 01:00, Simen kjaeraas
 <simen.kjaras gmail.com
 
<mailto:simen.kjaras gmail.com>> wrote:
 Here's a collection of templates I have created and use often. Some
 of these may be fit for inclusion in Phobos, others maybe not as
 
much.
 Please critique, and post your own indispensable snippets.
 
Hey, cool idea ! Do you have a site to put them online?
If not, please put them in dsource/scrapple.
If you need access, ping me and I'll get you in.
 The one you call Repeat, I call TypeNuple and use it almost on a
 daily basis.
 
 I have a bunch of those there:
 
 http://svn.dsource.org/projects/dranges/trunk/dranges/docs/templates.
 html
 
 I'm particularly fond of Compose, TemplateParametersTypeTuple, and
 TemplateFunArity. Any comme
 
 I also have templates acting specifically on typetuples there:
 
 http://svn.dsource.org/projects/dranges/trunk/dranges/docs/typetuple2
 .html
 
 Strangely enough, I _have_ uses for things like StaticScan...
 
-- ... <IXOYE><
May 28 2010
prev sibling parent "Simen kjaeraas" <simen.kjaras gmail.com> writes:
Simen kjaeraas <simen.kjaras gmail.com> wrote:

Another few that showed up now with my work on combinatorial products of  
ranges:

/**
Determines whether a template parameter is a type of value (alias).

Example:

----
template foo( T... ) if (allSatisfy!( isAlias, T ) {...}
----
*/
template isAlias( alias T ) {
     enum isAlias = true;
}

template isAlias( T ) {
     enum isAlias = false;
}


/**
Switches between template instantiations depending on the parameters  
passed.

Example:

----
alias staticSwitch( foo, 1, 2, 3 ).With callFoo;
callFoo( 2 ); // Actually calls foo!(2)( )
----
*/
template staticSwitch( alias F, T... ) if ( allSatisfy!( isAlias, T ) ) {
     auto With( CommonType!T index, ParameterTypeTuple!( F!( T[0] ) ) args  
) {
         switch ( index ) {
             foreach ( i, e; T ) {
                 mixin( Format!( q{case %s:}, e ) );
                 return F!( e )( args );
                 break;
             }
         }
         assert( false );
     }
}

version( unittest ) {
     int foo( int n ) {
         return n;
     }
}

unittest {
     assert( staticSwitch!( foo, 1, 2 ).With( 2 ) == 2 );
}

The latter does currently not work, due to bug 4292, but a patch has been  
submitted. Granted, a simple template would work around that problem, but  
better to remove it at the root.

Philippe, if you or anyone else want to add any of these templates to your  
dranges or their own collection of templates, I would be pleased to allow  
it. But please do give credit.

-- 
Simen
Jun 07 2010