1 | 'use strict';
|
2 |
|
3 | var callable = require('es5-ext/object/valid-callable')
|
4 | , clear = require('es5-ext/object/clear')
|
5 | , setPrototypeOf = require('es5-ext/object/set-prototype-of')
|
6 | , d = require('d')
|
7 | , iterator = require('es6-iterator/valid-iterable')
|
8 | , forOf = require('es6-iterator/for-of')
|
9 | , Set = require('../polyfill')
|
10 | , Iterator = require('../lib/primitive-iterator')
|
11 |
|
12 | , create = Object.create, defineProperties = Object.defineProperties
|
13 | , defineProperty = Object.defineProperty
|
14 | , hasOwnProperty = Object.prototype.hasOwnProperty
|
15 | , PrimitiveSet;
|
16 |
|
17 | module.exports = PrimitiveSet = function (/*iterable, serialize*/) {
|
18 | var iterable = arguments[0], serialize = arguments[1];
|
19 | if (!(this instanceof PrimitiveSet)) {
|
20 | return new PrimitiveSet(iterable, serialize);
|
21 | }
|
22 | if (this.__setData__ !== undefined) {
|
23 | throw new TypeError(this + " cannot be reinitialized");
|
24 | }
|
25 | if (iterable != null) iterator(iterable);
|
26 | if (serialize !== undefined) {
|
27 | callable(serialize);
|
28 | defineProperty(this, '_serialize', d('', serialize));
|
29 | }
|
30 | defineProperties(this, {
|
31 | __setData__: d('c', create(null)),
|
32 | __size__: d('w', 0)
|
33 | });
|
34 | if (!iterable) return;
|
35 | forOf(iterable, function (value) {
|
36 | var key = this._serialize(value);
|
37 | if (key == null) throw new TypeError(value + " cannot be serialized");
|
38 | if (hasOwnProperty.call(this.__setData__, key)) return;
|
39 | this.__setData__[key] = value;
|
40 | ++this.__size__;
|
41 | }, this);
|
42 | };
|
43 | if (setPrototypeOf) setPrototypeOf(PrimitiveSet, Set);
|
44 |
|
45 | PrimitiveSet.prototype = create(Set.prototype, {
|
46 | constructor: d(PrimitiveSet),
|
47 | _serialize: d(function (value) {
|
48 | if (value && (typeof value.toString !== 'function')) return null;
|
49 | return String(value);
|
50 | }),
|
51 | add: d(function (value) {
|
52 | var key = this._serialize(value);
|
53 | if (key == null) throw new TypeError(value + " cannot be serialized");
|
54 | if (hasOwnProperty.call(this.__setData__, key)) return this;
|
55 | this.__setData__[key] = value;
|
56 | ++this.__size__;
|
57 | this.emit('_add', key);
|
58 | return this;
|
59 | }),
|
60 | clear: d(function () {
|
61 | if (!this.__size__) return;
|
62 | clear(this.__setData__);
|
63 | this.__size__ = 0;
|
64 | this.emit('_clear');
|
65 | }),
|
66 | delete: d(function (value) {
|
67 | var key = this._serialize(value);
|
68 | if (key == null) return false;
|
69 | if (!hasOwnProperty.call(this.__setData__, key)) return false;
|
70 | delete this.__setData__[key];
|
71 | --this.__size__;
|
72 | this.emit('_delete', key);
|
73 | return true;
|
74 | }),
|
75 | entries: d(function () { return new Iterator(this, 'key+value'); }),
|
76 | get: d(function (key) {
|
77 | key = this._serialize(key);
|
78 | if (key == null) return;
|
79 | return this.__setData__[key];
|
80 | }),
|
81 | has: d(function (value) {
|
82 | var key = this._serialize(value);
|
83 | if (key == null) return false;
|
84 | return hasOwnProperty.call(this.__setData__, key);
|
85 | }),
|
86 | size: d.gs(function () { return this.__size__; }),
|
87 | values: d(function () { return new Iterator(this); })
|
88 | });
|