-module(ranged_int@builtin@uint). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([to_bigint/1, from_bigint/1, compare/2, add/2, subtract/2, multiply/2, divide/2, modulo/2, remainder/2, power/2, eject/1]). -export_type([uint/0]). -opaque uint() :: {uint, bigi:big_int()}. -spec to_bigint(uint()) -> bigi:big_int(). to_bigint(Uint) -> erlang:element(2, Uint). -spec from_bigint_unsafe(bigi:big_int()) -> uint(). from_bigint_unsafe(Value) -> {uint, Value}. -spec limits() -> ranged_int@interface:limits(ranged_int@interface:non_overflowable()). limits() -> ranged_int@interface:min_limit(bigi_ffi:from(0)). -spec from_bigint(bigi:big_int()) -> {ok, uint()} | {error, ranged_int@utils:overflow()}. from_bigint(Value) -> ranged_int@interface:from_bigint( Value, {interface, fun to_bigint/1, fun from_bigint_unsafe/1, fun limits/0} ). -spec compare(uint(), uint()) -> gleam@order:order(). compare(A, B) -> ranged_int@interface:compare( A, B, {interface, fun to_bigint/1, fun from_bigint_unsafe/1, fun limits/0} ). -spec add(uint(), bigi:big_int()) -> {ok, uint()} | {error, ranged_int@utils:overflow()}. add(A, B) -> ranged_int@interface:math_op( A, B, {interface, fun to_bigint/1, fun from_bigint_unsafe/1, fun limits/0}, fun bigi_ffi:add/2 ). -spec subtract(uint(), bigi:big_int()) -> {ok, uint()} | {error, ranged_int@utils:overflow()}. subtract(A, B) -> ranged_int@interface:math_op( A, B, {interface, fun to_bigint/1, fun from_bigint_unsafe/1, fun limits/0}, fun bigi_ffi:subtract/2 ). -spec multiply(uint(), bigi:big_int()) -> {ok, uint()} | {error, ranged_int@utils:overflow()}. multiply(A, B) -> ranged_int@interface:math_op( A, B, {interface, fun to_bigint/1, fun from_bigint_unsafe/1, fun limits/0}, fun bigi_ffi:multiply/2 ). -spec divide(uint(), bigi:big_int()) -> {ok, uint()} | {error, ranged_int@utils:overflow()}. divide(A, B) -> ranged_int@interface:math_op( A, B, {interface, fun to_bigint/1, fun from_bigint_unsafe/1, fun limits/0}, fun bigi_ffi:divide/2 ). -spec modulo(uint(), bigi:big_int()) -> {ok, uint()} | {error, ranged_int@utils:overflow()}. modulo(A, B) -> ranged_int@interface:math_op( A, B, {interface, fun to_bigint/1, fun from_bigint_unsafe/1, fun limits/0}, fun bigi_ffi:modulo/2 ). -spec remainder(uint(), bigi:big_int()) -> {ok, uint()} | {error, ranged_int@utils:overflow()}. remainder(A, B) -> ranged_int@interface:math_op( A, B, {interface, fun to_bigint/1, fun from_bigint_unsafe/1, fun limits/0}, fun bigi_ffi:remainder/2 ). -spec power(uint(), uint()) -> {ok, uint()} | {error, ranged_int@utils:overflow()}. power(A, B) -> _assert_subject = ranged_int@interface:fallible_op( A, to_bigint(B), {interface, fun to_bigint/1, fun from_bigint_unsafe/1, fun limits/0}, fun bigi_ffi:power/2 ), {ok, Result} = case _assert_subject of {ok, _} -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail, module => <<"ranged_int/builtin/uint"/utf8>>, function => <<"power"/utf8>>, line => 55}) end, Result. -spec eject({ok, uint()} | {error, ranged_int@utils:overflow()}) -> bigi:big_int(). eject(Op) -> ranged_int@interface:eject( Op, {interface, fun to_bigint/1, fun from_bigint_unsafe/1, fun limits/0} ).