UNPKG

4.68 kBJavaScriptView Raw
1var _includes =
2/*#__PURE__*/
3require("./_includes");
4
5var _Set =
6/*#__PURE__*/
7function () {
8 function _Set() {
9 /* globals Set */
10 this._nativeSet = typeof Set === 'function' ? new Set() : null;
11 this._items = {};
12 }
13
14 // until we figure out why jsdoc chokes on this
15 // @param item The item to add to the Set
16 // @returns {boolean} true if the item did not exist prior, otherwise false
17 //
18 _Set.prototype.add = function (item) {
19 return !hasOrAdd(item, true, this);
20 }; //
21 // @param item The item to check for existence in the Set
22 // @returns {boolean} true if the item exists in the Set, otherwise false
23 //
24
25
26 _Set.prototype.has = function (item) {
27 return hasOrAdd(item, false, this);
28 }; //
29 // Combines the logic for checking whether an item is a member of the set and
30 // for adding a new item to the set.
31 //
32 // @param item The item to check or add to the Set instance.
33 // @param shouldAdd If true, the item will be added to the set if it doesn't
34 // already exist.
35 // @param set The set instance to check or add to.
36 // @return {boolean} true if the item already existed, otherwise false.
37 //
38
39
40 return _Set;
41}();
42
43function hasOrAdd(item, shouldAdd, set) {
44 var type = typeof item;
45 var prevSize, newSize;
46
47 switch (type) {
48 case 'string':
49 case 'number':
50 // distinguish between +0 and -0
51 if (item === 0 && 1 / item === -Infinity) {
52 if (set._items['-0']) {
53 return true;
54 } else {
55 if (shouldAdd) {
56 set._items['-0'] = true;
57 }
58
59 return false;
60 }
61 } // these types can all utilise the native Set
62
63
64 if (set._nativeSet !== null) {
65 if (shouldAdd) {
66 prevSize = set._nativeSet.size;
67
68 set._nativeSet.add(item);
69
70 newSize = set._nativeSet.size;
71 return newSize === prevSize;
72 } else {
73 return set._nativeSet.has(item);
74 }
75 } else {
76 if (!(type in set._items)) {
77 if (shouldAdd) {
78 set._items[type] = {};
79 set._items[type][item] = true;
80 }
81
82 return false;
83 } else if (item in set._items[type]) {
84 return true;
85 } else {
86 if (shouldAdd) {
87 set._items[type][item] = true;
88 }
89
90 return false;
91 }
92 }
93
94 case 'boolean':
95 // set._items['boolean'] holds a two element array
96 // representing [ falseExists, trueExists ]
97 if (type in set._items) {
98 var bIdx = item ? 1 : 0;
99
100 if (set._items[type][bIdx]) {
101 return true;
102 } else {
103 if (shouldAdd) {
104 set._items[type][bIdx] = true;
105 }
106
107 return false;
108 }
109 } else {
110 if (shouldAdd) {
111 set._items[type] = item ? [false, true] : [true, false];
112 }
113
114 return false;
115 }
116
117 case 'function':
118 // compare functions for reference equality
119 if (set._nativeSet !== null) {
120 if (shouldAdd) {
121 prevSize = set._nativeSet.size;
122
123 set._nativeSet.add(item);
124
125 newSize = set._nativeSet.size;
126 return newSize === prevSize;
127 } else {
128 return set._nativeSet.has(item);
129 }
130 } else {
131 if (!(type in set._items)) {
132 if (shouldAdd) {
133 set._items[type] = [item];
134 }
135
136 return false;
137 }
138
139 if (!_includes(item, set._items[type])) {
140 if (shouldAdd) {
141 set._items[type].push(item);
142 }
143
144 return false;
145 }
146
147 return true;
148 }
149
150 case 'undefined':
151 if (set._items[type]) {
152 return true;
153 } else {
154 if (shouldAdd) {
155 set._items[type] = true;
156 }
157
158 return false;
159 }
160
161 case 'object':
162 if (item === null) {
163 if (!set._items['null']) {
164 if (shouldAdd) {
165 set._items['null'] = true;
166 }
167
168 return false;
169 }
170
171 return true;
172 }
173
174 /* falls through */
175
176 default:
177 // reduce the search size of heterogeneous sets by creating buckets
178 // for each type.
179 type = Object.prototype.toString.call(item);
180
181 if (!(type in set._items)) {
182 if (shouldAdd) {
183 set._items[type] = [item];
184 }
185
186 return false;
187 } // scan through all previously applied items
188
189
190 if (!_includes(item, set._items[type])) {
191 if (shouldAdd) {
192 set._items[type].push(item);
193 }
194
195 return false;
196 }
197
198 return true;
199 }
200} // A simple Set type that honours R.equals semantics
201
202
203module.exports = _Set;
\No newline at end of file