study: use checkedint as a drop-in replacement of native long

H. S. Teoh hsteoh at
Sat Aug 15 05:17:58 UTC 2020

More thoughts:

On Sat, Aug 15, 2020 at 04:28:05AM +0000, mw via Digitalmars-d wrote:
>   // 2. have to use .get to call math func
>   writeln(std.math.sgn(la));
>   writeln(std.math.abs(la));
> //writeln(std.math.sgn(ca));  // Error: template std.math.sgn cannot deduce
> function from argument types !()(Checked!(long, Abort)), candidates are:
> //writeln(std.math.abs(ca));  // Error: template instance
> std.math.abs!(Checked!(long, Abort)) error instantiating
>   writeln(std.math.sgn(ca.get));  // need .get
>   writeln(std.math.abs(ca.get));  // need .get

Technically you *could* use `alias this` to decay it to long
automatically, then these calls will work. But (1) that runs the risk of
implicit conversion accidentally losing the guarantees of Checked when
it silently turns into an unwrapped long, thereby defeating the purpose
of using Checked; and (2) `alias this` is frowned upon these days
because of its complicated relationship with subtyping.

One workaround is to write forwarding overloads for these functions as
member functions of Checked.  But this is D, and we dislike boilerplate,
so opDispatch comes to the rescue:

	struct Checked {
		auto opDispatch(string memb)(Checked arg)
			if (memb == "sgn" || memb == "abs" || ... /* etc */)
			return mixin(memb ~ "(this.get)");

The bad thing is that you have to manually list the functions. But if
then, you could import std.math and use introspection to extract the
list of functions automatically.  Good opportunity to take advantage of
D's metaprogramming capabilities.  Start with `__traits(allMembers,
std.math)` and go from there.


Why is it that all of the instruments seeking intelligent life in the
universe are pointed away from Earth? -- Michael Beibl

More information about the Digitalmars-d mailing list