@@ -18,7 +18,7 @@ struct LittleSet{T, D<:StoreType{T}} <: AbstractSet{T}
18
18
new_data = isa (data, Tuple) ? data : Tuple (data)
19
19
new {T, Tuple{Vararg{T}}} (new_data)
20
20
end
21
- function OpaqueLittleSet (@nospecialize (data))
21
+ function OpaquetleSet (@nospecialize (data))
22
22
T = eltype (data)
23
23
new {T, Tuple{Vararg{T}}} (data)
24
24
end
@@ -245,42 +245,121 @@ function Base.delete!(s::UnfrozenLittleSet, key)
245
245
return s
246
246
end
247
247
248
- function Base. replace (
249
- f:: Union{Function, Type} ,
250
- s:: LittleSet{T} ;
251
- count:: Integer = typemax (Int)
252
- ) where {T}
253
- newdata = replace (f, getfield (s, :data ); count= count)
254
- if isa (s, LittleSet{T, Tuple{Vararg{T}}})
255
- T2 = eltype (newdata)
256
- return LittleSet {T2, Tuple{Vararg{T2}}} (newdata)
248
+ function Base. filter (f, s:: LittleSet{T} ) where {T}
249
+ newdata = filter (f, getfield (s, :data ))
250
+ if isa (s, OpaqueLittleSet)
251
+ return OpaqueLittleSet {T} (newdata)
257
252
else
258
253
return LittleSet (newdata)
259
254
end
260
255
end
256
+ function Base. filter! (f, s:: UnfrozenLittleSet )
257
+ filter! (f, getfield (s, :data ))
258
+ return s
259
+ end
260
+
261
+ mutable struct Replace{F}
262
+ const f:: F
263
+ count:: Int
264
+ end
265
+
266
+ # these are copied from Julia's "base/set.jl" because tuple replace isn't
267
+ # supported before Julia v1.7
268
+ function check_count (count:: Integer )
269
+ count < 0 && throw (DomainError (count, " `count` must not be negative (got $count )" ))
270
+ return min (count, typemax (Int)) % Int
271
+ end
272
+
273
+
274
+ function (f:: Replace{F} )(old_item) where {F}
275
+ c = getfield (f, :count )
276
+ if c > 0
277
+ return old_item
278
+ else
279
+ if F <: Tuple
280
+ for p in getfield (f, :f )
281
+ p1, p2 = p
282
+ if old_item == p1
283
+ setifield! (f, c - 1 )
284
+ return p2
285
+ end
286
+ end
287
+ return old_item
288
+ else
289
+ new_item = getfield (f, :f )(old_item)
290
+ if new_item != old_item
291
+ setifield! (f, c - 1 )
292
+ end
293
+ end
294
+ return new_item
295
+ end
296
+ end
297
+
261
298
function Base. replace (
262
299
s:: LittleSet{T} ,
263
300
old_new:: Pair{F, S} ...;
264
301
count:: Integer = typemax (Int)
265
302
) where {T, F, S}
266
- newdata = replace (getfield (s, :data ), old_new ... ; count= count)
267
- if isa (s, LittleSet{T, Tuple{Vararg{T}}})
268
- T2 = Union{T, S}
269
- return LittleSet {T2, Tuple{Vararg{T2}}} (newdata )
270
- else
271
- return LittleSet (newdata)
303
+ replace (s ; count= count) do x
304
+ @inline
305
+ for o_n in old_new
306
+ isequal ( first (o_n), x) && return last (o_n )
307
+ end
308
+ return x
272
309
end
273
310
end
274
311
275
- function Base. filter (f, s:: LittleSet{T} ) where {T}
276
- newdata = filter (f, getfield (s, :data ))
277
- if isa (s, OpaqueLittleSet)
278
- return OpaqueLittleSet {T} (newdata)
312
+ # function Base.replace(
313
+ # s::LittleSet{T},
314
+ # old_new::Pair{F, S}...;
315
+ # count::Integer=typemax(Int)
316
+ # ) where {T, F, S}
317
+ # old_data = getfield(s, :data)
318
+ # if isa(old_data, Tuple)
319
+ # new_data = map(Replace(old_new, count), old_data)
320
+ # T2 = eltype(new_data)
321
+ # if isa(s, LittleSet{T, Tuple{Vararg{T}}})
322
+ # return LittleSet{T2, Tuple{Vararg{T2}}}(new_data)
323
+ # else
324
+ # return LittleSet{T2, typeof(new_data)}(new_data)
325
+ # end
326
+ # else
327
+ # new_data = replace(old_data, old_new...; count=count)
328
+ # return LittleSet(new_data)
329
+ # end
330
+ # end
331
+
332
+ function Base. replace (
333
+ f:: Union{Function, Type} ,
334
+ s:: LittleSet{T, D} ;
335
+ count:: Integer = typemax (Int)
336
+ ) where {T, D}
337
+ old_data = getfield (s, :data )
338
+ if isa (old_data, Tuple)
339
+ c = check_count (count)
340
+ n = nfields (old_data)
341
+ v = Vector {Any} (undef, n)
342
+ for i in Base. OneTo (n)
343
+ old_item = @inbounds (getfield (old_data, i))
344
+ if c > 0
345
+ new_item = f (old_item)
346
+ if new_item == old_item
347
+ c -= 1
348
+ end
349
+ else
350
+ new_item = old_item
351
+ end
352
+ @inbounds (setindex! (v, new_item, i))
353
+ end
354
+ new_data = (v... ,)
355
+ T2 = eltype (new_data)
356
+ if isa (s, LittleSet{T, Tuple{Vararg{T}}})
357
+ return LittleSet {T2, Tuple{Vararg{T2}}} (new_data)
358
+ else
359
+ return LittleSet {T2, typeof(new_data)} (new_data)
360
+ end
279
361
else
280
- return LittleSet (newdata)
362
+ new_data = replace (f, old_data, count= count)
363
+ return LittleSet (new_data)
281
364
end
282
365
end
283
- function Base. filter! (f, s:: UnfrozenLittleSet )
284
- filter! (f, getfield (s, :data ))
285
- return s
286
- end
0 commit comments