diff --git a/src/spaces/cartesianspace.jl b/src/spaces/cartesianspace.jl index 29eea1b0d..834c6f252 100644 --- a/src/spaces/cartesianspace.jl +++ b/src/spaces/cartesianspace.jl @@ -11,27 +11,31 @@ vector space that is implicitly assumed in most of matrix algebra. """ struct CartesianSpace <: ElementarySpace d::Int + + # required to avoid CartesianSpace(::Any) default constructor: + CartesianSpace(d::Int) = new(d) end + CartesianSpace(d::Integer = 0; dual = false) = CartesianSpace(Int(d)) -function CartesianSpace(dim::Pair; dual = false) - if dim.first === Trivial() - return CartesianSpace(dim.second; dual = dual) - else - msg = "$(dim) is not a valid dimension for CartesianSpace" - throw(SectorMismatch(msg)) - end -end -function CartesianSpace(dims::AbstractDict; kwargs...) - if length(dims) == 0 - return CartesianSpace(0; kwargs...) - elseif length(dims) == 1 - return CartesianSpace(first(dims); kwargs...) - else - msg = "$(dims) is not a valid dimension dictionary for CartesianSpace" - throw(SectorMismatch(msg)) - end +CartesianSpace(dim::Pair; kwargs...) = CartesianSpace((dim,); kwargs...) +function CartesianSpace(dims; dual::Bool = false) + # using manual iteration here to avoid depending on `length` while still checking it is + # 0 ≤ length ≤ 1 + next = Base.iterate(dims) + isnothing(next) && return CartesianSpace(0) + + (c, d), state = next + convert(Trivial, c) === Trivial() || + throw(SectorMismatch(lazy"$c is not a valid charge for CartesianSpace")) + + V = CartesianSpace(d) + + next = Base.iterate(dims, state) + isnothing(next) || + throw(SectorMismatch(lazy"$dims is not a valid dimension iterable for CartesianSpace")) + + return V end -CartesianSpace(g::Base.Generator; kwargs...) = CartesianSpace(g...; kwargs...) # convenience constructor Base.getindex(::RealNumbers) = CartesianSpace diff --git a/src/spaces/complexspace.jl b/src/spaces/complexspace.jl index 01e59f173..b10e8fb0d 100644 --- a/src/spaces/complexspace.jl +++ b/src/spaces/complexspace.jl @@ -11,26 +11,27 @@ struct ComplexSpace <: ElementarySpace d::Int dual::Bool end -ComplexSpace(d::Integer = 0; dual = false) = ComplexSpace(Int(d), dual) -function ComplexSpace(dim::Pair; dual = false) - if dim.first === Trivial() - return ComplexSpace(dim.second; dual = dual) - else - msg = "$(dim) is not a valid dimension for ComplexSpace" - throw(SectorMismatch(msg)) - end -end -function ComplexSpace(dims::AbstractDict; kwargs...) - if length(dims) == 0 - return ComplexSpace(0; kwargs...) - elseif length(dims) == 1 - return ComplexSpace(first(dims); kwargs...) - else - msg = "$(dims) is not a valid dimension dictionary for ComplexSpace" - throw(SectorMismatch(msg)) - end + +ComplexSpace(d::Integer = 0; dual::Bool = false) = ComplexSpace(Int(d), dual) +ComplexSpace(dim::Pair; kwargs...) = ComplexSpace((dim,); kwargs...) +function ComplexSpace(dims; dual::Bool = false) + # using manual iteration here to avoid depending on `length` while still checking it is + # 0 ≤ length ≤ 1 + next = Base.iterate(dims) + isnothing(next) && return ComplexSpace(0, dual) + + (c, d), state = next + convert(Trivial, c) === Trivial() || + throw(SectorMismatch(lazy"$c is not a valid charge for ComplexSpace")) + + V = ComplexSpace(d, dual) + + next = Base.iterate(dims, state) + isnothing(next) || + throw(SectorMismatch(lazy"$dims is not a valid dimension iterable for ComplexSpace")) + + return V end -ComplexSpace(g::Base.Generator; kwargs...) = ComplexSpace(g...; kwargs...) # convenience constructor Base.getindex(::ComplexNumbers) = ComplexSpace