forked from JuliaLang/julia
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathintset.j
87 lines (76 loc) · 1.77 KB
/
intset.j
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
type IntSet
bits::Array{Uint32,1}
limit::Int32 # todo: should be Int64
IntSet() = IntSet(1024)
IntSet(max::Int32) = (lim = (max+31) & -32;
new(zeros(Uint32,lim>>5), lim))
end
function intset(args...)
s = IntSet()
for i = args
add(s, i)
end
s
end
function add(s::IntSet, n::Int)
if n >= s.limit
lim = int32(n + div(n,2))
olsz = length(s.bits)
newbits = Array(Uint32,(lim+31)>>5)
newbits[1:olsz] = s.bits
for i=(olsz+1):length(newbits); newbits[i] = 0; end
s.bits = newbits
s.limit = lim
end
s.bits[n>>5 + 1] |= (1<<(n&31))
s
end
function del(s::IntSet, n::Int)
if n < s.limit
s.bits[n>>5 + 1] &= ~(1<<(n&31))
end
s
end
function del_all(s::IntSet)
s.bits[:] = 0
s
end
function has(s::IntSet, n::Int)
if n >= s.limit
false
else
(s.bits[n>>5 + 1] & (1<<(n&31))) != 0
end
end
start(s::IntSet) = 0
done(s::IntSet, i) = (next(s,i)[1] >= s.limit)
function next(s::IntSet, i)
n = ccall(:bitvector_next, Int32, (Ptr{Uint32}, Uint64, Uint64),
s.bits, uint64(i), uint64(s.limit))
(n, n+1)
end
isempty(s::IntSet) =
ccall(:bitvector_any1, Uint32, (Ptr{Uint32}, Uint32, Uint32),
s.bits, uint32(0), uint32(s.limit))==0
function choose(s::IntSet)
n = next(s,0)[1]
if n >= s.limit
error("choose: set is empty")
end
n
end
numel(s::IntSet) =
int32(ccall(:bitvector_count, Uint64, (Ptr{Uint32}, Uint32, Uint64),
s.bits, uint32(0), uint64(s.limit)))
function show(s::IntSet)
print("intset(")
first = true
for n = s
if !first
print(", ")
end
print(n)
first = false
end
print(")")
end