Questions about opAssign alternate and template quality
Oskar Linde
oskar.lindeREM at OVEgmail.com
Thu Aug 10 07:59:12 PDT 2006
nobody wrote:
> I wanted to try out D's template system so I decided to define data
> structures that represent all the permutations of RGB, HLS, RGBA and
> HLSA. I decided to convert between the various types by overriding
> opAssign under the mistaken impression that D supported it. Impressive
> when you do the math:
>
> 3! + 3! + 4! + 4! = 60 types
> (3! + 3! + 4! + 4!)^2 = 3600 opAssigns
>
> So my first question is whether anyone has an elegant alternative to
> using opAssign?
I don't know of any elegant alternative. I also find it very unfortunate
that opAssign isn't overloadable for structs.
> My second question is mostly an open invitation to make suggestions for
> improving my template writing style. In particular I am suspicious that
> there is a way to take better advantage of templates and not write out
> all 60 permutations.
>
> So here is the actual code. I only included the RGB permutations to keep
> it as short as possible.
Implicit function template instantiation and some static ifs can help
you. Unfortunately, IFTI isn't yet implemented for member functions, but
you can make a free function like:
void pixAssign(A,B)(out A A, in B b) {
static if (is(a.a) && is(b.a)) {
// Alpha
a.a = b.a;
} else static if(is(a.a)) {
a.a = typeof(a.a).max;
}
static if (is(a.r) && is(b.r)) {
// RGB->RGB
auto r = b.r;
auto g = b.g;
auto b = b.b;
a.r = r;
a.g = g;
a.b = b;
} else static if (is(a.h) && is(b.h)) {
// HLS -> HLS
auto h = b.h;
auto l = b.l;
auto s = b.s;
a.h = h;
a.l = l;
a.s = s;
} else static if(is(a.r)) {
// HLS -> RGB
assert(0,"not implemented.");
} else static if(is(b.r)) {
// RGB -> HLS
assert(0,"not implemented.");
}
}
Which should take care of all 3600 combinations of opAssign. is(x.y) is
there just to check for the existence of a field y in x.
Which can be called:
pixAssign(dst,src);
You can also add the following to your PixColor structs:
void opAssign(B)(B b) {
pixAssign(*this,b);
}
Bur, until IFTI is implemented for member functions, you would have to
call it:
c1.opAssign!(typeof(c2))(c2);
And one can always hope, that in the future it will be:
c1 = c2;
> align(1)
> {
> struct PixBGR { ubyte b; ubyte g; ubyte r; mixin PixBGR_Perms!(PixBGR); }
> struct PixBRG { ubyte b; ubyte r; ubyte g; mixin PixBGR_Perms!(PixBRG); }
> struct PixGBR { ubyte g; ubyte b; ubyte r; mixin PixBGR_Perms!(PixGBR); }
> struct PixGRB { ubyte g; ubyte r; ubyte b; mixin PixBGR_Perms!(PixGRB); }
> struct PixRBG { ubyte r; ubyte b; ubyte g; mixin PixBGR_Perms!(PixRBG); }
> struct PixRGB { ubyte r; ubyte g; ubyte b; mixin PixBGR_Perms!(PixRGB); }
> }
You can also make a template that automatically defines your Pix???
types, but I am not sure it is worth it.
alias Pix!(R,G,B) PixRGB;
alias Pix!(R,G,B,A) PixRGBA;
alias Pix!(A,R,G,B) PixARGB;
alias Pix!(H,L,S) PixHLS;
alias Pix!(B,G,R) PixBGR;
alias Pix!(R,B,G) PixRBG;
alias Pix!(B,R,G) PixBRG;
...
/Oskar
More information about the Digitalmars-d-learn
mailing list