On Sun, 27 Mar 2011 15:46:54 -0400, enuhtac <enuhtac_li...@gmx.de> wrote:
Hello everyone,
I'm new to D and to 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
Hmm... I don't know you're use case exactly, but it sounds like a case of
operator overload abuse. The design of opCmp was inspired by the amount of
bug prone repetition that happens with C++ style comparison operators.
Furthermore, both opCmp and opEquals have fixed return types in order to
limit abuse. (D also prevents the overload of certain operators for the
same reason). The main reason behind expression templates is to avoid
costly intermediates, but the expression is always going to be heavier
weight than an int, so why can't you evaluated the expression then and
there?