I think it might be necessary to have some way of passing "out of band" state to the library, and this would definitely need to be thread-safe.
The exception I commented on earlier appears to be caused by overflow checks being enabled at the project level, so when Int128 was compiled with overflow checks enabled at the project level mandatory exceptions were built in: they can't be disabled by {$q- } at the point of invocation.
So while for operands of <= 64 bits this works:
for i := 1 to Length(pp) do begin
{$push }
{$rangechecks off}
{$overflowchecks off }
result := result + Ord(pp[i]);
result *= alphabetPrime
{$pop }
end;
it's ineffective for 128-bit operands.
That implies that it would be useful to have something like PushChecks and PopChecks procedures, plus CheckOverflow and possibly something like CompilerMode so that a caller could tell the library how the mod operator should behave.
Also I think it would be desirable if all exception messages were distinct, even if they were only distinguished by (a), (b) and so on.
raise EIntOverflow.create( 'multiply tUInt128 by UInt64' ); // <=====
end else begin
Carry := UMul128by64L( Temp, O1, q );
if( Carry>0 ) then begin
raise EIntOverflow.create( 'multiply tUInt128 by UInt64' ); // <=====
If even a trivial change had been made to the library since it was last compiled, the exception address could easily be out of step with reality.
Let me try to tackle your feedback - not neccessarily in the order given above
- distinguished error messages <= count on me implementing that
- yes, if you compiled the library with range & overflow checks enabled there currently is no way to avoid them becoming active in case.
- issue is, the lib is a compound object and many of it's operations will not be inlined into the invocation
- You surely could compile the lib without checks enabled, but then loose these on all operations - which I understand is not desired
- the only way around this and support local enable / disable at invocation level is the installation of a thread save execution state var in the lib
- together with getter/setter functions and a dispatch to operation variants with / without checks this would probably address your requirements
- however this is a major rework and it will slow down execution speed, so I might have to put a way on top of this for those who don't care
- all doable, but not in short time frame - and I'd need independent testers. Would you stay in this?
- the handling of div, mod, divmod etc. is simpler I think - I can install a compile time switch that controls the code generation towards variant A or B
That's my shot from the hip.
Cheers,
MathMan
PS - there might be a better alternative - what do you think about the following
- implement a checked and unchecked type variant and extend the operator overloading accordingly
- if you want to disable checks on the invocation level then you can use the unchecked type for calculations