11
2- using Functors: functor
2+ using Functors: functor, usecache
33
44struct Foo; x; y; end
55@functor Foo
@@ -14,6 +14,7 @@ struct NoChildren2; x; y; end
1414
1515struct NoChild{T}; x:: T ; end
1616
17+
1718# ##
1819# ## Basic functionality
1920# ##
4748 @test (model′. x, model′. y, model′. z) == (1 , 4 , 3 )
4849end
4950
50- @testset " cache " begin
51+ @testset " Sharing " begin
5152 shared = [1 ,2 ,3 ]
5253 m1 = Foo (shared, Foo ([1 ,2 ,3 ], Foo (shared, [1 ,2 ,3 ])))
5354 m1f = fmap (float, m1)
5455 @test m1f. x === m1f. y. y. x
5556 @test m1f. x != = m1f. y. x
5657 m1p = fmapstructure (identity, m1; prune = nothing )
5758 @test m1p == (x = [1 , 2 , 3 ], y = (x = [1 , 2 , 3 ], y = (x = nothing , y = [1 , 2 , 3 ])))
59+ m1no = fmap (float, m1; cache = nothing ) # disable the cache by hand
60+ @test m1no. x != = m1no. y. y. x
5861
59- # A non-leaf node can also be repeated :
62+ # Here "4" is not shared, because Foo isn't leaf :
6063 m2 = Foo (Foo (shared, 4 ), Foo (shared, 4 ))
6164 @test m2. x === m2. y
6265 m2f = fmap (float, m2)
6366 @test m2f. x. x === m2f. y. x
6467 m2p = fmapstructure (identity, m2; prune = Bar (0 ))
65- @test m2p == (x = (x = [1 , 2 , 3 ], y = 4 ), y = Bar ( 0 ))
68+ @test m2p == (x = (x = [1 , 2 , 3 ], y = 4 ), y = (x = Bar {Int64} ( 0 ), y = 4 ))
6669
6770 # Repeated isbits types should not automatically be regarded as shared:
6871 m3 = Foo (Foo (shared, 1 : 3 ), Foo (1 : 3 , shared))
6972 m3p = fmapstructure (identity, m3; prune = 0 )
7073 @test m3p. y. y == 0
71- @test_broken m3p. y. x == 1 : 3
74+ @test m3p. y. x == 1 : 3
75+
76+ # All-isbits trees need not create a cache at all:
77+ m4 = (x= 1 , y= (2 , 3 ), z= 4 : 5 )
78+ @test isbits (fmap (float, m4))
79+ @test_skip 0 == @allocated fmap (float, m4) # true, but fails in tests
80+
81+ # Shared mutable containers are preserved, even if all children are isbits:
82+ ref = Ref (1 )
83+ m5 = (x = ref, y = ref, z = Ref (1 ))
84+ m5f = fmap (x -> x/ 2 , m5)
85+ @test m5f. x === m5f. y
86+ @test m5f. x != = m5f. z
87+
88+ @testset " usecache" begin
89+ d = IdDict ()
90+
91+ # Leaf types:
92+ @test usecache (d, [1 ,2 ])
93+ @test ! usecache (d, 4.0 )
94+ @test usecache (d, NoChild ([1 ,2 ]))
95+ @test ! usecache (d, NoChild ((3 ,4 )))
96+
97+ # Not leaf:
98+ @test usecache (d, Ref (3 )) # mutable container
99+ @test ! usecache (d, (5 , 6.0 ))
100+ @test ! usecache (d, (a = 2pi , b = missing ))
101+
102+ @test ! usecache (d, (5 , [6.0 ]' )) # contains mutable
103+ @test ! usecache (d, (x = [1 ,2 ,3 ], y = 4 ))
104+
105+ usecache (d, OneChild3 ([1 ,2 ], 3 , nothing )) # mutable isn't a child, do we care?
106+
107+ # No dictionary:
108+ @test ! usecache (nothing , [1 ,2 ])
109+ @test ! usecache (nothing , 3 )
110+ end
72111end
73112
74113@testset " functor(typeof(x), y) from @functor" begin
0 commit comments