template alias parameters

2011-04-06 Thread enuhtac
Hi,

I'm playing around with template alias parameters. At the moment I'm
considering the following simple code:

struct A
{};

struct B( T )
{
T t;
};

struct C( alias T )
{
T t;
};

void main()
{
B!A a;
C!A b;
}

What exactly is the difference between a and b? Both seem to do the same
thing but obviously there is a difference as I cannot instanciate C with
buildin types as template parameter ("C!int c" results in "Error:
template instance C!(int) does not match template declaration C(alias T)").

The other question is: is there a possibility to distinguinish between
different "things" passed to a template alias paramter? - Like "isType",
"isVariable", "isLiteral", "isTemplate" ...

enuhtac


Re: The is expression

2011-04-05 Thread enuhtac
Am 03.04.2011 16:11, schrieb Philippe Sigaud:
> On Sat, Apr 2, 2011 at 13:05, enuhtac  wrote:
>> This is the type I would like to check for:
>>
>> struct A( T, string s )
>> { ... };
> Hi,
>
> the trick is to use a function do the work for you. Let's define isAnA:
>
> void isAnA(T, string s)( A!(T,s) a) { }
>
> isAnA can only be called (compiled) with your A.
>
> A!(int, "abc") a;
> A!(double, "") b;
>
> isAnA(a); // OK
> isAnA(b); // OK
> isAnA(123); // does not compile.
>
> So you can nest it in a template and check at compile-time if it compiles:
>
> template isMyA(Type)
> {
> static if (__traits(compiles,
> {
> void isAnA(T, string s)(A!(T,s) a) {}
> isAnA(Type.init); // create a value of
> type Type, see if isAnA accepts it.
> }))
> enum bool isMyA = true;
> else
> enum bool isMyA = false;
> }
>
> Note that this is strictly tailored to A's with (T, string s) as
> arguments. You can relax the constraints by adapting the test
> function.
>
> For a more generic way to test for this, you can have a look there:
>
> http://svn.dsource.org/projects/dranges/trunk/dranges/docs/templates.html
>   ("isInstanceOf" and "Template ParametersTypeTuple")
> http://svn.dsource.org/projects/dranges/trunk/dranges/docs/typepattern.html
>  (look for "isA")
>
>
> Philippe

Hi Philippe,

thanks for your answer. If it is that complicated if I prefer explicit
specialization, I think. But I do not quite understand that it is not
possible to achieve this with a simple "is" expression (without a
function like "isAnA" and using "__traits") as the D language reference
includes a very similiar example based on arrays:


  static if (is(int[10] W : W[V], int V))

what is the essential difference to:

static if( is( A!(int, "xxx") T == A!(T, s), string s ) )

?

enuhtac


Re: The is expression

2011-04-02 Thread enuhtac
Am 02.04.2011 04:00, schrieb Caligo:
> On Fri, Apr 1, 2011 at 5:14 PM, enuhtac  wrote:
>> Hello,
>>
>> the "is" expression is a great feature of D - but its use is not very
>> intuitive, at least for me.
>> I'm trying to write a template that figures out if the template
>> parameter is of a given type.
>> This is the type I would like to check for:
>>
>> struct A( T, string s )
>> { ... };
>>
>> One possibility to accomplish this check is explicit template
>> specialization:
>>
>> template isA( T )
>> {
>>enum bool isA = false;
>> };
>>
>> template isA( T : A!( U, s ), U, string s )
>> {
>>enum bool isA = true;
>> };
>>
>> This more or less the C++ approach. But in D this could also be done
>> with static if and the "is" expression. As I understand "is" it should
>> be done like this:
>>
>> template isA( T )
>> {
>>static if( is( T U == A!( U, s ), string s ) )
>>enum bool isA = true;
>>else
>>enum bool isA = false;
>> };
>>
>> But this does not work. So what am I doing wrong?
>>
>> Regards,
>> enuhtac
>>
>>
> I'm new too, but I think it should be like this:
>
> template isA( T ){
>
>   enum bool isA = is(T : A)
> }
>
> if the name of enum is same as the template then you could use it as such:
>
> if( isA( T ) ){ }
>
> instead of
>
> if( isA( T ).isA ){ }
>
> Also note that : allows implicit conversion, while == requires the
> types to be exactly the same.
Your right. In your example it is possible to circumvent the "static if"
construct. I was not aware of this, so thanks for the hint.
But in my case this does not work as I'm using the following "is" form:

*is (* /Type/ /Identifier/ *==* /TypeSpecialization/ *,*
/TemplateParameterList/ *)

*Obviously "is" forms that include an "Identifier" can only be used in
"static if" constructs. Actually I could do without the "Identifier" but
I need the "TemplateParameterList". But there is no "is" form where you
get a "TemplateParameterList" without an "Identifier".
Actually that would be nice as this would look like the explicit
specialization:

template isA( T )
{
   static if( is( T == A!( U, s ), U, string s ) )
   enum bool isA = true;
   else
   enum bool isA = false;
};

Or with your simplification:

template isA( T )
{
   enum bool isA = is( T == A!( U, s ), U, string s );
};


But this is not possible as the "Identifier" is missing.

So still I do not know what I'm doing wrong in my original code.


Re: The is expression

2011-04-02 Thread enuhtac
Am 02.04.2011 11:24, schrieb spir:
> On 04/02/2011 12:14 AM, enuhtac wrote:
>> template isA( T )
>> {
>>  static if( is( T U == A!( U, s ), string s ) )
>>  enum bool isA = true;
>>  else
>>  enum bool isA = false;
>> };
>
> What does ", string s" do here inside the is expression?
>
> Denis
A takes two template parameters: a type "T" and a value "string s". So I
need to specify both parameters in the is expression. In the D manual
you find something similar:

static if (is(int[10] W : W[V], int V))




The is expression

2011-04-01 Thread enuhtac
Hello,

the "is" expression is a great feature of D - but its use is not very
intuitive, at least for me.
I'm trying to write a template that figures out if the template
parameter is of a given type.
This is the type I would like to check for:

struct A( T, string s )
{ ... };

One possibility to accomplish this check is explicit template
specialization:

template isA( T )
{
enum bool isA = false;
};

template isA( T : A!( U, s ), U, string s )
{
enum bool isA = true;
};

This more or less the C++ approach. But in D this could also be done
with static if and the "is" expression. As I understand "is" it should
be done like this:

template isA( T )
{
static if( is( T U == A!( U, s ), string s ) )
enum bool isA = true;
else
enum bool isA = false;
};

But this does not work. So what am I doing wrong?

Regards,
enuhtac



expression templates

2011-03-26 Thread Mr enuhtac
Hello everyone,

I'm new to D and this list (although I've had a look onto D a few years ago). I 
hope you guys can help me with my questions.

At the moment I'm trying to implement some expression template stuff. My first 
goal is to encode an expression into a type representing that expression 
without any additional functionality (like the possibility to evaluate that 
expression). Actually this is very simple and short in D. This is my approach:

struct OpBinary( string Op, R1, R2 )
{
alias typeof( mixin( "R1.EvalT.init" ~ Op ~ "R2.EvalT.init" ) ) EvalT;

enum string Operator = Op;
};

struct Constant( T, T v )
{
alias T EvalT;

enum T value = v;
};

struct Expr( R )
{
auto opBinary( string Op, R2 )( Expr!R2 )
{
return Expr!( OpBinary!( Op, R, R2 ) )();
}

auto opBinary( string Op, T )( T v ) if( isNumeric!T )
{
return Expr!( OpBinary!( Op, R, Constant!( T, v ) ) )();
}

auto opBinaryRight( string Op, T )( T v ) if( isNumeric!T )
{
return Expr!( OpBinary!( Op, Constant!( T, v ), R ) )();
}
};

But I cannot figure out how to implement expression templates for comparison 
operators, which is crucial for my purpose. The opCmp function is great for 
implementing comparison functionality, but when building an expression template 
tree the information on the actual comparison operator is needed. opCmp just 
knows that a comparison is going on, the actual type of comparison is unknown.
What I would like to have is something like this:

auto opCmp( string Op, R2 )( Expr!R2 )
{
return Expr!( OpBinary!( Op, R, R2 ) )();
}

So opCmp knows about the actual operator and would just use my OpBinary struct 
to encode it. But this is not possible.

The only workaround for I this problem I can imagine is using my own comparison 
functions instead of the comparison operators:
op!"<"( a, b ) instead of a < b.
Another possibility would be to call opBinary explicitly:
a.opCmp!"<"( b )
In this case I would not even have to write additional code.

But these workarounds are ugly, if would greatly prefer the normal comparison 
operators.
Does anyone has an idea how to use them?

Regards,
enuhtac
-- 
GMX DSL Doppel-Flat ab 19,99 Euro/mtl.! Jetzt mit 
gratis Handy-Flat! http://portal.gmx.net/de/go/dsl