Mercurial > repos > public > sbplib_julia
changeset 719:2f8c67c5979e feature/static_dict
Start adding a StaticDict type
author | Jonatan Werpers <jonatan@werpers.com> |
---|---|
date | Tue, 16 Mar 2021 17:28:40 +0100 |
parents | 05d8ea88c690 |
children | 172c55c4cf2e |
files | src/Sbplib.jl src/StaticDicts/StaticDicts.jl test/testStaticDicts.jl |
diffstat | 3 files changed, 95 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/src/Sbplib.jl Fri Mar 12 19:55:39 2021 +0100 +++ b/src/Sbplib.jl Tue Mar 16 17:28:40 2021 +0100 @@ -1,5 +1,6 @@ module Sbplib +include("StaticDicts/StaticDicts.jl") include("RegionIndices/RegionIndices.jl") include("LazyTensors/LazyTensors.jl") include("Grids/Grids.jl")
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/StaticDicts/StaticDicts.jl Tue Mar 16 17:28:40 2021 +0100 @@ -0,0 +1,52 @@ +module StaticDicts + +export StaticDict + +# Vidar 2021-02-27 +#NOTE: This type was added since ==-comparison of structs containing +# Dict (even Base.ImmutableDict) fails even though the fields satisfy +# ==-comparison. This is due to the fact that === is called for Dict-fields. +# See https://github.com/JuliaLang/julia/issues/4648. If the PR gets resolved +# we should consider removing StaticDict. +""" + StaticDict{K,V,N}(NTuple{N,Pair{K,V}}) + +A simple static dictonary. Performs lookup using linear search with ==-comparison +of keys. No hashing is used. +""" +struct StaticDict{K,V,N} <: AbstractDict{K,V} + pairs::NTuple{N,Pair{K,V}} +end + +function StaticDict(pairs::Vararg{Pair}) + K = typejoin(firsttype.(pairs)...) + V = typejoin(secondtype.(pairs)...) + N = length(pairs) + return StaticDict{K,V,N}(pairs) +end + +function Base.get(d::StaticDict, key, default) + for p ∈ d.pairs # TBD: Is this the best? Should we use the iterator on `d`? + if key == p.first + return p.second + end + end + + return default +end + +firsttype(::Pair{T1,T2}) where {T1,T2} = T1 +secondtype(::Pair{T1,T2}) where {T1,T2} = T2 + +Base.iterate(d::StaticDict) = iterate(d.pairs) +Base.iterate(d::StaticDict, state) = iterate(d.pairs,state) + +Base.length(d::StaticDict) = length(d.pairs) + + +# TODO documentation: duplicate keys not allowed atm. will error +function Base.merge(d1::StaticDict, d2::StaticDict) + return StaticDict(d1.pairs..., d2.pairs...) +end + +end # module
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/testStaticDicts.jl Tue Mar 16 17:28:40 2021 +0100 @@ -0,0 +1,42 @@ +using Test +using Sbplib.StaticDicts + +@testset "StaticDicts" begin + +@testset "StaticDict" begin + @testset "constructor" begin + @test (StaticDict{Int,Int,N} where N) <: AbstractDict + + d = StaticDict(1=>2, 3=>4) + @test d isa StaticDict{Int,Int} + @test d[1] == 2 + @test d[3] == 4 + + @test StaticDict(1=>3, 2=>4.) isa StaticDict{Int,Real} + @test StaticDict(1. =>3, 2=>4) isa StaticDict{Real,Int} + @test StaticDict(1. =>3, 2=>4.) isa StaticDict{Real,Real} + end + + @testset "equality" begin + @test StaticDict(1=>1) == StaticDict(1=>1) # This is not true for the regular Dict + end + + @testset "get" begin + d = StaticDict(1=>2, 3=>4) + + @test get(d,1,6) == 2 + @test get(d,3,6) == 4 + @test get(d,5,6) == 6 + end + + @testset "merge" begin + @test merge( + StaticDict(1=>3, 2=> 4), + StaticDict(3=>5,4=>6)) == StaticDict( + 1=>3, 2=>4, 3=>5, 4=>6 + ) + @test_broken merge(d,d) == d # Should this be valid? + end +end + +end