@@ -43,6 +43,7 @@ c = BB.c
43
43
module Parameters
44
44
import Base: @__doc__
45
45
import OrderedCollections: OrderedDict
46
+ using UnPack: @unpack , @pack!
46
47
47
48
export @with_kw , @with_kw_noshow , type2dict, reconstruct, @unpack , @pack! , @pack
48
49
@@ -656,154 +657,4 @@ macro with_kw_noshow(typedef)
656
657
return esc (with_kw (typedef, __module__, false ))
657
658
end
658
659
659
-
660
- # ##########################
661
- # Packing and unpacking @unpack, @pack!
662
- # #########################
663
- # Below code slightly adapted from Simon Danisch's GLVisualize via PR
664
- # https://github.com/mauro3/Parameters.jl/pull/13
665
-
666
- """
667
- This function is invoked to unpack one field/entry of some DataType
668
- `dt` and has signature:
669
-
670
- `unpack(dt::Any, ::Val{property}) -> value of property`
671
-
672
- The `property` is the symbol of the assigned variable.
673
-
674
- Three definitions are included in the package to unpack a composite type
675
- or a dictionary with Symbol or string keys:
676
- ```
677
- @inline unpack(x, ::Val{f}) where {f} = getproperty(x, f)
678
- @inline unpack(x::AbstractDict{Symbol}, ::Val{k}) where {k} = x[k]
679
- @inline unpack(x::AbstractDict{S}, ::Val{k}) where {S<:AbstractString,k} = x[string(k)]
680
- ```
681
-
682
- More methods can be added to allow for specialized unpacking of other datatypes.
683
-
684
- See also `pack!`.
685
- """
686
- function unpack end
687
- @inline unpack (x, :: Val{f} ) where {f} = getproperty (x, f)
688
- @inline unpack (x:: AbstractDict{Symbol} , :: Val{k} ) where {k} = x[k]
689
- @inline unpack (x:: AbstractDict{<:AbstractString} , :: Val{k} ) where {k} = x[string (k)]
690
-
691
- """
692
- This function is invoked to pack one entity into some DataType and has
693
- signature:
694
-
695
- `pack!(dt::Any, ::Val{property}, value) -> value`
696
-
697
- Two definitions are included in the package to pack into a composite
698
- type or into a dictionary with Symbol or string keys:
699
-
700
- ```
701
- @inline pack!(x, ::Val{f}, val) where {f} = setproperty!(x, f, val)
702
- @inline pack!(x::AbstractDict{Symbol}, ::Val{k}, val) where {k} = x[k]=val
703
- @inline pack!(x::AbstractDict{S}, ::Val{k}, val) where {S<:AbstractString,k} = x[string(k)]=val
704
- ```
705
-
706
- More methods can be added to allow for specialized packing of other
707
- datatypes.
708
-
709
- See also `unpack`.
710
- """
711
- function pack! end
712
- @inline pack! (x, :: Val{f} , val) where {f} = setproperty! (x, f, val)
713
- @inline pack! (x:: AbstractDict{Symbol} , :: Val{k} , val) where {k} = x[k]= val
714
- @inline pack! (x:: AbstractDict{<:AbstractString} , :: Val{k} , val) where {k} = x[string (k)]= val
715
-
716
- """
717
- Unpacks fields/properties/keys from a composite type, a `Dict{Symbol}`, a `Dict{String}`,
718
- or a module into variables
719
- ```julia_skip
720
- @unpack a, b, c = dict_or_typeinstance
721
- ```
722
-
723
- Example with dict:
724
- ```julia
725
- d = Dict{Symbol,Any}(:a=>5.0,:b=>2,:c=>"Hi!")
726
- @unpack a, c = d
727
- a == 5.0 #true
728
- c == "Hi!" #true
729
- ```
730
-
731
- Example with type:
732
- ```julia
733
- struct A; a; b; c; end
734
- d = A(4,7.0,"Hi")
735
- @unpack a, c = d
736
- a == 4 #true
737
- c == "Hi" #true
738
- ```
739
-
740
- Note that its functionality can be extende by adding methods to the
741
- `Parameters.unpack` function.
742
- """
743
- macro unpack (args)
744
- args. head!= :(= ) && error (" Expression needs to be of form `a, b = c`" )
745
- items, suitecase = args. args
746
- items = isa (items, Symbol) ? [items] : items. args
747
- suitecase_instance = gensym ()
748
- kd = [:( $ key = $ Parameters. unpack ($ suitecase_instance, Val {$(Expr(:quote, key))} ()) ) for key in items]
749
- kdblock = Expr (:block , kd... )
750
- expr = quote
751
- $ suitecase_instance = $ suitecase # handles if suitecase is not a variable but an expression
752
- $ kdblock
753
- $ suitecase_instance # return RHS of `=` as standard in Julia
754
- end
755
- esc (expr)
756
- end
757
-
758
-
759
- """
760
- Packs variables into a mutable, composite type, a `Dict{Symbol}`, or a `Dict{String}`
761
- ```julia_skip
762
- @pack! dict_or_typeinstance = a, b, c
763
- ```
764
-
765
- Example with dict:
766
- ```julia
767
- a = 5.0
768
- c = "Hi!"
769
- d = Dict{Symbol,Any}()
770
- @pack! d = a, c
771
- d # Dict{Symbol,Any}(:a=>5.0,:c=>"Hi!")
772
- ```
773
-
774
- Example with type:
775
- ```julia
776
- a = 99
777
- c = "HaHa"
778
- mutable struct A; a; b; c; end
779
- d = A(4,7.0,"Hi")
780
- @pack! d = a, c
781
- d.a == 99 #true
782
- d.c == "HaHa" #true
783
- ```
784
-
785
- Note that its functionality can be extende by adding methods to the
786
- `Parameters.pack!` function.
787
- """
788
- macro pack! (args)
789
- esc (_pack_bang (args))
790
- end
791
-
792
- function _pack_bang (args)
793
- args. head!= :(= ) && error (" Expression needs to be in the form of an assignment." )
794
- suitecase, items = args. args
795
- items = isa (items, Symbol) ? [items] : items. args
796
- suitecase_instance = gensym ()
797
- kd = [:( $ Parameters. pack! ($ suitecase_instance, Val {$(Expr(:quote, key))} (), $ key) ) for key in items]
798
- kdblock = Expr (:block , kd... )
799
- return quote
800
- $ suitecase_instance = $ suitecase # handles if suitecase is not a variable but an expression
801
- $ kdblock
802
- ($ (items... ),)
803
- end
804
- end
805
-
806
- # TODO : maybe add @pack_new for packing into a new instance. Could be
807
- # used with immutables also.
808
-
809
660
end # module
0 commit comments