1 type Multiset<T> @abstract = 2 let multiset = StdMultiset<T>.new 3 let mut is_invoking_callbacks = false 4 let on_added_callbacks = StdList<T -> Unit>.new 5 let on_removed_callbacks = StdList<T -> Unit>.new 6 let tokens = StdList<Token>.new 7 8 let invoke_callbacks (callbacks : StdList<T -> Unit>) (x : T) = 9 assert not is_invoking_callbacks 10 is_invoking_callbacks = true 11 12 for f in callbacks do 13 f x 14 15 is_invoking_callbacks = false 16 17 def is_empty = multiset.is_empty 18 def is_not_empty = multiset.is_not_empty 19 20 def contains (x : T) = multiset.contains x 21 def get_iterator = multiset.get_iterator 22 23 def subscribe (f : T -> Unit) (g : T -> Unit) = 24 assert not is_invoking_callbacks 25 26 on_added_callbacks.add f 27 on_removed_callbacks.add g 28 29 Token { assert not is_invoking_callbacks 30 on_added_callbacks.remove f 31 on_removed_callbacks.remove g } 32 33 def push_token (token : Token) = 34 tokens.add token 35 36 fun destruct = 37 for i = tokens.size - 1 downto 0 do 38 tokens[i].discard 39 40 type MutMultiset<T> @[mut_of Multiset] = 41 inherit Multiset<T> 42 43 def add (x : T) = 44 assert not is_invoking_callbacks 45 46 multiset.add x 47 48 if multiset.multiplicity x == 1 then 49 invoke_callbacks on_added_callbacks x 50 51 def remove (x : T) = 52 assert not is_invoking_callbacks 53 54 multiset.remove x 55 if not multiset.contains x then 56 invoke_callbacks on_removed_callbacks x 57 58 def as_readonly = self as Multiset<T> 59