1     begin@ list
2     
3     type List<T> @abstract @[mut local] =
4         let mut array = Array<T> 0
5         var size : u32 = 0
6         var version : u32 = 0
7     
8         fun get (i : u32) = array[i]
9         fun get (i : i32) =
10            assert i >= 0
11            array[i]
12    
13        fun get_ptr (i : u32) = array.as_ptr + i
14        fun get_ptr (i : i32) =
15            assert i >= 0
16            array.as_ptr + i
17    
18        def is_empty = size == 0
19        def is_not_empty = size <> 0
20    
21        local as_mut_slice () = MutSlice<T> array.as_mut_ptr size
22        def as_slice = Slice<T> array.as_ptr size
23        def as_safe_slice = SafeSlice<T> array.as_ptr size version@ptr version
24        def as_ptr = array.as_ptr
25    
26        def try_index_of (x : T) =
27            for i = 0 until size do
28                if array[i] == x then return Some i
29    
30            None
31    
32        def index_of x = try_index_of x |> unwrap_or_fail "no such item"
33    
34    type MutList<T> @[mut_of List] =
35        inherit List<T>
36    
37        fun get_mut_ptr (i : u32) = array.as_mut_ptr + i
38    
39        fun set (i : u32) value = array[i] = value
40        fun set (i : i32) value =
41            assert i >= 0
42            array[i] = value
43    
44        let set_array_size (x : u32) =
45            let prev_array = array
46            array = Array x
47            prev_array.copy_to array size
48            if prev_array.size <> 0 then
49                prev_array.discard
50    
51        def add (i : u32) x =
52            assert i <= size
53            if size == array.size then
54                set_array_size (if size == 0 then 4 else size * 2)
55    
56            if i <> size then
57                for j = size downto i + 1 do
58                    array[j] = array[j - 1]
59    
60            array[i] = x
61            size += 1
62            version += 1
63    
64        def add x = add size x
65    
66        def remove_at (index : u32) =
67            assert index < size
68    
69            if size > 1 then
70                for i = index to size - 2 do
71                    array[i] = array[i + 1]
72    
73            size -= 1
74            version += 1
75    
76        def remove_at @secondary (index : i32) =
77            assert index >= 0
78            remove_at index.as<u32>
79    
80        def remove x =
81            let index = index_of x
82            remove_at index
83    
84        def remove (i : u32) (x : T) =
85            let item = self[i]
86            assert item == x
87            remove_at i
88    
89        def clear =
90            size = 0
91            version += 1
92    
93        def provision (count : u32) =
94            if array.size < count then
95                set_array_size count
96                version += 1
97    
98        def as_readonly = self as List<T>
99    
100   object List<T> =
101       val empty = List<T>.new |> as_readonly
102