How to "extend" built-in types

simendsjo simendsjo at gmail.com
Fri Oct 26 06:55:34 PDT 2012


Not sure if this is a bug or intended behavior:

import std.traits;
struct S {
      int i;
      T opCast(T)() if(isFloatingPoint!T) {
          return cast(T)i;
      }
}

template myIsFloatingPoint(T) {
      enum myIsFloatingPoint =  isFloatingPoint!T
          || __traits(compiles, { cast(real)T.init; });
}

void main() {
      auto s = S(10);
      assert(cast(real)s == 10.0);
      // static assert( isFloatingPoint!S); // false
      static assert( myIsFloatingPoint!S);
      static assert( myIsFloatingPoint!float);
      static assert(!myIsFloatingPoint!int);
}


Think of a Fraction or RangedInt struct for instance:

import std.traits;

struct Ranged(T, T minValue, T maxValue)
      if(isNumeric!T)
{
      enum T max = maxValue;
      enum T min = minValue;
      T value = min;

      invariant() {
          assert(value >= min && value <= max);
      }

      T opCast()() {
          return value;
      }

      void opAssign(T value) {
          this.value = value;
      }

      bool opEquals(T value) {
          return this.value == value;
      }
}

void f(int v) {}

void g(T)(T v) if(isNumeric!T) {
}

void main() {
      Ranged!(int, 10, 20) v;
      assert(v == 10);
      v = 20;
      //v = 21; // assert as expected
      // f(v); // ok if we would use an alias this, but then the
Ranged isn't in effect anymore
      //g(v); // oops.. Ranged is not numeric

}

So.. What do I need to implement for a struct to be a valid
built-in type?
All valid properties (min, max etc) and operators for that type?


More information about the Digitalmars-d-learn mailing list