Questions about opAssign alternate and template quality

Oskar Linde oskar.lindeREM at
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:


You can also add the following to your PixColor structs:

	void opAssign(B)(B b) {

Bur, until IFTI is implemented for member functions, you would have to 
call it:


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;


More information about the Digitalmars-d-learn mailing list