opCast / operator overloading with additional template arguments

Ali Çehreli acehreli at yahoo.com
Mon Jan 11 02:37:24 UTC 2021


On 1/10/21 5:09 PM, Paul wrote:

 > I'll paste more of my file, I hope that's ok.

Not only ok but much appreciated. :)

 >>     T opCast(T)() const if (is(T : Vec!(size, S2), S2)) {

The is expression can be so complicated that I used a different approach 
below. I left notes in capital letters below. Especially cast(S2) looks 
wrong to me:

import std;

version (HoekjeD_Double) {
   private alias standard_accuracy = double;
} else {
   private alias standard_accuracy = float;
}

struct Vec(int size, S = standard_accuracy) {
   // You could add this instead of getting the type from
   // 'content' as in how S2 is aliased in opCast below:
   //
   // alias AccuracyType = S;

   union {
     S[size] content;
     static if (size >= 1) {
       struct {
         S x;
         static if (size >= 2) {
           S y;
           static if (size >= 3) {
             S z;
             static if (size >= 4)
               S w;
           }
         }
       }
     }
   }

   T opCast(T)() const
   // CHANGED:
   if (isInstanceOfVec!T &&
       T.init.content.length == size) {
     // ADDED:
     alias S2 = typeof(T.init.content[0]);
     T converted;
     static foreach (i; 0 .. size)
       // OBSERVATION: Should the cast below be S?
       converted.content[i] = cast(S2) content[i];
     return converted;
   }
}

enum isInstanceOfVec(T) = isInstanceOf!(Vec, T);

void main() {
   auto a = Vec!(42, float)();
   auto b = a.to!(Vec!(42, double));
}

Ali



More information about the Digitalmars-d-learn mailing list