Here’s something special!
For an upcoming rather large project I want to help myself making the Haxe code more readable.
Since I’m quite used to C data types I’d like to use those too. Unfortunately Haxe just offers me Int, UInt and Float. So I was thinking of using my own C-like data types and even throw an error if I accidentally assign a value that’s out of the range.
Let’s consider int8_t, ranging from -127 to 128.
So far I’ve tried defining an abstract in three ways.
A
/**
signed char (-128 .. 127)
**/
abstract Int8(Int) {
inline public function new(i:Int) {
if (i<-128 || i>127)
{
throw("value exceeds range");
}
this=i;
}
}
B
/**
signed char (-128 .. 127)
**/
abstract Int8(Int) from Int to Int {
}
C
/**
signed char (-128 .. 127)
**/
abstract Int8(Int) {
inline function new(i) this = i;
@:from static function _(i:Int):Int8 {
if (i<-128 || i>127)
{
throw("value exceeds range");
}
return new Int8(i);
}
}
With A, I would need to call the the constructor to get my range check.
So var a:Int8=new Int8(300); would throw an error (as desired) while var a:Int8=300; would work flawlessly.
Using the C approach, my error would be thrown in both cases (though the IDE points me to the throw message in the code, not where the error actually occured) but I’m afraid this method has it’s drawbacks.
Does it instantiate a new instance everytime I assign a different value to the variable?
Method B is just for reference - I won’t use it.
What would be the most elegant solution to achieve my goal?
Furthermore, this data types will be used all across my project - so many classes will be using it. How can I embedd the definition globally? It’s not like a class, is it?