Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove duplication #8

Merged
merged 1 commit into from
Mar 12, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 36 additions & 63 deletions src/DispatchedTuples.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,33 @@ dispatched tuples.
"""
abstract type AbstractDispatchedTuple{T <: Tuple, D} end

unwrap_pair(tup) = eltype(tup) <: Pair ?
map(x->(x.first, x.second), tup) : tup

function match_expr(dt, TT, T)
expr = quote tuple() end
found_match = false
for (i,k) in enumerate(fieldnames(TT))
if first_eltype(fieldtype(TT, i)) == T
found_match = true
push!(expr.args[2].args, :(dt.tup[$i][2]))
end
end
return expr, found_match
end

function match_expr_val(dt, TT, T)
match_count = 0
expr = quote end
for (i,k) in enumerate(fieldnames(TT))
if first_eltype(fieldtype(TT, i)) == T
match_count += 1
expr = :(dt.tup[$i][2])
end
end
return expr, match_count
end

#####
##### DispatchedTuple
#####
Expand Down Expand Up @@ -48,11 +75,7 @@ struct DispatchedTuple{T,D} <: AbstractDispatchedTuple{T, D}
tup::T
default::D
function DispatchedTuple(tup_in::T, default=NoDefaults()) where {T<:Tuple}
if eltype(tup_in) <: Pair
tup = map(x->(x.first, x.second), tup_in)
else
tup = tup_in
end
tup = unwrap_pair(tup_in)
return new{typeof(tup), typeof(default)}(tup, default)
end
end
Expand All @@ -64,14 +87,7 @@ Dispatch on the [`DispatchedTuple`](@ref), based
on the instance of the input type `type_instance`.
"""
@generated function dispatch(dt::DispatchedTuple{TT, NoDefaults}, ::T) where {TT, T}
expr = quote tuple() end
found_match = false
for (i,k) in enumerate(fieldnames(TT))
if first_eltype(fieldtype(TT, i)) == T
found_match = true
push!(expr.args[2].args, :(dt.tup[$i][2]))
end
end
expr, found_match = match_expr(dt, TT, T)
if !found_match
expr = quote end
push!(expr.args, :(throw(error("No method dispatch defined for type $T"))))
Expand All @@ -80,14 +96,7 @@ on the instance of the input type `type_instance`.
end

@generated function dispatch(dt::DispatchedTuple{TT,D}, ::T) where {TT, D, T}
expr = quote tuple() end
found_match = false
for (i,k) in enumerate(fieldnames(TT))
if first_eltype(fieldtype(TT, i)) == T
found_match = true
push!(expr.args[2].args, :(dt.tup[$i][2]))
end
end
expr, found_match = match_expr(dt, TT, T)
if !found_match
push!(expr.args[2].args, :(dt.default))
end
Expand All @@ -110,11 +119,7 @@ struct DispatchedTupleSet{T,D} <: AbstractDispatchedTuple{T, D}
tup::T
default::D
function DispatchedTupleSet(tup_in::T, default=NoDefaults()) where {T<:Tuple}
if eltype(tup_in) <: Pair
tup = map(x->(x.first, x.second), tup_in)
else
tup = tup_in
end
tup = unwrap_pair(tup_in)
return new{typeof(tup), typeof(default)}(tup, default)
end
end
Expand All @@ -126,14 +131,7 @@ Dispatch on the [`DispatchedTupleSet`](@ref), based
on the instance of the input type `type_instance`.
"""
@generated function dispatch(dt::DispatchedTupleSet{TT, NoDefaults}, ::T) where {TT, T}
match_count = 0
expr = quote end
for (i,k) in enumerate(fieldnames(TT))
if first_eltype(fieldtype(TT, i)) == T
match_count += 1
expr = :(dt.tup[$i][2])
end
end
expr, match_count = match_expr_val(dt, TT, T)
if match_count == 0
return :(throw(error("No method dispatch defined for type $T")))
elseif match_count > 1
Expand All @@ -144,14 +142,7 @@ on the instance of the input type `type_instance`.
end

@generated function dispatch(dt::DispatchedTupleSet{TT,D}, ::T) where {TT, D, T}
match_count = 0
expr = quote end
for (i,k) in enumerate(fieldnames(TT))
if first_eltype(fieldtype(TT, i)) == T
match_count += 1
expr = :(dt.tup[$i][2])
end
end
expr, match_count = match_expr_val(dt, TT, T)
if match_count == 0
return :(dt.default)
elseif match_count > 1
Expand All @@ -176,11 +167,7 @@ struct DispatchedTupleDict{T,D} <: AbstractDispatchedTuple{T, D}
tup::T
default::D
function DispatchedTupleDict(tup_in::T, default=NoDefaults()) where {T<:Tuple}
if eltype(tup_in) <: Pair
tup = map(x->(x.first, x.second), tup_in)
else
tup = tup_in
end
tup = unwrap_pair(tup_in)
return new{typeof(tup), typeof(default)}(tup, default)
end
end
Expand All @@ -192,29 +179,15 @@ Dispatch on the [`DispatchedTupleDict`](@ref), based
on the instance of the input type `type_instance`.
"""
@generated function dispatch(dt::DispatchedTupleDict{TT, NoDefaults}, ::T) where {TT, T}
match_count = 0
expr = quote end
for (i,k) in enumerate(fieldnames(TT))
if first_eltype(fieldtype(TT, i)) == T
match_count += 1
expr = :(dt.tup[$i][2])
end
end
expr, match_count = match_expr_val(dt, TT, T)
if match_count == 0
push!(expr.args, :(throw(error("No method dispatch defined for type $T"))))
end
return expr
end

@generated function dispatch(dt::DispatchedTupleDict{TT,D}, ::T) where {TT, D, T}
match_count = 0
expr = quote end
for (i,k) in enumerate(fieldnames(TT))
if first_eltype(fieldtype(TT, i)) == T
match_count += 1
expr = :(dt.tup[$i][2])
end
end
expr, match_count = match_expr_val(dt, TT, T)
if match_count == 0
return :(dt.default)
else
Expand Down