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