2 -- Copyright (C) 2008-2010 Matthew Wild
3 -- Copyright (C) 2008-2010 Waqas Hussain
5 -- This project is MIT/X11 licensed. Please see the
6 -- COPYING file in the source package for more information.
9 local ipairs
, pairs
, setmetatable
, next, tostring =
10 ipairs
, pairs
, setmetatable
, next, tostring;
11 local t_concat
= table.concat
;
16 local set_mt
= { __name
= "set" };
17 function set_mt
.__call(set
, _
, k
)
18 return next(set
._items
, k
);
22 function items_mt
.__call(items
, _
, k
)
23 return next(items
, k
);
26 function set_mt
:__freeze()
28 for item
in self
._items
do
34 local function new(list
)
35 local items
= setmetatable({}, items_mt
);
36 local set
= { _items
= items
};
38 -- We access the set through an upvalue in these methods, so ignore 'self' being unused
39 --luacheck: ignore 212/self
41 function set
:add(item
)
45 function set
:contains(item
)
53 function set
:remove(item
)
57 function set
:add_list(item_list
)
59 for _
, item
in ipairs(item_list
) do
65 function set
:include(otherset
)
66 for item
in otherset
do
71 function set
:exclude(otherset
)
72 for item
in otherset
do
78 return not next(items
);
85 return setmetatable(set
, set_mt
);
88 local function union(set1
, set2
)
90 local items
= set
._items
;
92 for item
in pairs(set1
._items
) do
96 for item
in pairs(set2
._items
) do
103 local function difference(set1
, set2
)
105 local items
= set
._items
;
107 for item
in pairs(set1
._items
) do
108 items
[item
] = (not set2
._items
[item
]) or nil;
114 local function intersection(set1
, set2
)
116 local items
= set
._items
;
118 set1
, set2
= set1
._items
, set2
._items
;
120 for item
in pairs(set1
) do
121 items
[item
] = (not not set2
[item
]) or nil;
127 local function xor(set1
, set2
)
128 return union(set1
, set2
) - intersection(set1
, set2
);
131 function set_mt
.__add(set1
, set2
)
132 return union(set1
, set2
);
134 function set_mt
.__sub(set1
, set2
)
135 return difference(set1
, set2
);
137 function set_mt
.__div(set
, func
)
138 local new_set
= new();
139 local items
, new_items
= set
._items
, new_set
._items
;
140 for item
in pairs(items
) do
141 local new_item
= func(item
);
142 if new_item
~= nil then
143 new_items
[new_item
] = true;
148 function set_mt
.__eq(set1
, set2
)
149 set1
, set2
= set1
._items
, set2
._items
;
150 for item
in pairs(set1
) do
151 if not set2
[item
] then
156 for item
in pairs(set2
) do
157 if not set1
[item
] then
164 function set_mt
.__tostring(set
)
165 local s
, items
= { }, set
._items
;
166 for item
in pairs(items
) do
167 s
[#s
+1] = tostring(item
);
169 return t_concat(s
, ", ");
175 difference
= difference
;
176 intersection
= intersection
;