From 7367922a57cf8fc3e3b7a20157281b6f313d82da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20H=C3=A4cker?= Date: Thu, 10 Sep 2026 04:59:46 +0200 Subject: [PATCH] Create BitIntegers package extension for cross-conversions between types --- Project.toml | 7 +++++++ README.md | 9 +++++++++ ext/BitIntegersExt.jl | 8 ++++++++ test/bitintegers.jl | 24 ++++++++++++++++++++++++ test/runtests.jl | 1 + 5 files changed, 49 insertions(+) create mode 100644 ext/BitIntegersExt.jl create mode 100644 test/bitintegers.jl diff --git a/Project.toml b/Project.toml index bf6397c..4264028 100644 --- a/Project.toml +++ b/Project.toml @@ -10,7 +10,14 @@ projects = ["test"] PrecompileTools = "aea7be01-6a6a-4083-8856-8a6e6704d82a" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +[weakdeps] +BitIntegers = "c3b6d118-76ef-56ca-8cc7-ebb389d030a1" + +[extensions] +BitIntegersExt = "BitIntegers" + [compat] +BitIntegers = "0.3" PrecompileTools = "1" Random = "1" julia = "1.10" diff --git a/README.md b/README.md index acabfd4..028c2db 100644 --- a/README.md +++ b/README.md @@ -128,6 +128,15 @@ const Int7_8 = Int7 The signedness of data and storage types are always identical. +When both packages are loaded, a package extension enables checked conversion +from emulated integers to BitIntegers types, including user-defined types from +`@define_integers`. + +```jldoctest usage +julia> Int256(UInt3(7)) +7 +``` + If you want to `@emulate` multiple types, you can simply provide multiple arguments to the macro with regular macro syntax: ```jldoctest usage diff --git a/ext/BitIntegersExt.jl b/ext/BitIntegersExt.jl new file mode 100644 index 0000000..cc01cf1 --- /dev/null +++ b/ext/BitIntegersExt.jl @@ -0,0 +1,8 @@ +module BitIntegersExt + +using EmulatedBitIntegers: EmulatedInteger +using BitIntegers: AbstractBitSigned, AbstractBitUnsigned + +(::Type{Target})(value::EmulatedInteger) where {Target<:Union{AbstractBitSigned, AbstractBitUnsigned}} = Target(value[]) + +end \ No newline at end of file diff --git a/test/bitintegers.jl b/test/bitintegers.jl new file mode 100644 index 0000000..86c64f6 --- /dev/null +++ b/test/bitintegers.jl @@ -0,0 +1,24 @@ +@define_integers 24 ConversionInt24 ConversionUInt24 + +@testset "BitIntegers conversion" begin + @emulate Int3 UInt3 Int3_128 UInt3_128 Int129 UInt129 + + for Source in (Int3, UInt3, Int3_128, UInt3_128, Int129, UInt129) + for Target in (Int256, UInt256, Int512, UInt512, Int1024, UInt1024, ConversionInt24, ConversionUInt24) + for value in (typemin(Source), zero(Source), one(Source), typemax(Source)) + if typemin(Target) <= BigInt(value[]) <= typemax(Target) + expected = Target(value[]) + @test (@inferred Target(value)) === expected + @test (@inferred convert(Target, value)) === expected + else + @test_throws InexactError Target(value) + @test_throws InexactError convert(Target, value) + end + end + end + end + + @test Int256(Int3(1)) === Int256(1) + extension = Base.get_extension(EmulatedBitIntegers, :BitIntegersExt) + @test isempty(Test.detect_ambiguities(EmulatedBitIntegers, BitIntegers, extension)) +end \ No newline at end of file diff --git a/test/runtests.jl b/test/runtests.jl index e81fac2..edeffaa 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -18,6 +18,7 @@ values(x) = x |> fieldvalues |> collect include("comparisons.jl") include("sums.jl") include("broadcasting.jl") +include("bitintegers.jl") # ============================================================================ # Static analysis