Packages

Type safe ranged integer operations for Gleam.

Current section

Files

Jump to
ranged_int src ranged_int@internal@limit.erl
Raw

src/ranged_int@internal@limit.erl

-module(ranged_int@internal@limit).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([check_limits/3]).
-export_type([limit/0, limit_check/0]).
-type limit() :: {bounded, bigi:big_int()} | unbounded.
-type limit_check() :: no_overflow |
{overflow, bigi:big_int()} |
{underflow, bigi:big_int()}.
-spec diff(limit(), bigi:big_int()) -> bigi:big_int().
diff(Limit, Value) ->
case Limit of
unbounded ->
bigi_ffi:zero();
{bounded, Lim} ->
bigi_ffi:subtract(Value, Lim)
end.
-spec check_limits(bigi:big_int(), limit(), limit()) -> limit_check().
check_limits(Value, Min, Max) ->
Max_diff = diff(Max, Value),
case bigi_ffi:compare(bigi_ffi:zero(), Max_diff) of
gt ->
{overflow, Max_diff};
eq ->
Min_diff = diff(Min, Value),
case bigi_ffi:compare(bigi_ffi:zero(), Min_diff) of
lt ->
{underflow, bigi_ffi:multiply(Min_diff, bigi_ffi:from(-1))};
eq ->
no_overflow;
gt ->
no_overflow
end;
lt ->
Min_diff = diff(Min, Value),
case bigi_ffi:compare(bigi_ffi:zero(), Min_diff) of
lt ->
{underflow, bigi_ffi:multiply(Min_diff, bigi_ffi:from(-1))};
eq ->
no_overflow;
gt ->
no_overflow
end
end.