typedefs are useless
Simen Kjaeraas
simen.kjaras at NOSPAM.gmail.com
Tue Dec 4 09:53:49 PST 2007
Steven Schveighoffer Wrote:
> FWIW, you can do stuff like this today by using a struct with a single
> member of the base type you want, but you must define all the operators, but
> there is no implicit cast back to the base type. A struct is POD, so it
> occupies the same space as the single member, so you get no loss of
> efficiency there.
>
> The other problem is that operators can't be used in constant expressions
> (which is another pet peeve I have about this). Using a typedef would allow
> operators to be used.
>
> I want to say I really like BCS's idea as it really allows you to redefine
> all aspects of a typedef. This would be perfect for what I am trying to do.
>
> -Steve
On Tue, 04 Dec 2007 15:38:40 +0100, Steven Schveighoffer <schveiguy at yahoo.com> wrote:
> FWIW, you can do stuff like this today by using a struct with a single
> member of the base type you want, but you must define all the operators,
> but
> there is no implicit cast back to the base type. A struct is POD, so it
> occupies the same space as the single member, so you get no loss of
> efficiency there.
>
> The other problem is that operators can't be used in constant expressions
> (which is another pet peeve I have about this). Using a typedef would
> allow
> operators to be used.
>
> I want to say I really like BCS's idea as it really allows you to
> redefine
> all aspects of a typedef. This would be perfect for what I am trying to
> do.
>
> -Steve
Have a template, it's on the house.
// start code
template TypeDef(T)
{
T value;
typeof(this) opNeg()
{
typeof(this) tmp;
tmp.value = -this.value;
return tmp;
}
typeof(this) opPostInc()
{
typeof(this) tmp;
tmp.value = value++;
return tmp;
}
typeof(this) opPostDec()
{
typeof(this) tmp;
tmp.value = value--;
return tmp;
}
T opCast()
{
return value;
}
static typeof(this) opCall(T rhs)
{
typeof(this) tmp;
tmp.value = rhs;
return tmp;
}
T opCall() // ugly hack to simulate implicit cast
{
return value;
}
typeof(this) opAdd(T rhs)
{
typeof(this) tmp;
tmp.value = value + rhs;
return tmp;
}
typeof(this) opSub(T rhs)
{
typeof(this) tmp;
tmp.value = value + rhs;
return tmp;
}
typeof(this) opMul(T rhs)
{
typeof(this) tmp;
tmp.value = value * rhs;
return tmp;
}
typeof(this) opDiv(T rhs)
{
typeof(this) tmp;
tmp.value = value / rhs;
return tmp;
}
typeof(this) opMod(T rhs)
{
typeof(this) tmp;
tmp.value = value % rhs;
return tmp;
}
typeof(this) opAssign(T rhs)
{
value = rhs;
return this;
}
typeof(this) opAddAssign(T rhs)
{
value += rhs;
return this;
}
typeof(this) opSubAssign(T rhs)
{
value -= rhs;
return this;
}
typeof(this) opMulAssign(T rhs)
{
value *= rhs;
return this;
}
typeof(this) opDivAssign(T rhs)
{
value /= rhs;
return this;
}
typeof(this) opModAssign(T rhs)
{
value %= rhs;
return this;
}
typeof(this) opAdd(typeof(this) rhs)
{
typeof(this) tmp;
tmp.value = value + rhs.value;
return tmp;
}
typeof(this) opSub(typeof(this) rhs)
{
typeof(this) tmp;
tmp.value = value + rhs.value;
return tmp;
}
typeof(this) opMul(typeof(this) rhs)
{
typeof(this) tmp;
tmp.value = value * rhs.value;
return tmp;
}
typeof(this) opDiv(typeof(this) rhs)
{
typeof(this) tmp;
tmp.value = value / rhs.value;
return tmp;
}
typeof(this) opMod(typeof(this) rhs)
{
typeof(this) tmp;
tmp.value = value % rhs.value;
return tmp;
}
typeof(this) opAddAssign(typeof(this) rhs)
{
value += rhs.value;
return this;
}
typeof(this) opSubAssign(typeof(this) rhs)
{
value -= rhs.value;
return this;
}
typeof(this) opMulAssign(typeof(this) rhs)
{
value *= rhs.value;
return this;
}
typeof(this) opDivAssign(typeof(this) rhs)
{
value /= rhs.value;
return this;
}
typeof(this) opModAssign(typeof(this) rhs)
{
value %= rhs.value;
return this;
}
string toString()
{
return std.stdio.toString(value);
}
}
// end code
Used it for a quick 'n dirty test like this:
// start code
struct ImaginaryNumber
{
mixin TypeDef!(int);
typeof(this) opAddAssign(int rhs){return this;}
typeof(this) opSubAssign(int rhs){return this;}
int opMulAssign(typeof(*this) rhs)
{
int result = value * rhs.value;
value = 0;
return -result;
}
typeof(this) opMulAssign(int rhs)
{
value *= rhs;
return this;
}
int opMul(typeof(*this) rhs)
{
return -value * rhs.value;
}
typeof(this) opMul(int rhs)
{
typeof(this) tmp;
tmp.value = value * rhs;
return tmp;
}
}
// end code
I'd like to have a T opImplicitCastTo() {return value;} in there as well, but that will have to wait.
More information about the Digitalmars-d
mailing list