View mode: basic / threaded / horizontal-split · Log in · Help
May 26, 2010
Handy templates
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 27, 2010
Re: Handy templates
>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 28, 2010
Re: Handy templates
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 29, 2010
Re: Handy templates
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><
June 07, 2010
Re: Handy templates
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
Top | Discussion index | About this forum | D home